Fixes: U4-4798 When new property types are added, the internal Examine index isn't notified and will ignore them
This commit is contained in:
@@ -61,6 +61,7 @@ namespace Umbraco.Web.Search
|
||||
CacheRefresherBase<PageCacheRefresher>.CacheUpdated += PublishedPageCacheRefresherCacheUpdated;
|
||||
CacheRefresherBase<MediaCacheRefresher>.CacheUpdated += MediaCacheRefresherCacheUpdated;
|
||||
CacheRefresherBase<MemberCacheRefresher>.CacheUpdated += MemberCacheRefresherCacheUpdated;
|
||||
CacheRefresherBase<ContentTypeCacheRefresher>.CacheUpdated += ContentTypeCacheRefresherCacheUpdated;
|
||||
|
||||
var contentIndexer = ExamineManager.Instance.IndexProviderCollection["InternalIndexer"] as UmbracoContentIndexer;
|
||||
if (contentIndexer != null)
|
||||
@@ -74,6 +75,25 @@ namespace Umbraco.Web.Search
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is used to refresh content indexers IndexData based on the DataService whenever a content type is changed since
|
||||
/// properties may have been added/removed
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <remarks>
|
||||
/// See: http://issues.umbraco.org/issue/U4-4798
|
||||
/// </remarks>
|
||||
[SecuritySafeCritical]
|
||||
static void ContentTypeCacheRefresherCacheUpdated(ContentTypeCacheRefresher sender, CacheRefresherEventArgs e)
|
||||
{
|
||||
var indexersToUpdated = ExamineManager.Instance.IndexProviderCollection.OfType<UmbracoContentIndexer>();
|
||||
foreach (var provider in indexersToUpdated)
|
||||
{
|
||||
provider.RefreshIndexerDataFromDataService();
|
||||
}
|
||||
}
|
||||
|
||||
[SecuritySafeCritical]
|
||||
static void MemberCacheRefresherCacheUpdated(MemberCacheRefresher sender, CacheRefresherEventArgs e)
|
||||
{
|
||||
|
||||
@@ -14,58 +14,63 @@ namespace UmbracoExamine.Config
|
||||
/// </summary>
|
||||
public static class IndexSetExtensions
|
||||
{
|
||||
|
||||
private static readonly object Locker = new object();
|
||||
|
||||
internal static IIndexCriteria ToIndexCriteria(this IndexSet set, IDataService svc,
|
||||
IEnumerable<StaticField> indexFieldPolicies)
|
||||
{
|
||||
|
||||
var attributeFields = set.IndexAttributeFields.Cast<IIndexField>().ToArray();
|
||||
var userFields = set.IndexUserFields.Cast<IIndexField>().ToArray();
|
||||
var includeNodeTypes = set.IncludeNodeTypes.ToList().Select(x => x.Name).ToArray();
|
||||
var excludeNodeTypes = set.ExcludeNodeTypes.ToList().Select(x => x.Name).ToArray();
|
||||
var parentId = set.IndexParentId;
|
||||
|
||||
//if there are no user fields defined, we'll populate them from the data source (include them all)
|
||||
if (set.IndexUserFields.Count == 0)
|
||||
{
|
||||
lock (Locker)
|
||||
//we need to add all user fields to the collection if it is empty (this is the default if none are specified)
|
||||
var userProps = svc.ContentService.GetAllUserPropertyNames();
|
||||
var fields = new List<IIndexField>();
|
||||
foreach (var u in userProps)
|
||||
{
|
||||
//we need to add all user fields to the collection if it is empty (this is the default if none are specified)
|
||||
var userFields = svc.ContentService.GetAllUserPropertyNames();
|
||||
foreach (var u in userFields)
|
||||
var field = new IndexField() { Name = u };
|
||||
var policy = indexFieldPolicies.FirstOrDefault(x => x.Name == u);
|
||||
if (policy != null)
|
||||
{
|
||||
var field = new IndexField() {Name = u};
|
||||
var policy = indexFieldPolicies.FirstOrDefault(x => x.Name == u);
|
||||
if (policy != null)
|
||||
{
|
||||
field.Type = policy.Type;
|
||||
field.EnableSorting = policy.EnableSorting;
|
||||
}
|
||||
set.IndexUserFields.Add(field);
|
||||
field.Type = policy.Type;
|
||||
field.EnableSorting = policy.EnableSorting;
|
||||
}
|
||||
fields.Add(field);
|
||||
}
|
||||
userFields = fields.ToArray();
|
||||
}
|
||||
|
||||
//if there are no attribute fields defined, we'll populate them from the data source (include them all)
|
||||
if (set.IndexAttributeFields.Count == 0)
|
||||
{
|
||||
lock (Locker)
|
||||
//we need to add all system fields to the collection if it is empty (this is the default if none are specified)
|
||||
var sysProps = svc.ContentService.GetAllSystemPropertyNames();
|
||||
var fields = new List<IIndexField>();
|
||||
foreach (var s in sysProps)
|
||||
{
|
||||
//we need to add all system fields to the collection if it is empty (this is the default if none are specified)
|
||||
var sysFields = svc.ContentService.GetAllSystemPropertyNames();
|
||||
foreach (var s in sysFields)
|
||||
var field = new IndexField() { Name = s };
|
||||
var policy = indexFieldPolicies.FirstOrDefault(x => x.Name == s);
|
||||
if (policy != null)
|
||||
{
|
||||
var field = new IndexField() { Name = s };
|
||||
var policy = indexFieldPolicies.FirstOrDefault(x => x.Name == s);
|
||||
if (policy != null)
|
||||
{
|
||||
field.Type = policy.Type;
|
||||
field.EnableSorting = policy.EnableSorting;
|
||||
}
|
||||
set.IndexAttributeFields.Add(field);
|
||||
field.Type = policy.Type;
|
||||
field.EnableSorting = policy.EnableSorting;
|
||||
}
|
||||
fields.Add(field);
|
||||
}
|
||||
attributeFields = fields.ToArray();
|
||||
}
|
||||
|
||||
|
||||
return new IndexCriteria(
|
||||
set.IndexAttributeFields.Cast<IIndexField>().ToArray(),
|
||||
set.IndexUserFields.Cast<IIndexField>().ToArray(),
|
||||
set.IncludeNodeTypes.ToList().Select(x => x.Name).ToArray(),
|
||||
set.ExcludeNodeTypes.ToList().Select(x => x.Name).ToArray(),
|
||||
set.IndexParentId);
|
||||
attributeFields,
|
||||
userFields,
|
||||
includeNodeTypes,
|
||||
excludeNodeTypes,
|
||||
parentId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -298,6 +298,19 @@ namespace UmbracoExamine
|
||||
base.RebuildIndex();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to refresh the current IndexerData from the data in the DataService. This can be used
|
||||
/// if there are more properties added/removed from the database
|
||||
/// </summary>
|
||||
public void RefreshIndexerDataFromDataService()
|
||||
{
|
||||
//TODO: This would be much better done if the IndexerData property had read/write locks applied
|
||||
// to it! Unless we update the base class there's really no way to prevent the IndexerData from being
|
||||
// changed during an operation that is reading from it.
|
||||
var newIndexerData = GetIndexerData(IndexSets.Instance.Sets[IndexSetName]);
|
||||
IndexerData = newIndexerData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override this method to strip all html from all user fields before raising the event, then after the event
|
||||
/// ensure our special Path field is added to the collection
|
||||
|
||||
Reference in New Issue
Block a user