<?php
namespace App\Repository;
use App\Entity\Contract;
use App\Entity\InterventionRequest;
use App\Entity\Reminder\Handler;
use App\Entity\Reminder\Log;
use App\Entity\User;
use App\Service\InterventionRequest\WorkflowPlace;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface;
/**
* @method User|null find($id, $lockMode = null, $lockVersion = null)
* @method User|null findOneBy(array $criteria, array $orderBy = null)
* @method User[] findAll()
* @method User[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class UserRepository extends ServiceEntityRepository implements UserLoaderInterface
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, User::class);
}
/**
* Used to upgrade (rehash) the user's password automatically over time.
*/
public function upgradePassword(User $user, string $newHashedPassword): void
{
$user->setPassword($newHashedPassword);
$this->_em->persist($user);
$this->_em->flush();
}
/**
* On every page this method is called to load the user from session
* We need here to load authorizations and groups in a single query
* for perf issues.
*
* @throws \Doctrine\ORM\NonUniqueResultException
*
* @see UserLoaderInterface
*/
public function loadUserByIdentifier(string $identifier): ?User
{
return $this->createQueryBuilder('u')
->leftJoin('u.authorizations', 'ua')
->addSelect('ua')
->leftJoin('ua.authorization', 'a')
->addSelect('a')
->leftJoin('u.groups', 'ug')
->addSelect('ug')
->leftJoin('ug.group', 'g')
->addSelect('g')
->leftJoin('g.authorizations', 'gga')
->addSelect('gga')
->leftJoin('gga.authorization', 'ga')
->addSelect('ga')
->andWhere('u.enabled = 1 AND u.deleted=0')
->andWhere('u.email = :val')
->setParameter('val', $identifier)
->getQuery()
->getOneOrNullResult()
;
}
/** @deprecated since Symfony 5.3 */
public function loadUserByUsername(string $username): ?User
{
return $this->loadUserByIdentifier($username);
}
// needed to refresh user by the provider
/**
* Refreshes the user after being reloaded from the session.
*
* When a user is logged in, at the beginning of each request, the
* User object is loaded from the session and then this method is
* called. Your job is to make sure the user's data is still fresh by,
* for example, re-querying for fresh User data.
*
* If your firewall is "stateless: true" (for a pure API), this
* method is not called.
*
* @return User
*/
public function refreshUser(User $user)
{
return $this->createQueryBuilder('u')
->leftJoin('u.authorizations', 'ua')
->addSelect('ua')
->leftJoin('ua.authorization', 'a')
->addSelect('a')
->leftJoin('u.groups', 'ug')
->addSelect('ug')
->leftJoin('ug.group', 'g')
->addSelect('g')
->leftJoin('g.authorizations', 'gga')
->addSelect('gga')
->leftJoin('gga.authorization', 'ga')
->addSelect('ga')
->andWhere('u.enabled = 1 AND u.deleted=0')
->andWhere('u.id = :val')
->setParameter('val', $user->getId())
->getQuery()
->getOneOrNullResult()
;
}
public function hasAccess(int $subjectCompanyId, int $userCompanyId): bool
{
return $this->getEntityManager()
->getRepository(Contract::class)
->hasContractBetween($subjectCompanyId, $userCompanyId);
}
public function findLateInterventionRequest(Handler $handler)
{
$expression = $this->_em->getExpressionBuilder();
$minDate = (new \DateTimeImmutable())->modify('-2 days');
$minReminder = (new \DateTimeImmutable())->modify('-1 day');
return $this
->createQueryBuilder('u')
->where('u.enabled = 1')
->andwhere('u.deleted = 0')
->andWhere(
$expression->exists(
$this->_em
->createQueryBuilder()
->select('i')
->from(InterventionRequest::class, 'i')
->where('i.deleted = 0 and i.enabled = 1')
->andWhere('(i.place = :planning AND i.updatedAt < :minDate)')
->andWhere('intervention_request__available_for__user(i.id, u.id) = true')
)
)
->andWhere(
$expression->not($expression->exists(
$this->_em->getRepository(Log::class)
->createQueryBuilder('l')
->where('l.handler = :handler')
->andWhere('l.createdAt > :minReminder')
))
)
->setParameter('minDate', $minDate)
->setParameter('minReminder', $minReminder)
->setParameter('handler', $handler)
->setParameter('planning', WorkflowPlace::PLANNING)
->setMaxResults(50)
->getQuery()
->getResult()
;
}
public function getAllUsersForCompany(int $companyId)
{
$existingUsers = $this->createQueryBuilder('u')
->where('u.externalId IS NOT NULL')
->andWhere('u.company = :companyId')
->setParameter('companyId', $companyId)
->getQuery()
->getResult();
$usersByExternalId = [];
foreach ($existingUsers as $us) {
$usersByExternalId[$us->getExternalId()] = $us;
}
return $usersByExternalId;
}
public function getAllByExternalId(int $companyId)
{
$existingUsers = $this->createQueryBuilder('u')
->where('u.externalId IS NOT NULL')
->andWhere('u.company = :companyId')
->setParameter('companyId', $companyId)
->getQuery()
->getResult();
$usersByExternalId = [];
foreach ($existingUsers as $us) {
$usersByExternalId[$us->getExternalId()] = $us;
}
return $usersByExternalId;
}
}