SlideShare a Scribd company logo

Symfony2, creare bundle e valore per il cliente

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

1 of 73
Download to read offline
Symfony2, creare bundle e valore
         per il cliente

          Leonardo Proietti
              @_leopro_




             Symfony day
        Torino, 5 ottobre 2012
Symfony2, creare bundle e valore per il cliente
valore per il cliente = benefici / costi
collaborazione
collaborazione
responsabilità
collaborazione
     responsabilità
reciproca soddisfazione

Recommended

Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Leonardo Proietti
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixturesBill Chang
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mockingKonstantin Kudryashov
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleHugo Hamon
 
The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016Kacper Gunia
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICKonstantin Kudryashov
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & RESTHugo Hamon
 

More Related Content

What's hot

Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Kacper Gunia
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of LithiumNate Abele
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needKacper Gunia
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistenceHugo Hamon
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design PatternsHugo Hamon
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful softwareJorn Oomen
 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkG Woo
 
Decoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDDDecoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDDAleix Vergés
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksNate Abele
 
Models and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsModels and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsRoss Tuck
 
Forget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowForget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowKacper Gunia
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
CQRS and Event Sourcing in a Symfony application
CQRS and Event Sourcing in a Symfony applicationCQRS and Event Sourcing in a Symfony application
CQRS and Event Sourcing in a Symfony applicationSamuel ROZE
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of LithiumNate Abele
 
Hacking Your Way To Better Security - Dutch PHP Conference 2016
Hacking Your Way To Better Security - Dutch PHP Conference 2016Hacking Your Way To Better Security - Dutch PHP Conference 2016
Hacking Your Way To Better Security - Dutch PHP Conference 2016Colin O'Dell
 
Rich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationRich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationKirill Chebunin
 
Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201Fabien Potencier
 
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionLithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionNate Abele
 

What's hot (20)

Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful software
 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php framework
 
Decoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDDDecoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDD
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate Frameworks
 
Models and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsModels and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and Hobgoblins
 
Min-Maxing Software Costs
Min-Maxing Software CostsMin-Maxing Software Costs
Min-Maxing Software Costs
 
Forget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowForget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers Cracow
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
CQRS and Event Sourcing in a Symfony application
CQRS and Event Sourcing in a Symfony applicationCQRS and Event Sourcing in a Symfony application
CQRS and Event Sourcing in a Symfony application
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of Lithium
 
Hacking Your Way To Better Security - Dutch PHP Conference 2016
Hacking Your Way To Better Security - Dutch PHP Conference 2016Hacking Your Way To Better Security - Dutch PHP Conference 2016
Hacking Your Way To Better Security - Dutch PHP Conference 2016
 
Rich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationRich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 Application
 
Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201
 
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionLithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
 

Similar to Symfony2, creare bundle e valore per il cliente

Symfony components in the wild, PHPNW12
Symfony components in the wild, PHPNW12Symfony components in the wild, PHPNW12
Symfony components in the wild, PHPNW12Jakub Zalas
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsMichael Peacock
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitsmueller_sandsmedia
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 
Symfony internals [english]
Symfony internals [english]Symfony internals [english]
Symfony internals [english]Raul Fraile
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using CodeceptionJeroen van Dijk
 
Filesystem abstractions and msg queue sergeev - symfony camp 2018
Filesystem abstractions and msg queue   sergeev - symfony camp 2018Filesystem abstractions and msg queue   sergeev - symfony camp 2018
Filesystem abstractions and msg queue sergeev - symfony camp 2018Юлия Коваленко
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony AppsKris Wallsmith
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Elena Kolevska
 
PhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsPhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsBastian Feder
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium AppsNate Abele
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Developmentjsmith92
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologyDaniel Knell
 
Meet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Meet Magento Sweden - Magento 2 Layout and Code Compilation for PerformanceMeet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Meet Magento Sweden - Magento 2 Layout and Code Compilation for PerformanceIvan Chepurnyi
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony TechniquesKris Wallsmith
 
Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)Fabien Potencier
 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 WorldFabien Potencier
 
