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/12/2011, 22h17   #1
Invité de passage
 
Homme
Inscription : septembre 2011
Messages : 15
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : septembre 2011
Messages : 15
Points : 2
Points : 2
Par défaut Problème insertion en bdd avec embedForm

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 :
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
 
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 }
L'action :

Code :
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);
      }
    }
  }
Les formulaires :
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
 
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);
  }
}
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
 
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) :',
    ));
  }
}
La vue :
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
 
        <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>
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 !
Images attachées
Type de fichier : jpg symp.JPG (55,9 Ko, 3 affichages)
mika87 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/12/2011, 19h33   #2
Invité de passage
 
Homme
Inscription : septembre 2011
Messages : 15
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : septembre 2011
Messages : 15
Points : 2
Points : 2
Bon j'ai résolu mon problème en supprimant le embedForm

A la place, j'affiche 2 forms différents sur la même vue et j'ai crée une méthode dans le modèle que je peux appeler depuis n'importe quel contrôleur pour l'envoi des messages privés. Elle prend 4 paramètres pour ceux que ça intéresserait voici le code de cette méthode :

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
 
    public function sendMessage($params = array())
    {    
      $pdo = Doctrine_Manager::getInstance()->getCurrentConnection()->getDbh();
 
      try
      {
        $sql = 'INSERT INTO sf_guard_private_message (sender_id, subject, message, created_at) VALUES (?, ?, ?, NOW())';
 
        $stmt = $pdo->prepare($sql);
 
        $stmt->bindParam(1, $params['sender_id'], PDO::PARAM_INT);
        $stmt->bindParam(2, $params['subject'], PDO::PARAM_STR);
        $stmt->bindParam(3, $params['message'], PDO::PARAM_STR);
 
        $stmt->execute();
 
        /* Get last pm id */
        $pm = $pdo->lastInsertId();
 
        $ids = explode(";", $params['receiver_id']);
 
        foreach ($ids as $id)
        {
          $sql = 'INSERT INTO sf_guard_private_message_receiver (message_id, receiver_id) VALUES (?, ?)';
 
          $stmt = $pdo->prepare($sql);
 
          $stmt->bindParam(1, $pm, PDO::PARAM_INT);
          $stmt->bindParam(2, $id, PDO::PARAM_INT);
 
          $stmt->execute();
        }
      }
      catch (PDOException $e)
      {
        throw new sfDatabaseException(sprintf('PDOException was thrown when trying to send private message. Message: %s', $e->getMessage()));
      }
    }
Et le code de l'action :
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
 
  public function executeNew(sfWebRequest $request)
  {       
    $this->form1 = new sfGuardPrivateMessageForm(null, array('height' => '350px'));
    $this->form2 = new sfGuardPrivateMessageReceiverForm();
 
    if ($request->isMethod('post'))
    {
      $this->form1->bind($request->getParameter($this->form1->getName()));
      $this->form2->bind($request->getParameter($this->form2->getName()));
 
      if ($this->form1->isValid() && $this->form2->isValid())
      {
        $params = array(
          'sender_id'   => $this->getUser()->getUserIdFromSessData(),
          'subject'     => $this->form1->getValue('subject'),
          'message'     => $this->form1->getValue('message'),
          'receiver_id' => $this->form2->getValue('receiver_id')
        );
 
        Doctrine_Core::getTable('sfGuardPrivateMessage')->sendMessage($params);
 
        $this->getUser()->setFlash('notice', 'Message Envoyé !', false);
      }
    }
  }
Problème résolu donc.
mika87 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/12/2011, 18h49   #3
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
C'est un peu le problème pour les applications de gestion de messagerie.

Il n'est pas évident de trouver une structure de donnée qui allie tous les avantages. En fait, c'est plutôt impossible.

Il faut donc bien analyser, au départ, ce que tu veux faire et jusqu'où tu veux aller, après, il sera plu simple de faire la mise en œuvre.


Le embed form présente un problème à la création d'un enregistrement. Mais fonctionne bien à l'édition. Ton problème vient peut-être de là.

Quoique, vu la structure, je ne suis pas sur que tu ais choisi la structure la plus souple.
__________________
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
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 18h08.


 
 
 
 
Partenaires

Hébergement Web