2
votes

I have a problem with Symfony2, I want to make a tag system but I can not manage to do I tried a lot but there are a lot of errors.

please can you help me and thank you in advance

the last error display :

Catchable Fatal Error: Argument 1 passed to Project\RmBundle\Entity\Posts::setTags() must be an instance of Project\RmBundle\Entity\Tags, string given, called in C:\wamp\www\Test\vendor\symfony\symfony\src\Symfony\Component\PropertyAccess\PropertyAccessor.php on line 438 and defined in C:\wamp\www\Test\src\Project\RmBundle\Entity\Posts.php line 390

Posts.php

class Posts{

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


/**
 * @var ArrayCollection $tags
 *
 * @ORM\ManyToMany(targetEntity="Project\RmBundle\Entity\Tags", inversedBy="posts")
 */
 private $tags;



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


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

/**
 * Add tags
 *
 * @param \Portfolio\GeneralBundle\Entity\Tags $tags
 * @return Article
 */
public function addTag(\Project\RmBundle\Entity\Tags $tags)
{
    $this->tags[] = $tags;
    return $this;
}

/**
 * Remove tags
 *
 * @param \Project\RmBundle\Entity\Tags $tags
 */
public function removeTag(\Project\RmBundle\Entity\Tags $tags)
{
    $this->tags->removeElement($tags);
}

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


/**
 * Set tags
 *
 * @param \Project\RmBundle\Entity\Tags $tags
 * @return Tags
 */
public function setTags(\Project\RmBundle\Entity\Tags $tags)
{
    $this->tags[] = $tags;

    return $this;
}}

and I have 2 FormType PostsType.php

class PostsType extends AbstractType{

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder

        ->add('tags', 'text');     
}}

TagsType.php

class TagsType extends AbstractType{

     private $om;

public function __construct(ObjectManager $om)
{
    $this->om = $om;
}

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $transformer = new StringToTagsTransformer($this->om);
    $builder->addModelTransformer($transformer);
}

 /**
 * @param OptionsResolverInterface $resolver
 */
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'Project\RmBundle\Entity\Tags'
    ));
} 
public function getName()
{
    return 'tags';}}

and i create a transform for that

class StringToTagsTransformer implements DataTransformerInterface{

private $om;

public function __construct(ObjectManager $om)
{
    $this->om = $om;
}

public function reverseTransform($ftags)
{
    $tags = new ArrayCollection();
    $tag = strtok($ftags, ",");
    while($tag !== false) {
        $itag = new Tags();
        $itag->setName($tag);
        if(!$tags->contains($itag))
            $tags[] = $itag;
        $tag = strtok(",");
    }
    return $tags;
}

public function transform($tags)
{
    $ftags = "";
    if($tags != null) {
    foreach($tags as $tag)
        $ftags = $ftags.','.$tag->getName();

    }
    return $ftags;}}

and finally my controller PostsController.php

   public function addBlogAction(Request $request){

      $em = $this->getDoctrine()->getManager();
      $posts = new Posts();
      $form = $this->createForm(new PostsType, $posts, array(
        'action' => $this->generateUrl('project_add_post'),
        'method' => 'POST'
        ));

     $em->getRepository('ProjectRmBundle:Tags')->filter($posts->getTags());

      if('POST' == $request->getMethod()){
        $form->handleRequest($request);

           if ($form->isValid()) {

              foreach($posts->getTags() as $tag){
                  $em->persist($tag);
              }
           }

            $em->persist($posts);
            $em->flush();

            return $this->redirect($this->generateUrl('project_posts'));

          }
  }

      return $this->render('ProjectRmBundle:Posts:add.html.twig', array('form'=>$form->createView())); }
1

1 Answers

0
votes

In your PostsType you've defined the tags field as having type text. You want it to use your TagsType, so you should do this:

class PostsType extends AbstractType{

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder

        ->add('tags', 'tags');     
}}

That is assuming you've declared it as a service.

Update:

You need to put the text field in TagsType. You would do something like this:

class TagsType extends AbstractType{

...

public function buildForm(FormBuilderInterface $builder, array $options)
{
    ...

    $builder
        ->add('name', 'text'); 
}

...