Search code examples
phpsymfonysonata

(Sonata) Impossible to create a OneToOne relation without having an Admin linked to it


I would like to create my application around Sonata but I'm encountering some problems ...

I extended the BaseUser to create my own User and I did the same for the UserAdmin. I created an other entity on which the User has a relation OneToOne BUT I don't want this entity to be manageable by the user with an Admin linked to this entity.

The only way I want the user to fill those entities will be by the UserAdmin, I tried something like this :

protected function configureFormFields(FormMapper $formMapper){
    parent::configureFormFields($formMapper);
    $formMapper
        ->tab('Client details')
            ->with('Client Identity', array('class' => 'col-md-6'))
                ->add("test", EntityType::class, array(
                   "class" => "AppBundle:PersonDetails",
                   "property_path" => "details.test"
                ))
            ->end()
        ->end();
}

Here is my User class :

/**
 * @ORM\Entity
 * @ORM\Table(name="fos_user")
 */
class User extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\OneToOne(targetEntity="PersonDetails")
     * @ORM\JoinColumn(name="details_id", referencedColumnName="id")
     */
    private $details;

    public function __construct()
    {
        parent::__construct();
        $this->details = new PersonDetails();
    }

    /**
     * @return PersonDetails
     */
    public function getDetails()
    {
        return $this->details;
    }

    /**
     * @param PersonDetails $details
     */
    public function setDetails($details)
    {
        $this->details = $details;
    }
}

The only thing I'm getting there is a select which wants me to pick an existing PersonDetails (I suppose).

How can I achieve this ? And, if it can be easily achieved, why doesn't it appeared in the documentation ? I think this case is not really uncommon ..

Thanks for your help


Solution

  • Sonata will try to parse the string passed to add("test"), so we can access our entity not driven by any Sonata administration by a simple add("details.test").

    We do not need any additional configuration for the relation to work. Just don't forget Doctrine configuration for Cascade Persist and Deletion :

    In the class User :

    public class User extends BaseUser{
        /**
         * @ORM\Id
         * @ORM\Column(type="integer")
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        protected $id;
    
        /**
         * @ORM\OneToOne(targetEntity="PersonDetails", cascade={"persist", "remove"})
         * @ORM\JoinColumn(name="details_id", referencedColumnName="id")
         */
        private $details;
    
        // The rest of the class
    }
    

    and in the UserAdmin class :

    protected function configureFormFields(FormMapper $formMapper)
    {
        parent::configureFormFields($formMapper);
    
        $formMapper
            ->tab('Client details')
                ->with('Client Identity', array('class' => 'col-md-6'))
                    ->add("details.test")
                ->end()
            ->end();
    }