Bonjour,
Voilà je suis en train de développer un système de messagerie privée avec Symfony et Doctrine, mais la réalisation est assez délicate... pour ne pas dire prise de tête !
Mon problème concerne l'envoi d'un message :
L'utilisateur renseigne les destinataires dans un champ unique (en utilisant jQuery Tokeninput). Ensuite, je récupère les id de chaque membre avec explode et j'insère les données dans 2 tables différentes (une pour le message + l'expéditeur et une autre pour les destinataires du message), pour ce faire j'ai utilisé embedForm.
Le problème est résumé par la capture d'écran que j'ai faite. Il y a une requête en trop dans la transaction à cause du embedForm (ligne 25, la ligne 23 n'est pas nette non plus mais bon passons!)
J'ai fini par pondre un truc qui "fonctionne" mais plus bancal que ça tu meurs !
Voici le schéma :
L'action :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 sfGuardPrivateMessage: options: symfony: filter: false charset: utf8 collate: utf8_general_ci actAs: Timestampable: updated: disabled: true columns: sender_id: { type: integer, notnull: true } subject: { type: string(100), notnull: true } message: { type: clob, notnull: true } is_read: { type: boolean, default: false, notnull: true } is_flagued: { type: boolean, default: false, notnull: true } has_replied: { type: boolean, default: false, notnull: true } is_reported: { type: boolean, default: false, notnull: true } in_archive: { type: boolean, default: false, notnull: true } in_trash: { type: boolean, default: false, notnull: true } relations: sfGuardUser: { local: sender_id, foreign: id, type: one } sfGuardPrivateMessageReceiver: options: symfony: filter: false charset: utf8 collate: utf8_general_ci columns: message_id: { type: integer, notnull: true } receiver_id: { type: integer, notnull: true } relations: sfGuardPrivateMessage: { local: message_id, foreign: id, type: many } sfGuardUser: { local: receiver_id, foreign: id, type: one }
Les formulaires :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 /** * Envoi d'un MP */ public function executeNew(sfWebRequest $request) { $this->form = new sfGuardPrivateMessageForm(null, array('height' => '350px')); if ($request->isMethod('post')) { $this->form->bind($request->getParameter($this->form->getName())); if ($this->form->isValid()) { $this->form->save(); $this->getUser()->setFlash('notice', 'Message Envoyé !', false); } } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 class sfGuardPrivateMessageForm extends PluginsfGuardPrivateMessageForm { public function configure() { unset($this['id']); $this->useFields(array('subject', 'message')); $this->widgetSchema->setNameFormat('pm[%s]'); $this->widgetSchema['message'] = new sfWidgetFormCKEditor( array('jsoptions' => array('toolbar' => 'MemberToolbar', 'enterMode' => 'CKEDITOR.ENTER_BR', 'height' => $this->getOption('height'))) ); $this->embedForm('receiver', new sfGuardPrivateMessageReceiverForm($this->getObject()->getSfGuardPrivateMessageReceiver())); /* * Error messages */ $this->validatorSchema['subject']->setMessages(array( 'required' => 'Le sujet est obligatoire' )); $this->validatorSchema['message']->setMessages(array( 'required' => 'Votre message est vide...' )); /* * Labels for input fields */ $this->widgetSchema->setLabels(array( 'subject' => 'Sujet :', 'message' => 'Message :' )); } public function saveEmbeddedForms($con = null, $forms = null) { if (null === $forms) { $values = $this->getValues(); $ids = explode(";", $values['receiver']['receiver_id']); foreach ($ids as $key => $id) { /* Hack pour ne pas insérer 2 fois le premier id */ if ($key > 0) { $receiver = new sfGuardPrivateMessageReceiver(); $receiver->setMessageId($this->getObject()->getId()); $receiver->setReceiverId($id); $receiver->save(); } } } return parent::saveEmbeddedForms($con, $forms); } }La vue :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 class sfGuardPrivateMessageReceiverForm extends PluginsfGuardPrivateMessageReceiverForm { public function configure() { unset($this['message_id'], $this['id']); $this->widgetSchema['receiver_id'] = new sfWidgetFormInputText(); /* * Error messages */ $this->validatorSchema['receiver_id']->setMessages(array( 'required' => 'Le message n\'a pas de destinataire' )); /* * Labels for input fields */ $this->widgetSchema->setLabels(array( 'receiver_id' => 'Destinataire(s) :', )); } }
L'idéal serait que la table sfGuardPrivateMessageReceiver contienne uniquement message_id et receiver_id en clé primaire et supprimer l'id auto-incrémenté. Enfin déjà si quelqu'un aurait l'extrême gentillesse de m'aider à trouver une solution plus propre que ça, ce serait un grand pas en avant pour moi !
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 <form action="<?php echo url_for('sfGuardPrivateMessage/new') ?>" method="post"> <fieldset> <p> <?php foreach ($form['receiver'] as $reveiver): ?> <?php echo $reveiver->renderLabel() ?> <?php echo $reveiver->render() ?> <?php endforeach; ?> </p> <p class="subject"> <?php echo $form['subject']->renderLabel(); ?> <?php echo $form['subject']->render(); ?> </p> </fieldset> <fieldset> <p> <?php echo $form['message']->render(); ?> </p> </fieldset> <?php echo $form->renderHiddenFields() ?> <p class="center"> <input type="submit" class="submit-button" value="Enregistrer" /> </p> </form>
Partager