The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

85
The Coolest Symfony Components you’ve never heard of with your friend @weaverryan (they’re just hiding in your project, waiting for their big break)

Transcript of The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

Page 1: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

The Coolest Symfony Components you’ve never

heard of

with your friend @weaverryan

(they’re just hiding in your project, waiting for their big break)

Page 2: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

> Lead of the Symfony documentation team

> Writer for KnpUniversity.com

> SensioLabs & Blackfire fanboy/evangelist

> Husband of the much more talented @leannapelham

knpuniversity.com twitter.com/weaverryan

Hallo!

> Father to my more handsome son, Beckett

Page 3: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

What is Symfony exactly?

@weaverryan

Page 4: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

Symfony: the reason you had to

wait 5 years for Drupal to come out

@weaverryan

Page 5: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

Nope!

(well maybe partially, but it was worth it!)

@weaverryan

Page 6: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

Symfony is a collection of small PHP libraries

(the components)

@weaverryan

Page 7: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

Drupal uses

of these libraries@weaverryan

100%65%80%53%

Page 8: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

And how many of the 26 included components

are you using?

@weaverryan

Page 9: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

Symfony & Composer

teamwork makes the dream work!

@weaverryan

Page 10: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

> ls vendor/symfony

Page 11: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

https://www.flickr.com/photos/debabratad/4569271310

Page 12: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
Page 13: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

> composer show

Page 14: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

symfony/debug

@weaverryan

Page 15: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

public function build() { $items = []; $items[] = Drupal::root(); return [ '#theme' => 'item_list', '#list_type' => 'ul', '#items' => $items, ];}

Do you want to build a snowman? Or a block?

Page 16: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

@weaverryan

Page 17: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

@weaverryan

Page 18: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

// sites/default/settings.phpuse Symfony\Component\Debug\Debug; Debug::enable();

Page 19: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

@weaverryan

Page 20: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

public function build() { $items = []; $items[] = \Drupal::root(); return [ '#theme' => 'item_list', '#list_type' => 'ul', '#items' => $items, ];}

Page 21: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

Wait! I didn’t need to install it?

@weaverryan

Page 22: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

Maybe not???

@weaverryan

Page 23: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

@weaverryan

Page 24: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

{ "require": { "composer/installers": "^1.0.24", "wikimedia/composer-merge-plugin": "~1.3" }}

composer.json

Page 25: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

{ "require": { "symfony/class-loader": "~2.8", "symfony/console": "~2.8", "symfony/dependency-injection": "~2.8", "symfony/event-dispatcher": "~2.8", "symfony/http-foundation": "~2.8", "symfony/http-kernel": "~2.8", "symfony/routing": "~2.8", "symfony/serializer": "~2.8", "symfony/translation": "~2.8", "symfony/validator": "~2.8", "symfony/process": "~2.8", "symfony/polyfill-iconv": "~1.0", "symfony/yaml": "~2.8", "twig/twig": "^1.23.1", }, }

core/composer.json

Page 26: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
Page 27: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

