FIX Prevent duplicate tags and categories.

This commit is contained in:
micmania1 2016-02-05 00:33:40 +00:00
parent 9526e13e5c
commit 8135f67b71
5 changed files with 127 additions and 11 deletions

View File

@ -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;

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
*/ */
@ -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]);
}
}
} }