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
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. $ sudo usermod -a -G www-data karsten $ sudo dscl . -append /Groups/_www GroupMembership karsten Linux: Mac OS X: 6
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
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
<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
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
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
TYPO3\FLOW3\Mvc\Controller\CommandController; 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
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
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
$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); • Repository von FLOW3 per DI geben lassen • Domänenobjekte (fast) wie ohne Framework behandeln 31
Einfluss auf das Datenbankfeld das mit der Class Property zusammenhängt. Besonders sinnvoll bei Text-Inhalten (type="text"). ORM\ManyToOne ORM\ OneToMany ORM\ ManyToMany ORM\ OneToOne Definiert Relationen zu Class-Properties anderer Entities. Im Gegensatz zu reinem Doctrine muss targetEntity nicht angegeben werden sondern wird aus der @var Annotation übernommen. cascade kaskadiert Operationen auf alle zusammengehörigen Objekte innerhalb des Aggregates. Wird ebenfalls automatisch gesetzt. 33
Klammern definiert: \Doctrine\Common\Collections\Collection<\TYPO3\Conference\Domain\Model\Comment> FLOW3\Transient Die Property wird ignoriert – also weder persistiert noch wiederhergstellt FLOW3\Identity Markiert die Property als Teil der Identität ORM\Id Definiert die Property, die als Primärschlüssel in der Datenbank dient. In FLOW3 wird dies automatisch im Hintergrund definiert. 34
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
/** * Finds most recent posts excluding the given post * * @param \TYPO3\Blog\Domain\Model\Post $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(\TYPO3\Blog\Domain\Model\Post $post, $limit = 20) { $query = $this->createQuery(); $posts = $query->matching($query->equals('blog', $post->getBlog())) ->setOrderings(array( 'date' => \TYPO3\FLOW3\Persistence\QueryInterface::ORDER_DESCENDING )) ->setLimit($limit) ->execute() ->toArray(); unset($posts[array_search($post, $posts)]); return $posts; } } PostRepository.php 36
* Finds most recent posts excluding the given post * * @param \TYPO3\Blog\Domain\Model\Post $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(\TYPO3\Blog\Domain\Model\Post $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 \TYPO3\Blog\Domain\Model\Post 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)); } } PostRepository.php 37
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
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
ohne Migrations zu verwenden • Für mache Situationen reichen Updates ohne Migrations • Hilfreich bei • der Nutzung existierender Datenbank-Dumps • fehlenden Migrations für die genutzte Datenbank • SQLite (beschränkte Unterstützung für Schema-Änderungen) 43
<f:then>There are some comments.</f:then> <f:else>There are no comments.</f:else> </f:if> // in the action controller: $this->view->assign('post', $blogPost); 47
{ /** * @FLOW3\Inject * @var \TYPO3\Blog\Domain\Repository\PostRepository */ protected $postRepository; /** * Creates a new post * * @param \TYPO3\Blog\Domain\Model\Post $newPost added to the repository * @return void */ public function createAction(\TYPO3\Blog\Domain\Model\Post $newPost) { $this->blog->addPost($newPost); $this->addFlashMessage('Your new post was created.'); $this->redirect('index'); } 53
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
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
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
• 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 \My\Stuff\Domain\Model\Stuff * @FLOW3\Validate(type=”My\Stuff\Domain\Validator\StuffValidator”) */ protected $stuff; 58
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
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
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
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
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 @FLOW3\SkipCsrfProtection je Methode abgeschaltet werden 67
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
• Debugging • Security /** * @aspect * @introduce TYPO3\FLOW3\Persistence\Aspect\PersistenceMagicInterface, TYP */ class PersistenceMagicAspect { /** * @pointcut classTaggedWith(entity) || classTaggedWith(valueobject) */ public function isEntityOrValueObject() {} /** * @var string * @Id * @Column(length="40") * @introduce TYPO3\FLOW3\Persistence\Aspect\PersistenceMagicAspect->isE */ protected $FLOW3_Persistence_Identifier; /** * After returning advice, making sure we have an UUID for each and every * * @param \TYPO3\FLOW3\AOP\JoinPointInterface $joinPoint The current join * @return void * @before classTaggedWith(entity) && method(.*->__construct()) */ public function generateUUID(\TYPO3\FLOW3\AOP\JoinPointInterface $joinPoin $proxy = $joinPoint->getProxy(); \TYPO3\FLOW3\Reflection\ObjectAccess::setProperty($proxy, 'FLOW3_Persi } 69
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
after the package manager has been * initialized. * * @param \TYPO3\FLOW3\Core\Bootstrap $bootstrap The current bootstrap * @return void */ public function boot(\TYPO3\FLOW3\Core\Bootstrap $bootstrap) { $dispatcher = $bootstrap->getSignalSlotDispatcher(); $dispatcher->connect( 'TYPO3\Blog\Controller\CommentController', 'commentCreated', 'TYPO3\Blog\Service\Notification', 'sendNewCommentNotification' ); } Im Bootstrap werden Signals mit Slots verdrahtet: 72
after the package manager has been * initialized. * * @param \TYPO3\FLOW3\Core\Bootstrap $bootstrap The current bootstrap * @return void */ public function boot(\TYPO3\FLOW3\Core\Bootstrap $bootstrap) { $dispatcher = $bootstrap->getSignalSlotDispatcher(); $dispatcher->connect( 'TYPO3\Blog\Service\Notification', '::aStaticMethodCanBeUsed' ); } Slots können auch statische Methoden sein: 74
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
• Give me feedback: [email protected] | [email protected] • Download FLOW3: http://flow3.typo3.org • Follow me on twitter: @kdambekalns • Support me using Thank You! 77