curso symfony clase 1

192
Frameworks de desarrollo Symfony Symfony Javier Eguíluz Clase 1 Clase 1 [email protected]

Upload: julio-cesar-brizuela

Post on 16-Nov-2014

739 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: curso symfony clase 1

Frameworks de desarrollo

SymfonySymfony

Javier Eguíluz

Clase 1Clase 1

[email protected]

Page 2: curso symfony clase 1

Esta obra dispone de una licencia de tipo CreativeCommons 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/

Page 3: curso symfony clase 1

This work is licensed under a Creative CommonsAttribution‐Noncommercial‐Share Alike 3.0 

The use of these slides in commercial courses ortrainings is explicitly prohibited

http://creativecommons.org/licenses/by‐nc‐sa/3.0/es/

Page 4: curso symfony clase 1

Capítulo 1

Comenzando el proyectoComenzando el proyecto

Page 5: curso symfony clase 1

¿Qué es Symfony?¿Qué es Symfony?

Page 6: curso symfony clase 1

Framework para el desarrollo de aplicaciones 

web con PHP

Page 7: curso symfony clase 1

• El más profesional

• El más documentado

• El mejor

Page 8: curso symfony clase 1

PHP      Frameworks

Productividad

Calidad programación

Mantenimiento

Rendimiento aplicación

Page 9: curso symfony clase 1

tiempo

aprend

izaje

Curva de aprendizaje de Symfony

Page 10: curso symfony clase 1

¿Qué es Jobeet?¿Qué es Jobeet?

Page 11: curso symfony clase 1

diciembre 2008

313029

28272625242322

21201918171615

141312111098

7654321

Page 12: curso symfony clase 1

La mejor forma de aprender Symfony 1.2 a través de 24

tutoriales de 1 hora

Page 13: curso symfony clase 1
Page 14: curso symfony clase 1

Un tutorialdiferenteUn tutorialdiferente

Page 15: curso symfony clase 1

• Serio

• Profesional

• Completo

Page 16: curso symfony clase 1

PrerrequisitosPrerrequisitos

Page 17: curso symfony clase 1

5.2.4

Page 18: curso symfony clase 1

Instalación de Symfony

Instalación de Symfony

Page 19: curso symfony clase 1

http://www.symfony‐project.org/installation/1_2

symfony‐1.2.4.tgz

Page 20: curso symfony clase 1

check_configuration.php

Page 21: curso symfony clase 1

$ php lib/vendor/symfony/data/bin/symfony

Page 22: curso symfony clase 1

Preparar el proyectoPreparar el proyecto

Page 23: curso symfony clase 1

frontend backend

Page 24: curso symfony clase 1

jobeet

frontend backend

proyecto

aplicación

Page 25: curso symfony clase 1

$ symfony generate:project jobeet

apps/

cache/

config/

lib/

log/

plugins/

test/

web/

Page 26: curso symfony clase 1

$ symfonygenerate:appjobeet‐‐escaping‐strategy=on‐‐csrf‐secret=UniqueSecret

frontend

config/

lib/

modules/

templates/

frontend/

Page 27: curso symfony clase 1

‐‐escaping‐strategy

‐‐csrf‐secret

XSS

CSRF

Page 28: curso symfony clase 1

require_once dirname(__FILE__).'/../lib/vendor/'.'symfony/lib/autoload/'.'sfCoreAutoload.class.php';

config/ProjectConfiguration.class.php

Page 29: curso symfony clase 1

Los entornosLos entornos

Page 30: curso symfony clase 1

• Entorno de desarrollo (dev)

• Entorno de pruebas

• Entorno intermedio

• Entorno de producción (prod)

Page 31: curso symfony clase 1

Errores en el entorno de desarrollo (dev)

Page 32: curso symfony clase 1

Errores en el entorno de producción (prod)

Page 33: curso symfony clase 1

<?php

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

$configuration = ProjectConfiguration::getApplicationConfiguration(

'frontend','prod',false

);

sfContext::createInstance($configuration)‐>dispatch();

web/index.php

Page 34: curso symfony clase 1

Configurar bien el servidor web

Configurar bien el servidor web

Page 35: curso symfony clase 1

<VirtualHost 127.0.0.1:80>ServerName jobeet.localhostDocumentRoot "/home/sfprojects/jobeet/web"DirectoryIndex index.php

