Slide 1

Slide 1 text

@saro0h Sarah Khalil A year of

Slide 2

Slide 2 text

A year ago…

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

2 main axes in this conference

Slide 6

Slide 6 text

1. Community

Slide 7

Slide 7 text

1. Community

Slide 8

Slide 8 text

2. Features

Slide 9

Slide 9 text

2. Features

Slide 10

Slide 10 text

2. Features

Slide 11

Slide 11 text

Community

Slide 12

Slide 12 text

A week of Symfony Every week!

Slide 13

Slide 13 text

A new core contributor Grégoire Pineau Merger on the Workflow component

Slide 14

Slide 14 text

Pull requests 1,282 merged 2,411 opened

Slide 15

Slide 15 text

Issues 1,438 closed

Slide 16

Slide 16 text

57 versions 2.6.x 1 version 2.7.x 14 versions 2.8.x 14 versions 3.0.x 9 versions 3.1.x 10 versions 3.2.x 4 versions ➡ ➡ ➡ ➡ ➡ ➡ Releases

Slide 17

Slide 17 text

New way of releasing Symfony • A new minor version every 6 months • in november and may, usually at the end of the month • A new major version every 2 years • released at the same time as the last minor version

Slide 18

Slide 18 text

SymfonyLive Cancelled

Slide 19

Slide 19 text

Virtual hackdays

Slide 20

Slide 20 text

Documentation Mercury project,150 hours of great work.

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

Getting started: all basics about developing apps with Symfony.

Slide 23

Slide 23 text

Getting started: all basics about developing apps with Symfony. Components: all about the standalone Symfony libraries. Bundles: commonly used bundles when developing Symfony apps. Reference: Form types, DI tags & Symfony configuration.

Slide 24

Slide 24 text

Getting started: all basics about developing apps with Symfony. Guides and tutorials: Everything else. Components: all about the standalone Symfony libraries. Bundles: commonly used bundles when developing Symfony apps. Reference: Form types, DI tags & Symfony configuration.

Slide 25

Slide 25 text

http://symfony.com/blog/the-new-symfony-documentation-search-engine Wanna use Algolia?

Slide 26

Slide 26 text

Influence of and many others…

Slide 27

Slide 27 text

Influence of and many others…

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

3.1 I chose 11 features

Slide 30

Slide 30 text

No content

Slide 31

Slide 31 text

Deprecation helper improvements Detection of deprecation are done thanks to the PHPUnit bridge. … 3.1

Slide 32

Slide 32 text

« disabled » PHPUnit won’t list the deprecations ; avoid your test suite failing. Deprecation helper improvements Detection of deprecation are done thanks to the PHPUnit bridge. … 3.1

Slide 33

Slide 33 text

« /Passing callable strings .*/ » Will be matched as a regular expression against the deprecation message. « disabled » PHPUnit won’t list the deprecations ; avoid your test suite failing. Deprecation helper improvements Detection of deprecation are done thanks to the PHPUnit bridge. … 3.1

Slide 34

Slide 34 text

« 10 » Test suite will fail if 10 or more deprecations are triggered. « /Passing callable strings .*/ » Will be matched as a regular expression against the deprecation message. « disabled » PHPUnit won’t list the deprecations ; avoid your test suite failing. Deprecation helper improvements Detection of deprecation are done thanks to the PHPUnit bridge. … 3.1

Slide 35

Slide 35 text

