2
votes

I have an Entity containing Self-Referenced mapping. I would like to add new categories and subcategories to the systems but I do not know how to build the add form correctly. Gets are generated and setters are generated in Entity. I'm getting an error:

Neither the property "parent" nor one of the methods "addParent()"/"removeParent()", "setParent()", "parent()", "__set()" or "__call()" exist and have public access in class "Adevo\ClassifiedsBundle\Entity\ClassifiedsCategory".


    namespace XXX\ClassifiedsBundle\Entity;

    use Doctrine\ORM\Mapping as ORM;


    /**
     * @ORM\Entity(repositoryClass="XXX\ClassifiedsBundle\Repository\ClassifiedsCategoryRepository")
     * @ORM\Table(name="classifieds_categories")
     */
    class ClassifiedsCategory extends ClassifiedsAbstractTaxonomy {

        /**
         * @ORM\OneToMany(
         *      targetEntity = "Classifieds",
         *      mappedBy = "category"
         * )
         */
        protected $classifieds;

        /**
         * @ORM\ManyToMany(targetEntity="ClassifiedsCategory", mappedBy="parent")
         */
        private $children;

        /**
         *
         * @ORM\ManyToMany(targetEntity="ClassifiedsCategory", inversedBy="children")
         * @ORM\JoinTable(name="subCategory",
         *  joinColumns={@ORM\JoinColumn(name="category_id", referencedColumnName="id")},
         *  inverseJoinColumns={@ORM\JoinColumn(name="parent_id", referencedColumnName="id")}
         *     )
         */
        private $parent;

        /**
         * Constructor
         */
        public function __construct() {

            $this->children = new \Doctrine\Common\Collections\ArrayCollection();
            $this->parent = new \Doctrine\Common\Collections\ArrayCollection();
        }

        /**
         * Add classified
         *
         * @param \XXX\ClassifiedsBundle\Entity\Classifieds $classified
         *
         * @return ClassifiedsCategory
         */
        public function addClassified(\XXX\ClassifiedsBundle\Entity\Classifieds $classified) {
            $this->classifieds[] = $classified;

            return $this;
        }

        /**
         * Remove classified
         *
         * @param \XXX\ClassifiedsBundle\Entity\Classifieds $classified
         */
        public function removeClassified(\XXX\ClassifiedsBundle\Entity\Classifieds $classified) {
            $this->classifieds->removeElement($classified);
        }

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

        /**
         * Add child
         *
         * @param \XXX\ClassifiedsBundle\Entity\ClassifiedsCategory $child
         *
         * @return ClassifiedsCategory
         */
        public function addChild(\XXX\ClassifiedsBundle\Entity\ClassifiedsCategory $child) {
            $this->children[] = $child;

            return $this;
        }

        /**
         * Remove child
         *
         * @param \XXX\ClassifiedsBundle\Entity\ClassifiedsCategory $child
         */
        public function removeChild(\XXX\ClassifiedsBundle\Entity\ClassifiedsCategory $child) {
            $this->children->removeElement($child);
        }

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

        /**
         * Add parent
         *
         * @param \XXX\ClassifiedsBundle\Entity\ClassifiedsCategory $parent
         *
         * @return ClassifiedsCategory
         */
        public function addParent(\XXX\ClassifiedsBundle\Entity\ClassifiedsCategory $parent) {
            $this->parent[] = $parent;

            return $this;
        }

        /**
         * Remove parent
         *
         * @param \XXX\ClassifiedsBundle\Entity\ClassifiedsCategory $parent
         */
        public function removeParent(\XXX\ClassifiedsBundle\Entity\ClassifiedsCategory $parent) {
            $this->parent->removeElement($parent);
        }

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

    }
    
<pre>



 namespace XXX\ClassifiedsBundle\Entity;

    use Doctrine\ORM\Mapping as ORM;


    /**
     * @ORM\MappedSuperclass
     * @ORM\HasLifecycleCallbacks
     */
    abstract class ClassifiedsAbstractTaxonomy {

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

        /**
         * @ORM\Column(type="string", length=120, unique=true)
         */
        private $name;

        /**
         * @ORM\Column(type="string", length=120, unique=true)
         */
        private $slug;

        protected $classifieds;


        /**
         * Constructor
         */
        public function __construct()
        {
            $this->classifieds = new \Doctrine\Common\Collections\ArrayCollection();
    //        $this->children = new \Doctrine\Common\Collections\ArrayCollection();
    //        $this->parent = new \Doctrine\Common\Collections\ArrayCollection();
        }

        /**
         * Add classifieds
         *
         * @param \XXX\ClassifiedsBundle\Entity\Classifieds $classifieds
         * @return ClassifiedsCategory
         */
        public function addClassifieds(\XXX\ClassifiedsBundle\Entity\Classifieds $classifieds)
        {
            $this->classifieds[] = $classifieds;

            return $this;
        }

        /**
         * Remove classifieds
         *
         * @param \XXX\ClassifiedsBundle\Entity\Classifieds $classifieds
         */
        public function removeClassifieds(\XXX\ClassifiedsBundle\Entity\Classifieds $classifieds)
        {
            $this->classifieds->removeElement($classifieds);
        }

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

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

        /**
         * Set name
         *
         * @param string $name
         * @return AbstractTaxonomy
         */
        public function setName($name)
        {
            $this->name = $name;

            return $this;
        }

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

        /**
         * Set slug
         *
         * @param string $slug
         * @return AbstractTaxonomy
         */
        public function setSlug($slug)
        {
            $this->slug = \XXX\ClassifiedsBundle\Libs\Utils::sluggify($slug);

            return $this;
        }

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

        /**
         * @ORM\PrePersist
         * @ORM\PreUpdate
         */
        public function preSave(){
            if(null === $this->slug){
                $this->setSlug($this->getName());
            }
        }
    }


    namespace XXX\AdminBundle\Form\Type;

    use XXX\AdminBundle\Form\Type\ClassifiedsTaxonomyType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolverInterface;

    class ClassifiedsCategoryType extends ClassifiedsTaxonomyType {

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

        public function buildForm(FormBuilderInterface $builder, array $options) {
            $builder
            ->add('name', 'text', array(
            'label' => 'Tytuł'
            ))
            ->add('slug', 'text', array(
            'label' => 'Alias'
            ))
            ->add('parent', 'entity', array(
            'class' => 'XXX\ClassifiedsBundle\Entity\ClassifiedsCategory',
            'property' => 'name',
            'empty_value' => 'Choose a parent category',
            'required' => false,
            ))

            ->add('save', 'submit', array(
                'label' => 'Zapisz'
            ));
        }

        public function setDefaultOptions(OptionsResolverInterface $resolver) {
            $resolver->setDefaults(array(
                'data_class' => 'XXX\ClassifiedsBundle\Entity\ClassifiedsCategory'
            ));
        }

    }

1

1 Answers

0
votes

Your FormType ClassifiedsCategoryType is expecting an instance of ClassifiedsCategory and this need the attribute parent so far so good. But when you handle the request from your form to the controller, the formbuilder component tries to set the entered value to the attribute via the set method on the entity. This set method (setParent) is missing in your entity class.

So you have to implement it like this:

public function setParent($parent)
{
    $this->parent = $parent;

    return $this;
}