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 10/03/2011, 19h36   #1
Invité de passage
 
Inscription : août 2009
Messages : 20
Détails du profil
Informations forums :
Inscription : août 2009
Messages : 20
Points : 2
Points : 2
Par défaut Admin-generator et champs notnull

Bonjour,

Je réalise une petite plateforme où des utilisateurs se connectent via login/mot de passe et gèrent un petit carnet de contacts. Comme j'utilise le plugin sfDoctrineGuard je pars sur un modèle ultra-simple pour mieux illustrer mon problème :
Code :
1
2
3
4
5
6
7
8
9
10
11
 
Contact:
  actAs: { Timestampable: ~ }
  columns:
    client_id:  { type: integer, notnull: true }
    nom:         { type: string(255), notnull: true }
    prenom:      { type: string(255), notnull: true }
    mail:         { type: string(255), notnull: true }
    tel:          { type: string(255), notnull: true }
  relations:
    SfGuardUser: { onDelete: CASCADE, local: client_id, foreign: id, foreignAlias: SfGuardUser }
C'est tout ! Une seule table donc, avec une clé étrangère correspondant à l'id de l'utilisateur identifié via le plugin sfGuardUser.

Pour simplifier la création du carnet d'adresse je créé un module "contact" avec l'admin-generator. Afin que chaque utilisateur n'ait accès qu'à ses contacts, je surcharge la fonction buildQuery de l'action.class générée par l'admin-generator :
Code :
1
2
3
4
5
6
7
8
9
10
 
