(TYPO3) FLOW · Dependency TYPO3 Fluid Injection. Model Controller View Domain-driven Design...

Preview:

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!"; }

}

}

Recommended