From a32765d653f4cf5072555a6307105effe729de3e Mon Sep 17 00:00:00 2001 From: Renaud Paquay Date: Thu, 25 Nov 2010 09:26:44 -0800 Subject: [PATCH] First step at simplifying Tags implementation --HG-- branch : dev rename : src/Orchard.Web/Modules/Orchard.Tags/Models/Tag.cs => src/Orchard.Web/Modules/Orchard.Tags/Models/TagRecord.cs --- .../Controllers/AdminController.cs | 20 ++-- .../Orchard.Tags/Drivers/TagsPartDriver.cs | 2 +- .../Orchard.Tags/Handlers/TagsPartHandler.cs | 20 ++-- .../Modules/Orchard.Tags/Migrations.cs | 2 +- .../Models/{Tag.cs => TagRecord.cs} | 2 +- .../Orchard.Tags/Models/TagsContentItems.cs | 6 +- .../Modules/Orchard.Tags/Models/TagsPart.cs | 11 +- .../Orchard.Tags/Models/TagsPartRecord.cs | 6 ++ .../Modules/Orchard.Tags/Orchard.Tags.csproj | 3 +- .../Orchard.Tags/Services/ITagService.cs | 19 ++-- .../Orchard.Tags/Services/TagService.cs | 100 +++++++++--------- .../Orchard.Tags/Services/XmlRpcHandler.cs | 2 +- .../ViewModels/TagsAdminIndexViewModel.cs | 2 +- .../ViewModels/TagsIndexViewModel.cs | 2 +- 14 files changed, 100 insertions(+), 97 deletions(-) rename src/Orchard.Web/Modules/Orchard.Tags/Models/{Tag.cs => TagRecord.cs} (79%) create mode 100644 src/Orchard.Web/Modules/Orchard.Tags/Models/TagsPartRecord.cs diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.Tags/Controllers/AdminController.cs index b1d1bb9a5..c7c1272c2 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.Tags/Controllers/AdminController.cs @@ -25,7 +25,7 @@ namespace Orchard.Tags.Controllers { public Localizer T { get; set; } public ActionResult Index() { - IEnumerable tags = _tagService.GetTags(); + IEnumerable tags = _tagService.GetTags(); var entries = tags.Select(CreateTagEntry).ToList(); var model = new TagsAdminIndexViewModel { Tags = entries }; return View(model); @@ -50,7 +50,7 @@ namespace Orchard.Tags.Controllers { return new HttpUnauthorizedResult(); foreach (TagEntry entry in checkedEntries) { - _tagService.DeleteTag(entry.Tag.Id); + _tagService.DeleteTag(entry.TagRecord.Id); } break; @@ -80,15 +80,15 @@ namespace Orchard.Tags.Controllers { } public ActionResult Edit(int id) { - Tag tag = _tagService.GetTag(id); + TagRecord tagRecord = _tagService.GetTag(id); - if(tag == null) { + if(tagRecord == null) { return RedirectToAction("Index"); } var viewModel = new TagsAdminEditViewModel { - Id = tag.Id, - TagName = tag.TagName, + Id = tagRecord.Id, + TagName = tagRecord.TagName, }; ViewData["ContentItems"] = _tagService.GetTaggedContentItems(id).ToList(); @@ -116,9 +116,9 @@ namespace Orchard.Tags.Controllers { if (!Services.Authorizer.Authorize(Permissions.ManageTags, T("Couldn't remove tag"))) return new HttpUnauthorizedResult(); - Tag tag = _tagService.GetTag(id); + TagRecord tagRecord = _tagService.GetTag(id); - if (tag == null) + if (tagRecord == null) return new HttpNotFoundResult(); _tagService.DeleteTag(id); @@ -129,9 +129,9 @@ namespace Orchard.Tags.Controllers { return RedirectToAction("Index"); } - private static TagEntry CreateTagEntry(Tag tag) { + private static TagEntry CreateTagEntry(TagRecord tagRecord) { return new TagEntry { - Tag = tag, + TagRecord = tagRecord, IsChecked = false, }; } diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Drivers/TagsPartDriver.cs b/src/Orchard.Web/Modules/Orchard.Tags/Drivers/TagsPartDriver.cs index 52a590d32..b3a4821c0 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Drivers/TagsPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.Tags/Drivers/TagsPartDriver.cs @@ -50,7 +50,7 @@ namespace Orchard.Tags.Drivers { var tagNames = TagHelpers.ParseCommaSeparatedTagNames(model.Tags); if (part.ContentItem.Id != 0) { - _tagService.UpdateTagsForContentItem(part.ContentItem.Id, tagNames); + _tagService.UpdateTagsForContentItem(part.ContentItem, tagNames); } return ContentShape("Parts_Tags_Edit", diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Handlers/TagsPartHandler.cs b/src/Orchard.Web/Modules/Orchard.Tags/Handlers/TagsPartHandler.cs index a0d470c22..855b452ae 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Handlers/TagsPartHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Tags/Handlers/TagsPartHandler.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; using Orchard.ContentManagement; @@ -10,20 +9,13 @@ using Orchard.Tags.Models; namespace Orchard.Tags.Handlers { [UsedImplicitly] public class TagsPartHandler : ContentHandler { - public TagsPartHandler(IRepository tagsRepository, IRepository tagsContentItemsRepository) { + public TagsPartHandler(IRepository tagsRepository, IRepository tagsContentItemsRepository) { OnLoading((context, tags) => { - - // provide names of all tags on demand - tags._allTags.Loader(list => tagsRepository.Table.ToList()); - // populate list of attached tags on demand tags._currentTags.Loader(list => { - var tagsContentItems = tagsContentItemsRepository.Fetch(x => x.ContentItemId == context.ContentItem.Id); - foreach (var tagContentItem in tagsContentItems) { - var tag = tagsRepository.Get(tagContentItem.TagId); - list.Add(tag); - } + foreach(var tag in tagsContentItemsRepository.Fetch(x => x.ContentItem == context.ContentItem.Record)) + list.Add(tag.Tag); return list; }); @@ -32,17 +24,17 @@ namespace Orchard.Tags.Handlers { OnRemoved((context, tags) => { tagsContentItemsRepository.Flush(); - TagsPart tagsPart = context.ContentItem.As(); + var tagsPart = context.ContentItem.As(); // delete orphan tags (for each tag, if there is no other contentItem than the one being deleted, it's an orphan) foreach ( var tag in tagsPart.CurrentTags ) { - if ( tagsContentItemsRepository.Fetch(x => x.ContentItemId != context.ContentItem.Id).Count() == 0 ) { + if ( tagsContentItemsRepository.Fetch(x => x.ContentItem != context.ContentItem.Record).Count() == 0 ) { tagsRepository.Delete(tag); } } // delete tag links with this contentItem (tagsContentItems) - foreach ( var tagsContentItem in tagsContentItemsRepository.Fetch(x => x.ContentItemId == context.ContentItem.Id) ) { + foreach ( var tagsContentItem in tagsContentItemsRepository.Fetch(x => x.ContentItem == context.ContentItem.Record) ) { tagsContentItemsRepository.Delete(tagsContentItem); } diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Migrations.cs b/src/Orchard.Web/Modules/Orchard.Tags/Migrations.cs index 7e8e93a82..30e17c923 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Migrations.cs +++ b/src/Orchard.Web/Modules/Orchard.Tags/Migrations.cs @@ -6,7 +6,7 @@ namespace Orchard.Tags { public class TagsDataMigration : DataMigrationImpl { public int Create() { - SchemaBuilder.CreateTable("Tag", + SchemaBuilder.CreateTable("TagRecord", table => table .Column("Id", column => column.PrimaryKey().Identity()) .Column("TagName") diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Models/Tag.cs b/src/Orchard.Web/Modules/Orchard.Tags/Models/TagRecord.cs similarity index 79% rename from src/Orchard.Web/Modules/Orchard.Tags/Models/Tag.cs rename to src/Orchard.Web/Modules/Orchard.Tags/Models/TagRecord.cs index d80ab9cb2..953217b2e 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Models/Tag.cs +++ b/src/Orchard.Web/Modules/Orchard.Tags/Models/TagRecord.cs @@ -1,5 +1,5 @@ namespace Orchard.Tags.Models { - public class Tag { + public class TagRecord { public virtual int Id { get; set; } public virtual string TagName { get; set; } } diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Models/TagsContentItems.cs b/src/Orchard.Web/Modules/Orchard.Tags/Models/TagsContentItems.cs index 1c1acfc39..079156744 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Models/TagsContentItems.cs +++ b/src/Orchard.Web/Modules/Orchard.Tags/Models/TagsContentItems.cs @@ -1,7 +1,9 @@ +using Orchard.ContentManagement.Records; + namespace Orchard.Tags.Models { public class TagsContentItems { public virtual int Id { get; set; } - public virtual int TagId { get; set; } - public virtual int ContentItemId { get; set; } + public virtual TagRecord Tag { get; set; } + public virtual ContentItemRecord ContentItem { get; set; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Models/TagsPart.cs b/src/Orchard.Web/Modules/Orchard.Tags/Models/TagsPart.cs index 0ece312d4..899805ade 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Models/TagsPart.cs +++ b/src/Orchard.Web/Modules/Orchard.Tags/Models/TagsPart.cs @@ -3,16 +3,13 @@ using Orchard.ContentManagement; using Orchard.ContentManagement.Utilities; namespace Orchard.Tags.Models { - public class TagsPart : ContentPart { + public class TagsPart : ContentPart { public TagsPart() { - AllTags = new List(); - CurrentTags = new List(); + CurrentTags = new List(); } - public readonly LazyField> _allTags = new LazyField>(); - public readonly LazyField> _currentTags = new LazyField>(); + public readonly LazyField> _currentTags = new LazyField>(); - public IList AllTags { get { return _allTags.Value; } set { _allTags.Value = value; } } - public IList CurrentTags { get { return _currentTags.Value; } set { _currentTags.Value = value; } } + public IList CurrentTags { get { return _currentTags.Value; } set { _currentTags.Value = value; } } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Models/TagsPartRecord.cs b/src/Orchard.Web/Modules/Orchard.Tags/Models/TagsPartRecord.cs new file mode 100644 index 000000000..ba36eb2de --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Tags/Models/TagsPartRecord.cs @@ -0,0 +1,6 @@ +using Orchard.ContentManagement.Records; + +namespace Orchard.Tags.Models { + public class TagsPartRecord : ContentPartRecord { + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Orchard.Tags.csproj b/src/Orchard.Web/Modules/Orchard.Tags/Orchard.Tags.csproj index f2a81d580..58783065e 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Orchard.Tags.csproj +++ b/src/Orchard.Web/Modules/Orchard.Tags/Orchard.Tags.csproj @@ -55,6 +55,7 @@ + @@ -63,7 +64,7 @@ - + diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Services/ITagService.cs b/src/Orchard.Web/Modules/Orchard.Tags/Services/ITagService.cs index f4ae69dc7..47512c66a 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Services/ITagService.cs +++ b/src/Orchard.Web/Modules/Orchard.Tags/Services/ITagService.cs @@ -4,14 +4,17 @@ using Orchard.Tags.Models; namespace Orchard.Tags.Services { public interface ITagService : IDependency { - IEnumerable GetTags(); - Tag GetTag(int id); - Tag GetTagByName(string tagName); + IEnumerable GetTags(); + TagRecord GetTag(int tagId); + TagRecord GetTagByName(string tagName); + IEnumerable GetTaggedContentItems(int tagId); + void CreateTag(string tagName); - void DeleteTag(int id); - void UpdateTag(int id, string tagName); - IEnumerable GetTaggedContentItems(int id); - void TagContentItem(int contentItemId, string tagName); - void UpdateTagsForContentItem(int contentItemId, IEnumerable tagNamesForContentItem); + + void DeleteTag(int tagId); + + void UpdateTag(int tagId, string tagName); + + void UpdateTagsForContentItem(ContentItem contentItem, IEnumerable tagNamesForContentItem); } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Services/TagService.cs b/src/Orchard.Web/Modules/Orchard.Tags/Services/TagService.cs index e5e530119..13768b5b5 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Services/TagService.cs +++ b/src/Orchard.Web/Modules/Orchard.Tags/Services/TagService.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; +using Orchard.ContentManagement.Records; using Orchard.Data; using Orchard.Localization; using Orchard.Logging; @@ -13,13 +14,13 @@ using Orchard.UI.Notify; namespace Orchard.Tags.Services { [UsedImplicitly] public class TagService : ITagService { - private readonly IRepository _tagRepository; + private readonly IRepository _tagRepository; private readonly IRepository _tagsContentItemsRepository; private readonly INotifier _notifier; private readonly IAuthorizationService _authorizationService; private readonly IOrchardServices _orchardServices; - public TagService(IRepository tagRepository, + public TagService(IRepository tagRepository, IRepository tagsContentItemsRepository, INotifier notifier, IAuthorizationService authorizationService, @@ -36,15 +37,15 @@ namespace Orchard.Tags.Services { public ILogger Logger { get; set; } public Localizer T { get; set; } - public IEnumerable GetTags() { + public IEnumerable GetTags() { return _tagRepository.Table.ToList(); } - public Tag GetTag(int id) { - return _tagRepository.Get(x => x.Id == id); + public TagRecord GetTag(int tagId) { + return _tagRepository.Get(x => x.Id == tagId); } - public Tag GetTagByName(string tagName) { + public TagRecord GetTagByName(string tagName) { return _tagRepository.Get(x => x.TagName == tagName); } @@ -52,97 +53,98 @@ namespace Orchard.Tags.Services { if (_tagRepository.Get(x => x.TagName == tagName) == null) { _authorizationService.CheckAccess(Permissions.CreateTag, _orchardServices.WorkContext.CurrentUser, null); - Tag tag = new Tag { TagName = tagName }; - _tagRepository.Create(tag); + TagRecord tagRecord = new TagRecord { TagName = tagName }; + _tagRepository.Create(tagRecord); } else { _notifier.Warning(T("The tag {0} already exists", tagName)); } } - public void DeleteTag(int id) { - _tagRepository.Delete(GetTag(id)); - IEnumerable tagsContentItems = _tagsContentItemsRepository.Fetch(x => x.TagId == id); + public void DeleteTag(int tagId) { + _tagRepository.Delete(GetTag(tagId)); + IEnumerable tagsContentItems = _tagsContentItemsRepository.Fetch(x => x.Tag.Id == tagId); foreach (var tagContentItem in tagsContentItems) { _tagsContentItemsRepository.Delete(tagContentItem); } } - public void UpdateTag(int id, string tagName) { - if ( String.IsNullOrEmpty(tagName) ) { + public void UpdateTag(int tagId, string tagName) { + if (String.IsNullOrEmpty(tagName)) { _notifier.Warning(T("Couldn't rename tag: name was empty")); return; } - Tag tag = GetTagByName(tagName); - if(tag != null) { - // new tag name already existing => merge - IEnumerable tagsContentItems = _tagsContentItemsRepository.Fetch(x => x.TagId == id); - - // get contentItems already tagged with the existing one - var taggedContentItems = GetTaggedContentItems(tag.Id); + var tagRecord = GetTagByName(tagName); - foreach ( var tagContentItem in tagsContentItems ) { - var tagContentItemId = tagContentItem.ContentItemId; - if ( !taggedContentItems.Any(c => c.ContentItem.Id == tagContentItemId) ) { - TagContentItem(tagContentItem.ContentItemId, tagName); + // new tag name already existing => merge + if (tagRecord != null) { + var tagsContentItems = _tagsContentItemsRepository.Fetch(x => x.Tag.Id == tagId); + + // get contentItems already tagged with the existing one + var taggedContentItems = GetTaggedContentItems(tagRecord.Id); + + foreach (var tagContentItem in tagsContentItems) { + if (!taggedContentItems.Any(c => c.ContentItem.Record == tagContentItem.ContentItem)) { + TagContentItem(tagContentItem.ContentItem, tagName); } _tagsContentItemsRepository.Delete(tagContentItem); } - _tagRepository.Delete(GetTag(id)); - } - else { - tag = _tagRepository.Get(id); - tag.TagName = tagName; + _tagRepository.Delete(GetTag(tagId)); + return; } + + // Create new tag + tagRecord = _tagRepository.Get(tagId); + tagRecord.TagName = tagName; } - public IEnumerable GetTaggedContentItems(int id) { + public IEnumerable GetTaggedContentItems(int tagId) { return _tagsContentItemsRepository - .Fetch(x => x.TagId == id) - .Select(t =>_orchardServices.ContentManager.Get(t.ContentItemId)) - .Where(c => c!= null); + .Fetch(x => x.Tag.Id == tagId) + .Select(t => _orchardServices.ContentManager.Get(t.ContentItem.Id)) + .Where(c => c != null); } - public void TagContentItem(int contentItemId, string tagName) { - Tag tag = GetTagByName(tagName); - TagsContentItems tagsContentItems = new TagsContentItems { ContentItemId = contentItemId, TagId = tag.Id }; + private void TagContentItem(ContentItemRecord contentItem, string tagName) { + var tagRecord = GetTagByName(tagName); + var tagsContentItems = new TagsContentItems { ContentItem = contentItem, Tag = tagRecord }; _tagsContentItemsRepository.Create(tagsContentItems); } - public void UpdateTagsForContentItem(int contentItemId, IEnumerable tagNamesForContentItem) { - List tags = new List(); + public void UpdateTagsForContentItem(ContentItem contentItem, IEnumerable tagNamesForContentItem) { + var tags = new List(); foreach (var tagName in tagNamesForContentItem) { - Tag tag = GetTagByName(tagName); - if (tag == null) { + TagRecord tagRecord = GetTagByName(tagName); + if (tagRecord == null) { CreateTag(tagName); - tag = GetTagByName(tagName); + tagRecord = GetTagByName(tagName); } - tags.Add(tag.Id); + tags.Add(tagRecord); } - ModifyTagsForContentItem(contentItemId, tags); + ModifyTagsForContentItem(contentItem, tags); } - private void ModifyTagsForContentItem(int contentItemId, IEnumerable tagsForContentItem) { - List newTagsForContentItem = new List(tagsForContentItem); - IEnumerable currentTagsForContentItem = _tagsContentItemsRepository.Fetch(x => x.ContentItemId == contentItemId); + private void ModifyTagsForContentItem(ContentItem contentItem, IEnumerable tagsForContentItem) { + var newTagsForContentItem = new List(tagsForContentItem); + var currentTagsForContentItem = _tagsContentItemsRepository.Fetch(x => x.ContentItem == contentItem.Record); foreach (var tagContentItem in currentTagsForContentItem) { - if (!newTagsForContentItem.Contains(tagContentItem.TagId)) { + if (!newTagsForContentItem.Contains(tagContentItem.Tag)) { _authorizationService.CheckAccess(Permissions.ApplyTag, _orchardServices.WorkContext.CurrentUser, null); _tagsContentItemsRepository.Delete(tagContentItem); } else { - newTagsForContentItem.Remove(tagContentItem.TagId); + newTagsForContentItem.Remove(tagContentItem.Tag); } } foreach (var newTagForContentItem in newTagsForContentItem) { _authorizationService.CheckAccess(Permissions.ApplyTag, _orchardServices.WorkContext.CurrentUser, null); - _tagsContentItemsRepository.Create(new TagsContentItems { ContentItemId = contentItemId, TagId = newTagForContentItem }); + _tagsContentItemsRepository.Create(new TagsContentItems { ContentItem = contentItem.Record, Tag = newTagForContentItem }); } } } diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Services/XmlRpcHandler.cs b/src/Orchard.Web/Modules/Orchard.Tags/Services/XmlRpcHandler.cs index c6262a6b2..2654e623c 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Services/XmlRpcHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Tags/Services/XmlRpcHandler.cs @@ -158,7 +158,7 @@ namespace Orchard.Tags.Services { return; _orchardServices.WorkContext.CurrentUser = user; - _tagService.UpdateTagsForContentItem(id, tags); + _tagService.UpdateTagsForContentItem(contentItem, tags); }); if (contentItemId > 0) diff --git a/src/Orchard.Web/Modules/Orchard.Tags/ViewModels/TagsAdminIndexViewModel.cs b/src/Orchard.Web/Modules/Orchard.Tags/ViewModels/TagsAdminIndexViewModel.cs index 919854cca..39b836846 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/ViewModels/TagsAdminIndexViewModel.cs +++ b/src/Orchard.Web/Modules/Orchard.Tags/ViewModels/TagsAdminIndexViewModel.cs @@ -8,7 +8,7 @@ namespace Orchard.Tags.ViewModels { } public class TagEntry { - public Tag Tag { get; set; } + public TagRecord TagRecord { get; set; } public bool IsChecked { get; set; } } diff --git a/src/Orchard.Web/Modules/Orchard.Tags/ViewModels/TagsIndexViewModel.cs b/src/Orchard.Web/Modules/Orchard.Tags/ViewModels/TagsIndexViewModel.cs index 900cae3a7..81f832149 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/ViewModels/TagsIndexViewModel.cs +++ b/src/Orchard.Web/Modules/Orchard.Tags/ViewModels/TagsIndexViewModel.cs @@ -3,6 +3,6 @@ using Orchard.Tags.Models; namespace Orchard.Tags.ViewModels { public class TagsIndexViewModel { - public IList Tags { get; set; } + public IList Tags { get; set; } } }