微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

php – 在非对象上调用成员函数removeElement()

我正在创建一个表单,以便能够向一组与特定课程相关联的学生发送电子邮件.认情况下,必须选择给定课程的所有学生,但邮件的发件人必须能够取消选择学生以排除他们接收邮件.发送到整个组是没有问题的.从select中删除学生时会出现问题.

我正在使用Sonata Admin的sonata_type_model和自定义查询.在结果表单上,如果我不更改选择选项并提交表单,一切正常.当我从列表中删除项目时,我在提交表单后收到错误

错误:在/xxx/xxx/xxx/vendor/sonata-project/doctrine-orm-admin-bundle/Model/ModelManager.PHP第607行中的非对象上调用成员函数removeElement()

经过两天的寻找答案,希望有人能帮助我朝着正确的方向前进.这是我使用的一些代码

管理员

$em = $this->modelManager->getEntityManager('Stnu\Edubundle\Entity\DealItem');
    $query = $em->createqueryBuilder('d')
            ->select('d')
            ->from('StnuEdubundle:DealItem', 'd')
            ->innerJoin('d.deal', 'de')
            ->where('d.course = :course')
            ->andWhere('de.status = :status')
            ->setParameter('course',$course)
            ->setParameter('status','order');

    $defaults = $query->getQuery()->getResult();


    $formMapper
            ->with('Certificaten verzenden cursus \''. $title .'\'', array('description' => 'Begeleidende tekst e-mail'))
                ->add('dealItems', 'sonata_type_model', array(
                    'required' => true,
                    'expanded' => false,
                    'btn_add' => false,
                    'multiple' => true,
                    'label' => 'Verzenden aan',
                    'query' => $query,
                    'property' => 'deal.user',
                    'data' => $defaults,
                    'validation_groups' => false
                ))
                ->add('subject', 'text', array('required' => true, 'label' => 'Onderwerp', 'data' => $subject))
                ->add('body', 'textarea', array('label' => 'Bericht', 'required' => false, 'data' => $body, 'attr' => array('class' => 'tinymce', 'data-theme' => 'fullpage', 'style' => 'height: 350px')));

控制器:

/**
 * Create action
 *
 * @return Response
 *
 * @throws AccessDeniedException If access is not granted
 */
