SlideShare a Scribd company logo
1 of 42
Download to read offline
UK Symfony Meetup
             November, 2012




                                           Symfony
                                           War Stories

                                                          Jakub Zalas
                                                         SensioLabsUK
http://www.rgbstock.com/bigphoto/mhY2DCY
Jakub Zalas a.k.a. Kuba


○ Remembers symfony 1.0
  (2007)
○ Open Source contributor
○ BDD advocate
○ Works at Sensio Labs UK
○ ZCE & Sensio Labs         ○ Twitter: @jakub_zalas
  Certified Symfony         ○ Blog: http://zalas.eu
  Developer                 ○ Github: @jakzal
Symfony War Stories
● Bundling the code
● Thinking outside of the bundle
● Being lazy
● Learning your stuff
● Keeping your playground clean
● Building the quality in
Bundling
                                           the code
http://www.rgbstock.com/bigphoto/mfXkYUq
VS
Whenever in doubt...
● Start simple and let the design emerge
● Extract bundles when you need to reuse it
  or you see it would improve clarity
● Avoid two-way dependencies between
  bundles
Thinking
                                            outside of
                                           the bundle




http://www.rgbstock.com/bigphoto/mfBYR2S
VS
To keep your design clean...
● Treat bundles as an integration layer
  between PHP libraries and the Symfony
  framework
● In your libraries, avoid dependencies on
  bundles
Being lazy




http://www.sxc.hu/photo/858871
There's a bundle for that!
Learning
                                  your stuff




http://www.sxc.hu/photo/1095604
Have you ever used?

● Event listeners and subscribers
● Form data transformers
● Twig extensions
● Profiler extensions
● DIC compiler passes
● more...
It's easy!




             let's see few examples...
Event listeners and subscribers (Doctrine)


 services:
    sensio.listener.search_indexer:
        class: SensioListenerSearchIndexer
        tags:
            -
                name: doctrine.event_listener
                event: postPersist
namespace SensioListener;

use DoctrineORMEventLifecycleEventArgs;
use SensioEntityProduct;

class SearchIndexer
{
    public function postPersist(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();
        $entityManager = $args->getEntityManager();

        if ($entity instanceof Product) { /* Index me */ }
    }
}
Lifecycle callbacks (Doctrine)

/**
  * @ORMEntity()
  * @ORMHasLifecycleCallbacks()
  */
class User
{
     /**
      * @ORMPrePersist
      */
     public function updateCreatedAt() { /* ... */ }
}
Event listeners and subscribers (Symfony)


services:
  sensio.action_listener:
    class: SensioMyBundleEventListenerMyListener
    tags:
      -
        name: kernel.event_listener
        event: kernel.controller
        method: onKernelController
namespace SensioMyBundleEventListener;

class MyListener
{
    public function onKernelController(
                             FilterControllerEvent $event)
    {
        $controller = $event->getController();
        $request = $event->getRequest();

        // ...
    }
}
Event listeners and subscribers (Forms)

$callback = function(FormEvent $event) {
    if (null === $event->getData()) {
        $formData = $event->getForm()->getData();
        $event->setData($formData);
    }
};

$builder->add('email', 'text');
$builder->get('email')
    ->addEventListener(
        FormEvents::PRE_BIND, $callback
    );
Data transformers (Forms)
class IssueToNumberTransformer
                 implements DataTransformerInterface
{
    public function transform($issue)
    {
        // return issue number
    }

    public function reverseTransform($number)
    {
        // return Issue instance
    }
}
$field = $builder->create('issue', 'text')
    ->addModelTransformer(new IssueToNumberTransformer());

$builder->add($field);
Twig extensions

<!-- Instead of: -->

<div class="price">
    ${{ 9800.333|number_format(2, '.', ',') }}
</div>

<!-- just do: -->

<div class="price">
    {{ 9800.333|price }}
