Get into the FLOW with Extbase and TYPO3 4.3

Preview:

DESCRIPTION

Slides of the presentation on Extbase on T3DD09. Extbase is a new Extension framework for TYPO3 backporting great features from FLOW3 - Domain Driven Design and Model View Controller. The video of this presentation can be found at http://t3dd09.typo3.org/recordings.html

Citation preview

Inspiring people toshare

T3DD09

Get into FLOW with Extbase

Get into the FLOW with Extbase

Jochen Rau <jochen.rau@typoplanet.de>Sebastian Kurfürst <sebastian@typo3.org>

with contributions by Oliver Hader

15.05.2009

Inspiring people toshareGet into FLOW with Extbase

Topictext

Who is that?

Dipl.-Ing. Mechanical Engineering (Stuttgart University)

infected with TYPO3 in 2001 (after that: 5 years of immunity)

today living and working in Tübingen

60% self-employed TYPO3-developer (since 2007)

60% father of a family (since 2003 ;-) )

before that

5 years: researcher at the Fraunhofer-Gesellschaft and the German Aerospace Center

Inspiring people toshareGet into FLOW with Extbase

- WARNING -TYPO3 addict

The current stateof the art

http://commons.wikimedia.org/wiki/File:Z%C3%BCrich_-_Seefeld_-_Heureka_IMG_1757.JPG

Inspiring people toshareGet into FLOW with Extbase

The current state of the art

The current state of the art

FEPlugin

Database tables

dispatches callsfetches data

renders outputResources

templatesJavaScript/CSS

imagesextends tslib_pibase TypoScript

FrontendExtension

Inspiring people toshareGet into FLOW with Extbase

The current state of the art

File structure

Inspiring people toshareGet into FLOW with Extbase

The current state of the art

A new extension: Blogging with TYPO3

define features of the new blogging application

implement the business logic

define the look and feel

take a look at security issues

Inspiring people toshareGet into FLOW with Extbase

The current state of the art

Blog features

administrate blogs, blog posts and blog comments

list all available blogs

list all blog posts of a blog

list all comments of a blog post

allow users to post new comments

Inspiring people toshareGet into FLOW with Extbase

The current state of the art

Blog

Post

Comment Tag

Inspiring people toshareGet into FLOW with Extbase

The current state of the art

Blog business logicpublic function main($content, $conf) { $this->conf = $conf; $this->pi_setPiVarDefaults(); $this->pi_loadLL();

if ($this->piVars['postUid']) { if ($this->piVars['newComment']) { $this->storeNewComment(); } $content = $this->renderPost(); } elseif ($this->piVars['blogUid']) { $content = $this->renderBlog(); } else { $content = $this->renderListOfBlogs(); } return $this->pi_wrapInBaseClass($content);}

Inspiring people toshareGet into FLOW with Extbase

The current state of the art

Task 1: Output a listing of blogs

fetch available blogs from database

implement a new method „renderListOfBlogs()“

protected function renderListOfBlogs() { $blogs = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( '*', 'tx_blogexample_blog', 'deleted=0 AND hidden=0 AND sys_language_uid=' .

$GLOBALS['TSFE']->sys_language_uid . $this->cObj->enableFields('tx_blogexample_blog'), '', 'name' );

...

Inspiring people toshareGet into FLOW with Extbase

The current state of the art

Task 1: Output a listing of blogs

iterate through all blogs and render them

... $template = $this->cObj->fileResource($this->conf['template']); $blogElementSubpart = $this->cObj->getSubpart($template, '###SUBPART_BLOGELEMENT###');

$blogs = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(...); foreach ($blogs as $blog) { $linkParameters = array('blogUid' => $blog['uid']); $markers = array( '###BLOG_NAME###' => $blog['name'], '###BLOG_LOGO###' => $this->cImage('uploads/tx_blog/' . $blog['logo']), '###BLOG_DESCRIPTION###' => $this->pi_RTEcssText($blog['description']), '###BLOG_MORELINK###' => $this->pi_linkTP('show blog', $linkParameters, true), ); $blogElements.= $this->cObj->substituteMarkerArray($blogElementSubpart, $markers); } return $content;}

Inspiring people toshareGet into FLOW with Extbase

The current state of the art

Task 1: Output a listing of blogs

create the template with markers and subparts

<!-- ###SUBPART_BLOGELEMENT### begin --><div class="blog element"> ###BLOG_NAME### ###BLOG_LOGO### ###BLOG_DESCRIPTION### ###BLOG_MORELINK###</div><!-- ###SUBPART_BLOGELEMENT### end -->

