3

我有两个实体,即 Quiz 和 QuizQuestion,具有多对多单向关系。我想以测验形式嵌入问题形式。我在 2.0 分支上。我可以开始sonata_type_model工作,在下拉列表中获取 id 列表,并使用“添加”按钮。但是,尝试使用时出现错误sonata_type_admin

Neither property "title" nor method "getTitle()" nor method "isTitle()" exists in class "Doctrine\ORM\PersistentCollection"
500 Internal Server Error - InvalidPropertyException

这是我的测验实体:

    <?php 

namespace Some\SiteBundle\Entity;

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


/**
 * Some\SiteBundle\Entity\Quiz
 * @ORM\Table(name="quiz")
 * @ORM\Entity(repositoryClass="Some\SiteBundle\Entity\QuizRepository")

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



    /**
     * @ORM\Column(type="datetime", name="created_at")
     * 
     * @var DateTime $createdAt
     */
    protected $createdAt;


    /**
     * @var string $title
     *
     * @ORM\Column(name="title", type="string", length=255)
     */
    private $title;


    /**
     * @var string $body
     *
     * @ORM\Column(name="body", type="text")
     */
    private $body;


  /**
    * @var QuizQuestion questions
     * @ORM\ManyToMany(targetEntity="QuizQuestion", cascade={"persist", "remove"} )
     **/
    protected $questions;


    public function __construct() {
        $this->questions = new ArrayCollection();
        $this->createdAt = new \DateTime();
    }


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

    /**
     * Set title
     *
     * @param string $title
     */
    public function setTitle($title)
    {
        $this->title = $title;
    }

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


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

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



    /**
     * Gets an object representing the date and time the quiz was created.
     * 
     * @return DateTime A DateTime object
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }   



    /**
     * Add questions
     *
     * @param Some\SiteBundle\Entity\QuizQuestion $questions
     */
    public function addQuestion(\Some\SiteBundle\Entity\QuizQuestion $question)
    {
        $this->questions[] = $question;
    }

    /**
     * set question
     *
     * @param Some\SiteBundle\Entity\QuizQuestion $questions
     */
    public function setQuestion(\Some\SiteBundle\Entity\QuizQuestion $question)
    {
        foreach ($this->questions as $doc) {
            $this->questions->removeElement($doc);
        }
        $this->questions[] = $question;
    }

    /**
     * Get questions
     *
     * @return Doctrine\Common\Collections\Collection 
     */
    public function getQuestions()
    {
        return $this->questions;
    }


    /**
     * @ORM\PrePersist
     */
    public function beforePersist()
    {
        //$this->setCreatedAt(new \DateTime());        
        //$this->setModifiedAt(new \DateTime());
    }


      public function __toString()
  {
    return 'Quiz';
  }
}

和 QuizQuestion 实体:

<?php 

namespace Some\SiteBundle\Entity;

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


/**
 * Some\SiteBundle\Entity\QuizQuestion
 * @ORM\Table(name="quiz_question")
 * @ORM\Entity
 */