{ "require": { "composer/installers": "^1.0.24", "wikimedia/composer-merge-plugin": “~1.3", "symfony/debug": "^2.8" }}

composer.json

Page 28: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

symfony/finder

@weaverryan

Page 29: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

use Symfony\Component\Finder\Finder; $finder = new Finder();$finder->files() ->in(\Drupal::root().'/core/themes/*/templates') ->name('*.twig') ->size('> 1k') ->sortByName(); $items = [];foreach ($finder as $file) { // Cool! But what is $file?}

Page 30: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

use Symfony\Component\Finder\Finder; $finder = new Finder();$finder->files() ->in('ftp://example.com/templates/*/templates') ->name('*.twig') ->size('> 1k') ->sortByName(); $items = [];foreach ($finder as $file) { // Cool! But what is $file?}

Page 31: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

use Symfony\Component\Finder\Finder; $finder = new Finder();$finder->files() ->in(\Drupal::root().'/core/themes/*/templates') ->name('*.twig') ->size('> 1k') ->sortByName(); $items = [];foreach ($finder as $file) { // Cool! But what is $file?}

Page 32: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

symfony/var-dumper

@weaverryan

Page 33: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

use Symfony\Component\Finder\Finder; use Symfony\Component\Finder\SplFileInfo; $finder = new Finder();$finder->files() ->in(\Drupal::root().'/core/themes/*/templates') ->name('*.twig') ->size('> 1k') ->sortByName(); $items = [];foreach ($finder as $file) { dump($file);}

Page 34: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

@weaverryan

Page 35: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

$items =[];

/** @var SplFileInfo $file */foreach ($finder as $file) { $items[] = sprintf( '%s (%s kb)', $file->getFilename(), round($file->getSize() / 1024) );}

Page 36: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

@weaverryan

Page 37: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

symfony/console

@weaverryan

Page 38: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

// command.phprequire __DIR__.'/vendor/autoload.php'; $app = new Application();$app->register('greet') ->addArgument('name', InputArgument::REQUIRED) ->addOption('yell', null, InputOption::VALUE_NONE) ->setCode(function($input, $output) { $name = $input->getArgument('name'); $greeting = sprintf( 'Hey <comment>'.$name.'!</comment>'); if ($input->getOption('yell')) { $greeting = strtoupper($greeting); } $output->writeln($greeting); });$app->run();

Page 39: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
Page 40: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

// command.phprequire __DIR__.'/vendor/autoload.php'; $app = new Application();$app->register('greet') ->addArgument('name', InputArgument::REQUIRED) ->addOption('yell', null, InputOption::VALUE_NONE) ->setCode(function($input, $output) { $name = $input->getArgument('name'); $greeting = sprintf( 'Hey <comment>'.$name.'!</comment>'); if ($input->getOption('yell')) { $greeting = strtoupper($greeting); } $output->writeln($greeting); });$app->run();

Page 41: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
Page 42: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

$app->register('templates:find') ->addArgument('dir', InputArgument::REQUIRED) ->setCode(function($input, $output) { $finder = new Finder(); $finder->files() ->in($input->getArgument('dir')) // ... ; /** @var SplFileInfo $file */ foreach ($finder as $file) { $output->writeln(sprintf( '<comment>%s</comment> <info>%s kb</info>', $file->getFilename(), round($file->getSize() / 1024) )); } });

Page 43: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
Page 44: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

@weaverryan

But wait, there’s more!

Page 45: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

$table = new Table($output); $table->setHeaders(['File', 'Size']);$progress = new ProgressBar($output, count($finder));foreach ($finder as $file) { $table->addRow([ '<comment>'.$file->getFilename().'</comment>', '<info>'.round($file->getSize() / 1024).'</info>' ]); $progress->advance(); usleep(500000);} $progress->clear();$table->render();

Page 46: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
Page 47: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

$app->register('some-db-process') ->setCode(function($input, $output) { $kernel = new DrupalKernel('prod', $autoloader); $kernel->handle(new Request()); $container = $kernel->getContainer(); $database = $container->get('database'); // do some work in the database! $stmt = $database->query('SHOW TABLES’); dump($stmt); });

Page 48: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
Page 49: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

symfony/filesystem

@weaverryan

Page 50: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

$fs = new Filesystem();$fs->mkdir(__DIR__.'/many/levels/deep');$fs->mirror( __DIR__.'/core/themes/bartik/templates', __DIR__.'/many/levels/deep'); $fs->chmod( Finder::create()->files() ->in(__DIR__.'/many/levels/deep') ->name('block*'), 0777);

Page 51: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

symfony/process

@weaverryan

Page 52: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

$process = new Process('cowsay Mooooo');$process->setTimeout(5); $process->start();while ($process->isRunning()) { echo 'Running....'; sleep(1); } if (!$process->isSuccessful()) { echo 'Something is wrong with the cow!'; echo $process->getErrorOutput();} else { echo $process->getOutput();}

Page 53: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
Page 54: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

symfony/lock

@weaverryan

Page 55: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

$store = new RedisStore( new \Predis\Client('tcp://localhost:6379') ); $store = new RetryTillSaveStore($store);$factory = new Factory($store); $lock = $factory->createLock('some-lock'); if ($lock->acquire()) { // do you stuff that needs locking! $lock->release();}

Page 56: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

symfony/dotenv

@weaverryan

Page 57: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

// sites/default/settings.php$databases['default']['default'] = array ( 'database' => getenv('DB_NAME'), 'username' => getenv('DB_USER'), 'password' => getenv('DB_PASS'), 'host' => getenv('DB_HOST'), 'driver' => 'mysql', );

Page 58: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

# .envDB_NAME=dcon_baltimoreDB_USER=rootDB_PASS=passDB_HOST=localhost

Page 59: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

// sites/default/settings.phpuse Symfony\Component\Dotenv\Dotenv; $dotenv = new Dotenv();$dotenv->load(__DIR__.'/../../.env');$databases['default']['default'] = array ( // ...);

Page 60: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

# .envDB_NAME=dcon_baltimoreDB_USER=rootDB_PASS=passDB_HOST=localhostDEBUG=1

# some services.yml file parameters: twig.config: debug: '%env(DEBUG)%'

… and in the future (8.4?) …

Page 61: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

symfony/cache

@weaverryan

Page 62: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

// create a new item by trying to get it from the cache$numProducts = $cache->getItem('stats.num_products');// assign a value to the item and save it$numProducts->set(4711);$cache->save($numProducts);// retrieve the cache item$numProducts = $cache->getItem('stats.num_products');if (!$numProducts->isHit()) { // ... item does not exists in the cache} // retrieve the value stored by the item$total = $numProducts->get();// remove the cache item$cache->deleteItem('stats.num_products');

Page 63: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

@weaverryan

✓choose from many adapters (apcu, db, memcached, redis, etc)

✓cache tagging invalidation

✓expiration

✓free cookies

Page 64: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

symfony/expression-language

@weaverryan

Page 65: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

# Get the special price ifuser.getGroup() in ['good_customers', 'collaborator']

# Promote article to the homepage whenarticle.commentCount > 100 and article.category not in ["misc"] # Send an alert whenproduct.stock < 15

What if you need to write business logic… that’s stored in the database?

Page 66: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

use Symfony\Component\ExpressionLanguage\ExpressionLanguage; $language = new ExpressionLanguage();class Apple{ public $variety; } $apple = new Apple();$apple->variety = 'Honeycrisp'; var_dump($language->evaluate( 'fruit.variety', array( 'fruit' => $apple, )));

Page 67: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

# ABC.routing.yml file old_bay_season_food: path: /season/oldbay/{count} # require there to be a ?load=1 on the URL condition: "context.getQueryString() == 'load=1'"

services: # new OldBaySeasoner( # $container->get('config.factory')->get('old_bay.default') # ); old_bay.seasoner: class: Drupal\old_bay\Service\OldBaySeasoner arguments: - '@=service("config.factory").get("old_bay.default")'

maybe in the future???

Page 68: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

symfony/property-info

@weaverryan

Page 69: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

symfony/workflow

@weaverryan

Page 70: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

$definition = new DefinitionBuilder() ->addPlaces(['draft', 'review', 'rejected', 'published']) // Transitions have a unique name, origin place & destination place ->addTransition(new Transition('to_review', 'draft', 'review')) ->addTransition(new Transition('publish', 'review', 'published')) ->addTransition(new Transition('reject', 'review', 'rejected')) ->build(); $marking = new SingleStateMarkingStore('currentState');$workflow = new Workflow($definition, $marking);

$workflow->can($post, 'publish'); // False$workflow->can($post, 'to_review'); // True$workflow->apply($post, 'to_review'); $workflow->can($post, 'publish'); // True // ['publish', 'reject']$workflow->getEnabledTransitions($post);0

Page 71: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

symfony/ldap

@weaverryan

Page 72: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

symfony/image?

@weaverryan

Page 73: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

symfony/utf8?

@weaverryan

Page 74: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

symfony/your-laundry?

https://pixabay.com/p-567951/

Page 75: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

Drupal is using Symfony

@weaverryan

Page 76: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

But are you?

@weaverryan

Page 77: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

@weaverryan

Page 78: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

@weaverryan

Page 79: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

@weaverryan

Page 80: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

Side Note: COMPOSER <3’S YOUR INSANE

LEGACY PROJECT

@weaverryan

(that you've been forced to maintain and not allowed to modernize, despite numerous meetings and efforts to explain things to management)

Page 81: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

https://www.flickr.com/photos/zzpza/3269784239

You have Drupal modules…

Page 82: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

https://www.flickr.com/photos/zzpza/3269784239

~50 Symfony components

Page 83: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

https://www.flickr.com/photos/zzpza/3269784239

… and every other PHP package on the planet

Page 84: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

So build something ridiculous

@weaverryan

Page 85: The Coolest Symfony Components you’ve never heard of - DrupalCon 2017

Ryan Weaver @weaverryan

THANK YOU!