<Directory "/home/sfprojects/jobeet/web">AllowOverride AllAllow from All

</Directory>

Alias /sf /home/sfprojects/jobeet/lib/vendor/symfony/data/web/sf<Directory "/home/sfprojects/jobeet/lib/vendor/symfony/data/web/sf">

AllowOverride AllAllow from All

</Directory></VirtualHost>

Page 36: curso symfony clase 1

/etc/hosts

c:\windows\system32\drivers\etc\hosts

127.0.0.1    jobeet.localhost

Page 37: curso symfony clase 1

http://jobeet.localhost/

prod

Page 38: curso symfony clase 1

http://jobeet.localhost/frontend_dev.php

dev

Page 39: curso symfony clase 1

Versionado de código

Versionado de código

Page 40: curso symfony clase 1
Page 41: curso symfony clase 1

Capítulo 2

El proyectoEl proyecto

Page 42: curso symfony clase 1

La idea del proyectoLa idea del proyecto

Page 43: curso symfony clase 1
Page 44: curso symfony clase 1

Aplicación de software libre que permite crear sitios web de búsqueda 

de empleo

Page 45: curso symfony clase 1

características

• Completo y personalizable

• Multilingüe

• AJAX, RSS y API

Page 46: curso symfony clase 1

Los escenarios del proyecto

Los escenarios del proyecto

Page 47: curso symfony clase 1

• administrador (admin)

• usuario (user)

• publicador (poster)

• afiliado (affiliate)

Page 48: curso symfony clase 1

F1

El usuario accede a la portada y ve las últimas ofertas de trabajo activas

Page 49: curso symfony clase 1

F2

El usuario puede visualizar todas las ofertas de trabajo de una categoría

Page 50: curso symfony clase 1

F3

El usuario refina el listado mediante palabras clave

Page 51: curso symfony clase 1

F4

El usuario pincha sobre una oferta de trabajo para ver más información

Page 52: curso symfony clase 1

F5

El usuario publica una nueva oferta de trabajo

Page 53: curso symfony clase 1

F6

El usuario quiere convertirse en un afiliado

Page 54: curso symfony clase 1

F7

Un usuario afiliado obtiene la lista de ofertas de trabajo activas

Page 55: curso symfony clase 1

B1El administrador configura el sitio web

B2El administrador gestiona las ofertas de trabajo

B3El administrador gestiona los afiliados

Page 56: curso symfony clase 1

Capítulo 3

El modelo de datosEl modelo de datos

Page 57: curso symfony clase 1

El modelo relacionalEl modelo relacional

Page 58: curso symfony clase 1
Page 59: curso symfony clase 1

objetos

relacion

al

ORM

Page 60: curso symfony clase 1

1. Describir la base de datos

2. Generar las clases PHP

3. Trabajar con objetos en vez de SQL

Page 61: curso symfony clase 1

El formato YAMLEl formato YAML

Page 62: curso symfony clase 1

YAMLFormato para serializar datos que es fácil de leer por las personas y es compatible con todos los lenguajes 

de programación

Page 63: curso symfony clase 1

$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'

));

Page 64: curso symfony clase 1

casa:familia:

apellido: Garcíapadres:

‐ Antonio‐ María

hijos:‐ Jose‐ Manuel

direccion:numero: 34calle: Gran Víaciudad: Cualquieracodigopostal: "12345"

Page 65: curso symfony clase 1

casa:familia: { apellido: García, padres: [Antonio, 

María], hijos: [Jose, Manuel] }direccion: { numero: 34, direccion: Gran Vía, 

ciudad: Cualquiera, codigopostal: "12345" }

Page 66: curso symfony clase 1

clave:clave: valorclave:

clave: valorclave:

‐ valor‐ valor

Sintaxisclave:clave: valor

2 espacios en blanco

Page 67: curso symfony clase 1

clave:‐ valor1‐ valor2‐ valor3

Arrays normales

clave:[valor1, valor2, valor3]

Page 68: curso symfony clase 1

clave:clave1: valor1clave2: valor2clave3: valor3

Arrays asociativos

clave: { clave1: valor1, clave2: valor2, clave3: valor3}

Page 69: curso symfony clase 1

<?xml version="1.0"?><club><players><player id="kramnik" name="Vladimir

