Partage

[Symfony2] Questions fréquemment posées

Merci de ne pas y poster vos questions.

Le 3 juin 2012 à 12:10:37

Salut à tous,

En parcourant vos sujets sur ce forum, je me rends compte que pas mal de questions reviennent souvent. Ce sont des questions qui sont un peu déconnectées du flux du tutoriel, je pensais donc les rassembler toutes dans un chapitre FAQ.

Je vous propose de lister dans ce sujet les questions que vous souhaiteriez voir dans ce futur chapitre. Poser donc vos questions, mais attention on parle d'une FAQ, soit des questions fréquentes, alors essayez de poser des questions assez génériques. Sinon, ouvrez un nouveau sujet ;) Et d'ailleurs si vous avez la réponse à votre propre question, n'hésitez pas :p L'idée est de construire ensemble une FAQ très complète sur Symfony2.

Voici la liste des questions que contient déjà cette FAQ :

  1. Comment rafraîchir les rôles du membre courant sans devoir se déconnecter/reconnecter ?

  2. Pourquoi la création d'une erreur 404 me créé une erreur 500 ?

  3. Pourquoi mon routing.yml principal ne se charge pas correctement ?

  4. A la validation de mon formulaire j'ai l'erreur ci-dessous, pourquoi ?
    Le jeton CSRF est invalide. Veuillez renvoyer le formulaire


  5. J'ai une erreur "the annotation X was never imported". Ça veut dire quoi?

  6. Comment je me mets à jour symfony et les autres vendors?

  7. À quoi sert le fichier deps.lock?

  8. J'en ai marre faire un assets:install à chaque fois que je modifie un fichier css ou js

  9. J'ai une erreur en console, pas assez précise

  10. Comment faire de l'AJAX avec Symfony2 ?

  11. mon projet symfony 2 m'affiche une page blanche, que faire?

  12. Pourquoi quand je fais : $objet->setEntiteliee(null) cela déclanche l'erreur : Catchable Fatal Error: Argument 1 passed to Mon\Bundle\Entity\UneEntite::setEntiteeliee() must be an instance of Mon\Bundle\Entity\EntiteLiee, null given ...

  13. Pourquoi l'erreur : Unexpected token "name" of value "AND" ("end of statement block" expected) in xBundle:x:x.html.twig at line x dans un template TWIG ?

  14. Un problème lié au dossier dev_old lors du vidage du cache ?

  15. Pourquoi dans un template Twig, mon {% render ... %} ne m'affiche pas le résultat de ma méthode ?

  16. La méthode persist() ne se comporte pas comme elle devrait quand je veux faire une édition. Elle ne modifie pas l'entrée que je viens d’éditer, mais en créé une autre.

  17. Pourquoi cette erreur survient lors d'une suppression ?
  18. Mon application fait plusieurs 100ène de mo, comment régler ça ?

  19. Je veux uploader un avatar et le redimensionner ?

  20. Pourquoi l'erreur : "SQLSTATE[HY000]: General error: 1553 Cannot drop index 'UNIQ_xxx' : needed in a foreign key constraint" lors d'un "doctrine:schema:update --force" ?

  21. J'ai traduit mon interface. Depuis que j'ai créé mes fichiers messages.(fr|en|…).(xliff|xlf|xml|yaml|php), je n'ai plus que la version anglaise qui s'affiche, ou des chaînes incompréhensibles et moches

  22. J'ai personnalisé les templates d'un bundle (FOSUserBundle, pour l'exemple). Mais depuis, je n'ai plus que la version anglaise qui s'affiche, ou des chaînes incompréhensibles et moches

  23. J'ai traduit mes entités avec StofDoctrineExtensionsBundle et/ou Doctrine Extensions, mais je n'ai que le contenu en anglais qui s'affiche !

  24. J'arrive à traduire beaucoup de choses, mais pas le contenu des balises

  25. J'aitout bien suivi le tutoriel sur la traduction, mais rien n'est tradit dans les vues où j'ai des {{ render() }}

  26. J'ai une erreur quand je soumets un formulaire ! A l'aide !

  27. Quand je persiste une entité qui embarque d'autres entités, celles qui sont embarquées ne sont pas persistées, malgré cascade={"persist"}. Pourquoi ?

  28. Je n'arrive pas à envoyer un mail depuis mon site hebergé chez OVH. Quand j'essaie, je tombe sur l'erreur:
  29. Sous Chrome/Firefox/Safari/Opera/Internet Explorer 10+, je ne peux pas soumettre mes formulaires, et je reçois un message comme quoi un de mes champs ne peut être vide, alors que j'ai spécifié qu'il pouvait l'être dans mes mappings !
    Et ça ne me fait pas ça avec IE 9 ni IE 8


  30. Quand j'essaie d'utiliser php bin/vendors quelquechose, j'ai un message qui me dit que git n'est pas reconnu, ou introuvable.

  31. J'aimerais inclure une librairie externe dans Symfony 2. Je fais comment ?

  32. Je n'arrive pas à faire fonctionner mon undle, téléchargé depuis githubm alors que j'ai suivi scru-pulueulse-ment les instructions pour le paramétrer, mais il y a encore une erreur !

  33. Comment afficher un bloc nécessitant un traitement complexe sur toutes les pages, sans avoir à hériter un contrôleur de base dans tous les contrôleurs?

  34. Pourquoi ais-je une erreur de duplication de clés lors de l'ajout d'une entrée dans ma base ?

  35. Je n'arrive pas à utiliser les méthodes de mon repository ! J'ai une erreur
  36. Au secours ! Je n'arrive pas à utiliser les messages Flash avec mon application !

  37. Avec une de mes méthodes pour récupérer tous les objets liés à un autre, j'ai une erreur qui ressemble à
  38. Comment ajouter un namespace dans l'autoload sous Symfony 2.1 ?

  39. J'ai un message
  40. J'ai toujours l'erreur date.timezone alors que j'ai modifié mon php.ini ! (solution SOUS MAC)

  41. Je viens d'installer mon application Symfony2 sous mac: PDO CONNECTION ERROR, mes paramètres de connexion sont bons, que faire ?

  42. J'ai étendu le bundle FOSUserBundle et je n'arrive pas à écraser les templates (=overriding), que faire ?

  43. Quand j'utilise doctrine:schema:update --force, il m'est dit que tout est bon, mais les tables pour certaines entités ne sont jamais créés/mises à jour !

  44. Quand j'utilise doctrine:generate:entities, les getters et setters ne sont pas créés dans certaines de mes entités !

  45. J'ai une erreur quand je tente d'uploader un fichier ! En substanceou
  46. J'ai suivi à la lettre le tutoriel, mais je n'arrive pas à faire fonctionner le code, que j'ai pourtant copié-collé !

  47. J'ai des formulaires embarqués pour une collection, mais Symfony/Doctrine ne me persiste que le dernier objet que j'y ai mis !

  48. J'ai des formulaires embarqués, mais à chaque fois que je soumets le formulaire princpal, j'ai une erreur de ce genre
  49. Quand j'essaie de récupérer mon repository dans mon contrôleur, j'ai une erreur
  50. Je veux ajouter une contrainte d'unicité d'un champ d'une entité avec l'annotation @UniqueEntity, mais elle n'est pas prise en compte.

  51. Comment récupérer l'id d'un article que je viens tout juste de créer ?

  52. J'ai une boucle for et j'aimerais pouvoir exécuter du code toute les x boucles, comment faire ?

  53. A la validation de mon formulaire j'ai l'erreur ci-dessous, pourquoi ?
  54. J'ai plusieurs catégories, j'aimerais afficher dans ma vue le nombre d'articles que contiennent chacune d'elles, comment faire ?

  55. J'ai cette erreur, comment faire ?
  56. J'ai une erreurMais je n'ai pas de route, j'utilise {% render %} ! Qu'est-ce qui ne va pas ?

  57. Comment puis-je générer un lien avec une ancre (la partie après le #) dans Twig, pour avoir quelque chose comme mon/url#monAncre ? N'y a-t-il pas moyen de le faire avec {{ path() }} ?

  58. J'ai des pages statiques dans mon application, mais je n'aimerais pas avoir à changer partout où j'ai des liens qui mènent vers ces pages quand je change leur URL ! Y a-t-il une solution ?

  59. J'ai supprimé un fichier lié à une annotation ainsi que l'annotation mais l'application en prod me dit qu'elle ne peut plus avoir accès au fichier (par exemple un repository) alors que je ne m'en sers plus. Pourtant j'ai vidé le cache et en dev tout fonctionne !

Si vous voulez contribuer à cette FAQ, et vous y êtes chaleureusement conviés, je vous propose de suivre ce modèle :

Citation

__Question__ : Comment rafraîchir les rôles du membre courant sans devoir se déconnecter/reconnecter ?

__Réponse__ : Il faut déconnecter manuellement le membre, qui se reconnectera automatiquement à la requête suivante : $this->get('security.context')->getToken()->setAuthenticated(false);

Le zCode :

<blockquote><div class="rmq question">Question</div>
<p><strong>Réponse :</strong></p></blockquote>

Merci de votre participation !

-
Edité par winzou le 10 août 2013 à 21:55:00

Publicité
Le 3 juin 2012 à 12:10:37
Le 3 juin 2012 à 12:25:31

Citation

Question : Pourquoi la création d'une erreur 404 me créé une erreur 500 ?
Réponse :
Attention, ce n'est throw new $this->createNotFoundException(); mais throw $this->createNotFoundException();. En effet, $this->createNotFoundException() n'est pas un objet !



Citation

Question : Pourquoi mon routing.yml principal ne se charge pas correctement ?
Réponse :
Attention à ne pas copier-coller du code yaml, car ce langage est très sensible. Faites aussi attention à l'indentation non pas en tabulations mais avec quatre espaces.
De plus, certains éditeurs de texte incluent des fonctionnalités pour vérifier la syntaxe YAML.

Webmaster d'un site de remontées mécaniques : Montagne-Câble !
Le 3 juin 2012 à 13:06:53

Excellente idée, il serait bien d'épingler quelque temps ce sujet vus le nombre de personne qui se lancent dans Symfony2, ça risque d'en aider plus d'un! :)

@remontees, j'ajouterai à ta deuxième solution qu'il y a le langage yaml des éditeur de texte qui permet de détecter les mauvaise tabulation est qu'il est possible de configurer notepad++ dans les options pour qu'il remplace les tabulations par 4 espaces afin d'éviter ces problèmes :)

Voici pour ma part :

Citation


Question :
A la validation de mon formulaire j'ai l'erreur ci-dessous, pourquoi ?
Le jeton CSRF est invalide. Veuillez renvoyer le formulaire

Réponse :
Vous avez probablement oublié de définir un ou plusieurs champs dans la vue de votre formulaire, pour éviter les oublies vous pouvez ajouter {{ form_rest(form) }} avant votre bouton submit, ce code s'occupera de générer pour vous les champs que vous n'avez pas encore défini dans votre vue (attention ce code affiche également les champs de type hidden !).

Le 3 juin 2012 à 23:43:48

Une bonne idée ce sujet! Vous allez voir que bientôt on aura carrément un sous-forum Symfony!

Citation

J'ai une erreur "the annotation X was never imported". Ça veut dire quoi?


Réponse :
Que tu as oublié d'importer la classe correspondant à ton annotation. Ça se fait grâce au mot-clé use, cf la documentation de l'annotation.
La plupart du temps, on importe juste le namespace de l'annotation, et on l'aliase en "ORM", ce qui fait qu'il ne faut pas oublier le ORM dans @ORM\Annotation
En résumé,

<?php
use Doctrine\ORM\Mapping as ORM;
/**
 * @ORM\Annotation()
 */



équivaut à

<?php
use Doctrine\ORM\Mapping;
/**
 * @Mapping\Annotation
 */



qui équivaut à

<?php
/**
 * @Doctrine\ORM\Mapping\Annotation
 */



Et en général, on utilise la première méthode.


Citation

Comment je me mets à jour symfony et les autres vendors?


Réponse :
1) Je regarde quel est la dernière version ici : https://github.com/symfony/symfony-standard/tags
2) Si la dernière version c'est 2.0.15, je compare ce fichier : https://raw.github.com/symfony/symfony [...] /v2.0.15/deps avec mon fichier deps .
3) Une fois le fichier deps mis à jour, deux solutions avec comme prérequis avoir installé git (windowsiens: cochez la case "installer git-bash" et utilisez git-bash au lieu du terminal de base <troll>ou alors passez carrément à Linux</troll>) :
a) J'ai installé symfony avec les vendors => php bin/vendors install --reinstall
b) J'ai installé symfony sans les vendors => php bin/vendors update


