SlideShare a Scribd company logo
1 of 44
Download to read offline
Robert Lemke


Fluent Development With
FLOW3 1.0
Robert Lemke

chief "architect" of TYPO3 5.0 and FLOW3

co-founder of the TYPO3 Association

35 years old

lives in Lübeck, Germany

1 wife, 1 daughter, 1 espresso machine

likes drumming
At a Glance

FLOW3 is a web application framework
 • brings PHP development to a new level



 • made for PHP 5.3, full namespaces support

 • modular, extensible, package based

 • free & Open Source (LGPL v3)

 • backed by one of the largest Open Source projects

   with 6000+ contributors
Foundation for the Next Generation


TYPO3 5.0 is the all-new
Enterprise CMS
 • content repository, workspaces,
   versions, i18n, ExtJS based UI ...

 • powered by FLOW3

 • compatible code base

 • use TYPO3 features in FLOW3
   standalone apps as you like
Work in Progress



            WARNING

           The current documen
                                 tation of FLOW3 does
           cover the version in                         not
                                our Git master – a lo
           changed since the la                       t has
                                st alpha release!
           We are currently upd
                                 ating the manuals an
           tutorials for the 1.0 b                     d
                                   eta release though.
Hello World!

Package.php


   <?php
   namespace F3Demo;

   use F3FLOW3PackagePackage as BasePackage;

   class Package extends BasePackage {
   }




   $ ./flow3_dev flow3:package:create Demo
Hello World!

StandardController.php

   <?php
   namespace F3DemoController;

   use F3FLOW3MVCControllerActionController;

   class StandardController extends ActionController {
   	
   	 /**
   	   * @param string $name
   	   * @return string
   	   */
   	 public function indexAction($name) {
   	 	 return "Hello $name!";
   	 }
   }

   ?>
Hello World!

http://dev.flow3.rob/demo/standard/index?name=Robert



 Hello Robert!
