I am reaching out because I am encountering a circular reference issue. I am using version 7 of the symfony framework I have tried to implement several solutions, such as the attribute: #[MaxDepth(2)]. I have also set up DTOs to avoid this kind of problem, but despite everything, when I try to return JSON, I encounter this error:
if ($filterParams['country'] != 'FR' || $filterParams['region'] || $filterParams['cityOrZip']) {
$alerts = $alertRepository->findByFilters($filterParams);
} else {
$alerts = $alertRepository->findAlertsByCoordinates($north, $south, $east, $west, $filterParams);
}
$returnedData = [];
foreach ($alerts as $item) {
$cardHtml = $this->renderView('alert/partials/_card.html.twig', ['alert' => $item]);
$returnedData[] = [$this->alertTransformer->transform($item), $cardHtml];
}
return $this->json($returnedData);
This is my Alert Entity :
#[ORMEntity(repositoryClass: AlertRepository::class)]
class Alert
{
#[ORMId]
#[ORMColumn(type: 'uuid', unique: true)]
#[ORMGeneratedValue(strategy: 'CUSTOM')]
#[ORMCustomIdGenerator(class: UuidGenerator::class)]
private ?UuidInterface $id = null;
#[ORMColumn(length: 255, nullable: true)]
private ?string $type = null;
#[ORMColumn(length: 255, nullable: true)]
private ?string $title = null;
#[ORMColumn(type: 'text', nullable: true)]
private ?string $description = null;
#[ORMColumn(type: 'datetime_immutable', nullable: true)]
private ?DateTimeImmutable $date_of_loss = null;
#[ORMColumn(length: 255, nullable: true)]
private ?string $state = null;
#[ORMColumn(type: 'datetime_immutable')]
private ?DateTimeImmutable $created_at = null;
#[ORMColumn(type: 'datetime_immutable', nullable: true)]
private ?DateTimeImmutable $updated_at = null;
#[ORMManyToOne(targetEntity: Address::class, cascade: ['persist'], fetch: 'EAGER', inversedBy: 'alerts')]
#[ORMJoinColumn(nullable: false)]
#[MaxDepth(2)]
private ?Address $location = null;
#[ORMManyToOne(targetEntity: User::class, inversedBy: 'alerts')]
#[ORMJoinColumn(nullable: false)]
#[MaxDepth(2)]
private ?User $owner = null;
#[ORMManyToOne(targetEntity: Animal::class, fetch: 'EAGER', inversedBy: 'alerts')]
#[MaxDepth(2)]
private ?Animal $animal = null;
#[ORMColumn(length: 255, nullable: true)]
private ?string $specie = null;
#[ORMOneToMany(mappedBy: 'alert', targetEntity: AlertPhoto::class, cascade: ['persist', 'remove'], fetch: 'EAGER')]
private Collection $photos;
#[ORMColumn(length: 255, nullable: true)]
private ?string $status = null;
#[ORMColumn(type: 'text', nullable: true)]
private ?string $additional_information = null;
#[ORMColumn(type: 'float', nullable: true)]
private ?float $bonus = null;
public function __construct()
{
$this->photos = new ArrayCollection();
$this->created_at = new DateTimeImmutable();
}
This is my address entity :
class Address
{
#[ORMId]
#[ORMColumn(type: 'uuid', unique: true)]
#[ORMGeneratedValue(strategy: 'CUSTOM')]
#[ORMCustomIdGenerator(class: UuidGenerator::class)]
private ?UuidInterface $id = null;
#[ORMColumn(length: 255)]
#[AssertNotBlank(message: "Le champ nom est obligatoire.")]
private ?string $name = null;
#[ORMColumn(length: 255, nullable: true)]
private ?string $address_line_1 = null;
#[ORMColumn(length: 255, nullable: true)]
private ?string $address_line_2 = null;
#[ORMColumn(length: 255)]
#[AssertNotBlank(message: "Le champ ville est obligatoire.")]
private ?string $city = null;
#[ORMColumn(length: 255, nullable: true)]
#[AssertNotBlank(message: "Le champ état ou région est obligatoire.")]
private ?string $state_or_region = null;
#[ORMColumn(length: 15)]
#[AssertRegex(
pattern: "/^d{5}$/",
message: "Le code postal doit être un nombre à 5 chiffres."
)]
private ?string $postal_code = null;
#[ORMColumn(length: 255)]
#[AssertNotBlank(message: "Le champ pays est obligatoire.")]
private ?string $country = null;
#[ORMColumn(length: 255)]
#[AssertChoice(
choices: ['personal', 'professional', 'animal'],
message: "Le type doit être l'un des suivants : personal, professional, animal."
)]
private ?string $type = null;
#[ORMOneToMany(mappedBy: 'address', targetEntity: User::class)]
#[MaxDepth(2)]
private Collection $owner_id;
#[ORMOneToMany(mappedBy: 'address', targetEntity: Animal::class)]
#[MaxDepth(2)]
private Collection $animal_id;
#[ORMOneToMany(mappedBy: 'location', targetEntity: Alert::class)]
#[MaxDepth(2)]
private Collection $alerts;
#[ORMColumn(type: 'float', nullable: true)]
private ?float $latitude = null;
#[ORMColumn(type: 'float', nullable: true)]
private ?float $longitude = null;
#[ORMColumn(length: 255, nullable: true)]
private ?string $department = null;
public function __construct()
{
$this->alerts = new ArrayCollection();
$this->owner_id = new ArrayCollection();
$this->animal_id = new ArrayCollection();
}
and this is my User entity :
#[ORMId]
#[ORMColumn(type: 'uuid', unique: true)]
#[ORMGeneratedValue(strategy: 'CUSTOM')]
#[ORMCustomIdGenerator(class: UuidGenerator::class)]
private UuidInterface $id;
#[ORMColumn(length: 180, unique: true)]
#[AssertNotBlank]
#[AssertEmail]
private ?string $email = null;
#[ORMColumn]
private array $roles = [];
#[AssertNotBlank(message: 'Votre mot de passe ne peut pas être vide.', groups: ["create"])]
#[AssertLength(
min: 8,
max: 50,
minMessage: 'Votre mot de passe doit contenir au moins {{ limit }} caractères.',
maxMessage: 'Votre mot de passe ne peut pas dépasser {{ limit }} caractères.'
)]
private ?string $plain_password;
#[ORMColumn(type: 'string')]
private string $password;
#[ORMColumn(length: 255)]
#[AssertNotBlank]
#[AssertLength(
min: 2,
max: 50,
minMessage: 'Votre prénom doit contenir au moins {{ limit }} caractères.',
maxMessage: 'Votre prénom ne peut pas dépasser {{ limit }} caractères.'
)]
private string $first_name;
#[ORMColumn(length: 50)]
#[AssertNotBlank]
#[AssertLength(
min: 2,
max: 50,
minMessage: 'Votre nom de famille doit contenir au moins {{ limit }} caractères.',
maxMessage: 'Votre nom de famille ne peut pas dépasser {{ limit }} caractères.'
)]
private string $last_name;
#[ORMColumn(nullable: true)]
private ?DateTimeImmutable $email_verified_at = null;
#[ORMColumn(length: 25)]
#[AssertNotBlank]
#[AssertChoice(
choices: ['Particular', 'Association']
)]
private string $account_type;
#[ORMColumn]
private ?DateTimeImmutable $created_at = null;
#[ORMColumn(nullable: true)]
private ?DateTimeImmutable $updated_at = null;
#[ORMColumn(length: 25)]
#[AssertChoice(
choices: ['created', 'checked', 'banned', 'deleted', 'disabled'],
message: 'Le status du compte n'est pas valide.'
)]
private ?string $account_status = null;
#[ORMOneToMany(mappedBy: 'owner', targetEntity: Animal::class)]
#[MaxDepth(2)]
private Collection $animals;
#[ORMManyToOne(cascade: ['persist', 'remove'], fetch: 'EAGER', inversedBy: 'owner_id')]
#[MaxDepth(2)]
private ?Address $address = null;
#[ORMColumn(length: 25, nullable: true)]
private ?string $phone = null;
#[ORMColumn(length: 25)]
#[AssertChoice(
choices: ['Homme', 'Femme', 'Non-binaire' ],
message: 'La valeur pour le genre n'est pas valide.
Seules les valeurs suivantes sont acceptées : homme, femme, non-binaire.'
)]
#[Groups(['read:user', 'write:user'])]
private ?string $gender = null;
#[ORMColumn(type: Types::DATE_IMMUTABLE, nullable: true)]
private ?DateTimeImmutable $birthday = null;
#[ORMOneToMany(mappedBy: 'owner', targetEntity: Alert::class)]
#[MaxDepth(2)]
private Collection $alerts;
#[VichUploadableField(mapping: 'user_image', fileNameProperty: 'imageName', size: 'imageSize')]
private ?File $imageFile = null;
#[ORMColumn(nullable: true)]
private ?string $imageName = null;
#[ORMColumn(nullable: true)]
private ?int $imageSize = null;
#[ORMColumn(type: 'boolean')]
private bool $isVerified = false;
#[ORMOneToMany(mappedBy: 'user', targetEntity: UserImage::class, cascade: ['persist', 'remove'])]
private Collection $images;
#[ORMOneToMany(mappedBy: 'user', targetEntity: AlertLinkUser::class, orphanRemoval: true)]
private Collection $alertLinkUsers;
public function __construct()
{
$this->created_at = new DateTimeImmutable();
$this->updated_at = new DateTimeImmutable();
$this->animals = new ArrayCollection();
$this->alerts = new ArrayCollection();
$this->images = new ArrayCollection();
$this->alertLinkUsers = new ArrayCollection();
}
This is the alertDTO but the error is same when i use that:
class AlertDTO
{
public ?string $id;
public ?string $type;
public ?string $title;
public ?string $description;
public ?DateTimeImmutable $date_of_loss;
public ?string $state;
public ?DateTimeImmutable $created_at;
public ?DateTimeImmutable $updated_at;
public ?AddressDTO $location;
public ?UserDTO $owner;
public ?AnimalDTO $animal;
public ?string $specie;
public array $photos = [];
public ?string $status;
public ?string $additional_information;
public ?float $bonus;
public function __construct(
?string $id,
?string $type,
?string $title,
?string $description,
?DateTimeImmutable $date_of_loss,
?string $state,
?DateTimeImmutable $created_at,
?DateTimeImmutable $updated_at,
?AddressDTO $location,
?UserDTO $owner,
?AnimalDTO $animal,
?string $specie,
array $photos,
?string $status,
?string $additional_information,
?float $bonus
) {
$this->id = $id;
$this->type = $type;
$this->title = $title;
$this->description = $description;
$this->date_of_loss = $date_of_loss;
$this->state = $state;
$this->created_at = $created_at;
$this->updated_at = $updated_at;
$this->location = $location;
$this->owner = $owner;
$this->animal = $animal;
$this->specie = $specie;
$this->photos = $photos;
$this->status = $status;
$this->additional_information = $additional_information;
$this->bonus = $bonus;
}
}
Thank you in advance for any leads or solutions you may provide.