SonataAdminBundle,sonata_type_collection和嵌入表单

时间:2014-01-07 06:45:14

标签: php symfony sonata-admin

Mensaje StackOverflow

各位大家好!

关于SonataAdminBundle,我有一个奇怪的问题(因为它已在几个月前解决了)。问题是我的嵌入表格不再有效。我的方法基本上遵循本教程:http://simonsaysblog.net/sonataadminbundle-doctrine-and-onetomany-relationship(以及网络上的许多其他教程)。

我有“用户”实体(由Sonata用户捆绑在FOSUserBundle上安装的实体),它有两个实体:电子邮件和电话,与用户的多对一关系(一个用户有很多电子邮件地址和许多电话号码)。

调用用户表单显示以下错误消息:

  

当前字段“电子邮件”未链接到管理员。请为目标实体创建一个:``

(您可以注意到,实体名称为空白)。

user.php的

<?php

namespace Application\Sonata\UserBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Mapping as ORM;
use Sonata\UserBundle\Entity\BaseUser as BaseUser;

/**
*
* @ORM\Table(name="system_user")
* @ORM\Entity(repositoryClass="Application\Sonata\UserBundle\Repository\UserRepository")
* @ORM\HasLifecycleCallbacks
*/
class User extends BaseUser
{
    /**
    * @var integer $id
    *
    * @ORM\Column(name="id", type="integer", nullable=false)
    * @ORM\Id
    * @ORM\GeneratedValue(strategy="SEQUENCE")
    * @ORM\SequenceGenerator(sequenceName="system_user_id_seq", allocationSize=1, initialValue=1)
    */
    protected $id;

    /**
    * @var ArrayCollection emails
    *
    * @ORM\OneToMany(targetEntity="MyApp\MyBundle\Entity\Email", mappedBy="user", cascade={"persist", "remove"}, orphanRemoval=true)
    */
    protected $emails;

    /**
    * @var ArrayCollection phones
    *
    * @ORM\OneToMany(targetEntity="MyApp\MyBundle\Entity\Phone", mappedBy="user", cascade={"persist", "remove"}, orphanRemoval=true)
    */
    protected $phones;

    // some other attributes

    /**
    * Constructor
    */
    public function __construct()
    {
        parent::__construct();

        $this->emails       = new \Doctrine\Common\Collections\ArrayCollection();
        $this->phones       = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
    * Get id
    *
    * @return integer $id
    */
    public function getId()
    {
        return $this->id;
    }

    /**
    * Set emails
    *
    * @param $emails
    */
    public function setEmails($emails)
    {
        $this->emails = new ArrayCollection();

        foreach ($emails as $email) {
            $this->addEmails($email);
        }
    }

    /**
    * Get emails
    *
    * @return ArrayCollection
    */
    public function getEmails()
    {
        return $this->emails;
    }

    /**
    * Add email
    *
    * @param \MyApp\MyBundle\Entity\Email $email
    */
    public function addEmails(\MyApp\MyBundle\Entity\Email $email)
    {
        $email->setUser($this);

        //$this->emails[] = $email;
        $this->emails->add($email);
    }

    /**
    * Remove email address
    *
    * @param \MyApp\MyBundle\Entity\Email $email
    */
    public function removeEmails(\MyApp\MyBundle\Entity\Email $email)
    {
        $this->emails->removeElement($email);
    }

    // some other methods
}

UserAdmin.php

<?php

namespace Application\Sonata\UserBundle\Admin;

use FOS\UserBundle\Model\UserManagerInterface;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;
use Sonata\UserBundle\Model\UserInterface;

class UserAdmin extends Admin
{
    // some other methods

    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->with('General')
                ->add('username')
                ->add('email')
                ->add('plainPassword', 'text', array(
                    'required' => (!$this->getSubject() || is_null($this->getSubject()->getId()))
                ))
                ->add('emails', 'sonata_type_collection',
                    array(
                        'label' => 'Emails',
                        'by_reference' => false,
                        'cascade_validation' => true
                    ),
                    array(
                        'edit' => 'inline',
                        'inline' => 'table',
                        'allow_delete' => true
                    )
                )
            // many other fields
        ;
    }

    // some other methods
}

Email.php

<?php

namespace MyApp\MyBundle\Entity;

use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Mapping as ORM;