Inspiring people toshareGet into FLOW with Extbase

The current state of the art

Task 2: Display a single post with its comments

implement a new method „renderPost()“protected function renderPost() { $post = $this->pi_getRecord('tx_blogexample_post', $this->piVars['postUid']); $comments = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( '*', 'tx_blogexample_comment', 'deleted=0 AND hidden=0 AND sys_language_uid=' .

$GLOBALS['TSFE']->sys_language_uid . ' AND post_uid=' . $this->piVars['postUid'] . ' AND post_table="tx_blogexample_post"' . $this->cObj->enableFields('tx_blogexample_comment'), '', 'date DESC' );

// fill marker arrays and substitute in template// return content

}

Inspiring people toshareGet into FLOW with Extbase

The current state of the art

Task 3: Add a new comment to a blog post

the whole plugin is cached („USER“)

dynamic user input won‘t be handled by the rendering when cached

define uncached behavior in TypoScript

[globalVar = _POST:tx_blogexample_pi1|newComment = 1] plugin.tx_blogexample_pi1 = USER_INT[global]

Inspiring people toshareGet into FLOW with Extbase

The current state of the art

Task 3: Add a new comment to a blog post

store new comment in database

protected function storeNewComment() { $fields = array( 'post_uid' => $this->piVars['postUid'], 'post_table' => 'tx_blogexample_post', 'date' => time(), 'author' => $this->piVars['author'], 'email' => $this->piVars['email'], 'content' => $this->piVars['content'], );

$GLOBALS['TYPO3_DB']->exec_INSERTquery( 'tx_blogexample_comment', $fields );}

Inspiring people toshareGet into FLOW with Extbase

The current state of the art

Take a look at security issues

possibility of SQL injections

unvalidated information submitted by a user

is there really a mail address where it was expected?

are integers really integers?

malicious information submitted by a user (XSS)

is there a possibility to inject JavaScript code?

Inspiring people toshareGet into FLOW with Extbase

The current state of the art

Security: SQL injections

unescaped or unchecked values that are transferred to the database directly$comments = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*','tx_blog_comment','deleted=0 AND hidden=0 AND sys_language_uid=' . $GLOBALS['TSFE']->sys_language_uid . ' AND post_uid=' . $this->piVars['postUid'] . ' AND post_table="tx_blog_post"' .$this->cObj->enableFields('tx_blog_comment'));

with &postUid=1; INSERT INTO be_users SET ...; SELECT * FROM tx_blog_comment WHERE 1=1

SELECT * FROM tx_blog_comment WHERE post_uid=1;INSERT INTO be_users SET ...;SELECT * FROM tx_blog_comment WHERE 1=1 AND post_table=“tx_blog_post“ ...

Inspiring people toshareGet into FLOW with Extbase

The current state of the art

Security: SQL injections - solution

always escape or cast variables from outside

' AND post_uid=' . intval($this->piVars['postUid']) . ' AND post_table="tx_blog_post"' .

Spaghetti codeLasagna code

Hmmm.Much better.

Extension Framework

Extension Framework

http://www.sxc.hu/photo/516864/

Extension buildingwith ExtbaseHow to build a typo3

v4 based app

Inspiring people toshareGet into FLOW with Extbase

Blog

Post

Comment Tag

http://www.flickr.com/photos/bunchofpants/106465356/sizes/o/

The model is arepresentation of

reality.

Model

Inspiring people toshareGet into FLOW with Extbase

