Merge pull request #372 from micmania1/271-prevent-duplicate-tags-categories

FIX Prevent duplicate tags and categories.
This commit is contained in:
Damian Mooyman 2016-02-09 14:56:36 +13:00
commit e7ef92c4e5
5 changed files with 127 additions and 11 deletions

View File

@ -37,7 +37,7 @@ class BlogEntry extends BlogPost implements MigratableObject
*/ */
public function up() public function up()
{ {
//Migrate comma separated tags into BlogTag objects. //Migrate comma separated tags into BlogTag objects.
foreach ($this->TagNames() as $tag) { foreach ($this->TagNames() as $tag) {
$existingTag = BlogTag::get()->filter(array('Title' => $tag, 'BlogID' => $this->ParentID)); $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. //if tag already exists we will simply add it to this post.
$tagObject = $existingTag->First(); $tagObject = $existingTag->First();
} else { } else {
//if the tag is now we create it and add it to this post. //if the tag is now we create it and add it to this post.
$tagObject = new BlogTag(); $tagObject = new BlogTag();
$tagObject->Title = $tag; $tagObject->Title = $tag;
@ -69,7 +68,7 @@ class BlogEntry extends BlogPost implements MigratableObject
$this->PublishDate = $this->Date; $this->PublishDate = $this->Date;
$this->AuthorNames = $this->Author; $this->AuthorNames = $this->Author;
$this->InheritSideBar = true; $this->InheritSideBar = true;
//Write and additionally publish the item if it was published before. //Write and additionally publish the item if it was published before.
$this->write(); $this->write();
if ($published) { if ($published) {
@ -78,7 +77,7 @@ class BlogEntry extends BlogPost implements MigratableObject
} else { } else {
$message = "DRAFT: "; $message = "DRAFT: ";
} }
return $message . $this->Title; return $message . $this->Title;
} }

View File

@ -13,6 +13,16 @@
*/ */
class BlogCategory extends DataObject implements CategorisationObject 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 * @var array
*/ */
@ -40,16 +50,16 @@ class BlogCategory extends DataObject implements CategorisationObject
private static $extensions = array( private static $extensions = array(
'URLSegmentExtension', 'URLSegmentExtension',
); );
/** /**
* @return DataList * @return DataList
*/ */
public function BlogPosts() public function BlogPosts()
{ {
$blogPosts = parent::BlogPosts(); $blogPosts = parent::BlogPosts();
$this->extend("updateGetBlogPosts", $blogPosts); $this->extend("updateGetBlogPosts", $blogPosts);
return $blogPosts; return $blogPosts;
} }
@ -67,6 +77,31 @@ class BlogCategory extends DataObject implements CategorisationObject
return $fields; 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. * Returns a relative link to this category.
* *

View File

@ -14,6 +14,16 @@
*/ */
class BlogTag extends DataObject implements CategorisationObject 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 * @var array
*/ */
@ -68,6 +78,31 @@ class BlogTag extends DataObject implements CategorisationObject
return $fields; 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. * Returns a relative URL for the tag link.
* *

View File

@ -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($admin), 'Admin should always be able to delete category.');
$this->assertTrue($category->canDelete($editor), 'Editor should 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]);
}
}
} }

View File

@ -137,16 +137,40 @@ class BlogTagTest extends FunctionalTest
$blog->Title = 'Testing for duplicates blog'; $blog->Title = 'Testing for duplicates blog';
$blog->write(); $blog->write();
$tag1 = new BlogTag(); $tag1 = new BlogTag();
$tag1->Title = 'Cat'; $tag1->Title = 'cat-test';
$tag1->BlogID = $blog->ID; $tag1->BlogID = $blog->ID;
$tag1->write(); $tag1->write();
$this->assertEquals('cat', $tag1->URLSegment); $this->assertEquals('cat-test', $tag1->URLSegment);
$tag2 = new BlogTag(); $tag2 = new BlogTag();
$tag2->Title = 'Cat'; $tag2->Title = 'cat test';
$tag2->BlogID = $blog->ID; $tag2->BlogID = $blog->ID;
$tag2->write(); $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]);
}
}
} }