using System; using System.Collections.Generic; using System.Linq; using Umbraco.Core.Composing; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Services; namespace Umbraco.Core { public static class PublishedContentExtensions { /// /// Determines whether the content has a culture. /// /// Culture is case-insensitive. public static bool HasCulture(this IPublishedContent content, string culture) => content.Cultures.ContainsKey(culture ?? string.Empty); /// /// Determines whether the content is invariant, or has a culture. /// /// Culture is case-insensitive. public static bool IsInvariantOrHasCulture(this IPublishedContent content, string culture) => !content.ContentType.VariesByCulture() || content.Cultures.ContainsKey(culture ?? ""); /// /// Filters a sequence of to return invariant items, and items that are published for the specified culture. /// /// The content items. /// /// The specific culture to filter for. If null is used the current culture is used. (Default is null). internal static IEnumerable WhereIsInvariantOrHasCulture(this IEnumerable contents, IVariationContextAccessor variationContextAccessor, string culture = null) where T : class, IPublishedContent { if (contents == null) throw new ArgumentNullException(nameof(contents)); culture = culture ?? variationContextAccessor.VariationContext?.Culture ?? ""; // either does not vary by culture, or has the specified culture return contents.Where(x => !x.ContentType.VariesByCulture() || HasCulture(x, culture)); } /// /// Gets the name of the content item. /// /// The content item. /// /// The specific culture to get the name for. If null is used the current culture is used (Default is null). public static string Name(this IPublishedContent content, IVariationContextAccessor variationContextAccessor, string culture = null) { // invariant has invariant value (whatever the requested culture) if (!content.ContentType.VariesByCulture()) return content.Cultures.TryGetValue("", out var invariantInfos) ? invariantInfos.Name : null; // handle context culture for variant if (culture == null) culture = variationContextAccessor?.VariationContext?.Culture ?? ""; // get return culture != "" && content.Cultures.TryGetValue(culture, out var infos) ? infos.Name : null; } /// /// Gets the url segment of the content item. /// /// The content item. /// /// The specific culture to get the url segment for. If null is used the current culture is used (Default is null). public static string UrlSegment(this IPublishedContent content, IVariationContextAccessor variationContextAccessor, string culture = null) { // invariant has invariant value (whatever the requested culture) if (!content.ContentType.VariesByCulture()) return content.Cultures.TryGetValue("", out var invariantInfos) ? invariantInfos.UrlSegment : null; // handle context culture for variant if (culture == null) culture = variationContextAccessor?.VariationContext?.Culture ?? ""; // get return culture != "" && content.Cultures.TryGetValue(culture, out var infos) ? infos.UrlSegment : null; } /// /// Gets the culture date of the content item. /// /// The content item. /// /// The specific culture to get the name for. If null is used the current culture is used (Default is null). public static DateTime CultureDate(this IPublishedContent content, IVariationContextAccessor variationContextAccessor, string culture = null) { // invariant has invariant value (whatever the requested culture) if (!content.ContentType.VariesByCulture()) return content.UpdateDate; // handle context culture for variant if (culture == null) culture = variationContextAccessor?.VariationContext?.Culture ?? ""; // get return culture != "" && content.Cultures.TryGetValue(culture, out var infos) ? infos.Date : DateTime.MinValue; } /// /// Gets the children of the content item. /// /// The content item. /// /// /// The specific culture to get the url children for. Default is null which will use the current culture in /// /// /// Gets children that are available for the specified culture. /// Children are sorted by their sortOrder. /// /// For culture, /// if null is used the current culture is used. /// If an empty string is used only invariant children are returned. /// If "*" is used all children are returned. /// /// /// If a variant culture is specified or there is a current culture in the then the Children returned /// will include both the variant children matching the culture AND the invariant children because the invariant children flow with the current culture. /// However, if an empty string is specified only invariant children are returned. /// /// public static IEnumerable Children(this IPublishedContent content, IVariationContextAccessor variationContextAccessor, string culture = null) { // handle context culture for variant if (culture == null) culture = variationContextAccessor?.VariationContext?.Culture ?? ""; var children = content.ChildrenForAllCultures; return culture == "*" ? children : children.Where(x => x.IsInvariantOrHasCulture(culture)); } public static string GetCreatorName(this IPublishedContent content, IUserService userService) { var user = userService.GetProfileById(content.CreatorId); return user?.Name; } public static string GetWriterName(this IPublishedContent content, IUserService userService) { var user = userService.GetProfileById(content.WriterId); return user?.Name; } } }