<?php
declare(strict_types=1);
namespace Harmonizely\Repository;
use DateTime;
use DateTimeZone;
use Doctrine\Common\Persistence\ManagerRegistry;
use Doctrine\ORM\OptimisticLockException;
use Doctrine\ORM\ORMException;
use Doctrine\ORM\Query\Expr\Join;
use Harmonizely\Core\ORM\Tools\Contract\IPaginator;
use Harmonizely\Core\ORM\Tools\Paginator;
use Harmonizely\DTO\SuperAdmin\Customer\Request\GetCustomerListRequestDTO;
use Harmonizely\Model\DomainAwareInterface;
use Harmonizely\Model\Organization;
use Harmonizely\Model\User;
use Harmonizely\Model\UserInterface;
use Harmonizely\Repository\Contract\IUserRepository;
use Doctrine\ORM\NonUniqueResultException;
class UserRepository extends EntityRepository implements IUserRepository, DomainAwareEntityRepositoryInterface
{
/**
* UserRepository constructor.
*
* @param ManagerRegistry $registry
*/
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, User::class);
}
public function findOneEnabledBySlug(string $slug): ?UserInterface
{
return $this->createQueryBuilder('u')
->where('u.slug = :slug')
->andWhere('u.enabled = 1')
->setParameter('slug', $slug)
->getQuery()
->getOneOrNullResult();
}
/**
* @param string $slug
* @return UserInterface|null
* @throws NonUniqueResultException
*/
public function findOneBySlug(string $slug): ?UserInterface
{
return $this->createQueryBuilder('u')
->where('u.slug = :slug')
->setParameter('slug', $slug)
->getQuery()
->getOneOrNullResult();
}
/**
* @param int $id
* @return UserInterface|null
* @throws NonUniqueResultException
*/
public function findOneById(int $id): ?UserInterface
{
return $this->createQueryBuilder('u')
->where('u.id = :id')
->setParameter('id', $id)
->getQuery()
->getOneOrNullResult();
}
/**
* @param string $verificationCode
* @param string $confirmationToken
* @return UserInterface|null
* @throws NonUniqueResultException
*/
public function findOneByVerificationCodeAndConfirmationToken(string $verificationCode, string $confirmationToken): ?UserInterface
{
return $this->createQueryBuilder('u')
->where('u.verificationCode = :verificationCode')
->andWhere('u.confirmationToken = :confirmationToken')
->setParameters([
'verificationCode' => $verificationCode,
'confirmationToken' => $confirmationToken
])
->getQuery()
->getOneOrNullResult();
}
/**
* {@inheritdoc}
*/
public function countUsersBySlug(string $slug): int
{
return (int)$this->createQueryBuilder('u')
->select('count(u)')
->where('u.slug = :slug')
->setParameter('slug', $slug)
->getQuery()
->getSingleScalarResult();
}
public function findUsersWithExpiredSubscriptions(): array
{
$now = new DateTime('now', new DateTimeZone('UTC'));
return $this->createQueryBuilder('u')
->leftJoin('u.subscription', 's')
->where('s.expireAt <= :now')
->setParameter('now', $now)
->getQuery()
->getResult();
}
public function findOneByDomain(string $domain): ?DomainAwareInterface
{
/** @var DomainAwareInterface $object */
$object = $this->findOneBy(['domain' => $domain]);
return $object;
}
/**
* @param UserInterface $user
* @return UserInterface
* @throws ORMException
* @throws OptimisticLockException
*/
public function save(UserInterface $user): UserInterface
{
$this->_em->persist($user);
$this->_em->flush();
return $user;
}
/**
* @param Organization $organization
* @return array|UserInterface[]
*/
public function getList(Organization $organization): array
{
return $this->createQueryBuilder('u')
->innerJoin('u.members', 'om')
->andWhere('om.organization = :organization')
->andWhere('u.enabled = 1')
->setParameter('organization', $organization)
->getQuery()
->getResult();
}
/**
* @param string $email
* @return UserInterface|null
*/
public function findByEmail(string $email): ?UserInterface
{
return $this->findOneBy(['email' => $email]);
}
/**
* @param string $token
* @return UserInterface|null
*/
public function findByConfirmationToken(string $token): ?UserInterface
{
return $this->findOneBy(['confirmationToken' => $token]);
}
/**
* @param DateTime $createdAt
* @param string|null $template
* @return array|UserInterface[]
*/
public function getListByCreatedAtForEmail(DateTime $createdAt, ?string $template): array
{
$query = $this->createQueryBuilder('u')
->where('DATE(u.createdAt) = :createdAt')
->setParameter('createdAt', $createdAt->format('Y-m-d'))
->andWhere('u.enabled = 1')
->leftJoin('u.userEmailUnsubscribe', 'ueu')
->andWhere('ueu.id IS NULL');
if ($template) {
$query->leftJoin('u.userEmailLog', 'uel',Join::WITH, 'uel.template = :template')
->andWhere('uel.id IS NULL')
->setParameter('template', $template);
}
return $query->getQuery()
->getResult();
}
/**
* @param GetCustomerListRequestDTO $request
* @return IPaginator
*/
public function getCustomerList(GetCustomerListRequestDTO $request): IPaginator
{
$qb = $this->createQueryBuilder('u')
->leftJoin('u.members', 'm')
->leftJoin('m.organization', 'o');
switch ($request->getOrderField()) {
case 'email':
case 'fullName':
case 'slug':
case 'domain':
case 'createdAt':
case 'lastLogin':
$qb->orderBy('u.' . $request->getOrderField(), $request->getOrderDirection());
break;
case 'phone':
$qb->orderBy('u.phoneNumber', $request->getOrderDirection());
break;
case 'isEnabled':
$qb->orderBy('u.enabled', $request->getOrderDirection());
break;
case 'organizationSlug':
$qb->orderBy('o.slug', $request->getOrderDirection());
break;
default:
$qb->orderBy('u.createdAt', $request->getOrderDirection());
break;
}
if ($request->getFilter()) {
if ($request->getFilter()->getSearch()) {
$qb->andWhere('u.username LIKE :search OR u.email LIKE :search OR u.fullName LIKE :search OR u.slug LIKE :search')
->setParameter('search', '%' . $request->getFilter()->getSearch() . '%');
}
if ($request->getFilter()->getId()) {
$qb->andWhere('u.id = :id')
->setParameter('id', $request->getFilter()->getId());
}
if ($request->getFilter()->getCreatedAtFrom()) {
$qb->andWhere('DATE(u.createdAt) >= :createdAtFrom')
->setParameter('createdAtFrom', $request->getFilter()->getCreatedAtFrom());
}
if ($request->getFilter()->getCreatedAtTo()) {
$qb->andWhere('DATE(u.createdAt) <= :createdAtTo')
->setParameter('createdAtTo', $request->getFilter()->getCreatedAtTo());
}
if ($request->getFilter()->getOrganizationId()) {
$qb->andWhere('o.id = :organizationId')
->setParameter('organizationId', $request->getFilter()->getOrganizationId());
}
}
if (!$request->isSkipPagination()) {
$qb->setMaxResults($request->getOnPage())
->setFirstResult($request->getOffset());
}
return new Paginator($qb->getQuery());
}
/**
* @return array|UserInterface[]
*/
public function getListWithDeviceToken(): array
{
return $this->createQueryBuilder('u')
->innerJoin('u.userDeviceToken', 'udt')
->getQuery()
->getResult();
}
}