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()
{
//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;
}

View File

@ -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.
*

View File

@ -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.
*

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($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->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]);
}
}
}