0

I've got another problem with symfony 2.

Here is my DB schema: Database Schema

Now, the problem.

When i m creating form in TranslationController:addAction() to create new translation, i can choose languages from lang table and strings from string table. That would be ok. Problem is, i need chose only languages that project have and only strings that are connected to this translation with string id.

I have TranslationController:addAction() like this:

/**
     * @Route("/project/{project_id}/string/{string_id}/translation/add/")
     * @Template()
     */
    public function addAction(Request $request)
    {
        $translation = new Translation();
        $translation->setCreatedBy('Vytvoril: ')
               ->setCorrectedBy('Koregoval: ')
               ->setText('Preklad: ')
               ->setNote('Poznámka');
        $form = $this->createFormBuilder($translation)
                ->add('createdBy', 'text')
                ->add('correctedBy', 'text')
                ->add('Text', 'text')
                ->add('note', 'text')
                ->add('lang', 'entity', array(
                    'class' => 'DomestosTranslatingBundle:Lang',
                    'expanded' => false,
                    'multiple' => false,
                    'property' => 'code',
                    ))
                ->add('string', 'entity', array(
                    'class' => 'DomestosTranslatingBundle:String',
                    'expanded' => false,
                    'multiple' => false,
                    'property' => 'code',
                    ))
                ->add('save', 'submit')
                ->getForm();

        $form->handleRequest($request);

        if($form->isSubmitted())
        {
            $em = $this->getDoctrine()->getManager();
            $em->persist($translation);
            $em->flush();
        }

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

But this code allows me to chose every language that has been created in lang and also every string that is in String table, not only those connected.

Thanks for any help.

1 Answer 1

1

Use the query_builder option on your entity field:

// ...
->add('string', 'entity', array(
    'class' => 'DomestosTranslatingBundle:String',
    'expanded' => false,
    'multiple' => false,
    'property' => 'code',
    'query_builder' => $em->getRepository('DomestosTranslatingBundle:String')
        ->createQueryBuilder('s')
        ->andWhere('s.project = :project')
        ->setParameter('project', $project)
))

Probably is much better to move the creation of the query builder inside your string repository to tidy up the code and not to repeat it every time you need that query. I assumed for the code above that you have your entity manager in $em and your project instance in $project.

Here's something to read: http://symfony.com/doc/current/reference/forms/types/entity.html#query-builder

If you want to use a closure:

// ...
->add('string', 'entity', array(
    'class' => 'DomestosTranslatingBundle:String',
    'expanded' => false,
    'multiple' => false,
    'property' => 'code',
    'query_builder' => function (EntityRepository $repository) use ($project) {
        return $repository->createQueryBuilder('s')
            ->andWhere('s.project = :project')
            ->setParameter('project', $project);
    }
))

Just remember to import Doctrine\ORM\EntityRepository in your type definition or controller.

Since you will need a reference to your project inside the form type, you could add to your TranslationType class the following property and methods:

protected $project;

public function setProject($p)
{
    $this->project = $p;

    return $this;
}

public function getProject()
{
    return $this->project;
}

And when creating the form in your controller you do something like:

$form = new TranslationType();
$form->setProject($project);

So when building the fields, before you define the closure you do $project = $this->getProject() and the project instance will be available to be used by the closure.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks too much, i will try it, but it makes sense. BTW: You assumed properly :) Thanks for help.
One more question, i moved my forms from controller to TranslationType.php class in /Form and i can not use $em = $this->getDoctrine() there ( dunno why ). How can i use your example now?
It's returning undefined variable project. I'm doing something wrong, but right now dont know what :D
Did you define $project somewhere inside your scope? Ie: when creating your form $form = new TranslationType(); can you then inject your project with something like $form->setProject($project); and then when building the form, before you define your closure you put something like: $project = $this->getProject(). Of course you need to define the getter and setter yourself, as well as adding a new property to store the project instance inside your TranslationType class.
I have project in controller, but not in that Form. Can i access that project throught $this->getDoctrine()->getRepository()? Or how?

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.