2018-11-26 13:33:15 +11:00
using Examine ;
using System.Collections.Generic ;
2019-02-07 15:13:45 +11:00
using System.Linq ;
2018-11-26 13:33:15 +11:00
using Umbraco.Core ;
using Umbraco.Core.Models ;
2020-04-22 10:37:23 +10:00
using Umbraco.Core.Models.Membership ;
2018-11-26 13:33:15 +11:00
using Umbraco.Core.PropertyEditors ;
2020-04-22 10:37:23 +10:00
using Umbraco.Core.Scoping ;
2018-11-26 13:33:15 +11:00
using Umbraco.Core.Services ;
using Umbraco.Core.Strings ;
namespace Umbraco.Examine
{
2018-12-05 16:53:25 +11:00
/// <summary>
/// Builds <see cref="ValueSet"/>s for <see cref="IContent"/> items
/// </summary>
public class ContentValueSetBuilder : BaseValueSetBuilder < IContent > , IContentValueSetBuilder , IPublishedContentValueSetBuilder
2018-11-26 13:33:15 +11:00
{
2019-01-16 11:37:20 +01:00
private readonly UrlSegmentProviderCollection _urlSegmentProviders ;
2018-11-26 13:33:15 +11:00
private readonly IUserService _userService ;
2020-04-22 10:37:23 +10:00
private readonly IScopeProvider _scopeProvider ;
2018-11-26 13:33:15 +11:00
2019-12-09 14:12:06 +01:00
private readonly IShortStringHelper _shortStringHelper ;
2018-11-26 13:33:15 +11:00
2018-11-26 14:27:44 +11:00
public ContentValueSetBuilder ( PropertyEditorCollection propertyEditors ,
2019-01-16 11:37:20 +01:00
UrlSegmentProviderCollection urlSegmentProviders ,
2018-12-05 16:53:25 +11:00
IUserService userService ,
2019-12-09 14:12:06 +01:00
IShortStringHelper shortStringHelper ,
2020-04-22 10:37:23 +10:00
IScopeProvider scopeProvider ,
2018-12-05 16:53:25 +11:00
bool publishedValuesOnly )
: base ( propertyEditors , publishedValuesOnly )
2018-11-26 13:33:15 +11:00
{
_urlSegmentProviders = urlSegmentProviders ;
_userService = userService ;
2019-12-09 14:12:06 +01:00
_shortStringHelper = shortStringHelper ;
2020-04-22 10:37:23 +10:00
_scopeProvider = scopeProvider ;
2018-11-26 13:33:15 +11:00
}
2018-11-28 14:46:45 +11:00
/// <inheritdoc />
public override IEnumerable < ValueSet > GetValueSets ( params IContent [ ] content )
2018-11-26 13:33:15 +11:00
{
2020-04-22 10:37:23 +10:00
Dictionary < int , IProfile > creatorIds ;
Dictionary < int , IProfile > writerIds ;
// We can lookup all of the creator/writer names at once which can save some
// processing below instead of one by one.
using ( var scope = _scopeProvider . CreateScope ( ) )
{
2020-04-23 08:38:29 +02:00
creatorIds = _userService . GetProfilesById ( content . Select ( x = > x . CreatorId ) . ToArray ( ) )
2020-04-22 10:37:23 +10:00
. ToDictionary ( x = > x . Id , x = > x ) ;
2020-04-23 08:38:29 +02:00
writerIds = _userService . GetProfilesById ( content . Select ( x = > x . WriterId ) . ToArray ( ) )
2020-04-22 10:37:23 +10:00
. ToDictionary ( x = > x . Id , x = > x ) ;
scope . Complete ( ) ;
}
2020-08-31 23:57:26 +10:00
return GetValueSetsEnumerable ( content , creatorIds , writerIds ) ;
}
private IEnumerable < ValueSet > GetValueSetsEnumerable ( IContent [ ] content , Dictionary < int , IProfile > creatorIds , Dictionary < int , IProfile > writerIds )
{
2019-01-27 01:17:32 -05:00
// TODO: There is a lot of boxing going on here and ultimately all values will be boxed by Lucene anyways
2018-11-26 13:33:15 +11:00
// 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 ( ) ;
2019-12-09 14:12:06 +01:00
var urlValue = c . GetUrlSegment ( _shortStringHelper , _urlSegmentProviders ) ; //Always add invariant urlName
2018-11-29 13:55:51 +11:00
var values = new Dictionary < string , IEnumerable < object > >
2018-11-26 13:33:15 +11:00
{
2019-02-07 15:13:45 +11:00
{ "icon" , c . ContentType . Icon ? . Yield ( ) ? ? Enumerable . Empty < string > ( ) } ,
2020-01-28 16:37:55 +11:00
{ UmbracoExamineFieldNames . PublishedFieldName , new object [ ] { c . Published ? "y" : "n" } } , //Always add invariant published value
2018-11-26 13:33:15 +11:00
{ "id" , new object [ ] { c . Id } } ,
2020-01-28 16:37:55 +11:00
{ UmbracoExamineFieldNames . NodeKeyFieldName , new object [ ] { c . Key } } ,
2018-11-26 13:33:15 +11:00
{ "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
2020-01-28 17:07:06 +11:00
{ UmbracoExamineFieldNames . NodeNameFieldName , ( PublishedValuesOnly //Always add invariant nodeName
2019-02-07 15:13:45 +11:00
? c . PublishName ? . Yield ( )
2019-08-02 13:01:02 +10:00
: c . Name ? . Yield ( ) ) ? ? Enumerable . Empty < string > ( ) } ,
2019-02-07 15:13:45 +11:00
{ "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 > ( ) } ,
2020-04-22 10:37:23 +10:00
{ "creatorName" , ( creatorIds . TryGetValue ( c . CreatorId , out var creatorProfile ) ? creatorProfile . Name : "??" ) . Yield ( ) } ,
2020-04-22 16:20:49 +02:00
{ "writerName" , ( writerIds . TryGetValue ( c . WriterId , out var writerProfile ) ? writerProfile . Name : "??" ) . Yield ( ) } ,
2018-11-26 13:33:15 +11:00
{ "writerID" , new object [ ] { c . WriterId } } ,
2019-01-10 18:31:13 +01:00
{ "templateID" , new object [ ] { c . TemplateId ? ? 0 } } ,
2020-01-28 16:37:55 +11:00
{ UmbracoExamineFieldNames . VariesByCultureFieldName , new object [ ] { "n" } } ,
2018-11-26 13:33:15 +11:00
} ;
if ( isVariant )
{
2020-01-28 16:37:55 +11:00
values [ UmbracoExamineFieldNames . VariesByCultureFieldName ] = new object [ ] { "y" } ;
2018-11-26 13:33:15 +11:00
foreach ( var culture in c . AvailableCultures )
{
2019-12-09 14:12:06 +01:00
var variantUrl = c . GetUrlSegment ( _shortStringHelper , _urlSegmentProviders , culture ) ;
2018-11-26 13:33:15 +11:00
var lowerCulture = culture . ToLowerInvariant ( ) ;
2019-02-07 15:13:45 +11:00
values [ $"urlName_{lowerCulture}" ] = variantUrl ? . Yield ( ) ? ? Enumerable . Empty < string > ( ) ;
values [ $"nodeName_{lowerCulture}" ] = ( PublishedValuesOnly
? c . GetPublishName ( culture ) ? . Yield ( )
: c . GetCultureName ( culture ) ? . Yield ( ) ) ? ? Enumerable . Empty < string > ( ) ;
2020-01-28 16:37:55 +11:00
values [ $"{UmbracoExamineFieldNames.PublishedFieldName}_{lowerCulture}" ] = ( c . IsCulturePublished ( culture ) ? "y" : "n" ) . Yield < object > ( ) ;
2019-02-07 15:13:45 +11:00
values [ $"updateDate_{lowerCulture}" ] = ( PublishedValuesOnly
? c . GetPublishDate ( culture )
: c . GetUpdateDate ( culture ) ) ? . Yield < object > ( ) ? ? Enumerable . Empty < object > ( ) ;
2018-11-26 13:33:15 +11:00
}
}
foreach ( var property in c . Properties )
{
if ( ! property . PropertyType . VariesByCulture ( ) )
{
2018-11-26 14:27:44 +11:00
AddPropertyValue ( property , null , null , values ) ;
2018-11-26 13:33:15 +11:00
}
else
{
foreach ( var culture in c . AvailableCultures )
2018-11-26 14:27:44 +11:00
AddPropertyValue ( property , culture . ToLowerInvariant ( ) , null , values ) ;
2018-11-26 13:33:15 +11:00
}
}
var vs = new ValueSet ( c . Id . ToInvariantString ( ) , IndexTypes . Content , c . ContentType . Alias , values ) ;
yield return vs ;
}
}
}
2018-11-26 14:27:44 +11:00
2018-11-26 13:33:15 +11:00
}