【问题标题】:How to integrate input from DateTimeInterface into Doctrine DBAL query builder?如何将来自 DateTimeInterface 的输入集成到 Doctrine DBAL 查询构建器中?
【发布时间】:2022-11-14 17:59:48
【问题描述】:

我对 PHP 非常陌生,并且正在为 Shopware (5.6) 开发一个插件。 目标是通过添加一个显示预购商品表(商品 ID、预购数量、$-value)的新选项卡来扩展商品统计信息。

该插件成功运行并且能够显示所需的信息,但是我无法集成来自 DateTimeInterface 的输入。我希望那里输入的日期与预购商品的发布日期相对应,因此我可以过滤特定时间范围并查看哪些预购商品将在该时间段内交付。

以下代码引用了 Shopware 控制器:


旧代码(工作,但显然没有 DateTimeInterface 集成) 结果,我得到了一张包含所有预购商品的表格

declare(strict_types=1);


class Shopware_Controllers_Backend_CustomStatsController extends Shopware_Controllers_Backend_ExtJs {
  /**
   * calls the getPreorderSubsAction function that connects with the database and
   * delivers the content for the statistics table
   *
   * @return void
   */
  public function getPreorderSubsAction() {
    $connection = $this->container->get('dbal_connection');
    $query = $connection->createQueryBuilder();
    $query->select([
      'ps.abo',
      'smao.name',
      'ROUND(SUM(ps.preordered * ps.unit_price),2) AS preorder_value'
      ])
      ->from('vw_PreorderSubs', 'ps')
      ->join('ps', 'salt_model_abo', 'smao', 'ps.abo = smao.id')
      ->where('ps.latest_issue_esd <= NOW()')
      ->groupBy('ps.abo');

    $data = $query->execute()->fetchAll();

    $this->View()->assign([
        'success' => true,
        'data' => $data,
        'count' => count($data)
    ]);
  }
}

新代码:(不起作用),选择“统计信息”选项卡时,查询似乎简直是空,因为什么也找不到。但是对于所选的时间范围,我应该得到一个包含 13 个项目的列表。

<?php
declare(strict_types=1);

class Shopware_Controllers_Backend_SaltCustomStatsController extends Shopware_Controllers_Backend_ExtJs {
  /**
   * calls the getPreorderSubsAction function that connects with the database and
   * delivers the content for the statistics table
   *
   * @return void
   */
  public function getPreorderSubsAction(\DateTimeInterface $from = null, \DateTimeInterface $to = null){
    $connection = $this->container->get('dbal_connection');
    $query = $connection->createQueryBuilder($from, $to);
    $query->select([
      'ps.abo',
      'smao.name',
      'ROUND(SUM(ps.preordered * ps.unit_price),2) AS preorder_value'
      ])
      ->from('vw_PreorderSubs', 'ps')
      ->join('ps', 's_model_abo', 'smao', 'ps.abo = smao.id')
      ->where('ps.latest_issue_esd <= NOW()')
      ->andWhere('ps.order_date <= "?"')
      ->andWhere('ps.order_date >= "?"')
      ->groupBy('ps.abo')
      ->setParameter(0, $from)
      ->setParameter(1, $to)
      ;

    $data = $query->execute()->fetchAll();

    $this->View()->assign([
        'success' => true,
        'data' => $data,
        'count' => count($data)
    ]);
  }
}

我尝试的变体不成功:

->from('vw_PreorderSubs', 'ps')
      ->join('ps', 's_model_abo', 'smao', 'ps.abo = smao.id')
      ->where('ps.latest_issue_esd <= NOW()')
      ->andWhere('ps.order_date between "?" and "?"')
      ->groupBy('ps.abo')
      ->setParameter(0, $from)
      ->setParameter(1, $to)
      ;

我确信这是显而易见的。由于它不会引发错误,因此代码似乎可以正常工作,就好像日期输入本身是正确的一样,但是没有结果可显示。

如何让代码正确地接受来自 Shopware 后端的 DateTimeInterface 的输入并将其插入到查询中?

ps.order_date 字段的格式为 YYYY-MM-DD。 `

【问题讨论】:

    标签: php plugins query-builder dbal shopware5


    【解决方案1】:

    解决方案非常简单: GET /backend/SaltCustomStatsController/getPreorderEbooks?_dc=1668154802232&node=root&fromDate=2022-10-11T00%3A00%3A00&toDate=2022-11-11T09%3A19%3A57&page=1&start=0&limit=25 HTTP/1.1

    从界面中选择的日期是 GET 请求的一部分。

    以下是它们在代码中的集成方式:

    public function getPreorderSubsAction(){
        $connection = $this->container->get('dbal_connection');
        $query = $connection->createQueryBuilder();
        $query->select([
          'ps.abo',
          'smao.name',
          'ROUND(SUM(ps.preordered * ps.unit_price),2) AS preorder_value'
          ])
          ->from('vw_PreorderSubs', 'ps')
          ->join('ps', 's_model_abo', 'smao', 'ps.abo = smao.id')
          ->where('ps.latest_issue_esd <= NOW()')
          ->andWhere('ps.order_date between :from and :to')
          ->setParameter('from', $this->getFromDate()->format('Y-m-d H:i:s'))
          ->setParameter('to', $this->getToDate()->format('Y-m-d H:i:s'))
          ->groupBy('ps.abo');
    
        $data = $query->execute()->fetchAll();
    
        $this->View()->assign([
            'success' => true,
            'data' => $data,
            'count' => count($data)
        ]);
      }
    

    我从 ShopwareControllersBackendAnalytics 添加了辅助函数来定义变量:

      /**
       * helper to get the from date in the right format
       *
       * return DateTimeInterface | fromDate
       */
      private function getFromDate()
      {
          $fromDate = $this->Request()->getParam('fromDate');
          if (empty($fromDate)) {
              $fromDate = new DateTime();
              $fromDate = $fromDate->sub(new DateInterval('P1M'));
          } else {
              $fromDate = new DateTime($fromDate);
          }
    
          return $fromDate;
      }
    
      /**
       * helper to get the to date in the right format
       *
       * return DateTime | toDate
       */
      private function getToDate()
      {
          //if a to date passed, format it over the DateTime object. Otherwise create a new date with today
          $toDate = $this->Request()->getParam('toDate');
          if (empty($toDate)) {
              $toDate = new DateTime();
          } else {
              $toDate = new DateTime($toDate);
          }
          //to get the right value cause 2012-02-02 is smaller than 2012-02-02 15:33:12
          $toDate = $toDate->add(new DateInterval('P1D'));
          $toDate = $toDate->sub(new DateInterval('PT1S'));
    
          return $toDate;
      }
    

    现在一切正常。

    【讨论】:

      猜你喜欢
      • 2023-03-04
      • 2015-11-09
      • 2014-10-15
      • 1970-01-01
      • 2015-11-01
      • 2015-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多