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 :

PostUpdate et PreUpdate sur objet i18n [1.x]


Sujet :

Symfony PHP

  1. #1
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2008
    Messages
    253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Corée

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Septembre 2008
    Messages : 253
    Par défaut PostUpdate et PreUpdate sur objet i18n
    Hello,

    J'ai remarqué que sur un objet i18n, les méthodes preUpdate(), postUpdate() ne se déclenchent que si on a modifié au moins un champs non internationalisé.

    Y a t-il une fonction embarquée pour gérer cette incohérence ?

    Sémantiquement, l'objet est modifié donc ces méthodes devraient être déclenchées.

  2. #2
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2008
    Messages
    253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Corée

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Septembre 2008
    Messages : 253
    Par défaut
    Après débug et génération d'un nombre incalculable d'erreurs (Rasmus Lerdorf a dur en avoir des frissons dans le dos), en remontant le cours de Doctrine,
    il s'avère que ces méthodes sont en fait bien appelées.

    Mais !

    Pas sur "monObjet" comme je m'y attendais, mais, sur l'objet : monObjetTranslation.

    --------

    Du coup première idée, je créé monObjetTranslation.class et j'y met une méthode potUpdate().

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class monObjetTranslation extends sfDoctrineRecord
    {
    	public function potUpdate($event) {
     
    	}
    }
    Gros plantage, il n'y trouve pas les autres méthodes qui sont cencé y être.
    Logique me direz vous !

    Bref,

    ---------

    Donc je test avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class héritierDeMonObjetTranlation extends monObjetTranslation
    {
    	public function postUpdate($event) {
     
    	}
    }
    Rien, classe non appelée. Forcément me direz vous encore une fois !

    ---------

    Dernière piste ; revenir sur la solution numéro 1 et imiter la structure des objets de symfony.

    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
    class MonObjetTranslation extends sfDoctrineRecord
    {
    	public function postUpdate($event) {
     
    	}
     
        public function setTableDefinition()
        {
            $this->setTableName('mon_objet_translation');
            $this->hasColumn('id', 'integer', null, array(
                 'type' => 'integer',
                 'primary' => true,
                 'autoincrement' => true,
                 ));
     
                 // Puis ajout de tous les champs nécessaires
                // ..............
     
                 // Cette colonne est la seule différence que j'imagine
            $this->hasColumn('lang', 'string', 2, array(
                 'type' => 'string',
                 'length' => 2,
                 ));
     
            $this->option('collate', 'utf8_unicode_ci');
            $this->option('charset', 'utf8');
        }
     
       public function setUp()
        {
            parent::setUp();
        }
    }
    Mais bon, aucun résultat satisfaisant, colonnes inconnues.
    500 | Internal Server Error | Doctrine_Connection_Mysql_Exception


    Bref, au final, la solution est un puzzle :

    Ajouter la fonction postUpdate() dans monObjetTranslation ; objet qui n'existe pas en tant que fichier, mais créé par doctrine.

    Help me !

  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
    Tu veux faire quoi dans ton pre et/ou post update ?

  4. #4
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2008
    Messages
    253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Corée

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Septembre 2008
    Messages : 253
    Par défaut
    Générer immédiatement des changements sur d'autres objets si n'importe quelle donnée de l'objet ou de l'objet traduit à été modifiée.

    En fait c'est pour des PDF accessibles en ligne en plusieurs langues.

    Il faut qu'il soient toujours à jour sachant que les changements sont imprévisibles (jamais ou souvent), je veux que cela soit transparent pour la personne qui édite les données.

    D'ou le post update : si modifié -> générer nouveau PDF.

  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
    Et la difficulté à générer depuis le post vu que les tables translation et leur tables d'origine ne sont pas intimement liées.

    Je pré-suppose que tu utilises du code dans une autre procédure pour générer ton PDF. L'idée pourrait être de générer le fichier PDF si l'une ou l'autre (ou les deux) tables sont modifiées. Ce qui implique que dans certains cas, tu peux te retrouver avec deux générations... Voir plus si le PDF englobe 6 tables traduites, et qu'elles sont toutes modifiées.

    Je vois donc deux autres solutions, une génération différée, traitée par batch. La méthode post permettant alors l'inscription dans une table des "a générer" avec une vérification de l’existence d'un enregistrement de demande de génération pour ce document. L’inconvénient étant qu'il est possible (probable suivant Murphy) que l'utilisateur soit mis en présence d'un PDF avec des données dépassées (de quelques minutes, serte, mais dépassées).

    Une autre solution serait simplement que le code dans le post supprime le fichier PDF sans le régénérer. La génération étant alors dédiée à la lecture. On aurait alors non pas un stock de fichiers généré mais une génération "à la demande" avec une mise en cache du PDF généré. Lors de la demande de lecture, ton code vérifie l’existence, si oui, il envoie, si non, il génère et envoie. Lors de la moindre modification, le cache pour ce PDF est supprimé. Le lecteur est alors sur de toujours avoir une version récente. Tu as un accès rapide, sauf à la première demande. Ce système peut être masqué entièrement, en effet, symfony peut parfaitement router des url pour des fichier d'extention pdf et donner l'impression qu'ils existent alors qu'il sont stockés dans une base de données...

    La deuxième solution aurait plutôt ma préférence. D'autant que rien n'empêche que, régulièrement, le cache soit purger pour s'assurer d'une mise à jour des PDF généré (en cas de changement d'un template par exemple). Ce qui permet facilement de modifier tous les PDF sans risquer de passer plusieurs minutes à tous les régénérer d'un coup, au risque de rendre indisponible le service plus que nécessaire.

  6. #6
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2008
    Messages
    253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Corée

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Septembre 2008
    Messages : 253
    Par défaut
    Exactement Michel,

    C'est cette deuxième solution que je cherche à mettre en place.

    Lors de la moindre modification, le cache pour ce PDF est supprimé.
    C'est là tout mon problème.

    Si on modifie uniquement un champ internationalisé, impossible d'avoir un déclencheur qui supprime le PDF existant, puisque postUpdate n'est pas déclenché.

    On revient au problème de base.

    Sinon, il faut surcharger l'internationalisation en tant que "timestampable", puis ajouter une date de génération aux données du PDF, donc aussi le stocker.

    Ça m’embête un peu si j'en arrive là, c'est un site et des données déjà en ligne, je préférerais rester dans le contrôleur uniquement pour gérer tout ça.

  7. #7
    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
    L'idéal serait d'être dans le modèle plutôt que dans le contrôleur.

    Et utiliser postSave() du modèle pourrait être une solution.

    Ensuite, je ne sais pas comment tu comptes nommer tes fichiers mais tu as l'id de base dans la table traduite, donc, au pire et au prix d'une requête, tu as le nom du fichier.

    Il conviendrait donc de générer sur ta classe matableTable.class.php une méthode statique du style supprimeCachePourId() qui prendrait l'Id en paramètre. Et supprime le cache correspondant.

    Il faudra alors mettre cette appel dans la table Et dans la translationtable.

  8. #8
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2008
    Messages
    253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Corée

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Septembre 2008
    Messages : 253
    Par défaut
    C'est bien ça.

    Le soucis est toujours le même.

    Je ne peux pas réécrire monObjetTranslation.class pour y ajouter un appel à une quelconque fonction, car il est créé par Doctrine automatiquement.

  9. #9
    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
    Je ne peux pas réécrire monObjetTranslation.class pour y ajouter un appel à une quelconque fonction, car il est créé par Doctrine automatiquement.
    Heu, comme tout objet du modèle, il y a deux objets créé, celui de base, écrit dans le dossier lib/modele/doctrine/base, qui est réécrit et l'autre dans le dossier doctrine qui n'est écrit que s'il n'existe pas. C'est lui qu'il faut modifier.

  10. #10
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2008
    Messages
    253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Corée

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Septembre 2008
    Messages : 253
    Par défaut
    C'est peut-être là qu'on ne se comprend pas.

    Mon objet s'appelle "Document" en l'occurence.

    On peut le résumer à ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Document:
      actAs:
        Timestampable: ~
        I18n:
          fields: [title, article]
      columns:
        id:             { type: integer, ... }
        title:          { type: string(255) }
        article:    { type: clob}
    Sont générés:
    lib/model/doctrine/Document.class.php
    lib/model/doctrine/base/BaseDocument.class.php

    Mais DocumentTranslation.class.php n'est pas généré.

    En le créant à la main, il y a une erreur (fonctions manquantes).
    Car, doctrine le génère virtuellement dans son code.

    Donc impossible de le réécrire et d'y ajouter mes méthodes.

  11. #11
    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
    Je comprend vite, à condition que l'on me parle longuement !

    Juste comme cela, un objet du modèle ayant été modifié returne isModified() a true.

    Il est possible de forcer le isModified à parcourir toute l’arborescence des objets liés par isModified(true) .

    Est-ce que dans ton cas tu ne pourrais pas utiliser ceci, avant la sauvegarde, pour effacer le cache ?

  12. #12
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2008
    Messages
    253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Corée

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Septembre 2008
    Messages : 253
    Par défaut
    C'est une piste qui n'a rien donné non plus.

    Finalement, j'ai réécris processForm dans l'action. N'importe quelle modification appel cette fonction.

    Dedans je supprime le fichier existant.
    Il est recréé lorsque l'on rappelle pour la première fois le PDF.

    Je cherche toujours à faire des trucs bizarres !

  13. #13
    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
    Cette solution ne me semble pas bizarre et me semble très réaliste.

    Bonne chance !

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

Discussions similaires

  1. Order By sur objet i18n
    Par Fused dans le forum ORM
    Réponses: 3
    Dernier message: 13/01/2011, 11h27
  2. [1.x] Problème sur backend, éditer un objet i18n
    Par Fused dans le forum Symfony
    Réponses: 1
    Dernier message: 10/08/2010, 07h20
  3. [C#] [VS.NET] Peut on faire un accesseur sur objets?
    Par Designotik dans le forum Windows Forms
    Réponses: 3
    Dernier message: 06/01/2005, 21h56
  4. Evenement sur objet dynamique
    Par CanardJM dans le forum AWT/Swing
    Réponses: 8
    Dernier message: 19/11/2004, 13h56
  5. [Debutant VC++.net] Obtenir un pointeur sur objet
    Par SteelBox dans le forum MFC
    Réponses: 6
    Dernier message: 17/06/2004, 18h36

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