diff --git a/src/Umbraco.Examine/MediaValueSetBuilder.cs b/src/Umbraco.Examine/MediaValueSetBuilder.cs
index 3839d008b3..03e7f4944b 100644
--- a/src/Umbraco.Examine/MediaValueSetBuilder.cs
+++ b/src/Umbraco.Examine/MediaValueSetBuilder.cs
@@ -1,9 +1,13 @@
-using Examine;
+using System;
+using Examine;
using System.Collections.Generic;
using System.Linq;
+using Newtonsoft.Json;
using Umbraco.Core;
+using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.PropertyEditors;
+using Umbraco.Core.PropertyEditors.ValueConverters;
using Umbraco.Core.Services;
using Umbraco.Core.Strings;
@@ -13,14 +17,16 @@ namespace Umbraco.Examine
{
private readonly UrlSegmentProviderCollection _urlSegmentProviders;
private readonly IUserService _userService;
+ private readonly ILogger _logger;
public MediaValueSetBuilder(PropertyEditorCollection propertyEditors,
UrlSegmentProviderCollection urlSegmentProviders,
- IUserService userService)
+ IUserService userService, ILogger logger)
: base(propertyEditors, false)
{
_urlSegmentProviders = urlSegmentProviders;
_userService = userService;
+ _logger = logger;
}
///
@@ -29,6 +35,42 @@ namespace Umbraco.Examine
foreach (var m in media)
{
var urlValue = m.GetUrlSegment(_urlSegmentProviders);
+
+ var umbracoFilePath = string.Empty;
+ var umbracoFile = string.Empty;
+
+ var umbracoFileSource = m.GetValue(Constants.Conventions.Media.File);
+
+ if (umbracoFileSource.DetectIsJson())
+ {
+ ImageCropperValue cropper = null;
+ try
+ {
+ cropper = JsonConvert.DeserializeObject(
+ m.GetValue(Constants.Conventions.Media.File));
+ }
+ catch (Exception ex)
+ {
+ _logger.Error(ex, $"Could not Deserialize ImageCropperValue for item with key {m.Key} ");
+ }
+
+ if (cropper != null)
+ {
+ umbracoFilePath = cropper.Src;
+ }
+ }
+ else
+ {
+ umbracoFilePath = umbracoFileSource;
+ }
+
+ if (!string.IsNullOrEmpty(umbracoFilePath))
+ {
+ // intentional dummy Uri
+ var uri = new Uri("https://localhost/" + umbracoFilePath);
+ umbracoFile = uri.Segments.Last();
+ }
+
var values = new Dictionary>
{
{"icon", m.ContentType.Icon?.Yield() ?? Enumerable.Empty()},
@@ -44,7 +86,8 @@ namespace Umbraco.Examine
{"urlName", urlValue?.Yield() ?? Enumerable.Empty()},
{"path", m.Path?.Yield() ?? Enumerable.Empty()},
{"nodeType", m.ContentType.Id.ToString().Yield() },
- {"creatorName", (m.GetCreatorProfile(_userService)?.Name ?? "??").Yield()}
+ {"creatorName", (m.GetCreatorProfile(_userService)?.Name ?? "??").Yield()},
+ {UmbracoExamineIndex.UmbracoFileFieldName, umbracoFile.Yield()}
};
foreach (var property in m.Properties)
diff --git a/src/Umbraco.Examine/UmbracoExamineIndex.cs b/src/Umbraco.Examine/UmbracoExamineIndex.cs
index 24952050da..e1dd77b994 100644
--- a/src/Umbraco.Examine/UmbracoExamineIndex.cs
+++ b/src/Umbraco.Examine/UmbracoExamineIndex.cs
@@ -32,6 +32,7 @@ namespace Umbraco.Examine
///
public const string IndexPathFieldName = SpecialFieldPrefix + "Path";
public const string NodeKeyFieldName = SpecialFieldPrefix + "Key";
+ public const string UmbracoFileFieldName = "umbracoFileSrc";
public const string IconFieldName = SpecialFieldPrefix + "Icon";
public const string PublishedFieldName = SpecialFieldPrefix + "Published";
diff --git a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs
index f7b1799d63..1653de827d 100644
--- a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs
+++ b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs
@@ -7,6 +7,7 @@ using Lucene.Net.Analysis;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.Store;
using Moq;
+using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Membership;
@@ -44,11 +45,10 @@ namespace Umbraco.Tests.UmbracoExamine
public static MediaIndexPopulator GetMediaIndexRebuilder(PropertyEditorCollection propertyEditors, IMediaService mediaService)
{
- var mediaValueSetBuilder = new MediaValueSetBuilder(propertyEditors, new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }), GetMockUserService());
+ var mediaValueSetBuilder = new MediaValueSetBuilder(propertyEditors, new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }), GetMockUserService(), GetMockLogger());
var mediaIndexDataSource = new MediaIndexPopulator(null, mediaService, mediaValueSetBuilder);
return mediaIndexDataSource;
}
-
public static IContentService GetMockContentService()
{
long longTotalRecs;
@@ -146,6 +146,11 @@ namespace Umbraco.Tests.UmbracoExamine
return mediaTypeServiceMock.Object;
}
+ public static IProfilingLogger GetMockLogger()
+ {
+ return new ProfilingLogger(Mock.Of(), Mock.Of());
+ }
+
public static UmbracoContentIndex GetUmbracoIndexer(
IProfilingLogger profilingLogger,
Directory luceneDir,
diff --git a/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs
index 2e44f1327b..f2099f2554 100644
--- a/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs
+++ b/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs
@@ -177,6 +177,14 @@ namespace Umbraco.Web.Models.Mapping
target.Name = source.Values.ContainsKey("nodeName") ? source.Values["nodeName"] : "[no name]";
+ if (source.Values.TryGetValue(UmbracoExamineIndex.UmbracoFileFieldName, out var umbracoFile))
+ {
+ if (umbracoFile != null)
+ {
+ target.Name = $"{target.Name} ({umbracoFile})";
+ }
+ }
+
if (source.Values.ContainsKey(UmbracoExamineIndex.NodeKeyFieldName))
{
if (Guid.TryParse(source.Values[UmbracoExamineIndex.NodeKeyFieldName], out var key))
diff --git a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs
index b351cca972..463f4b09df 100644
--- a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs
+++ b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs
@@ -67,7 +67,7 @@ namespace Umbraco.Web.Search
string type;
var indexName = Constants.UmbracoIndexes.InternalIndexName;
- var fields = new[] { "id", "__NodeId", "__Key" };
+ var fields = new List { "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...
@@ -87,7 +87,7 @@ namespace Umbraco.Web.Search
case UmbracoEntityTypes.Member:
indexName = Constants.UmbracoIndexes.MembersIndexName;
type = "member";
- fields = new[] { "id", "__NodeId", "__Key", "email", "loginName" };
+ fields.AddRange(new[]{ "email", "loginName"});
if (searchFrom != null && searchFrom != Constants.Conventions.MemberTypes.AllMembersListId && searchFrom.Trim() != "-1")
{
sb.Append("+__NodeTypeAlias:");
@@ -97,6 +97,7 @@ namespace Umbraco.Web.Search
break;
case UmbracoEntityTypes.Media:
type = "media";
+ fields.AddRange(new[] { UmbracoExamineIndex.UmbracoFileFieldName });
var allMediaStartNodes = _umbracoContext.Security.CurrentUser.CalculateMediaStartNodeIds(_entityService);
AppendPath(sb, UmbracoObjectTypes.Media, allMediaStartNodes, searchFrom, ignoreUserStartNodes, _entityService);
break;
@@ -161,7 +162,7 @@ namespace Umbraco.Web.Search
return _mapper.MapEnumerable(results);
}
- private bool BuildQuery(StringBuilder sb, string query, string searchFrom, string[] fields, string type)
+ private bool BuildQuery(StringBuilder sb, string query, string searchFrom, List fields, string type)
{
//build a lucene query:
// the nodeName will be boosted 10x without wildcards
@@ -234,11 +235,26 @@ namespace Umbraco.Web.Search
foreach (var f in fields)
{
+ var queryWordsReplaced = new string[querywords.Length];
+
+ // when searching file names containing hyphens we need to replace the hyphens with spaces
+ if (f.Equals(UmbracoExamineIndex.UmbracoFileFieldName))
+ {
+ for (var index = 0; index < querywords.Length; index++)
+ {
+ queryWordsReplaced[index] = querywords[index].Replace("\\-", " ").Replace("_", " ").Trim(" ");
+ }
+ }
+ else
+ {
+ queryWordsReplaced = querywords;
+ }
+
//additional fields normally
sb.Append(f);
sb.Append(":");
sb.Append("(");
- foreach (var w in querywords)
+ foreach (var w in queryWordsReplaced)
{
sb.Append(w.ToLower());
sb.Append("* ");