TYPO3 CMS  TYPO3_7-6
RelationTest.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
19 
21 {
25  protected $blog;
26 
30  protected $persistentManager;
31 
32  protected $testExtensionsToLoad = ['typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example'];
33 
34  protected $coreExtensionsToLoad = ['extbase', 'fluid'];
35 
39  protected $objectManager;
40 
44  protected function setUp()
45  {
46  parent::setUp();
47 
48  $this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/core/Tests/Functional/Fixtures/pages.xml');
49  $this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/extbase/Tests/Functional/Persistence/Fixtures/blogs.xml');
50  $this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/extbase/Tests/Functional/Persistence/Fixtures/posts.xml');
51  $this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/extbase/Tests/Functional/Persistence/Fixtures/tags.xml');
52  $this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/extbase/Tests/Functional/Persistence/Fixtures/post-tag-mm.xml');
53  $this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/extbase/Tests/Functional/Persistence/Fixtures/categories.xml');
54  $this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/extbase/Tests/Functional/Persistence/Fixtures/category-mm.xml');
55 
56  $this->objectManager = GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class);
57  $this->persistentManager = $this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager::class);
58  /* @var $blogRepository \TYPO3\CMS\Extbase\Persistence\Repository */
59  $blogRepository = $this->objectManager->get(\ExtbaseTeam\BlogExample\Domain\Repository\BlogRepository::class);
60  $this->blog = $blogRepository->findByUid(1);
61  }
62 
68  public function attachPostToBlogAtTheEnd()
69  {
70  $countPostsOriginal = $this->getDatabaseConnection()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post', 'blog =' . $this->blog->getUid());
71 
72  $newPostTitle = 'sdufhisdhuf';
74  $newPost = $this->objectManager->get(\ExtbaseTeam\BlogExample\Domain\Model\Post::class);
75  $newPost->setBlog($this->blog);
76  $newPost->setTitle($newPostTitle);
77  $newPost->setContent('Bla Bla Bla');
78 
79  $this->blog->addPost($newPost);
80  $this->updateAndPersistBlog();
81 
82  $countPosts = $this->getDatabaseConnection()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post', 'blog =' . $this->blog->getUid());
83  $this->assertSame(($countPostsOriginal + 1), $countPosts);
84 
85  $post = $this->getDatabaseConnection()->exec_SELECTgetSingleRow('title,sorting', 'tx_blogexample_domain_model_post', 'blog =' . $this->blog->getUid(), '', 'sorting DESC');
86  $this->assertSame($newPostTitle, $post['title']);
87  $this->assertSame((string)($countPostsOriginal + 1), $post['sorting']);
88  }
89 
95  public function removeLastPostFromBlog()
96  {
97  $countPostsOriginal = $this->getDatabaseConnection()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post', 'deleted=0');
98 
99  $post = $this->getDatabaseConnection()->exec_SELECTgetSingleRow('sorting', 'tx_blogexample_domain_model_post', 'blog =' . $this->blog->getUid(), '', 'sorting DESC');
100  $this->assertEquals(10, $post['sorting']);
101 
102  $posts = $this->blog->getPosts();
103  $postsArray = $posts->toArray();
104  $latestPost = array_pop($postsArray);
105 
106  $this->assertEquals(10, $latestPost->getUid());
107 
108  $this->blog->removePost($latestPost);
109  $this->updateAndPersistBlog();
110 
111  $countPosts = $this->getDatabaseConnection()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post', 'deleted=0');
112  $this->assertEquals(($countPostsOriginal - 1), $countPosts);
113 
114  $post = $this->getDatabaseConnection()->exec_SELECTgetSingleRow('uid', 'tx_blogexample_domain_model_post', 'uid =' . $latestPost->getUid() . ' AND deleted=0');
115  $this->assertSame(null, $post['uid']);
116 
117  $post = $this->getDatabaseConnection()->exec_SELECTgetSingleRow('title,sorting', 'tx_blogexample_domain_model_post', 'blog =' . $this->blog->getUid(), '', 'sorting DESC');
118  $this->assertSame('Post9', $post['title']);
119  $this->assertSame('9', $post['sorting']);
120  }
121 
127  public function addPostToBlogInTheMiddle()
128  {
129  $countPostsOriginal = $this->getDatabaseConnection()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post', 'deleted=0');
130 
132  $newPost = $this->objectManager->get(\ExtbaseTeam\BlogExample\Domain\Model\Post::class);
133 
134  $posts = clone $this->blog->getPosts();
135  $this->blog->getPosts()->removeAll($posts);
136  $counter = 1;
137  $newPostTitle = 'INSERTED POST at position 6';
138  foreach ($posts as $post) {
139  $this->blog->addPost($post);
140  if ($counter == 5) {
141  $newPost->setBlog($this->blog);
142  $newPost->setTitle($newPostTitle);
143  $newPost->setContent('Bla Bla Bla');
144  $this->blog->addPost($newPost);
145  }
146  $counter++;
147  }
148  $this->updateAndPersistBlog();
149 
150  $countPosts = $this->getDatabaseConnection()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post', 'deleted=0');
151  $this->assertSame(($countPostsOriginal + 1), $countPosts);
152 
153  //last post
154  $post = $this->getDatabaseConnection()->exec_SELECTgetSingleRow('title,sorting', 'tx_blogexample_domain_model_post', 'blog =' . $this->blog->getUid(), '', 'sorting DESC');
155  $this->assertSame('Post10', $post['title']);
156  $this->assertSame('11', $post['sorting']);
157 
158  // check sorting of the post added in the middle
159  $post = $this->getDatabaseConnection()->exec_SELECTgetSingleRow('title,sorting', 'tx_blogexample_domain_model_post', 'uid=' . $newPost->getUid());
160  $this->assertSame($newPostTitle, $post['title']);
161  $this->assertSame('6', $post['sorting']);
162  }
163 
169  public function removeMiddlePostFromBlog()
170  {
171  $countPostsOriginal = $this->getDatabaseConnection()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post', 'deleted=0');
172 
173  $posts = clone $this->blog->getPosts();
174  $counter = 1;
175  foreach ($posts as $post) {
176  if ($counter == 5) {
177  $this->blog->removePost($post);
178  }
179  $counter++;
180  }
181  $this->updateAndPersistBlog();
182 
183  $countPosts = $this->getDatabaseConnection()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post', 'deleted=0');
184  $this->assertSame(($countPostsOriginal - 1), $countPosts);
185 
186  $post = $this->getDatabaseConnection()->exec_SELECTgetSingleRow('title,sorting', 'tx_blogexample_domain_model_post', 'blog =' . $this->blog->getUid(), '', 'sorting DESC');
187  $this->assertSame('Post10', $post['title']);
188  $this->assertSame('10', $post['sorting']);
189  }
190 
196  public function movePostFromEndToTheMiddle()
197  {
198  $countPostsOriginal = $this->getDatabaseConnection()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post', 'deleted=0');
199 
200  $posts = clone $this->blog->getPosts();
201  $postsArray = $posts->toArray();
202  $latestPost = array_pop($postsArray);
203 
204  $this->blog->getPosts()->removeAll($posts);
205  $counter = 0;
206  $postCount = $posts->count();
207  foreach ($posts as $post) {
208  if ($counter != ($postCount - 1)) {
209  $this->blog->addPost($post);
210  }
211  if ($counter == 4) {
212  $latestPost->setTitle('MOVED POST ' . $latestPost->getTitle());
213  $this->blog->addPost($latestPost);
214  }
215  $counter++;
216  }
217  $this->updateAndPersistBlog();
218 
219  $countPosts = $this->getDatabaseConnection()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post', 'deleted=0');
220  $this->assertSame($countPostsOriginal, $countPosts);
221 
222  $post = $this->getDatabaseConnection()->exec_SELECTgetSingleRow('title,sorting', 'tx_blogexample_domain_model_post', 'blog =' . $this->blog->getUid(), '', 'sorting DESC');
223  $this->assertSame('Post9', $post['title']);
224  $this->assertSame('10', $post['sorting']);
225 
226  $post = $this->getDatabaseConnection()->exec_SELECTgetSingleRow('title,uid', 'tx_blogexample_domain_model_post', 'blog =' . $this->blog->getUid() . ' AND sorting=6');
227  $this->assertSame('MOVED POST Post10', $post['title']);
228  $this->assertSame('10', $post['uid']);
229  }
230 
236  public function attachTagToPostAtTheEnd()
237  {
238  $countOriginal = $this->getDatabaseConnection()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_tag');
239 
240  $newTagTitle = 'sdufhisdhuf';
241 
243  $newTag = $this->objectManager->get('ExtbaseTeam\\BlogExample\\Domain\\Model\\Tag', $newTagTitle);
244 
246  $postRepository = $this->objectManager->get(\ExtbaseTeam\BlogExample\Domain\Repository\PostRepository::class);
247  $post = $postRepository->findByUid(1);
248  $post->addTag($newTag);
249 
250  $postRepository->update($post);
251  $this->persistentManager->persistAll();
252 
253  $count = $this->getDatabaseConnection()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_tag');
254  $this->assertSame(($countOriginal + 1), $count);
255 
256  $tag = $this->getDatabaseConnection()->exec_SELECTgetSingleRow('uid_foreign', 'tx_blogexample_post_tag_mm', 'uid_local =' . $post->getUid(), '', 'sorting DESC');
257  $this->assertSame($newTag->getUid(), (int)$tag['uid_foreign']);
258  }
259 
265  public function removeLastTagFromPost()
266  {
267  $countOriginal = $this->getDatabaseConnection()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_tag', 'deleted=0');
268 
270  $postRepository = $this->objectManager->get(\ExtbaseTeam\BlogExample\Domain\Repository\PostRepository::class);
271  $post = $postRepository->findByUid(1);
272  $tags = $post->getTags();
273  $tagsArray = $tags->toArray();
274  $latestTag = array_pop($tagsArray);
275 
276  $this->assertEquals(10, $latestTag->getUid());
277 
278  $post->removeTag($latestTag);
279 
280  $postRepository->update($post);
281  $this->persistentManager->persistAll();
282 
283  $countPosts = $this->getDatabaseConnection()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_tag', 'deleted=0');
284  $this->assertEquals($countOriginal, $countPosts);
285 
286  $tag = $this->getDatabaseConnection()->exec_SELECTgetSingleRow('uid_foreign', 'tx_blogexample_post_tag_mm', 'uid_local =' . $post->getUid(), '', 'sorting DESC');
287  $this->assertSame('9', $tag['uid_foreign']);
288 
289  $tag = $this->getDatabaseConnection()->exec_SELECTgetSingleRow('uid_foreign', 'tx_blogexample_post_tag_mm', 'uid_local =' . $post->getUid() . ' AND uid_foreign=' . $latestTag->getUid());
290  $this->assertSame(null, $tag['uid_foreign']);
291  }
292 
298  public function addTagToPostInTheMiddle()
299  {
300  $countTagsOriginal = $this->getDatabaseConnection()->exec_SELECTcountRows('*', 'tx_blogexample_post_tag_mm', 'uid_local=1');
301 
303  $postRepository = $this->objectManager->get(\ExtbaseTeam\BlogExample\Domain\Repository\PostRepository::class);
304  $post = $postRepository->findByUid(1);
305  $tags = clone $post->getTags();
306  $post->setTags(new ObjectStorage());
307 
309  $newTag = $this->objectManager->get(\ExtbaseTeam\BlogExample\Domain\Model\Tag::class, 'INSERTED TAG at position 6 : ' . strftime(''));
310 
311  $counter = 1;
312  foreach ($tags as $tag) {
313  $post->addTag($tag);
314  if ($counter == 5) {
315  $post->addTag($newTag);
316  }
317  $counter++;
318  }
319 
320  $postRepository->update($post);
321  $this->persistentManager->persistAll();
322 
323  $countTags = $this->getDatabaseConnection()->exec_SELECTcountRows('*', 'tx_blogexample_post_tag_mm', 'uid_local=1');
324  $this->assertSame(($countTagsOriginal + 1), $countTags);
325 
326  $tag = $this->getDatabaseConnection()->exec_SELECTgetSingleRow('uid_foreign', 'tx_blogexample_post_tag_mm', 'uid_local =' . $post->getUid(), '', 'sorting DESC');
327  $this->assertSame('10', $tag['uid_foreign']);
328 
329  $tag = $this->getDatabaseConnection()->exec_SELECTgetSingleRow('uid_foreign', 'tx_blogexample_post_tag_mm', 'uid_local =' . $post->getUid() . ' AND sorting=6');
330  $this->assertSame($newTag->getUid(), (int)$tag['uid_foreign']);
331  }
332 
338  public function removeMiddleTagFromPost()
339  {
340  $countTags = $this->getDatabaseConnection()->exec_SELECTcountRows('*', 'tx_blogexample_post_tag_mm', 'uid_local=1');
341  $this->assertSame(10, $countTags);
342 
344  $postRepository = $this->objectManager->get(\ExtbaseTeam\BlogExample\Domain\Repository\PostRepository::class);
345  $post = $postRepository->findByUid(1);
346  $tags = clone $post->getTags();
347  $counter = 1;
348  foreach ($tags as $tag) {
349  if ($counter == 5) {
350  $post->removeTag($tag);
351  }
352  $counter++;
353  }
354 
355  $postRepository->update($post);
356  $this->persistentManager->persistAll();
357 
358  $countTags = $this->getDatabaseConnection()->exec_SELECTcountRows('*', 'tx_blogexample_post_tag_mm', 'uid_local=1');
359  $this->assertSame(9, $countTags);
360 
361  $tag = $this->getDatabaseConnection()->exec_SELECTgetSingleRow('uid_foreign,sorting', 'tx_blogexample_post_tag_mm', 'uid_local =' . $post->getUid(), '', 'sorting DESC');
362  $this->assertSame('10', $tag['uid_foreign']);
363  $this->assertSame('10', $tag['sorting']);
364 
365  $tag = $this->getDatabaseConnection()->exec_SELECTgetSingleRow('uid_foreign', 'tx_blogexample_post_tag_mm', 'uid_local =' . $post->getUid() . ' AND sorting=5');
366  $this->assertSame(null, $tag['uid_foreign']);
367  }
368 
374  public function moveTagFromEndToTheMiddle()
375  {
376  $countTags = $this->getDatabaseConnection()->exec_SELECTcountRows('*', 'tx_blogexample_post_tag_mm', 'uid_local=1');
377  $this->assertSame(10, $countTags);
378 
380  $postRepository = $this->objectManager->get(\ExtbaseTeam\BlogExample\Domain\Repository\PostRepository::class);
381  $post = $postRepository->findByUid(1);
382  $tags = clone $post->getTags();
383  $tagsArray = $tags->toArray();
384  $latestTag = array_pop($tagsArray);
385  $post->removeTag($latestTag);
386  $post->setTags(new ObjectStorage());
387 
388  $counter = 1;
389  $tagCount = $tags->count();
390  foreach ($tags as $tag) {
391  if ($counter != $tagCount) {
392  $post->addTag($tag);
393  }
394  if ($counter == 5) {
395  $post->addTag($latestTag);
396  }
397  $counter++;
398  }
399  $post->addTag($latestTag);
400 
401  $postRepository->update($post);
402  $this->persistentManager->persistAll();
403 
404  $countTags = $this->getDatabaseConnection()->exec_SELECTcountRows('*', 'tx_blogexample_post_tag_mm', 'uid_local=1');
405  $this->assertSame(10, $countTags);
406 
407  $tag = $this->getDatabaseConnection()->exec_SELECTgetSingleRow('uid_foreign,sorting', 'tx_blogexample_post_tag_mm', 'uid_local =' . $post->getUid(), '', 'sorting DESC');
408  $this->assertSame('9', $tag['uid_foreign']);
409  $this->assertSame('10', $tag['sorting']);
410 
411  $sorting = '6';
412  $tag = $this->getDatabaseConnection()->exec_SELECTgetSingleRow('uid_foreign', 'tx_blogexample_post_tag_mm', 'uid_local =' . $post->getUid() . ' AND sorting=' . $sorting);
413  $this->assertSame('10', $tag['uid_foreign']);
414  }
415 
421  public function timestampFieldIsUpdatedOnPostSave()
422  {
423  $rawPost = $this->getDatabaseConnection()->exec_SELECTgetSingleRow('*', 'tx_blogexample_domain_model_post', 'uid=1');
424 
426  $postRepository = $this->objectManager->get(\ExtbaseTeam\BlogExample\Domain\Repository\PostRepository::class);
427  $post = $postRepository->findByUid(1);
428  $post->setTitle('newTitle');
429 
430  $postRepository->update($post);
431  $this->persistentManager->persistAll();
432 
433  $rawPost2 = $this->getDatabaseConnection()->exec_SELECTgetSingleRow('*', 'tx_blogexample_domain_model_post', 'uid=1');
434  $this->assertTrue($rawPost2['tstamp'] > $rawPost['tstamp']);
435  }
436 
442  public function mmRelationWithoutMatchFieldIsResolved()
443  {
445  $postRepository = $this->objectManager->get(\ExtbaseTeam\BlogExample\Domain\Repository\PostRepository::class);
446  $posts = $postRepository->findByTagAndBlog('Tag2', $this->blog);
447  $this->assertSame(1, count($posts));
448  }
449 
453  public function mmRelationWithMatchFieldIsResolvedFromLocalSide()
454  {
455  $countCategories = $this->getDatabaseConnection()->exec_SELECTcountRows('*', 'sys_category_record_mm', 'uid_foreign=1 AND tablenames="tx_blogexample_domain_model_post" AND fieldname="categories"');
456  $this->assertSame(3, $countCategories);
457 
459  $postRepository = $this->objectManager->get(\ExtbaseTeam\BlogExample\Domain\Repository\PostRepository::class);
460  $post = $postRepository->findByUid(1);
461  $this->assertSame(3, count($post->getCategories()));
462  }
463 
469  public function mmRelationWithMatchFieldIsResolvedFromForeignSide()
470  {
472  $postRepository = $this->objectManager->get(\ExtbaseTeam\BlogExample\Domain\Repository\PostRepository::class);
473  $posts = $postRepository->findByCategory(1);
474  $this->assertSame(2, count($posts));
475 
476  $posts = $postRepository->findByCategory(4);
477  $this->assertSame(0, count($posts));
478  }
479 
483  public function mmRelationWithMatchFieldIsCreatedFromLocalSide()
484  {
485  $countCategories = $this->getDatabaseConnection()->exec_SELECTcountRows('*', 'sys_category_record_mm', 'uid_foreign=1 AND tablenames="tx_blogexample_domain_model_post" AND fieldname="categories"');
486  $this->assertSame(3, $countCategories);
487 
489  $postRepository = $this->objectManager->get(\ExtbaseTeam\BlogExample\Domain\Repository\PostRepository::class);
490  $post = $postRepository->findByUid(1);
491 
493  $newCategory = $this->objectManager->get(\TYPO3\CMS\Extbase\Domain\Model\Category::class);
494  $newCategory->setTitle('New Category');
495 
496  $post->addCategory($newCategory);
497 
498  $postRepository->update($post);
499  $this->persistentManager->persistAll();
500 
501  $countCategories = $this->getDatabaseConnection()->exec_SELECTcountRows(
502  '*',
503  'sys_category_record_mm',
504  'uid_foreign=1 AND tablenames="tx_blogexample_domain_model_post" AND fieldname="categories"'
505  );
506  $this->assertSame(4, $countCategories);
507  }
508 
514  public function adjustingMmRelationWithTablesnameAndFieldnameFieldDoNotTouchOtherRelations()
515  {
517  $postRepository = $this->objectManager->get(\ExtbaseTeam\BlogExample\Domain\Repository\PostRepository::class);
519  $post = $postRepository->findByUid(1);
520  // Move category down
521  foreach ($post->getCategories() as $category) {
522  $post->removeCategory($category);
523  $post->addCategory($category);
524  break;
525  }
526  $postRepository->update($post);
527  $this->persistentManager->persistAll();
528 
529  // re-fetch Post and Blog
530  $newBlogCategoryCount = $this->getDatabaseConnection()->exec_SELECTcountRows(
531  'uid_local',
532  'sys_category_record_mm',
533  'tablenames = "tx_blogexample_domain_model_blog"
534  AND fieldname = "categories"
535  AND uid_foreign = ' . $this->blog->getUid() . ''
536  );
537 
538  $this->assertSame($this->blog->getCategories()->count(), $newBlogCategoryCount);
539  }
540 
544  protected function updateAndPersistBlog()
545  {
547  $blogRepository = $this->objectManager->get(\ExtbaseTeam\BlogExample\Domain\Repository\BlogRepository::class);
548  $blogRepository->update($this->blog);
549  $this->persistentManager->persistAll();
550  }
551 }