Citation

À quoi sert le fichier deps.lock?


Réponse: Lorsque vous lancez php bin/vendors install, s'il n'y a pas d'entrée dans ce fichier pour une des dépendances, une nouvelle entrée est créée avec le nom de la dépendance et l'identifiant du dernier commit. S'il y a déjà une entrée, les mises à jour de la dépendance sont récupérées, mais le dépôt passe à la version correspondant au commit référencé dans l'entrée. Si vous lancez plutôt php bin/vendors update, alors les entrées du fichier deps.lock sont ignorées, et mises à jour. Si une version est spécifiée dans le fichier deps, la mise à jour se fait vers cette version. Le fichier deps.lock est donc là pour vous permettre d'installer de nouvelles dépendances sans mettre à jour les autres, même celles pour lesquelles vous n'avez pas spécifié de version.
Vous trouvez ça compliqué / pourri?
C'est pas grave, ça va changer pour utiliser quelque chose de meilleur en 2.1


Citation

J'en ai marre faire un assets:install à chaque fois que je modifie un fichier css ou js


Réponse :
Utilisez le lien symbolique plutôt que la copie, comme ceci:

app/console assets:install --symlink web



Citation

J'ai une erreur en console, pas assez précise


Réponse :
Utilisez l'option verbose:

app/console --verbose la:commande



