Symfony2, creare bundle e valore         per il cliente          Leonardo Proietti              @_leopro_             Symf...
valore per il cliente = benefici / costi
collaborazione
collaborazioneresponsabilità
collaborazione     responsabilitàreciproca soddisfazione
Il processo di sviluppo basato sullacollaborazione, sulla reciproca soddisfazione esul senso di responsabilità permette di...
bundle = è una cartella con una struttura bendefinita, che può ospitare qualsiasi cosa, dalle     classi ai controllori e ...
bundle = uno spazio dei nomi di PHP ovvero un   namespace, con con una classe Bundle http://symfony.com/it/doc/current/coo...
bundle = una libreria sufficientemente astrattada essere utilizzata in contesti diversi tra loro
la realizzazione di un bundle non è valore               per il cliente
Richiestaun sito web con contenuti aggiornabili      disponibili in diverse lingue
Analisigli strumenti esistenti sono valutati come non                     adatti
Idearelazione uno-a-molti, DIC, eventi
Sarà una libreria riutilizzabile?
Sarà una libreria riutilizzabile?Non è importante perchè lobiettivo principale è         produrre valore per il cliente
Ma non vogliamo spaghetti code
Test Driven Developmentovvero sviluppare guidati dai test
Test Driven Developmentovvero sviluppi meglio, vivi meglio
$article->getTitle();     /it/{article}  “Il mio articolo”   /en/{article}    “My article”
Acme  CoreBundle  Listener  LocaleListener.php  EntityListener.php  AnotherListener.php  Locale  Locale.php  LocaleInterfa...
Acme  CoreBundle  Listener  LocaleListener.php  EntityListener.php  AnotherListener.php  Locale  Locale.php  LocaleInterfa...
interface LocaleInterface{   function setLocale($locale);    function getLocale();    function getDefaultLocale();}
use AcmeCoreBundleModelTranslatingInterface;use AcmeCoreBundleLocaleLocaleInterface;interface TranslatableInterface{   fun...
use AcmeCoreBundleModelTranslatableInterface;interface TranslatingInterface{    function setTranslatable(TranslatableInter...
class Article{   /**   * @ORMOneToMany   * (targetEntity="ArticleI18n", mappedBy="translatable")   */   protected $transla...
class Article{   /**   * @ORMOneToMany   * (targetEntity="ArticleI18n", mappedBy="translatable")   */   protected $transla...
class ArticleI18n{   /**   * @ORMManyToOne(targetEntity="Article", inversedBy="translations"   * @ORMJoinColumn(name="arti...
Symfony2kernel.request
public function testOnKernelRequest(){  //SymfonyComponentHttpKernelEventGetResponseEvent  $this->event->expects($this->on...
public function testOnKernelRequest(){  //SymfonyComponentHttpKernelEventGetResponseEvent  $this->event->expects($this->on...
public function testOnKernelRequest(){  //SymfonyComponentHttpKernelEventGetResponseEvent  $this->event->expects($this->on...
public function testOnKernelRequest(){  //SymfonyComponentHttpKernelEventGetResponseEvent  $this->event->expects($this->on...
public function testOnKernelRequest(){  //SymfonyComponentHttpKernelEventGetResponseEvent  $this->event->expects($this->on...
public function testOnKernelRequest(){  //SymfonyComponentHttpKernelEventGetResponseEvent  $this->event->expects($this->on...
public function testOnKernelRequest(){  //SymfonyComponentHttpKernelEventGetResponseEvent  $this->event->expects($this->on...
public function testOnKernelRequest(){  //SymfonyComponentHttpKernelEventGetResponseEvent  $this->event->expects($this->on...
public function testOnKernelRequest(){  //SymfonyComponentHttpKernelEventGetResponseEvent  $this->event->expects($this->on...
Doctrine2postLoad
public function testPostLoad(){    //AcmeCoreBundleLocaleLocaleInterface    $this->locale;    //DoctrineORMEventLifecycleE...
public function testPostLoad(){    //AcmeCoreBundleLocaleLocaleInterface    $this->locale;    //DoctrineORMEventLifecycleE...
public function testPostLoad(){    //AcmeCoreBundleLocaleLocaleInterface    $this->locale;    //DoctrineORMEventLifecycleE...
public function testPostLoad(){    //AcmeCoreBundleLocaleLocaleInterface    $this->locale;    //DoctrineORMEventLifecycleE...
public function testPostLoad(){    //AcmeCoreBundleLocaleLocaleInterface    $this->locale;    //DoctrineORMEventLifecycleE...
public function testPostLoad(){    //AcmeCoreBundleLocaleLocaleInterface    $this->locale;    //DoctrineORMEventLifecycleE...
//tranlsations, defaultLocale, locale, tranlsationExpectedpublic function getTranslationProvider(){     return array(     ...
//tranlsations, defaultLocale, locale, tranlsationExpectedpublic function getTranslationProvider(){     return array(     ...
//tranlsations, defaultLocale, locale, tranlsationExpectedpublic function getTranslationProvider(){     return array(     ...
//tranlsations, defaultLocale, locale, tranlsationExpectedpublic function getTranslationProvider(){     return array(     ...
public function testGetTranslation($translations, $defaultLocale, $locale,$translationExpected){     $this->translatable =...
public function testGetTranslation($translations, $defaultLocale, $locale,$translationExpected){     $this->translatable =...
Non resta che soddisfare i test scrivendo del           codice funzionante :-)
configuriamo i servizi//src/Acme/CoreBundle/Resources/config/services.ymlservices: acme_core.locale:     class:   AcmeCore...
configuriamo i servizi//src/Acme/CoreBundle/Resources/config/services.ymlservices: acme_core.locale:     class:   AcmeCore...
class Article extends Translatable{   /**   * @ORMOneToMany   * (targetEntity="ArticleI18n", mappedBy="translatable")   */...
Una volta testata anche lintegrazione e  verificato che la richiesta del cliente è statasoddisfatta, abbiamo prodotto il v...
Nuovo cliente, stessa richiesta
Prendiamo il codice e lo isoliamo       PUGX/I18nBundle
AcmePlusPUGX  I18nBundle  Listener  LocaleListener.php  EntityListener.php  Locale  Locale.php  LocaleInterface.php  Model...
Il grosso è fatto, ora dovremo:- esporre una configurazione semantica- gestire le dipendenze (composer) e la configurazion...
AcmePlusPUGX  I18nBundle  DependencyInjection  Configuration.php  PUGXI18nExtension.php  […]  Tests  bootstrap.php  PUGXI1...
namespace PUGXI18nBundle;use SymfonyComponentHttpKernelBundleBundle;use PUGXI18nBundleDependencyInjectionPUGXI18nExtension...
namespace PUGXI18nBundleDependencyInjection;use SymfonyComponentConfigDefinitionBuilderTreeBuilder;use SymfonyComponentCon...
namespace PUGXI18nBundleDependencyInjection;use SymfonyComponentDependencyInjectionContainerBuilder;use SymfonyComponentCo...
Composergestisce le dipendenze
//src/PUGX/I18nBundle/composer.json{    "name": "pugx/i18n-bundle",    "type": "symfony-bundle",    "description": "Manage...
//src/PUGX/I18nBundle/Tests/bootstrap.phpif (!is_file($autoloadFile = __DIR__./../vendor/autoload.php)) {      throw new L...
//src/PUGX/I18nBundle/phpunit.xml.dist<?xml version="1.0" encoding="UTF-8"?><phpunit bootstrap="./Tests/bootstrap.php">   ...
Servizio rivolto alla comunità open source perla continuos integration di progetti pubblicati su                       git...
//src/PUGX/I18nBundle/.travis.ymllanguage: phpphp:   - 5.3   - 5.4before_script:    - curl -s http://getcomposer.org/insta...
Ora basta creare un repository su github eavremo dato il nostro piccolo contributo alla         comunità open source.
Creditssymfony.com/it/doc/2.0/book/internals.htmlsymfony.com/it/doc/2.0/cookbook/bundles/best_practices.htmlsymfony.com/it...
GRAZIE :-)
Symfony2, creare bundle e valore per il cliente
Upcoming SlideShare
Loading in …5
×

Symfony2, creare bundle e valore per il cliente

1,497 views

Published on

Un gioco in cui vincono tutti o due piccioni con una fava ;)

Lavorare rivolti alla creazione di valore per il cliente e da questo ottenere una libreria quasi pronta per essere pubblicata

Published in: Technology
  • Be the first to comment

Symfony2, creare bundle e valore per il cliente

  1. 1. Symfony2, creare bundle e valore per il cliente Leonardo Proietti @_leopro_ Symfony day Torino, 5 ottobre 2012
  2. 2. valore per il cliente = benefici / costi
  3. 3. collaborazione
  4. 4. collaborazioneresponsabilità
  5. 5. collaborazione responsabilitàreciproca soddisfazione
  6. 6. Il processo di sviluppo basato sullacollaborazione, sulla reciproca soddisfazione esul senso di responsabilità permette di ottenere un alto valore per il cliente.
  7. 7. bundle = è una cartella con una struttura bendefinita, che può ospitare qualsiasi cosa, dalle classi ai controllori e alle risorse webhttp://symfony.com/it/doc/current/cookbook/bundles/best_practices.html
  8. 8. bundle = uno spazio dei nomi di PHP ovvero un namespace, con con una classe Bundle http://symfony.com/it/doc/current/cookbook/bundles/best_practices.html
  9. 9. bundle = una libreria sufficientemente astrattada essere utilizzata in contesti diversi tra loro
  10. 10. la realizzazione di un bundle non è valore per il cliente
  11. 11. Richiestaun sito web con contenuti aggiornabili disponibili in diverse lingue
  12. 12. Analisigli strumenti esistenti sono valutati come non adatti
  13. 13. Idearelazione uno-a-molti, DIC, eventi
  14. 14. Sarà una libreria riutilizzabile?
  15. 15. Sarà una libreria riutilizzabile?Non è importante perchè lobiettivo principale è produrre valore per il cliente
  16. 16. Ma non vogliamo spaghetti code
  17. 17. Test Driven Developmentovvero sviluppare guidati dai test
  18. 18. Test Driven Developmentovvero sviluppi meglio, vivi meglio
  19. 19. $article->getTitle(); /it/{article} “Il mio articolo” /en/{article} “My article”
  20. 20. Acme CoreBundle Listener LocaleListener.php EntityListener.php AnotherListener.php Locale Locale.php LocaleInterface.php Model Translatable.php TranslatableInterface.php TranslatingInterface.php AnotherModelUtil.php Tests ...
  21. 21. Acme CoreBundle Listener LocaleListener.php EntityListener.php AnotherListener.php Locale Locale.php LocaleInterface.php Model Translatable.php TranslatableInterface.php TranslatingInterface.php AnotherModelUtil.php Tests ...
  22. 22. interface LocaleInterface{ function setLocale($locale); function getLocale(); function getDefaultLocale();}
  23. 23. use AcmeCoreBundleModelTranslatingInterface;use AcmeCoreBundleLocaleLocaleInterface;interface TranslatableInterface{ function addTranslation(TranslatingInterface $translation); function getTranslations(); function setLocale(LocaleInterface $locale);}
  24. 24. use AcmeCoreBundleModelTranslatableInterface;interface TranslatingInterface{ function setTranslatable(TranslatableInterface $translatable); function getLocale(); function setLocale($string);}
  25. 25. class Article{ /** * @ORMOneToMany * (targetEntity="ArticleI18n", mappedBy="translatable") */ protected $translations; public function getTitle() { return $this->getTranslation()->getTitle(); }}
  26. 26. class Article{ /** * @ORMOneToMany * (targetEntity="ArticleI18n", mappedBy="translatable") */ protected $translations; public function getTitle() { return $this->getTranslation()->getTitle(); }}
  27. 27. class ArticleI18n{ /** * @ORMManyToOne(targetEntity="Article", inversedBy="translations" * @ORMJoinColumn(name="article_id", referencedColumnName="id") */ protected $translatable; /** * @ORMColumn(type="string", length=128) */ private $title; public function getTitle() { return $this->title; }}
  28. 28. Symfony2kernel.request
  29. 29. public function testOnKernelRequest(){ //SymfonyComponentHttpKernelEventGetResponseEvent $this->event->expects($this->once() ->method(getRequest) ->will($this->returnValue($this->request)); //SymfonyComponentHttpFoundationRequest $this->request->expects($this->once()) ->method(getLocale) ->will($this->returnValue(en)); //AcmeCoreBundleLocaleLocaleInterface $this->locale->expects($this->once()) ->method(setLocale) ->with(en); //AcmeCoreBundleListenerLocaleListener $this->listener = new LocaleListener($this->locale); $this->listener->onKernelRequest($this->event);}
  30. 30. public function testOnKernelRequest(){ //SymfonyComponentHttpKernelEventGetResponseEvent $this->event->expects($this->once() ->method(getRequest) ->will($this->returnValue($this->request)); //SymfonyComponentHttpFoundationRequest $this->request->expects($this->once()) ->method(getLocale) ->will($this->returnValue(en)); //AcmeCoreBundleLocaleLocaleInterface $this->locale->expects($this->once()) ->method(setLocale) ->with(en); //AcmeCoreBundleListenerLocaleListener $this->listener = new LocaleListener($this->locale); $this->listener->onKernelRequest($this->event);}
  31. 31. public function testOnKernelRequest(){ //SymfonyComponentHttpKernelEventGetResponseEvent $this->event->expects($this->once() ->method(getRequest) ->will($this->returnValue($this->request)); //SymfonyComponentHttpFoundationRequest $this->request->expects($this->once()) ->method(getLocale) ->will($this->returnValue(en)); //AcmeCoreBundleLocaleLocaleInterface $this->locale->expects($this->once()) ->method(setLocale) ->with(en); //AcmeCoreBundleListenerLocaleListener $this->listener = new LocaleListener($this->locale); $this->listener->onKernelRequest($this->event);}
  32. 32. public function testOnKernelRequest(){ //SymfonyComponentHttpKernelEventGetResponseEvent $this->event->expects($this->once() ->method(getRequest) ->will($this->returnValue($this->request)); //SymfonyComponentHttpFoundationRequest $this->request->expects($this->once()) ->method(getLocale) ->will($this->returnValue(en)); //AcmeCoreBundleLocaleLocaleInterface $this->locale->expects($this->once()) ->method(setLocale) ->with(en); //AcmeCoreBundleListenerLocaleListener $this->listener = new LocaleListener($this->locale); $this->listener->onKernelRequest($this->event);}
  33. 33. public function testOnKernelRequest(){ //SymfonyComponentHttpKernelEventGetResponseEvent $this->event->expects($this->once() ->method(getRequest) ->will($this->returnValue($this->request)); //SymfonyComponentHttpFoundationRequest $this->request->expects($this->once()) ->method(getLocale) ->will($this->returnValue(en)); //AcmeCoreBundleLocaleLocaleInterface $this->locale->expects($this->once()) ->method(setLocale) ->with(en); //AcmeCoreBundleListenerLocaleListener $this->listener = new LocaleListener($this->locale); $this->listener->onKernelRequest($this->event);}
  34. 34. public function testOnKernelRequest(){ //SymfonyComponentHttpKernelEventGetResponseEvent $this->event->expects($this->once() ->method(getRequest) ->will($this->returnValue($this->request)); //SymfonyComponentHttpFoundationRequest $this->request->expects($this->once()) ->method(getLocale) ->will($this->returnValue(en)); //AcmeCoreBundleLocaleLocaleInterface $this->locale->expects($this->once()) ->method(setLocale) ->with(en); //AcmeCoreBundleListenerLocaleListener $this->listener = new LocaleListener($this->locale); $this->listener->onKernelRequest($this->event);}
  35. 35. public function testOnKernelRequest(){ //SymfonyComponentHttpKernelEventGetResponseEvent $this->event->expects($this->once() ->method(getRequest) ->will($this->returnValue($this->request)); //SymfonyComponentHttpFoundationRequest $this->request->expects($this->once()) ->method(getLocale) ->will($this->returnValue(en)); //AcmeCoreBundleLocaleLocaleInterface $this->locale->expects($this->once()) ->method(setLocale) ->with(en); //AcmeCoreBundleListenerLocaleListener $this->listener = new LocaleListener($this->locale); $this->listener->onKernelRequest($this->event);}
  36. 36. public function testOnKernelRequest(){ //SymfonyComponentHttpKernelEventGetResponseEvent $this->event->expects($this->once() ->method(getRequest) ->will($this->returnValue($this->request)); //SymfonyComponentHttpFoundationRequest $this->request->expects($this->once()) ->method(getLocale) ->will($this->returnValue(en)); //AcmeCoreBundleLocaleLocaleInterface $this->locale->expects($this->once()) ->method(setLocale) ->with(en); //AcmeCoreBundleListenerLocaleListener $this->listener = new LocaleListener($this->locale); $this->listener->onKernelRequest($this->event);}
  37. 37. public function testOnKernelRequest(){ //SymfonyComponentHttpKernelEventGetResponseEvent $this->event->expects($this->once() ->method(getRequest) ->will($this->returnValue($this->request)); //SymfonyComponentHttpFoundationRequest $this->request->expects($this->once()) ->method(getLocale) ->will($this->returnValue(en)); //AcmeCoreBundleLocaleLocaleInterface $this->locale->expects($this->once()) ->method(setLocale) ->with(en); //AcmeCoreBundleListenerLocaleListener $this->listener = new LocaleListener($this->locale); $this->listener->onKernelRequest($this->event);}
  38. 38. Doctrine2postLoad
  39. 39. public function testPostLoad(){ //AcmeCoreBundleLocaleLocaleInterface $this->locale; //DoctrineORMEventLifecycleEventArgs $this->args->expects($this->once()) ->method(getEntity) ->will($this->returnValue($this->entity)); //AcmeCoreBundleModelTranslatableInterface $this->entity->expects($this->once()) ->method(setLocale) ->with($this->locale); //AcmeCoreBundleListenerEntityListener $this->listener = new TranslatableListener($this->locale); $this->listener->postLoad($this->event);}
  40. 40. public function testPostLoad(){ //AcmeCoreBundleLocaleLocaleInterface $this->locale; //DoctrineORMEventLifecycleEventArgs $this->args->expects($this->once()) ->method(getEntity) ->will($this->returnValue($this->entity)); //AcmeCoreBundleModelTranslatableInterface $this->entity->expects($this->once()) ->method(setLocale) ->with($this->locale); //AcmeCoreBundleListenerEntityListener $this->listener = new TranslatableListener($this->locale); $this->listener->postLoad($this->event);}
  41. 41. public function testPostLoad(){ //AcmeCoreBundleLocaleLocaleInterface $this->locale; //DoctrineORMEventLifecycleEventArgs $this->args->expects($this->once()) ->method(getEntity) ->will($this->returnValue($this->entity)); //AcmeCoreBundleModelTranslatableInterface $this->entity->expects($this->once()) ->method(setLocale) ->with($this->locale); //AcmeCoreBundleListenerEntityListener $this->listener = new TranslatableListener($this->locale); $this->listener->postLoad($this->event);}
  42. 42. public function testPostLoad(){ //AcmeCoreBundleLocaleLocaleInterface $this->locale; //DoctrineORMEventLifecycleEventArgs $this->args->expects($this->once()) ->method(getEntity) ->will($this->returnValue($this->entity)); //AcmeCoreBundleModelTranslatableInterface $this->entity->expects($this->once()) ->method(setLocale) ->with($this->locale); //AcmeCoreBundleListenerEntityListener $this->listener = new TranslatableListener($this->locale); $this->listener->postLoad($this->event);}
  43. 43. public function testPostLoad(){ //AcmeCoreBundleLocaleLocaleInterface $this->locale; //DoctrineORMEventLifecycleEventArgs $this->args->expects($this->once()) ->method(getEntity) ->will($this->returnValue($this->entity)); //AcmeCoreBundleModelTranslatableInterface $this->entity->expects($this->once()) ->method(setLocale) ->with($this->locale); //AcmeCoreBundleListenerEntityListener $this->listener = new TranslatableListener($this->locale); $this->listener->postLoad($this->event);}
  44. 44. public function testPostLoad(){ //AcmeCoreBundleLocaleLocaleInterface $this->locale; //DoctrineORMEventLifecycleEventArgs $this->args->expects($this->once()) ->method(getEntity) ->will($this->returnValue($this->entity)); //AcmeCoreBundleModelTranslatableInterface $this->entity->expects($this->once()) ->method(setLocale) ->with($this->locale); //AcmeCoreBundleListenerEntityListener $this->listener = new TranslatableListener($this->locale); $this->listener->postLoad($this->event);}
  45. 45. //tranlsations, defaultLocale, locale, tranlsationExpectedpublic function getTranslationProvider(){ return array( array( array(it => translationIt, en => translationEn), en, en, translationEn), array( array(en => translationEn, it => translationIt), en, it, translationIt), array( array(en => translationEn), en, it, translationEn), )}
  46. 46. //tranlsations, defaultLocale, locale, tranlsationExpectedpublic function getTranslationProvider(){ return array( array( array(it => translationIt, en => translationEn), en, en, translationEn), array( array(en => translationEn, it => translationIt), en, it, translationIt), array( array(en => translationEn), en, it, translationEn), )}
  47. 47. //tranlsations, defaultLocale, locale, tranlsationExpectedpublic function getTranslationProvider(){ return array( array( array(it => translationIt, en => translationEn), en, en, translationEn), array( array(en => translationEn, it => translationIt), en, it, translationIt), array( array(en => translationEn), en, it, translationEn), )}
  48. 48. //tranlsations, defaultLocale, locale, tranlsationExpectedpublic function getTranslationProvider(){ return array( array( array(it => translationIt, en => translationEn), en, en, translationEn), array( array(en => translationEn, it => translationIt), en, it, translationIt), array( array(en => translationEn), en, it, translationEn), )}
  49. 49. public function testGetTranslation($translations, $defaultLocale, $locale,$translationExpected){ $this->translatable = new Translatable(); $this->translatable->setLocale($this->locale); foreach ($translations as $language => $translation) { $this->$translation->expects($this->exactly(2))->method(getLocale) ->will($this->returnValue($language)); $this->translatable->addTranslation($this->$translation); } $this->locale->expects($this->exactly(1)) ->method(getDefaultLocale) ->will($this->returnValue($defaultLocale)); $this->locale->expects($this->exactly(1)) ->method(getLocale) ->will($this->returnValue($locale)); $result = $this->translatable->getTranslation(); $this->assertEquals($this->$translationExpected, $result);}
  50. 50. public function testGetTranslation($translations, $defaultLocale, $locale,$translationExpected){ $this->translatable = new Translatable(); $this->translatable->setLocale($this->locale); foreach ($translations as $language => $translation) { $this->$translation->expects($this->exactly(2))->method(getLocale) ->will($this->returnValue($language)); $this->translatable->addTranslation($this->$translation); } $this->locale->expects($this->exactly(1)) ->method(getDefaultLocale) ->will($this->returnValue($defaultLocale)); $this->locale->expects($this->exactly(1)) ->method(getLocale) ->will($this->returnValue($locale)); $result = $this->translatable->getTranslation(); $this->assertEquals($this->$translationExpected, $result);}
  51. 51. Non resta che soddisfare i test scrivendo del codice funzionante :-)
  52. 52. configuriamo i servizi//src/Acme/CoreBundle/Resources/config/services.ymlservices: acme_core.locale: class: AcmeCoreBundleServiceLocale arguments: [%locale%] acme_core.listener.locale: class: AcmeCoreBundleServiceLocaleListener arguments: ["@acme.core.locale"] tags: - { name: kernel.event_listener, event: kernel.request } acme_core.listener.entity: class: AcmeCoreBundleServiceEntityListener arguments: ["@acme.core.locale"] tags: - { name: doctrine.event_listener, event: postLoad }
  53. 53. configuriamo i servizi//src/Acme/CoreBundle/Resources/config/services.ymlservices: acme_core.locale: class: AcmeCoreBundleServiceLocale arguments: [%locale%] acme_core.listener.locale: class: AcmeCoreBundleServiceLocaleListener arguments: ["@acme.core.locale"] tags: - { name: kernel.event_listener, event: kernel.request } acme_core.listener.entity: class: AcmeCoreBundleServiceEntityListener arguments: ["@acme.core.locale"] tags: - { name: doctrine.event_listener, event: postLoad }
  54. 54. class Article extends Translatable{ /** * @ORMOneToMany * (targetEntity="ArticleI18n", mappedBy="translatable") */ protected $translations; public function getTitle() { return $this->getTranslation()->getTitle(); }}
  55. 55. Una volta testata anche lintegrazione e verificato che la richiesta del cliente è statasoddisfatta, abbiamo prodotto il valore richiesto e ci possiamo fermare.
  56. 56. Nuovo cliente, stessa richiesta
  57. 57. Prendiamo il codice e lo isoliamo PUGX/I18nBundle
  58. 58. AcmePlusPUGX I18nBundle Listener LocaleListener.php EntityListener.php Locale Locale.php LocaleInterface.php Model Translatable.php TranslatableInterface.php TranslatingInterface.php Tests
  59. 59. Il grosso è fatto, ora dovremo:- esporre una configurazione semantica- gestire le dipendenze (composer) e la configurazione dei test- aggiungere la documentazione, la licenza ecc.
  60. 60. AcmePlusPUGX I18nBundle DependencyInjection Configuration.php PUGXI18nExtension.php […] Tests bootstrap.php PUGXI18nBundle.php composer.json phpunit.xml.dist
  61. 61. namespace PUGXI18nBundle;use SymfonyComponentHttpKernelBundleBundle;use PUGXI18nBundleDependencyInjectionPUGXI18nExtension;class PUGXI18nBundle extends Bundle{ public function getContainerExtension() { return new PUGXI18nExtension(); }}
  62. 62. namespace PUGXI18nBundleDependencyInjection;use SymfonyComponentConfigDefinitionBuilderTreeBuilder;use SymfonyComponentConfigDefinitionConfigurationInterface;class Configuration implements ConfigurationInterface{ public function getConfigTreeBuilder() { $treeBuilder = new TreeBuilder(); $rootNode = $treeBuilder->root(pugx_i18n); return $treeBuilder; }}
  63. 63. namespace PUGXI18nBundleDependencyInjection;use SymfonyComponentDependencyInjectionContainerBuilder;use SymfonyComponentConfigFileLocator;use SymfonyComponentHttpKernelDependencyInjectionExtension;use SymfonyComponentDependencyInjectionLoaderYamlFileLoader;class PUGXI18nExtension implements Extension{ public function load(array $configs, ContainerBuilder $container) { $configuration = new Configuration(); $config = $this->processConfiguration($configuration, $configs); $path = __DIR__./../Resources/config $loader = new YamlFileLoader($container, new FileLocator($path)); $loader->load(services.yml); } public function getAlias() { return pugx_i18n; }}
  64. 64. Composergestisce le dipendenze
  65. 65. //src/PUGX/I18nBundle/composer.json{ "name": "pugx/i18n-bundle", "type": "symfony-bundle", "description": "Manage i18n", "keywords": ["symfony2, i18n, translation"], "license": "MIT", "authors": [ { "name":"Leonardo Proietti", "email":"leonardo.proietti@gmail.com" } ], "minimum-stability": "dev", "require": { "php": ">=5.3.2", "symfony/framework-bundle": "2.1.*", "doctrine/orm": ">=2.2.3,<2.4-dev", "symfony/yaml": "2.1.*" }, "autoload": { "psr-0": { "PUGXI18nBundle": "" } }, "target-dir": "PUGX/I18nBundle"
  66. 66. //src/PUGX/I18nBundle/Tests/bootstrap.phpif (!is_file($autoloadFile = __DIR__./../vendor/autoload.php)) { throw new LogicException(Could not find autoload.php);}require $autoloadFile;
  67. 67. //src/PUGX/I18nBundle/phpunit.xml.dist<?xml version="1.0" encoding="UTF-8"?><phpunit bootstrap="./Tests/bootstrap.php"> <testsuites> <testsuite name="PUGXI18nBundle test suite"> <directory suffix="Test.php">./Tests</directory> </testsuite> </testsuites> <filter> <whitelist> <directory>./</directory> <exclude> <directory>./Resources</directory> <directory>./Tests</directory> </exclude> </whitelist> </filter></phpunit>
  68. 68. Servizio rivolto alla comunità open source perla continuos integration di progetti pubblicati su github https://travis-ci.org/
  69. 69. //src/PUGX/I18nBundle/.travis.ymllanguage: phpphp: - 5.3 - 5.4before_script: - curl -s http://getcomposer.org/installer | php - php composer.phar install –dev
  70. 70. Ora basta creare un repository su github eavremo dato il nostro piccolo contributo alla comunità open source.
  71. 71. Creditssymfony.com/it/doc/2.0/book/internals.htmlsymfony.com/it/doc/2.0/cookbook/bundles/best_practices.htmlsymfony.com/it/doc/2.0/cookbook/bundles/extension.htmlsviluppoagile.itPUG Roma
  72. 72. GRAZIE :-)

×