Précédent   Forum des professionnels en informatique > PHP > Bibliothèques et frameworks > symfony
symfony Forum d'entraide sur le framework PHP symfony. Avant de poster : cours symfony et FAQ symfony
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 03/04/2011, 16h36   #1
Invité régulier
 
Inscription : septembre 2009
Messages : 8
Détails du profil
Informations forums :
Inscription : septembre 2009
Messages : 8
Points : 6
Points : 6
Par défaut Formulaire imbriqués qui ne fonctionnent pas

Boujour à tous! Je développe une application où je dois remplir des bordereaux de notes pour une classe.
Les différentes classes que je gère sont:
Exam pour la composition, Student pour l'étudiant, Mark pour la note et ClassRoom pour la classe.

Je souhaite faire le réaliser l'édition des notes en une seule fois j'ai pensé faire une combinaison de formulaires de type Mark en un seul formulaire.

J'ai donc redefini le formulaire Mark de base afin d'afficher comme label le nom de l'étudiant comme ceci:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
class MarkForm extends BaseMarkForm
{
  public function configure()
  {
      parent::configure();
      $this->useFields(array('value'));
      $student =$this->getObject()->getStudent();
      $completeName = $student->getCompleteName();
      $this->widgetSchema->setLabels(array(
          'value' => $completeName
      ));
  }
}
et j'ai combiné les MarkForm comme ceci:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 
class ExamMarksCollectionForm extends BaseForm {
    public function configure() {
        $exam = $this->getOption('exam');
        if (!$exam) {
            throw new InvalidArgumentException('You must provide an Exam object');
        }
 
        $class = $exam->getCourse()->getClassRoom();
        $students = $class->getOrderedStudentList(true);
        $subForm = new sfForm();
        foreach($students as $student){
            $mark = new Mark();
            $mark->Student = $student;
            $mark->Exam = $exam;
            $form = new MarkForm($mark);
            $subForm->embedForm($student->getId(), $form);
        }
        $this->embedForm('marks', $subForm);
    }
}
le code de l'action qui traite le formulaire est:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
public function executeCreate(sfWebRequest $request){
      $this->exam = $this->getRoute()->getObject();
 
      $this->form = new ExamMarksCollectionForm(null, array(
          'exam' => $this->exam
      ));
 
      $this->processForm($request, $this->form);
      $this->setTemplate('edit');
  }
 
  protected  function processForm(sfWebRequest $request, sfForm $form){
      $form->bind($request->getParameter($form->getName()),
              $request->getFiles($form->getName()));
      if ($form->isValid()){
          $form->save();
          $this->redirect('mark_index');
      }
  }
le modèle des données est :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
 
Student:
  inheritance:
    extends: sfGuardUser
    type: concrete
  columns:
    matricule: { type: string(50), notnull: false, unique: true }
    class_room_id: { type: integer, notnull: false}
  relations:
    ClassRoom: {onDelete: CASCADE, local: class_room_id, foreign: id, foreignAlias: Students}
 
ClassRoom:
  actAs:
    Sluggable:
      fields: [ code ] 
      unique: true
      canUpdate: true
  columns:
    code: { type: string(10), notnull: true, unique: true }
    label: { type: string(255), notnull: true, unique: true }
  relations:
    Disciplines: { foreignAlias: ClassRooms, class: Discipline, refClass: Course }
 
Professor:
  columns:
    name: { type: string(255), notnull: true }
    surname: { type: string(255), notnull: true }
 
Discipline:
  columns:
    label: { type: string(255), notnull: true, unique: true }
 
Course:
  columns:
    id: { type: integer, primary: true, autoincrement: true }
    discipline_id: { type: integer }
    class_room_id: { type: integer }
    professor_id: { type: integer, notnull: true }
  relations:
    Professor: { onDelete: CASCADE, local: professor_id, foreign: id, foreignAlias: Courses }
    ClassRoom: { foreignAlias:  Courses }
    Discipline: { foreignAlias: Courses }
 
Program:
  columns:
    start: { type: timestamp, notnull: true }
    end:  { type: timestamp, notnull: true }
    course_id: { type: integer, notnull: true }
  relations:
    Course: { onDelete: CASCADE, local: course_id, foreign: id, foreignAlias: Programs }
 
CourseProgram:
  inheritance:
    extends: Program
    type: concrete
  columns:
    place: { type: string(20), notnull: true }
 
Exam:
  inheritance:
    extends: Program
    type: concrete
  relations:
    Students: { foreignAlias: Exams, class: Student, refClass: Mark  }
 
Mark:
  columns:
    student_id: { type: integer, primary: true }
    exam_id: { type: integer, primary: true }
    value: { type: float, notnull: false }
  relations:
    Student: { foreignAlias: Marks }
    Exam: { foreignAlias: Marks }
