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

Getting into
FLOW3
Robert Lemke

project founder of FLOW3 and TYPO3 “Phoenix”

co-founder of the TYPO3 Association

coach, coder, consultant

36 years old

lives in Lübeck, Germany

1 wife, 2 daughters, 1 espresso machine

likes drumming
Starters
Installation

Kickstart & Hello World!

Controller, Actions, Arguments & HTTP

Domain-Driven Design

Doctrine

Forms, Validation
Main Dishes

Resources, Image Upload

Session Handling

User, Account, Authentication

Authorization
Deserts
 Caching       Testing

 Logging       Deployment

 Signal-Slot   I18n

 Routing       Espresso
?
At a Glance

FLOW3 is a web application platform
 • holistic concept for your apps

 • modular, extensible, package based

 • pedantically clean with focus on quality

 • puts a smile on developer’s faces


 • free & Open Source (LGPL v3)

 • backed by one of the largest Open Source projects
Foundation for the Next Generation CMS


TYPO3 “Phoenix” is the all-new
Enterprise CMS
 • content repository, workspaces,
   versions, i18n, modular UI ...

 • powered by FLOW3

 • compatible code base

 • use TYPO3 features in FLOW3
   standalone apps as you like
FLOW3 Website and Download

#
Git Clone




$ git clone --recursive git://git.typo3.org/FLOW3/Distributions/Base.git .
Cloning into ....
remote: Counting objects: 3837, done.
remote: Compressing objects: 100% (2023/2023), done.
remote: Total 3837 (delta 2007), reused 2721 (delta 1465)
Receiving objects: 100% (3837/3837), 3.49 MiB | 28 KiB/s, done.
Resolving deltas: 100% (2007/2007), done.
Set File Permissions

  $ sudo ./flow3 core:setfilepermissions robert _www _www
  FLOW3 File Permission Script

  Checking permissions from here upwards.
  Making sure Data and Web/_Resources exist.
  Setting file permissions, trying to set ACLs via chmod ...
  Done.



Linux:


  $ sudo usermod -a -G www-data robert


Mac OS X:

  $ sudo dscl . -append /Groups/_www GroupMembership robert
Set Up Database Connection
Configuration/Settings.yaml



 #                                                       #
 # Global Settings                                       #
 #                                                       #

 TYPO3:
   FLOW3:
     persistence:
        backendOptions:
          dbname: 'demo'
          user: 'demo'
          password: 'password'
          host: '127.0.0.1'

      # only on Windows:
      core:
        phpBinaryPathAndFilename: 'C:/path/to/php.exe'
Set Up Virtual Host

Apache Virtual Host



  <VirtualHost *:80>
       DocumentRoot /opt/local/apache2/htdocs/Talks/FLOW3/Web/
       ServerName dev.flow3.rob
       SetEnv FLOW3_CONTEXT Development
  </VirtualHost>

  <VirtualHost *:80>
       DocumentRoot /opt/local/apache2/htdocs/Talks/FLOW3/Web/
       ServerName flow3.rob
       SetEnv FLOW3_CONTEXT Production
  </VirtualHost>
Final Check
C lo ne t h e Be a s t

 5         1                1   1
        Ro bert Lem ke
         D.P. F l u x t r
        time ();
Biggest Book Store: Amazon
Biggest River: Amazon River




                              © Google
Smallest River: Roe River




                            © Google
Smallest River: Roe River




                            © Google
Smallest River: Roe River




                            © Google
Smallest River: Roe River
Smallest Book Store: Roe Books
Sketchy Model
Jus t C o de a Sh o p

 5        2                1   1
       Ro bert Lem ke
        D.P. F l u x t r
       time ();
Tackling the Heart of Software Development

                                         /**
Domain-Driven Design                      * A Book
                                          *
                                          * @FLOW3Scope(“protot
                                                                 ype”)
                                          * @FLOW3Entity
A methodology which ...                   */
                                        class Book {

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

   across the project team          	       /**
                                    	        * @var string
                                    	        */
 • simplify the design of complex   	       protected $isbn;
   applications                     	       /**
                                    	        * @var string
                                    	        */
                                    	       protected $description
                                                                   ;
FLOW3 is the first PHP framework
                                    	       /**
tailored to Domain-Driven Design    	        * @var integer
                                    	        */
                                    	       protected $price;
Domain-Driven Design

Domain
 activity or business of the user

Domain-Driven Design
 is about

 • focussing on the domain and domain logic

 • accurately mapping the concepts to software

 • forming a ubiquitous language among the
   project members
Domain-Driven Design

Ubiquitous Language
 • important prerequisite for successful
   collaboration

 • use the same words for

   • discussion

   • modeling

   • development

   • documentation
Domain-Driven Design

Building Blocks
 • Entity: An object that is not defined by its attributes, but rather by a
   thread of continuity and its identity.

 • Value Object: An object that contains attributes but has no
   conceptual identity. They should be treated as immutable.

 • Aggregate: A collection of objects that are bound together by a root
   entity, otherwise known as an aggregate root. The aggregate root
   guarantees the consistency of changes being made within the
   aggregate by forbidding external objects from holding references to
   its members.
Domain-Driven Design

Building Blocks
 • Service: When an operation does not conceptually belong to any
   object. Following the natural contours of the problem, you can
   implement these operations in services.

 • Repository: methods for retrieving domain objects should delegate
   to a specialized Repository object such that alternative storage
   implementations may be easily interchanged.
Domain-Driven Design
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)
Constructor Injection