Practical PHP 5.3
Practical PHP 5.3Practical PHP 5.3
Practical PHP 5.3Nate Abele
 

Similar to Symfony2, creare bundle e valore per il cliente (20)

Symfony components in the wild, PHPNW12
Symfony components in the wild, PHPNW12Symfony components in the wild, PHPNW12
Symfony components in the wild, PHPNW12
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friends
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
Symfony internals [english]
Symfony internals [english]Symfony internals [english]
Symfony internals [english]
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using Codeception
 
Filesystem abstractions and msg queue sergeev - symfony camp 2018
Filesystem abstractions and msg queue   sergeev - symfony camp 2018Filesystem abstractions and msg queue   sergeev - symfony camp 2018
Filesystem abstractions and msg queue sergeev - symfony camp 2018
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony Apps
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
 
PhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsPhpUnit - The most unknown Parts
PhpUnit - The most unknown Parts
 
Oops in php
Oops in phpOops in php
Oops in php
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
 
Meet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Meet Magento Sweden - Magento 2 Layout and Code Compilation for PerformanceMeet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Meet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
 
Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)
 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 World
 
Event Sourcing with php
Event Sourcing with phpEvent Sourcing with php
Event Sourcing with php
 
Practical PHP 5.3
Practical PHP 5.3Practical PHP 5.3
Practical PHP 5.3
 

Recently uploaded

ChatGPT's Code Interpreter: Your secret weapon for SEO automation success - S...
ChatGPT's Code Interpreter: Your secret weapon for SEO automation success - S...ChatGPT's Code Interpreter: Your secret weapon for SEO automation success - S...
ChatGPT's Code Interpreter: Your secret weapon for SEO automation success - S...SearchNorwich
 
TrustArc Webinar - TrustArc's Latest AI Innovations
TrustArc Webinar - TrustArc's Latest AI InnovationsTrustArc Webinar - TrustArc's Latest AI Innovations
TrustArc Webinar - TrustArc's Latest AI InnovationsTrustArc
 
CloudStack Authentication Methods – Harikrishna Patnala, ShapeBlue
CloudStack Authentication Methods – Harikrishna Patnala, ShapeBlueCloudStack Authentication Methods – Harikrishna Patnala, ShapeBlue
CloudStack Authentication Methods – Harikrishna Patnala, ShapeBlueShapeBlue
 
Roundtable_-_API_Research__Testing_Tools.pdf
Roundtable_-_API_Research__Testing_Tools.pdfRoundtable_-_API_Research__Testing_Tools.pdf
Roundtable_-_API_Research__Testing_Tools.pdfMostafa Higazy
 
The Art of the Possible with Graph by Dr Jim Webber Neo4j.pptx
The Art of the Possible with Graph by Dr Jim Webber Neo4j.pptxThe Art of the Possible with Graph by Dr Jim Webber Neo4j.pptx
The Art of the Possible with Graph by Dr Jim Webber Neo4j.pptxNeo4j
 
PrismCRM-RealEstate-SalesCRM_byCode5Company
PrismCRM-RealEstate-SalesCRM_byCode5CompanyPrismCRM-RealEstate-SalesCRM_byCode5Company
PrismCRM-RealEstate-SalesCRM_byCode5CompanyMustafa Kuğu
 
Revolutionizing The Banking Industry: The Monzo Way by CPO, Monzo
Revolutionizing The Banking Industry: The Monzo Way by CPO, MonzoRevolutionizing The Banking Industry: The Monzo Way by CPO, Monzo
Revolutionizing The Banking Industry: The Monzo Way by CPO, MonzoProduct School
 
Unleash the Solace Pub Sub connector | Banaglore MuleSoft Meetup #31
Unleash the Solace Pub Sub connector | Banaglore MuleSoft Meetup #31Unleash the Solace Pub Sub connector | Banaglore MuleSoft Meetup #31
Unleash the Solace Pub Sub connector | Banaglore MuleSoft Meetup #31shyamraj55
 
Cultivating Entrepreneurial Mindset in Product Management: Strategies for Suc...
Cultivating Entrepreneurial Mindset in Product Management: Strategies for Suc...Cultivating Entrepreneurial Mindset in Product Management: Strategies for Suc...
Cultivating Entrepreneurial Mindset in Product Management: Strategies for Suc...Product School
 