Malheureusement le formulaire est retourné et les champs sont marqués comme requis.
Le problème est peut-être au niveau de $form->bind mais j'ai essayé toutes les combinaison possibles sans résultat. I need help!
chakalking est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/04/2011, 10h59   #2
Modérateur
 
Avatar de Michel Rotta
 
Homme Michel Rotta
Responsable d'exploitation informatique
Inscription : septembre 2005
Messages : 4 913
Détails du profil
Informations personnelles :
Nom : Homme Michel Rotta
Âge : 49
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Responsable d'exploitation informatique
Secteur : Distribution

Informations forums :
Inscription : septembre 2005
Messages : 4 913
Points : 7 505
Points : 7 505
Avant de rentrer dans le détail du formulaire, je pense qu'il faut stabiliser le schéma.

Il y a un lien qui est mal défini dans la table ClassRoom vers Dicsiplines, il fait référence à une refClass, ce qui s'utilise pour shunter des tables de liaison n-n dans une relation n-n, mais ici, le liens fait référence à une entité Course qui n'est pas une entité de liaison n-n. Donc le lien ne peut être compris par doctrine, ce qui ne peut que rendre plus difficile toute utilisation du schéma.
__________________
Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).
  • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
  • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
  • Une discussion est terminée ? Alors le bouton est votre ami !
Michel Rotta est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/04/2011, 21h44   #3
Invité régulier
 
Inscription : septembre 2009
Messages : 8
Détails du profil
Informations forums :
Inscription : septembre 2009
Messages : 8
Points : 6
Points : 6
Par défaut Raison du choix de modélisation et solution à mon problème

Citation:
Envoyé par Michel Rotta Voir le message
Avant de rentrer dans le détail du formulaire, je pense qu'il faut stabiliser le schéma.

Il y a un lien qui est mal défini dans la table ClassRoom vers Dicsiplines, il fait référence à une refClass, ce qui s'utilise pour shunter des tables de liaison n-n dans une relation n-n, mais ici, le liens fait référence à une entité Course qui n'est pas une entité de liaison n-n. Donc le lien ne peut être compris par doctrine, ce qui ne peut que rendre plus difficile toute utilisation du schéma.
La raison pour laquelle j'ai fait une relation n-n entre ClassRoom et Discipline (à prendre comme Matière) est qu'une même matière peut être enseignée dans plusieurs salles. Il me fallait donc une classe pour recueillir la relation et j'ai pas trouvé mieux comme nom que Course (j'avoue que ça peut prêter à confusion de penser ). Je me suis donc dis qu'un cours est une matière enseignée dans une classe par un professeur donné (raison du lien 1-n avec Professor).

Pour en revenir à mon problème la solution que j'ai trouvé pour résoudre mon problème est:
1- Modifier la classe Exam pour qu'elle créé pour chaque nouvel exam les objets de type Mark qui correspondent:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
class Exam extends BaseExam
{
    public function save(Doctrine_Connection $conn = null) {
        parent::save($conn);
        if ($this->isNew()){
            $class = $this->getCourse()->getClassRoom();
            $students =  $class->getOrderedStudentList(true);
            foreach ($students as $student){
                $mark = new Mark();
                $mark->setExamId($this->getId());
                $mark->setStudentId($student->getId());
                $mark->save();
            }
        }
 
    }
}
2- Redéfinir le formulaire de type MarkForm

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
class MarkForm extends BaseMarkForm
{
  public function configure()
  {
      parent::configure();
      $this->useFields(array('value'));
      $student =$this->getObject()->getStudent();
      $completeName = $student->getCompleteName();
      $this->widgetSchema->setLabels(array(
          'value' => $completeName
      ));
      $this->validatorSchema['value'] = new sfValidatorNumber(array(
          'required' => false,
          'min' => 0,
          'max' => 20
      ), array(
          'max' => 'Ce champ devrait être inférieur ou égal à 20',
          'min' => 'Ce champ doit être supérieur ou égal à 0',
          'invalid' => 'Valeur invalide'
      ));
  }
}
3- Ensuite créer un formulaire qui étend le formulaire ExamForm et le lier à tous les objets de type Mark qui correspondent grâce à sfFormDoctrinet::embedRelation().
Code :
1
2
3
4
5
6
7
8
9
 
class ExamMarksForm extends ExamForm{
 
    public function configure(){
        parent::configure();
        $this->useFields(array());
        $this->embedRelation('Marks');
    }
}
Et ça marche!!! Si il y d'autres idées d'implémentation je suis quand même preneur car c'est quand même (je trouves) contourner le problème.
Merci.
chakalking est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 01h39.


 
 
 
 
Partenaires

Hébergement Web