2. Karsten Dambekalns
Co-Lead von TYPO3 Phoenix und FLOW3
34 Jahre alt
lebt in Lübeck
1 Frau, 3 Söhne, 1 Espressomaschine
fährt gern Kanadier und klettert
2
3. Auf einen Blick
FLOW3 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. Grundlage für das Next-Generation CMS
TYPO3 Phoenix ist das komplett
neue Enterprise CMS
• Content Repository, Workspaces,
Versionierung, i18n, neues UI ...
• powered by FLOW3
• FLOW3 kompatible Code-Basis
• benutze TYPO3 Features in
eigenen FLOW3 Applikationen
4
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 help
FLOW3 1.1.0-dev ("Development" context)
usage: ./flow3 <command identifier>
…
$ FLOW3_CONTEXT=Production ./flow3 help
FLOW3 1.1.0-dev ("Production" context)
usage: ./flow3 <command identifier>
…
8
11. Git Submodule aktualisieren (bleeding edge)
$ git submodule foreach "git checkout master"
-✂-----✂-----✂-----✂-----✂-----✂-----✂-----✂-----✂-----✂-----✂-----✂-
$ git submodule foreach "git pull --rebase"
Entering 'Build/Common'
First, rewinding head to replay your work on top of it...
Fast-forwarded master to 6f27f1784240b414e966ce0e5a12e23cb2f7ab02.
Entering 'Packages/Application/TYPO3'
First, rewinding head to replay your work on top of it...
Fast-forwarded master to 5187430ee44d579ae2bac825e2a069c4cd3Acme8a4.
Entering 'Packages/Application/TYPO3CR'
First, rewinding head to replay your work on top of it...
Fast-forwarded master to b1f5331aa51d390fa3d973404Acme1b9fd773f7059.
Entering 'Packages/Application/Twitter'
Current branch master is up to date.
…
11
12. Kommandozeile
$ ./flow3 help
FLOW3 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. Kommandozeile
$ ./flow3 help kickstart:package
Kickstart a new package
COMMAND:
typo3.kickstart:kickstart:package
USAGE:
./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
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. Controller Kickstart
$ ./flow3 help kickstart:actioncontroller
Kickstart a new action controller
COMMAND:
typo3.kickstart:kickstart:actioncontroller
USAGE:
./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. 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. Das Wesentliche im Blick
/**
Domain-Driven Design * Paper submitted by
*
a speaker
* @scope prototype
* @entity
Eine 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. Domain-Driven Design
Domain
Aktivität oder Geschäftsdomäne des Nutzers
Domain-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. Domain-Driven Design
Ubiquitous Language
• allgemeingegenwärtige Begriffe sind wichtig für
die Kommunitation aller Beteiligten
• benutze dieselben Begriffe für
• Diskussionen
• Modeling
• Entwicklung
• Dokumentation
20
22. Object Management
Dependency 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. Object Management
FLOW3's 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. Constructor Injection
<?php
namespace 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. Setter Injection
<?php
namespace 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. Property Injection
<?php
namespace 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
29. Object Management
<?php
declare(ENCODING = 'u
tf-8');
namespace AcmeConfe
renceDoma inModelConference;
/**
FLOW3 erzeugt Proxy Klassen * Autogenerated Prox
y Class
um 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. Persistenz
Objekt 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. 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. Doctrine und Validierung mit Annotations
namespace 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. Persistenz-relevante Annotations
FLOW3Entity 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 anderer
ORM OneToMany Entities. Im Gegensatz zu reinem Doctrine muss
ORM ManyToMany targetEntity nicht angegeben werden sondern wird
ORM OneToOne aus der @var Annotation übernommen.
cascade kaskadiert Operationen auf alle
zusammengehörigen Objekte innerhalb des
Aggregates. Wird ebenfalls automatisch gesetzt.
33
34. Persistenz-relevante Annotations
var Definiert den Typ, Collections werden in spitzen
Klammern definiert:
DoctrineCommonCollectionsCollection<TYPO3ConferenceDomainModelComment>
FLOW3Transient Die Property wird ignoriert – also weder
persistiert noch wiederhergstellt
FLOW3Identity Markiert die Property als Teil der Identität
ORMId Definiert die Property, die als Primärschlüssel in
der Datenbank dient. In FLOW3 wird dies
automatisch im Hintergrund definiert.
34
35. Nutzung von Repositories
Das generische Basis-Repository unterstützt jedes Backend, das
Doctrine-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 eigenen
Repository hinzugefügt.
35
36. Eigene Abfragen mit dem QOM
PostRepository.php
class 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 $post's 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. Eigene Abfragen mit DQL
PostRepository.php
class 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 $post's 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. Schema Management
Doctrine 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
41. Schema Management
Migrationen erstellen
$ ./flow3 doctrine:migrationgenerate
Generated 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. Schema Management
Migrations-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 TO
typo3_flow3_resource_resourcepointer");
$this->addSql("RENAME TABLE flow3_resource_securitypublishingconfiguration TO
typo3_flow3_security_authorization_resource_securitypublis_6180a");
$this->addSql("RENAME TABLE flow3_security_account TO typo3_flow3_security_account");
}
42
43. Schema Management
Schema 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. Templating-Zen
FLOW3 bietet eine elegante, flexible und sichere
Templating-Engine: Fluid
• Templates sind valides HTML
• Templates enthalten keinen PHP-Code
• Object-Zugriff, Kontrollstrukturen, Schleifen…
• Designer-Kompatibel
• Erweiterbar (ViewHelper, Widgets)
44
45. Fluid
Beispiel 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. Fluid
Variablen 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. 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>
47
48. 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>
48
49. 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>
49
50. Fluid
ViewHelper – 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. 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
53. Formulare
<?php
namespace 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. Validierung
Validierung 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. Validierung
Validierung 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. Validierung
Validierungs-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. Validierung
Base 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. Validierung
Validatoren
• 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. Property Mapper
Eigenschaften 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
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. 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. Security
Touchless 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
65. Security
Cross-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. Security
Cross-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. Security
CSRF-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. AOP
Aspekt-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. AOP
/**
* @aspect
FLOW3 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. Signal-Slot Event Handling
Signal
• kann jederzeit ausgelöst werden
• kann frei vom Entwickler definiert werden
Slot
• wird aufgerufen wenn ein Signal ausgelöst wurde
• jede Methode kann als Slot genutzt werden
Jedes Signal kann mit jedem Slot verbunden werden
70
72. Signal-Slot Event Handling
Im 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. Signal-Slot Event Handling
Jede 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. Signal-Slot Event Handling
Slots 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. Speed und Performance
Fü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
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