Kramnik" rating="2700" status="GM" /> <player id="fritz" name="Deep

Fritz" rating="2700" status="Computer" />

<player id="mertz" name="David Mertz" rating="1400" status="Amateur" /></players><matches><match><Date>2002‐10‐04</Date><White refid="fritz" /> <Black refid="kramnik" /> <Result>Draw</Result> 

</match><match><Date>2002‐10‐06</Date><White refid="kramnik" /><Black refid="fritz" /><Result>White</Result>

</match></matches></club> 

players:Vladimir Kramnik: &kramnikrating: 2700status: GM

Deep Fritz: &fritzrating: 2700status: Computer

David Mertz: &mertzrating: 1400status: Amateur

matches:‐Date: 2002‐10‐04White: *fritzBlack: *kramnikResult: Draw

‐Date: 2002‐10‐06White: *kramnikBlack: *fritzResult: White

XML YAML

Page 70: curso symfony clase 1

El esquemaEl esquema

Page 71: curso symfony clase 1

config/schema.ymlpropel:

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 }

Page 72: curso symfony clase 1

propel:jobeet_category:

id:   ~name: { type: varchar(255),

required: true,index: unique

}

config/schema.yml

Page 73: curso symfony clase 1

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:   ~

config/schema.yml

Page 74: curso symfony clase 1

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: ~

config/schema.yml

Page 75: curso symfony clase 1

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

}

config/schema.yml

Page 76: curso symfony clase 1

• 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

config/schema.yml

Page 77: curso symfony clase 1

La base de datosLa base de datos

Page 78: curso symfony clase 1

$ mysqladmin ‐uroot ‐p create jobeet

$ symfony configure:database“mysql:host=localhost;dbname=jobeet”root ConTraSenA

config/databases.yml

Page 79: curso symfony clase 1

El ORMEl ORM

Page 80: curso symfony clase 1

$ symfony propel:build‐sql

$ symfony propel:insert‐sql ‐‐no‐confirmation

data/sql/

$ symfony propel:build‐model

lib/model/

Page 81: curso symfony clase 1

• JobeetJob

• BaseJobeetJob

• JobeetJobPeer

• BaseJobeetJobPeer

extends

extends

Page 82: curso symfony clase 1

$job = new JobeetJob();$job‐>setPosition('Web developer');$job‐>save();

echo $job‐>getPosition();

$job‐>delete();

Page 83: curso symfony clase 1

$category = new JobeetCategory(); $category‐>setName('Programming');

$job = new JobeetJob();$job‐>setCategory($category);

Page 84: curso symfony clase 1

$ symfony propel:build‐all ‐‐no‐confirmation

Page 85: curso symfony clase 1

$ symfony propel:build‐sql$ symfony propel:insert‐sql$ symfony propel:build‐model$ symfony propel:build‐forms$ symfony propel:build‐filters

$ symfony propel:build‐all+

Page 86: curso symfony clase 1

$ 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

Page 87: curso symfony clase 1

$ symfony cache:clear$ symfony cache:cl$ symfony ca:c$ symfony cc

Page 88: curso symfony clase 1

Los datos inicialesLos datos iniciales

Page 89: curso symfony clase 1

• Datos iniciales

• Datos de prueba

• Datos de usuarios

data/fixtures/

Page 90: curso symfony clase 1

JobeetCategory:design:        { name: Design }programming:   { name: Programming }manager:       { name: Manager }administrator: { name: Administrator }

data/fixtures/010_categories.yml

Page 91: curso symfony clase 1

JobeetJob:job_sensio_labs:category_id:  programmingtype:         full‐timecompany:      Sensio Labslogo:         sensio‐labs.gifurl:          http://www.sensiolabs.com/position:     Web Developerlocation:     Paris, Francedescription:  |You have already developed websites with symfony and you wantto work with Open‐Source technologies. You have a minimum of 3 years experience in web development with PHP or Java andyou wish to participate to development of Web 2.0 sites usingthe best frameworks available.

how_to_apply: |Send your resume to fabien.potencier [at] sensio.com

is_public:    trueis_activated: truetoken:        job_sensio_labsemail:        [email protected]_at:   2010‐10‐10

data/fixtures/020_jobs.yml

Page 92: curso symfony clase 1

$ symfony propel:data‐load

Page 93: curso symfony clase 1

$ 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