Vous utilisez git et (Composer, Sismo, Symfony ou ctags)? Simplifiez vous la vie avec des hooks!
Le 4 juin 2012 à 14:49:44

Citation : Zer0 Absolu

J'en ai marre faire un assets:install à chaque fois que je modifie un fichier css ou js

Utilisez le lien symbolique plutôt que la copie, comme ceci:
Code : Console - Sélectionner

app/console assets:install --symlink web



petit ajout: vous pouvez également utiliser la commande assetic:dump --watch

Cette commande va rafraîchir les assets à chaque fois qu'elle détecte un changement dans les fichiers js et css importés par assetic.
Le 4 juin 2012 à 20:43:11

Citation

Question : Comment faire de l'AJAX avec Symfony2 ?

Réponse :
Comme n'importe quelle autre page. Si vous ne comprenez pas pourquoi vous n'avez rien compris à l'AJAX. (Bon ok j'essayerai de le tourner autrement, mais globalement c'est ça la réponse).

Le 4 juin 2012 à 21:27:41

Euh je précise que la FAQ a vocation à intégrer le tutoriel sous la forme d'un chapitre dédié. Ici au contraire on peut discuter des idées et donner des questions sans réponse ;)
Le 4 juin 2012 à 21:51:09

Citation

mon projet symfony 2 m'affiche une page blanche, que faire?


reponse: Ce soucis peut provenir du cache, vider le cache permet en général de régler le probleme. Si ce n'est pas suffisant, cela vient certainement des vendors qui sont mal installés. lances une commande d'installation de vendors pour régler le problème



Je tiens à préciser que ce sont des expériences personnelles. Il doit y avoir d'autres raisons pour une page blanche (j'ai déja eu un cas de figure que ces deux choses ne pouvaient pas régler) donc si vous avez eu d'autres expériences que moi, merci de compléter! ;)
Le 9 juin 2012 à 15:43:30

Je ne sais pas si c'est une erreur commune mais cela ne me paraissait pas évident quand j'ai commencé à utiliser Sf. En tout cas elle n'est pas liée directement avec Symfony2 .. à voir.

Citation


Question : Pourquoi quand je fais : $objet->setEntiteliee(null) cela déclanche l'erreur : Catchable Fatal Error: Argument 1 passed to Tony\xBundle\Entity\UneEntite::setEntiteeliee() must be an instance of Tony\xBundle\Entity\Entiteliee, null given ...

Réponse :
Votre fonction setEntiteliee() n'accepte par défaut pas la valeur "null". Pour pouvoir passer cette valeur, il faut que vous ajoutiez "=null" après l'argument :

public function setEntiteliee(\Tony\xBundle\Entity\Entiteliee $foo=null)
{
   $this->foo = $foo;
}




Un truc tout bête aussi :

Citation


Question : Pourquoi l'erreur : Unexpected token "name" of value "AND" ("end of statement block" expected) in xBundle:x:x.html.twig at line x dans un template TWIG ?

Réponse :
Twig n'accepte pas de "AND" (en majuscule), mettez plutôt : "and".



Citation


Question : Un problème lié au dossier dev_old lors du vidage du cache ?

Réponse :
Supprimez le dossier dev_old. EDIT: Cela arrive aux utilisateur de Windows. Souvent 3 tentatives de vidage du cache avec suppression du dossier sont nécessaires.



Citation


Question : Pourquoi dans un template Twig, mon {% render ... %} ne m'affiche pas le résultat de ma méthode ?

Réponse :
Quand vous appelez une méthode depuis Twig directement, il faut que vous retourniez le résultat avec la classe Response :

use Symfony\Component\HttpFoundation\Response;

public function xxx()
{
   // ...

   return new Response('Mon résultat');
}


Le 12 juin 2012 à 15:31:24

Citation

la méthode persist() ne se comporte pas comme elle devrait quand je veux faire une édition. Elle ne modifie pas l'entrée que je viens d’éditer, mais en créé une autre.


réponse: Vous avez certainement défini la même vue de formulaire pour l'ajout et la modification, et l'action du formulaire doit pointer sur l'action d'ajout, et non de modification.
modifiez donc cette ligne: <form action="{{ path('sdzblog_ajouter') }}" method="post" {{ form_enctype(form) }}>
en enlevant le lien dans action: <form action="" method="post" {{ form_enctype(form) }}>

le formulaire une fois validé rechargera donc la page actuelle, permettant de garder la même vue de formulaire pour les deux actions



Ce n'est pas forcément une question courante (bien que ce soucis me soit arrivé et que je l'aie vu deux fois sur le forum) mais la solution est tellement peu évidente que je trouvais intéressant d'y répondre.
Le 12 juin 2012 à 18:37:01

Un truc que j'ai eu du mal à capter au début ^^ :

Citation


