Merged with v8/dev

This commit is contained in:
Kenn Jacobsen
2019-07-12 22:38:43 +02:00
433 changed files with 7616 additions and 4591 deletions

View File

@@ -0,0 +1,7 @@
namespace Umbraco.Web.Models
{
public class AnchorsModel
{
public string RteContent { get; set; }
}
}

View File

@@ -38,6 +38,8 @@ namespace Umbraco.Web.Models.ContentEditing
[DataMember(Name = "updater")]
public UserProfile Updater { get; set; }
public int ContentTypeId { get; set; }
[DataMember(Name = "contentTypeAlias", IsRequired = true)]
[Required(AllowEmptyStrings = false)]
public string ContentTypeAlias { get; set; }

View File

@@ -108,6 +108,9 @@ namespace Umbraco.Web.Models.ContentEditing
[DataMember(Name = "treeNodeUrl")]
public string TreeNodeUrl { get; set; }
[DataMember(Name = "contentTypeId")]
public int ContentTypeId { get; set; }
[DataMember(Name = "contentTypeAlias", IsRequired = true)]
[Required(AllowEmptyStrings = false)]
public string ContentTypeAlias { get; set; }

View File

@@ -1,4 +1,5 @@
using System.ComponentModel;
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using Umbraco.Core.PropertyEditors;
@@ -21,6 +22,10 @@ namespace Umbraco.Web.Models.ContentEditing
[Required]
public int Id { get; set; }
[DataMember(Name = "dataTypeKey", IsRequired = false)]
[ReadOnly(true)]
public Guid DataTypeKey { get; set; }
[DataMember(Name = "value")]
public object Value { get; set; }

View File

@@ -1,4 +1,5 @@
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
@@ -43,6 +44,10 @@ namespace Umbraco.Web.Models.ContentEditing
[Required]
public int DataTypeId { get; set; }
[DataMember(Name = "dataTypeKey")]
[ReadOnly(true)]
public Guid DataTypeKey { get; set; }
//SD: Is this really needed ?
[DataMember(Name = "groupId")]
public int GroupId { get; set; }

View File

@@ -0,0 +1,21 @@
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
[DataContract(Name = "urlAndAnchors", Namespace = "")]
public class UrlAndAnchors
{
public UrlAndAnchors(string url, IEnumerable<string> anchorValues)
{
Url = url;
AnchorValues = anchorValues;
}
[DataMember(Name = "url")]
public string Url { get; }
[DataMember(Name = "anchorValues")]
public IEnumerable<string> AnchorValues { get; }
}
}

View File

