using System.Collections;
using System.Globalization;
using Examine;
using Examine.Search;
using Microsoft.Extensions.DependencyInjection;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Core.PublishedCache;
using Umbraco.Cms.Core.Services.Navigation;
using Umbraco.Cms.Infrastructure.Examine;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure;
///
/// A class used to query for published content, media items
///
///
public class PublishedContentQuery : IPublishedContentQuery
{
private readonly IExamineManager _examineManager;
private readonly IPublishedContentCache _publishedContent;
private readonly IPublishedMediaCache _publishedMediaCache;
private readonly IVariationContextAccessor _variationContextAccessor;
private readonly IDocumentNavigationQueryService _documentNavigationQueryService;
private static readonly HashSet _returnedQueryFields =
new() { ExamineFieldNames.ItemIdFieldName, ExamineFieldNames.CategoryFieldName };
///
/// Initializes a new instance of the class.
///
public PublishedContentQuery(
IVariationContextAccessor variationContextAccessor,
IExamineManager examineManager,
IPublishedContentCache publishedContent,
IPublishedMediaCache publishedMediaCache,
IDocumentNavigationQueryService documentNavigationQueryService)
{
_variationContextAccessor = variationContextAccessor ??
throw new ArgumentNullException(nameof(variationContextAccessor));
_examineManager = examineManager ?? throw new ArgumentNullException(nameof(examineManager));
_publishedContent = publishedContent;
_publishedMediaCache = publishedMediaCache;
_documentNavigationQueryService = documentNavigationQueryService;
}
///
/// Initializes a new instance of the class.
///
[Obsolete("Scheduled for removal in Umbraco 18")]
public PublishedContentQuery(
IVariationContextAccessor variationContextAccessor,
IExamineManager examineManager,
IPublishedContentCache publishedContent,
IPublishedMediaCache publishedMediaCache)
: this(
variationContextAccessor,
examineManager,
publishedContent,
publishedMediaCache,
StaticServiceProvider.Instance.GetRequiredService())
{
}
#region Convert Helpers
private static bool ConvertIdObjectToInt(object id, out int intId)
{
switch (id)
{
case string s:
return int.TryParse(s, NumberStyles.Integer, CultureInfo.InvariantCulture, out intId);
case int i:
intId = i;
return true;
default:
intId = default;
return false;
}
}
private static bool ConvertIdObjectToGuid(object id, out Guid guidId)
{
switch (id)
{
case string s:
return Guid.TryParse(s, out guidId);
case Guid g:
guidId = g;
return true;
default:
guidId = default;
return false;
}
}
private static bool ConvertIdObjectToUdi(object id, out Udi? guidId)
{
switch (id)
{
case string s:
return UdiParser.TryParse(s, out guidId);
case Udi u:
guidId = u;
return true;
default:
guidId = default;
return false;
}
}
#endregion
#region Content
public IPublishedContent? Content(int id)
=> ItemById(id, _publishedContent);
public IPublishedContent? Content(Guid id)
=> ItemById(id, _publishedContent);
public IPublishedContent? Content(Udi? id)
{
if (!(id is GuidUdi udi))
{
return null;
}
return ItemById(udi.Guid, _publishedContent);
}
public IPublishedContent? Content(object id)
{
if (ConvertIdObjectToInt(id, out var intId))
{
return Content(intId);
}
if (ConvertIdObjectToGuid(id, out Guid guidId))
{
return Content(guidId);
}
if (ConvertIdObjectToUdi(id, out Udi? udiId))
{
return Content(udiId);
}
return null;
}
public IEnumerable Content(IEnumerable ids)
=> ItemsByIds(_publishedContent, ids);
public IEnumerable Content(IEnumerable ids)
=> ItemsByIds(_publishedContent, ids);
public IEnumerable Content(IEnumerable