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/05/2011, 09h50   #1
Membre régulier
 
Homme
Développeur Web
Inscription : septembre 2008
Messages : 253
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 26
Localisation : Corée

Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : septembre 2008
Messages : 253
Points : 90
Points : 90
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.
Fused est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/05/2011, 09h40   #2
Membre régulier
 
Homme
Développeur Web
Inscription : septembre 2008
Messages : 253
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 26
Localisation : Corée

Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : septembre 2008
Messages : 253
Points : 90
Points : 90
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 :
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 :
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 :
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.
Citation:
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 !
Fused est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/05/2011, 12h06   #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
Tu veux faire quoi dans ton pre et/ou post update ?
__________________
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 04/05/2011, 19h52   #4
Membre régulier
 
Homme
Développeur Web
Inscription : septembre 2008
Messages : 253
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 26
Localisation : Corée

Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : septembre 2008
Messages : 253
Points : 90
Points : 90
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.
Fused est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/05/2011, 10h11   #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
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.
__________________
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 05/05/2011, 11h23   #6
Membre régulier
 
Homme
Développeur Web
Inscription : septembre 2008
Messages : 253
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 26
Localisation : Corée

Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : septembre 2008
Messages : 253
Points : 90
Points : 90
Exactement Michel,

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

Citation:
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.
Fused est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/05/2011, 11h57   #7
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
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.
__________________
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 06/05/2011, 03h32   #8
Membre régulier
 
Homme
Développeur Web
Inscription : septembre 2008
Messages : 253
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 26
Localisation : Corée

Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : septembre 2008
Messages : 253
Points : 90
Points : 90
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.
Fused est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/05/2011, 17h02   #9
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:
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.
__________________
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/05/2011, 11h12   #10
Membre régulier
 
Homme
Développeur Web
Inscription : septembre 2008
Messages : 253
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 26
Localisation : Corée

Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : septembre 2008
Messages : 253
Points : 90
Points : 90
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 :
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.
Fused est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/05/2011, 15h14   #11
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
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 ?
__________________
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 27/05/2011, 04h50   #12
Membre régulier
 
Homme
Développeur Web
Inscription : septembre 2008
Messages : 253
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 26
Localisation : Corée

Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : septembre 2008
Messages : 253
Points : 90
Points : 90
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 !
Fused est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/05/2011, 10h19   #13
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
Cette solution ne me semble pas bizarre et me semble très réaliste.

Bonne chance !
__________________
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 07h30.


 
 
 
 
Partenaires

Hébergement Web