requestStack = $requestStack; } public static function isAllowed(): bool { return (bool) findModule(\Modules::ORDERS); } public function __construct(OrderWrapper $orderWrapper, ContextManager $contextManager) { $this->objectWrapper = $orderWrapper; $this->contextManager = $contextManager; } /** * @required */ public function setOrdersFilterSpecs(OrdersFilterSpecs $ordersFilterSpecs) { $this->ordersFilterSpecs = $ordersFilterSpecs; } public function getQuery(array $feedRow): QueryBuilder { $qb = sqlQueryBuilder()->select('o.*') ->from('orders', 'o'); $settings = json_decode($feedRow['settings'] ?? '', true) ?? []; $filter = $settings['filter'] ?? []; $days = $filter['order_days'] ?? 1; if (empty($days)) { $days = 1; } if ($this->requestStack->getMainRequest()?->get('date_from')) { // date is from GET parameter, its formated as Y-m-d $date = $this->requestStack->getMainRequest()?->get('date_from'); if (!$date_from = \DateTime::createFromFormat('Y-m-d H:i:s', $date)) { $date_from = $date.' 00:00:00'; } else { $date_from = $date_from->format('Y-m-d H:i:s'); } } else { // date is from admin field, we need to format it $date_from = $filter['date_created']['from'] ?? null; $date_from = empty($date_from) ? null : $this->prepareDate($date_from).' 00:00:00'; } if ($this->requestStack->getMainRequest()?->get('date_to')) { $date = $this->requestStack->getMainRequest()?->get('date_to'); if (!$date_to = \DateTime::createFromFormat('Y-m-d H:i:s', $date)) { $date_to = $date.' 23:59:59'; } else { $date_to = $date_to->format('Y-m-d H:i:s'); } } else { $date_to = $filter['date_created']['to'] ?? null; $date_to = empty($date_to) ? null : $this->prepareDate($date_to).' 23:59:59'; } // we handle date_created and date_updated manually, so we unset them to skip them in OrdersfIlterSpecs unset($filter['date_created']); if ($date_to || $date_from) { $qb->andWhere(Operator::orX( Operator::between('o.date_created', new \Range($date_from, $date_to)), )); } if (empty($filter['date_handled']['from']) && empty($filter['date_handled']['to']) && empty($date_from) && empty($date_to)) { // max days limit if ($filter['use_date_updated'] ?? false) { $qb->andWhere('COALESCE(date_updated, date_created) >= (DATE(NOW()) - INTERVAL :days DAY)') ->setParameter('days', $days); } else { $qb->andWhere('date_created >= (DATE(NOW()) - INTERVAL :days DAY)') ->setParameter('days', $days); } if ($filter['order_days_min'] ?? false) { // min days limit if ($filter['use_date_updated'] ?? false) { $qb->andWhere('COALESCE(date_updated, date_created) < (DATE(NOW()) - INTERVAL :days_min DAY)') ->setParameter('days_min', $filter['order_days_min']); } else { $qb->andWhere('date_created < (DATE(NOW()) - INTERVAL :days_min DAY)') ->setParameter('days_min', $filter['order_days_min']); } } } // orders filter $filterSpecs = null; if ($filter) { $filterSpecs = $this->ordersFilterSpecs->getSpecs($filter); } if ($filterSpecs) { $qb->andWhere($filterSpecs); } // Hard limit $qb->setMaxResults(100000); foreach ($this->specs as $spec) { $qb->andWhere($spec); } $this->query = $qb; return $qb; } public function filterByObjectID($objectID): void { $this->specs[] = function (QueryBuilder $qb) use ($objectID) { $qb->andWhere(Operator::equals(['o.id' => $objectID])); }; } public function getData(array $feedRow, ?int $limit = null): \Generator { $qb = $this->query ?? $this->getQuery($feedRow); $countQuery = (clone $qb) ->select('count(o.id) AS c') ->resetQueryPart('groupBy'); $count = (int) $countQuery->execute()->fetch()['c']; // use batching only if limit is NOT set $iterationLimit = isset($limit) ? 1 : ($count / (float) static::$batchSize); for ($i = 0; $i < $iterationLimit; $i++) { $qb->setFirstResult($i * static::$batchSize); $qb->setMaxResults($limit ?? static::$batchSize); $orders = new OrderCollection(); foreach ($qb->execute() as $row) { // TODO: predelat na OrdersList s multifetchama az jednou bude $order = new \Order(); $order->createFromArray($row); $orders->set((int) $row['id'], $order); // cast to (object) to force reference } $this->objectWrapper->setOrders($orders); foreach ($orders as $order) { yield $this->prepareSingleObject($order); } } } protected function initFeedGenerator(array $feedRow): void { if (isset($this->forcedFeedGenerator)) { $this->feedGenerator = $this->forcedFeedGenerator; } else { $this->feedGenerator = $this->v8FeedGenerator; } if (method_exists($this->feedGenerator, 'setBuildItemCallback')) { $this->feedGenerator->setBuildItemCallback(function (callable $callback, $v8Object) { /** @var $itemWrapper OrderWrapper */ $itemWrapper = $v8Object->value; $itemWrapper->activateOrderFor($callback); }); } } }