parent
5768c06f25
commit
f2f431b9a6
@ -0,0 +1,108 @@ |
||||
<?php |
||||
namespace vierbergenlars\AuthserverAutoExpireUsersBundle\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\AuthserverAutoExpireUsersBundle\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; |
||||
|
||||
class ExpireUsersCommand extends Command |
||||
{ |
||||
|
||||
protected function configure() |
||||
{ |
||||
$this->setName('expire:users') |
||||
->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.'); |
||||
} |
||||
|
||||
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 . ' users. 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 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 . ' users'); |
||||
} |
||||
} |
Reference in new issue