SlideShare une entreprise Scribd logo
1  sur  57
Télécharger pour lire hors ligne
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

Contenu connexe

En vedette

TYPO3 Flow package best practices
TYPO3 Flow package best practicesTYPO3 Flow package best practices
TYPO3 Flow package best practicesPankaj 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 2013die.agilen GmbH
 
TYPO3 Flow 2.0 Workshop T3BOARD13
TYPO3 Flow 2.0 Workshop T3BOARD13TYPO3 Flow 2.0 Workshop T3BOARD13
TYPO3 Flow 2.0 Workshop T3BOARD13Robert 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.tvdfeyer
 
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 Flowmhelmich
 
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 surfTobias Liebig
 
TYPO3 5.0 Experience Concept
TYPO3 5.0 Experience ConceptTYPO3 5.0 Experience Concept
TYPO3 5.0 Experience ConceptJens 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 BehatMarkus 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 FlowKarsten Dambekalns
 

En vedette (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
 

Similaire à 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 FlowVrann Tulika
 
Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13Jason Lotito
 
May 2010 - RestEasy
May 2010 - RestEasyMay 2010 - RestEasy
May 2010 - RestEasyJBug Italy
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Elena Kolevska
 
Application Layer in PHP
Application Layer in PHPApplication Layer in PHP
Application Layer in PHPPer 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.8Michelangelo 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-londonKris 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 BeginnersJonathan Wage
 
Using and reusing CakePHP plugins
Using and reusing CakePHP pluginsUsing and reusing CakePHP plugins
Using and reusing CakePHP pluginsPierre MARTIN
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium AppsNate Abele
 
I Phone On Rails
I Phone On RailsI Phone On Rails
I Phone On RailsJohn 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.0Robert Lemke
 
Getting started with TDD - Confoo 2014
Getting started with TDD - Confoo 2014Getting started with TDD - Confoo 2014
Getting started with TDD - Confoo 2014Eric Hogue
 

Similaire à 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
 

Plus de Robert Lemke

Neos Content Repository – Git for content
Neos Content Repository – Git for contentNeos Content Repository – Git for content
Neos Content Repository – Git for contentRobert 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 PHPRobert Lemke
 
Scaleable PHP Applications in Kubernetes
Scaleable PHP Applications in KubernetesScaleable PHP Applications in Kubernetes
Scaleable PHP Applications in KubernetesRobert Lemke
 
Flownative Beach - Neos Meetup Hamburg 2022
Flownative Beach - Neos Meetup Hamburg 2022Flownative Beach - Neos Meetup Hamburg 2022
Flownative Beach - Neos Meetup Hamburg 2022Robert Lemke
 
GitOps with Flux - IPC Munich 2022
GitOps with Flux - IPC Munich 2022GitOps with Flux - IPC Munich 2022
GitOps with Flux - IPC Munich 2022Robert Lemke
 
OpenID Connect with Neos and Flow
OpenID Connect with Neos and FlowOpenID Connect with Neos and Flow
OpenID Connect with Neos and FlowRobert Lemke
 
Neos Conference 2019 Keynote
Neos Conference 2019 KeynoteNeos Conference 2019 Keynote
Neos Conference 2019 KeynoteRobert 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 KeynoteRobert 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 CQRSRobert Lemke
 
Neos Conference 2017 Welcome Keynote
Neos Conference 2017 Welcome KeynoteNeos Conference 2017 Welcome Keynote
Neos Conference 2017 Welcome KeynoteRobert 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 DevelopersRobert Lemke
 
Docker in Production - IPC 2016
Docker in Production - IPC 2016Docker in Production - IPC 2016
Docker in Production - IPC 2016Robert 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 HHRobert Lemke
 

Plus de 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
 

Dernier

Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...apidays
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamUiPathCommunity
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKJago de Vreede
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024The Digital Insurer
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Orbitshub
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 

Dernier (20)

Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 

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