public function createAction()
{

    // the key used to lookup the template
    $templateKey = 'edit';

    if (false === $this->admin->isGranted('CREATE')) {
        throw new AccessDeniedException();
    }

    $object = $this->admin->getNewInstance();

    $this->admin->setSubject($object);


    /** @var $form \Symfony\Component\Form\Form */
    $form = $this->admin->getForm();
    $form->setData($object);


    if ($this->getRestMethod()== 'POST') {

        $object->setDealItems($object->getDealItems());

        $form->submit($this->get('request'));

错误出现在此点之后.

实体:

<?PHP

namespace Stnu\Edubundle\Entity;

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

/**
 * DocsEmail
 * 
 * @ORM\Entity
 */
class CertificateEmail {

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


    /**
     * @ORM\ManyToMany(targetEntity="DealItem")
     * @ORM\JoinTable(name="certificateemails_dealitems",
     *      joinColumns={@ORM\JoinColumn(name="certificateEmail_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="dealItem_id", referencedColumnName="id")}
     *      )
     */
    private $dealItems;

    private $subject;

    private $body;

    private $extraEmailTo;

    public function __construct() {
        $this->dealItems = new ArrayCollection();
    }

    /**
     * Add dealItem
     *
     */
    public function addDealItem(\Stnu\Edubundle\Entity\DealItem $dealItem) {

        $this->dealItems->add($dealItem);
        //$this->dealItems[] = $dealItem;
        return $this;
    }

    /**
     * Remove dealItem
     */
    public function removeDealItem(\Stnu\Edubundle\Entity\DealItem $dealItem) {

        foreach ($this->dealItems as $item) {
            if ($dealItem === $item) {
                // manager of Stnu\Edubundle\Entity\DealItem
                $entityManager->remove($dealItem);
            }
        }

    }

    /**
     * Get dealItems
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getDealItems() {

        return $this->dealItems;
    }

    public function setDealItems($dealItems) {
        $this->dealItems = new ArrayCollection();

        if (count($dealItems) > 0) {
            foreach ($dealItems as $dealItem) {
                $this->addDealItem($dealItem);
            }
        }

        return $this;
    }


    /**
     * Set subject
     *
     * @param string $subject
     */
    public function setSubject($subject) {
        $this->subject = $subject;

        return $this;
    }

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

    /**
     * Set body
     *
     * @param string $body
     */
    public function setBody($body) {
        $this->body = $body;

        return $this;
    }

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

    /**
     * Set extraEmailTo
     *
     * @param string $extraEmailTo
     */
    public function setExtraEmailTo($extraEmailTo) {
        $this->extraEmailTo = $extraEmailTo;

        return $this;
    }

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

}

希望有人可以帮助我!

解决方法:

我相信这更接近你的问题的答案.问题是,你问完全错误的问题.重要的内容如下,在“编辑 – 自定义多选字段”下.

你的removeDealItem方法都错了.试试这个:

    public function removeDealItem(\Stnu\Edubundle\Entity\DealItem $dealItem)
    {
        $this->dealItems->removeElement( $dealItem );

        return $this;
    }

你没有在这里调用$entityManager ……你不需要一个. Doctrine将检查您要删除的实体是否存在,如果存在则将其删除.您不需要遍历集合中的现有元素,并且您当然不需要在数据库级别上执行任何操作.

    public function addDealItem(\Stnu\Edubundle\Entity\DealItem $dealItem)
    {
        // Getting fancy - check if the item exists before adding it
        if( !$this->dealItems->contains($dealItem) )
        {
            $this->dealItems->add($dealItem);
        }
        return $this;
    }

添加项目同样容易……我们甚至可以使用它并使用Doctrine ArrayCollection :: contains()方法添加之前检查元素是否存在.你的addDealItem()方法没有任何问题 – 我只想向你展示contains()作为让ArrayCollection类为你工作的更明显的例证.

编辑 – 自定义多选字段

好的 – 在阅读了关于不一定需要保留数据的评论后,我想我会提供如何创建自定义多选框的简化示例.请理解这是一个“基本的”例子 – 但它应该引导你朝着正确的方向前进.显然,在不了解DealItem实体的结构的情况下,我只关注您需要访问的特定字段,以获取发送电子邮件所需的数据.

所以 – 在你的控制器中 – 首先我们得到数据:

$query = $em->createqueryBuilder('d')
            ->select('d')
            ->from('StnuEdubundle:DealItem', 'd')
            ->innerJoin('d.deal', 'de')
            ->where('d.course = :course')
            ->andWhere('de.status = :status')
            ->setParameter('course',$course)
            ->setParameter('status','order');

$defaults = $query->getQuery()->getResult();

$choices = array();

foreach( $defaults as $dealItem )
{
    $choices[ $dealItem->getEmailAddress() ] = $dealItem->getStudentName();
}

现在我们需要一个对象来接收数据.我从您的评论中收集到的是您不想保留数据,并且您只为CertificateEmail对象创建一个Entity,以便您可以构建表单.馊主意.您不需要实体 – 所以不要在第一时间构建实体.为了证明这一点,我将使用stdClass对象:

$certificateEmail = new \stdClass();

$certificateEmail->dealItems = array();
$certificateEmail->subject   = '';
$certificateEmail->body      = '';

然后我们构建表单:

$form = $this->createFormBuilder( $certificateEmail )
             ->add( 'dealItems', 'choice', array(
                         'choices'  => $choices,
                         'multiple' => true,
                         'required' => true,
                         'label'    => 'Verzenden aan' ) )
             ->add( 'subject', 'text', array( 'required' => true, 'label' => 'Onderwerp' ) )
             ->add( 'body', 'textarea', array( 'required' => false, 'label' => 'Bericht' ) )
             ->getForm();

最后,将它扔到模板上:

return $this->render( 'template.html.twig', array( 'form' => $form->createView() ) );

而且,希望你能从那里拿走它:)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