mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-13 13:54:23 +00:00
214 lines
5.6 KiB
PHP
214 lines
5.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/*
|
|
* Chill is a software for social workers
|
|
*
|
|
* For the full copyright and license information, please view
|
|
* the LICENSE file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Chill\MainBundle\Command;
|
|
|
|
use Chill\MainBundle\Entity\User;
|
|
use Chill\MainBundle\Notification\Mailer;
|
|
use Chill\MainBundle\Security\PasswordRecover\RecoverPasswordHelper;
|
|
use DateTime;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Exception;
|
|
use InvalidArgumentException;
|
|
use League\Csv\Reader;
|
|
use Psr\Log\LoggerInterface;
|
|
use Symfony\Component\Console\Command\Command;
|
|
use Symfony\Component\Console\Input\InputArgument;
|
|
use Symfony\Component\Console\Input\InputInterface;
|
|
use Symfony\Component\Console\Input\InputOption;
|
|
use Symfony\Component\Console\Output\OutputInterface;
|
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
|
|
|
use function array_key_exists;
|
|
use function array_merge;
|
|
use function in_array;
|
|
use function trim;
|
|
|
|
/**
|
|
* Class ChillUserSendRenewPasswordCodeCommand.
|
|
*/
|
|
class ChillUserSendRenewPasswordCodeCommand extends Command
|
|
{
|
|
/**
|
|
* @var EntityManagerInterface
|
|
*/
|
|
protected $em;
|
|
|
|
/**
|
|
* @var EventDispatcherInterface
|
|
*/
|
|
protected $eventDispatcher;
|
|
|
|
/**
|
|
* @var LoggerInterface
|
|
*/
|
|
protected $logger;
|
|
|
|
/**
|
|
* @var Mailer
|
|
*/
|
|
protected $mailer;
|
|
|
|
/**
|
|
* @var RecoverPasswordHelper
|
|
*/
|
|
protected $recoverPasswordHelper;
|
|
|
|
/**
|
|
* The current input interface.
|
|
*
|
|
* @var InputInterface
|
|
*/
|
|
private $input;
|
|
|
|
/**
|
|
* The current output interface.
|
|
*
|
|
* @var OutputInterface
|
|
*/
|
|
private $output;
|
|
|
|
public function __construct(
|
|
LoggerInterface $logger,
|
|
EntityManagerInterface $em,
|
|
RecoverPasswordHelper $recoverPasswordHelper,
|
|
EventDispatcherInterface $eventDispatcher
|
|
) {
|
|
$this->logger = $logger;
|
|
$this->em = $em;
|
|
$this->recoverPasswordHelper = $recoverPasswordHelper;
|
|
$this->eventDispatcher = $eventDispatcher;
|
|
|
|
parent::__construct();
|
|
}
|
|
|
|
protected function configure()
|
|
{
|
|
$this
|
|
->setName('chill:user:send-password-recover-code')
|
|
->setDescription('Send a message with code to recover password')
|
|
->addArgument('csvfile', InputArgument::REQUIRED, 'CSV file with the list of users')
|
|
->addOption('template', null, InputOption::VALUE_REQUIRED, 'Template for email')
|
|
->addOption('expiration', null, InputOption::VALUE_REQUIRED, 'Expiration of the link, as an unix timestamp')
|
|
->addOption('subject', null, InputOption::VALUE_REQUIRED, 'Subject of the email', 'Recover your password');
|
|
}
|
|
|
|
protected function execute(InputInterface $input, OutputInterface $output)
|
|
{
|
|
$this->input = $input;
|
|
$this->output = $output;
|
|
|
|
$reader = $this->getReader();
|
|
|
|
foreach ($reader->getRecords() as $offset => $r) {
|
|
$user = $this->getUser($r);
|
|
|
|
if (null === $user) {
|
|
$this->onUserNotFound($r, $offset);
|
|
|
|
continue;
|
|
}
|
|
|
|
$this->sendRecoverCode($user);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @throws Exception
|
|
*
|
|
* @return Reader
|
|
*/
|
|
protected function getReader()
|
|
{
|
|
try {
|
|
$reader = Reader::createFromPath($this->input->getArgument('csvfile'));
|
|
} catch (Exception $e) {
|
|
$this->logger->error('The csv file could not be read', [
|
|
'path' => $this->input->getArgument('csvfile'),
|
|
]);
|
|
|
|
throw $e;
|
|
}
|
|
|
|
$reader->setHeaderOffset(0);
|
|
|
|
$headers = $reader->getHeader();
|
|
|
|
if (
|
|
false === in_array('username', $headers, true)
|
|
&& false === in_array('email', $headers, true)
|
|
) {
|
|
throw new InvalidArgumentException('The csv file does not have an '
|
|
. 'username or email header');
|
|
}
|
|
|
|
return $reader;
|
|
}
|
|
|
|
protected function getUser($row)
|
|
{
|
|
/** @var \Chill\MainBundle\Repository\UserRepository $userRepository */
|
|
$userRepository = $this->em->getRepository(User::class);
|
|
|
|
try {
|
|
if (array_key_exists('email', $row)) {
|
|
return $userRepository->findOneByUsernameOrEmail(trim($row['email']));
|
|
}
|
|
} catch (\Doctrine\ORM\NoResultException $e) {
|
|
// continue, we will try username
|
|
}
|
|
|
|
try {
|
|
if (array_key_exists('username', $row)) {
|
|
return $userRepository->findOneByUsernameOrEmail(trim($row['username']));
|
|
}
|
|
} catch (\Doctrine\ORM\NoResultException $e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
protected function onUserNotFound($row, $offset)
|
|
{
|
|
$this->logger->alert('User not found', array_merge([
|
|
'offset' => $offset,
|
|
], $row));
|
|
}
|
|
|
|
protected function sendRecoverCode(User $user)
|
|
{
|
|
if (empty($user->getEmail())) {
|
|
$this->logger->alert('User without email', [
|
|
'user_id' => $user->getId(),
|
|
'username' => $user->getUsername(),
|
|
]);
|
|
|
|
return;
|
|
}
|
|
|
|
$template = $this->input->getOption('template');
|
|
$expiration = DateTime::createFromFormat(
|
|
'U',
|
|
$this->input->getOption('expiration')
|
|
);
|
|
|
|
$this->recoverPasswordHelper
|
|
->sendRecoverEmail(
|
|
$user,
|
|
$expiration,
|
|
$template,
|
|
['expiration' => $expiration],
|
|
false,
|
|
['_locale' => 'fr'],
|
|
$this->input->getOption('subject')
|
|
);
|
|
}
|
|
}
|