namespace AcmeDemoController;

use TYPO3FLOW3MvcControllerActionController;
use AcmeDemoServiceGreeterService;

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

	   /**
	     * @param AcmeDemoServiceGreeterService
	     */
	   public function __construct(GreeterService $greeterService) {
	   	    $this->greeterService = $greeterService;
	   }
	
    /**
      * @param string $name
      */
    public function helloAction($name) {
    	
    	     return $this->greeterService->greet($name);
    }
}
Setter Injection

namespace AcmeDemoController;

use TYPO3FLOW3MVCControllerActionController;
use AcmeDemoServiceGreeterService;

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

	   /**
	     * @param AcmeDemoServiceGreeterService
	     */
	   public function injectGreeterService(GreeterService $greeterService) {
	   	    $this->greeterService = $greeterService;
	   }
	
    /**
     * @param string $name
     */
    public function helloAction($name) {
    	
    	   return $this->greeterService->greet($name);
    }
}
Property Injection

namespace TYPO3DemoController;

use TYPO3FLOW3Annotations as FLOW3;
use TYPO3FLOW3MVCControllerActionController;
use AcmeDemoServiceGreeterService;

class DemoController extends ActionController {
	
	   /**
	     * @var TYPO3DemoServiceGreeterService
	     * @FLOW3Inject
	     */
	   protected $greeterService;
	
    /**
      * @param string $name
      */
    public function helloAction($name) {
    	
    	     return $this->greeterService->greet($name);
    }
}
Objects.yaml


   TYPO3FLOW3SecurityCryptographyRsaWalletServiceInterface:
     className: TYPO3FLOW3SecurityCryptographyRsaWalletServicePhp
     scope: singleton
     properties:
       keystoreCache:
         object:
           factoryObjectName: TYPO3FLOW3CacheCacheManager
           factoryMethodName: getCache
           arguments:
             1:
                value: FLOW3_Security_Cryptography_RSAWallet
Object Management


class Customer {

	   /**
	    * @FLOW3Inject
	    * @var AcmeCustomerNumberGenerator
	    */
	   protected $customerNumberGenerator;
    ...
}

