SonataAdminBundle configureFormFields 与两步相关实体

Posted

技术标签:

【中文标题】SonataAdminBundle configureFormFields 与两步相关实体【英文标题】:SonataAdminBundle configureFormFields with two step relationated entities 【发布时间】:2017-10-17 22:18:35 【问题描述】:

我有下一个实体

AppBundle/Entity/User.php

namespace AppBundle\Entity;

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

/**
 * @ORM\Entity
 * @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
 * @ORM\Table(name="fos_user_user")
 * 
 */
class User extends BaseUser

/**
 * @var int
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $id;

/**
 * @ORM\OneToMany(targetEntity="SmsHistory", mappedBy="user", cascade="persist", orphanRemoval=true)
 */
private $smsHistory;

public function __construct()

    parent::__construct();
    $smsHistory = new ArrayCollection;


/**
 * Get id
 *
 * @return int $id
 */
public function getId()

    return $this->id;


/**
* @param \Doctrine\Common\Collections\ArrayCollection $smsHistory
*/
public function setSmsHistory($smsHistory)
    if (count($smsHistory) > 0) 
        foreach ($smsHistory as $i) 
            $this->addSmsHistory($i);
        
    
    return $this;


/**
 * Add smsHistory
 *
 * @param \AppBundle\Entity\SmsHistory $smsHistory
 *
 * @return User
 */
public function addSmsHistory(\AppBundle\Entity\SmsHistory $smsHistory)

    $smsHistory->setUser($this);
    $this->smsHistory->add($smsHistory);


/**
 * Remove smsHistory
 *
 * @param \AppBundle\Entity\SmsHistory $smsHistory
 */
public function removeSmsHistory(\AppBundle\Entity\SmsHistory $smsHistory)

    $this->smsHistory->removeElement($smsHistory);


/**
 * Get smsHistory
 *
 * @return \Doctrine\Common\Collections\Collection
 */
public function getSmsHistory()

    return $this->smsHistory;

AppBundle/Entity/SmsHistory.php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * SmsHistory
 *
 * @ORM\Table(name="sms_history")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\SmsHistoryRepository")
 */
class SmsHistory

/**
 * @var int
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @ORM\ManyToOne(targetEntity="User", inversedBy="smsHistory")
 * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
 */
private $user;

/**
 * @ORM\ManyToOne(targetEntity="Contact", inversedBy="smsHistory")
 * @ORM\JoinColumn(name="contact_id", referencedColumnName="id")
 */
private $contact;

/**
 * Get id
 *
 * @return int
 */
public function getId()

    return $this->id;


/**
 * Set user
 *
 * @param \AppBundle\Entity\User $user
 *
 * @return SmsHistory
 */
public function setUser(\AppBundle\Entity\User $user = null)

    $this->user = $user;

    return $this;


/**
 * Get user
 *
 * @return \AppBundle\Entity\User
 */
public function getUser()

    return $this->user;


/**
 * Set contact
 *
 * @param \AppBundle\Entity\Contact $contact
 *
 * @return SmsHistory
 */
public function setContact(\AppBundle\Entity\Contact $contact = null)

    $this->contact = $contact;

    return $this;


/**
 * Get contact
 *
 * @return \AppBundle\Entity\Contact
 */
public function getContact()

    return $this->contact;

AppBundle/SmsHistory/Contact.php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * Contact
 *
 * @ORM\Table(name="contact")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\ContactRepository")
 */
class Contact

/**
 * @var int
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @ORM\ManyToOne(targetEntity="User", inversedBy="contact")
 * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
 */
private $user;

/**
 * @ORM\OneToMany(targetEntity="SmsHistory", mappedBy="contact", cascade="persist", orphanRemoval=true)
 */
private $smsHistory;

public function __construct() 
    $smsHistory = new ArrayCollection;


/**
 * Get id
 *
 * @return int
 */
public function getId()

    return $this->id;


/**
 * Set user
 *
 * @param \AppBundle\Entity\User $user
 *
 * @return Contact
 */
public function setUser(\AppBundle\Entity\User $user = null)

    $this->user = $user;

    return $this;


/**
 * Get user
 *
 * @return \AppBundle\Entity\User
 */
public function getUser()

    return $this->user;


/**
 * Add smsHistory
 *
 * @param \AppBundle\Entity\SmsHistory $smsHistory
 *
 * @return User
 */
public function addSmsHistory(\AppBundle\Entity\SmsHistory $smsHistory)

    $smsHistory->setContact($this);
    $this->smsHistory->add($smsHistory);


/**
 * Remove smsHistory
 *
 * @param \AppBundle\Entity\SmsHistory $smsHistory
 */
public function removeSmsHistory(\AppBundle\Entity\SmsHistory $smsHistory)

    $this->smsHistory->removeElement($smsHistory);


/**
 * Get smsHistory
 *
 * @return \Doctrine\Common\Collections\Collection
 */
public function getSmsHistory()

    return $this->smsHistory;

所有实体都与其他实体相关。

在我的 UserAdmin 中,我在 configureFormFields 中添加了添加联系人和添加 SmsHistory 的字段:

->add('contact', 'sonata_type_collection', array(
         'cascade_validation' => true,
         'by_reference' => true,
 ), array(
         'edit' => 'inline',
         'inline' => 'table',
 ))
->add('pushHistory', 'sonata_type_collection', array(
         'cascade_validation' => true,
         'by_reference' => true,
 ), array(
         'edit' => 'inline',
         'inline' => 'table',
 ))

在 SmsHistoryAdmin 中,我添加了联系人字段,以选择联系人:

->add('contact','sonata_type_model')

当我从 UserAdmin 添加 SmsHistory 时,我只想显示与我正在编辑的当前用户相关的联系人,但会显示所有用户的所有联系人。

我该怎么做?

谢谢!

【问题讨论】:

【参考方案1】:

我得到了解决方案,希望对某人有所帮助。

在 SmsHistoryAdmin 中,更改此行:

->add('contact','sonata_type_model', array())

有了这个:

->add('contact', null, [
    'query_builder' => $this->getAllowedContactQueryBuilder(),
])

并添加此功能:

/**
 * @return \Doctrine\Common\Persistence\ObjectManager|object
 */
protected function getEntityManager()

    return $this->getContainer()->get('doctrine')->getManager();


/**
 * @return null|\Symfony\Component\DependencyInjection\ContainerInterface
 */
protected function getContainer()

    return $this->getConfigurationPool()->getContainer();


/**
 * @return mixed
 */
private function getAllowedContactQueryBuilder()

    if (!$this->getSubject()) 
        return null;
    

    return $this->getContactRepository()
        ->getContactByUserQueryBuilder($this->getSubject()->getUser());


/**
 * @return \Doctrine\Common\Persistence\ObjectRepository
 */
public function getContactRepository()

    return $this->getEntityManager()->getRepository('AppBundle:Contact');

现在实体正在过滤与用户相关的联系人。

【讨论】:

以上是关于SonataAdminBundle configureFormFields 与两步相关实体的主要内容,如果未能解决你的问题,请参考以下文章

SonataAdminBundle 如何获取当前的管理类?

如何在 SonataAdminBundle 中使用角色

SonataAdminBundle :显示非粗略(统计)

将自己的操作添加到 SonataAdminBundle 下拉菜单

如何在 SonataAdminBundle 的上传字段上方显示当前图片?

SonataAdminBundle 自定义呈现列表中的文本字段