Curso Symfony Clase 4

  • Uploaded by: Julio Cesar Brizuela
  • 0
  • 0
  • June 2020
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Curso Symfony Clase 4 as PDF for free.

More details

  • Words: 1,917
  • Pages: 89
Frameworks de desarrollo

Symfony Clase 4

Javier Eguíluz [email protected]

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/

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/

Capítulo 16

Servicios web

long tail

sitio1.com

sitio2.com

sitio3.com

sitio4.com

Los afiliados

data/fixtures/

030_affiliates.yml

JobeetAffiliate: sensio_labs: url:       http://www.sensio‐labs.com/ email:     [email protected] is_active: true token:     sensio_labs jobeet_category_affiliates: [programming] symfony: url:       http://www.symfony‐project.org/ email:     [email protected] is_active: false token:     symfony jobeet_category_affiliates: [design, programming]

lib/model/JobeetAffiliate.php class JobeetAffiliate extends BaseJobeetAffiliate { public function save(PropelPDO $con = null) { if (!$this‐>getToken()) { $this‐>setToken( sha1($this‐>getEmail().rand(11111, 99999)) ); } return parent::save($con); } // ... }

apps/frontend/config/routing.yml api_jobs: url:   /api/:token/jobs.:sf_format class: sfPropelRoute param: { module: api, action: list } options: { model: JobeetJob, type: list, method: getForToken } requirements: sf_format: (?:xml|json|yaml)

lib/model/JobeetJobPeer.php static public function getForToken(array $parameters) { $affiliate = JobeetAffiliatePeer::getByToken($parameters['token']);

if (!$affiliate || !$affiliate‐>getIsActive()) { throw new sfError404Exception('...'); } return $affiliate‐>getActiveJobs(); }

lib/model/JobeetAffiliate.php class JobeetAffiliate extends BaseJobeetAffiliate { public function getActiveJobs() { $cas = $this‐>getJobeetCategoryAffiliates(); $categories = array(); foreach ($cas as $ca) { $categories[] = $ca‐>getCategoryId();  } $criteria = new Criteria(); $criteria‐>add( JobeetJobPeer::CATEGORY_ID, $categories, Criteria::IN );  JobeetJobPeer::addActiveJobsCriteria($criteria); return JobeetJobPeer::doSelect($criteria); } }

$ ./symfony generate:module frontend api apps/frontend/modules/api/actions/actions.class.php public function executeList(sfWebRequest $request) { $this‐>jobs = array(); foreach ($this‐>getRoute()‐>getObjects() as $job) { $url = $this‐>generateUrl('job_show_user', $job, true); $this‐>jobs[$url] = $job‐>asArray($request‐>getHost()); } }

XML

petición

JSON

executeList() YAML

apps/frontend/modules/api/templates/listSuccess.xml.php <jobs>  $job): ?> <job url="">  $value): ?> <> >

apps/frontend/modules/api/templates/listSuccess.json.php [  $job): ++$i ?> { "url": "",  $value): ++$j ?> "":  } ]

Cómo crear un nuevo formato 1. Crear la plantilla de la acción 

(xxxSuccess.formato.php) 2. Deshabilitar el layout y establecer el Content‐

Type de la respuesta 3. Crear las páginas de error y de excepción

(config/error/[error|exception].formato.yml)

apps/frontend/modules/api/templates/listSuccess.yaml.php  $job): ?> ‐ url:   $value): ?>

$this‐>setLayout(false); $this‐>getResponse()‐>setContentType('text/yaml');

config/error/exception.yaml.php  array( 'code' => $code, 'message' => $message, 'debug' => array( 'name' => $name, 'message' => $message, 'traces' => $traces, ), )), 4) ?>

config/error/error.yaml.php  array( 'code' => $code, 'message' => $message, ))) ?> 

apps/frontend/templates/layout.yaml.php

 

El formulario para  darse de alta como  afiliado

apps/frontend/config/routing.yml affiliate: class: sfPropelRouteCollection options: model:          JobeetAffiliate actions:        [new, create] object_actions: { wait: get }

$ ./symfony propel:generate‐module frontend affiliate JobeetAffiliate ‐‐non‐verbose‐templates

apps/frontend/modules/affiliate/templates/newSuccess.php

Conviértete en afiliado

 $form)) ?> 

apps/frontend/modules/affiliate/templates/_form.php ... ...

apps/frontend/modules/affiliate/templates/waitSuccess.php

Your affiliate account has been created

¡Gracias! Pronto recibirás un email... 


