Skip to content

Commit 459ddac

Browse files
Merge pull request #6325 from christianbeeznest/ras-22642
Internal: Add command to deactivate users without active sessions - refs BT#22642
2 parents 6aa0ea7 + 740fcca commit 459ddac

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/* For licensing terms, see /license.txt */
6+
7+
namespace Chamilo\CoreBundle\Command;
8+
9+
use Chamilo\CoreBundle\Entity\User;
10+
use DateTime;
11+
use DateTimeZone;
12+
use Doctrine\ORM\EntityManagerInterface;
13+
use Symfony\Component\Console\Attribute\AsCommand;
14+
use Symfony\Component\Console\Command\Command;
15+
use Symfony\Component\Console\Input\InputInterface;
16+
use Symfony\Component\Console\Input\InputOption;
17+
use Symfony\Component\Console\Output\OutputInterface;
18+
use Symfony\Component\Console\Style\SymfonyStyle;
19+
20+
#[AsCommand(
21+
name: 'app:deactivate-users-with-no-active-session',
22+
description: 'Deactivate users who are not part of any active session (where session end date has passed).'
23+
)]
24+
class DeactivateUsersWithNoActiveSessionCommand extends Command
25+
{
26+
public function __construct(
27+
private readonly EntityManagerInterface $entityManager
28+
) {
29+
parent::__construct();
30+
}
31+
32+
protected function configure(): void
33+
{
34+
$this
35+
->addOption('dry-run', null, InputOption::VALUE_NONE, 'Run without saving changes');
36+
}
37+
38+
protected function execute(InputInterface $input, OutputInterface $output): int
39+
{
40+
$io = new SymfonyStyle($input, $output);
41+
$dryRun = $input->getOption('dry-run');
42+
$now = new DateTime('now', new DateTimeZone('UTC'));
43+
44+
$io->title('Deactivating users without active sessions...');
45+
$io->text('Checking users as of ' . $now->format('Y-m-d H:i:s'));
46+
47+
// Subquery: user IDs with at least one session where end date is in the future
48+
$subQuery = $this->entityManager->createQueryBuilder()
49+
->select('IDENTITY(sru.user)')
50+
->from('Chamilo\CoreBundle\Entity\SessionRelUser', 'sru')
51+
->join('sru.session', 's')
52+
->where('s.displayEndDate > :now')
53+
->getDQL();
54+
55+
// Main query: get all active users not in the subquery
56+
$qb = $this->entityManager->createQueryBuilder();
57+
$usersToDeactivate = $qb
58+
->select('u')
59+
->from(User::class, 'u')
60+
->where('u.active = 1')
61+
->andWhere($qb->expr()->notIn('u.id', $subQuery))
62+
->setParameter('now', $now)
63+
->getQuery()
64+
->getResult();
65+
66+
$deactivatedCount = 0;
67+
68+
/* @var User $user */
69+
foreach ($usersToDeactivate as $user) {
70+
$user->setActive(0);
71+
$this->entityManager->persist($user);
72+
$io->writeln("Deactivated user ID {$user->getId()} ({$user->getUsername()})");
73+
$deactivatedCount++;
74+
}
75+
76+
if ($dryRun) {
77+
$io->warning("Dry run mode enabled. {$deactivatedCount} users would be deactivated.");
78+
} else {
79+
$this->entityManager->flush();
80+
$io->success("Successfully deactivated {$deactivatedCount} users without active sessions.");
81+
}
82+
83+
return Command::SUCCESS;
84+
}
85+
}

0 commit comments

Comments
 (0)