#8835: Merging imported SearchFields from recipes instead of overwriting them (Lombiq Technologies: ORCH-310) (#8870)

* Merging imported SearchFields from recipes instead of overwriting them

* The import process overwrites the given index's configuration, but does not drop the others (if they aren't included).

* Clarifying comments and a bit of code styling [skip ci]

---------

Co-authored-by: Benedek Farkas <benedek.farkas@lombiq.com>
This commit is contained in:
Gábor Domonkos
2025-11-19 15:32:12 +01:00
committed by GitHub
parent 75a4fd59a2
commit 860d6a4aeb
2 changed files with 43 additions and 10 deletions

View File

@@ -5,6 +5,7 @@ using Orchard.ContentManagement.Drivers;
using Orchard.ContentManagement.Handlers;
using Orchard.Indexing;
using Orchard.Localization;
using Orchard.Search.Helpers;
using Orchard.Search.Models;
using Orchard.Search.ViewModels;
@@ -35,7 +36,9 @@ namespace Orchard.Search.Drivers
var model = new SearchSettingsIndexViewModel
{
SelectedIndex = part.SearchIndex,
AvailableIndexes = _indexManager.GetSearchIndexProvider().List().ToList()
AvailableIndexes = _indexManager.HasIndexProvider()
? _indexManager.GetSearchIndexProvider().List().ToList()
: new List<string>()
};
if (updater != null)
@@ -102,7 +105,9 @@ namespace Orchard.Search.Drivers
context.ImportAttribute(part.PartDefinition.Name, "SearchFields", value =>
{
part.Store("SearchFields", value);
part.Store(
"SearchFields",
SearchSettingsHelper.MergeSearchFields(part.SearchFields, SearchSettingsHelper.DeserializeSearchFields(value)));
});
}
}

View File

@@ -27,15 +27,43 @@ namespace Orchard.Search.Helpers
return dictionary;
}
public static string SerializeSearchFields(IDictionary<string, string[]> value)
{
var data = string.Join("|", value.Select(x => string.Format("{0}:{1}", x.Key, string.Join(",", x.Value))));
return data;
}
public static string SerializeSearchFields(IDictionary<string, string[]> value) =>
string.Join("|", value.Select(x => string.Format("{0}:{1}", x.Key, string.Join(",", x.Value))));
public static string[] GetSearchFields(this SearchSettingsPart part, string index)
public static string[] GetSearchFields(this SearchSettingsPart part, string index) =>
part.SearchFields.ContainsKey(index) ? part.SearchFields[index] : new string[0];
/// <summary>
/// Merge existing search index settings with those being imported, with the latter taking precedence.
/// </summary>
/// <param name="existingSearchFields">The existing search indexes with their search fields. The key is the
/// index name and the value is the array of field names.</param>
/// <param name="searchFieldsToAdd">The new search indexes with their search fields to import. The key is the
/// index name and the value is the array of field names.</param>
/// <returns>The merged search indexes with their search fields.</returns>
public static string MergeSearchFields(IDictionary<string, string[]> existingSearchFields, IDictionary<string, string[]> searchFieldsToAdd)
{
return part.SearchFields.ContainsKey(index) ? part.SearchFields[index] : new string[0];
var mergedSearchFields = new Dictionary<string, string[]>();
// Process new search fields to add first so they take precedence.
foreach (var newSearchFieldsToAdd in searchFieldsToAdd.Keys)
{
if (!mergedSearchFields.ContainsKey(newSearchFieldsToAdd))
{
mergedSearchFields.Add(newSearchFieldsToAdd, searchFieldsToAdd[newSearchFieldsToAdd]);
}
}
// Then add existing search fields that are not already present.
foreach (var existingSearchFieldsToAdd in existingSearchFields.Keys)
{
if (!mergedSearchFields.ContainsKey(existingSearchFieldsToAdd))
{
mergedSearchFields.Add(existingSearchFieldsToAdd, existingSearchFields[existingSearchFieldsToAdd]);
}
}
return SerializeSearchFields(mergedSearchFields);
}
}
}
}