Files
Umbraco-CMS/src/Umbraco.Examine/ContentValueSetBuilder.cs
2019-08-02 13:01:02 +10:00

108 lines
5.5 KiB
C#

using Examine;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Services;
using Umbraco.Core.Strings;
namespace Umbraco.Examine
{
/// <summary>
/// Builds <see cref="ValueSet"/>s for <see cref="IContent"/> items
/// </summary>
public class ContentValueSetBuilder : BaseValueSetBuilder<IContent>, IContentValueSetBuilder, IPublishedContentValueSetBuilder
{
private readonly UrlSegmentProviderCollection _urlSegmentProviders;
private readonly IUserService _userService;
public ContentValueSetBuilder(PropertyEditorCollection propertyEditors,
UrlSegmentProviderCollection urlSegmentProviders,
IUserService userService,
bool publishedValuesOnly)
: base(propertyEditors, publishedValuesOnly)
{
_urlSegmentProviders = urlSegmentProviders;
_userService = userService;
}
/// <inheritdoc />
public override IEnumerable<ValueSet> GetValueSets(params IContent[] content)
{
// TODO: There is a lot of boxing going on here and ultimately all values will be boxed by Lucene anyways
// but I wonder if there's a way to reduce the boxing that we have to do or if it will matter in the end since
// Lucene will do it no matter what? One idea was to create a `FieldValue` struct which would contain `object`, `object[]`, `ValueType` and `ValueType[]`
// references and then each array is an array of `FieldValue[]` and values are assigned accordingly. Not sure if it will make a difference or not.
foreach (var c in content)
{
var isVariant = c.ContentType.VariesByCulture();
var urlValue = c.GetUrlSegment(_urlSegmentProviders); //Always add invariant urlName
var values = new Dictionary<string, IEnumerable<object>>
{
{"icon", c.ContentType.Icon?.Yield() ?? Enumerable.Empty<string>()},
{UmbracoExamineIndex.PublishedFieldName, new object[] {c.Published ? "y" : "n"}}, //Always add invariant published value
{"id", new object[] {c.Id}},
{UmbracoExamineIndex.NodeKeyFieldName, new object[] {c.Key}},
{"parentID", new object[] {c.Level > 1 ? c.ParentId : -1}},
{"level", new object[] {c.Level}},
{"creatorID", new object[] {c.CreatorId}},
{"sortOrder", new object[] {c.SortOrder}},
{"createDate", new object[] {c.CreateDate}}, //Always add invariant createDate
{"updateDate", new object[] {c.UpdateDate}}, //Always add invariant updateDate
{"nodeName", (PublishedValuesOnly //Always add invariant nodeName
? c.PublishName?.Yield()
: c.Name?.Yield()) ?? Enumerable.Empty<string>()},
{"urlName", urlValue?.Yield() ?? Enumerable.Empty<string>()}, //Always add invariant urlName
{"path", c.Path?.Yield() ?? Enumerable.Empty<string>()},
{"nodeType", c.ContentType.Id.ToString().Yield() ?? Enumerable.Empty<string>()},
{"creatorName", (c.GetCreatorProfile(_userService)?.Name ?? "??").Yield() },
{"writerName",(c.GetWriterProfile(_userService)?.Name ?? "??").Yield() },
{"writerID", new object[] {c.WriterId}},
{"templateID", new object[] {c.TemplateId ?? 0}},
{UmbracoContentIndex.VariesByCultureFieldName, new object[] {"n"}},
};
if (isVariant)
{
values[UmbracoContentIndex.VariesByCultureFieldName] = new object[] { "y" };
foreach (var culture in c.AvailableCultures)
{
var variantUrl = c.GetUrlSegment(_urlSegmentProviders, culture);
var lowerCulture = culture.ToLowerInvariant();
values[$"urlName_{lowerCulture}"] = variantUrl?.Yield() ?? Enumerable.Empty<string>();
values[$"nodeName_{lowerCulture}"] = (PublishedValuesOnly
? c.GetPublishName(culture)?.Yield()
: c.GetCultureName(culture)?.Yield()) ?? Enumerable.Empty<string>();
values[$"{UmbracoExamineIndex.PublishedFieldName}_{lowerCulture}"] = (c.IsCulturePublished(culture) ? "y" : "n").Yield<object>();
values[$"updateDate_{lowerCulture}"] = (PublishedValuesOnly
? c.GetPublishDate(culture)
: c.GetUpdateDate(culture))?.Yield<object>() ?? Enumerable.Empty<object>();
}
}
foreach (var property in c.Properties)
{
if (!property.PropertyType.VariesByCulture())
{
AddPropertyValue(property, null, null, values);
}
else
{
foreach (var culture in c.AvailableCultures)
AddPropertyValue(property, culture.ToLowerInvariant(), null, values);
}
}
var vs = new ValueSet(c.Id.ToInvariantString(), IndexTypes.Content, c.ContentType.Alias, values);
yield return vs;
}
}
}
}