SlideShare a Scribd company logo
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
?
Getting Into FLOW3 (DPC12)
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

PDF
IPCSE12: Getting into FLOW3
PDF
2012 08-11-flow3-northeast-php
PDF
Fluent Development with FLOW3 1.0
PDF
Hands on FLOW3 (DPC12)
PDF
PDF
IPCSE12: Hands on FLOW3
PDF
MidwestPHP Symfony2 Internals
PDF
PHP 良好實踐 (Best Practice)
IPCSE12: Getting into FLOW3
2012 08-11-flow3-northeast-php
Fluent Development with FLOW3 1.0
Hands on FLOW3 (DPC12)
IPCSE12: Hands on FLOW3
MidwestPHP Symfony2 Internals
PHP 良好實踐 (Best Practice)

What's hot (20)

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

Similar to Getting Into FLOW3 (DPC12) (20)

PDF
Getting Into FLOW3 (TYPO312CA)
PDF
FLOW3 Tutorial - T3CON11 Frankfurt
PDF
TYPO3 Flow 2.0 Workshop T3BOARD13
PDF
Fluent Development with FLOW3 1.0
PDF
Applications for the Enterprise with PHP (CPEurope)
PDF
Fluent Development with FLOW3
PDF
TYPO3 Flow and the Joy of Development (FOSDEM 2013)
PDF
TYPO3 Flow 2.0 (International PHP Conference 2013)
PDF
Creating Clean Code with AOP (WebExpo 2010)
PDF
TYPO3 Flow: Beyond the Blog Example (Inspiring Flow 2013)
PDF
TYPO3 Flow 2.0 (T3CON13 San Francisco)
PDF
TYPO3 Flow 2.0 in the field - webtech Conference 2013
PDF
Object Oriented Programming for WordPress Plugin Development
PDF
IPC07 Talk - Beautiful Code with AOP and DI
PDF
Lithium: The Framework for People Who Hate Frameworks
PDF
Design patterns illustrated-2015-03
PDF
From framework coupled code to #microservices through #DDD /by @codelytv
PDF
The current architecture of TYPO3 5.0
PDF
Beyond MVC: from Model to Domain
Getting Into FLOW3 (TYPO312CA)
FLOW3 Tutorial - T3CON11 Frankfurt
TYPO3 Flow 2.0 Workshop T3BOARD13
Fluent Development with FLOW3 1.0
Applications for the Enterprise with PHP (CPEurope)
Fluent Development with FLOW3
TYPO3 Flow and the Joy of Development (FOSDEM 2013)
TYPO3 Flow 2.0 (International PHP Conference 2013)
Creating Clean Code with AOP (WebExpo 2010)
TYPO3 Flow: Beyond the Blog Example (Inspiring Flow 2013)
TYPO3 Flow 2.0 (T3CON13 San Francisco)
TYPO3 Flow 2.0 in the field - webtech Conference 2013
Object Oriented Programming for WordPress Plugin Development
IPC07 Talk - Beautiful Code with AOP and DI
Lithium: The Framework for People Who Hate Frameworks
Design patterns illustrated-2015-03
From framework coupled code to #microservices through #DDD /by @codelytv
The current architecture of TYPO3 5.0
Beyond MVC: from Model to Domain
Ad

More from Robert Lemke (20)

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

Recently uploaded (20)

PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
Approach and Philosophy of On baking technology
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PPTX
Spectroscopy.pptx food analysis technology
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PPT
Teaching material agriculture food technology
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
gpt5_lecture_notes_comprehensive_20250812015547.pdf
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PPTX
Cloud computing and distributed systems.
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PPTX
Big Data Technologies - Introduction.pptx
PPTX
Machine Learning_overview_presentation.pptx
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Machine learning based COVID-19 study performance prediction
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Approach and Philosophy of On baking technology
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Spectroscopy.pptx food analysis technology
The Rise and Fall of 3GPP – Time for a Sabbatical?
Advanced methodologies resolving dimensionality complications for autism neur...
Teaching material agriculture food technology
Review of recent advances in non-invasive hemoglobin estimation
Network Security Unit 5.pdf for BCA BBA.
gpt5_lecture_notes_comprehensive_20250812015547.pdf
Digital-Transformation-Roadmap-for-Companies.pptx
Cloud computing and distributed systems.
Reach Out and Touch Someone: Haptics and Empathic Computing
Big Data Technologies - Introduction.pptx
Machine Learning_overview_presentation.pptx
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Machine learning based COVID-19 study performance prediction
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
20250228 LYD VKU AI Blended-Learning.pptx

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. ?
  • 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