Merge branch 'dev-v7.8' of https://github.com/umbraco/Umbraco-CMS into dev-v7.8

This commit is contained in:
Shannon
2018-01-15 20:41:47 +11:00
3 changed files with 216 additions and 38 deletions

View File

@@ -50,6 +50,18 @@ namespace Umbraco.Web
/// <returns></returns>
IEnumerable<IPublishedContent> TypedSearch(string term, bool useWildCards = true, string searchProvider = null);
/// <summary>
/// Searches content
/// </summary>
/// <param name="skip"></param>
/// <param name="take"></param>
/// <param name="totalRecords"></param>
/// <param name="term"></param>
/// <param name="useWildCards"></param>
/// <param name="searchProvider"></param>
/// <returns></returns>
IEnumerable<IPublishedContent> TypedSearch(int skip, int take, out int totalRecords, string term, bool useWildCards = true, string searchProvider = null);
/// <summary>
/// Searhes content
/// </summary>
@@ -57,5 +69,16 @@ namespace Umbraco.Web
/// <param name="searchProvider"></param>
/// <returns></returns>
IEnumerable<IPublishedContent> TypedSearch(Examine.SearchCriteria.ISearchCriteria criteria, Examine.Providers.BaseSearchProvider searchProvider = null);
/// <summary>
/// Searhes content
/// </summary>
/// <param name="totalrecords"></param>
/// <param name="criteria"></param>
/// <param name="searchProvider"></param>
/// <param name="skip"></param>
/// <param name="take"></param>
/// <returns></returns>
IEnumerable<IPublishedContent> TypedSearch(int skip, int take, out int totalrecords, Examine.SearchCriteria.ISearchCriteria criteria, Examine.Providers.BaseSearchProvider searchProvider = null);
}
}

View File