class contactActions extends autoContactActions
{
    protected function buildQuery()
    {
      $query = parent::buildQuery();
      $query->addWhere('client_id = ?', array($this->getUser()->getGuardUser()->getId()));
      return $query;
    }
}
Ainsi chaque utilisateur ne voit que son carnet d'adresse depuis le module contact. J'ai également fait en sorte que les référence à client_id (l'id de sf_guard_user) disparaissent des listes et des formulaires. D'ou le generator.yml :
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
 
generator:
  class: sfDoctrineGenerator
  param:
    model_class:           Contact
    theme:                 admin
    non_verbose_templates: true
    with_show:             false
    singular:              ~
    plural:                ~
    route_prefix:          contact
    with_doctrine_route:   true
    actions_base_class:    sfActions
 
    config:
      actions: ~
      fields:  ~
      list:        
        title: Contacts
        display: [=nom, prenom, mail, tel, created_at, updated_at]
      filter:
        display: [nom, prenom, mail, tel]
      form:
        display: [nom, prenom, mail, tel]
      edit:    ~
      new:     ~
Les champs created_at et updated_at étant notnull, j'ai pu faire un unset dessus sans que ca pose problème. Par contre si je fais un unset sur client_id je me retrouve avec un client_id en clé étrangère qui est égale à zéro. Je suis donc resté la dessus sur mon contactForm :
Code :
1
2
3
4
5
6
7
8
 
class ContactForm extends BaseContactForm
{
  public function configure()
  {
    unset($this['created_at'], $this['updated_at']);
  }
}
Le problème c'est que quand je créé un nouvel utilisateur, j'ai toujours une erreur parce que je n'ai pas renseigné la clé étrangère. Et je ne sais pas comment faire pour qu'elle soit réglée automatiquement :
Code :
1
2
3
4
5
6
7
8
9
10
11
 
# $form (ContactForm) Toggle details
 
    * $form['id'] (sfWidgetFormInputHidden)
    * $form['client_id'] (sfWidgetFormDoctrineChoice)
      Required.
    * $form['nom'] (sfWidgetFormInputText)
    * $form['prenom'] (sfWidgetFormInputText)
    * $form['mail'] (sfWidgetFormInputText)
    * $form['tel'] (sfWidgetFormInputText)
    * $form['_csrf_token'] (sfWidgetFormInputHidden)
(ci-dessus le message d'erreur avec 'required' associé à client_id)

Donc je ne sais pas trop quoi faire et j'appelle à l'aide. Quelqu'un sait-il comment je pourrais me dépêtrer ?
mika34 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/03/2011, 10h03   #2
Futur Membre du Club
 
Inscription : août 2009
Messages : 24
Détails du profil
Informations forums :
Inscription : août 2009
Messages : 24
Points : 18
Points : 18
Le fait de retirer le champ 'XXX_id' (clé étrangère) de la page de ton formulaire en ne le mettant pas dans le generator.yml ne va pas appliquer en réel qu'il n'est pas pris en compte par Symfony.

Pour laisser à la petite bête le soin de gérer des relations automatiques, il faut que tu unset ton champ XXX_id dans le formulaire, de la même manière que tu unset ton created_at.

EDIT: Au temps pour moi, je n'avais pas vu que tu avais un problème au niveau du unset, donc CF la réponse ci dessous qui devrait t'aider dans ta quête
ufretin est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/03/2011, 10h53   #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
Ton shema.yml revu et corrigé :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
Contact:
  actAs: { Timestampable: ~ }
  columns:
    client_id:  { type: integer, notnull: true }
    nom:         { type: string(255), notnull: true }
    prenom:      { type: string(255), notnull: true }
    mail:         { type: string(255), notnull: true }
    tel:          { type: string(255), notnull: true }
  relations:
    client: 
      class: sfGuardUser
      onDelete: CASCADE
      local: client_id
      foreign: id
      foreignAlias: Contacts
Quant tu utilises (en général) un CRUD basé sur un sfDoctrineForm, tu vas utilise ce cycle (en pseudo code)
Code :
1
2
3
4
5
6
7
 
$contact = nouveau contact vierge
$form = nouveau formContact joint a $contact
si retour en POST
   Lier $form aux données retournées ($request...)
   si $form est valide alors on sauve
fin si
Dans ton cas, on va juste modifier le début
Code :
1
2
3
4
5
 
$contact = nouveau contact vierge
$contact.setClientId = le Id du client connecté
$form = nouveau formContact joint a $contact
...
A adapte sur le contrôleur mais cela manifestement tu connais...
__________________
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 11/03/2011, 18h52   #4
Invité de passage
 
Inscription : août 2009
Messages : 20
Détails du profil
Informations forums :
Inscription : août 2009
Messages : 20
Points : 2
Points : 2
Bonjour,

Merci pour vos réponses à tous deux. Michel Rotta a raison : le form récupère un objet Contact, ainsi dans /cache/frontend/dev/modules/autoContact/actions/actions.class.php :
Code :
1
2
3
4
5
6
7
8
9
10
 
  public function executeCreate(sfWebRequest $request)
  {
    $this->form = $this->configuration->getForm();
    $this->contact = $this->form->getObject();
 
    $this->processForm($request, $this->form);
 
    $this->setTemplate('new');
  }
C'est à dire que $this->contact est créé d'après la configuration du formulaire. Il suffit donc de faire que l'attribut client_id de contact ait la valeur de l'id de l'user connecté à la plateforme et de lier le formulaire à cet objet Contact modifié avant de le traitement du formulaire. D'où la surcharge de la méthode dans /apps/frontend/modules/contact/actions/actions.class.php :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
 
    public function executeCreate(sfWebRequest $request)
    {
      $this->form = $this->configuration->getForm();
      $this->contact = $this->form->getObject();
      $this->contact->setClientId($this->getUser()->getGuardUser()->getId());
      $this->form = $this->configuration->getForm($this->contact);
 
      $this->processForm($request, $this->form);
 
      $this->setTemplate('new');
    }
En amont j'effectue un unset sur le champs client_id, ainsi que sur la clé primaire car je n'aime pas l'idée qu'elle puisse transiter chez le client même dans un champs hidden :
Code :
1
2
3
4
5
6
7
8
 
class ContactForm extends BaseContactForm
{
  public function configure()
  {
    unset($this['id'], $this['client_id'], $this['created_at'], $this['updated_at']);
  }
}
C'est suffisant ! Donc je peux créer un contact et me servir de l'admin-generator car les champs notnull sont définis dans le contrôleur. J'imagine que le principe de l'update est le même et j'ai la flemme de le détailler (je rentre du boulot).

Donc je remercie encore une fois Michel Rotta pour m'avoir donné la clé de l'enigme. Problème résolu !
mika34 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/03/2011, 09h48   #5
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
Citation:
Envoyé par mika34 Voir le message
... Michel Rotta a raison...
Je vais en faire un règlement pour cette salle, tu viens d'écrire l'article 1, l'article 2 sera : S'il se trompe, veuillez consulter l'article

[Mode sérieux ON]

Citation:
Envoyé par mika34 Voir le message
En amont j'effectue un unset sur le champs client_id, ainsi que sur la clé primaire car je n'aime pas l'idée qu'elle puisse transiter chez le client même dans un champs hidden...
Excellente chose. C'est ce qu'il est, a mon avis aussi, indispensable de faire.

Bonne chance pour la suite.
__________________
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 18h45.


 
 
 
 
Partenaires

Hébergement Web