Moved Models from Umbraco.Core to Umbraco.Infrastructure
This commit is contained in:
49
src/Umbraco.Infrastructure/Models/ContentTagsExtensions.cs
Normal file
49
src/Umbraco.Infrastructure/Models/ContentTagsExtensions.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides extension methods for the <see cref="IContentBase"/> class, to manage tags.
|
||||
/// </summary>
|
||||
public static class ContentTagsExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Assign tags.
|
||||
/// </summary>
|
||||
/// <param name="content">The content item.</param>
|
||||
/// <param name="propertyTypeAlias">The property alias.</param>
|
||||
/// <param name="tags">The tags.</param>
|
||||
/// <param name="merge">A value indicating whether to merge the tags with existing tags instead of replacing them.</param>
|
||||
/// <param name="culture">A culture, for multi-lingual properties.</param>
|
||||
public static void AssignTags(this IContentBase content, PropertyEditorCollection propertyEditors, IDataTypeService dataTypeService, string propertyTypeAlias, IEnumerable<string> tags, bool merge = false, string culture = null)
|
||||
{
|
||||
content.GetTagProperty(propertyTypeAlias).AssignTags(propertyEditors, dataTypeService, tags, merge, culture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove tags.
|
||||
/// </summary>
|
||||
/// <param name="content">The content item.</param>
|
||||
/// <param name="propertyTypeAlias">The property alias.</param>
|
||||
/// <param name="tags">The tags.</param>
|
||||
/// <param name="culture">A culture, for multi-lingual properties.</param>
|
||||
public static void RemoveTags(this IContentBase content, PropertyEditorCollection propertyEditors, IDataTypeService dataTypeService, string propertyTypeAlias, IEnumerable<string> tags, string culture = null)
|
||||
{
|
||||
content.GetTagProperty(propertyTypeAlias).RemoveTags(propertyEditors, dataTypeService, tags, culture);
|
||||
}
|
||||
|
||||
// gets and validates the property
|
||||
private static IProperty GetTagProperty(this IContentBase content, string propertyTypeAlias)
|
||||
{
|
||||
if (content == null) throw new ArgumentNullException(nameof(content));
|
||||
|
||||
var property = content.Properties[propertyTypeAlias];
|
||||
if (property != null) return property;
|
||||
|
||||
throw new IndexOutOfRangeException($"Could not find a property with alias \"{propertyTypeAlias}\".");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
namespace Umbraco.Core.Models.Identity
|
||||
{
|
||||
internal class UserLoginInfoWrapper : IUserLoginInfo
|
||||
{
|
||||
private readonly IUserLoginInfo _info;
|
||||
|
||||
public static IUserLoginInfo Wrap(IUserLoginInfo info) => new UserLoginInfoWrapper(info);
|
||||
|
||||
private UserLoginInfoWrapper(IUserLoginInfo info)
|
||||
{
|
||||
_info = info;
|
||||
}
|
||||
|
||||
public string LoginProvider
|
||||
{
|
||||
get => _info.LoginProvider;
|
||||
set => _info.LoginProvider = value;
|
||||
}
|
||||
|
||||
public string ProviderKey
|
||||
{
|
||||
get => _info.ProviderKey;
|
||||
set => _info.ProviderKey = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
230
src/Umbraco.Infrastructure/Models/PropertyTagsExtensions.cs
Normal file
230
src/Umbraco.Infrastructure/Models/PropertyTagsExtensions.cs
Normal file
@@ -0,0 +1,230 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Umbraco.Composing;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides extension methods for the <see cref="Property"/> class to manage tags.
|
||||
/// </summary>
|
||||
public static class PropertyTagsExtensions
|
||||
{
|
||||
// gets the tag configuration for a property
|
||||
// from the datatype configuration, and the editor tag configuration attribute
|
||||
internal static TagConfiguration GetTagConfiguration(this IProperty property, PropertyEditorCollection propertyEditors, IDataTypeService dataTypeService)
|
||||
{
|
||||
if (property == null) throw new ArgumentNullException(nameof(property));
|
||||
|
||||
var editor = propertyEditors[property.PropertyType.PropertyEditorAlias];
|
||||
var tagAttribute = editor.GetTagAttribute();
|
||||
if (tagAttribute == null) return null;
|
||||
|
||||
var configurationObject = dataTypeService.GetDataType(property.PropertyType.DataTypeId).Configuration;
|
||||
var configuration = ConfigurationEditor.ConfigurationAs<TagConfiguration>(configurationObject);
|
||||
|
||||
if (configuration.Delimiter == default)
|
||||
configuration.Delimiter = tagAttribute.Delimiter;
|
||||
|
||||
return configuration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assign tags.
|
||||
/// </summary>
|
||||
/// <param name="property">The property.</param>
|
||||
/// <param name="tags">The tags.</param>
|
||||
/// <param name="merge">A value indicating whether to merge the tags with existing tags instead of replacing them.</param>
|
||||
/// <param name="culture">A culture, for multi-lingual properties.</param>
|
||||
public static void AssignTags(this IProperty property, PropertyEditorCollection propertyEditors, IDataTypeService dataTypeService, IEnumerable<string> tags, bool merge = false, string culture = null)
|
||||
{
|
||||
if (property == null) throw new ArgumentNullException(nameof(property));
|
||||
|
||||
var configuration = property.GetTagConfiguration(propertyEditors, dataTypeService);
|
||||
if (configuration == null)
|
||||
throw new NotSupportedException($"Property with alias \"{property.Alias}\" does not support tags.");
|
||||
|
||||
property.AssignTags(tags, merge, configuration.StorageType, configuration.Delimiter, culture);
|
||||
}
|
||||
|
||||
// assumes that parameters are consistent with the datatype configuration
|
||||
private static void AssignTags(this IProperty property, IEnumerable<string> tags, bool merge, TagsStorageType storageType, char delimiter, string culture)
|
||||
{
|
||||
// set the property value
|
||||
var trimmedTags = tags.Select(x => x.Trim()).ToArray();
|
||||
|
||||
if (merge)
|
||||
{
|
||||
var currentTags = property.GetTagsValue(storageType, delimiter);
|
||||
|
||||
switch (storageType)
|
||||
{
|
||||
case TagsStorageType.Csv:
|
||||
property.SetValue(string.Join(delimiter.ToString(), currentTags.Union(trimmedTags)), culture); // csv string
|
||||
break;
|
||||
|
||||
case TagsStorageType.Json:
|
||||
property.SetValue(JsonConvert.SerializeObject(currentTags.Union(trimmedTags).ToArray()), culture); // json array
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (storageType)
|
||||
{
|
||||
case TagsStorageType.Csv:
|
||||
property.SetValue(string.Join(delimiter.ToString(), trimmedTags), culture); // csv string
|
||||
break;
|
||||
|
||||
case TagsStorageType.Json:
|
||||
property.SetValue(JsonConvert.SerializeObject(trimmedTags), culture); // json array
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes tags.
|
||||
/// </summary>
|
||||
/// <param name="property">The property.</param>
|
||||
/// <param name="tags">The tags.</param>
|
||||
/// <param name="culture">A culture, for multi-lingual properties.</param>
|
||||
public static void RemoveTags(this IProperty property, PropertyEditorCollection propertyEditors, IDataTypeService dataTypeService, IEnumerable<string> tags, string culture = null)
|
||||
{
|
||||
if (property == null) throw new ArgumentNullException(nameof(property));
|
||||
|
||||
var configuration = property.GetTagConfiguration(propertyEditors, dataTypeService);
|
||||
if (configuration == null)
|
||||
throw new NotSupportedException($"Property with alias \"{property.Alias}\" does not support tags.");
|
||||
|
||||
property.RemoveTags(tags, configuration.StorageType, configuration.Delimiter, culture);
|
||||
}
|
||||
|
||||
// assumes that parameters are consistent with the datatype configuration
|
||||
private static void RemoveTags(this IProperty property, IEnumerable<string> tags, TagsStorageType storageType, char delimiter, string culture)
|
||||
{
|
||||
// already empty = nothing to do
|
||||
var value = property.GetValue(culture)?.ToString();
|
||||
if (string.IsNullOrWhiteSpace(value)) return;
|
||||
|
||||
// set the property value
|
||||
var trimmedTags = tags.Select(x => x.Trim()).ToArray();
|
||||
var currentTags = property.GetTagsValue(storageType, delimiter, culture);
|
||||
switch (storageType)
|
||||
{
|
||||
case TagsStorageType.Csv:
|
||||
property.SetValue(string.Join(delimiter.ToString(), currentTags.Except(trimmedTags)), culture); // csv string
|
||||
break;
|
||||
|
||||
case TagsStorageType.Json:
|
||||
property.SetValue(JsonConvert.SerializeObject(currentTags.Except(trimmedTags).ToArray()), culture); // json array
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// used by ContentRepositoryBase
|
||||
internal static IEnumerable<string> GetTagsValue(this IProperty property, PropertyEditorCollection propertyEditors, IDataTypeService dataTypeService, string culture = null)
|
||||
{
|
||||
if (property == null) throw new ArgumentNullException(nameof(property));
|
||||
|
||||
var configuration = property.GetTagConfiguration(propertyEditors, dataTypeService);
|
||||
if (configuration == null)
|
||||
throw new NotSupportedException($"Property with alias \"{property.Alias}\" does not support tags.");
|
||||
|
||||
return property.GetTagsValue(configuration.StorageType, configuration.Delimiter, culture);
|
||||
}
|
||||
|
||||
private static IEnumerable<string> GetTagsValue(this IProperty property, TagsStorageType storageType, char delimiter, string culture = null)
|
||||
{
|
||||
if (property == null) throw new ArgumentNullException(nameof(property));
|
||||
|
||||
var value = property.GetValue(culture)?.ToString();
|
||||
if (string.IsNullOrWhiteSpace(value)) return Enumerable.Empty<string>();
|
||||
|
||||
switch (storageType)
|
||||
{
|
||||
case TagsStorageType.Csv:
|
||||
return value.Split(new[] { delimiter }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim());
|
||||
|
||||
case TagsStorageType.Json:
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject<JArray>(value).Select(x => x.ToString().Trim());
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
//cannot parse, malformed
|
||||
return Enumerable.Empty<string>();
|
||||
}
|
||||
|
||||
default:
|
||||
throw new NotSupportedException($"Value \"{storageType}\" is not a valid TagsStorageType.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets tags on a content property, based on the property editor tags configuration.
|
||||
/// </summary>
|
||||
/// <param name="property">The property.</param>
|
||||
/// <param name="value">The property value.</param>
|
||||
/// <param name="tagConfiguration">The datatype configuration.</param>
|
||||
/// <param name="culture">A culture, for multi-lingual properties.</param>
|
||||
/// <remarks>
|
||||
/// <para>The value is either a string (delimited string) or an enumeration of strings (tag list).</para>
|
||||
/// <para>This is used both by the content repositories to initialize a property with some tag values, and by the
|
||||
/// content controllers to update a property with values received from the property editor.</para>
|
||||
/// </remarks>
|
||||
public static void SetTagsValue(this IProperty property, object value, TagConfiguration tagConfiguration, string culture)
|
||||
{
|
||||
if (property == null) throw new ArgumentNullException(nameof(property));
|
||||
if (tagConfiguration == null) throw new ArgumentNullException(nameof(tagConfiguration));
|
||||
|
||||
var storageType = tagConfiguration.StorageType;
|
||||
var delimiter = tagConfiguration.Delimiter;
|
||||
|
||||
SetTagsValue(property, value, storageType, delimiter, culture);
|
||||
}
|
||||
|
||||
// assumes that parameters are consistent with the datatype configuration
|
||||
// value can be an enumeration of string, or a serialized value using storageType format
|
||||
private static void SetTagsValue(IProperty property, object value, TagsStorageType storageType, char delimiter, string culture)
|
||||
{
|
||||
if (value == null) value = Enumerable.Empty<string>();
|
||||
|
||||
// if value is already an enumeration of strings, just use it
|
||||
if (value is IEnumerable<string> tags1)
|
||||
{
|
||||
property.AssignTags(tags1, false, storageType, delimiter, culture);
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise, deserialize value based upon storage type
|
||||
switch (storageType)
|
||||
{
|
||||
case TagsStorageType.Csv:
|
||||
var tags2 = value.ToString().Split(new[] { delimiter }, StringSplitOptions.RemoveEmptyEntries);
|
||||
property.AssignTags(tags2, false, storageType, delimiter, culture);
|
||||
break;
|
||||
|
||||
case TagsStorageType.Json:
|
||||
try
|
||||
{
|
||||
var tags3 = JsonConvert.DeserializeObject<IEnumerable<string>>(value.ToString());
|
||||
property.AssignTags(tags3 ?? Enumerable.Empty<string>(), false, storageType, delimiter, culture);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Current.Logger.Warn(typeof(PropertyTagsExtensions), ex, "Could not automatically convert stored json value to an enumerable string '{Json}'", value.ToString());
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(storageType));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.Models.PublishedContent
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides strongly typed published content models services.
|
||||
/// </summary>
|
||||
public static class PublishedContentExtensionsForModels
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a strongly typed published content model for an internal published content.
|
||||
/// </summary>
|
||||
/// <param name="content">The internal published content.</param>
|
||||
/// <returns>The strongly typed published content model.</returns>
|
||||
public static IPublishedContent CreateModel(this IPublishedContent content, IPublishedModelFactory publishedModelFactory)
|
||||
{
|
||||
if (publishedModelFactory == null) throw new ArgumentNullException(nameof(publishedModelFactory));
|
||||
if (content == null)
|
||||
return null;
|
||||
|
||||
// get model
|
||||
// if factory returns nothing, throw
|
||||
var model = publishedModelFactory.CreateModel(content);
|
||||
if (model == null)
|
||||
throw new InvalidOperationException("Factory returned null.");
|
||||
|
||||
// if factory returns a different type, throw
|
||||
if (!(model is IPublishedContent publishedContent))
|
||||
throw new InvalidOperationException($"Factory returned model of type {model.GetType().FullName} which does not implement IPublishedContent.");
|
||||
|
||||
return publishedContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user