mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 03:25:23 +08:00
Cleaning up tag persistance layer (ITagService)
Also added unit tests --HG-- branch : dev rename : src/Orchard.Web/Modules/Orchard.Tags/Models/TagsContentItems.cs => src/Orchard.Web/Modules/Orchard.Tags/Models/ContentTagRecord.cs
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Autofac;
|
||||
@@ -64,8 +65,10 @@ namespace Orchard.Tests.Modules {
|
||||
}
|
||||
|
||||
protected void ClearSession() {
|
||||
Trace.WriteLine("Flush and clear session");
|
||||
_session.Flush();
|
||||
_session.Clear();
|
||||
Trace.WriteLine("Flushed and cleared session");
|
||||
}
|
||||
}
|
||||
}
|
@@ -146,6 +146,7 @@
|
||||
<Compile Include="Migrations\SchemaCommandGeneratorTests.cs" />
|
||||
<Compile Include="Scripting\ScriptingTests.cs" />
|
||||
<Compile Include="Settings\Blueprint\ShellDescriptorManagerTests.cs" />
|
||||
<Compile Include="Tags\Services\TagsServiceTests.cs" />
|
||||
<Compile Include="Themes\Services\ThemeServiceTests.cs" />
|
||||
<Compile Include="Values.cs" />
|
||||
<Compile Include="Users\Controllers\AdminControllerTests.cs" />
|
||||
@@ -199,6 +200,10 @@
|
||||
<Project>{8C7FCBC2-E6E1-405E-BFB5-D8D9E67A09C4}</Project>
|
||||
<Name>Orchard.Setup</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Orchard.Web\Modules\Orchard.Tags\Orchard.Tags.csproj">
|
||||
<Project>{5D0F00F0-26C9-4785-AD61-B85710C60EB0}</Project>
|
||||
<Name>Orchard.Tags</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Orchard.Web\Modules\Orchard.Themes\Orchard.Themes.csproj">
|
||||
<Project>{CDE24A24-01D3-403C-84B9-37722E18DFB7}</Project>
|
||||
<Name>Orchard.Themes</Name>
|
||||
|
260
src/Orchard.Tests.Modules/Tags/Services/TagsServiceTests.cs
Normal file
260
src/Orchard.Tests.Modules/Tags/Services/TagsServiceTests.cs
Normal file
@@ -0,0 +1,260 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using Autofac;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.ContentManagement.Records;
|
||||
using Orchard.Data;
|
||||
using Orchard.Environment;
|
||||
using Orchard.Security;
|
||||
using Orchard.Tags.Handlers;
|
||||
using Orchard.Tags.Models;
|
||||
using Orchard.Tags.Services;
|
||||
using Orchard.Tests.Stubs;
|
||||
using Orchard.Tests.Utility;
|
||||
using Orchard.UI.Notify;
|
||||
|
||||
namespace Orchard.Tests.Modules.Tags.Services {
|
||||
[TestFixture]
|
||||
public class TagsServiceTests : DatabaseEnabledTestsBase {
|
||||
private Mock<IAuthorizationService> _authz;
|
||||
private ITagService _tagService;
|
||||
private IContentManager _contentManager;
|
||||
|
||||
public override void Register(ContainerBuilder builder) {
|
||||
_authz = new Mock<IAuthorizationService>();
|
||||
|
||||
builder.RegisterAutoMocking(MockBehavior.Loose);
|
||||
builder.RegisterInstance(_authz.Object).As<IAuthorizationService>();
|
||||
builder.RegisterType<StubWorkContextAccessor>().As<IWorkContextAccessor>();
|
||||
builder.RegisterType<TagService>().As<ITagService>();
|
||||
builder.RegisterType<Notifier>().As<INotifier>();
|
||||
builder.RegisterType<ThingHandler>().As<IContentHandler>();
|
||||
builder.RegisterType<TagsPartHandler>().As<IContentHandler>();
|
||||
builder.RegisterType<OrchardServices>().As<IOrchardServices>();
|
||||
builder.RegisterType<DefaultContentManager>().As<IContentManager>();
|
||||
builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>));
|
||||
}
|
||||
|
||||
public override void Init() {
|
||||
base.Init();
|
||||
|
||||
_tagService = _container.Resolve<ITagService>();
|
||||
_contentManager = _container.Resolve<IContentManager>();
|
||||
}
|
||||
|
||||
|
||||
protected override IEnumerable<Type> DatabaseTypes {
|
||||
get {
|
||||
return new[] {
|
||||
typeof(ContentItemRecord),
|
||||
typeof(ContentItemVersionRecord),
|
||||
typeof(ContentTypeRecord),
|
||||
typeof(TagsPartRecord),
|
||||
typeof(TagRecord),
|
||||
typeof(ContentTagRecord)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TagServiceShouldResolve() {
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreateTagShouldBePersistent() {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
_tagService.CreateTag("tag" + i);
|
||||
}
|
||||
|
||||
ClearSession();
|
||||
|
||||
var tag5 = _tagService.GetTagByName("tag5");
|
||||
Assert.That(tag5, Is.Not.Null);
|
||||
Assert.That(tag5.TagName, Is.EqualTo("tag5"));
|
||||
|
||||
var tag50 = _tagService.GetTagByName("tag50");
|
||||
Assert.That(tag50, Is.Null);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void TagsShouldBeAvailableWhenGettingContentItem() {
|
||||
var thing = _contentManager.New("thing");
|
||||
_contentManager.Create(thing);
|
||||
_tagService.UpdateTagsForContentItem(thing, new string[] { "tag1", "tag2", "tag3" });
|
||||
|
||||
ClearSession();
|
||||
|
||||
var thing2 = _contentManager.Get(thing.Id);
|
||||
Assert.That(thing2.As<TagsPart>().CurrentTags.Any(tagRecord => tagRecord.TagName == "tag1"), Is.True);
|
||||
Assert.That(thing2.As<TagsPart>().CurrentTags.Any(tagRecord => tagRecord.TagName == "tag2"), Is.True);
|
||||
Assert.That(thing2.As<TagsPart>().CurrentTags.Any(tagRecord => tagRecord.TagName == "tag3"), Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ContentItemsShouldBeReturnedFromTagService() {
|
||||
var thing1 = _contentManager.New("thing");
|
||||
_contentManager.Create(thing1);
|
||||
_tagService.UpdateTagsForContentItem(thing1, new string[] { "tag1", "tag2", "tag3" });
|
||||
|
||||
var thing2 = _contentManager.New("thing");
|
||||
_contentManager.Create(thing2);
|
||||
_tagService.UpdateTagsForContentItem(thing2, new string[] { "tag4", "tag3" });
|
||||
|
||||
ClearSession();
|
||||
|
||||
Assert.That(_tagService.GetTaggedContentItems(25), Is.Empty);
|
||||
|
||||
Assert.That(_tagService.GetTaggedContentItems(_tagService.GetTagByName("tag1").Id).Count(), Is.EqualTo(1));
|
||||
Assert.That(_tagService.GetTaggedContentItems(_tagService.GetTagByName("tag1").Id).Any(c => c.Id == thing1.Id), Is.True);
|
||||
|
||||
Assert.That(_tagService.GetTaggedContentItems(_tagService.GetTagByName("tag2").Id).Count(), Is.EqualTo(1));
|
||||
Assert.That(_tagService.GetTaggedContentItems(_tagService.GetTagByName("tag2").Id).Any(c => c.Id == thing1.Id), Is.True);
|
||||
|
||||
Assert.That(_tagService.GetTaggedContentItems(_tagService.GetTagByName("tag3").Id).Count(), Is.EqualTo(2));
|
||||
Assert.That(_tagService.GetTaggedContentItems(_tagService.GetTagByName("tag3").Id).Any(c => c.Id == thing1.Id), Is.True);
|
||||
Assert.That(_tagService.GetTaggedContentItems(_tagService.GetTagByName("tag3").Id).Any(c => c.Id == thing2.Id), Is.True);
|
||||
|
||||
Assert.That(_tagService.GetTaggedContentItems(_tagService.GetTagByName("tag4").Id).Count(), Is.EqualTo(1));
|
||||
Assert.That(_tagService.GetTaggedContentItems(_tagService.GetTagByName("tag4").Id).Any(c => c.Id == thing2.Id), Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TagsDeletionShouldDeleteTagsAndAssociations() {
|
||||
var thing1 = _contentManager.New("thing");
|
||||
_contentManager.Create(thing1);
|
||||
_tagService.UpdateTagsForContentItem(thing1, new string[] {"tag1", "tag2", "tag3"});
|
||||
|
||||
var thing2 = _contentManager.New("thing");
|
||||
_contentManager.Create(thing2);
|
||||
_tagService.UpdateTagsForContentItem(thing2, new string[] {"tag2", "tag3", "tag4"});
|
||||
|
||||
ClearSession();
|
||||
|
||||
Trace.WriteLine(string.Format("Delete tag \"{0}\"", "tag1"));
|
||||
_tagService.DeleteTag(_tagService.GetTagByName("tag1").Id);
|
||||
ClearSession();
|
||||
|
||||
Assert.That(_tagService.GetTagByName("tag1"), Is.Null);
|
||||
|
||||
var test = _contentManager.Get(thing1.Id);
|
||||
Assert.That(test.As<TagsPart>().Record.Tags.Count, Is.EqualTo(2));
|
||||
Assert.That(test.As<TagsPart>().Record.Tags.Any(t => t.TagRecord.TagName == "tag2"), Is.True);
|
||||
Assert.That(test.As<TagsPart>().Record.Tags.Any(t => t.TagRecord.TagName == "tag3"), Is.True);
|
||||
|
||||
|
||||
Trace.WriteLine(string.Format("Delete tag \"{0}\"", "tag2"));
|
||||
_tagService.DeleteTag(_tagService.GetTagByName("tag2").Id);
|
||||
ClearSession();
|
||||
|
||||
Assert.That(_tagService.GetTagByName("tag2"), Is.Null);
|
||||
|
||||
test = _contentManager.Get(thing1.Id);
|
||||
Assert.That(test.As<TagsPart>().Record.Tags.Count, Is.EqualTo(1));
|
||||
Assert.That(test.As<TagsPart>().Record.Tags.Any(t => t.TagRecord.TagName == "tag3"), Is.True);
|
||||
|
||||
test = _contentManager.Get(thing2.Id);
|
||||
Assert.That(test.As<TagsPart>().Record.Tags.Count, Is.EqualTo(2));
|
||||
Assert.That(test.As<TagsPart>().Record.Tags.Any(t => t.TagRecord.TagName == "tag3"), Is.True);
|
||||
Assert.That(test.As<TagsPart>().Record.Tags.Any(t => t.TagRecord.TagName == "tag4"), Is.True);
|
||||
|
||||
Trace.WriteLine(string.Format("Delete tag \"{0}\"", "tag3"));
|
||||
_tagService.DeleteTag(_tagService.GetTagByName("tag3").Id);
|
||||
|
||||
Trace.WriteLine(string.Format("Delete tag \"{0}\"", "tag4"));
|
||||
_tagService.DeleteTag(_tagService.GetTagByName("tag4").Id);
|
||||
ClearSession();
|
||||
|
||||
Assert.That(_tagService.GetTags(), Is.Empty);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void TagsAssociationsShouldBeCreatedCorrectly() {
|
||||
var thing1 = _contentManager.New("thing");
|
||||
_contentManager.Create(thing1);
|
||||
_tagService.UpdateTagsForContentItem(thing1, new string[] { "tag1", "tag2", "tag3" });
|
||||
|
||||
var thing2 = _contentManager.New("thing");
|
||||
_contentManager.Create(thing2);
|
||||
_tagService.UpdateTagsForContentItem(thing2, new string[] { "tag2", "tag3", "tag4" });
|
||||
|
||||
ClearSession();
|
||||
|
||||
var test = _contentManager.Get(thing1.Id);
|
||||
Assert.That(test.As<TagsPart>().Record.Tags.Count, Is.EqualTo(3));
|
||||
Assert.That(test.As<TagsPart>().Record.Tags.Any(t => t.TagRecord.TagName == "tag1"), Is.True);
|
||||
Assert.That(test.As<TagsPart>().Record.Tags.Any(t => t.TagRecord.TagName == "tag2"), Is.True);
|
||||
Assert.That(test.As<TagsPart>().Record.Tags.Any(t => t.TagRecord.TagName == "tag3"), Is.True);
|
||||
|
||||
test = _contentManager.Get(thing2.Id);
|
||||
Assert.That(test.As<TagsPart>().Record.Tags.Count, Is.EqualTo(3));
|
||||
Assert.That(test.As<TagsPart>().Record.Tags.Any(t => t.TagRecord.TagName == "tag2"), Is.True);
|
||||
Assert.That(test.As<TagsPart>().Record.Tags.Any(t => t.TagRecord.TagName == "tag3"), Is.True);
|
||||
Assert.That(test.As<TagsPart>().Record.Tags.Any(t => t.TagRecord.TagName == "tag4"), Is.True);
|
||||
|
||||
Assert.That(_tagService.GetTagByName("tag1").ContentTags.Count, Is.EqualTo(1));
|
||||
Assert.That(_tagService.GetTagByName("tag1").ContentTags.Any(t => t.TagsPartRecord.Id == thing1.Id), Is.True);
|
||||
|
||||
Assert.That(_tagService.GetTagByName("tag2").ContentTags.Count, Is.EqualTo(2));
|
||||
Assert.That(_tagService.GetTagByName("tag2").ContentTags.Any(t => t.TagsPartRecord.Id == thing1.Id), Is.True);
|
||||
Assert.That(_tagService.GetTagByName("tag2").ContentTags.Any(t => t.TagsPartRecord.Id == thing2.Id), Is.True);
|
||||
|
||||
Assert.That(_tagService.GetTagByName("tag3").ContentTags.Count, Is.EqualTo(2));
|
||||
Assert.That(_tagService.GetTagByName("tag3").ContentTags.Any(t => t.TagsPartRecord.Id == thing1.Id), Is.True);
|
||||
Assert.That(_tagService.GetTagByName("tag3").ContentTags.Any(t => t.TagsPartRecord.Id == thing2.Id), Is.True);
|
||||
|
||||
Assert.That(_tagService.GetTagByName("tag4").ContentTags.Count, Is.EqualTo(1));
|
||||
Assert.That(_tagService.GetTagByName("tag4").ContentTags.Any(t => t.TagsPartRecord.Id == thing2.Id), Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RenamingATagShouldMergeTaggedItems() {
|
||||
var thing1 = _contentManager.New("thing");
|
||||
_contentManager.Create(thing1);
|
||||
_tagService.UpdateTagsForContentItem(thing1, new string[] { "tag1", "tag2", "tag3" });
|
||||
|
||||
var thing2 = _contentManager.New("thing");
|
||||
_contentManager.Create(thing2);
|
||||
_tagService.UpdateTagsForContentItem(thing2, new string[] { "tag2" });
|
||||
|
||||
var thing3 = _contentManager.New("thing");
|
||||
_contentManager.Create(thing3);
|
||||
_tagService.UpdateTagsForContentItem(thing3, new string[] { "tag3" });
|
||||
|
||||
// Renamed and merge "tag2" to "tag3"
|
||||
var tag = _tagService.GetTagByName("tag2");
|
||||
_tagService.UpdateTag(tag.Id, "tag3");
|
||||
|
||||
ClearSession();
|
||||
|
||||
Assert.That(_tagService.GetTags().Count(), Is.EqualTo(2));
|
||||
Assert.That(_tagService.GetTags().Any(tagRecord => tagRecord.TagName == "tag1"), Is.True);
|
||||
Assert.That(_tagService.GetTags().Any(tagRecord => tagRecord.TagName == "tag2"), Is.False);
|
||||
Assert.That(_tagService.GetTags().Any(tagRecord => tagRecord.TagName == "tag3"), Is.True);
|
||||
|
||||
Assert.That(_contentManager.Get(thing1.Id).As<TagsPart>().CurrentTags.Any(tagRecord => tagRecord.TagName == "tag1"), Is.True);
|
||||
Assert.That(_contentManager.Get(thing1.Id).As<TagsPart>().CurrentTags.Any(tagRecord => tagRecord.TagName == "tag2"), Is.False);
|
||||
Assert.That(_contentManager.Get(thing1.Id).As<TagsPart>().CurrentTags.Any(tagRecord => tagRecord.TagName == "tag3"), Is.True);
|
||||
|
||||
Assert.That(_contentManager.Get(thing2.Id).As<TagsPart>().CurrentTags.Any(tagRecord => tagRecord.TagName == "tag3"), Is.True);
|
||||
|
||||
Assert.That(_contentManager.Get(thing3.Id).As<TagsPart>().CurrentTags.Any(tagRecord => tagRecord.TagName == "tag3"), Is.True);
|
||||
}
|
||||
|
||||
public class ThingHandler : ContentHandler {
|
||||
public ThingHandler() {
|
||||
Filters.Add(new ActivatingFilter<Thing>("thing"));
|
||||
Filters.Add(new ActivatingFilter<TagsPart>("thing"));
|
||||
}
|
||||
}
|
||||
|
||||
public class Thing : ContentPart {
|
||||
}
|
||||
}
|
||||
}
|
@@ -50,7 +50,7 @@ namespace Orchard.Tags.Controllers {
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
foreach (TagEntry entry in checkedEntries) {
|
||||
_tagService.DeleteTag(entry.TagRecord.Id);
|
||||
_tagService.DeleteTag(entry.Tag.Id);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -131,7 +131,7 @@ namespace Orchard.Tags.Controllers {
|
||||
|
||||
private static TagEntry CreateTagEntry(TagRecord tagRecord) {
|
||||
return new TagEntry {
|
||||
TagRecord = tagRecord,
|
||||
Tag = tagRecord,
|
||||
IsChecked = false,
|
||||
};
|
||||
}
|
||||
|
@@ -9,13 +9,14 @@ using Orchard.Tags.Models;
|
||||
namespace Orchard.Tags.Handlers {
|
||||
[UsedImplicitly]
|
||||
public class TagsPartHandler : ContentHandler {
|
||||
public TagsPartHandler(IRepository<TagRecord> tagsRepository, IRepository<TagsContentItems> tagsContentItemsRepository) {
|
||||
public TagsPartHandler(IRepository<TagsPartRecord> repository, IRepository<TagRecord> tagsRepository, IRepository<ContentTagRecord> tagsContentItemsRepository) {
|
||||
Filters.Add(StorageFilter.For(repository));
|
||||
|
||||
OnLoading<TagsPart>((context, tags) => {
|
||||
// populate list of attached tags on demand
|
||||
tags._currentTags.Loader(list => {
|
||||
foreach(var tag in tagsContentItemsRepository.Fetch(x => x.ContentItem == context.ContentItem.Record))
|
||||
list.Add(tag.Tag);
|
||||
foreach(var tag in tagsContentItemsRepository.Fetch(x => x.TagsPartRecord.Id == context.ContentItem.Id))
|
||||
list.Add(tag.TagRecord);
|
||||
return list;
|
||||
});
|
||||
|
||||
@@ -28,13 +29,13 @@ namespace Orchard.Tags.Handlers {
|
||||
|
||||
// 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.ContentItem != context.ContentItem.Record).Count() == 0 ) {
|
||||
if ( tagsContentItemsRepository.Fetch(x => x.TagsPartRecord.Id != context.ContentItem.Id).Count() == 0 ) {
|
||||
tagsRepository.Delete(tag);
|
||||
}
|
||||
}
|
||||
|
||||
// delete tag links with this contentItem (tagsContentItems)
|
||||
foreach ( var tagsContentItem in tagsContentItemsRepository.Fetch(x => x.ContentItem == context.ContentItem.Record) ) {
|
||||
foreach ( var tagsContentItem in tagsContentItemsRepository.Fetch(x => x.TagsPartRecord.Id == context.ContentItem.Id) ) {
|
||||
tagsContentItemsRepository.Delete(tagsContentItem);
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,7 @@
|
||||
namespace Orchard.Tags.Models {
|
||||
public class ContentTagRecord {
|
||||
public virtual int Id { get; set; }
|
||||
public virtual TagRecord TagRecord { get; set; }
|
||||
public virtual TagsPartRecord TagsPartRecord { get; set; }
|
||||
}
|
||||
}
|
@@ -1,6 +1,9 @@
|
||||
namespace Orchard.Tags.Models {
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Orchard.Tags.Models {
|
||||
public class TagRecord {
|
||||
public virtual int Id { get; set; }
|
||||
public virtual string TagName { get; set; }
|
||||
public virtual IList<ContentTagRecord> ContentTags { get; set; }
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +0,0 @@
|
||||
using Orchard.ContentManagement.Records;
|
||||
|
||||
namespace Orchard.Tags.Models {
|
||||
public class TagsContentItems {
|
||||
public virtual int Id { get; set; }
|
||||
public virtual TagRecord Tag { get; set; }
|
||||
public virtual ContentItemRecord ContentItem { get; set; }
|
||||
}
|
||||
}
|
@@ -1,6 +1,11 @@
|
||||
using Orchard.ContentManagement.Records;
|
||||
using System.Collections.Generic;
|
||||
using Orchard.ContentManagement.Records;
|
||||
|
||||
namespace Orchard.Tags.Models {
|
||||
public class TagsPartRecord : ContentPartRecord {
|
||||
public TagsPartRecord() {
|
||||
Tags = new List<ContentTagRecord>();
|
||||
}
|
||||
public virtual IList<ContentTagRecord> Tags { get; set; }
|
||||
}
|
||||
}
|
@@ -54,7 +54,7 @@
|
||||
<Compile Include="AdminMenu.cs" />
|
||||
<Compile Include="Controllers\AdminController.cs" />
|
||||
<Compile Include="Migrations.cs" />
|
||||
<Compile Include="Models\TagsContentItems.cs" />
|
||||
<Compile Include="Models\ContentTagRecord.cs" />
|
||||
<Compile Include="Models\TagsPartRecord.cs" />
|
||||
<Compile Include="ResourceManifest.cs" />
|
||||
<Compile Include="Services\ITagService.cs" />
|
||||
|
@@ -9,7 +9,7 @@ namespace Orchard.Tags.Services {
|
||||
TagRecord GetTagByName(string tagName);
|
||||
IEnumerable<IContent> GetTaggedContentItems(int tagId);
|
||||
|
||||
void CreateTag(string tagName);
|
||||
TagRecord CreateTag(string tagName);
|
||||
|
||||
void DeleteTag(int tagId);
|
||||
|
||||
|
@@ -2,7 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Orchard.ContentManagement.Records;
|
||||
using Orchard.Data;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Logging;
|
||||
@@ -15,18 +14,18 @@ namespace Orchard.Tags.Services {
|
||||
[UsedImplicitly]
|
||||
public class TagService : ITagService {
|
||||
private readonly IRepository<TagRecord> _tagRepository;
|
||||
private readonly IRepository<TagsContentItems> _tagsContentItemsRepository;
|
||||
private readonly IRepository<ContentTagRecord> _contentTagRepository;
|
||||
private readonly INotifier _notifier;
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly IOrchardServices _orchardServices;
|
||||
|
||||
public TagService(IRepository<TagRecord> tagRepository,
|
||||
IRepository<TagsContentItems> tagsContentItemsRepository,
|
||||
IRepository<ContentTagRecord> contentTagRepository,
|
||||
INotifier notifier,
|
||||
IAuthorizationService authorizationService,
|
||||
IOrchardServices orchardServices) {
|
||||
_tagRepository = tagRepository;
|
||||
_tagsContentItemsRepository = tagsContentItemsRepository;
|
||||
_contentTagRepository = contentTagRepository;
|
||||
_notifier = notifier;
|
||||
_authorizationService = authorizationService;
|
||||
_orchardServices = orchardServices;
|
||||
@@ -49,27 +48,36 @@ namespace Orchard.Tags.Services {
|
||||
return _tagRepository.Get(x => x.TagName == tagName);
|
||||
}
|
||||
|
||||
public void CreateTag(string tagName) {
|
||||
if (_tagRepository.Get(x => x.TagName == tagName) == null) {
|
||||
public TagRecord CreateTag(string tagName) {
|
||||
var result = _tagRepository.Get(x => x.TagName == tagName);
|
||||
if (result == null) {
|
||||
_authorizationService.CheckAccess(Permissions.CreateTag, _orchardServices.WorkContext.CurrentUser, null);
|
||||
result = new TagRecord { TagName = tagName };
|
||||
_tagRepository.Create(result);
|
||||
}
|
||||
|
||||
TagRecord tagRecord = new TagRecord { TagName = tagName };
|
||||
_tagRepository.Create(tagRecord);
|
||||
}
|
||||
else {
|
||||
_notifier.Warning(T("The tag {0} already exists", tagName));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void DeleteTag(int tagId) {
|
||||
_tagRepository.Delete(GetTag(tagId));
|
||||
IEnumerable<TagsContentItems> tagsContentItems = _tagsContentItemsRepository.Fetch(x => x.Tag.Id == tagId);
|
||||
foreach (var tagContentItem in tagsContentItems) {
|
||||
_tagsContentItemsRepository.Delete(tagContentItem);
|
||||
_authorizationService.CheckAccess(Permissions.ManageTags, _orchardServices.WorkContext.CurrentUser, null);
|
||||
|
||||
var tag = GetTag(tagId);
|
||||
if (tag == null)
|
||||
return;
|
||||
|
||||
// Delete associations to content items
|
||||
foreach (var tagContentItem in _contentTagRepository.Fetch(x => x.TagRecord == tag)) {
|
||||
_contentTagRepository.Delete(tagContentItem);
|
||||
}
|
||||
|
||||
// Delete tag entity
|
||||
_tagRepository.Delete(tag);
|
||||
}
|
||||
|
||||
public void UpdateTag(int tagId, string tagName) {
|
||||
_authorizationService.CheckAccess(Permissions.ManageTags, _orchardServices.WorkContext.CurrentUser, null);
|
||||
|
||||
if (String.IsNullOrEmpty(tagName)) {
|
||||
_notifier.Warning(T("Couldn't rename tag: name was empty"));
|
||||
return;
|
||||
@@ -79,16 +87,16 @@ namespace Orchard.Tags.Services {
|
||||
|
||||
// new tag name already existing => merge
|
||||
if (tagRecord != null) {
|
||||
var tagsContentItems = _tagsContentItemsRepository.Fetch(x => x.Tag.Id == tagId);
|
||||
var tagsContentItems = _contentTagRepository.Fetch(x => x.TagRecord.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);
|
||||
if (!taggedContentItems.Any(c => c.ContentItem.Id == tagContentItem.TagsPartRecord.Id)) {
|
||||
TagContentItem(tagContentItem.TagsPartRecord, tagName);
|
||||
}
|
||||
_tagsContentItemsRepository.Delete(tagContentItem);
|
||||
_contentTagRepository.Delete(tagContentItem);
|
||||
}
|
||||
|
||||
_tagRepository.Delete(GetTag(tagId));
|
||||
@@ -101,50 +109,41 @@ namespace Orchard.Tags.Services {
|
||||
}
|
||||
|
||||
public IEnumerable<IContent> GetTaggedContentItems(int tagId) {
|
||||
return _tagsContentItemsRepository
|
||||
.Fetch(x => x.Tag.Id == tagId)
|
||||
.Select(t => _orchardServices.ContentManager.Get(t.ContentItem.Id))
|
||||
return _contentTagRepository
|
||||
.Fetch(x => x.TagRecord.Id == tagId)
|
||||
.Select(t => _orchardServices.ContentManager.Get(t.TagsPartRecord.Id))
|
||||
.Where(c => c != null);
|
||||
}
|
||||
|
||||
private void TagContentItem(ContentItemRecord contentItem, string tagName) {
|
||||
private void TagContentItem(TagsPartRecord tagsPartRecord, string tagName) {
|
||||
var tagRecord = GetTagByName(tagName);
|
||||
var tagsContentItems = new TagsContentItems { ContentItem = contentItem, Tag = tagRecord };
|
||||
_tagsContentItemsRepository.Create(tagsContentItems);
|
||||
var tagsContentItems = new ContentTagRecord { TagsPartRecord = tagsPartRecord, TagRecord = tagRecord };
|
||||
_contentTagRepository.Create(tagsContentItems);
|
||||
}
|
||||
|
||||
public void UpdateTagsForContentItem(ContentItem contentItem, IEnumerable<string> tagNamesForContentItem) {
|
||||
var tags = new List<TagRecord>();
|
||||
foreach (var tagName in tagNamesForContentItem) {
|
||||
TagRecord tagRecord = GetTagByName(tagName);
|
||||
if (tagRecord == null) {
|
||||
CreateTag(tagName);
|
||||
tagRecord = GetTagByName(tagName);
|
||||
}
|
||||
tags.Add(tagRecord);
|
||||
}
|
||||
ModifyTagsForContentItem(contentItem, tags);
|
||||
}
|
||||
if (contentItem.Id == 0)
|
||||
throw new OrchardException(T("Error adding tag to content item: the content item has not been created yet."));
|
||||
|
||||
private void ModifyTagsForContentItem(ContentItem contentItem, IEnumerable<TagRecord> tagsForContentItem) {
|
||||
var newTagsForContentItem = new List<TagRecord>(tagsForContentItem);
|
||||
var currentTagsForContentItem = _tagsContentItemsRepository.Fetch(x => x.ContentItem == contentItem.Record);
|
||||
var tags = tagNamesForContentItem.Select(name => CreateTag(name));
|
||||
var newTagsForContentItem = new List<TagRecord>(tags);
|
||||
var currentTagsForContentItem = _contentTagRepository.Fetch(x => x.TagsPartRecord.Id == contentItem.Id);
|
||||
|
||||
foreach (var tagContentItem in currentTagsForContentItem) {
|
||||
if (!newTagsForContentItem.Contains(tagContentItem.Tag)) {
|
||||
if (!newTagsForContentItem.Contains(tagContentItem.TagRecord)) {
|
||||
_authorizationService.CheckAccess(Permissions.ApplyTag, _orchardServices.WorkContext.CurrentUser, null);
|
||||
|
||||
_tagsContentItemsRepository.Delete(tagContentItem);
|
||||
_contentTagRepository.Delete(tagContentItem);
|
||||
}
|
||||
else {
|
||||
newTagsForContentItem.Remove(tagContentItem.Tag);
|
||||
newTagsForContentItem.Remove(tagContentItem.TagRecord);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var newTagForContentItem in newTagsForContentItem) {
|
||||
_authorizationService.CheckAccess(Permissions.ApplyTag, _orchardServices.WorkContext.CurrentUser, null);
|
||||
|
||||
_tagsContentItemsRepository.Create(new TagsContentItems { ContentItem = contentItem.Record, Tag = newTagForContentItem });
|
||||
_contentTagRepository.Create(new ContentTagRecord { TagsPartRecord = contentItem.As<TagsPart>().Record, TagRecord = newTagForContentItem });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@ namespace Orchard.Tags.ViewModels {
|
||||
}
|
||||
|
||||
public class TagEntry {
|
||||
public TagRecord TagRecord { get; set; }
|
||||
public TagRecord Tag { get; set; }
|
||||
public bool IsChecked { get; set; }
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user