• Implementation of the PSR-6 - Caching interface standard. • Cache arbitrary content in your application. • Symfony components use it to improve their performances. New component: Cache 3.1 class BlogController extends Controller { public function indexAction() { // create a new item and getting it from the cache $cachedCategories = $this->get('cache.app')->getItem('categories'); if (!$cachedCategories->isHit()) { $categories = ... // fetch categories from the database $cachedCategories->set($categories); $this->get('cache.app')->save($cachedCategories); } else { $categories = $cachedCategories->get(); } // ... } } Adapters for common backends Redis, APCu, Memcache…

Slide 36

Slide 36 text

• Implementation of the PSR-6 - Caching interface standard. • Cache arbitrary content in your application. • Symfony components use it to improve their performances. New component: Cache 3.1 class BlogController extends Controller { public function indexAction() { // create a new item and getting it from the cache $cachedCategories = $this->get('cache.app')->getItem('categories'); if (!$cachedCategories->isHit()) { $categories = ... // fetch categories from the database $cachedCategories->set($categories); $this->get('cache.app')->save($cachedCategories); } else { $categories = $cachedCategories->get(); } // ... } } Adapters for common backends Redis, APCu, Memcache…

Slide 37

Slide 37 text

Display forwards and redirects in the WDT and the profiler 3.1 Forward Redirect

Slide 38

Slide 38 text

Security profiler panel improvements 3.1

Slide 39

Slide 39 text

Security profiler panel improvements 3.1

Slide 40

Slide 40 text

WDT: Color coded HTTP status for ajax requests 3.1

Slide 41

Slide 41 text

WDT: Color coded HTTP status for ajax requests 3.1

Slide 42

Slide 42 text

Profiler: Silenced errors in logs 3.1

Slide 43

Slide 43 text

Profiler: Filters in requests 3.1

Slide 44

Slide 44 text

Profiler: Filters in requests 3.1

Slide 45

Slide 45 text

YAML deprecation 3.1 framework: secret: %secret% framework: secret: '%secret%' parameters: my_object: '!php/object:O:27:"AppBundle\Service\MyService":1:{s:1:"b";s:3:"foo";}' parameters: my_object: '!!php/object:O:27:"AppBundle\Service\MyService":1:{s:1:"b";s:3:"foo";}'

Slide 46

Slide 46 text

Process: Input stream 3.1 use Symfony\Component\Process\Process; $process = new Process('cat'); $process->setInput('file.txt'); $process->run(); use Symfony\Component\Process\InputStream; $input = new InputStream(); $input->write('foo'); $process = new Process('my_script'); $process->setInput($input); $process-> start(); // ... read process output or do other things $input->write('bar'); // ... read process output or do other things $input->write('qux'); $input-> close(); before Cannot provide more input now

Slide 47

Slide 47 text

Process: Output stream 3.1 Process::OUT Process::ERR or

Slide 48

Slide 48 text

Process: Output stream 3.1 Process::OUT Process::ERR or use Symfony\Component\Process\Process; $process = new Process('ls -lsa'); $process->start(); foreach ($process as $type => $data) { if ($process::OUT === $type) { echo $data."\n"; } else { echo "[ERR] ".$data."\n"; } } returns an iterator

Slide 49

Slide 49 text

Process: Output stream 3.1 Process::OUT Process::ERR or use Symfony\Component\Process\Process; $process = new Process('ls -lsa'); $process->start(); foreach ($process as $type => $data) { if ($process::OUT === $type) { echo $data."\n"; } else { echo "[ERR] ".$data."\n"; } } returns an iterator

Slide 50

Slide 50 text

3.2

Slide 51

Slide 51 text

« Saisissez une citation ici. »

Slide 52

Slide 52 text

use Symfony\Bundle\FrameworkBundle\Controller\Controller; class DefaultController extends Controller { public function downloadAction() { $pdfPath = $this->getParameter('dir.downloads').'/my_file.pdf'; return $this->file($pdfPath, ‘my_new_filename.pdf’, ResponseHeaderBag::DISPOSITION_INLINE); } } New file method helper protected function file($file, $fileName = null, $disposition = ResponseHeaderBag::DISPOSITION_ATTACHMENT) 3.2

Slide 53

Slide 53 text

YAML supports PHP constants parameters: # this is considered a regular string foo: PHP_INT_MAX # this is considered a PHP constant bar: !php/const:PHP_INT_MAX 3.2

Slide 54

Slide 54 text

Compiler pass improvements 1/2 // in compiler pass before 3.2 $warmers = array(); foreach ($container->findTaggedServiceIds('kernel.cache_warmer') as $id => $attributes) { $priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0; $warmers[$priority][] = new Reference($id); } krsort($warmers); $warmers = call_user_func_array('array_merge', $warmers); // since 3.2 $warmers = $this->findAndSortTaggedServices('kernel.cache_warmer', $container); 3.2

Slide 55

Slide 55 text

Compiler pass improvements 2/2 3.2 $container->addCompilerPass(new CustomPass(), PassConfig::TYPE_AFTER_REMOVING , 30 ); Step Priority

Slide 56

Slide 56 text

New form type: DateInterval 3.2 ->add('remindEvery', DateIntervalType::class, array( 'placeholder' => array('years' => 'Years', 'months' => 'Months', 'days' => 'Days'), 'widget' => 'choice', // customize which text boxes are shown 'with_years' => true, 'with_months' => true, 'with_days' => true, 'with_hours' => false, ))

Slide 57

Slide 57 text

Tagged cache $cache = new FilesystemAdapter(); $review = $cache->getItem('reviews-'.$reviewId); $review->set('...'); $review->tag(['reviews', 'products', 'product-'.$productId]); $cache->save($review); //… // the HTML structure of reviews has changed: // invalidate all reviews $cache->invalidateTags('reviews'); // instead of $cache->deleteItem('reviews-'.$reviewId); 3.2

Slide 58

Slide 58 text

Routing improvement 3.2 // generating a URL with a fragment $this->get('router')->generate('user_settings', ['_fragment' => 'password']); /settings#password // route definition /** * @Route("/settings", defaults={"_fragment" = "password"}, name="user_settings") */ public function settingsAction() { ... }

Slide 59

Slide 59 text

YAML deprecations • No more duplicated keys otherwise you’ll get a ParseException 3.2 parameters: foo: bar parameters: key: 'aaa' # ... key: 'bbb' • Always put a space after colon otherwise you’ll get a ParseException

Slide 60

Slide 60 text

Runtime Environment variable What’s new? • No longer obliged to prefix them by SYMFONY__ • The value is resolved at runtime! (the app has the updated value) 3.2 doctrine: dbal: # ... password: "%env(DB_PASSWORD)%" To set default value and avoid not set env variable: parameters: env(DB_PASSWORD): s3cr3t_p4ssw0rd

Slide 61

Slide 61 text

Console improvements 3.2 $output->writeln('Test>'); Multiple text style options Hidden commands namespace AppBundle\Command; use Symfony\Component\Console\Command\Command; class FooCommand extends Command { protected function configure() { $this ->setName('app:foo') // ... ->setHidden(true) ; } }

Slide 62

Slide 62 text

Serializer: CSV encoder 3.2 // instantiation, when using it inside the Symfony framework $serializer = $container->get('serializer'); $data = [ 'foo' => 'aaa', 'bar' => [ ['id' => 111, 1 => 'bbb'], ['lorem' => 'ipsum'], ] ]; file_put_contents( 'data.csv', $container->get('serializer')->encode($data, 'csv') ); // decoding CSV contents $data = $serializer->decode(file_get_contents('data.csv'), 'csv');

Slide 63

Slide 63 text

Serializer: YAML encoder 3.2 $obj = new \stdClass(); $obj->bar = 2; $data = $this->container->get('serializer')->encode( ['foo' => $obj], 'yaml' // these are the default values applied by the encoder ['yaml_inline' => 1, 'yaml_indent' => 4, 'yaml_flags' => 0] ); // $data = ' foo: !php/object:O:8:\"stdClass\":1:{s:3:\"bar\";i:2;}\n'; $data = $this->container->get('serializer')->decode( 'foo: !php/object:O:8:"stdClass":1:{s:3:"bar";i:2;}', 'yaml' ); // $data = ['foo' => $obj];

Slide 64

Slide 64 text

Cache improvements 3.2

Slide 65

Slide 65 text

Get information about the firewall 1/2 • Symfony\Bundle\SecurityBundle\Security\FirewallConfig • name, provider, context, entrypoint, access denied URL… 3.2

Slide 66

Slide 66 text

Get information about the firewall 2/2 3.2

Slide 67

Slide 67 text

Get information about the firewall 2/2 3.2

Slide 68

Slide 68 text

Translation improvements // Before $this->get('translator') ->transChoice('1 apple|%count% apples', 7, ['%count%' => 7]); // After $this->get('translator') ->transChoice('1 apple|%count% apples', 7); 3.2 ./bin/console translation:update en --force --domain=admin

Slide 69

Slide 69 text

Support for PhpStorm links (\o/) 3.2 # app/config/config.yml framework: ide: 'phpstorm://open?file=%%f&line=%%l

Slide 70

Slide 70 text

Source link 3.2

Slide 71

Slide 71 text

Unicode routing support UTF-8 characters in route paths and requirements /** * @Route( * "/category/{name}", * "requirements" = { "name": "䴰ᬨ|بيحرت" } * "options" = { "utf8": true } * ) */ public function categoryAction($name) { // ... } /category/䴰ᬨ, /category/بيحرت 3.2

Slide 72

Slide 72 text

Unicode routing support UTF-8 characters in route paths and requirements /** * @Route( * "/category/{name}", * "requirements" = { "name": "䴰ᬨ|بيحرت" } * "options" = { "utf8": true } * ) */ public function categoryAction($name) { // ... } /category/䴰ᬨ, /category/بيحرت not needed before 4.0 is able to detect UTF-8 3.2

Slide 73

Slide 73 text

• Implementation of the petri net (Transitions, places…) • Supports state machine New component: Workflow 3.2

Slide 74

Slide 74 text

• Implementation of the petri net (Transitions, places…) • Supports state machine New component: Workflow https://speakerdeck.com/lyrixx/le-reveil-du-workflow 3.2

Slide 75

Slide 75 text

• Implementation of the petri net (Transitions, places…) • Supports state machine New component: Workflow https://speakerdeck.com/lyrixx/le-reveil-du-workflow https://speakerdeck.com/tucksaun/symfonylive-london-2016-the-workflow-awakens 3.2

Slide 76

Slide 76 text

• Implementation of the petri net (Transitions, places…) • Supports state machine New component: Workflow https://speakerdeck.com/lyrixx/le-reveil-du-workflow https://speakerdeck.com/tucksaun/symfonylive-london-2016-the-workflow-awakens https://speakerdeck.com/saro0h/openclassrooms-workflow-component 3.2

Slide 77

Slide 77 text

Better support for one command applications 3.2 use Symfony\Component\Console\Application; $command = new \FooCommand(); $application = new Application(); $application->add($command); // the second boolean argument tells if this is a single-command app $application->setDefaultCommand($command->getName(), true); // this now executes the 'FooCommand' without passing its name $application->run();

Slide 78

Slide 78 text

Simpler command testing 3.2 use Symfony\Component\Console\Tester\CommandTester; $commandTester = new CommandTester($command); $helper = $command->getHelper('question'); $helper->setInputStream($this->getInputStream("123\nfoo\nbar\n")); protected function getInputStream($input) { $stream = fopen('php://memory', 'r+', false); fputs($stream, $input); rewind($stream); return $stream; } use Symfony\Component\Console\Tester\CommandTester; $commandTester = new CommandTester($command); $commandTester->setInputs(['123', 'foo', 'bar']);

Slide 79

Slide 79 text

Thank you Javier. Without you… our life would be…

Slide 80

Slide 80 text

Thank you Javier. Without you… our life would be…

Slide 81

Slide 81 text

" # Thank you Javi!

Slide 82

Slide 82 text

Big thank to this amazing community "

Slide 83

Slide 83 text

See ya next year! @catlannister