From c03b839bb1f2922112d85d3fc48dbd9a891481e5 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 24 Oct 2013 11:49:09 +1100 Subject: [PATCH] Completes: U4-3052 Create TagsService --- src/Umbraco.Core/Models/ContentExtensions.cs | 15 + .../Models/TaggableObjectTypes.cs | 12 + .../Interfaces/ITagsRepository.cs | 25 +- .../Repositories/TagsRepository.cs | 71 ++++- .../Repositories/VersionableRepositoryBase.cs | 4 +- src/Umbraco.Core/Services/ITagService.cs | 60 ++++ src/Umbraco.Core/Services/ServiceContext.cs | 26 +- src/Umbraco.Core/Services/TagService.cs | 127 +++++++++ src/Umbraco.Core/Umbraco.Core.csproj | 3 + src/Umbraco.Tests/MockTests.cs | 6 +- .../Repositories/TagRepositoryTest.cs | 269 ++++++++++++++++-- src/umbraco.cms/businesslogic/Tags/Tag.cs | 1 + src/umbraco.editorControls/tags/library.cs | 6 +- src/umbraco.interfaces/ITag.cs | 3 + 14 files changed, 570 insertions(+), 58 deletions(-) create mode 100644 src/Umbraco.Core/Models/TaggableObjectTypes.cs create mode 100644 src/Umbraco.Core/Services/ITagService.cs create mode 100644 src/Umbraco.Core/Services/TagService.cs diff --git a/src/Umbraco.Core/Models/ContentExtensions.cs b/src/Umbraco.Core/Models/ContentExtensions.cs index 7be7c17065..d377095a05 100644 --- a/src/Umbraco.Core/Models/ContentExtensions.cs +++ b/src/Umbraco.Core/Models/ContentExtensions.cs @@ -528,6 +528,21 @@ namespace Umbraco.Core.Models #region Tag methods + ///// + ///// Returns the tags for the given property + ///// + ///// + ///// + ///// + ///// + ///// + ///// The tags returned are only relavent for published content & saved media or members + ///// + //public static IEnumerable GetTags(this IContentBase content, string propertyTypeAlias, string tagGroup = "default") + //{ + + //} + /// /// Sets tags for the property - will add tags to the tags table and set the property value to be the comma delimited value of the tags. /// diff --git a/src/Umbraco.Core/Models/TaggableObjectTypes.cs b/src/Umbraco.Core/Models/TaggableObjectTypes.cs new file mode 100644 index 0000000000..4e9b70fd3e --- /dev/null +++ b/src/Umbraco.Core/Models/TaggableObjectTypes.cs @@ -0,0 +1,12 @@ +namespace Umbraco.Core.Models +{ + /// + /// Enum representing the taggable object types + /// + public enum TaggableObjectTypes + { + Content, + Media, + Member + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/Interfaces/ITagsRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Interfaces/ITagsRepository.cs index 0629c0ecb7..9dec8eef2f 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Interfaces/ITagsRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Interfaces/ITagsRepository.cs @@ -3,29 +3,38 @@ using Umbraco.Core.Models; namespace Umbraco.Core.Persistence.Repositories { - public interface ITagsRepository : IRepository + public interface ITagsRepository : IRepositoryQueryable { + /// + /// Returns all tags for an entity type (content/media/member) + /// + /// + /// Optional group + /// + IEnumerable GetTagsForEntityType(TaggableObjectTypes objectType, string group = null); /// /// Returns all tags that exist on the content item - Content/Media/Member /// /// The content item id to get tags for + /// Optional group /// - IEnumerable GetPublishedTagsForContent(int contentId); + IEnumerable GetTagsForEntity(int contentId, string group = null); /// /// Returns all tags that exist on the content item for the property specified - Content/Media/Member /// /// The content item id to get tags for - /// The property alias to get tags for + /// The property alias to get tags for + /// Optional group /// - IEnumerable GetPublishedTagsForProperty(int contentId, string propertyAlias); + IEnumerable GetTagsForProperty(int contentId, string propertyTypeAlias, string group = null); /// /// Assigns the given tags to a content item's property /// /// - /// + /// /// The tags to assign /// /// If set to true, this will replace all tags with the given tags, @@ -35,14 +44,14 @@ namespace Umbraco.Core.Persistence.Repositories /// /// This can also be used to remove all tags from a property by specifying replaceTags = true and an empty tag list. /// - void AssignPublishedTagsToProperty(int contentId, string propertyAlias, IEnumerable tags, bool replaceTags); + void AssignTagsToProperty(int contentId, string propertyTypeAlias, IEnumerable tags, bool replaceTags); /// /// Removes any of the given tags from the property association /// /// - /// + /// /// The tags to remove from the property - void RemovePublishedTagsFromProperty(int contentId, string propertyAlias, IEnumerable tags); + void RemoveTagsFromProperty(int contentId, string propertyTypeAlias, IEnumerable tags); } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/TagsRepository.cs b/src/Umbraco.Core/Persistence/Repositories/TagsRepository.cs index 62f1c8792d..fba75aae51 100644 --- a/src/Umbraco.Core/Persistence/Repositories/TagsRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/TagsRepository.cs @@ -160,21 +160,50 @@ namespace Umbraco.Core.Persistence.Repositories //TODO: Consider caching implications. - public IEnumerable GetPublishedTagsForContent(int contentId) + public IEnumerable GetTagsForEntityType(TaggableObjectTypes objectType, string group = null) { + var nodeObjectType = GetNodeObjectType(objectType); + var sql = new Sql() .Select("DISTINCT cmsTags.*") .From() .InnerJoin() - .On("cmsTagRelationship.tagId = cmsTags.id") - .Where(dto => dto.NodeId == contentId); + .On(left => left.TagId, right => right.Id) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(dto => dto.NodeObjectType == nodeObjectType); + + if (group.IsNullOrWhiteSpace() == false) + { + sql = sql.Where(dto => dto.Group == group); + } var factory = new TagFactory(); return Database.Fetch(sql).Select(factory.BuildEntity); } - public IEnumerable GetPublishedTagsForProperty(int contentId, string propertyAlias) + public IEnumerable GetTagsForEntity(int contentId, string group = null) + { + var sql = new Sql() + .Select("DISTINCT cmsTags.*") + .From() + .InnerJoin() + .On(left => left.TagId, right => right.Id); + + if (group.IsNullOrWhiteSpace() == false) + { + sql = sql.Where(dto => dto.Group == group); + } + + var factory = new TagFactory(); + + return Database.Fetch(sql).Select(factory.BuildEntity); + } + + public IEnumerable GetTagsForProperty(int contentId, string propertyTypeAlias, string group = null) { var sql = new Sql() .Select("DISTINCT cmsTags.*") @@ -184,7 +213,12 @@ namespace Umbraco.Core.Persistence.Repositories .InnerJoin() .On(left => left.Id, right => right.PropertyTypeId) .Where(dto => dto.NodeId == contentId) - .Where(dto => dto.Alias == propertyAlias); + .Where(dto => dto.Alias == propertyTypeAlias); + + if (group.IsNullOrWhiteSpace() == false) + { + sql = sql.Where(dto => dto.Group == group); + } var factory = new TagFactory(); @@ -195,7 +229,7 @@ namespace Umbraco.Core.Persistence.Repositories /// Assigns the given tags to a content item's property /// /// - /// + /// /// The tags to assign /// /// If set to true, this will replace all tags with the given tags, @@ -205,7 +239,7 @@ namespace Umbraco.Core.Persistence.Repositories /// /// This can also be used to remove all tags from a property by specifying replaceTags = true and an empty tag list. /// - public void AssignPublishedTagsToProperty(int contentId, string propertyAlias, IEnumerable tags, bool replaceTags) + public void AssignTagsToProperty(int contentId, string propertyTypeAlias, IEnumerable tags, bool replaceTags) { //First we need to ensure there are no duplicates var asArray = tags.Distinct(new TagComparer()).ToArray(); @@ -216,7 +250,7 @@ namespace Umbraco.Core.Persistence.Repositories return; } - var propertyTypeId = EnsureContentProperty(contentId, propertyAlias); + var propertyTypeId = EnsureContentProperty(contentId, propertyTypeAlias); //next check if we're removing all of the tags if (asArray.Length == 0 && replaceTags) @@ -292,11 +326,11 @@ namespace Umbraco.Core.Persistence.Repositories /// Removes any of the given tags from the property association /// /// - /// + /// /// The tags to remove from the property - public void RemovePublishedTagsFromProperty(int contentId, string propertyAlias, IEnumerable tags) + public void RemoveTagsFromProperty(int contentId, string propertyTypeAlias, IEnumerable tags) { - var propertyTypeId = EnsureContentProperty(contentId, propertyAlias); + var propertyTypeId = EnsureContentProperty(contentId, propertyTypeAlias); var tagSetSql = GetTagSet(tags); @@ -312,6 +346,21 @@ namespace Umbraco.Core.Persistence.Repositories Database.Execute(deleteSql); } + private Guid GetNodeObjectType(TaggableObjectTypes type) + { + switch (type) + { + case TaggableObjectTypes.Content: + return new Guid(Constants.ObjectTypes.Document); + case TaggableObjectTypes.Media: + return new Guid(Constants.ObjectTypes.Media); + case TaggableObjectTypes.Member: + return new Guid(Constants.ObjectTypes.Member); + default: + throw new ArgumentOutOfRangeException("type"); + } + } + /// /// This is a clever way to produce an SQL statement like this: /// diff --git a/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs index 0c89f747a2..d8cfbd4336 100644 --- a/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs +++ b/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs @@ -104,7 +104,7 @@ namespace Umbraco.Core.Persistence.Repositories if (tagProp.TagSupport.Behavior == PropertyTagBehavior.Remove) { //remove the specific tags - tagRepo.RemovePublishedTagsFromProperty( + tagRepo.RemoveTagsFromProperty( entity.Id, tagProp.Alias, tagProp.TagSupport.Tags.Select(x => new Tag { Text = x.Item1, Group = x.Item2 })); @@ -112,7 +112,7 @@ namespace Umbraco.Core.Persistence.Repositories else { //assign the tags - tagRepo.AssignPublishedTagsToProperty( + tagRepo.AssignTagsToProperty( entity.Id, tagProp.Alias, tagProp.TagSupport.Tags.Select(x => new Tag { Text = x.Item1, Group = x.Item2 }), diff --git a/src/Umbraco.Core/Services/ITagService.cs b/src/Umbraco.Core/Services/ITagService.cs new file mode 100644 index 0000000000..ab78fabd95 --- /dev/null +++ b/src/Umbraco.Core/Services/ITagService.cs @@ -0,0 +1,60 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using Umbraco.Core.Models; + +namespace Umbraco.Core.Services +{ + /// + /// Tag service to query for tags in the tags db table. The tags returned are only relavent for published content & saved media or members + /// + /// + /// If there is unpublished content with tags, those tags will not be contained + /// + public interface ITagService : IService + { + /// + /// Get every tag stored in the database (with optional group) + /// + IEnumerable GetAllTags(string group = null); + + /// + /// Get all tags for content items (with optional group) + /// + /// + /// + IEnumerable GetAllContentTags(string group = null); + + /// + /// Get all tags for media items (with optional group) + /// + /// + /// + IEnumerable GetAllMediaTags(string group = null); + + /// + /// Get all tags for member items (with optional group) + /// + /// + /// + IEnumerable GetAllMemberTags(string group = null); + + /// + /// Returns all tags attached to a property by entity id + /// + /// + /// + /// + /// + IEnumerable GetTagsForProperty(int contentId, string propertyTypeAlias, string tagGroup = null); + + /// + /// Returns all tags attached to an entity (content, media or member) by entity id + /// + /// + /// + /// + IEnumerable GetTagsForEntity(int contentId, string tagGroup = null); + + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Services/ServiceContext.cs b/src/Umbraco.Core/Services/ServiceContext.cs index ea9ec68fef..baa29f8915 100644 --- a/src/Umbraco.Core/Services/ServiceContext.cs +++ b/src/Umbraco.Core/Services/ServiceContext.cs @@ -12,6 +12,7 @@ namespace Umbraco.Core.Services /// public class ServiceContext { + private Lazy _tagService; private Lazy _contentService; private Lazy _userService; private Lazy _memberService; @@ -43,6 +44,7 @@ namespace Umbraco.Core.Services /// /// /// + /// public ServiceContext( IContentService contentService, IMediaService mediaService, @@ -54,8 +56,10 @@ namespace Umbraco.Core.Services IEntityService entityService, IRelationService relationService, ISectionService sectionService, - IApplicationTreeService treeService) + IApplicationTreeService treeService, + ITagService tagService) { + _tagService = new Lazy(() => tagService); _contentService = new Lazy(() => contentService); _mediaService = new Lazy(() => mediaService); _contentTypeService = new Lazy(() => contentTypeService); @@ -75,7 +79,8 @@ namespace Umbraco.Core.Services /// /// /// - internal ServiceContext(IDatabaseUnitOfWorkProvider dbUnitOfWorkProvider, IUnitOfWorkProvider fileUnitOfWorkProvider, BasePublishingStrategy publishingStrategy, CacheHelper cache) + /// + internal ServiceContext(IDatabaseUnitOfWorkProvider dbUnitOfWorkProvider, IUnitOfWorkProvider fileUnitOfWorkProvider, BasePublishingStrategy publishingStrategy, CacheHelper cache) { BuildServiceCache(dbUnitOfWorkProvider, fileUnitOfWorkProvider, publishingStrategy, cache, //this needs to be lazy because when we create the service context it's generally before the @@ -143,6 +148,9 @@ namespace Umbraco.Core.Services if (_memberTypeService == null) _memberTypeService = new Lazy(() => new MemberTypeService(provider, repositoryFactory.Value)); + + if (_tagService == null) + _tagService = new Lazy(() => new TagService(provider, repositoryFactory.Value)); } /// @@ -154,7 +162,15 @@ namespace Umbraco.Core.Services } /// - /// Gets the + /// Gets the + /// + public ITagService TagService + { + get { return _tagService.Value; } + } + + /// + /// Gets the /// public IMacroService MacroService { @@ -162,7 +178,7 @@ namespace Umbraco.Core.Services } /// - /// Gets the + /// Gets the /// public IEntityService EntityService { @@ -170,7 +186,7 @@ namespace Umbraco.Core.Services } /// - /// Gets the + /// Gets the /// public IRelationService RelationService { diff --git a/src/Umbraco.Core/Services/TagService.cs b/src/Umbraco.Core/Services/TagService.cs new file mode 100644 index 0000000000..9abd731d85 --- /dev/null +++ b/src/Umbraco.Core/Services/TagService.cs @@ -0,0 +1,127 @@ +using System.Collections.Generic; +using Umbraco.Core.Models; +using Umbraco.Core.Persistence; +using Umbraco.Core.Persistence.Querying; +using Umbraco.Core.Persistence.UnitOfWork; + +namespace Umbraco.Core.Services +{ + /// + /// Tag service to query for tags in the tags db table. The tags returned are only relavent for published content & saved media or members + /// + /// + /// If there is unpublished content with tags, those tags will not be contained + /// + public class TagService : ITagService + { + + private readonly RepositoryFactory _repositoryFactory; + private readonly IDatabaseUnitOfWorkProvider _uowProvider; + + public TagService() + : this(new RepositoryFactory()) + {} + + public TagService(RepositoryFactory repositoryFactory) + : this(new PetaPocoUnitOfWorkProvider(), repositoryFactory) + { + } + + public TagService(IDatabaseUnitOfWorkProvider provider) + : this(provider, new RepositoryFactory()) + { + } + + public TagService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory) + { + _repositoryFactory = repositoryFactory; + _uowProvider = provider; + } + + /// + /// Get every tag stored in the database (with optional group) + /// + public IEnumerable GetAllTags(string group = null) + { + using (var repository = _repositoryFactory.CreateTagsRepository(_uowProvider.GetUnitOfWork())) + { + if (group.IsNullOrWhiteSpace()) + { + return repository.GetAll(); + } + + var query = Query.Builder.Where(x => x.Group == group); + var definitions = repository.GetByQuery(query); + return definitions; + } + } + + /// + /// Get all tags for content items (with optional group) + /// + /// + /// + public IEnumerable GetAllContentTags(string group = null) + { + using (var repository = _repositoryFactory.CreateTagsRepository(_uowProvider.GetUnitOfWork())) + { + return repository.GetTagsForEntityType(TaggableObjectTypes.Content, group); + } + } + + /// + /// Get all tags for media items (with optional group) + /// + /// + /// + public IEnumerable GetAllMediaTags(string group = null) + { + using (var repository = _repositoryFactory.CreateTagsRepository(_uowProvider.GetUnitOfWork())) + { + return repository.GetTagsForEntityType(TaggableObjectTypes.Media, group); + } + } + + /// + /// Get all tags for member items (with optional group) + /// + /// + /// + public IEnumerable GetAllMemberTags(string group = null) + { + using (var repository = _repositoryFactory.CreateTagsRepository(_uowProvider.GetUnitOfWork())) + { + return repository.GetTagsForEntityType(TaggableObjectTypes.Member, group); + } + } + + /// + /// Returns all tags attached to a property by entity id + /// + /// + /// + /// + /// + public IEnumerable GetTagsForProperty(int contentId, string propertyTypeAlias, string tagGroup = null) + { + using (var repository = _repositoryFactory.CreateTagsRepository(_uowProvider.GetUnitOfWork())) + { + return repository.GetTagsForProperty(contentId, propertyTypeAlias, tagGroup); + } + } + + /// + /// Returns all tags attached to an entity (content, media or member) by entity id + /// + /// + /// + /// + public IEnumerable GetTagsForEntity(int contentId, string tagGroup = null) + { + using (var repository = _repositoryFactory.CreateTagsRepository(_uowProvider.GetUnitOfWork())) + { + return repository.GetTagsForEntity(contentId, tagGroup); + } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index eb647abd21..7e547d0988 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -325,6 +325,7 @@ + @@ -961,6 +962,7 @@ + @@ -972,6 +974,7 @@ + diff --git a/src/Umbraco.Tests/MockTests.cs b/src/Umbraco.Tests/MockTests.cs index 27c6a2d533..52c2ee3680 100644 --- a/src/Umbraco.Tests/MockTests.cs +++ b/src/Umbraco.Tests/MockTests.cs @@ -49,7 +49,8 @@ namespace Umbraco.Tests new RepositoryFactory(true), new Mock().Object), new Mock().Object, - new Mock().Object); + new Mock().Object, + new Mock().Object); Assert.Pass(); } @@ -87,7 +88,8 @@ namespace Umbraco.Tests new RepositoryFactory(true), new Mock().Object), new Mock().Object, - new Mock().Object), + new Mock().Object, + new Mock().Object), CacheHelper.CreateDisabledCacheHelper()); Assert.Pass(); } diff --git a/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs index cbf7bb7247..b5f934706a 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs @@ -111,7 +111,7 @@ namespace Umbraco.Tests.Persistence.Repositories var unitOfWork = provider.GetUnitOfWork(); using (var repository = CreateRepository(unitOfWork)) { - Assert.Throws(() => repository.AssignPublishedTagsToProperty(1234, "hello", Enumerable.Empty(), true)); + Assert.Throws(() => repository.AssignTagsToProperty(1234, "hello", Enumerable.Empty(), true)); } } @@ -134,7 +134,7 @@ namespace Umbraco.Tests.Persistence.Repositories using (var repository = CreateRepository(unitOfWork)) { - repository.AssignPublishedTagsToProperty( + repository.AssignTagsToProperty( content.Id, contentType.PropertyTypes.First().Alias, new[] @@ -143,7 +143,7 @@ namespace Umbraco.Tests.Persistence.Repositories new Tag {Text = "tag2", Group = "test"}, }, false); - Assert.AreEqual(2, repository.GetPublishedTagsForContent(content.Id).Count()); + Assert.AreEqual(2, repository.GetTagsForEntity(content.Id).Count()); } } } @@ -166,7 +166,7 @@ namespace Umbraco.Tests.Persistence.Repositories using (var repository = CreateRepository(unitOfWork)) { - repository.AssignPublishedTagsToProperty( + repository.AssignTagsToProperty( content.Id, contentType.PropertyTypes.First().Alias, new[] @@ -175,7 +175,7 @@ namespace Umbraco.Tests.Persistence.Repositories new Tag {Text = "tag2", Group = "test"}, }, false); - repository.AssignPublishedTagsToProperty( + repository.AssignTagsToProperty( content.Id, contentType.PropertyTypes.First().Alias, new[] @@ -184,7 +184,7 @@ namespace Umbraco.Tests.Persistence.Repositories new Tag {Text = "tag4", Group = "test"}, }, false); - Assert.AreEqual(4, repository.GetPublishedTagsForContent(content.Id).Count()); + Assert.AreEqual(4, repository.GetTagsForEntity(content.Id).Count()); } } } @@ -207,7 +207,7 @@ namespace Umbraco.Tests.Persistence.Repositories using (var repository = CreateRepository(unitOfWork)) { - repository.AssignPublishedTagsToProperty( + repository.AssignTagsToProperty( content.Id, contentType.PropertyTypes.First().Alias, new[] @@ -216,7 +216,7 @@ namespace Umbraco.Tests.Persistence.Repositories new Tag {Text = "tag2", Group = "test"}, }, false); - repository.AssignPublishedTagsToProperty( + repository.AssignTagsToProperty( content.Id, contentType.PropertyTypes.First().Alias, new[] @@ -225,7 +225,7 @@ namespace Umbraco.Tests.Persistence.Repositories new Tag {Text = "tag4", Group = "test"}, }, true); - var result = repository.GetPublishedTagsForContent(content.Id); + var result = repository.GetTagsForEntity(content.Id); Assert.AreEqual(2, result.Count()); Assert.AreEqual("tag3", result.ElementAt(0).Text); Assert.AreEqual("tag4", result.ElementAt(1).Text); @@ -251,7 +251,7 @@ namespace Umbraco.Tests.Persistence.Repositories using (var repository = CreateRepository(unitOfWork)) { - repository.AssignPublishedTagsToProperty( + repository.AssignTagsToProperty( content.Id, contentType.PropertyTypes.First().Alias, new[] @@ -260,7 +260,7 @@ namespace Umbraco.Tests.Persistence.Repositories new Tag {Text = "tag2", Group = "test"}, }, false); - repository.AssignPublishedTagsToProperty( + repository.AssignTagsToProperty( content.Id, contentType.PropertyTypes.First().Alias, new[] @@ -269,7 +269,7 @@ namespace Umbraco.Tests.Persistence.Repositories new Tag {Text = "tag3", Group = "test"}, }, false); - var result = repository.GetPublishedTagsForContent(content.Id); + var result = repository.GetTagsForEntity(content.Id); Assert.AreEqual(3, result.Count()); } } @@ -293,7 +293,7 @@ namespace Umbraco.Tests.Persistence.Repositories using (var repository = CreateRepository(unitOfWork)) { - repository.AssignPublishedTagsToProperty( + repository.AssignTagsToProperty( content.Id, contentType.PropertyTypes.First().Alias, new[] @@ -302,12 +302,12 @@ namespace Umbraco.Tests.Persistence.Repositories new Tag {Text = "tag2", Group = "test"}, }, false); - repository.AssignPublishedTagsToProperty( + repository.AssignTagsToProperty( content.Id, contentType.PropertyTypes.First().Alias, Enumerable.Empty(), true); - var result = repository.GetPublishedTagsForContent(content.Id); + var result = repository.GetTagsForEntity(content.Id); Assert.AreEqual(0, result.Count()); } } @@ -331,7 +331,7 @@ namespace Umbraco.Tests.Persistence.Repositories using (var repository = CreateRepository(unitOfWork)) { - repository.AssignPublishedTagsToProperty( + repository.AssignTagsToProperty( content.Id, contentType.PropertyTypes.First().Alias, new[] @@ -342,7 +342,7 @@ namespace Umbraco.Tests.Persistence.Repositories new Tag {Text = "tag4", Group = "test"} }, false); - repository.RemovePublishedTagsFromProperty( + repository.RemoveTagsFromProperty( content.Id, contentType.PropertyTypes.First().Alias, new[] @@ -351,7 +351,7 @@ namespace Umbraco.Tests.Persistence.Repositories new Tag {Text = "tag3", Group = "test"} }); - var result = repository.GetPublishedTagsForContent(content.Id); + var result = repository.GetTagsForEntity(content.Id); Assert.AreEqual(2, result.Count()); Assert.AreEqual("tag1", result.ElementAt(0).Text); Assert.AreEqual("tag4", result.ElementAt(1).Text); @@ -379,7 +379,7 @@ namespace Umbraco.Tests.Persistence.Repositories using (var repository = CreateRepository(unitOfWork)) { - repository.AssignPublishedTagsToProperty( + repository.AssignTagsToProperty( content1.Id, contentType.PropertyTypes.First().Alias, new[] @@ -390,7 +390,7 @@ namespace Umbraco.Tests.Persistence.Repositories new Tag {Text = "tag4", Group = "test"} }, false); - repository.AssignPublishedTagsToProperty( + repository.AssignTagsToProperty( content2.Id, contentType.PropertyTypes.First().Alias, new[] @@ -399,7 +399,53 @@ namespace Umbraco.Tests.Persistence.Repositories new Tag {Text = "tag2", Group = "test"} }, false); - var result = repository.GetPublishedTagsForContent(content2.Id); + var result = repository.GetTagsForEntity(content2.Id); + Assert.AreEqual(2, result.Count()); + } + } + } + + [Test] + public void Can_Get_Tags_For_Content_For_Group() + { + var provider = new PetaPocoUnitOfWorkProvider(); + var unitOfWork = provider.GetUnitOfWork(); + ContentTypeRepository contentTypeRepository; + using (var contentRepository = CreateContentRepository(unitOfWork, out contentTypeRepository)) + { + //create data to relate to + var contentType = MockedContentTypes.CreateSimpleContentType("test", "Test"); + contentTypeRepository.AddOrUpdate(contentType); + unitOfWork.Commit(); + var content1 = MockedContent.CreateSimpleContent(contentType); + contentRepository.AddOrUpdate(content1); + var content2 = MockedContent.CreateSimpleContent(contentType); + contentRepository.AddOrUpdate(content2); + unitOfWork.Commit(); + + using (var repository = CreateRepository(unitOfWork)) + { + repository.AssignTagsToProperty( + content1.Id, + contentType.PropertyTypes.First().Alias, + new[] + { + new Tag {Text = "tag1", Group = "test"}, + new Tag {Text = "tag2", Group = "test1"}, + new Tag {Text = "tag3", Group = "test"}, + new Tag {Text = "tag4", Group = "test1"} + }, false); + + repository.AssignTagsToProperty( + content2.Id, + contentType.PropertyTypes.First().Alias, + new[] + { + new Tag {Text = "tag1", Group = "test"}, + new Tag {Text = "tag2", Group = "test"} + }, false); + + var result = repository.GetTagsForEntity(content1.Id, "test1"); Assert.AreEqual(2, result.Count()); } } @@ -423,7 +469,7 @@ namespace Umbraco.Tests.Persistence.Repositories using (var repository = CreateRepository(unitOfWork)) { - repository.AssignPublishedTagsToProperty( + repository.AssignTagsToProperty( content1.Id, contentType.PropertyTypes.First().Alias, new[] @@ -434,7 +480,7 @@ namespace Umbraco.Tests.Persistence.Repositories new Tag {Text = "tag4", Group = "test"} }, false); - repository.AssignPublishedTagsToProperty( + repository.AssignTagsToProperty( content1.Id, contentType.PropertyTypes.Last().Alias, new[] @@ -443,14 +489,177 @@ namespace Umbraco.Tests.Persistence.Repositories new Tag {Text = "tag2", Group = "test"} }, false); - var result1 = repository.GetPublishedTagsForProperty(content1.Id, contentType.PropertyTypes.First().Alias).ToArray(); - var result2 = repository.GetPublishedTagsForProperty(content1.Id, contentType.PropertyTypes.Last().Alias).ToArray(); + var result1 = repository.GetTagsForProperty(content1.Id, contentType.PropertyTypes.First().Alias).ToArray(); + var result2 = repository.GetTagsForProperty(content1.Id, contentType.PropertyTypes.Last().Alias).ToArray(); + Assert.AreEqual(4, result1.Count()); Assert.AreEqual(2, result2.Count()); } } } + [Test] + public void Can_Get_Tags_For_Property_For_Group() + { + var provider = new PetaPocoUnitOfWorkProvider(); + var unitOfWork = provider.GetUnitOfWork(); + ContentTypeRepository contentTypeRepository; + using (var contentRepository = CreateContentRepository(unitOfWork, out contentTypeRepository)) + { + //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(); + + using (var repository = CreateRepository(unitOfWork)) + { + repository.AssignTagsToProperty( + content1.Id, + contentType.PropertyTypes.First().Alias, + new[] + { + new Tag {Text = "tag1", Group = "test"}, + new Tag {Text = "tag2", Group = "test1"}, + new Tag {Text = "tag3", Group = "test"}, + new Tag {Text = "tag4", Group = "test1"} + }, false); + + repository.AssignTagsToProperty( + content1.Id, + contentType.PropertyTypes.Last().Alias, + new[] + { + new Tag {Text = "tag1", Group = "test"}, + new Tag {Text = "tag2", Group = "test1"} + }, false); + + var result1 = repository.GetTagsForProperty(content1.Id, contentType.PropertyTypes.First().Alias, "test1").ToArray(); + var result2 = repository.GetTagsForProperty(content1.Id, contentType.PropertyTypes.Last().Alias, "test1").ToArray(); + + Assert.AreEqual(2, result1.Count()); + Assert.AreEqual(1, result2.Count()); + + } + } + + } + + [Test] + public void Can_Get_Tags_For_Entity_Type() + { + 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 mediaType = MockedContentTypes.CreateImageMediaType(); + 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().Alias, + 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().Alias, + new[] + { + new Tag {Text = "tag1", Group = "test"}, + new Tag {Text = "tag2", Group = "test1"} + }, false); + + var result1 = repository.GetTagsForEntityType(TaggableObjectTypes.Content).ToArray(); + var result2 = repository.GetTagsForEntityType(TaggableObjectTypes.Media).ToArray(); + + Assert.AreEqual(3, result1.Count()); + Assert.AreEqual(2, result2.Count()); + + } + } + + } + + [Test] + public void Can_Get_Tags_For_Entity_Type_For_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 mediaType = MockedContentTypes.CreateImageMediaType(); + 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().Alias, + new[] + { + new Tag {Text = "tag1", Group = "test"}, + new Tag {Text = "tag2", Group = "test1"}, + new Tag {Text = "tag3", Group = "test"}, + new Tag {Text = "tag4", Group = "test1"} + }, false); + + repository.AssignTagsToProperty( + media1.Id, + mediaType.PropertyTypes.Last().Alias, + new[] + { + new Tag {Text = "tag1", Group = "test"}, + new Tag {Text = "tag2", Group = "test1"} + }, false); + + var result1 = repository.GetTagsForEntityType(TaggableObjectTypes.Content, "test1").ToArray(); + var result2 = repository.GetTagsForEntityType(TaggableObjectTypes.Media, "test1").ToArray(); + + Assert.AreEqual(2, result1.Count()); + Assert.AreEqual(1, result2.Count()); + + } + } + + } + [Test] public void Cascade_Deletes_Tag_Relations() { @@ -469,7 +678,7 @@ namespace Umbraco.Tests.Persistence.Repositories using (var repository = CreateRepository(unitOfWork)) { - repository.AssignPublishedTagsToProperty( + repository.AssignTagsToProperty( content1.Id, contentType.PropertyTypes.First().Alias, new[] @@ -500,5 +709,13 @@ namespace Umbraco.Tests.Persistence.Repositories var repository = new ContentRepository(unitOfWork, NullCacheProvider.Current, contentTypeRepository, templateRepository, tagRepository); return repository; } + + private MediaRepository CreateMediaRepository(IDatabaseUnitOfWork unitOfWork, out MediaTypeRepository mediaTypeRepository) + { + var tagRepository = new TagsRepository(unitOfWork, NullCacheProvider.Current); + mediaTypeRepository = new MediaTypeRepository(unitOfWork, NullCacheProvider.Current); + var repository = new MediaRepository(unitOfWork, NullCacheProvider.Current, mediaTypeRepository, tagRepository); + return repository; + } } } \ No newline at end of file diff --git a/src/umbraco.cms/businesslogic/Tags/Tag.cs b/src/umbraco.cms/businesslogic/Tags/Tag.cs index d9a2b16898..e2cef52308 100644 --- a/src/umbraco.cms/businesslogic/Tags/Tag.cs +++ b/src/umbraco.cms/businesslogic/Tags/Tag.cs @@ -13,6 +13,7 @@ using umbraco.cms.businesslogic.web; namespace umbraco.cms.businesslogic.Tags { + [Obsolete("Use the TagService to query tags or the UmbracoHelper on the front-end and use the SetTags, RemoveTags extension methods on IContentBase to manipulate tags")] public class Tag : ITag { diff --git a/src/umbraco.editorControls/tags/library.cs b/src/umbraco.editorControls/tags/library.cs index 31bf2249a3..0f4e9afe23 100644 --- a/src/umbraco.editorControls/tags/library.cs +++ b/src/umbraco.editorControls/tags/library.cs @@ -13,11 +13,9 @@ using umbraco.interfaces; namespace umbraco.editorControls.tags { - [Obsolete("IDataType and all other references to the legacy property editors are no longer used this will be removed from the codebase in future versions")] + [Obsolete("Use the TagService to query tags or the UmbracoHelper on the front-end and use the SetTags, RemoveTags extension methods on IContentBase to manipulate tags")] public class library { - - /// /// Gets everything (content, media, members) in Umbraco with the specified tags. /// It returns the found nodes as: @@ -297,7 +295,7 @@ namespace umbraco.editorControls.tags } - [Obsolete("Use umbraco.cms.businesslogic.Tags.Tag class instead")] + [Obsolete("Use the TagService to query tags or the UmbracoHelper on the front-end and use the SetTags, RemoveTags extension methods on IContentBase to manipulate tags")] public class Tag : umbraco.interfaces.ITag { diff --git a/src/umbraco.interfaces/ITag.cs b/src/umbraco.interfaces/ITag.cs index fb31b1d4ff..e21d1c73da 100644 --- a/src/umbraco.interfaces/ITag.cs +++ b/src/umbraco.interfaces/ITag.cs @@ -1,5 +1,8 @@ +using System; + namespace umbraco.interfaces { + [Obsolete("Use the TagService to query tags or the UmbracoHelper on the front-end and use the SetTags, RemoveTags extension methods on IContentBase to manipulate tags")] public interface ITag { int Id { get; }