Lines 95.23% 20 / 21
Functions and Methods 80.00% 4 / 5
Classes and Traits 0.00% 0 / 1
Name Lines Functions and Methods CRAP Classes and Traits
AgentStatRepository 95.23% 20 / 21 80.00% 4 / 5 8 0.00% 0 / 1
 __construct 100.00% 1 / 1 100.00% 1 / 1 1
 findByOwner 100.00% 1 / 1 100.00% 1 / 1 1
 findPrevious 100.00% 6 / 6 100.00% 1 / 1 2
 has 100.00% 1 / 1 100.00% 1 / 1 1
 findLatestByOwners 91.66% 11 / 12 0.00% 0 / 1 3.01
1<?php
2
3declare(strict_types=1);
4
5namespace App\Repository;
6
7use App\Entity\AgentStat;
8use App\Entity\User;
9use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
10use Doctrine\Common\Collections\Criteria;
11use Doctrine\Common\Collections\Order;
12use Doctrine\Persistence\ManagerRegistry;
13
14/**
15 * @extends ServiceEntityRepository<AgentStat>
16 */
17class AgentStatRepository extends ServiceEntityRepository
18{
19    public function __construct(ManagerRegistry $registry)
20    {
21        parent::__construct($registry, AgentStat::class);
22    }
23
24    /**
25     * @return list<AgentStat> newest first
26     */
27    public function findByOwner(User $owner): array
28    {
29        return $this->findBy(['owner' => $owner], ['datetime' => 'DESC', 'id' => 'DESC']);
30    }
31
32    /**
33     * The owner's newest stats before [$agentStat].
34     */
35    public function findPrevious(AgentStat $agentStat): ?AgentStat
36    {
37        $criteria = Criteria::create()
38            ->where(Criteria::expr()->eq('owner', $agentStat->owner))
39            ->andWhere(Criteria::expr()->lt('datetime', $agentStat->datetime))
40            ->orderBy(['datetime' => Order::Descending])
41            ->setMaxResults(1);
42
43        return $this->matching($criteria)->first() ?: null;
44    }
45
46    public function has(User $owner, \DateTimeImmutable $datetime): bool
47    {
48        return null !== $this->findOneBy(['owner' => $owner, 'datetime' => $datetime]);
49    }
50
51    /**
52     * The newest stats of each of [$owners] that has some, by owner id.
53     *
54     * @param User[] $owners
55     *
56     * @return array<int, AgentStat>
57     */
58    public function findLatestByOwners(array $owners): array
59    {
60        if ([] === $owners) {
61            return [];
62        }
63
64        /** @var AgentStat[] $stats */
65        $stats = $this->createQueryBuilder('s')
66            ->where('s.owner IN (:owners)')
67            ->andWhere('s.datetime = (SELECT MAX(s2.datetime) FROM '.AgentStat::class.' s2 WHERE s2.owner = s.owner)')
68            ->setParameter('owners', $owners)
69            ->getQuery()
70            ->getResult();
71
72        $latest = [];
73        foreach ($stats as $stat) {
74            $latest[(int) $stat->owner->id] = $stat;
75        }
76
77        return $latest;
78    }
79}