Skip to content

Commit

Permalink
Merge branch 'AlamedaCMS' of github.com:gerMdz/AlamedaCMS into Alamed…
Browse files Browse the repository at this point in the history
…aCMS
  • Loading branch information
gerMdz committed Jun 19, 2022
2 parents bb4fdfd + 4744f0c commit 143c490
Show file tree
Hide file tree
Showing 16 changed files with 530 additions and 16 deletions.
249 changes: 249 additions & 0 deletions src/Command/AddUserCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace App\Command;

use App\Entity\User;
use App\Repository\UserRepository;
use App\Utils\Validator;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Exception\RuntimeException;
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\Console\Style\SymfonyStyle;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Stopwatch\Stopwatch;
use function Symfony\Component\String\u;

/**
* A console command that creates users and stores them in the database.
*
* To use this command, open a terminal window, enter into your project
* directory and execute the following:
*
* $ php bin/console app:add-user
*
* To output detailed information, increase the command verbosity:
*
* $ php bin/console app:add-user -vv
*
* See https://symfony.com/doc/current/console.html
*
* We use the default services.yaml configuration, so command classes are registered as services.
* See https://symfony.com/doc/current/console/commands_as_services.html
*
* @author Javier Eguiluz <[email protected]>
* @author Yonel Ceruto <[email protected]>
*/
class AddUserCommand extends Command
{
// to make your command lazily loaded, configure the $defaultName static property,
// so it will be instantiated only when the command is actually called.
protected static $defaultName = 'app:add-user';

/**
* @var SymfonyStyle
*/
private SymfonyStyle $io;

private EntityManagerInterface $entityManager;
private UserPasswordHasherInterface $passwordEncoder;
private Validator $validator;
private UserRepository $users;

public function __construct(EntityManagerInterface $em, UserPasswordHasherInterface $encoder, Validator $validator, UserRepository $users)
{
parent::__construct();

$this->entityManager = $em;
$this->passwordEncoder = $encoder;
$this->validator = $validator;
$this->users = $users;
}

/**
* {@inheritdoc}
*/
protected function configure(): void
{
$this
->setDescription('Creates users and stores them in the database')
->setHelp($this->getCommandHelp())
// commands can optionally define arguments and/or options (mandatory and optional)
// see https://symfony.com/doc/current/components/console/console_arguments.html
->addArgument('email', InputArgument::OPTIONAL, 'The email of the new user')
->addArgument('password', InputArgument::OPTIONAL, 'The plain password of the new user')
->addArgument('primerNombre', InputArgument::OPTIONAL, 'The primer nombre of the new user')
->addOption('role', null, InputOption::VALUE_OPTIONAL, 'If set, the user is created as Role')
;
}

/**
* This optional method is the first one executed for a command after configure()
* and is useful to initialize properties based on the input arguments and options.
*/
protected function initialize(InputInterface $input, OutputInterface $output): void
{
// SymfonyStyle is an optional feature that Symfony provides so, you can
// apply a consistent look to the commands of your application.
// See https://symfony.com/doc/current/console/style.html
$this->io = new SymfonyStyle($input, $output);
}

/**
* This method is executed after initialize() and before execute(). Its purpose
* is to check if 'some' options/arguments are missing and interactively
* ask the user for those values.
*
* This method is completely optional. If you are developing an internal console
* command, you probably should not implement this method because it requires
* quite a lot of work. However, if the command is meant to be used by external
* users, this method is a nice way to fall back and prevent errors.
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
if (null !== $input->getArgument('password') && null !== $input->getArgument('email') && null !== $input->getArgument('primerNombre')) {
return;
}

$this->io->title('Add User Command Interactive Wizard');
$this->io->text([
'If you prefer to not use this interactive wizard, provide the',
'arguments required by this command as follows:',
'',
' $ php bin/console app:add-user [email protected] password primerNombre',
'',
'Now we\'ll ask you for the value of all the missing command arguments.',
]);

// Ask for the email if it's not defined
$email = $input->getArgument('email');
if (null !== $email) {
$this->io->text(' > <info>Email</info>: '.$email);
} else {
$email = $this->io->ask('Email', null, [$this->validator, 'validateEmail']);
$input->setArgument('email', $email);
}

// Ask for the password if it's not defined
$password = $input->getArgument('password');
if (null !== $password) {
$this->io->text(' > <info>Password</info>: '.u('*')->repeat(u($password)->length()));
} else {
$password = $this->io->askHidden('Password (your type will be hidden)', [$this->validator, 'validatePassword']);
$input->setArgument('password', $password);
}


// Ask for the primer nombre if it's not defined
$primerNombre = $input->getArgument('primerNombre');
if (null !== $primerNombre) {
$this->io->text(' > <info>Primer Nombre</info>: '.$primerNombre);
} else {
$primerNombre = $this->io->ask('Primer Nombre', null, [$this->validator, 'validatePrimerNombre']);
$input->setArgument('primerNombre', $primerNombre);
}
}

/**
* This method is executed after interact() and initialize(). It usually
* contains the logic to execute to complete this command task.
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$stopwatch = new Stopwatch();
$stopwatch->start('add-user-command');

$email = $input->getArgument('email');
$plainPassword = $input->getArgument('password');
$primerNombre = $input->getArgument('primerNombre');
$isAdmin = $input->getOption('role');

// make sure to validate the user data is correct
$this->validateUserData($email, $plainPassword, $primerNombre);

// create the user and encode its password
$user = new User();
$user->setEmail($email);
$user->setRoles([$isAdmin ? 'ROLE_'.strtoupper($isAdmin) : 'ROLE_USER']);
$user->setIsActive(true);

// See https://symfony.com/doc/current/security.html#c-encoding-passwords
$encodedPassword = $this->passwordEncoder->hashPassword($user, $plainPassword);
$user->setPassword($encodedPassword);
$user->setPrimerNombre($primerNombre);
$user->aceptaTerminos( new DateTime('now'));

$this->entityManager->persist($user);
$this->entityManager->flush();

$this->io->success(sprintf('%s was successfully created: %s ', $isAdmin ? $isAdmin . ' user' : 'User', $user->getEmail()));

$event = $stopwatch->stop('add-user-command');
if ($output->isVerbose()) {
$this->io->comment(sprintf('New user database id: %d / Elapsed time: %.2f ms / Consumed memory: %.2f MB', $user->getId(), $event->getDuration(), $event->getMemory() / (1024 ** 2)));
}

return 0;
}

private function validateUserData($email, $plainPassword, $primerNombre): void
{
// first check if a user with the same email already exists.
$existingUser = $this->users->findOneBy(['email' => $email]);

if (null !== $existingUser) {
throw new RuntimeException(sprintf('There is already a user registered with the "%s" email.', $email));
}

// validate password and email if is not this input means interactive.
$this->validator->validatePassword($plainPassword);
$this->validator->validateEmail($email);
$this->validator->validatePrimerNombre($primerNombre);

}

/**
* The command help is usually included in to configure() method, but when
* it's too long, it's better to define a separate method to maintain the
* code readability.
*/
private function getCommandHelp(): string
{
return <<<'HELP'
The <info>%command.name%</info> command creates new users and saves them in the database:
<info>php %command.primerNombre%</info> <comment> password email</comment>
By default the command creates regular users. To create other rol users,
add the <comment>--role</comment> option:
<info>php %command.primerNombre%</info> password email <comment>--role</comment>
If you omit any of the three required arguments, the command will ask you to
provide the missing values:
# command will ask you for the email
<info>php %command.primerNombre%</info> <comment>email password</comment>
# command will ask you for the email and password
<info>php %command.primerNombre%</info> <comment>email</comment>
# command will ask you for all arguments
<info>php %command.primerNombre%</info>

HELP;
}
}
6 changes: 2 additions & 4 deletions src/Controller/IndexAlamedaController.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,10 @@ class IndexAlamedaController extends AbstractController
*/
public function index(IndexAlamedaRepository $indexAlamedaRepository): Response
{
// $em = $this->getDoctrine()->getManager();
// $indexAlameda = $em->getRepository(IndexAlameda::class)->findAll();

return $this->render('index_alameda/index.html.twig', [
'index_alamedas' => $indexAlamedaRepository->findAll(),
'datosIndex' => $indexAlamedaRepository->findAll()[0],
'index_alamedas' => $indexAlamedaRepository->findBy(['base'=>'index']),
// 'datosIndex' => $indexAlamedaRepository->findAll()[0],
]);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Entity/IndexAlameda.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class IndexAlameda
/**
* @ORM\ManyToOne(targetEntity=ModelTemplate::class)
*/
private $template;
private ?ModelTemplate $template;

public function __construct()
{
Expand Down
48 changes: 48 additions & 0 deletions src/Utils/MomentFormatConverter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace App\Utils;

/**
* This class is used to convert PHP date format to moment.js format.
*
* @author Yonel Ceruto <[email protected]>
*/
class MomentFormatConverter
{
/**
* This defines the mapping between PHP ICU date format (key) and moment.js date format (value)
* For ICU formats see http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax
* For Moment formats see https://momentjs.com/docs/#/displaying/format/.
*
* @var array
*/
private static $formatConvertRules = [
// year
'yyyy' => 'YYYY', 'yy' => 'YY', 'y' => 'YYYY',
// day
'dd' => 'DD', 'd' => 'D',
// day of week
'EE' => 'ddd', 'EEEEEE' => 'dd',
// timezone
'ZZZZZ' => 'Z', 'ZZZ' => 'ZZ',
// letter 'T'
'\'T\'' => 'T',
];

/**
* Returns associated moment.js format.
*/
public function convert(string $format): string
{
return strtr($format, self::$formatConvertRules);
}
}
72 changes: 72 additions & 0 deletions src/Utils/Validator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace App\Utils;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use function Symfony\Component\String\u;

/**
* This class is used to provide an example of integrating simple classes as
* services into a Symfony application.
*
* @author Javier Eguiluz <[email protected]>
*/
class Validator
{
public function validateUsername(?string $username): string
{
if (empty($username)) {
throw new InvalidArgumentException('The username can not be empty.');
}

if (1 !== preg_match('/^[a-z_]+$/', $username)) {
throw new InvalidArgumentException('The username must contain only lowercase latin characters and underscores.');
}

return $username;
}

public function validatePassword(?string $plainPassword): string
{
if (empty($plainPassword)) {
throw new InvalidArgumentException('The password can not be empty.');
}

if (u($plainPassword)->trim()->length() < 6) {
throw new InvalidArgumentException('The password must be at least 6 characters long.');
}

return $plainPassword;
}

public function validateEmail(?string $email): string
{
if (empty($email)) {
throw new InvalidArgumentException('The email can not be empty.');
}

if (null === u($email)->indexOf('@')) {
throw new InvalidArgumentException('The email should look like a real email.');
}

return $email;
}

public function validatePrimerNombre(?string $primerNombre): string
{
if (empty($primerNombre)) {
throw new InvalidArgumentException('The first name can not be empty.');
}

return $primerNombre;
}
}
Loading

0 comments on commit 143c490

Please sign in to comment.