mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
Merge remote-tracking branch 'upstream/1.9-int' into 1.9-int
This commit is contained in:
@@ -124,7 +124,7 @@ namespace Orchard.Alias.Implementation {
|
|||||||
return _aliasStorage.List(sourceStartsWith).Select(item => Tuple.Create(item.Item1, item.Item3.ToRouteValueDictionary(), item.Item4));
|
return _aliasStorage.List(sourceStartsWith).Select(item => Tuple.Create(item.Item1, item.Item3.ToRouteValueDictionary(), item.Item4));
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<VirtualPathData> LookupVirtualPaths(RouteValueDictionary routeValues,HttpContextBase httpContext) {
|
public IEnumerable<VirtualPathData> LookupVirtualPaths(RouteValueDictionary routeValues, HttpContextBase httpContext) {
|
||||||
return Utils.LookupVirtualPaths(httpContext, _routeDescriptors.Value, routeValues);
|
return Utils.LookupVirtualPaths(httpContext, _routeDescriptors.Value, routeValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,11 +6,13 @@ using System.Xml.Linq;
|
|||||||
using Orchard.Alias.Records;
|
using Orchard.Alias.Records;
|
||||||
using Orchard.Data;
|
using Orchard.Data;
|
||||||
using Orchard.Alias.Implementation.Holder;
|
using Orchard.Alias.Implementation.Holder;
|
||||||
|
using Orchard.Validation;
|
||||||
|
|
||||||
namespace Orchard.Alias.Implementation.Storage {
|
namespace Orchard.Alias.Implementation.Storage {
|
||||||
public interface IAliasStorage : IDependency {
|
public interface IAliasStorage : IDependency {
|
||||||
void Set(string path, IDictionary<string, string> routeValues, string source);
|
void Set(string path, IDictionary<string, string> routeValues, string source);
|
||||||
IDictionary<string, string> Get(string aliasPath);
|
IDictionary<string, string> Get(string aliasPath);
|
||||||
|
void Remove(Expression<Func<AliasRecord, bool>> filter);
|
||||||
void Remove(string path);
|
void Remove(string path);
|
||||||
void Remove(string path, string aliasSource);
|
void Remove(string path, string aliasSource);
|
||||||
void RemoveBySource(string aliasSource);
|
void RemoveBySource(string aliasSource);
|
||||||
@@ -88,38 +90,23 @@ namespace Orchard.Alias.Implementation.Storage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void Remove(string path) {
|
public void Remove(string path) {
|
||||||
|
Remove(x => x.Path == path && x.Source == path);
|
||||||
if (path == null) {
|
|
||||||
throw new ArgumentNullException("path");
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var aliasRecord in _aliasRepository.Fetch(r => r.Path == path)) {
|
|
||||||
_aliasRepository.Delete(aliasRecord);
|
|
||||||
// Bulk updates might go wrong if we don't flush
|
|
||||||
_aliasRepository.Flush();
|
|
||||||
var dict = ToDictionary(aliasRecord);
|
|
||||||
_aliasHolder.RemoveAlias(new AliasInfo() { Path = dict.Item1, Area = dict.Item2, RouteValues = dict.Item3 });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Remove(string path, string aliasSource) {
|
public void Remove(string path, string aliasSource) {
|
||||||
|
Remove(x => x.Path == path && x.Source == aliasSource);
|
||||||
if (path == null) {
|
|
||||||
throw new ArgumentNullException("path");
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var aliasRecord in _aliasRepository.Fetch(r => r.Path == path && r.Source == aliasSource)) {
|
|
||||||
_aliasRepository.Delete(aliasRecord);
|
|
||||||
// Bulk updates might go wrong if we don't flush
|
|
||||||
_aliasRepository.Flush();
|
|
||||||
var dict = ToDictionary(aliasRecord);
|
|
||||||
_aliasHolder.RemoveAlias(new AliasInfo() { Path = dict.Item1, Area = dict.Item2, RouteValues = dict.Item3 });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveBySource(string aliasSource) {
|
public void RemoveBySource(string aliasSource) {
|
||||||
foreach (var aliasRecord in _aliasRepository.Fetch(r => r.Source == aliasSource)) {
|
Remove(x => x.Source == aliasSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Remove(Expression<Func<AliasRecord, bool>> filter) {
|
||||||
|
Argument.ThrowIfNull(filter, "filter");
|
||||||
|
|
||||||
|
foreach (var aliasRecord in _aliasRepository.Fetch(filter)) {
|
||||||
_aliasRepository.Delete(aliasRecord);
|
_aliasRepository.Delete(aliasRecord);
|
||||||
// Bulk updates might go wrong if we don't flush
|
// Bulk updates might go wrong if we don't flush.
|
||||||
_aliasRepository.Flush();
|
_aliasRepository.Flush();
|
||||||
var dict = ToDictionary(aliasRecord);
|
var dict = ToDictionary(aliasRecord);
|
||||||
_aliasHolder.RemoveAlias(new AliasInfo() { Path = dict.Item1, Area = dict.Item2, RouteValues = dict.Item3 });
|
_aliasHolder.RemoveAlias(new AliasInfo() { Path = dict.Item1, Area = dict.Item2, RouteValues = dict.Item3 });
|
||||||
@@ -127,7 +114,7 @@ namespace Orchard.Alias.Implementation.Storage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Tuple<string, string, IDictionary<string, string>, string, int>> List() {
|
public IEnumerable<Tuple<string, string, IDictionary<string, string>, string, int>> List() {
|
||||||
return List((Expression<Func<AliasRecord, bool>>) null);
|
return List((Expression<Func<AliasRecord, bool>>)null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Tuple<string, string, IDictionary<string, string>, string, int>> List(Expression<Func<AliasRecord, bool>> predicate) {
|
public IEnumerable<Tuple<string, string, IDictionary<string, string>, string, int>> List(Expression<Func<AliasRecord, bool>> predicate) {
|
||||||
|
|||||||
@@ -3,23 +3,23 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Orchard.Alias;
|
using Orchard.Alias;
|
||||||
|
using Orchard.Alias.Implementation.Storage;
|
||||||
using Orchard.Autoroute.Models;
|
using Orchard.Autoroute.Models;
|
||||||
using Orchard.Autoroute.Settings;
|
using Orchard.Autoroute.Settings;
|
||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
using Orchard.ContentManagement.MetaData;
|
using Orchard.ContentManagement.MetaData;
|
||||||
using Orchard.ContentManagement.MetaData.Models;
|
using Orchard.ContentManagement.MetaData.Models;
|
||||||
using Orchard.Localization;
|
|
||||||
using Orchard.Logging;
|
|
||||||
using Orchard.Tokens;
|
using Orchard.Tokens;
|
||||||
|
|
||||||
namespace Orchard.Autoroute.Services {
|
namespace Orchard.Autoroute.Services {
|
||||||
public class AutorouteService : IAutorouteService {
|
public class AutorouteService : Component, IAutorouteService {
|
||||||
|
|
||||||
private readonly IAliasService _aliasService;
|
private readonly IAliasService _aliasService;
|
||||||
private readonly ITokenizer _tokenizer;
|
private readonly ITokenizer _tokenizer;
|
||||||
private readonly IContentDefinitionManager _contentDefinitionManager;
|
private readonly IContentDefinitionManager _contentDefinitionManager;
|
||||||
private readonly IContentManager _contentManager;
|
private readonly IContentManager _contentManager;
|
||||||
private readonly IRouteEvents _routeEvents;
|
private readonly IRouteEvents _routeEvents;
|
||||||
|
private readonly IAliasStorage _aliasStorage;
|
||||||
private const string AliasSource = "Autoroute:View";
|
private const string AliasSource = "Autoroute:View";
|
||||||
|
|
||||||
public AutorouteService(
|
public AutorouteService(
|
||||||
@@ -27,39 +27,36 @@ namespace Orchard.Autoroute.Services {
|
|||||||
ITokenizer tokenizer,
|
ITokenizer tokenizer,
|
||||||
IContentDefinitionManager contentDefinitionManager,
|
IContentDefinitionManager contentDefinitionManager,
|
||||||
IContentManager contentManager,
|
IContentManager contentManager,
|
||||||
IRouteEvents routeEvents) {
|
IRouteEvents routeEvents,
|
||||||
_aliasService = aliasService;
|
IAliasStorage aliasStorage) {
|
||||||
_tokenizer = tokenizer;
|
|
||||||
_contentDefinitionManager = contentDefinitionManager;
|
_aliasService = aliasService;
|
||||||
|
_tokenizer = tokenizer;
|
||||||
|
_contentDefinitionManager = contentDefinitionManager;
|
||||||
_contentManager = contentManager;
|
_contentManager = contentManager;
|
||||||
_routeEvents = routeEvents;
|
_routeEvents = routeEvents;
|
||||||
|
_aliasStorage = aliasStorage;
|
||||||
Logger = NullLogger.Instance;
|
|
||||||
T = NullLocalizer.Instance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ILogger Logger { get; set; }
|
|
||||||
public Localizer T { get; set; }
|
|
||||||
|
|
||||||
public string GenerateAlias(AutoroutePart part) {
|
public string GenerateAlias(AutoroutePart part) {
|
||||||
|
|
||||||
if (part == null) {
|
if (part == null) {
|
||||||
throw new ArgumentNullException("part");
|
throw new ArgumentNullException("part");
|
||||||
}
|
}
|
||||||
|
|
||||||
string pattern = GetDefaultPattern(part.ContentItem.ContentType).Pattern;
|
var pattern = GetDefaultPattern(part.ContentItem.ContentType).Pattern;
|
||||||
|
|
||||||
// String.Empty forces pattern based generation. "/" forces homepage
|
// String.Empty forces pattern based generation. "/" forces homepage.
|
||||||
if(part.UseCustomPattern
|
if (part.UseCustomPattern
|
||||||
&& (!String.IsNullOrWhiteSpace(part.CustomPattern) || String.Equals(part.CustomPattern, "/"))) {
|
&& (!String.IsNullOrWhiteSpace(part.CustomPattern) || String.Equals(part.CustomPattern, "/"))) {
|
||||||
pattern = part.CustomPattern;
|
pattern = part.CustomPattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert the pattern and route values via tokens
|
// Convert the pattern and route values via tokens.
|
||||||
var path = _tokenizer.Replace(pattern, BuildTokenContext(part.ContentItem), new ReplaceOptions { Encoding = ReplaceOptions.NoEncode });
|
var path = _tokenizer.Replace(pattern, BuildTokenContext(part.ContentItem), new ReplaceOptions { Encoding = ReplaceOptions.NoEncode });
|
||||||
|
|
||||||
// removing trailing slashes in case the container is empty, and tokens are base on it (e.g. home page)
|
// Removing trailing slashes in case the container is empty, and tokens are base on it (e.g. home page).
|
||||||
while(path.StartsWith("/")) {
|
while (path.StartsWith("/")) {
|
||||||
path = path.Substring(1);
|
path = path.Substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,9 +65,7 @@ namespace Orchard.Autoroute.Services {
|
|||||||
|
|
||||||
public void PublishAlias(AutoroutePart part) {
|
public void PublishAlias(AutoroutePart part) {
|
||||||
var displayRouteValues = _contentManager.GetItemMetadata(part).DisplayRouteValues;
|
var displayRouteValues = _contentManager.GetItemMetadata(part).DisplayRouteValues;
|
||||||
|
|
||||||
_aliasService.Replace(part.DisplayAlias, displayRouteValues, AliasSource);
|
_aliasService.Replace(part.DisplayAlias, displayRouteValues, AliasSource);
|
||||||
|
|
||||||
_routeEvents.Routed(part, part.DisplayAlias);
|
_routeEvents.Routed(part, part.DisplayAlias);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,7 +92,7 @@ namespace Orchard.Autoroute.Services {
|
|||||||
patterns.Add(routePattern);
|
patterns.Add(routePattern);
|
||||||
settings.Patterns = patterns;
|
settings.Patterns = patterns;
|
||||||
|
|
||||||
// define which pattern is the default
|
// Define which pattern is the default.
|
||||||
if (makeDefault || settings.Patterns.Count == 1) {
|
if (makeDefault || settings.Patterns.Count == 1) {
|
||||||
settings.DefaultPatternIndex = settings.Patterns.IndexOf(routePattern);
|
settings.DefaultPatternIndex = settings.Patterns.IndexOf(routePattern);
|
||||||
}
|
}
|
||||||
@@ -113,26 +108,33 @@ namespace Orchard.Autoroute.Services {
|
|||||||
public RoutePattern GetDefaultPattern(string contentType) {
|
public RoutePattern GetDefaultPattern(string contentType) {
|
||||||
var settings = GetTypePartSettings(contentType).GetModel<AutorouteSettings>();
|
var settings = GetTypePartSettings(contentType).GetModel<AutorouteSettings>();
|
||||||
|
|
||||||
// return a default pattern if none is defined
|
// Return a default pattern if none is defined.
|
||||||
if(settings.DefaultPatternIndex < settings.Patterns.Count) {
|
if (settings.DefaultPatternIndex < settings.Patterns.Count) {
|
||||||
return settings.Patterns.ElementAt(settings.DefaultPatternIndex);
|
return settings.Patterns.ElementAt(settings.DefaultPatternIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new RoutePattern {Name = "Title", Description = "my-title", Pattern = "{Content.Slug}"};
|
return new RoutePattern { Name = "Title", Description = "my-title", Pattern = "{Content.Slug}" };
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveAliases(AutoroutePart part) {
|
public void RemoveAliases(AutoroutePart part) {
|
||||||
_aliasService.Delete(part.Path, AliasSource);
|
// https://github.com/OrchardCMS/Orchard/issues/5137
|
||||||
}
|
// If the alias of the specified part is empty while not being the homepage,
|
||||||
|
// we need to make sure we are not removing all empty aliases in order to prevent losing the homepage content item being the homepage.
|
||||||
|
if (String.IsNullOrWhiteSpace(part.Path)) {
|
||||||
|
if (!IsHomePage(part)) {
|
||||||
|
// The item being removed is NOT the homepage, so we need to make sure we're not removing the alias for the homepage.
|
||||||
|
var aliasRecordId = GetHomePageAliasRecordId();
|
||||||
|
|
||||||
private SettingsDictionary GetTypePartSettings(string contentType) {
|
// Remove all aliases EXCEPT for the alias of the homepage.
|
||||||
var contentDefinition = _contentDefinitionManager.GetTypeDefinition(contentType);
|
_aliasStorage.Remove(x => x.Path == part.Path && x.Source == AliasSource && x.Id != aliasRecordId);
|
||||||
|
|
||||||
if (contentDefinition == null) {
|
// Done.
|
||||||
throw new OrchardException(T("Unknown content type: {0}", contentType));
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return contentDefinition.Parts.First(x => x.PartDefinition.Name == "AutoroutePart").Settings;
|
// Safe to delete all aliases for the specified part since it is definitely not the homepage.
|
||||||
|
_aliasService.Delete(part.Path, AliasSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GenerateUniqueSlug(AutoroutePart part, IEnumerable<string> existingPaths) {
|
public string GenerateUniqueSlug(AutoroutePart part, IEnumerable<string> existingPaths) {
|
||||||
@@ -142,22 +144,10 @@ namespace Orchard.Autoroute.Services {
|
|||||||
int? version = existingPaths.Select(s => GetSlugVersion(part.Path, s)).OrderBy(i => i).LastOrDefault();
|
int? version = existingPaths.Select(s => GetSlugVersion(part.Path, s)).OrderBy(i => i).LastOrDefault();
|
||||||
|
|
||||||
return version != null
|
return version != null
|
||||||
? string.Format("{0}-{1}", part.Path, version)
|
? String.Format("{0}-{1}", part.Path, version)
|
||||||
: part.Path;
|
: part.Path;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int? GetSlugVersion(string path, string potentialConflictingPath) {
|
|
||||||
int v;
|
|
||||||
string[] slugParts = potentialConflictingPath.Split(new[] { path }, StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
|
|
||||||
if (slugParts.Length == 0)
|
|
||||||
return 2;
|
|
||||||
|
|
||||||
return int.TryParse(slugParts[0].TrimStart('-'), out v)
|
|
||||||
? (int?)++v
|
|
||||||
: null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<AutoroutePart> GetSimilarPaths(string path) {
|
public IEnumerable<AutoroutePart> GetSimilarPaths(string path) {
|
||||||
return
|
return
|
||||||
_contentManager.Query<AutoroutePart, AutoroutePartRecord>()
|
_contentManager.Query<AutoroutePart, AutoroutePartRecord>()
|
||||||
@@ -170,11 +160,10 @@ namespace Orchard.Autoroute.Services {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public bool ProcessPath(AutoroutePart part) {
|
public bool ProcessPath(AutoroutePart part) {
|
||||||
|
|
||||||
var pathsLikeThis = GetSimilarPaths(part.Path).ToArray();
|
var pathsLikeThis = GetSimilarPaths(part.Path).ToArray();
|
||||||
|
|
||||||
// Don't include *this* part in the list
|
// Don't include *this* part in the list
|
||||||
// of slugs to consider for conflict detection
|
// of slugs to consider for conflict detection.
|
||||||
pathsLikeThis = pathsLikeThis.Where(p => p.ContentItem.Id != part.ContentItem.Id).ToArray();
|
pathsLikeThis = pathsLikeThis.Where(p => p.ContentItem.Id != part.ContentItem.Id).ToArray();
|
||||||
|
|
||||||
if (pathsLikeThis.Any()) {
|
if (pathsLikeThis.Any()) {
|
||||||
@@ -188,5 +177,37 @@ namespace Orchard.Autoroute.Services {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool IsHomePage(IContent content) {
|
||||||
|
var homePageRoute = _aliasService.Get("");
|
||||||
|
var homePageId = homePageRoute.ContainsKey("id") ? XmlHelper.Parse<int>((string)homePageRoute["id"]) : default(int?);
|
||||||
|
return content.Id == homePageId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetHomePageAliasRecordId() {
|
||||||
|
return _aliasStorage.List(x => x.Path == "").First().Item5;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SettingsDictionary GetTypePartSettings(string contentType) {
|
||||||
|
var contentDefinition = _contentDefinitionManager.GetTypeDefinition(contentType);
|
||||||
|
|
||||||
|
if (contentDefinition == null) {
|
||||||
|
throw new OrchardException(T("Unknown content type: {0}", contentType));
|
||||||
|
}
|
||||||
|
|
||||||
|
return contentDefinition.Parts.First(x => x.PartDefinition.Name == "AutoroutePart").Settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int? GetSlugVersion(string path, string potentialConflictingPath) {
|
||||||
|
int v;
|
||||||
|
var slugParts = potentialConflictingPath.Split(new[] { path }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
|
if (slugParts.Length == 0)
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
return Int32.TryParse(slugParts[0].TrimStart('-'), out v)
|
||||||
|
? (int?)++v
|
||||||
|
: null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
@model Orchard.Autoroute.ViewModels.AutoroutePartEditViewModel
|
@using Orchard.Autoroute
|
||||||
@using Orchard.Autoroute
|
|
||||||
@using Orchard.Mvc.Extensions
|
|
||||||
@using Orchard.Utility.Extensions;
|
|
||||||
@using Orchard.Environment.Configuration
|
@using Orchard.Environment.Configuration
|
||||||
|
@using Orchard.Mvc.Extensions
|
||||||
|
@model Orchard.Autoroute.ViewModels.AutoroutePartEditViewModel
|
||||||
|
|
||||||
@if(Model.Settings.DefaultPatternIndex == -1) {
|
@if(Model.Settings.DefaultPatternIndex == -1) {
|
||||||
<div class="message message-Error">@T("The current Content Type does not have a default Autoroute Pattern. Please edit the settings first.")</div>
|
<div class="message message-Error">@T("The current Content Type does not have a default Autoroute Pattern. Please edit the settings first.")</div>
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ namespace Orchard.Recipes.Services {
|
|||||||
_appDataFolder.DeleteFile(stepPath);
|
_appDataFolder.DeleteFile(stepPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stepIndex < 1) {
|
if (stepIndex < 0) {
|
||||||
_appDataFolder.DeleteFile(Path.Combine(_recipeQueueFolder, executionId));
|
_appDataFolder.DeleteFile(Path.Combine(_recipeQueueFolder, executionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,8 @@ namespace Orchard.Taxonomies.Handlers {
|
|||||||
|
|
||||||
// Fires off a processing engine task to run the count processing after the request so it's non-blocking.
|
// Fires off a processing engine task to run the count processing after the request so it's non-blocking.
|
||||||
private void RecalculateCount(IProcessingEngine processingEngine, ShellSettings shellSettings, IShellDescriptorManager shellDescriptorManager, TermsPart part) {
|
private void RecalculateCount(IProcessingEngine processingEngine, ShellSettings shellSettings, IShellDescriptorManager shellDescriptorManager, TermsPart part) {
|
||||||
processingEngine.AddTask(shellSettings, shellDescriptorManager.GetShellDescriptor(), "ITermCountProcessor.Process", new Dictionary<string, object> { { "termsPartId", part.ContentItem.Id } });
|
var termPartRecordIds = part.Terms.Select(t => t.TermRecord.Id).ToArray();
|
||||||
|
processingEngine.AddTask(shellSettings, shellDescriptorManager.GetShellDescriptor(), "ITermCountProcessor.Process", new Dictionary<string, object> { { "termPartRecordIds", termPartRecordIds } });
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,6 @@ using Orchard.Events;
|
|||||||
|
|
||||||
namespace Orchard.Taxonomies.Services {
|
namespace Orchard.Taxonomies.Services {
|
||||||
public interface ITermCountProcessor : IEventHandler {
|
public interface ITermCountProcessor : IEventHandler {
|
||||||
void Process(int termsPartId);
|
void Process(params int[] termPartRecordIds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ using Orchard.ContentManagement.MetaData;
|
|||||||
using Orchard.Core.Common.Models;
|
using Orchard.Core.Common.Models;
|
||||||
using Orchard.Core.Title.Models;
|
using Orchard.Core.Title.Models;
|
||||||
using Orchard.Data;
|
using Orchard.Data;
|
||||||
|
using Orchard.Environment.Configuration;
|
||||||
|
using Orchard.Environment.Descriptor;
|
||||||
|
using Orchard.Environment.State;
|
||||||
using Orchard.Localization;
|
using Orchard.Localization;
|
||||||
using Orchard.Logging;
|
using Orchard.Logging;
|
||||||
using Orchard.Security;
|
using Orchard.Security;
|
||||||
@@ -23,6 +26,10 @@ namespace Orchard.Taxonomies.Services {
|
|||||||
private readonly IAuthorizationService _authorizationService;
|
private readonly IAuthorizationService _authorizationService;
|
||||||
private readonly IContentDefinitionManager _contentDefinitionManager;
|
private readonly IContentDefinitionManager _contentDefinitionManager;
|
||||||
private readonly IOrchardServices _services;
|
private readonly IOrchardServices _services;
|
||||||
|
private readonly IProcessingEngine _processingEngine;
|
||||||
|
private readonly ShellSettings _shellSettings;
|
||||||
|
private readonly IShellDescriptorManager _shellDescriptorManager;
|
||||||
|
|
||||||
|
|
||||||
public TaxonomyService(
|
public TaxonomyService(
|
||||||
IRepository<TermContentItem> termContentItemRepository,
|
IRepository<TermContentItem> termContentItemRepository,
|
||||||
@@ -30,13 +37,20 @@ namespace Orchard.Taxonomies.Services {
|
|||||||
INotifier notifier,
|
INotifier notifier,
|
||||||
IContentDefinitionManager contentDefinitionManager,
|
IContentDefinitionManager contentDefinitionManager,
|
||||||
IAuthorizationService authorizationService,
|
IAuthorizationService authorizationService,
|
||||||
IOrchardServices services) {
|
IOrchardServices services,
|
||||||
|
IProcessingEngine processingEngine,
|
||||||
|
ShellSettings shellSettings,
|
||||||
|
IShellDescriptorManager shellDescriptorManager)
|
||||||
|
{
|
||||||
_termContentItemRepository = termContentItemRepository;
|
_termContentItemRepository = termContentItemRepository;
|
||||||
_contentManager = contentManager;
|
_contentManager = contentManager;
|
||||||
_notifier = notifier;
|
_notifier = notifier;
|
||||||
_authorizationService = authorizationService;
|
_authorizationService = authorizationService;
|
||||||
_contentDefinitionManager = contentDefinitionManager;
|
_contentDefinitionManager = contentDefinitionManager;
|
||||||
_services = services;
|
_services = services;
|
||||||
|
_processingEngine = processingEngine;
|
||||||
|
_shellSettings = shellSettings;
|
||||||
|
_shellDescriptorManager = shellDescriptorManager;
|
||||||
|
|
||||||
Logger = NullLogger.Instance;
|
Logger = NullLogger.Instance;
|
||||||
T = NullLocalizer.Instance;
|
T = NullLocalizer.Instance;
|
||||||
@@ -230,24 +244,31 @@ namespace Orchard.Taxonomies.Services {
|
|||||||
var termsPart = contentItem.As<TermsPart>();
|
var termsPart = contentItem.As<TermsPart>();
|
||||||
|
|
||||||
// removing current terms for specific field
|
// removing current terms for specific field
|
||||||
var fieldIndexes = termsPart.Terms.Select((t, i) => new {Term = t, Index = i})
|
var termList = termsPart.Terms.Select((t, i) => new {Term = t, Index = i})
|
||||||
.Where(x => x.Term.Field == field)
|
.Where(x => x.Term.Field == field)
|
||||||
.Select(x => x.Index)
|
.Select(x => x)
|
||||||
.OrderByDescending(i => i)
|
.OrderByDescending(i => i.Index)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
foreach(var x in fieldIndexes) {
|
foreach (var x in termList) {
|
||||||
termsPart.Terms.RemoveAt(x);
|
termsPart.Terms.RemoveAt(x.Index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// adding new terms list
|
// adding new terms list
|
||||||
foreach(var term in terms) {
|
foreach(var term in terms) {
|
||||||
|
// Remove the newly added terms because they will get processed by the Published-Event
|
||||||
|
termList.RemoveAll(t => t.Term.Id == term.Id);
|
||||||
termsPart.Terms.Add(
|
termsPart.Terms.Add(
|
||||||
new TermContentItem {
|
new TermContentItem {
|
||||||
TermsPartRecord = termsPart.Record,
|
TermsPartRecord = termsPart.Record,
|
||||||
TermRecord = term.Record, Field = field
|
TermRecord = term.Record, Field = field
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var termPartRecordIds = termList.Select(t => t.Term.TermRecord.Id).ToArray();
|
||||||
|
_processingEngine.AddTask(_shellSettings, _shellDescriptorManager.GetShellDescriptor(), "ITermCountProcessor.Process", new Dictionary<string, object> { { "termPartRecordIds", termPartRecordIds } });
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IContentQuery<TermsPart, TermsPartRecord> GetContentItemsQuery(TermPart term, string fieldName = null) {
|
public IContentQuery<TermsPart, TermsPartRecord> GetContentItemsQuery(TermPart term, string fieldName = null) {
|
||||||
|
|||||||
@@ -15,16 +15,10 @@ namespace Orchard.Taxonomies.Services {
|
|||||||
_taxonomyService = taxonomyService;
|
_taxonomyService = taxonomyService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Process(int termsPartId) {
|
public void Process(params int[] termPartRecordIds) {
|
||||||
var termsPart = _contentManager.Get<TermsPart>(termsPartId);
|
|
||||||
|
|
||||||
if (termsPart == null) {
|
foreach (var id in termPartRecordIds) {
|
||||||
return;
|
var termPart = _taxonomyService.GetTerm(id);
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve the number of associated content items, for the whole hierarchy
|
|
||||||
foreach (var term in termsPart.Terms) {
|
|
||||||
var termPart = _taxonomyService.GetTerm(term.TermRecord.Id);
|
|
||||||
while (termPart != null) {
|
while (termPart != null) {
|
||||||
termPart.Count = (int)_taxonomyService.GetContentItemsCount(termPart);
|
termPart.Count = (int)_taxonomyService.GetContentItemsCount(termPart);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user