SlideShare a Scribd company logo
Robert Lemke_


The Real World
Beyond the Blog Example
project founder of TYPO3 Flow and TYPO3 Neos

co-founder of the TYPO3 Association

coach, coder, consultant

36 years old

                      TEXT HERE
lives in Lübeck, Germany

1 wife, 2 daughters, 1 espresso machine

likes drumming
"the leftovers talks"
TEXT HERE
Application Structure
Request / Response
    and MVC
$context = getenv('FLOW_CONTEXT') ?: (getenv('REDIRECT_FLOW_CONTEXT') ?: 'Development');
$bootstrap = new TYPO3FlowCoreBootstrap($context);
$bootstrap->run();
/**
 * Bootstraps the minimal infrastructure, resolves a fitting request handler and
 * then passes control over to that request handler.
 *
 * @return void
 * @api
 */
public function run() {
    Scripts::initializeClassLoader($this);
    Scripts::initializeSignalSlot($this);
    Scripts::initializePackageManagement($this);

    $this->activeRequestHandler = $this->resolveRequestHandler();
    $this->activeRequestHandler->handleRequest();
}
/**
 * Handles a HTTP request
 *
 * @return void
 */
public function handleRequest() {
    $this->request = Request::createFromEnvironment();
    $this->response = new Response();

    $this->boot();
    $this->resolveDependencies();
    $this->request->injectSettings($this->settings);

    $this->router->setRoutesConfiguration($this->routesConfiguration);
    $actionRequest = $this->router->route($this->request);
    $this->securityContext->setRequest($actionRequest);

    $this->dispatcher->dispatch($actionRequest, $this->response);

    $this->response->makeStandardsCompliant($this->request);
    $this->response->send();

    $this->bootstrap->shutdown('Runtime');
    $this->exit->__invoke();
}
/**
  * Dispatches a request to a controller
  *
  * @param TYPO3FlowMvcRequestInterface $request The request to dispatch
  * @param TYPO3FlowMvcResponseInterface $response The response, to be modified by the cont
  * @return void
  * @throws TYPO3FlowMvcExceptionInfiniteLoopException
  * @api
  */
public function dispatch(RequestInterface $request, ResponseInterface $response) {
     $dispatchLoopCount = 0;
     while (!$request->isDispatched()) {
        $controller = $this->resolveController($request);
        try {
           $this->emitBeforeControllerInvocation($request, $response, $controller);
           $controller->processRequest($request, $response);
           $this->emitAfterControllerInvocation($request, $response, $controller);
        } catch (StopActionException $exception) {
           $this->emitAfterControllerInvocation($request, $response, $controller);
           if ($exception instanceof ForwardException) {
              $request = $exception->getNextRequest();
           } elseif ($request->isMainRequest() === FALSE) {
              $request = $request->getParentRequest();
           }
        }
     }
}
/**
 * Book controller for the RobertLemke.Example.Bookshop package
 */
class BookController extends ActionController {

    /**
     * @FlowInject
     * @var RobertLemkeExampleBookshopDomainRepositoryBookRepository
     */
    protected $bookRepository;

    /**
      * Shows a single book object
      *
      * @param RobertLemkeExampleBookshopDomainModelBook $book The book to show
      * @return void
      */
    public function showAction(Book $book) {
         $this->view->assign('book', $book);
    }

}
/**
  * Dispatches a request to a controller
  *
  * @param TYPO3FlowMvcRequestInterface $request The request to dispatch
  * @param TYPO3FlowMvcResponseInterface $response The response, to be modified by the cont
  * @return void
  * @throws TYPO3FlowMvcExceptionInfiniteLoopException
  * @api
  */
public function dispatch(RequestInterface $request, ResponseInterface $response) {
     $dispatchLoopCount = 0;
     while (!$request->isDispatched()) {
        $controller = $this->resolveController($request);
        try {
           $this->emitBeforeControllerInvocation($request, $response, $controller);
           $controller->processRequest($request, $response);
           $this->emitAfterControllerInvocation($request, $response, $controller);
        } catch (StopActionException $exception) {
           $this->emitAfterControllerInvocation($request, $response, $controller);
           if ($exception instanceof ForwardException) {
              $request = $exception->getNextRequest();
           } elseif ($request->isMainRequest() === FALSE) {
              $request = $request->getParentRequest();
           }
        }
     }
}
/**
 * Handles a HTTP request
 *
 * @return void
 */
public function handleRequest() {
    $this->request = Request::createFromEnvironment();
    $this->response = new Response();

    $this->boot();
    $this->resolveDependencies();
    $this->request->injectSettings($this->settings);

    $this->router->setRoutesConfiguration($this->routesConfiguration);
    $actionRequest = $this->router->route($this->request);
    $this->securityContext->setRequest($actionRequest);

    $this->dispatcher->dispatch($actionRequest, $this->response);

    $this->response->makeStandardsCompliant($this->request);
    $this->response->send();

    $this->bootstrap->shutdown('Runtime');
    $this->exit->__invoke();
}
/**
 * GeneratePdf action
 *
 * @param AcmeDemoDomainModelInvoice $invoice
 * @param boolean $forward
 */
