curso symfony clase 1
-
Upload
julio-cesar-brizuela -
Category
Documents
-
view
739 -
download
0
Transcript of 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/
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/
Capítulo 1
Comenzando el proyectoComenzando el proyecto
¿Qué es Symfony?¿Qué es Symfony?
Framework para el desarrollo de aplicaciones
web con PHP
• El más profesional
• El más documentado
• El mejor
PHP Frameworks
Productividad
Calidad programación
Mantenimiento
Rendimiento aplicación
tiempo
aprend
izaje
Curva de aprendizaje de Symfony
¿Qué es Jobeet?¿Qué es Jobeet?
diciembre 2008
313029
28272625242322
21201918171615
141312111098
7654321
La mejor forma de aprender Symfony 1.2 a través de 24
tutoriales de 1 hora
Un tutorialdiferenteUn tutorialdiferente
• Serio
• Profesional
• Completo
PrerrequisitosPrerrequisitos
5.2.4
Instalación de Symfony
Instalación de Symfony
http://www.symfony‐project.org/installation/1_2
symfony‐1.2.4.tgz
check_configuration.php
$ php lib/vendor/symfony/data/bin/symfony
Preparar el proyectoPreparar el proyecto
frontend backend
jobeet
frontend backend
proyecto
aplicación
$ symfony generate:project jobeet
apps/
cache/
config/
lib/
log/
plugins/
test/
web/
$ symfonygenerate:appjobeet‐‐escaping‐strategy=on‐‐csrf‐secret=UniqueSecret
frontend
config/
lib/
modules/
templates/
frontend/
‐‐escaping‐strategy
‐‐csrf‐secret
XSS
CSRF
require_once dirname(__FILE__).'/../lib/vendor/'.'symfony/lib/autoload/'.'sfCoreAutoload.class.php';
config/ProjectConfiguration.class.php
Los entornosLos entornos
• Entorno de desarrollo (dev)
• Entorno de pruebas
• Entorno intermedio
• Entorno de producción (prod)
Errores en el entorno de desarrollo (dev)
Errores en el entorno de producción (prod)
<?php
require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php');
$configuration = ProjectConfiguration::getApplicationConfiguration(
'frontend','prod',false
);
sfContext::createInstance($configuration)‐>dispatch();
web/index.php
Configurar bien el servidor web
Configurar bien el servidor web
<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>
/etc/hosts
c:\windows\system32\drivers\etc\hosts
127.0.0.1 jobeet.localhost
http://jobeet.localhost/
prod
http://jobeet.localhost/frontend_dev.php
dev
Versionado de código
Versionado de código
Capítulo 2
El proyectoEl proyecto
La idea del proyectoLa idea del proyecto
Aplicación de software libre que permite crear sitios web de búsqueda
de empleo
características
• Completo y personalizable
• Multilingüe
• AJAX, RSS y API
Los escenarios del proyecto
Los escenarios del proyecto
• administrador (admin)
• usuario (user)
• publicador (poster)
• afiliado (affiliate)
F1
El usuario accede a la portada y ve las últimas ofertas de trabajo activas
F2
El usuario puede visualizar todas las ofertas de trabajo de una categoría
F3
El usuario refina el listado mediante palabras clave
F4
El usuario pincha sobre una oferta de trabajo para ver más información
F5
El usuario publica una nueva oferta de trabajo
F6
El usuario quiere convertirse en un afiliado
F7
Un usuario afiliado obtiene la lista de ofertas de trabajo activas
B1El administrador configura el sitio web
B2El administrador gestiona las ofertas de trabajo
B3El administrador gestiona los afiliados
Capítulo 3
El modelo de datosEl modelo de datos
El modelo relacionalEl modelo relacional
objetos
relacion
al
ORM
1. Describir la base de datos
2. Generar las clases PHP
3. Trabajar con objetos en vez de SQL
El formato YAMLEl formato YAML
YAMLFormato para serializar datos que es fácil de leer por las personas y es compatible con todos los lenguajes
de programación
$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'
));
casa:familia:
apellido: Garcíapadres:
‐ Antonio‐ María
hijos:‐ Jose‐ Manuel
direccion:numero: 34calle: Gran Víaciudad: Cualquieracodigopostal: "12345"
casa:familia: { apellido: García, padres: [Antonio,
María], hijos: [Jose, Manuel] }direccion: { numero: 34, direccion: Gran Vía,
ciudad: Cualquiera, codigopostal: "12345" }
clave:clave: valorclave:
clave: valorclave:
‐ valor‐ valor
Sintaxisclave:clave: valor
2 espacios en blanco
clave:‐ valor1‐ valor2‐ valor3
Arrays normales
clave:[valor1, valor2, valor3]
clave:clave1: valor1clave2: valor2clave3: valor3
Arrays asociativos
clave: { clave1: valor1, clave2: valor2, clave3: valor3}
<?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
El esquemaEl esquema
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 }
propel:jobeet_category:
id: ~name: { type: varchar(255),
required: true,index: unique
}
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: ~
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: ~
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
}
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
config/schema.yml
La base de datosLa base de datos
$ mysqladmin ‐uroot ‐p create jobeet
$ symfony configure:database“mysql:host=localhost;dbname=jobeet”root ConTraSenA
config/databases.yml
El ORMEl ORM
$ symfony propel:build‐sql
$ symfony propel:insert‐sql ‐‐no‐confirmation
data/sql/
$ symfony propel:build‐model
lib/model/
• JobeetJob
• BaseJobeetJob
• JobeetJobPeer
• BaseJobeetJobPeer
extends
extends
$job = new JobeetJob();$job‐>setPosition('Web developer');$job‐>save();
echo $job‐>getPosition();
$job‐>delete();
$category = new JobeetCategory(); $category‐>setName('Programming');
$job = new JobeetJob();$job‐>setCategory($category);
$ symfony propel:build‐all ‐‐no‐confirmation
$ symfony propel:build‐sql$ symfony propel:insert‐sql$ symfony propel:build‐model$ symfony propel:build‐forms$ symfony propel:build‐filters
$ symfony propel:build‐all+
$ 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
$ symfony cache:clear$ symfony cache:cl$ symfony ca:c$ symfony cc
Los datos inicialesLos datos iniciales
• Datos iniciales
• Datos de prueba
• Datos de usuarios
data/fixtures/
JobeetCategory:design: { name: Design }programming: { name: Programming }manager: { name: Manager }administrator: { name: Administrator }
data/fixtures/010_categories.yml
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
$ symfony propel:data‐load
$ 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
+
Probando la aplicación en el navegador
Probando la aplicación en el navegador
jobeet
frontend backend
proyecto
aplicación
job
mód
ulo
$ symfony propel:generate‐module‐‐with‐show ‐‐non‐verbose‐templatesfrontend job JobeetJob
actions/
templates/
frontend/modules/job
index
show
new
create
edit
update
delete
frontend/modules/job/actions/actions.class.php
frontend_devjob
http://jobeet.localhost/frontend_dev.php/job
Categoría __toString()
Objeto Representación textual
class JobeetCategory extends BaseJobeetCategory{
public function __toString(){
return $this‐>getName();}
}
lib/model/JobeetCategory.php
class JobeetJob extends BaseJobeetJob{
public function __toString(){
return sprintf('%s at %s (%s)',$this‐>getPosition(),$this‐>getCompany(),$this‐>getLocation()
);}
}
lib/model/JobeetJob.php
class JobeetAffiliate extends BaseJobeetAffiliate{
public function __toString(){
return $this‐>getUrl();}
}
lib/model/JobeetAffiliate.php
http://jobeet.localhost/frontend_dev.php/job
Capítulo 4
El controlador y la vistaEl controlador y la vista
La arquitectura MVCLa arquitectura MVC
¿Cómo se programaba con PHP en el siglo pasado?
1 página del sitio web = 1 archivo PHP
diferente
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?
ModeloVistaControlador
ModeloDirectorio /lib/model
VistaDirectorios templates/
ControladorArchivos index.php y frontend_dev.phpArchivos actions.class.php
El layoutEl layout
patrón de diseño decorator
apps/frontend/templates/layout.php
<!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
Plantillas Symfony
• Archivos PHP normales
• Existe un plugin para Smarty
• Symfony 2.0 podría incluir plantillas
Las hojas de estilos, imágenes y archivos
JavaScript
Las hojas de estilos, imágenes y archivos
JavaScript
<head>...<?php include_stylesheets() ?>
</head>
helpers
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
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
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
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
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
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
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
metas:stylesheets: [job]
view.yml
plantilla
plantilla
<?phpuse_stylesheet(‘job.css’)?>
La portada del módulo de las ofertas de
trabajo
La portada del módulo de las ofertas de
trabajo
apps/frontend/modules/job/actions/actions.class.phptemplates/indexSuccess.php
= +acción
plantilla
http://jobeet.localhost/frontend_dev.php/job/index
frontend (aplicación)
_dev (entorno)
job (módulo)
index (acción executeIndex y plantilla indexSuccess)
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
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]]
<?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
La plantilla de la página de una oferta de
trabajo
La plantilla de la página de una oferta de
trabajo
SlotsSlots
<title>Jobeet</title> <title>
plantillalayout
<title> </title> Título de la página
plantillalayout
<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
La acción de la página de una oferta de
trabajo
La acción de la página de una oferta de
trabajo
public function executeShow(sfWebRequest $request){
$this‐>job = JobeetJobPeer::retrieveByPk($request‐>getParameter('id')
);
$this‐>forward404Unless($this‐>job);}
apps/frontend/modules/job/actions/actions.class.php
La petición y la respuesta
La petición y la respuesta
class jobActions extends sfActions{
public function executeShow(sfWebRequest $request){
$peticion = $request;$origen = $peticion‐>getReferer();$metodo = $peticion‐>getMethod();
}
// ...}
objeto sfWebRequest
$_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
public function executeShow(sfWebRequest $request){
...$request‐>getParameter('id');
...
}
/ruta1/ruta2/ruta3?id=3&clave1=valor1&clave2=valor2
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
plantilla<?php use_stylesheet('job.css') ?>
acción
archivo de configuraciónmetas:
stylesheets: [job]
$this‐>getResponse()‐>addStyleSheet('/css/job.css');
Capítulo 5
El sistema de enrutamientoEl sistema de enrutamiento
URLURL
URL URIsistema de
enrutamiento
internet symfony
'job/show?id='.$job‐>getId()
job/show/id/1
url_for()
URI
URL
URI
modulo/accion?clave1=valor1&clave2=valor2&...
Configurando el enrutamientoConfigurando el enrutamiento
apps/frontend/config/routing.yml
homepage:url: /param: { module: default, action: index }
default_index:url: /:moduleparam: { action: index }
default:url: /:module/:action/*
default_index:url: /:moduleparam: { action: index }
nombre
patrón
parámetros
homepage:url: /param: { module: default, action: index }
default_index:url: /:moduleparam: { action: index }
default:url: /:module/:action/*
/job
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
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
url_for('job/show?id='.$job‐>getId())
URI URLurl_for()
/job/show/id/1
url_for('@default?id='.$job‐>getId())
URI URLurl_for()
Personalizando el enrutamiento
Personalizando el enrutamiento
homepage:url: /param: { module: job, action: index }
default_index:url: /:moduleparam: { action: index }
default:url: /:module/:action/*
apps/frontend/config/routing.yml
<h1><a href="<?php echo url_for('@homepage') ?>"><img src="/images/jobeet.gif" alt="Jobeet" /></a></h1>
/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
/job/sensio‐labs/paris‐france/1/web‐developer
1. Identificar el patrón de la URL
/job/:company/:location/:id/:position
/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 }
url_for('job/show?'.'id='.$job‐>getId().'&company='.$job‐>getCompany().'&location='.$job‐>getLocation().'&position='.$job‐>getPosition()
)
url_for(array('module' => 'job','action' => 'show','id' => $job‐>getId(),'company' => $job‐>getCompany(),'location' => $job‐>getLocation(),'position' => $job‐>getPosition(),
))
RequisitosRequisitos
/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+
La clase sfRouteLa clase sfRoute
HTTP Navegadores Symfony
GET
POST
HEAD
PUT
DELETE
job_show_user:url: /job/:company/:location/:id/:positionclass: sfRequestRouteparam: { module: job, action: show }requirements:id: \d+sf_method: [get]
La clase para las rutas basadas en
objetos
La clase para las rutas basadas en
objetos
url_for('job/show?'.'id='.$job‐>getId().'&company='.$job‐>getCompany().'&location='.$job‐>getLocation().'&position='.$job‐>getPosition()
)
job_show_user:url: /job/:company/:location/:id/:positionclass: sfPropelRouteoptions:model: JobeetJobtype: object
param: { module: job, action: show }requirements:id: \d+sf_method: [get]
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
))
/job/sensio‐labs/paris‐france/1/web‐developer
Lo que queremos…
/job/Sensio+Labs/Paris%2C+France/1/Web+Developer
Lo que tenemos…
Job
idnamedescription...
schema.yml
getId()
getName()
getDescription()
gettersvirtuales
getShortDescription()
getSlug()
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/
Job
idnamedescription...
schema.yml
getId()
getName()
getDescription()
gettersvirtuales
getPositionSlug()
getCompanySlug()
getLocationSlug()
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
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
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]
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(); }
// ...}
Enrutamiento en acciones y plantillas
Enrutamiento en acciones y plantillas
<?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>
class jobActions extends sfActions{public function executeIndex(sfWebRequest $request){
// ...
$this‐>redirect($this‐>generateUrl('job_show_user', $job)
);}
// ...}
La clase de las colecciones de
rutas
La clase de las colecciones de
rutas
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]
$ php symfony app:routes frontend