SlideShare una empresa de Scribd logo
1 de 52
Desarrollo de aplicaciones con
Symfony 2
CRUD básico
@symfony_zgz
Symfony 2
Recordemos
algo ya visto en la
primera charla
Crear el proyecto Symfony 2
composer create-project symfony/framework-standard-edition <directorio> 2.4.*
Ejemplo en Windows
C:> composer create-project symfony/framework-standard-edition
"D:ProyectosCupon" 2.4.*
Ejemplo en Linux y Mac OS X
$ composer create-project symfony/framework-standard-edition "/prueba" 2.4.*
*Importante - Permisos
Un problema común al instalar Symfony2 es que los directorios
app/cache y app/logs deben tener permiso de escritura, tanto para el
servidor web cómo para el usuario de la consola de comandos.
Podeis ver como hacerlo en el apartado ‘3.1.2. Instalando y
configurando’ de
http://librosweb.es/symfony_2_4/capitulo_3/instalando_una_distribucio
n_de_symfony2.html
*Importante - Entornos
Si revisas el directorio web/, encontrarás dos archivos PHP: app.php y
app_dev.php. Estos archivos son controladores frontales: todas las
peticiones a la aplicación se hacen a través de ellos. Pero, ¿por qué
tenemos dos controladores frontales si hemos definido sólo una
aplicación?
Muy sencillo, ambos archivos apuntan a la misma aplicación pero para
distintos entornos.
Y un entorno symfony es un conjunto único de ajustes de
configuración. El framework Symfony incluye tres de ellos: dev, test, y
prod.
Producción: www.symfony-demo.local/app.php
Desarrollo: www.symfony-demo.local/app_dev.php
Comprobar la instalación
Antes de empezar a programar tu aplicación debes asegurarte de que tu
ordenador cumple con los requisitos para que Symfony2 funcione bien.
$ php app/check.php
El script check.php muestra por consola una lista de requisitos obligatorios
(Mandatory requirements) y otra lista de requisitos deseables (Optional
checks) para ejecutar Symfony2. No sigas adelante si incumples alguno de los
requisitos obligatorio
Estructura de directorios
app
Contiene los archivos de configuración, la caché, los logs y los recursos
globales.
app/config/
Guarda todos los archivos de configuración de la aplicación.
app/cache/
Contiene todos los archivos generados por las numerosas cachés de
Symfony2 (clases, enrutamiento, plantillas, entidades, validación, etc.). Junto
con el directorio app/logs/ es el único en el que Symfony2 debe tener
permisos de escritura.
Estructura de directorios
app/logs/
Contiene los archivos de log generados por la aplicación en cualquier entorno
de ejecución (desarrollo, producción, tests, etc.). Junto con el directorio
app/cache/ es el único en el que Symfony2 debe tener permisos de escritura.
app/Resources/
Almacena los recursos que se utilizan globalmente en el proyecto (como por
ejemplo el layout de las plantillas) o recursos muy especiales que no encajan
en ningún otro sitio (como por ejemplo una librería Java para comprimir
archivos CSS y JavaScript)
Estructura de directorios
src/
Guarda todo el código fuente propio del proyecto. Aquí es donde creas los
bundles de tu aplicación.
vendor/
Contiene todo el código fuente de Symfony2 y de todas las librerías externas.
web/
El único directorio público del proyecto. Contiene los archivos web (CSS,
JavaScript e imágenes) y los controladores frontales de la aplicación (app.php
y app_dev.php)
Estructura de directorios de un
bundle
( veámoslo en un editor)
YAML
YAML es un lenguaje muy sencillo que permite describir los datos como en
XML, pero con una sintaxis mucho más sencilla. YAML es un formato
especialmente útil para describir datos que pueden ser transformados en
arrays simples y asociativos.
$casa = array(
'familia' => array('apellido' => 'García', 'padres' => array('Antonio',
'María'), 'hijos' => array('Jose', 'Manuel', 'Carmen')),
'direccion' => array( 'numero' => 34, 'calle' => 'Gran Vía',
'ciudad' => 'Cualquiera', 'codigopostal' => '12345' )
);
YAML
casa:
familia:
apellido: García
padres:
- Antonio
- María
hijos:
- Jose
- Manuel
- Carmen
direccion:
numero: 34
calle: “Gran Vía”
ciudad: Cualquiera
codigopostal: “12345”
Doctrine
Doctrine es un mapeador de objetos-relacional (ORM) escrito en PHP que
proporciona una capa de persistencia para objetos PHP. Es una capa de
abstracción que se sitúa justo encima de un SGBD.
TWIG
Twig es un motor y lenguaje de plantillas para PHP muy rápido y eficiente.
Symfony2 recomienda utilizar Twig para crear todas las plantillas de la
aplicación. No obstante, si lo prefieres puedes seguir escribiendo las plantillas
con código PHP normal y corriente.
La sintaxis de Twig se ha diseñado para que las plantillas sean concisas y muy
fáciles de leer y de escribir.
Esto en Twig:
{% if usuario is defined %}
Hola {{ usuario.nombre }} hoy es {{ 'now' | date('d/m/Y') }}
{% endif %}
¿A que
esperamos?
¡Empecemos ya!
Symfony 2
Aplicando la filosofía de Symfony
Antes de empezar a programar la aplicación, es necesario adaptar todas las
funcionalidades y wireframes a la filosofía de trabajo de Symfony2. Planificar
bien el proyecto según la forma de pensar de Symfony2 te asegura que
podrás desarrollarlo lo más eficientemente posible.
El orden recomendado para aplicar la filosofía de
Symfony consiste en definir primero las entidades,
después los bundles y por último el enrutamiento.
Nuestro caso
Entidades
Solo una, Prueba (name, surname, email, phone)
Bundles
Solo uno, Prueba
Enrutamiento
/
/new/
/view/{id}
/edit/{id}
/delete/{id}
Creando el bundle
Dentro de un bundle puedes utilizar cualquier estructura de directorios, pero
Symfony2 espera que utilices una estructura muy específica para simplificar
su trabajo.
Para ayudarte, Symfony tiene el siguiente comando:
$ php app/console generate:bundle
Este comando te hará una serie de preguntas:
- Bundle namespace: SymfonyZgz/PruebaBundle
- Bundle name: PruebaBundle
- Target directory: <Enter> (para elegir el valor por defecto)
- Configuration format: yml
Creando el bundle
- Do you want to generate the whole directory structure?Respuesta
recomendada: no
- Confirm automatic update of your Kernel?, contesta yes para que el bundle
se active en la aplicación después de generarlo
- Confirm automatic update of the Routing?, contesta también yes para que
el archivo de enrutamiento del bundle se cargue automáticamente desde el
archivo de enrutamiento general de la aplicación.
Creando la entidad
Para ayudarte, Symfony tiene el siguiente comando:
$ php app/console doctrine:generate:entity
The Entity shortcut name: PruebaBundle:Prueba
Configuration format (yml, xml, php, or annotation) [annotation]: <Enter>
// Vamos creando los campos
New field name (press <return> to stop adding fields): nombre
Field type [string]: <Enter>
Field length [255]: <Enter>
La base de datos
# app/config/parameters.yml
parameters:
database_driver: pdo_mysql
database_host: 127.0.0.1
database_port: null
database_name: prueba
database_user: root
database_password: mipass
// Creando la base de datos
php app/console doctrine:database:create
// Creando la estructura
php app/console doctrine:schema:create
// Actualizando la estructura
php app/console doctrine:schema:update --force
Creando las rutas
# src/SymfonyZgz/PruebaBundle/Resources/config/routing.yml
prueba:
path: /
defaults: { _controller: "PruebaBundle:Prueba:index" }
prueba_new:
path: /new
defaults: { _controller: "PruebaBundle:Prueba:new" }
prueba_view:
path: /view/{id}
defaults: { _controller: "PruebaBundle:Prueba:view" }
prueba_edit:
path: /edit/{id}
defaults: { _controller: "PruebaBundle:Prueba:edit" }
prueba_delete:
path: /delete/{id}
defaults: { _controller: "PruebaBundle:Prueba:delete" }
Nuestro controlador
# src/SymfonyZgz/PruebaBundle/Controller/PruebaController.php
use SymfonyZgzPruebaBundleEntityPrueba;
use SymfonyZgzPruebaBundleFormPruebaType;
class PruebaController extends Controller
{
public function indexAction(){...}
public function newAction(){...}
public function viewAction(){...}
public function editAction(){...}
public function deleteAction(){...}
}
indexAction
public function indexAction(){
$results = $this->getDoctrine()->getRepository('PruebaBundle:Prueba’)->findAll();
return $this->render('PruebaBundle:Prueba:list.html.twig', array('results' => $results));
}
newAction
public function newAction(){
$prueba = new Prueba();
$form = $this->createForm(new PruebaType(), $prueba );
$request = $this->getRequest();
$form->handleRequest($request);
if($form->isSubmitted()){
if($form->isValid()){
$em = $this->getDoctrine()->getManager();
$em->persist($prueba);
$em->flush();
return $this->redirect(
$this->generateUrl('prueba_view', array('id' => $prueba )),301);
}
}
return $this->render('PruebaBundle:Prueba:edit.html.twig', array(
'form' => $form->createView(), 'prueba' => $prueba));
}
viewAction
public function viewAction($id){
$prueba = $this->getDoctrine()->getRepository('PruebaBundle:Prueba')->find($id);
return $this->render('PruebaBundle:Prueba:view.html.twig', array('prueba' => $prueba));
}
editAction
public function editAction($id){
$prueba = $this->getDoctrine()->getRepository('PruebaBundle:Prueba')->find($id);
$form = $this->createForm(new PruebaType(), $prueba );
$request = $this->getRequest();
$form->handleRequest($request);
if($form->isSubmitted()){
if($form->isValid()){
$em = $this->getDoctrine()->getManager();
$em->persist($prueba);
$em->flush();
return $this->redirect($this->generateUrl('prueba_view', array('id'
=> $id)),301);
}
}
return $this->render('PruebaBundle:Prueba:edit.html.twig', array(
'form' => $form->createView(), 'prueba' => $prueba));
}
deleteAction
public function deleteAction($id){
$prueba = $this->getDoctrine()->getRepository('PruebaBundle:Prueba')->find($id);
if($prueba){
$em = $this->getDoctrine()->getManager();
$em->remove($prueba);
$em->flush();
}
return $this->redirect( $this->generateUrl('prueba'), 301 );
}
Nuestro formulario
namespace SymfonyZgzPruebaBundleFormType;
use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentOptionsResolverOptionsResolverInterface;
class PruebaType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options){...}
public function setDefaultOptions(OptionsResolverInterface $resolver){..}
public function getName(){..}
}
Nuestro formulario - buildForm
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', <tipo>, <array options>)
->add('surname', 'text', array('label' => 'Apellidos','required' => false))
->add('email', 'text', array('label' => 'Email','required' => false))
->add('phone', 'text', array('label' => 'Teléfono’','required' => false));
$builder->add('save', 'submit');
}
Nuestro formulario-tipos de campo
Campos de texto
● text
● textarea
● email
● integer
● money
● number
● password
● percent
● search
● url
Campos de selección
● choice
● entity
● country
● language
● locale
● timezone
Campos de fecha y hora
● date
● datetime
● time
● birthday
● Otros campos
● checkbox
● file
● radio
Campos para grupos
● collection
● repeated
● Campos ocultos
● hidden
● csrf
● Campos base
● field
● form
Nuestro formulario - dataClass
Cada formulario debe conocer el nombre de la clase asociada al objeto manejado por el
formulario. Por lo general, esta información se deduce automáticamente en función del objeto
que se pasa como segundo argumento del método ‘createForm’, aunque es recomendable
indicarlo:
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'SymfonyZgzPruebaBundleEntityPrueba'
));
}
Nuestro formulario - getName
Simplemente devuelve un identificador único para este tipo de formulario.
public function getName()
{
return ‘prueba’;
}
Nuestro formulario - Validaciones
El método $form->isValid() en realidad es un atajo que pregunta al objeto $prueba si tiene datos
válidos o no.
Validación en archivo yml
# SymfonyZgz/PruebaBundle/Resources/config/validation.yml
SymfonyZgzPruebaBundleEntityPrueba:
properties:
name:
- NotBlank: ~
surname:
- NotBlank: ~
Nuestro formulario - Validaciones
Validación con anotaciones:
use SymfonyComponentValidatorConstraints as Assert;
class Prueba
{
/**
* @AssertNotBlank()
*/
public $name;
/**
* @AssertNotBlank()
*/
protected $surname;
}
Las vistas
Se crean en la carpeta:
src/SymfonyZgz/PruebaBundle/Resources/views/<nombre_controller>
En nuesto caso:
src/SymfonyZgz/PruebaBundle/Resources/views/Prueba
index.html.twig
edit.html.twig
view.html.twig
Si en lugar de utilizar Twig, quisiésemos utitilizar PHP, bastaría con
cambiar la extensión de la vista:
index.html.php
edit.html.php
…
Las vistas - index.html.twig
{% extends '::base.html.twig' %}
{% block body %}
<h1>Listado</h1>
<ul>
{% for row in results %}
<li>
{{ row.name }}
<a href="{{ path('prueba_view', { 'id': row.id }) }}">ver</a>
<a href="{{ path('prueba_edit', { 'id': row.id }) }}">edit</a>
<a href="{{ path('prueba_delete', { 'id': row.id }) }}">borrar</a>
</li>
{% endfor %}
</ul>
<a href="{{ path('prueba_new') }}">Nueva</a>
{% endblock %}
Las vistas - view.html.twig
{% extends '::base.html.twig' %}
{% block body %}
<h1>Ver</h1>
Id: {{ prueba.id }}<br/>
Name {{ prueba.name }}<br/>
Surname {{ prueba.surname }}<br/>
Email {{ prueba.email }}<br/>
Phone {{ prueba.phone }}<br/>
<br/>
<a href="{{ path('prueba_edit', { 'id': prueba.id }) }}">edit</a>
<a href="{{ path('prueba_delete', { 'id': prueba.id }) }}">borrar</a>
<a href="{{ path('prueba') }}">Listado</a>
{% endblock %}
Las vistas - edit.html.twig
{% extends '::base.html.twig' %}
{% block body %}
<h1>Edición</h1>
{{ form_start(form) }}
{{ form_errors(form) }}
{{ form_row(form.name) }}
{{ form_row(form.surname) }}
{{ form_row(form.email) }}
{{ form_row(form.phone) }}
{{ form_row(form.save) }}
{{ form_end(form) }}
<a href="{{ path('prueba') }}">Listado</a>
{% endblock %}
Las vistas - Formularios
form_start(form), muestra la etiqueta <form> de apertura del formulario.
form_errors(form), muestra los errores globales del formulario (los errores específicos se muestran al lado
de cada campo de formulario erróneo).
form_row(form.name), muestra el título, los errores (si los hay) y las etiquetas HTML necesarias para
mostrar el campo indicado (por ejemplo, dueDate). Por defecto todos estos elementos se agrupan dentro
de una etiqueta <div>.
form_end(form), muesta la etiqueta </form> de cierre del formulario y todos los campos de formulario que
no se han mostrado todavía. Por lo general es buena idea utilizar este helper en la parte inferior de cada
formulario (por si te has olvidado de mostrar algún campo o para no tener que mostrar uno a uno los
campos ocultos del formulario). Este helper también es muy útil para mostrar automáticamente el campo
oculto relacionado con la protección CSRF.
Si quisiésemos tener más control a la hora de pintar los campos, podríamos utilizar
en lugar de form_row:
{{ form_label(form.name) }}
{{ form_errors(form.mane) }}
{{ form_widget(form.name, { 'attr': {'class': 'mi_class'} }) }}
Las vistas - Un poco más
Uso de funciones:
{{ prueba.descripcion | striptags }}
{{ prueba.name | upper }}
Todos los filtros de Symfony2 se pueden encadenar para aplicarlos en cascada
{{ prueba.descripcion | striptags | upper }}
Fechas:
{{ prueba.fecha | date('d/m/Y') }}
Asignar un valor a las variables que no existen o están vacías.
{{ descripcion | default('Presentación de Symfony Zgz') }}
Twig por defecto escapa los caracteres hml. Para no aplicar el mecanismo de
escape en una determinada variable
{{ producto.descripcion | raw }}
Las vistas - Un poco más
Declarar variables:
{% set variable = valor %}
Arrays:
{% set miArray = [4, 8, 18] %}
Estructuras de control
{% for articulo in articulos %}
{# ... #}
{% endfor %}
{% if articulos is divisibleby(5) %}
{# ... #}
{% endif %}
Las vistas - Herencia
Plantilla base:
# base.html.twig #}
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>{% block titulo %}{% endblock %}</title>
<link href="estilos.css" rel="stylesheet" type="text/css" />
</head>
<body>
{% block contenido %}{% endblock %}
</body>
</html>
Las vistas - Herencia
{% extends 'base.html.twig' %}
{% block titulo %}Aquí pondríamos el título{% endblock %}
{% block contenido %}
Y aquí el contenido
{% endblock %}
Reutilizando el contenido de los bloques:
{% block contenido %}
<h1>{{ block('titulo') }}</h1>
Y aquí el contenido
{% endblock %}
Las vistas - Herencia
Anidando bloques
{% block contenido %}
<article>
{% block principal %}
<section></section>
{% endblock principal %}
{% block secundario %}
<aside></aside>
{% endblock secundario %}
</article>
{% endblock contenido %}
Las vistas - Herencia
Herencia dinámica
{% extends opciones.compacta ? 'listado.html.twig' : 'tabla.html.twig' %}
Reutilización
{% include '::admin/header.html.twig' %}
Reutilización dinámica
{% for oferta in ofertas %}
{% include oferta.tipo == 'destacada' ?
'destacada.html.twig' : 'oferta.html.twig' %}
{% endfor %}
¡¡¡ Tengo una pregunta !!!
Si esto se repite en
las mayoría de proyectos
¿no hay un comando?
Generar CRUD por consola
Todo el tiempo dedicado a realizar este CRUD podríamos haber ejecutado
este comando y habernos ido de cañas :)
php app/console generate:doctrine:crud --entity=PruebaBundle:Prueba
--format=yml --with-write
https://groups.google.com/forum/#!forum/symfony-zaragoza
@symfony_zgz
@david_labarta
@grisendo
¡ Gracias por su atención !
¿Preguntas?
Bibliografía
• http://symfony.com/doc
• Desarrollo web ágil con Symfony2:
http://symfony.es/libro/
• Symfony 2.4, el libro oficial:
http://librosweb.es/symfony_2_x/

Más contenido relacionado

La actualidad más candente

Base de datos
Base de datosBase de datos
Base de datosDavid
 
Comparativa sgbd comercial vs libre
Comparativa sgbd comercial vs libreComparativa sgbd comercial vs libre
Comparativa sgbd comercial vs libreFportavella
 
Ventajas vs desventajas de los gestores de bases
Ventajas  vs desventajas de los gestores de basesVentajas  vs desventajas de los gestores de bases
Ventajas vs desventajas de los gestores de basesMiluska Guerra Guerra
 
Introducción a la base de datos
Introducción a la base de datosIntroducción a la base de datos
Introducción a la base de datosAlexys González
 
Diagramas de uml generacion de codigos
Diagramas de uml generacion de codigosDiagramas de uml generacion de codigos
Diagramas de uml generacion de codigosJesus Rodriguez
 
Seguridad En Sistemas Distribuidos
Seguridad En Sistemas DistribuidosSeguridad En Sistemas Distribuidos
Seguridad En Sistemas DistribuidosHECTOR JAVIER
 
Seguridad en los sistemas operativos
Seguridad en los sistemas operativosSeguridad en los sistemas operativos
Seguridad en los sistemas operativosjetmu
 
Modelado de casos de uso
Modelado de casos de usoModelado de casos de uso
Modelado de casos de usobelleta55
 
Ciclos de vida orientados a objetos
Ciclos de vida orientados a objetosCiclos de vida orientados a objetos
Ciclos de vida orientados a objetosJose Diaz Silva
 
Modelamiento con uml definiciones
Modelamiento con uml definicionesModelamiento con uml definiciones
Modelamiento con uml definicionesBoris Salleg
 

La actualidad más candente (16)

Base de datos
Base de datosBase de datos
Base de datos
 
Comparativa sgbd comercial vs libre
Comparativa sgbd comercial vs libreComparativa sgbd comercial vs libre
Comparativa sgbd comercial vs libre
 
HA2NV50 EQ8-StarUML
HA2NV50 EQ8-StarUMLHA2NV50 EQ8-StarUML
HA2NV50 EQ8-StarUML
 
Ventajas vs desventajas de los gestores de bases
Ventajas  vs desventajas de los gestores de basesVentajas  vs desventajas de los gestores de bases
Ventajas vs desventajas de los gestores de bases
 
Introducción a la base de datos
Introducción a la base de datosIntroducción a la base de datos
Introducción a la base de datos
 
Diagramas de uml generacion de codigos
Diagramas de uml generacion de codigosDiagramas de uml generacion de codigos
Diagramas de uml generacion de codigos
 
Seguridad En Sistemas Distribuidos
Seguridad En Sistemas DistribuidosSeguridad En Sistemas Distribuidos
Seguridad En Sistemas Distribuidos
 
Seguridad en los sistemas operativos
Seguridad en los sistemas operativosSeguridad en los sistemas operativos
Seguridad en los sistemas operativos
 
Diagramas uml
Diagramas umlDiagramas uml
Diagramas uml
 
Diagrama de clases
Diagrama de clasesDiagrama de clases
Diagrama de clases
 
Java layered pane
Java layered paneJava layered pane
Java layered pane
 
Bases de datos orientadas a objetos
Bases de datos orientadas a objetosBases de datos orientadas a objetos
Bases de datos orientadas a objetos
 
Modelado de casos de uso
Modelado de casos de usoModelado de casos de uso
Modelado de casos de uso
 
Ciclos de vida orientados a objetos
Ciclos de vida orientados a objetosCiclos de vida orientados a objetos
Ciclos de vida orientados a objetos
 
Modelos de red
Modelos de redModelos de red
Modelos de red
 
Modelamiento con uml definiciones
Modelamiento con uml definicionesModelamiento con uml definiciones
Modelamiento con uml definiciones
 

Destacado

Desarrollo de aplicaciones web con PHP y symfony
Desarrollo de aplicaciones web con PHP y symfonyDesarrollo de aplicaciones web con PHP y symfony
Desarrollo de aplicaciones web con PHP y symfonyJuan Eladio Sánchez Rosas
 
Curso de Magento 1.9: Unidad Didáctica 08 Estructura de un Tema
Curso de Magento 1.9: Unidad Didáctica 08 Estructura de un TemaCurso de Magento 1.9: Unidad Didáctica 08 Estructura de un Tema
Curso de Magento 1.9: Unidad Didáctica 08 Estructura de un TemaDavid Vaquero
 
Curso de liferay 6.2: Unidad didáctica 02 Funcionalidades Principales
Curso de liferay 6.2: Unidad didáctica 02 Funcionalidades PrincipalesCurso de liferay 6.2: Unidad didáctica 02 Funcionalidades Principales
Curso de liferay 6.2: Unidad didáctica 02 Funcionalidades PrincipalesDavid Vaquero
 
Dns en linux debían squeeze 6
Dns  en linux debían squeeze 6Dns  en linux debían squeeze 6
Dns en linux debían squeeze 6Aldo Vilches Godoy
 
Symfony en Drupal 8 - DrupalCamp Spain
Symfony en Drupal 8 - DrupalCamp Spain Symfony en Drupal 8 - DrupalCamp Spain
Symfony en Drupal 8 - DrupalCamp Spain Raul Fraile
 
Adentrándonos al Framework Symfony
Adentrándonos al  Framework SymfonyAdentrándonos al  Framework Symfony
Adentrándonos al Framework SymfonyRodrigo Miranda
 
Desarrollo rápido con PHP y Symfony (I): Introducción a Symfony
Desarrollo rápido con PHP y Symfony (I): Introducción a SymfonyDesarrollo rápido con PHP y Symfony (I): Introducción a Symfony
Desarrollo rápido con PHP y Symfony (I): Introducción a SymfonyDavid J. Brenes
 
Django avanzado: Dia 2
Django avanzado: Dia 2Django avanzado: Dia 2
Django avanzado: Dia 2Esau Rodriguez
 
Taller de introducción al desarrollo web con Django
Taller de introducción al desarrollo web con DjangoTaller de introducción al desarrollo web con Django
Taller de introducción al desarrollo web con DjangoJuan Rodríguez
 
Django - Plataforma de sitios web
Django - Plataforma de sitios webDjango - Plataforma de sitios web
Django - Plataforma de sitios webjcarazo
 
Desarrollo rápido de apps web con laravel - DevAcademy
Desarrollo rápido de apps web con laravel - DevAcademyDesarrollo rápido de apps web con laravel - DevAcademy
Desarrollo rápido de apps web con laravel - DevAcademyJorge Antonio Linares Vera
 
Desarrollo Web Ágil con Symfony, Bootstrap y Angular
Desarrollo Web Ágil con Symfony, Bootstrap y AngularDesarrollo Web Ágil con Symfony, Bootstrap y Angular
Desarrollo Web Ágil con Symfony, Bootstrap y AngularFreelancer
 
Tienda virtual php_mysql
Tienda virtual php_mysqlTienda virtual php_mysql
Tienda virtual php_mysqljubacalo
 

Destacado (20)

Desarrollo de aplicaciones web con PHP y symfony
Desarrollo de aplicaciones web con PHP y symfonyDesarrollo de aplicaciones web con PHP y symfony
Desarrollo de aplicaciones web con PHP y symfony
 
Curso de Magento 1.9: Unidad Didáctica 08 Estructura de un Tema
Curso de Magento 1.9: Unidad Didáctica 08 Estructura de un TemaCurso de Magento 1.9: Unidad Didáctica 08 Estructura de un Tema
Curso de Magento 1.9: Unidad Didáctica 08 Estructura de un Tema
 
Curso de liferay 6.2: Unidad didáctica 02 Funcionalidades Principales
Curso de liferay 6.2: Unidad didáctica 02 Funcionalidades PrincipalesCurso de liferay 6.2: Unidad didáctica 02 Funcionalidades Principales
Curso de liferay 6.2: Unidad didáctica 02 Funcionalidades Principales
 
Introducción a Silex
Introducción a SilexIntroducción a Silex
Introducción a Silex
 
Dns en linux debían squeeze 6
Dns  en linux debían squeeze 6Dns  en linux debían squeeze 6
Dns en linux debían squeeze 6
 
Introducción a Symfony2
Introducción a Symfony2Introducción a Symfony2
Introducción a Symfony2
 
Sculpin
SculpinSculpin
Sculpin
 
Symfony en Drupal 8 - DrupalCamp Spain
Symfony en Drupal 8 - DrupalCamp Spain Symfony en Drupal 8 - DrupalCamp Spain
Symfony en Drupal 8 - DrupalCamp Spain
 
Adentrándonos al Framework Symfony
Adentrándonos al  Framework SymfonyAdentrándonos al  Framework Symfony
Adentrándonos al Framework Symfony
 
Desarrollo rápido con PHP y Symfony (I): Introducción a Symfony
Desarrollo rápido con PHP y Symfony (I): Introducción a SymfonyDesarrollo rápido con PHP y Symfony (I): Introducción a Symfony
Desarrollo rápido con PHP y Symfony (I): Introducción a Symfony
 
Django Avanzado: Dia3
Django Avanzado: Dia3Django Avanzado: Dia3
Django Avanzado: Dia3
 
Django avanzado: Dia 2
Django avanzado: Dia 2Django avanzado: Dia 2
Django avanzado: Dia 2
 
Presentación appy/pod
Presentación appy/podPresentación appy/pod
Presentación appy/pod
 
Django avanzado: Dia1
Django avanzado: Dia1Django avanzado: Dia1
Django avanzado: Dia1
 
Taller de introducción al desarrollo web con Django
Taller de introducción al desarrollo web con DjangoTaller de introducción al desarrollo web con Django
Taller de introducción al desarrollo web con Django
 
Composer: Gestionando dependencias en PHP
Composer: Gestionando dependencias en PHP Composer: Gestionando dependencias en PHP
Composer: Gestionando dependencias en PHP
 
Django - Plataforma de sitios web
Django - Plataforma de sitios webDjango - Plataforma de sitios web
Django - Plataforma de sitios web
 
Desarrollo rápido de apps web con laravel - DevAcademy
Desarrollo rápido de apps web con laravel - DevAcademyDesarrollo rápido de apps web con laravel - DevAcademy
Desarrollo rápido de apps web con laravel - DevAcademy
 
Desarrollo Web Ágil con Symfony, Bootstrap y Angular
Desarrollo Web Ágil con Symfony, Bootstrap y AngularDesarrollo Web Ágil con Symfony, Bootstrap y Angular
Desarrollo Web Ágil con Symfony, Bootstrap y Angular
 
Tienda virtual php_mysql
Tienda virtual php_mysqlTienda virtual php_mysql
Tienda virtual php_mysql
 

Similar a CRUD básico con Symfony

Mis primeros pasos con Symfony 2
Mis primeros pasos con Symfony 2Mis primeros pasos con Symfony 2
Mis primeros pasos con Symfony 2Edgar Dueñas
 
Clase 3 instalación y primeros pasos
Clase 3 instalación y primeros pasosClase 3 instalación y primeros pasos
Clase 3 instalación y primeros pasoshydras_cs
 
Symfony2 Formacion y primeros pasos
Symfony2  Formacion y primeros pasosSymfony2  Formacion y primeros pasos
Symfony2 Formacion y primeros pasosSoni BM
 
Creación de extensiones nativas
Creación de extensiones nativasCreación de extensiones nativas
Creación de extensiones nativasAngel Vazquez
 
Elementos sobre Symfony 2.1
Elementos sobre Symfony 2.1Elementos sobre Symfony 2.1
Elementos sobre Symfony 2.1Yaismel Miranda
 
Desplegando Proyectos Symfony2 con Capistrano-Capifony y Git
Desplegando Proyectos Symfony2 con Capistrano-Capifony y GitDesplegando Proyectos Symfony2 con Capistrano-Capifony y Git
Desplegando Proyectos Symfony2 con Capistrano-Capifony y Gitmoisesgallego
 
Symfony: construyendo aplicaciones web
Symfony: construyendo aplicaciones webSymfony: construyendo aplicaciones web
Symfony: construyendo aplicaciones websergiovier
 
Tutorial A Z A - Programador PHP
Tutorial A Z A - Programador PHPTutorial A Z A - Programador PHP
Tutorial A Z A - Programador PHPJuan Belón Pérez
 
Desarrollo Aplicaciones Zend Framework
Desarrollo Aplicaciones Zend FrameworkDesarrollo Aplicaciones Zend Framework
Desarrollo Aplicaciones Zend Frameworkricsoc
 
Programacion C#.NET
Programacion C#.NETProgramacion C#.NET
Programacion C#.NETSaviotec
 
Introducción a Zend Framework
Introducción a Zend FrameworkIntroducción a Zend Framework
Introducción a Zend FrameworkIrontec
 
Zend framework
Zend frameworkZend framework
Zend frameworkluislolo
 
Mi primer programa en Symfony2
Mi primer programa en Symfony2Mi primer programa en Symfony2
Mi primer programa en Symfony2César Hernández
 

Similar a CRUD básico con Symfony (20)

Mis primeros pasos con Symfony 2
Mis primeros pasos con Symfony 2Mis primeros pasos con Symfony 2
Mis primeros pasos con Symfony 2
 
Clase 3 instalación y primeros pasos
Clase 3 instalación y primeros pasosClase 3 instalación y primeros pasos
Clase 3 instalación y primeros pasos
 
Symfony Parte 2
Symfony Parte 2Symfony Parte 2
Symfony Parte 2
 
Symfony2 Formacion y primeros pasos
Symfony2  Formacion y primeros pasosSymfony2  Formacion y primeros pasos
Symfony2 Formacion y primeros pasos
 
Symfony
SymfonySymfony
Symfony
 
nn
nnnn
nn
 
TUTORIAL
TUTORIALTUTORIAL
TUTORIAL
 
Creación de extensiones nativas
Creación de extensiones nativasCreación de extensiones nativas
Creación de extensiones nativas
 
Elementos sobre Symfony 2.1
Elementos sobre Symfony 2.1Elementos sobre Symfony 2.1
Elementos sobre Symfony 2.1
 
Desplegando Proyectos Symfony2 con Capistrano-Capifony y Git
Desplegando Proyectos Symfony2 con Capistrano-Capifony y GitDesplegando Proyectos Symfony2 con Capistrano-Capifony y Git
Desplegando Proyectos Symfony2 con Capistrano-Capifony y Git
 
Symfony: construyendo aplicaciones web
Symfony: construyendo aplicaciones webSymfony: construyendo aplicaciones web
Symfony: construyendo aplicaciones web
 
CodeIgniter
CodeIgniterCodeIgniter
CodeIgniter
 
Resumen semana2
Resumen semana2Resumen semana2
Resumen semana2
 
Tutorial A Z A - Programador PHP
Tutorial A Z A - Programador PHPTutorial A Z A - Programador PHP
Tutorial A Z A - Programador PHP
 
Desarrollo Aplicaciones Zend Framework
Desarrollo Aplicaciones Zend FrameworkDesarrollo Aplicaciones Zend Framework
Desarrollo Aplicaciones Zend Framework
 
Programacion C#.NET
Programacion C#.NETProgramacion C#.NET
Programacion C#.NET
 
Introducción a Zend Framework
Introducción a Zend FrameworkIntroducción a Zend Framework
Introducción a Zend Framework
 
Sf2 pr5 mi primer proyecto
Sf2 pr5 mi primer proyectoSf2 pr5 mi primer proyecto
Sf2 pr5 mi primer proyecto
 
Zend framework
Zend frameworkZend framework
Zend framework
 
Mi primer programa en Symfony2
Mi primer programa en Symfony2Mi primer programa en Symfony2
Mi primer programa en Symfony2
 

Último

¡Descubre el Poder del Masaje Holístico en nuestra Primera Sesión del Seminar...
¡Descubre el Poder del Masaje Holístico en nuestra Primera Sesión del Seminar...¡Descubre el Poder del Masaje Holístico en nuestra Primera Sesión del Seminar...
¡Descubre el Poder del Masaje Holístico en nuestra Primera Sesión del Seminar...CENECOnline
 
Las redes sociales en el mercado digital
Las redes sociales en el mercado digitalLas redes sociales en el mercado digital
Las redes sociales en el mercado digitalNayaniJulietaRamosRa
 
Unidad V. Disoluciones quimica de las disoluciones
Unidad V. Disoluciones quimica de las disolucionesUnidad V. Disoluciones quimica de las disoluciones
Unidad V. Disoluciones quimica de las disolucioneschorantina325
 
Corte de luz 2024 Guayaquil Guayas ecuad
Corte de luz 2024 Guayaquil Guayas ecuadCorte de luz 2024 Guayaquil Guayas ecuad
Corte de luz 2024 Guayaquil Guayas ecuadJonathanHctorSilvaRo
 
PPT-HISTORIA-6°-ABC.pptxjjjjjjjjjjjjjjjjjjjjjj
PPT-HISTORIA-6°-ABC.pptxjjjjjjjjjjjjjjjjjjjjjjPPT-HISTORIA-6°-ABC.pptxjjjjjjjjjjjjjjjjjjjjjj
PPT-HISTORIA-6°-ABC.pptxjjjjjjjjjjjjjjjjjjjjjjNachisRamos
 
PSICOPATOLOGIA I.pptxdhehehehehehehehehe
PSICOPATOLOGIA I.pptxdhehehehehehehehehePSICOPATOLOGIA I.pptxdhehehehehehehehehe
PSICOPATOLOGIA I.pptxdheheheheheheheheheErickRolandoPadillaC1
 

Último (6)

¡Descubre el Poder del Masaje Holístico en nuestra Primera Sesión del Seminar...
¡Descubre el Poder del Masaje Holístico en nuestra Primera Sesión del Seminar...¡Descubre el Poder del Masaje Holístico en nuestra Primera Sesión del Seminar...
¡Descubre el Poder del Masaje Holístico en nuestra Primera Sesión del Seminar...
 
Las redes sociales en el mercado digital
Las redes sociales en el mercado digitalLas redes sociales en el mercado digital
Las redes sociales en el mercado digital
 
Unidad V. Disoluciones quimica de las disoluciones
Unidad V. Disoluciones quimica de las disolucionesUnidad V. Disoluciones quimica de las disoluciones
Unidad V. Disoluciones quimica de las disoluciones
 
Corte de luz 2024 Guayaquil Guayas ecuad
Corte de luz 2024 Guayaquil Guayas ecuadCorte de luz 2024 Guayaquil Guayas ecuad
Corte de luz 2024 Guayaquil Guayas ecuad
 
PPT-HISTORIA-6°-ABC.pptxjjjjjjjjjjjjjjjjjjjjjj
PPT-HISTORIA-6°-ABC.pptxjjjjjjjjjjjjjjjjjjjjjjPPT-HISTORIA-6°-ABC.pptxjjjjjjjjjjjjjjjjjjjjjj
PPT-HISTORIA-6°-ABC.pptxjjjjjjjjjjjjjjjjjjjjjj
 
PSICOPATOLOGIA I.pptxdhehehehehehehehehe
PSICOPATOLOGIA I.pptxdhehehehehehehehehePSICOPATOLOGIA I.pptxdhehehehehehehehehe
PSICOPATOLOGIA I.pptxdhehehehehehehehehe
 

CRUD básico con Symfony

  • 1. Desarrollo de aplicaciones con Symfony 2 CRUD básico @symfony_zgz
  • 2. Symfony 2 Recordemos algo ya visto en la primera charla
  • 3. Crear el proyecto Symfony 2 composer create-project symfony/framework-standard-edition <directorio> 2.4.* Ejemplo en Windows C:> composer create-project symfony/framework-standard-edition "D:ProyectosCupon" 2.4.* Ejemplo en Linux y Mac OS X $ composer create-project symfony/framework-standard-edition "/prueba" 2.4.*
  • 4. *Importante - Permisos Un problema común al instalar Symfony2 es que los directorios app/cache y app/logs deben tener permiso de escritura, tanto para el servidor web cómo para el usuario de la consola de comandos. Podeis ver como hacerlo en el apartado ‘3.1.2. Instalando y configurando’ de http://librosweb.es/symfony_2_4/capitulo_3/instalando_una_distribucio n_de_symfony2.html
  • 5. *Importante - Entornos Si revisas el directorio web/, encontrarás dos archivos PHP: app.php y app_dev.php. Estos archivos son controladores frontales: todas las peticiones a la aplicación se hacen a través de ellos. Pero, ¿por qué tenemos dos controladores frontales si hemos definido sólo una aplicación? Muy sencillo, ambos archivos apuntan a la misma aplicación pero para distintos entornos. Y un entorno symfony es un conjunto único de ajustes de configuración. El framework Symfony incluye tres de ellos: dev, test, y prod. Producción: www.symfony-demo.local/app.php Desarrollo: www.symfony-demo.local/app_dev.php
  • 6. Comprobar la instalación Antes de empezar a programar tu aplicación debes asegurarte de que tu ordenador cumple con los requisitos para que Symfony2 funcione bien. $ php app/check.php El script check.php muestra por consola una lista de requisitos obligatorios (Mandatory requirements) y otra lista de requisitos deseables (Optional checks) para ejecutar Symfony2. No sigas adelante si incumples alguno de los requisitos obligatorio
  • 7. Estructura de directorios app Contiene los archivos de configuración, la caché, los logs y los recursos globales. app/config/ Guarda todos los archivos de configuración de la aplicación. app/cache/ Contiene todos los archivos generados por las numerosas cachés de Symfony2 (clases, enrutamiento, plantillas, entidades, validación, etc.). Junto con el directorio app/logs/ es el único en el que Symfony2 debe tener permisos de escritura.
  • 8. Estructura de directorios app/logs/ Contiene los archivos de log generados por la aplicación en cualquier entorno de ejecución (desarrollo, producción, tests, etc.). Junto con el directorio app/cache/ es el único en el que Symfony2 debe tener permisos de escritura. app/Resources/ Almacena los recursos que se utilizan globalmente en el proyecto (como por ejemplo el layout de las plantillas) o recursos muy especiales que no encajan en ningún otro sitio (como por ejemplo una librería Java para comprimir archivos CSS y JavaScript)
  • 9. Estructura de directorios src/ Guarda todo el código fuente propio del proyecto. Aquí es donde creas los bundles de tu aplicación. vendor/ Contiene todo el código fuente de Symfony2 y de todas las librerías externas. web/ El único directorio público del proyecto. Contiene los archivos web (CSS, JavaScript e imágenes) y los controladores frontales de la aplicación (app.php y app_dev.php)
  • 10. Estructura de directorios de un bundle ( veámoslo en un editor)
  • 11. YAML YAML es un lenguaje muy sencillo que permite describir los datos como en XML, pero con una sintaxis mucho más sencilla. YAML es un formato especialmente útil para describir datos que pueden ser transformados en arrays simples y asociativos. $casa = array( 'familia' => array('apellido' => 'García', 'padres' => array('Antonio', 'María'), 'hijos' => array('Jose', 'Manuel', 'Carmen')), 'direccion' => array( 'numero' => 34, 'calle' => 'Gran Vía', 'ciudad' => 'Cualquiera', 'codigopostal' => '12345' ) );
  • 12. YAML casa: familia: apellido: García padres: - Antonio - María hijos: - Jose - Manuel - Carmen direccion: numero: 34 calle: “Gran Vía” ciudad: Cualquiera codigopostal: “12345”
  • 13. Doctrine Doctrine es un mapeador de objetos-relacional (ORM) escrito en PHP que proporciona una capa de persistencia para objetos PHP. Es una capa de abstracción que se sitúa justo encima de un SGBD.
  • 14. TWIG Twig es un motor y lenguaje de plantillas para PHP muy rápido y eficiente. Symfony2 recomienda utilizar Twig para crear todas las plantillas de la aplicación. No obstante, si lo prefieres puedes seguir escribiendo las plantillas con código PHP normal y corriente. La sintaxis de Twig se ha diseñado para que las plantillas sean concisas y muy fáciles de leer y de escribir. Esto en Twig: {% if usuario is defined %} Hola {{ usuario.nombre }} hoy es {{ 'now' | date('d/m/Y') }} {% endif %}
  • 16. Aplicando la filosofía de Symfony Antes de empezar a programar la aplicación, es necesario adaptar todas las funcionalidades y wireframes a la filosofía de trabajo de Symfony2. Planificar bien el proyecto según la forma de pensar de Symfony2 te asegura que podrás desarrollarlo lo más eficientemente posible. El orden recomendado para aplicar la filosofía de Symfony consiste en definir primero las entidades, después los bundles y por último el enrutamiento.
  • 17. Nuestro caso Entidades Solo una, Prueba (name, surname, email, phone) Bundles Solo uno, Prueba Enrutamiento / /new/ /view/{id} /edit/{id} /delete/{id}
  • 18. Creando el bundle Dentro de un bundle puedes utilizar cualquier estructura de directorios, pero Symfony2 espera que utilices una estructura muy específica para simplificar su trabajo. Para ayudarte, Symfony tiene el siguiente comando: $ php app/console generate:bundle Este comando te hará una serie de preguntas: - Bundle namespace: SymfonyZgz/PruebaBundle - Bundle name: PruebaBundle - Target directory: <Enter> (para elegir el valor por defecto) - Configuration format: yml
  • 19. Creando el bundle - Do you want to generate the whole directory structure?Respuesta recomendada: no - Confirm automatic update of your Kernel?, contesta yes para que el bundle se active en la aplicación después de generarlo - Confirm automatic update of the Routing?, contesta también yes para que el archivo de enrutamiento del bundle se cargue automáticamente desde el archivo de enrutamiento general de la aplicación.
  • 20. Creando la entidad Para ayudarte, Symfony tiene el siguiente comando: $ php app/console doctrine:generate:entity The Entity shortcut name: PruebaBundle:Prueba Configuration format (yml, xml, php, or annotation) [annotation]: <Enter> // Vamos creando los campos New field name (press <return> to stop adding fields): nombre Field type [string]: <Enter> Field length [255]: <Enter>
  • 21. La base de datos # app/config/parameters.yml parameters: database_driver: pdo_mysql database_host: 127.0.0.1 database_port: null database_name: prueba database_user: root database_password: mipass // Creando la base de datos php app/console doctrine:database:create // Creando la estructura php app/console doctrine:schema:create // Actualizando la estructura php app/console doctrine:schema:update --force
  • 22. Creando las rutas # src/SymfonyZgz/PruebaBundle/Resources/config/routing.yml prueba: path: / defaults: { _controller: "PruebaBundle:Prueba:index" } prueba_new: path: /new defaults: { _controller: "PruebaBundle:Prueba:new" } prueba_view: path: /view/{id} defaults: { _controller: "PruebaBundle:Prueba:view" } prueba_edit: path: /edit/{id} defaults: { _controller: "PruebaBundle:Prueba:edit" } prueba_delete: path: /delete/{id} defaults: { _controller: "PruebaBundle:Prueba:delete" }
  • 23. Nuestro controlador # src/SymfonyZgz/PruebaBundle/Controller/PruebaController.php use SymfonyZgzPruebaBundleEntityPrueba; use SymfonyZgzPruebaBundleFormPruebaType; class PruebaController extends Controller { public function indexAction(){...} public function newAction(){...} public function viewAction(){...} public function editAction(){...} public function deleteAction(){...} }
  • 24. indexAction public function indexAction(){ $results = $this->getDoctrine()->getRepository('PruebaBundle:Prueba’)->findAll(); return $this->render('PruebaBundle:Prueba:list.html.twig', array('results' => $results)); }
  • 25. newAction public function newAction(){ $prueba = new Prueba(); $form = $this->createForm(new PruebaType(), $prueba ); $request = $this->getRequest(); $form->handleRequest($request); if($form->isSubmitted()){ if($form->isValid()){ $em = $this->getDoctrine()->getManager(); $em->persist($prueba); $em->flush(); return $this->redirect( $this->generateUrl('prueba_view', array('id' => $prueba )),301); } } return $this->render('PruebaBundle:Prueba:edit.html.twig', array( 'form' => $form->createView(), 'prueba' => $prueba)); }
  • 26. viewAction public function viewAction($id){ $prueba = $this->getDoctrine()->getRepository('PruebaBundle:Prueba')->find($id); return $this->render('PruebaBundle:Prueba:view.html.twig', array('prueba' => $prueba)); }
  • 27. editAction public function editAction($id){ $prueba = $this->getDoctrine()->getRepository('PruebaBundle:Prueba')->find($id); $form = $this->createForm(new PruebaType(), $prueba ); $request = $this->getRequest(); $form->handleRequest($request); if($form->isSubmitted()){ if($form->isValid()){ $em = $this->getDoctrine()->getManager(); $em->persist($prueba); $em->flush(); return $this->redirect($this->generateUrl('prueba_view', array('id' => $id)),301); } } return $this->render('PruebaBundle:Prueba:edit.html.twig', array( 'form' => $form->createView(), 'prueba' => $prueba)); }
  • 28. deleteAction public function deleteAction($id){ $prueba = $this->getDoctrine()->getRepository('PruebaBundle:Prueba')->find($id); if($prueba){ $em = $this->getDoctrine()->getManager(); $em->remove($prueba); $em->flush(); } return $this->redirect( $this->generateUrl('prueba'), 301 ); }
  • 29. Nuestro formulario namespace SymfonyZgzPruebaBundleFormType; use SymfonyComponentFormAbstractType; use SymfonyComponentFormFormBuilderInterface; use SymfonyComponentOptionsResolverOptionsResolverInterface; class PruebaType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options){...} public function setDefaultOptions(OptionsResolverInterface $resolver){..} public function getName(){..} }
  • 30. Nuestro formulario - buildForm public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('name', <tipo>, <array options>) ->add('surname', 'text', array('label' => 'Apellidos','required' => false)) ->add('email', 'text', array('label' => 'Email','required' => false)) ->add('phone', 'text', array('label' => 'Teléfono’','required' => false)); $builder->add('save', 'submit'); }
  • 31. Nuestro formulario-tipos de campo Campos de texto ● text ● textarea ● email ● integer ● money ● number ● password ● percent ● search ● url Campos de selección ● choice ● entity ● country ● language ● locale ● timezone Campos de fecha y hora ● date ● datetime ● time ● birthday ● Otros campos ● checkbox ● file ● radio Campos para grupos ● collection ● repeated ● Campos ocultos ● hidden ● csrf ● Campos base ● field ● form
  • 32. Nuestro formulario - dataClass Cada formulario debe conocer el nombre de la clase asociada al objeto manejado por el formulario. Por lo general, esta información se deduce automáticamente en función del objeto que se pasa como segundo argumento del método ‘createForm’, aunque es recomendable indicarlo: public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array( 'data_class' => 'SymfonyZgzPruebaBundleEntityPrueba' )); }
  • 33. Nuestro formulario - getName Simplemente devuelve un identificador único para este tipo de formulario. public function getName() { return ‘prueba’; }
  • 34. Nuestro formulario - Validaciones El método $form->isValid() en realidad es un atajo que pregunta al objeto $prueba si tiene datos válidos o no. Validación en archivo yml # SymfonyZgz/PruebaBundle/Resources/config/validation.yml SymfonyZgzPruebaBundleEntityPrueba: properties: name: - NotBlank: ~ surname: - NotBlank: ~
  • 35. Nuestro formulario - Validaciones Validación con anotaciones: use SymfonyComponentValidatorConstraints as Assert; class Prueba { /** * @AssertNotBlank() */ public $name; /** * @AssertNotBlank() */ protected $surname; }
  • 36. Las vistas Se crean en la carpeta: src/SymfonyZgz/PruebaBundle/Resources/views/<nombre_controller> En nuesto caso: src/SymfonyZgz/PruebaBundle/Resources/views/Prueba index.html.twig edit.html.twig view.html.twig Si en lugar de utilizar Twig, quisiésemos utitilizar PHP, bastaría con cambiar la extensión de la vista: index.html.php edit.html.php …
  • 37. Las vistas - index.html.twig {% extends '::base.html.twig' %} {% block body %} <h1>Listado</h1> <ul> {% for row in results %} <li> {{ row.name }} <a href="{{ path('prueba_view', { 'id': row.id }) }}">ver</a> <a href="{{ path('prueba_edit', { 'id': row.id }) }}">edit</a> <a href="{{ path('prueba_delete', { 'id': row.id }) }}">borrar</a> </li> {% endfor %} </ul> <a href="{{ path('prueba_new') }}">Nueva</a> {% endblock %}
  • 38. Las vistas - view.html.twig {% extends '::base.html.twig' %} {% block body %} <h1>Ver</h1> Id: {{ prueba.id }}<br/> Name {{ prueba.name }}<br/> Surname {{ prueba.surname }}<br/> Email {{ prueba.email }}<br/> Phone {{ prueba.phone }}<br/> <br/> <a href="{{ path('prueba_edit', { 'id': prueba.id }) }}">edit</a> <a href="{{ path('prueba_delete', { 'id': prueba.id }) }}">borrar</a> <a href="{{ path('prueba') }}">Listado</a> {% endblock %}
  • 39. Las vistas - edit.html.twig {% extends '::base.html.twig' %} {% block body %} <h1>Edición</h1> {{ form_start(form) }} {{ form_errors(form) }} {{ form_row(form.name) }} {{ form_row(form.surname) }} {{ form_row(form.email) }} {{ form_row(form.phone) }} {{ form_row(form.save) }} {{ form_end(form) }} <a href="{{ path('prueba') }}">Listado</a> {% endblock %}
  • 40. Las vistas - Formularios form_start(form), muestra la etiqueta <form> de apertura del formulario. form_errors(form), muestra los errores globales del formulario (los errores específicos se muestran al lado de cada campo de formulario erróneo). form_row(form.name), muestra el título, los errores (si los hay) y las etiquetas HTML necesarias para mostrar el campo indicado (por ejemplo, dueDate). Por defecto todos estos elementos se agrupan dentro de una etiqueta <div>. form_end(form), muesta la etiqueta </form> de cierre del formulario y todos los campos de formulario que no se han mostrado todavía. Por lo general es buena idea utilizar este helper en la parte inferior de cada formulario (por si te has olvidado de mostrar algún campo o para no tener que mostrar uno a uno los campos ocultos del formulario). Este helper también es muy útil para mostrar automáticamente el campo oculto relacionado con la protección CSRF. Si quisiésemos tener más control a la hora de pintar los campos, podríamos utilizar en lugar de form_row: {{ form_label(form.name) }} {{ form_errors(form.mane) }} {{ form_widget(form.name, { 'attr': {'class': 'mi_class'} }) }}
  • 41. Las vistas - Un poco más Uso de funciones: {{ prueba.descripcion | striptags }} {{ prueba.name | upper }} Todos los filtros de Symfony2 se pueden encadenar para aplicarlos en cascada {{ prueba.descripcion | striptags | upper }} Fechas: {{ prueba.fecha | date('d/m/Y') }} Asignar un valor a las variables que no existen o están vacías. {{ descripcion | default('Presentación de Symfony Zgz') }} Twig por defecto escapa los caracteres hml. Para no aplicar el mecanismo de escape en una determinada variable {{ producto.descripcion | raw }}
  • 42. Las vistas - Un poco más Declarar variables: {% set variable = valor %} Arrays: {% set miArray = [4, 8, 18] %} Estructuras de control {% for articulo in articulos %} {# ... #} {% endfor %} {% if articulos is divisibleby(5) %} {# ... #} {% endif %}
  • 43. Las vistas - Herencia Plantilla base: # base.html.twig #} <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>{% block titulo %}{% endblock %}</title> <link href="estilos.css" rel="stylesheet" type="text/css" /> </head> <body> {% block contenido %}{% endblock %} </body> </html>
  • 44. Las vistas - Herencia {% extends 'base.html.twig' %} {% block titulo %}Aquí pondríamos el título{% endblock %} {% block contenido %} Y aquí el contenido {% endblock %} Reutilizando el contenido de los bloques: {% block contenido %} <h1>{{ block('titulo') }}</h1> Y aquí el contenido {% endblock %}
  • 45. Las vistas - Herencia Anidando bloques {% block contenido %} <article> {% block principal %} <section></section> {% endblock principal %} {% block secundario %} <aside></aside> {% endblock secundario %} </article> {% endblock contenido %}
  • 46. Las vistas - Herencia Herencia dinámica {% extends opciones.compacta ? 'listado.html.twig' : 'tabla.html.twig' %} Reutilización {% include '::admin/header.html.twig' %} Reutilización dinámica {% for oferta in ofertas %} {% include oferta.tipo == 'destacada' ? 'destacada.html.twig' : 'oferta.html.twig' %} {% endfor %}
  • 47. ¡¡¡ Tengo una pregunta !!!
  • 48. Si esto se repite en las mayoría de proyectos ¿no hay un comando?
  • 49. Generar CRUD por consola Todo el tiempo dedicado a realizar este CRUD podríamos haber ejecutado este comando y habernos ido de cañas :) php app/console generate:doctrine:crud --entity=PruebaBundle:Prueba --format=yml --with-write
  • 52. Bibliografía • http://symfony.com/doc • Desarrollo web ágil con Symfony2: http://symfony.es/libro/ • Symfony 2.4, el libro oficial: http://librosweb.es/symfony_2_x/