2019-01-07 23:49:29 +11:00
|
|
|
using System.Collections;
|
2021-09-15 13:40:08 +02:00
|
|
|
using System.Globalization;
|
2018-06-29 19:52:40 +02:00
|
|
|
using Examine;
|
2018-12-17 12:17:03 +11:00
|
|
|
using Examine.Search;
|
2021-02-09 10:22:42 +01:00
|
|
|
using Umbraco.Cms.Core;
|
|
|
|
|
using Umbraco.Cms.Core.Models.PublishedContent;
|
|
|
|
|
using Umbraco.Cms.Core.PublishedCache;
|
2021-02-12 10:57:50 +01:00
|
|
|
using Umbraco.Cms.Infrastructure.Examine;
|
2021-02-09 11:26:22 +01:00
|
|
|
using Umbraco.Extensions;
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
namespace Umbraco.Cms.Infrastructure;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// A class used to query for published content, media items
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <seealso cref="Umbraco.Cms.Core.IPublishedContentQuery" />
|
|
|
|
|
public class PublishedContentQuery : IPublishedContentQuery
|
2018-06-29 19:52:40 +02:00
|
|
|
{
|
2022-06-02 08:18:31 +02:00
|
|
|
private readonly IExamineManager _examineManager;
|
2024-10-01 15:03:02 +02:00
|
|
|
private readonly IPublishedContentCache _publishedContent;
|
|
|
|
|
private readonly IPublishedMediaCache _publishedMediaCache;
|
2022-06-02 08:18:31 +02:00
|
|
|
private readonly IVariationContextAccessor _variationContextAccessor;
|
2022-07-13 11:14:31 +02:00
|
|
|
private static readonly HashSet<string> _returnedQueryFields =
|
2022-06-23 00:36:37 +02:00
|
|
|
new() { ExamineFieldNames.ItemIdFieldName, ExamineFieldNames.CategoryFieldName };
|
|
|
|
|
|
2018-06-29 19:52:40 +02:00
|
|
|
/// <summary>
|
2022-06-02 08:18:31 +02:00
|
|
|
/// Initializes a new instance of the <see cref="PublishedContentQuery" /> class.
|
2018-06-29 19:52:40 +02:00
|
|
|
/// </summary>
|
Resolved more warnings, and marked more warning types as errors (#16991)
* Fix warnings SA1111, SA1028, SA1500, IDE1270 in Umbraco.Web.Website, and updated rules.
* Remove warnings: IDE0270: Null check can be simplified
* More SqlServer project warnings resolved
* CS0105 namespace appeared already
* Suppress warning until implementation:
#pragma warning disable CS0162 // Unreachable code detected
#pragma warning disable CS0618 // Type or member is obsolete
CS0162 remove unreachable code
SA1028 remove trailing whitespace
SA1106 no empty statements
CS1570 malformed XML
CS1572 corrected xml parameter
CS1573 param tag added
IDE0007 var not explicit
IDE0008 explicit not var
IDE0057 simplify substring
IDE0074 compound assignment
CA1825 array.empty
Down to 3479 warnings
* - SA1116, SA117 params on same line
- IDE0057 substring simplified
Specific warnings for Umbraco.Tests.Benchmarks
* Fixed IDE0074 compound assignment and added specific warnings for Umbraco.Tests.Common
* Specific warnings for Umbraco.Tests.Integration and Umbraco.Tests.Common
Fixed:
- SA1111, SA1116, SA117 params and line formatting (not all as there are many)
- SA1122 string.Empty
- IDE0057 simplify substring
- IDE0044,IDE0044 make field readonly
- IDE1006 naming rule violation (add _)
- SA1111 closing parenthesis on line of last parameter
- SA1649 filename match type name
- SA1312,SA1306 lowercase variable and field names
* Fixed various warnings where they are more straight-forward, including:
- SA1649 file name match type name
- SA111 parenthesis on line of last parameter
- IDE0028 simplify collection initializer
- SA1306 lower-case letter field
- IDE044 readonly field
- SA1122 string.Empty
- SA1116 params same line
- IDE1006 upper casing
- IDE0041 simplify null check
Updated the following projects to only list their remaining specific warning codes:
- Umbraco.Tests.UnitTests
Typo in `Umbraco.Web.Website` project
* Reverted test change
* Now 1556 warnings.
Fixed various warnings where they are more straight-forward, including:
- SA1111/SA1116/SA1119 parenthesis
- SA1117 params
- SA1312 lowercase variable
- SA1121 built-in type
- SA1500/SA1513/SA1503 formatting braces
- SA1400 declare access modifier
- SA1122 string.Empty
- SA1310 no underscore
- IDE0049 name simplified
- IDE0057 simplify substring
- IDE0074 compound assignment
- IDE0032 use auto-property
- IDE0037 simplify member name
- IDE0008 explicit type not var
- IDE0016/IDE0270/IDE0041 simplify null checks
- IDE0048/SA1407 clarity in arithmetic
- IDE1006 correct param names
- IDE0042 deconstruct variable
- IDE0044 readonly
- IDE0018 inline variable declarations
- IDE0074/IDE0054 compound assignment
- IDE1006 naming
- CS1573 param XML
- CS0168 unused variable
Comment formatting in project files for consistency.
Updated all projects to only list remaining specific warning codes as warnings instead of errors (errors is now default).
* Type not var, and more warning exceptions
* Tweaked merge issue, readded comment about rollback
* Readded comment re rollback.
* Readded comments
* Comment tweak
* Comment tweak
2024-09-24 12:56:28 +01:00
|
|
|
public PublishedContentQuery(
|
|
|
|
|
IVariationContextAccessor variationContextAccessor,
|
2024-10-01 15:03:02 +02:00
|
|
|
IExamineManager examineManager,
|
|
|
|
|
IPublishedContentCache publishedContent,
|
|
|
|
|
IPublishedMediaCache publishedMediaCache)
|
2018-06-29 19:52:40 +02:00
|
|
|
{
|
2022-06-02 08:18:31 +02:00
|
|
|
_variationContextAccessor = variationContextAccessor ??
|
|
|
|
|
throw new ArgumentNullException(nameof(variationContextAccessor));
|
|
|
|
|
_examineManager = examineManager ?? throw new ArgumentNullException(nameof(examineManager));
|
2024-10-01 15:03:02 +02:00
|
|
|
_publishedContent = publishedContent;
|
|
|
|
|
_publishedMediaCache = publishedMediaCache;
|
2022-06-02 08:18:31 +02:00
|
|
|
}
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
#region Convert Helpers
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
private static bool ConvertIdObjectToInt(object id, out int intId)
|
|
|
|
|
{
|
|
|
|
|
switch (id)
|
2018-06-29 19:52:40 +02:00
|
|
|
{
|
2022-06-02 08:18:31 +02:00
|
|
|
case string s:
|
|
|
|
|
return int.TryParse(s, NumberStyles.Integer, CultureInfo.InvariantCulture, out intId);
|
2020-03-03 11:59:17 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
case int i:
|
|
|
|
|
intId = i;
|
|
|
|
|
return true;
|
2020-03-03 11:59:17 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
default:
|
|
|
|
|
intId = default;
|
|
|
|
|
return false;
|
2018-06-29 19:52:40 +02:00
|
|
|
}
|
2022-06-02 08:18:31 +02:00
|
|
|
}
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
private static bool ConvertIdObjectToGuid(object id, out Guid guidId)
|
|
|
|
|
{
|
|
|
|
|
switch (id)
|
2018-06-29 19:52:40 +02:00
|
|
|
{
|
2022-06-02 08:18:31 +02:00
|
|
|
case string s:
|
|
|
|
|
return Guid.TryParse(s, out guidId);
|
2020-03-03 11:59:17 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
case Guid g:
|
|
|
|
|
guidId = g;
|
|
|
|
|
return true;
|
2020-03-03 11:59:17 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
default:
|
|
|
|
|
guidId = default;
|
|
|
|
|
return false;
|
2020-03-03 11:59:17 +01:00
|
|
|
}
|
2022-06-02 08:18:31 +02:00
|
|
|
}
|
2022-02-15 16:46:20 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
private static bool ConvertIdObjectToUdi(object id, out Udi? guidId)
|
|
|
|
|
{
|
|
|
|
|
switch (id)
|
2020-03-03 11:59:17 +01:00
|
|
|
{
|
2022-06-02 08:18:31 +02:00
|
|
|
case string s:
|
|
|
|
|
return UdiParser.TryParse(s, out guidId);
|
2020-03-03 11:59:17 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
case Udi u:
|
|
|
|
|
guidId = u;
|
|
|
|
|
return true;
|
2020-03-03 11:59:17 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
default:
|
|
|
|
|
guidId = default;
|
|
|
|
|
return false;
|
2018-06-29 19:52:40 +02:00
|
|
|
}
|
2022-06-02 08:18:31 +02:00
|
|
|
}
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
#endregion
|
2020-03-03 11:59:17 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
#region Content
|
2020-03-03 11:59:17 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
public IPublishedContent? Content(int id)
|
2024-10-01 15:03:02 +02:00
|
|
|
=> ItemById(id, _publishedContent);
|
2020-03-03 11:59:17 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
public IPublishedContent? Content(Guid id)
|
2024-10-01 15:03:02 +02:00
|
|
|
=> ItemById(id, _publishedContent);
|
2020-03-03 11:59:17 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
public IPublishedContent? Content(Udi? id)
|
|
|
|
|
{
|
|
|
|
|
if (!(id is GuidUdi udi))
|
2018-06-29 19:52:40 +02:00
|
|
|
{
|
2022-06-02 08:18:31 +02:00
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-01 15:03:02 +02:00
|
|
|
return ItemById(udi.Guid, _publishedContent);
|
2022-06-02 08:18:31 +02:00
|
|
|
}
|
2022-03-16 14:39:28 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
public IPublishedContent? Content(object id)
|
|
|
|
|
{
|
|
|
|
|
if (ConvertIdObjectToInt(id, out var intId))
|
|
|
|
|
{
|
|
|
|
|
return Content(intId);
|
2018-06-29 19:52:40 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
if (ConvertIdObjectToGuid(id, out Guid guidId))
|
2018-06-29 19:52:40 +02:00
|
|
|
{
|
2022-06-02 08:18:31 +02:00
|
|
|
return Content(guidId);
|
|
|
|
|
}
|
2022-02-15 16:46:20 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
if (ConvertIdObjectToUdi(id, out Udi? udiId))
|
|
|
|
|
{
|
|
|
|
|
return Content(udiId);
|
|
|
|
|
}
|
2022-02-15 16:46:20 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
return null;
|
|
|
|
|
}
|
2022-02-15 16:46:20 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
public IEnumerable<IPublishedContent> Content(IEnumerable<int> ids)
|
2024-10-01 15:03:02 +02:00
|
|
|
=> ItemsByIds(_publishedContent, ids);
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
public IEnumerable<IPublishedContent> Content(IEnumerable<Guid> ids)
|
2024-10-01 15:03:02 +02:00
|
|
|
=> ItemsByIds(_publishedContent, ids);
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
public IEnumerable<IPublishedContent> Content(IEnumerable<object> ids)
|
|
|
|
|
=> ids.Select(Content).WhereNotNull();
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
public IEnumerable<IPublishedContent> ContentAtRoot()
|
2024-10-01 15:03:02 +02:00
|
|
|
=> ItemsAtRoot(_publishedContent);
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
#endregion
|
2020-03-03 11:59:17 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
#region Media
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
public IPublishedContent? Media(int id)
|
2024-10-01 15:03:02 +02:00
|
|
|
=> ItemById(id, _publishedMediaCache);
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
public IPublishedContent? Media(Guid id)
|
2024-10-01 15:03:02 +02:00
|
|
|
=> ItemById(id, _publishedMediaCache);
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
public IPublishedContent? Media(Udi? id)
|
|
|
|
|
{
|
|
|
|
|
if (!(id is GuidUdi udi))
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2024-10-01 15:03:02 +02:00
|
|
|
return ItemById(udi.Guid, _publishedMediaCache);
|
2022-06-02 08:18:31 +02:00
|
|
|
}
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
public IPublishedContent? Media(object id)
|
|
|
|
|
{
|
|
|
|
|
if (ConvertIdObjectToInt(id, out var intId))
|
2018-06-29 19:52:40 +02:00
|
|
|
{
|
2022-06-02 08:18:31 +02:00
|
|
|
return Media(intId);
|
|
|
|
|
}
|
2022-03-16 14:39:28 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
if (ConvertIdObjectToGuid(id, out Guid guidId))
|
|
|
|
|
{
|
|
|
|
|
return Media(guidId);
|
2018-06-29 19:52:40 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
if (ConvertIdObjectToUdi(id, out Udi? udiId))
|
2018-06-29 19:52:40 +02:00
|
|
|
{
|
2022-06-02 08:18:31 +02:00
|
|
|
return Media(udiId);
|
|
|
|
|
}
|
2022-02-15 16:46:20 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
return null;
|
|
|
|
|
}
|
2022-02-15 16:46:20 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
public IEnumerable<IPublishedContent> Media(IEnumerable<int> ids)
|
2024-10-01 15:03:02 +02:00
|
|
|
=> ItemsByIds(_publishedMediaCache, ids);
|
2022-02-15 16:46:20 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
public IEnumerable<IPublishedContent> Media(IEnumerable<object> ids)
|
|
|
|
|
=> ids.Select(Media).WhereNotNull();
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
public IEnumerable<IPublishedContent> Media(IEnumerable<Guid> ids)
|
2024-10-01 15:03:02 +02:00
|
|
|
=> ItemsByIds(_publishedMediaCache, ids);
|
2022-02-15 16:46:20 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
public IEnumerable<IPublishedContent> MediaAtRoot()
|
2024-10-01 15:03:02 +02:00
|
|
|
=> ItemsAtRoot(_publishedMediaCache);
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
#endregion
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
#region Used by Content/Media
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
private static IPublishedContent? ItemById(int id, IPublishedCache? cache)
|
|
|
|
|
=> cache?.GetById(id);
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
private static IPublishedContent? ItemById(Guid id, IPublishedCache? cache)
|
|
|
|
|
=> cache?.GetById(id);
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
private static IEnumerable<IPublishedContent> ItemsByIds(IPublishedCache? cache, IEnumerable<int> ids)
|
|
|
|
|
=> ids.Select(eachId => ItemById(eachId, cache)).WhereNotNull();
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
private IEnumerable<IPublishedContent> ItemsByIds(IPublishedCache? cache, IEnumerable<Guid> ids)
|
|
|
|
|
=> ids.Select(eachId => ItemById(eachId, cache)).WhereNotNull();
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
private static IEnumerable<IPublishedContent> ItemsAtRoot(IPublishedCache? cache)
|
|
|
|
|
=> cache?.GetAtRoot() ?? Array.Empty<IPublishedContent>();
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
#endregion
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
#region Search
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
/// <inheritdoc />
|
|
|
|
|
public IEnumerable<PublishedSearchResult> Search(string term, string culture = "*",
|
|
|
|
|
string indexName = Constants.UmbracoIndexes.ExternalIndexName)
|
|
|
|
|
=> Search(term, 0, 0, out _, culture, indexName);
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
/// <inheritdoc />
|
|
|
|
|
public IEnumerable<PublishedSearchResult> Search(string term, int skip, int take, out long totalRecords,
|
|
|
|
|
string culture = "*", string indexName = Constants.UmbracoIndexes.ExternalIndexName,
|
|
|
|
|
ISet<string>? loadedFields = null)
|
|
|
|
|
{
|
|
|
|
|
if (skip < 0)
|
|
|
|
|
{
|
|
|
|
|
throw new ArgumentOutOfRangeException(nameof(skip), skip,
|
|
|
|
|
"The value must be greater than or equal to zero.");
|
|
|
|
|
}
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
if (take < 0)
|
|
|
|
|
{
|
|
|
|
|
throw new ArgumentOutOfRangeException(nameof(take), take,
|
|
|
|
|
"The value must be greater than or equal to zero.");
|
|
|
|
|
}
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
if (string.IsNullOrEmpty(indexName))
|
2018-06-29 19:52:40 +02:00
|
|
|
{
|
2022-06-02 08:18:31 +02:00
|
|
|
indexName = Constants.UmbracoIndexes.ExternalIndexName;
|
|
|
|
|
}
|
2020-01-05 22:55:55 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
if (!_examineManager.TryGetIndex(indexName, out IIndex? index) || index is not IUmbracoIndex umbIndex)
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException(
|
|
|
|
|
$"No index found by name {indexName} or is not of type {typeof(IUmbracoIndex)}");
|
|
|
|
|
}
|
2020-01-05 22:55:55 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
IQuery? query = umbIndex.Searcher.CreateQuery(IndexTypes.Content);
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
IOrdering ordering;
|
|
|
|
|
if (culture == "*")
|
|
|
|
|
{
|
|
|
|
|
// Search everything
|
|
|
|
|
ordering = query.ManagedQuery(term);
|
|
|
|
|
}
|
|
|
|
|
else if (string.IsNullOrWhiteSpace(culture))
|
|
|
|
|
{
|
|
|
|
|
// Only search invariant
|
|
|
|
|
ordering = query
|
|
|
|
|
.Field(UmbracoExamineFieldNames.VariesByCultureFieldName, "n") // Must not vary by culture
|
|
|
|
|
.And().ManagedQuery(term);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Only search the specified culture
|
|
|
|
|
var fields =
|
|
|
|
|
umbIndex.GetCultureAndInvariantFields(culture)
|
|
|
|
|
.ToArray(); // Get all index fields suffixed with the culture name supplied
|
2022-02-15 16:46:20 +01:00
|
|
|
|
2024-02-07 13:43:37 +01:00
|
|
|
// Filter out unpublished content for the specified culture if the content varies by culture
|
|
|
|
|
// The published__{culture} field is not populated when the content is not published in that culture
|
|
|
|
|
ordering = query
|
|
|
|
|
.ManagedQuery(term, fields)
|
|
|
|
|
.Not().Group(q => q
|
|
|
|
|
.Field(UmbracoExamineFieldNames.VariesByCultureFieldName, "y")
|
|
|
|
|
.Not().Field($"{UmbracoExamineFieldNames.PublishedFieldName}_{culture.ToLowerInvariant()}", "y"));
|
|
|
|
|
}
|
2022-02-15 16:46:20 +01:00
|
|
|
|
2024-02-07 13:43:37 +01:00
|
|
|
return Search(ordering, skip, take, out totalRecords, culture);
|
2022-06-02 08:18:31 +02:00
|
|
|
}
|
2019-11-13 14:39:11 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
/// <inheritdoc />
|
|
|
|
|
public IEnumerable<PublishedSearchResult> Search(IQueryExecutor query)
|
|
|
|
|
=> Search(query, 0, 0, out _);
|
2019-01-07 23:49:29 +11:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
/// <inheritdoc />
|
|
|
|
|
public IEnumerable<PublishedSearchResult> Search(IQueryExecutor query, int skip, int take, out long totalRecords)
|
2024-02-07 13:43:37 +01:00
|
|
|
=> Search(query, skip, take, out totalRecords, null);
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public IEnumerable<PublishedSearchResult> Search(IQueryExecutor query, int skip, int take, out long totalRecords, string? culture)
|
2022-06-02 08:18:31 +02:00
|
|
|
{
|
|
|
|
|
if (skip < 0)
|
|
|
|
|
{
|
|
|
|
|
throw new ArgumentOutOfRangeException(nameof(skip), skip,
|
|
|
|
|
"The value must be greater than or equal to zero.");
|
2018-06-29 19:52:40 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
if (take < 0)
|
|
|
|
|
{
|
|
|
|
|
throw new ArgumentOutOfRangeException(nameof(take), take,
|
|
|
|
|
"The value must be greater than or equal to zero.");
|
|
|
|
|
}
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
if (query is IOrdering ordering)
|
2018-06-29 19:52:40 +02:00
|
|
|
{
|
2024-02-07 13:43:37 +01:00
|
|
|
// Filter selected fields because results are loaded from the published snapshot based on these
|
|
|
|
|
query = ordering.SelectFields(_returnedQueryFields);
|
2022-06-02 08:18:31 +02:00
|
|
|
}
|
2020-01-05 22:55:55 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
ISearchResults? results = skip == 0 && take == 0
|
|
|
|
|
? query.Execute()
|
|
|
|
|
: query.Execute(QueryOptions.SkipTake(skip, take));
|
2022-02-15 16:46:20 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
totalRecords = results.TotalItemCount;
|
|
|
|
|
|
2024-02-07 13:43:37 +01:00
|
|
|
return culture.IsNullOrWhiteSpace()
|
2024-10-01 15:03:02 +02:00
|
|
|
? results.ToPublishedSearchResults(_publishedContent)
|
|
|
|
|
: new CultureContextualSearchResults(results.ToPublishedSearchResults(_publishedContent), _variationContextAccessor, culture);
|
2022-06-02 08:18:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// This is used to contextualize the values in the search results when enumerating over them, so that the correct
|
|
|
|
|
/// culture values are used.
|
|
|
|
|
/// </summary>
|
2025-07-21 08:32:54 +02:00
|
|
|
private sealed class CultureContextualSearchResults : IEnumerable<PublishedSearchResult>
|
2022-06-02 08:18:31 +02:00
|
|
|
{
|
|
|
|
|
private readonly string _culture;
|
|
|
|
|
private readonly IVariationContextAccessor _variationContextAccessor;
|
|
|
|
|
private readonly IEnumerable<PublishedSearchResult> _wrapped;
|
2020-01-05 22:55:55 +01:00
|
|
|
|
Resolved more warnings, and marked more warning types as errors (#16991)
* Fix warnings SA1111, SA1028, SA1500, IDE1270 in Umbraco.Web.Website, and updated rules.
* Remove warnings: IDE0270: Null check can be simplified
* More SqlServer project warnings resolved
* CS0105 namespace appeared already
* Suppress warning until implementation:
#pragma warning disable CS0162 // Unreachable code detected
#pragma warning disable CS0618 // Type or member is obsolete
CS0162 remove unreachable code
SA1028 remove trailing whitespace
SA1106 no empty statements
CS1570 malformed XML
CS1572 corrected xml parameter
CS1573 param tag added
IDE0007 var not explicit
IDE0008 explicit not var
IDE0057 simplify substring
IDE0074 compound assignment
CA1825 array.empty
Down to 3479 warnings
* - SA1116, SA117 params on same line
- IDE0057 substring simplified
Specific warnings for Umbraco.Tests.Benchmarks
* Fixed IDE0074 compound assignment and added specific warnings for Umbraco.Tests.Common
* Specific warnings for Umbraco.Tests.Integration and Umbraco.Tests.Common
Fixed:
- SA1111, SA1116, SA117 params and line formatting (not all as there are many)
- SA1122 string.Empty
- IDE0057 simplify substring
- IDE0044,IDE0044 make field readonly
- IDE1006 naming rule violation (add _)
- SA1111 closing parenthesis on line of last parameter
- SA1649 filename match type name
- SA1312,SA1306 lowercase variable and field names
* Fixed various warnings where they are more straight-forward, including:
- SA1649 file name match type name
- SA111 parenthesis on line of last parameter
- IDE0028 simplify collection initializer
- SA1306 lower-case letter field
- IDE044 readonly field
- SA1122 string.Empty
- SA1116 params same line
- IDE1006 upper casing
- IDE0041 simplify null check
Updated the following projects to only list their remaining specific warning codes:
- Umbraco.Tests.UnitTests
Typo in `Umbraco.Web.Website` project
* Reverted test change
* Now 1556 warnings.
Fixed various warnings where they are more straight-forward, including:
- SA1111/SA1116/SA1119 parenthesis
- SA1117 params
- SA1312 lowercase variable
- SA1121 built-in type
- SA1500/SA1513/SA1503 formatting braces
- SA1400 declare access modifier
- SA1122 string.Empty
- SA1310 no underscore
- IDE0049 name simplified
- IDE0057 simplify substring
- IDE0074 compound assignment
- IDE0032 use auto-property
- IDE0037 simplify member name
- IDE0008 explicit type not var
- IDE0016/IDE0270/IDE0041 simplify null checks
- IDE0048/SA1407 clarity in arithmetic
- IDE1006 correct param names
- IDE0042 deconstruct variable
- IDE0044 readonly
- IDE0018 inline variable declarations
- IDE0074/IDE0054 compound assignment
- IDE1006 naming
- CS1573 param XML
- CS0168 unused variable
Comment formatting in project files for consistency.
Updated all projects to only list remaining specific warning codes as warnings instead of errors (errors is now default).
* Type not var, and more warning exceptions
* Tweaked merge issue, readded comment about rollback
* Readded comment re rollback.
* Readded comments
* Comment tweak
* Comment tweak
2024-09-24 12:56:28 +01:00
|
|
|
public CultureContextualSearchResults(
|
|
|
|
|
IEnumerable<PublishedSearchResult> wrapped,
|
|
|
|
|
IVariationContextAccessor variationContextAccessor,
|
|
|
|
|
string culture)
|
2022-06-02 08:18:31 +02:00
|
|
|
{
|
|
|
|
|
_wrapped = wrapped;
|
|
|
|
|
_variationContextAccessor = variationContextAccessor;
|
|
|
|
|
_culture = culture;
|
|
|
|
|
}
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
public IEnumerator<PublishedSearchResult> GetEnumerator()
|
|
|
|
|
{
|
|
|
|
|
// We need to change the current culture to what is requested and then change it back
|
|
|
|
|
VariationContext? originalContext = _variationContextAccessor.VariationContext;
|
|
|
|
|
if (!_culture.IsNullOrWhiteSpace() && !_culture.InvariantEquals(originalContext?.Culture))
|
|
|
|
|
{
|
|
|
|
|
_variationContextAccessor.VariationContext = new VariationContext(_culture);
|
|
|
|
|
}
|
2019-11-01 10:49:45 +01:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
// Now the IPublishedContent returned will be contextualized to the culture specified and will be reset when the enumerator is disposed
|
|
|
|
|
return new CultureContextualSearchResultsEnumerator(_wrapped.GetEnumerator(), _variationContextAccessor,
|
|
|
|
|
originalContext);
|
2018-06-29 19:52:40 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
|
|
|
|
|
2019-01-07 23:49:29 +11:00
|
|
|
/// <summary>
|
2022-06-02 08:18:31 +02:00
|
|
|
/// Resets the variation context when this is disposed.
|
2019-01-07 23:49:29 +11:00
|
|
|
/// </summary>
|
2025-07-21 08:32:54 +02:00
|
|
|
private sealed class CultureContextualSearchResultsEnumerator : IEnumerator<PublishedSearchResult>
|
2019-01-07 23:49:29 +11:00
|
|
|
{
|
2022-06-02 08:18:31 +02:00
|
|
|
private readonly VariationContext? _originalContext;
|
2020-03-03 11:59:17 +01:00
|
|
|
private readonly IVariationContextAccessor _variationContextAccessor;
|
2022-06-02 08:18:31 +02:00
|
|
|
private readonly IEnumerator<PublishedSearchResult> _wrapped;
|
2019-01-07 23:49:29 +11:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
public CultureContextualSearchResultsEnumerator(
|
|
|
|
|
IEnumerator<PublishedSearchResult> wrapped,
|
|
|
|
|
IVariationContextAccessor variationContextAccessor,
|
|
|
|
|
VariationContext? originalContext)
|
2019-01-07 23:49:29 +11:00
|
|
|
{
|
|
|
|
|
_wrapped = wrapped;
|
|
|
|
|
_variationContextAccessor = variationContextAccessor;
|
2022-06-02 08:18:31 +02:00
|
|
|
_originalContext = originalContext;
|
2019-01-07 23:49:29 +11:00
|
|
|
}
|
|
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
public PublishedSearchResult Current => _wrapped.Current;
|
2019-01-07 23:49:29 +11:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
object IEnumerator.Current => Current;
|
2019-01-07 23:49:29 +11:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
public void Dispose()
|
2019-01-07 23:49:29 +11:00
|
|
|
{
|
2022-06-02 08:18:31 +02:00
|
|
|
_wrapped.Dispose();
|
2019-01-07 23:49:29 +11:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
// Reset to original variation context
|
|
|
|
|
_variationContextAccessor.VariationContext = _originalContext;
|
|
|
|
|
}
|
2019-01-07 23:49:29 +11:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
public bool MoveNext() => _wrapped.MoveNext();
|
2019-01-07 23:49:29 +11:00
|
|
|
|
2022-06-02 08:18:31 +02:00
|
|
|
public void Reset() => _wrapped.Reset();
|
2019-01-07 23:49:29 +11:00
|
|
|
}
|
2018-06-29 19:52:40 +02:00
|
|
|
}
|
2022-06-02 08:18:31 +02:00
|
|
|
|
|
|
|
|
#endregion
|
2018-06-29 19:52:40 +02:00
|
|
|
}
|