2019-09-12 20:59:05 +00:00
---
title: Live Blogging From SymfonyLive London 2019
tags:
- conference
- symfony
- symfonylive
- php
---
Inspired by [Matt Stauffer ](https://twitter.com/stauffermatt )'s [live blogging of the keynote ](https://mattstauffer.com/blog/introducing-laravel-vapor ) at Laracon US, I’ m going to do the same for the sessions that I’ m attending at [SymfonyLive London 2019 ](https://london2019.live.symfony.com )...
2019-09-13 08:07:34 +00:00
## Keynote (Back to the basics)
2019-09-13 08:03:44 +00:00
2019-09-13 08:10:54 +00:00
**Embrace the Linux philosophy**
2019-09-13 08:11:22 +00:00
* How we grow the Symfony ecosystem. Built abstracts.
* HttpFoundation, HttpKernel
* Moved to infrastructure
2019-09-13 08:47:55 +00:00
* A few abstractions on top of PHP. Improved versions of PHP functions (`dump` and `var_dump` )
2019-09-13 08:11:22 +00:00
* Started a add higher level abstractions (e.g. Mailer), built on the lower ones.
2019-09-13 08:11:59 +00:00
* Recently worked on PHPUnit assertions. Mailer in Symony 4.4. Can test if an email is sent or queued
2019-09-13 08:47:14 +00:00
**Building flexible high-level abstractions on top of low-level ones**
2019-09-13 08:11:59 +00:00
2019-09-13 08:12:24 +00:00
### What's next?
2019-09-13 08:11:59 +00:00
2019-09-13 08:12:58 +00:00
* Mailer announced in London last year. New component.
2019-09-13 08:13:18 +00:00
* System emails? e.g. new customer, new invoice.
2019-09-13 08:13:58 +00:00
* Symfony Mailer = Built-in responsive, flexible, and generic system emails
2019-09-13 08:15:11 +00:00
- Twig with TwigExtraBundle
- Twig `inky-extra` package (Twig 1.12+)
- Zurb Foundation for Emails CSS stylesheet
- Twig `cssinliner-extra` package (Twig 1.12+)
- Optimised Twig layouts
2019-09-13 08:17:20 +00:00
* `SystemEmail` class extends templated email
2019-09-13 08:17:07 +00:00
* Can set importance,
2019-09-13 08:17:27 +00:00
* Customisable
2019-09-13 08:18:09 +00:00
* Always trying to keep flexible, so things can be overidden and customised
2019-09-13 08:18:33 +00:00
### Sending SMS messages
2019-09-13 08:18:57 +00:00
2019-09-13 08:19:13 +00:00
* new `Texter` and `SmsMessage` class for sending SMS messages
2019-09-13 08:19:31 +00:00
* Same abstraction as emails, but for SMS messages
2019-09-13 08:20:21 +00:00
* Based on HttpClient + Symfony Messenger and third-party providers (Twilio and Nexmo) `twilio://` and `nemxo://`
2019-09-13 08:21:44 +00:00
* Can set via transport `$sms->setTransport('nexmo')`
2019-09-13 08:27:51 +00:00
* Extend the `SystemEmail` and do what you want
2019-09-13 08:47:14 +00:00
* Failover
2019-09-13 08:28:44 +00:00
### Sending Messages
2019-09-13 08:28:56 +00:00
* Create `ChatMessage`
2019-09-13 08:29:03 +00:00
* Telegram and Slack
2019-09-13 08:29:56 +00:00
* `$message->setTransport('telegram')` , `$bus->dispatch($message)`
2019-09-13 08:47:14 +00:00
* Send to Slack **and** Telegram
* `SlackOptions` and `TelegramOptions` for adding emojis etc
* Common transport layer `TransportInterface` , `MessageInterface`
* Failover - e.g. if Twilio is down, send to Telegram
### New component - SymfonyNotifier
* Channels - email, SMS, chat
* Transport, slack, telegram, twilio
* Create a notification, arguments are message and transports (array)
* Receiver
* Customise notifications, `InvoiceNotification` extends `Notification` . `getChannels`
* Override default rendering
* `ChatNotificationInterface` - `asChatMessage()`
* Semantic configuration
* `composer req twilio-notifier telegram-notifier`
* Channels
- Mailer
- Chatter
- Texter
- Browser
- Pusher (iOS, Android, Desktop native notifications)
- Database (web notification centre)
- **A unified way to notify Users via a unified Transport layer**
* Each integration is only 40 lines of code
### What about a SystemNotification?
* Autoconfigured channels
* `new SystemNotification` , `Notifier::getSystemReceivers`
* Importance, automatically configures channels
* Different channels based on importance
* `ExceptionNotification` - get email with stack trace attached
Notifier
* send messages via a unified api
* send to one or many receivers
* Default configu or custom one
### How can we leverage this new infrastructure?
* `Monolog NotifierHandler` - triggered on `Error` level logs
* Uses notified channel configuration
* Converts Error level logs to importance levels
* Configurablelike other Notifications
* 40 lines of code
* Failed Messages Listener - 10 lines of glue code
* **Experimental component in 5.0**
* Can't in in 4.4 as it's a LTS version
* First time an experimental component is added
* Stable in 5.1
2019-09-13 09:07:53 +00:00
## Queues, busses and the Messenger component (Tobias Nyholm)
2019-09-13 09:09:05 +00:00
* Stack is top and buttom - Last-in, first-out
* Queue is back and front - last in, first out
2019-09-13 09:12:30 +00:00
### 2013
* Using Symfony, used 40 or 50 bundles in a project - too much information!
* Used to copy and paste, duplicate a lot of code
* Testing your controllers - controllers as services?
2019-09-13 09:12:44 +00:00
* Controllers are 'comfortable'
2019-09-13 09:13:46 +00:00
* Tried adding `CurrentUserProvider` service to core, should be passed as an argument. Cannot test.
2019-09-13 09:14:18 +00:00
* 'Having Symfony all over the place wasn't the best thing' - when to framework (Matthias Noback)
2019-09-13 09:15:44 +00:00
- Hexagonal architecture
- Keep your kernel away from infrastructure. Let the framework handle the infrastructure.
2019-09-13 09:18:18 +00:00
* Controller -> Command -> Command Bus -> `CommandHandler`
2019-09-13 09:17:33 +00:00
2019-09-13 09:22:33 +00:00
#### What did we win?
2019-09-13 09:18:14 +00:00
* Can leverage Middleware with a command bus
2019-09-13 09:18:51 +00:00
* Queues as a service (RabbitMQ)
2019-09-13 09:20:16 +00:00
* Work queue - one producer, multiple consumers
* Queues should be durable - messages are also stored on disk, consumers should acknowledge a message once a message is handled
2019-09-13 09:21:19 +00:00
* Publish/subscribe
- Producer -> Fanout/direct with routing (multiple queues) -> multiple consumers
2019-09-13 09:21:46 +00:00
* Topics - wildcards
2019-09-13 09:22:33 +00:00
### 2016
* New intern. Understand everything, 'just PHP'. Plain PHP application, not 'scary Symfony'
2019-09-13 09:25:37 +00:00
### Symfony Messenger
2019-09-13 09:29:16 +00:00
2019-09-13 09:22:33 +00:00
* `composer req symfony/messager` - best MessageBus implementation
2019-09-13 09:23:04 +00:00
* Message -> Message bus -> Message handler
2019-09-13 09:23:20 +00:00
* Message is a plain PHP class
2019-09-13 09:24:13 +00:00
* Handler is a normal PHP class which is invokable
2019-09-13 09:24:52 +00:00
* `messenger:message_hander` tag in config
* Autowire with `MessageHandlerInterface`
2019-09-13 09:26:45 +00:00
* What if it takes 20 seconds to send a message? Use asynchronous.
2019-09-13 09:27:40 +00:00
* Transports as middleware (needs sender, receiver, configurable with DSN, encode/decode). `MESSENGER_DSN` added to `.env`
2019-09-13 09:28:03 +00:00
* Start consumer with `bin/console messager:consume-messages` . Time limit with `--time-limit 300`
2019-09-13 09:29:10 +00:00
* PHP Enqueue - production ready, battle-tested messaging solution for PHP
2019-09-13 09:34:16 +00:00
### Issues
* Transformers, takes an object and transforms into an array - `FooTransformer implements TransformerInterface` .
2019-09-13 09:34:52 +00:00
* Don't break other apps by changing the payload.
2019-09-13 09:35:41 +00:00
2019-09-13 09:44:44 +00:00
#### Multiple buses
2019-09-13 09:35:41 +00:00
2019-09-13 09:37:41 +00:00
* Command bus, query bus, event bus
* Separate actions from reactions
2019-09-13 09:44:44 +00:00
#### Envelope
2019-09-13 09:37:41 +00:00
2019-09-13 09:38:28 +00:00
* Stamps for metadata - has the item been on the queue already?
2019-09-13 09:39:05 +00:00
2019-09-13 09:44:44 +00:00
#### Failures
2019-09-13 09:39:05 +00:00
2019-09-13 09:39:48 +00:00
* Requeue, different queue or same queue after a period of time
2019-09-13 09:40:27 +00:00
* Failed queue 1 every minute, failed queue 2 every hour - temporary glitches or a bug?
2019-09-13 09:44:44 +00:00
#### Creating entities
* What if two users registered at the same tiem? Use uuids rather than IDs.
* Symfony validation - can be used on messages, not just forms.
2019-09-13 09:46:40 +00:00
* Cache everything
- Option 1: HTTP request -> Thin app (gets responses from Redis) -> POST to queue. Every GET request would warm cache
- Option 2: HTTP request -> Thin app -> return 200 response -> pass to workers
2019-09-13 09:47:55 +00:00
* Tip: put Command and CommandHandlers in the same directory
2019-09-13 10:26:09 +00:00
2019-09-13 10:33:37 +00:00
## HttpClient (Nicolas Grekas)
2019-09-13 10:26:09 +00:00
* new symfony component, released in may
* Httpclient contracts, separate package that contains interfaces
2019-09-13 10:26:43 +00:00
* Symfony
* PHP-FIG
* Httplug
2019-09-13 10:26:09 +00:00
* `HttpClient::create()` . `$client->get()`
* JSON decoded with error handling
* Used on symfony.com website (#1391). Replaces Guzzle `Client` for `HttpClientInterface`
* Object is stateless, Guzzle is not. Doesn't handle cookies, cookies are state
* Remove boilerplate - use `toArray()`
* Options as third argument - array of headers, similar to Guzzle
2019-09-13 10:31:31 +00:00
### What can we do with the Response?
* `getStatusCode(): int`
* `getHeaders(): array`
* `getContent(): string`
* `toArray(): array`
* `cancel(): void`
* `getInfo(): array` - metadata
2019-09-13 10:26:09 +00:00
* Everything is lazy!
* 80% of use-cases covered
2019-09-13 10:31:31 +00:00
### What about PSR-18?
* Decorator/adapter to change to PSR compatible
* Same for Httplug
### What about the remaining 20%?
* Options are part of the abstraction, not the implementation
2019-09-13 10:31:55 +00:00
#### Some of the options
* `timeout` - control inactivity periods
* `proxy` - get through a http proxy
* `on_progress` - display a progress bar / build a scoped client
* `base_url` - resolve relative URLS / build a scoped client
* `resolve` - protect webhooks against calls to internal endpoints
* `max_redirects` - disable or limit redirects
2019-09-13 10:33:06 +00:00
* Robust and failsafe by default
2019-09-13 10:34:44 +00:00
2019-09-13 10:36:47 +00:00
* Streamable uploads - `$mimeParts->toIterable()` .
* donwload a file
```php
foreach ($client->stream($response) as $chunk) {
// ...
}
```
- Responses are lazy, requests are concurrent
2019-09-13 10:37:54 +00:00
- Asychronus requests. Reading in network order
```
foreach ($client->stream($responses) as $response => $chunk) {
if ($chunk->isLast()) {
2019-09-13 10:38:35 +00:00
// a $response completed
2019-09-13 10:37:54 +00:00
} else {
2019-09-13 10:38:35 +00:00
// a $response's got network activity or timeout
2019-09-13 10:37:54 +00:00
}
}
```
2019-09-13 10:40:42 +00:00
2019-09-13 10:38:53 +00:00
* 379 request completed in 0.4s!
2019-09-13 10:39:54 +00:00
* `Stream` has second argument, max number of seconds to wait before yielding a timeout chunk
2019-09-13 10:40:42 +00:00
* `ResponseInterface::getInfo()` - get response headers, redirect count and URL, start time, HTTP method and code, user data and URL
2019-09-13 10:41:29 +00:00
* `getInfo('debug')` - displays debug information
2019-09-13 10:43:57 +00:00
### The components
2019-09-13 10:44:07 +00:00
* `NativeHttpClient` and `CurlHttpClient`
2019-09-13 10:46:08 +00:00
- both provide
+ 100% contracts
+ secure directs
+ extended (time) info
+ transparent HTTP compression and (de)chunking
+ automatic HTTP proxy configuration via env vars
#### `NativeHttpClient`
- is most portable, works for everyone
- based on HTTP stream wrapper with fixed redirect logic
- blocking until response headers arrive
#### `CurlHttpClient`
- Requires ext-curl with fixed redirection logic
- Multiplexing response headers and bodies
- Leverages HTTP/2 and PUSH when available
- Keeps connections open also between synchronous requests, no DNS resolution so things are faster
2019-09-13 10:47:34 +00:00
#### Decorators
- ScopingHttpClient - auto-configure options based on request URL
- MockHttpClient - for testing, doesn't make actual HTTP requests
2019-09-13 10:48:48 +00:00
- CachingHttpClient - adds caching on a HTTP request
2019-09-13 10:47:34 +00:00
- Psr18Client
- HttplugClient
- TraceableHttpClient
2019-09-13 10:48:48 +00:00
### Combining
#### FrameworkBundle/Autowiring
2019-09-13 10:49:33 +00:00
```yml
framework:
http_client:
max_host_connections: 4
deault_options:
# ....
scoped_client:
# ...
```
2019-09-13 10:49:08 +00:00
#### HttpBrowser
2019-09-13 10:50:19 +00:00
* HttpClient + DomCrawler + CssSelector + HttpKernel + BrowserKit
* RIP Goutte!
2019-09-13 10:53:22 +00:00
2019-09-13 10:53:30 +00:00
### Coming in 4.4...
2019-09-13 10:53:22 +00:00
- `max_duration`
- `buffer` based on a callable
- `$chunk->isInformational()`
- `$response->toStream()`
- Async-compatible extensibility, when decoration is not enough
2019-09-13 10:55:11 +00:00
`composer req symfony/http-client`
2019-09-13 10:59:12 +00:00
## Symfony Checker is coming (Valentine Boineau)
2019-09-13 11:14:45 +00:00
2019-09-13 11:17:13 +00:00
* Static analysis tool for Symfony
2019-09-13 11:16:27 +00:00
- Does a method exist?
- Is it deprecated?
2019-09-13 11:14:45 +00:00
* insight.symfony.com
* @symfonyinsight
2019-09-13 11:15:54 +00:00
* Released soon
2019-09-13 11:16:45 +00:00
### Differences
* Specialise in Symfony - can see more relevant things
* Different interface to other services
2019-09-13 12:15:54 +00:00
2019-09-13 13:23:30 +00:00
## Feeling unfulfilled by SPA promises? Go back to Twig (Dan Blows)
2019-09-13 12:15:54 +00:00
2019-09-13 12:56:11 +00:00
A way on the front-end JS, CSS, images at the beginning of the request, sends a HTTP request (XHR/AJAX) to the back-end
2019-09-13 12:57:05 +00:00
### Why SPAs?
2019-09-13 12:56:11 +00:00
- A way on the front-end JS, CSS, images at the beginning of the request, sends a HTTP request (XHR/AJAX) to the back-end
- no full page refresh
- Supposed to be much quicker
- 'Right tool for the job' - JS on the front-end, PHP on the back-end
- Division of responsibility == faster development
- Reusable API - Api -> Mobile App and SPA - easy to add another consumer
2019-09-13 13:24:18 +00:00
- Easier to debug?
2019-09-13 12:56:11 +00:00
2019-09-13 12:57:05 +00:00
### Why not SPAs?
2019-09-13 12:56:11 +00:00
- Lots of HTTP requests (400 to load the initial page on one project) == slow front end
- Blurred responsibilities == tightly coupled teams
- harder to debug, bugs fall between systems and teams. Huge gap between front-end and back-end, passing responsibilites.
- You can fix these problems in SPAs, but is it worth it?
2019-09-13 12:56:43 +00:00
+ Examples of good SPAs - Trello, Flickr
2019-09-13 12:56:11 +00:00
2019-09-13 12:57:05 +00:00
### Using Twig as an alternative to an SPA?
2019-09-13 12:56:11 +00:00
2019-09-13 13:24:43 +00:00
#### Faster UI - Try and figure out where the problem is.
2019-09-13 12:58:19 +00:00
If you're trying to speed things up, find out where the problem is.
* Browser tools
2019-09-13 12:58:43 +00:00
* Web Debug Toolbar
2019-09-13 12:58:19 +00:00
* Blackfire
* Optimise and monitor
2019-09-13 13:24:43 +00:00
#### Speed up Twig
2019-09-13 13:14:17 +00:00
- Speeding up Symfony
- ext/twig (PHP5 only, not PHP 7)
- Store compiled templates in Opcache, make sure it's enabled
- Render assets though the webserver (assetic not running all the time)
2019-09-13 13:24:43 +00:00
#### Edge side includes
2019-09-13 13:14:17 +00:00
- Component cached differently to the rest of the page
- Varnish/Nginx
- `render_esi`
2019-09-13 13:24:43 +00:00
- News block that caches frequently, rest of the page
2019-09-13 13:14:17 +00:00
2019-09-13 13:24:43 +00:00
#### HTTP/2 with Weblink
2019-09-13 13:14:17 +00:00
- slow finding CSS files to load - 'push' over CSS files, doesn't need to wait
- `preload()` - https://symfony.com/doc/current/web_link.html
2019-09-13 13:24:43 +00:00
#### Live updating pages
2019-09-13 13:14:17 +00:00
- Instantly update when sports results are updated, news articles are added
- Mercure - https://github.com/symfony/mercure
- LiveTwig - whole block or whole section, and live update `render_live`
- Turbolinks - replace whole body, keeps CSS and JS in memory. Merges new stuff in. `helthe/turbolinks`
- ReactPHP - shares kernel between requests
### Writing better code with Twig
- Keep templates simple. Avoid spaghetti code, only about UI. HTML or small amounts of Twig.
- Avoid delimeter chains
- Bad:`blog_post.authors.first.user_account.email_address`
- Good `{{ blog_post.authors_email_address }}`
- Less brittle, slow
* Filters
- Use filters to be precise
- Custom filters
- Avoid chains. Can cause odd results. Create a new filter in PHP
* Functions
- Write your own functions
- Simpler templates
- Get data, can use boolean statements
* Components
- Break a page into components rather than one large page
- `include()`
- Use `only` to only pass that data. less tightenly coupled.
* `render` calls the whole of Symfony, boots Kernel, can be expensive and slow
* Loosely couple templates and controllers
- Keep responses simple
- What makes sense
- if you need extra data in the template, get it in the template
* View models
- Mixed results
- `BlogPostViewModel`
- Can result in boilerplate code
- Can be useful if the view model is different to the Entity
* DRY
- "Don't repeat yourself"
2019-09-13 13:16:26 +00:00
+ Faster development
* Separate UI tests from back-end tests. Different layers for different teams. People don't need to run everything if they are only changing certain things.
- Help your front end
2019-09-13 13:16:39 +00:00
+ Webpack - Encore
2019-09-13 13:17:09 +00:00
+ Type hinting in functions and filters, easier to debug
2019-09-13 13:16:26 +00:00
+ Logging
+ Friendly exceptions - help front-end devs by returning meaningful, readbale errors
2019-09-13 13:19:27 +00:00
+ Web Debug Toolbar and Profiler, provide training for toolbar and profilers
+ Twig-friendly development environment - Twig support in IDEs and text editors
2019-09-13 13:19:33 +00:00
SPAs are sometimes teh right solution. Why do they want to use it, can the same benefits be added with Twig?
2019-09-13 13:19:27 +00:00
3 most important points:
- Profile, identidy, optimise, monitor
- Loosely couple templates to your app code
2019-09-13 13:19:59 +00:00
- Help your front ends - put your front end developers first
2019-09-13 13:21:40 +00:00
- You don't need to use a SPA for single pages, use JavaScript for that one page. It doesn't need to be all or nothing.
2019-09-13 13:16:26 +00:00
2019-09-13 12:15:54 +00:00
## BDD Your Symfony Application (Kamil Kokot)
2019-09-13 13:43:17 +00:00
* Applying BDD to Sylius
* 2 years since release of Sylius (Symfony 2 alpha)
2019-09-13 13:42:36 +00:00
* The business part is more important than the code part
2019-09-13 13:43:54 +00:00
### What is BDD?
2019-09-13 13:42:56 +00:00
* Behaviour driven development. Combines TDD and DDD, into an agile methodology
2019-09-13 13:44:21 +00:00
* Encourages communication and creates shared understanding
2019-09-13 13:44:37 +00:00
* Living, executable documentation that non-programmers understand. Always correct.
2019-09-13 13:45:13 +00:00
* Feature file
- Feature
2019-09-13 13:46:18 +00:00
- Scenario - example of the behaviour for this feature. Simple, atomic. (e.g. I need a product in order to add it to a cart)
2019-09-13 13:45:13 +00:00
- In order to...
- Who gets the benefit?
2019-09-13 13:41:16 +00:00
2019-09-13 13:46:20 +00:00
### BDD in practice
2019-09-13 13:46:55 +00:00
* Feature: booking flight tickets
* Scenario: booking flight ticket for one person
2019-09-13 13:47:31 +00:00
- Given there are the following flights...
2019-09-13 13:47:54 +00:00
- When I visit '/flight/LTN-WAW'
- Then I should be on '/flight/LTN-WAW'
- Add I should see "Your flight has been booked." in "#result"
2019-09-13 13:48:46 +00:00
* In the BDD way - what is the business logic? What is the value for this scenario? What is the reason 'why', and who benefits from this?
2019-09-13 13:50:19 +00:00
* We just need to know that there are 5 seats left on a flight
* Talk and communicate about how the feature is going to work - not just developers
* BDD aids communication
2019-09-13 13:51:47 +00:00
* Questions we can ask
2019-09-13 13:50:19 +00:00
* Can we get a different outcome when the context changes?
2019-09-13 13:51:47 +00:00
- When there was only one seat available
- When there were no available seats
* Can we get the same outcome when the event changes? Can we change 'When' and 'Then stays the same'
2019-09-13 13:52:05 +00:00
- When it is booked for an adult and a child
- When it is booked for an adult
2019-09-13 13:54:36 +00:00
* Does anything else happen that is not mentioned?
* Generate an invoice if a seat is booked
* a pilot would like to get a notification that a seat was booked.
- Figuring out the rules
+ Adults are 15+ years old
+ Children are 2-14 years old
+ Infants and children can only travel with an adult
+ We don't allow for overbooking
2019-09-13 13:55:43 +00:00
* Translating rules into examples
- Add a new scenario for each rule - e.g. don't allow over booking
+ "And the flight should be no longer available..."
2019-09-13 13:55:45 +00:00
2019-09-13 13:56:20 +00:00
### Behat
2019-09-13 13:56:31 +00:00
* Used to automate and execute BDD tests, also SpecDDD
2019-09-13 13:57:12 +00:00
* maps steps to PHP code
* Given a context, when an event, then an outcome
* Domain Context, API context
2019-09-13 13:58:12 +00:00
* class implements `Context` , annotations for `@Given` , `@When` , `@Then` . allows for arguments and regular expressions
2019-09-13 13:59:06 +00:00
* Suites: change what code is executed, and what scenarios are executed. context and tags
2019-09-13 13:59:42 +00:00
* FriendsOfBehat SymfonyExtension - integrates Behat with Symfony
2019-09-13 14:00:49 +00:00
- Contexts registered as Symfony services - inject dependencies, service as a context in Behat. Need to be 'public' for it to work
- Reduces boilerplate code. Supports autowiring.
2019-09-13 14:02:55 +00:00
- Zero configuration
### Domain context
2019-09-13 14:03:26 +00:00
* `Given` verb matches `@Given` annotation. Same for `When` and `Then` .
2019-09-13 14:02:55 +00:00
* Transformers, type hint name string, return Client instance
2019-09-13 13:56:20 +00:00
2019-09-13 14:06:04 +00:00
### API context
* inject `FlightBookingService` and `KernelBrowser`
* Use `$this->kernelBrowser->request()`
* Use `assert()` function wuthin `@Then`
2019-09-13 14:09:00 +00:00
### Back to reality - how it's done with Sylius
* Business part applies to all context. Start talking about what needs to be done, start communicating
* Implement contexts for UI and API
* 12716 steps, 1175 scenarios, 8 min 8 sec, 2.4 scenarios /sec
2019-09-13 14:10:01 +00:00
* 12x faster than JS (17 min 48 sec, 0.19 scenario / sec)
2019-09-13 14:12:00 +00:00
* Treat test CI environment like production
- Turn off debug settings, add caching
- Enable OPcache
2019-09-13 14:09:00 +00:00
2019-09-13 14:17:44 +00:00
* Write features in a natural way
* Too many setup steps - merge steps. less visual debt. e.g. Create currency, zone and locale when creating a store
2019-09-13 14:18:10 +00:00
* Avoid scenarios that are too detailed. You should specify only what's important to this scenario.
2019-09-13 14:12:49 +00:00
2019-09-13 12:15:54 +00:00
## Migrating to Symfony one route at a time (Steve Winter)
2019-09-13 15:11:40 +00:00
* New client with an old application, built in an old version of another framework with unusual dependency management, no tests, no version control and deploying via FTP. Done over a ~3 month period.
2019-09-13 14:55:37 +00:00
* Subscription based index of suppliers
* New requirements to implement by the client
2019-09-13 14:56:04 +00:00
* Our requirements: Needed a deployment process, make it testable, fix the build chain
2019-09-13 14:56:18 +00:00
* Solution attempt 1: Migrate to a new version of the current framework
2019-09-13 14:58:16 +00:00
- Minor template and design changes were fine
- Modifiy features, add new dependencies.
* Solution attempt 2: Upgrade to the latest version - same outcome due to multiple BC breaks (no semver), lots of manual steps
2019-09-13 14:58:43 +00:00
* Solution attempt 3: Symfony!
2019-09-13 15:00:46 +00:00
- Semver! Backwards compatibility promise
- Symfony app to run in parallel, Apache proxy rules and minor changes to the legacy app, added data transfer mechanisms
- Anything new done in Symfony
- Installed on the same server with it's own vhost but not publicly accessible
- Deployed independently of legacy app
2019-09-13 14:52:58 +00:00
2019-09-13 15:02:01 +00:00
### Apache proxy rules
Proxy `/public` to symfony app
### Legacy app
2019-09-13 15:03:16 +00:00
* Shared cookie for single login between apps - user account details (name etc), session details (login time)
2019-09-13 15:04:33 +00:00
### Added functionality
2019-09-13 15:03:16 +00:00
* Built in Symfony
* new proxy rules for new routes
* Add menu links to legacy app menu
2019-09-13 15:03:43 +00:00
* How do we show how many reminders are active?
- Symfony based API called from the front-end
2019-09-13 15:02:01 +00:00
2019-09-13 15:04:33 +00:00
### Migrating routes
* Rebuilt or extend in Symfony app
2019-09-13 15:05:10 +00:00
* Test and deploy, then update the apache config to add new proxy rules
2019-09-13 15:04:33 +00:00
2019-09-13 15:05:46 +00:00
### A gotcha
- Legacy app uses CSRF
2019-09-13 15:06:00 +00:00
- Needed to track the token, added to shared cookie and pass through to the Symfony side
2019-09-13 15:05:46 +00:00
2019-09-13 15:06:49 +00:00
### Storing data
- Both apps using the same data with different credentials
- Some shared tables, some tables are specific to each app
2019-09-13 15:07:14 +00:00
### Remaining challenges
* User session management, still handled by legacy app
2019-09-13 15:08:18 +00:00
* Templating/CSS - two versions of everything
2019-09-13 15:08:43 +00:00
- Next step: move all CSS to Symfony
2019-09-13 15:10:11 +00:00
### Summary
2019-09-13 15:15:49 +00:00
- Add Symfony app, Apache proxy rules for routes
2019-09-13 15:10:11 +00:00
- User transfer mechanisms
- New functionality added in Symfony
2019-09-13 15:07:14 +00:00
2019-09-13 15:10:22 +00:00
### Is this right for you?
2019-09-13 15:11:12 +00:00
It depends. Fine for a 'modest' size. Use a real proxy for larger scale apps, use different servers with database replication.
2019-09-13 15:10:22 +00:00
2019-09-13 12:15:54 +00:00
## Closing Keynote: The fabulous World of Emojis and other Unicode symbols (Nicolas Grekas)
2019-09-13 15:18:34 +00:00
2019-09-13 15:43:45 +00:00
* ASCII. Still used today. Map between the first 128 numbers to characters. OK for UK and US.
2019-09-13 15:44:39 +00:00
* 256 numbers in Windows-1252 (character sets). Each country had their own set.
2019-09-13 15:46:06 +00:00
* It's legacy. 0.2% for Windows-1252. 88.8% for UTF-8 (Feb 2017)
2019-09-13 15:46:57 +00:00
* Unicode: 130k characters, 135 scripts (alphabets)
2019-09-13 15:50:23 +00:00
* Validation errors using native alphabet - e.g. invalid last name when submitting a form
* 17 plans, each square is 255 code points
2019-09-13 15:52:22 +00:00
* Emojis are characters, not images