Actualización de Symfony 1.0 a Symfony 1.1

(Traducción de la guía oficial de actualización de Symfony 1.0 a Symfony 1.1)

Este documento describe los cambios introducidos por Symfony 1.1 y detalla los pasos necesarios para actualizar los proyectos desarrollados con Symfony 1.0.

AVISO: Symfony 1.1 sólo es compatible con las versiones de PHP superiores a 5.1

¿Cómo actualizar los proyectos?

Para actualizar un proyecto realizado con Symfony 1.0 de modo que sea compatible con Symfony 1.1, debes realizar los siguientes pasos:

1) Si no utilizas una herramienta de gestión del código fuente (SCM) tipo Subversion, Perforce o Visual Source Safe, deberías realizar una copia de seguridad de todo tu proyecto.

Como Symfony reemplaza algunos archivos durante la actualización (como por ejemplo los controladores frontales) es necesario tener una copia de los archivos originales para poder luego restaurar los cambios que habías realizado en esos archivos.

2) Actualiza el archivo llamado symfony que se encuentra en el directorio raíz del proyecto, cambiando estas tres líneas:

chdir(dirname(__FILE__));
include('config/config.php');
include($sf_symfony_data_dir.'/bin/symfony.php');

por estas otras cuatro líneas:

chdir(dirname(__FILE__));
require_once(dirname(__FILE__).'/config/ProjectConfiguration.class.php');
$configuration = new ProjectConfiguration();
include($configuration->getSymfonyLibDir().'/command/cli.php');

Otra alternativa es copiar directamente el archivo desde la nueva instalación de Symfony 1.1:

$ cd /ruta/hasta/directorio/raíz/proyecto
$ cp /ruta/hasta/symfony/lib/task/generator/skeleton/project/symfony symfony

Si utilizas Windows, cambia el comando cp por el comando copy

3) Crea un archivo llamado ProjectConfiguration.class.php en el directorio config del proyecto y añádele el siguiente contenido:

require_once '##SYMFONY_LIB_DIR##/autoload/sfCoreAutoload.class.php';
sfCoreAutoload::register();

class ProjectConfiguration extends sfProjectConfiguration
{
  public function setup()
  {
  }
}

Después, reemplaza el valor ##SYMFONY_LIB_DIR## por la ruta al directorio lib/ de tu instalación de Symfony 1.1. Esta es la nueva forma de cambiar la versión de Symfony que utiliza tu proyecto.

Otra alternativa es copiar directamente el archivo desde la nueva instalación de Symfony 1.1:

$ cp /ruta/hasta/symfony/lib/task/generator/skeleton/project/config/ProjectConfiguration.class.php config/ProjectConfiguration.class.php

Si utilizas Windows, cambia el comando cp por el comando copy

4) Ejecuta la tarea project:upgrade1.1 en el directorio raíz de tu proyecto para realizar una actualización automática:

$ ./symfony project:upgrade1.1

Esta tarea se puede ejecutar varias veces sobre un mismo proyecto sin consecuencias negativas. La tarea de actualización tienes que ejecutarla en cada proyecto que quieras actualizar a la versión Symfony 1.1 beta o final.

5) Si no vas a actualizar la parte de validación de formularios o el sistema de envío de correo electrónico, tienes que activar la opción de compatibilidad con la versión anterior en el archivo settings.yml:

all:
  .settings:
    compat_10: on

Cuando se activa la opción de compatibilidad con la versión anterior, se habilitan los siguientes componentes (para obtener más información puedes ver el plugin sfCompat10Plugin que está incluido en Symfony 1.1):

  • Los bridges a los frameworks Zend y ezComponents
  • sfProcessCache
  • Sistema de validación (archivo validate.yml, clases de validación, etc.)
  • Filtro fillin para el relleno automático de datos en los formularios
  • Envío de correos electrónicos mediante sfMail y phpmailer

 

 


 

 

El resto de secciones de este documento detallan los cambios que son incompatibles con la versión 1.0 de Symfony.

Archivos por lotes

Los archivos por lotes desaparecen y se transforman en tareas de la línea de comandos (CLI). La nueva línea de comandos permite añadir fácilmente comandos a los proyectos Symfony, por lo que deberías consultar el capítulo 16 del libro de Symfony 1.1 (aún no disponible) para comprender los detalles de las tareas.

Si quieres seguir ejecutando tus archivos por lotes, tienes que modificar las primeras líneas de todos esos archivos (las líneas que se parecen a la inicialización de los controladores frontales). Por lo tanto, la siguientes líneas…

