<?php
namespace App\Entity;
use App\Repository\UserRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity(repositoryClass=UserRepository::class)
* @UniqueEntity(
* fields={"email"},
* message="Este correo ya está registrado."
* )
*/
class User implements UserInterface, PasswordAuthenticatedUserInterface
{
public function __construct()
{
$this->roles = ["ROLE_CLIENT"];
$this->patients = new ArrayCollection();
$this->createdAt = new \DateTimeImmutable();
$this->useTemporaryEmail = false;
$this->notifyClinica = false;
}
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=180, unique=true)
* @Assert\NotBlank(message="El correo es obligatorio.")
* @Assert\Email(
* message="Introduce un correo válido (ej: usuario@dominio.com).",
* mode="strict"
* )
*/
private $email;
/**
* @ORM\Column(type="json")
*/
private $roles = [];
/**
* @ORM\Column(type="string")
*/
private $password;
/**
* @Assert\NotBlank(message="La contraseña es obligatoria.", groups={"patients"})
* @Assert\Length(
* min = 8,
* minMessage = "La contraseña debe tener al menos {{ limit }} caracteres."
* )
* @Assert\Regex(pattern="/[A-Z]/", message="La contraseña debe contener al menos una letra mayúscula.")
* @Assert\Regex(pattern="/[a-z]/", message="La contraseña debe contener al menos una letra minúscula.")
* @Assert\Regex(pattern="/\d/", message="La contraseña debe contener al menos un número.")
* @Assert\Regex(pattern="/[\W_]/", message="La contraseña debe contener al menos un carácter especial.")
*/
private $plainPassword;
/**
* @ORM\Column(type="string", length=255)
* @Assert\NotBlank(message="El nombre es obligatorio.", groups={"Default", "profile", "provider"})
* @Assert\Length(min=3, minMessage="El nombre debe tener al menos 3 caracteres.", groups={"Default", "profile", "provider"})
*/
private $name;
/**
* @ORM\Column(name="lastname", type="string", length=255)
* @Assert\NotBlank(message="El apellido es obligatorio.", groups={"Default", "profile"})
* @Assert\Length(min=3, minMessage="El apellido debe tener al menos 3 caracteres.", groups={"Default", "profile"})
*/
private $lastName;
/**
* @ORM\Column(type="string", length=20, nullable=true)
* @Assert\Length(min=8, minMessage="El teléfono debe tener al menos 8 dígitos.", groups={"Default", "profile", "provider"})
* @Assert\Regex(pattern="/^\+?[0-9]+$/", message="El teléfono solo puede contener números y el signo + al inicio.", groups={"Default", "profile", "provider"})
*/
private $phone;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $address;
/**
* @ORM\Column(type="datetime_immutable")
*/
private $createdAt;
/**
* @ORM\Column(type="date", nullable=true)
* @Assert\NotNull(
* message="La fecha de nacimiento es obligatoria.",
* groups={"Default", "profile"}
* )
* @Assert\LessThan(
* "today",
* message="La fecha de nacimiento debe ser anterior a hoy."
* )
*/
private $birthDate;
/**
* Relación ManyToMany: un proveedor puede tener varios pacientes asignados.
* Esta relación es opcional y solo se usa para ROLE_PROVIDER.
*
* @ORM\ManyToMany(targetEntity="App\Entity\User")
* @ORM\JoinTable(
* name="provider_patient",
* joinColumns={@ORM\JoinColumn(name="provider_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="patient_id", referencedColumnName="id")}
* )
*/
private $patients;
/**
* @ORM\Column(type="string", length=20, options={"default": "persona"})
*/
private $entityType = 'persona';
/**
* @ORM\Column(type="string", length=100, nullable=true)
*/
private $resetToken;
/**
* @ORM\Column(type="datetime_immutable", nullable=true)
*/
private $tokenExpiresAt;
/**
* @ORM\Column(type="boolean", options={"default": 0})
*/
private $useTemporaryEmail = false;
/**
* @ORM\Column(type="boolean", options={"default": 0})
*/
private $notifyClinica = false;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $clinicNotificationEmail;
public function getId(): ?int
{
return $this->id;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
public function getUserIdentifier(): string
{
return (string) $this->email;
}
/** @deprecated since Symfony 5.3 */
public function getUsername(): string
{
return (string) $this->email;
}
public function getRoles(): array
{
return $this->roles ?? [];
}
public function setRoles($roles): self
{
if (!is_array($roles)) {
$roles = [$roles];
}
$this->roles = $roles;
return $this;
}
public function getPassword(): string
{
return $this->password;
}
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
public function getPlainPassword(): ?string
{
return $this->plainPassword;
}
public function setPlainPassword(?string $plainPassword): self
{
$this->plainPassword = $plainPassword;
return $this;
}
public function getSalt(): ?string
{
return null;
}
public function eraseCredentials()
{
$this->plainPassword = null;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getLastName(): ?string
{
return $this->lastName;
}
public function setLastName(string $lastName): self
{
$this->lastName = $lastName;
return $this;
}
public function getPhone(): ?string
{
return $this->phone;
}
public function setPhone(?string $phone): self
{
$this->phone = $phone;
return $this;
}
public function getAddress(): ?string
{
return $this->address;
}
public function setAddress(?string $address): self
{
$this->address = $address;
return $this;
}
/**
* @return Collection|User[]
*/
public function getPatients(): Collection
{
return $this->patients;
}
public function addPatient(User $patient): self
{
if (!$this->patients->contains($patient)) {
$this->patients[] = $patient;
}
return $this;
}
public function removePatient(User $patient): self
{
$this->patients->removeElement($patient);
return $this;
}
public function getCreatedAt(): ?\DateTimeImmutable
{
return $this->createdAt;
}
public function setCreatedAt(\DateTimeImmutable $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
public function getEntityType(): string
{
return $this->entityType;
}
public function setEntityType(string $entityType): self
{
$this->entityType = $entityType;
return $this;
}
public function getResetToken(): ?string
{
return $this->resetToken;
}
public function setResetToken(?string $resetToken): self
{
$this->resetToken = $resetToken;
return $this;
}
public function getTokenExpiresAt(): ?\DateTimeImmutable
{
return $this->tokenExpiresAt;
}
public function setTokenExpiresAt(?\DateTimeImmutable $tokenExpiresAt): self
{
$this->tokenExpiresAt = $tokenExpiresAt;
return $this;
}
public function getUseTemporaryEmail(): bool
{
return $this->useTemporaryEmail;
}
public function setUseTemporaryEmail(bool $useTemporaryEmail): self
{
$this->useTemporaryEmail = $useTemporaryEmail;
return $this;
}
public function getNotifyClinica(): bool
{
return $this->notifyClinica;
}
public function setNotifyClinica(bool $notifyClinica): self
{
$this->notifyClinica = $notifyClinica;
return $this;
}
public function getClinicNotificationEmail(): ?string
{
return $this->clinicNotificationEmail;
}
public function setClinicNotificationEmail(?string $clinicNotificationEmail): self
{
$this->clinicNotificationEmail = $clinicNotificationEmail;
return $this;
}
public function getBirthDate(): ?\DateTimeImmutable
{
if ($this->birthDate instanceof \DateTime) {
// Convertir mutable a immutable
$this->birthDate = \DateTimeImmutable::createFromMutable($this->birthDate);
}
return $this->birthDate;
}
public function setBirthDate(?\DateTimeImmutable $birthDate): self
{
$this->birthDate = $birthDate;
return $this;
}
public function getAge(): ?int
{
if (!$this->birthDate) {
return null;
}
$today = new \DateTimeImmutable();
return $this->birthDate->diff($today)->y;
}
}