Smarty3 y autoload

Smarty Logo

Uno de los errores comunes al implementar Smarty3 es:

Fatal error: Class ‘Smarty_Internal_Wrapper’ not found

Fatal error: Class ‘Smarty_Internal_Register’ not found

Fatal error: Class ‘Smarty_Internal_Template’ not found

Estos se deban, probablemente, a que en tu aplicación estás utilizando la función __autoload también necesaria por Smarty3. La solución a este problema pasa por utilizar la función que PHP nos brinda spl_autoload_register.

En una aplicación, sólo puede existir una llamada a la función __autload, sin embargo, con spl_autoload_register podemos añadir tantos manejadores como queramos y estos se irán ejecutando en el orden en el que los hayamos registrado.

Un ejemplo sencillo de su uso sería:


class AutoloadHandler
{
static public function launch( $classname )
{
print '[['. $name .']]';
}
}

spl_autoload_register( 'AutoloadHandler::launch' );

new ThisClassNotExists();

El resultado de ejecutar este script sería algo así:

[[ThisClassNotExists]]

Fatal error: Class ‘ThisClassNotExists’ not found in …

El cual nos indica que está llamando de manera correcta al autoload, pero al no estar implementado de manera correcta y no existir la clase ‘ThisClassNotExists’ nos devuelve un error.

En definitiva, para solventar el problema, no será necesario que modifiques el código Smarty, pues este ya está utilizando de manera correcta spl_autoload_register, lo que debes hacer es sustituir tu __autoload por una clase con una función ‘launch’ (llámala como quieras) y registrarla mediante:

spl_autoload_register( 'MyAutoloadHandler::launch' );

Smarty3 y gettext

Si estás utilizando Smarty2 y te has decidido a dar el salto a Smarty3 para aprovecharte de sus nuevas funcionalidades (como por ejemplo la nada despreciable opción de herencia en templates), verás que existen algunas incompatibilidades, por ejemplo, se han decidido por seguir el estandar camelCase en el nombre de las funciones, utilizan getters y setters para los atributos o han cambiado la manera de registrar bloques.

En el caso del popular plugin smarty-gettext, si tenemos personalizada la llamada al traductor con, por ejemplo ‘{t}’ como es mi caso, nos encontraremos con un bonito error:

function call ‘register_block’ is unknown or deprecated

Esto es debido a que la forma correcta de registrar bloques en Smarty3 es:


$this->register->block('t', 'translate');

en lugar de:


$this->register_block( 't', 'translate' );

Una vez hecho esto, el siguiente error que nos deja Smarty es:

Plugin “t” not callable

En lugar del antiguo ‘translate’, el segundo parámetro deberá ser el nombre correcto de la función, es decir ‘smarty_translate’:


$this->register->block('t', 'smarty_translate');

de este modo solventaremos el problema y podremos seguir disfrutando de nuestro plugin de traducción.

Symfony: Upgrade de 1.2.x a 1.4 con PEAR

Antes de empezar a hacer el upgrade de symfony debemos asegurarnos que los plugins utilizados actualmente en el proyecto son compatibles con la versión 1.4, en caso de no ser compatibles, tenemos tres opciones:

  1. Buscar un plugin similar que sí sea compatible.
  2. Modificar nuestra aplicación para que no utilice dicho plugin.
  3. Si no podemos prescindir de él, habrá que esperar a que saquen la compatibilidad o hackearlo nosotros mismos (lo qual podría ser muy fácil o muy difícil en función del tipo de problema).

Pasos a seguir para subir de versión:

1) Update de los canales de pear

sudo pear update-channels

2) Upgrade de symfony a la versión 1.3

sudo pear upgrade -f symfony/symfony-1.3.0

3) Validamos que no estamos usando métodos deprecated (estós están eliminados en la versión 1.4)

symfony project:validate

En caso de obtener errores del validador, los solventaremos antes de hacer el upgrade siguiendo instrucciónes en la página Deprecations and removals in 1.3

4) Upgrade del projecto a la versión 1.3

symfony project:upgrade1.3

5) Upgrade de los plugins a la última versión

symfony plugin:upgrade [plugin]

6) Upgrade de symfony a la última versión

sudo pear upgrade symfony/symfony

7) Limpiamos la caché antes de probar

symfony cc

Ahora deberíamos tener nuestro proyecto updateado a la última versión estable de symfony 😀

Symfony i18n con gettext

Symfony permite varios métodos para internazionalizar nuestra aplicación. Por defecto, utilizan el formato XLIFF sin embargo, personalmente me gusta más gettext.

¿Cómo configurar symfony para usar gettext?

Para configurar symfony para que utilice gettext seguiremos los siguientes pasos:

1) Activamos el módulo I18N modificando el archivo settings.yml:

#apps/<appName>/config/settings.yml
all:
  .settings:
    charset:                utf-8
    i18n:                   on
    standard_helpers:       [ [TUS_HELPERS_ACTIVADOS]..., I18N]

2) Abrimos el archivo factories.yml y añadimos la entrada i18n:

