Einführung in FLOW3/ Blog Package

Post on 19-May-2015

6.566 views 1 download

description

Einführung in FLOW3 mit dem Blockpackage als Referenz. Gehalten an der MFUGhttp://www.mfug.de

Transcript of Einführung in FLOW3/ Blog Package

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

@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

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

Domain Model

3

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

Package Aufbau

4

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

@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

@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

@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

@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

@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

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

TYPO3\Blog\Domain\Model Blog

11

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

TYPO3\Blog\Domain\Model Post

12

@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

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

Model und Repositories

14

@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

@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.

@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

@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

@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

@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()

@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

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

View

22

@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

@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

@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'}" />

@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.

@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.

@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

@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

@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: mgoldbeck@cross-content.com

www.cross-content.com

Kontakt

31