php – Symfony 4 : How to edit entity and related entity with relation one-to-one-ThrowExceptions

Exception or error:

I have two entities (page and slug) with relation one to one unidirectional.

The problem appears when I leave the field slug empty because I want to update the Slug object by title if it is empty.

Error: Expected argument of type “string”, “null” given at property path “name”.

Here is my code.

MY CONTROLLER:

public function edit(Page $page, Request $request, EntityManagerInterface $entityManager)
    {
        $form = $this->createForm(PageType::class, $page);
        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            $entityManager->flush();
            $this->addFlash(
                'success',
                "Page  <strong>{$page->getTitle()}</strong> Updated successfully. "
            );
            return $this->redirectToRoute("backoffice_page_edit", ["id" => $page->getId()]);
        }
        return $this->render('back_office/page/edit.html.twig', [
            'form' => $form->createView(),
        ]);
    }

ENTITY PAGE:

class Page extends EntityBase
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $title;

    /**
     * @ORM\Column(type="text")
     */
    private $content;

    /**
     * @ORM\Column(type="boolean")
     */
    private $status;

    /**
     * @ORM\OneToOne(targetEntity="App\Entity\Slug", inversedBy="page", cascade={"persist", "remove"})
     * @ORM\JoinColumn(nullable=false)
     * @Assert\Valid
     */
    private $slug;

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

    public function getTitle(): ?string
    {
        return $this->title;
    }

    public function setTitle(string $title): self
    {
        $this->title = $title;

        return $this;
    }

    public function getContent(): ?string
    {
        return $this->content;
    }

    public function setContent(string $content): self
    {
        $this->content = $content;

        return $this;
    }

    public function getStatus(): ?bool
    {
        return $this->status;
    }

    public function setStatus(bool $status): self
    {
        $this->status = $status;

        return $this;
    }

    public function getSlug(): ?Slug
    {

        return $this->slug;
    }

    public function setSlug(Slug $slug): self
    {

        $this->slug = $slug;
        return $this;
    }
    /**
     * Set the Slug object by title if it is empty
     * @ORM\PrePersist
     * @ORM\PreUpdate
     */
    public function setSlugByTitle(): void
    {
        if (null === $this->getSlug()) {
            $slug = new Slug();
            $slug->setName($this->getTitle());
            $this->setSlug($slug);
        }

    }
}

ENTITY Slug:

class Slug  extends EntityBase
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $name;

    /**
     * @ORM\OneToOne(targetEntity="App\Entity\Page", mappedBy="slug", cascade={"persist", "remove"})
     */
    private $page;

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

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

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

        return $this;
    }

    public function getPage(): ?Page
    {
        return $this->page;
    }

    public function setPage(Page $page): self
    {
        $this->page = $page;

        // set the owning side of the relation if necessary
        if ($page->getSlug() !== $this) {
            $page->setSlug($this);
        }

        return $this;
    }

    /**
     * @ORM\PreUpdate()
     * @ORM\PrePersist()
     */
    public function initializeSlug()
    {
        $slugify = new Slugify();
        $this->name = $slugify->slugify($this->name);
    }
}


FORM PAGE:

class PageType extends ApplicationType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title', TextType::class, $this->getConfiguration("Title", "Type a title for this page"))
            ->add('slug', SlugType::class, $this->getConfiguration(false, false, [
                'required' => false,
            ]))
            ->add('content', CKEditorType::class, $this->getConfiguration("Content", ""))
            ->add('status', CheckboxType::class, $this->getConfiguration("Published", "", [
                'attr' => ['checked' => 'checked'],
                'required' => false,
            ]));
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Page::class,
        ]);
    }
}

FORM Slug:

class SlugType extends ApplicationType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', TextType::class, $this->getConfiguration("Slug", "Type a slug valid for this page"));
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Slug::class,
        ]);
    }
}
How to solve:

Leave a Reply

Your email address will not be published. Required fields are marked *