Transcript
Page 1: Einführung in FLOW3/ Blog Package

Überblick über FLOW3 mit dem Blog-Package als Referenz

Page 2: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

Agenda

• Domain Model• Package Aufbau• Model

• Validation• Association Mapping

• Model und Repository• Repository

• Blog Repsitory• Post Repository

• Controller• View• Validation• Routing

2

Page 3: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

Domain Model

3

Page 4: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

Package Aufbau

4

Page 5: Einführung in FLOW3/ Blog Package

Datum: 06.12.2011

• Namespacenamespace\Blog\Domain\Model;

• Namespacenamespace TYPO3\Blog\Domain\Model;

• Namespacenamespace TYPO3\Blog\Domain\Model;

• Namespacenamespace TYPO3\Blog\Domain\Model;

@MarkusGoldbeckFLOW3 Einführung / log Package www.cross-content.com

Model

5

Page 6: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

TYPO3\Blog\Domain\Model Post

6

• Namespacenamespace TYPO3\Blog\Domain\Model;

• Annotations

use Doctrine\ORM\Mapping as ORM;use TYPO3\FLOW3\Annotations as FLOW3;

/** * A blog * * @FLOW3\Entity */class Post {

• Class Post• Dieses Model nach den Konzepten von DDD eine Entitiy• Instanzen dieser Klasse können gespeichert werden

Page 7: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

TYPO3\Blog\Domain\Model Post

7

/** * The post‘s title. * * @var string * @FLOW3\Validate(type="Text") * @FLOW3\Validate(type="StringLength", options={ "minimum"=1, "maximum"=80 }) * @ORM\Column(length=80) */protected $title = '';

• Properties• Variablen Deklaration als String• Validierung auf Datentyp und Länge• Validierung des Datentyps innerhalb des Models und Repositories

Page 8: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

TYPO3\Blog\Domain\Model Post

8

/*** @var \TYPO3\Blog\Domain\Model\Blog* @ORM\ManyToOne(inversedBy="posts")*/protected $blog;

• Property $blog• Deklaration als Blog Objekt• Association Mapping OneToMany

/*** @FLOW3\Identity* @var \DateTime*/protected $date;

• Property $date• Deklaration als Date Objekt• Identity

Page 9: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

Association Mapping

9

Model Blog$posts

/** The posts contained in this blog * @var \Doctrine\Common\Collections\Collection<\TYPO3\Blog\Domain\Model\Post> * @ORM\OneToMany(mappedBy="blog") * @ORM\OrderBy({"date" = "DESC"}) */protected $posts;

Model Post$blog

/**The blog * @var \TYPO3\Blog\Domain\Model\Blog * @ORM\ManyToOne(inversedBy="posts") */protected $blog;

• OneToMany <-> ManyToOne

Page 10: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

Association Mapping

10

Model Post$tags

/*** @var \Doctrine\Common\Collections\Collection<\TYPO3\Blog\Domain\Model\Tag>* @ORM\ManyToMany(inversedBy="posts")*/protected $tags;

Model Tag$posts

/**The posts tagged with this tag* @var \Doctrine\Common\Collections\Collection<\TYPO3\Blog\Domain\Model\Post>* @ORM\ManyToMany(mappedBy="tags")*/protected $posts;

• ManyToMany <-> ManyToMany

Page 11: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

TYPO3\Blog\Domain\Model Blog

11

Page 12: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

TYPO3\Blog\Domain\Model Post

12

Page 13: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

TYPO3\Blog\Domain\Model Blog

13

/**Sets this blog's title* @param string $title The blog's title* @return void*/public function setTitle($title) { $this->title = $title;}

• Setter

/**Returns the blog's title* @return string The blog's title*/public function getTitle() { return $this->title;}

• Getter

Page 14: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

Model und Repositories

14

Page 15: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

Blog Repository

15

<?phpnamespace TYPO3\Blog\Domain\Repository;/* * This script belongs to the FLOW3 package "TYPO3.Blog". *//** * A repository for Blogs * * @FLOW3\Scope("singleton") */class BlogRepository extends \TYPO3\FLOW3\Persistence\Repository { // add customized methods here}?>

• Standard Blog Repository

Page 16: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

Blog Repository

16

• Standard Methoden des Repositories• add• remove• findAll• findBy* (magic methods)• findOneBy* (magic methods)

findBy* und findOneBy* sind sog. Magic Methods die durch das Repository zur Verfügung gestellt werden. Diese Methoden erlauben einen Objekte durch Properties zu finden.Das BlogRepository zum Beispiel erlaubt einem die Magic Methoden findByDescription('foo') oder findOneByTitle('bar')auszuführen.

Page 17: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

Post Repository

17

/** * Finds posts by the specified blog * @param \TYPO3\Blog\Domain\Model\Blog $blog The blog the post must refer to * @param integer $limit The number of posts to return at max * @return \TYPO3\FLOW3\Persistence\QueryResultProxy The posts */public function findByBlog(\TYPO3\Blog\Domain\Model\Blog $blog) {

$query = $this->createQuery();return $query->matching($query->equals('blog', $blog))

->setOrderings(array('date' => QueryInterface::ORDER_DESCENDING))

->execute();}

• Post Repository spezifische Methode findByBlog

Page 18: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

Post Repository

18

/**Finds posts by the specified tag and blog* @param \TYPO3\Blog\Domain\Model\Tag $tag* @param \TYPO3\Blog\Domain\Model\Blog $blog The blog the post must refer to* @return \TYPO3\FLOW3\Persistence\QueryResultProxy The posts */public function findByTagAndBlog(\TYPO3\Blog\Domain\Model\Tag $tag, \TYPO3\Blog\Domain\Model\Blog $blog) { $query = $this->createQuery(); return $query->matching( $query->logicalAnd( $query->equals('blog', $blog), $query->contains('tags', $tag) ) ) ->setOrderings(array('date' => QueryInterface::ORDER_DESCENDING)) ->execute(); }

• Post Repository spezifische Methode findByTagAndBlog

Page 19: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

Post Repository

19

/*** Finds most recent posts by the specified blog** @param \TYPO3\Blog\Domain\Model\Blog $blog The blog the post must refer to* @param integer $limit The number of posts to return at max* @return \TYPO3\FLOW3\Persistence\QueryResultProxy The posts*/public function findRecentByBlog(\TYPO3\Blog\Domain\Model\Blog $blog, $limit = 5) { $query = $this->createQuery(); return $query->matching($query->equals('blog', $blog)) ->setOrderings(array('date' => QueryInterface::ORDER_DESCENDING)) ->setLimit($limit) ->execute(); }

• Post Repository spezifische Methode findRecentByBlog

Page 20: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

Post Controller

20

/*** List action for this controller. Displays latest posts* @param \TYPO3\Blog\Domain\Model\Tag $tag The tag to display posts for* @param \TYPO3\Blog\Domain\Model\Category $category The category to display posts for* @return void*/public function indexAction(\TYPO3\Blog\Domain\Model\Tag $tag = NULL, \TYPO3\Blog\Domain\Model\Category $category = NULL) { if ($tag === NULL && $category === NULL) { $posts = $this->postRepository->findByBlog($this->blog); } elseif ($tag !== NULL) { $posts = $this->postRepository->findByTagAndBlog($tag, $this->blog); $this->view->assign('tag', $tag); } else { $posts = $this->postRepository->findByCategoryAndBlog($category, $this->blog); $this->view->assign('category', $category); } $this->view->assign('blog', $this->blog); $this->view->assign('posts', $posts); $this->view->assign('recentPosts', $this->postRepository->findRecentByBlog($this->blog));}

• Post Controller indexAction()

Page 21: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

Post Controller

21

/*** @FLOW3\Inject* @var \TYPO3\Blog\Domain\Repository\CategoryRepository*/protected $categoryRepository;

/**Displays a form for creating a new post* @return void*/public function newAction() { $account = $this->findCurrentAccount(); $newPost = new \TYPO3\Blog\Domain\Model\Post(); $newPost->setAuthor($account->getParty()->getName()->getFullName());

$this->view->assign('blog', $this->blog); $this->view->assign('existingPosts', $this->postRepository->findByBlog($this->blog)); $this->view->assign('categories', $this->categoryRepository->findAll()); $this->view->assign('newPost', $newPost);}

• Post Controller Dependency Injection

Page 22: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

View

22

Page 23: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

View

23

<body> <div id="header">

<!-- some stuff --> </div> <div id="maincontainer"> <div id="mainbox"><f:render section="mainbox" /></div>

• Master Template - /Private/Layouts/Master.html

<f:layout name="Master" />

<f:section name="mainbox"> <!-- some formular--> <f:render partial="FormErrors" arguments="{for: 'post'}" /></f:section>

• Post Template - /Private/Template/Post/Edit.html/Private/Layouts/Master.html

/Private/Partials/FormErrors.html

<f:form.validationResults for="{for}"> <f:if condition="{validationResults.flattenedErrors}"> <!-- -->

</f:if></f:form.validationResults>

• Partial Template - /Private/Partials/FormErrors.html

Page 24: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

View

24

<f:security.ifHasRole role="Editor"> <div id="navigation"> <span class="buttons"><f:link.action action="new" controller="Post"><img src="{f:uri.resource(path: 'Icons/FamFamFam/page_add.png')}" title="{f:translate(value: 'Create a new post')}"/></f:link.action></span>

<div class="clear"></div> </div></f:security.ifHasRole>

• security - /Private/Templates/Post/Index.html

Page 25: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

Validation

25

<f:form.validationResults for="{for}"> <f:if condition="{validationResults.flattenedErrors}"> <dl class="errors"> <f:for each="{validationResults.flattenedErrors}" key="propertyPath" as="errors"> <dt> {propertyPath}: </dt> <dd> <f:for each="{errors}" as="error">{error}</f:for> </dd> </f:for> </dl> </f:if></f:form.validationResults>

• Partial Template - /Private/Partials/FormErrors.htmlObjekt Post wurde übergeben

<f:render partial="FormErrors" arguments="{for: 'post'}" />

Page 26: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

Routing Subroute

26

### Blog subroutes

- name: 'Blog' uriPattern: '<BlogSubroutes>' defaults: '@package': 'TYPO3.Blog' '@format': 'html' subRoutes: BlogSubroutes: package: 'TYPO3.Blog'

• Route auf das TYPO3.Blog Package /Configuration/Routes.yaml

• Routet auf das TYPO3.Blog Package /Packages/Application/TYPO3.Blog/Routes.yaml

• Erste zutreffende Regel in Routes.yaml wird ausgeführt.• nur Leerzeichen verwenden, keine Tabs.

Page 27: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

Routing Package

27

- name: 'Post index' uriPattern: '(posts)' defaults: '@package': 'TYPO3.Blog' '@controller': 'Post' '@action': 'index' '@format': 'html'

• /Packages/Application/TYPO3.Blog/Routes.yaml

• passt für http://mfug.demo/ und http://mfug.demo/posts, da durch die Klammern posts optional ist.

Page 28: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

Routing Package

28

- name: 'Post actions 1' uriPattern: 'posts/{@action}' defaults: '@controller': 'Post'

• Action Routing•/Packages/Application/TYPO3.Blog/Routes.yaml

• passt http://mfug.demo/posts/new

Page 29: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

Routing Package

29

- name: 'Post actions 2' uriPattern: 'posts/{post}/{@action}' defaults: '@controller': 'Post' routeParts: post: objectType: 'TYPO3\Blog\Domain\Model\Post' uriPattern: '{date:Y}/{date:m}/{date:d}/{title}'

• Object Routes Part•/Packages/Application/TYPO3.Blog/Routes.yamlhttp://dev.tutorial.local/post/edit?post%5B__identity%5D=229e2b23-b6f3-4422-8b7a-efb196dbc88b

http://dev.tutorial.local/post/2010/01/18/post-title/edit

Page 31: Einführung in FLOW3/ Blog Package

@MarkusGoldbeckFLOW3 Einführung / Blog Package www.cross-content.comDatum: 10.01.2012

Cross Content Media Gesellschaft für Online Business Solutions mbHLandshuter Allee 8

80637 München

Twitter: @MarkusGoldbeckE-Mail: [email protected]

www.cross-content.com

Kontakt

31


Recommended