$customer = new Customer();
$customer->getCustomerNumber();
Object Management
                                     <?php
                                     declare(ENCODING = 'u
                                                           tf-8');
                                     namespace TYPO3Conf
                                                          erenceDomainModel
                                     use TYPO3FLOW3Anno                      Conference;
                                                          tations as FLOW3;

FLOW3 creates proxy classes         /**
                                     * Autogenerated Prox
                                                           y Class
for realizing DI and AOP magic       * @FLOW3Scope(“prot
                                                           otype”)
                                     * @FLOW3Entity
                                     */

 • new operator is supported       class Paper extends
                                   TYPO3FLOW3Persist
                                                         Paper_Original implem
                                                                                ents TYPO3FLOW3Obj
                                                                                                      ect
                                                         enceAspectPersiste
                                                                               nceMagicInterface {
                                   	     /**
 • proxy classes are created       	      * @var string
                                  	
   on the fly                      	
                                          * @ORMId
                                          * @ORMColumn(length
                                                               ="40")
                                  	       * introduced by TYPO
                                                               3FLOW3Persistence
                                  	       */                                        AspectPersistenceMa
 • 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()
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);
Validation and Doctrine Annotations

namespace TYPO3BlogDomainModel;

/**
 * A Blog object
 *
 * @Entity
 */
class Blog {

    /**
     * @var string
     * @validate Text, StringLength(minimum = 1, maximum = 80)
     * @Column(length="80")
     */
    protected $title;

    /**
     * @var DoctrineCommonCollectionsCollection<TYPO3BlogDomainModelPost>
     * @OneToMany(mappedBy="blog")
     * @OrderBy({"date" = "DESC"})
     */
    protected $posts;

    ...

}
Persistence-related Annotations


@Entity        Declares a class as "entity"

@Column        Controls the database column related to the class
               property. Very useful for longer text content
               (type="text" !)

@ManyToOne     Defines relations to other entities. Unlike with
@OneToMany     vanilla Doctrine targetEntity does not have to be
@ManyToMany    given but will be reused from the @var
@OneToOne      annotation.

               cascade can be used to cascade operation to
               related objects.
Persistence-related Annotations




@var           Defines the type of a property, collections can be
               typed using angle brackets:
               DoctrineCommonCollectionsCollection<TYPO3ConferenceDomainModelComment>


@transient     The property will be ignored, it will neither be
               persisted nor reconstituted

@identity      Marks the property as part of an objects identity
Custom Queries using the Query Object Model
/**
 * A PostRepository
 */
class PostRepository extends TYPO3FLOW3PersistenceRepository {

    /**
      * Finds posts by the specified tag and blog
      *
      * @param TYPO3BlogDomainModelTag $tag
      * @param TYPO3BlogDomainModelBlog $blog The blog the post must refer to
      * @return TYPO3FLOW3PersistenceQueryResultInterface The posts
      */
    public function findByTagAndBlog(TYPO3BlogDomainModelTag $tag,
        TYPO3BlogDomainModelBlog $blog) {
          $query = $this->createQuery();
          return $query->matching(
              $query->logicalAnd(
                  $query->equals('blog', $blog),
                  $query->contains('tags', $tag)
              )
          )
          ->setOrderings(array(
              'date' => TYPO3FLOW3PersistenceQueryInterface::ORDER_DESCENDING)
          )
          ->execute();
    }
}
Schema Management

Running Migrations
• needed after installation or upgrade:


$ ./flow3 doctrine:migrate
Schema Management

Manual database updates
• for simple situations this can be good enough:


$ ./flow3 doctrine:create

$ ./flow3 doctrine:update




• useful when

 • you are just starting a project and have never released
Schema Management

Generating migrations

$ ./flow3 doctrine:migrationgenerate
Generated new migration class to "…/Version20110608074324.php"
from schema differences.
$




• Generated migrations can contain errors and should be checked
  and adjusted as needed

• Migrations need to be moved to their “owning” package manually
Validation

Validation in FLOW3

• you do not want to code checks into your controllers

• FLOW3 separates validation from your controller’s concerns

 • no PHP code needed for validation

 • declared through annotations
Validation

Validation Models

• BaseProperties
  rules defining the minimum requirements on individual properties of a
  model

• BaseModel
  rules or custom validators enforcing the minimum requirements on the
  combination of properties of a model

• Supplemental
  rules defining additional requirements on a model for a specific
  situation (e.g. a certain action method)
Validation

Base Properties

• Validation rules defined directly at the properties


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

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

Validators

• validators provided by FLOW3 can be used through their short name

 • Count, Float, NotEmpty, RegularExpression, Uuid, DateTime,
   NumberRange, StringLength, Alphanumeric, Integer, Number, String,
   EmailAddress, Label, Raw, Text

• custom validators need to implement the ValidatorInterface

• use them by specifying the fully qualified class name
 	   /**
 	    * @var DambekalnsStuffDomainModelStuff
 	    * @validate DambekalnsStuffDomainValidatorStuffValidator
 	    */
 	   protected $stuff;
Property Mapper




	   $articleArray = array(
	   	 'headline' => 'Hello World!',
	   	 'story' => 'Just a demo ...'
	   );

	   $article = $mapper->convert($sourceArray, 'Acme.DemoDomainModelArticle');
Resource Management

 Image Upload
 Resources are handled like other properties in a form:



	 <f:form method="blog" action="update" object="{blog}" name="blog"
enctype="multipart/form-data">
	 	 <f:if condition="{blog.authorPicture}">
	 	 	 <img src="{f:uri.resource(resource: blog.authorPicture)}" />
	 	 </f:if>
	 	 <label for="authorPicture">Author picture</label>
	 	 <f:form.upload property="authorPicture" id="authorPicture" />
	 	 <f:form.submit value="Update"/>
	 </f:form>
Property Mapper

    Allow nested object structures
    For security reasons the creation of nested structure through the
    property mapper is disabled by default

	   /**
	     * @return void
	     */
	   public function initializeUpdateAction() {
	   	 $this->arguments['article']->getPropertyMappingConfiguration()
            ->allowCreationForSubProperty('picture');
	   	 $this->arguments['article']->getPropertyMappingConfiguration()
            ->allowModificationForSubProperty('picture');
	   }
Fluid


Example for assigning a string to a Fluid variable:

	   	 // in the action controller:
	   $this->view->assign('title', 'Welcome to Fluid');




	   <!-- in the Fluid template: -->
	   <head>
	   	 <title>{title}</title>
	   </head>
Fluid


Variables can also be objects:

	   	 // in the action controller:
	   $this->view->assign('conference', $conference);




	   <!-- in the Fluid template: -->
	   <div class="venue">
	   	 <p>Venue Street: {conference.venue.street}</p>
	   </div>
Fluid


if-then-else:

	   	 // in the action controller:
	   $this->view->assign('post', $blogPost);




	   <!-- in the Fluid template: -->
	   <f:if condition="{post.comments}">
	   	 <f:then>There are some comments.</f:then>
	   	 <f:else>There are no comments.</f:else>		
	   </f:if>
Fluid


for-each:

	   	 // in the action controller:
	   $this->view->assign('ages', array("Karsten" => 34, "Robert" => 35));




	   <!-- in the Fluid template: -->
	   <ul>
	   	 <f:for each="{ages}" as="age" key="name">
	   	 	 <li>{name} is {age} year old.</li>
	   	 </f:for>
	   </ul>
Fluid


for-each:

	   	 // in the action controller:
	   $this->view->assign('post', $blogPost);




	   <!-- in the Fluid template: -->
	   <f:if condition="{post.comments}">
	   	 <ul>
	   	 	 <f:for each="{post.comments}" as="comment" >
	   	 	 	 <li>{post.title}</li>
	   	 	 </f:for>
	   	 </ul>	 	 	
	   </f:if>
Fluid


View helpers – in this case the link.action view helper:


	   <!-- in the Fluid template: -->
	   {namespace f=TYPO3FluidViewHelpers}

	   <f:link.action action="delete" arguments="{post: post, really: 'yes'}">
	   	 Delete this post
	   </f:link.action>
Security Policy
Security

Cross-Site Request Forgery
 • enables an attacker to execute privileged operations without being
   authenticated

 • the risk lies in using malicious links or forms while still being
   authenticated

 • imagine a link coming in through an URL shortener...
Security

Avoiding Cross-Site Request Forgery
 • add a (truly!) random string token to each link or form

 • make sure this token is correct before executing anything



 • change the token as often as possible to make it impossible to send
   you a working malicious link while you’re logged in

 • in most cases, we can assume that it should be enough to generate
   one token when you log in – that’s the default
Security

CSRF Protection in FLOW3
 • you must not forget to add that token to any link

 • FLOW3 automatically adds the CSRF token to each

   • link you generate

   • each form you create with Fluid

 • and checks it for every call to a protected action



 • the protection can be disabled using
   @skipCsrfProtection on an action
Roadmap

http://forge.typo3.org/projects/flow3-distribution-base/roadmap
Conference App

git://git.typo3.org/TYPO3v5/Distributions/Conference.git
Blog App

git://git.typo3.org/FLOW3/Applications/Blog.git
Rossmann
• second biggest drug store
  in Germany
• 5,13 billion € turnover
• 31,000 employees
Customer Database
• custom persistence with CouchDB
• SOAP support
• continuous delivery
• cluster setup
                                    by networkteam, Kiel
Amadeus
• world’s biggest
  e-ticket provider
• 217 markets
• 948 million billable
  transactions / year
• 2,7 billion € revenue
Social Media Suite
• central hub for social media activities
  for potentially thousands of travel
  agencies
• advanced form engine
• various detail improvements         by AKOM360, Munich
• uses an early version of
  TYPO3 Phoenix
“Our senior developers are
extremely happy with FLOW3 –

it is definitely the most
capable PHP framework we       Fabian Pfütze
                                 Project Lead
have come across
so far.”
?
Thanks for having me!

Slides:     http://slideshare.net/robertlemke

Examples:   http://github.com/robertlemke

Blog:       http://robertlemke.com

Twitter:    @robertlemke

Feedback:   robert@typo3.org

FLOW3:      http://flow3.typo3.org

More Related Content

What's hot

PHP traits, treat or threat?
PHP traits, treat or threat?PHP traits, treat or threat?
PHP traits, treat or threat?
Nick Belhomme
 

What's hot (20)

Debugging on rails
Debugging on railsDebugging on rails
Debugging on rails
 
Spl in the wild
Spl in the wildSpl in the wild
Spl in the wild
 
170517 damien gérard framework facebook
170517 damien gérard   framework facebook170517 damien gérard   framework facebook
170517 damien gérard framework facebook
 
Streams, sockets and filters oh my!
Streams, sockets and filters oh my!Streams, sockets and filters oh my!
Streams, sockets and filters oh my!
 
PECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterPECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life better
 
Mastering Namespaces in PHP
Mastering Namespaces in PHPMastering Namespaces in PHP
Mastering Namespaces in PHP
 
嵌入式Linux課程-GNU Toolchain
嵌入式Linux課程-GNU Toolchain嵌入式Linux課程-GNU Toolchain
嵌入式Linux課程-GNU Toolchain
 
PHP traits, treat or threat?
PHP traits, treat or threat?PHP traits, treat or threat?
PHP traits, treat or threat?
 
Rails vs Web2py
Rails vs Web2pyRails vs Web2py
Rails vs Web2py
 
Php on the Web and Desktop
Php on the Web and DesktopPhp on the Web and Desktop
Php on the Web and Desktop
 
Perl Programming - 01 Basic Perl
Perl Programming - 01 Basic PerlPerl Programming - 01 Basic Perl
Perl Programming - 01 Basic Perl
 
Unit 1-introduction to perl
Unit 1-introduction to perlUnit 1-introduction to perl
Unit 1-introduction to perl
 
HHVM and Hack: A quick introduction
HHVM and Hack: A quick introductionHHVM and Hack: A quick introduction
HHVM and Hack: A quick introduction
 
Beautiful Bash: Let's make reading and writing bash scripts fun again!
Beautiful Bash: Let's make reading and writing bash scripts fun again!Beautiful Bash: Let's make reading and writing bash scripts fun again!
Beautiful Bash: Let's make reading and writing bash scripts fun again!
 
Perl Basics with Examples
Perl Basics with ExamplesPerl Basics with Examples
Perl Basics with Examples
 
Cross platform php
Cross platform phpCross platform php
Cross platform php
 
WEB PROGRAMMING UNIT VI BY BHAVSINGH MALOTH
WEB PROGRAMMING UNIT VI BY BHAVSINGH MALOTHWEB PROGRAMMING UNIT VI BY BHAVSINGH MALOTH
WEB PROGRAMMING UNIT VI BY BHAVSINGH MALOTH
 
You suck at Memory Analysis
You suck at Memory AnalysisYou suck at Memory Analysis
You suck at Memory Analysis
 
HipHop Virtual Machine
HipHop Virtual MachineHipHop Virtual Machine
HipHop Virtual Machine
 
Introduction to Perl
Introduction to PerlIntroduction to Perl
Introduction to Perl
 

Similar to Getting Into FLOW3 (DPC12)

Before & After Docker Init
Before & After Docker InitBefore & After Docker Init
Before & After Docker Init
Angel Borroy López
 

Similar to Getting Into FLOW3 (DPC12) (20)

Getting Into FLOW3 (TYPO312CA)
Getting Into FLOW3 (TYPO312CA)Getting Into FLOW3 (TYPO312CA)
Getting Into FLOW3 (TYPO312CA)
 
Fluent Development with FLOW3 1.0
Fluent Development with FLOW3 1.0Fluent Development with FLOW3 1.0
Fluent Development with FLOW3 1.0
 
FLOW3 Tutorial - T3CON11 Frankfurt
FLOW3 Tutorial - T3CON11 FrankfurtFLOW3 Tutorial - T3CON11 Frankfurt
FLOW3 Tutorial - T3CON11 Frankfurt
 
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)
 
