Robert Lemke_
2.0
TEXT HERE
project founder of TYPO3 Flow and TYPO3 Neos
co-founder of the TYPO3 Association
coach, coder, consultant
37 years old
lives in Lübeck, Germany
1 wife, 2 daughters, 1 espresso machine
likes drumming
2005
2.0
72 new major features
236 improvements
177 bug fixes
Speed
FLOW3 1.1
Uncached Welcome Screen
Uncached Welcome Screen
Flow 2.0 beta 3
26 ms
Uncached Welcome Screen
27 ms
Composer
$ curl -s https://getcomposer.org/installer | php
$ sudo mv composer.phar /usr/local/bin/composer
$ composer create-project --stability="beta" --dev typo3/flow-base-distribution
Composer is a
Development Tool
Application
My Flow App
Acme.Demo
Classes
Configuration
Native Flow Package
Controller
HelloWorldController.php
CoolProductController.php
AwesomeSauceController.php
MediocreCoffeeController.php
Domain
…
…
Packages
Resources
Libraries
My Flow App
symfony
yaml
Symfony
Standalone Package
composer.json
Dumper.php
Escaper.php
Parser.php
Packages
Component
Yaml phpunit.xml.dist
README.MDimagine
doctrine
http://bit.ly/flow-composer-video
Native
Sessions
written in pure PHP
based on our HTTP foundation
for the cloud
/**
* @FlowInject
* @var TYPO3FlowSessionSessionManagerInterface
*/
protected $sessionManager;
…
$session = $this->sessionManager->getCurrentSession();
$session->isStarted();
$session->getId();
$session->putData('username', 'robert');
$session->hasKey('username');
$username = $session->getData('username');
$session = $this->sessionManager->getSession($sessionId);
$username = $session->getData('username');
$session->addTag('user12345');
…
$session = $this->sessionManager->getSessionByTag('user12345');
Caches.yaml:
Flow_Session_Storage:
backend: TYPO3FlowCacheBackendApcBackend
based on Flow cache system
404, 505
TYPO3:
Flow:
error:
exceptionHandler:
defaultRenderingOptions: []
renderingGroups:
notFoundExceptions:
matchingStatusCodes: [404]
options:
templatePathAndFilename: 'resource://TYPO3.Flow/Private/Templates/E
variables:
errorDescription: 'Sorry, the page you requested was not found.'
databaseConnectionExceptions:
matchingExceptionClassNames: ['TYPO3FlowPersistenceDoctrineDataba
options:
templatePathAndFilename: 'resource://TYPO3.Flow/Private/Templates/E
variables:
errorDescription: 'Sorry, the database connection couldn''t be es
Persisted
Roles
roles:
User: []
Manager: ['User']
Editor: ['User', 'TYPO3.Neos:Editor']
$role = $this->policyService->createRole('Vendor.Package:Role');
$this->policyService->hasRole('Vendor.Package:Role');
$role = $this->policyService->getRole('Vendor.Package:Role');
Safe
Request
Methods
Network Working Group R. Fielding
Request for Comments: 2616 UC Irvine
Obsoletes: 2068 J. Gettys
Category: Standards Track Compaq/W3C
J. Mogul
Compaq
H. Frystyk
W3C/MIT
L. Masinter
Xerox
P. Leach
Microsoft
T. Berners-Lee
W3C/MIT
June 1999
Hypertext Transfer Protocol -- HTTP/1.1
Status of this Memo
This document specifies an Internet standards track protocol for the
Internet community, and requests discussion and suggestions for
improvements. Please refer to the current edition of the "Internet
9.1 Safe and Idempotent Methods
9.1.1 Safe Methods
Implementors should be aware that the software represents the user in
their interactions over the Internet, and should be careful to allow the
user to be aware of any actions they might take which may have an
unexpected significance to themselves or others.
In particular, the convention has been established that the GET and HEAD
methods SHOULD NOT have the significance of taking an action other than
retrieval. These methods ought to be considered "safe". This allows user
agents to represent other methods, such as POST, PUT and DELETE, in a
special way, so that the user is made aware of the fact that a possibly
unsafe action is being requested.
Naturally, it is not possible to ensure that the server does not generate
side-effects as a result of performing a GET request; in fact, some
dynamic resources consider that a feature. The important distinction here
is that the user did not request the side-effects, so therefore cannot be
held accountable for them.
9.1.2 Idempotent Methods
no automatic persistence
speeds up link generation
Static
Method
Compilation
/**
* Returns a map of action method names and their parameters.
*
* @return array Array of method parameters by action name
*/
public function getActionMethodParameters() {
$methodParameters = $this->reflectionService->getMethodParameters(
get_class($this), $this->actionMethodName);
foreach ($methodParameters as $parameterName => $parameterInfo) {
...
}
return $methodParameters;
}
}
/**
* @return integer
*/
public function getNumberOfMethods() {
return $class_methods = get_class_methods('myclass');
}
/**
* @return integer
* @FlowCompileStatic
*/
public function getNumberOfMethods() {
return $class_methods = get_class_methods('myclass');
}
/**
* @return integer
* @FlowCompileStatic
*/
public function getNumberOfMethods() {
return $class_methods = get_class_methods('myclass');
}
/**
* @return integer
*/
public function getNumberOfMethods() {
return 42;
}
Lazy
Dependency
Injection
class BookController extends ActionController {
/**
* @FlowInject
* @var BookRepository
*/
protected $bookRepository;
}
class BookController extends ActionController {
…
public function myAction() {
// $this->bookRepository is instance of Dependency Proxy
$this->bookRepository->findAll();
// $this->bookRepository is the real BookRepository
}
}
class BookController extends ActionController {
/**
* @FlowInject(lazy = false)
* @var BookRepository
*/
protected $bookRepository;
}
// $this->bookRepository is maybe instance of Dependency Proxy
if ($this->bookRepository instanceof DependencyProxy) {
$this->bookRepository->_activateDependency();
}
// $this->bookRepository is the real BookRepository
$this->otherService->otherMethod($this->bookRepository);
2.1
Cloud Resources
resource:
# Definition of resource storages provided by the Flow core.
# Storages are used for storing and retrieving resources.
storages:
#
defaultPersistentResourcesStorage:
storage: 'TYPO3FlowResourceStorageFileSystemStorage'
storageOptions:
path: %FLOW_PATH_DATA%Persistent/Resources/
# Definition of the default resource collections.
# Collections are used to bundle / group static or persistent resources
# for common processing and publication.
collections:
# Collection which contains all persistent resources
persistentResources:
sources:
-
storage: 'defaultPersistentResourcesStorage'
target: 'localWebDirectoryPersistentResourcesTarget'
# Definition of the basic resource publication targets.
targets:
# Target for publishing persistent resources to the local web directory
localWebDirectoryPersistentResourcesTarget:
target: 'TYPO3FlowResourceTargetFileSystemTarget'
targetOptions:
path: '%FLOW_PATH_WEB%_Resources/Persistent/'
baseUri: '_Resources/Persistent/'
mirrorMode: 'link'
Minifying & Filters
Routing: Request Methods
2.2
Page Cache & Reverse Proxy
Multi Persistence
neos.typo3.org
Questions?
inspiring-flow.com
TYPO3 Flow Trainings and
Inhouse Workshops
Robert Lemke_
robertlemke.com
@robertlemke
Lazy
Dependency
Injection
Behind the
Scenes
class BookController extends ActionController {
/**
* @FlowInject
* @var BookRepository
*/
protected $bookRepository;
}
class BookController extends ActionController {
…
public function myAction() {
// $this->bookRepository is instance of Dependency Proxy
$this->bookRepository->findAll();
// $this->bookRepository is the real BookRepository
}
}
$greet = function($name) {
printf("Hello %s", $name);
};
$greet('World');
class BookController extends BookController_Original
implements ProxyInterface {
/**
* Autogenerated Proxy Method
*/
public function __construct() {
$this->Flow_Proxy_injectProperties();
}
$bookRepository_reference = &$this->bookRepository;
$this->bookRepository =
Bootstrap::$staticObjectManager->getLazyDependencyByHash(
'd0e87f8f658d7866eec63db44a6918b4', $bookRepository_reference
);
if ($this->bookRepository === NULL) {
$this->bookRepository = Bootstrap::$staticObjectManager->createLazyDependency(
'd0e87f8f658d7866eec63db44a6918b4', $bookRepository_reference,
'RobertLemkeExampleBookshopDomainRepositoryBookRepository',
function() {
return Bootstrap::$staticObjectManager->get(
'RobertLemkeExampleBookshopDomainRepositoryBookRepository'
);
});
}
class BookController extends ActionController {
…
public function myAction() {
$this->bookRepository->findAll();
}
}
class DependencyProxy {
…
/**
* Proxy magic call method which triggers the injection of the real dependency
* and returns the result of a call to the original method in the dependency
*
* @param string $methodName Name of the method to be called
* @param array $arguments An array of arguments to be passed to the method
* @return mixed
*/
public function __call($methodName, array $arguments) {
return call_user_func_array(array($this->_activateDependency(), $methodName),
$arguments);
}
/**
* Activate the dependency and set it in the object.
*
* @return object The real dependency object
* @api
*/
public function _activateDependency() {
$realDependency = $this->builder->__invoke();
foreach($this->propertyVariables as &$propertyVariable) {
$propertyVariable = $realDependency;
}
return $realDependency;
}

TYPO3 Flow 2.0 (International PHP Conference 2013)