@@ -1,7 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Xml.XPath;
using Examine;
using Examine.LuceneEngine.Providers;
using Examine.LuceneEngine.SearchCriteria;
using Examine.Providers;
using Examine.SearchCriteria;
using umbraco;
using Umbraco.Core;
using Umbraco.Core.Configuration;
@@ -375,7 +381,7 @@ namespace Umbraco.Web
/// <param name="criteria"></param>
/// <param name="searchProvider"></param>
/// <returns></returns>
public dynamic Search(Examine.SearchCriteria.ISearchCriteria criteria, Examine.Providers.BaseSearchProvider searchProvider = null)
public dynamic Search(ISearchCriteria criteria, BaseSearchProvider searchProvider = null)
{
return _dynamicContentQuery == null
? new DynamicPublishedContentList(
@@ -383,6 +389,51 @@ namespace Umbraco.Web
: _dynamicContentQuery.Search(criteria, searchProvider);
}
/// <summary>
/// Searches content
/// </summary>
/// <param name="skip"></param>
/// <param name="take"></param>
/// <param name="totalRecords"></param>
/// <param name="term"></param>
/// <param name="useWildCards"></param>
/// <param name="searchProvider"></param>
/// <returns></returns>
public IEnumerable<IPublishedContent> TypedSearch(int skip, int take, out int totalRecords, string term, bool useWildCards = true, string searchProvider = null)
{
if (_typedContentQuery != null) return _typedContentQuery.TypedSearch(skip, take, out totalRecords, term, useWildCards, searchProvider);
var searcher = ExamineManager.Instance.DefaultSearchProvider;
if (string.IsNullOrEmpty(searchProvider) == false)
searcher = ExamineManager.Instance.SearchProviderCollection[searchProvider];
//if both are zero, use the native Examine API
if (skip == 0 && take == 0)
{
var results = searcher.Search(term, useWildCards);
totalRecords = results.TotalItemCount;
return results.ConvertSearchResultToPublishedContent(_contentCache);
}
var luceneSearcher = searcher as BaseLuceneSearcher;
//if the searcher is not a base lucene searcher, we'll have to use Linq Take (edge case)
if (luceneSearcher == null)
{
var results = searcher.Search(term, useWildCards);
totalRecords = results.TotalItemCount;
return results
.Skip(skip) //uses Examine Skip
.ConvertSearchResultToPublishedContent(_contentCache)
.Take(take); //uses Linq Take
}
//create criteria for all fields
var allSearchFieldCriteria = SearchAllFields(term, useWildCards, luceneSearcher);
return TypedSearch(skip, take, out totalRecords, allSearchFieldCriteria, searcher);
}
/// <summary>
/// Searches content
/// </summary>
@@ -391,16 +442,51 @@ namespace Umbraco.Web
/// <param name="searchProvider"></param>
/// <returns></returns>
public IEnumerable<IPublishedContent> TypedSearch(string term, bool useWildCards = true, string searchProvider = null)
{
if (_typedContentQuery != null) return _typedContentQuery.TypedSearch(term, useWildCards, searchProvider);
var searcher = Examine.ExamineManager.Instance.DefaultSearchProvider;
if (string.IsNullOrEmpty(searchProvider) == false)
searcher = Examine.ExamineManager.Instance.SearchProviderCollection[searchProvider];
var results = searcher.Search(term, useWildCards);
return results.ConvertSearchResultToPublishedContent(_contentCache);
{
int total;
return TypedSearch(0, 0, out total, term, useWildCards, searchProvider);
}
/// <summary>
/// Searhes content
/// </summary>
/// <param name="skip"></param>
/// <param name="take"></param>
/// <param name="totalRecords"></param>
/// <param name="criteria"></param>
/// <param name="searchProvider"></param>
/// <returns></returns>
public IEnumerable<IPublishedContent> TypedSearch(int skip, int take, out int totalRecords, ISearchCriteria criteria, BaseSearchProvider searchProvider = null)
{
if (_typedContentQuery != null) return _typedContentQuery.TypedSearch(skip, take, out totalRecords, criteria, searchProvider);
var s = ExamineManager.Instance.DefaultSearchProvider;
if (searchProvider != null)
s = searchProvider;
//if both are zero, use the simple native Examine API
if (skip == 0 && take == 0)
{
var r = s.Search(criteria);
totalRecords = r.TotalItemCount;
return r.ConvertSearchResultToPublishedContent(_contentCache);
}
var maxResults = skip + take;
var results = s.Search(criteria,
//don't return more results than we need for the paging
//this is the 'trick' - we need to be able to load enough search results to fill
//all items to the maxResults
maxResults: maxResults);
totalRecords = results.TotalItemCount;
//use examine to skip, this will ensure the lucene data is not loaded for those items
var records = results.Skip(skip);
return records.ConvertSearchResultToPublishedContent(_contentCache);
}
/// <summary>
/// Searhes content
@@ -410,14 +496,54 @@ namespace Umbraco.Web
/// <returns></returns>
public IEnumerable<IPublishedContent> TypedSearch(Examine.SearchCriteria.ISearchCriteria criteria, Examine.Providers.BaseSearchProvider searchProvider = null)
{
if (_typedContentQuery != null) return _typedContentQuery.TypedSearch(criteria, searchProvider);
var total = 0;
return TypedSearch(0, 0, out total, criteria, searchProvider);
}
var s = Examine.ExamineManager.Instance.DefaultSearchProvider;
if (searchProvider != null)
s = searchProvider;
/// <summary>
/// Helper method to create an ISearchCriteria for searching all fields in a <see cref="BaseLuceneSearcher"/>
/// </summary>
/// <param name="searchText"></param>
/// <param name="useWildcards"></param>
/// <param name="searcher"></param>
/// <returns></returns>
/// <remarks>
/// This is here because some of this stuff is internal in Examine
/// </remarks>
private ISearchCriteria SearchAllFields(string searchText, bool useWildcards, BaseLuceneSearcher searcher)
{
var sc = searcher.CreateSearchCriteria();
var results = s.Search(criteria);
return results.ConvertSearchResultToPublishedContent(_contentCache);
if (_examineGetSearchFields == null)
{
//get the GetSearchFields method from BaseLuceneSearcher
_examineGetSearchFields = typeof(BaseLuceneSearcher).GetMethod("GetSearchFields", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
}
//get the results of searcher.BaseLuceneSearcher() using ugly reflection since it's not public
var searchFields = (IEnumerable<string>)_examineGetSearchFields.Invoke(searcher, null);
//this is what Examine does internally to create ISearchCriteria for searching all fields
var strArray = searchText.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
sc = useWildcards == false
? sc.GroupedOr(searchFields, strArray).Compile()
: sc.GroupedOr(searchFields, strArray.Select(x => new CustomExamineValue(Examineness.ComplexWildcard, x.MultipleCharacterWildcard().Value)).ToArray<IExamineValue>()).Compile();
return sc;
}
private static MethodInfo _examineGetSearchFields;
//support class since Examine doesn't expose it's own ExamineValue class publicly
private class CustomExamineValue : IExamineValue
{
public CustomExamineValue(Examineness vagueness, string value)
{
this.Examineness = vagueness;
this.Value = value;
this.Level = 1f;
}
public Examineness Examineness { get; private set; }
public string Value { get; private set; }
public float Level { get; private set; }
}
#endregion

View File

@@ -1251,24 +1251,53 @@ namespace Umbraco.Web
public IEnumerable<IPublishedContent> TypedSearch(string term, bool useWildCards = true, string searchProvider = null)
{
return ContentQuery.TypedSearch(term, useWildCards, searchProvider);
}
/// <summary>
/// Searhes content
/// </summary>
/// <param name="criteria"></param>
}
/// <summary>
/// Searches content
/// </summary>
/// <param name="skip"></param>
/// <param name="take"></param>
/// <param name="totalRecords"></param>
/// <param name="term"></param>
/// <param name="useWildCards"></param>
/// <param name="searchProvider"></param>
/// <returns></returns>
public IEnumerable<IPublishedContent> TypedSearch(Examine.SearchCriteria.ISearchCriteria criteria, Examine.Providers.BaseSearchProvider searchProvider = null)
public IEnumerable<IPublishedContent> TypedSearch(int skip, int take, out int totalRecords, string term, bool useWildCards = true, string searchProvider = null)
{
return ContentQuery.TypedSearch(skip, take, out totalRecords, term, useWildCards, searchProvider);
}
/// <summary>
/// Searhes content
/// </summary>
/// <param name="skip"></param>
/// <param name="take"></param>
/// <param name="totalRecords"></param>
/// <param name="criteria"></param>
/// <param name="searchProvider"></param>
/// <returns></returns>
public IEnumerable<IPublishedContent> TypedSearch(int skip, int take, out int totalRecords, Examine.SearchCriteria.ISearchCriteria criteria, Examine.Providers.BaseSearchProvider searchProvider = null)
{
return ContentQuery.TypedSearch(criteria, searchProvider);
}
#endregion
#region Xml
public dynamic ToDynamicXml(string xml)
return ContentQuery.TypedSearch(skip, take, out totalRecords, criteria, searchProvider);
}
/// <summary>
/// Searhes content
/// </summary>
/// <param name="criteria"></param>
/// <param name="searchProvider"></param>
/// <returns></returns>
public IEnumerable<IPublishedContent> TypedSearch(Examine.SearchCriteria.ISearchCriteria criteria, Examine.Providers.BaseSearchProvider searchProvider = null)
{
return ContentQuery.TypedSearch(criteria, searchProvider);
}
#endregion
#region Xml
public dynamic ToDynamicXml(string xml)
{
if (string.IsNullOrWhiteSpace(xml)) return null;
var xElement = XElement.Parse(xml);
@@ -1439,8 +1468,8 @@ namespace Umbraco.Web
/// </summary>
public IHtmlString Truncate(string html, int length, bool addElipsis, bool treatTagsAsContent)
{
return _stringUtilities.Truncate(html, length, addElipsis, treatTagsAsContent);
}
return _stringUtilities.Truncate(html, length, addElipsis, treatTagsAsContent);
}
#region Truncate by Words
/// <summary>
@@ -1451,7 +1480,7 @@ namespace Umbraco.Web
int length = _stringUtilities.WordsToLength(html, words);
return Truncate(html, length, true, false);
}
}
/// <summary>
/// Truncates a string to a given amount of words, can add a elipsis at the end (...). Method checks for open html tags, and makes sure to close them
@@ -1481,12 +1510,12 @@ namespace Umbraco.Web
int length = _stringUtilities.WordsToLength(html.ToHtmlString(), words);
return Truncate(html, length, addElipsis, false);
}
#endregion
}
#endregion
#endregion
#region If
/// <summary>
/// If the test is true, the string valueIfTrue will be returned, otherwise the valueIfFalse will be returned.
/// </summary>