define('SF_ROOT_DIR', realpath(dirname(__FILE__).'/..'));
define('SF_APP', 'frontend');
define('SF_ENVIRONMENT', 'prod');
define('SF_DEBUG', false);

require_once(SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.SF_APP.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php');
// Código del archivo por lotes

…se deben modificar por estas otras líneas:

require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php');
$configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'prod', false);
sfContext::createInstance($configuration);

// Código del archivo por lotes

Si necesitas inicializar la conexión con la base de datos, añade las siguientes líneas:

$databaseManager = new sfDatabaseManager($configuration);
$databaseManager->loadConfiguration();

Atributos flash

Los atributos flash ahora se gestionan directamente desde sfUser. Nueva forma de utilizar los atributos flash:

// En la acción
$this->getUser()->setFlash('aviso', 'Cualquier mensaje...');
$aviso = $this->getUser()->getFlash('aviso');

// En la plantilla
<?php hasFlash('aviso'): ?>
<?php getFlash('aviso') ?>

La clave flash del archivo de configuración filters.yml desaparece porque el filtro sfFlashFilter ya no existe.

La tarea project:upgrade1.1 realiza todos estos cambios de forma automática.

Métodos de sfComponent declarados obsoletos

Los siguientes métodos de sfComponent se han eliminado:

->getPresentationFor()
->sendEmail()

Ahora se pueden acceder mediante sfController:

// En la acción
$this->getController()->getPresentationFor(...);

La tarea project:upgrade1.1 realiza todos estos cambios de forma automática.

Singletons

Los objetos sfI18N, sfRouting y sfLogger se han transformado en factorías y por tanto ya no son singletons.

Para obtener estos objetos desde el código de la aplicación, se debe utilizar el objeto sfContext:

sfContext::getInstance()->getI18N()
sfContext::getInstance()->getRouting()
sfContext::getInstance()->getLogger()

Enrutamiento

El archivo factories.yml incluye una nueva configuración del sistema de enrutamiento:

routing:
  class: sfPatternRouting
  param:
    load_configuration: true

La tarea project:upgrade1.1 realiza todos estos cambios de forma automática.

Sistema de log

El archivo factories.yml incluye una nueva configuración del sistema de logs:

logger:
  class: sfAggregateLogger
  param:
    level: debug
    loggers:
      sf_web_debug:
        class: sfWebDebugLogger
          param:
            condition: %SF_WEB_DEBUG%
            xdebug_logging: true
          sf_file_debug:
            class: sfFileLogger
            param:
              file: %SF_LOG_DIR%/%SF_APP%_%SF_ENVIRONMENT%.log

El archivo de configuración logging.yml ya no se utiliza, por lo que todos los cambios en la configuración del mecanismo de logs se debe realizar en el archivo factories.yml.

Para deshabilitar los logs en el entorno de producción, se debe modificar el archivo factories.yml de la aplicación:

prod:
  logger:
    class: sfNoLogger
    param:
      level: err
      loggers: ~

Se ha creado una nueva opción de configuración llamada logging_enabled en el archivo settings.yml. Esta opción permite deshabilitar completamente los logs en el entorno de producción:

prod:
  .settings:
    logging_enabled: off

La tarea project:upgrade1.1 realiza todos estos cambios de forma automática.

Internacionalización (i18n)

El archivo factories.yml incluye una nueva configuración del sistema de i18n:

i18n:
  class: sfI18N
  param:
    source: XLIFF
    debug: off
    untranslated_prefix: "[T]"
    untranslated_suffix: "[/T]"
    cache:
      class: sfFileCache
      param:
        automatic_cleaning_factor: 0
        cache_dir: %SF_I18N_CACHE_DIR%
        lifetime: 86400
        prefix: %SF_APP_DIR%

El archivo de configuración i18n.yml ya no se utiliza, por lo que todos los cambios en la configuración del mecanismo de i18n se debe realizar en el archivo factories.yml.

La única excepción es la opción de configuración default_culture que ahora se configura en el archivo settings.yml y ya no depende del mecanismo de i18n:

default_culture: en

Si tu proyecto tiene otras opciones específicas, tienes que pasarlas del archivo i18n.yml al archivo factories.yml y tienes que añadir la cultura por defecto de la aplicación en el archivo settings.yml

Sistema de Cache

La clase sfFunctionCache ya no hereda de sfFileCache. Además, es necesario pasar un objeto de tipo caché al constructor. El primer argumento de ->call() ahora tiene que ser una función ejecutable de PHP.

El nombre de algunas opciones de configuración de sfCache ahora utilizan guiones bajos:

