From ff1e1bf25afcdd3867f675b7b3208ebf917c038d Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Sun, 19 Oct 2014 14:03:29 -0400 Subject: [PATCH] TagCloud Functionality to filter by User --- .../Orchard.Tags/Drivers/TagCloudDriver.cs | 2 + .../Orchard.Tags/Handlers/TagCloudHandler.cs | 13 ++-- .../Orchard.Tags/Models/TagCloudPart.cs | 5 ++ .../Modules/Orchard.Tags/Module.txt | 2 +- .../Modules/Orchard.Tags/Orchard.Tags.csproj | 4 ++ .../Orchard.Tags/Services/ITagCloudService.cs | 2 +- .../Orchard.Tags/Services/TagCloudService.cs | 68 +++++++++---------- .../EditorTemplates/Parts/TagCloud.cshtml | 10 ++- src/Orchard.Web/Orchard.Web.csproj | 11 +-- 9 files changed, 66 insertions(+), 51 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Drivers/TagCloudDriver.cs b/src/Orchard.Web/Modules/Orchard.Tags/Drivers/TagCloudDriver.cs index 345c8f576..908db1d97 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Drivers/TagCloudDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.Tags/Drivers/TagCloudDriver.cs @@ -40,11 +40,13 @@ namespace Orchard.Tags.Drivers { protected override void Exporting(TagCloudPart part, ExportContentContext context) { context.Element(part.PartDefinition.Name).SetAttributeValue("Slug", part.Slug); context.Element(part.PartDefinition.Name).SetAttributeValue("Buckets", part.Buckets); + context.Element(part.PartDefinition.Name).SetAttributeValue("Username", part.Username); } protected override void Importing(TagCloudPart part, ImportContentContext context) { part.Slug = context.Attribute(part.PartDefinition.Name, "Slug"); part.Buckets = Convert.ToInt32(context.Attribute(part.PartDefinition.Name, "Buckets")); + part.Username = context.Attribute(part.PartDefinition.Name, "Username"); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Handlers/TagCloudHandler.cs b/src/Orchard.Web/Modules/Orchard.Tags/Handlers/TagCloudHandler.cs index 786dc5f38..00caa3c8e 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Handlers/TagCloudHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Tags/Handlers/TagCloudHandler.cs @@ -4,22 +4,27 @@ using Orchard.ContentManagement.Handlers; using Orchard.Environment.Extensions; using Orchard.Tags.Models; using Orchard.Tags.Services; +using Orchard.Tokens; namespace Orchard.Tags.Handlers { [OrchardFeature("Orchard.Tags.TagCloud")] public class TagCloudHandler : ContentHandler { private readonly ISignals _signals; + private readonly ITokenizer _tokenizer; public TagCloudHandler( ITagCloudService tagCloudService, - ISignals signals) { + ISignals signals, + ITokenizer tokenizer) { _signals = signals; + _tokenizer = tokenizer; OnInitializing((context, part) => part - ._tagCountField.Loader(tags => - tagCloudService.GetPopularTags(part.Buckets, part.Slug).ToList() - )); + ._tagCountField.Loader(tags => { + var username = _tokenizer.Replace(part.Username, new object()); + return tagCloudService.GetPopularTags(part.Buckets, part.Slug, username).ToList(); + })); OnPublished((context, part) => InvalidateTagCloudCache()); OnRemoved((context, part) => InvalidateTagCloudCache()); diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Models/TagCloudPart.cs b/src/Orchard.Web/Modules/Orchard.Tags/Models/TagCloudPart.cs index e82fa3e87..338f52b9b 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Models/TagCloudPart.cs +++ b/src/Orchard.Web/Modules/Orchard.Tags/Models/TagCloudPart.cs @@ -19,5 +19,10 @@ namespace Orchard.Tags.Models { get { return this.Retrieve(r => r.Slug); } set { this.Store(r => r.Slug, value); } } + + public string Username { + get { return this.Retrieve(r => r.Username); } + set { this.Store(r => r.Username, value); } + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Module.txt b/src/Orchard.Web/Modules/Orchard.Tags/Module.txt index 40f10bc16..7437d2641 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Module.txt +++ b/src/Orchard.Web/Modules/Orchard.Tags/Module.txt @@ -18,5 +18,5 @@ Features: Orchard.Tags.TagCloud: Name: Tag Cloud Description: Adds a tag cloud widget. - Dependencies: Orchard.Tags, Orchard.Autoroute + Dependencies: Orchard.Tags, Orchard.Autoroute, Orchard.Tokens Category: Navigation diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Orchard.Tags.csproj b/src/Orchard.Web/Modules/Orchard.Tags/Orchard.Tags.csproj index bee3974ec..6039fa72c 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Orchard.Tags.csproj +++ b/src/Orchard.Web/Modules/Orchard.Tags/Orchard.Tags.csproj @@ -133,6 +133,10 @@ {66FCCD76-2761-47E3-8D11-B45D0001DDAA} Orchard.Autoroute + + {6f759635-13d7-4e94-bcc9-80445d63f117} + Orchard.Tokens + diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Services/ITagCloudService.cs b/src/Orchard.Web/Modules/Orchard.Tags/Services/ITagCloudService.cs index 36f74e55f..e22339465 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Services/ITagCloudService.cs +++ b/src/Orchard.Web/Modules/Orchard.Tags/Services/ITagCloudService.cs @@ -3,6 +3,6 @@ using Orchard.Tags.Models; namespace Orchard.Tags.Services { public interface ITagCloudService : IDependency { - IEnumerable GetPopularTags(int buckets, string slug); + IEnumerable GetPopularTags(int buckets, string slug, string username = null); } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Services/TagCloudService.cs b/src/Orchard.Web/Modules/Orchard.Tags/Services/TagCloudService.cs index 13691ebb8..a18a34234 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Services/TagCloudService.cs +++ b/src/Orchard.Web/Modules/Orchard.Tags/Services/TagCloudService.cs @@ -7,6 +7,7 @@ using Orchard.ContentManagement; using Orchard.Core.Common.Models; using Orchard.Data; using Orchard.Environment.Extensions; +using Orchard.Security; using Orchard.Tags.Models; namespace Orchard.Tags.Services { @@ -17,6 +18,7 @@ namespace Orchard.Tags.Services { private readonly IContentManager _contentManager; private readonly ICacheManager _cacheManager; private readonly ISignals _signals; + private readonly IMembershipService _membershipService; internal static readonly string TagCloudTagsChanged = "Orchard.Tags.TagCloud.TagsChanged"; public TagCloudService( @@ -24,33 +26,33 @@ namespace Orchard.Tags.Services { IRepository autorouteRepository, IContentManager contentManager, ICacheManager cacheManager, - ISignals signals) { + ISignals signals, + IMembershipService membershipService) { _contentTagRepository = contentTagRepository; _autorouteRepository = autorouteRepository; _contentManager = contentManager; _cacheManager = cacheManager; _signals = signals; + _membershipService = membershipService; } - public IEnumerable GetPopularTags(int buckets, string slug) { - var cacheKey = "Orchard.Tags.TagCloud." + (slug ?? "") + '.' + buckets; + public IEnumerable GetPopularTags(int buckets, string slug, string username = null) { + var cacheKey = "Orchard.Tags.TagCloud." + + (!string.IsNullOrWhiteSpace(slug) ? "slug-" + slug : string.Empty) + + (!string.IsNullOrWhiteSpace(username) ? "username-" + username : string.Empty) + + '.' + buckets; + return _cacheManager.Get(cacheKey, ctx => { ctx.Monitor(_signals.When(TagCloudTagsChanged)); - IEnumerable tagCounts; - if (string.IsNullOrWhiteSpace(slug)) { - tagCounts = (from tc in _contentTagRepository.Table - where tc.TagsPartRecord.ContentItemRecord.Versions.Any(v => v.Published) - group tc by tc.TagRecord.TagName - into g - select new TagCount { - TagName = g.Key, - Count = g.Count() - }).ToList(); - } - else { - if (slug == "/") { + + var tagQuery = _contentManager + .Query(VersionOptions.Published) + .Join(); + + if (!string.IsNullOrWhiteSpace(slug)) { + if (slug == "/"){ slug = ""; } @@ -60,26 +62,24 @@ namespace Orchard.Tags.Services { .ToList() // don't try to optimize with slicing as there should be only one result .FirstOrDefault(); - if (containerId == 0) { - return new List(); - } + tagQuery = tagQuery.Where(record => record.Container.Id == containerId); + } - tagCounts = _contentManager - .Query(VersionOptions.Published) - .Join() - .Where(t => t.Container.Id == containerId) - .List() - .SelectMany(t => t.CurrentTags) - .GroupBy(t => t) - .Select(g => new TagCount { - TagName = g.Key, - Count = g.Count() - }) - .ToList(); + if (!string.IsNullOrWhiteSpace(username)) { + var user = _membershipService.GetUser(username); + tagQuery = tagQuery.Where(record => record.OwnerId == user.Id); + } - if (!tagCounts.Any()) { - return new List(); - } + var tagCounts = tagQuery.List() + .SelectMany(t => t.CurrentTags) + .GroupBy(t => t) + .Select(g => new TagCount { + TagName = g.Key, + Count = g.Count() + }).ToList(); + + if (!tagCounts.Any()) { + return new List(); } // initialize centroids with a linear distribution diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Views/EditorTemplates/Parts/TagCloud.cshtml b/src/Orchard.Web/Modules/Orchard.Tags/Views/EditorTemplates/Parts/TagCloud.cshtml index 932694e2e..0f1e4c1d4 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Views/EditorTemplates/Parts/TagCloud.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Tags/Views/EditorTemplates/Parts/TagCloud.cshtml @@ -16,5 +16,13 @@ @Html.ValidationMessageFor(model => model.Slug) @T("Enter the slug of the container for which you want the tag cloud, e.g. blog, /, or leave empty for the cloud to be scoped to the whole site. ") + +
+ @Html.LabelFor(model => model.Username) + @Html.TextBoxFor(model => model.Username, new { @class = "text medium tokenized" }) + @Html.ValidationMessageFor(model => model.Username) + @T("The Username owning content whose tags that will get rendered in the cloud.") +
+ - \ No newline at end of file +@Display.TokenHint() \ No newline at end of file diff --git a/src/Orchard.Web/Orchard.Web.csproj b/src/Orchard.Web/Orchard.Web.csproj index ce62a26bf..a0077052c 100644 --- a/src/Orchard.Web/Orchard.Web.csproj +++ b/src/Orchard.Web/Orchard.Web.csproj @@ -221,16 +221,7 @@ - False - False - 30321 - /OrchardLocal - http://localhost:30322/OrchardLocal - False - False - - - False + True