+

Page 94: curso symfony clase 1

Probando la aplicación en el navegador

Probando la aplicación en el navegador

Page 95: curso symfony clase 1

jobeet

frontend backend

proyecto

aplicación

job

mód

ulo

Page 96: curso symfony clase 1

$ symfony propel:generate‐module‐‐with‐show ‐‐non‐verbose‐templatesfrontend job JobeetJob

actions/

templates/

frontend/modules/job

Page 97: curso symfony clase 1

index

show

new

create

edit

update

delete

frontend/modules/job/actions/actions.class.php

Page 98: curso symfony clase 1

frontend_devjob

http://jobeet.localhost/frontend_dev.php/job

Page 99: curso symfony clase 1

Categoría __toString()

Objeto Representación textual

Page 100: curso symfony clase 1

class JobeetCategory extends BaseJobeetCategory{

public function __toString(){

return $this‐>getName();}

}

lib/model/JobeetCategory.php

Page 101: curso symfony clase 1

class JobeetJob extends BaseJobeetJob{

public function __toString(){

return sprintf('%s at %s (%s)',$this‐>getPosition(),$this‐>getCompany(),$this‐>getLocation()

);}

}

lib/model/JobeetJob.php

Page 102: curso symfony clase 1

class JobeetAffiliate extends BaseJobeetAffiliate{

public function __toString(){

return $this‐>getUrl();}

}

lib/model/JobeetAffiliate.php

Page 103: curso symfony clase 1

http://jobeet.localhost/frontend_dev.php/job

Page 104: curso symfony clase 1

Capítulo 4

El controlador y la vistaEl controlador y la vista

Page 105: curso symfony clase 1

La arquitectura MVCLa arquitectura MVC

Page 106: curso symfony clase 1

¿Cómo se programaba con PHP en el siglo pasado?

1 página del sitio web = 1 archivo PHP 

diferente

Page 107: curso symfony clase 1

inicialización y configuración

lógica de negocio

acceso a BBDD

generar código HTML

pagina.php

¿Cómo se programaba con PHP en el siglo pasado?

Page 108: curso symfony clase 1

ModeloVistaControlador

Page 109: curso symfony clase 1
Page 110: curso symfony clase 1

ModeloDirectorio /lib/model

VistaDirectorios templates/

ControladorArchivos index.php y frontend_dev.phpArchivos actions.class.php

Page 111: curso symfony clase 1

El layoutEl layout

Page 112: curso symfony clase 1
Page 113: curso symfony clase 1

patrón de diseño decorator

apps/frontend/templates/layout.php

Page 114: curso symfony clase 1

<!DOCTYPE html PUBLIC "‐//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1‐transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head><title>Jobeet ‐ Your best job board</title><link rel="shortcut icon" href="/favicon.ico" /><?php include_javascripts() ?><?php include_stylesheets() ?>

</head><body>...<div class="content">

<?php echo $sf_content ?></div>

</body></html>

apps/frontend/templates/layout.php

Page 115: curso symfony clase 1

Plantillas Symfony

• Archivos PHP normales

• Existe un plugin para Smarty

• Symfony 2.0 podría incluir plantillas

Page 116: curso symfony clase 1

Las hojas de estilos, imágenes y archivos 

JavaScript

Las hojas de estilos, imágenes y archivos 

JavaScript

Page 117: curso symfony clase 1
Page 118: curso symfony clase 1

<head>...<?php include_stylesheets() ?>

</head>

helpers

Page 119: curso symfony clase 1

default:http_metas:

content‐type: text/htmlmetas:

#title: symfony project#description: symfony project#keywords: symfony, project#language: en#robots: index, follow

stylesheets: [main.css]

javascripts: []

has_layout: onlayout: layout

apps/frontend/config/view.yml

Page 120: curso symfony clase 1

default:...stylesheets:  [main.css, jobs.css, job.css]...

<link rel="stylesheet" type="text/css" media="screen" href="/css/main.css" />

<link rel="stylesheet" type="text/css" media="screen" href="/css/jobs.css" />

<link rel="stylesheet" type="text/css" media="screen" href="/css/job.css" />

apps/frontend/config/view.yml

Page 121: curso symfony clase 1

default:...stylesheets:  [main.css, jobs.css, job]...

<link rel="stylesheet" type="text/css" media="screen" href="/css/main.css" />