public function generatePdfAction(AcmeDemoDomainModelInvoice $invoice, $forward = TRUE)
    $fopCommand = $this->settings['pdf']['fopCommand'];

   $storageInvoiceFilename = $this->renderInvoiceFilename($invoice);

   $outputPath = $this->environment->getPathToTemporaryDirectory() . 'Acme.Demo/';

   $packageResourcesPath = $this->packageManager->getPackage('Acme.Demo')->getResourcesPath(
   $xmlPathAndFilename = $outputPath . 'Xml/'. $storageInvoiceFilename . '.xml';
   $configurationPathAndFilename = $outputPath . 'Configuration.xml';
   $pdfPathAndFilename = $outputPath.'Pdf/'. $storageInvoiceFilename;
   $fontsPath = $packageResourcesPath . 'Private/Fop/Fonts/';
   $xslPathAndFilename = $packageResourcesPath . 'Private/Fop/Xsl/Document.xsl';

   if (!file_exists($outputPath . 'Pdf')){
      Files::createDirectoryRecursively($outputPath . 'Pdf');
   }
   if (!file_exists($outputPath . 'Xml')){
      Files::createDirectoryRecursively($outputPath . 'Xml');
   }

   $standaloneView = new StandaloneView();
   $standaloneView->setTemplatePathAndFilename('resource://Acme.Demo/Private/Fop/Xml/Documen
   $standaloneView->assign('invoice', $invoice);
namespace AcmeDemo;

class InvoiceController extends AcmeDemoControllerAbstractBaseController {

   /**
    * @var AcmeDemoApplicationServiceInvoiceGenerator
    * @FlowInject
    */
   protected $invoiceGenerator;

   /**
     * GeneratePdf action
     *
     * @param AcmeDemoDomainModelInvoice $invoice
     * @param boolean $forward
     */
   public function generatePdfAction(AcmeDemoDomainModelInvoice $invoice, $forward = TRUE)
        $this->invoiceGeneratorService->generate($invoice, $pdf);
        $this->forward('download', NULL, NULL, array('invoice' => $invoice));
   }
Forms
TEXT HERE
HTTP Caches
$this->response->getHeaders()
  ->setCacheControlDirective('s-max-age', 100);
Safe Request / method tunneling
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
CSRF
<a href="http://myserver.com/book/amazing-apps-with-flow/
delete">Delete Book</a>
<a href="http://myserver.com/book/amazing-apps-with-flow/delete?
__csrfToken=abcdef1234567890">Delete Book</a>
<form enctype="multipart/form-data" name="newBook" action="book/create" method="post">

    <input type="hidden" name="__trustedProperties" value="a:1:{s:7:&quot;newBook&quot;;a:6:
    <input type="hidden" name="__csrfToken" value="10fa21087d49e5bb37d9c91248ea693a"/>

    ...
speed!
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

    }

}
$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;
   }
Accounts, Users, Authentication

Flow distinguishes between accounts and persons:
 _ account: TYPO3FlowSecurityAccount
 _ person: TYPO3PartyDomainModelPerson


A person (or machine) can have any number of accounts.
Creating Accounts

 _ always use the AccountFactory
 _ create a party (eg. a Person) separately
 _ assign the account to the party
 _ add account and party to their respective repositories
$account = $this->accountFactory->createAccountWithPassword(
   $accountIdentifier,
   $password,
   array($role)
);

$this->accountRepository->add($account);

$person = new Person();
$person->addAccount($account);

$name = new PersonName('', 'Robert', '', 'Lemke');
$person->setName($name);

$this->partyRepository->add($person);
Roles
roles:
  User: []
  Manager: ['User']
  Editor: ['User', 'TYPO3.Neos:Editor']
/**
 * Create a role and return a role instance for it.
 *
 * @param string $roleIdentifier
 * @return TYPO3FlowSecurityPolicyRole
 * @throws TYPO3FlowSecurityExceptionRoleExistsException
 */