automaticCleaningFactor -> automatic_cleaning_factor
cacheDir -> cache_dir

La tarea project:upgrade1.1 realiza todos estos cambios de forma automática.

Carga automática de clases

La opción de configuración autoloading_function del archivo settings.yml ya no se utiliza. La clase de configuración de la aplicación permite registrar las funciones y clases que se cargan automáticamente.

Gracias al nuevo método sfAutoload::autoloadAgain(), ya no es necesario borrar la caché cada vez que se crean o modifican las clases de un proyecto. Este método detecta automáticamente todos los cambios y borra la caché de carga automática de clases.

VERSION

El archivo lib/VERSION ya no existe. Si quieres obtener la versión actual de Symfony, tienes que utilizar la constante SYMFONY_VERSION. Esta constante se define en autoload/sfCoreAutoload.class.php

Sistema de enrutamiento

Para incluir parámetros por defecto en las rutas, ahora se utiliza el método ->setDefaultParameter() en vez de la opción de configuración sf_routing_defaults:

$this->context->getRouting()->setDefaultParameter($clave, $valor);

Internacionalización (i18n)

Las clases del núcleo de Symfony ya no devuelven las cadenas de texto traducidas:

<?php echo __($sf_request->getError('valor')) ?>

El comportamiento anterior se ha cambiado por los siguientes métodos y funciones:

sfWebRequest::getError()
sfWebResponse::addMeta()

Los siguientes helpers (del plugin sfCompat10Plugin) todavía devuelven las cadenas de texto traducidas:

form_error()
include_metas()

La clase sfI18N ya no incluye los métodos getGlobalMessageSource() y getGlobalMessageFormat(). Ahora se utilizan getMessageSource() y getMessageFormat() respectivamente.

Mecanismo de logs

Los niveles de log ahora se establecen mediante constantes:

sfLogger::INFO

La tarea project:upgrade1.1 realiza todos estos cambios de forma automática.

Métodos de sfAction declarados obsoletos

Los siguientes métodos de sfAction se han declarado obsoletos y lanzan una excepción de tipo sfConfigurationException si la opción de configuración sf_compat_10 vale false:

->validate()
->handleError()

Métodos de sfRequest declarados obsoletos

Los siguientes métodos de sfRequest se han declarado obsoletos y lanzan una excepción de tipo sfConfigurationException si la opción de configuración sf_compat_10 vale false:

->getError()
->getErrors()
->getErrorNames()
->hasError()
->hasErrors()
->setError()
->setErrors()
->removeError()

Métodos de sfWebRequest declarados obsoletos

Los siguientes métodos de sfWebRequest se han declarado obsoletos y lanzan una excepción de tipo sfConfigurationException si la opción de configuración sf_compat_10 vale false:

->getFile()
->getFileError()
->getFileName()
->getFileNames()
->getFilePath()
->getFileSize()
->getFileType()
->hasFile()
->hasFileError()
->hasFileErrors()
->hasFiles()
->getFileValue()
->getFileValues()
->getFileExtension()
->moveFile()

Métodos ->initialize()

La mayoría de clases del núcleo de Symfony se inicializan mediante un método llamado ->initialize(). En Symfony 1.1 este método se invoca de forma automática desde __construct(), por lo que ya no es necesario invocarlo de forma manual

Carga de archivos de configuración

Algunas de las principales clases de Symfony se pueden configurar mediante un archivo de tipo .yml:

Clase Archivo de configuración
sfAction security.yml
sfAutoload autoload.yml
sfConfigCache config_handlers.yml
sfContext factories.yml
sfController generator.yml y module.yml
sfDatabaseManager databases.yml
sfFilterChain filters.yml
sfI18N i18n.yml
sfPatternRouting routing.yml
sfPHPView view.yml
sfViewCacheManager cache.yml

En Symfony 1.1 la carga del archivo de configuración de algunas de sus partes se realiza mediante el método loadConfiguration(), para que sea más fácil desacoplar esas partes y utilizarlas de forma independiente al resto del framework:

sfDatabaseManager
sfI18N
sfPatternRouting

Por lo tanto, si necesitas utilizar la base de datos en un archivo por lotes, se deben modificar las siguientes líneas de código:

$baseDatos = new sfDatabaseManager();
$baseDatos->initialize();

…por estas otras:

$configuracion = ProjectConfiguration::getApplicationConfiguration($aplicacion, $entorno, true);
$baseDatos = new sfDatabaseManager($configuracion);
$baseDatos->loadConfiguration();

La llamada a la función initialize() ya no es necesaria, tal y como se ha explicado anteriormente.

