Buy Access to Course
03.

Personalizar la clase de usuario

|

Share this awesome video!

|

Lo bueno de la clase User es que... ¡es nuestra clase! Mientras implementemosUserInterface, podemos añadir lo que queramos:

115 lines | src/Entity/User.php
// ... lines 1 - 7
use Symfony\Component\Security\Core\User\UserInterface;
// ... lines 9 - 12
class User implements UserInterface
{
// ... lines 15 - 113
}

Por ejemplo, me gustaría almacenar el nombre de mis usuarios. Así que vamos a añadir una propiedad para eso. En tu terminal, ejecuta:

symfony console make:entity

Editaremos la entidad User, añadiremos una propiedad firstName, haremos que sea una cadena, de 255 de longitud... y diremos "sí" a anulable. Hagamos que esta propiedad sea opcional en la base de datos.

Ya está De vuelta a la clase User, ¡no hay sorpresas! Tenemos una nueva propiedad... y nuevos métodos getter y setter:

132 lines | src/Entity/User.php
// ... lines 1 - 12
class User implements UserInterface
{
// ... lines 15 - 31
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $firstName;
// ... lines 36 - 119
public function getFirstName(): ?string
{
return $this->firstName;
}
public function setFirstName(string $firstName): self
{
$this->firstName = $firstName;
return $this;
}
}

Ve a generar una migración para nuestro nuevo User. En el terminal, ejecuta

symfony console make:migration

¡Genial! Gira y abre eso para asegurarte de que no esconde ninguna sorpresa:

32 lines | migrations/Version20211001172813.php
// ... lines 1 - 2
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20211001172813 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE user (id INT AUTO_INCREMENT NOT NULL, email VARCHAR(180) NOT NULL, roles JSON NOT NULL, first_name VARCHAR(255) DEFAULT NULL, UNIQUE INDEX UNIQ_8D93D649E7927C74 (email), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('DROP TABLE user');
}
}

Ejecuta: CREATE TABLE user con las columnas id, email, roles y first_name. Cierra esto... y ejecútalo:

symfony console doctrine:migrations:migrate

¡Éxito!

Añadiendo las entidades de los usuarios

Y como la entidad User es... una entidad normal de Doctrine, también podemos añadir usuarios ficticios a nuestra base de datos utilizando el sistema de accesorios.

Abre src/DataFixtures/AppFixtures.php. Vamos a utilizar Foundry para ayudarnos a cargar los datos. Así que vamos a crear una nueva fábrica de Foundry para User. Como nos estamos divirtiendo tanto ejecutando comandos en este vídeo, vamos a colar uno... o tres más:

symfony console make:factory

¡Sí! Queremos una para User. Ve a abrirlo: src/Factory/UserFactory.php:

61 lines | src/Factory/UserFactory.php
// ... lines 1 - 2
namespace App\Factory;
use App\Entity\User;
use App\Repository\UserRepository;
use Zenstruck\Foundry\RepositoryProxy;
use Zenstruck\Foundry\ModelFactory;
use Zenstruck\Foundry\Proxy;
// ... lines 10 - 28
final class UserFactory extends ModelFactory
{
public function __construct()
{
parent::__construct();
// TODO inject services if required (https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#factories-as-services)
}
protected function getDefaults(): array
{
return [
// TODO add your default values here (https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#model-factories)
'email' => self::faker()->text(),
'roles' => [],
'firstName' => self::faker()->text(),
];
}
protected function initialize(): self
{
// see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#initialization
return $this
// ->afterInstantiate(function(User $user) {})
;
}
protected static function getClass(): string
{
return User::class;
}
}

Nuestro trabajo en getDefaults() es asegurarnos de que todas las propiedades necesarias tienen buenos valores por defecto. Establece email en self::faker()->email(), no estableceré ninguna función por ahora y establece firstName en self::faker()->firstName():

59 lines | src/Factory/UserFactory.php
// ... lines 1 - 28
final class UserFactory extends ModelFactory
{
// ... lines 31 - 37
protected function getDefaults(): array
{
return [
'email' => self::faker()->email(),
'firstName' => self::faker()->firstName(),
];
}
// ... lines 45 - 57
}

¡Genial! En AppFixtures, en la parte inferior, crea un usuario: UserFactory::createOne(). Pero utiliza un correo electrónico específico para que podamos iniciar sesión con él más tarde. Qué tal,abraca_admin@example.com:

54 lines | src/DataFixtures/AppFixtures.php
// ... lines 1 - 11
use App\Factory\UserFactory;
// ... lines 13 - 15
class AppFixtures extends Fixture
{
public function load(ObjectManager $manager)
{
// ... lines 20 - 41
AnswerFactory::new(function() use ($questions) {
// ... lines 43 - 45
})->needsApproval()->many(20)->create();
UserFactory::createOne(['email' => 'abraca_admin@example.com']);
// ... lines 49 - 51
}
}

Luego, para rellenar un poco el sistema, añade UserFactory::createMany(10):

54 lines | src/DataFixtures/AppFixtures.php
// ... lines 1 - 11
use App\Factory\UserFactory;
// ... lines 13 - 15
class AppFixtures extends Fixture
{
public function load(ObjectManager $manager)
{
// ... lines 20 - 47
UserFactory::createOne(['email' => 'abraca_admin@example.com']);
UserFactory::createMany(10);
// ... lines 50 - 51
}
}

¡Vamos a probarlo! De vuelta al terminal, ejecuta:

symfony console doctrine:fixtures:load

¡No hay errores! Comprueba la nueva tabla:

symfony console doctrine:query:sql 'SELECT * FROM user'

Y... ¡ahí están! Ahora que tenemos usuarios en la base de datos, tenemos que añadir una o varias formas para que se autentiquen. ¡Es hora de construir un formulario de acceso!