How to write an effective Cyber Incident Response Plan
How to write an effective Cyber Incident Response PlanHow to write an effective Cyber Incident Response Plan
How to write an effective Cyber Incident Response PlanDatabarracks
 
National Institute of Standards and Technology (NIST) Cybersecurity Framework...
National Institute of Standards and Technology (NIST) Cybersecurity Framework...National Institute of Standards and Technology (NIST) Cybersecurity Framework...
National Institute of Standards and Technology (NIST) Cybersecurity Framework...MichaelBenis1
 
Confoo 2024 Gettings started with OpenAI and data science
Confoo 2024 Gettings started with OpenAI and data scienceConfoo 2024 Gettings started with OpenAI and data science
Confoo 2024 Gettings started with OpenAI and data scienceSusan Ibach
 
Elevating Cloud Infrastructure with Object Storage, DRS, VM Scheduling, and D...
Elevating Cloud Infrastructure with Object Storage, DRS, VM Scheduling, and D...Elevating Cloud Infrastructure with Object Storage, DRS, VM Scheduling, and D...
Elevating Cloud Infrastructure with Object Storage, DRS, VM Scheduling, and D...ShapeBlue
 
Q4 2023 Quarterly Investor Presentation - FINAL.pdf
Q4 2023 Quarterly Investor Presentation - FINAL.pdfQ4 2023 Quarterly Investor Presentation - FINAL.pdf
Q4 2023 Quarterly Investor Presentation - FINAL.pdfTejal81
 
Large Language Models and Applications in Healthcare
Large Language Models and Applications in HealthcareLarge Language Models and Applications in Healthcare
Large Language Models and Applications in HealthcareAsma Ben Abacha
 
Artificial Intelligence, Design, and More-than-Human Justice
Artificial Intelligence, Design, and More-than-Human JusticeArtificial Intelligence, Design, and More-than-Human Justice
Artificial Intelligence, Design, and More-than-Human JusticeJosh Gellers
 
How AI and ChatGPT are changing cybersecurity forever.pptx
How AI and ChatGPT are changing cybersecurity forever.pptxHow AI and ChatGPT are changing cybersecurity forever.pptx
How AI and ChatGPT are changing cybersecurity forever.pptxInfosec
 
Enterprise Architecture As Strategy - Book Review
Enterprise Architecture As Strategy - Book ReviewEnterprise Architecture As Strategy - Book Review
Enterprise Architecture As Strategy - Book ReviewAshraf Fouad
 
Dev Dives: Leverage APIs and Gen AI to power automations for RPA and software...
Dev Dives: Leverage APIs and Gen AI to power automations for RPA and software...Dev Dives: Leverage APIs and Gen AI to power automations for RPA and software...
Dev Dives: Leverage APIs and Gen AI to power automations for RPA and software...UiPathCommunity
 
Synergy in Leadership and Product Excellence: A Blueprint for Growth by CPO, ...
Synergy in Leadership and Product Excellence: A Blueprint for Growth by CPO, ...Synergy in Leadership and Product Excellence: A Blueprint for Growth by CPO, ...
Synergy in Leadership and Product Excellence: A Blueprint for Growth by CPO, ...Product School
 

Recently uploaded (20)

ChatGPT's Code Interpreter: Your secret weapon for SEO automation success - S...
ChatGPT's Code Interpreter: Your secret weapon for SEO automation success - S...ChatGPT's Code Interpreter: Your secret weapon for SEO automation success - S...
ChatGPT's Code Interpreter: Your secret weapon for SEO automation success - S...
 
TrustArc Webinar - TrustArc's Latest AI Innovations
TrustArc Webinar - TrustArc's Latest AI InnovationsTrustArc Webinar - TrustArc's Latest AI Innovations
TrustArc Webinar - TrustArc's Latest AI Innovations
 
