I use Symfony 4 with Sonata Admin. I have One Project To Many News association. And I found a problem trying in my Project admin page add some news and update the Project. The problem is News have not been added to the Project. And then I solved this problem by adding this code into my ProjectsAdmin.php file:
public function prePersist($project)
{
$this->preUpdate($project);
}
public function preUpdate($project)
{
$project->setNews($project->getNews());
}
But there is still some problems. The second one is I can't delete News from Project, after clicking update button nothing happens. Sure if I use 'orphanRemoval=true' in my Projects Entity for field news it would work but it would delete News that I only want to remove from Project. How can I fix this problem?
And the last but not least I have PreUpdate event listener that checks: if I update Project entity than add to this Project all News. The thing is it doesn't work when I do it for Projects Entity but when I do the same for News Entity it works. I forgot to mention that it is so similar with my problems in admin panel, because when I go to News Admin and there try to add Project to News it works without any fixes and when I try to delete Project from News in News Admin it also works as expected. So on inversedBy side everything works but on mappedBy side I have problems.
Here is my Event Listener:
public function PreUpdate(LifecycleEventArgs $args): void {
$entity = $args->getEntity();
$newsRepo = $args->getEntityManager()->getRepository(News::class);
if ($entity instanceof Projects) {
foreach ($newsRepo as $new){
$news = $args->getEntityManager()->getReference(News::class, $new->getId());
$entity->setNews($news);
}
}
}
My Projects Entity:
/**
* @ORM\Entity(repositoryClass=ProjectsRepository::class)
* @ORM\HasLifecycleCallbacks()
*/
class Projects {
/**
* @ORM\OneToMany(targetEntity=News::class, mappedBy="project", orphanRemoval=true)
*/
private $news;
public function __construct() {
$this->news = new ArrayCollection();
}
/**
* @return Collection|News[]
*/
public function getNews(): Collection {
return $this->news;
}
/**
* @param mixed $news
* @return Projects
*/
public function setNews($news) {
if (count($news) > 0) {
foreach ($news as $i) {
$this->addNews($i);
}
}
return $this;
}
/**
* @param News $news
*/
public function addNews(News $news) {
$news->setProject($this);
$this->news->add($news);
}
/**
* @param News $news
*/
public function removeNews(News $news) {
$this->news->removeElement($news);
}
}
News Entity:
/**
* @ORM\Entity(repositoryClass="App\Repository\NewsRepository")
* @ORM\HasLifecycleCallbacks()
*/
class News {
/**
* @ORM\ManyToOne(targetEntity=Projects::class, inversedBy="news")
* @ORM\JoinColumn(nullable=true)
*/
private $project;
public function getProject(): ?Projects {
return $this->project;
}
public function setProject(?Projects $project): self {
$this->project = $project;
return $this;
}
}
Projects Repository:
/**
* @method Projects|null find($id, $lockMode = null, $lockVersion = null)
* @method Projects|null findOneBy(array $criteria, array $orderBy = null)
* @method Projects[] findAll()
* @method Projects[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class ProjectsRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Projects::class);
}
}
News Repository:
/**
* @method News|null find($id, $lockMode = null, $lockVersion = null)
* @method News|null findOneBy(array $criteria, array $orderBy = null)
* @method News[] findAll()
* @method News[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class NewsRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, News::class);
}
}