<?php
namespace App\Repository;
use App\Entity\UserSessionLog;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @method UserSessionLog|null find($id, $lockMode = null, $lockVersion = null)
* @method UserSessionLog|null findOneBy(array $criteria, array $orderBy = null)
* @method UserSessionLog[] findAll()
* @method UserSessionLog[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class UserSessionLogRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, UserSessionLog::class);
}
/**
* Find active session by session ID
*/
public function findActiveBySessionId(string $sessionId): ?UserSessionLog
{
return $this->createQueryBuilder('s')
->andWhere('s.sessionId = :sessionId')
->andWhere('s.logoutAt IS NULL')
->setParameter('sessionId', $sessionId)
->getQuery()
->getOneOrNullResult();
}
/**
* Find all active sessions
*/
public function findActiveSessions(): array
{
return $this->createQueryBuilder('s')
->andWhere('s.logoutAt IS NULL')
->orderBy('s.lastActivityAt', 'DESC')
->getQuery()
->getResult();
}
/**
* Close inactive sessions (no activity for more than X minutes)
*/
public function closeInactiveSessions(int $inactiveMinutes = 30): int
{
$threshold = new \DateTime();
$threshold->modify("-{$inactiveMinutes} minutes");
$qb = $this->createQueryBuilder('s');
return $qb->update()
->set('s.logoutAt', ':now')
->set('s.duration', 'TIMESTAMPDIFF(SECOND, s.loginAt, s.lastActivityAt)')
->where('s.logoutAt IS NULL')
->andWhere('s.lastActivityAt < :threshold')
->setParameter('now', new \DateTime())
->setParameter('threshold', $threshold)
->getQuery()
->execute();
}
/**
* Get user session statistics
*/
public function getUserStats(int $userId, \DateTimeInterface $from, \DateTimeInterface $to): array
{
$qb = $this->createQueryBuilder('s');
return $qb->select([
'COUNT(s.id) as total_sessions',
'SUM(s.duration) as total_duration',
'AVG(s.duration) as avg_duration',
'MAX(s.duration) as max_duration',
'MIN(s.duration) as min_duration',
])
->where('s.user = :userId')
->andWhere('s.loginAt >= :from')
->andWhere('s.loginAt <= :to')
->setParameter('userId', $userId)
->setParameter('from', $from)
->setParameter('to', $to)
->getQuery()
->getSingleResult();
}
}