Tackling the Heart of Software Development

                                         /**
Domain-Driven Design                      * Paper submmited by
                                          *
                                                               a speaker

                                          * @scope prototype
                                          * @entity
A methodology which ...                   */
                                        class Paper {

 • results in rich domain models        	    /**
                                        	     * @var Participant
                                        	     */
 • provides a common language           	    protected $author;

   across the project team          	       /**
                                    	        * @var string
                                    	        */
 • simplify the design of complex   	       protected $title;
   applications                     	       /**
                                    	        * @var string
                                    	        */
                                    	       protected $shortAbstra
                                                                   ct;
FLOW3 is the first PHP framework
                                    	       /**
tailored to Domain-Driven Design    	        * @var string
                                    	        */
                                    	       protected $abstract;
Domain-Driven Design
Persistence

Object Persistence in the Flow
 • based on Doctrine 2

 • seamless integration into FLOW3

 • provides all the great Doctrine 2 features

 • uses UUIDs

 • low level persistence API:

   • allows for own, custom persistence
     backends (instead of Doctrine 2)

   • CouchDB is supported natively
Basic Object Persistence




	   	 // Create a new customer and persist it:
	   $customer = new Customer("Robert");
	   $this->customerRepository->add($customer);

	   	 // Find an existing customer:
	   $otherCustomer = $this->customerRepository->findByFirstName("Karsten");
	
	   	 // and delete it:
	   $this->customerRepository->remove($otherCustomer);
Advanced Queries
PostRepository.php
	   /**
	     * Finds most recent posts excluding the given post
	     *
	     * @param F3BlogDomainModelPost $post Post to exclude from result
	     * @param integer $limit The number of posts to return at max
	     * @return array All posts of the $post's blog except for $post
	     */
	   public function findRecentExceptThis(F3BlogDomainModelPost $post, $limit = 20) {
	   	    $query = $this->createQuery();
	   	    $posts = $query->matching($query->equals('blog', $post->getBlog()))
	   	    	    	   ->setOrderings(array('date' => F3FLOW3PersistenceQueryInterface::ORDER_DESCENDING))
	   	    	    	   ->setLimit($limit)
	   	    	    	   ->execute()
	   	    	    	   ->toArray();
	   	    unset($posts[array_search($post, $posts)]);
	   	    return $posts;



	   	   	   // this is an alternative way of doing this when extending the Doctrine 2
	   	   	   // specific repository and using DQL.
	   	   return $this->entityManager
	   	   	   ->createQuery('SELECT p FROM F3BlogDomainModelPost p WHERE p.blog = :blog' .
                           'AND NOT p = :excludedPost ORDER BY p.date DESC')
	   	   	   ->setMaxResults($limit)
	   	   	   ->execute(array('blog' => $post->getBlog(), 'excludedPost' => $post));
	   }
Purely Doctrine 2
       <?php
       namespace MyExample;

       /**
        * @Entity(repositoryClass="BugRepository")
        */
       class Bug {

       	   /**
       	    * @var integer
       	    * @Id
         	 * @Column(type="integer")
       	    * @GeneratedValue
       	    */
            public $id;

       	   /**
       	    * @var string
       	    * @Column(type="string")
       	    */
            public $description;

       	   /**
       	    * @var DateTime
Doctrine 2 in FLOW3
       <?php
       namespace MyExample;

       /**
        * @Entity(repositoryClass="BugRepository")
        */
       class Bug {

       	   /**
       	    * @var integer
       	    * @Id
         	 * @Column(type="integer")
       	    * @GeneratedValue
       	    */
            public $id;

       	   /**
       	    * @var string
       	    * @Column(type="string")
       	    */
            public $description;

       	   /**
       	    * @var DateTime
Purely Doctrine 2

    	    /**
    	     * @var DateTime
    	     * @Column(type="datetime")
    	     */
          public $created;

    	    /**
    	     * @var User
    	     * @ManyToOne(targetEntity="User", inversedBy="assignedBugs")
    	     */
          private $engineer;

    	    /**
    	     * @var DoctrineCommonCollectionsArrayCollection<Product>
    	     * @ManyToMany(targetEntity="Product")
    	     */
          private $products;
    }

    ?>
Doctrine 2 in FLOW3

    	    /**
    	     * @var DateTime
    	     * @Column(type="datetime")
    	     */
          public $created;

    	    /**
    	     * @var User
    	     * @ManyToOne(targetEntity="User", inversedBy="assignedBugs")
    	     */
          private $engineer;

    	    /**
    	     * @var DoctrineCommonCollectionsArrayCollection<Product>
    	     * @ManyToMany(targetEntity="Product")
    	     */
          private $products;
    }

    ?>
Object Management

Dependency Injection
 • a class doesn't create or retrieve the instance
   of another class but get's it injected

 • fosters loosely-coupling and high cohesion

 ‣ more stable, reusable code
Object Management

FLOW3's take on Dependency Injection
 • one of the first PHP implementations
   (started in 2006, improved ever since)

 • object management for the whole lifecycle of all objects

 • no unnecessary configuration if information can be
   gatered automatically (autowiring)

 • intuitive use and no bad magical surprises

 • fast! (like hardcoded or faster)
War
Constructor Injection: Symfony 2                                                   nin
                                                                                       g
                                                                                    (I'm
                                                                                           :m
                                                                                                 igh
                                                                                           no           t co
                                                                                                Sym
                                                                                                    f          nta
                                                                                                     ony
                                                                                                           exp     in     erro
    <?php                                                                                                      ert ..
                                                                                                                     .)       rs
namespace AcmeDemoBundleController;

use   SymfonyBundleFrameworkBundleControllerController;
use   SymfonyComponentHttpFoundationRedirectResponse;
use   SensioBundleFrameworkExtraBundleConfigurationRoute;
use   SensioBundleFrameworkExtraBundleConfigurationTemplate;
use   AcmeDemoBundleGreeterService;

class DemoController extends Controller {
	
	   /**
	    * @var AcmeDemoBundleGreeterService
	    */
	   protected $greeterService;

	     /**
	       * @param AcmeDemoBundleGreeterService
	       */
	     public function __construct($greeterService = NULL) {
	     	    $this->greeterService = $greeterService;
	     }
	
      /**
        * @Route("/hello/{name}", name="_demo_hello")
        */
      public function helloAction($name) {
      	    return new Response('Hello ' . $name, 200, array('Content-Type' => 'text/plain'));
      }
}
War
  Constructor Injection: Symfony 2                                                 nin
                                                                                       g
                                                                                    (I'm
                                                                                           :m
                                                                                                 igh
                                                                                           no           t co
                                                                                                Sym
                                                                                                    f          nta
                                                                                                     ony
                                                                                                           exp     in     erro
                                                                                                               ert ..
                                                                                                                     .)       rs




   <?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/
services-1.0.xsd">

    <services>
        <service id="acme.demo.greeterservice" class="AcmeDemoBundleGreeterService" public="false" />
        <service id="acme.demo.democontroller" class="AcmeDemoBundleControllerDemoController">
             <argument type="service" id="acme.demo.greeterservice" />
        </service>
    </services>
</container>
Constructor Injection

    <?php
namespace F3DemoController;

use F3FLOW3MVCControllerActionController;
use F3DemoServiceGreeterService;

class DemoController extends ActionController {
	
	   /**
	    * @var F3DemoServiceGreeterService
	    */
	   protected $greeterService;

	   /**
	     * @param F3DemoServiceGreeterService
	     */
	   public function __construct(F3DemoServiceGreeterService $greeterService) {
	   	    $this->greeterService = $greeterService;
	   }
	
    /**
      * @param string $name
      */
    public function helloAction($name) {
    	
    	     return 'Hello ' . $name;
    }
}
Constructor Injection
Setter Injection

<?php
namespace F3DemoController;

use F3FLOW3MVCControllerActionController;
use F3DemoServiceGreeterService;

class DemoController extends ActionController {
	
	   /**
	    * @var F3DemoServiceGreeterService
	    */
	   protected $greeterService;

	   /**
	     * @param F3DemoServiceGreeterService
	     */
	   public function injectGreeterService(F3DemoServiceGreeterService $greeterService) {
	   	    $this->greeterService = $greeterService;
	   }
	
    /**
      * @param string $name
      */
    public function helloAction($name) {
    	    	   return 'Hello ' . $name;
    }
}
Property Injection

<?php
namespace F3DemoController;

use F3FLOW3MVCControllerActionController;
use F3DemoServiceGreeterService;

class DemoController extends ActionController {
	
	   /**
	     * @var F3DemoServiceGreeterService
	     * @inject
	     */
	   protected $greeterService;
	
    /**
      * @param string $name
      */
    public function helloAction($name) {
    	
    	     return 'Hello ' . $name;
    }
}
Objects.yaml


   F3FLOW3SecurityCryptographyRsaWalletServiceInterface:
     className: F3FLOW3SecurityCryptographyRsaWalletServicePhp
     scope: singleton
     properties:
       keystoreCache:
         object:
           factoryObjectName: F3FLOW3CacheCacheManager
           factoryMethodName: getCache
           arguments:
             1:
                value: FLOW3_Security_Cryptography_RSAWallet
Object Management

FLOW3's take on Dependency Injection
 • one of the first PHP implementations
   (started in 2006, improved ever since)

 • object management for the whole lifecycle of all objects

 • no unnecessary configuration if information can be
   gatered automatically (autowiring)

 • intuitive use and no bad magical surprises

 • fast! (like hardcoded or faster)
Object Management

    class Customer {

	   /**
	    * @inject
	    * @var CustomerNumberGenerator
	    */
	   protected $customerNumberGenerator;

	   ...
}

$customer = new Customer();
Object Management
                                     <?php
                                     declare(ENCODING = 'u
                                                           tf-8');
                                     namespace F3Confere
                                                          nceDomain   ModelConference;
                                    /**
FLOW3 creates proxy classes          * Autogenerated Prox
                                                           y Class
for realizing DI and AOP magic       * @scope prototype
                                     * @entity
                                     */
                                   class Paper extends
 • new operator is supported       F3FLOW3Persistenc
                                                         Paper_Original implem
                                                         eAspectPersistence
                                                                               ents F3FLOW3Object
                                                                              MagicInterface {
                                                                                                     Pr

                                   	     /**
 • proxy classes are created      	
                                   	      * @var string
                                          * @Id
   on the fly                      	
                                  	
                                          * @Column(length="40
                                                               ")
                                          * introduced by F3F
                                                               LOW3PersistenceAsp
                                  	       */                                        ectPersistenceMagic

 • in production context all      	     protected $FLOW3_Per
                                                             sistence_Identifier
                                                                                  = NULL;

   code is static                	      private $FLOW3_AOP_P
                                                             roxy_targetMethodsAn
                                                                                  dGroupedAdvices = ar
                                                                                                       ra
                                 	     private $FLOW3_AOP_P
                                                             roxy_groupedAdviceCh
                                                                                  ains = array();
                                 	     private $FLOW3_AOP_P
                                                            roxy_methodIsInAdvic
                                                                                 eMode = array();

                                 	    /**
                                 	     * Autogenerated Prox
                                                            y Method
                                 	     */
                                 	    public function __co
                                                           nstruct()    {
AOP

Aspect-Oriented Programming
 • programming paradigm

 • separates concerns to improve modularization

 • OOP modularizes concerns into objects

 • AOP modularizes cross-cutting concerns into aspects



 • FLOW3 makes it easy (and possible at all) to use AOP in PHP
AOP
                                 /**
                                  * @aspect
FLOW3 uses AOP for ...            * @introduce
                                  */
                                                  F3FLOW3Pers
                                                                istenceAspec
                                                                              tPersistence
                                class Persist                                               MagicInterfac
                                                enceMagicAspe                                              e, F3FLO
                                                              ct {
 • persistence magic           	
                               	
                                       /**
                                        * @pointcut c
                                                      lassTaggedWit
                               	        */                          h(entity) ||
                                                                                  classTaggedWi
                              	                                                                 th(valueobjec
 • logging                            public functi
                                                     on isEntityOr
                                                                   ValueObject()
                                                                                  {}
                                                                                                               t)

                              	       /**
                             	         * @var string

 • debugging                 	
                             	
                                       * @Id
                                       * @Column(len
                                                     gth="40")
                             	        * @introduce
                                                     F3FLOW3Pers
                            	         */                           istenceAspec
                                                                                 tPersistence
 • security                 	       protected $FL
                                                   OW3_Persisten
                                                                 ce_Identifier
                                                                               ;
                                                                                               MagicAspect->
                                                                                                              isEnti

                           	        /**
                           	         * After retur
                                                    ning advice,
                           	         *                            making sure w
                                                                                e have an UUI
                           	         * @param F3                                            D for each an
                                                    FLOW3AOPJoi                                            d every
                          	         * @return voi                 nPointInterfa
                                                   d                            ce $joinPoint
                          	         * @before cla                                              The current j
                                                   ssTaggedWith(                                              oin po
                          	         */                           entity) && me
                                                                               thod(.*->__co
                         	        public functi                                              nstruct())
                                                  on generateUU
                         	        	      $proxy = $joi          ID(F3FLOW3
                                                       nPoint->getPr          AOPJoinPoint
                         	       	                                   oxy();                 Interface $jo
                                         F3FLOW3Ref                                                     inPoint)
                         	                             lectionObjec
                                 }                                   tAccess::setP
                                                                                   roperty($prox
                                                                                                 y , 'FLOW3_Per
                                                                                                                siste
Security

Touchless Security, Flow-Style
 • security is handled at a central place (through AOP)

 • third-party code is as secure as possible by default

 • modeled after our experiences in the TYPO3 project and
   Spring Security (Java framework)

 • provides authentication, authorization, validation, filtering ...

   • can intercept arbitrary method calls

   • transparently filters content through query-rewriting

 • extensible for new authentication or authorization mechanisms
Security Policy
The Zen of Templating

FLOW3 comes with an elegant, flexible and secure
templating engine: Fluid

 • templates are valid HTML

 • templates contain no PHP

 • object access, control structures, loops ...

 • designer-friendly

 • extensible (view helpers, widgets)
The Zen of Templating
...
<body>
	   <h1>Latest Blog Posts</h1>
	   <f:if condition="{posts}">
	   	   <f:then>
	   	   	   <ol>
	   	   	   	   <f:for each="{posts}" as="post">
	   	   	   	   	   <li class="post">
	   	   	   	   	   	   <h2>
	   	   	   	   	   	   	   <f:link.action action="show" controller="Post" arguments="{post: post}">{post.title}
	   	   	   	   	   	   	   <f:security.ifHasRole role="Editor">
	   	   	   	   	   	   	   	   <f:link.action action="edit" arguments="{post: post}" controller="Post"><img src
	   	   	   	   	   	   	   	   <f:link.action onclick="return confirm('Really delete this post?');" action="del
	   	   	   	   	   	   	   </f:security.ifHasRole>
	   	   	   	   	   	   </h2>
	   	   	   	   	   	   <f:render partial="PostMetaData" arguments="{post: post}"/>
	   	   	   	   	   	   <f:link.action action='show' arguments='{post: post}'>Read more</f:link.action></p>
	   	   	   	   	   </li>
	   	   	   	   </f:for>
	   	   	   </ol>
	   	   </f:then>
	   	   <f:else>
	   	   	   <p>This blog currently doesn't contain any posts.
    	   	      <f:link.action action="new" controller="Post">Create the first post</f:link.action>
            </p>
	   	   </f:else>
	   </f:if>
</f:section>
Forms

 <?php
 namespace F3BlogDomainModel;

 /**
  * A blog post
  *
  * @scope prototype
  * @entity
  */
 class Post {

 	   /**
 	    * @var string
 	    * @validate StringLength(minimum = 1, maximum = 100)
 	    */
 	   protected $title;

 	   /**
 	    * @var string
 	    * @validate StringLength(minimum = 1, maximum = 50)
 	    */
 	   protected $author;
Forms



<h2>Create a new post</h2>

<f:form action="create" object="{newPost}" name="newPost" enctype="multipart/form-data">
	 <label for="title">Title</label><br />
	 <f:form.textbox property="title" id="title" /><br />

	   <label for="content">Content</label><br />
	   <f:form.textarea property="content" rows="5" cols="40" id="content" /><br />

	 <label for="image">Image resource</label><br />
	 <f:form.textbox property="image.title" value="My image title" />
	 <f:form.upload property="image.originalResource" />
</f:form>
Forms

<?php
namespace F3BlogController;
use F3FLOW3MVCControllerActionController;

class PostController extends ActionController {

	    /**
	     * @inject
	     * @var F3BlogDomainRepositoryPostRepository
	     */
	    protected $postRepository;

	    /**
	      * Creates a new post
	      *
	      * @param F3BlogDomainModelPost $newPostadded to the repository
	      * @return void
	      */
	    public function createAction(F3BlogDomainModelPost $newPost) {
	    	 $this->blog->addPost($newPost);
	    	 $this->flashMessageContainer->add('Your new post was created.');
	    	 $this->redirect('index');
	    }
Speed and Performance

For the snappy user experience:

 • multi-layered, tagged caches

 • various cache backends (file, Memcached, APC, Redis, PDO, ...)

 • reverse-proxy support (Varnish, ESI) in the works

 • code compilation

 • regular benchmarks

 • focus on good scalibility
More Features

Command Line Support
(including interactive shell!)
More Features

 • Resource Management (CDNs, private resources, ...)

 • Logging

 • Caching

 • Signal Slot event handling

 • File Monitoring

 • Configuration Management

 • Routing

 • REST / SOAP

 • ...
Roadmap

http://forge.typo3.org/projects/flow3-distribution-base/roadmap
Live Projects?
Thank You!

 • These slides: http://slideshare.net/robertlemke

 • Download FLOW3: http://flow3.typo3.org

 • Follow me on Twitter: @t3rob

 • Give me feedback:

   • robert@typo3.org

   • http://joind.in/3492

More Related Content

What's hot

Beauty and Power of Go
Beauty and Power of GoBeauty and Power of Go
Beauty and Power of GoFrank Müller
 
What's New In Python 2.4
What's New In Python 2.4What's New In Python 2.4
What's New In Python 2.4Richard Jones
 
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
 
Symfony 2.0
Symfony 2.0Symfony 2.0
Symfony 2.0GrUSP
 
Doctrine with Symfony - SymfonyCon 2019
Doctrine with Symfony - SymfonyCon 2019Doctrine with Symfony - SymfonyCon 2019
Doctrine with Symfony - SymfonyCon 2019julien pauli
 
Flex lexer.h -c++-- flexlexer.h -- define interfaces f
Flex lexer.h  -c++-- flexlexer.h -- define interfaces fFlex lexer.h  -c++-- flexlexer.h -- define interfaces f
Flex lexer.h -c++-- flexlexer.h -- define interfaces faman39650
 
PHP Internals and Virtual Machine
PHP Internals and Virtual MachinePHP Internals and Virtual Machine
PHP Internals and Virtual Machinejulien pauli
 
PHP 良好實踐 (Best Practice)
PHP 良好實踐 (Best Practice)PHP 良好實踐 (Best Practice)
PHP 良好實踐 (Best Practice)Win Yu
 
Objective-C A Beginner's Dive (with notes)
Objective-C A Beginner's Dive (with notes)Objective-C A Beginner's Dive (with notes)
Objective-C A Beginner's Dive (with notes)Altece
 
Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11Pedro Cunha
 
O que vem por aí com Rails 3
O que vem por aí com Rails 3O que vem por aí com Rails 3
O que vem por aí com Rails 3Frevo on Rails
 
T-121-5300 (2008) User Interface Design 10 - UIML
T-121-5300 (2008) User Interface Design 10 - UIMLT-121-5300 (2008) User Interface Design 10 - UIML
T-121-5300 (2008) User Interface Design 10 - UIMLmniemi
 
Things about Functional JavaScript
Things about Functional JavaScriptThings about Functional JavaScript
Things about Functional JavaScriptChengHui Weng
 
運用Closure Compiler 打造高品質的JavaScript
運用Closure Compiler 打造高品質的JavaScript運用Closure Compiler 打造高品質的JavaScript
運用Closure Compiler 打造高品質的JavaScripttaobao.com
 

What's hot (20)

Beauty and Power of Go
Beauty and Power of GoBeauty and Power of Go
Beauty and Power of Go
 
What's New In Python 2.4
What's New In Python 2.4What's New In Python 2.4
What's New In Python 2.4
 
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)
 
Symfony 2.0
Symfony 2.0Symfony 2.0
Symfony 2.0
 
Doctrine with Symfony - SymfonyCon 2019
Doctrine with Symfony - SymfonyCon 2019Doctrine with Symfony - SymfonyCon 2019
Doctrine with Symfony - SymfonyCon 2019
 
Flex lexer.h -c++-- flexlexer.h -- define interfaces f
Flex lexer.h  -c++-- flexlexer.h -- define interfaces fFlex lexer.h  -c++-- flexlexer.h -- define interfaces f
Flex lexer.h -c++-- flexlexer.h -- define interfaces f
 
AFPS_2011
AFPS_2011AFPS_2011
AFPS_2011
 
PHP Internals and Virtual Machine
PHP Internals and Virtual MachinePHP Internals and Virtual Machine
PHP Internals and Virtual Machine
 
C# 6.0 Preview
C# 6.0 PreviewC# 6.0 Preview
C# 6.0 Preview
 
PHP 良好實踐 (Best Practice)
PHP 良好實踐 (Best Practice)PHP 良好實踐 (Best Practice)
PHP 良好實踐 (Best Practice)
 
Objective-C A Beginner's Dive (with notes)
Objective-C A Beginner's Dive (with notes)Objective-C A Beginner's Dive (with notes)
Objective-C A Beginner's Dive (with notes)
 
Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11
 
O que vem por aí com Rails 3
O que vem por aí com Rails 3O que vem por aí com Rails 3
O que vem por aí com Rails 3
 
Design patterns in PHP
Design patterns in PHPDesign patterns in PHP
Design patterns in PHP
 
T-121-5300 (2008) User Interface Design 10 - UIML
T-121-5300 (2008) User Interface Design 10 - UIMLT-121-5300 (2008) User Interface Design 10 - UIML
T-121-5300 (2008) User Interface Design 10 - UIML
 
C++ idioms.pptx
C++ idioms.pptxC++ idioms.pptx
C++ idioms.pptx
 
Things about Functional JavaScript
Things about Functional JavaScriptThings about Functional JavaScript
Things about Functional JavaScript
 
Spl in the wild
Spl in the wildSpl in the wild
Spl in the wild
 
運用Closure Compiler 打造高品質的JavaScript
運用Closure Compiler 打造高品質的JavaScript運用Closure Compiler 打造高品質的JavaScript
運用Closure Compiler 打造高品質的JavaScript
 
Function in C++
Function in C++Function in C++
Function in C++
 

Viewers also liked

Current State of TYPO3 Phoenix (T3CON10)
Current State of TYPO3 Phoenix (T3CON10)Current State of TYPO3 Phoenix (T3CON10)
Current State of TYPO3 Phoenix (T3CON10)Robert Lemke
 
T3CON09 Dallas Keynote
T3CON09 Dallas KeynoteT3CON09 Dallas Keynote
T3CON09 Dallas KeynoteRobert Lemke
 
FuelPHP - a PHP HMVC Framework by silicongulf.com
FuelPHP - a PHP HMVC Framework by silicongulf.comFuelPHP - a PHP HMVC Framework by silicongulf.com
FuelPHP - a PHP HMVC Framework by silicongulf.comChristopher Cubos
 
The Secret Recipe of a Juicy M
The Secret Recipe of a Juicy MThe Secret Recipe of a Juicy M
The Secret Recipe of a Juicy MRobert Lemke
 

Viewers also liked (6)

Current State of TYPO3 Phoenix (T3CON10)
Current State of TYPO3 Phoenix (T3CON10)Current State of TYPO3 Phoenix (T3CON10)
Current State of TYPO3 Phoenix (T3CON10)
 
T3CON09 Dallas Keynote
T3CON09 Dallas KeynoteT3CON09 Dallas Keynote
T3CON09 Dallas Keynote
 
FuelPHP - a PHP HMVC Framework by silicongulf.com
FuelPHP - a PHP HMVC Framework by silicongulf.comFuelPHP - a PHP HMVC Framework by silicongulf.com
FuelPHP - a PHP HMVC Framework by silicongulf.com
 
The Secret Recipe of a Juicy M
The Secret Recipe of a Juicy MThe Secret Recipe of a Juicy M
The Secret Recipe of a Juicy M
 
La quinta disciplina
La quinta disciplinaLa quinta disciplina
La quinta disciplina
 
Introducción a la Dinámica de Sistemas
Introducción a la Dinámica de SistemasIntroducción a la Dinámica de Sistemas
Introducción a la Dinámica de Sistemas
 

Similar to Fluent Development with FLOW3 1.0

Fluent Development with FLOW3 1.0
Fluent Development with FLOW3 1.0Fluent Development with FLOW3 1.0
Fluent Development with FLOW3 1.0Robert Lemke
 
The Beauty and the Beast
The Beauty and the BeastThe Beauty and the Beast
The Beauty and the BeastBastian Feder
 
The Beauty And The Beast Php N W09
The Beauty And The Beast Php N W09The Beauty And The Beast Php N W09
The Beauty And The Beast Php N W09Bastian Feder
 
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
 
FLOW3 Tutorial - T3CON11 Frankfurt
FLOW3 Tutorial - T3CON11 FrankfurtFLOW3 Tutorial - T3CON11 Frankfurt
FLOW3 Tutorial - T3CON11 FrankfurtRobert Lemke
 
The beautyandthebeast phpbat2010
The beautyandthebeast phpbat2010The beautyandthebeast phpbat2010
The beautyandthebeast phpbat2010Bastian Feder
 
Getting Into FLOW3 (TYPO312CA)
Getting Into FLOW3 (TYPO312CA)Getting Into FLOW3 (TYPO312CA)
Getting Into FLOW3 (TYPO312CA)Robert Lemke
 
InspiringCon15: Bringing TYPO3 Legacy Applications into the Flow
InspiringCon15: Bringing TYPO3 Legacy Applications into the FlowInspiringCon15: Bringing TYPO3 Legacy Applications into the Flow
InspiringCon15: Bringing TYPO3 Legacy Applications into the Flowmhelmich
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy CodeRowan Merewood
 
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 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase frameworkTYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase frameworkChristian Trabold
 
How to improve the quality of your TYPO3 extensions
How to improve the quality of your TYPO3 extensionsHow to improve the quality of your TYPO3 extensions
How to improve the quality of your TYPO3 extensionsChristian Trabold
 
Speed up your developments with Symfony2
Speed up your developments with Symfony2Speed up your developments with Symfony2
Speed up your developments with Symfony2Hugo Hamon
 
The Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup BelgiumThe Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup BelgiumMatthias Noback
 
Commenting in Agile Development
Commenting in Agile DevelopmentCommenting in Agile Development
Commenting in Agile DevelopmentJan Rybák Benetka
 
Php Documentor The Beauty And The Beast
Php Documentor The Beauty And The BeastPhp Documentor The Beauty And The Beast
Php Documentor The Beauty And The BeastBastian Feder
 
The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014Matthias Noback
 

Similar to Fluent Development with FLOW3 1.0 (20)

Fluent Development with FLOW3 1.0
Fluent Development with FLOW3 1.0Fluent Development with FLOW3 1.0
Fluent Development with FLOW3 1.0
 
The Beauty and the Beast
The Beauty and the BeastThe Beauty and the Beast
The Beauty and the Beast
 
The Beauty And The Beast Php N W09
The Beauty And The Beast Php N W09The Beauty And The Beast Php N W09
The Beauty And The Beast Php N W09
 
Doctrine in FLOW3
Doctrine in FLOW3Doctrine in FLOW3
Doctrine in FLOW3
 
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)
 
FLOW3 Tutorial - T3CON11 Frankfurt
FLOW3 Tutorial - T3CON11 FrankfurtFLOW3 Tutorial - T3CON11 Frankfurt
FLOW3 Tutorial - T3CON11 Frankfurt
 
The beautyandthebeast phpbat2010
The beautyandthebeast phpbat2010The beautyandthebeast phpbat2010
The beautyandthebeast phpbat2010
 
Getting Into FLOW3 (TYPO312CA)
Getting Into FLOW3 (TYPO312CA)Getting Into FLOW3 (TYPO312CA)
Getting Into FLOW3 (TYPO312CA)
 
Inside DocBlox
Inside DocBloxInside DocBlox
Inside DocBlox
 
InspiringCon15: Bringing TYPO3 Legacy Applications into the Flow
InspiringCon15: Bringing TYPO3 Legacy Applications into the FlowInspiringCon15: Bringing TYPO3 Legacy Applications into the Flow
InspiringCon15: Bringing TYPO3 Legacy Applications into the Flow
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy Code
 
TYPO3 Flow 2.0 Workshop T3BOARD13
TYPO3 Flow 2.0 Workshop T3BOARD13TYPO3 Flow 2.0 Workshop T3BOARD13
TYPO3 Flow 2.0 Workshop T3BOARD13
 
TYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase frameworkTYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase framework
 
How to improve the quality of your TYPO3 extensions
How to improve the quality of your TYPO3 extensionsHow to improve the quality of your TYPO3 extensions
How to improve the quality of your TYPO3 extensions
 
Speed up your developments with Symfony2
Speed up your developments with Symfony2Speed up your developments with Symfony2
Speed up your developments with Symfony2
 
The Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup BelgiumThe Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup Belgium
 
Ant vs Phing
Ant vs PhingAnt vs Phing
Ant vs Phing
 
Commenting in Agile Development
Commenting in Agile DevelopmentCommenting in Agile Development
Commenting in Agile Development
 
Php Documentor The Beauty And The Beast
Php Documentor The Beauty And The BeastPhp Documentor The Beauty And The Beast
Php Documentor The Beauty And The Beast
 
The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 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

Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfAijun Zhang
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6DianaGray10
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7DianaGray10
 
Nanopower In Semiconductor Industry.pdf
Nanopower  In Semiconductor Industry.pdfNanopower  In Semiconductor Industry.pdf
Nanopower In Semiconductor Industry.pdfPedro Manuel
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Adtran
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsSeth Reyes
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1DianaGray10
 
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsIgniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsSafe Software
 
NIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopNIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopBachir Benyammi
 
20230202 - Introduction to tis-py
20230202 - Introduction to tis-py20230202 - Introduction to tis-py
20230202 - Introduction to tis-pyJamie (Taka) Wang
 
Designing A Time bound resource download URL
Designing A Time bound resource download URLDesigning A Time bound resource download URL
Designing A Time bound resource download URLRuncy Oommen
 
Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024SkyPlanner
 
VoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXVoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXTarek Kalaji
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAshyamraj55
 
Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioChristian Posta
 
Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.YounusS2
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfDaniel Santiago Silva Capera
 

Recently uploaded (20)

Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdf
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7
 
20150722 - AGV
20150722 - AGV20150722 - AGV
20150722 - AGV
 
Nanopower In Semiconductor Industry.pdf
Nanopower  In Semiconductor Industry.pdfNanopower  In Semiconductor Industry.pdf
Nanopower In Semiconductor Industry.pdf
 
20230104 - machine vision
20230104 - machine vision20230104 - machine vision
20230104 - machine vision
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and Hazards
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1
 
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsIgniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
 
201610817 - edge part1
201610817 - edge part1201610817 - edge part1
201610817 - edge part1
 
NIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopNIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 Workshop
 
20230202 - Introduction to tis-py
20230202 - Introduction to tis-py20230202 - Introduction to tis-py
20230202 - Introduction to tis-py
 
Designing A Time bound resource download URL
Designing A Time bound resource download URLDesigning A Time bound resource download URL
Designing A Time bound resource download URL
 
Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024
 
VoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXVoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBX
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
 
Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and Istio
 
Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
 

Fluent Development with FLOW3 1.0

  • 2. Robert Lemke chief "architect" of TYPO3 5.0 and FLOW3 co-founder of the TYPO3 Association 35 years old lives in Lübeck, Germany 1 wife, 1 daughter, 1 espresso machine likes drumming
  • 3. At a Glance FLOW3 is a web application framework • brings PHP development to a new level • made for PHP 5.3, full namespaces support • modular, extensible, package based • free & Open Source (LGPL v3) • backed by one of the largest Open Source projects with 6000+ contributors
  • 4. Foundation for the Next Generation TYPO3 5.0 is the all-new Enterprise CMS • content repository, workspaces, versions, i18n, ExtJS based UI ... • powered by FLOW3 • compatible code base • use TYPO3 features in FLOW3 standalone apps as you like
  • 5. Work in Progress WARNING The current documen tation of FLOW3 does cover the version in not our Git master – a lo changed since the la t has st alpha release! We are currently upd ating the manuals an tutorials for the 1.0 b d eta release though.
  • 6. Hello World! Package.php <?php namespace F3Demo; use F3FLOW3PackagePackage as BasePackage; class Package extends BasePackage { } $ ./flow3_dev flow3:package:create Demo
  • 7. Hello World! StandardController.php <?php namespace F3DemoController; use F3FLOW3MVCControllerActionController; class StandardController extends ActionController { /** * @param string $name * @return string */ public function indexAction($name) { return "Hello $name!"; } } ?>
  • 9. Tackling the Heart of Software Development /** Domain-Driven Design * Paper submmited by * a speaker * @scope prototype * @entity A methodology which ... */ class Paper { • results in rich domain models /** * @var Participant */ • provides a common language protected $author; across the project team /** * @var string */ • simplify the design of complex protected $title; applications /** * @var string */ protected $shortAbstra ct; FLOW3 is the first PHP framework /** tailored to Domain-Driven Design * @var string */ protected $abstract;
  • 11. Persistence Object Persistence in the Flow • based on Doctrine 2 • seamless integration into FLOW3 • provides all the great Doctrine 2 features • uses UUIDs • low level persistence API: • allows for own, custom persistence backends (instead of Doctrine 2) • CouchDB is supported natively
  • 12. Basic Object Persistence // Create a new customer and persist it: $customer = new Customer("Robert"); $this->customerRepository->add($customer); // Find an existing customer: $otherCustomer = $this->customerRepository->findByFirstName("Karsten"); // and delete it: $this->customerRepository->remove($otherCustomer);
  • 13. Advanced Queries PostRepository.php /** * Finds most recent posts excluding the given post * * @param F3BlogDomainModelPost $post Post to exclude from result * @param integer $limit The number of posts to return at max * @return array All posts of the $post's blog except for $post */ public function findRecentExceptThis(F3BlogDomainModelPost $post, $limit = 20) { $query = $this->createQuery(); $posts = $query->matching($query->equals('blog', $post->getBlog())) ->setOrderings(array('date' => F3FLOW3PersistenceQueryInterface::ORDER_DESCENDING)) ->setLimit($limit) ->execute() ->toArray(); unset($posts[array_search($post, $posts)]); return $posts; // this is an alternative way of doing this when extending the Doctrine 2 // specific repository and using DQL. return $this->entityManager ->createQuery('SELECT p FROM F3BlogDomainModelPost p WHERE p.blog = :blog' . 'AND NOT p = :excludedPost ORDER BY p.date DESC') ->setMaxResults($limit) ->execute(array('blog' => $post->getBlog(), 'excludedPost' => $post)); }
  • 14. Purely Doctrine 2 <?php namespace MyExample; /** * @Entity(repositoryClass="BugRepository") */ class Bug { /** * @var integer * @Id * @Column(type="integer") * @GeneratedValue */ public $id; /** * @var string * @Column(type="string") */ public $description; /** * @var DateTime
  • 15. Doctrine 2 in FLOW3 <?php namespace MyExample; /** * @Entity(repositoryClass="BugRepository") */ class Bug { /** * @var integer * @Id * @Column(type="integer") * @GeneratedValue */ public $id; /** * @var string * @Column(type="string") */ public $description; /** * @var DateTime
  • 16. Purely Doctrine 2 /** * @var DateTime * @Column(type="datetime") */ public $created; /** * @var User * @ManyToOne(targetEntity="User", inversedBy="assignedBugs") */ private $engineer; /** * @var DoctrineCommonCollectionsArrayCollection<Product> * @ManyToMany(targetEntity="Product") */ private $products; } ?>
  • 17. Doctrine 2 in FLOW3 /** * @var DateTime * @Column(type="datetime") */ public $created; /** * @var User * @ManyToOne(targetEntity="User", inversedBy="assignedBugs") */ private $engineer; /** * @var DoctrineCommonCollectionsArrayCollection<Product> * @ManyToMany(targetEntity="Product") */ private $products; } ?>
  • 18. Object Management Dependency Injection • a class doesn't create or retrieve the instance of another class but get's it injected • fosters loosely-coupling and high cohesion ‣ more stable, reusable code
  • 19. Object Management FLOW3's take on Dependency Injection • one of the first PHP implementations (started in 2006, improved ever since) • object management for the whole lifecycle of all objects • no unnecessary configuration if information can be gatered automatically (autowiring) • intuitive use and no bad magical surprises • fast! (like hardcoded or faster)
  • 20. War Constructor Injection: Symfony 2 nin g (I'm :m igh no t co Sym f nta ony exp in erro <?php ert .. .) rs namespace AcmeDemoBundleController; use SymfonyBundleFrameworkBundleControllerController; use SymfonyComponentHttpFoundationRedirectResponse; use SensioBundleFrameworkExtraBundleConfigurationRoute; use SensioBundleFrameworkExtraBundleConfigurationTemplate; use AcmeDemoBundleGreeterService; class DemoController extends Controller { /** * @var AcmeDemoBundleGreeterService */ protected $greeterService; /** * @param AcmeDemoBundleGreeterService */ public function __construct($greeterService = NULL) { $this->greeterService = $greeterService; } /** * @Route("/hello/{name}", name="_demo_hello") */ public function helloAction($name) { return new Response('Hello ' . $name, 200, array('Content-Type' => 'text/plain')); } }
  • 21. War Constructor Injection: Symfony 2 nin g (I'm :m igh no t co Sym f nta ony exp in erro ert .. .) rs <?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/ services-1.0.xsd"> <services> <service id="acme.demo.greeterservice" class="AcmeDemoBundleGreeterService" public="false" /> <service id="acme.demo.democontroller" class="AcmeDemoBundleControllerDemoController"> <argument type="service" id="acme.demo.greeterservice" /> </service> </services> </container>
  • 22. Constructor Injection <?php namespace F3DemoController; use F3FLOW3MVCControllerActionController; use F3DemoServiceGreeterService; class DemoController extends ActionController { /** * @var F3DemoServiceGreeterService */ protected $greeterService; /** * @param F3DemoServiceGreeterService */ public function __construct(F3DemoServiceGreeterService $greeterService) { $this->greeterService = $greeterService; } /** * @param string $name */ public function helloAction($name) { return 'Hello ' . $name; } }
  • 24. Setter Injection <?php namespace F3DemoController; use F3FLOW3MVCControllerActionController; use F3DemoServiceGreeterService; class DemoController extends ActionController { /** * @var F3DemoServiceGreeterService */ protected $greeterService; /** * @param F3DemoServiceGreeterService */ public function injectGreeterService(F3DemoServiceGreeterService $greeterService) { $this->greeterService = $greeterService; } /** * @param string $name */ public function helloAction($name) { return 'Hello ' . $name; } }
  • 25. Property Injection <?php namespace F3DemoController; use F3FLOW3MVCControllerActionController; use F3DemoServiceGreeterService; class DemoController extends ActionController { /** * @var F3DemoServiceGreeterService * @inject */ protected $greeterService; /** * @param string $name */ public function helloAction($name) { return 'Hello ' . $name; } }
  • 26. Objects.yaml F3FLOW3SecurityCryptographyRsaWalletServiceInterface: className: F3FLOW3SecurityCryptographyRsaWalletServicePhp scope: singleton properties: keystoreCache: object: factoryObjectName: F3FLOW3CacheCacheManager factoryMethodName: getCache arguments: 1: value: FLOW3_Security_Cryptography_RSAWallet
  • 27. Object Management FLOW3's take on Dependency Injection • one of the first PHP implementations (started in 2006, improved ever since) • object management for the whole lifecycle of all objects • no unnecessary configuration if information can be gatered automatically (autowiring) • intuitive use and no bad magical surprises • fast! (like hardcoded or faster)
  • 28. Object Management class Customer { /** * @inject * @var CustomerNumberGenerator */ protected $customerNumberGenerator; ... } $customer = new Customer();
  • 29. Object Management <?php declare(ENCODING = 'u tf-8'); namespace F3Confere nceDomain ModelConference; /** FLOW3 creates proxy classes * Autogenerated Prox y Class for realizing DI and AOP magic * @scope prototype * @entity */ class Paper extends • new operator is supported F3FLOW3Persistenc Paper_Original implem eAspectPersistence ents F3FLOW3Object MagicInterface { Pr /** • proxy classes are created * @var string * @Id on the fly * @Column(length="40 ") * introduced by F3F LOW3PersistenceAsp */ ectPersistenceMagic • in production context all protected $FLOW3_Per sistence_Identifier = NULL; code is static private $FLOW3_AOP_P roxy_targetMethodsAn dGroupedAdvices = ar ra private $FLOW3_AOP_P roxy_groupedAdviceCh ains = array(); private $FLOW3_AOP_P roxy_methodIsInAdvic eMode = array(); /** * Autogenerated Prox y Method */ public function __co nstruct() {
  • 30. AOP Aspect-Oriented Programming • programming paradigm • separates concerns to improve modularization • OOP modularizes concerns into objects • AOP modularizes cross-cutting concerns into aspects • FLOW3 makes it easy (and possible at all) to use AOP in PHP
  • 31. AOP /** * @aspect FLOW3 uses AOP for ... * @introduce */ F3FLOW3Pers istenceAspec tPersistence class Persist MagicInterfac enceMagicAspe e, F3FLO ct { • persistence magic /** * @pointcut c lassTaggedWit */ h(entity) || classTaggedWi th(valueobjec • logging public functi on isEntityOr ValueObject() {} t) /** * @var string • debugging * @Id * @Column(len gth="40") * @introduce F3FLOW3Pers */ istenceAspec tPersistence • security protected $FL OW3_Persisten ce_Identifier ; MagicAspect-> isEnti /** * After retur ning advice, * making sure w e have an UUI * @param F3 D for each an FLOW3AOPJoi d every * @return voi nPointInterfa d ce $joinPoint * @before cla The current j ssTaggedWith( oin po */ entity) && me thod(.*->__co public functi nstruct()) on generateUU $proxy = $joi ID(F3FLOW3 nPoint->getPr AOPJoinPoint oxy(); Interface $jo F3FLOW3Ref inPoint) lectionObjec } tAccess::setP roperty($prox y , 'FLOW3_Per siste
  • 32. Security Touchless Security, Flow-Style • security is handled at a central place (through AOP) • third-party code is as secure as possible by default • modeled after our experiences in the TYPO3 project and Spring Security (Java framework) • provides authentication, authorization, validation, filtering ... • can intercept arbitrary method calls • transparently filters content through query-rewriting • extensible for new authentication or authorization mechanisms
  • 34. The Zen of Templating FLOW3 comes with an elegant, flexible and secure templating engine: Fluid • templates are valid HTML • templates contain no PHP • object access, control structures, loops ... • designer-friendly • extensible (view helpers, widgets)
  • 35. The Zen of Templating ... <body> <h1>Latest Blog Posts</h1> <f:if condition="{posts}"> <f:then> <ol> <f:for each="{posts}" as="post"> <li class="post"> <h2> <f:link.action action="show" controller="Post" arguments="{post: post}">{post.title} <f:security.ifHasRole role="Editor"> <f:link.action action="edit" arguments="{post: post}" controller="Post"><img src <f:link.action onclick="return confirm('Really delete this post?');" action="del </f:security.ifHasRole> </h2> <f:render partial="PostMetaData" arguments="{post: post}"/> <f:link.action action='show' arguments='{post: post}'>Read more</f:link.action></p> </li> </f:for> </ol> </f:then> <f:else> <p>This blog currently doesn't contain any posts. <f:link.action action="new" controller="Post">Create the first post</f:link.action> </p> </f:else> </f:if> </f:section>
  • 36. Forms <?php namespace F3BlogDomainModel; /** * A blog post * * @scope prototype * @entity */ class Post { /** * @var string * @validate StringLength(minimum = 1, maximum = 100) */ protected $title; /** * @var string * @validate StringLength(minimum = 1, maximum = 50) */ protected $author;
  • 37. Forms <h2>Create a new post</h2> <f:form action="create" object="{newPost}" name="newPost" enctype="multipart/form-data"> <label for="title">Title</label><br /> <f:form.textbox property="title" id="title" /><br /> <label for="content">Content</label><br /> <f:form.textarea property="content" rows="5" cols="40" id="content" /><br /> <label for="image">Image resource</label><br /> <f:form.textbox property="image.title" value="My image title" /> <f:form.upload property="image.originalResource" /> </f:form>
  • 38. Forms <?php namespace F3BlogController; use F3FLOW3MVCControllerActionController; class PostController extends ActionController { /** * @inject * @var F3BlogDomainRepositoryPostRepository */ protected $postRepository; /** * Creates a new post * * @param F3BlogDomainModelPost $newPostadded to the repository * @return void */ public function createAction(F3BlogDomainModelPost $newPost) { $this->blog->addPost($newPost); $this->flashMessageContainer->add('Your new post was created.'); $this->redirect('index'); }
  • 39. Speed and Performance For the snappy user experience: • multi-layered, tagged caches • various cache backends (file, Memcached, APC, Redis, PDO, ...) • reverse-proxy support (Varnish, ESI) in the works • code compilation • regular benchmarks • focus on good scalibility
  • 40. More Features Command Line Support (including interactive shell!)
  • 41. More Features • Resource Management (CDNs, private resources, ...) • Logging • Caching • Signal Slot event handling • File Monitoring • Configuration Management • Routing • REST / SOAP • ...
  • 44. Thank You! • These slides: http://slideshare.net/robertlemke • Download FLOW3: http://flow3.typo3.org • Follow me on Twitter: @t3rob • Give me feedback: • robert@typo3.org • http://joind.in/3492