<testsuite name="EXT:workspaces tests">
<directory>../../../../typo3/sysext/workspaces/Tests/Functional/</directory>
</testsuite>
+ <testsuite name="EXT:extbase tests">
+ <directory>../../../../typo3/sysext/extbase/Tests/Functional/Relations</directory>
+ </testsuite>
</testsuites>
</phpunit>
--- /dev/null
+<?php
+
+namespace ExtbaseTeam\BlogExample\Domain\Model;
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+ * (c) 2011 Bastian Waidelich <bastian@typo3.org>
+ * All rights reserved
+ *
+ * This script is part of the TYPO3 project. The TYPO3 project is
+ * free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The GNU General Public License can be found at
+ * http://www.gnu.org/copyleft/gpl.html.
+ *
+ * This script is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * An Administrator of a Blog
+ */
+class Administrator extends \TYPO3\CMS\Extbase\Domain\Model\FrontendUser {
+
+}
+?>
\ No newline at end of file
--- /dev/null
+<?php
+namespace ExtbaseTeam\BlogExample\Domain\Model;
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+ * (c) 2011 Bastian Waidelich <bastian@typo3.org>
+ * All rights reserved
+ *
+ * This script is part of the TYPO3 project. The TYPO3 project is
+ * free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The GNU General Public License can be found at
+ * http://www.gnu.org/copyleft/gpl.html.
+ *
+ * This script is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * A blog
+ */
+class Blog extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
+
+ /**
+ * The blog's title.
+ *
+ * @var string
+ * @validate StringLength(minimum = 1, maximum = 80)
+ */
+ protected $title = '';
+
+ /**
+ * A short description of the blog
+ *
+ * @var string
+ * @validate StringLength(maximum = 150)
+ */
+ protected $description = '';
+
+ /**
+ * A relative path to a logo image
+ *
+ * @var string
+ */
+ protected $logo = '';
+
+ /**
+ * The posts of this blog
+ *
+ * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\ExtbaseTeam\BlogExample\Domain\Model\Post>
+ * @lazy
+ * @cascade remove
+ */
+ protected $posts = NULL;
+
+ /**
+ * The blog's administrator
+ *
+ * @var \ExtbaseTeam\BlogExample\Domain\Model\Administrator
+ * @lazy
+ */
+ protected $administrator = NULL;
+
+ /**
+ * Constructs a new Blog
+ *
+ */
+ public function __construct() {
+ $this->posts = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
+ }
+
+ /**
+ * Sets this blog's title
+ *
+ * @param string $title The blog's title
+ * @return void
+ */
+ public function setTitle($title) {
+ $this->title = $title;
+ }
+
+ /**
+ * Returns the blog's title
+ *
+ * @return string The blog's title
+ */
+ public function getTitle() {
+ return $this->title;
+ }
+
+ /**
+ * @param string $logo
+ * @return void
+ */
+ public function setLogo($logo) {
+ $this->logo = $logo;
+ }
+
+ /**
+ * @return string
+ */
+ public function getLogo() {
+ return $this->logo;
+ }
+
+ /**
+ * Sets the description for the blog
+ *
+ * @param string $description
+ * @return void
+ */
+ public function setDescription($description) {
+ $this->description = $description;
+ }
+
+ /**
+ * Returns the description
+ *
+ * @return string
+ */
+ public function getDescription() {
+ return $this->description;
+ }
+
+ /**
+ * Adds a post to this blog
+ *
+ * @param Post $post
+ * @return void
+ */
+ public function addPost(Post $post) {
+ $this->posts->attach($post);
+ }
+
+ /**
+ * Remove a post from this blog
+ *
+ * @param Post $postToRemove The post to be removed
+ * @return void
+ */
+ public function removePost(Post $postToRemove) {
+ $this->posts->detach($postToRemove);
+ }
+
+ /**
+ * Remove all posts from this blog
+ *
+ * @return void
+ */
+ public function removeAllPosts() {
+ $this->posts = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
+ }
+
+ /**
+ * Returns all posts in this blog
+ *
+ * @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage
+ */
+ public function getPosts() {
+ return $this->posts;
+ }
+
+ /**
+ * Sets the administrator value
+ *
+ * @param Administrator $administrator The Administrator of this Blog
+ * @return void
+ */
+ public function setAdministrator(Administrator $administrator) {
+ $this->administrator = $administrator;
+ }
+
+ /**
+ * Returns the administrator value
+ *
+ * @return Administrator
+ */
+ public function getAdministrator() {
+ return $this->administrator;
+ }
+
+}
+?>
\ No newline at end of file
--- /dev/null
+<?php
+namespace ExtbaseTeam\BlogExample\Domain\Model;
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+ * (c) 2011 Bastian Waidelich <bastian@typo3.org>
+ * All rights reserved
+ *
+ * This script is part of the TYPO3 project. The TYPO3 project is
+ * free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The GNU General Public License can be found at
+ * http://www.gnu.org/copyleft/gpl.html.
+ *
+ * This script is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * A blog post comment
+ */
+class Comment extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
+
+ /**
+ * @var \DateTime
+ */
+ protected $date;
+
+ /**
+ * @var string
+ * @validate NotEmpty
+ */
+ protected $author = '';
+
+ /**
+ * @var string
+ * @validate EmailAddress
+ */
+ protected $email = '';
+
+ /**
+ * @var string
+ * @validate StringLength(maximum = 500)
+ */
+ protected $content = '';
+
+ /**
+ * Constructs this post
+ */
+ public function __construct() {
+ $this->date = new \DateTime();
+ }
+
+ /**
+ * Setter for date
+ *
+ * @param \DateTime $date
+ * @return void
+ */
+ public function setDate(\DateTime $date) {
+ $this->date = $date;
+ }
+
+ /**
+ * Getter for date
+ *
+ * @return \DateTime
+ */
+ public function getDate() {
+ return $this->date;
+ }
+
+ /**
+ * Sets the author for this comment
+ *
+ * @param string $author
+ * @return void
+ */
+ public function setAuthor($author) {
+ $this->author = $author;
+ }
+
+ /**
+ * Getter for author
+ *
+ * @return string
+ */
+ public function getAuthor() {
+ return $this->author;
+ }
+
+ /**
+ * Sets the authors email for this comment
+ *
+ * @param string $email email of the author
+ * @return void
+ */
+ public function setEmail($email) {
+ $this->email = $email;
+ }
+
+ /**
+ * Getter for authors email
+ *
+ * @return string
+ */
+ public function getEmail() {
+ return $this->email;
+ }
+
+ /**
+ * Sets the content for this comment
+ *
+ * @param string $content
+ * @return void
+ */
+ public function setContent($content) {
+ $this->content = $content;
+ }
+
+ /**
+ * Getter for content
+ *
+ * @return string
+ */
+ public function getContent() {
+ return $this->content;
+ }
+
+ /**
+ * Returns this comment as a formatted string
+ *
+ * @return string
+ */
+ public function __toString() {
+ return $this->author . ' (' . $this->email . ') said on ' . $this->date->format('Y-m-d') . ':' . chr(10) .
+ $this->content . chr(10);
+ }
+}
+?>
\ No newline at end of file
--- /dev/null
+<?php
+namespace ExtbaseTeam\BlogExample\Domain\Model;
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+ * (c) 2011 Bastian Waidelich <bastian@typo3.org>
+ * All rights reserved
+ *
+ * This script is part of the TYPO3 project. The TYPO3 project is
+ * free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The GNU General Public License can be found at
+ * http://www.gnu.org/copyleft/gpl.html.
+ *
+ * This script is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * A person - acting as author
+ */
+class Person extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
+
+ /**
+ * @var string
+ */
+ protected $firstname = '';
+
+ /**
+ * @var string
+ */
+ protected $lastname = '';
+
+ /**
+ * @var string
+ */
+ protected $email = '';
+
+ /**
+ * Constructs a new Person
+ *
+ */
+ public function __construct($firstname, $lastname, $email) {
+ $this->setFirstname($firstname);
+ $this->setLastname($lastname);
+ $this->setEmail($email);
+ }
+
+ /**
+ * Sets this persons's firstname
+ *
+ * @param string $firstname The person's firstname
+ * @return void
+ */
+ public function setFirstname($firstname) {
+ $this->firstname = $firstname;
+ }
+
+ /**
+ * Returns the person's firstname
+ *
+ * @return string The persons's firstname
+ */
+ public function getFirstname() {
+ return $this->firstname;
+ }
+
+ /**
+ * Sets this persons's lastname
+ *
+ * @param string $lastname The person's lastname
+ * @return void
+ */
+ public function setLastname($lastname) {
+ $this->lastname = $lastname;
+ }
+
+ /**
+ * Returns the person's lastname
+ *
+ * @return string The persons's lastname
+ */
+ public function getLastname() {
+ return $this->lastname;
+ }
+
+ /**
+ * Returns the person's full name
+ *
+ * @return string The persons's lastname
+ */
+ public function getFullName() {
+ return $this->firstname . ' ' . $this->lastname;
+ }
+
+ /**
+ * Sets this persons's email adress
+ *
+ * @param string $email The person's email adress
+ * @return void
+ */
+ public function setEmail($email) {
+ $this->email = $email;
+ }
+
+ /**
+ * Returns the person's email address
+ *
+ * @return string The persons's email address
+ */
+ public function getEmail() {
+ return $this->email;
+ }
+
+}
+?>
\ No newline at end of file
--- /dev/null
+<?php
+namespace ExtbaseTeam\BlogExample\Domain\Model;
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+ * (c) 2011 Bastian Waidelich <bastian@typo3.org>
+ * All rights reserved
+ *
+ * This script is part of the TYPO3 project. The TYPO3 project is
+ * free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The GNU General Public License can be found at
+ * http://www.gnu.org/copyleft/gpl.html.
+ *
+ * This script is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * A blog post
+ */
+class Post extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
+
+ /**
+ * @var \ExtbaseTeam\BlogExample\Domain\Model\Blog
+ */
+ protected $blog = NULL;
+
+ /**
+ * @var string
+ * @validate StringLength(minimum = 3, maximum = 50)
+ */
+ protected $title = '';
+
+ /**
+ * @var \DateTime
+ */
+ protected $date = NULL;
+
+ /**
+ * @var \ExtbaseTeam\BlogExample\Domain\Model\Person
+ */
+ protected $author = NULL;
+
+ /**
+ * @var string
+ * @validate StringLength(minimum = 3)
+ */
+ protected $content = '';
+
+ /**
+ * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\ExtbaseTeam\BlogExample\Domain\Model\Tag>
+ */
+ protected $tags = NULL;
+
+ /**
+ * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\ExtbaseTeam\BlogExample\Domain\Model\Comment>
+ * @lazy
+ * @cascade remove
+ */
+ protected $comments = NULL;
+
+ /**
+ * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\ExtbaseTeam\BlogExample\Domain\Model\Post>
+ * @lazy
+ */
+ protected $relatedPosts = NULL;
+
+ /**
+ * Constructs this post
+ */
+ public function __construct() {
+ $this->tags = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
+ $this->comments = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
+ $this->relatedPosts = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
+ $this->date = new \DateTime();
+ }
+
+ /**
+ * Sets the blog this post is part of
+ *
+ * @param \ExtbaseTeam\BlogExample\Domain\Model\Blog $blog The blog
+ * @return void
+ */
+ public function setBlog(\ExtbaseTeam\BlogExample\Domain\Model\Blog $blog) {
+ $this->blog = $blog;
+ }
+
+ /**
+ * Returns the blog this post is part of
+ *
+ * @return \ExtbaseTeam\BlogExample\Domain\Model\Blog The blog this post is part of
+ */
+ public function getBlog() {
+ return $this->blog;
+ }
+
+ /**
+ * Setter for title
+ *
+ * @param string $title
+ * @return void
+ */
+ public function setTitle($title) {
+ $this->title = $title;
+ }
+
+ /**
+ * Getter for title
+ *
+ * @return string
+ */
+ public function getTitle() {
+ return $this->title;
+ }
+
+ /**
+ * Setter for date
+ *
+ * @param \DateTime $date
+ * @return void
+ */
+ public function setDate(\DateTime $date) {
+ $this->date = $date;
+ }
+
+ /**
+ * Getter for date
+ *
+ *
+ * @return \DateTime
+ */
+ public function getDate() {
+ return $this->date;
+ }
+
+ /**
+ * Setter for tags
+ *
+ * @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage $tags One or more Tag objects
+ * @return void
+ */
+ public function setTags(\TYPO3\CMS\Extbase\Persistence\ObjectStorage $tags) {
+ $this->tags = $tags;
+ }
+
+ /**
+ * Adds a tag to this post
+ *
+ * @param Tag $tag
+ * @return void
+ */
+ public function addTag(Tag $tag) {
+ $this->tags->attach($tag);
+ }
+
+ /**
+ * Removes a tag from this post
+ *
+ * @param Tag $tag
+ * @return void
+ */
+ public function removeTag(Tag $tag) {
+ $this->tags->detach($tag);
+ }
+
+ /**
+ * Remove all tags from this post
+ *
+ * @return void
+ */
+ public function removeAllTags() {
+ $this->tags = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
+ }
+
+ /**
+ * Getter for tags
+ * Note: We return a clone of the tags because they must not be modified as they are Value Objects
+ *
+ * @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage A storage holding objects
+ */
+ public function getTags() {
+ return clone $this->tags;
+ }
+
+ /**
+ * Sets the author for this post
+ *
+ * @param \ExtbaseTeam\BlogExample\Domain\Model\Person $author
+ * @return void
+ */
+ public function setAuthor(\ExtbaseTeam\BlogExample\Domain\Model\Person $author) {
+ $this->author = $author;
+ }
+
+ /**
+ * Getter for author
+ *
+ * @return \ExtbaseTeam\BlogExample\Domain\Model\Person
+ */
+ public function getAuthor() {
+ return $this->author;
+ }
+
+ /**
+ * Sets the content for this post
+ *
+ * @param string $content
+ * @return void
+ */
+ public function setContent($content) {
+ $this->content = $content;
+ }
+
+ /**
+ * Getter for content
+ *
+ * @return string
+ */
+ public function getContent() {
+ return $this->content;
+ }
+
+ /**
+ * Setter for the comments to this post
+ *
+ * @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage $comments An Object Storage of related Comment instances
+ * @return void
+ */
+ public function setComments(\TYPO3\CMS\Extbase\Persistence\ObjectStorage $comments) {
+ $this->comments = $comments;
+ }
+
+ /**
+ * Adds a comment to this post
+ *
+ * @param Comment $comment
+ * @return void
+ */
+ public function addComment(Comment $comment) {
+ $this->comments->attach($comment);
+ }
+
+ /**
+ * Removes Comment from this post
+ *
+ * @param Comment $commentToDelete
+ * @return void
+ */
+ public function removeComment(Comment $commentToDelete) {
+ $this->comments->detach($commentToDelete);
+ }
+
+ /**
+ * Remove all comments from this post
+ *
+ * @return void
+ */
+ public function removeAllComments() {
+ $comments = clone $this->comments;
+ $this->comments->removeAll($comments);
+ }
+
+ /**
+ * Returns the comments to this post
+ *
+ * @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage holding instances of Comment
+ */
+ public function getComments() {
+ return $this->comments;
+ }
+
+ /**
+ * Setter for the related posts
+ *
+ * @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage $relatedPosts An Object Storage containing related Posts instances
+ * @return void
+ */
+ public function setRelatedPosts(\TYPO3\CMS\Extbase\Persistence\ObjectStorage $relatedPosts) {
+ $this->relatedPosts = $relatedPosts;
+ }
+
+ /**
+ * Adds a related post
+ *
+ * @param Post $post
+ * @return void
+ */
+ public function addRelatedPost(Post $post) {
+ $this->relatedPosts->attach($post);
+ }
+
+ /**
+ * Remove all related posts
+ *
+ * @return void
+ */
+ public function removeAllRelatedPosts() {
+ $relatedPosts = clone $this->relatedPosts;
+ $this->relatedPosts->removeAll($relatedPosts);
+ }
+
+ /**
+ * Returns the related posts
+ *
+ * @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage holding instances of Post
+ */
+ public function getRelatedPosts() {
+ return $this->relatedPosts;
+ }
+
+ /**
+ * Returns this post as a formatted string
+ *
+ * @return string
+ */
+ public function __toString() {
+ return $this->title . chr(10) .
+ ' written on ' . $this->date->format('Y-m-d') . chr(10) .
+ ' by ' . $this->author->getFullName() . chr(10) .
+ wordwrap($this->content, 70, chr(10)) . chr(10) .
+ implode(', ', $this->tags->toArray());
+ }
+}
+?>
\ No newline at end of file
--- /dev/null
+<?php
+namespace ExtbaseTeam\BlogExample\Domain\Model;
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+ * (c) 2011 Bastian Waidelich <bastian@typo3.org>
+ * All rights reserved
+ *
+ * This script is part of the TYPO3 project. The TYPO3 project is
+ * free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The GNU General Public License can be found at
+ * http://www.gnu.org/copyleft/gpl.html.
+ *
+ * This script is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * A blog post tag
+ */
+class Tag extends \TYPO3\CMS\Extbase\DomainObject\AbstractValueObject {
+
+ /**
+ * @var string
+ */
+ protected $name = '';
+
+ /**
+ * Constructs this tag
+ *
+ * @param $name
+ */
+ public function __construct($name) {
+ $this->name = $name;
+ }
+
+ /**
+ * Returns this tag's name
+ *
+ * @return string This tag's name
+ */
+ public function getName() {
+ return $this->name;
+ }
+
+ /**
+ * Returns this tag as a formatted string
+ *
+ * @return string
+ */
+ public function __toString() {
+ return $this->getName();
+ }
+}
+?>
\ No newline at end of file
--- /dev/null
+<?php
+namespace ExtbaseTeam\BlogExample\Domain\Repository;
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+ * (c) 2011 Bastian Waidelich <bastian@typo3.org>
+ * All rights reserved
+ *
+ * This script is part of the TYPO3 project. The TYPO3 project is
+ * free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The GNU General Public License can be found at
+ * http://www.gnu.org/copyleft/gpl.html.
+ *
+ * This script is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * A repository for administrators
+ */
+class AdministratorRepository extends \TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository {
+
+}
+?>
\ No newline at end of file
--- /dev/null
+<?php
+namespace ExtbaseTeam\BlogExample\Domain\Repository;
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+ * (c) 2011 Bastian Waidelich <bastian@typo3.org>
+ * All rights reserved
+ *
+ * This script is part of the TYPO3 project. The TYPO3 project is
+ * free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The GNU General Public License can be found at
+ * http://www.gnu.org/copyleft/gpl.html.
+ *
+ * This script is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * A repository for blogs
+ */
+class BlogRepository extends \TYPO3\CMS\Extbase\Persistence\Repository {
+
+ protected $defaultOrderings = array(
+ 'crdate' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING,
+ 'uid' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING
+ );
+
+ /**
+ * Life cycle method.
+ *
+ * @return void
+ */
+ public function initializeObject() {
+ /*
+ $querySettings = $this->objectManager->create('\TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings');
+ $querySettings->setRespectStoragePage(FALSE);
+ $this->setDefaultQuerySettings($querySettings);
+ */
+ }
+
+}
+?>
\ No newline at end of file
--- /dev/null
+<?php
+namespace ExtbaseTeam\BlogExample\Domain\Repository;
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+ * (c) 2011 Bastian Waidelich <bastian@typo3.org>
+ * All rights reserved
+ *
+ * This script is part of the TYPO3 project. The TYPO3 project is
+ * free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The GNU General Public License can be found at
+ * http://www.gnu.org/copyleft/gpl.html.
+ *
+ * This script is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * A repository for persons
+ */
+class PersonRepository extends \TYPO3\CMS\Extbase\Persistence\Repository {
+
+}
+?>
\ No newline at end of file
--- /dev/null
+<?php
+namespace ExtbaseTeam\BlogExample\Domain\Repository;
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+ * (c) 2011 Bastian Waidelich <bastian@typo3.org>
+ * All rights reserved
+ *
+ * This script is part of the TYPO3 project. The TYPO3 project is
+ * free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The GNU General Public License can be found at
+ * http://www.gnu.org/copyleft/gpl.html.
+ *
+ * This script is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * A repository for blog posts
+ */
+class PostRepository extends \TYPO3\CMS\Extbase\Persistence\Repository {
+
+ protected $defaultOrderings = array('date' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING);
+
+ /**
+ * Finds all posts by the specified blog
+ *
+ * @param \ExtbaseTeam\BlogExample\Domain\Model\Blog $blog The blog the post must refer to
+ * @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface The posts
+ */
+ public function findAllByBlog(\ExtbaseTeam\BlogExample\Domain\Model\Blog $blog) {
+ $query = $this->createQuery();
+ return $query
+ ->matching(
+ $query->equals('blog', $blog)
+ )
+ ->execute();
+ }
+
+ /**
+ * Finds posts by the specified tag and blog
+ *
+ * @param string $tag
+ * @param \ExtbaseTeam\BlogExample\Domain\Model\Blog $blog The blog the post must refer to
+ * @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface The posts
+ */
+ public function findByTagAndBlog($tag, \ExtbaseTeam\BlogExample\Domain\Model\Blog $blog) {
+ $query = $this->createQuery();
+ return $query
+ ->matching(
+ $query->logicalAnd(
+ $query->equals('blog', $blog),
+ $query->equals('tags.name', $tag)
+ )
+ )
+ ->execute();
+ }
+
+ /**
+ * Finds all remaining posts of the blog
+ *
+ * @param \ExtbaseTeam\BlogExample\Domain\Model\Post $post The reference post
+ * @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface The posts
+ */
+ public function findRemaining(\ExtbaseTeam\BlogExample\Domain\Model\Post $post) {
+ $blog = $post->getBlog();
+ $query = $this->createQuery();
+ return $query
+ ->matching(
+ $query->logicalAnd(
+ $query->equals('blog', $blog),
+ $query->logicalNot(
+ $query->equals('uid', $post->getUid())
+ )
+ )
+ )
+ ->execute();
+ }
+
+ /**
+ * Finds the previous of the given post
+ *
+ * @param \ExtbaseTeam\BlogExample\Domain\Model\Post $post The reference post
+ * @return \ExtbaseTeam\BlogExample\Domain\Model\Post
+ */
+ public function findPrevious(\ExtbaseTeam\BlogExample\Domain\Model\Post $post) {
+ $query = $this->createQuery();
+ return $query
+ ->matching(
+ $query->lessThan('date', $post->getDate())
+ )
+ ->execute()
+ ->getFirst();
+ }
+
+ /**
+ * Finds the post next to the given post
+ *
+ * @param \ExtbaseTeam\BlogExample\Domain\Model\Post $post The reference post
+ * @return \ExtbaseTeam\BlogExample\Domain\Model\Post
+ */
+ public function findNext(\ExtbaseTeam\BlogExample\Domain\Model\Post $post) {
+ $query = $this->createQuery();
+ return $query
+ ->matching(
+ $query->greaterThan('date', $post->getDate())
+ )
+ ->execute()
+ ->getFirst();
+ }
+
+ /**
+ * Finds most recent posts by the specified blog
+ *
+ * @param \ExtbaseTeam\BlogExample\Domain\Model\Blog $blog The blog the post must refer to
+ * @param integer $limit The number of posts to return at max
+ * @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface The posts
+ */
+ public function findRecentByBlog(\ExtbaseTeam\BlogExample\Domain\Model\Blog $blog, $limit = 5) {
+ $query = $this->createQuery();
+ return $query
+ ->matching(
+ $query->equals('blog', $blog)
+ )
+ ->setLimit((integer)$limit)
+ ->execute();
+ }
+
+}
+?>
\ No newline at end of file
--- /dev/null
+<T3DataStructure>
+ <sheets>
+ <sDEF>
+ <ROOT>
+ <TCEforms>
+ <sheetTitle>Options</sheetTitle>
+ </TCEforms>
+ <type>array</type>
+ <el>
+ <settings.postsPerPage>
+ <TCEforms>
+ <label>Max. number of posts to display per page</label>
+ <config>
+ <type>input</type>
+ <size>2</size>
+ <eval>int</eval>
+ <default>3</default>
+ </config>
+ </TCEforms>
+ </settings.postsPerPage>
+ </el>
+ </ROOT>
+ </sDEF>
+ </sheets>
+</T3DataStructure>
\ No newline at end of file
--- /dev/null
+<?php
+if (!defined ('TYPO3_MODE')) {
+ die ('Access denied.');
+}
+
+$TCA['tx_blogexample_domain_model_blog'] = array(
+ 'ctrl' => $TCA['tx_blogexample_domain_model_blog']['ctrl'],
+ 'interface' => array(
+ 'showRecordFieldList' => 'title, posts, administrator'
+ ),
+ 'columns' => array(
+ 'sys_language_uid' => Array (
+ 'exclude' => 1,
+ 'label' => 'LLL:EXT:lang/locallang_general.php:LGL.language',
+ 'config' => Array (
+ 'type' => 'select',
+ 'foreign_table' => 'sys_language',
+ 'foreign_table_where' => 'ORDER BY sys_language.title',
+ 'items' => Array(
+ Array('LLL:EXT:lang/locallang_general.php:LGL.allLanguages',-1),
+ Array('LLL:EXT:lang/locallang_general.php:LGL.default_value',0)
+ )
+ )
+ ),
+ 'l18n_parent' => Array (
+ 'displayCond' => 'FIELD:sys_language_uid:>:0',
+ 'exclude' => 1,
+ 'label' => 'LLL:EXT:lang/locallang_general.php:LGL.l18n_parent',
+ 'config' => Array (
+ 'type' => 'select',
+ 'items' => Array (
+ Array('', 0),
+ ),
+ 'foreign_table' => 'tx_blogexample_domain_model_blog',
+ 'foreign_table_where' => 'AND tx_blogexample_domain_model_blog.uid=###REC_FIELD_l18n_parent### AND tx_blogexample_domain_model_blog.sys_language_uid IN (-1,0)',
+ )
+ ),
+ 'l18n_diffsource' => Array(
+ 'config'=>array(
+ 'type'=>'passthrough'
+ )
+ ),
+ 't3ver_label' => Array (
+ 'displayCond' => 'FIELD:t3ver_label:REQ:true',
+ 'label' => 'LLL:EXT:lang/locallang_general.php:LGL.versionLabel',
+ 'config' => Array (
+ 'type'=>'none',
+ 'cols' => 27
+ )
+ ),
+ 'hidden' => array(
+ 'exclude' => 1,
+ 'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.hidden',
+ 'config' => array(
+ 'type' => 'check'
+ )
+ ),
+ 'title' => array(
+ 'exclude' => 0,
+ 'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_blog.title',
+ 'config' => array(
+ 'type' => 'input',
+ 'size' => 20,
+ 'eval' => 'trim,required',
+ 'max' => 256
+ )
+ ),
+ 'description' => array(
+ 'exclude' => 1,
+ 'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_blog.description',
+ 'config' => array(
+ 'type' => 'text',
+ 'eval' => 'required',
+ 'rows' => 30,
+ 'cols' => 80,
+ )
+ ),
+ 'logo' => array(
+ 'exclude' => 1,
+ 'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_blog.logo',
+ 'config' => array(
+ 'type' => 'group',
+ 'internal_type' => 'file',
+ 'allowed' => $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'],
+ 'max_size' => 3000,
+ 'uploadfolder' => 'uploads/pics',
+ 'show_thumbs' => 1,
+ 'size' => 1,
+ 'maxitems' => 1,
+ 'minitems' => 0
+ )
+ ),
+ 'posts' => array(
+ 'exclude' => 1,
+ 'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_blog.posts',
+ 'config' => array(
+ 'type' => 'inline',
+ 'foreign_table' => 'tx_blogexample_domain_model_post',
+ 'foreign_field' => 'blog',
+ 'foreign_sortby' => 'sorting',
+ 'maxitems' => 999999,
+ 'appearance' => array(
+ 'collapseAll' => 1,
+ 'expandSingle' => 1,
+ ),
+ )
+ ),
+ 'administrator' => Array (
+ 'exclude' => 1,
+ 'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_blog.administrator',
+ 'config' => Array (
+ 'type' => 'select',
+ 'foreign_table' => 'fe_users',
+ 'foreign_table_where' => "AND fe_users.tx_extbase_type='Tx_BlogExample_Domain_Model_Administrator'",
+ 'items' => array(
+ array('--none--', 0),
+ ),
+ 'wizards' => Array(
+ '_PADDING' => 1,
+ '_VERTICAL' => 1,
+ 'edit' => Array(
+ 'type' => 'popup',
+ 'title' => 'Edit',
+ 'script' => 'wizard_edit.php',
+ 'icon' => 'edit2.gif',
+ 'popup_onlyOpenIfSelected' => 1,
+ 'JSopenParams' => 'height=350,width=580,status=0,menubar=0,scrollbars=1',
+ ),
+ 'add' => Array(
+ 'type' => 'script',
+ 'title' => 'Create new',
+ 'icon' => 'add.gif',
+ 'params' => Array(
+ 'table'=>'fe_users',
+ 'pid' => '###CURRENT_PID###',
+ 'setValue' => 'prepend'
+ ),
+ 'script' => 'wizard_add.php',
+ ),
+ )
+ )
+ ),
+ ),
+ 'types' => array(
+ '1' => array('showitem' => 'sys_language_uid, hidden, title, description, logo, posts, administrator')
+ ),
+ 'palettes' => array(
+ '1' => array('showitem' => '')
+ )
+);
\ No newline at end of file
--- /dev/null
+<?php
+if (!defined ('TYPO3_MODE')) {
+ die ('Access denied.');
+}
+
+$TCA['tx_blogexample_domain_model_comment'] = array(
+ 'ctrl' => $TCA['tx_blogexample_domain_model_comment']['ctrl'],
+ 'interface' => array(
+ 'showRecordFieldList' => 'hidden, date, author, email, content'
+ ),
+ 'columns' => array(
+ 'hidden' => array(
+ 'exclude' => 1,
+ 'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.hidden',
+ 'config' => array(
+ 'type' => 'check'
+ )
+ ),
+ 'date' => array(
+ 'exclude' => 1,
+ 'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_comment.date',
+ 'config' => array(
+ 'type' => 'input',
+ 'size' => 12,
+ 'checkbox' => 1,
+ 'eval' => 'datetime, required',
+ 'default' => time()
+ )
+ ),
+ 'author' => array(
+ 'exclude' => 0,
+ 'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_comment.author',
+ 'config' => array(
+ 'type' => 'input',
+ 'size' => 20,
+ 'eval' => 'trim, required',
+ 'max' => 256
+ )
+ ),
+ 'email' => array(
+ 'exclude' => 0,
+ 'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_comment.email',
+ 'config' => array(
+ 'type' => 'input',
+ 'size' => 20,
+ 'eval' => 'trim, required',
+ 'max' => 256
+ )
+ ),
+ 'content' => array(
+ 'exclude' => 1,
+ 'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_comment.content',
+ 'config' => array(
+ 'type' => 'text',
+ 'rows' => 30,
+ 'cols' => 80
+ )
+ ),
+ 'post' => array(
+ 'config' => array(
+ 'type' => 'passthrough',
+ )
+ ),
+ ),
+ 'types' => array(
+ '1' => array('showitem' => 'hidden, date, author, email, content')
+ ),
+ 'palettes' => array(
+ '1' => array('showitem' => '')
+ )
+);
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+if (!defined ('TYPO3_MODE')) {
+ die ('Access denied.');
+}
+
+$TCA['tx_blogexample_domain_model_person'] = array(
+ 'ctrl' => $TCA['tx_blogexample_domain_model_person']['ctrl'],
+ 'interface' => array(
+ 'showRecordFieldList' => 'firstname, lastname, email, avatar'
+ ),
+ 'columns' => array(
+ 'hidden' => array(
+ 'exclude' => 1,
+ 'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.hidden',
+ 'config' => array(
+ 'type' => 'check'
+ )
+ ),
+ 'firstname' => array(
+ 'exclude' => 0,
+ 'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_person.firstname',
+ 'config' => array(
+ 'type' => 'input',
+ 'size' => 20,
+ 'eval' => 'trim,required',
+ 'max' => 256
+ )
+ ),
+ 'lastname' => array(
+ 'exclude' => 0,
+ 'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_person.lastname',
+ 'config' => array(
+ 'type' => 'input',
+ 'size' => 20,
+ 'eval' => 'trim,required',
+ 'max' => 256
+ )
+ ),
+ 'email' => array(
+ 'exclude' => 0,
+ 'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_person.email',
+ 'config' => array(
+ 'type' => 'input',
+ 'size' => 20,
+ 'eval' => 'trim, required',
+ 'max' => 256
+ )
+ )
+ ),
+ 'types' => array(
+ '1' => array('showitem' => 'firstname, lastname, email, avatar')
+ ),
+ 'palettes' => array(
+ '1' => array('showitem' => '')
+ )
+);
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+if (!defined ('TYPO3_MODE')) {
+ die ('Access denied.');
+}
+
+$TCA['tx_blogexample_domain_model_post'] = array(
+ 'ctrl' => $TCA['tx_blogexample_domain_model_post']['ctrl'],
+ 'interface' => array(
+ 'showRecordFieldList' => 'title, date, author',
+ 'maxDBListItems' => 100,
+ 'maxSingleDBListItems' => 500
+ ),
+ 'types' => array(
+ '1' => array('showitem' => 'sys_language_uid, hidden, blog, title, date, author, content, tags, comments, related_posts')
+ ),
+ 'columns' => array(
+ 'sys_language_uid' => Array (
+ 'exclude' => 1,
+ 'label' => 'LLL:EXT:lang/locallang_general.php:LGL.language',
+ 'config' => Array (
+ 'type' => 'select',
+ 'foreign_table' => 'sys_language',
+ 'foreign_table_where' => 'ORDER BY sys_language.title',
+ 'items' => Array(
+ Array('LLL:EXT:lang/locallang_general.php:LGL.allLanguages',-1),
+ Array('LLL:EXT:lang/locallang_general.php:LGL.default_value',0)
+ )
+ )
+ ),
+ 'l18n_parent' => Array (
+ 'displayCond' => 'FIELD:sys_language_uid:>:0',
+ 'exclude' => 1,
+ 'label' => 'LLL:EXT:lang/locallang_general.php:LGL.l18n_parent',
+ 'config' => Array (
+ 'type' => 'select',
+ 'items' => Array (
+ Array('', 0),
+ ),
+ 'foreign_table' => 'tx_blogexample_domain_model_post',
+ 'foreign_table_where' => 'AND tx_blogexample_domain_model_post.uid=###REC_FIELD_l18n_parent### AND tx_blogexample_domain_model_post.sys_language_uid IN (-1,0)',
+ )
+ ),
+ 'l18n_diffsource' => Array(
+ 'config'=>array(
+ 'type'=>'passthrough'
+ )
+ ),
+ 'hidden' => array(
+ 'exclude' => 1,
+ 'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.hidden',
+ 'config' => array(
+ 'type' => 'check'
+ )
+ ),
+ 'blog' => Array (
+ 'exclude' => 1,
+ 'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_post.blog',
+ 'config' => Array (
+ 'type' => 'select',
+ 'foreign_table' => 'tx_blogexample_domain_model_blog',
+ 'maxitems' => 1,
+ )
+ ),
+ 'title' => array(
+ 'exclude' => 0,
+ 'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_post.title',
+ 'config' => array(
+ 'type' => 'input',
+ 'size' => 20,
+ 'eval' => 'trim, required',
+ 'max' => 256
+ )
+ ),
+ 'date' => array(
+ 'exclude' => 1,
+ 'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_post.date',
+ 'config' => array(
+ 'type' => 'input',
+ 'size' => 12,
+ 'checkbox' => 1,
+ 'eval' => 'datetime, required',
+ 'default' => time()
+ )
+ ),
+ 'author' => array(
+ 'exclude' => 1,
+ 'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_post.author',
+ 'config' => array(
+ 'type' => 'select',
+ 'foreign_table' => 'tx_blogexample_domain_model_person',
+ 'wizards' => Array(
+ '_PADDING' => 1,
+ '_VERTICAL' => 1,
+ 'edit' => Array(
+ 'type' => 'popup',
+ 'title' => 'Edit',
+ 'script' => 'wizard_edit.php',
+ 'icon' => 'edit2.gif',
+ 'popup_onlyOpenIfSelected' => 1,
+ 'JSopenParams' => 'height=350,width=580,status=0,menubar=0,scrollbars=1',
+ ),
+ 'add' => Array(
+ 'type' => 'script',
+ 'title' => 'Create new',
+ 'icon' => 'add.gif',
+ 'params' => Array(
+ 'table'=>'tx_blogexample_domain_model_person',
+ 'pid' => '###CURRENT_PID###',
+ 'setValue' => 'prepend'
+ ),
+ 'script' => 'wizard_add.php',
+ ),
+ )
+ )
+ ),
+ 'content' => array(
+ 'exclude' => 1,
+ 'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_post.content',
+ 'config' => array(
+ 'type' => 'text',
+ 'rows' => 30,
+ 'cols' => 80
+ )
+ ),
+ 'tags' => array(
+ 'exclude' => 1,
+ 'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_post.tags',
+ 'config' => array(
+ 'type' => 'inline',
+ 'foreign_table' => 'tx_blogexample_domain_model_tag',
+ 'MM' => 'tx_blogexample_post_tag_mm',
+ 'maxitems' => 9999,
+ 'appearance' => array(
+ 'useCombination' => 1,
+ 'useSortable' => 1,
+ 'collapseAll' => 1,
+ 'expandSingle' => 1,
+ )
+ )
+ ),
+ 'comments' => array(
+ 'exclude' => 1,
+ 'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_post.comments',
+ 'config' => array(
+ 'type' => 'inline',
+ 'foreign_table' => 'tx_blogexample_domain_model_comment',
+ 'foreign_field' => 'post',
+ 'size' => 10,
+ 'maxitems' => 9999,
+ 'autoSizeMax' => 30,
+ 'multiple' => 0,
+ 'appearance' => array(
+ 'collapseAll' => 1,
+ 'expandSingle' => 1,
+ )
+ )
+ ),
+ 'related_posts' => array(
+ 'exclude' => 1,
+ 'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_post.related',
+ 'config' => array(
+ 'type' => 'select',
+ 'size' => 10,
+ 'maxitems' => 9999,
+ 'autoSizeMax' => 30,
+ 'multiple' => 0,
+ 'foreign_table' => 'tx_blogexample_domain_model_post',
+ 'foreign_table_where' => 'AND ###THIS_UID### != tx_blogexample_domain_model_post.uid',
+ 'MM' => 'tx_blogexample_post_post_mm',
+ 'MM_opposite_field' => 'related_posts',
+ )
+ ),
+ )
+);
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+if (!defined ('TYPO3_MODE')) {
+ die ('Access denied.');
+}
+
+$TCA['tx_blogexample_domain_model_tag'] = array(
+ 'ctrl' => $TCA['tx_blogexample_domain_model_tag']['ctrl'],
+ 'interface' => array(
+ 'showRecordFieldList' => 'hidden, name, posts'
+ ),
+ 'columns' => array(
+ 'sys_language_uid' => Array (
+ 'exclude' => 1,
+ 'label' => 'LLL:EXT:lang/locallang_general.php:LGL.language',
+ 'config' => Array (
+ 'type' => 'select',
+ 'foreign_table' => 'sys_language',
+ 'foreign_table_where' => 'ORDER BY sys_language.title',
+ 'items' => Array(
+ Array('LLL:EXT:lang/locallang_general.php:LGL.allLanguages',-1),
+ Array('LLL:EXT:lang/locallang_general.php:LGL.default_value',0)
+ )
+ )
+ ),
+ 'l18n_parent' => Array (
+ 'displayCond' => 'FIELD:sys_language_uid:>:0',
+ 'exclude' => 1,
+ 'label' => 'LLL:EXT:lang/locallang_general.php:LGL.l18n_parent',
+ 'config' => Array (
+ 'type' => 'select',
+ 'items' => Array (
+ Array('', 0),
+ ),
+ 'foreign_table' => 'tx_blogexample_domain_model_tag',
+ 'foreign_table_where' => 'AND tx_blogexample_domain_model_tag.uid=###REC_FIELD_l18n_parent### AND tx_blogexample_domain_model_tag.sys_language_uid IN (-1,0)',
+ )
+ ),
+ 'l18n_diffsource' => Array(
+ 'config'=>array(
+ 'type'=>'passthrough'
+ )
+ ),
+ 'hidden' => array(
+ 'exclude' => 1,
+ 'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.hidden',
+ 'config' => array(
+ 'type' => 'check'
+ )
+ ),
+ 'name' => array(
+ 'exclude' => 0,
+ 'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_tag.name',
+ 'config' => array(
+ 'type' => 'input',
+ 'size' => 20,
+ 'eval' => 'trim, required',
+ 'max' => 256
+ )
+ ),
+ 'posts' => array(
+ 'exclude' => 1,
+ 'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_tag.posts',
+ 'config' => array(
+ 'type' => 'select',
+ 'size' => 10,
+ 'minitems' => 0,
+ 'maxitems' => 9999,
+ 'autoSizeMax' => 30,
+ 'multiple' => 0,
+ 'foreign_table' => 'tx_blogexample_domain_model_post',
+ 'MM' => 'tx_blogexample_post_tag_mm',
+ 'MM_opposite_field' => 'tags',
+ )
+ ),
+ ),
+ 'types' => array(
+ '1' => array('showitem' => 'sys_language_uid, hidden, name, posts')
+ ),
+ 'palettes' => array(
+ '1' => array('showitem' => '')
+ )
+);
+
+?>
\ No newline at end of file
--- /dev/null
+ # Include BlogExample default styles
+
+page.includeCSS.tx_blogexample = EXT:blog_example/Resources/Public/Css/BlogExample.css
\ No newline at end of file
--- /dev/null
+plugin.tx_blogexample {
+ settings {
+ # cat=plugin.tx_blogexample/a; type=int+; label=Editor FE Usergroup uid:Enter the uid of the FE Usergroup that should be allowed to edit Blogs and Post in the frontend
+ editorUsergroupUid = 1
+ # cat=plugin.tx_blogexample/a; type=int+; label=Plaintext page type:If the default plaintext page typenum (778) conflicts with your setup, you can override this setting here
+ plaintextPageType = 778
+ }
+ view {
+ # cat=plugin.tx_blogexample/file; type=string; label=Path to template root (FE)
+ templateRootPath = EXT:blog_example/Resources/Private/Templates/
+ # cat=plugin.tx_blogexample/file; type=string; label=Path to template partials (FE)
+ partialRootPath = EXT:blog_example/Resources/Private/Partials/
+ # cat=plugin.tx_blogexample/file; type=string; label=Path to template layouts (FE)
+ layoutRootPath = EXT:blog_example/Resources/Private/Layouts/
+ }
+ persistence {
+ # cat=plugin.tx_blogexample//a; type=int+; label=Default storage PID
+ storagePid =
+ }
+}
+module.tx_blogexample {
+ view {
+ # cat=module.tx_blogexample/file; type=string; label=Path to template root (BE)
+ templateRootPath = EXT:blog_example/Resources/Private/Backend/Templates/
+ # cat=module.tx_blogexample/file; type=string; label=Path to template partials (BE)
+ partialRootPath = EXT:blog_example/Resources/Private/Partials/
+ # cat=module.tx_blogexample/file; type=string; label=Path to template layouts (BE)
+ layoutRootPath = EXT:blog_example/Resources/Private/Backend/Layouts/
+ }
+}
\ No newline at end of file
--- /dev/null
+ # Plugin configuration
+plugin.tx_blogexample {
+ settings {
+ # maximum number of posts to display per page
+ postsPerPage = 3
+ # Editor FE Usergroup uid
+ editorUsergroupUid = {$plugin.tx_blogexample.settings.editorUsergroupUid}
+ # Plaintext page type number
+ plaintextPageType = {$plugin.tx_blogexample.settings.plaintextPageType}
+ }
+ persistence {
+ storagePid = {$plugin.tx_blogexample.persistence.storagePid}
+ }
+ view {
+ templateRootPath = {$plugin.tx_blogexample.view.templateRootPath}
+ partialRootPath = {$plugin.tx_blogexample.view.partialRootPath}
+ layoutRootPath = {$plugin.tx_blogexample.view.layoutRootPath}
+ defaultPid = auto
+ }
+ # This is an example how to modify the translation
+ _LOCAL_LANG {
+ default {
+ someUnusedKey = foo
+ }
+ }
+}
+
+ # Module configuration
+module.tx_blogexample {
+ settings < plugin.tx_blogexample.settings
+ persistence < plugin.tx_blogexample.persistence
+ view < plugin.tx_blogexample.view
+ view {
+ templateRootPath = {$module.tx_blogexample.view.templateRootPath}
+ partialRootPath = {$module.tx_blogexample.view.partialRootPath}
+ layoutRootPath = {$module.tx_blogexample.view.layoutRootPath}
+ }
+}
+
+ # plaintext rendering
+tx_blogexample_plaintext = PAGE
+tx_blogexample_plaintext {
+ typeNum = {$plugin.tx_blogexample.settings.plaintextPageType}
+ 10 = USER
+ 10 {
+ userFunc = tx_extbase_core_bootstrap->run
+ extensionName = BlogExample
+ pluginName = PostList
+ switchableControllerActions {
+ Post {
+ 1 = index
+ }
+ }
+ }
+ config {
+ admPanel = 0
+ no_cache = 1
+ disableAllHeaderCode = 1
+ additionalHeaders = Content-type:text/plain
+ defaultGetVars {
+ tx_blogexample_postlist.format = txt
+ }
+ }
+}
+
+ # Adjust plaintext rendering, if blog_example runs as single, fully fledged plugin
+[globalVar = TYPO3_CONF_VARS|EXTCONF|blog_example|registerSinglePlugin > 0]
+ tx_blogexample_plaintext {
+ 10.pluginName = Pi1
+ #config.defaultGetVars =
+ }
+[end]
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<T3locallang>
+ <meta type="array">
+ <type>CSH</type>
+ <description>Language labels for the blog_example context sensitive help (CSH)</description>
+ <csh_table>_MOD_txblogexampleM1</csh_table>
+ </meta>
+ <data type="array">
+ <languageKey index="default" type="array">
+ <label index=".alttitle">Blog Example</label>
+ <label index=".description">This is some dummy help. But it's context sensitive!</label>
+ <label index=".seeAlso">_MOD_web_func:tx_wizardcrpages, _MOD_web_func:tx_wizardsortpages</label>
+ </languageKey>
+ </data>
+</T3locallang>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<T3locallang>
+ <meta type="array">
+ <type>database</type>
+ <description>Language labels for database tables/fields belonging to extension 'blog_example'</description>
+ </meta>
+ <data type="array">
+ <languageKey index="default" type="array">
+ <label index="tx_blogexample_domain_model_blog">Blog</label>
+ <label index="tx_blogexample_domain_model_blog.title">Blog title</label>
+ <label index="tx_blogexample_domain_model_blog.description">Short description</label>
+ <label index="tx_blogexample_domain_model_blog.logo">Logo</label>
+ <label index="tx_blogexample_domain_model_blog.posts">Posts</label>
+ <label index="tx_blogexample_domain_model_blog.administrator">Administrator</label>
+ <label index="tx_blogexample_domain_model_post">Post</label>
+ <label index="tx_blogexample_domain_model_post.blog">Related to</label>
+ <label index="tx_blogexample_domain_model_post.title">Title</label>
+ <label index="tx_blogexample_domain_model_post.date">Date</label>
+ <label index="tx_blogexample_domain_model_post.author">Author</label>
+ <label index="tx_blogexample_domain_model_post.content">Content</label>
+ <label index="tx_blogexample_domain_model_post.votes">Votes</label>
+ <label index="tx_blogexample_domain_model_post.published">Published</label>
+ <label index="tx_blogexample_domain_model_post.tags">Tags</label>
+ <label index="tx_blogexample_domain_model_post.comments">Comments</label>
+ <label index="tx_blogexample_domain_model_post.related">Related posts</label>
+ <label index="tx_blogexample_domain_model_person">Person</label>
+ <label index="tx_blogexample_domain_model_person.firstname">Firstname</label>
+ <label index="tx_blogexample_domain_model_person.lastname">Lastname</label>
+ <label index="tx_blogexample_domain_model_person.email">E-Mail</label>
+ <label index="tx_blogexample_domain_model_person.avatar">Avatar</label>
+ <label index="tx_blogexample_domain_model_comment">Comment</label>
+ <label index="tx_blogexample_domain_model_comment.date">Date</label>
+ <label index="tx_blogexample_domain_model_comment.author">Author</label>
+ <label index="tx_blogexample_domain_model_comment.email">Email</label>
+ <label index="tx_blogexample_domain_model_comment.content">Content</label>
+ <label index="tx_blogexample_domain_model_tag">Tag</label>
+ <label index="tx_blogexample_domain_model_tag.name">Name</label>
+ <label index="tx_blogexample_domain_model_tag.posts">Related posts</label>
+ <label index="fe_users.tx_extbase_type.Tx_BlogExample_Domain_Model_Administrator">Blog Admin (BlogExample)</label>
+ </languageKey>
+ </data>
+</T3locallang>
\ No newline at end of file
--- /dev/null
+<?php
+
+########################################################################
+# Extension Manager/Repository config file for ext "blog_example".
+#
+# Auto generated 15-02-2011 19:01
+#
+# Manual updates:
+# Only the data in the array - everything else is removed by next
+# writing. "version" and "dependencies" must not be touched!
+########################################################################
+
+$EM_CONF[$_EXTKEY] = array(
+ 'title' => 'A Blog Example for the Extbase Framework',
+ 'description' => 'An example extension demonstrating the features of the Extbase Framework. It is the back-ported and tweaked Blog Example package of FLOW3. Have fun playing with it!',
+ 'category' => 'example',
+ 'author' => 'TYPO3 core team',
+ 'author_company' => '',
+ 'author_email' => '',
+ 'shy' => '',
+ 'dependencies' => 'extbase,fluid',
+ 'conflicts' => '',
+ 'priority' => '',
+ 'module' => '',
+ 'state' => 'stable',
+ 'internal' => '',
+ 'uploadfolder' => 0,
+ 'createDirs' => '',
+ 'modify_tables' => '',
+ 'clearCacheOnLoad' => 1,
+ 'lockType' => '',
+ 'version' => '1.4.0-devel',
+ 'constraints' => array(
+ 'depends' => array(
+ 'php' => '5.2.0-0.0.0',
+ 'typo3' => '4.5.0-0.0.0',
+ 'extbase' => '1.3.0-0.0.0',
+ 'fluid' => '1.3.0-0.0.0',
+ ),
+ 'conflicts' => array(
+ ),
+ 'suggests' => array(
+ ),
+ ),
+ '_md5_values_when_last_written' => 'a:77:{s:16:"ext_autoload.php";s:4:"91f9";s:21:"ext_conf_template.txt";s:4:"9b9c";s:12:"ext_icon.gif";s:4:"e922";s:17:"ext_localconf.php";s:4:"e7f7";s:14:"ext_tables.php";s:4:"b3b3";s:14:"ext_tables.sql";s:4:"33b2";s:41:"Classes/Controller/AbstractController.php";s:4:"44c4";s:37:"Classes/Controller/BlogController.php";s:4:"4f84";s:40:"Classes/Controller/CommentController.php";s:4:"fbc0";s:37:"Classes/Controller/PostController.php";s:4:"c44f";s:38:"Classes/Domain/Model/Administrator.php";s:4:"67d5";s:29:"Classes/Domain/Model/Blog.php";s:4:"1c30";s:32:"Classes/Domain/Model/Comment.php";s:4:"a01a";s:31:"Classes/Domain/Model/Person.php";s:4:"7fac";s:29:"Classes/Domain/Model/Post.php";s:4:"1285";s:28:"Classes/Domain/Model/Tag.php";s:4:"c0e8";s:53:"Classes/Domain/Repository/AdministratorRepository.php";s:4:"dd2e";s:44:"Classes/Domain/Repository/BlogRepository.php";s:4:"b84b";s:46:"Classes/Domain/Repository/PersonRepository.php";s:4:"58b9";s:44:"Classes/Domain/Repository/PostRepository.php";s:4:"58a3";s:38:"Classes/Domain/Service/BlogFactory.php";s:4:"643c";s:42:"Classes/Domain/Validator/BlogValidator.php";s:4:"e8bb";s:42:"Classes/ViewHelpers/GravatarViewHelper.php";s:4:"662a";s:41:"Configuration/FlexForms/flexform_list.xml";s:4:"11b7";s:25:"Configuration/TCA/tca.php";s:4:"875b";s:38:"Configuration/TypoScript/constants.txt";s:4:"0b87";s:34:"Configuration/TypoScript/setup.txt";s:4:"11cd";s:48:"Configuration/TypoScript/DefaultStyles/setup.txt";s:4:"ece4";s:46:"Resources/Private/Backend/Layouts/Default.html";s:4:"8b03";s:50:"Resources/Private/Backend/Templates/Blog/Edit.html";s:4:"9011";s:51:"Resources/Private/Backend/Templates/Blog/Index.html";s:4:"f4ca";s:49:"Resources/Private/Backend/Templates/Blog/New.html";s:4:"e68c";s:50:"Resources/Private/Backend/Templates/Post/Edit.html";s:4:"905a";s:51:"Resources/Private/Backend/Templates/Post/Index.html";s:4:"2247";s:50:"Resources/Private/Backend/Templates/Post/Index.txt";s:4:"ac46";s:49:"Resources/Private/Backend/Templates/Post/New.html";s:4:"ed51";s:50:"Resources/Private/Backend/Templates/Post/Show.html";s:4:"ab24";s:40:"Resources/Private/Language/locallang.xml";s:4:"0618";s:44:"Resources/Private/Language/locallang_csh.xml";s:4:"5e95";s:43:"Resources/Private/Language/locallang_db.xml";s:4:"e603";s:44:"Resources/Private/Language/locallang_mod.xml";s:4:"cd5d";s:38:"Resources/Private/Layouts/Default.html";s:4:"4ed3";s:40:"Resources/Private/Partials/BlogForm.html";s:4:"721f";s:43:"Resources/Private/Partials/CommentForm.html";s:4:"6606";s:42:"Resources/Private/Partials/FormErrors.html";s:4:"a141";s:40:"Resources/Private/Partials/PostForm.html";s:4:"04f6";s:44:"Resources/Private/Partials/PostMetaData.html";s:4:"9215";s:40:"Resources/Private/Partials/PostTags.html";s:4:"5d24";s:42:"Resources/Private/Templates/Blog/Edit.html";s:4:"8fab";s:43:"Resources/Private/Templates/Blog/Index.html";s:4:"69cc";s:41:"Resources/Private/Templates/Blog/New.html";s:4:"caaf";s:42:"Resources/Private/Templates/Post/Edit.html";s:4:"4dcf";s:43:"Resources/Private/Templates/Post/Index.html";s:4:"b81d";s:42:"Resources/Private/Templates/Post/Index.txt";s:4:"c3e6";s:41:"Resources/Private/Templates/Post/New.html";s:4:"9e3d";s:42:"Resources/Private/Templates/Post/Show.html";s:4:"bf64";s:36:"Resources/Public/Css/BlogExample.css";s:4:"9b2b";s:43:"Resources/Public/Icons/default_gravatar.gif";s:4:"6087";s:37:"Resources/Public/Icons/icon_close.gif";s:4:"31ee";s:38:"Resources/Public/Icons/icon_delete.gif";s:4:"90c6";s:36:"Resources/Public/Icons/icon_edit.gif";s:4:"3248";s:35:"Resources/Public/Icons/icon_new.gif";s:4:"5098";s:36:"Resources/Public/Icons/icon_next.gif";s:4:"6add";s:41:"Resources/Public/Icons/icon_plaintext.gif";s:4:"af96";s:40:"Resources/Public/Icons/icon_populate.gif";s:4:"500c";s:40:"Resources/Public/Icons/icon_previous.gif";s:4:"50c0";s:40:"Resources/Public/Icons/icon_relation.gif";s:4:"9e5c";s:64:"Resources/Public/Icons/icon_tx_blogexample_domain_model_blog.gif";s:4:"50a3";s:67:"Resources/Public/Icons/icon_tx_blogexample_domain_model_comment.gif";s:4:"53ba";s:66:"Resources/Public/Icons/icon_tx_blogexample_domain_model_person.gif";s:4:"0bef";s:64:"Resources/Public/Icons/icon_tx_blogexample_domain_model_post.gif";s:4:"cf99";s:63:"Resources/Public/Icons/icon_tx_blogexample_domain_model_tag.gif";s:4:"3731";s:46:"Resources/Public/Icons/FlashMessages/error.png";s:4:"1c8f";s:52:"Resources/Public/Icons/FlashMessages/information.png";s:4:"6235";s:47:"Resources/Public/Icons/FlashMessages/notice.png";s:4:"813d";s:43:"Resources/Public/Icons/FlashMessages/ok.png";s:4:"e36c";s:48:"Resources/Public/Icons/FlashMessages/warning.png";s:4:"dada";}',
+ 'suggests' => array(
+ ),
+);
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+if (!defined ('TYPO3_MODE')) die ('Access denied.');
+
+/**
+ * Add labels for context sensitive help (CSH)
+ */
+\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addLLrefForTCAdescr('_MOD_web_BlogExampleTxBlogexampleM1', 'EXT:' . $_EXTKEY . '/Resources/Private/Language/locallang_csh.xml');
+
+\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile($_EXTKEY, 'Configuration/TypoScript', 'BlogExample setup');
+\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile($_EXTKEY, 'Configuration/TypoScript/DefaultStyles', 'BlogExample CSS Styles (optional)');
+
+\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::allowTableOnStandardPages('tx_blogexample_domain_model_blog');
+$TCA['tx_blogexample_domain_model_blog'] = array (
+ 'ctrl' => array (
+ 'title' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_blog',
+ 'label' => 'title',
+ 'tstamp' => 'tstamp',
+ 'crdate' => 'crdate',
+ 'versioningWS' => 2,
+ 'versioning_followPages' => true,
+ 'origUid' => 't3_origuid',
+ 'languageField' => 'sys_language_uid',
+ 'transOrigPointerField' => 'l18n_parent',
+ 'transOrigDiffSourceField' => 'l18n_diffsource',
+ 'delete' => 'deleted',
+ 'enablecolumns' => array(
+ 'disabled' => 'hidden'
+ ),
+ 'dynamicConfigFile' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath($_EXTKEY) . 'Configuration/TCA/Blog.php',
+ 'iconfile' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath($_EXTKEY) . 'Resources/Public/Icons/icon_tx_blogexample_domain_model_blog.gif'
+ )
+);
+
+\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::allowTableOnStandardPages('tx_blogexample_domain_model_post');
+$TCA['tx_blogexample_domain_model_post'] = array (
+ 'ctrl' => array (
+ 'title' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_post',
+ 'label' => 'title',
+ 'label_alt' => 'author',
+ 'label_alt_force' => TRUE,
+ 'tstamp' => 'tstamp',
+ 'crdate' => 'crdate',
+ 'versioningWS' => 2,
+ 'versioning_followPages' => true,
+ 'origUid' => 't3_origuid',
+ 'languageField' => 'sys_language_uid',
+ 'transOrigPointerField' => 'l18n_parent',
+ 'transOrigDiffSourceField' => 'l18n_diffsource',
+ 'delete' => 'deleted',
+ 'enablecolumns' => array(
+ 'disabled' => 'hidden'
+ ),
+ 'dynamicConfigFile' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath($_EXTKEY) . 'Configuration/TCA/Post.php',
+ 'iconfile' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath($_EXTKEY) . 'Resources/Public/Icons/icon_tx_blogexample_domain_model_post.gif'
+ )
+);
+
+\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::allowTableOnStandardPages('tx_blogexample_domain_model_comment');
+$TCA['tx_blogexample_domain_model_comment'] = array (
+ 'ctrl' => array (
+ 'title' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_comment',
+ 'label' => 'date',
+ 'label_alt' => 'author',
+ 'label_alt_force' => TRUE,
+ 'tstamp' => 'tstamp',
+ 'crdate' => 'crdate',
+ 'delete' => 'deleted',
+ 'enablecolumns' => array (
+ 'disabled' => 'hidden'
+ ),
+ 'dynamicConfigFile' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath($_EXTKEY) . 'Configuration/TCA/Comment.php',
+ 'iconfile' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath($_EXTKEY) . 'Resources/Public/Icons/icon_tx_blogexample_domain_model_comment.gif'
+ )
+);
+
+\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::allowTableOnStandardPages('tx_blogexample_domain_model_person');
+$TCA['tx_blogexample_domain_model_person'] = array (
+ 'ctrl' => array (
+ 'title' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_person',
+ 'label' => 'lastname',
+ 'label_alt' => 'firstname',
+ 'label_alt_force' => TRUE,
+ 'tstamp' => 'tstamp',
+ 'crdate' => 'crdate',
+ 'versioningWS' => 2,
+ 'versioning_followPages' => true,
+ 'origUid' => 't3_origuid',
+ 'prependAtCopy' => 'LLL:EXT:lang/locallang_general.xml:LGL.prependAtCopy',
+ 'delete' => 'deleted',
+ 'enablecolumns' => array(
+ 'disabled' => 'hidden'
+ ),
+ 'dynamicConfigFile' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath($_EXTKEY) . 'Configuration/TCA/Person.php',
+ 'iconfile' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath($_EXTKEY) . 'Resources/Public/Icons/icon_tx_blogexample_domain_model_person.gif'
+ )
+);
+
+\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::allowTableOnStandardPages('tx_blogexample_domain_model_tag');
+$TCA['tx_blogexample_domain_model_tag'] = array (
+ 'ctrl' => array (
+ 'title' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_tag',
+ 'label' => 'name',
+ 'tstamp' => 'tstamp',
+ 'crdate' => 'crdate',
+ 'delete' => 'deleted',
+ 'enablecolumns' => array (
+ 'disabled' => 'hidden'
+ ),
+ 'dynamicConfigFile' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath($_EXTKEY) . 'Configuration/TCA/Tag.php',
+ 'iconfile' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath($_EXTKEY) . 'Resources/Public/Icons/icon_tx_blogexample_domain_model_tag.gif'
+ )
+);
+
+if (is_array($TCA['fe_users']['columns']['tx_extbase_type'])) {
+ $TCA['fe_users']['types']['Tx_BlogExample_Domain_Model_Administrator'] = $TCA['fe_users']['types']['0'];
+ array_push($TCA['fe_users']['columns']['tx_extbase_type']['config']['items'], array('LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:fe_users.tx_extbase_type.Tx_BlogExample_Domain_Model_Administrator', 'Tx_BlogExample_Domain_Model_Administrator'));
+}
+?>
\ No newline at end of file
--- /dev/null
+#
+# Table structure for table 'tx_blogexample_domain_model_blog'
+#
+CREATE TABLE tx_blogexample_domain_model_blog (
+ uid int(11) unsigned DEFAULT '0' NOT NULL auto_increment,
+ pid int(11) DEFAULT '0' NOT NULL,
+
+ title varchar(255) DEFAULT '' NOT NULL,
+ description text NOT NULL,
+ logo tinyblob NOT NULL,
+ administrator varchar(255) DEFAULT '',
+
+ posts varchar(255) DEFAULT '' NOT NULL,
+
+ tstamp int(11) unsigned DEFAULT '0' NOT NULL,
+ crdate int(11) unsigned DEFAULT '0' NOT NULL,
+ deleted tinyint(4) unsigned DEFAULT '0' NOT NULL,
+ hidden tinyint(4) unsigned DEFAULT '0' NOT NULL,
+
+ t3ver_oid int(11) DEFAULT '0' NOT NULL,
+ t3ver_id int(11) DEFAULT '0' NOT NULL,
+ t3ver_wsid int(11) DEFAULT '0' NOT NULL,
+ t3ver_label varchar(30) DEFAULT '' NOT NULL,
+ t3ver_state tinyint(4) DEFAULT '0' NOT NULL,
+ t3ver_stage tinyint(4) DEFAULT '0' NOT NULL,
+ t3ver_count int(11) DEFAULT '0' NOT NULL,
+ t3ver_tstamp int(11) DEFAULT '0' NOT NULL,
+ t3ver_move_id int(11) DEFAULT '0' NOT NULL,
+ t3_origuid int(11) DEFAULT '0' NOT NULL,
+
+ sys_language_uid int(11) DEFAULT '0' NOT NULL,
+ l18n_parent int(11) DEFAULT '0' NOT NULL,
+ l18n_diffsource mediumblob NOT NULL,
+
+ PRIMARY KEY (uid),
+ KEY parent (pid),
+ KEY t3ver_oid (t3ver_oid,t3ver_wsid),
+);
+
+#
+# Table structure for table 'tx_blogexample_domain_model_post'
+#
+CREATE TABLE tx_blogexample_domain_model_post (
+ uid int(11) unsigned DEFAULT '0' NOT NULL auto_increment,
+ pid int(11) DEFAULT '0' NOT NULL,
+
+ blog int(11) DEFAULT '0' NOT NULL,
+
+ title varchar(255) DEFAULT '' NOT NULL,
+ date int(11) DEFAULT '0' NOT NULL,
+ author int(255) DEFAULT '0' NOT NULL,
+ content text NOT NULL,
+ tags int(11) unsigned DEFAULT '0' NOT NULL,
+ comments int(11) unsigned DEFAULT '0' NOT NULL,
+ related_posts int(11) unsigned DEFAULT '0' NOT NULL,
+
+ tstamp int(11) unsigned DEFAULT '0' NOT NULL,
+ crdate int(11) unsigned DEFAULT '0' NOT NULL,
+ deleted tinyint(4) unsigned DEFAULT '0' NOT NULL,
+ hidden tinyint(4) unsigned DEFAULT '0' NOT NULL,
+ sorting tinyint(4) unsigned DEFAULT '0' NOT NULL,
+
+ t3ver_oid int(11) DEFAULT '0' NOT NULL,
+ t3ver_id int(11) DEFAULT '0' NOT NULL,
+ t3ver_wsid int(11) DEFAULT '0' NOT NULL,
+ t3ver_label varchar(30) DEFAULT '' NOT NULL,
+ t3ver_state tinyint(4) DEFAULT '0' NOT NULL,
+ t3ver_stage tinyint(4) DEFAULT '0' NOT NULL,
+ t3ver_count int(11) DEFAULT '0' NOT NULL,
+ t3ver_tstamp int(11) DEFAULT '0' NOT NULL,
+ t3ver_move_id int(11) DEFAULT '0' NOT NULL,
+ t3_origuid int(11) DEFAULT '0' NOT NULL,
+
+ sys_language_uid int(11) DEFAULT '0' NOT NULL,
+ l18n_parent int(11) DEFAULT '0' NOT NULL,
+ l18n_diffsource mediumblob NOT NULL,
+
+ PRIMARY KEY (uid),
+ KEY parent (pid),
+ KEY t3ver_oid (t3ver_oid,t3ver_wsid),
+);
+
+#
+# Table structure for table 'tx_blogexample_domain_model_comment'
+#
+CREATE TABLE tx_blogexample_domain_model_comment (
+ uid int(11) unsigned DEFAULT '0' NOT NULL auto_increment,
+ pid int(11) DEFAULT '0' NOT NULL,
+
+ post int(11) DEFAULT '0' NOT NULL,
+
+ date int(11) DEFAULT '0' NOT NULL,
+ author varchar(255) DEFAULT '' NOT NULL,
+ email varchar(255) DEFAULT '' NOT NULL,
+ content text NOT NULL,
+
+ tstamp int(11) unsigned DEFAULT '0' NOT NULL,
+ crdate int(11) unsigned DEFAULT '0' NOT NULL,
+ deleted tinyint(4) unsigned DEFAULT '0' NOT NULL,
+ hidden tinyint(4) unsigned DEFAULT '0' NOT NULL,
+
+ PRIMARY KEY (uid),
+ KEY parent (pid),
+);
+
+#
+# Table structure for table 'tx_blogexample_domain_model_person'
+#
+CREATE TABLE tx_blogexample_domain_model_person (
+ uid int(11) unsigned DEFAULT '0' NOT NULL auto_increment,
+ pid int(11) DEFAULT '0' NOT NULL,
+
+ firstname varchar(255) DEFAULT '' NOT NULL,
+ lastname varchar(255) DEFAULT '' NOT NULL,
+ email varchar(255) DEFAULT '' NOT NULL,
+
+ tstamp int(11) unsigned DEFAULT '0' NOT NULL,
+ crdate int(11) unsigned DEFAULT '0' NOT NULL,
+ deleted tinyint(4) unsigned DEFAULT '0' NOT NULL,
+ hidden tinyint(4) unsigned DEFAULT '0' NOT NULL,
+
+ t3ver_oid int(11) DEFAULT '0' NOT NULL,
+ t3ver_id int(11) DEFAULT '0' NOT NULL,
+ t3ver_wsid int(11) DEFAULT '0' NOT NULL,
+ t3ver_label varchar(30) DEFAULT '' NOT NULL,
+ t3ver_state tinyint(4) DEFAULT '0' NOT NULL,
+ t3ver_stage tinyint(4) DEFAULT '0' NOT NULL,
+ t3ver_count int(11) DEFAULT '0' NOT NULL,
+ t3ver_tstamp int(11) DEFAULT '0' NOT NULL,
+ t3ver_move_id int(11) DEFAULT '0' NOT NULL,
+ t3_origuid int(11) DEFAULT '0' NOT NULL,
+
+ PRIMARY KEY (uid),
+ KEY parent (pid),
+ KEY t3ver_oid (t3ver_oid,t3ver_wsid),
+);
+
+#
+# Table structure for table 'tx_blogexample_domain_model_tag'
+#
+CREATE TABLE tx_blogexample_domain_model_tag (
+ uid int(11) unsigned DEFAULT '0' NOT NULL auto_increment,
+ pid int(11) DEFAULT '0' NOT NULL,
+
+ name varchar(255) DEFAULT '' NOT NULL,
+ posts int(11) unsigned DEFAULT '0' NOT NULL,
+
+ tstamp int(11) unsigned DEFAULT '0' NOT NULL,
+ crdate int(11) unsigned DEFAULT '0' NOT NULL,
+ deleted tinyint(4) unsigned DEFAULT '0' NOT NULL,
+ hidden tinyint(4) unsigned DEFAULT '0' NOT NULL,
+
+ sys_language_uid int(11) DEFAULT '0' NOT NULL,
+ l18n_parent int(11) DEFAULT '0' NOT NULL,
+ l18n_diffsource mediumblob NOT NULL,
+
+ PRIMARY KEY (uid),
+ KEY parent (pid),
+);
+
+#
+# Table structure for table 'tx_blogexample_post_tag_mm'
+#
+CREATE TABLE tx_blogexample_post_tag_mm (
+ uid_local int(11) unsigned DEFAULT '0' NOT NULL,
+ uid_foreign int(11) unsigned DEFAULT '0' NOT NULL,
+ sorting int(11) unsigned DEFAULT '0' NOT NULL,
+ sorting_foreign int(11) unsigned DEFAULT '0' NOT NULL,
+
+ KEY uid_local (uid_local),
+ KEY uid_foreign (uid_foreign)
+);
+
+#
+# Table structure for table 'tx_blogexample_post_post_mm'
+#
+CREATE TABLE tx_blogexample_post_post_mm (
+ uid_local int(11) unsigned DEFAULT '0' NOT NULL,
+ uid_foreign int(11) unsigned DEFAULT '0' NOT NULL,
+ sorting int(11) unsigned DEFAULT '0' NOT NULL,
+ sorting_foreign int(11) unsigned DEFAULT '0' NOT NULL,
+
+ KEY uid_local (uid_local),
+ KEY uid_foreign (uid_foreign)
+);
--- /dev/null
+ # global configuration
+
+config.tx_extbase {
+ persistence{
+ classes {
+ Extbase\Domain\ModelFrontendUser {
+ subclasses {
+ ExtbaseTeam\BlogExample\Domain\Model\Administrator = ExtbaseTeam\BlogExample\Domain\Model\Administrator
+ }
+ }
+ ExtbaseTeam\BlogExample\Domain\Model\Administrator {
+ mapping {
+ tableName = fe_users
+ recordType = ExtbaseTeam\BlogExample\Domain\Model\Administrator
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<dataset>
+ <tx_blogexample_domain_model_blog>
+ <uid>1</uid>
+ <pid>0</pid>
+ <title>Blog1</title>
+ <deleted>0</deleted>
+ <posts>10</posts>
+ </tx_blogexample_domain_model_blog>
+</dataset>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<dataset><!-- foregin == tag-->
+ <tx_blogexample_post_tag_mm>
+ <uid_local>1</uid_local>
+ <uid_foreign>1</uid_foreign>
+ <sorting>1</sorting>
+ <sorting_foreign>1</sorting_foreign>
+ </tx_blogexample_post_tag_mm>
+ <tx_blogexample_post_tag_mm>
+ <uid_local>1</uid_local>
+ <uid_foreign>2</uid_foreign>
+ <sorting>2</sorting>
+ <sorting_foreign>1</sorting_foreign>
+ </tx_blogexample_post_tag_mm>
+ <tx_blogexample_post_tag_mm>
+ <uid_local>1</uid_local>
+ <uid_foreign>3</uid_foreign>
+ <sorting>3</sorting>
+ <sorting_foreign>1</sorting_foreign>
+ </tx_blogexample_post_tag_mm>
+ <tx_blogexample_post_tag_mm>
+ <uid_local>1</uid_local>
+ <uid_foreign>4</uid_foreign>
+ <sorting>4</sorting>
+ <sorting_foreign>1</sorting_foreign>
+ </tx_blogexample_post_tag_mm>
+ <tx_blogexample_post_tag_mm>
+ <uid_local>1</uid_local>
+ <uid_foreign>5</uid_foreign>
+ <sorting>5</sorting>
+ <sorting_foreign>1</sorting_foreign>
+ </tx_blogexample_post_tag_mm>
+ <tx_blogexample_post_tag_mm>
+ <uid_local>1</uid_local>
+ <uid_foreign>6</uid_foreign>
+ <sorting>6</sorting>
+ <sorting_foreign>1</sorting_foreign>
+ </tx_blogexample_post_tag_mm>
+ <tx_blogexample_post_tag_mm>
+ <uid_local>1</uid_local>
+ <uid_foreign>7</uid_foreign>
+ <sorting>7</sorting>
+ <sorting_foreign>1</sorting_foreign>
+ </tx_blogexample_post_tag_mm>
+ <tx_blogexample_post_tag_mm>
+ <uid_local>1</uid_local>
+ <uid_foreign>8</uid_foreign>
+ <sorting>8</sorting>
+ <sorting_foreign>1</sorting_foreign>
+ </tx_blogexample_post_tag_mm>
+ <tx_blogexample_post_tag_mm>
+ <uid_local>1</uid_local>
+ <uid_foreign>9</uid_foreign>
+ <sorting>9</sorting>
+ <sorting_foreign>1</sorting_foreign>
+ </tx_blogexample_post_tag_mm>
+ <tx_blogexample_post_tag_mm>
+ <uid_local>1</uid_local>
+ <uid_foreign>10</uid_foreign>
+ <sorting>10</sorting>
+ <sorting_foreign>1</sorting_foreign>
+ </tx_blogexample_post_tag_mm>
+
+ <!-- tag id 1 has 10 posts -->
+
+ <tx_blogexample_post_tag_mm>
+ <uid_local>2</uid_local>
+ <uid_foreign>1</uid_foreign>
+ <sorting>1</sorting>
+ <sorting_foreign>2</sorting_foreign>
+ </tx_blogexample_post_tag_mm>
+ <tx_blogexample_post_tag_mm>
+ <uid_local>3</uid_local>
+ <uid_foreign>1</uid_foreign>
+ <sorting>1</sorting>
+ <sorting_foreign>3</sorting_foreign>
+ </tx_blogexample_post_tag_mm>
+ <tx_blogexample_post_tag_mm>
+ <uid_local>4</uid_local>
+ <uid_foreign>1</uid_foreign>
+ <sorting>1</sorting>
+ <sorting_foreign>4</sorting_foreign>
+ </tx_blogexample_post_tag_mm>
+ <tx_blogexample_post_tag_mm>
+ <uid_local>5</uid_local>
+ <uid_foreign>1</uid_foreign>
+ <sorting>1</sorting>
+ <sorting_foreign>5</sorting_foreign>
+ </tx_blogexample_post_tag_mm>
+ <tx_blogexample_post_tag_mm>
+ <uid_local>6</uid_local>
+ <uid_foreign>1</uid_foreign>
+ <sorting>1</sorting>
+ <sorting_foreign>6</sorting_foreign>
+ </tx_blogexample_post_tag_mm>
+ <tx_blogexample_post_tag_mm>
+ <uid_local>7</uid_local>
+ <uid_foreign>1</uid_foreign>
+ <sorting>1</sorting>
+ <sorting_foreign>7</sorting_foreign>
+ </tx_blogexample_post_tag_mm>
+ <tx_blogexample_post_tag_mm>
+ <uid_local>8</uid_local>
+ <uid_foreign>1</uid_foreign>
+ <sorting>1</sorting>
+ <sorting_foreign>8</sorting_foreign>
+ </tx_blogexample_post_tag_mm>
+ <tx_blogexample_post_tag_mm>
+ <uid_local>9</uid_local>
+ <uid_foreign>1</uid_foreign>
+ <sorting>1</sorting>
+ <sorting_foreign>9</sorting_foreign>
+ </tx_blogexample_post_tag_mm>
+ <tx_blogexample_post_tag_mm>
+ <uid_local>10</uid_local>
+ <uid_foreign>1</uid_foreign>
+ <sorting>1</sorting>
+ <sorting_foreign>10</sorting_foreign>
+ </tx_blogexample_post_tag_mm>
+</dataset>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<dataset>
+ <tx_blogexample_domain_model_post>
+ <uid>1</uid>
+ <pid>0</pid>
+ <tstamp>121319</tstamp>
+ <blog>1</blog>
+ <tags>10</tags>
+ <title>Post1</title>
+ <sorting>1</sorting>
+ <deleted>0</deleted>
+ </tx_blogexample_domain_model_post>
+ <tx_blogexample_domain_model_post>
+ <uid>2</uid>
+ <pid>0</pid>
+ <blog>1</blog>
+ <tags>1</tags>
+ <title>Post2</title>
+ <sorting>2</sorting>
+ <deleted>0</deleted>
+ </tx_blogexample_domain_model_post>
+ <tx_blogexample_domain_model_post>
+ <uid>3</uid>
+ <pid>0</pid>
+ <blog>1</blog>
+ <tags>1</tags>
+ <title>Post3</title>
+ <sorting>3</sorting>
+ <deleted>0</deleted>
+ </tx_blogexample_domain_model_post>
+ <tx_blogexample_domain_model_post>
+ <uid>4</uid>
+ <pid>0</pid>
+ <blog>1</blog>
+ <tags>1</tags>
+ <title>Post4</title>
+ <sorting>4</sorting>
+ <deleted>0</deleted>
+ </tx_blogexample_domain_model_post>
+ <tx_blogexample_domain_model_post>
+ <uid>5</uid>
+ <pid>0</pid>
+ <blog>1</blog>
+ <tags>1</tags>
+ <title>Post5</title>
+ <sorting>5</sorting>
+ <deleted>0</deleted>
+ </tx_blogexample_domain_model_post>
+ <tx_blogexample_domain_model_post>
+ <uid>6</uid>
+ <pid>0</pid>
+ <blog>1</blog>
+ <tags>1</tags>
+ <title>Post6</title>
+ <sorting>6</sorting>
+ <deleted>0</deleted>
+ </tx_blogexample_domain_model_post>
+ <tx_blogexample_domain_model_post>
+ <uid>7</uid>
+ <pid>0</pid>
+ <blog>1</blog>
+ <tags>1</tags>
+ <title>Post7</title>
+ <sorting>7</sorting>
+ <deleted>0</deleted>
+ </tx_blogexample_domain_model_post>
+ <tx_blogexample_domain_model_post>
+ <uid>8</uid>
+ <pid>0</pid>
+ <blog>1</blog>
+ <tags>1</tags>
+ <title>Post8</title>
+ <sorting>8</sorting>
+ <deleted>0</deleted>
+ </tx_blogexample_domain_model_post>
+ <tx_blogexample_domain_model_post>
+ <uid>9</uid>
+ <pid>0</pid>
+ <blog>1</blog>
+ <tags>1</tags>
+ <title>Post9</title>
+ <sorting>9</sorting>
+ <deleted>0</deleted>
+ </tx_blogexample_domain_model_post>
+ <tx_blogexample_domain_model_post>
+ <uid>10</uid>
+ <pid>0</pid>
+ <blog>1</blog>
+ <tags>1</tags>
+ <title>Post10</title>
+ <sorting>10</sorting>
+ <deleted>0</deleted>
+ </tx_blogexample_domain_model_post>
+</dataset>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<dataset>
+ <tx_blogexample_domain_model_tag>
+ <uid>1</uid>
+ <pid>0</pid>
+ <posts>10</posts>
+ <name>Tag1</name>
+ <deleted>0</deleted>
+ </tx_blogexample_domain_model_tag>
+ <tx_blogexample_domain_model_tag>
+ <uid>2</uid>
+ <pid>0</pid>
+ <posts>1</posts>
+ <name>Tag2</name>
+ <deleted>0</deleted>
+ </tx_blogexample_domain_model_tag>
+ <tx_blogexample_domain_model_tag>
+ <uid>3</uid>
+ <pid>0</pid>
+ <posts>1</posts>
+ <name>Tag3</name>
+ <deleted>0</deleted>
+ </tx_blogexample_domain_model_tag>
+ <tx_blogexample_domain_model_tag>
+ <uid>4</uid>
+ <pid>0</pid>
+ <posts>1</posts>
+ <name>Tag4</name>
+ <deleted>0</deleted>
+ </tx_blogexample_domain_model_tag>
+ <tx_blogexample_domain_model_tag>
+ <uid>5</uid>
+ <pid>0</pid>
+ <posts>1</posts>
+ <name>Tag5</name>
+ <deleted>0</deleted>
+ </tx_blogexample_domain_model_tag>
+ <tx_blogexample_domain_model_tag>
+ <uid>6</uid>
+ <pid>0</pid>
+ <posts>1</posts>
+ <name>Tag6</name>
+ <deleted>0</deleted>
+ </tx_blogexample_domain_model_tag>
+ <tx_blogexample_domain_model_tag>
+ <uid>7</uid>
+ <pid>0</pid>
+ <posts>1</posts>
+ <name>Tag7</name>
+ <deleted>0</deleted>
+ </tx_blogexample_domain_model_tag>
+ <tx_blogexample_domain_model_tag>
+ <uid>8</uid>
+ <pid>0</pid>
+ <posts>1</posts>
+ <name>Tag8</name>
+ <deleted>0</deleted>
+ </tx_blogexample_domain_model_tag>
+ <tx_blogexample_domain_model_tag>
+ <uid>9</uid>
+ <pid>0</pid>
+ <posts>1</posts>
+ <name>Tag9</name>
+ <deleted>0</deleted>
+ </tx_blogexample_domain_model_tag>
+ <tx_blogexample_domain_model_tag>
+ <uid>10</uid>
+ <pid>0</pid>
+ <posts>1</posts>
+ <name>Tag10</name>
+ <deleted>0</deleted>
+ </tx_blogexample_domain_model_tag>
+</dataset>
\ No newline at end of file
--- /dev/null
+<?php
+namespace TYPO3\CMS\Extbase\Tests\Functional\Relations;
+
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2014 Tymoteusz Motylewski <t.motylewski@gmail.com>
+ * All rights reserved
+ *
+ * This script is part of the TYPO3 project. The TYPO3 project is
+ * free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The GNU General Public License can be found at
+ * http://www.gnu.org/copyleft/gpl.html.
+ *
+ * This script is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
+
+class RelationTest extends \TYPO3\CMS\Core\Tests\FunctionalTestCase {
+
+ /**
+ * @var \ExtbaseTeam\BlogExample\Domain\Model\Blog
+ */
+ protected $blog;
+
+ /**
+ * @var \TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager
+ */
+ protected $persistentManager;
+
+ protected $testExtensionsToLoad = array('typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example');
+
+ protected $coreExtensionsToLoad = array('extbase', 'fluid');
+
+ /**
+ * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface The object manager
+ */
+ protected $objectManager;
+
+ /**
+ * Sets up this test suite.
+ */
+ public function setUp() {
+ parent::setUp();
+
+ $this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/core/Tests/Functional/Fixtures/pages.xml');
+ $this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/extbase/Tests/Functional/Relations/Fixtures/blogs.xml');
+ $this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/extbase/Tests/Functional/Relations/Fixtures/posts.xml');
+ $this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/extbase/Tests/Functional/Relations/Fixtures/tags.xml');
+ $this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/extbase/Tests/Functional/Relations/Fixtures/post-tag-mm.xml');
+
+ $this->objectManager = GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
+ $this->persistentManager = $this->objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\PersistenceManager');
+ /* @var $blogRepository \TYPO3\CMS\Extbase\Persistence\Repository */
+ $blogRepository = $this->objectManager->get('ExtbaseTeam\\BlogExample\\Domain\\Repository\\BlogRepository');
+ $this->blog = $blogRepository->findByUid(1);
+ }
+
+ /**
+ * Tests adding object at the end of sorted 1:M relation (Blog:Posts)
+ *
+ * @test
+ */
+ public function attachPostToBlogAtTheEnd() {
+ $countPosts = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post');
+ $this->assertSame(10, $countPosts);
+
+ $newPostTitle = 'sdufhisdhuf';
+ $newPost = $this->objectManager->get('ExtbaseTeam\\BlogExample\\Domain\\Model\\Post');
+ $newPost->setBlog($this->blog);
+ $newPost->setTitle($newPostTitle);
+ $newPost->setContent('Bla Bla Bla');
+
+ $this->blog->addPost($newPost);
+ $this->updateAndPersistBlog();
+
+ $countPosts = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post');
+ $this->assertSame(11, $countPosts);
+
+ $post = $this->getDatabase()->exec_SELECTgetSingleRow('title,sorting', 'tx_blogexample_domain_model_post', 'blog =' . $this->blog->getUid(), '', 'sorting DESC');
+ $this->assertSame($newPostTitle, $post['title']);
+ $this->assertSame('11', $post['sorting']);
+ }
+
+ /**
+ * Tests removing object from the end of sorted 1:M relation (Blog:Posts)
+ *
+ * @test
+ */
+ public function removeLastPostFromBlog() {
+ $countPosts = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post');
+ $this->assertSame(10, $countPosts);
+
+ $post = $this->getDatabase()->exec_SELECTgetSingleRow('sorting', 'tx_blogexample_domain_model_post', 'blog =' . $this->blog->getUid(), '', 'sorting DESC');
+ $this->assertEquals(10, $post['sorting']);
+
+ $posts = $this->blog->getPosts();
+ $postsArray = $posts->toArray();
+ $latestPost = array_pop($postsArray);
+
+ $this->assertEquals(10, $latestPost->getUid());
+
+ $this->blog->removePost($latestPost);
+ $this->updateAndPersistBlog();
+
+ $countPosts = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post', 'deleted=0');
+ $this->assertEquals(9, $countPosts);
+
+ $post = $this->getDatabase()->exec_SELECTgetSingleRow('uid', 'tx_blogexample_domain_model_post', 'uid =' . $latestPost->getUid() . ' AND deleted=0');
+ $this->assertSame(NULL, $post['uid']);
+
+ $post = $this->getDatabase()->exec_SELECTgetSingleRow('title,sorting', 'tx_blogexample_domain_model_post', 'blog =' . $this->blog->getUid(), '', 'sorting DESC');
+ $this->assertSame('Post9', $post['title']);
+ $this->assertSame('9', $post['sorting']);
+ }
+
+ /**
+ * Tests adding object in the middle of the sorted 1:M relation (Blog:Posts)
+ *
+ * @test
+ */
+ public function addPostToBlogInTheMiddle() {
+ $countPosts = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post');
+ $this->assertSame(10, $countPosts);
+
+ $posts = clone $this->blog->getPosts();
+ $this->blog->getPosts()->removeAll($posts);
+ $counter = 1;
+ $newPostTitle = 'INSERTED POST at position 6';
+ foreach ($posts as $post) {
+ $this->blog->addPost($post);
+ if ($counter == 5) {
+ $newPost = $this->objectManager->get('ExtbaseTeam\\BlogExample\\Domain\\Model\\Post');
+ $newPost->setBlog($this->blog);
+ $newPost->setTitle($newPostTitle);
+ $newPost->setContent('Bla Bla Bla');
+ $this->blog->addPost($newPost);
+ }
+ $counter++;
+ }
+ $this->updateAndPersistBlog();
+
+ $countPosts = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post', 'deleted=0');
+ $this->assertSame(11, $countPosts);
+
+ //last post
+ $post = $this->getDatabase()->exec_SELECTgetSingleRow('title,sorting', 'tx_blogexample_domain_model_post', 'blog =' . $this->blog->getUid(), '', 'sorting DESC');
+ $this->assertSame('Post10', $post['title']);
+ $this->assertSame('11', $post['sorting']);
+
+ // check sorting of the post added in the middle
+ $post = $this->getDatabase()->exec_SELECTgetSingleRow('title,sorting', 'tx_blogexample_domain_model_post', 'uid=11');
+ $this->assertSame($newPostTitle, $post['title']);
+ $this->assertSame('6', $post['sorting']);
+ }
+
+ /**
+ * Tests removing object from the middle of sorted 1:M relation (Blog:Posts)
+ *
+ * @test
+ */
+ public function removeMiddlePostFromBlog() {
+ $countPosts = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post');
+ $this->assertSame(10, $countPosts);
+
+ $posts = clone $this->blog->getPosts();
+ $counter = 1;
+ foreach ($posts as $post) {
+ if ($counter == 5) {
+ $this->blog->removePost($post);
+ }
+ $counter++;
+ }
+ $this->updateAndPersistBlog();
+
+ $countPosts = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post', 'deleted=0');
+ $this->assertSame(9, $countPosts);
+
+ $post = $this->getDatabase()->exec_SELECTgetSingleRow('title,sorting', 'tx_blogexample_domain_model_post', 'blog ='.$this->blog->getUid(), '', 'sorting DESC');
+ $this->assertSame('Post10', $post['title']);
+ $this->assertSame('10', $post['sorting']);
+ }
+
+ /**
+ * Tests moving object from the end to the middle of the sorted 1:M relation (Blog:Posts)
+ *
+ * @test
+ */
+ public function movePostFromEndToTheMiddle() {
+ $countPosts = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post');
+ $this->assertSame(10, $countPosts);
+
+ $posts = clone $this->blog->getPosts();
+ $postsArray = $posts->toArray();
+ $latestPost = array_pop($postsArray);
+
+ $this->blog->getPosts()->removeAll($posts);
+ $counter = 0;
+ $postCount = $posts->count();
+ foreach ($posts as $post) {
+ if ($counter != ($postCount - 1)) {
+ $this->blog->addPost($post);
+ }
+ if ($counter == 4) {
+ $latestPost->setTitle('MOVED POST ' . $latestPost->getTitle());
+ $this->blog->addPost($latestPost);
+ }
+ $counter++;
+ }
+ $this->updateAndPersistBlog();
+
+ $countPosts = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post', 'deleted=0');
+ $this->assertSame(10, $countPosts);
+
+ $post = $this->getDatabase()->exec_SELECTgetSingleRow('title,sorting', 'tx_blogexample_domain_model_post', 'blog ='.$this->blog->getUid(), '', 'sorting DESC');
+ $this->assertSame('Post9', $post['title']);
+ $this->assertSame('10', $post['sorting']);
+
+ $post = $this->getDatabase()->exec_SELECTgetSingleRow('title,uid', 'tx_blogexample_domain_model_post', 'blog ='.$this->blog->getUid().' AND sorting=6');
+ $this->assertSame('MOVED POST Post10', $post['title']);
+ $this->assertSame('10', $post['uid']);
+ }
+
+ /**
+ * Tests adding object at the end of sorted M:M relation (Post:Tag)
+ *
+ * @test
+ */
+ public function attachTagToPostAtTheEnd() {
+ $count = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_tag');
+ $this->assertSame(10, $count);
+
+ $newTagTitle = 'sdufhisdhuf';
+ $newTag = $this->objectManager->get('ExtbaseTeam\\BlogExample\\Domain\\Model\\Tag', $newTagTitle);
+
+ $postRepository = $this->objectManager->get('ExtbaseTeam\\BlogExample\\Domain\\Repository\\PostRepository');
+ $post = $postRepository->findByUid(1);
+ $post->addTag($newTag);
+
+ $postRepository->update($post);
+ $this->persistentManager->persistAll();
+
+ $count = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_tag');
+ $this->assertSame(11, $count);
+
+ $tag = $this->getDatabase()->exec_SELECTgetSingleRow('uid_foreign', 'tx_blogexample_post_tag_mm', 'uid_local ='.$post->getUid(), '', 'sorting DESC');
+ $this->assertSame('11', $tag['uid_foreign']);
+ }
+
+
+ /**
+ * Tests removing object from the end of sorted M:M relation (Post:Tag)
+ *
+ * @test
+ */
+ public function removeLastTagFromPost() {
+ $count = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_tag');
+ $this->assertSame(10, $count);
+
+ $postRepository = $this->objectManager->get('ExtbaseTeam\\BlogExample\\Domain\\Repository\\PostRepository');
+ $post = $postRepository->findByUid(1);
+ $tags = $post->getTags();
+ $tagsArray = $tags->toArray();
+ $latestTag = array_pop($tagsArray);
+
+ $this->assertEquals(10, $latestTag->getUid());
+
+ $post->removeTag($latestTag);
+
+ $postRepository->update($post);
+ $this->persistentManager->persistAll();
+
+ $countPosts = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_tag', 'deleted=0' );
+ $this->assertEquals(10, $countPosts);
+
+ $tag = $this->getDatabase()->exec_SELECTgetSingleRow('uid_foreign', 'tx_blogexample_post_tag_mm', 'uid_local ='.$post->getUid(), '', 'sorting DESC');
+ $this->assertSame('9', $tag['uid_foreign']);
+
+ $tag = $this->getDatabase()->exec_SELECTgetSingleRow('uid_foreign', 'tx_blogexample_post_tag_mm', 'uid_local ='.$post->getUid().' AND uid_foreign='.$latestTag->getUid());
+ $this->assertSame(NULL, $tag['uid_foreign']);
+ }
+
+ /**
+ * Tests adding object in the middle of sorted M:M relation (Post:Tag)
+ *
+ * @test
+ */
+ public function addTagToPostInTheMiddle() {
+ $countTags = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_post_tag_mm', 'uid_local=1');
+ $this->assertSame(10, $countTags);
+
+ $postRepository = $this->objectManager->get('ExtbaseTeam\\BlogExample\\Domain\\Repository\\PostRepository');
+ $post = $postRepository->findByUid(1);
+ $tags = clone $post->getTags();
+ $post->setTags(new ObjectStorage());
+
+ $counter = 1;
+ foreach ($tags as $tag) {
+ $post->addTag($tag);
+ if ($counter == 5) {
+ $newTag = $this->objectManager->get('ExtbaseTeam\\BlogExample\\Domain\\Model\\Tag', 'INSERTED TAG at position 6 : ' . strftime(''));
+ $post->addTag($newTag);
+ }
+ $counter++;
+ }
+
+ $postRepository->update($post);
+ $this->persistentManager->persistAll();
+
+ $countTags = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_post_tag_mm', 'uid_local=1');
+ $this->assertSame(11, $countTags);
+
+ $tag = $this->getDatabase()->exec_SELECTgetSingleRow('uid_foreign', 'tx_blogexample_post_tag_mm', 'uid_local ='.$post->getUid(), '', 'sorting DESC');
+ $this->assertSame('10', $tag['uid_foreign']);
+
+ $tag = $this->getDatabase()->exec_SELECTgetSingleRow('uid_foreign', 'tx_blogexample_post_tag_mm', 'uid_local ='.$post->getUid().' AND sorting=6');
+ $this->assertSame('11', $tag['uid_foreign']);
+ }
+
+
+ /**
+ * Tests removing object from the middle of the sorted M:M relation (Post:Tag)
+ *
+ * @test
+ */
+ public function removeMiddleTagFromPost() {
+ $countTags = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_post_tag_mm', 'uid_local=1');
+ $this->assertSame(10, $countTags);
+
+ $postRepository = $this->objectManager->get('ExtbaseTeam\\BlogExample\\Domain\\Repository\\PostRepository');
+ $post = $postRepository->findByUid(1);
+ $tags = clone $post->getTags();
+ $counter = 1;
+ foreach ($tags as $tag) {
+ if ($counter == 5) {
+ $post->removeTag($tag);
+ }
+ $counter++;
+ }
+
+ $postRepository->update($post);
+ $this->persistentManager->persistAll();
+
+ $countTags = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_post_tag_mm', 'uid_local=1');
+ $this->assertSame(9, $countTags);
+
+ $tag = $this->getDatabase()->exec_SELECTgetSingleRow('uid_foreign,sorting', 'tx_blogexample_post_tag_mm', 'uid_local ='.$post->getUid(), '', 'sorting DESC');
+ $this->assertSame('10', $tag['uid_foreign']);
+ $this->assertSame('10', $tag['sorting']);
+
+ $tag = $this->getDatabase()->exec_SELECTgetSingleRow('uid_foreign', 'tx_blogexample_post_tag_mm', 'uid_local ='.$post->getUid().' AND sorting=5');
+ $this->assertSame(NULL, $tag['uid_foreign']);
+ }
+
+ /**
+ * Tests moving object from the end to the middle of sorted M:M relation (Post:Tag)
+ *
+ * @test
+ */
+ public function moveTagFromEndToTheMiddle() {
+ $countTags = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_post_tag_mm', 'uid_local=1');
+ $this->assertSame(10, $countTags);
+
+ $postRepository = $this->objectManager->get('ExtbaseTeam\\BlogExample\\Domain\\Repository\\PostRepository');
+ $post = $postRepository->findByUid(1);
+ $tags = clone $post->getTags();
+ $tagsArray = $tags->toArray();
+ $latestTag = array_pop($tagsArray);
+ $post->removeTag($latestTag);
+ $post->setTags(new ObjectStorage());
+
+ $counter = 1;
+ $tagCount = $tags->count();
+ foreach ($tags as $tag) {
+ if ($counter != $tagCount) {
+ $post->addTag($tag);
+ }
+ if ($counter == 5) {
+ $post->addTag($latestTag);
+ }
+ $counter++;
+ }
+ $post->addTag($latestTag);
+
+ $postRepository->update($post);
+ $this->persistentManager->persistAll();
+
+ $countTags = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_post_tag_mm', 'uid_local=1');
+ $this->assertSame(10, $countTags);
+
+ $tag = $this->getDatabase()->exec_SELECTgetSingleRow('uid_foreign,sorting', 'tx_blogexample_post_tag_mm', 'uid_local ='.$post->getUid(), '', 'sorting DESC');
+ $this->assertSame('9', $tag['uid_foreign']);
+ $this->assertSame('10', $tag['sorting']);
+
+ $sorting = '6';
+ $tag = $this->getDatabase()->exec_SELECTgetSingleRow('uid_foreign', 'tx_blogexample_post_tag_mm', 'uid_local ='.$post->getUid().' AND sorting='.$sorting);
+ $this->assertSame('10', $tag['uid_foreign']);
+ }
+
+ /**
+ * Test if timestamp field is updated when updating a record
+ *
+ * @test
+ */
+ public function timestampFieldIsUpdatedOnPostSave() {
+ $rawPost = $this->getDatabase()->exec_SELECTgetSingleRow('*', 'tx_blogexample_domain_model_post', 'uid=1');
+
+ $postRepository = $this->objectManager->get('ExtbaseTeam\\BlogExample\\Domain\\Repository\\PostRepository');
+ $post = $postRepository->findByUid(1);
+ $post->setTitle("newTitle");
+
+ $postRepository->update($post);
+ $this->persistentManager->persistAll();
+
+ $rawPost2 = $this->getDatabase()->exec_SELECTgetSingleRow('*', 'tx_blogexample_domain_model_post', 'uid=1');
+ $this->assertTrue($rawPost2['tstamp'] > $rawPost['tstamp']);
+ }
+
+ /**
+ * Helper method for persisting blog
+ */
+ protected function updateAndPersistBlog() {
+ /** @var \ExtbaseTeam\BlogExample\Domain\Repository\BlogRepository $blogRepository */
+ $blogRepository = $this->objectManager->get('ExtbaseTeam\\BlogExample\\Domain\\Repository\\BlogRepository');
+ $blogRepository->update($this->blog);
+ $this->persistentManager->persistAll();
+ }
+}
\ No newline at end of file