Home > Net >  Entity in Symfony bundle that is associate with main app entity for a plugin system
Entity in Symfony bundle that is associate with main app entity for a plugin system

Time:10-31

I'm trying to create a plug-in system using Symfony and its bundle system. I know bundle must be independent but for my system, I know my bundle will never be used in another context.

I have a doctrine entity called "Mark" and I want to associate an entity from the main application called "Student" so a student can have a mark from my mark plugin.

For the moment, I only have an entity Mark that is really simple and I don't know how to associate a new field to my Student entity

namespace Zenith\QuinzeBundle\Model; 
[...]
#[ORM\Entity(repositoryClass: MarkRepository::class)]
class Mark
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 255)]
    private ?string $comment = null;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getComment(): ?string
    {
        return $this->comment;
    }

    public function setComment(string $comment): self
    {
        $this->comment = $comment;

        return $this;
    }
}

And this is my Student entity (simplified) :

namespace Zenith\Entity;
[...]
#[ORM\Entity(repositoryClass: StudentRepository::class)]
class Student
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 255)]
    private ?string $firstname = null;

    #[ORM\Column(length: 255)]
    private ?string $name = null;

    public function __construct()
    {
        $this->userfieldValues = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getFirstname(): ?string
    {
        return $this->firstname;
    }

    public function setFirstname(string $firstname): self
    {
        $this->firstname = $firstname;

        return $this;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

How can I associate this two entities that one is in an app and the other in a bundle ?

CodePudding user response:

You can create a single foreign key link table to the student table. Connecting table: student | mark | plugin entity where student is the foreign key to the student entity. Mark is the identifier of the plug-in assigned to the student, without using any foreign keys. With this solution, you can add a new student plugin at any time without modifying the student entity.

CodePudding user response:

As @bechir suggested, I used this link form Doctrine documentation and worked as a charm !

EDIT : As the comment said the part that solve the problem is the use of the ResolveTargetEntityListener class from Doctrine tools. It can permit you to inject an Entity that implements the same interface that is needed. I created a bundle for contracts and added every interfaces I need for my entities. Then required this contracts bundle in my main app and my bundle then inject my entities into the doctrine metadata to rewrite the association.

In ContractsBundle

namespace Zenith\ContractsBundle;

interface StudentInterface { ... }

namespace Zenith\ContractsBundle;

interface MarkInterface { ... }

In main Symfony app :

namespace Zenith\Entity;

use Zenith\ContractsBundle\StudentInterface;

class Student implements StudentInterface {

    {...}
    #[ORM\OneToMany(mappedBy: 'student', targetEntity: MarkInterface::class)]
    private Collection $marks;

}

In bundle : In main Symfony app :

namespace Zenith\MyBundle\Entity;

use Zenith\ContractsBundle\MarkInterface;

class Mark implements MarkInterface { ... }

Then, define the doctrine listener in your services.

  • Related