CloudStack Authentication Methods – Harikrishna Patnala, ShapeBlue
CloudStack Authentication Methods – Harikrishna Patnala, ShapeBlueCloudStack Authentication Methods – Harikrishna Patnala, ShapeBlue
CloudStack Authentication Methods – Harikrishna Patnala, ShapeBlue
 
Roundtable_-_API_Research__Testing_Tools.pdf
Roundtable_-_API_Research__Testing_Tools.pdfRoundtable_-_API_Research__Testing_Tools.pdf
Roundtable_-_API_Research__Testing_Tools.pdf
 
The Art of the Possible with Graph by Dr Jim Webber Neo4j.pptx
The Art of the Possible with Graph by Dr Jim Webber Neo4j.pptxThe Art of the Possible with Graph by Dr Jim Webber Neo4j.pptx
The Art of the Possible with Graph by Dr Jim Webber Neo4j.pptx
 
PrismCRM-RealEstate-SalesCRM_byCode5Company
PrismCRM-RealEstate-SalesCRM_byCode5CompanyPrismCRM-RealEstate-SalesCRM_byCode5Company
PrismCRM-RealEstate-SalesCRM_byCode5Company
 
Revolutionizing The Banking Industry: The Monzo Way by CPO, Monzo
Revolutionizing The Banking Industry: The Monzo Way by CPO, MonzoRevolutionizing The Banking Industry: The Monzo Way by CPO, Monzo
Revolutionizing The Banking Industry: The Monzo Way by CPO, Monzo
 
Unleash the Solace Pub Sub connector | Banaglore MuleSoft Meetup #31
Unleash the Solace Pub Sub connector | Banaglore MuleSoft Meetup #31Unleash the Solace Pub Sub connector | Banaglore MuleSoft Meetup #31
Unleash the Solace Pub Sub connector | Banaglore MuleSoft Meetup #31
 
Cultivating Entrepreneurial Mindset in Product Management: Strategies for Suc...
Cultivating Entrepreneurial Mindset in Product Management: Strategies for Suc...Cultivating Entrepreneurial Mindset in Product Management: Strategies for Suc...
Cultivating Entrepreneurial Mindset in Product Management: Strategies for Suc...
 
How to write an effective Cyber Incident Response Plan
How to write an effective Cyber Incident Response PlanHow to write an effective Cyber Incident Response Plan
How to write an effective Cyber Incident Response Plan
 
National Institute of Standards and Technology (NIST) Cybersecurity Framework...
National Institute of Standards and Technology (NIST) Cybersecurity Framework...National Institute of Standards and Technology (NIST) Cybersecurity Framework...
National Institute of Standards and Technology (NIST) Cybersecurity Framework...
 
Confoo 2024 Gettings started with OpenAI and data science
Confoo 2024 Gettings started with OpenAI and data scienceConfoo 2024 Gettings started with OpenAI and data science
Confoo 2024 Gettings started with OpenAI and data science
 
Elevating Cloud Infrastructure with Object Storage, DRS, VM Scheduling, and D...
Elevating Cloud Infrastructure with Object Storage, DRS, VM Scheduling, and D...Elevating Cloud Infrastructure with Object Storage, DRS, VM Scheduling, and D...
Elevating Cloud Infrastructure with Object Storage, DRS, VM Scheduling, and D...
 
Q4 2023 Quarterly Investor Presentation - FINAL.pdf
Q4 2023 Quarterly Investor Presentation - FINAL.pdfQ4 2023 Quarterly Investor Presentation - FINAL.pdf
Q4 2023 Quarterly Investor Presentation - FINAL.pdf
 
Large Language Models and Applications in Healthcare
Large Language Models and Applications in HealthcareLarge Language Models and Applications in Healthcare
Large Language Models and Applications in Healthcare
 
Artificial Intelligence, Design, and More-than-Human Justice
Artificial Intelligence, Design, and More-than-Human JusticeArtificial Intelligence, Design, and More-than-Human Justice
Artificial Intelligence, Design, and More-than-Human Justice
 
How AI and ChatGPT are changing cybersecurity forever.pptx
How AI and ChatGPT are changing cybersecurity forever.pptxHow AI and ChatGPT are changing cybersecurity forever.pptx
How AI and ChatGPT are changing cybersecurity forever.pptx
 
