Integración de Doctrine
Doctrine se ha actualizado a su versión 1.2, de la que puedes obtener más información en la documentación de su sitio web: http://www.doctrine-project.org/documentation/1_2/en
Generando las clases de formulario
Los esquemas YAML de Doctrine ahora permite especificar opciones adicionales pra Symfony, entre otras la posibilidad de deshabilitar la generación automática de filtros y formularios.
Si se considera el típico modelo muchos-a-muchos, no necesitas ningún formulario ni filtro para la clase que relaciona los dos modelos, por lo que puedes indicar lo siguiente:
UserGroup:
options:
symfony:
form: false
filter: false
columns:
user_id:
type: integer
primary: true
group_id:
type: integer
primary: true
Herencia de las clases de formulario
Cuando se generan los formularios de modelos que contienen herencia, las clases generadas ahora respetan esa herencia y generan formularios que siguen la misma estructura de herencia.
Nuevas tareas
Para facilitar la programación con Doctrine se han creado nuevas tareas.
Creando las tablas del modelo
Ahora se pueden crear individualmente las tablas de los modelos especificados. Las tablas se borran antes de intentar crearlas de nuevo. Su principal utilidad es cuando estás desarrollando nuevos modelos en un proyecto existente y no quieres cargarte toda la base de datos sino que es suficiente reconstruir un pequeño grupo de tablas.
$ php symfony doctrine:create-model-tables Modelo1 Modelo2 Modelo3
Borrar archivos del modelo
Resulta habitual modificar el contenido del esquema YAML renombrando modelos y columnas, creando nuevos modelos, borrando los modelos que ya no se usan, etc. Si borras un modelo existente en el esquema, te encontrarás con clases, formularios y filtros huérfanos que ya no se utilizan. Ahora es posible borrar manualmente todas las clases relacionadas con un modelo que ya no existe mediante la tarea doctrine:delete-model-files.
$ php symfony doctrine:delete-model-files NombreModelo
La tarea anterior busca todos los archivos generados automáticamente y que guardan relación con el modelo indicado. Antes de borrarlos, la tarea muestra todos los archivos encontrados y te pregunta si realmente quieres borrarlos.
Borrado automático de archivos del modelo
Si quieres automatizar el proceso anterior, puedes emplear la tarea doctrine:clean-model-files para buscar los modelos para los que existen archivos generados pero ya no están definidos en el esquema YAML.
$ php symfony doctrine:clean-model-files
El comando anterior compara tus esquemas YAML con los archivos y modelos generados para determinar lo que debe ser borrado. Los modelos marcados para borrar se pasan a la tarea doctrine:delete-model-files, que solicita la confirmación del usuario antes de borrarlos.
Recargar los datos
Eliminar toda la base de datos y volver a cargar la información de los archivos de datos es una operación habitual al desarrollar aplicaciones Symfony. La tarea doctrine:build-all-reload se encarga de ello y de muchas otras cosas como la generación de los modelos, formularios y filtros, por lo que es una tarea cuya ejecución lleva mucho tiempo en los proyectos grandes. Si sólo quieres cargar los datos, ahora puedes utilizar la tarea doctrine:reload-data.
El siguiente comando:
$ php symfony doctrine:reload-data
Es equivalente a ejecutar los siguientes comandos:
$ php symfony doctrine:drop-db $ php symfony doctrine:build-db $ php symfony doctrine:insert-sql $ php symfony doctrine:data-load
Generando de todo
La nueva tarea doctrine:build permite especificar exactamente lo que quieres que generen Symfony y Doctrine. Esta tarea reemplaza a muchas otras tareas combinadas, que han sido declaradas obsoletas en detrimento de esta solución mucho más flexible.
A continuación se muestran algunos ejemplos de uso de doctrine:build:
$ php symfony doctrine:build --db --and-load
El comando anterior elimina (:drop-db) y vuelve a crear (:build-db) la base de datos, también crea las tablas configuradas en schema.yml (:insert-sql) y carga la información de los archivos de datos (:data-load).
$ php symfony doctrine:build --all-classes --and-migrate
El comando anterior construye el modelo (:build-model), los formularios (:build-forms), los filtros (:build-filters) y ejecuta cualquier migración pendiente (:migrate).
$ php symfony doctrine:build --model --and-migrate --and-append=data/fixtures/categories.yml
El comando anterior construye el modelo (:build-model), migra la base de datos (:migrate) y carga un archivo de datos llamado categories.yml (:data-load --append --dir=data/fixtures/categories.yml).
Si quieres más información sobre esta tarea, consulta la ayuda de doctrine:build.
La nueva opción –migrate
Las siguientes tareas ahora incluyen una opción --migrate que reemplaza la tarea doctrine:insert-sql por doctrine:migrate.
doctrine:build-alldoctrine:build-all-loaddoctrine:build-all-reloaddoctrine:build-all-reload-test-alldoctrine:rebuild-dbdoctrine:reload-data
doctrine:generate-migration –editor-cmd
La tarea doctrine:generate-migration ahora incluye una opción llamada --editor-cmd que hace que se abra el editor de textos indicado justo después de generar la clase de la migración, para facilitar la edición de esa clase.
$ php symfony doctrine:generate-migration AddUserEmailColumn --editor-cmd=mate
En el ejemplo anterior, después de generar la clase de la migración se abrirá el archivo de la clase en el editor de textos TextMate.
doctrine:generate-migrations-diff
Esta nueva tara genera automáticamente clases de migraciones completas comparando tus nuevos y viejos esquemas de datos.
Crear o eliminar conexiones específicas
Cuando se ejecutan las tareas doctrine:build-db y doctrine:drop-db ahora se puede especificar el nombre de la conexión con la base de datos:
$ php symfony doctrine:drop-db master slave1 slave2
Setters y Getters de fechas
Se han añadido dos nuevos métodos para obtener las fechas de Doctrine o los timestamp como objetos de tipo DateTime de PHP.
echo $articulo->getDateTimeObject('created_at') ->format('m/d/Y');
También se puede establecer una fecha simplemente invocando el método setDateTimeObject y pasando una instancia válida de DateTime.
$articulo->setDateTimeObject('created_at', new DateTime('09/01/1985'));
doctrine:migrate –down
La tarea doctrine:migrate ahora incluye las opciones up y down para migrar el esquema de datos a una versión anterior o posterior a la actual.
$ php symfony doctrine:migrate --down
doctrine:migrate –dry-run
Si tu base de datos soporta el roll back de sentencias DDL (MySQL no lo soporta), puedes utilizar la nueva opción dry-run que ejecuta la tarea sin realizar ninguna modificación.
$ php symfony doctrine:migrate --dry-run
Mostrar un resultado DQL como una tabla
En las versiones anteriores, el resultado de ejecutar la tarea doctrine:dql se mostraba en formato YAML. Ahora se ha añadido la opción --table para mostrar el resultado como una tabla, similar a como se muestran los resultados en la línea de comandos de MySQL.
$ ./symfony doctrine:dql "FROM Articulo a" --table >> doctrine executing dql query DQL: FROM Articulo a +----+----------+----------------+---------------------+---------------------+ | id | autor_id | is_on_homepage | created_at | updated_at | +----+----------+----------------+---------------------+---------------------+ | 1 | 1 | | 2009-07-07 18:02:24 | 2009-07-07 18:02:24 | | 2 | 2 | | 2009-07-07 18:02:24 | 2009-07-07 18:02:24 | +----+----------+----------------+---------------------+---------------------+ (2 results)
Paso de parámetros a doctrine:dql
La tarea doctrine:dql también se ha mejorado para aceptar como argumentos los parámetros de tipo “query string”:
$ php symfony doctrine:dql "FROM Articulo a WHERE nombre LIKE ?" Jose%
Depurando consultas en las pruebas funcionales
La clase sfTesterDoctrine ahora incluye un método llamado ->debug(), que muestra toda la información sobre las consultas que se han ejecutado en el contexto actual.
$browser-> get('/articles')-> with('doctrine')->debug() ;
Si se pasa un número entero al método, sólo se muestran las N últimas consultas ejecutadas. Si se pasa una regular expresión como cadena de texto, sólo se muestran las consultas cuyo contenido cumpla co la expresión regular indicada.
$browser-> get('/articles')-> with('doctrine')->debug('/from articles/i') ;
sfFormFilterDoctrine
A la clase sfFormFilterDoctrine ahora se le puede pasar un objeto de tipo Doctrine_Query mediante la opción query:
$filter = new ArticleFormFilter(array(), array( 'query' => $table->createQuery()->select('title, body'), ));
El método de la tabla especificado mediante ->setTableMethod() (ahora mediante la opción table_method) ya no es necesario para devolver un objeto de tipo consulta. Cualquiera de los siguientes son métodos de tabla válidos para sfFormFilterDoctrine:
// funciona en Symfony >= 1.2 public function getQuery() { return $this->createQuery()->select('title, body'); } //funciona en Symfony >= 1.2 public function filterQuery(Doctrine_Query $query) { return $query->select('title, body'); } // funciona en Symfony >= 1.3 public function modifyQuery(Doctrine_Query $query) { $query->select('title, body'); }
Personalizar un filtro de formulario ahora es mucho más fácil. Si quieres añadir un nuevo campo de filtrado, sólo tienes que añadir un widget y el método que lo procesa.
class UserFormFilter extends BaseUserFormFilter { public function configure() { $this->widgetSchema['name'] = new sfWidgetFormInputText(); $this->validatorSchema['name'] = new sfValidatorString(array('required' => false)); } public function addNameColumnQuery($query, $field, $value) { if (!empty($value)) { $query->andWhere(sprintf('CONCAT(%s.f_name, %1$s.l_name) LIKE ?', $query->getRootAlias()), $value); } } }
En las versiones anteriores era necesario extender el método getFields() además de crear el widget y el método.
Configurando Doctrine
Ahora se puede configurar Doctrine mediante los eventos doctrine.configure y doctrine.configure_connection. Esto significa que incluso un plugin puede modificar fácilmente la configuración de Doctrine, siempre que el plugin se habilite antes que sfDoctrinePlugin.
doctrine:generate-module, doctrine:generate-admin y doctrine:generate-admin-for-route
Las tareas doctrine:generate-module, doctrine:generate-admin y doctrine:generate-admin-for-route ahora incluyen una opción llamada --actions-base-class que permite configurar la clase base de las acciones de los módulos generados automáticamente.
Métodos mágicos y etiquetas PHPdoc
Los métodos mágicos de tipo getter y setter que genera Symfony para los modelos de Doctrine ahora se incluyen dentro del PHPdoc de cada clase base generada. Si tu IDE soporta el autocompletado de código, ahora verás los métodos getLoQueSea() y setLoQueSea() en los objetos del modelo, donde LoQueSea es la versión CamelCase del nombre del campo.
Utilizando una versión diferente de Doctrine
Utilizar una versión diferente de Doctrine es tan sencillo como utilizar la variable de configuración sf_doctrine_dir en la clase ProjectConfiguration:
// config/ProjectConfiguration.class.php public function setup() { $this->enablePlugins('sfDoctrinePlugin'); sfConfig::set('sf_doctrine_dir', '/ruta/hasta/doctrine/lib'); }