Personalizar la clase de usuario
Lo bueno de la clase User
es que... ¡es nuestra clase! Mientras implementemosUserInterface
, podemos añadir lo que queramos:
// ... 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:
// ... 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:
// ... 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
:
// ... 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()
:
// ... 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
:
// ... 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)
:
// ... 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!
Hi, the symfony console make:factroy command is not defined, I'm with symfony 6.3.x what can I replace it with ? Thanks