Fixes: U4-4420 TagQuery / TagService missing method to get content with tag.

This commit is contained in:
Shannon
2014-05-07 14:27:10 +10:00
parent cfd21bc924
commit a6cd2b9e18
7 changed files with 256 additions and 31 deletions

View File

@@ -1,10 +1,38 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Models
{
public class TaggedEntity
{
public TaggedEntity(int entityId, IEnumerable<TaggedProperty> taggedProperties)
{
EntityId = entityId;
TaggedProperties = taggedProperties;
}
public int EntityId { get; private set; }
public IEnumerable<TaggedProperty> TaggedProperties { get; private set; }
}
public class TaggedProperty
{
public TaggedProperty(int propertyTypeId, string propertyTypeAlias, IEnumerable<Tag> tags)
{
PropertyTypeId = propertyTypeId;
PropertyTypeAlias = propertyTypeAlias;
Tags = tags;
}
public int PropertyTypeId { get; private set; }
public string PropertyTypeAlias { get; private set; }
public IEnumerable<Tag> Tags { get; private set; }
}
[Serializable]
[DataContract(IsReference = true)]
public class Tag : Entity, ITag

View File

@@ -5,9 +5,9 @@ namespace Umbraco.Core.Persistence.Repositories
{
public interface ITagsRepository : IRepositoryQueryable<int, ITag>
{
IEnumerable<int> GetIdsForEntityTypeByTagGroup(TaggableObjectTypes objectType, string tagGroup);
IEnumerable<TaggedEntity> GetTaggedEntitiesByTagGroup(TaggableObjectTypes objectType, string tagGroup);
IEnumerable<int> GetIdsForEntityTypeByTag(TaggableObjectTypes objectType, string tag, string tagGroup = null);
IEnumerable<TaggedEntity> GetTaggedEntitiesByTag(TaggableObjectTypes objectType, string tag, string tagGroup = null);
/// <summary>
/// Returns all tags for an entity type (content/media/member)

View File

@@ -161,36 +161,41 @@ namespace Umbraco.Core.Persistence.Repositories
//TODO: Consider caching implications.
public IEnumerable<int> GetIdsForEntityTypeByTagGroup(TaggableObjectTypes objectType, string tagGroup)
public IEnumerable<TaggedEntity> GetTaggedEntitiesByTagGroup(TaggableObjectTypes objectType, string tagGroup)
{
var nodeObjectType = GetNodeObjectType(objectType);
var sql = new Sql()
.Select("DISTINCT cmsTagRelationship.nodeId")
.Select("cmsTagRelationship.nodeId, cmsPropertyType.Alias, cmsPropertyType.id as propertyTypeId, cmsTags.tag, cmsTags.id as tagId, cmsTags." + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("group"))
.From<TagDto>()
.InnerJoin<TagRelationshipDto>()
.On<TagRelationshipDto, TagDto>(left => left.TagId, right => right.Id)
.InnerJoin<ContentDto>()
.On<ContentDto, TagRelationshipDto>(left => left.NodeId, right => right.NodeId)
.InnerJoin<PropertyTypeDto>()
.On<PropertyTypeDto, TagRelationshipDto>(left => left.Id, right => right.PropertyTypeId)
.InnerJoin<NodeDto>()
.On<NodeDto, ContentDto>(left => left.NodeId, right => right.NodeId)
.Where<NodeDto>(dto => dto.NodeObjectType == nodeObjectType)
.Where<TagDto>(dto => dto.Group == tagGroup);
.Where<TagDto>(dto => dto.Group == tagGroup);
return ApplicationContext.Current.DatabaseContext.Database.Fetch<int>(sql);
return CreateTaggedEntityCollection(
ApplicationContext.Current.DatabaseContext.Database.Fetch<dynamic>(sql));
}
public IEnumerable<int> GetIdsForEntityTypeByTag(TaggableObjectTypes objectType, string tag, string tagGroup = null)
public IEnumerable<TaggedEntity> GetTaggedEntitiesByTag(TaggableObjectTypes objectType, string tag, string tagGroup = null)
{
var nodeObjectType = GetNodeObjectType(objectType);
var sql = new Sql()
.Select("DISTINCT cmsTagRelationship.nodeId")
.Select("cmsTagRelationship.nodeId, cmsPropertyType.Alias, cmsPropertyType.id as propertyTypeId, cmsTags.tag, cmsTags.id as tagId, cmsTags." + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("group"))
.From<TagDto>()
.InnerJoin<TagRelationshipDto>()
.On<TagRelationshipDto, TagDto>(left => left.TagId, right => right.Id)
.InnerJoin<ContentDto>()
.On<ContentDto, TagRelationshipDto>(left => left.NodeId, right => right.NodeId)
.InnerJoin<PropertyTypeDto>()
.On<PropertyTypeDto, TagRelationshipDto>(left => left.Id, right => right.PropertyTypeId)
.InnerJoin<NodeDto>()
.On<NodeDto, ContentDto>(left => left.NodeId, right => right.NodeId)
.Where<NodeDto>(dto => dto.NodeObjectType == nodeObjectType)
@@ -201,7 +206,24 @@ namespace Umbraco.Core.Persistence.Repositories
sql = sql.Where<TagDto>(dto => dto.Group == tagGroup);
}
return ApplicationContext.Current.DatabaseContext.Database.Fetch<int>(sql);
return CreateTaggedEntityCollection(
ApplicationContext.Current.DatabaseContext.Database.Fetch<dynamic>(sql));
}
private IEnumerable<TaggedEntity> CreateTaggedEntityCollection(IEnumerable<dynamic> dbResult)
{
var list = new List<TaggedEntity>();
foreach (var node in dbResult.GroupBy(x => (int)x.nodeId))
{
var properties = new List<TaggedProperty>();
foreach (var propertyType in node.GroupBy(x => new { id = (int)x.propertyTypeId, alias = (string)x.Alias }))
{
var tags = propertyType.Select(x => new Tag((int)x.tagId, (string)x.tag, (string)x.group));
properties.Add(new TaggedProperty(propertyType.Key.id, propertyType.Key.alias, tags));
}
list.Add(new TaggedEntity(node.Key, properties));
}
return list;
}
public IEnumerable<ITag> GetTagsForEntityType(TaggableObjectTypes objectType, string group = null)

View File

@@ -17,12 +17,12 @@ namespace Umbraco.Core.Services
public interface ITagService : IService
{
IEnumerable<int> GetContentIdsByTagGroup(string tagGroup);
IEnumerable<int> GetContentIdsByTag(string tag, string tagGroup = null);
IEnumerable<int> GetMediaIdsByTagGroup(string tagGroup);
IEnumerable<int> GetMediaIdsByTag(string tag, string tagGroup = null);
IEnumerable<int> GetMemberIdsByTagGroup(string tagGroup);
IEnumerable<int> GetMemberIdsByTag(string tag, string tagGroup = null);
IEnumerable<TaggedEntity> GetTaggedContentByTagGroup(string tagGroup);
IEnumerable<TaggedEntity> GetTaggedContentByTag(string tag, string tagGroup = null);
IEnumerable<TaggedEntity> GetTaggedMediaByTagGroup(string tagGroup);
IEnumerable<TaggedEntity> GetTaggedMediaByTag(string tag, string tagGroup = null);
IEnumerable<TaggedEntity> GetTaggedMembersByTagGroup(string tagGroup);
IEnumerable<TaggedEntity> GetTaggedMembersByTag(string tag, string tagGroup = null);
/// <summary>
/// Get every tag stored in the database (with optional group)

View File

@@ -41,51 +41,51 @@ namespace Umbraco.Core.Services
_uowProvider = provider;
}
public IEnumerable<int> GetContentIdsByTagGroup(string tagGroup)
public IEnumerable<TaggedEntity> GetTaggedContentByTagGroup(string tagGroup)
{
using (var repository = _repositoryFactory.CreateTagsRepository(_uowProvider.GetUnitOfWork()))
{
return repository.GetIdsForEntityTypeByTagGroup(TaggableObjectTypes.Content, tagGroup);
return repository.GetTaggedEntitiesByTagGroup(TaggableObjectTypes.Content, tagGroup);
}
}
public IEnumerable<int> GetContentIdsByTag(string tag, string tagGroup = null)
public IEnumerable<TaggedEntity> GetTaggedContentByTag(string tag, string tagGroup = null)
{
using (var repository = _repositoryFactory.CreateTagsRepository(_uowProvider.GetUnitOfWork()))
{
return repository.GetIdsForEntityTypeByTag(TaggableObjectTypes.Content, tag, tagGroup);
return repository.GetTaggedEntitiesByTag(TaggableObjectTypes.Content, tag, tagGroup);
}
}
public IEnumerable<int> GetMediaIdsByTagGroup(string tagGroup)
public IEnumerable<TaggedEntity> GetTaggedMediaByTagGroup(string tagGroup)
{
using (var repository = _repositoryFactory.CreateTagsRepository(_uowProvider.GetUnitOfWork()))
{
return repository.GetIdsForEntityTypeByTagGroup(TaggableObjectTypes.Media, tagGroup);
return repository.GetTaggedEntitiesByTagGroup(TaggableObjectTypes.Media, tagGroup);
}
}
public IEnumerable<int> GetMediaIdsByTag(string tag, string tagGroup = null)
public IEnumerable<TaggedEntity> GetTaggedMediaByTag(string tag, string tagGroup = null)
{
using (var repository = _repositoryFactory.CreateTagsRepository(_uowProvider.GetUnitOfWork()))
{
return repository.GetIdsForEntityTypeByTag(TaggableObjectTypes.Media, tag, tagGroup);
return repository.GetTaggedEntitiesByTag(TaggableObjectTypes.Media, tag, tagGroup);
}
}
public IEnumerable<int> GetMemberIdsByTagGroup(string tagGroup)
public IEnumerable<TaggedEntity> GetTaggedMembersByTagGroup(string tagGroup)
{
using (var repository = _repositoryFactory.CreateTagsRepository(_uowProvider.GetUnitOfWork()))
{
return repository.GetIdsForEntityTypeByTagGroup(TaggableObjectTypes.Member, tagGroup);
return repository.GetTaggedEntitiesByTagGroup(TaggableObjectTypes.Member, tagGroup);
}
}
public IEnumerable<int> GetMemberIdsByTag(string tag, string tagGroup = null)
public IEnumerable<TaggedEntity> GetTaggedMembersByTag(string tag, string tagGroup = null)
{
using (var repository = _repositoryFactory.CreateTagsRepository(_uowProvider.GetUnitOfWork()))
{
return repository.GetIdsForEntityTypeByTag(TaggableObjectTypes.Member, tag, tagGroup);
return repository.GetTaggedEntitiesByTag(TaggableObjectTypes.Member, tag, tagGroup);
}
}

View File

@@ -691,6 +691,177 @@ namespace Umbraco.Tests.Persistence.Repositories
}
[Test]
public void Can_Get_Tagged_Entities_For_Tag_Group()
{
var provider = new PetaPocoUnitOfWorkProvider();
var unitOfWork = provider.GetUnitOfWork();
MediaTypeRepository mediaTypeRepository;
ContentTypeRepository contentTypeRepository;
using (var contentRepository = CreateContentRepository(unitOfWork, out contentTypeRepository))
using (var mediaRepository = CreateMediaRepository(unitOfWork, out mediaTypeRepository))
{
//create data to relate to
var contentType = MockedContentTypes.CreateSimpleContentType("test", "Test");
contentTypeRepository.AddOrUpdate(contentType);
unitOfWork.Commit();
var content1 = MockedContent.CreateSimpleContent(contentType);
contentRepository.AddOrUpdate(content1);
unitOfWork.Commit();
var content2 = MockedContent.CreateSimpleContent(contentType);
contentRepository.AddOrUpdate(content2);
unitOfWork.Commit();
var mediaType = MockedContentTypes.CreateImageMediaType("image2");
mediaTypeRepository.AddOrUpdate(mediaType);
unitOfWork.Commit();
var media1 = MockedMedia.CreateMediaImage(mediaType, -1);
mediaRepository.AddOrUpdate(media1);
unitOfWork.Commit();
using (var repository = CreateRepository(unitOfWork))
{
repository.AssignTagsToProperty(
content1.Id,
contentType.PropertyTypes.First().Id,
new[]
{
new Tag {Text = "tag1", Group = "test"},
new Tag {Text = "tag2", Group = "test1"},
new Tag {Text = "tag3", Group = "test"}
}, false);
repository.AssignTagsToProperty(
content2.Id,
contentType.PropertyTypes.Last().Id,
new[]
{
new Tag {Text = "tag1", Group = "test"},
new Tag {Text = "tag2", Group = "test1"},
new Tag {Text = "tag3", Group = "test"}
}, false);
repository.AssignTagsToProperty(
media1.Id,
mediaType.PropertyTypes.Last().Id,
new[]
{
new Tag {Text = "tag1", Group = "test"},
new Tag {Text = "tag2", Group = "test1"}
}, false);
var contentTestIds = repository.GetTaggedEntitiesByTagGroup(TaggableObjectTypes.Content, "test").ToArray();
//there are two content items tagged against the 'test' group
Assert.AreEqual(2, contentTestIds.Count());
//there are a total of two property types tagged against the 'test' group
Assert.AreEqual(2, contentTestIds.SelectMany(x => x.TaggedProperties).Count());
//there are a total of 2 tags tagged against the 'test' group
Assert.AreEqual(2, contentTestIds.SelectMany(x => x.TaggedProperties).SelectMany(x => x.Tags).Select(x => x.Id).Distinct().Count());
var contentTest1Ids = repository.GetTaggedEntitiesByTagGroup(TaggableObjectTypes.Content, "test1").ToArray();
//there are two content items tagged against the 'test1' group
Assert.AreEqual(2, contentTest1Ids.Count());
//there are a total of two property types tagged against the 'test1' group
Assert.AreEqual(2, contentTest1Ids.SelectMany(x => x.TaggedProperties).Count());
//there are a total of 1 tags tagged against the 'test1' group
Assert.AreEqual(1, contentTest1Ids.SelectMany(x => x.TaggedProperties).SelectMany(x => x.Tags).Select(x => x.Id).Distinct().Count());
var mediaTestIds = repository.GetTaggedEntitiesByTagGroup(TaggableObjectTypes.Media, "test");
Assert.AreEqual(1, mediaTestIds.Count());
var mediaTest1Ids = repository.GetTaggedEntitiesByTagGroup(TaggableObjectTypes.Media, "test1");
Assert.AreEqual(1, mediaTest1Ids.Count());
}
}
}
[Test]
public void Can_Get_Tagged_Entities_For_Tag()
{
var provider = new PetaPocoUnitOfWorkProvider();
var unitOfWork = provider.GetUnitOfWork();
MediaTypeRepository mediaTypeRepository;
ContentTypeRepository contentTypeRepository;
using (var contentRepository = CreateContentRepository(unitOfWork, out contentTypeRepository))
using (var mediaRepository = CreateMediaRepository(unitOfWork, out mediaTypeRepository))
{
//create data to relate to
var contentType = MockedContentTypes.CreateSimpleContentType("test", "Test");
contentTypeRepository.AddOrUpdate(contentType);
unitOfWork.Commit();
var content1 = MockedContent.CreateSimpleContent(contentType);
contentRepository.AddOrUpdate(content1);
unitOfWork.Commit();
var content2 = MockedContent.CreateSimpleContent(contentType);
contentRepository.AddOrUpdate(content2);
unitOfWork.Commit();
var mediaType = MockedContentTypes.CreateImageMediaType("image2");
mediaTypeRepository.AddOrUpdate(mediaType);
unitOfWork.Commit();
var media1 = MockedMedia.CreateMediaImage(mediaType, -1);
mediaRepository.AddOrUpdate(media1);
unitOfWork.Commit();
using (var repository = CreateRepository(unitOfWork))
{
repository.AssignTagsToProperty(
content1.Id,
contentType.PropertyTypes.First().Id,
new[]
{
new Tag {Text = "tag1", Group = "test"},
new Tag {Text = "tag2", Group = "test1"},
new Tag {Text = "tag3", Group = "test"}
}, false);
repository.AssignTagsToProperty(
content2.Id,
contentType.PropertyTypes.Last().Id,
new[]
{
new Tag {Text = "tag1", Group = "test"},
new Tag {Text = "tag2", Group = "test1"},
}, false);
repository.AssignTagsToProperty(
media1.Id,
mediaType.PropertyTypes.Last().Id,
new[]
{
new Tag {Text = "tag1", Group = "test"},
new Tag {Text = "tag2", Group = "test1"}
}, false);
var contentTestIds = repository.GetTaggedEntitiesByTag(TaggableObjectTypes.Content, "tag1").ToArray();
//there are two content items tagged against the 'tag1' tag
Assert.AreEqual(2, contentTestIds.Count());
//there are a total of two property types tagged against the 'tag1' tag
Assert.AreEqual(2, contentTestIds.SelectMany(x => x.TaggedProperties).Count());
//there are a total of 1 tags since we're only looking against one tag
Assert.AreEqual(1, contentTestIds.SelectMany(x => x.TaggedProperties).SelectMany(x => x.Tags).Select(x => x.Id).Distinct().Count());
var contentTest1Ids = repository.GetTaggedEntitiesByTag(TaggableObjectTypes.Content, "tag3").ToArray();
//there are 1 content items tagged against the 'tag3' tag
Assert.AreEqual(1, contentTest1Ids.Count());
//there are a total of two property types tagged against the 'tag3' tag
Assert.AreEqual(1, contentTest1Ids.SelectMany(x => x.TaggedProperties).Count());
//there are a total of 1 tags since we're only looking against one tag
Assert.AreEqual(1, contentTest1Ids.SelectMany(x => x.TaggedProperties).SelectMany(x => x.Tags).Select(x => x.Id).Distinct().Count());
var mediaTestIds = repository.GetTaggedEntitiesByTag(TaggableObjectTypes.Media, "tag1");
Assert.AreEqual(1, mediaTestIds.Count());
}
}
}
private ContentRepository CreateContentRepository(IDatabaseUnitOfWork unitOfWork, out ContentTypeRepository contentTypeRepository)
{
var templateRepository = new TemplateRepository(unitOfWork, NullCacheProvider.Current);

View File

@@ -38,7 +38,8 @@ namespace Umbraco.Web
/// <returns></returns>
public IEnumerable<IPublishedContent> GetContentByTag(string tag, string tagGroup = null)
{
var ids = _tagService.GetContentIdsByTag(tag, tagGroup);
var ids = _tagService.GetTaggedContentByTag(tag, tagGroup)
.Select(x => x.EntityId);
return _contentQuery.TypedContent(ids)
.Where(x => x != null);
}
@@ -50,7 +51,8 @@ namespace Umbraco.Web
/// <returns></returns>
public IEnumerable<IPublishedContent> GetContentByTagGroup(string tagGroup)
{
var ids = _tagService.GetContentIdsByTagGroup(tagGroup);
var ids = _tagService.GetTaggedContentByTagGroup(tagGroup)
.Select(x => x.EntityId);
return _contentQuery.TypedContent(ids)
.Where(x => x != null);
}
@@ -63,7 +65,8 @@ namespace Umbraco.Web
/// <returns></returns>
public IEnumerable<IPublishedContent> GetMediaByTag(string tag, string tagGroup = null)
{
var ids = _tagService.GetMediaIdsByTag(tag, tagGroup);
var ids = _tagService.GetTaggedMediaByTag(tag, tagGroup)
.Select(x => x.EntityId);
return _contentQuery.TypedMedia(ids)
.Where(x => x != null);
}
@@ -75,7 +78,8 @@ namespace Umbraco.Web
/// <returns></returns>
public IEnumerable<IPublishedContent> GetMediaByTagGroup(string tagGroup)
{
var ids = _tagService.GetMediaIdsByTagGroup(tagGroup);
var ids = _tagService.GetTaggedMediaByTagGroup(tagGroup)
.Select(x => x.EntityId);
return _contentQuery.TypedMedia(ids)
.Where(x => x != null);
}