Merge branch 'temp8' into temp8-fs

This commit is contained in:
Stephan
2019-01-10 16:45:50 +01:00
41 changed files with 284 additions and 723 deletions
+1 -1
View File
@@ -25,7 +25,7 @@
<dependency id="ClientDependency" version="[1.9.7,1.999999)" />
<dependency id="ClientDependency-Mvc5" version="[1.8.0,1.999999)" />
<dependency id="CSharpTest.Net.Collections" version="[14.906.1403.1082,14.999999)" />
<dependency id="Examine" version="[1.0.0-beta067,1.999999)" />
<dependency id="Examine" version="[1.0.0-beta072,1.999999)" />
<dependency id="HtmlAgilityPack" version="[1.8.9,1.999999)" />
<dependency id="ImageProcessor" version="[2.6.2.25,2.999999)" />
<dependency id="LightInject.Mvc" version="[2.0.0,2.999999)" />
@@ -2744,8 +2744,23 @@ namespace Umbraco.Core.Services.Implement
content.CreatorId = userId;
content.WriterId = userId;
foreach (var property in blueprint.Properties)
content.SetValue(property.Alias, property.GetValue()); //fixme doesn't take into account variants
var now = DateTime.Now;
var cultures = blueprint.CultureInfos.Any() ? blueprint.CultureInfos.Select(x=>x.Key) : new[] {(string)null};
foreach (var culture in cultures)
{
foreach (var property in blueprint.Properties)
{
content.SetValue(property.Alias, property.GetValue(culture), culture);
}
content.Name = blueprint.Name;
if (!string.IsNullOrEmpty(culture))
{
content.SetCultureInfo(culture, blueprint.GetCultureName(culture), now);
}
}
return content;
}
@@ -1,36 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using Examine;
namespace Umbraco.Examine.Config
{
/// <summary>
/// a data structure for storing indexing/searching instructions based on config based indexers
/// </summary>
public class ConfigIndexCriteria
{
///<summary>
/// Constructor
///</summary>
///<param name="standardFields"></param>
///<param name="userFields"></param>
///<param name="includeNodeTypes"></param>
///<param name="excludeNodeTypes"></param>
///<param name="parentNodeId"></param>
public ConfigIndexCriteria(IEnumerable<FieldDefinition> standardFields, IEnumerable<FieldDefinition> userFields, IEnumerable<string> includeNodeTypes, IEnumerable<string> excludeNodeTypes, int? parentNodeId)
{
UserFields = userFields.ToList();
StandardFields = standardFields.ToList();
IncludeItemTypes = includeNodeTypes;
ExcludeItemTypes = excludeNodeTypes;
ParentNodeId = parentNodeId;
}
public IEnumerable<FieldDefinition> StandardFields { get; internal set; }
public IEnumerable<FieldDefinition> UserFields { get; internal set; }
public IEnumerable<string> IncludeItemTypes { get; internal set; }
public IEnumerable<string> ExcludeItemTypes { get; internal set; }
public int? ParentNodeId { get; internal set; }
}
}
@@ -1,61 +0,0 @@
using System.Configuration;
namespace Umbraco.Examine.Config
{
///<summary>
/// A configuration item representing a field to index
///</summary>
public sealed class ConfigIndexField : ConfigurationElement
{
[ConfigurationProperty("Name", IsRequired = true)]
public string Name
{
get => (string)this["Name"];
set => this["Name"] = value;
}
[ConfigurationProperty("EnableSorting", IsRequired = false)]
public bool EnableSorting
{
get => (bool)this["EnableSorting"];
set => this["EnableSorting"] = value;
}
[ConfigurationProperty("Type", IsRequired = false, DefaultValue = "String")]
public string Type
{
get => (string)this["Type"];
set => this["Type"] = value;
}
public bool Equals(ConfigIndexField other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return string.Equals(Name, other.Name);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((ConfigIndexField)obj);
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
public static bool operator ==(ConfigIndexField left, ConfigIndexField right)
{
return Equals(left, right);
}
public static bool operator !=(ConfigIndexField left, ConfigIndexField right)
{
return !Equals(left, right);
}
}
}
@@ -1,47 +0,0 @@
using System.Configuration;
namespace Umbraco.Examine.Config
{
public sealed class IndexFieldCollection : ConfigurationElementCollection
{
#region Overridden methods to define collection
protected override ConfigurationElement CreateNewElement()
{
return new ConfigIndexField();
}
protected override object GetElementKey(ConfigurationElement element)
{
ConfigIndexField field = (ConfigIndexField)element;
return field.Name;
}
public override bool IsReadOnly()
{
return false;
}
#endregion
/// <summary>
/// Adds an index field to the collection
/// </summary>
/// <param name="field"></param>
public void Add(ConfigIndexField field)
{
BaseAdd(field, true);
}
/// <summary>
/// Default property for accessing an IndexField definition
/// </summary>
/// <value>Field Name</value>
/// <returns></returns>
public new ConfigIndexField this[string name]
{
get
{
return (ConfigIndexField)this.BaseGet(name);
}
}
}
}
@@ -1,15 +0,0 @@
using System.Collections.Generic;
namespace Umbraco.Examine.Config
{
public static class IndexFieldCollectionExtensions
{
public static List<ConfigIndexField> ToList(this IndexFieldCollection indexes)
{
List<ConfigIndexField> fields = new List<ConfigIndexField>();
foreach (ConfigIndexField field in indexes)
fields.Add(field);
return fields;
}
}
}
-80
View File
@@ -1,80 +0,0 @@
using System.Configuration;
using System.IO;
using System.Web;
using System.Web.Hosting;
namespace Umbraco.Examine.Config
{
public sealed class IndexSet : ConfigurationElement
{
[ConfigurationProperty("SetName", IsRequired = true, IsKey = true)]
public string SetName => (string)this["SetName"];
/// <summary>
/// When this property is set, the indexing will only index documents that are descendants of this node.
/// </summary>
[ConfigurationProperty("IndexParentId", IsRequired = false, IsKey = false)]
public int? IndexParentId
{
get
{
if (this["IndexParentId"] == null)
return null;
return (int)this["IndexParentId"];
}
}
/// <summary>
/// The collection of node types to index, if not specified, all node types will be indexed (apart from the ones specified in the ExcludeNodeTypes collection).
/// </summary>
[ConfigurationCollection(typeof(IndexFieldCollection))]
[ConfigurationProperty("IncludeNodeTypes", IsDefaultCollection = false, IsRequired = false)]
public IndexFieldCollection IncludeNodeTypes => (IndexFieldCollection)base["IncludeNodeTypes"];
/// <summary>
/// The collection of node types to not index. If specified, these node types will not be indexed.
/// </summary>
[ConfigurationCollection(typeof(IndexFieldCollection))]
[ConfigurationProperty("ExcludeNodeTypes", IsDefaultCollection = false, IsRequired = false)]
public IndexFieldCollection ExcludeNodeTypes => (IndexFieldCollection)base["ExcludeNodeTypes"];
/// <summary>
/// A collection of user defined umbraco fields to index
/// </summary>
/// <remarks>
/// If this property is not specified, or if it's an empty collection, the default user fields will be all user fields defined in Umbraco
/// </remarks>
[ConfigurationCollection(typeof(IndexFieldCollection))]
[ConfigurationProperty("IndexUserFields", IsDefaultCollection = false, IsRequired = false)]
public IndexFieldCollection IndexUserFields => (IndexFieldCollection)base["IndexUserFields"];
/// <summary>
/// The fields umbraco values that will be indexed. i.e. id, nodeTypeAlias, writer, etc...
/// </summary>
/// <remarks>
/// If this is not specified, or if it's an empty collection, the default optins will be specified:
/// - id
/// - version
/// - parentID
/// - level
/// - writerID
/// - creatorID
/// - nodeType
/// - template
/// - sortOrder
/// - createDate
/// - updateDate
/// - nodeName
/// - urlName
/// - writerName
/// - creatorName
/// - nodeTypeAlias
/// - path
/// </remarks>
[ConfigurationCollection(typeof(IndexFieldCollection))]
[ConfigurationProperty("IndexAttributeFields", IsDefaultCollection = false, IsRequired = false)]
public IndexFieldCollection IndexAttributeFields => (IndexFieldCollection)base["IndexAttributeFields"];
}
}
@@ -1,29 +0,0 @@
using System.Configuration;
namespace Umbraco.Examine.Config
{
public sealed class IndexSetCollection : ConfigurationElementCollection
{
#region Overridden methods to define collection
protected override ConfigurationElement CreateNewElement()
{
return new IndexSet();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((IndexSet)element).SetName;
}
public override ConfigurationElementCollectionType CollectionType => ConfigurationElementCollectionType.BasicMap;
protected override string ElementName => "IndexSet";
#endregion
/// <summary>
/// Default property for accessing Image Sets
/// </summary>
/// <param name="setName"></param>
/// <returns></returns>
public new IndexSet this[string setName] => (IndexSet)this.BaseGet(setName);
}
}
-21
View File
@@ -1,21 +0,0 @@
using System.Configuration;
namespace Umbraco.Examine.Config
{
public sealed class IndexSets : ConfigurationSection
{
#region Singleton definition
private IndexSets() { }
public static IndexSets Instance { get; } = ConfigurationManager.GetSection(SectionName) as IndexSets;
#endregion
private const string SectionName = "ExamineLuceneIndexSets";
[ConfigurationCollection(typeof(IndexSetCollection))]
[ConfigurationProperty("", IsDefaultCollection = true, IsRequired = true)]
public IndexSetCollection Sets => (IndexSetCollection)base[""];
}
}
+3 -1
View File
@@ -58,8 +58,10 @@ namespace Umbraco.Examine
_parentId = parentId;
}
protected override void PopulateIndexes(IEnumerable<IIndex> indexes)
protected override void PopulateIndexes(IReadOnlyList<IIndex> indexes)
{
if (indexes.Count == 0) return;
const int pageSize = 10000;
var pageIndex = 0;
+3 -5
View File
@@ -1,22 +1,20 @@
using System.Collections.Generic;
using Examine;
using Examine;
namespace Umbraco.Examine
{
public interface IIndexPopulator
{
/// <summary>
/// If this index is registered with this populatr
/// If this index is registered with this populator
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
bool IsRegistered(IIndex index);
/// <summary>
/// Populate indexers
/// Populate indexers
/// </summary>
/// <param name="indexes"></param>
void Populate(params IIndex[] indexes);
}
}
+2 -2
View File
@@ -38,9 +38,9 @@ namespace Umbraco.Examine
public void Populate(params IIndex[] indexes)
{
PopulateIndexes(indexes.Where(IsRegistered));
PopulateIndexes(indexes.Where(IsRegistered).ToList());
}
protected abstract void PopulateIndexes(IEnumerable<IIndex> indexes);
protected abstract void PopulateIndexes(IReadOnlyList<IIndex> indexes);
}
}
+2
View File
@@ -42,6 +42,8 @@ namespace Umbraco.Examine
? ExamineManager.Indexes.Where(x => !x.IndexExists())
: ExamineManager.Indexes).ToArray();
if (indexes.Length == 0) return;
foreach (var index in indexes)
{
index.CreateIndex(); // clear the index
+3 -1
View File
@@ -39,8 +39,10 @@ namespace Umbraco.Examine
_mediaValueSetBuilder = mediaValueSetBuilder;
}
protected override void PopulateIndexes(IEnumerable<IIndex> indexes)
protected override void PopulateIndexes(IReadOnlyList<IIndex> indexes)
{
if (indexes.Count == 0) return;
const int pageSize = 10000;
var pageIndex = 0;
+3 -1
View File
@@ -17,8 +17,10 @@ namespace Umbraco.Examine
_memberService = memberService;
_valueSetBuilder = valueSetBuilder;
}
protected override void PopulateIndexes(IEnumerable<IIndex> indexes)
protected override void PopulateIndexes(IReadOnlyList<IIndex> indexes)
{
if (indexes.Count == 0) return;
const int pageSize = 1000;
var pageIndex = 0;
+1 -8
View File
@@ -48,19 +48,12 @@
</ItemGroup>
<ItemGroup>
<!-- note: NuGet deals with transitive references now -->
<PackageReference Include="Examine" Version="1.0.0-beta067" />
<PackageReference Include="Examine" Version="1.0.0-beta072" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="NPoco" Version="3.9.4" />
</ItemGroup>
<ItemGroup>
<Compile Include="BaseValueSetBuilder.cs" />
<Compile Include="Config\ConfigIndexCriteria.cs" />
<Compile Include="Config\ConfigIndexField.cs" />
<Compile Include="Config\IndexFieldCollection.cs" />
<Compile Include="Config\IndexFieldCollectionExtensions.cs" />
<Compile Include="Config\IndexSet.cs" />
<Compile Include="Config\IndexSetCollection.cs" />
<Compile Include="Config\IndexSets.cs" />
<Compile Include="ContentIndexPopulator.cs" />
<Compile Include="ContentValueSetBuilder.cs" />
<Compile Include="ExamineExtensions.cs" />
+22 -92
View File
@@ -6,14 +6,10 @@ using System.Linq;
using Examine;
using Umbraco.Core;
using Umbraco.Core.Services;
using Umbraco.Core.Strings;
using Examine.LuceneEngine.Indexing;
using Examine.LuceneEngine.Providers;
using Lucene.Net.Analysis;
using Lucene.Net.Store;
using Umbraco.Core.Composing;
using Umbraco.Core.Logging;
using Umbraco.Examine.Config;
using Examine.LuceneEngine;
namespace Umbraco.Examine
@@ -27,18 +23,7 @@ namespace Umbraco.Examine
protected ILocalizationService LanguageService { get; }
#region Constructors
/// <summary>
/// Constructor for configuration providers
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public UmbracoContentIndex()
{
LanguageService = Current.Services.LocalizationService;
//note: The validator for this config based indexer is set in the Initialize method
}
/// <summary>
/// Create an index at runtime
/// </summary>
@@ -52,14 +37,14 @@ namespace Umbraco.Examine
/// <param name="indexValueTypes"></param>
public UmbracoContentIndex(
string name,
FieldDefinitionCollection fieldDefinitions,
Directory luceneDirectory,
FieldDefinitionCollection fieldDefinitions,
Analyzer defaultAnalyzer,
IProfilingLogger profilingLogger,
ILocalizationService languageService,
IContentValueSetValidator validator,
IReadOnlyDictionary<string, IFieldValueTypeFactory> indexValueTypes = null)
: base(name, fieldDefinitions, luceneDirectory, defaultAnalyzer, profilingLogger, validator, indexValueTypes)
: base(name, luceneDirectory, fieldDefinitions, defaultAnalyzer, profilingLogger, validator, indexValueTypes)
{
if (validator == null) throw new ArgumentNullException(nameof(validator));
LanguageService = languageService ?? throw new ArgumentNullException(nameof(languageService));
@@ -70,65 +55,6 @@ namespace Umbraco.Examine
#endregion
#region Initialize
/// <summary>
/// Set up all properties for the indexer based on configuration information specified. This will ensure that
/// all of the folders required by the indexer are created and exist. This will also create an instruction
/// file declaring the computer name that is part taking in the indexing. This file will then be used to
/// determine the master indexer machine in a load balanced environment (if one exists).
/// </summary>
/// <param name="name">The friendly name of the provider.</param>
/// <param name="config">A collection of the name/value pairs representing the provider-specific attributes specified in the configuration for this provider.</param>
/// <exception cref="T:System.ArgumentNullException">
/// The name of the provider is null.
/// </exception>
/// <exception cref="T:System.ArgumentException">
/// The name of the provider has a length of zero.
/// </exception>
/// <exception cref="T:System.InvalidOperationException">
/// An attempt is made to call <see cref="M:System.Configuration.Provider.ProviderBase.Initialize(System.String,System.Collections.Specialized.NameValueCollection)"/> on a provider after the provider has already been initialized.
/// </exception>
[EditorBrowsable(EditorBrowsableState.Never)]
public override void Initialize(string name, NameValueCollection config)
{
base.Initialize(name, config);
var supportUnpublished = false;
var supportProtected = false;
//check if there's a flag specifying to support unpublished content,
//if not, set to false;
if (config["supportUnpublished"] != null)
bool.TryParse(config["supportUnpublished"], out supportUnpublished);
//check if there's a flag specifying to support protected content,
//if not, set to false;
if (config["supportProtected"] != null)
bool.TryParse(config["supportProtected"], out supportProtected);
//now we need to build up the indexer options so we can create our validator
int? parentId = null;
if (IndexSetName.IsNullOrWhiteSpace() == false)
{
var indexSet = IndexSets.Instance.Sets[IndexSetName];
parentId = indexSet.IndexParentId;
}
ValueSetValidator = new ContentValueSetValidator(
supportUnpublished, supportProtected,
//Using a singleton here, we can't inject this when using config based providers and we don't use this
//anywhere else in this class
Current.Services.PublicAccessService,
parentId,
ConfigIndexCriteria?.IncludeItemTypes, ConfigIndexCriteria?.ExcludeItemTypes);
PublishedValuesOnly = supportUnpublished;
}
#endregion
/// <summary>
/// Special check for invalid paths
/// </summary>
@@ -166,8 +92,8 @@ namespace Umbraco.Examine
//these are the invalid items so we'll delete them
//since the path is not valid we need to delete this item in case it exists in the index already and has now
//been moved to an invalid parent.
foreach (var i in group)
base.PerformDeleteFromIndex(i.Id, args => { /*noop*/ });
base.PerformDeleteFromIndex(group.Select(x => x.Id), args => { /*noop*/ });
}
else
{
@@ -192,24 +118,28 @@ namespace Umbraco.Examine
/// When a content node is deleted, we also need to delete it's children from the index so we need to perform a
/// custom Lucene search to find all decendents and create Delete item queues for them too.
/// </remarks>
/// <param name="nodeId">ID of the node to delete</param>
/// <param name="itemIds">ID of the node to delete</param>
/// <param name="onComplete"></param>
protected override void PerformDeleteFromIndex(string nodeId, Action<IndexOperationEventArgs> onComplete)
protected override void PerformDeleteFromIndex(IEnumerable<string> itemIds, Action<IndexOperationEventArgs> onComplete)
{
//find all descendants based on path
var descendantPath = $@"\-1\,*{nodeId}\,*";
var rawQuery = $"{IndexPathFieldName}:{descendantPath}";
var searcher = GetSearcher();
var c = searcher.CreateQuery();
var filtered = c.NativeQuery(rawQuery);
var results = filtered.Execute();
var idsAsList = itemIds.ToList();
foreach (var nodeId in idsAsList)
{
//find all descendants based on path
var descendantPath = $@"\-1\,*{nodeId}\,*";
var rawQuery = $"{IndexPathFieldName}:{descendantPath}";
var searcher = GetSearcher();
var c = searcher.CreateQuery();
var filtered = c.NativeQuery(rawQuery);
var results = filtered.Execute();
ProfilingLogger.Debug(GetType(), "DeleteFromIndex with query: {Query} (found {TotalItems} results)", rawQuery, results.TotalItemCount);
ProfilingLogger.Debug(GetType(), "DeleteFromIndex with query: {Query} (found {TotalItems} results)", rawQuery, results.TotalItemCount);
//need to queue a delete item for each one found
QueueIndexOperation(results.Select(r => new IndexOperation(new ValueSet(r.Id), IndexOperationType.Delete)));
//need to queue a delete item for each one found
QueueIndexOperation(results.Select(r => new IndexOperation(new ValueSet(r.Id), IndexOperationType.Delete)));
}
base.PerformDeleteFromIndex(nodeId, onComplete);
base.PerformDeleteFromIndex(idsAsList, onComplete);
}
}
+5 -116
View File
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Examine.LuceneEngine.Providers;
using Lucene.Net.Analysis;
@@ -9,11 +8,9 @@ using Lucene.Net.Index;
using Umbraco.Core;
using Examine;
using Examine.LuceneEngine;
using Examine.LuceneEngine.Indexing;
using Lucene.Net.Store;
using Umbraco.Core.Composing;
using Umbraco.Core.Logging;
using Umbraco.Examine.Config;
using Directory = Lucene.Net.Store.Directory;
namespace Umbraco.Examine
@@ -43,17 +40,6 @@ namespace Umbraco.Examine
/// </summary>
public const string RawFieldPrefix = SpecialFieldPrefix + "Raw_";
/// <summary>
/// Constructor for config provider based indexes
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
protected UmbracoExamineIndex()
{
ProfilingLogger = Current.ProfilingLogger;
_configBased = true;
_diagnostics = new UmbracoExamineIndexDiagnostics(this, ProfilingLogger);
}
/// <summary>
/// Create a new <see cref="UmbracoExamineIndex"/>
/// </summary>
@@ -66,13 +52,13 @@ namespace Umbraco.Examine
/// <param name="indexValueTypes"></param>
protected UmbracoExamineIndex(
string name,
FieldDefinitionCollection fieldDefinitions,
Directory luceneDirectory,
FieldDefinitionCollection fieldDefinitions,
Analyzer defaultAnalyzer,
IProfilingLogger profilingLogger,
IValueSetValidator validator = null,
IReadOnlyDictionary<string, IFieldValueTypeFactory> indexValueTypes = null)
: base(name, fieldDefinitions, luceneDirectory, defaultAnalyzer, validator, indexValueTypes)
: base(name, luceneDirectory, fieldDefinitions, defaultAnalyzer, validator, indexValueTypes)
{
ProfilingLogger = profilingLogger ?? throw new ArgumentNullException(nameof(profilingLogger));
@@ -102,106 +88,19 @@ namespace Umbraco.Examine
return searcher.GetAllIndexedFields();
}
protected ConfigIndexCriteria ConfigIndexCriteria { get; private set; }
/// <summary>
/// The index set name which references an Examine <see cref="IndexSet"/>
/// </summary>
public string IndexSetName { get; private set; }
#region Initialize
/// <summary>
/// Setup the properties for the indexer from the provider settings
/// </summary>
/// <param name="name"></param>
/// <param name="config"></param>
/// <remarks>
/// This is ONLY used for configuration based indexes
/// </remarks>
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
ProfilingLogger.Debug(GetType(), "{IndexerName} indexer initializing", name);
if (config["enableDefaultEventHandler"] != null && bool.TryParse(config["enableDefaultEventHandler"], out var enabled))
{
EnableDefaultEventHandler = enabled;
}
//this is config based, so add the default definitions
foreach (var field in UmbracoFieldDefinitionCollection.UmbracoIndexFieldDefinitions)
{
FieldDefinitionCollection.TryAdd(field);
}
//Need to check if the index set is specified...
if (config["indexSet"] == null)
{
var possibleSuffixes = new[] {"Index", "Indexer"};
foreach (var suffix in possibleSuffixes)
{
if (!name.EndsWith(suffix)) continue;
var setNameByConvension = name.Remove(name.LastIndexOf(suffix, StringComparison.Ordinal)) + "IndexSet";
//check if we can assign the index set by naming convention
var set = IndexSets.Instance.Sets.Cast<IndexSet>().SingleOrDefault(x => x.SetName == setNameByConvension);
if (set == null) continue;
//we've found an index set by naming conventions :)
IndexSetName = set.SetName;
var indexSet = IndexSets.Instance.Sets[IndexSetName];
//get the index criteria and ensure folder
ConfigIndexCriteria = CreateFieldDefinitionsFromConfig(indexSet);
foreach (var fieldDefinition in ConfigIndexCriteria.StandardFields.Union(ConfigIndexCriteria.UserFields))
{
//replace any existing or add
FieldDefinitionCollection.AddOrUpdate(fieldDefinition);
}
break;
}
}
else
{
//if an index set is specified, ensure it exists and initialize the indexer based on the set
if (IndexSets.Instance.Sets[config["indexSet"]] == null)
throw new ArgumentException("The indexSet specified for the LuceneExamineIndexer provider does not exist");
IndexSetName = config["indexSet"];
var indexSet = IndexSets.Instance.Sets[IndexSetName];
//get the index criteria and ensure folder
ConfigIndexCriteria = CreateFieldDefinitionsFromConfig(indexSet);
foreach (var fieldDefinition in ConfigIndexCriteria.StandardFields.Union(ConfigIndexCriteria.UserFields))
{
//replace any existing or add
FieldDefinitionCollection.AddOrUpdate(fieldDefinition);
}
}
base.Initialize(name, config);
}
#endregion
/// <summary>
/// override to check if we can actually initialize.
/// </summary>
/// <remarks>
/// This check is required since the base examine lib will try to rebuild on startup
/// </remarks>
protected override void PerformDeleteFromIndex(string nodeId, Action<IndexOperationEventArgs> onComplete)
protected override void PerformDeleteFromIndex(IEnumerable<string> itemIds, Action<IndexOperationEventArgs> onComplete)
{
if (CanInitialize())
{
using (new SafeCallContext())
{
base.PerformDeleteFromIndex(nodeId, onComplete);
base.PerformDeleteFromIndex(itemIds, onComplete);
}
}
}
@@ -285,17 +184,7 @@ namespace Umbraco.Examine
e.ValueSet.Values[IconFieldName] = icon;
}
}
private ConfigIndexCriteria CreateFieldDefinitionsFromConfig(IndexSet indexSet)
{
return new ConfigIndexCriteria(
indexSet.IndexAttributeFields.Cast<ConfigIndexField>().Select(x => new FieldDefinition(x.Name, x.Type)).ToArray(),
indexSet.IndexUserFields.Cast<ConfigIndexField>().Select(x => new FieldDefinition(x.Name, x.Type)).ToArray(),
indexSet.IncludeNodeTypes.ToList().Select(x => x.Name).ToArray(),
indexSet.ExcludeNodeTypes.ToList().Select(x => x.Name).ToArray(),
indexSet.IndexParentId);
}
#region IIndexDiagnostics
private readonly UmbracoExamineIndexDiagnostics _diagnostics;
@@ -64,7 +64,7 @@ namespace Umbraco.Examine
{
[nameof(UmbracoExamineIndex.CommitCount)] = _index.CommitCount,
[nameof(UmbracoExamineIndex.DefaultAnalyzer)] = _index.DefaultAnalyzer.GetType().Name,
[nameof(UmbracoExamineIndex.DirectoryFactory)] = _index.DirectoryFactory,
["LuceneDirectory"] = _index.GetLuceneDirectory().GetType().Name,
[nameof(UmbracoExamineIndex.EnableDefaultEventHandler)] = _index.EnableDefaultEventHandler,
[nameof(UmbracoExamineIndex.LuceneIndexFolder)] =
_index.LuceneIndexFolder == null
+2 -28
View File
@@ -1,18 +1,7 @@
using System;
using System.Linq;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Services;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Collections.Generic;
using Examine;
using Examine.LuceneEngine;
using Examine.LuceneEngine.Indexing;
using Examine.LuceneEngine.Providers;
using Lucene.Net.Analysis;
using Umbraco.Core.Composing;
using Umbraco.Core.Logging;
using Directory = Lucene.Net.Store.Directory;
@@ -24,14 +13,6 @@ namespace Umbraco.Examine
/// </summary>
public class UmbracoMemberIndex : UmbracoExamineIndex
{
/// <summary>
/// Constructor for config/provider based indexes
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public UmbracoMemberIndex()
{
}
/// <summary>
/// Constructor to allow for creating an indexer at runtime
/// </summary>
@@ -48,17 +29,10 @@ namespace Umbraco.Examine
Analyzer analyzer,
IProfilingLogger profilingLogger,
IValueSetValidator validator = null) :
base(name, fieldDefinitions, luceneDirectory, analyzer, profilingLogger, validator)
base(name, luceneDirectory, fieldDefinitions, analyzer, profilingLogger, validator)
{
}
public override void Initialize(string name, NameValueCollection config)
{
base.Initialize(name, config);
ValueSetValidator = new MemberValueSetValidator(ConfigIndexCriteria.IncludeItemTypes, ConfigIndexCriteria.ExcludeItemTypes);
}
/// <summary>
/// Overridden to ensure that the umbraco system field definitions are in place
/// </summary>
@@ -9,14 +9,16 @@ namespace Umbraco.Tests.TestHelpers.Stubs
private readonly ConcurrentDictionary<string, IIndex> _indexers = new ConcurrentDictionary<string, IIndex>();
private readonly ConcurrentDictionary<string, ISearcher> _searchers = new ConcurrentDictionary<string, ISearcher>();
public void AddIndex(IIndex indexer)
public IIndex AddIndex(IIndex indexer)
{
_indexers.TryAdd(indexer.Name, indexer);
return indexer;
}
public void AddSearcher(ISearcher searcher)
public ISearcher AddSearcher(ISearcher searcher)
{
_searchers.TryAdd(searcher.Name, searcher);
return searcher;
}
public void Dispose()
+1 -1
View File
@@ -77,7 +77,7 @@
<ItemGroup>
<PackageReference Include="AutoMapper" Version="7.0.1" />
<PackageReference Include="Castle.Core" Version="4.2.1" />
<PackageReference Include="Examine" Version="1.0.0-beta067" />
<PackageReference Include="Examine" Version="1.0.0-beta072" />
<PackageReference Include="HtmlAgilityPack">
<Version>1.8.9</Version>
</PackageReference>
@@ -164,8 +164,8 @@ namespace Umbraco.Tests.UmbracoExamine
var i = new UmbracoContentIndex(
"testIndexer",
new UmbracoFieldDefinitionCollection(),
luceneDir,
new UmbracoFieldDefinitionCollection(),
analyzer,
profilingLogger,
languageService,
@@ -146,7 +146,6 @@ function valFormManager(serverValidationManager, $rootScope, $timeout, $location
var infiniteEditors = editorService.getEditors();
if (!formCtrl.$dirty && infiniteEditors.length === 0 || isSavingNewItem && infiniteEditors.length === 0) {
confirmed = true;
return;
}
@@ -6,11 +6,12 @@
var vm = this;
vm.loading = true;
vm.hasPristineVariants = false;
vm.isNew = true;
vm.changeSelection = changeSelection;
vm.dirtyVariantFilter = dirtyVariantFilter;
vm.pristineVariantFilter = pristineVariantFilter;
/** Returns true if publishing is possible based on if there are un-published mandatory languages */
function canPublish() {
var selected = [];
@@ -22,7 +23,7 @@
var published = !(variant.state === "NotCreated" || variant.state === "Draft");
if ((variant.language.isMandatory && !published) && (!publishable || !variant.publish)) {
//if a mandatory variant isn't published
//if a mandatory variant isn't published
//and it's not publishable or not selected to be published
//then we cannot continue
@@ -53,12 +54,35 @@
return (variant.active || variant.isDirty || variant.state === "Draft" || variant.state === "PublishedPendingChanges" || variant.state === "NotCreated");
}
function hasAnyData(variant) {
var result = variant.isDirty != null || (variant.name != null && variant.name.length > 0);
if(result) return true;
for (var t=0; t < variant.tabs.length; t++){
for (var p=0; p < variant.tabs[t].properties.length; p++){
var property = variant.tabs[t].properties[p];
if(property.culture == null) continue;
result = result || (property.value != null && property.value.length > 0);
if(result) return true;
}
}
return result;
}
function pristineVariantFilter(variant) {
return !(dirtyVariantFilter(variant));
}
function onInit() {
vm.variants = $scope.model.variants;
if (!$scope.model.title) {
@@ -69,6 +93,13 @@
vm.hasPristineVariants = false;
_.each(vm.variants,
function (variant) {
if(variant.state !== "NotCreated"){
vm.isNew = false;
}
});
_.each(vm.variants,
function (variant) {
variant.compositeId = variant.language.culture + "_" + (variant.segment ? variant.segment : "");
@@ -78,6 +109,10 @@
if (!vm.hasPristineVariants) {
vm.hasPristineVariants = pristineVariantFilter(variant);
}
if(vm.isNew && hasAnyData(variant)){
variant.save = true;
}
});
if (vm.variants.length !== 0) {
@@ -103,8 +138,16 @@
$scope.model.disableSubmitButton = true;
}
vm.loading = false;
var labelKey = vm.isNew ? "content_languagesToPublishForFirstTime" : "content_languagesToPublish";
localizationService.localize(labelKey).then(function (value) {
vm.headline = value;
vm.loading = false;
});
}
onInit();
@@ -1,7 +1,7 @@
<div ng-controller="Umbraco.Overlays.PublishController as vm">
<div style="margin-bottom: 15px;">
<p><localize key="content_languagesToPublish"></localize></p>
<p>{{vm.headline}}</p>
</div>
<div ng-if="vm.loading" style="min-height: 50px; position: relative;">
@@ -65,7 +65,7 @@
<div ng-repeat="notification in variant.notifications">
<div class="umb-permission__description" style="color: #1FB572;">{{notification.message}}</div>
</div>
</div>
</div>
</div>
@@ -1,16 +1,17 @@
(function () {
"use strict";
function SaveContentController($scope, localizationService) {
var vm = this;
vm.loading = true;
vm.hasPristineVariants = false;
vm.isNew = true;
vm.changeSelection = changeSelection;
vm.dirtyVariantFilter = dirtyVariantFilter;
vm.pristineVariantFilter = pristineVariantFilter;
function changeSelection(variant) {
var firstSelected = _.find(vm.variants, function (v) {
return v.save;
@@ -30,8 +31,28 @@
return !(dirtyVariantFilter(variant));
}
function onInit() {
function hasAnyData(variant) {
var result = variant.isDirty != null || (variant.name != null && variant.name.length > 0);
if(result) return true;
for (var t=0; t < variant.tabs.length; t++){
for (var p=0; p < variant.tabs[t].properties.length; p++){
var property = variant.tabs[t].properties[p];
if(property.culture == null) continue;
result = result || (property.value != null && property.value.length > 0);
if(result) return true;
}
}
return result;
}
function onInit() {
vm.variants = $scope.model.variants;
if(!$scope.model.title) {
@@ -42,6 +63,13 @@
vm.hasPristineVariants = false;
_.each(vm.variants,
function (variant) {
if(variant.state !== "NotCreated"){
vm.isNew = false;
}
});
_.each(vm.variants,
function (variant) {
variant.compositeId = variant.language.culture + "_" + (variant.segment ? variant.segment : "");
@@ -51,6 +79,10 @@
if (!vm.hasPristineVariants) {
vm.hasPristineVariants = pristineVariantFilter(variant);
}
if(vm.isNew && hasAnyData(variant)){
variant.save = true;
}
});
if (vm.variants.length !== 0) {
@@ -88,5 +120,5 @@
}
angular.module("umbraco").controller("Umbraco.Overlays.SaveContentController", SaveContentController);
})();
@@ -1,72 +1,120 @@
<div ng-controller="Umbraco.Overlays.SaveContentController as vm">
<div style="margin-bottom: 15px;">
<p><localize key="content_languagesToSave"></localize></p>
</div>
<div ng-if="vm.loading" style="min-height: 50px; position: relative;">
<umb-load-indicator></umb-load-indicator>
</div>
<div class="umb-list umb-list--condensed" ng-if="!vm.loading">
<div class="umb-list-item" ng-repeat="variant in vm.variants | filter:vm.dirtyVariantFilter track by variant.compositeId">
<ng-form name="saveVariantSelectorForm">
<div class="flex">
<input id="{{variant.htmlId}}"
name="saveVariantSelector"
type="checkbox"
ng-model="variant.save"
ng-change="vm.changeSelection(variant)"
style="margin-right: 8px;"
val-server-field="{{variant.htmlId}}" />
<div>
<label for="{{variant.htmlId}}" style="margin-bottom: 2px;">
<span>{{ variant.language.name }}</span>
<strong ng-if="variant.language.isMandatory" class="umb-control-required">*</strong>
</label>
<div ng-if="!saveVariantSelectorForm.$invalid && !(variant.notifications && variant.notifications.length > 0)">
<umb-variant-state class="umb-permission__description" variant="variant"></umb-variant-state>
</div>
<div ng-messages="saveVariantSelectorForm.saveVariantSelector.$error" show-validation-on-submit>
<div class="umb-permission__description" style="color: #F02E28;" ng-message="valServerField">{{saveVariantSelectorForm.saveVariantSelector.errorMsg}}</div>
</div>
<div ng-repeat="notification in variant.notifications">
<div class="umb-permission__description" style="color: #1FB572;">{{notification.message}}</div>
</div>
</div>
</div>
</ng-form>
<div ng-if="vm.isNew && !vm.loading">
<div style="margin-bottom: 15px;">
<p><localize key="content_languagesToSaveForFirstTime"></localize></p>
</div>
<div class="umb-list umb-list--condensed">
<div class="umb-list-item" ng-repeat="variant in vm.variants">
<ng-form name="saveVariantSelectorForm">
<div class="flex">
<input id="{{variant.htmlId}}"
name="saveVariantSelector"
type="checkbox"
ng-model="variant.save"
ng-disabled="vm.isNew"
style="margin-right: 8px;"
val-server-field="{{variant.htmlId}}" />
<div>
<label for="{{variant.htmlId}}" style="margin-bottom: 2px;">
<span>{{ variant.language.name }}</span>
<strong ng-if="variant.language.isMandatory" class="umb-control-required">*</strong>
</label>
<div ng-if="!saveVariantSelectorForm.$invalid && !(variant.notifications && variant.notifications.length > 0)">
<umb-variant-state class="umb-permission__description" variant="variant"></umb-variant-state>
</div>
<div ng-messages="saveVariantSelectorForm.saveVariantSelector.$error" show-validation-on-submit>
<div class="umb-permission__description" style="color: #F02E28;" ng-message="valServerField">{{saveVariantSelectorForm.saveVariantSelector.errorMsg}}</div>
</div>
<div ng-repeat="notification in variant.notifications">
<div class="umb-permission__description" style="color: #1FB572;">{{notification.message}}</div>
</div>
</div>
</div>
</ng-form>
</div>
<br/>
</div>
<br/>
</div>
<div class="umb-list umb-list--condensed" ng-if="!vm.loading && vm.hasPristineVariants">
<div style="margin-bottom: 15px; font-weight: bold;">
<p><localize key="content_unmodifiedLanguages"></localize></p>
<div ng-if="!vm.isNew && !vm.loading">
<div style="margin-bottom: 15px;">
<p><localize key="content_languagesToSave"></localize></p>
</div>
<div class="umb-list-item" ng-repeat="variant in vm.variants | filter:vm.pristineVariantFilter">
<div>
<div style="margin-bottom: 2px;">
<span>{{ variant.language.name }}</span>
<strong ng-if="variant.language.isMandatory" class="umb-control-required">*</strong>
</div>
<div class="umb-list umb-list--condensed">
<div ng-if="!(variant.notifications && variant.notifications.length > 0)">
<umb-variant-state class="umb-permission__description" variant="variant"></umb-variant-state>
</div>
<div class="umb-list-item" ng-repeat="variant in vm.variants | filter:vm.dirtyVariantFilter track by variant.compositeId">
<ng-form name="saveVariantSelectorForm">
<div class="flex">
<input id="{{variant.htmlId}}"
name="saveVariantSelector"
type="checkbox"
ng-model="variant.save"
ng-change="vm.changeSelection(variant)"
style="margin-right: 8px;"
val-server-field="{{variant.htmlId}}" />
<div>
<label for="{{variant.htmlId}}" style="margin-bottom: 2px;">
<span>{{ variant.language.name }}</span>
<strong ng-if="variant.language.isMandatory" class="umb-control-required">*</strong>
</label>
<div ng-repeat="notification in variant.notifications">
<div class="umb-permission__description" style="color: #1FB572;">{{notification.message}}</div>
<div ng-if="!saveVariantSelectorForm.$invalid && !(variant.notifications && variant.notifications.length > 0)">
<umb-variant-state class="umb-permission__description" variant="variant"></umb-variant-state>
</div>
<div ng-messages="saveVariantSelectorForm.saveVariantSelector.$error" show-validation-on-submit>
<div class="umb-permission__description" style="color: #F02E28;" ng-message="valServerField">{{saveVariantSelectorForm.saveVariantSelector.errorMsg}}</div>
</div>
<div ng-repeat="notification in variant.notifications">
<div class="umb-permission__description" style="color: #1FB572;">{{notification.message}}</div>
</div>
</div>
</div>
</ng-form>
</div>
<br/>
</div>
<div class="umb-list umb-list--condensed" ng-if="vm.hasPristineVariants">
<div style="margin-bottom: 15px; font-weight: bold;">
<p><localize key="content_unmodifiedLanguages"></localize></p>
</div>
<div class="umb-list-item" ng-repeat="variant in vm.variants | filter:vm.pristineVariantFilter">
<div>
<div style="margin-bottom: 2px;">
<span>{{ variant.language.name }}</span>
<strong ng-if="variant.language.isMandatory" class="umb-control-required">*</strong>
</div>
<div ng-if="!(variant.notifications && variant.notifications.length > 0)">
<umb-variant-state class="umb-permission__description" variant="variant"></umb-variant-state>
</div>
<div ng-repeat="notification in variant.notifications">
<div class="umb-permission__description" style="color: #1FB572;">{{notification.message}}</div>
</div>
</div>
</div>
</div>
</div>
</div>
+1 -12
View File
@@ -88,7 +88,7 @@
<PackageReference Include="CSharpTest.Net.Collections" Version="14.906.1403.1082" />
<PackageReference Include="ClientDependency" Version="1.9.7" />
<PackageReference Include="ClientDependency-Mvc5" Version="1.8.0.0" />
<PackageReference Include="Examine" Version="1.0.0-beta067" />
<PackageReference Include="Examine" Version="1.0.0-beta072" />
<PackageReference Include="ImageProcessor.Web" Version="4.9.3.25" />
<PackageReference Include="ImageProcessor.Web.Config" Version="2.4.1.19" />
<PackageReference Include="Microsoft.AspNet.Identity.Owin" Version="2.2.2" />
@@ -260,16 +260,9 @@
<None Include="Config\scripting.Release.config">
<DependentUpon>scripting.config</DependentUpon>
</None>
<None Include="Config\ExamineSettings.Release.config">
<DependentUpon>ExamineSettings.config</DependentUpon>
</None>
<None Include="Config\feedProxy.Release.config">
<DependentUpon>feedProxy.config</DependentUpon>
</None>
<None Include="Config\ExamineIndex.Release.config">
<DependentUpon>ExamineIndex.config</DependentUpon>
<SubType>Designer</SubType>
</None>
<None Include="Config\Dashboard.Release.config">
<DependentUpon>Dashboard.config</DependentUpon>
<SubType>Designer</SubType>
@@ -317,10 +310,6 @@
<Content Include="Config\ClientDependency.config">
<SubType>Designer</SubType>
</Content>
<Content Include="Config\ExamineSettings.config" />
<Content Include="Config\ExamineIndex.config">
<SubType>Designer</SubType>
</Content>
<Content Include="Config\scripting.config" />
<Content Include="Config\feedProxy.config" />
<Content Include="Config\applications.config" />
@@ -270,8 +270,10 @@
<key alias="includeUnpublished">Include drafts: also publish unpublished content items.</key>
<key alias="isSensitiveValue">This value is hidden. If you need access to view this value please contact your website administrator.</key>
<key alias="isSensitiveValue_short">This value is hidden.</key>
<key alias="languagesToPublishForFirstTime">What languages would you like to publish? All languages with content are saved!</key>
<key alias="languagesToPublish">What languages would you like to publish?</key>
<key alias="languagesToSave">What languages would you like to save?</key>
<key alias="languagesToSaveForFirstTime">All languages with content are saved on creation!</key>
<key alias="languagesToSendForApproval">What languages would you like to send for approval?</key>
<key alias="languagesToSchedule">What languages would you like to schedule?</key>
<key alias="languagesToUnpublish">Select the languages to unpublish. Unpublishing a mandatory language will unpublish all languages.</key>
@@ -1,10 +0,0 @@
<?xml version="1.0"?>
<!--
Umbraco examine is an extensible indexer and search engine.
This configuration file can be extended to create your own index sets.
Index/Search providers can be defined in the UmbracoSettings.config
More information and documentation can be found on GitHub: https://github.com/Shazwazza/Examine/
-->
<ExamineLuceneIndexSets>
</ExamineLuceneIndexSets>
@@ -1,14 +0,0 @@
<?xml version="1.0"?>
<!--
Umbraco examine is an extensible indexer and search engine.
This configuration file can be extended to create your own index sets.
Index/Search providers can be defined in the UmbracoSettings.config
More information and documentation can be found on Our:
https://our.umbraco.com/Documentation/Reference/Searching/Examine/
https://our.umbraco.com/Documentation/Reference/Config/ExamineIndex/
https://our.umbraco.com/Documentation/Reference/Config/ExamineSettings/
-->
<ExamineLuceneIndexSets>
</ExamineLuceneIndexSets>
@@ -1,21 +0,0 @@
<?xml version="1.0"?>
<!--
Umbraco examine is an extensible indexer and search engine.
This configuration file can be extended to add your own search/index providers.
Index sets can be defined in the ExamineIndex.config if you're using the standard provider model.
More information and documentation can be found on GitHub: https://github.com/Shazwazza/Examine/
-->
<Examine>
<ExamineIndexProviders>
<providers>
</providers>
</ExamineIndexProviders>
<ExamineSearchProviders>
<providers>
</providers>
</ExamineSearchProviders>
</Examine>
@@ -1,23 +0,0 @@
<?xml version="1.0"?>
<!--
Umbraco examine is an extensible indexer and search engine.
This configuration file can be extended to add your own search/index providers.
Index sets can be defined in the ExamineIndex.config if you're using the standard provider model.
More information and documentation can be found on Our:
https://our.umbraco.com/Documentation/Reference/Searching/Examine/
https://our.umbraco.com/Documentation/Reference/Config/ExamineIndex/
https://our.umbraco.com/Documentation/Reference/Config/ExamineSettings/
-->
<Examine>
<ExamineIndexProviders>
<providers>
</providers>
</ExamineIndexProviders>
<ExamineSearchProviders>
<providers>
</providers>
</ExamineSearchProviders>
</Examine>
+12 -2
View File
@@ -1,7 +1,8 @@
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<!--
<!--
Defines transforms that apply to web.Template.config when creating the Debug web.config.
This file should contain changes that need to go into the Debug config (the one that everybody
@@ -11,8 +12,17 @@
One can edit web.config, it will not be overritten, but it WILL be altered by this transform
file everytime Umbraco builds.
-->
<configSections>
<section name="Examine" xdt:Transform="Remove" xdt:Locator="Match(name)" />
<section name="ExamineLuceneIndexSets" xdt:Transform="Remove" xdt:Locator="Match(name)" />
</configSections>
<Examine xdt:Transform="Remove" />
<ExamineLuceneIndexSets xdt:Transform="Remove" />
<system.web>
<compilation debug="true" xdt:Transform="SetAttributes(debug)" />
</system.web>
</configuration>
-4
View File
@@ -10,8 +10,6 @@
<configSections>
<section name="microsoft.scripting" type="Microsoft.Scripting.Hosting.Configuration.Section, Microsoft.Scripting, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" />
<section name="clientDependency" type="ClientDependency.Core.Config.ClientDependencySection, ClientDependency.Core" requirePermission="false" />
<section name="Examine" type="Examine.Config.ExamineSettings, Examine" requirePermission="false" />
<section name="ExamineLuceneIndexSets" type="Umbraco.Examine.Config.IndexSets, Umbraco.Examine" requirePermission="false" />
<sectionGroup name="umbracoConfiguration">
<section name="settings" type="Umbraco.Core.Configuration.UmbracoSettings.UmbracoSettingsSection, Umbraco.Core" requirePermission="false" />
@@ -36,8 +34,6 @@
<microsoft.scripting configSource="config\scripting.config" />
<clientDependency configSource="config\ClientDependency.config" />
<Examine configSource="config\ExamineSettings.config" />
<ExamineLuceneIndexSets configSource="config\ExamineIndex.config" />
<appSettings>
<add key="umbracoConfigurationStatus" value="" />
+4 -3
View File
@@ -515,13 +515,14 @@ namespace Umbraco.Web.Editors
[HttpPost]
public SimpleNotificationModel CreateBlueprintFromContent([FromUri]int contentId, [FromUri]string name)
{
if (string.IsNullOrWhiteSpace(name)) throw new ArgumentException("Value cannot be null or whitespace.", "name");
if (string.IsNullOrWhiteSpace(name))
throw new ArgumentException("Value cannot be null or whitespace.", nameof(name));
var content = Services.ContentService.GetById(contentId);
if (content == null)
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
EnsureUniqueName(name, content, "name");
EnsureUniqueName(name, content, nameof(name));
var blueprint = Services.ContentService.CreateContentFromBlueprint(content, name, Security.GetUserId().ResultOr(0));
@@ -612,7 +613,7 @@ namespace Umbraco.Web.Editors
var msKey = $"Variants[{variantCount}].Name";
if (ModelState.ContainsKey(msKey))
{
if (!variant.Save)
if (!variant.Save || IsCreatingAction(contentItem.Action))
ModelState.Remove(msKey);
else
variantNameErrors.Add(variant.Culture);
@@ -239,9 +239,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
try
{
if (eMgr.TryGetIndex(Constants.UmbracoIndexes.InternalIndexName, out var index))
return index.GetSearcher();
throw new InvalidOperationException($"No index found by name {Constants.UmbracoIndexes.InternalIndexName}");
return eMgr.TryGetIndex(Constants.UmbracoIndexes.InternalIndexName, out var index) ? index.GetSearcher() : null;
}
catch (FileNotFoundException)
{
+5 -5
View File
@@ -21,12 +21,12 @@ namespace Umbraco.Web.Search
{
base.Compose(composition);
// populators are not a collection: once cannot remove ours, and can only add more
// populators are not a collection: one cannot remove ours, and can only add more
// the container can inject IEnumerable<IIndexPopulator> and get them all
composition.Register<IIndexPopulator, MemberIndexPopulator>(Lifetime.Singleton);
composition.Register<IIndexPopulator, ContentIndexPopulator>(Lifetime.Singleton);
composition.Register<IIndexPopulator, PublishedContentIndexPopulator>(Lifetime.Singleton);
composition.Register<IIndexPopulator, MediaIndexPopulator>(Lifetime.Singleton);
composition.Register<MemberIndexPopulator>(Lifetime.Singleton);
composition.Register<ContentIndexPopulator>(Lifetime.Singleton);
composition.Register<PublishedContentIndexPopulator>(Lifetime.Singleton);
composition.Register<MediaIndexPopulator>(Lifetime.Singleton);
composition.Register<IndexRebuilder>(Lifetime.Singleton);
composition.RegisterUnique<IUmbracoIndexesCreator, UmbracoIndexesCreator>();
@@ -1,20 +1,11 @@
using System.Collections.Generic;
using Umbraco.Core.Logging;
using Umbraco.Core.Services;
using Umbraco.Core.Strings;
using Umbraco.Examine;
using Umbraco.Core.Persistence;
using Umbraco.Core.IO;
using System.IO;
using Lucene.Net.Store;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.Analysis;
using Examine.LuceneEngine;
using Examine;
using Examine.LuceneEngine.Providers;
using System.Linq;
using Umbraco.Core;
using Umbraco.Core.Models;
namespace Umbraco.Web.Search
{
@@ -59,8 +50,8 @@ namespace Umbraco.Web.Search
{
var index = new UmbracoContentIndex(
Constants.UmbracoIndexes.InternalIndexName,
new UmbracoFieldDefinitionCollection(),
CreateFileSystemLuceneDirectory(Constants.UmbracoIndexes.InternalIndexPath),
new UmbracoFieldDefinitionCollection(),
new CultureInvariantWhitespaceAnalyzer(),
ProfilingLogger,
LanguageService,
@@ -72,8 +63,8 @@ namespace Umbraco.Web.Search
{
var index = new UmbracoContentIndex(
Constants.UmbracoIndexes.ExternalIndexName,
new UmbracoFieldDefinitionCollection(),
CreateFileSystemLuceneDirectory(Constants.UmbracoIndexes.ExternalIndexPath),
new UmbracoFieldDefinitionCollection(),
new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30),
ProfilingLogger,
LanguageService,
+1 -1
View File
@@ -63,7 +63,7 @@
<PackageReference Include="AutoMapper" Version="7.0.1" />
<PackageReference Include="ClientDependency" Version="1.9.7" />
<PackageReference Include="CSharpTest.Net.Collections" Version="14.906.1403.1082" />
<PackageReference Include="Examine" Version="1.0.0-beta067" />
<PackageReference Include="Examine" Version="1.0.0-beta072" />
<PackageReference Include="HtmlAgilityPack" Version="1.8.9" />
<PackageReference Include="ImageProcessor">
<Version>2.6.2.25</Version>