Fix previous conversion of SearchAll to async ignoring the SortOrder value from SearchableTree (#12595)
* Fix previous conversion of SearchAll to async ignoring the SortOrder value from SearchableTree * small refactoring Co-authored-by: Paul Woodland <paul.woodland@pwnewmedia.com> Co-authored-by: Michael <michael@crossingpaths.be>
This commit is contained in:
@@ -174,100 +174,98 @@ public class EntityController : UmbracoAuthorizedJsonController
|
||||
return ExamineSearch(query, type, searchFrom, ignoreUserStartNodes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches for all content that the user is allowed to see (based on their allowed sections)
|
||||
/// </summary>
|
||||
/// <param name="query"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// Even though a normal entity search will allow any user to search on a entity type that they may not have access to
|
||||
/// edit, we need
|
||||
/// to filter these results to the sections they are allowed to edit since this search function is explicitly for the
|
||||
/// global search
|
||||
/// so if we showed entities that they weren't allowed to edit they would get errors when clicking on the result.
|
||||
/// The reason a user is allowed to search individual entity types that they are not allowed to edit is because those
|
||||
/// search
|
||||
/// methods might be used in things like pickers in the content editor.
|
||||
/// </remarks>
|
||||
[HttpGet]
|
||||
public async Task<IDictionary<string, TreeSearchResult>> SearchAll(string query)
|
||||
{
|
||||
var result = new ConcurrentDictionary<string, TreeSearchResult>();
|
||||
|
||||
if (string.IsNullOrEmpty(query))
|
||||
/// <summary>
|
||||
/// Searches for all content that the user is allowed to see (based on their allowed sections)
|
||||
/// </summary>
|
||||
/// <param name="query"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// Even though a normal entity search will allow any user to search on a entity type that they may not have access to
|
||||
/// edit, we need
|
||||
/// to filter these results to the sections they are allowed to edit since this search function is explicitly for the
|
||||
/// global search
|
||||
/// so if we showed entities that they weren't allowed to edit they would get errors when clicking on the result.
|
||||
/// The reason a user is allowed to search individual entity types that they are not allowed to edit is because those
|
||||
/// search
|
||||
/// methods might be used in things like pickers in the content editor.
|
||||
/// </remarks>
|
||||
[HttpGet]
|
||||
public async Task<IDictionary<string, TreeSearchResult>> SearchAll(string query)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
var culture = ClientCulture();
|
||||
var allowedSections = _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.AllowedSections.ToArray();
|
||||
|
||||
var searchTasks = new List<Task>();
|
||||
foreach (KeyValuePair<string, SearchableApplicationTree> searchableTree in _searchableTreeCollection
|
||||
.SearchableApplicationTrees.OrderBy(t => t.Value.SortOrder))
|
||||
{
|
||||
if (allowedSections?.Contains(searchableTree.Value.AppAlias) ?? false)
|
||||
if (string.IsNullOrEmpty(query))
|
||||
{
|
||||
Tree? tree = _treeService.GetByAlias(searchableTree.Key);
|
||||
if (tree == null)
|
||||
{
|
||||
continue; //shouldn't occur
|
||||
}
|
||||
return new Dictionary<string, TreeSearchResult>();
|
||||
}
|
||||
|
||||
var rootNodeDisplayName = Tree.GetRootNodeDisplayName(tree, _localizedTextService);
|
||||
if (rootNodeDisplayName is not null)
|
||||
var culture = ClientCulture();
|
||||
var allowedSections = _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.AllowedSections.ToArray();
|
||||
|
||||
var searchTasks = new List<Task<KeyValuePair<string, TreeSearchResult>>>();
|
||||
foreach (KeyValuePair<string, SearchableApplicationTree> searchableTree in _searchableTreeCollection
|
||||
.SearchableApplicationTrees.OrderBy(t => t.Value.SortOrder))
|
||||
{
|
||||
if (allowedSections?.Contains(searchableTree.Value.AppAlias) ?? false)
|
||||
{
|
||||
searchTasks.Add(ExecuteSearchAsync(query, culture, searchableTree, rootNodeDisplayName, result));
|
||||
Tree? tree = _treeService.GetByAlias(searchableTree.Key);
|
||||
if (tree == null)
|
||||
{
|
||||
continue; //shouldn't occur
|
||||
}
|
||||
|
||||
var rootNodeDisplayName = Tree.GetRootNodeDisplayName(tree, _localizedTextService);
|
||||
if (rootNodeDisplayName is not null)
|
||||
{
|
||||
searchTasks.Add(ExecuteSearchAsync(query, culture, searchableTree, rootNodeDisplayName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var taskResults = await Task.WhenAll(searchTasks);
|
||||
|
||||
return new Dictionary<string, TreeSearchResult>(taskResults);
|
||||
}
|
||||
|
||||
await Task.WhenAll(searchTasks);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static async Task ExecuteSearchAsync(
|
||||
string query,
|
||||
string? culture,
|
||||
KeyValuePair<string, SearchableApplicationTree> searchableTree,
|
||||
string rootNodeDisplayName,
|
||||
ConcurrentDictionary<string, TreeSearchResult> result)
|
||||
{
|
||||
ISearchableTree searcher = searchableTree.Value.SearchableTree;
|
||||
const int pageSize = 200;
|
||||
IEnumerable<SearchResultEntity> results = (
|
||||
searcher is ISearchableTreeWithCulture searcherWithCulture
|
||||
? await searcherWithCulture.SearchAsync(query, pageSize, 0, culture: culture)
|
||||
: await searcher.SearchAsync(query, pageSize, 0))
|
||||
.WhereNotNull();
|
||||
|
||||
var searchResult = new TreeSearchResult
|
||||
private static async Task<KeyValuePair<string, TreeSearchResult>> ExecuteSearchAsync(
|
||||
string query,
|
||||
string? culture,
|
||||
KeyValuePair<string, SearchableApplicationTree> searchableTree,
|
||||
string rootNodeDisplayName)
|
||||
{
|
||||
Results = results,
|
||||
TreeAlias = searchableTree.Key,
|
||||
AppAlias = searchableTree.Value.AppAlias,
|
||||
JsFormatterService = searchableTree.Value.FormatterService,
|
||||
JsFormatterMethod = searchableTree.Value.FormatterMethod
|
||||
};
|
||||
ISearchableTree searcher = searchableTree.Value.SearchableTree;
|
||||
const int pageSize = 200;
|
||||
IEnumerable<SearchResultEntity> results = (
|
||||
searcher is ISearchableTreeWithCulture searcherWithCulture
|
||||
? await searcherWithCulture.SearchAsync(query, pageSize, 0, culture: culture)
|
||||
: await searcher.SearchAsync(query, pageSize, 0))
|
||||
.WhereNotNull();
|
||||
|
||||
result.AddOrUpdate(rootNodeDisplayName, _ => searchResult, (_, _) => searchResult);
|
||||
}
|
||||
var searchResult = new TreeSearchResult
|
||||
{
|
||||
Results = results,
|
||||
TreeAlias = searchableTree.Key,
|
||||
AppAlias = searchableTree.Value.AppAlias,
|
||||
JsFormatterService = searchableTree.Value.FormatterService,
|
||||
JsFormatterMethod = searchableTree.Value.FormatterMethod
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path for a given node ID
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
public IConvertToActionResult GetPath(int id, UmbracoEntityTypes type)
|
||||
{
|
||||
ActionResult<EntityBasic?> foundContentResult = GetResultForId(id, type);
|
||||
EntityBasic? foundContent = foundContentResult.Value;
|
||||
if (foundContent is null)
|
||||
{
|
||||
return foundContentResult;
|
||||
return new KeyValuePair<string, TreeSearchResult>(rootNodeDisplayName, searchResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path for a given node ID
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
public IConvertToActionResult GetPath(int id, UmbracoEntityTypes type)
|
||||
{
|
||||
ActionResult<EntityBasic?> foundContentResult = GetResultForId(id, type);
|
||||
EntityBasic? foundContent = foundContentResult.Value;
|
||||
if (foundContent is null)
|
||||
{
|
||||
return foundContentResult;
|
||||
}
|
||||
|
||||
return new ActionResult<IEnumerable<int>>(foundContent.Path
|
||||
.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries).Select(
|
||||
s => int.Parse(s, CultureInfo.InvariantCulture)));
|
||||
|
||||
Reference in New Issue
Block a user