SlideShare una empresa de Scribd logo
1 de 42
Descargar para leer sin conexión
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!

Más contenido relacionado

La actualidad más candente

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
 

La actualidad más candente (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 a 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 a 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
 

Último

The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxfnnc6jmgwh
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Kaya Weers
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesManik S Magar
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructureitnewsafrica
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024TopCSSGallery
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 

Último (20)

The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 

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