Outils pour utilisateurs

Outils du site


informatique:php:symfony:gestion_de_la_langue_de_l_utilisateur

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 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:

<!-- apps/frontend/modules/default/templates/_changeLanguage.php -->
<form action="<?php echo url_for('@change_language') ?>" method="post">
  <label for="language">Choose a language:</label>
  <?php echo $form['language'] ?>
  <?php echo $form->renderHiddenFields() ?>
  <input type="submit" value="ok">
</form>

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é…

informatique/php/symfony/gestion_de_la_langue_de_l_utilisateur.txt · Dernière modification: 19/05/2012 00:18 (modification externe)