Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions src/Umbraco.Infrastructure/Examine/ContentValueSetValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace Umbraco.Cms.Infrastructure.Examine;
public class ContentValueSetValidator : ValueSetValidator, IContentValueSetValidator
{
private const string PathKey = "path";
private static readonly IEnumerable<string> ValidCategories = new[] {IndexTypes.Content, IndexTypes.Media};
private static readonly IEnumerable<string> ValidCategories = new[] { IndexTypes.Content, IndexTypes.Media };
private readonly IPublicAccessService? _publicAccessService;
private readonly IScopeProvider? _scopeProvider;

Expand Down Expand Up @@ -105,15 +105,19 @@ public bool ValidateProtectedContent(string path, string category)

public override ValueSetValidationResult Validate(ValueSet valueSet)
{
// Notes on status on the result:
// A result status of filtered means that this whole value set result is to be filtered from the index
// For example the path is incorrect or it is in the recycle bin
// It does not mean that the values it contains have been through a filtering (for example if an language variant is not published)
// See notes on issue 11383

ValueSetValidationResult baseValidate = base.Validate(valueSet);
valueSet = baseValidate.ValueSet;
if (baseValidate.Status == ValueSetValidationStatus.Failed)
{
return new ValueSetValidationResult(ValueSetValidationStatus.Failed, valueSet);
}

var isFiltered = baseValidate.Status == ValueSetValidationStatus.Filtered;

var filteredValues = valueSet.Values.ToDictionary(x => x.Key, x => x.Value.ToList());
//check for published content
if (valueSet.Category == IndexTypes.Content && PublishedValuesOnly)
Expand All @@ -133,18 +137,15 @@ public override ValueSetValidationResult Validate(ValueSet valueSet)
&& 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 (KeyValuePair<string, IReadOnlyList<object>> publishField in valueSet.Values
.Where(x => x.Key.StartsWith($"{UmbracoExamineFieldNames.PublishedFieldName}_")).ToList())
foreach (KeyValuePair<string, IReadOnlyList<object>> publishField in valueSet.Values.Where(x => x.Key.StartsWith($"{UmbracoExamineFieldNames.PublishedFieldName}_")).ToList())
{
if (publishField.Value.Count <= 0 || !publishField.Value[0].Equals("y"))
{
//this culture is not published, so remove all of these culture values
var cultureSuffix = publishField.Key.Substring(publishField.Key.LastIndexOf('_'));
foreach (KeyValuePair<string, IReadOnlyList<object>> cultureField in valueSet.Values
.Where(x => x.Key.InvariantEndsWith(cultureSuffix)).ToList())
foreach (KeyValuePair<string, IReadOnlyList<object>> cultureField in valueSet.Values.Where(x => x.Key.InvariantEndsWith(cultureSuffix)).ToList())
{
filteredValues.Remove(cultureField.Key);
isFiltered = true;
}
}
}
Expand Down Expand Up @@ -175,17 +176,18 @@ public override ValueSetValidationResult Validate(ValueSet valueSet)
var path = pathValues[0].ToString();

var filteredValueSet = new ValueSet(valueSet.Id, valueSet.Category, valueSet.ItemType, filteredValues.ToDictionary(x => x.Key, x => (IEnumerable<object>)x.Value));

// We need to validate the path of the content based on ParentId, protected content and recycle bin rules.
// We cannot return FAILED here because we need the value set to get into the indexer and then deal with it from there
// because we need to remove anything that doesn't pass by protected content in the cases that umbraco data is moved to an illegal parent.
// Therefore we return FILTERED to indicate this whole set needs to be filtered out
if (!ValidatePath(path!, valueSet.Category)
|| !ValidateRecycleBin(path!, valueSet.Category)
|| !ValidateProtectedContent(path!, valueSet.Category))
{
return new ValueSetValidationResult(ValueSetValidationStatus.Filtered, filteredValueSet);
}

return new ValueSetValidationResult(
isFiltered ? ValueSetValidationStatus.Filtered : ValueSetValidationStatus.Valid, filteredValueSet);
return new ValueSetValidationResult(ValueSetValidationStatus.Valid, filteredValueSet);
}
}
14 changes: 8 additions & 6 deletions src/Umbraco.Infrastructure/Examine/ValueSetValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ public ValueSetValidator(

public virtual ValueSetValidationResult Validate(ValueSet valueSet)
{
/* Notes on status on the result:
* A result status of filtered means that this whole value set result is to be filtered from the index
* For example the path is incorrect or it is in the recycle bin
* It does not mean that the values it contains have been through a filtering (for example if an language variant is not published)
* See notes on issue 11383 */

if (ValidIndexCategories != null && !ValidIndexCategories.InvariantContains(valueSet.Category))
{
return new ValueSetValidationResult(ValueSetValidationStatus.Failed, valueSet);
Expand All @@ -74,8 +80,6 @@ public virtual ValueSetValidationResult Validate(ValueSet valueSet)
return new ValueSetValidationResult(ValueSetValidationStatus.Failed, valueSet);
}

var isFiltered = false;

var filteredValues = valueSet.Values.ToDictionary(x => x.Key, x => x.Value.ToList());

// filter based on the fields provided (if any)
Expand All @@ -86,19 +90,17 @@ public virtual ValueSetValidationResult Validate(ValueSet valueSet)
if (IncludeFields != null && !IncludeFields.InvariantContains(key))
{
filteredValues.Remove(key); // remove any value with a key that doesn't match the inclusion list
isFiltered = true;
}

if (ExcludeFields != null && ExcludeFields.InvariantContains(key))
{
filteredValues.Remove(key); // remove any value with a key that matches the exclusion list
isFiltered = true;
}

}
}

