Ver índice de contenidos del libro

8.2. Personalizando el objeto traductor

Si quieres utilizar los formularios de Symfony sin la parte de internacionalización de Symfony, debes crear un objeto traductor propio. Un objeto traductor es simplemente un elemento PHP que se puede ejecutar (un PHP callable), por lo que puede ser cualquiera de estos tres elementos:

  • Una cadena de texto que representa el nombre de una función, como por ejemplo mi_funcion
  • Un array con el nombre de la instancia de una clase (es decir, el nombre de un objeto) y el nombre de uno de sus métodos, como por ejemplo array($unObjeto, 'nombreDeUnoDeSusMetodos')
  • Una instancia de sfCallable. Esta clase se utiliza para encapsular de forma consistente un elemento ejecutable de PHP.

Nota Un elemento ejecutable de PHP (también llamado PHP callable) es una referencia a una función o al método de un objeto. También puede ser una variable PHP que devuelve true cuando se pasa a la función is_callable().

En el siguiente ejemplo se considera que se está migrando un proyecto que ya dispone de su propio mecanismo de internacionalización a través de la clase que se muestra en el listado 8-6.

Listado 8-6 - Clase propia para la internacionalización

class miI18n
{
  static protected $cultura_defecto = 'en';
  static protected $mensajes = array('fr' => array(
    'Nombre'  => 'Nom',
    'Email'   => 'Courrier électronique',
    'Asunto'  => 'Sujet',
    'Mensaje' => 'Message',
  )); 
 
  static public function traducirTexto($texto)
  {
    $cultura = isset($_SESSION['cultura']) ? $_SESSION['cultura'] : self::$cultura_defecto; 
    if (array_key_exists($cultura, self::$mensajes)
        && array_key_exists($texto, self::$mensajes[$cultura]))
    {
      return self::$mensajes[$_SESSION['cultura']][$texto];
    }
    return $texto;
  }
}
 
// Ejemplos de uso de la clase anterior
$miI18n = new miI18n();
 
$_SESSION['cultura'] = 'es';
echo $miI18n->translateText('Asunto'); // => muestra "Asunto"
 
$_SESSION['cultura'] = 'fr';
echo $miI18n->translateText('Asunto'); // => muestra "Sujet"

Como se muestra en el listado 8-7, cada formulario puede definir el elemento PHP que se encarga de traducir los elementos del formulario.

Listado 8-7 - Redefiniendo el método de internacionalización de un formulario

class FormularioContacto extends sfForm
{
  public function configure()
  {
    // ...
    $this->widgetSchema->getFormFormatter()->setTranslationCallable(array(new miI18n(), 'traducirTexto'));
  }
}

8.2.1. Parámetros del objeto traductor

El objeto traductor puede recibir hasta tres parámetros:

  • El texto que debe traducir.
  • Un array asociativo con los elementos que se deben sustituir en el texto original, normalmente utilizados para reemplazar argumentos dinámicos como se ha visto previamente en este capítulo.
  • El nombre del catálogo que se debe utilizar para traducir el texto.

A continuación se muestra la llamada que realiza el método sfFormWidgetSchemaFormatter::translate() para ejecutar el objeto traductor:

return call_user_func(self::$translationCallable, $texto, $parametros, $catalogo);

El elemento self::$translationCallable es una referencia al objeto traductor. Por lo tanto, el código anterior es equivalente al siguiente:

$miI18n->traducirTexto($texto, $parametros, $catalogo);

Seguidamente se muestra la versión actualizada de la clase MiI18n que soporta estos argumentos adicionales:

class miI18n
{
  static protected $cultura_defecto = 'en';
  static protected $mensajes = array('fr' => array(
    'mensajes' => array(
      'Nombre'  => 'Nom',
      'Email'   => 'Courrier électronique',
      'Asunto'  => 'Sujet',
      'Mensaje' => 'Message',
    ),
  ));
 
  static public function traducirTexto($texto, $parametros = array(), $catalogo = 'mensajes')
  {
    $cultura = isset($_SESSION['cultura']) ? $_SESSION['cultura'] : self::$cultura_defecto; 
    if (array_key_exists($cultura, self::$mensajes) &&
        array_key_exists($mensajes, self::$mensajes[$cultura] &&
        array_key_exists($texto, self::$mensajes[$cultura][$mensajes]))
    {   
      $texto = self::$mensajes[$_SESSION['cultura']][$mensajes][$texto];
      $texto = strtr($texto, $parametros);
    }
    return $texto;
  }
}