class Tx_BlogExample_Domain_Model_Blog extends Tx_Extbase_DomainObject_AbstractEntity {

// Comments are missing protected $name = ''; protected $description = ''; protected $logo; protected $posts = array();

public function setName($name) { $this->name = $name; } public function getName() { return $this->name; }

public function addPost(Tx_BlogExample_Domain_Model_Post $post) { $this->posts[] = $post; } public function removeAllPosts() { $this->posts = array(); }

/** * Returns all posts in this blog * * @return array of Tx_BlogExample_Domain_Model_Post */ public function getPosts() { return $this->posts; }

Inspiring people toshareGet into FLOW with Extbase

Inspiring people toshareGet into FLOW with Extbase

class Tx_BlogExample_Domain_Model_Comment extends Tx_Extbase_DomainObject_AbstractEntity {

protected $date; protected $author; protected $email; protected $content;

public function __construct() { $this->date = new DateTime(); }

public function setDate(DateTime $date) { $this->date = $date; }

public function getDate() { return $this->date; }

public function setAuthor($author) { $this->author = $author; }

public function getAuthor() { return $this->author; }

public function setEmail($email) { $this->email = $email; }

public function getEmail() { return $this->email; }

public function setContent($content) { $this->content = $content; }

public function getContent() { return $this->content; }}

Inspiring people toshareGet into FLOW with Extbase

Model classes are POPOs (almost)

POPO = Plain Old PHP Object

domain object encapsulates data + behavior

and...

action

http://www.sxc.hu/photo/444174/

Inspiring people toshareGet into FLOW with Extbase

Extension building with Extbase

Task 1: Output a listing of blog postings

You want to output the postings of a predefined blog.

public function showAction() { $blogUid = 1; // get blog by UID // render blog}

How could you get a blog?

How could you get a book?

Inspiring people toshareGet into FLOW with Extbase

Blog

Post

Comment Tag

Extension building with Extbase - Blog Example

ModelBlogRepository

Inspiring people toshareGet into FLOW with Extbase

Extension building with Extbase - Blog Example

Repositories

Encapsulate all data access

SQL is allowed only in the Repository

Magic methods: findBy*, findOneBy*

Extension building with Extbase - Blog Example

Repositories

class Tx_BlogExample_Domain_Model_BlogRepository extends Tx_Extbase_Persistence_Repository {}

Inspiring people toshareGet into FLOW with Extbase

Extension building with Extbase - Blog Example

Task 1: Output a listing of blog postings

You want to output the postings of a predefined blog.

public function showAction() { $blogUid = 1; $blog = $this->blogRepository->findOneByUid($blogUid); // render blog}

Inspiring people toshareGet into FLOW with Extbase

Extension building with Extbase - Blog Example

Task 1: Output a listing of blog postings

You want to output the postings of a predefined blog.

public function showAction() { $blogUid = 1; $blog = $this->blogRepository->findOneByUid($blogUid); $this->view->assign('blog', $blog); return $this->view->render(); // can be omitted}

Inspiring people toshareGet into FLOW with Extbase

Extension building with Extbase - Blog Example

Task 1: Output a listing of blog postings

Inside the template:

<h1>Welcome to {blog.name}</h1>

<f:for each="{blog.posts}" as="singlePost"> <h1>{singlePost.title}</h1> <f:link controller="Post" action="show" arguments="{post : singlePost}">read more </f:link></f:for>

Inspiring people toshareGet into FLOW with Extbase

Extension building with Extbase - Blog Example

Task 2: Display a single blog post

Display a post with comments

public function showAction() { // Get the post // Pass post to view so it can be rendered}

Inspiring people toshareGet into FLOW with Extbase

Extension building with Extbase - Blog Example

Task 2: Display a single blog post

/** * Display a post * * @param Tx_Blog_Domain_Model_Post $post The post to show */public function showAction(Tx_Blog_Domain_Model_Post $post) { // Pass post to view so it can be rendered}

Inspiring people toshareGet into FLOW with Extbase

Extension building with Extbase - Blog Example

Arguments

All arguments must be registered.

Registration of expected arguments happens through defining them as method parameters.

PHPDoc is mandatory as it is used for data type validation

Inspiring people toshareGet into FLOW with Extbase

Extension building with Extbase - Blog Example

Arguments - more advanced

/** * Action that displays one single post * * @param string $title Title of the post * @param string $content Content of the post * @validate $title Length(maximum=100) * @return string The rendered view */public function createAction($title, $content) {}

Do additional validation

Inspiring people toshareGet into FLOW with Extbase

Extension building with Extbase - Blog Example

Task 2: Display a single blog post

/** * Display a post * * @param Tx_Blog_Domain_Model_Post $post The post to show */public function showAction(Tx_Blog_Domain_Model_Post $post) { $this->view->assign('post', $post);}

Inspiring people toshareGet into FLOW with Extbase

Extension building with Extbase - Blog Example

Task 2: Display a single blog post - template

Inspiring people toshareGet into FLOW with Extbase

Extension building with Extbase - Blog Example

Task 3: Add a new comment

a new comment needs to be stored for a given post

1. Create the template

2. Add the comment in the controller

Inspiring people toshareGet into FLOW with Extbase

<f:form name="comment" method="post" controllerName="Comment" actionName="create" object="{comment}" arguments="{post : post}"> <h4>Add your own</h4> <label for="author">name <span class="required">(required)</span></label><br /> <f:form.textbox id="author" property="author" /> <br /> <label for="email">email <span class="required">(required)</span></label><br /> <f:form.textbox id="email" property="email" /> <br /> <label for="text">message <span class="required">(required)</span></label><br /> <f:form.textarea id="text" property="content" rows="8" cols="46"/> <br /> <f:form.submit>Say it</f:form.submit></f:form>

Inspiring people toshareGet into FLOW with Extbase

/** * Action that adds a comment to a blog post and redirects to single view * * @param Tx_BlogExample_Domain_Model_Post $post The post the comment is related to * @param Tx_BlogExample_Domain_Model_Comment $comment The comment to create * @return void */ public function createAction(Tx_BlogExample_Domain_Model_Post $post, Tx_BlogExample_Domain_Model_Comment $comment) { $post->addComment($comment); $this->redirect('show', 'Post', NULL, array('post' => $post)); }

<f:form name="comment" method="post" controllerName="Comment" actionName="create" object="{comment}" arguments="{post : post}">

ExtbaseDispatcher

Controller

Repository View

Request

findByName('MyBlog')

Response

Blog

assign(Blog)

Response

TYPO3

Domain Model

HTML

render()

userFunc

12

3

4

5

6

Blog

Post

Comment Tag

BlogExample

Inspiring people toshareGet into FLOW with Extbase

Extension building with Extbase

Controller

Controllers contain actions: *Action

all controllers inherit from Tx_Extbase_MVC_Controller_ActionController

Default action: indexAction

Model

View

Other Stuff

Controller

Inspiring people toshareGet into FLOW with Extbase

Persistence

Blog

Post

Comment Tag

Aggregate RootgetLatestComment()

Inspiring people toshareGet into FLOW with Extbase

Persistence

adding a blog

the blog is an aggregate root

Now, the Blog is a managed object - changes are now automatically persisted!

Persistent objectsBlogRepository

Blog$blogRepository->add(Blog $blog);

Inspiring people toshareGet into FLOW with Extbase

PostRepository

Comment is no aggregate root

Thus, Comment is automatically persisted

Persistence

adding a comment

Persistent objects

Comment

PostPost

Inspiring people toshareGet into FLOW with Extbase

Persistence

Transparent object persistence

All objects (and their child-objects) managed by a repository are automatically persisted

changes to these objects are automatically persisted

Inspiring people toshareGet into FLOW with Extbase

Domain Driven Design

Domain describes activity or business of user.

Ubiquitous LAnguage

Blog

Post

Comment Tag

ValueObject

Entity

Inspiring people toshareGet into FLOW with Extbase

Core concepts - Domain Driven Design

Principles of Domain Driven Design

focus on the domain = activity or business of user

we start with the business logic (PHP classes)

we don't care about the database backend / persistence layer

bbjects represent things in the real world, with their attributes and behavior

ubiquitous language

building blocks

Entity

Value Objects

Repositories

Inspiring people toshareGet into FLOW with Extbase

Why should you use DDD?

Build complexSQL queries

Implement application logic

Mix PHP and HTML templateto build a template-based

layout

Read lots of TypoScriptand core API docs

Build frontend formswith error handling

Care about securityadapt to the coding style,structure and thinking of

different developers

http://www.sxc.hu/photo/929504

Implement application logic

http://www.sxc.hu/photo/768249

Flow [flō] is the mental state of operation in which the person is fully immersed in what he or she is doing by a feeling of energized focus, full involvement, and success in the process of the activity.

Inspiring people toshareGet into FLOW with Extbase

Outlook

Inspiring people toshareGet into FLOW with Extbase

Outlook

Availability and documentation

Extbase will be included in TYPO3 4.3

full-blown replacement for pibase

new preferred way to write extensions

futureproof, with concepts of FLOW3

Currently no documentation, but will be available with the final release

Inspiring people toshareGet into FLOW with Extbase

Outlook

New kickstarter

currently ongoing project by the core development team

will be released shortly after 4.3

Domain Driven Design - Don't think in databases, think in Objects!

Inspiring people toshareGet into FLOW with Extbase

Resources and links

Project web site: http://forge.typo3.org/projects/show/typo3v4-mvc

SVN: https://svn.typo3.org/TYPO3v4/CoreProjects/MVC/

we will provide documentation until the release of TYPO3 4.3

First release with TYPO3 4.3 alpha3: http://typo3.org/download/packages/

Inspiring people toshareGet into FLOW with Extbase

Conclusion

Greatly reusablecomponents

+

Easy and consistent API

+

Easily testable+

Needs initiallearning time

-

Extensionsneed proper

planning

-

You willget addicted

-

Feel the flowin TYPO3 v4

Christopher Hlubek

Niels Pardon

Bastian Waidelich

Benjamin Mack

Ingmar Schlecht

and the TYPO3 V5 Team for all the inspiration and the beautiful code

Thank You

?????????????

inspiring people to share.

Recommended