FLOW3-Workshop F3X12

6,764 views

Published on

Folien zum FLOW3 Workshop von der F3X12

Published in: Technology, Business
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
6,764
On SlideShare
0
From Embeds
0
Number of Embeds
753
Actions
Shares
0
Downloads
30
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

FLOW3-Workshop F3X12

  1. 1. Karsten Dambekalns Einführung in FLOW3 FLOW3 Experience 2012 1
  2. 2. Karsten DambekalnsCo-Lead von TYPO3 Phoenix und FLOW334 Jahre altlebt in Lübeck1 Frau, 3 Söhne, 1 Espressomaschinefährt gern Kanadier und klettert 2
  3. 3. Auf einen BlickFLOW3 ist eine Web Application Platform • ermöglicht eine neue Art von PHP-Entwicklung • basiert auf PHP 5.3, vollständiger Namespaces Support • modular, erweiterbar, paket-basiert • frei & Open Source (LGPL v3) • unterstützt von einem der größten Open Source Projekte, mit mehr als 6000 Entwicklern 3
  4. 4. Grundlage für das Next-Generation CMSTYPO3 Phoenix ist das komplettneue Enterprise CMS • Content Repository, Workspaces, Versionierung, i18n, neues UI ... • powered by FLOW3 • FLOW3 kompatible Code-Basis • benutze TYPO3 Features in eigenen FLOW3 Applikationen 4
  5. 5. 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. 5
  6. 6. Zugriffsrechte einrichten $ sudo ./flow3 core:setfilepermissions karsten _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 karstenMac OS X: $ sudo dscl . -append /Groups/_www GroupMembership karsten 6
  7. 7. Datenbankverbindung einrichtenConfiguration/Settings.yaml TYPO3: FLOW3: persistence: backendOptions: dbname: demo user: demo password: password host: 127.0.0.1 # doctrine: # sqlLogger: TYPO3FLOW3PersistenceDoctrineLoggingSqlLogger 7
  8. 8. Konfiguration per Kontext• FLOW3 bietet verschiedene Kontexte für Entwicklung, Test und Produktivbetrieb• je nach Kontext konfigurieren: Datenbank, Logging, …• Unterscheidung per Umgebungsvariable im Virtual Host und auf der Konsole:$ ./flow3 helpFLOW3 1.1.0-dev ("Development" context)usage: ./flow3 <command identifier> …$ FLOW3_CONTEXT=Production ./flow3 helpFLOW3 1.1.0-dev ("Production" context)usage: ./flow3 <command identifier> … 8
  9. 9. Virtual Host einrichtenApache Virtual Host <VirtualHost *:80> DocumentRoot /opt/local/apache2/htdocs/Talks/FLOW3/Web/ ServerName dev.flow3.kmac </VirtualHost> <VirtualHost *:80> DocumentRoot /opt/local/apache2/htdocs/Talks/FLOW3/Web/ ServerName flow3.kmac SetEnv FLOW3_CONTEXT Production </VirtualHost> 9
  10. 10. Funktionierts? 10
  11. 11. Git Submodule aktualisieren (bleeding edge)$ 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 5187430ee44d579ae2bac825e2a069c4cd3Acme8a4.Entering Packages/Application/TYPO3CRFirst, rewinding head to replay your work on top of it...Fast-forwarded master to b1f5331aa51d390fa3d973404Acme1b9fd773f7059.Entering Packages/Application/TwitterCurrent branch master is up to date.… 11
  12. 12. Kommandozeile$ ./flow3 helpFLOW3 1.1.0-dev ("Development" context)usage: ./flow3 <command identifier>The following commands are currently available:PACKAGE "TYPO3.FLOW3":-------------------------------------------------------------------------------* flow3:cache:flush Flush all caches cache:warmup Warm up caches configuration:show Show the active configuration settings* flow3:core:setfilepermissions Adjust file permissions for CLI and web server access* flow3:core:shell Run the interactive Shell doctrine:validate Validate the class/table mappings doctrine:create Create the database schema doctrine:update Update the database schema doctrine:entitystatus Show the current status of entities and mappings doctrine:dql Run arbitrary DQL and display results doctrine:migrationstatus Show the current migration status doctrine:migrate Migrate the database schema doctrine:migrationexecute Execute a single migration doctrine:migrationversion Mark/unmark a migration as migrated 12
  13. 13. Kommandozeile$ ./flow3 help kickstart:packageKickstart a new packageCOMMAND: typo3.kickstart:kickstart:packageUSAGE: ./flow3 kickstart:package <package key>ARGUMENTS: --package-key The package key, for example "MyCompany.MyPackageName"DESCRIPTION: Creates a new package and creates a standard Action Controller and a sample template for its Index Action. For creating a new package without sample code use the package:create command.SEE ALSO: typo3.flow3:package:create (Create a new package) 13
  14. 14. Hallo Welt! $ ./flow3 kickstart:package Acme.Demo 14
  15. 15. Hallo Welt!StandardController.php <?php namespace AcmeDemoController; use TYPO3FLOW3MvcControllerActionController; class StandardController extends ActionController { /** * @param string $name * @return string */ public function indexAction($name) { return "Hello $name!"; } } ?> 15
  16. 16. Controller Kickstart$ ./flow3 help kickstart:actioncontrollerKickstart a new action controllerCOMMAND: typo3.kickstart:kickstart:actioncontrollerUSAGE: ./flow3 kickstart:actioncontroller [<options>] <package key> <controller name>ARGUMENTS: --package-key The package key of the package for the new controller with an optional subpackage, (e.g. "MyCompany.MyPackage/Admin"). --controller-name The name for the new controller. This may also be a comma separated list of controller names.OPTIONS: --generate-actions Also generate index, new, create, edit, update and delete actions. --generate-templates Also generate the templates for each action. --generate-related Also create the mentioned package, related model and repository if neccessary. --force Overwrite any existing controller or template code. Regardless of this flag, the package, model and repository will never be overwritten.DESCRIPTION: Generates an Action Controller with the given name in the specified package. In its default mode it will create just the controller containing a sample 16
  17. 17. Eigene Commands $ ./flow3 kickstart:commandcontroller Acme.Demo Test namespace AcmeDemoController; use TYPO3FLOW3MvcControllerCommandController; class TestCommandController extends CommandController { /** * An example command * * @param string $requiredArgument This argument is required * @param string $optionalArgument This argument is optional * @return void */ public function exampleCommand($name) { $this->outputLine("Hello %s!", array($name)); } } 17
  18. 18. Das Wesentliche im Blick /**Domain-Driven Design * Paper submitted by * a speaker * @scope prototype * @entityEine Methode die ... */ class Paper { • zu aussagekräftigen Modellen /** verhilft * @var Participant */ protected $author; • eine gemeinsames Vokabular /** etabliert * @var string */ protected $title; • das Design von komplexen /** Anwendungen erleichtert * @var string */ protected $shortAbstra ct; /** * @var string */ protected $abstract; 18
  19. 19. Domain-Driven DesignDomain Aktivität oder Geschäftsdomäne des NutzersDomain-Driven Design bedeutet • Fokus auf die Domäne und Domänen-Logik • sorgfältiges Mapping der Konzepte auf das Model • etablieren einer gemeinsamen Sprache innerhalb des gesamten Projekt-Teams 19
  20. 20. Domain-Driven DesignUbiquitous Language • allgemeingegenwärtige Begriffe sind wichtig für die Kommunitation aller Beteiligten • benutze dieselben Begriffe für • Diskussionen • Modeling • Entwicklung • Dokumentation 20
  21. 21. Domain-Driven Design Spannend un d unterhaltsamStandardwer k 21
  22. 22. Object ManagementDependency Injection • anstatt eine Instanz einer Klasse zu erzeugen oder sie aktiv zu holen, wird sie injected • fördert lose Kopplung und starke Kohäsion ‣ stabilerer, wiederverwendbarer Code 22
  23. 23. Object ManagementFLOW3s Ansatz für Dependency Injection • eine der ersten PHP Implementierungen (2006 begonnen, seitdem ständig verbessert) • Object Management für den gesamten Lebenszyklus aller Objekte • keine unnötige Konfiguration wenn die Informationen automatisch ermittelt werden können (Autowiring) • intuitive Nutzung ohne böse (magische) Überraschungen • schnell! (wie selbstgemacht oder schneller) 23
  24. 24. Constructor Injection<?phpnamespace AcmeDemoController;use TYPO3FLOW3MVCControllerActionController;use AcmeDemoServiceGreeterService;class DemoController extends ActionController { /** * @var AcmeDemoServiceGreeterService */ protected $greeterService; /** * @param AcmeDemoServiceGreeterService */ public function __construct(AcmeDemoServiceGreeterService $greeterService) { $this->greeterService = $greeterService; } /** * @param string $name */ public function helloAction($name) { return $this->greeterService->hello($name); }} 24
  25. 25. Setter Injection<?phpnamespace AcmeDemoController;use TYPO3FLOW3MVCControllerActionController;use AcmeDemoServiceGreeterService;class DemoController extends ActionController { /** * @var AcmeDemoServiceGreeterService */ protected $greeterService; /** * @param AcmeDemoServiceGreeterService */ public function injectGreeterService(AcmeDemoServiceGreeterService $greeterService) { $this->greeterService = $greeterService; } /** * @param string $name */ public function helloAction($name) { return $this->greeterService->hello($name); }} 25
  26. 26. Property Injection<?phpnamespace AcmeDemoController;use TYPO3FLOW3Annotations as FLOW3;use TYPO3FLOW3MVCControllerActionController;use AcmeDemoServiceGreeterService;class DemoController extends ActionController { /** * @var AcmeDemoServiceGreeterService * @FLOW3Inject */ protected $greeterService; /** * @param string $name */ public function helloAction($name) { return $this->greeterService->hello($name); }} 26
  27. 27. Objects.yaml TYPO3FLOW3SecurityCryptographyRsaWalletServiceInterface: className: AcmeFLOW3SecurityCryptographyRsaWalletServicePhp scope: singleton properties: keystoreCache: object: factoryObjectName: TYPO3FLOW3CacheCacheManager factoryMethodName: getCache arguments: 1: value: FLOW3_Security_Cryptography_RSAWallet 27
  28. 28. Object Managementclass Customer { /** * @FLOW3Inject * @var CustomerNumberGenerator */ protected $customerNumberGenerator; ...}$customer = new Customer();$customer->getCustomerNumber(); 28
  29. 29. Object Management <?php declare(ENCODING = u tf-8); namespace AcmeConfe renceDoma inModelConference; /**FLOW3 erzeugt Proxy Klassen * Autogenerated Prox y Classum DI und AOP zu ermöglichen * @TYPO3FLOW3Annot * @ TYPO3FLOW3Anno ationsScope(“protot ype”) tationsEntity */ class Paper extends • new Operator wird FLOW3PersistenceA Paper_Original implem spectPersistenceMag ents TYPO3FLOW3Obj icInterface { ect unterstützt /** * @var string * @DoctrineORMMapp ingId • Proxy Klassen werden on- * @DoctrineORMMapp * introduced by TYPO ingColumn(length="4 0") 3FLOW3Persistence the-fly erzeugt */ AspectPersistenceMa protected $FLOW3_Per sistence_Identifier = NULL; • im Production Kontext ist private $FLOW3_Aop_P roxy_targetMethodsAn dGroupedAdvices = ar ra sämtlicher Code statisch private $FLOW3_Aop_P roxy_groupedAdviceCh ains = array(); private $FLOW3_Aop_P roxy_methodIsInAdvic eMode = array(); /** * Autogenerated Prox y Method */ public function __co nstruct() { 29
  30. 30. PersistenzObjekt Persistenz im Fluss • basiert auf Doctrine 2 • nahtlose Integration in FLOW3 • bietet alle Doctrine 2 Features • nutzt UUIDs • Low Level Persistence API: • ermöglichte eingene Persistenz Mechanismen (anstelle von Doctrine 2) • CouchDB 30
  31. 31. Persistenz Basics • Repository von FLOW3 per DI geben lassen • Domänenobjekte (fast) wie ohne Framework behandeln // Create a new customer and persist it: $customer = new Customer("Robert"); $this->customerRepository->add($customer); // Update a customer: $customer->setName("I, Robot"); $this->customerRepository->update($customer); // Find an existing customer: $otherCustomer = $this->customerRepository->findByFirstName("Karsten"); // … and delete it: $this->customerRepository->remove($otherCustomer); 31
  32. 32. Doctrine und Validierung mit Annotationsnamespace TYPO3BlogDomainModel;use TYPO3FLOW3Annotations as FLOW3;use DoctrineORMMapping as ORM;/** * @FLOW3Entity */class Blog { /** * @var string * @FLOW3Validate(“Text”) * @FLOW3Validate(type=”StringLength”, options={“minimum” = 1, “maximum” = 80}) * @ORMColumn(length=80) */ protected $title; /** * @var DoctrineCommonCollectionsCollection<TYPO3BlogDomainModelPost> * @ORMOneToMany(mappedBy="blog") * @ORMOrderBy({"date" = "DESC"}) */ protected $posts; ...} 32
  33. 33. Persistenz-relevante AnnotationsFLOW3Entity Deklariert eine Klasse als "Entity"ORMColumn Nimmt Einfluss auf das Datenbankfeld das mit der Class Property zusammenhängt. Besonders sinnvoll bei Text-Inhalten (type="text").ORMManyToOne Definiert Relationen zu Class-Properties andererORM OneToMany Entities. Im Gegensatz zu reinem Doctrine mussORM ManyToMany targetEntity nicht angegeben werden sondern wirdORM OneToOne aus der @var Annotation übernommen. cascade kaskadiert Operationen auf alle zusammengehörigen Objekte innerhalb des Aggregates. Wird ebenfalls automatisch gesetzt. 33
  34. 34. Persistenz-relevante Annotationsvar Definiert den Typ, Collections werden in spitzen Klammern definiert: DoctrineCommonCollectionsCollection<TYPO3ConferenceDomainModelComment>FLOW3Transient Die Property wird ignoriert – also weder persistiert noch wiederhergstelltFLOW3Identity Markiert die Property als Teil der IdentitätORMId Definiert die Property, die als Primärschlüssel in der Datenbank dient. In FLOW3 wird dies automatisch im Hintergrund definiert. 34
  35. 35. Nutzung von RepositoriesDas generische Basis-Repository unterstützt jedes Backend, dasDoctrine-Basis-Repository bietet Zugriff auf Doctrine-Spezifika.Die Nutzung der Basis-Repositories von FLOW3 • Stellt grundlegende Methoden breit: findAll(), countAll(), remove(), removeAll() • Bietet automatische Methoden um nach Properties zu suchen: findByPropertyName($value), findOneByPropertyName($value)Eigene, spezialisierte Finder-Methoden werden einfach dem eigenenRepository hinzugefügt. 35
  36. 36. Eigene Abfragen mit dem QOMPostRepository.phpclass PostRepository extends FLOW3PersistenceRepository { /** * Finds most recent posts excluding the given post * * @param TYPO3BlogDomainModelPost $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(TYPO3BlogDomainModelPost $post, $limit = 20) { $query = $this->createQuery(); $posts = $query->matching($query->equals(blog, $post->getBlog())) ->setOrderings(array( date => TYPO3FLOW3PersistenceQueryInterface::ORDER_DESCENDING )) ->setLimit($limit) ->execute() ->toArray(); unset($posts[array_search($post, $posts)]); return $posts; }} 36
  37. 37. Eigene Abfragen mit DQLPostRepository.phpclass PostRepository extends FLOW3PersistenceDoctrineRepository { /** * Finds most recent posts excluding the given post * * @param TYPO3BlogDomainModelPost $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(TYPO3BlogDomainModelPost $post, $limit = 20) { // this is an alternative way of doing this when extending the Doctrine 2 // specific repository and using DQL. $query = $this->entityManager->createQuery(SELECT p FROM TYPO3BlogDomainModelPost p WHERE p.blog = :blog AND NOT p= :excludedPost ORDER BY p.date DESC); return $query ->setMaxResults($limit) ->execute(array(blog => $post->getBlog(), excludedPost => $post)); }} 37
  38. 38. Schema ManagementDoctrine 2 Migrations• Migrationen ermöglichen Schema Versionierung und das Deployment von Änderungen• Migrationen sind der empfohlene Weg für Datanbank Anpassungen• Kann auch zum Deplyoment und Update bestehender Daten genutzt werden• Tools für das Erstellen und Deployen von Migrationen sind in FLOW3 enthalten 38
  39. 39. Schema ManagementAusführen von Migrationen• notwendig nach Neuinstallation oder Upgrades:$ ./flow3 doctrine:migrate 39
  40. 40. Schema ManagementMigrations-Status prüfen$ ./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: TYPO3FLOW3PersistenceDoctrineMigrations >> Migrations Directory: /…/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 40
  41. 41. Schema ManagementMigrationen erstellen$ ./flow3 doctrine:migrationgenerateGenerated new migration class!Next Steps:- Move …/Version20120329190824.php to YourPackage/Migrations/Mysql/- Review and adjust the generated migration.- (optional) execute the migration using ./flow3 doctrine:migrate 41
  42. 42. Schema ManagementMigrations-Dateien enthalten meist wirklich einfachen Code/** * Rename FLOW3 tables to follow FQCN */class Version20110824124835 extends AbstractMigration { /** * @param Schema $schema * @return void */ public function up(Schema $schema) { $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql"); $this->addSql("RENAME TABLE flow3_policy_role TO typo3_flow3_security_policy_role"); $this->addSql("RENAME TABLE flow3_resource_resource TO typo3_flow3_resource_resource"); $this->addSql("RENAME TABLE flow3_resource_resourcepointer TOtypo3_flow3_resource_resourcepointer"); $this->addSql("RENAME TABLE flow3_resource_securitypublishingconfiguration TOtypo3_flow3_security_authorization_resource_securitypublis_6180a"); $this->addSql("RENAME TABLE flow3_security_account TO typo3_flow3_security_account"); } 42
  43. 43. Schema ManagementSchema aktualisieren ohne Migrations zu verwenden• Für mache Situationen reichen Updates ohne Migrations$ ./flow3 doctrine:create$ ./flow3 doctrine:update• Hilfreich bei • der Nutzung existierender Datenbank-Dumps • fehlenden Migrations für die genutzte Datenbank • SQLite (beschränkte Unterstützung für Schema-Änderungen) 43
  44. 44. Templating-ZenFLOW3 bietet eine elegante, flexible und sichereTemplating-Engine: Fluid • Templates sind valides HTML • Templates enthalten keinen PHP-Code • Object-Zugriff, Kontrollstrukturen, Schleifen… • Designer-Kompatibel • Erweiterbar (ViewHelper, Widgets) 44
  45. 45. FluidBeispiel einer String-Zuweisung an eine Fluid-Variable: // in the action controller: $this->view->assign(title, Welcome to Fluid); <!-- in the Fluid template: --> <head> <title>{title}</title> </head> 45
  46. 46. FluidVariablen können auch Objekte sein: // in the action controller: $this->view->assign(conference, $conference); <!-- in the Fluid template: --> <div class="venue"> <p>Venue Street: {conference.venue.street}</p> </div> 46
  47. 47. Fluidif-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> 47
  48. 48. Fluidfor-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> 48
  49. 49. Fluidfor-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> 49
  50. 50. FluidViewHelper – hier der link.action ViewHelper: <!-- in the Fluid template: --> {namespace f=F3FluidViewHelpers} <f:link.action action="delete" arguments="{post: post, really: yes}"> Delete this post </f:link.action> 50
  51. 51. Formulare <?php namespace TYPO3BlogDomainModel; /** * A blog post * * @FLOW3Scope(“prototype”) * @FLOW3Entity */ class Post { /** * @var string * @FLOW3Validate(type=“StringLength”, options={“minimum” = 10}) */ protected $title; /** * @var string * @FLOW3Validate(type=“StringLength”, options={“maximum” = 50}) */ protected $author; /** 51
  52. 52. Formulare<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.textfield 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.textfield property="image.title" value="My image title" /> <f:form.upload property="image.originalResource" /></f:form> 52
  53. 53. Formulare<?phpnamespace TYPO3BlogController;use TYPO3FLOW3MVCControllerActionController;class PostController extends ActionController { /** * @FLOW3Inject * @var TYPO3BlogDomainRepositoryPostRepository */ protected $postRepository; /** * Creates a new post * * @param TYPO3BlogDomainModelPost $newPost added to the repository * @return void */ public function createAction(TYPO3BlogDomainModelPost $newPost) { $this->blog->addPost($newPost); $this->addFlashMessage(Your new post was created.); $this->redirect(index); } 53
  54. 54. ValidierungValidierung behandelt verschiedene Dinge• hereinkommende Daten müssen abgesichert werden • kein böses Markup in Content vom Client• Die Integrität des Domain Model muss sichergestellt werden • Eine E-Mail muss (syntaktisch) korrekt sein • Kreditkarten-Nummern sollten nur aus Zahlen bestehen 54
  55. 55. ValidierungValidierung in FLOW3• keiner möchte solche Prüfungen in seinen Controllern implementieren• FLOW3 trennt die Validierung von den Aufgaben des Controllers • kein PHP-Code für die Validierung notwendig • Regeln werden durch Annotations definiert 55
  56. 56. ValidierungValidierungs-Modelle• Base Properties Minimale Anforderungen an individuelle Properties eines Models• Base Model Minimale Anforderungen an eine Kombination von Properties eines Models, Prüfung ggf. durch eigenen Validator• Supplemental Zusätzliche Anforderungen an ein Model in spezifischen Situationen (z.B. für eine bestimmte Action-Methode) 56
  57. 57. ValidierungBase Properties• Validierungsregeln direkt an den Properties /** * @var string * @FLOW3Validate(type=”StringLength”, options={“minimum” = 10}) */ protected $title; /** * @var string * @FLOW3Validate(type=”StringLength”, options={“maximum” = 50}) */ protected $author; 57
  58. 58. ValidierungValidatoren• Validatoren aus FLOW3 mit verkürztem Namen ansprechen • Count, Float, NotEmpty, RegularExpression, Uuid, DateTime, NumberRange, StringLength, Alphanumeric, Integer, Number, String, EmailAddress, Label, Raw, Text• Eigene Validatoren müssen das ValidatorInterface implementieren• Um sie zu nutzen, den fully qualified class name angeben /** * @var MyStuffDomainModelStuff * @FLOW3Validate(type=”MyStuffDomainValidatorStuffValidator”) */ protected $stuff; 58
  59. 59. Property MapperEigenschaften von A nach B übertragen • ermöglicht komplette oder teilweise Kopien von Objekten und Objektstrukturen • wird vom MVC-Framework für das Mapping von rohen GET- und POST-Argumenten auf Argument-Objekte verwendet 59
  60. 60. Property Mapper $articleArray = array( headline => Hello World!, story => Just a demo ... ); $article = $mapper->convert($sourceArray, Acme.DemoDomainModelArticle); 60
  61. 61. Resource Management Bilder Upload Resourcen werden wie andere Properties auch in Formular eingebunden:: <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> 61
  62. 62. Property Mapper Verschachtelte Objektstrukturen erlauben Aus Sicherheitsgründen ist dies standardmäßig abgeschaltet /** * @return void */ public function initializeUpdateAction() { $this->arguments[blog]->getPropertyMappingConfiguration() ->allowCreationForSubProperty(authorPicture); $this->arguments[blog]->getPropertyMappingConfiguration() ->allowModificationForSubProperty(authorPicture); } 62
  63. 63. SecurityTouchless Security, Flow-Style • Security wird zentralisiert umgesetzt (durch AOP) • Basiert auf unseren Erfahrungen im TYPO3-Projekt und der Spring Security (Java framework) • Bietet Authentifizierung, Authorisierung, Rollen, ACLs, … • Kann beliebige Methoden-Aufrufe abfangen • Filtert den Zugriff auf Content durch das Umschreiben von Abfragen in der Persistenz • Erweiterbar um neue Mechanismen zu Authentifizierung und Authorisierung 63
  64. 64. Security Policy# ## Security policy definition ## ## This file contains the security policy configuration for the ## Conference package #resources: methods: TYPO3_Conference_AccountActions: method(TYPO3ConferenceControllerAccount(Overview|Spe TYPO3_Conference_MyPapersActions: method(TYPO3ConferenceControllerConferencePaperContdelete)Action()) TYPO3_Conference_PaperReviewActions: method(TYPO3ConferenceControllerConferencePaperC TYPO3_Conference_PaperVotingResultActions: method(TYPO3ConferenceControllerConferenceroles: Conference_Visitor: [] Speaker: [Conference_Visitor] ConfirmedSpeaker: [Conference_Visitor] TrackChair: [Conference_Visitor] Administrator: [Conference_Visitor]acls: Conference_Visitor: methods: TYPO3_Conference_AccountActions: GRANT Speaker: methods: 64
  65. 65. SecurityCross-Site Request Forgery • ermöglicht einem Angreifer die Ausführung privilegierter Operationen ohne selbst authentifiziert zu sein • die Gefahr liegt in der Nutzung von manipulierten Links oder Formularen während man am System angemeldet ist • URL-Shortener bieten eine gute Basis für solche Angriffe… 65
  66. 66. SecurityCross-Site Request Forgery verhindern • Ein (wirklich!) zufälliges Token an jeden Link und jedes Formular anhängen • und die Korrektheit dieses Tokens vor jeder Aktion überprüfen • Das Token so oft wie möglich ändern um zu verhindern das ein gültiger Link geschickt werden kann während der Benutzer angemeldet ist • In den meisten Fällen reicht es aus, bei jedem Login ein neues Token zu erzeugen – das ist die Standard-Einstellung in FLOW3 66
  67. 67. SecurityCSRF-Schutz in FLOW3 • Man darf das Token nie vergessen • FLOW3 fügt das CSRF-Token automatisch zu jedem • Link der generiert wird und • jedem mit Fluid erzeugten Formular hinzu • und prüft das Token vor jeder Action-Methode • Der CSRF-Schutz kann durch @FLOW3SkipCsrfProtection je Methode abgeschaltet werden 67
  68. 68. AOPAspekt-Orientierte Programmierung • ist ein Programmier-Paradigma • kapselt Zuständigkeiten um die Modularisierung zu verbessern • OOP modularisiert Zuständigkeiten in Objekte • AOP modularisiert cross-cutting concerns in Aspekten • FLOW3 macht die Nutzung von AOP in PHP einfach (und überhaupt erst möglicht) 68
  69. 69. AOP /** * @aspectFLOW3 nutzt AOP für ... * @introduce */ TYPO3FLOW3P ersistenceAs pectPersiste class Persist nceMagicInter enceMagicAspe face, TYP ct { • Persistenz /** * @pointcut c lassTaggedWit */ h(entity) || classTaggedWi th(valueobjec • Logging public functi on isEntityOr ValueObject() {} t) /** * @var string • Debugging * @Id * @Column(len gth="40") * @introduce TYPO3FLOW3P */ ersistenceAs pectPersiste • Security protected $FL OW3_Persisten ce_Identifier ; nceMagicAspec t->isE /** * After retur ning advice, * making sure w e have an UUI * @param TYP D for each an O3FLOW3AOP d every * @return voi JoinPointInte d rface $joinPo * @before cla int The curre ssTaggedWith( nt join */ entity) && me thod(.*->__co public functi nstruct()) on generateUU $proxy = $joi ID(TYPO3FLO nPoint->getPr W3AOPJoinPo oxy(); intInterface TYPO3FLOW3 $joinPoin ReflectionOb } jectAccess::s etProperty($p r o x y , FLOW3_ Persi 69
  70. 70. Signal-Slot Event HandlingSignal • kann jederzeit ausgelöst werden • kann frei vom Entwickler definiert werdenSlot • wird aufgerufen wenn ein Signal ausgelöst wurde • jede Methode kann als Slot genutzt werdenJedes Signal kann mit jedem Slot verbunden werden 70
  71. 71. Signal-Slot Event Handling /** * @param TYPO3BlogDomainModelPost $post * @param TYPO3BlogDomainModelComment $newComment * @return void */ public function createAction(TYPO3BlogDomainModelPost $post, TYPO3BlogDomainModelComment $newComment) { $post->addComment($newComment); $this->emitCommentCreated($newComment, $post); … } /** * @param TYPO3BlogDomainModelComment $comment * @param TYPO3BlogDomainModelPost $post * @return void * @FLOW3Signal */ protected function emitCommentCreated(TYPO3BlogDomainModelComment $comment, TYPO3BlogDomainModelPost $post) {} 71
  72. 72. Signal-Slot Event HandlingIm Bootstrap werden Signals mit Slots verdrahtet: /** * Invokes custom PHP code directly after the package manager has been * initialized. * * @param TYPO3FLOW3CoreBootstrap $bootstrap The current bootstrap * @return void */ public function boot(TYPO3FLOW3CoreBootstrap $bootstrap) { $dispatcher = $bootstrap->getSignalSlotDispatcher(); $dispatcher->connect( TYPO3BlogControllerCommentController, commentCreated, TYPO3BlogServiceNotification, sendNewCommentNotification ); } 72
  73. 73. Signal-Slot Event HandlingJede Methode kann ein Slot sein: /** * @param TYPO3BlogDomainModelComment $comment * @param TYPO3BlogDomainModelPost $post * @return void */ public function sendNewCommentNotification( TYPO3BlogDomainModelComment $comment, TYPO3BlogDomainModelPost $post) { $mail = new TYPO3SwiftMailerMessage(); $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(); } 73
  74. 74. Signal-Slot Event HandlingSlots können auch statische Methoden sein: /** * Invokes custom PHP code directly after the package manager has been * initialized. * * @param TYPO3FLOW3CoreBootstrap $bootstrap The current bootstrap * @return void */ public function boot(TYPO3FLOW3CoreBootstrap $bootstrap) { $dispatcher = $bootstrap->getSignalSlotDispatcher(); $dispatcher->connect( TYPO3BlogServiceNotification, ::aStaticMethodCanBeUsed ); } 74
  75. 75. Speed und PerformanceFür den ungeduldigen Nutzer: • multi-layered, tagged Caches • Diverse Cache-Backends (File, Memcached, APC, Redis, PDO, ...) • Unterstützung für Reverse-Proxy (Varnish, ESI) ist in Arbeit • Code-Kompilierung • Regelmäßige Benchmarks • Fokus auf gute Skalierbarkeit 75
  76. 76. Mehr Features • Resource Management (CDNs, private Ressourcen, ...) • Logging • File Monitoring • Configuration Management • Routing • REST / SOAP • ... 76
  77. 77. Thank You! • These slides can be found at: http://speakerdeck.com/u/kdambekalns | http://slideshare.net/kfish • Give me feedback: karsten@typo3.org | karsten@dambekalns.de • Download FLOW3: http://flow3.typo3.org • Follow me on twitter: @kdambekalns • Support me using 77

×