From 4a1ae0573ffe1118233fa71527dc7be95004cfe9 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 8 Jan 2019 13:25:07 +1100 Subject: [PATCH] Gets definitions dynamically applied for culture specific fields. --- src/Umbraco.Examine/ExamineExtensions.cs | 33 +++++++++- src/Umbraco.Examine/Umbraco.Examine.csproj | 2 +- .../UmbracoFieldDefinitionCollection.cs | 60 ++++++++++++------- .../PublishedMediaCacheTests.cs | 2 +- src/Umbraco.Tests/Umbraco.Tests.csproj | 2 +- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 2 +- src/Umbraco.Web/PublishedContentQuery.cs | 19 +----- src/Umbraco.Web/Umbraco.Web.csproj | 2 +- 8 files changed, 75 insertions(+), 47 deletions(-) diff --git a/src/Umbraco.Examine/ExamineExtensions.cs b/src/Umbraco.Examine/ExamineExtensions.cs index 525f0deaa1..4fe6c359d7 100644 --- a/src/Umbraco.Examine/ExamineExtensions.cs +++ b/src/Umbraco.Examine/ExamineExtensions.cs @@ -1,5 +1,7 @@ using System; +using System.Collections.Generic; using System.Linq; +using System.Text.RegularExpressions; using Examine; using Examine.LuceneEngine.Providers; using Lucene.Net.Analysis; @@ -7,6 +9,7 @@ using Lucene.Net.Index; using Lucene.Net.QueryParsers; using Lucene.Net.Search; using Lucene.Net.Store; +using Umbraco.Core; using Version = Lucene.Net.Util.Version; using Umbraco.Core.Logging; @@ -15,9 +18,35 @@ namespace Umbraco.Examine /// /// Extension methods for the LuceneIndex /// - internal static class ExamineExtensions + public static class ExamineExtensions { - public static bool TryParseLuceneQuery(string query) + /// + /// Matches a culture iso name suffix + /// + /// + /// myFieldName_en-us will match the "en-us" + /// + internal static readonly Regex CultureIsoCodeFieldNameMatchExpression = new Regex("^([_\\w]+)_([a-z]{2}-[a-z0-9]{2,4})$", RegexOptions.Compiled); + + /// + /// Returns all index fields that are culture specific (suffixed) + /// + /// + /// + /// + public static IEnumerable GetCultureFields(this IUmbracoIndex index, string culture) + { + var allFields = index.GetFields(); + // ReSharper disable once LoopCanBeConvertedToQuery + foreach (var field in allFields) + { + var match = CultureIsoCodeFieldNameMatchExpression.Match(field); + if (match.Success && match.Groups.Count == 3 && culture.InvariantEquals(match.Groups[2].Value)) + yield return field; + } + } + + internal static bool TryParseLuceneQuery(string query) { //TODO: I'd assume there would be a more strict way to parse the query but not that i can find yet, for now we'll // also do this rudimentary check diff --git a/src/Umbraco.Examine/Umbraco.Examine.csproj b/src/Umbraco.Examine/Umbraco.Examine.csproj index 6864329bff..68df7b7ddd 100644 --- a/src/Umbraco.Examine/Umbraco.Examine.csproj +++ b/src/Umbraco.Examine/Umbraco.Examine.csproj @@ -48,7 +48,7 @@ - + diff --git a/src/Umbraco.Examine/UmbracoFieldDefinitionCollection.cs b/src/Umbraco.Examine/UmbracoFieldDefinitionCollection.cs index 43c9553400..8030eaecaf 100644 --- a/src/Umbraco.Examine/UmbracoFieldDefinitionCollection.cs +++ b/src/Umbraco.Examine/UmbracoFieldDefinitionCollection.cs @@ -1,4 +1,7 @@ -using Examine; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using Examine; +using Umbraco.Core; namespace Umbraco.Examine { @@ -45,31 +48,42 @@ namespace Umbraco.Examine new FieldDefinition(UmbracoContentIndex.VariesByCultureFieldName, FieldDefinitionTypes.Raw), }; - ///// - ///// Overridden to dynamically add field definitions for culture variations - ///// - ///// - ///// - ///// - //public override bool TryGetValue(string fieldName, out FieldDefinition fieldDefinition) - //{ - // var result = base.TryGetValue(fieldName, out fieldDefinition); - // if (result) return true; - // //if the fieldName is not suffixed with _iso-Code - // var underscoreIndex = fieldName.LastIndexOf('_'); - // if (underscoreIndex == -1) return false; + /// + /// Overridden to dynamically add field definitions for culture variations + /// + /// + /// + /// + /// + /// We need to do this so that we don't have to maintain a huge static list of all field names and their definitions + /// otherwise we'd have to dynamically add/remove definitions anytime languages are added/removed, etc... + /// For example, we have things like `nodeName` and `__Published` which are also used for culture fields like `nodeName_en-us` + /// and we don't want to have a full static list of all of these definitions when we can just define the one definition and then + /// dynamically apply that to culture specific fields. + /// + public override bool TryGetValue(string fieldName, out FieldDefinition fieldDefinition) + { + if (base.TryGetValue(fieldName, out fieldDefinition)) + return true; + //before we use regex to match do some faster simple matching since this is going to execute quite a lot + if (!fieldName.Contains("_")) + return false; + if (!fieldName.Contains("-")) + return false; + var match = ExamineExtensions.CultureIsoCodeFieldNameMatchExpression.Match(fieldName); + if (match.Success && match.Groups.Count == 3) + { + var nonCultureFieldName = match.Groups[1].Value; + //check if there's a definition for this and if so return the field definition for the culture field based on the non-culture field + if (base.TryGetValue(nonCultureFieldName, out fieldDefinition)) + return true; + } + return false; + } - // var isoCode = fieldName.Substring(underscoreIndex); - // if (isoCode.Length < 6) return false; //invalid isoCode - - // var hyphenIndex = isoCode.IndexOf('-'); - // if (hyphenIndex != 3) return false; //invalid isoCode - - // //we'll assume this is a valid isoCode - - //} + } } diff --git a/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs b/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs index 5237b92ab8..d8a53bc829 100644 --- a/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs +++ b/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs @@ -201,7 +201,7 @@ namespace Umbraco.Tests.Cache.PublishedCache {"creatorName", "Shannon"} }; - var result = new SearchResult("1234", 1, 1, () => fields.ToDictionary(x => x.Key, x => new List { x.Value })); + var result = new SearchResult("1234", 1, () => fields.ToDictionary(x => x.Key, x => new List { x.Value })); var store = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new StaticCacheProvider(), ContentTypesCache); var doc = store.CreateFromCacheValues(store.ConvertFromSearchResult(result)); diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 8eb6d086a1..8a6ca29b2c 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -77,7 +77,7 @@ - + 1.8.9 diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index dae0781926..f3324be30f 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -88,7 +88,7 @@ - + diff --git a/src/Umbraco.Web/PublishedContentQuery.cs b/src/Umbraco.Web/PublishedContentQuery.cs index 03a0e8dfb2..2c4d08502e 100644 --- a/src/Umbraco.Web/PublishedContentQuery.cs +++ b/src/Umbraco.Web/PublishedContentQuery.cs @@ -216,17 +216,8 @@ namespace Umbraco.Web else { //get all index fields suffixed with the culture name supplied - var cultureFields = new List(); - var fields = umbIndex.GetFields(); + var cultureFields = umbIndex.GetCultureFields(culture); var qry = searcher.CreateQuery().Field(UmbracoContentIndex.VariesByCultureFieldName, "y"); //must vary by culture - // ReSharper disable once LoopCanBeConvertedToQuery - foreach (var field in fields) - { - var match = CultureIsoCodeFieldName.Match(field); - if (match.Success && match.Groups.Count == 2 && culture.InvariantEquals(match.Groups[1].Value)) - cultureFields.Add(field); - } - qry = qry.And().ManagedQuery(term, cultureFields.ToArray()); results = qry.Execute(count); } @@ -323,13 +314,7 @@ namespace Umbraco.Web } } - /// - /// Matches a culture iso name suffix - /// - /// - /// myFieldName_en-us will match the "en-us" - /// - private static readonly Regex CultureIsoCodeFieldName = new Regex("^[_\\w]+_([a-z]{2}-[a-z0-9]{2,4})$", RegexOptions.Compiled); + #endregion diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 83268bb78e..fd9822d172 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -63,7 +63,7 @@ - + 2.6.2.25