TYPO3 Flow 2.0 Workshop T3BOARD13
TYPO3 Flow 2.0 Workshop T3BOARD13TYPO3 Flow 2.0 Workshop T3BOARD13
TYPO3 Flow 2.0 Workshop T3BOARD13
 
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
 
The Beauty and the Beast
The Beauty and the BeastThe Beauty and the Beast
The Beauty and the Beast
 
Inside DocBlox
Inside DocBloxInside DocBlox
Inside DocBlox
 
The beautyandthebeast phpbat2010
The beautyandthebeast phpbat2010The beautyandthebeast phpbat2010
The beautyandthebeast phpbat2010
 
Going to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific LanguagesGoing to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific Languages
 
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
 
Building maintainable javascript applications
Building maintainable javascript applicationsBuilding maintainable javascript applications
Building maintainable javascript applications
 
Phonegap 2.x
Phonegap 2.xPhonegap 2.x
Phonegap 2.x
 
Ant vs Phing
Ant vs PhingAnt vs Phing
Ant vs Phing
 
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)
 
Before & After Docker Init
Before & After Docker InitBefore & After Docker Init
Before & After Docker Init
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy Code
 
Ext 0523
Ext 0523Ext 0523
Ext 0523
 
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry PiGrâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
 

More from Robert Lemke