</div>
class SensioExtension extends Twig_Extension
{
    public function getFilters()
    {
        return array(
            'price' => new Twig_Filter_Method(
                                     $this, 'priceFilter')
        );
    }

    public function getName()
    {
        return 'sensio_extension';
    }

    public function priceFilter($number, /* ... */ ) {}
}
public function priceFilter(
    $number, $decimals = 0, $decPoint = '.', $sep = ',')
{
    $price = number_format(
        $number, $decimals, $decPoint, $sep
    );

    return '$'.$price;
}
services:
    sensio.twig.acme_extension:
        class: SensioTwigSensioExtension
        tags:
            - { name: twig.extension }
Web profiler
Debugging commands



./app/console container:debug
./app/console container:debug twig.loader

./app/console router:debug
./app/console router:debug homepage

./app/console router:match /logout
Debugging commands
http://www.rgbstock.com/bigphoto/mZTKnw6




Keeping your playground clean
Use the service container!
public function publishAction($date)
{
    $show = $this->findShow($date);
    $fileName = sprintf('show-%s.json', $date->format('Y-m-d'));

    while (file_exists($fileName)) {
        $fileName = $fileName.preg_replace('/.json$/', '-1.json');
    }

    $options = array( /* options here */ );
    $s3 = new AmazonS3($options);

    $objectOptions = array(
        'body' => json_encode($show), 'acl' => $options['objectAcl']);

    if (!$s3->create_object('my-bucket', $fileName, $objectOptions) {
        throw new Exception('Could not save file');
    }

    // ...
}
public function publishAction($date)
{
    $show = $this->findShow($date);

    $fileNameResolver = new FileNameResolver();
    $filesystem = $this->get('gafrette_filesystem');

    $publisher = new Publisher(
        $fileNameResolver, $filesystem
    );

    $publisher->publish($show, $date);
}
Use the service container!



public function publishAction($date)
{
    $show = $this->findShow($date);
    $publisher = $this->get('sensio.publisher');
    $publisher->publish($show, $date);
}
Be SOLID!
/**
  * @ORMEntity()
  */
class Product
{
     // ...

    public function createOrderReport($month)
    {
        // $this->em->getRepository() ...
    }

    public function setEntityManager($em)
    {
        $this->em = $em;
    }
}
class OrderReportGenerator
{
    private $em = null;

    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    public function generate(Product $product, $month)
    {
        // ...
    }
}
Building quality in




http://www.rgbstock.com/photo/nrcyovQ/perfect
Unit tests

class ReportTest extends PHPUnit_Framework_TestCase
{
    public function testThatItReturnsFilePath()
    {
        $report = new Report();

        $file = $report->create('January');

        $this->assertSame('/january.csv', $file);
    }
}
... or specs


namespace spec;

class Report extends PHPSpec2ObjectBehavior
{
    function it_returns_file_path()
    {
        $this->create('January')
             ->shouldReturn('/january.csv');
    }
}
Managing expectations
Feature: Viewing recent news on the homepage
  As a Marketing Manager
  I want Visitors to see recent news on the homepage
  In order to get them interested in the content

 Scenario: Viewing recent news
   Given there are 10 news items
     And there were 5 news items written since yesterday
    When I visit the homepage
    Then I should see 5 recent news items in the news section

 Scenario: There is not enough news
   Given there are 10 news items
     But there were 3 news items written since yesterday
    When I visit the homepage
    Then I should see 3 recent news items in the news section
Thank you!

More Related Content

What's hot

Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design PatternsHugo Hamon
 
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
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & RESTHugo Hamon
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of LithiumNate Abele
 
Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)Kris Wallsmith
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of LithiumNate Abele
 
Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201Fabien Potencier
 
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
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteLeonardo Proietti
 
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
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixturesBill Chang
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP GeneratorsMark Baker
 
Symfony 2 (PHP Quebec 2009)
Symfony 2 (PHP Quebec 2009)Symfony 2 (PHP Quebec 2009)
Symfony 2 (PHP Quebec 2009)Fabien Potencier
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium AppsNate Abele
 