/**
* Email
*
* @ORM\Table(name="email")
* @ORM\Entity(repositoryClass="MyApp\MyBundle\Repository\EmailRepository")
* @ORM\HasLifecycleCallbacks
*/
class Email
{
    /**
    * @var integer
    *
    * @ORM\Column(name="id", type="integer", length=18, nullable=false)
    * @ORM\Id
    * @ORM\GeneratedValue(strategy="SEQUENCE")
    * @ORM\SequenceGenerator(sequenceName="email_id_seq", allocationSize=1, initialValue=1)
    */
    private $id;

    /**
    * @var \Application\Sonata\UserBundle\Entity\User
    *
    * @ORM\ManyToOne(targetEntity="Application\Sonata\UserBundle\Entity\User", inversedBy="emails")
    * @ORM\JoinColumns({
    *   @ORM\JoinColumn(name="system_user_id", referencedColumnName="id")
    * })
    */
    private $user;

    // some other attributes

    /**
    * Set user
    *
    * @param \Application\Sonata\UserBundle\Entity\User $user
    * @return Email
    */
    public function setUser(\Application\Sonata\UserBundle\Entity\User $user = null)
    {
        $this->user = $user;

        return $this;
    }

    /**
    * Get user
    *
    * @return \Application\Sonata\UserBundle\Entity\User
    */
    public function getUser()
    {
        return $this->user;
    }

    // some other methods
}

EmailAdmin.php

namespace MyApp\MyBundle\Admin;

use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;
use Sonata\AdminBundle\Validator\ErrorElement;

class EmailAdmin extends Admin
{
    // other methods

    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('address')
            ->add('notes', 'textarea', array('required' => false))
        ;
    }
    // more methods
}

Phone.php

<?php

namespace MyApp\MyBundle\Entity;

use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Mapping as ORM;

/**
 * Phone
 *
 * @ORM\Table(name="phone")
 * @ORM\Entity(repositoryClass="MyApp\MyBundle\Repository\PhoneRepository")
 * @ORM\HasLifecycleCallbacks
 */
class Phone
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", length=18, nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="SEQUENCE")
     * @ORM\SequenceGenerator(sequenceName="phone_id_seq", allocationSize=1, initialValue=1)
     */
    private $id;
        /**
     * @var \Application\Sonata\UserBundle\Entity\User
     *
     * @ORM\ManyToOne(targetEntity="Application\Sonata\UserBundle\Entity\User", inversedBy="phones")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="system_user_id", referencedColumnName="id")
     * })
     */
    private $user;
   /**
     * Get id
     *
     * @return string
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set phoneNumber
     *
     * @param string $phoneNumber
     * @return Phone
     */
    public function setPhoneNumber($phoneNumber)
    {
        $this->phoneNumber = $phoneNumber;

        return $this;
    }

    /**
     * Get phoneNumber
     *
     * @return string
     */
    public function getPhoneNumber()
    {
        return $this->phoneNumber;
    }

    // more methods
}

PhoneAdmin.php

<?php

namespace MyApp\MyBundle\Admin;

use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;
use Sonata\AdminBundle\Validator\ErrorElement;

class PhoneAdmin extends Admin
{
    // other methods

    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('phoneNumber')
            ->add('notes', 'textarea', array('required' => false))
        ;
    }

    // other methods
}

admin.xml的

    <service id="myapp.my_bundle.admin.email" class="MyApp\MyBundle\Admin\EmailAdmin">
        <tag name="sonata.admin" manager_type="orm" group="Configuration" label="Emails" />
        <tag name="security.secure_service" />
        <argument />
        <argument>MyApp\MyBundle\Entity\Email</argument>
        <argument>MyAppMyBundle:EmailAdmin</argument>
    </service>

    <service id="myapp.my_bundle.admin.phone" class="MyApp\MyBundle\Admin\PhoneAdmin">
        <tag name="sonata.admin" manager_type="orm" group="Configuration" label="Phones" />
        <tag name="security.secure_service" />
        <argument />
        <argument>MyApp\MyBundle\Entity\Phone</argument>
        <argument>MyAppMyBundle:PhoneAdmin</argument>
    </service>

我认为它唯一改变的是所有Sonata用户文件的位置。在将它们定位到 MyApp \ MyBundle 之前,现在它们现在进入 Application \ Sonata \ UserAdmin \ 文件夹(如Sonata项目文档中所示)。

如果我取消了对应于电子邮件的UserAdmin类中的add()方法,则表单呈现正常(非常缓慢,但呈现正常)。

1 个答案:

答案 0 :(得分:0)

如果我理解该消息,您必须为MyApp\MyBundle\Entity\EmailMyApp\MyBundle\Entity\Phone实体定义另外两个管理类(以便将它们作为sonata_type_collection链接到UserAdmin 1}} class)。