Question : Pourquoi cette erreur survient lors d'un suppression :
InvalidArgumentException: A new entity was found through the relationship 'Tony\xBundle\Entity\x#userBanni' that was not configured to cascade persist operations for entity: Tony\xBundle\Entity\utilisateurs_bannis@000000003cd051ca00000000dd88f9da. Explicitly persist the new entity or configure cascading persist operations on the relationship. If you cannot find out which entity causes the problem implement 'Tony\xBundle\Entity\utilisateurs_bannis#__toString()' to get a clue.
?

Réponse :
Avant de supprimer entrée dans la base de données, il faut supprimer toutes ses liaisons avec d'autres tables. Prenons un cas concret : je souhaite dé-bannir un utilisateur. J'ai une relation OneToOne entre la table utilisateur et utilisateurs_bannis. Pour dé-bannir un utilisateur je dois supprimer l'entrée qui lui est associée dans utilisateurs_bannis ET auparavant : la relation liant la ligne utilisateur et utilisateurs_bannis :

La relation est unidirectionnelle :

/**
 * @ORM\OneToOne(targetEntity="Tony\AdminBundle\Entity\utilisateurs_bannis", mappedBy="utilisateur", cascade={"remove"})
 */
private $userBanni;



La suppression :

private function deBannirUser($user)
{
   $banni = $user->getUserBanni();

   // /!\ Suppression de la relation /!\
   $user->setUserbanni(null);
   // fin suppression


   $em = $this->getDoctrine()->getEntityManager();
   $em->remove($banni);
   $em->flush();

return true;
}


Pour une relation ManyToOne : imaginons un achat et un historique associé à cet achat. Je souhaite vider son historique sans toucher à l'achat.

La relation est bidirectionnelle :

/**
 * @ORM\OneToMany(targetEntity="Tony\AchatBundle\Entity\Achats_historique", mappedBy="achat", cascade={"remove"})
 */
private $historique;


/**
 * @ORM\ManyToOne(targetEntity="Tony\AchatBundle\Entity\Achats", inversedBy="historique")
 * @ORM\JoinColumn(name="id_achat", referencedColumnName="id")
 */
    private $achat;



On peut fait $achat->getHistorique(); mais impossible de faire $achat->setHistorique(null); Il faut alors annuler la relation depuis chacun des éléments de l'historique de cette manière :

La suppression :

private function supprimerHistorique($historique)
{
   foreach($historique as $evenement)
   {
      $evenement->setAchat(null);
      $this->getEm()->remove($evenement);
   }
}



ATTENTION:

$historique = $achat->getHistorique(); // --> $historique != null
foreach($historique as $evenement)
{
   $evenement->setAchat(null); // --> $evenement == null car $evenement émane de $historique = $achat->getHistorique() et on vient de briser la relation !
   $this->getEm()->remove($evenement); // --> remove(null) --> ne marche pas, l'évènement n'est pas supprimé
}


récupérez plutôt l'historique de manière indépendante à l'objet $achat :

// récupération de l'historique sans utiliser la relation achat-historique :
$historique = $this->getHistoriqueByAchat($id_achat); // doit retourner un objet contenant tous les évènements de l'historique



Le 15 juin 2012 à 18:13:44

Citation

Question : Mon application fait plusieurs 100ène de mo, comment régler ça ?

