Curso Symfony - Clase 1

20,925 views
20,781 views

Published on

Presentación de la primera clase de un curso sobre el framework Symfony
--
Slides used in the first class of a symfony framework training.

Published in: Technology
3 Comments
39 Likes
Statistics
Notes
No Downloads
Views
Total views
20,925
On SlideShare
0
From Embeds
0
Number of Embeds
9,417
Actions
Shares
0
Downloads
0
Comments
3
Likes
39
Embeds 0
No embeds

No notes for slide
  • http://xkcd.com/285/
  • http://www.ibm.com/developerworks/xml/library/x-matters23.html
  • Curso Symfony - Clase 1

    1. 1. Frameworks de desarrollo Symfony Clase 1 Javier Eguíluz javier.eguiluz@gmail.com
    2. 2. Esta obra dispone de una licencia de tipo Creative Commons Reconocimiento‐No comercial‐ Compartir  bajo la misma licencia 3.0  Se prohíbe explícitamente el uso de este material en  actividades de formación comerciales http://creativecommons.org/licenses/by‐nc‐sa/3.0/es/
    3. 3. This work is licensed under a Creative Commons Attribution‐Noncommercial‐Share Alike 3.0  The use of these slides in commercial courses or trainings is explicitly prohibited http://creativecommons.org/licenses/by‐nc‐sa/3.0/es/
    4. 4. Capítulo 1 Comenzando el  proyecto
    5. 5. ¿Qué es  Symfony?
    6. 6. Framework para el  desarrollo de aplicaciones  web con PHP
    7. 7. • El más profesional • El más documentado • El mejor
    8. 8. PHP      Frameworks Productividad Calidad programación Mantenimiento Rendimiento aplicación
    9. 9. Curva de aprendizaje  de Symfony aprendizaje tiempo
    10. 10. ¿Qué es Jobeet?
    11. 11. diciembre 2008 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
    12. 12. La mejor forma de aprender  Symfony 1.2 a través de 24 tutoriales de 1 hora
    13. 13. Un tutorial diferente
    14. 14. • Serio • Profesional • Completo
    15. 15. Prerrequisitos
    16. 16. 5.2.4
    17. 17. Instalación de  Symfony
    18. 18. http://www.symfony‐project.org/installation/1_2 symfony‐1.2.4.tgz
    19. 19. check_configuration.php
    20. 20. $ php lib/vendor/symfony/data/bin/symfony
    21. 21. Preparar el  proyecto
    22. 22. frontend backend
    23. 23. proyecto jobeet aplicación backend frontend
    24. 24. $ symfony generate:project jobeet apps/ log/ cache/ plugins/ config/ test/ lib/ web/
    25. 25. frontend/ $ symfony config/ generate:app lib/ jobeet ‐‐escaping‐strategy=on modules/ ‐‐csrf‐secret=UniqueSecret frontend templates/
    26. 26. ‐‐escaping‐strategy XSS ‐‐csrf‐secret CSRF
    27. 27. config/ProjectConfiguration.class.php require_once dirname(__FILE__). '/../lib/vendor/'. 'symfony/lib/autoload/'. 'sfCoreAutoload.class.php';
    28. 28. Los entornos
    29. 29. • Entorno de desarrollo (dev) • Entorno de pruebas • Entorno intermedio • Entorno de producción (prod)
    30. 30. Errores en el entorno de desarrollo (dev)
    31. 31. Errores en el entorno de producción (prod)
    32. 32. web/index.php <?php require_once(dirname(__FILE__). '/../config/ProjectConfiguration.class.php'); $configuration =  ProjectConfiguration::getApplicationConfiguration( 'frontend', 'prod', false ); sfContext::createInstance($configuration)‐>dispatch();
    33. 33. Configurar bien el  servidor web
    34. 34. <VirtualHost 127.0.0.1:80> ServerName jobeet.localhost DocumentRoot quot;/home/sfprojects/jobeet/webquot; DirectoryIndex index.php <Directory quot;/home/sfprojects/jobeet/webquot;> AllowOverride All Allow from All </Directory> Alias /sf /home/sfprojects/jobeet/lib/vendor/symfony/data/web/sf <Directory quot;/home/sfprojects/jobeet/lib/vendor/symfony/data/web/sfquot;> AllowOverride All Allow from All </Directory> </VirtualHost>
    35. 35. /etc/hosts c:windowssystem32driversetchosts 127.0.0.1    jobeet.localhost
    36. 36. http://jobeet.localhost/ prod
    37. 37. http://jobeet.localhost/frontend_dev.php dev
    38. 38. Versionado de  código
    39. 39. Capítulo 2 El proyecto
    40. 40. La idea del  proyecto
    41. 41. Aplicación de software  libre que permite crear  sitios web de búsqueda  de empleo
    42. 42. características • Completo y personalizable • Multilingüe • AJAX, RSS y API
    43. 43. Los escenarios del  proyecto
    44. 44. • administrador (admin) • usuario (user) • publicador (poster) • afiliado (affiliate)
    45. 45. F1 El usuario accede a  la portada y ve las  últimas ofertas de  trabajo activas
    46. 46. F2 El usuario puede  visualizar todas  las ofertas de  trabajo de una  categoría
    47. 47. F3 El usuario refina el  listado mediante  palabras clave
    48. 48. F4 El usuario pincha  sobre una oferta de  trabajo para ver  más información
    49. 49. F5 El usuario publica  una nueva oferta  de trabajo
    50. 50. F6 El usuario quiere  convertirse en un  afiliado
    51. 51. F7 Un usuario afiliado  obtiene la lista de  ofertas de trabajo  activas
    52. 52. B1 El administrador configura el sitio web B2 El administrador gestiona las ofertas de  trabajo B3 El administrador gestiona los afiliados
    53. 53. Capítulo 3 El modelo de  datos
    54. 54. El modelo  relacional
    55. 55. relacional objetos ORM
    56. 56. 1. Describir la base de datos 2. Generar las clases PHP 3. Trabajar con objetos en vez  de SQL
    57. 57. El formato YAML
    58. 58. YAML Formato para serializar datos que  es fácil de leer por las personas y es  compatible con todos los lenguajes  de programación
    59. 59. $casa = array( 'familia' => array( 'apellido' => 'García', 'padres' => array('Antonio', 'María'),    'hijos' => array('Jose', 'Manuel') ), 'direccion' => array( 'numero' => 34, 'calle' => 'Gran Vía', 'ciudad' => 'Cualquiera', 'codigopostal' => '12345' ) );
    60. 60. casa: familia: apellido: García padres: ‐ Antonio ‐ María hijos: ‐ Jose ‐ Manuel direccion: numero: 34 calle: Gran Vía ciudad: Cualquiera codigopostal: quot;12345quot;
    61. 61. casa: familia: { apellido: García, padres: [Antonio,  María], hijos: [Jose, Manuel] } direccion: { numero: 34, direccion: Gran Vía,  ciudad: Cualquiera, codigopostal: quot;12345quot; }
    62. 62. Sintaxis clave: clave: clave: valor clave: valor clave: clave: valor clave: 2 espacios  ‐ valor en blanco ‐ valor
    63. 63. Arrays normales clave: ‐ valor1 ‐ valor2 ‐ valor3 clave:[valor1, valor2, valor3]
    64. 64. Arrays asociativos clave: clave1: valor1 clave2: valor2 clave3: valor3 clave: { clave1: valor1,  clave2: valor2, clave3: valor3}
    65. 65. <?xml version=quot;1.0quot;?> XML YAML <club> players: <players> Vladimir Kramnik: &kramnik <player id=quot;kramnikquot; name=quot;Vladimir rating: 2700 Kramnikquot; rating=quot;2700quot; status=quot;GMquot; />  <player id=quot;fritzquot; name=quot;Deep status: GM Fritzquot; rating=quot;2700quot; status=quot;Computerquot;  Deep Fritz: &fritz /> rating: 2700 <player id=quot;mertzquot; name=quot;David  status: Computer Mertzquot; rating=quot;1400quot; status=quot;Amateurquot;  David Mertz: &mertz /> rating: 1400 </players> status: Amateur <matches> matches: <match> <Date>2002‐10‐04</Date> ‐ <White refid=quot;fritzquot; />  Date: 2002‐10‐04 <Black refid=quot;kramnikquot; />  White: *fritz <Result>Draw</Result>  Black: *kramnik </match> Result: Draw <match> ‐ <Date>2002‐10‐06</Date> Date: 2002‐10‐06 <White refid=quot;kramnikquot; /> White: *kramnik <Black refid=quot;fritzquot; /> <Result>White</Result> Black: *fritz </match> Result: White </matches> </club> 
    66. 66. El esquema
    67. 67. config/schema.yml propel: jobeet_category: id:   ~ name: { type: varchar(255), required: true, index: unique } jobeet_job: id:           ~ category_id:  { type: integer, foreignTable: jobeet_category, foreignReference: id, required: true } type:         { type: varchar(255) } company:      { type: varchar(255), required: true } logo:         { type: varchar(255) } url:          { type: varchar(255) } position:     { type: varchar(255), required: true } location:     { type: varchar(255), required: true } description:  { type: longvarchar, required: true } how_to_apply: { type: longvarchar, required: true } token:        { type: varchar(255), required: true, index: unique } is_public:    { type: boolean, required: true, default: 1 } is_activated: { type: boolean, required: true, default: 0 } email:        { type: varchar(255), required: true } expires_at:   { type: timestamp, required: true } created_at:   ~ updated_at:   ~ jobeet_affiliate: id:         ~ url:        { type: varchar(255), required: true } email:      { type: varchar(255), required: true, index: unique } token:      { type: varchar(255), required: true } is_active:  { type: boolean, required: true, default: 0 } created_at: ~ jobeet_category_affiliate: category_id:  { type: integer, foreignTable: jobeet_category, foreignReference: id, required: true, primaryKey:  true, onDelete: cascade } affiliate_id: { type: integer, foreignTable: jobeet_affiliate, foreignReference: id, required: true, primaryKey:  true, onDelete: cascade }
    68. 68. config/schema.yml propel: jobeet_category: id:   ~ name: { type: varchar(255), required: true, index: unique }
    69. 69. config/schema.yml jobeet_job: id:           ~ category_id:  { type: integer, foreignTable: jobeet_category,  foreignReference: id, required: true } type:         { type: varchar(255) } company:      { type: varchar(255), required: true } logo:         { type: varchar(255) } url:          { type: varchar(255) } position:     { type: varchar(255), required: true } location:     { type: varchar(255), required: true } description:  { type: longvarchar, required: true } how_to_apply: { type: longvarchar, required: true } token:        { type: varchar(255), required: true, index:  unique } is_public:    { type: boolean, required: true, default: 1 } is_activated: { type: boolean, required: true, default: 0 } email:        { type: varchar(255), required: true } expires_at:   { type: timestamp, required: true } created_at:   ~ updated_at:   ~
    70. 70. config/schema.yml jobeet_affiliate: id:         ~ url:        { type: varchar(255), required: true } email:      { type: varchar(255), required: true, index: unique } token:      { type: varchar(255), required: true } is_active:  { type: boolean, required: true, default: 0 } created_at: ~
    71. 71. config/schema.yml jobeet_category_affiliate: category_id:  { type: integer, foreignTable: jobeet_category, foreignReference: id, required: true, primaryKey: true, onDelete: cascade } affiliate_id: { type: integer, foreignTable: jobeet_affiliate, foreignReference: id, required: true, primaryKey: true, onDelete: cascade }
    72. 72. config/schema.yml type: boolean, tinyint, smallint, integer, bigint, double, float,  • real, decimal, char, varchar(size), longvarchar, date, time,  timestamp, blob, clob required: true, false • index: true, false • primaryKey: true, false • foreignKey, foreignReference •
    73. 73. La base de datos
    74. 74. $ mysqladmin ‐uroot ‐p create jobeet $ symfony configure:database “mysql:host=localhost;dbname=jobeet” root ConTraSenA config/databases.yml
    75. 75. El ORM
    76. 76. $ symfony propel:build‐sql data/sql/ $ symfony propel:insert‐sql ‐‐no‐confirmation $ symfony propel:build‐model lib/model/
    77. 77. extends JobeetJob • BaseJobeetJob • extends JobeetJobPeer • BaseJobeetJobPeer •
    78. 78. $job = new JobeetJob(); $job‐>setPosition('Web developer'); $job‐>save(); echo $job‐>getPosition(); $job‐>delete();
    79. 79. $category = new JobeetCategory();  $category‐>setName('Programming'); $job = new JobeetJob(); $job‐>setCategory($category);
    80. 80. $ symfony propel:build‐all ‐‐no‐confirmation
    81. 81. $ symfony propel:build‐sql $ symfony propel:insert‐sql $ symfony propel:build‐model $ symfony propel:build‐forms + $ symfony propel:build‐filters $ symfony propel:build‐all
    82. 82. $ symfony cc Borra la caché de Symfony • • Ejecutar siempre que añades  clases (autoload) • La solución de casi todos los  errores de los principiantes
    83. 83. $ symfony cache:clear $ symfony cache:cl $ symfony ca:c $ symfony cc
    84. 84. Los datos iniciales
    85. 85. data/fixtures/ Datos iniciales • Datos de prueba • Datos de usuarios •
    86. 86. data/fixtures/010_categories.yml JobeetCategory: design:        { name: Design } programming:   { name: Programming } manager:       { name: Manager } administrator: { name: Administrator }
    87. 87. data/fixtures/020_jobs.yml JobeetJob: job_sensio_labs: category_id:  programming type:         full‐time company:      Sensio Labs logo:         sensio‐labs.gif url:          http://www.sensiolabs.com/ position:     Web Developer location:     Paris, France description:  | You have already developed websites with symfony and you want to work with Open‐Source technologies. You have a minimum of  3 years experience in web development with PHP or Java and you wish to participate to development of Web 2.0 sites using the best frameworks available. how_to_apply: | Send your resume to fabien.potencier [at] sensio.com is_public:    true is_activated: true token:        job_sensio_labs email:        job@example.com expires_at:   2010‐10‐10
    88. 88. $ symfony propel:data‐load
    89. 89. $ symfony propel:build‐sql $ symfony propel:insert‐sql $ symfony propel:build‐model $ symfony propel:build‐forms $ symfony propel:build‐filters + $ symfony propel:data‐load $ symfony propel:build‐all‐load
    90. 90. Probando la  aplicación en el  navegador
    91. 91. proyecto jobeet aplicación backend frontend job módulo
    92. 92. $ symfony propel:generate‐module ‐‐with‐show ‐‐non‐verbose‐templates frontend job JobeetJob frontend/modules/job actions/ templates/
    93. 93. frontend/modules/job/actions/actions.class.php index edit show update delete new create
    94. 94. http://jobeet.localhost/frontend_dev.php/job frontend _dev job
    95. 95. Representación  Objeto textual _ _toString() Categoría
    96. 96. lib/model/JobeetCategory.php class JobeetCategory extends BaseJobeetCategory { public function __toString() { return $this‐>getName(); } }
    97. 97. lib/model/JobeetJob.php class JobeetJob extends BaseJobeetJob { public function __toString() { return sprintf( '%s at %s (%s)', $this‐>getPosition(), $this‐>getCompany(), $this‐>getLocation() ); } }
    98. 98. lib/model/JobeetAffiliate.php class JobeetAffiliate extends BaseJobeetAffiliate { public function __toString() { return $this‐>getUrl(); } }
    99. 99. http://jobeet.localhost/frontend_dev.php/job
    100. 100. Capítulo 4 El controlador y  la vista
    101. 101. La arquitectura MVC
    102. 102. ¿Cómo se programaba con PHP en  el siglo pasado? 1 página del  1 archivo PHP  = sitio web diferente
    103. 103. ¿Cómo se programaba con PHP en  el siglo pasado? inicialización y  configuración lógica de  negocio acceso a BBDD generar  código HTML pagina.php
    104. 104. Modelo Vista Controlador
    105. 105. Modelo Directorio /lib/model Vista Directorios templates/ Controlador Archivos index.php y frontend_dev.php Archivos actions.class.php
    106. 106. El layout
    107. 107. patrón de diseño decorator apps/frontend/templates/layout.php
    108. 108. apps/frontend/templates/layout.php <!DOCTYPE html PUBLIC quot;‐//W3C//DTD XHTML 1.0 Transitional//ENquot; quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1‐transitional.dtdquot;> <html xmlns=quot;http://www.w3.org/1999/xhtmlquot; xml:lang=quot;enquot; lang=quot;enquot;> <head> <title>Jobeet ‐ Your best job board</title> <link rel=quot;shortcut iconquot; href=quot;/favicon.icoquot; /> <?php include_javascripts() ?> <?php include_stylesheets() ?> </head> <body> ... <div class=quot;contentquot;> <?php echo $sf_content ?> </div> </body> </html>
    109. 109. Plantillas Symfony • Archivos PHP  normales • Existe un plugin  para Smarty • Symfony 2.0 podría  incluir plantillas
    110. 110. Las hojas de estilos,  imágenes y archivos  JavaScript
    111. 111. helpers <head> ... <?php include_stylesheets() ?> </head>
    112. 112. apps/frontend/config/view.yml default: http_metas: content‐type: text/html metas: #title: symfony project #description: symfony project #keywords: symfony, project #language: en #robots: index, follow stylesheets: [main.css] javascripts: [] has_layout: on layout: layout
    113. 113. apps/frontend/config/view.yml default: ... stylesheets:  [main.css, jobs.css, job.css] ... <link rel=quot;stylesheetquot; type=quot;text/cssquot;  media=quot;screenquot; href=quot;/css/main.cssquot; /> <link rel=quot;stylesheetquot; type=quot;text/cssquot;  media=quot;screenquot; href=quot;/css/jobs.cssquot; /> <link rel=quot;stylesheetquot; type=quot;text/cssquot;  media=quot;screenquot; href=quot;/css/job.cssquot; />
    114. 114. apps/frontend/config/view.yml default: ... stylesheets:  [main.css, jobs.css, job] ... <link rel=quot;stylesheetquot; type=quot;text/cssquot;  media=quot;screenquot; href=quot;/css/main.cssquot; /> <link rel=quot;stylesheetquot; type=quot;text/cssquot;  media=quot;screenquot; href=quot;/css/jobs.cssquot; /> <link rel=quot;stylesheetquot; type=quot;text/cssquot;  media=quot;screenquot; href=quot;/css/job.cssquot; />
    115. 115. apps/frontend/config/view.yml default: ... stylesheets:  [main.css, /css/v2/jobs.css] ... <link rel=quot;stylesheetquot; type=quot;text/cssquot;  media=quot;screenquot; href=quot;/css/main.cssquot; /> <link rel=quot;stylesheetquot; type=quot;text/cssquot;  media=quot;screenquot; href=quot;/css/v2/jobs.cssquot; />
    116. 116. apps/frontend/config/view.yml default: ... stylesheets: [main.css, jobs: { media: print } ] ... <link rel=quot;stylesheetquot; type=quot;text/cssquot;  media=quot;screenquot; href=quot;/css/main.cssquot; /> <link rel=quot;stylesheetquot; type=quot;text/cssquot;  media=quot;printquot; href=quot;/css/jobs.cssquot; />
    117. 117. metas: Symfony title: El título 1 metas: Proyecto title: El título 2 metas: Aplicación title: El título 3 metas: Módulo title: El título 4 view.yml
    118. 118. Symfony lib/vendor/symfony/lib/config/config/view.yml Proyecto config/view.yml Aplicación apps/frontend/config/view.yml Módulo apps/frontend/modules/job/config/view.yml
    119. 119. metas: stylesheets: [job] <?php use_stylesheet(‘job.css’) view.yml ?> plantilla plantilla
    120. 120. La portada del módulo  de las ofertas de  trabajo
    121. 121. apps/ frontend/ modules/ job/ actions/ actions.class.php templates/ indexSuccess.php
    122. 122. acción + = plantilla
    123. 123. http://jobeet.localhost/frontend_dev.php/job/index frontend (aplicación) _dev (entorno) job (módulo) index (acción executeIndex y  plantilla indexSuccess)
    124. 124. apps/frontend/modules/job/actions/actions.class.php class jobActions extends sfActions { public function executeIndex(sfWebRequest $request) { $this‐>jobeet_job_list = JobeetJobPeer::doSelect(new Criteria()); } // ... }
    125. 125. SELECT [ALL | DISTINCT | DISTINCTROW ] [HIGH_PRIORITY] [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] select_expr [, select_expr ...] [FROM table_references [WHERE where_condition] [GROUP BY {col_name | expr | position} [ASC | DESC], ... [WITH ROLLUP]] [HAVING where_condition] [ORDER BY {col_name | expr | position} [ASC | DESC], ...] [LIMIT {[offset,] row_count | row_count OFFSET offset}] [PROCEDURE procedure_name(argument_list)] [INTO OUTFILE 'file_name' export_options | INTO DUMPFILE 'file_name' | INTO var_name [, var_name]] [FOR UPDATE | LOCK IN SHARE MODE]]
    126. 126. apps/frontend/modules/job/templates/indexSuccess.php <?php foreach ($jobeet_job_list as $jobeet_job): ?> ... <td> <a href=quot;...quot;> <?php echo $jobeet_job‐>getId() ?> </a> </td> ... <?php endforeach; ?> 
    127. 127. La plantilla de la página  de una oferta de  trabajo
    128. 128. Slots
    129. 129. <title>Jobeet</title> <title> layout plantilla
    130. 130. <title>             </title> Título de la página layout plantilla
    131. 131. apps/frontend/templates/layout.php <title> <?php include_slot('title') ?> </title> apps/frontend/modules/job/templates/indexSuccess.php <?php slot('title', 'Título de la página') ?>  <?php slot( 'title', sprintf('%s is looking for a %s', $job‐>getCompany(), $job‐>getPosition() ) ) ?> 
    132. 132. La acción de la página  de una oferta de  trabajo
    133. 133. apps/frontend/modules/job/actions/actions.class.php public function executeShow(sfWebRequest $request) { $this‐>job = JobeetJobPeer::retrieveByPk( $request‐>getParameter('id') ); $this‐>forward404Unless($this‐>job); }
    134. 134. La petición y la  respuesta
    135. 135. objeto sfWebRequest class jobActions extends sfActions { public function executeShow(sfWebRequest $request) { $peticion = $request; $origen = $peticion‐>getReferer(); $metodo = $peticion‐>getMethod(); } // ... }
    136. 136. Nombre del método Equivalente de PHP getMethod() $_SERVER['REQUEST_METHOD'] getUri() $_SERVER['REQUEST_URI'] getReferer() $_SERVER['HTTP_REFERER'] getHost() $_SERVER['HTTP_HOST'] getLanguages() $_SERVER['HTTP_ACCEPT_LANGUAGE'] getCharsets() $_SERVER['HTTP_ACCEPT_CHARSET'] isXmlHttpRequest() $_SERVER['X_REQUESTD_WITH'] == 'XMLHttpRequest' getHttpHeader() $_SERVER getCookie() $_COOKIE isSecure() $_SERVER['HTTPS'] getFiles() $_FILES getGetParameter() $_GET getPostParameter() $_POST getUrlParameter() $_SERVER['PATH_INFO'] getRemoteAddress() $_SERVER['REMOTE_ADDR']
    137. 137. public function executeShow(sfWebRequest $request) { ... $request‐>getParameter('id'); ... } /ruta1/ruta2/ruta3?id=3&clave1= valor1&clave2=valor2
    138. 138. objeto sfWebResponse class jobActions extends sfActions { public function executeShow(sfWebRequest $request) { $respuesta = $this‐>getResponse(); $respuesta‐>setStatusCode(404); $respuesta‐>addStyleSheet('/css/job.css'); $respuesta‐>setTitle('Título de la página'); } // ... }
    139. 139. archivo de configuración metas: stylesheets: [job] plantilla use_stylesheet('job.css') <?php ?> acción $this‐>getResponse()‐> addStyleSheet('/css/job.css');
    140. 140. Capítulo 5 El sistema de  enrutamiento
    141. 141. URL
    142. 142. internet symfony URL URI sistema de  enrutamiento
    143. 143. URI 'job/show?id='.$job‐>getId() url_for() job/show/id/1 URL
    144. 144. URI modulo/accion?clave1= valor1&clave2=valor2& ...
    145. 145. Configurando el  enrutamiento
    146. 146. apps/frontend/config/routing.yml homepage: url: / param: { module: default, action: index } default_index: url: /:module param: { action: index } default: url: /:module/:action/*
    147. 147. nombre patrón default_index: url: /:module param: { action: index } parámetros
    148. 148. homepage: url: / param: { module: default, action: index } default_index: url: /:module param: { action: index } default: url: /:module/:action/*  /job
    149. 149. /frontend_dev.php/job 1 entorno aplicación ??? ¿acción? ¿módulo? apps/frontend/config/routing.yml 2 default_index: /job url: /:module param: { action: index } :module = job = módulo
    150. 150. 3 apps/frontend/config/routing.yml default_index: acción = index url: /:module param: { action: index } /frontend_dev.php/job 4 aplicación = frontend módulo = job entorno = dev acción = index
    151. 151. url_for() URI URL url_for('job/show?id='.$job‐>getId()) /job/show/id/1
    152. 152. url_for() URI URL url_for('@default?id='.$job‐>getId())
    153. 153. Personalizando el  enrutamiento
    154. 154. apps/frontend/config/routing.yml homepage: url: / param: { module: job, action: index } default_index: url: /:module param: { action: index } default: url: /:module/:action/* 
    155. 155. <h1> <a href=quot;<?php echo url_for('@homepage') ?>quot;> <img src=quot;/images/jobeet.gifquot; alt=quot;Jobeetquot; /> </a> </h1>
    156. 156. /job/sensio‐labs/paris‐france/1/web‐developer 1. Identificar el patrón de la URL 2. Incluir la ruta a routing.yml 3. Añadir las restricciones adecuadas
    157. 157. /job/sensio‐labs/paris‐france/1/web‐developer 1. Identificar el patrón de la URL /job/:company/:location/:id/:position
    158. 158. /job/sensio‐labs/paris‐france/1/web‐developer 2. Incluir la ruta en routing.yml job_show_user: url:   /job/:company/:location/:id/:position param: { module: job, action: show }
    159. 159. url_for('job/show?'. 'id='.$job‐>getId(). '&company='.$job‐>getCompany(). '&location='.$job‐>getLocation(). '&position='.$job‐>getPosition() )
    160. 160. url_for(array( 'module' => 'job', 'action' => 'show', 'id' => $job‐>getId(), 'company' => $job‐>getCompany(), 'location' => $job‐>getLocation(), 'position' => $job‐>getPosition(),  ))
    161. 161. Requisitos
    162. 162. /job/sensio‐labs/paris‐france/1/web‐developer 3. Añadir las restricciones adecuadas job_show_user: url:   /job/:company/:location/:id/:position param: { module: job, action: show } requirements: id: d+
    163. 163. La clase sfRoute
    164. 164. HTTP     Navegadores      Symfony GET POST HEAD PUT DELETE
    165. 165. job_show_user: url:     /job/:company/:location/:id/:position class: sfRequestRoute param:   { module: job, action: show } requirements: id: d+ sf_method: [get]
    166. 166. La clase para las  rutas basadas en  objetos
    167. 167. url_for('job/show?'. 'id='.$job‐>getId(). '&company='.$job‐>getCompany(). '&location='.$job‐>getLocation(). '&position='.$job‐>getPosition() )
    168. 168. job_show_user: url:      /job/:company/:location/:id/:position class:  sfPropelRoute options: model: JobeetJob type:  object param:     { module: job, action: show } requirements: id: d+ sf_method: [get]
    169. 169. url_for('job/show?'. 'id='.$job‐>getId(). '&company='.$job‐>getCompany(). '&location='.$job‐>getLocation(). '&position='.$job‐>getPosition() ) url_for('job_show_user', $job) url_for(array( 'sf_route' => 'job_show_user', 'sf_subject' => $job ))
    170. 170. Lo que queremos… /job/sensio‐labs/paris‐france/1/web‐developer Lo que tenemos… /job/Sensio+Labs/Paris%2C+France/1/Web+Developer
    171. 171. getId() id name getName() description Job getDescription() ... getSlug() schema.yml getShortDescription() getters virtuales
    172. 172. slug Comienza el curso de Symfony en Vitoria‐Gasteiz www.symfony.es/2009/01/29/comienza‐el‐curso‐de‐symfony‐en‐vitoria‐gasteiz Twitto, el framework PHP más pequeño www.symfony.es/2009/01/11/twitto‐el‐framework‐php‐mas‐pequeno/
    173. 173. getId() id name getName() description Job getDescription() ... getCompanySlug() getPositionSlug() schema.yml getLocationSlug() getters virtuales
    174. 174. lib/model/JobeetJob.php public function getCompanySlug() { return Jobeet::slugify($this‐>getCompany()); } public function getPositionSlug() { return Jobeet::slugify($this‐>getPosition()); } public function getLocationSlug() { return Jobeet::slugify($this‐>getLocation()); }
    175. 175. lib/Jobeet.class.php class Jobeet { static public function slugify($text) { // replace all non letters or digits by ‐ $text = preg_replace('/W+/', '‐', $text); // trim and lowercase $text = strtolower(trim($text, '‐')); return $text; } }
    176. 176. job_show_user: url: /job/:company_slug/:location_slug/:id/:position_slug class:   sfPropelRoute options: { model: JobeetJob, type:  object } param:   { module: job, action: show } requirements: id: d+ sf_method: [get]
    177. 177. class jobActions extends sfActions { public function executeShow(sfWebRequest $request) { $this‐>job = JobeetJobPeer::retrieveByPk($request‐>getParameter('id')); $this‐>forward404Unless($this‐>job); } // ... } class jobActions extends sfActions { public function executeShow(sfWebRequest $request) { $this‐>job = $this‐>getRoute()‐>getObject();  } // ... }
    178. 178. Enrutamiento en  acciones y  plantillas
    179. 179. <?php echo link_to( quot;Texto del enlacequot;, 'job_show_user', $job ) ?> <a href=quot; <?php echo url_for( 'job_show_user', $job, true ); ?>quot;> Texto del enlace </a>
    180. 180. class jobActions extends sfActions { public function executeIndex(sfWebRequest $request) { // ... $this‐>redirect( $this‐>generateUrl('job_show_user', $job) ); } // ... }
    181. 181. La clase de las  colecciones de  rutas
    182. 182. job: class:   sfPropelRouteCollection options: { model: JobeetJob } job_show_user: url: /job/:company_slug/:location_slug/:id/:position_slug class: sfPropelRoute options: { model: JobeetJob, type:  object } param: { module: job, action: show } requirements: id: d+ sf_method: [get]
    183. 183. $ php symfony app:routes frontend

    ×