er = :newsletter') ->andWhere('sts.subscriber = :subscriber') ->setParameter('newsletter', $newsletter) ->setParameter('subscriber', $subscriberId) ->getQuery() ->getResult(); } public function findOneScheduledByNewsletterAndSubscriber(NewsletterEntity $newsletter, SubscriberEntity $subscriber): ?ScheduledTaskEntity { $scheduledTask = $this->doctrineRepository->createQueryBuilder('st') ->join(SendingQueueEntity::class, 'sq', Join::WITH, 'st = sq.task') ->join(ScheduledTaskSubscriberEntity::class, 'sts', Join::WITH, 'st = sts.task') ->andWhere('st.status = :status') ->andWhere('sq.newsletter = :newsletter') ->andWhere('sts.subscriber = :subscriber') ->setMaxResults(1) ->setParameter('status', ScheduledTaskEntity::STATUS_SCHEDULED) ->setParameter('newsletter', $newsletter) ->setParameter('subscriber', $subscriber) ->getQuery() ->getOneOrNullResult(); // for phpstan because it detects mixed instead of entity return ($scheduledTask instanceof ScheduledTaskEntity) ? $scheduledTask : null; } public function findScheduledOrRunningTask(?string $type): ?ScheduledTaskEntity { $queryBuilder = $this->doctrineRepository->createQueryBuilder('st') ->select('st') ->where('((st.status = :scheduledStatus) OR (st.status is NULL))') ->andWhere('st.deletedAt IS NULL') ->setParameter('scheduledStatus', ScheduledTaskEntity::STATUS_SCHEDULED) ->setMaxResults(1) ->orderBy('st.scheduledAt', 'DESC'); if (!empty($type)) { $queryBuilder ->andWhere('st.type = :type') ->setParameter('type', $type); } return $queryBuilder->getQuery()->getOneOrNullResult(); } public function findScheduledTask(?string $type): ?ScheduledTaskEntity { $queryBuilder = $this->doctrineRepository->createQueryBuilder('st') ->select('st') ->where('st.status = :scheduledStatus') ->andWhere('st.deletedAt IS NULL') ->setParameter('scheduledStatus', ScheduledTaskEntity::STATUS_SCHEDULED) ->setMaxResults(1) ->orderBy('st.scheduledAt', 'DESC'); if (!empty($type)) { $queryBuilder ->andWhere('st.type = :type') ->setParameter('type', $type); } return $queryBuilder->getQuery()->getOneOrNullResult(); } public function findPreviousTask(ScheduledTaskEntity $task): ?ScheduledTaskEntity { return $this->doctrineRepository->createQueryBuilder('st') ->select('st') ->where('st.type = :type') ->setParameter('type', $task->getType()) ->andWhere('st.createdAt < :created') ->setParameter('created', $task->getCreatedAt()) ->orderBy('st.scheduledAt', 'DESC') ->setMaxResults(1) ->getQuery() ->getOneOrNullResult(); } public function findDueByType($type, $limit = null) { return $this->findByTypeAndStatus($type, ScheduledTaskEntity::STATUS_SCHEDULED, $limit); } public function findRunningByType($type, $limit = null) { return $this->findByTypeAndStatus($type, null, $limit); } public function findCompletedByType($type, $limit = null) { return $this->findByTypeAndStatus($type, ScheduledTaskEntity::STATUS_COMPLETED, $limit); } public function findFutureScheduledByType($type, $limit = null) { return $this->findByTypeAndStatus($type, ScheduledTaskEntity::STATUS_SCHEDULED, $limit, true); } public function getCountsPerStatus(string $type = 'sending') { $stats = [ ScheduledTaskEntity::STATUS_COMPLETED => 0, ScheduledTaskEntity::STATUS_PAUSED => 0, ScheduledTaskEntity::STATUS_SCHEDULED => 0, ScheduledTaskEntity::STATUS_CANCELLED => 0, ScheduledTaskEntity::VIRTUAL_STATUS_RUNNING => 0, ]; $counts = $this->doctrineRepository->createQueryBuilder('st') ->select('COUNT(st.id) as value') ->addSelect('st.status') ->where('st.deletedAt IS NULL') ->andWhere('st.type = :type') ->setParameter('type', $type) ->addGroupBy('st.status') ->getQuery() ->getResult(); foreach ($counts as $count) { if ($count['status'] === null) { $stats[ScheduledTaskEntity::VIRTUAL_STATUS_RUNNING] = (int)$count['value']; continue; } $stats[$count['status']] = (int)$count['value']; } return $stats; } /** * @param string|null $type * @param array $statuses * @param int $limit * @return array */ public function getLatestTasks( $type = null, $statuses = [ ScheduledTaskEntity::STATUS_COMPLETED, ScheduledTaskEntity::STATUS_CANCELLED, ScheduledTaskEntity::STATUS_SCHEDULED, ScheduledTaskEntity::STATUS_PAUSED, ScheduledTaskEntity::VIRTUAL_STATUS_RUNNING, ], $limit = self::TASK_BATCH_SIZE ) { $result = []; foreach ($statuses as $status) { $tasksQuery = $this->doctrineRepository->createQueryBuilder('st') ->select('st') ->where('st.deletedAt IS NULL'); if ($status === ScheduledTaskEntity::VIRTUAL_STATUS_RUNNING) { $tasksQuery = $tasksQuery->andWhere('st.status = :status OR st.status IS NULL'); } else { $tasksQuery = $tasksQuery->andWhere('st.status = :status'); } if ($type) { $tasksQuery = $tasksQuery->andWhere('st.type = :type') ->setParameter('type', $type); } $tasks = $tasksQuery ->setParameter('status', $status) ->setMaxResults($limit) ->orderBy('st.id', 'desc') ->getQuery() ->getResult(); $result = array_merge($result, $tasks); } return $result; } /** * @return ScheduledTaskEntity[] */ public function findRunningSendingTasks(?int $limit = null): array { return $this->doctrineRepository->createQueryBuilder('st') ->select('st') ->join('st.sendingQueue', 'sq') ->where('st.type = :type') ->andWhere('st.status IS NULL') ->andWhere('st.deletedAt IS NULL') ->orderBy('st.priority', 'ASC') ->addOrderBy('st.updatedAt', 'ASC') ->setMaxResults($limit) ->setParameter('type', SendingQueue::TASK_TYPE) ->getQuery() ->getResult(); } /** * @param string $type * @param SubscriberEntity $subscriber * @return ScheduledTaskEntity[] * @throws \MailPoetVendor\Doctrine\ORM\NonUniqueResultException */ public function findByTypeAndSubscriber(string $type, SubscriberEntity $subscriber): array { $query = $this->doctrineRepository->createQueryBuilder('st') ->select('st') ->join(ScheduledTaskSubscriberEntity::class, 'sts', Join::WITH, 'st = sts.task') ->where('st.type = :type') ->andWhere('sts.subscriber = :subscriber') ->andWhere('st.deletedAt IS NULL') ->andWhere('st.status = :status') ->setParameter('type', $type) ->setParameter('subscriber', $subscriber->getId()) ->setParameter('status', ScheduledTaskEntity::STATUS_SCHEDULED) ->getQuery(); $tasks = $query->getResult(); return $tasks; } public function touchAllByIds(array $ids): void { $now = Carbon::now()->millisecond(0); $this->entityManager->createQueryBuilder() ->update(ScheduledTaskEntity::class, 'st') ->set('st.updatedAt', ':updatedAt') ->setParameter('updatedAt', $now) ->where('st.id IN (:ids)') ->setParameter('ids', $ids, ArrayParameterType::INTEGER) ->getQuery() ->execute(); // update was done via DQL, make sure the entities are also refreshed in the entity manager $this->refreshAll(function (ScheduledTaskEntity $entity) use ($ids) { return in_array($entity->getId(), $ids, true); }); } /** * @return ScheduledTaskEntity[] */ public function findScheduledSendingTasks(?int $limit = null): array { $now = Carbon::now()->millisecond(0); return $this->doctrineRepository->createQueryBuilder('st') ->select('st') ->join('st.sendingQueue', 'sq') ->where('st.deletedAt IS NULL') ->andWhere('st.status = :status') ->andWhere('st.scheduledAt <= :now') ->andWhere('st.type = :type') ->orderBy('st.updatedAt', 'ASC') ->setMaxResults($limit) ->setParameter('status', ScheduledTaskEntity::STATUS_SCHEDULED) ->setParameter('now', $now) ->setParameter('type', SendingQueue::TASK_TYPE) ->getQuery() ->getResult(); } public function invalidateTask(ScheduledTaskEntity $task): void { $task->setStatus(ScheduledTaskEntity::STATUS_INVALID); $this->persist($task); $this->flush(); } public function cancelTask(ScheduledTaskEntity $task): void { if (!in_array($task->getStatus(), self::CANCELLABLE_STATUSES)) { throw new \Exception(__('Only scheduled and running tasks can be cancelled', 'mailpoet'), 400); } $task->setStatus(ScheduledTaskEntity::STATUS_CANCELLED); $task->setCancelledAt(Carbon::now()->millisecond(0)); $this->persist($task); $this->flush(); } public function rescheduleTask(ScheduledTaskEntity $task): void { if ($task->getStatus() !== ScheduledTaskEntity::STATUS_CANCELLED) { throw new \Exception(__('Only cancelled tasks can be rescheduled', 'mailpoet'), 400); } if ($task->getScheduledAt() <= Carbon::now()->millisecond(0)) { $task->setStatus(ScheduledTaskEntity::VIRTUAL_STATUS_RUNNING); $queue = $task->getSendingQueue(); if ($queue) { $this->sendingQueuesRepository->resume($queue); } } else { $task->setStatus(ScheduledTaskEntity::STATUS_SCHEDULED); } $task->setCancelledAt(null); $this->persist($task); $this->flush(); } /** @param int[] $ids */ public function deleteByIds(array $ids): void { $this->entityManager->createQueryBuilder() ->delete(ScheduledTaskEntity::class, 't') ->where('t.id IN (:ids)') ->setParameter('ids', $ids) ->getQuery() ->execute(); // delete was done via DQL, make sure the entities are also detached from the entity manager $this->detachAll(function (ScheduledTaskEntity $entity) use ($ids) { return in_array($entity->getId(), $ids, true); }); } protected function findByTypeAndStatus($type, $status, $limit = null, $future = false) { $queryBuilder = $this->doctrineRepository->createQueryBuilder('st') ->select('st') ->where('st.type = :type') ->setParameter('type', $type) ->andWhere('st.deletedAt IS NULL'); if (is_null($status)) { $queryBuilder->andWhere('st.status IS NULL'); } else { $queryBuilder ->andWhere('st.status = :status') ->setParameter('status', $status); } if ($future) { $queryBuilder->andWhere('st.scheduledAt > :now'); } else { $queryBuilder->andWhere('st.scheduledAt <= :now'); } $now = Carbon::now()->millisecond(0); $queryBuilder->setParameter('now', $now); if ($limit) { $queryBuilder->setMaxResults($limit); } return $queryBuilder->getQuery()->getResult(); } protected function getEntityClassName() { return ScheduledTaskEntity::class; } }
Fatal error: Uncaught Error: Class "MailPoet\Newsletter\Sending\ScheduledTasksRepository" not found in /htdocs/wp-content/plugins/mailpoet/generated/FreeCachedContainer.php:4222 Stack trace: #0 /htdocs/wp-content/plugins/mailpoet/generated/FreeCachedContainer.php(4182): MailPoetGenerated\FreeCachedContainer->getScheduledTasksRepositoryService() #1 /htdocs/wp-content/plugins/mailpoet/generated/FreeCachedContainer.php(4909): MailPoetGenerated\FreeCachedContainer->getWelcomeSchedulerService() #2 /htdocs/wp-content/plugins/mailpoet/generated/FreeCachedContainer.php(2714): MailPoetGenerated\FreeCachedContainer->getWPService() #3 /htdocs/wp-content/plugins/mailpoet/generated/FreeCachedContainer.php(2607): MailPoetGenerated\FreeCachedContainer->getPopulatorService() #4 /htdocs/wp-content/plugins/mailpoet/generated/FreeCachedContainer.php(2681): MailPoetGenerated\FreeCachedContainer->getActivatorService() #5 /htdocs/wp-content/plugins/mailpoet/vendor-prefixed/symfony/dependency-injection/Container.php(122): MailPoetGenerated\FreeCachedContainer->getInitializerService() #6 /htdocs/wp-content/plugins/mailpoet/vendor-prefixed/symfony/dependency-injection/Container.php(110): MailPoetVendor\Symfony\Component\DependencyInjection\Container->make('MailPoet\\Config...', 1) #7 /htdocs/wp-content/plugins/mailpoet/lib/DI/ContainerWrapper.php(39): MailPoetVendor\Symfony\Component\DependencyInjection\Container->get('MailPoet\\Config...') #8 /htdocs/wp-content/plugins/mailpoet/mailpoet_initializer.php(88): MailPoet\DI\ContainerWrapper->get('MailPoet\\Config...') #9 /htdocs/wp-content/plugins/mailpoet/mailpoet.php(194): require_once('/htdocs/wp-cont...') #10 /htdocs/wp-settings.php(526): include_once('/htdocs/wp-cont...') #11 /htdocs/wp-config.php(78): require_once('/htdocs/wp-sett...') #12 /htdocs/wp-load.php(50): require_once('/htdocs/wp-conf...') #13 /htdocs/wp-blog-header.php(13): require_once('/htdocs/wp-load...') #14 /htdocs/index.php(17): require('/htdocs/wp-blog...') #15 {main} thrown in /htdocs/wp-content/plugins/mailpoet/generated/FreeCachedContainer.php on line 4222