2

I have friends and categories - each friend has a category. At the home page a list of all friends is seen and there is a drop down menu with all categories and a submit button - when you choose category and click it, you see only the friends from this category.

This is Category.php:

<?php

namespace EM\MyFriendsBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * EM\MyFriendsBundle\Entity\Category
 * @ORM\Entity
 * @ORM\Table(name="categories")
 * @ORM\Entity(repositoryClass="EM\MyFriendsBundle\Entity\SameRepository")
 */
class Category 
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\Column(type="string", length=100)
     * @Assert\NotBlank()
     * @Assert\MinLength(
     *         limit=3,
     *         message="The name is too short." )
     */
    protected $name;

    /**
     * @ORM\Column(type="string", length=225, nullable=true)
     */
    protected $description;

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

    /**
     * @ORM\OneToMany(targetEntity="Friend", mappedBy="category")
     * @ORM\OrderBy({"name" = "ASC"})
     */
    protected $friends;

    public function __construct()
    {
        $this->friends = new \Doctrine\Common\Collections\ArrayCollection();
    } 

    public function getId()
    {
        return $this->id;
    }

    public function setName($name)
    {
        $this->name = $name;
    }

    public function getName()
    {
        return $this->name;
    }

    public function setDescription($description)
    {
        $this->description = $description;
    }

    public function getDescription()
    {
        return $this->description;
    }

    public function setUser(\EM\MyFriendsBundle\Entity\User $user)
    {
        $this->user = $user;
    }

    public function getUser()
    {
        return $this->user;
    }

    public function addFriend(\EM\MyFriendsBundle\Entity\Friend $friend)
    {
        $this->friends[] = $friend;
    }

    public function getFriends()
    {
        return $this->friends;
    }
} 

ChooseCatType.php:

<?php

namespace EM\MyFriendsBundle\Entity;

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

class ChooseCatType extends AbstractType
{
    protected $user;

    function __construct($user) 
    {
        $this->user = $user;
    }

    public function buildForm(FormBuilder $builder, array $options)
    {
        $user = $this->user;

        $builder->add('name', 'entity', array(
            'class' => 'EMMyFriendsBundle:Category',
            'property' => 'name',
            'empty_value' => 'All friends',
            'required' => false,
            'query_builder' => function ($repository) use ($user)
                { return $repository->createQueryBuilder('cat')
                                    ->select('cat')
                                    ->where('cat.user = :user')
                                    ->orderBy('cat.name', 'ASC')
                                    ->setParameter('user', $user);
                }, ));
    }

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

and this is the controller's action:

public function filterAction(Request $request)
   {
       $this->init();

       $cat = new Category();

       $dd_form = $this->createForm(new ChooseCatType($this->user), $cat);

       if($request->getMethod() == 'POST') { 
           $dd_form->bindRequest($request);

           if($cat->getName() == null) {      
               return $this->redirect($this->generateUrl('home_display'));
           }

           $filter = $cat->getName()->getId();

           if ($dd_form->isValid()) {   
               $friends = $this->em->getRepository('EMMyFriendsBundle:Friend')
                   ->filterFriends($filter);

               if(!$friends) {
                   $this->setFlash('There are no frieds in this category.', 'error');
                   return $this->redirect($this->generateUrl('home_display'));
               }
           }

           return $this->render('EMMyFriendsBundle:Home:filtered_home.html.twig', array(
                   'friends' => $friends, 'category' => $cat->getName()->getName(), 
                   'dd_form' => $dd_form->createView()));   
       }

       return $this->redirect($this->generateUrl('home_display'));
   }
}

where init() sets $this->em = $this->getDoctrine()->getEntityManager(); and $this->user = $this->get('security.context')->getToken()->getUser();

I get an error: Expected argument of type string, object given, but can not understand from where it comes and how to fix it. Any help, please? It will be really appreciated. I think that it occures on this line $dd_form->bindRequest($request);, bacause when I put exit; before it the program exits, but when I put it after it, it shows the error.

Another thing is that when I remove

@Assert\MinLength(
         *         limit=3,
         *         message="The name is too short." )

which is above the name property in Category.php, everything works perfect.

Any ideas will be helpful! Thanks for your time!

And one more thing - why to get the id of a category I should use $cat->getName()->getId();? I thought that it should be only $cat->getId(), but it wasn't.

3
  • It is really weird that you need to use $cat->getName()->getId();. This should not be. What do you get if you use $cat->getId()? Commented Sep 19, 2012 at 10:29
  • Ah, I know what is wrong. See answer Commented Sep 19, 2012 at 10:31
  • @Carlos Granados, I get that getId() is not called on a object or something like this. Commented Sep 19, 2012 at 10:36

1 Answer 1

3

When you use an 'entity' field type, what you get back from it is an entity, so it does not make sense that this field is called "name". So I would change your builder to:

$builder->add('category', 'entity', array(
...

Then, you DON´T need to pass a Category object to this form builder. This is usually done when the form connects each field with an object property but this is not the case. You are not using this form to get the "category" property of the Category object. This is just a form that will return us a Category object, which you can get from the form data. So change your controller to this:

public function filterAction(Request $request)
   {
       $this->init();

       $dd_form = $this->createForm(new ChooseCatType($this->user));

       if($request->getMethod() == 'POST') { 
           $dd_form->bindRequest($request);

           if ($dd_form->isValid()) {   
               $data = $form->getData();
               $cat = $data['category'];

               $filter = $cat->getId();
               $friends = $this->em->getRepository('EMMyFriendsBundle:Friend')
                   ->filterFriends($filter);

               if(!$friends) {
                   $this->setFlash('There are no frieds in this category.', 'error');
                   return $this->redirect($this->generateUrl('home_display'));
               }
               return $this->render('EMMyFriendsBundle:Home:filtered_home.html.twig', array(
                   'friends' => $friends, 'category' => $cat->getName(), 
                   'dd_form' => $dd_form->createView()));   
           }

       }

       return $this->redirect($this->generateUrl('home_display'));
   }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you very much! But I gen an error: Neither property "category" nor method "getCategory()" nor method "isCategory()" exists in class "EM\MyFriendsBundle\Entity\Category"
On the page where the form should be displayed, it doesn't like $builder->add('category', 'entity', array( ...
Did you remove the new Category() line and the $cat parameter from the createform call?
I have to leave now. Please post your whole code as it is now (controller, entity, formtype) somewhere (pastebin) and I´ll take a look when I come back (a couple of hours)
Thank you very much! I will post it, but there is no need to do this if you are busy, or if you don't want. I feel guilty for taking your time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.