Dealing with Continuous Data Processing, ConFoo 2012
Dealing with Continuous Data Processing, ConFoo 2012Dealing with Continuous Data Processing, ConFoo 2012
Dealing with Continuous Data Processing, ConFoo 2012Michael Peacock
 
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
 
How I started to love design patterns
How I started to love design patternsHow I started to love design patterns
How I started to love design patternsSamuel ROZE
 
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)

Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns
 
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 mocking
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
 
Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of Lithium
 
Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201
 
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)
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il cliente
 
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
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixtures
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP Generators
 
Symfony 2 (PHP Quebec 2009)
Symfony 2 (PHP Quebec 2009)Symfony 2 (PHP Quebec 2009)
Symfony 2 (PHP Quebec 2009)
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
 
Dealing with Continuous Data Processing, ConFoo 2012
Dealing with Continuous Data Processing, ConFoo 2012Dealing with Continuous Data Processing, ConFoo 2012
Dealing with Continuous Data Processing, ConFoo 2012
 
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.5
 
How I started to love design patterns
How I started to love design patternsHow I started to love design patterns
How I started to love design patterns
 
Nubilus Perl
Nubilus PerlNubilus Perl
Nubilus Perl
 
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 Symfony War Stories

How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony AppsKris Wallsmith
 
Multilingualism makes better programmers
Multilingualism makes better programmersMultilingualism makes better programmers
Multilingualism makes better programmersAlexander Varwijk
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8Alexei Gorobets
 
Symfony tips and tricks
Symfony tips and tricksSymfony tips and tricks
Symfony tips and tricksJavier Eguiluz
 
Writing JavaScript that doesn't suck
Writing JavaScript that doesn't suckWriting JavaScript that doesn't suck
Writing JavaScript that doesn't suckRoss Bruniges
 
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
 
Singletons in PHP - Why they are bad and how you can eliminate them from your...
Singletons in PHP - Why they are bad and how you can eliminate them from your...Singletons in PHP - Why they are bad and how you can eliminate them from your...
Singletons in PHP - Why they are bad and how you can eliminate them from your...go_oh
 
The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014Matthias Noback
 
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
 
Symfony Under the Hood
Symfony Under the HoodSymfony Under the Hood
Symfony Under the HoodeZ Systems
 
Build powerfull and smart web applications with Symfony2
Build powerfull and smart web applications with Symfony2Build powerfull and smart web applications with Symfony2
Build powerfull and smart web applications with Symfony2Hugo Hamon
 
The Naked Bundle - Tryout
The Naked Bundle - TryoutThe Naked Bundle - Tryout
The Naked Bundle - TryoutMatthias Noback
 
The Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony BarcelonaThe Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony BarcelonaMatthias Noback
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
The Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup BelgiumThe Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup BelgiumMatthias Noback
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to DjangoJames Casey
 
Symfony 4 Workshop - Limenius
Symfony 4 Workshop - LimeniusSymfony 4 Workshop - Limenius
Symfony 4 Workshop - LimeniusIgnacio Martín
 
TypeScript for Java Developers
TypeScript for Java DevelopersTypeScript for Java Developers
TypeScript for Java DevelopersYakov Fain
 

Similar to Symfony War Stories (20)

How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony Apps
 
Multilingualism makes better programmers
Multilingualism makes better programmersMultilingualism makes better programmers
Multilingualism makes better programmers
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8
 
Symfony tips and tricks
Symfony tips and tricksSymfony tips and tricks
Symfony tips and tricks
 
The IoC Hydra
The IoC HydraThe IoC Hydra
The IoC Hydra
 
Writing JavaScript that doesn't suck
Writing JavaScript that doesn't suckWriting JavaScript that doesn't suck
Writing JavaScript that doesn't suck
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
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 2016
 