Depuración web

La opción de configuración web_debug desaparece del archivo filters.yml porque el filtro sfWebDebugFilter ya no existe. La barra de depuración web se incluye en la respuesta mediante un listener.

La tarea project:upgrade1.1 realiza todos estos cambios de forma automática.

Tiempo de validez de las sesiones

La opción de configuración sf_timeout ya no se utiliza. Para modificar el tiempo de validez de las sesiones, ahora se debe modificar el archivo factories.yml en vez de settings.yml. En concreto, se deben modificar la opciones de la factoría user:

all:
  user:
    class: myUser
    param:
      timeout: 1800 # session timeout in seconds

Configuración del sistema de enrutamiento

Las opciones sf_suffix, sf_default_module y sf_default_action ya no se utilizan. Para cambiar el sufijo, módulo o acción que se utilizan por defecto, se modifica el archivo factories.yml en vez de settings.yml. Las opciones se encuentran en la factoría routing:

all:
  routing:
    class: sfPatternRouting
    param:
      load_configuration: true
      suffix: . # Default suffix for generated URLs. If set to a single dot (.), no suffix is added. Possible values: .html, .php, and so on.
      default_module: default # Default module and action to be called when
      default_action: index # A routing rule doesn't set it

Archivo de configuración php.yml

El archivo de configuración php.yml ya no existe.

La única opción de configuración que se debe comprobar manualmente es log_errors, cuyo valor era on en el archivo php.yml.

El archivo php.yml se reemplaza por la utilidad check_configuration.php que se puede encontrar en el directorio data/bin y que comprueba si tus sistemas son compatibles con los requisitos de Symfony (por ejemplo la versión de PHP que esté instalada). La aplicación se puede ejecutar desde cualquier directorio:

$ php /ruta/hasta/symfony/data/bin/check_configuration.php

Aunque esta utilidad se puede ejecutar mediante la línea de comandos, se recomienda encarecidamente que la ejecutes desde un navegador copiándola en el directorio web raíz de tu aplicación, ya que PHP puede utilizar diferentes archivos de configuración php.ini para la línea de comandos y para la web.

Directorio $sf_symfony_data_dir

En Symfony 1.1, el directorio $sf_symfony_data_dir desaparece. Todos los archivos y directorios importantes del directorio data se han movido al directorio lib:

Ruta anterior Nueva ruta
data/config lib/config/config
data/i18n lib/i18n/data
data/skeleton lib/task/generator/skeleton
data/modules/default lib/controller/default
data/web/errors lib/exception/data
data/exception.* lib/exception/data

Todas las clases del núcleo de Symfony han modificado las rutas de acceso anteriores.

sfLoader

Todos los métodos estáticos de sfLoader (excepto ::getHelperDirs() y ::loadHelpers()) se han movido a las clases sfProjectConfiguration y sfApplicationConfiguration

sfProjectConfiguration:

  • ->getGeneratorSkeletonDirs()
  • ->getGeneratorTemplate()
  • ->getGeneratorTemplateDirs()
  • ->getModelDirs()

sfApplicationConfiguration:

  • ->getControllerDirs()
  • ->getTemplateDirs()
  • ->getTemplateDir()
  • ->getTemplatePath()
  • ->getI18NGlobalDirs()
  • ->getI18NDirs()
  • ->getConfigPaths()

sfCore

sfCore desaparece y su código se reparte entre las clases sfProjectConfiguration, sfApplicationConfiguration y sfContext.

Controladores frontales

Todos los controladores frontales tienen que ser actualizados. Las constantes SF_DEBUG, SF_APP, SF_ENVIRONMENT y SF_ROOT_DIR desaparecen. Si utilizas alguna de estas constantes en tu proyecto, tienes que utilizar en su lugar el método sfConfig::get(''):

Constante Método
SF_ROOT_DIR sfConfig::get('sf_root_dir')
SF_ENVIRONMENT sfConfig::get('sf_environment')
SF_APP sfConfig::get('sf_app')
SF_DEBUG sfConfig::get('sf_debug')

La tarea project:upgrade1.1 actualiza todos estos cambios en los controladores frontales. Si has hecho alguna modificación en los controladores, Symfony muestra un mensaje de aviso y no los actualiza. En este caso, puedes utilizar como base del nuevo controlador frontal el esqueleto que se encuentra en el archivo /ruta/hasta/symfony/lib/task/generator/skeleton/app/web/index.php

config.php

Todos los archivos de configuración config.php se han eliminado. En su lugar, se utiliza la clase ProjectConfiguration y las clases de configuración de cada aplicación.

