0

So I explain my problem As we can see here, I have two entities (Users and Module) linked by a ManyToMany association with two extra fields (Note and observation). It seems that it’s impossible to do this kind of relation with symphony. To solve this problem I created a third entity (Result) which is linked to others by a ManyToOne relation. And I defined the 2 extras fields as attribute for the third Entity.

Now I have to make a form which save into database the result for a student. I don’t like to save one by one the result for each student, but I want to have (as shown on the picture) one form which contain all users, and with only one submit, I save the result for all users in the form to database.

Here is the code of my entities, controllers and forms:

Entity User.php

class User extends BaseUser {
protected $id;
/**@ORM\OneToMany(targetEntity="App\ScholarityBundle\Entity\Result", mappedBy="markUserIds")     */
protected $markUserIds;
public function __construct() {
    parent::__construct();
    $this->markUserIds = new ArrayCollection();
}
public function getMarkUserIds()    {
    return $this->markUserIds;
}

Entity Module.php

class Module{
/**
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $id;
/**
 * @ORM\OneToMany(targetEntity="App\ScholarityBundle\Entity\Result", mappedBy="markClassCoursesIds")
 */
protected $markClassCoursesIds;
public function __construct()    {
    $this->markClassCoursesIds = new ArrayCollection();
}
public function getId()    {
    return $this->id;
}    
public function addMarkClassCoursesId(\App\ScholarityBundle\Entity\Result $markClassCoursesIds)    {
    $this->markClassCoursesIds[] = $markClassCoursesIds;
    return $this;
}
public function getMarkClassCoursesIds()    {
    return $this->markClassCoursesIds;
}

}

Entity Result.php

class Result{
/**
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $id;
/**
 * @ORM\Column(type="integer", length=2)
 */
private $mark;
/**
 * @ORM\Column(type="string", length=100)
 */
private $observation;
/**
 * @ORM\ManyToOne(targetEntity="App\SettingBundle\Entity\Module", inversedBy="markClassCoursesIds")
 * @ORM\JoinColumn(name="class_courses_id", referencedColumnName="id")
 */
private $markClassCoursesId;
/**
 * @ORM\ManyToOne(targetEntity="AppBundle\Entity\User", inversedBy="markUserIds")
 * @ORM\JoinColumn(name="mark_user_Id", referencedColumnName="id")
 */
private $markUserId;

public function getId()    {
    return $this->id;
}
public function setMark($mark)    {
    $this->mark = $mark;
    return $this;
}
public function getMark()    {
    return $this->mark;
}
public function setObservation($observation)    {
    $this->observation = $observation;
    return $this;
}
public function getObservation()    {
    return $this->observation;
}
public function setMarkClassCoursesId(\App\SettingBundle\Entity\Module $markClassCoursesId = null)    {
    $this->markClassCoursesId = $markClassCoursesId;
    return $this;
}
public function getMarkClassCoursesId()    {
    return $this->markClassCoursesId;
}
public function setMarkUserId(\AppBundle\Entity\User $markUserId = null)    {
    $this->markUserId = $markUserId;
    return $this;
}
public function getMarkUserId()    {
    return $this->markUserId;
}

}

Controller ResultController.php

class ResultController extends Controller{
public function newAction(Request $request)
{
    $result = new Result();
    $em = $this->getDoctrine()->getEntityManager();
    $repository = $em->getRepository('AppBundle:User');
    $users= $repository->findAllStudent();
    $form = $this->createForm(new ResultType(), $result, array('users' => $users));
    if ($request->isMethod('POST')) {
        $form->handleRequest($request);
        if ($form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($result);
            $em->flush();
            return $this->redirect($this->generateUrl('scholarity_coursesmark')); 
        }
    }
    return $this->render('AppScholarityBundle:result:new.html.twig', array(
        'form' => $form->createView(),
    )); 
}

}

Form CustomResultType.php

class CustomResultType extends AbstractType{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('mark');
    $builder->add('observation');
    $builder->add('markUserId');
}

}

Form ResultType.php

class ResultType extends AbstractType{
public function buildForm(FormBuilderInterface $builder, array $options)    {
    foreach ($options['users'] as $user) {
        $builder->add('markUserId' . $user->getId(), CustomResultType::class, [
            'data' => $user,
        ]);
    }
}
public function configureOptions(OptionsResolver $resolver)    {
    $resolver->setDefaults(array(
        'data_class' => 'App\ScholarityBundle\Entity\Result',
        'users' => null,
    ));
}
public function getName()    {
    return 'result';
}

}

1
  • Could you post the code of you entities and relations here ? Commented Jun 30, 2016 at 15:59

1 Answer 1

1

This is actually quite easy using Symfony's Form component. First you need to create a custom type, eg UserModuleType which represents a single user (or in your last picture: one row).

Now you can create another type, let's call it MultipleUserModuleType (can probably be named better). Inside that you can either do something like

foreach ($options['users'] as $user) {
    $builder->add('usermodule' . $user->getId(), UserModuleType::class, [
        'data' => $user,
    ]);
}

Or directly use CollectionType like so (untested)

$builder->add('usermodules', CollectionType::class, [
    'entry_type' => UserModuleType::class,
]);
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your answer, but when I try to apply it, I have this error Neither the property "markUserId3" nor one of the methods "getMarkUserId3()", "markUserId3()", "isMarkUserId3()", "hasMarkUserId3()", "__get()" exist and have public access in class “AppBundle\Entity\Result”. You can see my entities, controllers and forms class above.
@kabisko I can only properly answer you on Monday, sorry. You can set mapped to false on markUserId3
Now this is my ResultType.php content: foreach ($options['users'] as $user) { $builder->add('markUserId' . $user->getId(), CustomResultType::class, [ 'label' => $user->getUsername(), 'data' => $user, 'mapped' => false, 'attr' => array('class' => 'markUserId'), ]); }
In my CustomResultType I have this one: public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('mark', 'text' , ['required' => false, 'mapped' => false]); $builder->add('observation', 'text' , ['required' => false, 'mapped' => false]); } But when I submit my request, I can only access to the user value and not the mark and observation value

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.