diff --git a/src/Umbraco.Core/Models/ContentExtensions.cs b/src/Umbraco.Core/Models/ContentExtensions.cs index fed9de16ea..0c4cc70c46 100644 --- a/src/Umbraco.Core/Models/ContentExtensions.cs +++ b/src/Umbraco.Core/Models/ContentExtensions.cs @@ -537,7 +537,7 @@ namespace Umbraco.Core.Models /// True to replace the tags on the current property with the tags specified or false to merge them with the currently assigned ones /// The group/category to assign the tags, the default value is "default" /// - public static void SetTags(this IContent content, string propertyTypeAlias, IEnumerable tags, bool replaceTags, string tagGroup = "default") + public static void SetTags(this IContentBase content, string propertyTypeAlias, IEnumerable tags, bool replaceTags, string tagGroup = "default") { var property = content.Properties[propertyTypeAlias]; if (property == null) @@ -572,7 +572,7 @@ namespace Umbraco.Core.Models /// /// /// The group/category that the tags are currently assigned to, the default value is "default" - public static void RemoveTags(this IContent content, string propertyTypeAlias, IEnumerable tags, string tagGroup = "default") + public static void RemoveTags(this IContentBase content, string propertyTypeAlias, IEnumerable tags, string tagGroup = "default") { var property = content.Properties[propertyTypeAlias]; if (property == null) diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs index ab52e1fa53..99667a779e 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs @@ -28,6 +28,9 @@ namespace Umbraco.Core.Persistence.Repositories public ContentRepository(IDatabaseUnitOfWork work, IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository, ITagsRepository tagRepository) : base(work) { + if (contentTypeRepository == null) throw new ArgumentNullException("contentTypeRepository"); + if (templateRepository == null) throw new ArgumentNullException("templateRepository"); + if (tagRepository == null) throw new ArgumentNullException("tagRepository"); _contentTypeRepository = contentTypeRepository; _templateRepository = templateRepository; _tagRepository = tagRepository; @@ -38,6 +41,9 @@ namespace Umbraco.Core.Persistence.Repositories public ContentRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache, IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository, ITagsRepository tagRepository) : base(work, cache) { + if (contentTypeRepository == null) throw new ArgumentNullException("contentTypeRepository"); + if (templateRepository == null) throw new ArgumentNullException("templateRepository"); + if (tagRepository == null) throw new ArgumentNullException("tagRepository"); _contentTypeRepository = contentTypeRepository; _templateRepository = templateRepository; _tagRepository = tagRepository; diff --git a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs index bfa22429dd..b2d2b38cd8 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs @@ -20,19 +20,26 @@ namespace Umbraco.Core.Persistence.Repositories internal class MediaRepository : VersionableRepositoryBase, IMediaRepository { private readonly IMediaTypeRepository _mediaTypeRepository; + private readonly ITagsRepository _tagRepository; - public MediaRepository(IDatabaseUnitOfWork work, IMediaTypeRepository mediaTypeRepository) + public MediaRepository(IDatabaseUnitOfWork work, IMediaTypeRepository mediaTypeRepository, ITagsRepository tagRepository) : base(work) { + if (mediaTypeRepository == null) throw new ArgumentNullException("mediaTypeRepository"); + if (tagRepository == null) throw new ArgumentNullException("tagRepository"); _mediaTypeRepository = mediaTypeRepository; + _tagRepository = tagRepository; EnsureUniqueNaming = true; } - public MediaRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache, IMediaTypeRepository mediaTypeRepository) + public MediaRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache, IMediaTypeRepository mediaTypeRepository, ITagsRepository tagRepository) : base(work, cache) { + if (mediaTypeRepository == null) throw new ArgumentNullException("mediaTypeRepository"); + if (tagRepository == null) throw new ArgumentNullException("tagRepository"); _mediaTypeRepository = mediaTypeRepository; + _tagRepository = tagRepository; EnsureUniqueNaming = true; } @@ -247,6 +254,8 @@ namespace Umbraco.Core.Persistence.Repositories property.Id = keyDictionary[property.PropertyTypeId]; } + UpdatePropertyTags(entity); + ((ICanBeDirty)entity).ResetDirtyProperties(); } @@ -324,6 +333,8 @@ namespace Umbraco.Core.Persistence.Repositories } } + UpdatePropertyTags(entity); + ((ICanBeDirty)entity).ResetDirtyProperties(); } @@ -359,6 +370,34 @@ namespace Umbraco.Core.Persistence.Repositories #endregion + /// + /// Updates the tag repository with any tag enabled properties and their values + /// + /// + private void UpdatePropertyTags(IContentBase entity) + { + foreach (var tagProp in entity.Properties.Where(x => x.TagSupport.Enable)) + { + if (tagProp.TagSupport.Behavior == PropertyTagBehavior.Remove) + { + //remove the specific tags + _tagRepository.RemovePublishedTagsFromProperty( + entity.Id, + tagProp.Alias, + tagProp.TagSupport.Tags.Select(x => new Tag { Text = x.Item1, Group = x.Item2 })); + } + else + { + //assign the tags + _tagRepository.AssignPublishedTagsToProperty( + entity.Id, + tagProp.Alias, + tagProp.TagSupport.Tags.Select(x => new Tag { Text = x.Item1, Group = x.Item2 }), + tagProp.TagSupport.Behavior == PropertyTagBehavior.Replace); + } + } + } + private PropertyCollection GetPropertyCollection(int id, Guid versionId, IMediaType contentType, DateTime createDate, DateTime updateDate) { var sql = new Sql(); diff --git a/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs index 6425c9f566..b97227d783 100644 --- a/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs +++ b/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs @@ -27,7 +27,9 @@ namespace Umbraco.Core.Persistence.Repositories internal RepositoryBase(IUnitOfWork work, IRepositoryCacheProvider cache) { - _work = work; + if (work == null) throw new ArgumentNullException("work"); + if (cache == null) throw new ArgumentNullException("cache"); + _work = work; _cache = cache; } diff --git a/src/Umbraco.Core/Persistence/RepositoryFactory.cs b/src/Umbraco.Core/Persistence/RepositoryFactory.cs index 525274b5f4..c4e71ac711 100644 --- a/src/Umbraco.Core/Persistence/RepositoryFactory.cs +++ b/src/Umbraco.Core/Persistence/RepositoryFactory.cs @@ -85,7 +85,8 @@ namespace Umbraco.Core.Persistence return new MediaRepository( uow, _disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : RuntimeCacheProvider.Current, - CreateMediaTypeRepository(uow)) { EnsureUniqueNaming = _settings.Content.EnsureUniqueNaming }; + CreateMediaTypeRepository(uow), + CreateTagsRepository(uow)) { EnsureUniqueNaming = _settings.Content.EnsureUniqueNaming }; } public virtual IMediaTypeRepository CreateMediaTypeRepository(IDatabaseUnitOfWork uow) diff --git a/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs index 28d89f4baf..a038965ce2 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs @@ -30,7 +30,8 @@ namespace Umbraco.Tests.Persistence.Repositories private MediaRepository CreateRepository(IDatabaseUnitOfWork unitOfWork, out MediaTypeRepository mediaTypeRepository) { mediaTypeRepository = new MediaTypeRepository(unitOfWork, NullCacheProvider.Current); - var repository = new MediaRepository(unitOfWork, NullCacheProvider.Current, mediaTypeRepository); + var tagRepository = new TagsRepository(unitOfWork, NullCacheProvider.Current); + var repository = new MediaRepository(unitOfWork, NullCacheProvider.Current, mediaTypeRepository, tagRepository); return repository; } diff --git a/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs index 8c1f18705e..cbf7bb7247 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs @@ -451,6 +451,47 @@ namespace Umbraco.Tests.Persistence.Repositories } + [Test] + public void Cascade_Deletes_Tag_Relations() + { + 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.AssignPublishedTagsToProperty( + content1.Id, + contentType.PropertyTypes.First().Alias, + new[] + { + new Tag {Text = "tag1", Group = "test"}, + new Tag {Text = "tag2", Group = "test"}, + new Tag {Text = "tag3", Group = "test"}, + new Tag {Text = "tag4", Group = "test"} + }, false); + + contentRepository.Delete(content1); + + unitOfWork.Commit(); + + Assert.AreEqual(0, DatabaseContext.Database.ExecuteScalar( + "SELECT COUNT(*) FROM cmsTagRelationship WHERE nodeId=@nodeId AND propertyTypeId=@propTypeId", + new { nodeId = content1.Id, propTypeId = contentType.PropertyTypes.First().Id })); + } + } + + } + private ContentRepository CreateContentRepository(IDatabaseUnitOfWork unitOfWork, out ContentTypeRepository contentTypeRepository) { var templateRepository = new TemplateRepository(unitOfWork, NullCacheProvider.Current);