====== Gestion de la langue de l'utilisateur ====== Dans cette page nous allons détecter automatique la langue de l'utilisateur (sfFilter et sfRequest::getPreferredCulture()) puis lui proposer de la changer (sfComponents et sfFormLanguage). ===== Détection automatique de la langue ===== On créer un filtre (sfFilter) qui va détecter la langue de l'utilisateur et la lui affecter dans l'objet user (sfUser->setCulture()). Pour que le code du filtre ne s'exécute pas à toute les requêtes, on va forcer Symfony a ne pas affecter à l'utilisateur la langue par défaut. Il faut aussi indiquer au filtre les langues disponibles sur le site. ==== Pas de culture par défaut ==== # apps/frontend/config/settings.yml all: .settings: default_culture: null ==== Les langues disponibles sur le site ==== # apps/frontend/config/app.yml all: .global: available_cultures: [fr,en] ==== Le filtre AutoLanguageFilter ==== La classe AutoLanguageFilter qui hérite de sfFilter : # apps/frontend/lib/AutoLanguageFilter.class.php class AutoLanguageFilter extends sfFilter { public function execute( $filterChain ) { // Est-ce que la culture de l'utilisateur est nulle ? if( $this->getContext()->getUser()->getCulture() == null ) { // retrouve les cultures dispo pour le site $available_cultures = sfConfig::get('app_available_cultures'); if( ! is_array($available_cultures) ) { // Pas trouvées, erreurs de configuration throw new sfConfigurationException(sprintf('%s requires a "available_cultures" configuration key.', get_class($this))); } // retrouve automatique la culture préférée de l'utilisateur, parmi celles dispo sur le site. $this->getContext()->getUser()->setCulture( $this->getContext()->getRequest()->getPreferredCulture( $available_cultures ) ); //sfContext::getInstance()->getLogger()->debug( 'automatic user\'s culture selection : '.$user->getCulture() ); } // Execute next filter $filterChain->execute(); } } et activation du filtre: # apps/frontend/config/filters.yml ... # insert your own filters here AutoLanguageFilter: class: AutoLanguageFilter ===== Sélection de la langue par l'utilisateur ===== ==== Création IHM de sélection ==== On va tout d'abord créer un composant pour gérer l'affichage (IHM) de la sélection de la langue par l'utilisateur. Ce composant hérite de sfComponent et utilise le form sfFormLanguage fourni par le plugin [[http://www.symfony-project.org/plugins/sfFormExtraPlugin|sfFormExtraPlugin]]. # apps/frontend/modules/default/actions/components.class.php class defaultComponents extends sfComponents { public function executeChangeLanguage(sfWebRequest $request) { $available_cultures = sfConfig::get('app_available_cultures'); if( ! is_array($available_cultures) ) { throw new sfConfigurationException(sprintf('%s requires a "available_cultures" configuration key.', get_class($this))); } $this->form = new sfFormLanguage( $this->getUser(), array('languages' => $available_cultures ) ); } } Le template associé à ce composant contient le Form nécessaire à sfFormLanguage:
renderHiddenFields() ?>
Ce code (defaultComponents->executeChangeLanguage()) réalise par mal de traitement, via sfFormLanguage qui retrouve toutes les langues dispo dans Symfony pour en extraire celles indiquées dans la configuration du site. On va donc éviter du travail au moteur Php en activant le cache pour ce composant, de cette façon il ne sera exécuté que la 1ère fois. # apps/frontend/modules/default/config/cache.yml _changeLanguage: enabled: true ==== Traitement de la sélection ==== Création d'une route pour l'action @change_language: # apps/frontend/config/routing.yml change_language: url: /change_language param: { module: default, action: changeLanguage } Et le code de l'action: # apps/frontend/modules/default/actions/actions.class.php class defaultActions extends sfActions { ... public function executeChangeLanguage($request) { $available_cultures = sfConfig::get('app_available_cultures'); if( ! is_array($available_cultures) ) { throw new sfConfigurationException(sprintf('%s requires a "available_cultures" configuration key.', get_class($this))); } $this->form = new sfFormLanguage( $this->getUser(), array('languages' => $available_cultures ) ); if ($this->form->process($request)) { // culture has been changed } return $this->redirect('@homepage'); } } Et voilà, j'espère ne rien avoir oublié...