apps/frontend/templates/layout.php ...
  • "> Become an affiliate
  • ...

    Administrando los  afiliados

    $ ./symfony propel:generate‐admin backend JobeetAffiliate ‐‐module=affiliate

    apps/backend/modules/affiliate/config/generator.yml config: fields: is_active: { label: Active? } list: title:   Affiliate Management display: [is_active, url, email, token] sort:    [is_active] object_actions:

    activate:   ~ deactivate: ~ batch_actions:

    activate:   ~ deactivate: ~ actions: {} filter: display: [url, email, is_active]

    apps/backend/modules/affiliate/lib/affiliateGeneratorConfiguration.class.php

    public function getFilterDefaults() { return array('is_active' => '0'); }

    Enviando emails

    Zend Framework

    Zend_Mail "Zend_Mail provides generalized functionality to compose and send both text and MIME‐compliant multipart e‐mail  messages. Mail can be sent with Zend_Mail via the default Zend_Mail_Transport_Sendmail transport or via Zend_Mail_Transport_Smtp"

    1. Descargar Zend Framework 2.

    Descomprimirlo en lib/vendor/Zend

    3.

    Eliminar todo salvo: •

    Loader/



    Exception.php



    Loader.php



    Mime/



    Mail/



    Mime.php



    Mail.php



    Search/

    config/

    ProjectConfiguration.class.php

    class ProjectConfiguration extends sfProjectConfiguration { static protected $zendLoaded = false; static public function registerZend() { if (self::$zendLoaded) { return; } set_include_path(sfConfig::get('sf_lib_dir'). '/vendor'. PATH_SEPARATOR. get_include_path() ); require_once sfConfig::get('sf_lib_dir'). '/vendor/Zend/Loader.php';

    Zend_Loader::registerAutoload(); self::$zendLoaded = true; } }

    apps/backend/modules/affiliate/actions/

    actions.class.php

    ProjectConfiguration::registerZend(); $mail = new Zend_Mail(); $mail‐>setBodyText("Hemos activado tu cuenta y tu  token secreto es {$affiliate‐>getToken()}") ‐>setFrom('[email protected]', 'Jobeet Bot') ‐>addTo($affiliate‐>getEmail()) ‐>setSubject('Jobeet affiliate token') ‐>send();

    Capítulo 17

    El buscador

    La tecnología

    "No reinventes la rueda" NIH (Not Invented Here) “persistent sociological, corporate or institutional culture that avoids using or buying already existing products, research or knowledge because of its different origins”

    Zend Framework

    Zend_Search_Lucene "...un buscador genérico de texto escrito completamente  con PHP 5. Como guarda sus índices en archivos y no  requiere de un servidor de bases de datos, permite incluir  un buscador en cualquier sitio web construido con PHP."

    1. Descargar Zend Framework 2.

    Descomprimirlo en lib/vendor/Zend

    3.

    Eliminar todo salvo: •

    Loader/



    Exception.php



    Loader.php



    Mime/



    Mail/



    Mime.php



    Mail.php



    Search/

    config/

    ProjectConfiguration.class.php

    class ProjectConfiguration extends sfProjectConfiguration { static protected $zendLoaded = false; static public function registerZend() { if (self::$zendLoaded) { return; } set_include_path(sfConfig::get('sf_lib_dir'). '/vendor'. PATH_SEPARATOR. get_include_path() ); require_once sfConfig::get('sf_lib_dir'). '/vendor/Zend/Loader.php';

    Zend_Loader::registerAutoload(); self::$zendLoaded = true; } }

    Índices

    lib/model/

    JobeetJobPeer.php

    static public function getLuceneIndex() { ProjectConfiguration::registerZend(); if (file_exists($index = self::getLuceneIndexFile())) { return Zend_Search_Lucene::open($index); } else { return Zend_Search_Lucene::create($index); } } static public function getLuceneIndexFile() { return sfConfig::get('sf_data_dir'). '/job.'. sfConfig::get('sf_environment'). '.index'; }

    lib/model/

    JobeetJob.php

    public function save(PropelPDO $con = null) { // ... $ret = parent::save($con); $this‐>updateLuceneIndex(); return $ret; }

    lib/model/

    JobeetJob.php

    public function updateLuceneIndex() { $index = JobeetJobPeer::getLuceneIndex(); $doc = new Zend_Search_Lucene_Document(); $doc‐>addField(Zend_Search_Lucene_Field::UnIndexed( 'pk', $this‐>getId()) ); $doc‐>addField(Zend_Search_Lucene_Field::UnStored( 'position', $this‐>getPosition(), 'utf‐8') ); // ... $index‐>addDocument($doc); $index‐>commit(); }

    lib/model/

    JobeetJob.php

    public function save(PropelPDO $con = null) { // ... if (is_null($con)) { $con = Propel::getConnection(JobeetJobPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);

    } $con‐>beginTransaction(); try { $ret = parent::save($con); $this‐>updateLuceneIndex(); $con‐>commit(); return $ret; } catch (Exception $e) { $con‐>rollBack(); throw $e; } }

    lib/model/

    JobeetJob.php

    public function delete(PropelPDO $con = null) { $index = JobeetJobPeer::getLuceneIndex(); if ($hit = $index‐>find('pk:'.$this‐>getId())) { $index‐>delete($hit‐>id); } return parent::delete($con); }

    Búsquedas

    apps/frontend/config/

    job_search: url:   /search param: { module: job, action: search } apps/frontend/modules/job/actions/

    routing.yml

    actions.class.php

    class jobActions extends sfActions { public function executeSearch(sfWebRequest $request) { if (!$query = $request‐>getParameter('query')) { return $this‐>forward('job', 'index'); } $this‐>jobs = JobeetJobPeer::getForLuceneQuery($query);  } // ... }

    lib/model/

    JobeetJobPeer.php

    static public function getForLuceneQuery($query) { $hits = self::getLuceneIndex()‐>find($query); $pks = array(); foreach ($hits as $hit) { $pks[] = $hit‐>pk; } $criteria = new Criteria(); $criteria‐>add(self::ID, $pks, Criteria::IN); $criteria‐>setLimit(20); return self::doSelect(self::addActiveJobsCriteria($criteria)); }

    Capítulo 18

    AJAX

    web/js/jquery‐1.2.6.min.js

    Incluyendo jQuery

    apps/frontend/templates/

    layout.php

    ...

    mejora el  rendimiento ...

    Añadiendo los  comportamientos

    $('#search_keywords').keyup(function(key) { if (this.value.length >= 3 || this.value == '') { $('#jobs').load( $(this).parents('form').attr('action'), { query: this.value + '*' } ); } }); $('.search input[type="submit"]').hide();

    web/js/search.js $(document).ready(function() { $('.search input[type="submit"]').hide(); $('#search_keywords').keyup(function(key) { if (this.value.length >= 3 || this.value == '') { $('#loader').show(); $('#jobs').load( $(this).parents('form').attr('action'), { query: this.value + '*' }, function() { $('#loader').hide(); } ); } }); });

    apps/frontend/templates/layout.php



    AJAX en las acciones

    AJAX layout + renderPartial()

    JavaScript layout + searchSuccess.php

    apps/frontend/modules/job/actions/actions.class.php public function executeSearch(sfWebRequest $request) { if (!$query = $request‐>getParameter('query')) { return $this‐>forward('job', 'index'); } $this‐>jobs = JobeetJobPeer::getForLuceneQuery($query); if ($request‐>isXmlHttpRequest()) { return $this‐>renderPartial( 'job/list', array('jobs' => $this‐>jobs) ); }

    AJAX

    }

    apps/frontend/modules/job/actions/actions.class.php public function executeSearch(sfWebRequest $request) { if (!$query = $request‐>getParameter('query')) { return $this‐>forward('job', 'index'); } $this‐>jobs = JobeetJobPeer::getForLuceneQuery($query);

    if ($request‐>isXmlHttpRequest()) { if ('*' == $query || !$this‐>jobs) { return $this‐>renderText('No results.'); } else { return $this‐>renderPartial( 'job/list', array('jobs' => $this‐>jobs) ); } } }

    http://www.symfony‐project.org/api/1_2/sfAction

    renderText() renderPartial() renderComponent()

    Capítulo 19

    i18n y l10n

    i18n y l10n "La internacionalización es el proceso de diseñar aplicaciones de  software que puedan ser adaptadas a distintos idiomas y  regiones sin necesidad de realizar cambios en su ingeniería."

    "La localización es el proceso de adaptar el software para una  región o idioma específicos mediante la inclusión de componentes  específicos de esa región y mediante la traducción del texto."

    El usuario

    idioma + país = cultura es_ES

    fr_FR

    es_AR

    fr_BE

    es_MX

    fr_CA

    es_PE

    idioma (ISO 3166‐1) país (ISO 639‐1)

    $this‐>getUser()‐>setCulture('fr_BE'); echo $this‐>getUser()‐>getCulture();

    apps/frontend/config/

    all: .settings: default_culture: es_ES

    settings.yml

    $idiomas = $request‐>getLanguages(); $idiomas = $request‐>getPreferredCulture( array('en', 'fr') ); 

    Incluyendo la cultura  en la URL

    apps/frontend/config/

    settings.yml

    category: url:     /:sf_culture/category/:slug.:sf_format class:   sfPropelRoute param:   { module: category, action: show, sf_format: html } options: { model: JobeetCategory, type: object } requirements: sf_format: (?:html|atom) job_search: url:   /:sf_culture/search param: { module: job, action: search }

    Cambiando de  idioma

    $ ./symfony plugin:install sfFormExtraPlugin

    $ ./symfony cc

    apps/frontend/templates/

    layout.php

     

    $ ./symfony generate:module frontend idioma

    apps/frontend/modules/idioma/actions/

    components.class.php

    class languageComponents extends sfComponents { public function executeIdioma(sfWebRequest $request) { $this‐>form = new sfFormLanguage( $this‐>getUser(), array('languages' => array('en', 'fr')) ); } }

    apps/frontend/config/

    routing.yml

    cambiar_idioma: url:   /cambiar_idioma param: { module: idioma, action: cambiarIdioma } apps/frontend/modules/idioma/actions/

    actions.class.php

    class idiomaActions extends sfActions { public function executeCambiarIdioma(sfWebRequest $request) { $form = new sfFormLanguage( $this‐>getUser(), array('languages' => array('en', 'fr')) ); $form‐>process($request); return $this‐>redirect('@localized_homepage'); } }

    apps/frontend/config/

    localized_homepage: url:   /:sf_culture/ param: { module: job, action: index } requirements: sf_culture: (?:fr|en|es|eu)

    routing.yml

    Internacionalización

    Where are you from?

    Vous êtes d'où ? 

    どこから来ましたか

    ASCII

    ISO‐8859‐1

    UTF‐8

    apps/frontend/config/

    settings.yml

    all: .settings: charset: utf‐8 i18n:    on standard_helpers: [Partial, Cache, I18N]

    layout.php

    apps/frontend/templates/
    •  
    •  
      • gettext • SQLite

    _ _( )

    • MySQL

    • XLIFF

    $ ./symfony i18n:extract frontend fr ‐‐auto‐save apps/frontend/i18n/fr/

    messages.xml



    <xliff version="1.0">


    <source>About Jobeet <source>Feed ...

     link_to($count, 'category', $category) )) ?>


     '<strong>'.$pager‐>getNbResults().'' ), $pager‐>getNbResults() ) ?>

    $ ./symfony i18n:extract frontend fr ‐‐auto‐save

    apps/frontend/i18n/fr/

    messages.xml

    <source> [0]No job in this category| [1]One job in this category| (1,+Inf]%count% jobs in this category [0]Aucune annonce dans cette catégorie| [1]Une annonce dans cette catégorie| (1,+Inf]%count% annonces dans cette catégorie

    config/

    schema.yml

    jobeet_category: _attributes: { isI18N: true, i18nTable:  jobeet_category_i18n } id:          ~ jobeet_category_i18n: id:      { type: integer, required: true, primaryKey:  true, foreignTable: jobeet_category,  foreignReference: id } culture: { isCulture: true, type: varchar, size: 7,  required: true, primaryKey: true } name:    { type: varchar(255), required: true } slug:    { type: varchar(255), required: true }

    data/fixtures/

    010_categories.yml

    JobeetCategory: design:        { } programming:   { } JobeetCategoryI18n: design_en:      { id: design, culture: en, name: Design } programming_en: { id: programming, culture: en, name:  Programming } design_fr:      { id: design, culture: fr, name: Design } programming_fr: { id: programming, culture: fr, name:  Programmation }

    apps/frontend/config/

    routing.yml

    category: url:     /:sf_culture/category/:slug.:sf_format class:   sfPropelRoute param:   { module: category, action: show, sf_format: html } options: { model: JobeetCategory, type: object, method:  doSelectForSlug } requirements: sf_format: (?:html|atom)

    $ ./symfony propel:data‐load /frontend_dev.php/fr/category/programmation /frontend_dev.php/en/category/programming

    lib/form/

    JobeetCategoryForm.class.php

    class JobeetCategoryForm extends BaseJobeetCategoryForm { public function configure() { unset($this['jobeet_category_affiliate_list']);

    $this‐>embedI18n(array('en', 'fr')); $this‐>widgetSchema‐>setLabel('en', 'English');  $this‐>widgetSchema‐>setLabel('fr', 'French'); } }

    Localización

    format_date() format_datetime() format_number() format_currency() format_country() format_language()

    sfWidgetFormI18nDate sfWidgetFormI18nDateTime sfWidgetFormI18nTime sfWidgetFormI18nSelectCountry sfWidgetFormI18nSelectCurrency sfWidgetFormI18nSelectLanguage sfValidatorI18nChoiceCountry sfValidatorI18nChoiceLanguage

    Related Documents


    More Documents from ""

    Blender - Tutorial Casa
    October 2019 12
    December 2019 15
    Curso Symfony Clase 2
    June 2020 12
    Curso Symfony Clase 4
    June 2020 12
    Blender - Tutorial Ginger
    October 2019 20