Mensaje StackOverflow
Hello everybody!
I'm having a strange issue (cause it was already solved many months ago) regarding SonataAdminBundle. The thing is that my embed forms is not longer working. My approach basically follows this tutorial: http://simonsaysblog.net/sonataadminbundle-doctrine-and-onetomany-relationship (and many other tutorials around the Net).
I have the "User" entity (the one installed by Sonata User Bundle over FOSUserBundle) which has two entities: Email and Phone, in a Many-to-One relationship with User (One user has many email addresses and many phone numbers).
Call the User form display this error message:
The current field `emails` is not linked to an admin. Please create one for the target entity : ``
(The entity name is blank as you can notice).
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>
The only one thing I could think it has changed is the location of all the Sonata User files. Before they were locatated into MyApp\\MyBundle , now they are now into Application\\Sonata\\UserAdmin\\ folder (as is showed in the Sonata Project documentation).
If I take off the add() method, in the UserAdmin class, corresponding to email, the form renders OK (very slowly, but it renders OK).
如果我对消息很了解,则必须为MyApp\\MyBundle\\Entity\\Email
和MyApp\\MyBundle\\Entity\\Phone
实体定义另外两个管理类(以便在UserAdmin
类sonata_type_collection
它们链接为sonata_type_collection
)。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.