1 pièce(s) jointe(s)
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 !