Réponse : Il faut supprimer les dossiers/fichiers présents dans :
app/cache/*
app/logs/*
Et tous les dossiers nommé .git (faite une recherche) qui peuvent se trouver dans les bundles que vous avez installé/mis à jours.



J'avais eu le coup d'une application de plus de 100mo (compréssé) en .git/log/cache inutile.
Mon 30ko d'upload avait pas aimé ^^
Le 16 juin 2012 à 13:49:13

Citation : remontees


Question : Je veux uploader un avatar et le redimensionner ?
Réponse : ???



Il existe un bundle qui gère plutot bien l'upload et le redimentionnement en plusieurs miniatures de grandeurs definies: SonataMediaBundle : documentation

Tu peux t'en inspirer ou simplement l'utiliser.

Mais je suis un peu dacord avec Zer0 Abs0lu sur le fait que ce n'est pas vraiment une question FAQ
Le 16 juin 2012 à 18:05:44

Citation


Question : Pourquoi l'erreur : "SQLSTATE[HY000]: General error: 1553 Cannot drop index 'UNIQ_xxx' : needed in a foreign key constraint" lors d'un "doctrine:schema:update --force" ?

Réponse :
Cette erreur survient dès que vous faites un "doctrine:schema:update --force" avec une mauvaise relation entre deux entités.
Personnellement, cela m'arrive quand je me trompe sur les mappedBy="xx" et inversedBy="xx" d'une relation. Doctrine ne détecte pas cette erreur et met à jour le schéma buggé.

Pour régler le problème :
1. Trouvez les deux entités qui posent problème grâce à un "php app/console doctrine:schema:update --dump-sql"
2. Supprimez la relation entre ces deux entités
3. Faites un "php app/console doctrine:schema:update --force"
4. Refaites la relation en corrigeant les mappedBy="xx" et inversedBy="xx"
5. Remettez de nouveau le schéma à jour : "php app/console doctrine:schema:update --force"



Voilà, j'espère que c'est une bonne question et une bonne réponse :)
Le 17 juin 2012 à 11:43:28

Avant toute chose, assurez-vous bien d'avoir nettoyé le cache de l'environnement qui pose problème

Citation

J'ai traduit mon interface. Depuis que j'ai créé mes fichiers messages.(fr|en|…).(xliff|xlf|xml|yaml|php), je n'ai plus que la version anglaise qui s'affiche, ou des chaînes incompréhensibles et moches


Réponse (pour Symfony 2.1.x et ultérieures)

Il y a plusieurs choses auxquelles il faut faire attention quand on met en place les traductions de l'interface :
  • La locale globale de votre application
    parameters:
        # …
        locale: fr
    
  • les deux endroits dans config.yml où la locale spécifiée doit être changée
    framework:
        #esi:             ~
        translator:      { fallback: %locale% }
        # …
        default_locale: %locale%
    
  • le domaine de traduction spécifié dans le template
    <p>{{ 'fos_user.registration.fos_user_registration_username'|trans(
        {},
        'FOSUserBundle'
    ) }}</p>
    
    N'oubliez pas le premier argument si vous spécifiez un domaine
    Notez que vous n'avez pas besoin de spécifier le domaine 'messages', car c'est celui par défaut.
  • si vous utilisez le format XLIFF, il y a un paramètre à spécifier dans le fichier de traduction, à la ligne 4 du code ci-dessous
    <?xml version="1.0"?>
    <xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
        <file
                source-language="fr"
                datatype="plaintext"
                original="file.ext">
            <body>
                <trans-unit id="1">
                    <source>J'aime Symfony2</source>
                    <target>Symfony2 is great</target>
                </trans-unit>
            </body>
        </file>
    </xliff>
    


Réponse (pour Symfony 2.0.x)

Il y a plusieurs choses auxquelles il faut faire attention quand on met en place les traductions de l'interface :
  • La locale globale de votre application
    [parameters]
    ; …
        ; N'oubliez pas les guillemets !
        locale="fr"
    
  • les deux endroits dans config.yml où la locale spécifiée doit être changée
    framework:
        #esi:             ~
        translator:      { fallback: %locale% }
        # …
        session:
            default_locale: %locale%
            auto_start:     true
    
  • le domaine de traduction spécifié dans le template
    <p>{{ 'fos_user.registration.fos_user_registration_username'|trans(
        {},
        'FOSUserBundle'
    ) }}</p>
    
    N'oubliez pas le premier argument si vous spécifiez un domaine
    Notez que vous n'avez pas besoin de spécifier le domaine 'messages', car c'est celui par défaut.
  • si vous utilisez le format XLIFF, il y a un paramètre à spécifier dans le fichier de traduction
    <?xml version="1.0"?>
    <xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
        <file
                source-language="fr"
                datatype="plaintext"
                original="file.ext">
            <body>
                <trans-unit id="1">
                    <source>J'aime Symfony2</source>
                    <target>Symfony2 is great</target>
                </trans-unit>
            </body>
        </file>
    </xliff>
    
N'hésitez pas à mentionner d'autres pistes, je crois bien en avoir oublié au fil des sujets où j'ai répondu. Probablement que j'éditerai ce message pour centraliser les réponses

Citation

J'ai personnalisé les templates d'un bundle (FOSUserBundle, pour l'exemple). Mais depuis, je n'ai plus que la version anglaise qui s'affiche, ou des chaînes incompréhensibles et moches


Réponse :
Plus que pour d'autres traductions, il faut faire attention au domaine.

  • Voir le troisième point ci-dessus pour votre version de Symfony
  • Pour Symfony 2.0.x
    • Vérifiez que vous n'avez pas redéfini certains blocs que FOSUserBundle lui-même redéfinit, notamment field_label
      {% block field_label %}
      {% spaceless %}
          <label for="{{ id }}">{{ id|trans([], 'FOSUserBundle') }}</label>
      {% endspaceless %}
      {% endblock field_label %}
      
    • Vérifiez que votre bundle est bien enfant de FOSUserBundle
      <?php
          public function getParent()
          {
              return 'FOSUserBundle';
          }
      
      Si vos templates remaniés sont bien dans votre UserBundle, ils utiliseront le bloc défini au point précédent
  • Dès Symfony 2.2.x, vous pouvez utiliser {% trans_default_domain "myDefaultDomainForThisTemplate" %}

    Attention : même s'il s'agit d'un tag Twig, c'est un ajout qui nous vient de Symfony. Si vous utilisez Twig sans Symfony, ce tag n'est pas disponible.

Citation

J'ai traduit mes entités avec StofDoctrineExtensionsBundle et/ou Doctrine Extensions, mais je n'ai que le contenu en Anglais qui s'affiche !


Réponse :
Là aussi, il y a une locale qui est par défaut en Anglais

stof_doctrine_extensions:
    default_locale: %locale%


Citation

J'arrive à traduire beaucoup de choses, mais pas le contenu des balises <label>


Réponse :
Les labels des champs de formulaire sont traduisibles, mais d'une manière un peu différente. Vous aurez peut-être remarqué que la version non traduite est très semblable aux noms des champs dans vos ***Type. C'est effectivement de là que ce que vous voyez est créé.
Lors du rendu d'un formulaire, Symfony récupère le nom du champ et l'humanise. En fait, il appelle une fonction (humanize) qui remplace tous les caractères "_" par un espace et met la première lettre en majuscule. C'est donc ce résultat qui sera traduit, et non le nom du champ dans votre ***Type.
Prenons un exemple :

<?php // …
class Personne
{
    // …
    private $date_of_birth;
    // …
}

Dans le formulaire pour cette entité, vous aurez déclaré le champ ainsi :

<?php
$builder->add('date_of_birth', 'birthday')

Et le code HTML que vous verrez dans la page de votre formulaire se présentera à peu près ainsi :

<label for="personne_date_of_birth">
	Date of birth
</label>
<input type="date" name="personne[date_of_birth]" id="personne_date_of_birth" />

Pour traduire le contenu de la balise <label>, il faudrait avoir l'élément suivant :

# …
Date of birth: Date de naissance
Si vous utilisez les traductions sur niveaux multiples en YAML ou en PHP, vous êtes obligés de mettre la chaîne à traduire au premier niveau, sans pouvoir la scinder.


Citation

J'ai tout bien suivi le tutoriel sur la traduction, mais rien n'est traduit dans les vues où j'ai des {{ render() }} !


Réponse : {{ render(…) }} génère une nouvelle requête HTTP interne. Seulement, cette requête doit aussi connaître la locale souhaitée, et Symfony ne la renseigne pas automatiquement quand vous utilisez {{ render() }}. Du coup, c'est la locale par défaut qui sera utilisée… pour l'entier de la page, et non juste pour la partie intégrée !

Il vous faut donc spécifier la locale en utilisant un paramètre supplémentaire, ce qui donne {{ render(controller([votre action], { '_locale': app.request.locale })) }}

-
Edité par Ymox le 9 septembre 2013 à 13:07:07

BBQ de Simple ITFAQ PHPTutoriel WAMPPas de MP. Je suis là où il reste un Zeste de Savoir-vivre
Le 19 juin 2012 à 16:53:54

Citation

J'ai une erreur
Expected argument of type "Mon\Bundle\Entity\MonEntité", "array" given
quand je soumets un formulaire ! A l'aide !


Réponse :
Vous avez probablement une méthode add*** dans votre entité, pour une relation OneToMany ou ManyToMany. Mais vous n'avez pas de set***, et c'est cela qui gêne. Ajoutez une méthode set***.
Pour les besoins de l'exemple, imaginez une entité Article liée en OneToMany avec Tag. La méthode à ajouter dans Article est celle-ci :

<?php
public function setTags($tags)
{
   $this->tags = $tags;
}

Citation

Quand je persiste une entité qui embarque d'autres entités, celles qui sont embarquées ne sont pas persistées, malgré cascade={"persist"}. Pourquoi ?
Quand je persiste une entité qui embarque d'autres entités, la liaison n'est pas enregitrée, malgré cascade={"persist"}, j'ai ma clé étrangère qui est vide. Pourquoi ?


Réponse :
Dans le cas de relations *ToMany, il faut rendre plus forte la liaison dans la classe parent, et ajouter un peu de traitement dans la méthode d'ajout (add*), puis l'appeler dans la méthode de définition (set*) si vous l'avez. Pour suivre l'exemple utilisé ci-dessus, voici à quoi vont ressembler les mutateurs dans Article :

public function setTags($tags)
{
    foreach ($tags as $tag) {
        $this->addTag($tag);
    }

    return $this;
}

public function addTag($tag)
{
    // L'ordre de ces deux lignes est important !
    $tag->setArticle($this);
    $this->articles[] = $tag;

    return $this;
}

Si tout cela ne suffit pas, vérifiez que vous n'êtes pas dans le cas où vos mappings ne sont pas pris en compte

-
Edité par Ymox le 30 juin 2014 à 8:13:11

BBQ de Simple ITFAQ PHPTutoriel WAMPPas de MP. Je suis là où il reste un Zeste de Savoir-vivre
Le 19 juin 2012 à 17:18:59

Citation

Je n'arrive pas à envoyer un mail depuis mon site hebergé chez OVH. Quand j'essaie, je tombe sur l'erreur:
request.CRITICAL: Swift_TransportException: Connection could not be established with host localhost



Reponse: OVH ne permet pas d'envoyer de mail par le protocole SMTP depuis un site hebergé en mutualisé. Il faut remplacer le paramètre transport dans parameters.ini par "mail" au lieu de "smtp"

Le 20 juin 2012 à 16:34:57

Citation

Sous Chrome/Firefox/Safari/Opera/Internet Explorer 10+, je ne peux pas soumettre mes formulaires, et je reçois un message comme quoi un de mes champs ne peut être vide, alors que j'ai spécifié qu'il pouvait l'être dans mes mappings !
Et ça ne me fait pas ça avec IE 9 ni IE 8


Réponse :
Certains vieux navigateurs (ou certains dont le développeur principal peut se permettre de laisser traîner les choses…) ne supportent pas un petit attribut, nouveau en HTML5, qui dit aux navigateurs qu'un champ de formulaire ne peut être vide. C'est un peu comme une validation avec du JavaScript, mais sans que vous n'ayez besoin d'en faire :magicien: (pour plus d'informations, je vous propose de regarder la partie sur les formulaires du tutoriel HTML5 / CSS3, et peut-être plus particulièrement la sous-section "Finaliser et envoyer le formulaire", titre "Rendre un champ obligatoire").
Symfony est très gentil, et ajoute ça par défaut à tous les champs qui

  • ne sont pas spécifiés comme nullable: true dans les mappings, et dont le type de widget n'est pas défini, mais laissé à deviner à Symfony (<?php $builder->add('mon champ'); ou <?php $builder->add('mon champ', null, array( /* … */)) ;
  • ont le type de widget défini (<?php $builder->add('mon champ', 'text'/*, … */)), et ce quels que soient les mappings
