<?php declare(strict_types=1);
namespace Sq\Service\Repository\ORM;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\Query\ResultSetMappingBuilder;
use Doctrine\Persistence\ManagerRegistry;
use Sq\Entity\Schema\ORM\User;
use Sq\Service\Config\SqConfig;
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
/**
* @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 UserProviderInterface
{
private string $encryptionKey = '';
public function __construct(ManagerRegistry $registry, SqConfig $config)
{
parent::__construct($registry, User::class);
$key = $config->getConfig()['crypto_key'] ?? '';
$this->encryptionKey = is_string($key) ? $key : '';
}
/**
* This complicated query is necessary to ignore case differences.
*/
public function findOneByEmail(string $email): ?User
{
$rsm = new ResultSetMappingBuilder($this->getEntityManager());
$rsm->addRootEntityFromClassMetadata(User::class, 'u');
$query = $this->getEntityManager()->createNativeQuery(sprintf(
'SELECT %s FROM `users` AS `u` WHERE LOWER(CONVERT(AES_DECRYPT(`u`.`u_email`, :key) USING \'utf8\')) = :email LIMIT 1;',
$rsm->generateSelectClause(['u' => 'u'])
), $rsm);
$query->setParameters(['email' => strtolower($email), 'key' => $this->encryptionKey]);
return $query->getOneOrNullResult();
}
public function supportsClass(string $class): bool
{
return $class === User::class;
}
public function refreshUser(UserInterface $user): UserInterface
{
$this->getEntityManager()->refresh($user);
return $user;
}
/** @deprecated (delete when upgrading to Symfony 6+) */
public function loadUserByUsername(string $username): UserInterface
{
return $this->loadUserByIdentifier($username);
}
public function loadUserByIdentifier(string $identifier): UserInterface
{
if (null === $user = $this->findOneBy(['id' => $identifier]))
{
throw new UserNotFoundException;
}
// make sure the user is still in overhaul
if ($user->isRolledBackToLegacy())
{
throw new UserNotFoundException;
}
return $user;
}
}