More from Robert Lemke (20)

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

Recently uploaded

Recently uploaded (20)

Salesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
Salesforce Adoption – Metrics, Methods, and Motivation, Antone KomSalesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
Salesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
 
Demystifying gRPC in .Net by John Staveley
Demystifying gRPC in .Net by John StaveleyDemystifying gRPC in .Net by John Staveley
Demystifying gRPC in .Net by John Staveley
 
Speed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in MinutesSpeed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in Minutes
 
ECS 2024 Teams Premium - Pretty Secure
ECS 2024   Teams Premium - Pretty SecureECS 2024   Teams Premium - Pretty Secure
ECS 2024 Teams Premium - Pretty Secure
 
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
 
IESVE for Early Stage Design and Planning
IESVE for Early Stage Design and PlanningIESVE for Early Stage Design and Planning
IESVE for Early Stage Design and Planning
 
THE BEST IPTV in GERMANY for 2024: IPTVreel
THE BEST IPTV in  GERMANY for 2024: IPTVreelTHE BEST IPTV in  GERMANY for 2024: IPTVreel
THE BEST IPTV in GERMANY for 2024: IPTVreel
 
IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024
 
Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024
 
WSO2CONMay2024OpenSourceConferenceDebrief.pptx
WSO2CONMay2024OpenSourceConferenceDebrief.pptxWSO2CONMay2024OpenSourceConferenceDebrief.pptx
WSO2CONMay2024OpenSourceConferenceDebrief.pptx
 
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
 
Top 10 Symfony Development Companies 2024
Top 10 Symfony Development Companies 2024Top 10 Symfony Development Companies 2024
Top 10 Symfony Development Companies 2024
 
10 Differences between Sales Cloud and CPQ, Blanka Doktorová
10 Differences between Sales Cloud and CPQ, Blanka Doktorová10 Differences between Sales Cloud and CPQ, Blanka Doktorová
10 Differences between Sales Cloud and CPQ, Blanka Doktorová
 
Intro in Product Management - Коротко про професію продакт менеджера
Intro in Product Management - Коротко про професію продакт менеджераIntro in Product Management - Коротко про професію продакт менеджера
Intro in Product Management - Коротко про професію продакт менеджера
 
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi IbrahimzadeFree and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
 
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya HalderCustom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
 
AI presentation and introduction - Retrieval Augmented Generation RAG 101
AI presentation and introduction - Retrieval Augmented Generation RAG 101AI presentation and introduction - Retrieval Augmented Generation RAG 101
AI presentation and introduction - Retrieval Augmented Generation RAG 101
 
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
 
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdfHow Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
 
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdfIntroduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
 