var filteredValueSet = new ValueSet(valueSet.Id, valueSet.Category, valueSet.ItemType, filteredValues.ToDictionary(x => x.Key, x => (IEnumerable<object>)x.Value));
return new ValueSetValidationResult(
isFiltered ? ValueSetValidationStatus.Filtered : ValueSetValidationStatus.Valid, filteredValueSet);
return new ValueSetValidationResult(ValueSetValidationStatus.Valid, filteredValueSet);
}
}
2 changes: 1 addition & 1 deletion src/Umbraco.Web.Common/Views/UmbracoViewPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public UmbracoHelper Umbraco

_helper = Context.RequestServices.GetRequiredService<UmbracoHelper>();

TModel model = ViewData.Model;
TModel? model = ViewData.Model;
var content = model as IPublishedContent;

if (content is null && model is IContentModel contentModel)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,9 @@ public void Inclusion_Field_List()
"test-content",
new { hello = "world", path = "-1,555", world = "your oyster" });
var result = validator.Validate(valueSet);
Assert.AreEqual(ValueSetValidationStatus.Filtered, result.Status);

// Note - Result is still valid, excluded is not the same as filtered.
Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status);

Assert.IsFalse(result.ValueSet.Values.ContainsKey("path"));
Assert.IsTrue(result.ValueSet.Values.ContainsKey("hello"));
Expand All @@ -128,7 +130,9 @@ public void Exclusion_Field_List()
"test-content",
new { hello = "world", path = "-1,555", world = "your oyster" });
var result = validator.Validate(valueSet);
Assert.AreEqual(ValueSetValidationStatus.Filtered, result.Status);

// Note - Result is still valid, excluded is not the same as filtered.
Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status);

Assert.IsTrue(result.ValueSet.Values.ContainsKey("path"));
Assert.IsFalse(result.ValueSet.Values.ContainsKey("hello"));
Expand All @@ -150,7 +154,9 @@ public void Inclusion_Exclusion_Field_List()
"test-content",
new { hello = "world", path = "-1,555", world = "your oyster" });
var result = validator.Validate(valueSet);
Assert.AreEqual(ValueSetValidationStatus.Filtered, result.Status);

// Note - Result is still valid, excluded is not the same as filtered.
Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status);

Assert.IsFalse(result.ValueSet.Values.ContainsKey("path"));
Assert.IsTrue(result.ValueSet.Values.ContainsKey("hello"));
Expand Down Expand Up @@ -416,7 +422,9 @@ public void Published_Only_With_Variants()
Assert.IsTrue(valueSet.Values.ContainsKey("title_es-ES"));

result = validator.Validate(valueSet);
Assert.AreEqual(ValueSetValidationStatus.Filtered, result.Status);

// Note - Result is still valid, excluded is not the same as filtered.
Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status);

Assert.AreEqual(7, result.ValueSet.Values.Count()); // filtered to 7 values (removes es-es values)
Assert.IsFalse(result.ValueSet.Values.ContainsKey($"{UmbracoExamineFieldNames.PublishedFieldName}_es-es"));
Expand Down