Si has realizado algún cambio en los archivos config.php, tienes que adaptar los cambios para incluirlos en las nuevas clases.

Estructura de directorios

Se han eliminado todas las constantes de sfConfig que acaban en _dir_name.

Claves de la caché

Los métodos sfViewCacheManager::removePattern() y sfToolkit::clearGlob() ya no se pueden utilizar para borrar de una vez varias partes de la caché. No obstante, el método sfViewCacheManager::remove() ahora permite utilizar URL internas con comodines. De esta forma, se puede reemplazar la siguiente instrucción:

$cacheManager->removePattern('*/all/user/show/id/*');

por esta otra instrucción:

$cacheManager->remove('user/show?id=*', '*', 'all');

Lo anterior también se puede utilizar para los elementos parciales, de modo que la siguiente instrucción:

$cacheManager->removePattern('/sf_cache_partial/user/_my_partial/sf_cache_key/*');

se puede reemplazar por:

$cacheManager->remove('@sf_cache_partial?module=user&action=_my_partial&sf_cache_key=*');

Lo mejor de todo es que este nuevo método permite borrar los contenidos de cualquier caché, no sólo los que almacena sfFileCache.

Layout

Las variables de las plantillas ya no están disponibles en los layouts. Por lo tanto, los layouts sólo tienen acceso a las variables globales (todas las variables que empiezan por sf_) y a las variables registradas mediante el evento template.filter_parameters.

Leer más información sobre cómo actualizar los layouts para Symfony 1.1

Tareas

Se han modificado los nombres de todas las tareas de la línea de comandos de Symfony. El nuevo formato del nombre simula el uso de namespaces. No obstante, los nombres anteriores siguen funcionando a modo de alias del nuevo nombre de cada tarea. A continuación se muestran todos los cambios:

Nombre anterior Nuevo nombre
clear-cache cache:clear
clear-controllers project:clear-controllers
disable project:disable
downgrade No disponible
enable project:enable
fix-perms project:permissions
freeze project:freeze
init-app generate:app
init-batch No disponible
init-controller No disponible
init-module generate:module
init-project generate:project
log-purge log:clear
log-rotate log:rotate
plugin-install plugin:install
plugin-list plugin:list
plugin-uninstall plugin:uninstall
plugin-upgrade plugin:upgrade
propel-build-all propel:build-all
propel-build-all-load propel:build-all-load
propel:build-db propel:build-db
propel-build-model propel:build-model
propel-build-schema propel:build-schema
propel-build-sql propel:build-sql
propel-convert-xml-schema propel:schema-to-yml
propel-convert-yml-schema propel:schema-to-xml
propel-dump-data propel:data-dump
propel-generate-crud propel:generate-crud
propel-init-admin propel:init-admin
propel-init-crud No disponible
propel-insert-sql propel:insert-sql
propel-load-data propel:data-load
sync project:deploy
test-all test:all
test-functional test:functional
test-unit test:unit
unfreeze project:unfreeze
upgrade project:freeze

Al igual que en Symfony 1.0, si quieres ver la lista completa de tareas disponibles, sólo tienes que ejecutar el comando symfony sin ningún argumento:

> php symfony

AVISO para los que están probando las versiones beta de Symfony 1.1

Si has actualizado tu proyecto y tienes un archivo llamado lib/ProjectConfiguration.class.php, entonces tienes que actualizar tu proyecto a mano antes de poder ejecutar la tarea project:upgrade1.1.

A continuación se muestran los pasos que debes seguir:

1) Mueve el archivo lib/ProjectConfiguration.class.php a config/ProjectConfiguration.class.php

2) Si es necesario, modifica la ruta hasta Symfony en el archivo config/ProjectConfiguration.class.php.

3) Mueve todas las clases de configuración de la aplicación (lib/$NOMBRE_APLICACION$Configuration.class.php) a sus respectivos directorios en apps/$NOMBRE_APLICACION$/config/.

4) Elimina la instrucción require_once dirname(__FILE__).'/ProjectConfiguration.class.php'; en todas las clases de configuración de la aplicación.

5) Modifica la ruta del archivo ProjectConfiguration.class.php en el script symfony y pon la ruta del archivo que se encuentra en el directorio config/

6) Modifica todos los controladores frontales para que tengan el siguiente contenido:

<?php

require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php');

$configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'dev', true);
sfContext::createInstance($configuration)->dispatch();

Después de realizar todos estos cambios ya puedes ejecutar la tarea project:upgrade1.1 para completar el proceso de actualización.