Getting Into FLOW3 (DPC12)

  • 2. Robert Lemke project founder of FLOW3 and TYPO3 “Phoenix” co-founder of the TYPO3 Association coach, coder, consultant 36 years old lives in Lübeck, Germany 1 wife, 2 daughters, 1 espresso machine likes drumming
  • 3. Starters Installation Kickstart & Hello World! Controller, Actions, Arguments & HTTP Domain-Driven Design Doctrine Forms, Validation
  • 4. Main Dishes Resources, Image Upload Session Handling User, Account, Authentication Authorization
  • 5. Deserts Caching Testing Logging Deployment Signal-Slot I18n Routing Espresso
  • 6. ?
  • 7.
  • 8. At a Glance FLOW3 is a web application platform • holistic concept for your apps • modular, extensible, package based • pedantically clean with focus on quality • puts a smile on developer’s faces • free & Open Source (LGPL v3) • backed by one of the largest Open Source projects
  • 9. Foundation for the Next Generation CMS TYPO3 “Phoenix” is the all-new Enterprise CMS • content repository, workspaces, versions, i18n, modular UI ... • powered by FLOW3 • compatible code base • use TYPO3 features in FLOW3 standalone apps as you like
  • 10. FLOW3 Website and Download #
  • 11. Git Clone $ git clone --recursive git://git.typo3.org/FLOW3/Distributions/Base.git . Cloning into .... remote: Counting objects: 3837, done. remote: Compressing objects: 100% (2023/2023), done. remote: Total 3837 (delta 2007), reused 2721 (delta 1465) Receiving objects: 100% (3837/3837), 3.49 MiB | 28 KiB/s, done. Resolving deltas: 100% (2007/2007), done.
  • 12. Set File Permissions $ sudo ./flow3 core:setfilepermissions robert _www _www FLOW3 File Permission Script Checking permissions from here upwards. Making sure Data and Web/_Resources exist. Setting file permissions, trying to set ACLs via chmod ... Done. Linux: $ sudo usermod -a -G www-data robert Mac OS X: $ sudo dscl . -append /Groups/_www GroupMembership robert
  • 13. Set Up Database Connection Configuration/Settings.yaml # # # Global Settings # # # TYPO3: FLOW3: persistence: backendOptions: dbname: 'demo' user: 'demo' password: 'password' host: '127.0.0.1' # only on Windows: core: phpBinaryPathAndFilename: 'C:/path/to/php.exe'
  • 14. Set Up Virtual Host Apache Virtual Host <VirtualHost *:80> DocumentRoot /opt/local/apache2/htdocs/Talks/FLOW3/Web/ ServerName dev.flow3.rob SetEnv FLOW3_CONTEXT Development </VirtualHost> <VirtualHost *:80> DocumentRoot /opt/local/apache2/htdocs/Talks/FLOW3/Web/ ServerName flow3.rob SetEnv FLOW3_CONTEXT Production </VirtualHost>
  • 16. C lo ne t h e Be a s t 5 1 1 1 Ro bert Lem ke D.P. F l u x t r time ();
  • 18. Biggest River: Amazon River © Google
  • 19. Smallest River: Roe River © Google
  • 20. Smallest River: Roe River © Google
  • 21. Smallest River: Roe River © Google
  • 23. Smallest Book Store: Roe Books
  • 25. Jus t C o de a Sh o p 5 2 1 1 Ro bert Lem ke D.P. F l u x t r time ();
  • 26. Tackling the Heart of Software Development /** Domain-Driven Design * A Book * * @FLOW3Scope(“protot ype”) * @FLOW3Entity A methodology which ... */ class Book { • results in rich domain models /** * @var string */ • provides a common language protected $title; across the project team /** * @var string */ • simplify the design of complex protected $isbn; applications /** * @var string */ protected $description ; FLOW3 is the first PHP framework /** tailored to Domain-Driven Design * @var integer */ protected $price;
  • 27. Domain-Driven Design Domain activity or business of the user Domain-Driven Design is about • focussing on the domain and domain logic • accurately mapping the concepts to software • forming a ubiquitous language among the project members
  • 28. Domain-Driven Design Ubiquitous Language • important prerequisite for successful collaboration • use the same words for • discussion • modeling • development • documentation
  • 29. Domain-Driven Design Building Blocks • Entity: An object that is not defined by its attributes, but rather by a thread of continuity and its identity. • Value Object: An object that contains attributes but has no conceptual identity. They should be treated as immutable. • Aggregate: A collection of objects that are bound together by a root entity, otherwise known as an aggregate root. The aggregate root guarantees the consistency of changes being made within the aggregate by forbidding external objects from holding references to its members.
  • 30. Domain-Driven Design Building Blocks • Service: When an operation does not conceptually belong to any object. Following the natural contours of the problem, you can implement these operations in services. • Repository: methods for retrieving domain objects should delegate to a specialized Repository object such that alternative storage implementations may be easily interchanged.
  • 32. 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)
  • 33. Constructor Injection namespace AcmeDemoController; use TYPO3FLOW3MvcControllerActionController; use AcmeDemoServiceGreeterService; class DemoController extends ActionController { /** * @var AcmeDemoServiceGreeterService */ protected $greeterService; /** * @param AcmeDemoServiceGreeterService */ public function __construct(GreeterService $greeterService) { $this->greeterService = $greeterService; } /** * @param string $name */ public function helloAction($name) { return $this->greeterService->greet($name); } }
  • 34. Setter Injection namespace AcmeDemoController; use TYPO3FLOW3MVCControllerActionController; use AcmeDemoServiceGreeterService; class DemoController extends ActionController { /** * @var AcmeDemoServiceGreeterService */ protected $greeterService; /** * @param AcmeDemoServiceGreeterService */ public function injectGreeterService(GreeterService $greeterService) { $this->greeterService = $greeterService; } /** * @param string $name */ public function helloAction($name) { return $this->greeterService->greet($name); } }
  • 35. Property Injection namespace TYPO3DemoController; use TYPO3FLOW3Annotations as FLOW3; use TYPO3FLOW3MVCControllerActionController; use AcmeDemoServiceGreeterService; class DemoController extends ActionController { /** * @var TYPO3DemoServiceGreeterService * @FLOW3Inject */ protected $greeterService; /** * @param string $name */ public function helloAction($name) { return $this->greeterService->greet($name); } }
  • 36. Objects.yaml TYPO3FLOW3SecurityCryptographyRsaWalletServiceInterface: className: TYPO3FLOW3SecurityCryptographyRsaWalletServicePhp scope: singleton properties: keystoreCache: object: factoryObjectName: TYPO3FLOW3CacheCacheManager factoryMethodName: getCache arguments: 1: value: FLOW3_Security_Cryptography_RSAWallet
  • 37. Object Management class Customer { /** * @FLOW3Inject * @var AcmeCustomerNumberGenerator */ protected $customerNumberGenerator; ... } $customer = new Customer(); $customer->getCustomerNumber();
  • 38. Object Management <?php declare(ENCODING = 'u tf-8'); namespace TYPO3Conf erenceDomainModel use TYPO3FLOW3Anno Conference; tations as FLOW3; FLOW3 creates proxy classes /** * Autogenerated Prox y Class for realizing DI and AOP magic * @FLOW3Scope(“prot otype”) * @FLOW3Entity */ • new operator is supported class Paper extends TYPO3FLOW3Persist Paper_Original implem ents TYPO3FLOW3Obj ect enceAspectPersiste nceMagicInterface { /** • proxy classes are created * @var string on the fly * @ORMId * @ORMColumn(length ="40") * introduced by TYPO 3FLOW3Persistence */ AspectPersistenceMa • 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()
  • 39. 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);
  • 40. Validation and Doctrine Annotations namespace TYPO3BlogDomainModel; /** * A Blog object * * @Entity */ class Blog { /** * @var string * @validate Text, StringLength(minimum = 1, maximum = 80) * @Column(length="80") */ protected $title; /** * @var DoctrineCommonCollectionsCollection<TYPO3BlogDomainModelPost> * @OneToMany(mappedBy="blog") * @OrderBy({"date" = "DESC"}) */ protected $posts; ... }
  • 41. Persistence-related Annotations @Entity Declares a class as "entity" @Column Controls the database column related to the class property. Very useful for longer text content (type="text" !) @ManyToOne Defines relations to other entities. Unlike with @OneToMany vanilla Doctrine targetEntity does not have to be @ManyToMany given but will be reused from the @var @OneToOne annotation. cascade can be used to cascade operation to related objects.
  • 42. Persistence-related Annotations @var Defines the type of a property, collections can be typed using angle brackets: DoctrineCommonCollectionsCollection<TYPO3ConferenceDomainModelComment> @transient The property will be ignored, it will neither be persisted nor reconstituted @identity Marks the property as part of an objects identity
  • 43. Custom Queries using the Query Object Model /** * A PostRepository */ class PostRepository extends TYPO3FLOW3PersistenceRepository { /** * Finds posts by the specified tag and blog * * @param TYPO3BlogDomainModelTag $tag * @param TYPO3BlogDomainModelBlog $blog The blog the post must refer to * @return TYPO3FLOW3PersistenceQueryResultInterface The posts */ public function findByTagAndBlog(TYPO3BlogDomainModelTag $tag, TYPO3BlogDomainModelBlog $blog) { $query = $this->createQuery(); return $query->matching( $query->logicalAnd( $query->equals('blog', $blog), $query->contains('tags', $tag) ) ) ->setOrderings(array( 'date' => TYPO3FLOW3PersistenceQueryInterface::ORDER_DESCENDING) ) ->execute(); } }
  • 44. Schema Management Running Migrations • needed after installation or upgrade: $ ./flow3 doctrine:migrate
  • 45. Schema Management Manual database updates • for simple situations this can be good enough: $ ./flow3 doctrine:create $ ./flow3 doctrine:update • useful when • you are just starting a project and have never released
  • 46. Schema Management Generating migrations $ ./flow3 doctrine:migrationgenerate Generated new migration class to "…/Version20110608074324.php" from schema differences. $ • Generated migrations can contain errors and should be checked and adjusted as needed • Migrations need to be moved to their “owning” package manually
  • 47. Validation Validation in FLOW3 • you do not want to code checks into your controllers • FLOW3 separates validation from your controller’s concerns • no PHP code needed for validation • declared through annotations
  • 48. Validation Validation Models • BaseProperties rules defining the minimum requirements on individual properties of a model • BaseModel rules or custom validators enforcing the minimum requirements on the combination of properties of a model • Supplemental rules defining additional requirements on a model for a specific situation (e.g. a certain action method)
  • 49. Validation Base Properties • Validation rules defined directly at the properties /** * @var string * @validate StringLength(minimum = 10, maximum = 100) */ protected $title; /** * @var string * @validate StringLength(minimum = 1, maximum = 50) */ protected $author;
  • 50. Validation Validators • validators provided by FLOW3 can be used through their short name • Count, Float, NotEmpty, RegularExpression, Uuid, DateTime, NumberRange, StringLength, Alphanumeric, Integer, Number, String, EmailAddress, Label, Raw, Text • custom validators need to implement the ValidatorInterface • use them by specifying the fully qualified class name /** * @var DambekalnsStuffDomainModelStuff * @validate DambekalnsStuffDomainValidatorStuffValidator */ protected $stuff;
  • 51. Property Mapper $articleArray = array( 'headline' => 'Hello World!', 'story' => 'Just a demo ...' ); $article = $mapper->convert($sourceArray, 'Acme.DemoDomainModelArticle');
  • 52. Resource Management Image Upload Resources are handled like other properties in a form: <f:form method="blog" action="update" object="{blog}" name="blog" enctype="multipart/form-data"> <f:if condition="{blog.authorPicture}"> <img src="{f:uri.resource(resource: blog.authorPicture)}" /> </f:if> <label for="authorPicture">Author picture</label> <f:form.upload property="authorPicture" id="authorPicture" /> <f:form.submit value="Update"/> </f:form>
  • 53. Property Mapper Allow nested object structures For security reasons the creation of nested structure through the property mapper is disabled by default /** * @return void */ public function initializeUpdateAction() { $this->arguments['article']->getPropertyMappingConfiguration() ->allowCreationForSubProperty('picture'); $this->arguments['article']->getPropertyMappingConfiguration() ->allowModificationForSubProperty('picture'); }
  • 54. Fluid Example for assigning a string to a Fluid variable: // in the action controller: $this->view->assign('title', 'Welcome to Fluid'); <!-- in the Fluid template: --> <head> <title>{title}</title> </head>
  • 55. Fluid Variables can also be objects: // in the action controller: $this->view->assign('conference', $conference); <!-- in the Fluid template: --> <div class="venue"> <p>Venue Street: {conference.venue.street}</p> </div>
  • 56. Fluid if-then-else: // in the action controller: $this->view->assign('post', $blogPost); <!-- in the Fluid template: --> <f:if condition="{post.comments}"> <f:then>There are some comments.</f:then> <f:else>There are no comments.</f:else> </f:if>
  • 57. Fluid for-each: // in the action controller: $this->view->assign('ages', array("Karsten" => 34, "Robert" => 35)); <!-- in the Fluid template: --> <ul> <f:for each="{ages}" as="age" key="name"> <li>{name} is {age} year old.</li> </f:for> </ul>
  • 58. Fluid for-each: // in the action controller: $this->view->assign('post', $blogPost); <!-- in the Fluid template: --> <f:if condition="{post.comments}"> <ul> <f:for each="{post.comments}" as="comment" > <li>{post.title}</li> </f:for> </ul> </f:if>
  • 59. Fluid View helpers – in this case the link.action view helper: <!-- in the Fluid template: --> {namespace f=TYPO3FluidViewHelpers} <f:link.action action="delete" arguments="{post: post, really: 'yes'}"> Delete this post </f:link.action>
  • 61. Security Cross-Site Request Forgery • enables an attacker to execute privileged operations without being authenticated • the risk lies in using malicious links or forms while still being authenticated • imagine a link coming in through an URL shortener...
  • 62. Security Avoiding Cross-Site Request Forgery • add a (truly!) random string token to each link or form • make sure this token is correct before executing anything • change the token as often as possible to make it impossible to send you a working malicious link while you’re logged in • in most cases, we can assume that it should be enough to generate one token when you log in – that’s the default
  • 63. Security CSRF Protection in FLOW3 • you must not forget to add that token to any link • FLOW3 automatically adds the CSRF token to each • link you generate • each form you create with Fluid • and checks it for every call to a protected action • the protection can be disabled using @skipCsrfProtection on an action
  • 67. Rossmann • second biggest drug store in Germany • 5,13 billion € turnover • 31,000 employees
  • 68. Customer Database • custom persistence with CouchDB • SOAP support • continuous delivery • cluster setup by networkteam, Kiel
  • 69. Amadeus • world’s biggest e-ticket provider • 217 markets • 948 million billable transactions / year • 2,7 billion € revenue
  • 70. Social Media Suite • central hub for social media activities for potentially thousands of travel agencies • advanced form engine • various detail improvements by AKOM360, Munich • uses an early version of TYPO3 Phoenix
  • 71. “Our senior developers are extremely happy with FLOW3 – it is definitely the most capable PHP framework we Fabian Pfütze Project Lead have come across so far.”
  • 72. ?
  • 73. Thanks for having me! Slides: http://slideshare.net/robertlemke Examples: http://github.com/robertlemke Blog: http://robertlemke.com Twitter: @robertlemke Feedback: robert@typo3.org FLOW3: http://flow3.typo3.org