IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Symfony PHP Discussion :

Admin-generator et champs notnull [1.x]


Sujet :

Symfony PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Août 2009
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 21
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : 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
     
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 ?

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Août 2009
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 25
    Par défaut
    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

  3. #3
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    Ton shema.yml revu et corrigé :
    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
     
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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...

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Août 2009
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 21
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 !

  5. #5
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    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.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [1.x] icone dans les th des champs de ma liste via l'admin generator?
    Par symfony30000 dans le forum Symfony
    Réponses: 4
    Dernier message: 10/06/2010, 15h57
  2. [1.x] Admin generator et relations champs id
    Par kreatik dans le forum Symfony
    Réponses: 4
    Dernier message: 27/02/2010, 00h33
  3. [1.x] Champ de téléchargement dans l'admin generator
    Par qlimamax dans le forum Symfony
    Réponses: 5
    Dernier message: 17/04/2009, 11h34
  4. Réponses: 1
    Dernier message: 18/08/2008, 17h12
  5. [1.x] Champs i18n disabled par l'admin generator
    Par wadzat dans le forum Symfony
    Réponses: 1
    Dernier message: 22/05/2008, 14h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo