diff --git a/src/Umbraco.Examine/ContentValueSetBuilder.cs b/src/Umbraco.Examine/ContentValueSetBuilder.cs
index 07e5e4565b..18cd5e311f 100644
--- a/src/Umbraco.Examine/ContentValueSetBuilder.cs
+++ b/src/Umbraco.Examine/ContentValueSetBuilder.cs
@@ -44,7 +44,7 @@ namespace Umbraco.Examine
{"icon", c.ContentType.Icon.Yield()},
{UmbracoExamineIndex.PublishedFieldName, new object[] {c.Published ? 1 : 0}}, //Always add invariant published value
{"id", new object[] {c.Id}},
- {"key", new object[] {c.Key}},
+ {UmbracoExamineIndex.NodeKeyFieldName, new object[] {c.Key}},
{"parentID", new object[] {c.Level > 1 ? c.ParentId : -1}},
{"level", new object[] {c.Level}},
{"creatorID", new object[] {c.CreatorId}},
@@ -61,12 +61,12 @@ namespace Umbraco.Examine
{"writerName",(c.GetWriterProfile(_userService)?.Name ?? "??").Yield() },
{"writerID", new object[] {c.WriterId}},
{"template", new object[] {c.Template?.Id ?? 0}},
- {UmbracoContentIndex.VariesByCultureFieldName, new object[] {0}},
+ {UmbracoContentIndex.VariesByCultureFieldName, new object[] {"n"}},
};
if (isVariant)
{
- values[UmbracoContentIndex.VariesByCultureFieldName] = new object[] { 1 };
+ values[UmbracoContentIndex.VariesByCultureFieldName] = new object[] { "y" };
foreach (var culture in c.AvailableCultures)
{
diff --git a/src/Umbraco.Examine/ContentValueSetValidator.cs b/src/Umbraco.Examine/ContentValueSetValidator.cs
index d4f6ceb15f..bcceafc272 100644
--- a/src/Umbraco.Examine/ContentValueSetValidator.cs
+++ b/src/Umbraco.Examine/ContentValueSetValidator.cs
@@ -100,7 +100,7 @@ namespace Umbraco.Examine
//deal with variants, if there are unpublished variants than we need to remove them from the value set
if (valueSet.Values.TryGetValue(UmbracoContentIndex.VariesByCultureFieldName, out var variesByCulture)
- && variesByCulture.Count > 0 && variesByCulture[0].Equals(1))
+ && variesByCulture.Count > 0 && variesByCulture[0].Equals("y"))
{
//so this valueset is for a content that varies by culture, now check for non-published cultures and remove those values
foreach(var publishField in valueSet.Values.Where(x => x.Key.StartsWith($"{UmbracoExamineIndex.PublishedFieldName}_")).ToList())
diff --git a/src/Umbraco.Examine/MediaValueSetBuilder.cs b/src/Umbraco.Examine/MediaValueSetBuilder.cs
index f0e5e895e6..2676093eeb 100644
--- a/src/Umbraco.Examine/MediaValueSetBuilder.cs
+++ b/src/Umbraco.Examine/MediaValueSetBuilder.cs
@@ -32,7 +32,7 @@ namespace Umbraco.Examine
{
{"icon", m.ContentType.Icon.Yield()},
{"id", new object[] {m.Id}},
- {"key", new object[] {m.Key}},
+ {UmbracoExamineIndex.NodeKeyFieldName, new object[] {m.Key}},
{"parentID", new object[] {m.Level > 1 ? m.ParentId : -1}},
{"level", new object[] {m.Level}},
{"creatorID", new object[] {m.CreatorId}},
diff --git a/src/Umbraco.Examine/MemberValueSetBuilder.cs b/src/Umbraco.Examine/MemberValueSetBuilder.cs
index 9864aba18d..d9f0b7806d 100644
--- a/src/Umbraco.Examine/MemberValueSetBuilder.cs
+++ b/src/Umbraco.Examine/MemberValueSetBuilder.cs
@@ -23,7 +23,7 @@ namespace Umbraco.Examine
{
{"icon", m.ContentType.Icon.Yield()},
{"id", new object[] {m.Id}},
- {"key", new object[] {m.Key}},
+ {UmbracoExamineIndex.NodeKeyFieldName, new object[] {m.Key}},
{"parentID", new object[] {m.Level > 1 ? m.ParentId : -1}},
{"level", new object[] {m.Level}},
{"creatorID", new object[] {m.CreatorId}},
diff --git a/src/Umbraco.Examine/Umbraco.Examine.csproj b/src/Umbraco.Examine/Umbraco.Examine.csproj
index a68131da0d..6864329bff 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 97d1f68727..43c9553400 100644
--- a/src/Umbraco.Examine/UmbracoFieldDefinitionCollection.cs
+++ b/src/Umbraco.Examine/UmbracoFieldDefinitionCollection.cs
@@ -30,7 +30,7 @@ namespace Umbraco.Examine
new FieldDefinition("createDate", FieldDefinitionTypes.DateTime),
new FieldDefinition("updateDate", FieldDefinitionTypes.DateTime),
- new FieldDefinition("key", FieldDefinitionTypes.InvariantCultureIgnoreCase),
+ new FieldDefinition(UmbracoExamineIndex.NodeKeyFieldName, FieldDefinitionTypes.InvariantCultureIgnoreCase),
new FieldDefinition("version", FieldDefinitionTypes.Raw),
new FieldDefinition("nodeType", FieldDefinitionTypes.InvariantCultureIgnoreCase),
new FieldDefinition("template", FieldDefinitionTypes.Raw),
@@ -40,9 +40,9 @@ namespace Umbraco.Examine
new FieldDefinition("email", FieldDefinitionTypes.EmailAddress),
new FieldDefinition(UmbracoExamineIndex.PublishedFieldName, FieldDefinitionTypes.Raw),
- new FieldDefinition(UmbracoExamineIndex.NodeKeyFieldName, FieldDefinitionTypes.Raw),
new FieldDefinition(UmbracoExamineIndex.IndexPathFieldName, FieldDefinitionTypes.Raw),
- new FieldDefinition(UmbracoExamineIndex.IconFieldName, FieldDefinitionTypes.Raw)
+ new FieldDefinition(UmbracoExamineIndex.IconFieldName, FieldDefinitionTypes.Raw),
+ new FieldDefinition(UmbracoContentIndex.VariesByCultureFieldName, FieldDefinitionTypes.Raw),
};
/////
diff --git a/src/Umbraco.Examine/UmbracoMemberIndex.cs b/src/Umbraco.Examine/UmbracoMemberIndex.cs
index 9782f94fe4..fbf8a1cc0f 100644
--- a/src/Umbraco.Examine/UmbracoMemberIndex.cs
+++ b/src/Umbraco.Examine/UmbracoMemberIndex.cs
@@ -32,35 +32,6 @@ namespace Umbraco.Examine
base(name, luceneDirectory, fieldDefinitions, analyzer, profilingLogger, validator)
{
}
-
- ///
- /// Overridden to ensure that the umbraco system field definitions are in place
- ///
- ///
- ///
- protected override FieldValueTypeCollection CreateFieldValueTypes(IReadOnlyDictionary indexValueTypesFactory = null)
- {
- var keyDef = new FieldDefinition("__key", FieldDefinitionTypes.Raw);
- FieldDefinitionCollection.TryAdd(keyDef);
-
- return base.CreateFieldValueTypes(indexValueTypesFactory);
- }
-
- ///
- /// Ensure some custom values are added to the index
- ///
- ///
- protected override void OnTransformingIndexValues(IndexingItemEventArgs e)
- {
- base.OnTransformingIndexValues(e);
-
- if (e.ValueSet.Values.TryGetValue("key", out var key) && e.ValueSet.Values.ContainsKey("__key") == false)
- {
- //double __ prefix means it will be indexed as culture invariant
- e.ValueSet.Values["__key"] = key;
- }
-
- }
-
+
}
}
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs
index c5b8e21870..5f3a51f4f6 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs
@@ -195,7 +195,7 @@ namespace Umbraco.Tests.PublishedContent
[Test]
public void PublishedContentQueryTypedContentList()
{
- var query = new PublishedContentQuery(UmbracoContext.Current.ContentCache, UmbracoContext.Current.MediaCache);
+ var query = new PublishedContentQuery(UmbracoContext.Current.ContentCache, UmbracoContext.Current.MediaCache, UmbracoContext.Current.VariationContextAccessor);
var result = query.Content(new[] { 1, 2, 4 }).ToArray();
Assert.AreEqual(2, result.Length);
Assert.AreEqual(1, result[0].Id);
diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj
index bed1281bf8..8eb6d086a1 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.Tests/UmbracoExamine/UmbracoContentValueSetValidatorTests.cs b/src/Umbraco.Tests/UmbracoExamine/UmbracoContentValueSetValidatorTests.cs
index 8d7a446ccb..08db6b35e0 100644
--- a/src/Umbraco.Tests/UmbracoExamine/UmbracoContentValueSetValidatorTests.cs
+++ b/src/Umbraco.Tests/UmbracoExamine/UmbracoContentValueSetValidatorTests.cs
@@ -237,7 +237,7 @@ namespace Umbraco.Tests.UmbracoExamine
{
["hello"] = "world",
["path"] = "-1,555",
- [UmbracoContentIndex.VariesByCultureFieldName] = 1,
+ [UmbracoContentIndex.VariesByCultureFieldName] = "y",
[UmbracoExamineIndex.PublishedFieldName] = 0
}));
Assert.AreEqual(ValueSetValidationResult.Failed, result);
@@ -247,7 +247,7 @@ namespace Umbraco.Tests.UmbracoExamine
{
["hello"] = "world",
["path"] = "-1,555",
- [UmbracoContentIndex.VariesByCultureFieldName] = 1,
+ [UmbracoContentIndex.VariesByCultureFieldName] = "y",
[UmbracoExamineIndex.PublishedFieldName] = 1
}));
Assert.AreEqual(ValueSetValidationResult.Valid, result);
@@ -257,7 +257,7 @@ namespace Umbraco.Tests.UmbracoExamine
{
["hello"] = "world",
["path"] = "-1,555",
- [UmbracoContentIndex.VariesByCultureFieldName] = 1,
+ [UmbracoContentIndex.VariesByCultureFieldName] = "y",
[$"{UmbracoExamineIndex.PublishedFieldName}_en-us"] = 1,
["hello_en-us"] = "world",
["title_en-us"] = "my title",
diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
index 2fc199d06a..dae0781926 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/ExamineExtensions.cs b/src/Umbraco.Web/ExamineExtensions.cs
index f1ed6c0659..9a9fa98d95 100644
--- a/src/Umbraco.Web/ExamineExtensions.cs
+++ b/src/Umbraco.Web/ExamineExtensions.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Linq;
using Examine;
using Umbraco.Core;
diff --git a/src/Umbraco.Web/PublishedContentQuery.cs b/src/Umbraco.Web/PublishedContentQuery.cs
index 3d8f36ec1a..03a0e8dfb2 100644
--- a/src/Umbraco.Web/PublishedContentQuery.cs
+++ b/src/Umbraco.Web/PublishedContentQuery.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
@@ -24,16 +25,19 @@ namespace Umbraco.Web
{
private readonly IPublishedContentCache _contentCache;
private readonly IPublishedMediaCache _mediaCache;
+ private readonly IVariationContextAccessor _variationContextAccessor;
///
/// Constructor used to return results from the caches
///
///
///
- public PublishedContentQuery(IPublishedContentCache contentCache, IPublishedMediaCache mediaCache)
+ ///
+ public PublishedContentQuery(IPublishedContentCache contentCache, IPublishedMediaCache mediaCache, IVariationContextAccessor variationContextAccessor)
{
_contentCache = contentCache ?? throw new ArgumentNullException(nameof(contentCache));
_mediaCache = mediaCache ?? throw new ArgumentNullException(nameof(mediaCache));
+ _variationContextAccessor = variationContextAccessor ?? throw new ArgumentNullException(nameof(variationContextAccessor));
}
#region Content
@@ -201,6 +205,9 @@ namespace Umbraco.Web
// default to max 500 results
var count = skip == 0 && take == 0 ? 500 : skip + take;
+ //set this to the specific culture or to the culture in the request
+ culture = culture ?? _variationContextAccessor.VariationContext.Culture;
+
ISearchResults results;
if (culture.IsNullOrWhiteSpace())
{
@@ -211,7 +218,7 @@ namespace Umbraco.Web
//get all index fields suffixed with the culture name supplied
var cultureFields = new List();
var fields = umbIndex.GetFields();
- var qry = searcher.CreateQuery().Field(UmbracoContentIndex.VariesByCultureFieldName, 1); //must vary by culture
+ var qry = searcher.CreateQuery().Field(UmbracoContentIndex.VariesByCultureFieldName, "y"); //must vary by culture
// ReSharper disable once LoopCanBeConvertedToQuery
foreach (var field in fields)
{
@@ -225,7 +232,8 @@ namespace Umbraco.Web
}
totalRecords = results.TotalItemCount;
- return results.ToPublishedSearchResults(_contentCache);
+
+ return new CultureContextualSearchResults(results.ToPublishedSearchResults(_contentCache), _variationContextAccessor, culture);
}
///
@@ -245,6 +253,76 @@ namespace Umbraco.Web
return results.ToPublishedSearchResults(_contentCache);
}
+ ///
+ /// This is used to contextualize the values in the search results when enumerating over them so that the correct culture values are used
+ ///
+ private class CultureContextualSearchResults : IEnumerable
+ {
+ private readonly IEnumerable _wrapped;
+ private readonly IVariationContextAccessor _variationContextAccessor;
+ private readonly string _culture;
+
+ public CultureContextualSearchResults(IEnumerable wrapped, IVariationContextAccessor variationContextAccessor, string culture)
+ {
+ _wrapped = wrapped;
+ _variationContextAccessor = variationContextAccessor;
+ _culture = culture;
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ //We need to change the current culture to what is requested and then change it back
+ var originalContext = _variationContextAccessor.VariationContext;
+ if (!_culture.IsNullOrWhiteSpace() && !_culture.InvariantEquals(originalContext.Culture))
+ _variationContextAccessor.VariationContext = new VariationContext(_culture);
+
+ //now the IPublishedContent returned will be contextualized to the culture specified and will be reset when the enumerator is disposed
+ return new CultureContextualSearchResultsEnumerator(_wrapped.GetEnumerator(), _variationContextAccessor, originalContext);
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ ///
+ /// Resets the variation context when this is disposed
+ ///
+ private class CultureContextualSearchResultsEnumerator : IEnumerator
+ {
+ private readonly IEnumerator _wrapped;
+ private readonly IVariationContextAccessor _variationContextAccessor;
+ private readonly VariationContext _originalContext;
+
+ public CultureContextualSearchResultsEnumerator(IEnumerator wrapped, IVariationContextAccessor variationContextAccessor, VariationContext originalContext)
+ {
+ _wrapped = wrapped;
+ _variationContextAccessor = variationContextAccessor;
+ _originalContext = originalContext;
+ }
+
+ public void Dispose()
+ {
+ _wrapped.Dispose();
+ //reset
+ _variationContextAccessor.VariationContext = _originalContext;
+ }
+
+ public bool MoveNext()
+ {
+ return _wrapped.MoveNext();
+ }
+
+ public void Reset()
+ {
+ _wrapped.Reset();
+ }
+
+ public PublishedSearchResult Current => _wrapped.Current;
+ object IEnumerator.Current => Current;
+ }
+ }
+
///
/// Matches a culture iso name suffix
///
diff --git a/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs b/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs
index 99b4e22b5a..1f01270bc6 100644
--- a/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs
+++ b/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs
@@ -63,7 +63,7 @@ namespace Umbraco.Web.Routing
var error404 = NotFoundHandlerHelper.GetCurrentNotFoundPageId(
_contentConfigSection.Error404Collection.ToArray(),
_entityService,
- new PublishedContentQuery(frequest.UmbracoContext.ContentCache, frequest.UmbracoContext.MediaCache),
+ new PublishedContentQuery(frequest.UmbracoContext.ContentCache, frequest.UmbracoContext.MediaCache, frequest.UmbracoContext.VariationContextAccessor),
errorCulture);
IPublishedContent content = null;
diff --git a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs
index 47e73d383c..a60e5f1d1b 100644
--- a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs
+++ b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs
@@ -367,9 +367,9 @@ namespace Umbraco.Web.Search
{
m.AdditionalData["Email"] = result.Values["email"];
}
- if (result.Values.ContainsKey("__key") && result.Values["__key"] != null)
+ if (result.Values.ContainsKey(UmbracoExamineIndex.NodeKeyFieldName) && result.Values[UmbracoExamineIndex.NodeKeyFieldName] != null)
{
- if (Guid.TryParse(result.Values["__key"], out var key))
+ if (Guid.TryParse(result.Values[UmbracoExamineIndex.NodeKeyFieldName], out var key))
{
m.Key = key;
}
@@ -416,7 +416,7 @@ namespace Umbraco.Web.Search
if (intId.Success)
{
//if it varies by culture, return the default language URL
- if (result.Values.TryGetValue(UmbracoContentIndex.VariesByCultureFieldName, out var varies) && varies == "1")
+ if (result.Values.TryGetValue(UmbracoContentIndex.VariesByCultureFieldName, out var varies) && varies == "y")
{
entity.AdditionalData["Url"] = _umbracoHelper.Url(intId.Result, defaultLang);
}
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index 7a695ff4ef..83268bb78e 100755
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -63,7 +63,7 @@
-
+
2.6.2.25
diff --git a/src/Umbraco.Web/UmbracoHelper.cs b/src/Umbraco.Web/UmbracoHelper.cs
index 6914efb3e2..f4be2a1700 100644
--- a/src/Umbraco.Web/UmbracoHelper.cs
+++ b/src/Umbraco.Web/UmbracoHelper.cs
@@ -106,7 +106,7 @@ namespace Umbraco.Web
/// Gets the query context.
///
public IPublishedContentQuery ContentQuery => _query ??
- (_query = new PublishedContentQuery(UmbracoContext.ContentCache, UmbracoContext.MediaCache));
+ (_query = new PublishedContentQuery(UmbracoContext.ContentCache, UmbracoContext.MediaCache, UmbracoContext.VariationContextAccessor));
///
/// Gets the Umbraco context.