class QuizQuestion
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;



    /**
     * @ORM\Column(type="datetime", name="created_at")
     * 
     * @var DateTime $createdAt
     */
    protected $createdAt;


    /**
     * @var string $title
     *
     * @ORM\Column(name="title", type="string", length=255)
     */
    private $title;


    /**
     * @var string $body
     *
     * @ORM\Column(name="body", type="text")
     */
    private $body;

     /**
     * @var string $answer1
     *
     * @ORM\Column(name="answer1", type="text")
     */
    private $answer1;

     /**
     * @var string $answer2
     *
     * @ORM\Column(name="answer2", type="text")
     */
    private $answer2;

      /**
     * @var string $answer3
     *
     * @ORM\Column(name="answer3", type="text")
     */
    private $answer3;

     /**
     * @var string $answer4
     *
     * @ORM\Column(name="answer4", type="text")
     */
    private $answer4;

    /**
     * @var string $correctAnswer
     *
     * @ORM\Column(name="correct_answer", type="integer", length="1")
     */
    private $correctAnswer;




    public function __construct() {
        $this->createdAt = new \DateTime();
    }


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

    /**
     * Set title
     *
     * @param string $title
     */
    public function setTitle($title)
    {
        $this->title = $title;
    }

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


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

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


    /**
     * Get question answer1.
     * 
     * @return string answer1
     */
    public function getAnswer1()
    {
        return $this->answer1;
    }

    /**
     * Sets answer1
     * 
     * @param string $value answer1
     */
    public function setAnswer1($answer1)
    {
        $this->answer1 = $answer1;
    }

        /**
     * Get question answer2.
     * 
     * @return string answer2
     */
    public function getAnswer2()
    {
        return $this->answer2;
    }

    /**
     * Sets answer2
     * 
     * @param string $value answer2
     */
    public function setAnswer2($answer2)
    {
        $this->answer2 = $answer2;
    }

        /**
     * Get question answer3.
     * 
     * @return string answer3
     */
    public function getAnswer3()
    {
        return $this->answer3;
    }

    /**
     * Sets answer3
     * 
     * @param string $value answer3
     */
    public function setAnswer3($answer3)
    {
        $this->answer3 = $answer3;
    }

        /**
     * Get question answer4.
     * 
     * @return string answer4
     */
    public function getAnswer4()
    {
        return $this->answer4;
    }

    /**
     * Sets answer4
     * 
     * @param string $value answer4
     */
    public function setAnswer4($answer4)
    {
        $this->answer4 = $answer4;
    }

     /**
     * Get question correctAnswer.
     * 
     * @return string correctAnswer
     */
    public function getCorrectAnswer()
    {
        return $this->correctAnswer;
    }

    /**
     * Sets answer1
     * 
     * @param string $value correctAnswer
     */
    public function setCorrectAnswer($correctAnswer)
    {
        $this->correctAnswer = $correctAnswer;
    }

    /**
     * Gets an object representing the date and time the question was created.
     * 
     * @return DateTime A DateTime object
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }   




  public function __toString()
  {
    return $this->title;
  }
}

以及相关的管理课程。测验管理员第一:

    <?php 

namespace Some\SiteBundle;

use Some\SiteBundle\Form\QuizQuestionType;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Validator\ErrorElement;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\Request;

class QuizAdmin extends Admin
{


    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
              ->add('title', NULL, array('label' => 'tytuł:'))
              ->add('body', NULL, array('label' => 'opis:', 'required' => false, 'attr' => array(
                  'class' => 'tinymce', 'data-theme' => 'simple')
              ))
              ->add('questions', 'sonata_type_admin', array(), array('required' => false, 'edit' => 'inline'));
              //->add('categories', NULL, array('label' => 'kategorie:'))
        ;
    }

    protected function configureDatagridFilters(DatagridMapper $datagridMapper)
    {
        $datagridMapper
            ->add('title')
            ->add('body')
        ;
    }

    protected function configureListFields(ListMapper $listMapper)
    {
        $listMapper
            ->addIdentifier('id')
            ->add('title')
            ->add('_action', 'actions', array(
                'actions' => array(
                    'view' => array(),
                    'edit' => array(),
                )
            ))
            //->add('body')
        ;

    }

    public function validate(ErrorElement $errorElement, $object)
    {
        $errorElement
            ->with('title')
                ->assertMinLength(array('limit' => 2))
            ->end()
        ;
    }



}

和 QuizQuestionAdmin:

    <?php 

namespace Some\SiteBundle;

use Some\SiteBundle\Form\QuizQuestionType;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Validator\ErrorElement;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\Request;

class QuizAdmin extends Admin
{


    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
              ->add('title', NULL, array('label' => 'tytuł:'))
              ->add('body', NULL, array('label' => 'opis:', 'required' => false, 'attr' => array(
                  'class' => 'tinymce', 'data-theme' => 'simple')
              ))
              ->add('questions', 'sonata_type_admin', array(), array('required' => false, 'edit' => 'inline'));
              //->add('categories', NULL, array('label' => 'kategorie:'))
        ;
    }

    protected function configureDatagridFilters(DatagridMapper $datagridMapper)
    {
        $datagridMapper
            ->add('title')
            ->add('body')
        ;
    }

    protected function configureListFields(ListMapper $listMapper)
    {
        $listMapper
            ->addIdentifier('id')
            ->add('title')
            ->add('_action', 'actions', array(
                'actions' => array(
                    'view' => array(),
                    'edit' => array(),
                )
            ))
            //->add('body')
        ;

    }

    public function validate(ErrorElement $errorElement, $object)
    {
        $errorElement
            ->with('title')
                ->assertMinLength(array('limit' => 2))
            ->end()
        ;
    }



}

我尝试将 quizQuestion 注册为服务,但后来我得到了Expected argument of type "Festus\SiteBundle\Entity\QuizQuestion", "Doctrine\ORM\PersistentCollection" given 500 Internal Server Error - UnexpectedTypeException

经过几个小时的查找后找不到任何解决方案...

4

2 回答 2

4

好的,我解决了这个问题:

->add('questions', 'sonata_type_admin', array(), array('required' => false, 'edit' => 'inline'));

有了这个:

->add('questions','collection', array( 'type' =>  new QuizQuestionType(),
                                          'allow_add' => true,
                                          'prototype' => true,
                                          'by_reference' => true,
                                          ));

但对我来说,它看起来更像是一种解决方法而不是解决方案:-|

无论如何,我检查了 bundles 版本,symfony 分支并没有发现任何不连贯的东西,一切都在 2.0 分支上。

PS - QuizQuestionType 类,如果有人感兴趣的话……这里没什么特别的,只是普通的形式类:

<?php 

namespace Some\SiteBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;

class QuizQuestionType extends AbstractType
  {
      public function buildForm(FormBuilder $builder, array $options)
      {
    $builder
         ->add('title', NULL, array('label' => 'pytanie:'))
         ->add('body', NULL, array('label' => 'treść:', 'attr' => array(
          'class' => 'tinymce', 'data-theme' => 'simple')
         ))
         ->add('answer1', NULL, array('label' => 'odp. 1:'))
         ->add('answer2', NULL, array('label' => 'odp. 2:'))
         ->add('answer3', NULL, array('label' => 'odp. 3:'))
         ->add('answer4', NULL, array('label' => 'odp. 4:'))
         ->add('correctAnswer', NULL, array('label' => 'prawidłowa odp.:'))
    ;
    }

    public function getName()
    {
        return 'quiz_question';
    }

    public function getDefaultOptions(array $options){
        return array('data_class' => 'Some\SiteBundle\Entity\QuizQuestion');
    }
}
于 2012-07-27T17:21:51.970 回答
2

看起来错误解释了为什么您会遇到不存在的方法的异常。

您正在尝试传递集合而不是对象。可能,您调用addQuestion()setQuestion()方法到集合而不是来自它的对象。

这通常发生在关系填充的对象上。

在您使用该方法的地方,尝试调用$object->first()->addQuestion()而不是$object->addQuestion()

于 2012-07-27T13:37:01.783 回答