Upload
others
View
14
Download
0
Embed Size (px)
Citation preview
(TYPO3)FLOW
?
NEOSCMSEXTBASE
Model Controller ViewController
Model Controller ViewController
Modellierung&
SpeicherungSteuerung des
ProgrammflussesDarstellung
Model Controller ViewController
Domain-drivenDesign TYPO3 FluidDependency
Injection
Model Controller ViewController
Domain-drivenDesign TYPO3 FluidDependency
Injection
Aspect-oriented Programming
Model Controller ViewController
Domain-drivenDesign
Entwickler
Kunde
Entwickler
Kunde
Entwickler
Kunde
Entwickler
Kunde
Entwickler
Kunde
Domänen-
ModellubiquitäreSprache
Entwickler
Kunde
Domänen-
ModellubiquitäreSprache
KUH● Name● Geburtstag● …
WEIDE● Größe● Ort● …
FARBE● RGB-Wert
GRASHALM● Länge● …
KUH● Name● Geburtstag● …
WEIDE● Größe● Ort● …
FARBE● RGB-Wert
GRASHALM● Länge● …
Entitäten
KUH● Name● Geburtstag● …
WEIDE● Größe● Ort● …
FARBE● RGB-Wert
GRASHALM● Länge● …
Wertobjekt
KUH● Name● Geburtstag● …
WEIDE● Größe● Ort● …
FARBE● RGB-Wert
GRASHALM● Länge● …
lebt auf
hat
hat
Assoziationen
KUH● Name● Geburtstag● …
WEIDE● Größe● Ort● …
FARBE● RGB-Wert
GRASHALM● Länge● …
1n
1
n
n
1
Assoziationen
Aggregate
KUH● Name● Geburtstag● …
WEIDE● Größe● Ort● …
FARBE● RGB-Wert
GRASHALM● Länge● …
GRASTYP● Name
KUHRepository
WEIDERepository
FARBE● RGB-Wert
GRASHALM● Länge● …
GRASTYP● Name
use TYPO3\Flow\Annotations as Flow;use Doctrine\ORM\Mapping as ORM;
/** * @Flow\Entity */class Cow {
/** * @var string * @Flow\Identity * @ORM\Column(length=80)
*/protected $name;
/** * @var \DateTime
*/protected $birthday;
…
use TYPO3\Flow\Annotations as Flow;
/**
* @Flow\Scope("singleton")
*/
class CowRepository extends \TYPO3\Flow\Persistence\Repository{}
Model Controller ViewController
DependencyInjection
http://cows.local/<PACKAGE>/<CONTROLLER>/<ACTION>
http://cows.local/my.package/cow/list
class CowController extends \TYPO3\Flow\Mvc\Controller\ActionController {
public function listAction() {
$cows = $this->cowRepository->findAll();
$this->view->assign("cows", $cows);
}
}
class CowController extends \TYPO3\Flow\Mvc\Controller\ActionController {
public function listAction() {
$cows = $this->cowRepository->findAll();
$this->view->assign("cows", $cows);
}
}
class CowController extends \TYPO3\Flow\Mvc\Controller\ActionController {
/** * @var MY\PACKAGE\Domain\Repository\CowRepository * @Flow\Inject */protected $cowRepository;
public function listAction() {
$cows = $this->cowRepository->findAll();
$this->view->assign("cows", $cows);
}
}
Dependency Injection
Dependency Injection
"Dependency Injection" is a 25-dollar term for a 5-cent concept
● Inversion of ControlKontrolle über den Programmfluss wird an eine (übergeordnete) Komponente abgegeben
● Hollywood-Prinzip„Don‘t call us, we‘ll call you“
Dependency Injection
/** * @var MY\PACKAGE\Interfaces\CowInterface * @Flow\Inject */protected $cowInterface;
mit Dependency Injection
Dependency Injection
/** * @var MY\PACKAGE\Interfaces\CowInterface * @Flow\Inject */protected $cowInterface;
protected $cowInterface;
public function __construct() {$cowInterface = new ConcreteCow();
}
mit Dependency Injection
ohne Dependency Injection
class CowController extends \TYPO3\Flow\Mvc\Controller\ActionController {
/** * @param MY\PACKAGE\Domain\Model\Cow $cow */public function showAction(Cow $cow) {
$this->view->assign("cow", $cow);}
}
class CowController extends \TYPO3\Flow\Mvc\Controller\ActionController {
/** * @param MY\PACKAGE\Domain\Model\Cow $cow */public function showAction(Cow $cow) {
$this->view->assign("cow", $cow);}
}
http://cows.local/my.package/cow/show/99ad52e5-61a7-4060-b616-2715c74eaafd
Property Mapping
class CowController extends \TYPO3\Flow\Mvc\Controller\ActionController {
/** * @param MY\PACKAGE\Domain\Model\Cow $cow */public function showAction(Cow $cow) {
$this->view->assign("cow", $cow);}
}
http://cows.local/cows/volma
Property Mapping
Model Controller ViewController
TYPO3 Fluid
<f:layout name="Default" />
<f:section name="Title">{cow.name}</f:section>
<f:section name="Content">
<h1>{cow.name}</h1>
<f:format.date format="d.m.Y">{cow.birthday}</f:format.date>
</f:section>
…/MY.PACKAGE/Resources/Private/Templates/Cow/Show.html
Fluid-Template
<f:layout name="Default" />
<f:section name="Title">{cow.name}</f:section>
<f:section name="Content">
<h1>{cow.name}</h1>
<f:format.date format="d.m.Y">{cow.birthday}</f:format.date>
</f:section>
…/MY.PACKAGE/Resources/Private/Templates/Cow/Show.html
Platzhalter
<f:layout name="Default" />
<f:section name="Title">{cow.name}</f:section>
<f:section name="Content">
<h1>{cow.name}</h1>
<f:format.date format="d.m.Y">{cow.birthday}</f:format.date>
</f:section>
…/MY.PACKAGE/Resources/Private/Templates/Cow/Show.html
Fluid-ViewHelper
{namespace cow=MY\PACKAGE\ViewHelpers}
<f:layout name="Default" />
<f:section name="Title">{cow.name}</f:section>
<f:section name="Content">
<h1>{cow.name}</h1>
<f:format.date format="d.m.Y">{cow.birthday}</f:format.date>
<cow:isVolma cow="{cow}" />
</f:section>
…/MY.PACKAGE/Resources/Private/Templates/Cow/Show.html
eigene ViewHelper
http://cows.local/cows/volma
Model Controller ViewController
Aspect-oriented Programming
1
2
3
4
5
6
7
8
9
SomeClass.php
1
2
3
4
5
6
7
8
9
Core Concerndomänenspezifisch
SomeClass.php
1
2
3
4
5
6
7
8
9
Core Concerndomänenspezifisch
LoggingConcern
SomeClass.php
Core Concerndomänenspezifisch
LoggingConcern
SecurityConcern
1
2
3
4
5
6
7
8
9
SomeClass.php
Core Concerndomänenspezifisch
LoggingConcern
SecurityConcern
1
2
3
4
5
6
7
8
9
Cross-cuttingConcerns
SomeClass.php
SomeClass.php
Core Concerndomänenspezifisch
LoggingConcern
SecurityConcern
1
2
3
4
5
6
7
8
9
Cross-cutting Concerns
Core Concerndomänenspezifisch
LoggingConcern
SecurityConcern
1
2
3
4
5
6
7
8
9
SomeClass.php
1
2
3
4
5
6
Core Concerndomänenspezifisch
LoggingConcern
SecurityConcern
Core Concerndomänenspezifisch
LoggingConcern
SecurityConcern
Separation of Concerns
1
2
1
1
2
3
4
5
6
Core Concerndomänenspezifisch
LoggingConcern
SecurityConcern
Core Concerndomänenspezifisch
LoggingConcern
SecurityConcern
1
2
1
Aspekte
use TYPO3\Flow\Annotations as Flow;
class CowController extends \TYPO3\Flow\Mvc\Controller\ActionController {
/** * @param MY\PACKAGE\Domain\Model\Cow $cow */public function showAction(Cow $cow) {
Logger::log("A cow has been shown");$this->view->assign("cow", $cow);
}
}
/* * @Flow\Aspect */class LoggingAspect {
}
Aspect
/* * @Flow\Aspect */class LoggingAspect {
public function logAdvice() {}
}
Advice
/* * @Flow\Aspect */class LoggingAspect {
/** * @param JoinPointInterface $joinPoint */
public function logAdvice(JoinPointInterface $joinPoint) {}
}
Join point
Programmausführung
/* * @Flow\Aspect */class LoggingAspect {
/** * @param JoinPointInterface $joinPoint * @Flow\After() */
public function logAdvice(JoinPointInterface $joinPoint) {}
}
Pointcut
/* * @Flow\Aspect */class LoggingAspect {
/** * @param JoinPointInterface $joinPoint * @Flow\After("method()") */
public function logAdvice(JoinPointInterface $joinPoint) {}
}
Target
/* * @Flow\Aspect */class LoggingAspect {
/** * @param JoinPointInterface $joinPoint * @Flow\After("method(MY\PACKAGE\Controller\.*->.*())") */
public function logAdvice(JoinPointInterface $joinPoint) {}
}
Target
CowController->showAction()
LoggingAspect->logAdvice()
Programmausführung
/* * @Flow\Aspect */class LoggingAspect {
/** * @param JoinPointInterface $joinPoint * @Flow\After("method(MY\PACKAGE\Controller\.*->.*())") */public function logAdvice(JoinPointInterface $joinPoint) {
Logger::log($joinPoint->getClassName().‘->‘.$joinPoint->getMethodName().‘() has been executed‘
);}
}
1
2
3
4
5
6
Core Concerndomänenspezifisch
LoggingConcern
SecurityConcern
Core Concerndomänenspezifisch
LoggingConcern
SecurityConcern
1
2
1
Model Controller ViewController
Domain-drivenDesign TYPO3 FluidDependency
Injection
Aspect-oriented Programming
Test-driven Development
Object Validation
Lokalisierung
Signals & Slots
Resource Management
CLI
Package Management
Security
Cache
Doctrine ORM
Vielen Dank für Eure Aufmerksamkeit
Fragen?
cowuser> ./flow doctrine:create
cowuser> ./flow doctrine:create
ORM
(Doctrine)Model-Klasse
relationalesSchema
cowuser> ./flow doctrine:create
ORM
(Doctrine)Model-Klasse
relationalesSchema
-
name: 'single cow route'
uriPattern: 'cows/{cow}'
defaults:
'@package': 'MY.PACKAGE'
'@controller': 'Cow'
'@action': 'show'
routeParts:
cow:
objectType: 'MY\PACKAGE\Domain\Model\Cow'
http://cows.local/cows/volma
Routing
{namespace cow=MY\PACKAGE\ViewHelpers}
<f:layout name="Default" />
<f:section name="Title">{cow.name}</f:section>
<f:section name="Content">
<h1>{cow.name}</h1>
<f:format.date format="d.m.Y">{cow.birthday}</f:format.date>
<cow:isVolma cow="{cow}" />
</f:section>
…/MY.PACKAGE/Resources/Private/Templates/Cow/Show.html
eigene ViewHelper
class IsVolmaViewHelper extends \TYPO3\Fluid\Core\ViewHelper\AbstractViewHelper {
}
class IsVolmaViewHelper extends \TYPO3\Fluid\Core\ViewHelper\AbstractViewHelper {
/**
* @param \MY\PACKAGE\Domain\Model\Cow $cow
*/
public function render($cow) {}
}
class IsVolmaViewHelper extends \TYPO3\Fluid\Core\ViewHelper\AbstractViewHelper {
/**
* @param \MY\PACKAGE\Domain\Model\Cow $cow
*/
public function render($cow) {
if($cow->getName() === "Volma"){ return "YES!"; }
}
}