using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Exceptions;
namespace Umbraco.Core.Models
{
///
/// Extension methods used to manipulate content variations by the document repository
///
internal static class ContentRepositoryExtensions
{
public static void SetPublishInfo(this IContent content, string culture, string name, DateTime date)
{
if (string.IsNullOrWhiteSpace(name))
throw new ArgumentNullOrEmptyException(nameof(name));
if (culture.IsNullOrWhiteSpace())
throw new ArgumentNullOrEmptyException(nameof(culture));
content.PublishCultureInfos.AddOrUpdate(culture, name, date);
}
// adjust dates to sync between version, cultures etc used by the repo when persisting
public static void AdjustDates(this IContent content, DateTime date)
{
foreach (var culture in content.PublishedCultures.ToList())
{
if (!content.PublishCultureInfos.TryGetValue(culture, out var publishInfos))
continue;
//fixme: Removing the logic here for the old WasCulturePublished and the _publishInfosOrig has broken
// the test Can_Rollback_Version_On_Multilingual, but we need to understand what it's doing since I don't
content.PublishCultureInfos.AddOrUpdate(culture, publishInfos.Name, date);
if (content.CultureInfos.TryGetValue(culture, out var infos))
SetCultureInfo(content, culture, infos.Name, date);
}
}
// sets the edited cultures on the content
public static void SetCultureEdited(this IContent content, IEnumerable cultures)
{
if (cultures == null)
content.EditedCultures = null;
else
{
var editedCultures = new HashSet(cultures.Where(x => !x.IsNullOrWhiteSpace()), StringComparer.OrdinalIgnoreCase);
content.EditedCultures = editedCultures.Count > 0 ? editedCultures : null;
}
}
public static void SetCultureInfo(this IContentBase content, string culture, string name, DateTime date)
{
if (name.IsNullOrWhiteSpace())
throw new ArgumentNullOrEmptyException(nameof(name));
if (culture.IsNullOrWhiteSpace())
throw new ArgumentNullOrEmptyException(nameof(culture));
content.CultureInfos.AddOrUpdate(culture, name, date);
}
public static bool PublishCulture(this IContent content, string culture = "*")
{
culture = culture.NullOrWhiteSpaceAsNull();
// the variation should be supported by the content type properties
// if the content type is invariant, only '*' and 'null' is ok
// if the content type varies, everything is ok because some properties may be invariant
if (!content.ContentType.SupportsPropertyVariation(culture, "*", true))
throw new NotSupportedException($"Culture \"{culture}\" is not supported by content type \"{content.ContentType.Alias}\" with variation \"{content.ContentType.Variations}\".");
// the values we want to publish should be valid
if (content.ValidateProperties(culture).Any())
return false;
var alsoInvariant = false;
if (culture == "*") // all cultures
{
foreach (var c in content.AvailableCultures)
{
var name = content.GetCultureName(c);
if (string.IsNullOrWhiteSpace(name))
return false;
content.SetPublishInfo(c, name, DateTime.Now);
}
}
else if (culture == null) // invariant culture
{
if (string.IsNullOrWhiteSpace(content.Name))
return false;
// PublishName set by repository - nothing to do here
}
else // one single culture
{
var name = content.GetCultureName(culture);
if (string.IsNullOrWhiteSpace(name))
return false;
content.SetPublishInfo(culture, name, DateTime.Now);
alsoInvariant = true; // we also want to publish invariant values
}
// property.PublishValues only publishes what is valid, variation-wise
foreach (var property in content.Properties)
{
property.PublishValues(culture);
if (alsoInvariant)
property.PublishValues(null);
}
content.PublishedState = PublishedState.Publishing;
return true;
}
public static void UnpublishCulture(this IContent content, string culture = "*")
{
culture = culture.NullOrWhiteSpaceAsNull();
// the variation should be supported by the content type properties
if (!content.ContentType.SupportsPropertyVariation(culture, "*", true))
throw new NotSupportedException($"Culture \"{culture}\" is not supported by content type \"{content.ContentType.Alias}\" with variation \"{content.ContentType.Variations}\".");
if (culture == "*") // all cultures
content.ClearPublishInfos();
else // one single culture
content.ClearPublishInfo(culture);
// property.PublishValues only publishes what is valid, variation-wise
foreach (var property in content.Properties)
property.UnpublishValues(culture);
content.PublishedState = PublishedState.Publishing;
}
public static void ClearPublishInfos(this IContent content)
{
content.PublishCultureInfos = null;
}
public static void ClearPublishInfo(this IContent content, string culture)
{
if (culture.IsNullOrWhiteSpace())
throw new ArgumentNullOrEmptyException(nameof(culture));
content.PublishCultureInfos.Remove(culture);
// set the culture to be dirty - it's been modified
content.TouchCultureInfo(culture);
}
public static void TouchCultureInfo(this IContent content, string culture)
{
if (!content.CultureInfos.TryGetValue(culture, out var infos)) return;
content.CultureInfos.AddOrUpdate(culture, infos.Name, DateTime.Now);
}
}
}