Cependant, cela ne remplace pas la validation côté serveur, qui reste indispensable.
Voyez le chapitre "Validez vos données" à ce propos
Ce genre de souci doit aussi vous faire vous poser la question :
est-ce que de permettre que ce champ soit vide a du sens ?
Si toutes les lignes add de vos ***Type::buildForm ne comportent pas de deuxième paramètre (comme <?php $builder->add('mon champ'); ou <?php $builder->add('mon champ', null, array(/* … */)), spécifiez dans vos mappings que les propriétés peuvent être nulles. Cependant, dès que vous donnez un paramètre supplémentaire (<?php $builder->add('mon champ', 'text'/*, … */)), cette solution n'est plus valable. Une autre est proposée ci-après.


Maintenant que vous savez ce que vous voulez faire et que vous en êtes sûr : pour éviter d'être forcé de remplir des champs qui peuvent rester vide, il faut le spécifier dans votre ***Type avec cette simple ligne

<?php
$builder
    ->add('mon_champ', 'texte', array(
        'required' => false,
    ))


Votre champ est dans un formulaire embarqué

Votre code dans la fonction buildForm sera probablement un peu différent

<?php
$builder
    ->add('mon_champ_entite_embarquee')
Par défaut, tous les champs d'un formulaire embarqué sont obligatoires, sauf si vous avez spécifié que non dans le formulaire de votre entité embarquée.

Vous pouvez néanmoins rendre les formulaires embarqués complètement facultatifs depuis le formulaire de l'entité mère, sans changer quoi que ce soit dans le ***Type embarqué

<?php
$builder
    ->add('mon_champ_entite_embarquee', new MonEntiteEmbarqueeType(), array(
        'required' => false,
    ))

-
Edité par Ymox le 27 mars 2014 à 21:15:56

BBQ de Simple ITFAQ PHPTutoriel WAMPPas de MP. Je suis là où il reste un Zeste de Savoir-vivre
Le 20 juin 2012 à 16:58:41

Attention en mettant required à false votre formulaire pourra être validé alors qu'il manque des champs. Il faut que cela corresponde vraiment au comportement que vous voulez.
Le 20 juin 2012 à 17:17:09

@Ymox, il faut aussi ajouter nullable="true" dans l'entité, par exemple pour "extrait" :


Citation

* @ORM\Column(name="extrait", type="text", nullable="true")


Le 20 juin 2012 à 17:33:40

Citation : winzou

Attention en mettant required à false votre formulaire pourra être validé alors qu'il manque des champs. Il faut que cela corresponde vraiment au comportement que vous voulez.


J'ajoute qu'il me semble (dites moi si je me trompe) qu'on peut aussi valider un formulaire ayant required à true, si on a un navigateur suffisamment mauvais. Si vous voulez rendre un champ obligatoire, alors je crois qu'il faut utiliser la contrainte NotBlank() pour avoir une vraie validation côté serveur.
Vous utilisez git et (Composer, Sismo, Symfony ou ctags)? Simplifiez vous la vie avec des hooks!
Le 21 juin 2012 à 19:59:30

Citation

Quand j'essaie d'utiliser php bin/vendors quelquechose, j'ai un message qui me dit que git n'est pas reconnu, ou introuvable.


Réponse :

  • Si vous êtes sous linux, installez git.
  • Si vous êtes sous windows, installez git et pendant l'installation, cochez la case pour installer git-bash. Ensuite, oubliez définitivement votre invite de commande et utilisez git-bash à la place. Vous aurez un vrai terminal, avec des couleurs et de l'auto-complétion.
Vous utilisez git et (Composer, Sismo, Symfony ou ctags)? Simplifiez vous la vie avec des hooks!
Le 22 juin 2012 à 13:47:31

Citation

J'aimerais inclure une librairie externe dans Symfony 2. Je fais comment ?


Réponse Pour Symfony 2.1.x et ultérieures (pour Symfony 2.0.x, voir plus bas)

Vous ne devriez plus toucher à autoload.php depuis Symfony 2.1.x si vous utilisez composer

Vérifiez si la librairie que vous souhaitez utiliser est renseignée pour Composer, et suivez les instructions le cas échéant

Lisez le tutoriel de winzou sur Symfony 2, plus précisément la section Installer un bundle grâce à Composer – Installer un bundle grâce à Composer : Gérer l'autoload d'une bibliothèque manuellement. Avec ça, pas besoin de télécharger vous-même ni de vous préoccuper d'où extraire la librairie :magicien:
Pour ceux qui aiment y aller un peu à l'ancienne, lisez la suite.
Le principe est similaire à la réponse pour Symfony 2.0.x (voir plus bas) et PHP 5.3+ (PAS PEAR) puis il faut regarder dans ce message (deuxième point) pour l'enregistrement du namespace.

Pour ceux qui souhaiteraient aller plus vite qu'en suivant les liens, voici un exemple pour embarquer HTML2PDF
  1. Préparez une nouvelle architecture. Une bonne idée serait d'utiliser vendor/[mondelalibrairie]/lib/[NomDuDéveloppeur]/[NomDeLaLibrairie]/, donc /vendor/html2pdf/lib/Spipu/Html2Pdf. Vous pouvez ignorer la partie [NomDuDéveloppeur] si vous le souhaitez.
  2. Créez une classe PHP dans /vendor/html2pdf/lib/Spipu/Html2Pdf, en adaptant le code suivant :
    namespace Spipu\Html2Pdf;
     
    require_once __DIR__ . '/src/html2pdf.class.php';
     
    class Html2Pdf extends \HTML2PDF
    {
    }
    
    Si la classe principale possède un constructeur, il vous faut le surcharger en respectant la signature (nombre d'arguments et type)
  3. Renseignez Symfony sur le nouveau namespace. Si vous utilisez composer, modifiez votre fichier composer.jsoncomme suit
    {
        // …
        "autoload": {
            "psr-0": {
                "Symfony": "src/",
                // …
                "Spipu\Html2Pdf": "vendor/html2pdf/lib/"
            }
        }
         
        // …
    }
    Notez que vous devrez lancer php composer.phar dump-autoload avant de pouvoir utiliser le tout

    Si vous n'utilisez pas composer, modifiez autoload.phpcomme suit :
        $loader
            // …
            ->add('Spipu\Html2Pdf', __DIR__.'/../vendor/html2pdf/lib');
    

    Une fois terminé, vous devriez avoir l'arborescence suivante
    vendor
    └───html2pdf
        └───lib    <---- là pointe le namespace
            └───Spipu
                └───Html2Pdf
                    ├───src
                    |   └───html2pdf.class.php (class HTML2PDF)
                    └───Html2Pdf.php (class Html2Pdf extends HTML2PDF)
                          C'est le fichier qu'on a créé au point 2
  4. Ensuite, créez un service de cette librairie
       html2pdf:
            class: Spipu\Html2Pdf\Html2Pdf
    



Pour Symfony 2.0.x

Il y a plusieurs possibilités, selon l'ancienneté de la librairie que vous souhaitez inclure dans votre application Symfony et la complexité de ladite librairie : si elle est prévue pour PHP 5.3+, si ce n'est pas le cas mais suit les conventions PEAR, et si elle ne semble suivre rien de particulier. Dans ce dernier cas, je vous invite à essayer par vous-même et proposer votre solution sur le forum, mais pas ici.

Pour l'exemple, je vais ajouter la librairie GeSHi à Symfony 2, librairie développée par des membres de la communauté SourceForge.

La librairie est pensée pour des version de PHP plus anciennes que 5.3 et suit les convensions PEAR
La convention de nommage PEAR est proche des namespaces, mais remplace les antislashes par des underscores dans les noms de classe. Exemple : Twig
  1. Préparez une nouvelle architecture. Une bonne idée serait d'utiliser vendor/[NomDuDéveloppeur]/lib/[NomDeLaLibrairie]/src/, donc /vendor/SourceForge/lib/GeSHi/src/.
    Vous pouvez remplacer par ce que vous voulez la partie [NomDuDéveloppeur] si vous ne le connaissez pas, ou que vous n'allez pas utiliser plus d'une librairie de cette même source. Par défaut, vous pouvez réutiliser le nom de la librairie.
  2. Créez une classe PHP dans /vendor/SourceForge/lib/GeSHi/, en adaptant le code suivant :
    <?php
    
    require_once __DIR__.'/src/geshi.php';
    
    class GeSHi_GeSHi extends GeSHi {
    }
    
  3. Renseignez Symfony sur le nouveau préfixe
    <?php
    $loader->registerPrefixes(array(
        // …
        'GeSHi_' => '/../vendor/Sourceforge/lib',
    
    Une fois terminé, vous devriez avoir l'arborescence suivante
    vendor
    └───Sourceforge
        └───lib    <---- là pointe le préfixe
            └───GeSHi
                ├───src
                |  └───geshi.php (class GeSHi)
                └───GeSHi.php (class GeSHi_GeSHi extends GeSHi)
                      C'est le fichier qu'on a créé au point 2
  4. (Optionnel) Créer un service de cette classe
    geshi:
        class: GeSHi_GeSHi
        #…
    

La librairie est prévue pour PHP 5.3+
Les librairies prévues pour PHP >= 5.3 contiennent des namespaces
GeSHi n'est PAS prévue pour PHP 5.3+, mais je ferai comme si
  1. Préparez une nouvelle architecture. Une bonne idée serait d'utiliser vendor/[NomDuDéveloppeur]/lib/[NomDeLaLibrairie]/, donc /vendor/SourceForge/lib/GeSHi/. Vous pouvez remplacer par ce que vous voulez la partie [NomDuDéveloppeur] si vous ne le connaissez pas, ou que vous n'allez pas utiliser plus d'une librairie de cette même source. Par défaut, vous pouvez réutiliser le nom de la librairie.
  2. Renseignez Symfony sur le nouveau namespace
    <?php
    $loader->registerNamespaces(array(
        // …
        'GeSHi' => __DIR__ . '/../vendor/SourceForge/lib/GeSHi',
        /* Si vous avez plusieurs librairies du même fournisseur
         * et que vous avez un namespace pour cela */
        'SourceForge\\Geshi' => '../vendor/SourceForge/lib/GeSHi'
    
  3. (Optionnel) Créer un service de cette classe
    geshi:
        # Version GeSHi uniquement
        class: GeSHi\GeSHi
        # Version avec namespace de développeur
        class: SourceForge\GeSHi\GeSHi
    

La librairie ne contient qu'un seul fichier de code
Là, c'est à vous de voir. Vous pouvez suivre la partie pour PEAR et remplacer le "doublage de nom" par l'ajout d'un namespace, et déclarer ce nouveau namespace dans autoload.php, pointant toujours sur lib. En revanche, l'ajout de la librairie comme un service est vivement recommandé.

Source pour la partie PEAR et Symfony 2.0.x

Source 1 et source 2 pour la partie Symfony 2.1.x et ultérieures

Si vous avez d'autres méthodes

  1. qui semblent applicables à beaucoup de librairies
  2. qui sont utilisables en respectant PSR-0 ou PSR-4
je les inclurai volontiers ici. Envoyez-moi un MP :)

-
Edité par Ymox le 21 mai 2014 à 16:58:59

BBQ de Simple ITFAQ PHPTutoriel WAMPPas de MP. Je suis là où il reste un Zeste de Savoir-vivre
Le 3 juillet 2012 à 15:45:08

Citation

Je n'arrive pas à faire fonctionner mon bundle, téléchargé depuis github, alors que j'ai suivi scru-pu-leu-se-ment les instructions pour le paramétrer, mais il y a encore une erreur !

Une seule ? Vous êtes chanceux :p

Essayez le plus possible de vous mettre à Composer. C'est prévu entre autres pour éviter ce genre de problème



Réponse :
Vérifiez dans la documentation du bundle si vous avez bien téléchargé la version compatible avec vos versions de Symfony et Doctrine. Certains développeurs, comme celui de DoctrineExtensions ainsi que ceux de FOSUserBundle, proposent des versions qui ne sont plus compatibles qu'avec la version master du framework ou/et de l'ORM.

Même si la version que vous téléchargez semble être la bonne, ne prenez que celle qui est taguée, renseignée comme fonctionnant avec votre version de Symfony, et dont vous trouvez le lien [après avoir cliqué sur "tags" depuis la page github de FOSUserBundle, par exemple

-
Edité par Ymox le 10 janvier 2014 à 11:14:46

BBQ de Simple ITFAQ PHPTutoriel WAMPPas de MP. Je suis là où il reste un Zeste de Savoir-vivre
Le 3 juillet 2012 à 16:19:42

Citation

Comment afficher un bloc nécessitant un traitement complexe sur toutes les pages, sans avoir à hériter un contrôleur de base dans tous les contrôleurs?


Réponse:
En utilisant un contrôleur embarqué.

Vous utilisez git et (Composer, Sismo, Symfony ou ctags)? Simplifiez vous la vie avec des hooks!
Le 11 juillet 2012 à 20:41:01

Je continue à dire que ces messages masqués sont plutot pénibles. Le sujet va devenir difficilement compréhensible ainsi.
Le 11 juillet 2012 à 20:48:41

C'est moi qui ai masqué les précédents messages car ils étaient réellement hors sujet (genre "j'ai un problème" + 150 lignes de code). Mais les messages de discussion autour de la FAQ sont les bienvenus :)
Le 11 juillet 2012 à 21:04:55

dacord, merci pour la correction alors.
Le 13 juillet 2012 à 16:46:47

Pourquoi ais-je une erreur de duplication de clés lors de l'ajout d'une entrée dans ma base ?


Réponse :
Vous tentez de lier plusieurs entrées à une autre alors que la relation est OneToOne. Modifiez alors votre relation en ManyToOne pour que cela puisse fonctionner.
/!\ ATTENTION: Il est nécessaire de supprimer la relation, de faire un update de la table puis de remettre la relation et refaire un update pour que la modification soit prise en compte/
Le 14 juillet 2012 à 19:09:17

Citation
Je n'arrive pas à utiliser les méthodes de mon repository ! J'ai l'erreur
Undefined method 'UneMéthodeDeMonRepository'. The method name must start with either findBy or findOneBy!


Réponse :
Vous avez très probablement

  • oublié de renseigner votre repository dans vos mappings
    <?php
    /**
     * @ORM\Entity(
     *    repositoryClass="[[ le nom de votre classe repository, avec le namespace ]]"
     * )
     */
    
  • mis le mauvais nom/namespace pour le repository (attention à la casse et aux contre-obliques)
  • mis le fichier de votre repository dans un dossier ne correspondant pas au namespace dudit repository
  • mal nommé la classe

Citation

Je n'arrive toujours pas à utiliser les méthodes de mon repository, et j'ai ajouté l'annotation ci-dessus, avec le namespace, et je suis sûr qu'il est correct aux trois points mentionnés ci-dessus !


Je vous conseille d'aller voir ce message

-
Edité par Ymox le 17 juin 2014 à 22:21:03

BBQ de Simple ITFAQ PHPTutoriel WAMPPas de MP. Je suis là où il reste un Zeste de Savoir-vivre

[Symfony2] Questions fréquemment posées

× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
  • Editeur
  • Markdown