public function createRole($roleIdentifier) {
    $this->initializeRolesFromPolicy();

    if (isset($this->systemRoles[$roleIdentifier])) {
       throw new RoleExistsException(sprintf('Could not create role %s because a system role wi
    }

    if (preg_match('/^[w]+((.[w]+)*:[w]+)+$/', $roleIdentifier) !== 1) {
       throw new InvalidArgumentException(sprintf('Could not create role %s because it does no
    }

    if ($this->roleRepository->findByIdentifier($roleIdentifier) !== NULL) {
       throw new RoleExistsException(sprintf('Could not create role %s because a role with that
    }

    $role = new Role($roleIdentifier);
    $this->roleRepository->add($roleIdentifier);

    return $role;
}
Virtual Browser
/**
 * @FlowInject
 * @var TYPO3FlowHttpClientBrowser
 */
protected $browser;

/**
 * @return array
 */
public function getBookInfo($isbn) {
    $this->browser->setRequestEngine(new CurlEngine());
    $response = $this->browser->request(
        'http://isbndb.com/api/books.xml?index1=isbn&value1=' . $isbn);
    $xml = simplexml_load_string($response->getContent());

    …

    return $bookInfo;
}
Page Cache
/**
  * Shows a list of books
  *
  * @return void
  */
public function indexAction() {
     $this->view->assign('books', $books);
}
RobertLemke_Example_Bookshop_Html:
  frontend: TYPO3FlowCacheFrontendStringFrontend
  backend: TYPO3FlowCacheBackendFileBackend
/**
  * Shows a list of books
  *
  * @return string
  */
public function indexAction() {
     $output = $this->htmlCache->get('BookController_index');
     if ($output === FALSE) {
        $books = $this->bookRepository->findAll();
        $this->view->assign('books', $books);
        $output = $this->view->render();
        $this->htmlCache->set('BookController_index', $output);
     }
     return $output;
}
RobertLemkeExampleBookshopControllerBookController:
  properties:
    htmlCache:
      object:
        factoryObjectName: TYPO3FlowCacheCacheManager
        factoryMethodName: getCache
        arguments:
          1:
             value: 'RobertLemke_Example_Bookshop_Html'
Ask me anything *



                * technical
https://github.com/robertlemke
TYPO3 Flow Trainings and
Inhouse Workshops
Robert Lemke Blog
Robert Lemke_
robertlemke.com
@robertlemke

More Related Content

Viewers also liked

TYPO3 Flow package best practices
TYPO3 Flow package best practicesTYPO3 Flow package best practices
TYPO3 Flow package best practices
Pankaj Lele
 
TYPO3 Flow 2.0 in the field - webtech Conference 2013
TYPO3 Flow 2.0 in the field - webtech Conference 2013TYPO3 Flow 2.0 in the field - webtech Conference 2013
TYPO3 Flow 2.0 in the field - webtech Conference 2013
die.agilen GmbH
 
TYPO3 Flow 2.0 Workshop T3BOARD13
TYPO3 Flow 2.0 Workshop T3BOARD13TYPO3 Flow 2.0 Workshop T3BOARD13
TYPO3 Flow 2.0 Workshop T3BOARD13
Robert Lemke
 
TYPO3 Flow and the Joy of Development (FOSDEM 2013)
TYPO3 Flow and the Joy of Development (FOSDEM 2013)TYPO3 Flow and the Joy of Development (FOSDEM 2013)
TYPO3 Flow and the Joy of Development (FOSDEM 2013)
Robert Lemke
 
TYPO3 Flow a solid foundation for medialib.tv
TYPO3 Flow a solid foundation for medialib.tvTYPO3 Flow a solid foundation for medialib.tv
TYPO3 Flow a solid foundation for medialib.tv
dfeyer
 
T3CON14EU: Migrating from TYPO3 CMS to TYPO3 Flow
T3CON14EU: Migrating from TYPO3 CMS to TYPO3 FlowT3CON14EU: Migrating from TYPO3 CMS to TYPO3 Flow
T3CON14EU: Migrating from TYPO3 CMS to TYPO3 Flow
mhelmich
 
TYPO3 Flow 2.0 (International PHP Conference 2013)
TYPO3 Flow 2.0 (International PHP Conference 2013)TYPO3 Flow 2.0 (International PHP Conference 2013)
TYPO3 Flow 2.0 (International PHP Conference 2013)
Robert Lemke
 
T3CON12 Flow and TYPO3 deployment with surf
T3CON12 Flow and TYPO3 deployment with surfT3CON12 Flow and TYPO3 deployment with surf
T3CON12 Flow and TYPO3 deployment with surf
Tobias Liebig
 
TYPO3 5.0 Experience Concept
TYPO3 5.0 Experience ConceptTYPO3 5.0 Experience Concept
TYPO3 5.0 Experience Concept
Jens Hoffmann
 
TYPO3 Flow - PHP Framework for Developer Happiness
TYPO3 Flow - PHP Framework for Developer HappinessTYPO3 Flow - PHP Framework for Developer Happiness
TYPO3 Flow - PHP Framework for Developer HappinessChristian Müller
 
Testing TYPO3 Flow Applications with Behat
Testing TYPO3 Flow Applications with BehatTesting TYPO3 Flow Applications with Behat
Testing TYPO3 Flow Applications with Behat
Markus Goldbeck
 
TYPO3 Neos - past, present and future (T3CON14EU)
TYPO3 Neos - past, present and future (T3CON14EU)TYPO3 Neos - past, present and future (T3CON14EU)
TYPO3 Neos - past, present and future (T3CON14EU)
Robert Lemke
 
Using Document Databases with TYPO3 Flow
Using Document Databases with TYPO3 FlowUsing Document Databases with TYPO3 Flow
Using Document Databases with TYPO3 Flow
Karsten Dambekalns
 

Viewers also liked (13)

TYPO3 Flow package best practices
TYPO3 Flow package best practicesTYPO3 Flow package best practices
TYPO3 Flow package best practices
 
TYPO3 Flow 2.0 in the field - webtech Conference 2013
TYPO3 Flow 2.0 in the field - webtech Conference 2013TYPO3 Flow 2.0 in the field - webtech Conference 2013
TYPO3 Flow 2.0 in the field - webtech Conference 2013
 
TYPO3 Flow 2.0 Workshop T3BOARD13
TYPO3 Flow 2.0 Workshop T3BOARD13TYPO3 Flow 2.0 Workshop T3BOARD13
TYPO3 Flow 2.0 Workshop T3BOARD13
 
TYPO3 Flow and the Joy of Development (FOSDEM 2013)
TYPO3 Flow and the Joy of Development (FOSDEM 2013)TYPO3 Flow and the Joy of Development (FOSDEM 2013)
TYPO3 Flow and the Joy of Development (FOSDEM 2013)
 
TYPO3 Flow a solid foundation for medialib.tv
TYPO3 Flow a solid foundation for medialib.tvTYPO3 Flow a solid foundation for medialib.tv
TYPO3 Flow a solid foundation for medialib.tv
 
T3CON14EU: Migrating from TYPO3 CMS to TYPO3 Flow
T3CON14EU: Migrating from TYPO3 CMS to TYPO3 FlowT3CON14EU: Migrating from TYPO3 CMS to TYPO3 Flow
T3CON14EU: Migrating from TYPO3 CMS to TYPO3 Flow
 
TYPO3 Flow 2.0 (International PHP Conference 2013)
TYPO3 Flow 2.0 (International PHP Conference 2013)TYPO3 Flow 2.0 (International PHP Conference 2013)
TYPO3 Flow 2.0 (International PHP Conference 2013)
 
T3CON12 Flow and TYPO3 deployment with surf
T3CON12 Flow and TYPO3 deployment with surfT3CON12 Flow and TYPO3 deployment with surf
T3CON12 Flow and TYPO3 deployment with surf
 
TYPO3 5.0 Experience Concept
TYPO3 5.0 Experience ConceptTYPO3 5.0 Experience Concept
TYPO3 5.0 Experience Concept
 
TYPO3 Flow - PHP Framework for Developer Happiness
TYPO3 Flow - PHP Framework for Developer HappinessTYPO3 Flow - PHP Framework for Developer Happiness
TYPO3 Flow - PHP Framework for Developer Happiness
 
Testing TYPO3 Flow Applications with Behat
Testing TYPO3 Flow Applications with BehatTesting TYPO3 Flow Applications with Behat
Testing TYPO3 Flow Applications with Behat
 
TYPO3 Neos - past, present and future (T3CON14EU)
TYPO3 Neos - past, present and future (T3CON14EU)TYPO3 Neos - past, present and future (T3CON14EU)
TYPO3 Neos - past, present and future (T3CON14EU)
 
Using Document Databases with TYPO3 Flow
Using Document Databases with TYPO3 FlowUsing Document Databases with TYPO3 Flow
Using Document Databases with TYPO3 Flow
 

Similar to TYPO3 Flow: Beyond the Blog Example (Inspiring Flow 2013)

Applications for the Enterprise with PHP (CPEurope)
Applications for the Enterprise with PHP (CPEurope)Applications for the Enterprise with PHP (CPEurope)
Applications for the Enterprise with PHP (CPEurope)
Robert Lemke
 
Magento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request FlowMagento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request Flow
Vrann Tulika
 
RESTEasy
RESTEasyRESTEasy
Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13
Jason Lotito
 
May 2010 - RestEasy
May 2010 - RestEasyMay 2010 - RestEasy
May 2010 - RestEasy
JBug Italy
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
Elena Kolevska
 
ReactPHP
ReactPHPReactPHP
ReactPHP
Philip Norton
 
Application Layer in PHP
Application Layer in PHPApplication Layer in PHP
Application Layer in PHP
Per Bernhardt
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8
Michelangelo van Dam
 
Auto-loading of Drupal CCK Nodes
Auto-loading of Drupal CCK NodesAuto-loading of Drupal CCK Nodes
Auto-loading of Drupal CCK Nodesnihiliad
 
How kris-writes-symfony-apps-london
How kris-writes-symfony-apps-londonHow kris-writes-symfony-apps-london
How kris-writes-symfony-apps-london
Kris Wallsmith
 
Drupal 7 module development
Drupal 7 module developmentDrupal 7 module development
Drupal 7 module developmentAdam Kalsey
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
Jonathan Wage
 
Using and reusing CakePHP plugins
Using and reusing CakePHP pluginsUsing and reusing CakePHP plugins
Using and reusing CakePHP plugins
Pierre MARTIN
 
Chekout demistified
Chekout demistifiedChekout demistified
Chekout demistified
Damijan Ćavar
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
Nate Abele
 
I Phone On Rails
I Phone On RailsI Phone On Rails
I Phone On Rails
John Wilker
 
Speed up your developments with Symfony2
Speed up your developments with Symfony2Speed up your developments with Symfony2
Speed up your developments with Symfony2Hugo Hamon
 
Fluent Development with FLOW3 1.0
Fluent Development with FLOW3 1.0Fluent Development with FLOW3 1.0
Fluent Development with FLOW3 1.0
Robert Lemke
 
Getting started with TDD - Confoo 2014
Getting started with TDD - Confoo 2014Getting started with TDD - Confoo 2014
Getting started with TDD - Confoo 2014
Eric Hogue
 

Similar to TYPO3 Flow: Beyond the Blog Example (Inspiring Flow 2013) (20)

Applications for the Enterprise with PHP (CPEurope)
Applications for the Enterprise with PHP (CPEurope)Applications for the Enterprise with PHP (CPEurope)
Applications for the Enterprise with PHP (CPEurope)
 
Magento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request FlowMagento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request Flow
 
RESTEasy
RESTEasyRESTEasy
RESTEasy
 
Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13
 
May 2010 - RestEasy
May 2010 - RestEasyMay 2010 - RestEasy
May 2010 - RestEasy
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
 
ReactPHP
ReactPHPReactPHP
ReactPHP
 
Application Layer in PHP
Application Layer in PHPApplication Layer in PHP
Application Layer in PHP
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8
 
Auto-loading of Drupal CCK Nodes
Auto-loading of Drupal CCK NodesAuto-loading of Drupal CCK Nodes
Auto-loading of Drupal CCK Nodes
 
How kris-writes-symfony-apps-london
How kris-writes-symfony-apps-londonHow kris-writes-symfony-apps-london
How kris-writes-symfony-apps-london
 
Drupal 7 module development
Drupal 7 module developmentDrupal 7 module development
Drupal 7 module development
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Using and reusing CakePHP plugins
Using and reusing CakePHP pluginsUsing and reusing CakePHP plugins
Using and reusing CakePHP plugins
 
Chekout demistified
Chekout demistifiedChekout demistified
Chekout demistified
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
 
I Phone On Rails
I Phone On RailsI Phone On Rails
I Phone On Rails
 
Speed up your developments with Symfony2
Speed up your developments with Symfony2Speed up your developments with Symfony2
Speed up your developments with Symfony2
 
Fluent Development with FLOW3 1.0
Fluent Development with FLOW3 1.0Fluent Development with FLOW3 1.0
Fluent Development with FLOW3 1.0
 
Getting started with TDD - Confoo 2014
Getting started with TDD - Confoo 2014Getting started with TDD - Confoo 2014
Getting started with TDD - Confoo 2014
 

More from Robert Lemke

Neos Content Repository – Git for content
Neos Content Repository – Git for contentNeos Content Repository – Git for content
Neos Content Repository – Git for content
Robert Lemke
 
A General Purpose Docker Image for PHP
A General Purpose Docker Image for PHPA General Purpose Docker Image for PHP
A General Purpose Docker Image for PHP
Robert Lemke
 
Scaleable PHP Applications in Kubernetes
Scaleable PHP Applications in KubernetesScaleable PHP Applications in Kubernetes
Scaleable PHP Applications in Kubernetes
Robert Lemke
 
Flownative Beach - Neos Meetup Hamburg 2022
Flownative Beach - Neos Meetup Hamburg 2022Flownative Beach - Neos Meetup Hamburg 2022
Flownative Beach - Neos Meetup Hamburg 2022
Robert Lemke
 
GitOps with Flux - IPC Munich 2022
GitOps with Flux - IPC Munich 2022GitOps with Flux - IPC Munich 2022
GitOps with Flux - IPC Munich 2022
Robert Lemke
 
OpenID Connect with Neos and Flow
OpenID Connect with Neos and FlowOpenID Connect with Neos and Flow
OpenID Connect with Neos and Flow
Robert Lemke
 
Neos Conference 2019 Keynote
Neos Conference 2019 KeynoteNeos Conference 2019 Keynote
Neos Conference 2019 Keynote
Robert Lemke
 
A practical introduction to Kubernetes (IPC 2018)
A practical introduction to Kubernetes (IPC 2018)A practical introduction to Kubernetes (IPC 2018)
A practical introduction to Kubernetes (IPC 2018)
Robert Lemke
 
Neos Conference 2018 Welcome Keynote
Neos Conference 2018 Welcome KeynoteNeos Conference 2018 Welcome Keynote
Neos Conference 2018 Welcome Keynote
Robert Lemke
 
A practical introduction to Event Sourcing and CQRS
A practical introduction to Event Sourcing and CQRSA practical introduction to Event Sourcing and CQRS
A practical introduction to Event Sourcing and CQRS
Robert Lemke
 
Neos Conference 2017 Welcome Keynote
Neos Conference 2017 Welcome KeynoteNeos Conference 2017 Welcome Keynote
Neos Conference 2017 Welcome Keynote
Robert Lemke
 
IPC16: A Practical Introduction to Kubernetes
IPC16: A Practical Introduction to Kubernetes IPC16: A Practical Introduction to Kubernetes
IPC16: A Practical Introduction to Kubernetes
Robert Lemke
 
IPC 2016: Content Strategy for Developers
IPC 2016: Content Strategy for DevelopersIPC 2016: Content Strategy for Developers
IPC 2016: Content Strategy for Developers
Robert Lemke
 
Docker in Production - IPC 2016
Docker in Production - IPC 2016Docker in Production - IPC 2016
Docker in Production - IPC 2016
Robert Lemke
 
Is this Open Source Thing Really Worth it? (IPC 2016 Berlin)
Is this Open Source Thing Really Worth it? (IPC 2016 Berlin)Is this Open Source Thing Really Worth it? (IPC 2016 Berlin)
Is this Open Source Thing Really Worth it? (IPC 2016 Berlin)
Robert Lemke
 
The Neos Brand (Inspiring Conference 2016)
The Neos Brand (Inspiring Conference 2016)The Neos Brand (Inspiring Conference 2016)
The Neos Brand (Inspiring Conference 2016)
Robert Lemke
 
Neos - past, present, future (Inspiring Conference 2016)
Neos - past, present, future (Inspiring Conference 2016)Neos - past, present, future (Inspiring Conference 2016)
Neos - past, present, future (Inspiring Conference 2016)
Robert Lemke
 
Meet Neos Nürnberg 2016: Ja ich will!
Meet Neos Nürnberg 2016: Ja ich will!Meet Neos Nürnberg 2016: Ja ich will!
Meet Neos Nürnberg 2016: Ja ich will!
Robert Lemke
 
Meet Neos Nürnberg 2016: Hallo Neos!
Meet Neos Nürnberg 2016: Hallo Neos!Meet Neos Nürnberg 2016: Hallo Neos!
Meet Neos Nürnberg 2016: Hallo Neos!
Robert Lemke
 
Turning Neos inside out / React.js HH
Turning Neos inside out / React.js HHTurning Neos inside out / React.js HH
Turning Neos inside out / React.js HH
Robert Lemke
 

More from Robert Lemke (20)

Neos Content Repository – Git for content
Neos Content Repository – Git for contentNeos Content Repository – Git for content
Neos Content Repository – Git for content
 
A General Purpose Docker Image for PHP
A General Purpose Docker Image for PHPA General Purpose Docker Image for PHP
A General Purpose Docker Image for PHP
 
Scaleable PHP Applications in Kubernetes
Scaleable PHP Applications in KubernetesScaleable PHP Applications in Kubernetes
Scaleable PHP Applications in Kubernetes
 
Flownative Beach - Neos Meetup Hamburg 2022
Flownative Beach - Neos Meetup Hamburg 2022Flownative Beach - Neos Meetup Hamburg 2022
Flownative Beach - Neos Meetup Hamburg 2022
 
GitOps with Flux - IPC Munich 2022
GitOps with Flux - IPC Munich 2022GitOps with Flux - IPC Munich 2022
GitOps with Flux - IPC Munich 2022
 
OpenID Connect with Neos and Flow
OpenID Connect with Neos and FlowOpenID Connect with Neos and Flow
OpenID Connect with Neos and Flow
 
Neos Conference 2019 Keynote
Neos Conference 2019 KeynoteNeos Conference 2019 Keynote
Neos Conference 2019 Keynote
 
A practical introduction to Kubernetes (IPC 2018)
A practical introduction to Kubernetes (IPC 2018)A practical introduction to Kubernetes (IPC 2018)
A practical introduction to Kubernetes (IPC 2018)
 
Neos Conference 2018 Welcome Keynote
Neos Conference 2018 Welcome KeynoteNeos Conference 2018 Welcome Keynote
Neos Conference 2018 Welcome Keynote
 
A practical introduction to Event Sourcing and CQRS
A practical introduction to Event Sourcing and CQRSA practical introduction to Event Sourcing and CQRS
A practical introduction to Event Sourcing and CQRS
 
Neos Conference 2017 Welcome Keynote
Neos Conference 2017 Welcome KeynoteNeos Conference 2017 Welcome Keynote
Neos Conference 2017 Welcome Keynote
 
IPC16: A Practical Introduction to Kubernetes
IPC16: A Practical Introduction to Kubernetes IPC16: A Practical Introduction to Kubernetes
IPC16: A Practical Introduction to Kubernetes
 
IPC 2016: Content Strategy for Developers
IPC 2016: Content Strategy for DevelopersIPC 2016: Content Strategy for Developers
IPC 2016: Content Strategy for Developers
 
Docker in Production - IPC 2016
Docker in Production - IPC 2016Docker in Production - IPC 2016
Docker in Production - IPC 2016
 
Is this Open Source Thing Really Worth it? (IPC 2016 Berlin)
Is this Open Source Thing Really Worth it? (IPC 2016 Berlin)Is this Open Source Thing Really Worth it? (IPC 2016 Berlin)
Is this Open Source Thing Really Worth it? (IPC 2016 Berlin)
 
The Neos Brand (Inspiring Conference 2016)
The Neos Brand (Inspiring Conference 2016)The Neos Brand (Inspiring Conference 2016)
The Neos Brand (Inspiring Conference 2016)
 
Neos - past, present, future (Inspiring Conference 2016)
Neos - past, present, future (Inspiring Conference 2016)Neos - past, present, future (Inspiring Conference 2016)
Neos - past, present, future (Inspiring Conference 2016)
 
Meet Neos Nürnberg 2016: Ja ich will!
Meet Neos Nürnberg 2016: Ja ich will!Meet Neos Nürnberg 2016: Ja ich will!
Meet Neos Nürnberg 2016: Ja ich will!
 
Meet Neos Nürnberg 2016: Hallo Neos!
Meet Neos Nürnberg 2016: Hallo Neos!Meet Neos Nürnberg 2016: Hallo Neos!
Meet Neos Nürnberg 2016: Hallo Neos!
 
Turning Neos inside out / React.js HH
Turning Neos inside out / React.js HHTurning Neos inside out / React.js HH
Turning Neos inside out / React.js HH
 

Recently uploaded

"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
Fwdays
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Product School
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
Prayukth K V
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
Thijs Feryn
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Product School
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Product School
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
ODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User Group
CatarinaPereira64715
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
Abida Shariff
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
Product School
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Inflectra
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Tobias Schneck
 
Search and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesSearch and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical Futures
Bhaskar Mitra
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 

Recently uploaded (20)

"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
ODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User Group
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
Search and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesSearch and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical Futures
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 

TYPO3 Flow: Beyond the Blog Example (Inspiring Flow 2013)

  • 1. Robert Lemke_ The Real World Beyond the Blog Example
  • 2. project founder of TYPO3 Flow and TYPO3 Neos co-founder of the TYPO3 Association coach, coder, consultant 36 years old TEXT HERE lives in Lübeck, Germany 1 wife, 2 daughters, 1 espresso machine likes drumming
  • 6.
  • 8. $context = getenv('FLOW_CONTEXT') ?: (getenv('REDIRECT_FLOW_CONTEXT') ?: 'Development'); $bootstrap = new TYPO3FlowCoreBootstrap($context); $bootstrap->run();
  • 9. /** * Bootstraps the minimal infrastructure, resolves a fitting request handler and * then passes control over to that request handler. * * @return void * @api */ public function run() { Scripts::initializeClassLoader($this); Scripts::initializeSignalSlot($this); Scripts::initializePackageManagement($this); $this->activeRequestHandler = $this->resolveRequestHandler(); $this->activeRequestHandler->handleRequest(); }
  • 10. /** * Handles a HTTP request * * @return void */ public function handleRequest() { $this->request = Request::createFromEnvironment(); $this->response = new Response(); $this->boot(); $this->resolveDependencies(); $this->request->injectSettings($this->settings); $this->router->setRoutesConfiguration($this->routesConfiguration); $actionRequest = $this->router->route($this->request); $this->securityContext->setRequest($actionRequest); $this->dispatcher->dispatch($actionRequest, $this->response); $this->response->makeStandardsCompliant($this->request); $this->response->send(); $this->bootstrap->shutdown('Runtime'); $this->exit->__invoke(); }
  • 11. /** * Dispatches a request to a controller * * @param TYPO3FlowMvcRequestInterface $request The request to dispatch * @param TYPO3FlowMvcResponseInterface $response The response, to be modified by the cont * @return void * @throws TYPO3FlowMvcExceptionInfiniteLoopException * @api */ public function dispatch(RequestInterface $request, ResponseInterface $response) { $dispatchLoopCount = 0; while (!$request->isDispatched()) { $controller = $this->resolveController($request); try { $this->emitBeforeControllerInvocation($request, $response, $controller); $controller->processRequest($request, $response); $this->emitAfterControllerInvocation($request, $response, $controller); } catch (StopActionException $exception) { $this->emitAfterControllerInvocation($request, $response, $controller); if ($exception instanceof ForwardException) { $request = $exception->getNextRequest(); } elseif ($request->isMainRequest() === FALSE) { $request = $request->getParentRequest(); } } } }
  • 12. /** * Book controller for the RobertLemke.Example.Bookshop package */ class BookController extends ActionController { /** * @FlowInject * @var RobertLemkeExampleBookshopDomainRepositoryBookRepository */ protected $bookRepository; /** * Shows a single book object * * @param RobertLemkeExampleBookshopDomainModelBook $book The book to show * @return void */ public function showAction(Book $book) { $this->view->assign('book', $book); } }
  • 13. /** * Dispatches a request to a controller * * @param TYPO3FlowMvcRequestInterface $request The request to dispatch * @param TYPO3FlowMvcResponseInterface $response The response, to be modified by the cont * @return void * @throws TYPO3FlowMvcExceptionInfiniteLoopException * @api */ public function dispatch(RequestInterface $request, ResponseInterface $response) { $dispatchLoopCount = 0; while (!$request->isDispatched()) { $controller = $this->resolveController($request); try { $this->emitBeforeControllerInvocation($request, $response, $controller); $controller->processRequest($request, $response); $this->emitAfterControllerInvocation($request, $response, $controller); } catch (StopActionException $exception) { $this->emitAfterControllerInvocation($request, $response, $controller); if ($exception instanceof ForwardException) { $request = $exception->getNextRequest(); } elseif ($request->isMainRequest() === FALSE) { $request = $request->getParentRequest(); } } } }
  • 14. /** * Handles a HTTP request * * @return void */ public function handleRequest() { $this->request = Request::createFromEnvironment(); $this->response = new Response(); $this->boot(); $this->resolveDependencies(); $this->request->injectSettings($this->settings); $this->router->setRoutesConfiguration($this->routesConfiguration); $actionRequest = $this->router->route($this->request); $this->securityContext->setRequest($actionRequest); $this->dispatcher->dispatch($actionRequest, $this->response); $this->response->makeStandardsCompliant($this->request); $this->response->send(); $this->bootstrap->shutdown('Runtime'); $this->exit->__invoke(); }
  • 15. /** * GeneratePdf action * * @param AcmeDemoDomainModelInvoice $invoice * @param boolean $forward */ public function generatePdfAction(AcmeDemoDomainModelInvoice $invoice, $forward = TRUE) $fopCommand = $this->settings['pdf']['fopCommand']; $storageInvoiceFilename = $this->renderInvoiceFilename($invoice); $outputPath = $this->environment->getPathToTemporaryDirectory() . 'Acme.Demo/'; $packageResourcesPath = $this->packageManager->getPackage('Acme.Demo')->getResourcesPath( $xmlPathAndFilename = $outputPath . 'Xml/'. $storageInvoiceFilename . '.xml'; $configurationPathAndFilename = $outputPath . 'Configuration.xml'; $pdfPathAndFilename = $outputPath.'Pdf/'. $storageInvoiceFilename; $fontsPath = $packageResourcesPath . 'Private/Fop/Fonts/'; $xslPathAndFilename = $packageResourcesPath . 'Private/Fop/Xsl/Document.xsl'; if (!file_exists($outputPath . 'Pdf')){ Files::createDirectoryRecursively($outputPath . 'Pdf'); } if (!file_exists($outputPath . 'Xml')){ Files::createDirectoryRecursively($outputPath . 'Xml'); } $standaloneView = new StandaloneView(); $standaloneView->setTemplatePathAndFilename('resource://Acme.Demo/Private/Fop/Xml/Documen $standaloneView->assign('invoice', $invoice);
  • 16. namespace AcmeDemo; class InvoiceController extends AcmeDemoControllerAbstractBaseController { /** * @var AcmeDemoApplicationServiceInvoiceGenerator * @FlowInject */ protected $invoiceGenerator; /** * GeneratePdf action * * @param AcmeDemoDomainModelInvoice $invoice * @param boolean $forward */ public function generatePdfAction(AcmeDemoDomainModelInvoice $invoice, $forward = TRUE) $this->invoiceGeneratorService->generate($invoice, $pdf); $this->forward('download', NULL, NULL, array('invoice' => $invoice)); }
  • 17. Forms
  • 21. Safe Request / method tunneling
  • 22. 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
  • 23. 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
  • 25. CSRF
  • 28. <form enctype="multipart/form-data" name="newBook" action="book/create" method="post"> <input type="hidden" name="__trustedProperties" value="a:1:{s:7:&quot;newBook&quot;;a:6: <input type="hidden" name="__csrfToken" value="10fa21087d49e5bb37d9c91248ea693a"/> ...
  • 31. class BookController extends ActionController { /** * @FlowInject * @var BookRepository */ protected $bookRepository; }
  • 32. class BookController extends ActionController { … public function myAction() { // $this->bookRepository is instance of Dependency Proxy $this->bookRepository->findAll(); // $this->bookRepository is the real BookRepository } }
  • 33. $greet = function($name) { printf("Hello %s", $name); }; $greet('World');
  • 34. class BookController extends BookController_Original implements ProxyInterface { /** * Autogenerated Proxy Method */ public function __construct() { $this->Flow_Proxy_injectProperties(); }
  • 35. $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' ); }); }
  • 36. class BookController extends ActionController { … public function myAction() { $this->bookRepository->findAll(); } }
  • 37. 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; }
  • 38. Accounts, Users, Authentication Flow distinguishes between accounts and persons: _ account: TYPO3FlowSecurityAccount _ person: TYPO3PartyDomainModelPerson A person (or machine) can have any number of accounts.
  • 39. Creating Accounts _ always use the AccountFactory _ create a party (eg. a Person) separately _ assign the account to the party _ add account and party to their respective repositories
  • 40. $account = $this->accountFactory->createAccountWithPassword( $accountIdentifier, $password, array($role) ); $this->accountRepository->add($account); $person = new Person(); $person->addAccount($account); $name = new PersonName('', 'Robert', '', 'Lemke'); $person->setName($name); $this->partyRepository->add($person);
  • 41. Roles
  • 42. roles: User: [] Manager: ['User'] Editor: ['User', 'TYPO3.Neos:Editor']
  • 43.
  • 44.
  • 45. /** * Create a role and return a role instance for it. * * @param string $roleIdentifier * @return TYPO3FlowSecurityPolicyRole * @throws TYPO3FlowSecurityExceptionRoleExistsException */ public function createRole($roleIdentifier) { $this->initializeRolesFromPolicy(); if (isset($this->systemRoles[$roleIdentifier])) { throw new RoleExistsException(sprintf('Could not create role %s because a system role wi } if (preg_match('/^[w]+((.[w]+)*:[w]+)+$/', $roleIdentifier) !== 1) { throw new InvalidArgumentException(sprintf('Could not create role %s because it does no } if ($this->roleRepository->findByIdentifier($roleIdentifier) !== NULL) { throw new RoleExistsException(sprintf('Could not create role %s because a role with that } $role = new Role($roleIdentifier); $this->roleRepository->add($roleIdentifier); return $role; }
  • 47. /** * @FlowInject * @var TYPO3FlowHttpClientBrowser */ protected $browser; /** * @return array */ public function getBookInfo($isbn) { $this->browser->setRequestEngine(new CurlEngine()); $response = $this->browser->request( 'http://isbndb.com/api/books.xml?index1=isbn&value1=' . $isbn); $xml = simplexml_load_string($response->getContent()); … return $bookInfo; }
  • 49. /** * Shows a list of books * * @return void */ public function indexAction() { $this->view->assign('books', $books); }
  • 50. RobertLemke_Example_Bookshop_Html: frontend: TYPO3FlowCacheFrontendStringFrontend backend: TYPO3FlowCacheBackendFileBackend
  • 51. /** * Shows a list of books * * @return string */ public function indexAction() { $output = $this->htmlCache->get('BookController_index'); if ($output === FALSE) { $books = $this->bookRepository->findAll(); $this->view->assign('books', $books); $output = $this->view->render(); $this->htmlCache->set('BookController_index', $output); } return $output; }
  • 52. RobertLemkeExampleBookshopControllerBookController: properties: htmlCache: object: factoryObjectName: TYPO3FlowCacheCacheManager factoryMethodName: getCache arguments: 1: value: 'RobertLemke_Example_Bookshop_Html'
  • 53. Ask me anything * * technical
  • 55. TYPO3 Flow Trainings and Inhouse Workshops