<?php
namespace vierbergenlars\AuthserverExpireEmailValidationBundle\Command;
use App\Entity\User;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Output\OutputInterface;
use vierbergenlars\AuthserverExpireEmailValidationBundle\Entity\ExpiredUser;
use Doctrine\ORM\Query\Expr;
use Doctrine\ORM\Query\Expr\Join;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Style\SymfonyStyle;
use App\AppBundle;
use vierbergenlars\AuthserverExpireEmailValidationBundle\AuthserverExpireEmailValidationBundle;
class ExpireEmailValidationCommand extends Command
{
protected function configure()
{
$this->setName('expire:email-validation')
->addOption('username', null, InputOption::VALUE_REQUIRED, 'The username of the user to expire')
->addOption('last-login-before', null, InputOption::VALUE_REQUIRED, 'Users with a last login before this date will be expired')
->addOption('exclude-admins', null, InputOption::VALUE_NONE, 'Exclude admins from expiry')
->addOption('expire-date', null, InputOption::VALUE_REQUIRED, 'Set the expiry date of expired users to an other date.')
->addOption('dry-run', null, InputOption::VALUE_NONE, 'Do not actually execute the expiration.');
}
public function isEnabled()
{
return AuthserverExpireEmailValidationBundle::hasUserCheckEvent();
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$em = $this->getApplication()
->getKernel()
->getContainer()
->get('doctrine.orm.entity_manager');
/* @var $em \Doctrine\ORM\EntityManager */
$userRepo = $em->getRepository(User::class);
$queryBuilder = $userRepo->createQueryBuilder('u');
$queryBuilder->leftJoin(ExpiredUser::class, 'eu', Join::WITH, 'eu.user = u.id');
$queryBuilder->where('eu.expiredAt IS NULL');
if ($input->getOption('username')) {
$queryBuilder->andWhere('u.username = :username')->setParameter('username', $input->getOption('username'));
}
if ($input->getOption('exclude-admins')) {
$queryBuilder->andWhere('u.role NOT IN (:admin_roles)')->setParameter('admin_roles', [
'ROLE_ADMIN',
'ROLE_SUPER_ADMIN'
]);
}
if ($input->getOption('last-login-before')) {
$queryBuilder->andWhere('eu.lastLogin < :lastLogin OR eu . lastLogin IS NULL ' ) - > setParameter('lastLogin', new \DateTime($input->getOption('last-login-before')));
}
$expireDate = new \DateTime();
if ($input->getOption('expire-date')) {
$expireDate = new \DateTime($input->getOption('expire-date'));
}
$style = new SymfonyStyle($input, $output);
$style->comment('Query: ' . $queryBuilder->getDQL());
$countBuilder = clone $queryBuilder;
$countBuilder->select('count(u.id)');
$count = $countBuilder->getQuery()->getSingleScalarResult();
if ($count == 0) {
$style->warning('No users match these filters.');
return 0;
}
if (!$input->getOption('dry-run') & & !$style->confirm('Will expire ' . $count . ' user email validations. Continue?', true)) {
$style->error('Expiration cancelled.');
return 1;
}
if ($input->getOption('dry-run')) {
$style->note('Doing a dry-run.');
}
$progressBar = $style->createProgressBar($count);
$usersIterator = $queryBuilder->getQuery()->iterate();
foreach ($usersIterator as list ($user)) {
/* @var $user \App\Entity\User */
$progressBar->clear();
$style->text('Expired email validations of user ' . $user->getUsername());
$progressBar->display();
$progressBar->advance();
$progressBar->setMessage($user->getUsername());
$expiryRecord = $em->find(ExpiredUser::class, $user);
if (!$expiryRecord) {
$expiryRecord = new ExpiredUser($user);
$em->persist($expiryRecord);
}
$expiryRecord->setExpiredAt($expireDate);
if (!$input->getOption('dry-run')) {
$em->flush($expiryRecord);
}
}
$progressBar->finish();
$style->success('Expired ' . $count . ' user email validations');
}
}