Enterprise Architecture As Strategy - Book Review
Enterprise Architecture As Strategy - Book ReviewEnterprise Architecture As Strategy - Book Review
Enterprise Architecture As Strategy - Book Review
 
Dev Dives: Leverage APIs and Gen AI to power automations for RPA and software...
Dev Dives: Leverage APIs and Gen AI to power automations for RPA and software...Dev Dives: Leverage APIs and Gen AI to power automations for RPA and software...
Dev Dives: Leverage APIs and Gen AI to power automations for RPA and software...
 
Synergy in Leadership and Product Excellence: A Blueprint for Growth by CPO, ...
Synergy in Leadership and Product Excellence: A Blueprint for Growth by CPO, ...Synergy in Leadership and Product Excellence: A Blueprint for Growth by CPO, ...
Synergy in Leadership and Product Excellence: A Blueprint for Growth by CPO, ...
 

Symfony2, creare bundle e valore per il cliente

  • 1. Symfony2, creare bundle e valore per il cliente Leonardo Proietti @_leopro_ Symfony day Torino, 5 ottobre 2012
  • 3. valore per il cliente = benefici / costi
  • 6. collaborazione responsabilità reciproca soddisfazione
  • 7. 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
  • 11. la realizzazione di un bundle non è valore per il cliente
  • 12. Richiesta un sito web con contenuti aggiornabili disponibili in diverse lingue
  • 13. Analisi gli strumenti esistenti sono valutati come non adatti
  • 15. Sarà una libreria riutilizzabile?
  • 16. Sarà una libreria riutilizzabile? Non è importante perchè l'obiettivo principale è produrre valore per il cliente
  • 17. Ma non vogliamo spaghetti code
  • 18. Test Driven Development ovvero sviluppare guidati dai test
  • 19. Test Driven Development ovvero sviluppi meglio, vivi meglio
  • 20. $article->getTitle(); /it/{article} “Il mio articolo” /en/{article} “My article”
  • 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 ...
  • 23. interface LocaleInterface { function setLocale($locale); function getLocale(); function getDefaultLocale(); }
  • 24. use AcmeCoreBundleModelTranslatingInterface; use AcmeCoreBundleLocaleLocaleInterface; interface TranslatableInterface { function addTranslation(TranslatingInterface $translation); function getTranslations(); function setLocale(LocaleInterface $locale); }
  • 25. use AcmeCoreBundleModelTranslatableInterface; interface TranslatingInterface { function setTranslatable(TranslatableInterface $translatable); function getLocale(); function setLocale($string); }
  • 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.
  • 58. Prendiamo il codice e lo isoliamo PUGX/I18nBundle
  • 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
  • 62. namespace PUGXI18nBundle; use SymfonyComponentHttpKernelBundleBundle; use PUGXI18nBundleDependencyInjectionPUGXI18nExtension; class PUGXI18nBundle extends Bundle { public function getContainerExtension() { return new PUGXI18nExtension(); } }
  • 63. namespace PUGXI18nBundleDependencyInjection; use SymfonyComponentConfigDefinitionBuilderTreeBuilder; use SymfonyComponentConfigDefinitionConfigurationInterface; class Configuration implements ConfigurationInterface { public function getConfigTreeBuilder() { $treeBuilder = new TreeBuilder(); $rootNode = $treeBuilder->root('pugx_i18n'); return $treeBuilder; } }
  • 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"
  • 67. //src/PUGX/I18nBundle/Tests/bootstrap.php if (!is_file($autoloadFile = __DIR__.'/../vendor/autoload.php')) { throw new LogicException('Could not find autoload.php'); } require $autoloadFile;
  • 68. //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>
  • 69. Servizio rivolto alla comunità open source per la continuos integration di progetti pubblicati su github https://travis-ci.org/
  • 70. //src/PUGX/I18nBundle/.travis.yml language: php php: - 5.3 - 5.4 before_script: - curl -s http://getcomposer.org/installer | php - php composer.phar install –dev
  • 71. Ora basta creare un repository su github e avremo dato il nostro piccolo contributo alla comunità open source.