#apps/<appName>/config/factories.yml
all:
  i18n:
    class: sfI18N
    param:
      default_culture:  en_US
      source:           gettext</pre>

3) Crearemos una carpeta i18n dentro de apps//:

apps/<appName>/i18n/<lang>

Donde <lang> será el idioma en dos letras (en, es, fr…) y dentro tendremos los ficheros messages.po y messages.mo.

Ahora podemos utilizar la función __( ‘texto_a_traducir’ ) con doble underscore [ _ ] en lugar del simple utilizado normalmente.

¿Cómo generar automáticamente nuestros ficheros po y mo?

Symfony trae una serie de herramientas que nos permiten generar los archivos po y mo de manera automática. Invocando el comando:

symfony i18n:extract frontend en --auto-save

Se recorrerá todos los archivos php de nuestra aplicación (código y templates) y sacará los textos que encuentre en las funciones __().

También se puede utilizar el mismo comando de la siguiente manera:

symfony i18n:extract frontend en --auto-delete

para eliminar las cadenas de texto que ya no existen.

La clase sfConfig de Symfony

Aquí os dejo algo de información sobre como solicitar variables de configuración en symfony además de un listado muy útil con todas las variables que Symfony trae predefinidas.

Cómo pedir variables definidas

Se puede llamar a la función estática get del objeto sfConfig para solicitar cualquier variable definida pasándo dos valores. El primero indica el nombre de la variable solicitada y el segundo, el valor que retornará en caso de no existir dicha variable.

sfConfig::get('sf_config_variable', 'The default value'); // The default is optional

Continue reading

Cómo usar sfWidgetFormJQueryDate de sfFormExtraPlugin?

sfFormExtraPlugin es un excelente plugin que mantienen los desarrolladores de Symfony con un montón de características adicionales que te ayudarán a construir formularios más completos.

¿Qué podemos encontrar en este plugin?

Són varias las utilidades que nos ofrece, desde la creación de campos captcha para evitar el spam hasta campos de texto autocompletables en función de lo que vayamos escribiendo. Aquí os dejo una lista con sus posibilidades:

  1. ReCaptcha widget y validador
  2. Editor HTML WYSIWYG para campos de texto
  3. Selector de fechas tipo calendario
  4. Selectores de idioma
  5. Widget de listas dobles
  6. Widget de autocompletado en campos de texto

¿Cómo instalar y usar sfWidgetFormJQueryDate?

sfWidgetFormJQueryDate nos creará un selector de fechas con unas configuraciones mínimas para facilitar la tarea de rellenar los campos date en nuestros formularios. En la siguiente imágen, puedes ver el resultado de su correcta implementación:

sfwidgetformjquerydate
Continue reading

Crear una relación many-to-many con Doctrine

Vamos a ver como informar al magnífico ORM Doctrine de que debe tratar un par de tablas con una relación many-to-many utilizando una tabla intermedia.

Supongamos que tenemos una talba de jugadores de fútbol y una tabla de equipos. Un equipo estará compuesto por varios jugadores y a su vez, un jugador puede estar relacionado con varios equipos (el actual, más los equipos por los que ha pasado en su vida deportiva).

Para este ejemplo necesitaremos tres tablas: Team, Player  y una relacional TeamPlayer. Continue reading

Configurar Doctrine en Symfony

Doctrine Logo Symfony integra Propel ORM por defecto, sin embargo, Doctrine está ganando puntos sobre su rival.

La principal ventaja de cada uno de ellos es:

Propel: Está completamente integrado con Symfony y decenas de plugins sólo funcionan para Propel.

Doctrine: Tiene muy buen rendimiento en ejecución y una forma muy concisa al escribir consultas complejas.

Si te has decidido a utilizar Doctrine en lugar de Propel y no sabes como integrarlo con Symfony, aquí te dejo los pasos para activarlo. Continue reading

Qué es Doctrine ORM?

Qué es un ORM?

Un ORM o (Object Relation Mapper) es una técnica de programación que nos permite convertir datos entre el sistema de tipos utilizado en un lenguaje de programación orientado a objetos y el utilizado en una base de datos relacional, es decir, las tablas de nuestra base de datos pasan a ser clases y los registros objetos que podemos manejar con facilidad.

fig02

Continue reading

Implementar FullCalendar en Symfony

FullCalendar es un plugin jQuery que nos permite implementar de manera sencilla un calendario con una interfaz visual excelente y muy fácil de personalizar. Además, podemos hacer Drag&Drop (arrastrar y soltar) de los eventos agendados para pasarlos de un día a otro.

Hoy vamos a montar en symfony un módulo que nos mostrará un calendario con los eventos almacenados en nuestra base de datos. La parte de administración no la desarrollaré, pero con las completas herramientas que nos ofrece symfony, nos será muy fácil montarlo (si estás dando tus primeros pasos con Symfony, te recomiendo realizar este tutorial donde podrás ver paso a paso como se implementa un projecto con Symfony).

FullCalendar

Continue reading