Mais conteúdo relacionado Semelhante a Symfony2, creare bundle e valore per il cliente (20) Symfony2, creare bundle e valore per il cliente7. Il processo di sviluppo basato sulla
collaborazione, sulla reciproca soddisfazione e
sul senso di responsabilità permette di ottenere
un alto valore per il cliente.
8. bundle = è una cartella con una struttura ben
definita, che può ospitare qualsiasi cosa, dalle
classi ai controllori e alle risorse web
http://symfony.com/it/doc/current/cookbook/bundles/best_practices.html
9. 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
10. bundle = una libreria sufficientemente astratta
da essere utilizzata in contesti diversi tra loro
16. Sarà una libreria riutilizzabile?
Non è importante perchè l'obiettivo principale è
produrre valore per il cliente
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. Acme
CoreBundle
Listener
LocaleListener.php
EntityListener.php
AnotherListener.php
Locale
Locale.php
LocaleInterface.php
Model
Translatable.php
TranslatableInterface.php
TranslatingInterface.php
AnotherModelUtil.php
Tests
...
26. class Article
{
/**
* @ORMOneToMany
* (targetEntity="ArticleI18n", mappedBy="translatable")
*/
protected $translations;
public function getTitle()
{
return $this->getTranslation()->getTitle();
}
}
27. class Article
{
/**
* @ORMOneToMany
* (targetEntity="ArticleI18n", mappedBy="translatable")
*/
protected $translations;
public function getTitle()
{
return $this->getTranslation()->getTitle();
}
}
28. 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;
}
}
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. 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. 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. 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. 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. 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. 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. 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. 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);
}
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. 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. 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. 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. 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. 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);
}
46. //tranlsations, defaultLocale, locale, tranlsationExpected
public 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. //tranlsations, defaultLocale, locale, tranlsationExpected
public 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. //tranlsations, defaultLocale, locale, tranlsationExpected
public 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. //tranlsations, defaultLocale, locale, tranlsationExpected
public 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'),
)
}
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. 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);
}
52. Non resta che soddisfare i test scrivendo del
codice funzionante :-)
53. configuriamo i servizi
//src/Acme/CoreBundle/Resources/config/services.yml
services:
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. configuriamo i servizi
//src/Acme/CoreBundle/Resources/config/services.yml
services:
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 }
55. class Article extends Translatable
{
/**
* @ORMOneToMany
* (targetEntity="ArticleI18n", mappedBy="translatable")
*/
protected $translations;
public function getTitle()
{
return $this->getTranslation()->getTitle();
}
}
56. Una volta testata anche l'integrazione e
verificato che la richiesta del cliente è stata
soddisfatta, abbiamo prodotto il valore richiesto
e ci possiamo fermare.
59. AcmePlus
PUGX
I18nBundle
Listener
LocaleListener.php
EntityListener.php
Locale
Locale.php
LocaleInterface.php
Model
Translatable.php
TranslatableInterface.php
TranslatingInterface.php
Tests
60. Il grosso è fatto, ora dovremo:
- esporre una configurazione semantica
- gestire le dipendenze (composer) e la configurazione dei test
- aggiungere la documentazione, la licenza ecc.
61. AcmePlus
PUGX
I18nBundle
DependencyInjection
Configuration.php
PUGXI18nExtension.php
[…]
Tests
bootstrap.php
PUGXI18nBundle.php
composer.json
phpunit.xml.dist
64. 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';
}
}
66. //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"
69. Servizio rivolto alla comunità open source per
la continuos integration di progetti pubblicati su
github
https://travis-ci.org/
71. Ora basta creare un repository su github e
avremo dato il nostro piccolo contributo alla
comunità open source.