<link rel="stylesheet" type="text/css" media="screen" href="/css/jobs.css" />

<link rel="stylesheet" type="text/css" media="screen" href="/css/job.css" />

apps/frontend/config/view.yml

Page 122: curso symfony clase 1

default:...stylesheets:  [main.css, /css/v2/jobs.css]...

<link rel="stylesheet" type="text/css" media="screen" href="/css/main.css" />

<link rel="stylesheet" type="text/css" media="screen" href="/css/v2/jobs.css" />

apps/frontend/config/view.yml

Page 123: curso symfony clase 1

default:...stylesheets: [main.css, jobs: { media: print } ]...

<link rel="stylesheet" type="text/css" media="screen" href="/css/main.css" />

<link rel="stylesheet" type="text/css" media="print" href="/css/jobs.css" />

apps/frontend/config/view.yml

Page 124: curso symfony clase 1

metas:title: El título 1

metas:title: El título 2

metas:title: El título 3

metas:title: El título 4

Symfony

Proyecto

Aplicación

Módulo

view.yml

Page 125: curso symfony clase 1

Symfonylib/vendor/symfony/lib/config/config/view.yml

Proyectoconfig/view.yml

Aplicaciónapps/frontend/config/view.yml

Móduloapps/frontend/modules/job/config/view.yml

Page 126: curso symfony clase 1

metas:stylesheets: [job]

view.yml

plantilla

plantilla

<?phpuse_stylesheet(‘job.css’)?>

Page 127: curso symfony clase 1

La portada del módulo de las ofertas de 

trabajo

La portada del módulo de las ofertas de 

trabajo

Page 128: curso symfony clase 1

apps/frontend/modules/job/actions/actions.class.phptemplates/indexSuccess.php

Page 129: curso symfony clase 1

= +acción

plantilla

Page 130: curso symfony clase 1

http://jobeet.localhost/frontend_dev.php/job/index

frontend (aplicación)

_dev (entorno)

job (módulo)

index (acción executeIndex y plantilla indexSuccess)

Page 131: curso symfony clase 1

class jobActions extends sfActions{

public function executeIndex(sfWebRequest $request){

$this‐>jobeet_job_list =JobeetJobPeer::doSelect(new Criteria());

}

// ...}

apps/frontend/modules/job/actions/actions.class.php

Page 132: curso symfony clase 1

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]]

Page 133: curso symfony clase 1

<?php foreach ($jobeet_job_list as $jobeet_job): ?>...<td>

<a href="..."><?php echo $jobeet_job‐>getId() ?>

</a></td>...

<?php endforeach; ?> 

apps/frontend/modules/job/templates/indexSuccess.php

Page 134: curso symfony clase 1

La plantilla de la página de una oferta de 

trabajo

La plantilla de la página de una oferta de 

trabajo

Page 135: curso symfony clase 1
Page 136: curso symfony clase 1

SlotsSlots

Page 137: curso symfony clase 1

<title>Jobeet</title> <title>

plantillalayout

Page 138: curso symfony clase 1

<title>             </title> Título de la página

plantillalayout

Page 139: curso symfony clase 1
Page 140: curso symfony clase 1

<title><?php include_slot('title') ?>

</title>

apps/frontend/templates/layout.php

<?php slot('title', 'Título de la página') ?> 

<?php slot('title',sprintf('%s is looking for a %s',

$job‐>getCompany(),$job‐>getPosition()

)) ?> 

apps/frontend/modules/job/templates/indexSuccess.php

Page 141: curso symfony clase 1

La acción de la página de una oferta de 

trabajo

La acción de la página de una oferta de 

trabajo

Page 142: curso symfony clase 1

public function executeShow(sfWebRequest $request){

$this‐>job = JobeetJobPeer::retrieveByPk($request‐>getParameter('id')

);

$this‐>forward404Unless($this‐>job);}

apps/frontend/modules/job/actions/actions.class.php

Page 143: curso symfony clase 1

La petición y la respuesta

La petición y la respuesta

Page 144: curso symfony clase 1

