San Francisco, USAKarsten Dambekalns & Robert LemkeFluent Developmentwith FLOW3
San Francisco, USAKarsten Dambekalnsco-lead of TYPO3 5.0 and FLOW334 years oldlives in Lübeck, Germany1 wife, 3 sons, 1 es...
San Francisco, USARobert Lemkechief "architect" of TYPO3 5.0 and FLOW3co-founder of the TYPO3 Association35 years oldlives...
San Francisco, USAAt a GlanceFLOW3 is a web application framework • brings PHP development to a new level • made for PHP 5...
San Francisco, USA Foundation for the Next GenerationTYPO3 5.0 is the all-newEnterprise CMS • content repository, workspac...
San Francisco, USAWork in Progress            WARNING           The current documen                                 tation...
San Francisco, USACheck Out from Git – Stable State$ git clone --recursive git://git.typo3.org/FLOW3/Distributions/Base.gi...
San Francisco, USASet File Permissions$ ./Packages/Framework/FLOW3/Scripts/setfilepermissions.sh robert _www _wwwFLOW3 Fil...
San Francisco, USASet Up DatabaseConfiguration/Settings.yaml #                                                             ...
San Francisco, USASet Up Virtual HostApache Virtual Host  <VirtualHost *:80>       DocumentRoot /opt/local/apache2/htdocs/...
San Francisco, USAFinal Check
San Francisco, USAUpdate from Git to Latest State$ git submodule foreach "git checkout master"-✂-----✂-----✂-----✂-----✂--...
San Francisco, USAHello World!Package.php   <?php   namespace F3Demo;   use F3FLOW3PackagePackage as BasePackage;   class ...
L i ve H ac k ing 5        1                1   1        K. Damb ek aln s & R. Lem ke        D.P. F l u x t r       time ();
San Francisco, USAHello World!StandardController.php   <?php   namespace F3DemoController;   use F3FLOW3MVCControllerActio...
San Francisco, USAHello World!http://dev.flow3.rob/demo/standard/index?name=Robert Hello Robert!
San Francisco, USATackling the Heart of Software Development                                         /**Domain-Driven Desi...
San Francisco, USADomain-Driven DesignDomain activity or business of the userDomain-Driven Design is about • focussing on ...
San Francisco, USADomain-Driven DesignUbiquitous Language • important prerequisite for successful   collaboration • use th...
San Francisco, USADomain: Conference
Ex t re me Mo de li ng 5        2                1   1       K. Damb ek aln s & R. Lem ke        D.P. F l u x t r       ti...
San Francisco, USAExample Model: Paper    /** * A Paper * * @scope prototype * @entity */class Paper {	   /**	    * @var F...
San Francisco, USAExample Model: Paper    	   /**	    * @var string	    * @Column(type="text")	    * @validate StringLengt...
San Francisco, USAExample Model: Paper    	   /**	    * @var F3ConferenceDomainModelConferenceTrack	    * @ManyToOne(casca...
San Francisco, USAExample Model: Paper    	   /**	    * @var string	    * @Column(type="text", nullable=true)	    */	   pr...
San Francisco, USAExample Model: Paper    	   /**	    * STATUS_* constants	    */	   const STATUS_DRAFT = draft;	   const ...
San Francisco, USADomain-Driven Design
San Francisco, USAPersistenceObject Persistence in the Flow • based on Doctrine 2 • seamless integration into FLOW3 • prov...
San Francisco, USA    Basic Object Persistence	   	 // Create a new customer and persist it:	   $customer = new Customer("...
San Francisco, USA    Advanced QueriesPostRepository.php	   /**	     * Finds most recent posts excluding the given post	  ...
San Francisco, USAPurely Doctrine 2       <?php       namespace MyExample;       /**        * @Entity(repositoryClass="Bug...
San Francisco, USADoctrine 2 in FLOW3       <?php       namespace MyExample;       /**        * @Entity(repositoryClass="B...
San Francisco, USAPurely Doctrine 2    	    /**    	     * @var DateTime    	     * @Column(type="datetime")    	     */  ...
San Francisco, USADoctrine 2 in FLOW3    	    /**    	     * @var DateTime    	     * @Column(type="datetime")    	     */...
San Francisco, USAObject ManagementDependency Injection • a class doesnt create or retrieve the instance   of another clas...
San Francisco, USAObject ManagementFLOW3s take on Dependency Injection • one of the first PHP implementations   (started in...
San Francisco, USA                                                                               WarConstructor Injection:...
San Francisco, USA                                                                               War  Constructor Injectio...
San Francisco, USAConstructor Injection    <?phpnamespace F3DemoController;use F3FLOW3MVCControllerActionController;use F3...
San Francisco, USAConstructor Injection
San Francisco, USASetter Injection<?phpnamespace F3DemoController;use F3FLOW3MVCControllerActionController;use F3DemoServi...
San Francisco, USAProperty Injection<?phpnamespace F3DemoController;use F3FLOW3MVCControllerActionController;use F3DemoSer...
San Francisco, USAObjects.yaml   F3FLOW3SecurityCryptographyRsaWalletServiceInterface:     className: F3FLOW3SecurityCrypt...
San Francisco, USAObject ManagementFLOW3s take on Dependency Injection • one of the first PHP implementations   (started in...
San Francisco, USAObject Management    class Customer {	   /**	    * @inject	    * @var CustomerNumberGenerator	    */	   ...
San Francisco, USAObject Management                                     <?php                                     declare(...
Birt h o f a Blo g 5        3                1   1        K. Damb ek aln s & R. Lem ke        D.P. F l u x t r       time ...
San Francisco, USAThe Zen of TemplatingFLOW3 comes with an elegant, flexible and securetemplating engine: Fluid • templates...
San Francisco, USAFluidExample for assigning a string to a Fluid variable:	   	 // in the action controller:	   $this->vie...
San Francisco, USAFluidVariables can also be objects:	   	 // in the action controller:	   $this->view->assign(conference,...
San Francisco, USAFluidif-then-else:	   	 // in the action controller:	   $this->view->assign(post, $blogPost);	   <!-- in...
San Francisco, USAFluidfor-each:	   	 // in the action controller:	   $this->view->assign(ages, array("Karsten" => 34, "Ro...
San Francisco, USAFluidfor-each:	   	 // in the action controller:	   $this->view->assign(post, $blogPost);	   <!-- in the...
San Francisco, USAFluidView helpers – in this case the link.action view helper:	   <!-- in the Fluid template: -->	   {nam...
F lue n t F lu id 5         8                1   1         K. Damb ek aln s & R. Lem ke         D.P. F l u x t r        ti...
San Francisco, USAForms <?php namespace F3BlogDomainModel; /**  * A blog post  *  * @scope prototype  * @entity  */ class ...
San Francisco, USA    Forms<h2>Create a new post</h2><f:form action="create" object="{newPost}" name="newPost" enctype="mu...
San Francisco, USA    Forms<?phpnamespace F3BlogController;use F3FLOW3MVCControllerActionController;class PostController e...
San Francisco, USAKarsten Dambekalns & Robert LemkeFluent Developmentwith FLOW3 (PART TWO)
San Francisco, USAValidationValidation is about different things• incoming data needs to be validated for security reasons...
San Francisco, USAValidationValidation in FLOW3• you do not want to code checks into your controllers• FLOW3 separates val...
San Francisco, USAValidationValidation Models• BaseProperties  rules defining the minimum requirements on individual proper...
San Francisco, USAValidationBase Properties• Validation rules defined directly at the properties  	   /**  	    * @var stri...
San Francisco, USAValidationValidators• validators provided by FLOW3 can be used through their short name • Count, Float, ...
San Francisco, USASchema ManagementAutomatic database updates• when first running FLOW3 the schema will be created• when a ...
San Francisco, USASchema ManagementManual database updates• for simple situations this can be good enough:$ ./flow3_dev fl...
San Francisco, USASchema ManagementDoctrine 2 Migrations• Migrations allow schema versioning and  change deployment• Migra...
San Francisco, USASchema ManagementMigrations Workflow• use schema auto update in early development until your model is  re...
San Francisco, USASchema ManagementMigrations Workflow$ ./flow3_dev flow3:doctrine:migrationstatus == Configuration    >> N...
San Francisco, USASchema ManagementMigrations Workflow• rinse and repeat: from now on create a new migration whenever  you ...
S ch e m at ic De mo 5        8                1   1       K. Damb ek aln s & R. Lem ke        D.P. F l u x t r       time...
San Francisco, USACommand Line Support
Sh e b a ng! 5        8                1   1        K. Damb ek aln s & R. Lem ke        D.P. F l u x t r       time ();
San Francisco, USA    Command Line Support<?phpnamespace F3FLOW3Command;/** * Package command controller to handle package...
San Francisco, USASecurityTouchless Security, Flow-Style • security is handled at a central place (through AOP) • third-pa...
San Francisco, USASecurity Policy
San Francisco, USASecurityCross-Site Request Forgery • enables an attacker to execute privileged operations without being ...
San Francisco, USASecurityAvoiding Cross-Site Request Forgery • add a (truly!) random string token to each link or form • ...
San Francisco, USASecurityCSRF Protection in FLOW3 • you must not forget to add that token to any link • FLOW3 automatical...
Us e rs a n d L o g in 5         8                1   1        K. Damb ek aln s & R. Lem ke         D.P. F l u x t r      ...
San Francisco, USAAOPAspect-Oriented Programming • programming paradigm • separates concerns to improve modularization • O...
San Francisco, USAAOP                                 /**                                  * @aspectFLOW3 uses AOP for ......
Th e Wiz a rd o f AOP 5       8                1   1      K. Damb ek aln s & R. Lem ke       D.P. F l u x t r      time ();
San Francisco, USASignal-Slot Event HandlingSignal  • can be fired on any event  • can be freely defined by the developerSlo...
San Francisco, USASignal-Slot Event Handling   /**     * @param F3BlogDomainModelPost $post     * @param F3BlogDomainModel...
San Francisco, USASignal-Slot Event HandlingSignals are wired to Slots in a package’s bootstrap: /**   * Invokes custom PH...
San Francisco, USASignal-Slot Event HandlingAny method can be a slot:  /**   * @param F3BlogDomainModelComment $comment   ...
San Francisco, USASpeed and PerformanceFor the snappy user experience: • multi-layered, tagged caches • various cache back...
San Francisco, USAMore Features • Resource Management (CDNs, private resources, ...) • Logging • File Monitoring • Configur...
San Francisco, USARoadmaphttp://forge.typo3.org/projects/flow3-distribution-base/roadmap
San Francisco, USADiscover the source code of the conference appgit://git.typo3.org/TYPO3v5/Distributions/Conference.git
San Francisco, USATry out the blog appgit://git.typo3.org/FLOW3/Applications/Blog.git
San Francisco, USAThank You! • These slides: http://slideshare.net/robertlemke • Download FLOW3: http://flow3.typo3.org • F...
Fluent Development with FLOW3 1.0
Upcoming SlideShare
Loading in …5
×

Fluent Development with FLOW3 1.0

3,654 views

Published on

FLOW3 is an application framework which will change the way you code PHP. It aims to back up developers with security and infrastructure while they focus on the application logic.

FLOW3 is one of the first application frameworks to choose Domain-Driven Design as its major underlying concept. This approach makes FLOW3 easy to learn and at the same time clean and flexible for even complex projects. Built with PHP 5.3 in mind from the beginning, it features namespaces and has an emphasis on clean, object-oriented code.

Thanks to its Doctrine 2 integration, FLOW3 gives you access to a wide range of databases while letting you forget the fact that you're using a database at all (think objects, not tables). FLOW3's unique way of supporting Dependency Injection (no configuration necessary) lets you truly enjoy creating a stable and easy-to-test application architecture. Being the only Aspect-Oriented Programming capable PHP framework, FLOW3 allows you to cleanly separate cross cutting concerns like security from your main application logic.

This tutorial provides a comprehensive overview of the main features of FLOW3 and how you can get started with your first app.

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,654
On SlideShare
0
From Embeds
0
Number of Embeds
167
Actions
Shares
0
Downloads
48
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Fluent Development with FLOW3 1.0

  1. 1. San Francisco, USAKarsten Dambekalns & Robert LemkeFluent Developmentwith FLOW3
  2. 2. San Francisco, USAKarsten Dambekalnsco-lead of TYPO3 5.0 and FLOW334 years oldlives in Lübeck, Germany1 wife, 3 sons, 1 espresso machinelikes canoeing
  3. 3. San Francisco, USARobert Lemkechief "architect" of TYPO3 5.0 and FLOW3co-founder of the TYPO3 Association35 years oldlives in Lübeck, Germany1 wife, 1 daughter, 1 espresso machinelikes drumming
  4. 4. San Francisco, USAAt a GlanceFLOW3 is a web application framework • brings PHP development to a new level • made for PHP 5.3, full namespaces support • modular, extensible, package based • free & Open Source (LGPL v3) • backed by one of the largest Open Source projects with 6000+ contributors
  5. 5. San Francisco, USA Foundation for the Next GenerationTYPO3 5.0 is the all-newEnterprise CMS • content repository, workspaces, versions, i18n, ExtJS based UI ... • powered by FLOW3 • compatible code base • use TYPO3 features in FLOW3 standalone apps as you like
  6. 6. San Francisco, USAWork in Progress WARNING The current documen tation of FLOW3 does cover the version in not our Git master – a lo changed since the la t has st alpha release! We are currently upd ating the manuals an tutorials for the 1.0 b d eta release though.
  7. 7. San Francisco, USACheck Out from Git – Stable State$ 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.
  8. 8. San Francisco, USASet File Permissions$ ./Packages/Framework/FLOW3/Scripts/setfilepermissions.sh robert _www _wwwFLOW3 File Permission ScriptChecking permissions from here upwards ... (if a password prompt appears its from sudo)Password:Making sure Data and Web/_Resources exist ...Setting file permissions, this might take a minute ...$
  9. 9. San Francisco, USASet Up DatabaseConfiguration/Settings.yaml # # # Global Settings # # # FLOW3: persistence: backendOptions: driver: pdo_mysql dbname: blog user: bloguser password: blogpassword host: 127.0.0.1 path: 127.0.0.1 port: 3306 doctrine: dbal: sessionInitialization: SET NAMES utf8 COLLATE utf8_unicode_ci
  10. 10. San Francisco, USASet Up Virtual HostApache 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>
  11. 11. San Francisco, USAFinal Check
  12. 12. San Francisco, USAUpdate from Git to Latest State$ git submodule foreach "git checkout master"-✂-----✂-----✂-----✂-----✂-----✂-----✂-----✂-----✂-----✂-----✂-----✂-$ git submodule foreach "git pull --rebase"Entering Build/CommonFirst, rewinding head to replay your work on top of it...Fast-forwarded master to 6f27f1784240b414e966ce0e5a12e23cb2f7ab02.Entering Packages/Application/TYPO3First, rewinding head to replay your work on top of it...Fast-forwarded master to 5187430ee44d579ae2bac825e2a069c4cd3f38a4.Entering Packages/Application/TYPO3CRFirst, rewinding head to replay your work on top of it...Fast-forwarded master to b1f5331aa51d390fa3d973404f31b9fd773f7059.Entering Packages/Application/TwitterCurrent branch master is up to date.…
  13. 13. San Francisco, USAHello World!Package.php <?php namespace F3Demo; use F3FLOW3PackagePackage as BasePackage; class Package extends BasePackage { }Today: $ ./flow3_dev flow3:package:create --package-key DemoSoon: $ ./flow3_dev flow3:package:create Demo
  14. 14. L i ve H ac k ing 5 1 1 1 K. Damb ek aln s & R. Lem ke D.P. F l u x t r time ();
  15. 15. San Francisco, USAHello World!StandardController.php <?php namespace F3DemoController; use F3FLOW3MVCControllerActionController; class StandardController extends ActionController { /** * @param string $name * @return string */ public function indexAction($name) { return "Hello $name!"; } } ?>
  16. 16. San Francisco, USAHello World!http://dev.flow3.rob/demo/standard/index?name=Robert Hello Robert!
  17. 17. San Francisco, USATackling the Heart of Software Development /**Domain-Driven Design * Paper submitted by * a speaker * @scope prototype * @entityA methodology which ... */ class Paper { • results in rich domain models /** * @var Participant */ • provides a common language protected $author; across the project team /** * @var string */ • simplify the design of complex protected $title; applications /** * @var string */ protected $shortAbstra ct;FLOW3 is the first PHP framework /**tailored to Domain-Driven Design * @var string */ protected $abstract;
  18. 18. San Francisco, USADomain-Driven DesignDomain activity or business of the userDomain-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
  19. 19. San Francisco, USADomain-Driven DesignUbiquitous Language • important prerequisite for successful collaboration • use the same words for • discussion • modeling • development • documentation
  20. 20. San Francisco, USADomain: Conference
  21. 21. Ex t re me Mo de li ng 5 2 1 1 K. Damb ek aln s & R. Lem ke D.P. F l u x t r time ();
  22. 22. San Francisco, USAExample Model: Paper /** * A Paper * * @scope prototype * @entity */class Paper { /** * @var F3ConferenceDomainModelAccountParticipant * @ManyToOne(cascade={"persist"}) * @validate NotEmpty */ protected $author; /** * @var string * @validate StringLength(minimum = 1, maximum = 50) */ protected $title;
  23. 23. San Francisco, USAExample Model: Paper /** * @var string * @Column(type="text") * @validate StringLength(minimum = 30, maximum = 150) */ protected $shortAbstract; /** * @var string * @Column(type="text") * @validate StringLength(minimum = 100, maximum = 1000) */ protected $abstract; /** * @var F3ConferenceDomainModelConferenceSessionType * @ManyToOne(cascade={"persist"}) * @validate NotEmpty */ protected $proposedSessionType;
  24. 24. San Francisco, USAExample Model: Paper /** * @var F3ConferenceDomainModelConferenceTrack * @ManyToOne(cascade={"persist"}) * @validate NotEmpty */ protected $proposedTrack; /** * @var DoctrineCommonCollectionsArrayCollection<F3ConferenceDomainModelComment> * @ManyToMany(cascade={"persist", "remove"}) */ protected $comments; /** * @var string */ protected $slideShareUrl; /** * @var string */ protected $tags;
  25. 25. San Francisco, USAExample Model: Paper /** * @var string * @Column(type="text", nullable=true) */ protected $links; /** * @var DoctrineCommonCollectionsArrayCollection<F3ConferenceDomainModelAccountParticipant> * @ManyToMany(cascade={"all"}) */ protected $speakers; /** * one of the STATUS_* constants * @var string */ protected $status = self::STATUS_DRAFT;
  26. 26. San Francisco, USAExample Model: Paper /** * STATUS_* constants */ const STATUS_DRAFT = draft; const STATUS_SUBMITTED = submitted; const STATUS_REJECTED = rejected; const STATUS_ACCEPTED = accepted; const STATUS_SCHEDULED = scheduled; public function __construct() { $this->comments = new DoctrineCommonCollectionsArrayCollection(); $this->speakers = new DoctrineCommonCollectionsArrayCollection(); } /** * @param F3ConferenceDomainModelAccountParticipant $author * @return void */ public function setAuthor(F3ConferenceDomainModelAccountParticipant $author) { $this->author = $author; } /** * @return F3ConferenceDomainModelAccountParticipant */ public function getAuthor() {
  27. 27. San Francisco, USADomain-Driven Design
  28. 28. San Francisco, USAPersistenceObject Persistence in the Flow • based on Doctrine 2 • seamless integration into FLOW3 • provides all the great Doctrine 2 features • uses UUIDs • low level persistence API: • allows for own, custom persistence backends (instead of Doctrine 2) • CouchDB is supported natively
  29. 29. San Francisco, USA 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);
  30. 30. San Francisco, USA Advanced QueriesPostRepository.php /** * Finds most recent posts excluding the given post * * @param F3BlogDomainModelPost $post Post to exclude from result * @param integer $limit The number of posts to return at max * @return array All posts of the $posts blog except for $post */ public function findRecentExceptThis(F3BlogDomainModelPost $post, $limit = 20) { $query = $this->createQuery(); $posts = $query->matching($query->equals(blog, $post->getBlog())) ->setOrderings(array(date => F3FLOW3PersistenceQueryInterface::ORDER_DESCENDING)) ->setLimit($limit) ->execute() ->toArray(); unset($posts[array_search($post, $posts)]); return $posts; // this is an alternative way of doing this when extending the Doctrine 2 // specific repository and using DQL. return $this->entityManager ->createQuery(SELECT p FROM F3BlogDomainModelPost p WHERE p.blog = :blog . AND NOT p = :excludedPost ORDER BY p.date DESC) ->setMaxResults($limit) ->execute(array(blog => $post->getBlog(), excludedPost => $post)); }
  31. 31. San Francisco, USAPurely Doctrine 2 <?php namespace MyExample; /** * @Entity(repositoryClass="BugRepository") */ class Bug { /** * @var integer * @Id * @Column(type="integer") * @GeneratedValue */ public $id; /** * @var string * @Column(type="string") */ public $description; /** * @var DateTime
  32. 32. San Francisco, USADoctrine 2 in FLOW3 <?php namespace MyExample; /** * @Entity(repositoryClass="BugRepository") */ class Bug { /** * @var integer * @Id * @Column(type="integer") * @GeneratedValue */ public $id; /** * @var string * @Column(type="string") */ public $description; /** * @var DateTime
  33. 33. San Francisco, USAPurely Doctrine 2 /** * @var DateTime * @Column(type="datetime") */ public $created; /** * @var User * @ManyToOne(targetEntity="User", inversedBy="assignedBugs") */ private $engineer; /** * @var DoctrineCommonCollectionsArrayCollection<Product> * @ManyToMany(targetEntity="Product") */ private $products; } ?>
  34. 34. San Francisco, USADoctrine 2 in FLOW3 /** * @var DateTime * @Column(type="datetime") */ public $created; /** * @var User * @ManyToOne(targetEntity="User", inversedBy="assignedBugs") */ private $engineer; /** * @var DoctrineCommonCollectionsArrayCollection<Product> * @ManyToMany(targetEntity="Product") */ private $products; } ?>
  35. 35. San Francisco, USAObject ManagementDependency Injection • a class doesnt create or retrieve the instance of another class but gets it injected • fosters loosely-coupling and high cohesion ‣ more stable, reusable code
  36. 36. San Francisco, USAObject ManagementFLOW3s 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 gathered automatically (autowiring) • intuitive use and no bad magical surprises • fast! (like hardcoded or faster)
  37. 37. San Francisco, USA WarConstructor Injection: Symfony 2 nin g (Im :m igh no t co Sym f nta ony exp in erro <?php ert .. .) rsnamespace AcmeDemoBundleController;use SymfonyBundleFrameworkBundleControllerController;use SymfonyComponentHttpFoundationRedirectResponse;use SensioBundleFrameworkExtraBundleConfigurationRoute;use SensioBundleFrameworkExtraBundleConfigurationTemplate;use AcmeDemoBundleGreeterService;class DemoController extends Controller { /** * @var AcmeDemoBundleGreeterService */ protected $greeterService; /** * @param AcmeDemoBundleGreeterService */ public function __construct($greeterService = NULL) { $this->greeterService = $greeterService; } /** * @Route("/hello/{name}", name="_demo_hello") */ public function helloAction($name) { return new Response(Hello . $name, 200, array(Content-Type => text/plain)); }}
  38. 38. San Francisco, USA War Constructor Injection: Symfony 2 nin g (Im :m igh no t co Sym f nta ony exp in erro ert .. .) rs <?xml version="1.0" ?><container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="acme.demo.greeterservice" class="AcmeDemoBundleGreeterService" public="false" /> <service id="acme.demo.democontroller" class="AcmeDemoBundleControllerDemoController"> <argument type="service" id="acme.demo.greeterservice" /> </service> </services></container>
  39. 39. San Francisco, USAConstructor Injection <?phpnamespace F3DemoController;use F3FLOW3MVCControllerActionController;use F3DemoServiceGreeterService;class DemoController extends ActionController { /** * @var F3DemoServiceGreeterService */ protected $greeterService; /** * @param F3DemoServiceGreeterService */ public function __construct(F3DemoServiceGreeterService $greeterService) { $this->greeterService = $greeterService; } /** * @param string $name */ public function helloAction($name) { return Hello . $name; }}
  40. 40. San Francisco, USAConstructor Injection
  41. 41. San Francisco, USASetter Injection<?phpnamespace F3DemoController;use F3FLOW3MVCControllerActionController;use F3DemoServiceGreeterService;class DemoController extends ActionController { /** * @var F3DemoServiceGreeterService */ protected $greeterService; /** * @param F3DemoServiceGreeterService */ public function injectGreeterService(F3DemoServiceGreeterService $greeterService) { $this->greeterService = $greeterService; } /** * @param string $name */ public function helloAction($name) { return Hello . $name; }}
  42. 42. San Francisco, USAProperty Injection<?phpnamespace F3DemoController;use F3FLOW3MVCControllerActionController;use F3DemoServiceGreeterService;class DemoController extends ActionController { /** * @var F3DemoServiceGreeterService * @inject */ protected $greeterService; /** * @param string $name */ public function helloAction($name) { return Hello . $name; }}
  43. 43. San Francisco, USAObjects.yaml F3FLOW3SecurityCryptographyRsaWalletServiceInterface: className: F3FLOW3SecurityCryptographyRsaWalletServicePhp scope: singleton properties: keystoreCache: object: factoryObjectName: F3FLOW3CacheCacheManager factoryMethodName: getCache arguments: 1: value: FLOW3_Security_Cryptography_RSAWallet
  44. 44. San Francisco, USAObject ManagementFLOW3s 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)
  45. 45. San Francisco, USAObject Management class Customer { /** * @inject * @var CustomerNumberGenerator */ protected $customerNumberGenerator; ...}$customer = new Customer();$customer->getCustomerNumber();
  46. 46. San Francisco, USAObject Management <?php declare(ENCODING = u tf-8); namespace F3Confere nceDomain ModelConference; /**FLOW3 creates proxy classes * Autogenerated Prox y Classfor realizing DI and AOP magic * @scope prototype * @entity */ class Paper extends • new operator is supported F3FLOW3Persistenc Paper_Original implem eAspectPersistence ents F3FLOW3Object MagicInterface { Pr /** • proxy classes are created * @var string * @Id on the fly * @Column(length="40 ") * introduced by F3F LOW3PersistenceAsp */ ectPersistenceMagic • in production context all protected $FLOW3_Per sistence_Identifier = NULL; code is static private $FLOW3_AOP_P roxy_targetMethodsAn dGroupedAdvices = ar ra private $FLOW3_AOP_P roxy_groupedAdviceCh ains = array(); private $FLOW3_AOP_P roxy_methodIsInAdvic eMode = array(); /** * Autogenerated Prox y Method */ public function __co nstruct() {
  47. 47. Birt h o f a Blo g 5 3 1 1 K. Damb ek aln s & R. Lem ke D.P. F l u x t r time ();
  48. 48. San Francisco, USAThe Zen of TemplatingFLOW3 comes with an elegant, flexible and securetemplating engine: Fluid • templates are valid HTML • templates contain no PHP code • object access, control structures, loops ... • designer-friendly • extensible (view helpers, widgets)
  49. 49. San Francisco, USAFluidExample 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>
  50. 50. San Francisco, USAFluidVariables 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>
  51. 51. San Francisco, USAFluidif-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>
  52. 52. San Francisco, USAFluidfor-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>
  53. 53. San Francisco, USAFluidfor-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>
  54. 54. San Francisco, USAFluidView helpers – in this case the link.action view helper: <!-- in the Fluid template: --> {namespace f=F3FluidViewHelpers} <f:link.action action="delete" arguments="{post: post, really: yes}"> Delete this post </f:link.action>
  55. 55. F lue n t F lu id 5 8 1 1 K. Damb ek aln s & R. Lem ke D.P. F l u x t r time ();
  56. 56. San Francisco, USAForms <?php namespace F3BlogDomainModel; /** * A blog post * * @scope prototype * @entity */ class Post { /** * @var string * @validate StringLength(minimum = 1, maximum = 100) */ protected $title; /** * @var string * @validate StringLength(minimum = 1, maximum = 50) */ protected $author;
  57. 57. San Francisco, USA Forms<h2>Create a new post</h2><f:form action="create" object="{newPost}" name="newPost" enctype="multipart/form-data"> <label for="title">Title</label><br /> <f:form.textbox property="title" id="title" /><br /> <label for="content">Content</label><br /> <f:form.textarea property="content" rows="5" cols="40" id="content" /><br /> <label for="image">Image resource</label><br /> <f:form.textbox property="image.title" value="My image title" /> <f:form.upload property="image.originalResource" /></f:form>
  58. 58. San Francisco, USA Forms<?phpnamespace F3BlogController;use F3FLOW3MVCControllerActionController;class PostController extends ActionController { /** * @inject * @var F3BlogDomainRepositoryPostRepository */ protected $postRepository; /** * Creates a new post * * @param F3BlogDomainModelPost $newPostadded to the repository * @return void */ public function createAction(F3BlogDomainModelPost $newPost) { $this->blog->addPost($newPost); $this->flashMessageContainer->add(Your new post was created.); $this->redirect(index); }
  59. 59. San Francisco, USAKarsten Dambekalns & Robert LemkeFluent Developmentwith FLOW3 (PART TWO)
  60. 60. San Francisco, USAValidationValidation is about different things• incoming data needs to be validated for security reasons • no evil markup in submitted content• domain model integrity needs to be ensured • an email needs to be (syntactically) valid • credit card numbers should consist only of digits
  61. 61. San Francisco, USAValidationValidation 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
  62. 62. San Francisco, USAValidationValidation 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)
  63. 63. San Francisco, USAValidationBase 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;
  64. 64. San Francisco, USAValidationValidators• 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;
  65. 65. San Francisco, USASchema ManagementAutomatic database updates• when first running FLOW3 the schema will be created• when a model has changed, the schema is updated• be careful with existing data, updates can be destructive• for production you should manually manage schema changes
  66. 66. San Francisco, USASchema ManagementManual database updates• for simple situations this can be good enough:$ ./flow3_dev flow3:doctrine:create$ ./flow3_dev flow3:doctrine:update• useful when • you need to use an existing database dump • using SQLite, due to limited schema change functionality
  67. 67. San Francisco, USASchema ManagementDoctrine 2 Migrations• Migrations allow schema versioning and change deployment• Migrations are the recommended way for DB updates• Tools to create and deploy migrations are integrated with FLOW3
  68. 68. San Francisco, USASchema ManagementMigrations Workflow• use schema auto update in early development until your model is ready for a first “freeze”, then switch off schema auto update and drop your tables• create migration diff and customize it$ ./flow3_dev flow3:doctrine:migrationdiffGenerated new migration class to "…/Version20110608074324.php" from schema differences.$ vi …/Version20110608074324.php• migrate to create the tables$ ./flow3_dev flow3:doctrine:migrate
  69. 69. San Francisco, USASchema ManagementMigrations Workflow$ ./flow3_dev flow3:doctrine:migrationstatus == Configuration >> Name: Doctrine Database Migrations >> Database Driver: pdo_mysql >> Database Name: blog >> Configuration Source: manually configured >> Version Table Name: flow3_doctrine_migrationstatus >> Migrations Namespace: F3FLOW3PersistenceDoctrineMigrations >> Migrations Directory: /Users/karsten/Sites/blog/Configuration/Doctrine/Migrations >> Current Version: 2011-06-08 07:43:24 (20110608074324) >> Latest Version: 2011-06-08 07:43:24 (20110608074324) >> Executed Migrations: 1 >> Available Migrations: 1 >> New Migrations: 0 == Migration Versions >> 2011-06-08 07:43:24 (20110608074324) migrated
  70. 70. San Francisco, USASchema ManagementMigrations Workflow• rinse and repeat: from now on create a new migration whenever you changed your model classes• generated migrations most probably need to be adjusted • e.g. renaming a model means renaming a table, not dropping and creating • data migration needs to be added• remember: good migrations make your user’s day
  71. 71. S ch e m at ic De mo 5 8 1 1 K. Damb ek aln s & R. Lem ke D.P. F l u x t r time ();
  72. 72. San Francisco, USACommand Line Support
  73. 73. Sh e b a ng! 5 8 1 1 K. Damb ek aln s & R. Lem ke D.P. F l u x t r time ();
  74. 74. San Francisco, USA Command Line Support<?phpnamespace F3FLOW3Command;/** * Package command controller to handle packages from CLI (create/activate/deactivate packages) * * @scope singleton */class PackageCommandController extends F3FLOW3MVCControllerCommandController { /** * @inject * @var F3FLOW3PackagePackageManagerInterface */ protected $packageManager; /** * Creates a new package * * Creates a new package with the given package key. The package key * should be the vendor namespace segments. * * @param string $packageKey The package key of the package to create * @return string */ public function createCommand($packageKey) { if (!$this->packageManager->isPackageKeyValid($packageKey)) { $this->response->appendContent(The package key " . $packageKey . " is not
  75. 75. San Francisco, USASecurityTouchless Security, Flow-Style • security is handled at a central place (through AOP) • third-party code is as secure as possible by default • modeled after our experiences in the TYPO3 project and Spring Security (Java framework) • provides authentication, authorization, validation, filtering ... • can intercept arbitrary method calls • transparently filters content through query-rewriting • extensible for new authentication or authorization mechanisms
  76. 76. San Francisco, USASecurity Policy
  77. 77. San Francisco, USASecurityCross-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...
  78. 78. San Francisco, USASecurityAvoiding 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
  79. 79. San Francisco, USASecurityCSRF 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
  80. 80. Us e rs a n d L o g in 5 8 1 1 K. Damb ek aln s & R. Lem ke D.P. F l u x t r time ();
  81. 81. San Francisco, USAAOPAspect-Oriented Programming • programming paradigm • separates concerns to improve modularization • OOP modularizes concerns into objects • AOP modularizes cross-cutting concerns into aspects • FLOW3 makes it easy (and possible at all) to use AOP in PHP
  82. 82. San Francisco, USAAOP /** * @aspectFLOW3 uses AOP for ... * @introduce */ F3FLOW3Pers istenceAspec tPersistence class Persist MagicInterfac enceMagicAspe e, F3FLO ct { • persistence magic /** * @pointcut c lassTaggedWit */ h(entity) || classTaggedWi th(valueobjec • logging public functi on isEntityOr ValueObject() {} t) /** * @var string • debugging * @Id * @Column(len gth="40") * @introduce F3FLOW3Pers */ istenceAspec tPersistence • security protected $FL OW3_Persisten ce_Identifier ; MagicAspect-> isEnti /** * After retur ning advice, * making sure w e have an UUI * @param F3 D for each an FLOW3AOPJoi d every * @return voi nPointInterfa d ce $joinPoint * @before cla The current j ssTaggedWith( oin po */ entity) && me thod(.*->__co public functi nstruct()) on generateUU $proxy = $joi ID(F3FLOW3 nPoint->getPr AOPJoinPoint oxy(); Interface $jo F3FLOW3Ref inPoint) lectionObjec } tAccess::setP roperty($prox y , FLOW3_Per siste
  83. 83. Th e Wiz a rd o f AOP 5 8 1 1 K. Damb ek aln s & R. Lem ke D.P. F l u x t r time ();
  84. 84. San Francisco, USASignal-Slot Event HandlingSignal • can be fired on any event • can be freely defined by the developerSlot • is invoked when a signal is emitted • any method can be used as a slotany signal can be wired to any slot
  85. 85. San Francisco, USASignal-Slot Event Handling /** * @param F3BlogDomainModelPost $post * @param F3BlogDomainModelComment $newComment * @return void */ public function createAction(F3BlogDomainModelPost $post, F3BlogDomainModelComment $newComment) { $post->addComment($newComment); $this->emitCommentCreated($newComment, $post); … } /** * @param F3BlogDomainModelComment $comment * @param F3BlogDomainModelPost $post * @return void * @signal */ protected function emitCommentCreated(F3BlogDomainModelComment $comment, F3BlogDomainModelPost $post) {}
  86. 86. San Francisco, USASignal-Slot Event HandlingSignals are wired to Slots in a package’s bootstrap: /** * Invokes custom PHP code directly after the package manager has been * initialized. * * @param F3FLOW3CoreBootstrap $bootstrap The current bootstrap * @return void */ public function boot(F3FLOW3CoreBootstrap $bootstrap) { $dispatcher = $bootstrap->getSignalSlotDispatcher(); $dispatcher->connect( F3BlogControllerCommentController, commentCreated, F3BlogServiceNotification, sendNewCommentNotification ); }
  87. 87. San Francisco, USASignal-Slot Event HandlingAny method can be a slot: /** * @param F3BlogDomainModelComment $comment * @param F3BlogDomainModelPost $post * @return void */ public function sendNewCommentNotification(F3BlogDomainModelComment $comment, F3BlogDomainModelPost $post) { $mail = new F3SwiftMailerMessage(); $mail ->setFrom(array(john@doe.org => John Doe)) ->setTo(array(karsten@typo3.org => Karsten Dambekalns)) ->setSubject(New comment on blog post " . $post->getTitle() . ") ->setBody($comment->getContent()) ->send(); }
  88. 88. San Francisco, USASpeed and PerformanceFor the snappy user experience: • multi-layered, tagged caches • various cache backends (file, Memcached, APC, Redis, PDO, ...) • reverse-proxy support (Varnish, ESI) in the works • code compilation • regular benchmarks • focus on good scalability
  89. 89. San Francisco, USAMore Features • Resource Management (CDNs, private resources, ...) • Logging • File Monitoring • Configuration Management • Routing • REST / SOAP • ...
  90. 90. San Francisco, USARoadmaphttp://forge.typo3.org/projects/flow3-distribution-base/roadmap
  91. 91. San Francisco, USADiscover the source code of the conference appgit://git.typo3.org/TYPO3v5/Distributions/Conference.git
  92. 92. San Francisco, USATry out the blog appgit://git.typo3.org/FLOW3/Applications/Blog.git
  93. 93. San Francisco, USAThank You! • These slides: http://slideshare.net/robertlemke • Download FLOW3: http://flow3.typo3.org • Follow us on Twitter: @t3rob (Robert) @k_fish (Karsten) • Give us feedback: • robert@typo3.org / karsten@typo3.org • http://joind.in/3535

×