diff --git a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs
index c3c3dc75ce..b351cca972 100644
--- a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs
+++ b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs
@@ -7,6 +7,8 @@ using Examine;
using Umbraco.Core;
using Umbraco.Core.Mapping;
using Umbraco.Core.Models;
+using Umbraco.Core.Models.Entities;
+using Umbraco.Core.Persistence;
using Umbraco.Core.Services;
using Umbraco.Examine;
using Umbraco.Web.Models.ContentEditing;
@@ -14,6 +16,7 @@ using Umbraco.Web.Trees;
namespace Umbraco.Web.Search
{
+
///
/// Used for internal Umbraco implementations of
///
@@ -24,22 +27,25 @@ namespace Umbraco.Web.Search
private readonly ILocalizationService _languageService;
private readonly IEntityService _entityService;
private readonly UmbracoMapper _mapper;
+ private readonly ISqlContext _sqlContext;
public UmbracoTreeSearcher(IExamineManager examineManager,
UmbracoContext umbracoContext,
ILocalizationService languageService,
IEntityService entityService,
- UmbracoMapper mapper)
+ UmbracoMapper mapper,
+ ISqlContext sqlContext)
{
_examineManager = examineManager ?? throw new ArgumentNullException(nameof(examineManager));
_umbracoContext = umbracoContext;
_languageService = languageService;
_entityService = entityService;
_mapper = mapper;
+ _sqlContext = sqlContext;
}
///
- /// Searches for results based on the entity type
+ /// Searches Examine for results based on the entity type
///
///
///
@@ -61,7 +67,7 @@ namespace Umbraco.Web.Search
string type;
var indexName = Constants.UmbracoIndexes.InternalIndexName;
- var fields = new[] { "id", "__NodeId" };
+ var fields = new[] { "id", "__NodeId", "__Key" };
// TODO: WE should try to allow passing in a lucene raw query, however we will still need to do some manual string
// manipulation for things like start paths, member types, etc...
@@ -70,12 +76,18 @@ namespace Umbraco.Web.Search
//}
+ //special GUID check since if a user searches on one specifically we need to escape it
+ if (Guid.TryParse(query, out var g))
+ {
+ query = "\"" + g.ToString() + "\"";
+ }
+
switch (entityType)
{
case UmbracoEntityTypes.Member:
indexName = Constants.UmbracoIndexes.MembersIndexName;
type = "member";
- fields = new[] { "id", "__NodeId", "email", "loginName" };
+ fields = new[] { "id", "__NodeId", "__Key", "email", "loginName" };
if (searchFrom != null && searchFrom != Constants.Conventions.MemberTypes.AllMembersListId && searchFrom.Trim() != "-1")
{
sb.Append("+__NodeTypeAlias:");
@@ -129,6 +141,26 @@ namespace Umbraco.Web.Search
}
}
+ ///
+ /// Searches with the for results based on the entity type
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public IEnumerable EntitySearch(UmbracoObjectTypes objectType, string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null)
+ {
+ //if it's a GUID, match it
+ Guid.TryParse(query, out var g);
+
+ var results = _entityService.GetPagedDescendants(objectType, pageIndex, pageSize, out totalFound,
+ filter: _sqlContext.Query().Where(x => x.Name.Contains(query) || x.Key == g));
+ return _mapper.MapEnumerable(results);
+ }
+
private bool BuildQuery(StringBuilder sb, string query, string searchFrom, string[] fields, string type)
{
//build a lucene query:
diff --git a/src/Umbraco.Web/Trees/ContentTreeController.cs b/src/Umbraco.Web/Trees/ContentTreeController.cs
index 970191e510..3373a6fa8b 100644
--- a/src/Umbraco.Web/Trees/ContentTreeController.cs
+++ b/src/Umbraco.Web/Trees/ContentTreeController.cs
@@ -15,6 +15,10 @@ using Umbraco.Web.WebApi.Filters;
using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.Search;
using Constants = Umbraco.Core.Constants;
+using Umbraco.Core.Cache;
+using Umbraco.Core.Configuration;
+using Umbraco.Core.Logging;
+using Umbraco.Core.Persistence;
namespace Umbraco.Web.Trees
{
@@ -36,20 +40,21 @@ namespace Umbraco.Web.Trees
private readonly UmbracoTreeSearcher _treeSearcher;
private readonly ActionCollection _actions;
- public ContentTreeController(UmbracoTreeSearcher treeSearcher, ActionCollection actions)
- {
- _treeSearcher = treeSearcher;
- _actions = actions;
- }
-
protected override int RecycleBinId => Constants.System.RecycleBinContent;
protected override bool RecycleBinSmells => Services.ContentService.RecycleBinSmells();
private int[] _userStartNodes;
+
protected override int[] UserStartNodes
=> _userStartNodes ?? (_userStartNodes = Security.CurrentUser.CalculateContentStartNodeIds(Services.EntityService));
+ public ContentTreeController(UmbracoTreeSearcher treeSearcher, ActionCollection actions, IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ISqlContext sqlContext, ServiceContext services, AppCaches appCaches, IProfilingLogger logger, IRuntimeState runtimeState, UmbracoHelper umbracoHelper) : base(globalSettings, umbracoContextAccessor, sqlContext, services, appCaches, logger, runtimeState, umbracoHelper)
+ {
+ _treeSearcher = treeSearcher;
+ _actions = actions;
+ }
+
///
protected override TreeNode GetSingleTreeNode(IEntitySlim entity, string parentId, FormDataCollection queryStrings)
{
diff --git a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs
index 015c91cb81..c3458f93a2 100644
--- a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs
+++ b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs
@@ -18,11 +18,23 @@ using System.Web.Http.ModelBinding;
using Umbraco.Web.Actions;
using Umbraco.Web.Composing;
using Umbraco.Core.Security;
+using Umbraco.Core.Cache;
+using Umbraco.Core.Configuration;
+using Umbraco.Core.Persistence;
namespace Umbraco.Web.Trees
{
public abstract class ContentTreeControllerBase : TreeController
{
+
+ protected ContentTreeControllerBase(IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ISqlContext sqlContext, ServiceContext services, AppCaches appCaches, IProfilingLogger logger, IRuntimeState runtimeState, UmbracoHelper umbracoHelper) : base(globalSettings, umbracoContextAccessor, sqlContext, services, appCaches, logger, runtimeState, umbracoHelper)
+ {
+ }
+
+ protected ContentTreeControllerBase()
+ {
+ }
+
#region Actions
///
@@ -529,6 +541,8 @@ namespace Umbraco.Web.Trees
private bool? _ignoreUserStartNodes;
+
+
///
/// If the request should allows a user to choose nodes that they normally don't have access to
///
diff --git a/src/Umbraco.Web/Trees/ContentTypeTreeController.cs b/src/Umbraco.Web/Trees/ContentTypeTreeController.cs
index bead6aa141..a865df8f36 100644
--- a/src/Umbraco.Web/Trees/ContentTypeTreeController.cs
+++ b/src/Umbraco.Web/Trees/ContentTypeTreeController.cs
@@ -3,11 +3,17 @@ using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Formatting;
using Umbraco.Core;
+using Umbraco.Core.Cache;
+using Umbraco.Core.Configuration;
+using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Entities;
+using Umbraco.Core.Persistence;
+using Umbraco.Core.Services;
using Umbraco.Web.Actions;
using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.Models.Trees;
+using Umbraco.Web.Search;
using Umbraco.Web.WebApi.Filters;
namespace Umbraco.Web.Trees
@@ -18,6 +24,13 @@ namespace Umbraco.Web.Trees
[CoreTree]
public class ContentTypeTreeController : TreeController, ISearchableTree
{
+ private readonly UmbracoTreeSearcher _treeSearcher;
+
+ public ContentTypeTreeController(UmbracoTreeSearcher treeSearcher, IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ISqlContext sqlContext, ServiceContext services, AppCaches appCaches, IProfilingLogger logger, IRuntimeState runtimeState, UmbracoHelper umbracoHelper) : base(globalSettings, umbracoContextAccessor, sqlContext, services, appCaches, logger, runtimeState, umbracoHelper)
+ {
+ _treeSearcher = treeSearcher;
+ }
+
protected override TreeNode CreateRootNode(FormDataCollection queryStrings)
{
var root = base.CreateRootNode(queryStrings);
@@ -135,10 +148,7 @@ namespace Umbraco.Web.Trees
}
public IEnumerable Search(string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null)
- {
- var results = Services.EntityService.GetPagedDescendants(UmbracoObjectTypes.DocumentType, pageIndex, pageSize, out totalFound,
- filter: SqlContext.Query().Where(x => x.Name.Contains(query)));
- return Mapper.MapEnumerable(results);
- }
+ => _treeSearcher.EntitySearch(UmbracoObjectTypes.DocumentType, query, pageSize, pageIndex, out totalFound, searchFrom);
+
}
}
diff --git a/src/Umbraco.Web/Trees/DataTypeTreeController.cs b/src/Umbraco.Web/Trees/DataTypeTreeController.cs
index 2465b4d45a..4e5b1df631 100644
--- a/src/Umbraco.Web/Trees/DataTypeTreeController.cs
+++ b/src/Umbraco.Web/Trees/DataTypeTreeController.cs
@@ -12,6 +12,11 @@ using Umbraco.Core.Services;
using Umbraco.Web.Actions;
using Umbraco.Web.Models.ContentEditing;
using Constants = Umbraco.Core.Constants;
+using Umbraco.Core.Cache;
+using Umbraco.Core.Configuration;
+using Umbraco.Core.Logging;
+using Umbraco.Core.Persistence;
+using Umbraco.Web.Search;
namespace Umbraco.Web.Trees
{
@@ -21,6 +26,13 @@ namespace Umbraco.Web.Trees
[CoreTree]
public class DataTypeTreeController : TreeController, ISearchableTree
{
+ private readonly UmbracoTreeSearcher _treeSearcher;
+
+ public DataTypeTreeController(UmbracoTreeSearcher treeSearcher, IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ISqlContext sqlContext, ServiceContext services, AppCaches appCaches, IProfilingLogger logger, IRuntimeState runtimeState, UmbracoHelper umbracoHelper) : base(globalSettings, umbracoContextAccessor, sqlContext, services, appCaches, logger, runtimeState, umbracoHelper)
+ {
+ _treeSearcher = treeSearcher;
+ }
+
protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings)
{
var intId = id.TryConvertTo();
@@ -148,10 +160,6 @@ namespace Umbraco.Web.Trees
}
public IEnumerable Search(string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null)
- {
- var results = Services.EntityService.GetPagedDescendants(UmbracoObjectTypes.DataType, pageIndex, pageSize, out totalFound,
- filter: SqlContext.Query().Where(x => x.Name.Contains(query)));
- return Mapper.MapEnumerable(results);
- }
+ => _treeSearcher.EntitySearch(UmbracoObjectTypes.DataType, query, pageSize, pageIndex, out totalFound, searchFrom);
}
}
diff --git a/src/Umbraco.Web/Trees/MediaTreeController.cs b/src/Umbraco.Web/Trees/MediaTreeController.cs
index f4f373f9a4..df44a809c9 100644
--- a/src/Umbraco.Web/Trees/MediaTreeController.cs
+++ b/src/Umbraco.Web/Trees/MediaTreeController.cs
@@ -16,6 +16,10 @@ using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.Search;
using Constants = Umbraco.Core.Constants;
using Umbraco.Core.Services.Implement;
+using Umbraco.Core.Cache;
+using Umbraco.Core.Configuration;
+using Umbraco.Core.Logging;
+using Umbraco.Core.Persistence;
namespace Umbraco.Web.Trees
{
@@ -35,7 +39,7 @@ namespace Umbraco.Web.Trees
{
private readonly UmbracoTreeSearcher _treeSearcher;
- public MediaTreeController(UmbracoTreeSearcher treeSearcher)
+ public MediaTreeController(UmbracoTreeSearcher treeSearcher, IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ISqlContext sqlContext, ServiceContext services, AppCaches appCaches, IProfilingLogger logger, IRuntimeState runtimeState, UmbracoHelper umbracoHelper) : base(globalSettings, umbracoContextAccessor, sqlContext, services, appCaches, logger, runtimeState, umbracoHelper)
{
_treeSearcher = treeSearcher;
}
diff --git a/src/Umbraco.Web/Trees/MediaTypeTreeController.cs b/src/Umbraco.Web/Trees/MediaTypeTreeController.cs
index 53e30a4ee5..f85aefcace 100644
--- a/src/Umbraco.Web/Trees/MediaTypeTreeController.cs
+++ b/src/Umbraco.Web/Trees/MediaTypeTreeController.cs
@@ -10,6 +10,11 @@ using Umbraco.Web.WebApi.Filters;
using Umbraco.Core.Services;
using Umbraco.Web.Actions;
using Umbraco.Web.Models.ContentEditing;
+using Umbraco.Core.Cache;
+using Umbraco.Core.Configuration;
+using Umbraco.Core.Logging;
+using Umbraco.Core.Persistence;
+using Umbraco.Web.Search;
namespace Umbraco.Web.Trees
{
@@ -19,6 +24,13 @@ namespace Umbraco.Web.Trees
[CoreTree]
public class MediaTypeTreeController : TreeController, ISearchableTree
{
+ private readonly UmbracoTreeSearcher _treeSearcher;
+
+ public MediaTypeTreeController(UmbracoTreeSearcher treeSearcher, IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ISqlContext sqlContext, ServiceContext services, AppCaches appCaches, IProfilingLogger logger, IRuntimeState runtimeState, UmbracoHelper umbracoHelper) : base(globalSettings, umbracoContextAccessor, sqlContext, services, appCaches, logger, runtimeState, umbracoHelper)
+ {
+ _treeSearcher = treeSearcher;
+ }
+
protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings)
{
var intId = id.TryConvertTo();
@@ -117,10 +129,7 @@ namespace Umbraco.Web.Trees
}
public IEnumerable Search(string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null)
- {
- var results = Services.EntityService.GetPagedDescendants(UmbracoObjectTypes.MediaType, pageIndex, pageSize, out totalFound,
- filter: SqlContext.Query().Where(x => x.Name.Contains(query)));
- return Mapper.MapEnumerable(results);
- }
+ => _treeSearcher.EntitySearch(UmbracoObjectTypes.MediaType, query, pageSize, pageIndex, out totalFound, searchFrom);
+
}
}
diff --git a/src/Umbraco.Web/Trees/TemplatesTreeController.cs b/src/Umbraco.Web/Trees/TemplatesTreeController.cs
index 8c37718c9b..d0ca8d1b2e 100644
--- a/src/Umbraco.Web/Trees/TemplatesTreeController.cs
+++ b/src/Umbraco.Web/Trees/TemplatesTreeController.cs
@@ -3,12 +3,18 @@ using System.Globalization;
using System.Linq;
using System.Net.Http.Formatting;
using Umbraco.Core;
+using Umbraco.Core.Cache;
+using Umbraco.Core.Configuration;
+using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Entities;
+using Umbraco.Core.Persistence;
+using Umbraco.Core.Services;
using Umbraco.Web.Actions;
using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.Models.Trees;
using Umbraco.Web.Mvc;
+using Umbraco.Web.Search;
using Umbraco.Web.WebApi.Filters;
using Constants = Umbraco.Core.Constants;
@@ -20,6 +26,13 @@ namespace Umbraco.Web.Trees
[CoreTree]
public class TemplatesTreeController : TreeController, ISearchableTree
{
+ private readonly UmbracoTreeSearcher _treeSearcher;
+
+ public TemplatesTreeController(UmbracoTreeSearcher treeSearcher, IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ISqlContext sqlContext, ServiceContext services, AppCaches appCaches, IProfilingLogger logger, IRuntimeState runtimeState, UmbracoHelper umbracoHelper) : base(globalSettings, umbracoContextAccessor, sqlContext, services, appCaches, logger, runtimeState, umbracoHelper)
+ {
+ _treeSearcher = treeSearcher;
+ }
+
protected override TreeNode CreateRootNode(FormDataCollection queryStrings)
{
var root = base.CreateRootNode(queryStrings);
@@ -119,10 +132,6 @@ namespace Umbraco.Web.Trees
}
public IEnumerable Search(string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null)
- {
- var results = Services.EntityService.GetPagedDescendants(UmbracoObjectTypes.Template, pageIndex, pageSize, out totalFound,
- filter: SqlContext.Query().Where(x => x.Name.Contains(query)));
- return Mapper.MapEnumerable(results);
- }
+ => _treeSearcher.EntitySearch(UmbracoObjectTypes.Template, query, pageSize, pageIndex, out totalFound, searchFrom);
}
}