class jobActions extends sfActions{

public function executeShow(sfWebRequest $request){

$peticion = $request;$origen = $peticion‐>getReferer();$metodo = $peticion‐>getMethod();

}

// ...}

objeto sfWebRequest

Page 145: curso symfony clase 1

$_SERVER['REMOTE_ADDR']getRemoteAddress()

$_SERVER['PATH_INFO']getUrlParameter()

$_POSTgetPostParameter()

$_GETgetGetParameter()

$_FILESgetFiles()

$_SERVER['HTTPS']isSecure()

$_COOKIEgetCookie()

$_SERVERgetHttpHeader()

$_SERVER['X_REQUESTD_WITH'] == 'XMLHttpRequest'isXmlHttpRequest()

$_SERVER['HTTP_ACCEPT_CHARSET']getCharsets()

$_SERVER['HTTP_ACCEPT_LANGUAGE']getLanguages()

$_SERVER['HTTP_HOST']getHost()

$_SERVER['HTTP_REFERER']getReferer()

$_SERVER['REQUEST_URI']getUri()

$_SERVER['REQUEST_METHOD']getMethod()

Equivalente de PHPNombre del método

Page 146: curso symfony clase 1

public function executeShow(sfWebRequest $request){

...$request‐>getParameter('id');

...

}

/ruta1/ruta2/ruta3?id=3&clave1=valor1&clave2=valor2

Page 147: curso symfony clase 1

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');

}

// ...}

objeto sfWebResponse

Page 148: curso symfony clase 1

plantilla<?php use_stylesheet('job.css') ?>

acción

archivo de configuraciónmetas:

stylesheets: [job]

$this‐>getResponse()‐>addStyleSheet('/css/job.css');

Page 149: curso symfony clase 1

Capítulo 5

El sistema de enrutamientoEl sistema de enrutamiento

Page 150: curso symfony clase 1

URLURL

Page 151: curso symfony clase 1

URL URIsistema de 

enrutamiento

internet symfony

Page 152: curso symfony clase 1

'job/show?id='.$job‐>getId()

job/show/id/1

url_for()

URI

URL

Page 153: curso symfony clase 1

URI

modulo/accion?clave1=valor1&clave2=valor2&...

Page 154: curso symfony clase 1

Configurando el enrutamientoConfigurando el enrutamiento

Page 155: curso symfony clase 1

apps/frontend/config/routing.yml

homepage:url: /param: { module: default, action: index }

default_index:url: /:moduleparam: { action: index }