Singletons in PHP - Why they are bad and how you can eliminate them from your...
Singletons in PHP - Why they are bad and how you can eliminate them from your...Singletons in PHP - Why they are bad and how you can eliminate them from your...
Singletons in PHP - Why they are bad and how you can eliminate them from your...
 
The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014
 
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
 
Symfony Under the Hood
Symfony Under the HoodSymfony Under the Hood
Symfony Under the Hood
 
Build powerfull and smart web applications with Symfony2
Build powerfull and smart web applications with Symfony2Build powerfull and smart web applications with Symfony2
Build powerfull and smart web applications with Symfony2
 
The Naked Bundle - Tryout
The Naked Bundle - TryoutThe Naked Bundle - Tryout
The Naked Bundle - Tryout
 
The Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony BarcelonaThe Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony Barcelona
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
The Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup BelgiumThe Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup Belgium
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to Django
 
Symfony 4 Workshop - Limenius
Symfony 4 Workshop - LimeniusSymfony 4 Workshop - Limenius
Symfony 4 Workshop - Limenius
 
TypeScript for Java Developers
TypeScript for Java DevelopersTypeScript for Java Developers
TypeScript for Java Developers
 

Recently uploaded

Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 

Recently uploaded (20)

Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 

Symfony War Stories

  • 1. UK Symfony Meetup November, 2012 Symfony War Stories Jakub Zalas SensioLabsUK http://www.rgbstock.com/bigphoto/mhY2DCY
  • 2. Jakub Zalas a.k.a. Kuba ○ Remembers symfony 1.0 (2007) ○ Open Source contributor ○ BDD advocate ○ Works at Sensio Labs UK ○ ZCE & Sensio Labs ○ Twitter: @jakub_zalas Certified Symfony ○ Blog: http://zalas.eu Developer ○ Github: @jakzal
  • 3. Symfony War Stories ● Bundling the code ● Thinking outside of the bundle ● Being lazy ● Learning your stuff ● Keeping your playground clean ● Building the quality in
  • 4. Bundling the code http://www.rgbstock.com/bigphoto/mfXkYUq
  • 5. VS
  • 6. Whenever in doubt... ● Start simple and let the design emerge ● Extract bundles when you need to reuse it or you see it would improve clarity ● Avoid two-way dependencies between bundles
  • 7. Thinking outside of the bundle http://www.rgbstock.com/bigphoto/mfBYR2S
  • 8. VS
  • 9. To keep your design clean... ● Treat bundles as an integration layer between PHP libraries and the Symfony framework ● In your libraries, avoid dependencies on bundles
  • 11. There's a bundle for that!
  • 12. Learning your stuff http://www.sxc.hu/photo/1095604
  • 13. Have you ever used? ● Event listeners and subscribers ● Form data transformers ● Twig extensions ● Profiler extensions ● DIC compiler passes ● more...
  • 14. It's easy! let's see few examples...
  • 15. Event listeners and subscribers (Doctrine) services: sensio.listener.search_indexer: class: SensioListenerSearchIndexer tags: - name: doctrine.event_listener event: postPersist
  • 16. namespace SensioListener; use DoctrineORMEventLifecycleEventArgs; use SensioEntityProduct; class SearchIndexer { public function postPersist(LifecycleEventArgs $args) { $entity = $args->getEntity(); $entityManager = $args->getEntityManager(); if ($entity instanceof Product) { /* Index me */ } } }
  • 17. Lifecycle callbacks (Doctrine) /** * @ORMEntity() * @ORMHasLifecycleCallbacks() */ class User { /** * @ORMPrePersist */ public function updateCreatedAt() { /* ... */ } }
  • 18. Event listeners and subscribers (Symfony) services: sensio.action_listener: class: SensioMyBundleEventListenerMyListener tags: - name: kernel.event_listener event: kernel.controller method: onKernelController
  • 19. namespace SensioMyBundleEventListener; class MyListener { public function onKernelController( FilterControllerEvent $event) { $controller = $event->getController(); $request = $event->getRequest(); // ... } }
  • 20. Event listeners and subscribers (Forms) $callback = function(FormEvent $event) { if (null === $event->getData()) { $formData = $event->getForm()->getData(); $event->setData($formData); } }; $builder->add('email', 'text'); $builder->get('email') ->addEventListener( FormEvents::PRE_BIND, $callback );
  • 21. Data transformers (Forms) class IssueToNumberTransformer implements DataTransformerInterface { public function transform($issue) { // return issue number } public function reverseTransform($number) { // return Issue instance } }
  • 22. $field = $builder->create('issue', 'text') ->addModelTransformer(new IssueToNumberTransformer()); $builder->add($field);
  • 23. Twig extensions <!-- Instead of: --> <div class="price"> ${{ 9800.333|number_format(2, '.', ',') }} </div> <!-- just do: --> <div class="price"> {{ 9800.333|price }} </div>
  • 24. class SensioExtension extends Twig_Extension { public function getFilters() { return array( 'price' => new Twig_Filter_Method( $this, 'priceFilter') ); } public function getName() { return 'sensio_extension'; } public function priceFilter($number, /* ... */ ) {} }
  • 25. public function priceFilter( $number, $decimals = 0, $decPoint = '.', $sep = ',') { $price = number_format( $number, $decimals, $decPoint, $sep ); return '$'.$price; }
  • 26. services: sensio.twig.acme_extension: class: SensioTwigSensioExtension tags: - { name: twig.extension }
  • 28. Debugging commands ./app/console container:debug ./app/console container:debug twig.loader ./app/console router:debug ./app/console router:debug homepage ./app/console router:match /logout
  • 31. Use the service container!
  • 32. public function publishAction($date) { $show = $this->findShow($date); $fileName = sprintf('show-%s.json', $date->format('Y-m-d')); while (file_exists($fileName)) { $fileName = $fileName.preg_replace('/.json$/', '-1.json'); } $options = array( /* options here */ ); $s3 = new AmazonS3($options); $objectOptions = array( 'body' => json_encode($show), 'acl' => $options['objectAcl']); if (!$s3->create_object('my-bucket', $fileName, $objectOptions) { throw new Exception('Could not save file'); } // ... }
  • 33. public function publishAction($date) { $show = $this->findShow($date); $fileNameResolver = new FileNameResolver(); $filesystem = $this->get('gafrette_filesystem'); $publisher = new Publisher( $fileNameResolver, $filesystem ); $publisher->publish($show, $date); }
  • 34. Use the service container! public function publishAction($date) { $show = $this->findShow($date); $publisher = $this->get('sensio.publisher'); $publisher->publish($show, $date); }
  • 36. /** * @ORMEntity() */ class Product { // ... public function createOrderReport($month) { // $this->em->getRepository() ... } public function setEntityManager($em) { $this->em = $em; } }
  • 37. class OrderReportGenerator { private $em = null; public function __construct(EntityManager $em) { $this->em = $em; } public function generate(Product $product, $month) { // ... } }
  • 39. Unit tests class ReportTest extends PHPUnit_Framework_TestCase { public function testThatItReturnsFilePath() { $report = new Report(); $file = $report->create('January'); $this->assertSame('/january.csv', $file); } }
  • 40. ... or specs namespace spec; class Report extends PHPSpec2ObjectBehavior { function it_returns_file_path() { $this->create('January') ->shouldReturn('/january.csv'); } }
  • 41. Managing expectations Feature: Viewing recent news on the homepage As a Marketing Manager I want Visitors to see recent news on the homepage In order to get them interested in the content Scenario: Viewing recent news Given there are 10 news items And there were 5 news items written since yesterday When I visit the homepage Then I should see 5 recent news items in the news section Scenario: There is not enough news Given there are 10 news items But there were 3 news items written since yesterday When I visit the homepage Then I should see 3 recent news items in the news section