SlideShare a Scribd company logo
1 of 57
Download to read offline
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 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
 

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

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

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

Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
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
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 

Recently uploaded (20)

Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
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
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 

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