default:url: /:module/:action/*

Page 156: curso symfony clase 1

default_index:url: /:moduleparam: { action: index }

nombre

patrón

parámetros

Page 157: curso symfony clase 1

homepage:url: /param: { module: default, action: index }

default_index:url: /:moduleparam: { action: index }

default:url: /:module/:action/* 

/job

Page 158: curso symfony clase 1

aplicación1 /frontend_dev.php/job

entorno ???

2 apps/frontend/config/routing.yml

/jobdefault_index:url: /:moduleparam: { action: index }

¿módulo? ¿acción?

:module = job = módulo

Page 159: curso symfony clase 1

3

4

apps/frontend/config/routing.yml

default_index:url: /:moduleparam: { action: index }

aplicación = frontendentorno = dev

acción = index

/frontend_dev.php/jobmódulo = jobacción = index

Page 160: curso symfony clase 1

url_for('job/show?id='.$job‐>getId())

URI URLurl_for()

/job/show/id/1

Page 161: curso symfony clase 1

url_for('@default?id='.$job‐>getId())

URI URLurl_for()

Page 162: curso symfony clase 1

Personalizando el enrutamiento

Personalizando el enrutamiento

Page 163: curso symfony clase 1

homepage:url: /param: { module: job, action: index }

default_index:url: /:moduleparam: { action: index }

default:url: /:module/:action/* 

apps/frontend/config/routing.yml

Page 164: curso symfony clase 1

<h1><a href="<?php echo url_for('@homepage') ?>"><img src="/images/jobeet.gif" alt="Jobeet" /></a></h1>

Page 165: curso symfony clase 1

/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

Page 166: curso symfony clase 1

/job/sensio‐labs/paris‐france/1/web‐developer

1. Identificar el patrón de la URL

/job/:company/:location/:id/:position

Page 167: curso symfony clase 1

/job/sensio‐labs/paris‐france/1/web‐developer

2. Incluir la ruta en routing.yml

job_show_user:url:   /job/:company/:location/:id/:positionparam: { module: job, action: show }

Page 168: curso symfony clase 1

url_for('job/show?'.'id='.$job‐>getId().'&company='.$job‐>getCompany().'&location='.$job‐>getLocation().'&position='.$job‐>getPosition()

)

Page 169: curso symfony clase 1

url_for(array('module' => 'job','action' => 'show','id' => $job‐>getId(),'company' => $job‐>getCompany(),'location' => $job‐>getLocation(),'position' => $job‐>getPosition(), 

))

Page 170: curso symfony clase 1

RequisitosRequisitos

Page 171: curso symfony clase 1

/job/sensio‐labs/paris‐france/1/web‐developer

3. Añadir las restricciones adecuadas

job_show_user:url:   /job/:company/:location/:id/:positionparam: { module: job, action: show }requirements:

id: \d+

Page 172: curso symfony clase 1

La clase sfRouteLa clase sfRoute

Page 173: curso symfony clase 1

HTTP     Navegadores      Symfony

GET

POST

HEAD

PUT

DELETE

Page 174: curso symfony clase 1

job_show_user:url:     /job/:company/:location/:id/:positionclass: sfRequestRouteparam:   { module: job, action: show }requirements:id: \d+sf_method: [get]

Page 175: curso symfony clase 1

La clase para las rutas basadas en 

objetos

La clase para las rutas basadas en 

objetos

Page 176: curso symfony clase 1

url_for('job/show?'.'id='.$job‐>getId().'&company='.$job‐>getCompany().'&location='.$job‐>getLocation().'&position='.$job‐>getPosition()

)

Page 177: curso symfony clase 1

job_show_user:url:      /job/:company/:location/:id/:positionclass:  sfPropelRouteoptions:model: JobeetJobtype:  object

param:     { module: job, action: show }requirements:id: \d+sf_method: [get]

Page 178: curso symfony clase 1

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

))

Page 179: curso symfony clase 1

/job/sensio‐labs/paris‐france/1/web‐developer

Lo que queremos…

/job/Sensio+Labs/Paris%2C+France/1/Web+Developer

Lo que tenemos…

Page 180: curso symfony clase 1

Job

idnamedescription...

schema.yml

getId()

getName()

getDescription()

gettersvirtuales

getShortDescription()

getSlug()

Page 181: curso symfony clase 1

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/

Page 182: curso symfony clase 1

Job

idnamedescription...

schema.yml

getId()

getName()

getDescription()

gettersvirtuales

getPositionSlug()

getCompanySlug()

getLocationSlug()

Page 183: curso symfony clase 1

public function getCompanySlug() {return Jobeet::slugify($this‐>getCompany());

}

public function getPositionSlug() {return Jobeet::slugify($this‐>getPosition());

}

public function getLocationSlug() {return Jobeet::slugify($this‐>getLocation());

}

lib/model/JobeetJob.php

Page 184: curso symfony clase 1

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;}

}

lib/Jobeet.class.php

Page 185: curso symfony clase 1

job_show_user:url: /job/:company_slug/:location_slug/:id/:position_slug

class:   sfPropelRouteoptions: { model: JobeetJob, type:  object }param:   { module: job, action: show }requirements:id: \d+sf_method: [get]

Page 186: curso symfony clase 1

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(); }

// ...}

Page 187: curso symfony clase 1

Enrutamiento en acciones y plantillas

Enrutamiento en acciones y plantillas

Page 188: curso symfony clase 1

<?php echo link_to("Texto del enlace",'job_show_user',$job

) ?>

<a href="<?php echo url_for(

'job_show_user',$job,true

); ?>">Texto del enlace</a>

Page 189: curso symfony clase 1

class jobActions extends sfActions{public function executeIndex(sfWebRequest $request){

// ...

$this‐>redirect($this‐>generateUrl('job_show_user', $job)

);}

// ...}

Page 190: curso symfony clase 1

La clase de las colecciones de 

rutas

La clase de las colecciones de 

rutas

Page 191: curso symfony clase 1

job:class:   sfPropelRouteCollectionoptions: { model: JobeetJob }

job_show_user:url: /job/:company_slug/:location_slug/:id/:position_slugclass: sfPropelRouteoptions: { model: JobeetJob, type:  object }param: { module: job, action: show }requirements:id: \d+sf_method: [get]

Page 192: curso symfony clase 1

$ php symfony app:routes frontend