Symfony War Stories

4,691
-1

Published on

UK Symfony Meetup, November 2012

Original presentation: https://docs.google.com/presentation/pub?id=1PLcqTby6yqSbfWlMIDHknH852DU6DO6OAgQJOtSEdsg&start=false&loop=false&delayms=3000

Published in: Technology
0 Comments
12 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
4,691
On Slideshare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
29
Comments
0
Likes
12
Embeds 0
No embeds

No notes for slide

Symfony War Stories

  1. UK Symfony Meetup November, 2012 Symfony War Stories Jakub Zalas SensioLabsUKhttp://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 codehttp://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 bundlehttp://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
  10. Being lazyhttp://www.sxc.hu/photo/858871
  11. Theres a bundle for that!
  12. Learning your stuffhttp://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. Its easy! lets 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 }
  27. Web profiler
  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
  29. Debugging commands
  30. http://www.rgbstock.com/bigphoto/mZTKnw6Keeping your playground clean
  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);}
  35. Be SOLID!
  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) { // ... }}
  38. Building quality inhttp://www.rgbstock.com/photo/nrcyovQ/perfect
  39. Unit testsclass ReportTest extends PHPUnit_Framework_TestCase{ public function testThatItReturnsFilePath() { $report = new Report(); $file = $report->create(January); $this->assertSame(/january.csv, $file); }}
  40. ... or specsnamespace spec;class Report extends PHPSpec2ObjectBehavior{ function it_returns_file_path() { $this->create(January) ->shouldReturn(/january.csv); }}
  41. Managing expectationsFeature: 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
  42. Thank you!
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×