@@ -73,6 +73,7 @@ namespace Umbraco.Web.Models.Mapping
target.AllowedActions = GetActions(source);
target.AllowedTemplates = GetAllowedTemplates(source);
target.ContentApps = _commonMapper.GetContentApps(source);
target.ContentTypeId = source.ContentType.Id;
target.ContentTypeAlias = source.ContentType.Alias;
target.ContentTypeName = _localizedTextService.UmbracoDictionaryTranslate(source.ContentType.Name);
target.DocumentType = _commonMapper.GetContentType(source, context);
@@ -117,6 +118,7 @@ namespace Umbraco.Web.Models.Mapping
// Umbraco.Code.MapAll -Alias
private void Map(IContent source, ContentItemBasic<ContentPropertyBasic> target, MapperContext context)
{
target.ContentTypeId = source.ContentType.Id;
target.ContentTypeAlias = source.ContentType.Alias;
target.CreateDate = source.CreateDate;
target.Edited = source.Edited;

View File

@@ -16,15 +16,17 @@ namespace Umbraco.Web.Models.Mapping
internal class ContentPropertyBasicMapper<TDestination>
where TDestination : ContentPropertyBasic, new()
{
private readonly IEntityService _entityService;
private readonly ILogger _logger;
private readonly PropertyEditorCollection _propertyEditors;
protected IDataTypeService DataTypeService { get; }
public ContentPropertyBasicMapper(IDataTypeService dataTypeService, ILogger logger, PropertyEditorCollection propertyEditors)
public ContentPropertyBasicMapper(IDataTypeService dataTypeService, IEntityService entityService, ILogger logger, PropertyEditorCollection propertyEditors)
{
_logger = logger;
_propertyEditors = propertyEditors;
DataTypeService = dataTypeService;
_entityService = entityService;
}
/// <summary>
@@ -48,6 +50,7 @@ namespace Umbraco.Web.Models.Mapping
dest.Alias = property.Alias;
dest.PropertyEditor = editor;
dest.Editor = editor.Alias;
dest.DataTypeKey = property.PropertyType.DataTypeKey;
// if there's a set of property aliases specified, we will check if the current property's value should be mapped.
// if it isn't one of the ones specified in 'includeProperties', we will just return the result without mapping the Value.

View File

@@ -14,8 +14,8 @@ namespace Umbraco.Web.Models.Mapping
{
private readonly ILocalizedTextService _textService;
public ContentPropertyDisplayMapper(IDataTypeService dataTypeService, ILocalizedTextService textService, ILogger logger, PropertyEditorCollection propertyEditors)
: base(dataTypeService, logger, propertyEditors)
public ContentPropertyDisplayMapper(IDataTypeService dataTypeService, IEntityService entityService, ILocalizedTextService textService, ILogger logger, PropertyEditorCollection propertyEditors)
: base(dataTypeService, entityService, logger, propertyEditors)
{
_textService = textService;
}

View File

@@ -12,8 +12,8 @@ namespace Umbraco.Web.Models.Mapping
/// </summary>
internal class ContentPropertyDtoMapper : ContentPropertyBasicMapper<ContentPropertyDto>
{
public ContentPropertyDtoMapper(IDataTypeService dataTypeService, ILogger logger, PropertyEditorCollection propertyEditors)
: base(dataTypeService, logger, propertyEditors)
public ContentPropertyDtoMapper(IDataTypeService dataTypeService, IEntityService entityService, ILogger logger, PropertyEditorCollection propertyEditors)
: base(dataTypeService, entityService, logger, propertyEditors)
{ }
public override void Map(Property property, ContentPropertyDto dest, MapperContext context)

View File

@@ -17,11 +17,11 @@ namespace Umbraco.Web.Models.Mapping
private readonly ContentPropertyDtoMapper _contentPropertyDtoConverter;
private readonly ContentPropertyDisplayMapper _contentPropertyDisplayMapper;
public ContentPropertyMapDefinition(IDataTypeService dataTypeService, ILocalizedTextService textService, ILogger logger, PropertyEditorCollection propertyEditors)
public ContentPropertyMapDefinition(IDataTypeService dataTypeService, IEntityService entityService, ILocalizedTextService textService, ILogger logger, PropertyEditorCollection propertyEditors)
{
_contentPropertyBasicConverter = new ContentPropertyBasicMapper<ContentPropertyBasic>(dataTypeService, logger, propertyEditors);
_contentPropertyDtoConverter = new ContentPropertyDtoMapper(dataTypeService, logger, propertyEditors);
_contentPropertyDisplayMapper = new ContentPropertyDisplayMapper(dataTypeService, textService, logger, propertyEditors);
_contentPropertyBasicConverter = new ContentPropertyBasicMapper<ContentPropertyBasic>(dataTypeService, entityService, logger, propertyEditors);
_contentPropertyDtoConverter = new ContentPropertyDtoMapper(dataTypeService, entityService, logger, propertyEditors);
_contentPropertyDisplayMapper = new ContentPropertyDisplayMapper(dataTypeService, entityService, textService, logger, propertyEditors);
}
public void DefineMaps(UmbracoMapper mapper)

View File

@@ -219,6 +219,7 @@ namespace Umbraco.Web.Models.Mapping
{
target.Name = source.Label;
target.DataTypeId = source.DataTypeId;
target.DataTypeKey = source.DataTypeKey;
target.Mandatory = source.Validation.Mandatory;
target.ValidationRegExp = source.Validation.Pattern;
target.Variations = source.AllowCultureVariant ? ContentVariation.Culture : ContentVariation.Nothing;
@@ -334,6 +335,7 @@ namespace Umbraco.Web.Models.Mapping
target.Alias = source.Alias;
target.AllowCultureVariant = source.AllowCultureVariant;
target.DataTypeId = source.DataTypeId;
target.DataTypeKey = source.DataTypeKey;
target.Description = source.Description;
target.GroupId = source.GroupId;
target.Id = source.Id;
@@ -349,6 +351,7 @@ namespace Umbraco.Web.Models.Mapping
target.Alias = source.Alias;
target.AllowCultureVariant = source.AllowCultureVariant;
target.DataTypeId = source.DataTypeId;
target.DataTypeKey = source.DataTypeKey;
target.Description = source.Description;
target.GroupId = source.GroupId;
target.Id = source.Id;

View File

@@ -146,19 +146,26 @@ namespace Umbraco.Web.Models.Mapping
var fields = context.MapEnumerable<ConfigurationField,DataTypeConfigurationFieldDisplay>(configurationEditor.Fields);
var configurationDictionary = configurationEditor.ToConfigurationEditor(dataType.Configuration);
MapConfigurationFields(fields, configurationDictionary);
MapConfigurationFields(dataType, fields, configurationDictionary);
return fields;
}
private void MapConfigurationFields(List<DataTypeConfigurationFieldDisplay> fields, IDictionary<string, object> configuration)
private void MapConfigurationFields(IDataType dataType, List<DataTypeConfigurationFieldDisplay> fields, IDictionary<string, object> configuration)
{
if (fields == null) throw new ArgumentNullException(nameof(fields));
if (configuration == null) throw new ArgumentNullException(nameof(configuration));
// now we need to wire up the pre-values values with the actual fields defined
foreach (var field in fields)
foreach (var field in fields.ToList())
{
//filter out the not-supported pre-values for built-in data types
if (dataType != null && dataType.IsBuildInDataType() && field.Key.InvariantEquals(Constants.DataTypes.ReservedPreValueKeys.IgnoreUserStartNodes))
{
fields.Remove(field);
continue;
}
if (configuration.TryGetValue(field.Key, out var value))
{
field.Value = value;
@@ -194,7 +201,7 @@ namespace Umbraco.Web.Models.Mapping
var defaultConfiguration = configurationEditor.DefaultConfiguration;
if (defaultConfiguration != null)
MapConfigurationFields(fields, defaultConfiguration);
MapConfigurationFields(null, fields, defaultConfiguration);
return fields;
}

View File

@@ -43,12 +43,12 @@ namespace Umbraco.Web.Models.Mapping
target.Udi = Udi.Create(ObjectTypes.GetUdiType(source.NodeObjectType), source.Key);
if (source.NodeObjectType == Constants.ObjectTypes.Member && target.Icon.IsNullOrWhiteSpace())
target.Icon = "icon-user";
target.Icon = Constants.Icons.Member;
if (source.NodeObjectType == Constants.ObjectTypes.Media && source is IContentEntitySlim contentSlim)
if (source is IContentEntitySlim contentSlim)
source.AdditionalData["ContentTypeAlias"] = contentSlim.ContentTypeAlias;
if (source.NodeObjectType == Constants.ObjectTypes.Media && source is IMediaEntitySlim mediaSlim)
if (source is IMediaEntitySlim mediaSlim)
source.AdditionalData["MediaPath"] = mediaSlim.MediaPath;
// NOTE: we're mapping the objects in AdditionalData by object reference here.
@@ -89,7 +89,7 @@ namespace Umbraco.Web.Models.Mapping
private static void Map(IUser source, EntityBasic target, MapperContext context)
{
target.Alias = source.Username;
target.Icon = "icon-user";
target.Icon = Constants.Icons.User;
target.Id = source.Id;
target.Key = source.Key;
target.Name = source.Name;
@@ -101,7 +101,7 @@ namespace Umbraco.Web.Models.Mapping
private static void Map(ITemplate source, EntityBasic target, MapperContext context)
{
target.Alias = source.Alias;
target.Icon = "icon-layout";
target.Icon = Constants.Icons.Template;
target.Id = source.Id;
target.Key = source.Key;
target.Name = source.Name;
@@ -144,15 +144,15 @@ namespace Umbraco.Web.Models.Mapping
if (target.Icon.IsNullOrWhiteSpace())
{
if (source.NodeObjectType == Constants.ObjectTypes.Member)
target.Icon = "icon-user";
target.Icon = Constants.Icons.Member;
else if (source.NodeObjectType == Constants.ObjectTypes.DataType)
target.Icon = "icon-autofill";
target.Icon = Constants.Icons.DataType;
else if (source.NodeObjectType == Constants.ObjectTypes.DocumentType)
target.Icon = "icon-item-arrangement";
target.Icon = Constants.Icons.ContentType;
else if (source.NodeObjectType == Constants.ObjectTypes.MediaType)
target.Icon = "icon-thumbnails";
target.Icon = Constants.Icons.MediaType;
else if (source.NodeObjectType == Constants.ObjectTypes.TemplateType)
target.Icon = "icon-newspaper-alt";
target.Icon = Constants.Icons.Template;
}
}
@@ -167,7 +167,7 @@ namespace Umbraco.Web.Models.Mapping
//get the icon if there is one
target.Icon = source.Values.ContainsKey(UmbracoExamineIndex.IconFieldName)
? source.Values[UmbracoExamineIndex.IconFieldName]
: "icon-document";
: Constants.Icons.DefaultIcon;
target.Name = source.Values.ContainsKey("nodeName") ? source.Values["nodeName"] : "[no name]";

View File

@@ -31,7 +31,7 @@ namespace Umbraco.Web.Models.Mapping
private static void Map(IMacro source, EntityBasic target, MapperContext context)
{
target.Alias = source.Alias;
target.Icon = "icon-settings-alt";
target.Icon = Constants.Icons.Macro;
target.Id = source.Id;
target.Key = source.Key;
target.Name = source.Name;

View File

@@ -50,6 +50,7 @@ namespace Umbraco.Web.Models.Mapping
{
target.ContentApps = _commonMapper.GetContentApps(source);
target.ContentType = _commonMapper.GetContentType(source, context);
target.ContentTypeId = source.ContentType.Id;
target.ContentTypeAlias = source.ContentType.Alias;
target.ContentTypeName = source.ContentType.Name;
target.CreateDate = source.CreateDate;
@@ -75,6 +76,7 @@ namespace Umbraco.Web.Models.Mapping
// Umbraco.Code.MapAll -Edited -Updater -Alias
private void Map(IMedia source, ContentItemBasic<ContentPropertyBasic> target, MapperContext context)
{
target.ContentTypeId = source.ContentType.Id;
target.ContentTypeAlias = source.ContentType.Alias;
target.CreateDate = source.CreateDate;
target.Icon = source.ContentType.Icon;

View File

@@ -76,6 +76,7 @@ namespace Umbraco.Web.Models.Mapping
// Umbraco.Code.MapAll -Trashed -IsContainer -VariesByCulture
private void Map(IMember source, MemberDisplay target, MapperContext context)
{
target.ContentTypeId = source.ContentType.Id;
target.ContentTypeAlias = source.ContentType.Alias;
target.ContentTypeName = source.ContentType.Name;
target.CreateDate = source.CreateDate;
@@ -101,6 +102,7 @@ namespace Umbraco.Web.Models.Mapping
// Umbraco.Code.MapAll -Trashed -Edited -Updater -Alias -VariesByCulture
private void Map(IMember source, MemberBasic target, MapperContext context)
{
target.ContentTypeId = source.ContentType.Id;
target.ContentTypeAlias = source.ContentType.Alias;
target.CreateDate = source.CreateDate;
target.Email = source.Email;
@@ -121,12 +123,12 @@ namespace Umbraco.Web.Models.Mapping
//TODO: SD: I can't remember why this mapping is here?
// Umbraco.Code.MapAll -Udi -Properties -ParentId -Path -SortOrder -Edited -Updater
// Umbraco.Code.MapAll -Trashed -Alias -ContentTypeAlias -VariesByCulture
// Umbraco.Code.MapAll -Trashed -Alias -ContentTypeId -ContentTypeAlias -VariesByCulture
private void Map(MembershipUser source, MemberBasic target, MapperContext context)
{
target.CreateDate = source.CreationDate;
target.Email = source.Email;
target.Icon = "icon-user";
target.Icon = Constants.Icons.Member;
target.Id = int.MaxValue;
target.Key = source.ProviderUserKey.TryConvertTo<Guid>().Result;
target.Name = source.UserName;

View File

@@ -96,7 +96,7 @@ namespace Umbraco.Web.Models.Mapping
linkText = source.ContentType.Name,
url = memberTypeLink,
target = "_self",
icon = "icon-item-arrangement"
icon = Constants.Icons.ContentType
}
};
docTypeProperty.View = "urllist";

View File

@@ -231,6 +231,7 @@ namespace Umbraco.Web.Models.Mapping
GroupId = groupId,
Inherited = inherited,
DataTypeId = p.DataTypeId,
DataTypeKey = p.DataTypeKey,
SortOrder = p.SortOrder,
ContentTypeId = contentType.Id,
ContentTypeName = contentType.Name,

View File

@@ -26,7 +26,7 @@ namespace Umbraco.Web.Models.Mapping
target.ContentId = source.ContentId;
target.CreateDateUtc = source.CreateDateUtc;
target.Culture = source.Culture;
target.DestinationUrl = source.ContentId > 0 ? UmbracoContext?.UrlProvider?.GetUrl(source.ContentId, source.Culture) : "#";
target.DestinationUrl = source.ContentId > 0 ? UmbracoContext?.UrlProvider?.GetUrl(source.ContentId, culture: source.Culture) : "#";
target.OriginalUrl = UmbracoContext?.UrlProvider?.GetUrlFromRoute(source.ContentId, source.Url, source.Culture);
target.RedirectId = source.Key;
}

View File

@@ -179,7 +179,7 @@ namespace Umbraco.Web.Models.Mapping
target.DefaultPermissions = MapUserGroupDefaultPermissions(source);
if (target.Icon.IsNullOrWhiteSpace())
target.Icon = "icon-users";
target.Icon = Constants.Icons.UserGroup;
}
// Umbraco.Code.MapAll -Trashed -Alias -AssignedPermissions
@@ -194,7 +194,7 @@ namespace Umbraco.Web.Models.Mapping
target.Udi = Udi.Create(ObjectTypes.GetUdiType(source.NodeObjectType), source.Key);
if (source.NodeObjectType == Constants.ObjectTypes.Member && target.Icon.IsNullOrWhiteSpace())
target.Icon = "icon-user";
target.Icon = Constants.Icons.Member;
}
// Umbraco.Code.MapAll -ContentStartNode -MediaStartNode -Sections -Notifications -Udi
@@ -350,7 +350,7 @@ namespace Umbraco.Web.Models.Mapping
target.ContentStartNode = CreateRootNode(_textService.Localize("content/contentRoot"));
if (target.Icon.IsNullOrWhiteSpace())
target.Icon = "icon-users";
target.Icon = Constants.Icons.UserGroup;
}
private IDictionary<string, IEnumerable<Permission>> MapUserGroupDefaultPermissions(IUserGroup source)

View File

@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Diagnostics;
using Umbraco.Core;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PropertyEditors.ValueConverters;
namespace Umbraco.Web.Models
{
@@ -12,19 +11,12 @@ namespace Umbraco.Web.Models
/// </summary>
/// <remarks>This base class does which (a) consistently resolves and caches the Url, (b) provides an implementation
/// for this[alias], and (c) provides basic content set management.</remarks>
[DebuggerDisplay("Content Id: {Id}, Name: {Name}")]
[DebuggerDisplay("Content Id: {Id}")]
public abstract class PublishedContentBase : IPublishedContent
{
protected PublishedContentBase(IUmbracoContextAccessor umbracoContextAccessor)
{
UmbracoContextAccessor = umbracoContextAccessor ?? throw new ArgumentNullException(nameof(umbracoContextAccessor));
}
protected IUmbracoContextAccessor UmbracoContextAccessor { get; }
#region ContentType
public abstract PublishedContentType ContentType { get; }
public abstract IPublishedContentType ContentType { get; }
#endregion
@@ -41,10 +33,10 @@ namespace Umbraco.Web.Models
public abstract int Id { get; }
/// <inheritdoc />
public abstract string Name { get; }
public virtual string Name => this.Name();
/// <inheritdoc />
public abstract string UrlSegment { get; }
public virtual string UrlSegment => this.UrlSegment();
/// <inheritdoc />
public abstract int SortOrder { get; }
@@ -77,34 +69,7 @@ namespace Umbraco.Web.Models
public abstract DateTime UpdateDate { get; }
/// <inheritdoc />
public virtual string Url => GetUrl();
/// <inheritdoc />
/// <remarks>
/// The url of documents are computed by the document url providers. The url of medias are computed by the media url providers
/// </remarks>
public virtual string GetUrl(string culture = null) // TODO: consider .GetCulture("fr-FR").Url
{
var umbracoContext = UmbracoContextAccessor.UmbracoContext;
if (umbracoContext == null)
throw new InvalidOperationException("Cannot compute Url for a content item when UmbracoContext is null.");
if (umbracoContext.UrlProvider == null)
throw new InvalidOperationException("Cannot compute Url for a content item when UmbracoContext.UrlProvider is null.");
switch (ItemType)
{
case PublishedItemType.Content:
return umbracoContext.UrlProvider.GetUrl(this, culture);
case PublishedItemType.Media:
return umbracoContext.UrlProvider.GetMediaUrl(this, Constants.Conventions.Media.File, culture);
default:
throw new NotSupportedException();
}
}
/// <inheritdoc />
public abstract PublishedCultureInfo GetCulture(string culture = null);
public virtual string Url => this.Url();
/// <inheritdoc />
public abstract IReadOnlyDictionary<string, PublishedCultureInfo> Cultures { get; }
@@ -126,7 +91,10 @@ namespace Umbraco.Web.Models
public abstract IPublishedContent Parent { get; }
/// <inheritdoc />
public abstract IEnumerable<IPublishedContent> Children { get; }
public virtual IEnumerable<IPublishedContent> Children => this.Children();
/// <inheritdoc />
public abstract IEnumerable<IPublishedContent> ChildrenForAllCultures { get; }
#endregion

View File

@@ -1,58 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Web.Composing;
namespace Umbraco.Web.Models
{
public static class PublishedProperty
{
/// <summary>
/// Maps a collection of Property to a collection of IPublishedProperty for a specified collection of PublishedPropertyType.
/// </summary>
/// <param name="propertyTypes">The published property types.</param>
/// <param name="properties">The properties.</param>
/// <param name="map">A mapping function.</param>
/// <returns>A collection of IPublishedProperty corresponding to the collection of PublishedPropertyType
/// and taking values from the collection of Property.</returns>
/// <remarks>Ensures that all conversions took place correctly.</remarks>
internal static IEnumerable<IPublishedProperty> MapProperties(
IEnumerable<PublishedPropertyType> propertyTypes, IEnumerable<Property> properties,
Func<PublishedPropertyType, object, IPublishedProperty> map)
{
var propertyEditors = Current.PropertyEditors;
var dataTypeService = Current.Services.DataTypeService;
// TODO: not dealing with variants
// but the entire thing should die anyways
return propertyTypes.Select(x =>
{
var p = properties.SingleOrDefault(xx => xx.Alias == x.Alias);
var v = p == null || p.GetValue() == null ? null : p.GetValue();
if (v != null)
{
var e = propertyEditors[x.EditorAlias];
// We are converting to string, even for database values which are integer or
// DateTime, which is not optimum. Doing differently would require that we have a way to tell
// whether the conversion to XML string changes something or not... which we don't, and we
// don't want to implement it as PropertyValueEditor.ConvertDbToXml/String should die anyway.
// Don't think about improving the situation here: this is a corner case and the real
// thing to do is to get rig of PropertyValueEditor.ConvertDbToXml/String.
// Use ConvertDbToString to keep it simple, although everywhere we use ConvertDbToXml and
// nothing ensures that the two methods are consistent.
if (e != null)
v = e.GetValueEditor().ConvertDbToString(p.PropertyType, v, dataTypeService);
}
return map(x, v);
});
}
}
}