From 8135f67b714496c442ac14f77707b30859ec71af Mon Sep 17 00:00:00 2001 From: micmania1 Date: Fri, 5 Feb 2016 00:33:40 +0000 Subject: [PATCH] FIX Prevent duplicate tags and categories. --- code/compat/pages/BlogEntry.php | 7 +++--- code/model/BlogCategory.php | 41 ++++++++++++++++++++++++++++++--- code/model/BlogTag.php | 35 ++++++++++++++++++++++++++++ tests/BlogCategoryTest.php | 23 ++++++++++++++++++ tests/BlogTagTest.php | 32 +++++++++++++++++++++---- 5 files changed, 127 insertions(+), 11 deletions(-) diff --git a/code/compat/pages/BlogEntry.php b/code/compat/pages/BlogEntry.php index 6c51530..190d475 100644 --- a/code/compat/pages/BlogEntry.php +++ b/code/compat/pages/BlogEntry.php @@ -37,7 +37,7 @@ class BlogEntry extends BlogPost implements MigratableObject */ public function up() { - + //Migrate comma separated tags into BlogTag objects. foreach ($this->TagNames() as $tag) { $existingTag = BlogTag::get()->filter(array('Title' => $tag, 'BlogID' => $this->ParentID)); @@ -45,7 +45,6 @@ class BlogEntry extends BlogPost implements MigratableObject //if tag already exists we will simply add it to this post. $tagObject = $existingTag->First(); } else { - //if the tag is now we create it and add it to this post. $tagObject = new BlogTag(); $tagObject->Title = $tag; @@ -69,7 +68,7 @@ class BlogEntry extends BlogPost implements MigratableObject $this->PublishDate = $this->Date; $this->AuthorNames = $this->Author; $this->InheritSideBar = true; - + //Write and additionally publish the item if it was published before. $this->write(); if ($published) { @@ -78,7 +77,7 @@ class BlogEntry extends BlogPost implements MigratableObject } else { $message = "DRAFT: "; } - + return $message . $this->Title; } diff --git a/code/model/BlogCategory.php b/code/model/BlogCategory.php index 3dce22f..a678e40 100644 --- a/code/model/BlogCategory.php +++ b/code/model/BlogCategory.php @@ -13,6 +13,16 @@ */ class BlogCategory extends DataObject implements CategorisationObject { + + /** + * Use an exception code so that attempted writes can continue on + * duplicate errors. + * + * @const string + * This must be a string because ValidationException has decided we can't use int + */ + const DUPLICATE_EXCEPTION = "DUPLICATE"; + /** * @var array */ @@ -40,16 +50,16 @@ class BlogCategory extends DataObject implements CategorisationObject private static $extensions = array( 'URLSegmentExtension', ); - + /** * @return DataList */ public function BlogPosts() { $blogPosts = parent::BlogPosts(); - + $this->extend("updateGetBlogPosts", $blogPosts); - + return $blogPosts; } @@ -67,6 +77,31 @@ class BlogCategory extends DataObject implements CategorisationObject return $fields; } + /** + * {@inheritdoc} + */ + protected function validate() + { + $validation = parent::validate(); + if($validation->valid()) { + // Check for duplicate categories + $blog = $this->Blog(); + if($blog && $blog->exists()) { + $existing = $blog->Categories()->filter('Title', $this->Title); + if($this->ID) { + $existing = $existing->exclude('ID', $this->ID); + } + if($existing->count() > 0) { + $validation->error(_t( + 'BlogCategory.Duplicate', + 'A blog category already exists with that name' + ), BlogCategory::DUPLICATE_EXCEPTION); + } + } + } + return $validation; + } + /** * Returns a relative link to this category. * diff --git a/code/model/BlogTag.php b/code/model/BlogTag.php index c5b7376..47c9e57 100644 --- a/code/model/BlogTag.php +++ b/code/model/BlogTag.php @@ -14,6 +14,16 @@ */ class BlogTag extends DataObject implements CategorisationObject { + + /** + * Use an exception code so that attempted writes can continue on + * duplicate errors. + * + * @const string + * This must be a string because ValidationException has decided we can't use int + */ + const DUPLICATE_EXCEPTION = "DUPLICATE"; + /** * @var array */ @@ -68,6 +78,31 @@ class BlogTag extends DataObject implements CategorisationObject return $fields; } + /** + * {@inheritdoc} + */ + protected function validate() + { + $validation = parent::validate(); + if($validation->valid()) { + // Check for duplicate tags + $blog = $this->Blog(); + if($blog && $blog->exists()) { + $existing = $blog->Tags()->filter('Title', $this->Title); + if($this->ID) { + $existing = $existing->exclude('ID', $this->ID); + } + if($existing->count() > 0) { + $validation->error(_t( + 'BlogTag.Duplicate', + 'A blog tags already exists with that name' + ), BlogTag::DUPLICATE_EXCEPTION); + } + } + } + return $validation; + } + /** * Returns a relative URL for the tag link. * diff --git a/tests/BlogCategoryTest.php b/tests/BlogCategoryTest.php index c6aef8b..3acf08a 100755 --- a/tests/BlogCategoryTest.php +++ b/tests/BlogCategoryTest.php @@ -123,4 +123,27 @@ class BlogCategoryTest extends FunctionalTest $this->assertTrue($category->canDelete($admin), 'Admin should always be able to delete category.'); $this->assertTrue($category->canDelete($editor), 'Editor should be able to delete category.'); } + + public function testDuplicateCategories() { + $blog = new Blog(); + $blog->Title = 'Testing for duplicate categories'; + $blog->write(); + + $category = new BlogCategory(); + $category->Title = 'Test'; + $category->BlogID = $blog->ID; + $category->write(); + + $category = new BlogCategory(); + $category->Title = 'Test'; + $category->BlogID = $blog->ID; + try { + $category->write(); + $this->fail('Duplicate BlogCategory written'); + } catch (ValidationException $e) { + $codeList = $e->getResult()->codeList(); + $this->assertCount(1, $codeList); + $this->assertEquals(BlogTag::DUPLICATE_EXCEPTION, $codeList[0]); + } + } } diff --git a/tests/BlogTagTest.php b/tests/BlogTagTest.php index 1c16576..ba70dea 100755 --- a/tests/BlogTagTest.php +++ b/tests/BlogTagTest.php @@ -137,16 +137,40 @@ class BlogTagTest extends FunctionalTest $blog->Title = 'Testing for duplicates blog'; $blog->write(); $tag1 = new BlogTag(); - $tag1->Title = 'Cat'; + $tag1->Title = 'cat-test'; $tag1->BlogID = $blog->ID; $tag1->write(); - $this->assertEquals('cat', $tag1->URLSegment); + $this->assertEquals('cat-test', $tag1->URLSegment); $tag2 = new BlogTag(); - $tag2->Title = 'Cat'; + $tag2->Title = 'cat test'; $tag2->BlogID = $blog->ID; $tag2->write(); - $this->assertEquals('cat-0', $tag2->URLSegment); + $this->assertEquals('cat-test-0', $tag2->URLSegment); } + + public function testDuplicateTags() { + $blog = new Blog(); + $blog->Title = 'Testing for duplicate tags'; + $blog->write(); + + $tag = new BlogTag(); + $tag->Title = 'Test'; + $tag->BlogID = $blog->ID; + $tag->write(); + + $tag = new BlogTag(); + $tag->Title = 'Test'; + $tag->BlogID = $blog->ID; + try { + $tag->write(); + $this->fail('Duplicate BlogTag written'); + } catch (ValidationException $e) { + $codeList = $e->getResult()->codeList(); + $this->assertCount(1, $codeList); + $this->assertEquals(BlogTag::DUPLICATE_EXCEPTION, $codeList[0]); + } + } + }