Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Curso Symfony - Clase 1

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

  • Login to see the comments

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

×