Merge remote-tracking branch 'origin/v8/dev' into v8/merge/v715

# Conflicts:
#	src/Umbraco.Core/Constants-DataTypes.cs
#	src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs
#	src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/linkpicker/linkpicker.controller.js
#	src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js
This commit is contained in:
Shannon
2019-07-02 10:49:20 +10:00
106 changed files with 899 additions and 461 deletions
+2 -2
View File
@@ -42,8 +42,8 @@ namespace Umbraco.Core.Composing
private string _currentAssembliesHash;
private IEnumerable<Assembly> _assemblies;
private bool _reportedChange;
private static string _localTempPath;
private static string _fileBasePath;
private readonly string _localTempPath;
private string _fileBasePath;
/// <summary>
/// Initializes a new instance of the <see cref="TypeLoader"/> class.
+4 -1
View File
@@ -10,23 +10,26 @@ namespace Umbraco.Core
//constants, it would make more sense to have these suffixed with "ID" or in a Subclass called "INT", for
//now all we can do is make a subclass called Guids to put the GUID IDs.
public const int LabelString = -92;
public const int LabelString = System.DefaultLabelDataTypeId;
public const int LabelInt = -91;
public const int LabelBigint = -93;
public const int LabelDateTime = -94;
public const int LabelTime = -98;
public const int LabelDecimal = -99;
public const int Textarea = -89;
public const int Textbox = -88;
public const int Boolean = -49;
public const int DateTime = -36;
public const int DropDownSingle = -39;
public const int DropDownMultiple = -42;
public const int Upload = -90;
public const int DefaultContentListView = -95;
public const int DefaultMediaListView = -96;
public const int DefaultMembersListView = -97;
public const int ImageCropper = 1043;
public const int Tags = 1041;
public static class ReservedPreValueKeys
+56 -6
View File
@@ -5,39 +5,89 @@
public static class Icons
{
/// <summary>
/// System contenttype icon
/// System default icon
/// </summary>
public const string ContentType = "icon-arrangement";
public const string DefaultIcon = Content;
/// <summary>
/// System datatype icon
/// System content icon
/// </summary>
public const string Content = "icon-document";
/// <summary>
/// System content type icon
/// </summary>
public const string ContentType = "icon-item-arrangement";
/// <summary>
/// System data type icon
/// </summary>
public const string DataType = "icon-autofill";
/// <summary>
/// System property editor icon
/// System list view icon
/// </summary>
public const string PropertyEditor = "icon-autofill";
public const string ListView = "icon-thumbnail-list";
/// <summary>
/// System macro icon
/// </summary>
public const string Macro = "icon-settings-alt";
/// <summary>
/// System media file icon
/// </summary>
public const string MediaFile = "icon-document";
/// <summary>
/// System media folder icon
/// </summary>
public const string MediaFolder = "icon-folder";
/// <summary>
/// System media image icon
/// </summary>
public const string MediaImage = "icon-picture";
/// <summary>
/// System media type icon
/// </summary>
public const string MediaType = "icon-thumbnails";
/// <summary>
/// System member icon
/// </summary>
public const string Member = "icon-user";
/// <summary>
/// System member icon
/// System member group icon
/// </summary>
public const string MemberGroup = "icon-users-alt";
/// <summary>
/// System member type icon
/// </summary>
public const string MemberType = "icon-users";
/// <summary>
/// System property editor icon
/// </summary>
public const string PropertyEditor = "icon-autofill";
/// <summary>
/// System member icon
/// </summary>
public const string Template = "icon-layout";
/// <summary>
/// System user icon
/// </summary>
public const string User = "icon-user";
/// <summary>
/// System user group icon
/// </summary>
public const string UserGroup = "icon-users";
}
}
}
@@ -101,33 +101,33 @@ namespace Umbraco.Core.Migrations.Install
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -1, Trashed = false, ParentId = -1, UserId = -1, Level = 0, Path = "-1", SortOrder = 0, UniqueId = new Guid("916724a5-173d-4619-b97e-b9de133dd6f5"), Text = "SYSTEM DATA: umbraco master root", NodeObjectType = Constants.ObjectTypes.SystemRoot, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -20, Trashed = false, ParentId = -1, UserId = -1, Level = 0, Path = "-1,-20", SortOrder = 0, UniqueId = new Guid("0F582A79-1E41-4CF0-BFA0-76340651891A"), Text = "Recycle Bin", NodeObjectType = Constants.ObjectTypes.ContentRecycleBin, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -21, Trashed = false, ParentId = -1, UserId = -1, Level = 0, Path = "-1,-21", SortOrder = 0, UniqueId = new Guid("BF7C7CBC-952F-4518-97A2-69E9C7B33842"), Text = "Recycle Bin", NodeObjectType = Constants.ObjectTypes.MediaRecycleBin, CreateDate = DateTime.Now });
InsertDataTypeNodeDto(Constants.DataTypes.LabelString, 35, Constants.DataTypes.Guids.LabelString, "Label");
InsertDataTypeNodeDto(Constants.DataTypes.LabelString, 35, Constants.DataTypes.Guids.LabelString, "Label (string)");
InsertDataTypeNodeDto(Constants.DataTypes.LabelInt, 36, Constants.DataTypes.Guids.LabelInt, "Label (integer)");
InsertDataTypeNodeDto(Constants.DataTypes.LabelBigint, 36, Constants.DataTypes.Guids.LabelBigInt, "Label (bigint)");
InsertDataTypeNodeDto(Constants.DataTypes.LabelDateTime, 37, Constants.DataTypes.Guids.LabelDateTime, "Label (datetime)");
InsertDataTypeNodeDto(Constants.DataTypes.LabelTime, 38, Constants.DataTypes.Guids.LabelTime, "Label (time)");
InsertDataTypeNodeDto(Constants.DataTypes.LabelDecimal, 39, Constants.DataTypes.Guids.LabelDecimal, "Label (decimal)");
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -90, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-90", SortOrder = 34, UniqueId = Constants.DataTypes.Guids.UploadGuid, Text = "Upload", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -89, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-89", SortOrder = 33, UniqueId = Constants.DataTypes.Guids.TextareaGuid, Text = "Textarea", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Upload, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Upload}", SortOrder = 34, UniqueId = Constants.DataTypes.Guids.UploadGuid, Text = "Upload", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Textarea, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Textarea}", SortOrder = 33, UniqueId = Constants.DataTypes.Guids.TextareaGuid, Text = "Textarea", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -88, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-88", SortOrder = 32, UniqueId = Constants.DataTypes.Guids.TextstringGuid, Text = "Textstring", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -87, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-87", SortOrder = 4, UniqueId = Constants.DataTypes.Guids.RichtextEditorGuid, Text = "Richtext editor", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -51, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-51", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.NumericGuid, Text = "Numeric", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -49, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-49", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.CheckboxGuid, Text = "True/false", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Boolean, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Boolean}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.CheckboxGuid, Text = "True/false", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -43, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-43", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.CheckboxListGuid, Text = "Checkbox list", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DropDownSingle, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DropDownSingle}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.DropdownGuid, Text = "Dropdown", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -41, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-41", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.DatePickerGuid, Text = "Date Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -40, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-40", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.RadioboxGuid, Text = "Radiobox", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DropDownMultiple, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DropDownMultiple}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.DropdownMultipleGuid, Text = "Dropdown multiple", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -37, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-37", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.ApprovedColorGuid, Text = "Approved Color", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -36, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-36", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.DatePickerWithTimeGuid, Text = "Date Picker with time", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DateTime, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DateTime}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.DatePickerWithTimeGuid, Text = "Date Picker with time", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DefaultContentListView, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DefaultContentListView}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.ListViewContentGuid, Text = Constants.Conventions.DataTypes.ListViewPrefix + "Content", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DefaultMediaListView, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DefaultMediaListView}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.ListViewMediaGuid, Text = Constants.Conventions.DataTypes.ListViewPrefix + "Media", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DefaultMembersListView, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DefaultMembersListView}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.ListViewMembersGuid, Text = Constants.Conventions.DataTypes.ListViewPrefix + "Members", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1031, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1031", SortOrder = 2, UniqueId = new Guid("f38bd2d7-65d0-48e6-95dc-87ce06ec2d3d"), Text = Constants.Conventions.MediaTypes.Folder, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1032, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1032", SortOrder = 2, UniqueId = new Guid("cc07b313-0843-4aa8-bbda-871c8da728c8"), Text = Constants.Conventions.MediaTypes.Image, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1033, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1033", SortOrder = 2, UniqueId = new Guid("4c52d8ab-54e6-40cd-999c-7a5f24903e4d"), Text = Constants.Conventions.MediaTypes.File, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1041, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1041", SortOrder = 2, UniqueId = new Guid("b6b73142-b9c1-4bf8-a16d-e1c23320b549"), Text = "Tags", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1043, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1043", SortOrder = 2, UniqueId = new Guid("1df9f033-e6d4-451f-b8d2-e0cbc50a836f"), Text = "Image Cropper", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Tags, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Tags}", SortOrder = 2, UniqueId = new Guid("b6b73142-b9c1-4bf8-a16d-e1c23320b549"), Text = "Tags", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.ImageCropper, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.ImageCropper}", SortOrder = 2, UniqueId = new Guid("1df9f033-e6d4-451f-b8d2-e0cbc50a836f"), Text = "Image Cropper", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1044, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1044", SortOrder = 0, UniqueId = new Guid("d59be02f-1df9-4228-aa1e-01917d806cda"), Text = Constants.Conventions.MemberTypes.DefaultAlias, NodeObjectType = Constants.ObjectTypes.MemberType, CreateDate = DateTime.Now });
//New UDI pickers with newer Ids
@@ -155,10 +155,10 @@ namespace Umbraco.Core.Migrations.Install
private void CreateContentTypeData()
{
_database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 532, NodeId = 1031, Alias = Constants.Conventions.MediaTypes.Folder, Icon = "icon-folder", Thumbnail = "icon-folder", IsContainer = false, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 533, NodeId = 1032, Alias = Constants.Conventions.MediaTypes.Image, Icon = "icon-picture", Thumbnail = "icon-picture", AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 534, NodeId = 1033, Alias = Constants.Conventions.MediaTypes.File, Icon = "icon-document", Thumbnail = "icon-document", AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 531, NodeId = 1044, Alias = Constants.Conventions.MemberTypes.DefaultAlias, Icon = "icon-user", Thumbnail = "icon-user", Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 532, NodeId = 1031, Alias = Constants.Conventions.MediaTypes.Folder, Icon = Constants.Icons.MediaFolder, Thumbnail = Constants.Icons.MediaFolder, IsContainer = false, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 533, NodeId = 1032, Alias = Constants.Conventions.MediaTypes.Image, Icon = Constants.Icons.MediaImage, Thumbnail = Constants.Icons.MediaImage, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 534, NodeId = 1033, Alias = Constants.Conventions.MediaTypes.File, Icon = Constants.Icons.MediaFile, Thumbnail = Constants.Icons.MediaFile, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 531, NodeId = 1044, Alias = Constants.Conventions.MemberTypes.DefaultAlias, Icon = Constants.Icons.Member, Thumbnail = Constants.Icons.Member, Variations = (byte) ContentVariation.Nothing });
}
private void CreateUserData()
@@ -210,19 +210,19 @@ namespace Umbraco.Core.Migrations.Install
private void CreatePropertyTypeData()
{
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 6, UniqueId = 6.ToGuid(), DataTypeId = 1043, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.File, Name = "Upload image", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 6, UniqueId = 6.ToGuid(), DataTypeId = Constants.DataTypes.ImageCropper, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.File, Name = "Upload image", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 7, UniqueId = 7.ToGuid(), DataTypeId = Constants.DataTypes.LabelInt, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Width, Name = "Width", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in pixels", Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 8, UniqueId = 8.ToGuid(), DataTypeId = Constants.DataTypes.LabelInt, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Height, Name = "Height", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in pixels", Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 9, UniqueId = 9.ToGuid(), DataTypeId = Constants.DataTypes.LabelBigint, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in bytes", Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 10, UniqueId = 10.ToGuid(), DataTypeId = -92, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 24, UniqueId = 24.ToGuid(), DataTypeId = -90, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.File, Name = "Upload file", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 24, UniqueId = 24.ToGuid(), DataTypeId = Constants.DataTypes.Upload, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.File, Name = "Upload file", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 25, UniqueId = 25.ToGuid(), DataTypeId = -92, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 26, UniqueId = 26.ToGuid(), DataTypeId = Constants.DataTypes.LabelBigint, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in bytes", Variations = (byte) ContentVariation.Nothing });
//membership property types
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 28, UniqueId = 28.ToGuid(), DataTypeId = -89, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.Comments, Name = Constants.Conventions.Member.CommentsLabel, SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 28, UniqueId = 28.ToGuid(), DataTypeId = Constants.DataTypes.Textarea, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.Comments, Name = Constants.Conventions.Member.CommentsLabel, SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 29, UniqueId = 29.ToGuid(), DataTypeId = Constants.DataTypes.LabelInt, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.FailedPasswordAttempts, Name = Constants.Conventions.Member.FailedPasswordAttemptsLabel, SortOrder = 1, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 30, UniqueId = 30.ToGuid(), DataTypeId = -49, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.IsApproved, Name = Constants.Conventions.Member.IsApprovedLabel, SortOrder = 2, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 31, UniqueId = 31.ToGuid(), DataTypeId = -49, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.IsLockedOut, Name = Constants.Conventions.Member.IsLockedOutLabel, SortOrder = 3, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 30, UniqueId = 30.ToGuid(), DataTypeId = Constants.DataTypes.Boolean, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.IsApproved, Name = Constants.Conventions.Member.IsApprovedLabel, SortOrder = 2, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 31, UniqueId = 31.ToGuid(), DataTypeId = Constants.DataTypes.Boolean, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.IsLockedOut, Name = Constants.Conventions.Member.IsLockedOutLabel, SortOrder = 3, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 32, UniqueId = 32.ToGuid(), DataTypeId = Constants.DataTypes.LabelDateTime, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.LastLockoutDate, Name = Constants.Conventions.Member.LastLockoutDateLabel, SortOrder = 4, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 33, UniqueId = 33.ToGuid(), DataTypeId = Constants.DataTypes.LabelDateTime, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.LastLoginDate, Name = Constants.Conventions.Member.LastLoginDateLabel, SortOrder = 5, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 34, UniqueId = 34.ToGuid(), DataTypeId = Constants.DataTypes.LabelDateTime, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.LastPasswordChangeDate, Name = Constants.Conventions.Member.LastPasswordChangeDateLabel, SortOrder = 6, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
@@ -266,30 +266,30 @@ namespace Umbraco.Core.Migrations.Install
const string layouts = "[" + cardLayout + "," + listLayout + "]";
// TODO: Check which of the DataTypeIds below doesn't exist in umbracoNode, which results in a foreign key constraint errors.
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -49, EditorAlias = Constants.PropertyEditors.Aliases.Boolean, DbType = "Integer" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.Boolean, EditorAlias = Constants.PropertyEditors.Aliases.Boolean, DbType = "Integer" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -51, EditorAlias = Constants.PropertyEditors.Aliases.Integer, DbType = "Integer" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -87, EditorAlias = Constants.PropertyEditors.Aliases.TinyMce, DbType = "Ntext",
Configuration = "{\"value\":\",code,undo,redo,cut,copy,mcepasteword,stylepicker,bold,italic,bullist,numlist,outdent,indent,mcelink,unlink,mceinsertanchor,mceimage,umbracomacro,mceinserttable,umbracoembed,mcecharmap,|1|1,2,3,|0|500,400|1049,|true|\"}" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -88, EditorAlias = Constants.PropertyEditors.Aliases.TextBox, DbType = "Nvarchar" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -89, EditorAlias = Constants.PropertyEditors.Aliases.TextArea, DbType = "Ntext" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -90, EditorAlias = Constants.PropertyEditors.Aliases.UploadField, DbType = "Nvarchar" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.Textarea, EditorAlias = Constants.PropertyEditors.Aliases.TextArea, DbType = "Ntext" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.Upload, EditorAlias = Constants.PropertyEditors.Aliases.UploadField, DbType = "Nvarchar" });
InsertDataTypeDto(Constants.DataTypes.LabelString, Constants.PropertyEditors.Aliases.Label, "Nvarchar", "{\"umbracoDataValueType\":\"STRING\"}");
InsertDataTypeDto(Constants.DataTypes.LabelInt, Constants.PropertyEditors.Aliases.Label, "Integer", "{\"umbracoDataValueType\":\"INT\"}");
InsertDataTypeDto(Constants.DataTypes.LabelBigint, Constants.PropertyEditors.Aliases.Label, "Nvarchar", "{\"umbracoDataValueType\":\"BIGINT\"}");
InsertDataTypeDto(Constants.DataTypes.LabelDateTime, Constants.PropertyEditors.Aliases.Label, "Date", "{\"umbracoDataValueType\":\"DATETIME\"}");
InsertDataTypeDto(Constants.DataTypes.LabelDecimal, Constants.PropertyEditors.Aliases.Label, "Decimal", "{\"umbracoDataValueType\":\"DECIMAL\"}");
InsertDataTypeDto(Constants.DataTypes.LabelTime, Constants.PropertyEditors.Aliases.Label, "Date", "{\"umbracoDataValueType\":\"TIME\"}");
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -36, EditorAlias = Constants.PropertyEditors.Aliases.DateTime, DbType = "Date" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.DateTime, EditorAlias = Constants.PropertyEditors.Aliases.DateTime, DbType = "Date" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -37, EditorAlias = Constants.PropertyEditors.Aliases.ColorPicker, DbType = "Nvarchar" });
InsertDataTypeDto(Constants.DataTypes.DropDownSingle, Constants.PropertyEditors.Aliases.DropDownListFlexible, "Nvarchar", "{\"multiple\":false}");
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -40, EditorAlias = Constants.PropertyEditors.Aliases.RadioButtonList, DbType = "Nvarchar" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -41, EditorAlias = "Umbraco.DateTime", DbType = "Date", Configuration = "{\"format\":\"YYYY-MM-DD\"}" });
InsertDataTypeDto(Constants.DataTypes.DropDownMultiple, Constants.PropertyEditors.Aliases.DropDownListFlexible, "Nvarchar", "{\"multiple\":true}");
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -43, EditorAlias = Constants.PropertyEditors.Aliases.CheckBoxList, DbType = "Nvarchar" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1041, EditorAlias = Constants.PropertyEditors.Aliases.Tags, DbType = "Ntext",
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.Tags, EditorAlias = Constants.PropertyEditors.Aliases.Tags, DbType = "Ntext",
Configuration = "{\"group\":\"default\", \"storageType\":\"Json\"}"
});
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1043, EditorAlias = Constants.PropertyEditors.Aliases.ImageCropper, DbType = "Ntext" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.ImageCropper, EditorAlias = Constants.PropertyEditors.Aliases.ImageCropper, DbType = "Ntext" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.DefaultContentListView, EditorAlias = Constants.PropertyEditors.Aliases.ListView, DbType = "Nvarchar",
Configuration = "{\"pageSize\":100, \"orderBy\":\"updateDate\", \"orderDirection\":\"desc\", \"layouts\":" + layouts + ", \"includeProperties\":[{\"alias\":\"updateDate\",\"header\":\"Last edited\",\"isSystem\":1},{\"alias\":\"owner\",\"header\":\"Updated by\",\"isSystem\":1}]}" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.DefaultMediaListView, EditorAlias = Constants.PropertyEditors.Aliases.ListView, DbType = "Nvarchar",
+1 -31
View File
@@ -81,37 +81,7 @@ namespace Umbraco.Core.Models.Entities
_key = Guid.Empty;
_hasIdentity = false;
}
/// <summary>
/// Updates the entity when it is being saved for the first time.
/// </summary>
internal virtual void AddingEntity()
{
var now = DateTime.Now;
// set the create and update dates, if not already set
if (IsPropertyDirty("CreateDate") == false || _createDate == default)
CreateDate = now;
if (IsPropertyDirty("UpdateDate") == false || _updateDate == default)
UpdateDate = now;
}
/// <summary>
/// Updates the entity when it is being saved.
/// </summary>
internal virtual void UpdatingEntity()
{
var now = DateTime.Now;
// just in case
if (_createDate == default)
CreateDate = now;
// set the update date if not already set
if (IsPropertyDirty("UpdateDate") == false || _updateDate == default)
UpdateDate = now;
}
public virtual bool Equals(EntityBase other)
{
return other != null && (ReferenceEquals(this, other) || SameIdentityAs(other));
@@ -0,0 +1,46 @@
using System;
namespace Umbraco.Core.Models.Entities
{
internal static class EntityExtensions
{
/// <summary>
/// Updates the entity when it is being saved.
/// </summary>
internal static void UpdatingEntity(this IEntity entity)
{
var now = DateTime.Now;
// just in case
if (entity.CreateDate == default)
{
entity.CreateDate = now;
}
// set the update date if not already set
if (entity.UpdateDate == default || (entity is ICanBeDirty canBeDirty && canBeDirty.IsPropertyDirty("UpdateDate") == false))
{
entity.UpdateDate = now;
}
}
/// <summary>
/// Updates the entity when it is being saved for the first time.
/// </summary>
internal static void AddingEntity(this IEntity entity)
{
var now = DateTime.Now;
var canBeDirty = entity as ICanBeDirty;
// set the create and update dates, if not already set
if (entity.CreateDate == default || canBeDirty?.IsPropertyDirty("CreateDate") == false)
{
entity.CreateDate = now;
}
if (entity.UpdateDate == default || canBeDirty?.IsPropertyDirty("UpdateDate") == false)
{
entity.UpdateDate = now;
}
}
}
}
-13
View File
@@ -478,19 +478,6 @@ namespace Umbraco.Core.Models
set => SetPropertyValueAndDetectChanges(value, ref _providerUserKey, nameof(ProviderUserKey));
}
/// <summary>
/// Method to call when Entity is being saved
/// </summary>
/// <remarks>Created date is set and a Unique key is assigned</remarks>
internal override void AddingEntity()
{
base.AddingEntity();
if (ProviderUserKey == null)
ProviderUserKey = Key;
}
/* Internal experiment - only used for mapping queries.
* Adding these to have first level properties instead of the Properties collection.
*/
@@ -18,7 +18,8 @@ namespace Umbraco.Core.Persistence.Mappers
DefineMap<AuditItem, LogDto>(nameof(AuditItem.Id), nameof(LogDto.NodeId));
DefineMap<AuditItem, LogDto>(nameof(AuditItem.CreateDate), nameof(LogDto.Datestamp));
DefineMap<AuditItem, LogDto>(nameof(AuditItem.UserId), nameof(LogDto.UserId));
DefineMap<AuditItem, LogDto>(nameof(AuditItem.AuditType), nameof(LogDto.Header));
// we cannot map that one - because AuditType is an enum but Header is a string
//DefineMap<AuditItem, LogDto>(nameof(AuditItem.AuditType), nameof(LogDto.Header));
DefineMap<AuditItem, LogDto>(nameof(AuditItem.Comment), nameof(LogDto.Comment));
}
}
@@ -85,6 +85,17 @@ namespace Umbraco.Core.Persistence.Querying
// I'm just unsure right now due to time constraints how to make it correct. It won't matter right now and has been working already with this bug but I've
// only just discovered what it is actually doing.
// TODO
// in most cases we want to convert the value to a plain object,
// but for in some rare cases, we may want to do it differently,
// for instance a Models.AuditType (an enum) may in some cases
// need to be converted to its string value.
// but - we cannot have specific code here, really - and how would
// we configure this? is it even possible?
/*
var toString = typeof(object).GetMethod("ToString");
var member = Expression.Call(m, toString);
*/
var member = Expression.Convert(m, typeof(object));
var lambda = Expression.Lambda<Func<object>>(member);
var getter = lambda.Compile();
@@ -33,5 +33,7 @@ namespace Umbraco.Core.Persistence.Repositories
Direction orderDirection,
AuditType[] auditTypeFilter,
IQuery<IAuditItem> customFilter);
IEnumerable<IAuditItem> Get(AuditType type, IQuery<IAuditItem> query);
}
}
@@ -100,7 +100,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
/// <inheritdoc />
protected override void PersistNewItem(IAuditEntry entity)
{
((EntityBase) entity).AddingEntity();
entity.AddingEntity();
var dto = AuditEntryFactory.BuildDto(entity);
Database.Insert(dto);
@@ -74,6 +74,18 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
return dtos.Select(x => new AuditItem(x.NodeId, Enum<AuditType>.Parse(x.Header), x.UserId ?? Constants.Security.UnknownUserId, x.EntityType, x.Comment, x.Parameters)).ToList();
}
public IEnumerable<IAuditItem> Get(AuditType type, IQuery<IAuditItem> query)
{
var sqlClause = GetBaseQuery(false)
.Where<LogDto>(x => x.Header == type.ToString());
var translator = new SqlTranslator<IAuditItem>(sqlClause, query);
var sql = translator.Translate();
var dtos = Database.Fetch<LogDto>(sql);
return dtos.Select(x => new AuditItem(x.NodeId, Enum<AuditType>.Parse(x.Header), x.UserId ?? Constants.Security.UnknownUserId, x.EntityType, x.Comment, x.Parameters)).ToList();
}
protected override Sql<ISqlContext> GetBaseQuery(bool isCount)
{
var sql = SqlContext.Sql();
@@ -69,7 +69,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
/// <inheritdoc />
protected override void PersistNewItem(IConsent entity)
{
((EntityBase) entity).AddingEntity();
entity.AddingEntity();
var dto = ConsentFactory.BuildDto(entity);
Database.Insert(dto);
@@ -80,7 +80,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
/// <inheritdoc />
protected override void PersistUpdatedItem(IConsent entity)
{
((EntityBase) entity).UpdatingEntity();
entity.UpdatingEntity();
var dto = ConsentFactory.BuildDto(entity);
Database.Update(dto);
@@ -5,6 +5,7 @@ using NPoco;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Entities;
using Umbraco.Core.Persistence.Dtos;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
@@ -230,7 +231,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
throw ex;
}
((ContentType)entity).AddingEntity();
entity.AddingEntity();
PersistNewBaseContentType(entity);
PersistTemplates(entity, false);
@@ -270,7 +271,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
ValidateAlias(entity);
//Updates Modified date
((ContentType)entity).UpdatingEntity();
entity.UpdatingEntity();
//Look up parent to get and set the correct Path if ParentId has changed
if (entity.IsPropertyDirty("ParentId"))
@@ -9,6 +9,7 @@ using Umbraco.Core.Events;
using Umbraco.Core.Exceptions;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Entities;
using Umbraco.Core.Persistence.Dtos;
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Querying;
@@ -106,7 +107,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
protected override void PersistNewItem(IDataType entity)
{
((DataType)entity).AddingEntity();
entity.AddingEntity();
//ensure a datatype has a unique name before creating it
entity.Name = EnsureUniqueNodeName(entity.Name);
@@ -174,7 +175,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
}
//Updates Modified date
((DataType)entity).UpdatingEntity();
entity.UpdatingEntity();
//Look up parent to get and set the correct Path if ParentId has changed
if (entity.IsPropertyDirty("ParentId"))
@@ -148,7 +148,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
protected override void PersistUpdatedItem(IDictionaryItem entity)
{
((EntityBase)entity).UpdatingEntity();
entity.UpdatingEntity();
foreach (var translation in entity.Translations)
translation.Value = translation.Value.ToValidXmlString();
@@ -6,6 +6,7 @@ using Umbraco.Core.Cache;
using Umbraco.Core.Exceptions;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Entities;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Persistence.Dtos;
using Umbraco.Core.Persistence.Factories;
@@ -205,7 +206,10 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
"DELETE FROM " + Constants.DatabaseSchema.Tables.ContentVersionCultureVariation + " WHERE versionId IN (SELECT id FROM " + Constants.DatabaseSchema.Tables.ContentVersion + " WHERE nodeId = @id)",
"DELETE FROM " + Constants.DatabaseSchema.Tables.ContentVersion + " WHERE nodeId = @id",
"DELETE FROM " + Constants.DatabaseSchema.Tables.Content + " WHERE nodeId = @id",
"DELETE FROM " + Constants.DatabaseSchema.Tables.AccessRule + " WHERE accessId IN (SELECT id FROM " + Constants.DatabaseSchema.Tables.Access + " WHERE nodeId = @id OR loginNodeId = @id OR noAccessNodeId = @id)",
"DELETE FROM " + Constants.DatabaseSchema.Tables.Access + " WHERE nodeId = @id",
"DELETE FROM " + Constants.DatabaseSchema.Tables.Access + " WHERE loginNodeId = @id",
"DELETE FROM " + Constants.DatabaseSchema.Tables.Access + " WHERE noAccessNodeId = @id",
"DELETE FROM " + Constants.DatabaseSchema.Tables.Node + " WHERE id = @id"
};
return list;
@@ -260,21 +264,16 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
protected override void PersistNewItem(IContent entity)
{
// TODO: https://github.com/umbraco/Umbraco-CMS/issues/4234 - sort out IContent vs Content
// however, it's not just so we have access to AddingEntity
// there are tons of things at the end of the methods, that can only work with a true Content
// and basically, the repository requires a Content, not an IContent
var content = (Content)entity;
entity.AddingEntity();
content.AddingEntity();
var publishing = content.PublishedState == PublishedState.Publishing;
var publishing = entity.PublishedState == PublishedState.Publishing;
// ensure that the default template is assigned
if (entity.TemplateId.HasValue == false)
entity.TemplateId = entity.ContentType.DefaultTemplate?.Id;
// sanitize names
SanitizeNames(content, publishing);
SanitizeNames(entity, publishing);
// ensure that strings don't contain characters that are invalid in xml
// TODO: do we really want to keep doing this here?
@@ -324,11 +323,11 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
contentVersionDto.NodeId = nodeDto.NodeId;
contentVersionDto.Current = !publishing;
Database.Insert(contentVersionDto);
content.VersionId = contentVersionDto.Id;
entity.VersionId = contentVersionDto.Id;
// persist the document version dto
var documentVersionDto = dto.DocumentVersionDto;
documentVersionDto.Id = content.VersionId;
documentVersionDto.Id = entity.VersionId;
if (publishing)
documentVersionDto.Published = true;
Database.Insert(documentVersionDto);
@@ -336,62 +335,62 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
// and again in case we're publishing immediately
if (publishing)
{
content.PublishedVersionId = content.VersionId;
entity.PublishedVersionId = entity.VersionId;
contentVersionDto.Id = 0;
contentVersionDto.Current = true;
contentVersionDto.Text = content.Name;
contentVersionDto.Text = entity.Name;
Database.Insert(contentVersionDto);
content.VersionId = contentVersionDto.Id;
entity.VersionId = contentVersionDto.Id;
documentVersionDto.Id = content.VersionId;
documentVersionDto.Id = entity.VersionId;
documentVersionDto.Published = false;
Database.Insert(documentVersionDto);
}
// persist the property data
var propertyDataDtos = PropertyFactory.BuildDtos(content.ContentType.Variations, content.VersionId, content.PublishedVersionId, entity.Properties, LanguageRepository, out var edited, out var editedCultures);
var propertyDataDtos = PropertyFactory.BuildDtos(entity.ContentType.Variations, entity.VersionId, entity.PublishedVersionId, entity.Properties, LanguageRepository, out var edited, out var editedCultures);
foreach (var propertyDataDto in propertyDataDtos)
Database.Insert(propertyDataDto);
// if !publishing, we may have a new name != current publish name,
// also impacts 'edited'
if (!publishing && content.PublishName != content.Name)
if (!publishing && entity.PublishName != entity.Name)
edited = true;
// persist the document dto
// at that point, when publishing, the entity still has its old Published value
// so we need to explicitly update the dto to persist the correct value
if (content.PublishedState == PublishedState.Publishing)
if (entity.PublishedState == PublishedState.Publishing)
dto.Published = true;
dto.NodeId = nodeDto.NodeId;
content.Edited = dto.Edited = !dto.Published || edited; // if not published, always edited
entity.Edited = dto.Edited = !dto.Published || edited; // if not published, always edited
Database.Insert(dto);
//insert the schedule
PersistContentSchedule(content, false);
PersistContentSchedule(entity, false);
// persist the variations
if (content.ContentType.VariesByCulture())
if (entity.ContentType.VariesByCulture())
{
// bump dates to align cultures to version
if (publishing)
content.AdjustDates(contentVersionDto.VersionDate);
entity.AdjustDates(contentVersionDto.VersionDate);
// names also impact 'edited'
// ReSharper disable once UseDeconstruction
foreach (var cultureInfo in content.CultureInfos)
if (cultureInfo.Name != content.GetPublishName(cultureInfo.Culture))
foreach (var cultureInfo in entity.CultureInfos)
if (cultureInfo.Name != entity.GetPublishName(cultureInfo.Culture))
(editedCultures ?? (editedCultures = new HashSet<string>(StringComparer.OrdinalIgnoreCase))).Add(cultureInfo.Culture);
// insert content variations
Database.BulkInsertRecords(GetContentVariationDtos(content, publishing));
Database.BulkInsertRecords(GetContentVariationDtos(entity, publishing));
// insert document variations
Database.BulkInsertRecords(GetDocumentVariationDtos(content, publishing, editedCultures));
Database.BulkInsertRecords(GetDocumentVariationDtos(entity, publishing, editedCultures));
}
// refresh content
content.SetCultureEdited(editedCultures);
entity.SetCultureEdited(editedCultures);
// trigger here, before we reset Published etc
OnUowRefreshedEntity(new ScopedEntityEventArgs(AmbientScope, entity));
@@ -399,23 +398,23 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
// flip the entity's published property
// this also flips its published state
// note: what depends on variations (eg PublishNames) is managed directly by the content
if (content.PublishedState == PublishedState.Publishing)
if (entity.PublishedState == PublishedState.Publishing)
{
content.Published = true;
content.PublishTemplateId = content.TemplateId;
content.PublisherId = content.WriterId;
content.PublishName = content.Name;
content.PublishDate = content.UpdateDate;
entity.Published = true;
entity.PublishTemplateId = entity.TemplateId;
entity.PublisherId = entity.WriterId;
entity.PublishName = entity.Name;
entity.PublishDate = entity.UpdateDate;
SetEntityTags(entity, _tagRepository);
}
else if (content.PublishedState == PublishedState.Unpublishing)
else if (entity.PublishedState == PublishedState.Unpublishing)
{
content.Published = false;
content.PublishTemplateId = null;
content.PublisherId = null;
content.PublishName = null;
content.PublishDate = null;
entity.Published = false;
entity.PublishTemplateId = null;
entity.PublisherId = null;
entity.PublishName = null;
entity.PublishDate = null;
ClearEntityTags(entity, _tagRepository);
}
@@ -437,34 +436,33 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
protected override void PersistUpdatedItem(IContent entity)
{
// however, it's not just so we have access to AddingEntity
// there are tons of things at the end of the methods, that can only work with a true Content
// and basically, the repository requires a Content, not an IContent
var content = (Content)entity;
var entityBase = entity as EntityBase;
var isEntityDirty = entityBase != null && entityBase.IsDirty();
// check if we need to make any database changes at all
if ((content.PublishedState == PublishedState.Published || content.PublishedState == PublishedState.Unpublished)
&& !content.IsEntityDirty() && !content.IsAnyUserPropertyDirty())
if ((entity.PublishedState == PublishedState.Published || entity.PublishedState == PublishedState.Unpublished)
&& !isEntityDirty && !entity.IsAnyUserPropertyDirty())
return; // no change to save, do nothing, don't even update dates
// whatever we do, we must check that we are saving the current version
var version = Database.Fetch<ContentVersionDto>(SqlContext.Sql().Select<ContentVersionDto>().From<ContentVersionDto>().Where<ContentVersionDto>(x => x.Id == content.VersionId)).FirstOrDefault();
var version = Database.Fetch<ContentVersionDto>(SqlContext.Sql().Select<ContentVersionDto>().From<ContentVersionDto>().Where<ContentVersionDto>(x => x.Id == entity.VersionId)).FirstOrDefault();
if (version == null || !version.Current)
throw new InvalidOperationException("Cannot save a non-current version.");
// update
content.UpdatingEntity();
var publishing = content.PublishedState == PublishedState.Publishing;
entity.UpdatingEntity();
var publishing = entity.PublishedState == PublishedState.Publishing;
// check if we need to create a new version
if (publishing && content.PublishedVersionId > 0)
if (publishing && entity.PublishedVersionId > 0)
{
// published version is not published anymore
Database.Execute(Sql().Update<DocumentVersionDto>(u => u.Set(x => x.Published, false)).Where<DocumentVersionDto>(x => x.Id == content.PublishedVersionId));
Database.Execute(Sql().Update<DocumentVersionDto>(u => u.Set(x => x.Published, false)).Where<DocumentVersionDto>(x => x.Id == entity.PublishedVersionId));
}
// sanitize names
SanitizeNames(content, publishing);
SanitizeNames(entity, publishing);
// ensure that strings don't contain characters that are invalid in xml
// TODO: do we really want to keep doing this here?
@@ -504,13 +502,13 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
// and, if publishing, insert new content & document version dtos
if (publishing)
{
content.PublishedVersionId = content.VersionId;
entity.PublishedVersionId = entity.VersionId;
contentVersionDto.Id = 0; // want a new id
contentVersionDto.Current = true; // current version
contentVersionDto.Text = content.Name;
contentVersionDto.Text = entity.Name;
Database.Insert(contentVersionDto);
content.VersionId = documentVersionDto.Id = contentVersionDto.Id; // get the new id
entity.VersionId = documentVersionDto.Id = contentVersionDto.Id; // get the new id
documentVersionDto.Published = false; // non-published version
Database.Insert(documentVersionDto);
@@ -518,31 +516,31 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
// replace the property data (rather than updating)
// only need to delete for the version that existed, the new version (if any) has no property data yet
var versionToDelete = publishing ? content.PublishedVersionId : content.VersionId;
var versionToDelete = publishing ? entity.PublishedVersionId : entity.VersionId;
var deletePropertyDataSql = Sql().Delete<PropertyDataDto>().Where<PropertyDataDto>(x => x.VersionId == versionToDelete);
Database.Execute(deletePropertyDataSql);
// insert property data
var propertyDataDtos = PropertyFactory.BuildDtos(content.ContentType.Variations, content.VersionId, publishing ? content.PublishedVersionId : 0,
var propertyDataDtos = PropertyFactory.BuildDtos(entity.ContentType.Variations, entity.VersionId, publishing ? entity.PublishedVersionId : 0,
entity.Properties, LanguageRepository, out var edited, out var editedCultures);
foreach (var propertyDataDto in propertyDataDtos)
Database.Insert(propertyDataDto);
// if !publishing, we may have a new name != current publish name,
// also impacts 'edited'
if (!publishing && content.PublishName != content.Name)
if (!publishing && entity.PublishName != entity.Name)
edited = true;
if (content.ContentType.VariesByCulture())
if (entity.ContentType.VariesByCulture())
{
// bump dates to align cultures to version
if (publishing)
content.AdjustDates(contentVersionDto.VersionDate);
entity.AdjustDates(contentVersionDto.VersionDate);
// names also impact 'edited'
// ReSharper disable once UseDeconstruction
foreach (var cultureInfo in content.CultureInfos)
if (cultureInfo.Name != content.GetPublishName(cultureInfo.Culture))
foreach (var cultureInfo in entity.CultureInfos)
if (cultureInfo.Name != entity.GetPublishName(cultureInfo.Culture))
{
edited = true;
(editedCultures ?? (editedCultures = new HashSet<string>(StringComparer.OrdinalIgnoreCase))).Add(cultureInfo.Culture);
@@ -560,7 +558,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
Database.Execute(deleteContentVariations);
// replace the document version variations (rather than updating)
var deleteDocumentVariations = Sql().Delete<DocumentCultureVariationDto>().Where<DocumentCultureVariationDto>(x => x.NodeId == content.Id);
var deleteDocumentVariations = Sql().Delete<DocumentCultureVariationDto>().Where<DocumentCultureVariationDto>(x => x.NodeId == entity.Id);
Database.Execute(deleteDocumentVariations);
// TODO: NPoco InsertBulk issue?
@@ -570,32 +568,32 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
// (same in PersistNewItem above)
// insert content variations
Database.BulkInsertRecords(GetContentVariationDtos(content, publishing));
Database.BulkInsertRecords(GetContentVariationDtos(entity, publishing));
// insert document variations
Database.BulkInsertRecords(GetDocumentVariationDtos(content, publishing, editedCultures));
Database.BulkInsertRecords(GetDocumentVariationDtos(entity, publishing, editedCultures));
}
// refresh content
content.SetCultureEdited(editedCultures);
entity.SetCultureEdited(editedCultures);
// update the document dto
// at that point, when un/publishing, the entity still has its old Published value
// so we need to explicitly update the dto to persist the correct value
if (content.PublishedState == PublishedState.Publishing)
if (entity.PublishedState == PublishedState.Publishing)
dto.Published = true;
else if (content.PublishedState == PublishedState.Unpublishing)
else if (entity.PublishedState == PublishedState.Unpublishing)
dto.Published = false;
content.Edited = dto.Edited = !dto.Published || edited; // if not published, always edited
entity.Edited = dto.Edited = !dto.Published || edited; // if not published, always edited
Database.Update(dto);
//update the schedule
if (content.IsPropertyDirty("ContentSchedule"))
PersistContentSchedule(content, true);
if (entity.IsPropertyDirty("ContentSchedule"))
PersistContentSchedule(entity, true);
// if entity is publishing, update tags, else leave tags there
// means that implicitly unpublished, or trashed, entities *still* have tags in db
if (content.PublishedState == PublishedState.Publishing)
if (entity.PublishedState == PublishedState.Publishing)
SetEntityTags(entity, _tagRepository);
// trigger here, before we reset Published etc
@@ -603,23 +601,23 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
// flip the entity's published property
// this also flips its published state
if (content.PublishedState == PublishedState.Publishing)
if (entity.PublishedState == PublishedState.Publishing)
{
content.Published = true;
content.PublishTemplateId = content.TemplateId;
content.PublisherId = content.WriterId;
content.PublishName = content.Name;
content.PublishDate = content.UpdateDate;
entity.Published = true;
entity.PublishTemplateId = entity.TemplateId;
entity.PublisherId = entity.WriterId;
entity.PublishName = entity.Name;
entity.PublishDate = entity.UpdateDate;
SetEntityTags(entity, _tagRepository);
}
else if (content.PublishedState == PublishedState.Unpublishing)
else if (entity.PublishedState == PublishedState.Unpublishing)
{
content.Published = false;
content.PublishTemplateId = null;
content.PublisherId = null;
content.PublishName = null;
content.PublishDate = null;
entity.Published = false;
entity.PublishTemplateId = null;
entity.PublisherId = null;
entity.PublishName = null;
entity.PublishDate = null;
ClearEntityTags(entity, _tagRepository);
}
@@ -1335,7 +1333,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
#region Utilities
private void SanitizeNames(Content content, bool publishing)
private void SanitizeNames(IContent content, bool publishing)
{
// a content item *must* have an invariant name, and invariant published name
// else we just cannot write the invariant rows (node, content version...) to the database
@@ -1400,7 +1398,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
x.NodeId != SqlTemplate.Arg<int>("id"))
.OrderBy<ContentVersionCultureVariationDto>(x => x.LanguageId));
private void EnsureVariantNamesAreUnique(Content content, bool publishing)
private void EnsureVariantNamesAreUnique(IContent content, bool publishing)
{
if (!EnsureUniqueNaming || !content.ContentType.VariesByCulture() || content.CultureInfos.Count == 0) return;
@@ -6,6 +6,7 @@ using NPoco;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Entities;
using Umbraco.Core.Persistence.Dtos;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Scoping;
@@ -101,7 +102,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
if (languageExists == 0) throw new NullReferenceException("No language exists with id " + entity.LanguageId.Value);
}
((UmbracoDomain)entity).AddingEntity();
entity.AddingEntity();
var factory = new DomainModelFactory();
var dto = factory.BuildDto(entity);
@@ -120,7 +121,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
protected override void PersistUpdatedItem(IDomain entity)
{
((UmbracoDomain)entity).UpdatingEntity();
entity.UpdatingEntity();
var exists = Database.ExecuteScalar<int>("SELECT COUNT(*) FROM umbracoDomain WHERE domainName = @domainName AND umbracoDomain.id <> @id",
new { domainName = entity.DomainName, id = entity.Id });
@@ -139,7 +139,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
protected override void PersistNewItem(IIdentityUserLogin entity)
{
((EntityBase)entity).AddingEntity();
entity.AddingEntity();
var dto = ExternalLoginFactory.BuildDto(entity);
@@ -151,7 +151,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
protected override void PersistUpdatedItem(IIdentityUserLogin entity)
{
((EntityBase)entity).UpdatingEntity();
entity.UpdatingEntity();
var dto = ExternalLoginFactory.BuildDto(entity);
@@ -129,7 +129,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
if (entity.IsoCode.IsNullOrWhiteSpace() || entity.CultureName.IsNullOrWhiteSpace())
throw new InvalidOperationException("Cannot save a language without an ISO code and a culture name.");
((EntityBase) entity).AddingEntity();
entity.AddingEntity();
// deal with entity becoming the new default entity
if (entity.IsDefault)
@@ -156,7 +156,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
if (entity.IsoCode.IsNullOrWhiteSpace() || entity.CultureName.IsNullOrWhiteSpace())
throw new InvalidOperationException("Cannot save a language without an ISO code and a culture name.");
((EntityBase) entity).UpdatingEntity();
entity.UpdatingEntity();
if (entity.IsDefault)
{
@@ -132,7 +132,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
protected override void PersistNewItem(IMacro entity)
{
((EntityBase)entity).AddingEntity();
entity.AddingEntity();
var dto = MacroFactory.BuildDto(entity);
@@ -152,7 +152,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
protected override void PersistUpdatedItem(IMacro entity)
{
((EntityBase)entity).UpdatingEntity();
entity.UpdatingEntity();
;
var dto = MacroFactory.BuildDto(entity);
@@ -8,6 +8,7 @@ using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Exceptions;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Entities;
using Umbraco.Core.Persistence.Dtos;
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Querying;
@@ -217,7 +218,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
protected override void PersistNewItem(IMedia entity)
{
var media = (Models.Media) entity;
media.AddingEntity();
entity.AddingEntity();
// ensure unique name on the same level
entity.Name = EnsureUniqueNodeName(entity.ParentId, entity.Name);
@@ -5,6 +5,7 @@ using NPoco;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Entities;
using Umbraco.Core.Persistence.Dtos;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Scoping;
@@ -102,7 +103,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
protected override void PersistNewItem(IMediaType entity)
{
((MediaType)entity).AddingEntity();
entity.AddingEntity();
PersistNewBaseContentType(entity);
@@ -114,7 +115,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
ValidateAlias(entity);
//Updates Modified date
((MediaType)entity).UpdatingEntity();
entity.UpdatingEntity();
//Look up parent to get and set the correct Path if ParentId has changed
if (entity.IsPropertyDirty("ParentId"))
@@ -6,6 +6,7 @@ using Umbraco.Core.Cache;
using Umbraco.Core.Events;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Entities;
using Umbraco.Core.Persistence.Dtos;
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Querying;
@@ -91,8 +92,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
protected override void PersistNewItem(IMemberGroup entity)
{
//Save to db
entity.AddingEntity();
var group = (MemberGroup)entity;
group.AddingEntity();
var dto = MemberGroupFactory.BuildDto(group);
var o = Database.IsNew(dto) ? Convert.ToInt32(Database.Insert(dto)) : Database.Update(dto);
group.Id = dto.NodeId; //Set Id on entity to ensure an Id is set
@@ -6,6 +6,7 @@ using NPoco;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Entities;
using Umbraco.Core.Persistence.Dtos;
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Querying;
@@ -232,8 +233,13 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
protected override void PersistNewItem(IMember entity)
{
if (entity.ProviderUserKey == null)
{
entity.ProviderUserKey = entity.Key;
}
entity.AddingEntity();
var member = (Member) entity;
member.AddingEntity();
// ensure that strings don't contain characters that are invalid in xml
// TODO: do we really want to keep doing this here?
@@ -5,6 +5,7 @@ using NPoco;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Entities;
using Umbraco.Core.Persistence.Dtos;
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Querying;
@@ -131,12 +132,12 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
{
ValidateAlias(entity);
((MemberType)entity).AddingEntity();
entity.AddingEntity();
//set a default icon if one is not specified
if (entity.Icon.IsNullOrWhiteSpace())
{
entity.Icon = "icon-user";
entity.Icon = Constants.Icons.Member;
}
//By Convention we add 9 standard PropertyTypes to an Umbraco MemberType
@@ -165,7 +166,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
ValidateAlias(entity);
//Updates Modified date
((MemberType)entity).UpdatingEntity();
entity.UpdatingEntity();
//Look up parent to get and set the correct Path if ParentId has changed
if (entity.IsPropertyDirty("ParentId"))
@@ -5,6 +5,7 @@ using NPoco;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Entities;
using Umbraco.Core.Persistence.Dtos;
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Querying;
@@ -134,7 +134,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
protected override void PersistNewItem(IRelation entity)
{
((EntityBase)entity).AddingEntity();
entity.AddingEntity();
var factory = new RelationFactory(entity.RelationType);
var dto = factory.BuildDto(entity);
@@ -147,7 +147,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
protected override void PersistUpdatedItem(IRelation entity)
{
((EntityBase)entity).UpdatingEntity();
entity.UpdatingEntity();
var factory = new RelationFactory(entity.RelationType);
var dto = factory.BuildDto(entity);
@@ -133,7 +133,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
protected override void PersistNewItem(IRelationType entity)
{
((EntityBase)entity).AddingEntity();
entity.AddingEntity();
var dto = RelationTypeFactory.BuildDto(entity);
@@ -145,7 +145,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
protected override void PersistUpdatedItem(IRelationType entity)
{
((EntityBase)entity).UpdatingEntity();
entity.UpdatingEntity();
var dto = RelationTypeFactory.BuildDto(entity);
Database.Update(dto);
@@ -5,6 +5,7 @@ using NPoco;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Entities;
using Umbraco.Core.Persistence.Dtos;
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Querying;
@@ -96,7 +97,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
protected override void PersistNewItem(IServerRegistration entity)
{
((ServerRegistration)entity).AddingEntity();
entity.AddingEntity();
var dto = ServerRegistrationFactory.BuildDto(entity);
@@ -108,7 +109,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
protected override void PersistUpdatedItem(IServerRegistration entity)
{
((ServerRegistration)entity).UpdatingEntity();
entity.UpdatingEntity();
var dto = ServerRegistrationFactory.BuildDto(entity);
@@ -85,7 +85,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
/// <inheritdoc />
protected override void PersistNewItem(ITag entity)
{
((EntityBase)entity).AddingEntity();
entity.AddingEntity();
var dto = TagFactory.BuildDto(entity);
var id = Convert.ToInt32(Database.Insert(dto));
@@ -97,7 +97,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
/// <inheritdoc />
protected override void PersistUpdatedItem(ITag entity)
{
((EntityBase)entity).UpdatingEntity();
entity.UpdatingEntity();
var dto = TagFactory.BuildDto(entity);
Database.Update(dto);
@@ -290,7 +290,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
protected override void PersistNewItem(IUserGroup entity)
{
((UserGroup) entity).AddingEntity();
entity.AddingEntity();
var userGroupDto = UserGroupFactory.BuildDto(entity);
@@ -304,7 +304,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
protected override void PersistUpdatedItem(IUserGroup entity)
{
((UserGroup) entity).UpdatingEntity();
entity.UpdatingEntity();
var userGroupDto = UserGroupFactory.BuildDto(entity);
@@ -445,7 +445,7 @@ ORDER BY colName";
return;
}
((User) entity).AddingEntity();
entity.AddingEntity();
// ensure security stamp if missing
if (entity.SecurityStamp.IsNullOrWhiteSpace())
@@ -495,7 +495,7 @@ ORDER BY colName";
protected override void PersistUpdatedItem(IUser entity)
{
// updates Modified date
((User) entity).UpdatingEntity();
entity.UpdatingEntity();
// ensure security stamp if missing
if (entity.SecurityStamp.IsNullOrWhiteSpace())
@@ -51,8 +51,8 @@ namespace Umbraco.Core.Services.Implement
using (var scope = ScopeProvider.CreateScope())
{
var result = sinceDate.HasValue == false
? _auditRepository.Get(Query<IAuditItem>().Where(x => x.UserId == userId && x.AuditType == type))
: _auditRepository.Get(Query<IAuditItem>().Where(x => x.UserId == userId && x.AuditType == type && x.CreateDate >= sinceDate.Value));
? _auditRepository.Get(type, Query<IAuditItem>().Where(x => x.UserId == userId))
: _auditRepository.Get(type, Query<IAuditItem>().Where(x => x.UserId == userId && x.CreateDate >= sinceDate.Value));
scope.Complete();
return result;
}
@@ -63,8 +63,8 @@ namespace Umbraco.Core.Services.Implement
using (var scope = ScopeProvider.CreateScope())
{
var result = sinceDate.HasValue == false
? _auditRepository.Get(Query<IAuditItem>().Where(x => x.AuditType == type))
: _auditRepository.Get(Query<IAuditItem>().Where(x => x.AuditType == type && x.CreateDate >= sinceDate.Value));
? _auditRepository.Get(type, Query<IAuditItem>())
: _auditRepository.Get(type, Query<IAuditItem>().Where(x => x.CreateDate >= sinceDate.Value));
scope.Complete();
return result;
}
+1
View File
@@ -234,6 +234,7 @@
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\RenamingPreValueMigrator.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\RichTextPreValueMigrator.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\MergeDateAndDateTimePropertyEditor.cs" />
<Compile Include="Models\Entities\EntityExtensions.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\PreValueMigratorBase.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\PreValueDto.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\PropertyEditorsMigrationBase.cs" />
@@ -264,6 +264,74 @@ namespace Umbraco.Tests.PublishedContent
yield return CreateKit(12, 4, 2);
}
private IEnumerable<ContentNodeKit> GetVariantWithDraftKits()
{
var paths = new Dictionary<int, string> { { -1, "-1" } };
Dictionary<string, CultureVariation> GetCultureInfos(int id, DateTime now)
{
var en = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
var fr = new[] { 1, 3, 4, 6, 7, 9, 10, 12 };
var infos = new Dictionary<string, CultureVariation>();
if (en.Contains(id))
infos["en-US"] = new CultureVariation { Name = "N" + id + "-" + "en-US", Date = now, IsDraft = false };
if (fr.Contains(id))
infos["fr-FR"] = new CultureVariation { Name = "N" + id + "-" + "fr-FR", Date = now, IsDraft = false };
return infos;
}
ContentNodeKit CreateKit(int id, int parentId, int sortOrder)
{
if (!paths.TryGetValue(parentId, out var parentPath))
throw new Exception("Unknown parent.");
var path = paths[id] = parentPath + "," + id;
var level = path.Count(x => x == ',');
var now = DateTime.Now;
ContentData CreateContentData(bool published) => new ContentData
{
Name = "N" + id,
Published = published,
TemplateId = 0,
VersionId = 1,
VersionDate = now,
WriterId = 0,
Properties = new Dictionary<string, PropertyData[]>(),
CultureInfos = GetCultureInfos(id, now)
};
var withDraft = id%2==0;
var withPublished = !withDraft;
return new ContentNodeKit
{
ContentTypeId = _contentTypeVariant.Id,
Node = new ContentNode(id, Guid.NewGuid(), level, path, sortOrder, parentId, DateTime.Now, 0),
DraftData = withDraft ? CreateContentData(false) : null,
PublishedData = withPublished ? CreateContentData(true) : null
};
}
yield return CreateKit(1, -1, 1);
yield return CreateKit(2, -1, 2);
yield return CreateKit(3, -1, 3);
yield return CreateKit(4, 1, 1);
yield return CreateKit(5, 1, 2);
yield return CreateKit(6, 1, 3);
yield return CreateKit(7, 2, 3);
yield return CreateKit(8, 2, 2);
yield return CreateKit(9, 2, 1);
yield return CreateKit(10, 3, 1);
yield return CreateKit(11, 4, 1);
yield return CreateKit(12, 4, 2);
}
[Test]
public void EmptyTest()
{
@@ -747,6 +815,25 @@ namespace Umbraco.Tests.PublishedContent
AssertDocuments(documents, "N9", "N8", "N7");
}
[Test]
public void AtRootTest()
{
Init(GetVariantWithDraftKits());
var snapshot = _snapshotService.CreatePublishedSnapshot(previewToken: null);
_snapshotAccessor.PublishedSnapshot = snapshot;
_variationAccesor.VariationContext = new VariationContext("en-US");
// N2 is draft only
var documents = snapshot.Content.GetAtRoot().ToArray();
AssertDocuments(documents, "N1-en-US", /*"N2-en-US",*/ "N3-en-US");
documents = snapshot.Content.GetAtRoot(true).ToArray();
AssertDocuments(documents, "N1-en-US", "N2-en-US", "N3-en-US");
}
private void AssertDocuments(IPublishedContent[] documents, params string[] names)
{
Assert.AreEqual(names.Length, documents.Length);
@@ -4,6 +4,7 @@ using NUnit.Framework;
using Umbraco.Core.Services.Implement;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.Testing;
using Umbraco.Core.Models;
namespace Umbraco.Tests.Services
{
@@ -48,5 +49,19 @@ namespace Umbraco.Tests.Services
Assert.AreEqual(123 + 5, entries[0].PerformingUserId);
Assert.AreEqual(123 + 4, entries[1].PerformingUserId);
}
[Test]
public void CanReadEntries()
{
var yesterday = DateTime.UtcNow.AddDays(-1);
for (var i = 0; i < 10; i++)
{
yesterday = yesterday.AddMinutes(1);
ServiceContext.AuditService.Add(AuditType.Unpublish, -1, 33, "", "blah");
}
var logs = ServiceContext.AuditService.GetUserLogs(-1, AuditType.Unpublish);
}
}
}
+1 -1
View File
@@ -35,7 +35,7 @@
"lazyload-js": "1.0.0",
"moment": "2.22.2",
"ng-file-upload": "12.2.13",
"nouislider": "12.1.0",
"nouislider": "14.0.1",
"npm": "^6.4.1",
"signalr": "2.4.0",
"spectrum-colorpicker": "1.8.0",
@@ -95,7 +95,8 @@ Use this directive to render an umbraco button. The directive can be used to gen
size: "@?",
alias: "@?",
addEllipsis: "@?",
showCaret: "@?"
showCaret: "@?",
autoFocus: "@?"
}
});
@@ -101,14 +101,14 @@ angular.module('umbraco.directives')
var eventBindings = [];
function oneTimeClick(event) {
var el = event.target.nodeName;
//ignore link and button clicks
var els = ["INPUT", "A", "BUTTON"];
if (els.indexOf(el) >= 0) { return; }
// ignore clicks on button groups toggles (i.e. the save and publish button)
var parents = $(event.target).closest("[data-element='button-group-toggle']");
if (parents.length > 0) {
return;
}
// ignore clicks on new overlay
var parents = $(event.target).parents("a,button,.umb-overlay,.umb-tour");
parents = $(event.target).parents(".umb-overlay,.umb-tour");
if (parents.length > 0) {
return;
}
@@ -136,7 +136,8 @@ angular.module('umbraco.directives')
return;
}
angularHelper.safeApply(scope, attrs.onOutsideClick);
// please to not use angularHelper.safeApply here, it won't work
scope.$apply(attrs.onOutsideClick);
}
@@ -9,8 +9,10 @@ angular.module("umbraco.directives")
}
};
$timeout(function() {
update();
});
if (attr.umbAutoFocus !== "false") {
$timeout(function() {
update();
});
}
};
});
@@ -311,9 +311,8 @@ Opens an overlay to show a custom YSOD. </br>
var submitOnEnter = document.activeElement.hasAttribute("overlay-submit-on-enter");
var submitOnEnterValue = submitOnEnter ? document.activeElement.getAttribute("overlay-submit-on-enter") : "";
if(clickableElements.indexOf(activeElementType) === 0) {
document.activeElement.trigger("click");
event.preventDefault();
if(clickableElements.indexOf(activeElementType) >= 0) {
// don't do anything, let the browser Enter key handle this
} else if(activeElementType === "TEXTAREA" && !submitOnEnter) {
@@ -1,16 +1,20 @@
(function() {
'use strict';
function UmbContextDialog(navigationService, keyboardService) {
function UmbContextDialog(navigationService, keyboardService, localizationService, overlayService) {
function link($scope) {
$scope.outSideClick = function() {
navigationService.hideDialog();
}
keyboardService.bind("esc", function() {
navigationService.hideDialog();
$scope.dialog = {
confirmDiscardChanges: false
};
$scope.outSideClick = function() {
hide();
};
keyboardService.bind("esc", function () {
hide();
});
//ensure to unregister from all events!
@@ -18,6 +22,35 @@
keyboardService.unbind("esc");
});
function hide() {
if ($scope.dialog.confirmDiscardChanges) {
localizationService.localizeMany(["prompt_unsavedChanges", "prompt_unsavedChangesWarning", "prompt_discardChanges", "prompt_stay"]).then(
function (values) {
var overlay = {
"view": "default",
"title": values[0],
"content": values[1],
"disableBackdropClick": true,
"disableEscKey": true,
"submitButtonLabel": values[2],
"closeButtonLabel": values[3],
submit: function () {
overlayService.close();
navigationService.hideDialog();
},
close: function () {
overlayService.close();
}
};
overlayService.open(overlay);
}
);
}
else {
navigationService.hideDialog();
}
}
}
var directive = {
@@ -474,6 +474,11 @@
if (!property.inherited) {
var oldPropertyModel = angular.copy(property);
if (oldPropertyModel.allowCultureVariant === undefined) {
// this is necessary for comparison when detecting changes to the property
oldPropertyModel.allowCultureVariant = scope.model.allowCultureVariant;
oldPropertyModel.alias = "";
}
var propertyModel = angular.copy(property);
var propertySettings = {
@@ -71,7 +71,7 @@
}
// set published state for content
if (c.metaData) {
c.hasChildren = c.metaData.HasChildren;
c.hasChildren = c.metaData.hasChildren;
if(scope.entityType === "Document") {
c.published = c.metaData.IsPublished;
}
@@ -79,7 +79,7 @@
// filter items if there is a filter and it's not advanced
// ** ignores advanced filter at the moment
if (scope.entityTypeFilter && !scope.entityTypeFilter.filterAdvanced) {
if (scope.entityTypeFilter && scope.entityTypeFilter.filter && !scope.entityTypeFilter.filterAdvanced) {
var a = scope.entityTypeFilter.filter.toLowerCase().replace(/\s/g, '').split(',');
var found = a.indexOf(c.metaData.ContentTypeAlias.toLowerCase()) >= 0;
@@ -29,35 +29,48 @@ angular.module('umbraco.services')
var resourceFileLoadStatus = "none";
var resourceLoadingPromise = [];
function _lookup(value, tokens, dictionary) {
// array to hold the localized resource string entries
var innerDictionary = [];
function _lookup(alias, tokens, dictionary, fallbackValue) {
//strip the key identifier if its there
if (value && value[0] === "@") {
value = value.substring(1);
if (alias && alias[0] === "@") {
alias = alias.substring(1);
}
var underscoreIndex = alias.indexOf("_");
//if no area specified, add general_
if (value && value.indexOf("_") < 0) {
value = "general_" + value;
if (alias && underscoreIndex < 0) {
alias = "general_" + alias;
underscoreIndex = alias.indexOf("_");
}
var entry = dictionary[value];
if (entry) {
return service.tokenReplace(entry, tokens);
var areaAlias = alias.substring(0, underscoreIndex);
var valueAlias = alias.substring(underscoreIndex + 1);
var areaEntry = dictionary[areaAlias];
if (areaEntry) {
var valueEntry = areaEntry[valueAlias];
if (valueEntry) {
return service.tokenReplace(valueEntry, tokens);
}
}
return "[" + value + "]";
if (fallbackValue) return fallbackValue;
return "[" + alias + "]";
}
var service = {
// array to hold the localized resource string entries
dictionary: [],
// loads the language resource file from the server
initLocalizedResources: function () {
var deferred = $q.defer();
if (resourceFileLoadStatus === "loaded") {
deferred.resolve(service.dictionary);
deferred.resolve(innerDictionary);
return deferred.promise;
}
@@ -77,7 +90,7 @@ angular.module('umbraco.services')
$http({ method: "GET", url: url, cache: false })
.then(function (response) {
resourceFileLoadStatus = "loaded";
service.dictionary = response.data;
innerDictionary = response.data;
eventsService.emit("localizationService.updated", response.data);
@@ -159,11 +172,14 @@ angular.module('umbraco.services')
* @param {Array} tokens if specified this array will be sent as parameter values
* This replaces %0% and %1% etc in the dictionary key value with the passed in strings
*
* @param {String} fallbackValue if specified this string will be returned if no matching
* entry was found in the dictionary
*
* @returns {String} localized resource string
*/
localize: function (value, tokens) {
localize: function (value, tokens, fallbackValue) {
return service.initLocalizedResources().then(function (dic) {
return _lookup(value, tokens, dic);
return _lookup(value, tokens, dic, fallbackValue);
});
},
@@ -244,8 +260,8 @@ angular.module('umbraco.services')
//Build a concat string by looping over the array of resolved promises/translations
var returnValue = "";
for(var i = 0; i < localizedValues.length; i++){
returnValue += localizedValues[i];
for(var j = 0; j < localizedValues.length; j++){
returnValue += localizedValues[j];
}
return returnValue;
@@ -292,11 +308,11 @@ angular.module('umbraco.services')
return $q.all(promises).then(function(localizedValues){
//Replace {0} and {1} etc in message with the localized values
for(var i = 0; i < localizedValues.length; i++){
var token = "%" + i + "%";
for(var j = 0; j < localizedValues.length; j++){
var token = "%" + j + "%";
var regex = new RegExp(token, "g");
message = message.replace(regex, localizedValues[i]);
message = message.replace(regex, localizedValues[j]);
}
return message;
@@ -0,0 +1,24 @@
// sr-only - based on the boot strap naming conventions used to remove an element from the view, whilst retaining accessibily for screen readers. More info available at https://getbootstrap.com/docs/4.0/utilities/screenreaders/
// --------------------------------------------------
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0,0,0,0);
border: 0;
&--focusable:active,
&--focusable:focus,
&--hoverable:hover {
position: static;
width: auto;
height: auto;
margin: 0;
overflow: visible;
clip: auto;
}
}
@@ -80,8 +80,10 @@
@import "forms/umb-validation-label.less";
// Umbraco Accessibility
@import "accessibility/sr-only.less";
// Umbraco Components
@import "components/application/umb-app-a11y.less";
@import "components/application/umb-app-header.less";
@import "components/application/umb-app-content.less";
@import "components/application/umb-tour.less";
@@ -1,10 +0,0 @@
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0,0,0,0);
border: 0;
}
@@ -27,6 +27,7 @@
}
.umb-action-link {
position: relative;
white-space: nowrap;
font-size: 15px;
color: @black;
@@ -34,6 +35,7 @@
text-decoration: none;
cursor: pointer;
display: flex;
width: 100%;
align-items: center;
body.touch & {
@@ -8,12 +8,28 @@
user-select: none;
}
&:hover ins {
&:hover .umb-tree-item__arrow {
visibility: visible;
cursor: pointer
}
}
.umb-tree-item__arrow {
position: relative;
margin-left: -16px;
width: 16px;
height: 16px;
visibility: hidden;
text-decoration: none;
font-size: 12px;
line-height: 12px;
transition: color 120ms;
&:hover {
color: @ui-option-type-hover;
}
}
.umb-tree-item > .umb-tree-item__inner {
&:hover .umb-tree-item__label {
@@ -95,7 +111,7 @@
a,
.umb-tree-icon,
ins {
.umb-tree-item__arrow {
color: @ui-active-type !important;
}
}
@@ -15,20 +15,6 @@
text-decoration: none;
}
ins {
margin: -4px 0 0 -16px;
width: 16px;
height: 16px;
visibility: hidden;
text-decoration: none;
font-size: 12px;
transition: color 120ms;
&:hover {
color: @ui-option-type-hover;
}
}
i.noSpr {
display: inline-block;
margin-top: 1px;
@@ -62,7 +48,7 @@
}
body.touch .umb-tree {
ins {
.umb-tree-item__arrow {
font-size: 14px;
visibility: visible;
padding: 7px;
@@ -104,7 +90,13 @@ body.touch .umb-tree {
}
> .umb-options {
visibility: visible;
position: relative;
width: auto;
height: auto;
margin: 0 10px 0 auto;
padding: 9px 5px;
overflow: visible;
clip: auto;
}
.umb-tree-icon {
@@ -178,7 +170,7 @@ body.touch .umb-tree {
}
.umb-options {
visibility: hidden;
position: relative;
display: flex;
flex: 0 0 auto;
justify-content: flex-end;
@@ -192,6 +184,20 @@ body.touch .umb-tree {
background: @btnBackgroundHighlight;
}
// NOTE - We're having to repeat ourselves here due to an .sr-only class appearing in umbraco/lib/font-awesome/css/font-awesome.min.css
&.sr-only--hoverable:hover,
&.sr-only--focusable:focus {
position: relative;
display: flex;
flex: 0 0 auto;
justify-content: flex-end;
padding: 9px 5px;
text-align: center;
margin: 0 10px 0 auto;
cursor: pointer;
border-radius: 3px;
}
i {
height: 5px !important;
width: 5px !important;
@@ -6,7 +6,7 @@
flex-wrap: wrap;
align-items: center;
position: relative;
padding: 0;
padding: 0 !important;
margin: 0;
min-height: 22px;
line-height: 22px;
@@ -113,6 +113,10 @@
bottom: 0px;
padding: 20px;
margin: 0;
.btn.umb-outline {
position: relative
}
}
/*we will always make sure to wrap iframe dialogs in proper padding*/
@@ -369,20 +369,32 @@ angular.module("umbraco")
mediaItem.thumbnail = mediaHelper.resolveFileFromEntity(mediaItem, true);
mediaItem.image = mediaHelper.resolveFileFromEntity(mediaItem, false);
// set properties to match a media object
if (mediaItem.metaData &&
mediaItem.metaData.umbracoWidth &&
mediaItem.metaData.umbracoHeight) {
mediaItem.properties = [
{
alias: "umbracoWidth",
value: mediaItem.metaData.umbracoWidth.Value
},
{
alias: "umbracoHeight",
value: mediaItem.metaData.umbracoHeight.Value
}
];
if (mediaItem.metaData) {
mediaItem.properties = [];
if (mediaItem.metaData.umbracoWidth && mediaItem.metaData.umbracoHeight) {
mediaItem.properties.push(
{
alias: "umbracoWidth",
editor: mediaItem.metaData.umbracoWidth.PropertyEditorAlias,
value: mediaItem.metaData.umbracoWidth.Value
},
{
alias: "umbracoHeight",
editor: mediaItem.metaData.umbracoHeight.PropertyEditorAlias,
value: mediaItem.metaData.umbracoHeight.Value
}
);
}
if (mediaItem.metaData.umbracoFile) {
// this is required for resolving files through the mediahelper
mediaItem.properties.push(
{
alias: "umbracoFile",
editor: mediaItem.metaData.umbracoFile.PropertyEditorAlias,
value: mediaItem.metaData.umbracoFile.Value
}
);
}
}
}
@@ -6,10 +6,14 @@
<div class='umb-modalcolumn-body'>
<ul class="umb-actions">
<li data-element="action-{{action.alias}}" ng-click="executeMenuItem(action)" class="umb-action" ng-class="{sep:action.separator, '-opens-dialog': action.opensDialog}" ng-repeat="action in menuActions">
<a class="umb-action-link" prevent-default>
<button class="umb-action-link btn-reset umb-outline" prevent-default umb-auto-focus ng-if="$index === 0">
<i class="icon icon-{{action.cssclass}}"></i>
<span class="menu-label">{{action.name}}</span>
</a>
</button>
<button class="umb-action-link btn-reset umb-outline" prevent-default ng-if="$index !== 0">
<i class="icon icon-{{action.cssclass}}"></i>
<span class="menu-label">{{action.name}}</span>
</button>
</li>
</ul>
</div>
@@ -15,7 +15,7 @@
</span>
</a>
<button ng-if="vm.type === 'button'" type="button" class="btn umb-button__button {{vm.style}} umb-button--{{vm.size}}" ng-click="vm.clickButton($event)" hotkey="{{vm.shortcut}}" hotkey-when-hidden="{{vm.shortcutWhenHidden}}" ng-disabled="vm.disabled">
<button ng-if="vm.type === 'button'" type="button" class="btn umb-button__button {{vm.style}} umb-button--{{vm.size}}" ng-click="vm.clickButton($event)" hotkey="{{vm.shortcut}}" hotkey-when-hidden="{{vm.shortcutWhenHidden}}" ng-disabled="vm.disabled" umb-auto-focus="{{vm.autoFocus && !vm.disabled ? 'true' : 'false'}}">
<span class="umb-button__content" ng-class="{'-hidden': vm.innerState !== 'init'}">
<i ng-if="vm.icon" class="{{vm.icon}} umb-button__icon"></i>
{{vm.buttonLabel}}
@@ -23,7 +23,7 @@
</span>
</button>
<button ng-if="vm.type === 'submit'" type="submit" class="btn umb-button__button {{vm.style}} umb-button--{{vm.size}}" hotkey="{{vm.shortcut}}" hotkey-when-hidden="{{vm.shortcutWhenHidden}}" ng-disabled="vm.disabled">
<button ng-if="vm.type === 'submit'" type="submit" class="btn umb-button__button {{vm.style}} umb-button--{{vm.size}}" hotkey="{{vm.shortcut}}" hotkey-when-hidden="{{vm.shortcutWhenHidden}}" ng-disabled="vm.disabled" umb-auto-focus="{{vm.autoFocus && !vm.disabled ? 'true' : 'false'}}">
<span class="umb-button__content" ng-class="{'-hidden': vm.innerState !== 'init'}">
<i ng-if="vm.icon" class="{{vm.icon}} umb-button__icon"></i>
{{vm.buttonLabel}}
@@ -50,7 +50,8 @@
label="Confirm"
type="button"
disabled="!directive.enableConfirmButton"
action="submitForm(model)">
action="submitForm(model)"
auto-focus="true">
</umb-button>
</div>
</div>
@@ -74,7 +75,8 @@
type="button"
disabled="model.disableSubmitButton"
action="submitForm(model)"
state="model.submitButtonState">
state="model.submitButtonState"
auto-focus="true">
</umb-button>
</div>
@@ -1,16 +1,20 @@
<li class="umb-tree-item" data-element="tree-item-{{::node.dataElement}}" ng-class="getNodeCssClass(node)" on-right-click="altSelect(node, $event)">
<div class="umb-tree-item__inner" ng-swipe-right="options(node, $event)" ng-dblclick="load(node)" >
<ins data-element="tree-item-expand"
<button data-element="tree-item-expand"
class="umb-tree-item__arrow umb-outline btn-reset"
ng-class="{'icon-navigation-right': !node.expanded || node.metaData.isContainer, 'icon-navigation-down': node.expanded && !node.metaData.isContainer}"
ng-style="{'visibility': (scope.enablelistviewexpand === 'true' || node.hasChildren && (!node.metaData.isContainer || isDialog)) ? 'visible' : 'hidden'}"
ng-click="load(node)">&nbsp;</ins>
ng-click="load(node)">&nbsp;
<!-- TODO: Use localization for this text -->
<span class="sr-only">Expand child items for {{node.name}}</span>
</button>
<i class="icon umb-tree-icon sprTree" ng-class="::node.cssClass" title="{{::node.title}}" ng-click="select(node, $event)" ng-style="::node.style"></i>
<span class="umb-tree-item__annotation"></span>
<a class="umb-tree-item__label umb-outline" ng-href="#/{{::node.routePath}}" ng-click="select(node, $event)" title="{{::node.title}}">{{node.name}}</a>
<!-- NOTE: These are the 'option' elipses -->
<a data-element="tree-item-options" class="umb-options" ng-click="options(node, $event)" ng-if="::node.menuUrl"><i></i><i></i><i></i></a>
<button data-element="tree-item-options" class="umb-options btn-reset sr-only sr-only--focusable sr-only--hoverable" ng-click="options(node, $event)" ng-if="::node.menuUrl"><i></i><i></i><i></i></button>
<div ng-show="node.loading" class="l"><div></div></div>
</div>
@@ -8,9 +8,9 @@
{{tree.name}}
</a>
</h5>
<a data-element="tree-item-options" class="umb-options" ng-hide="tree.root.isContainer || !tree.root.menuUrl" ng-click="options(tree.root, $event)" ng-swipe-right="options(tree.root, $event)">
<button data-element="tree-item-options" class="umb-options btn-reset sr-only sr-only--focusable sr-only--hoverable" ng-hide="tree.root.isContainer || !tree.root.menuUrl" ng-click="options(tree.root, $event)" ng-swipe-right="options(tree.root, $event)">
<i></i><i></i><i></i>
</a>
</button>
</div>
<umb-tree-item class="umb-animated"
ng-repeat="child in tree.root.children"
@@ -34,9 +34,9 @@
{{group.name}}
</a>
</h5>
<a data-element="tree-item-options" class="umb-options umb-outline" ng-hide="group.isContainer || !group.menuUrl" ng-click="options(group, $event)" ng-swipe-right="options(group, $event)">
<button data-element="tree-item-options" class="umb-options umb-outline btn-reset sr-only sr-only--focusable sr-only--hoverable" ng-hide="group.isContainer || !group.menuUrl" ng-click="options(group, $event)" ng-swipe-right="options(group, $event)">
<i></i><i></i><i></i>
</a>
</button>
</div>
<umb-tree-item class="umb-animated"
@@ -102,6 +102,7 @@
};
});
navigationService.syncTree({ tree: "content", path: $scope.currentNode.path, forceReload: true });
$scope.dialog.confirmDiscardChanges = true;
}, function (error) {
vm.error = error;
vm.buttonState = "error";
@@ -117,6 +118,7 @@
function toggle(group) {
group.selected = !group.selected;
$scope.dialog.confirmDiscardChanges = true;
}
function pickGroup() {
@@ -137,6 +139,7 @@
});
editorService.close();
navigationService.allowHideDialog(true);
$scope.dialog.confirmDiscardChanges = true;
},
close: function() {
editorService.close();
@@ -147,6 +150,7 @@
function removeGroup(group) {
vm.groups = _.reject(vm.groups, function(g) { return g.id === group.id });
$scope.dialog.confirmDiscardChanges = true;
}
function pickMember() {
@@ -186,6 +190,7 @@
$q.all(promises).then(function() {
vm.loading = false;
});
$scope.dialog.confirmDiscardChanges = true;
}
},
close: function () {
@@ -219,6 +224,7 @@
}
editorService.close();
navigationService.allowHideDialog(true);
$scope.dialog.confirmDiscardChanges = true;
},
close: function () {
editorService.close();
@@ -1,7 +1,7 @@
(function () {
"use strict";
function ContentRightsController($scope, $timeout, contentResource, localizationService, angularHelper, navigationService) {
function ContentRightsController($scope, $timeout, contentResource, localizationService, angularHelper, navigationService, overlayService) {
var vm = this;
var currentForm;
@@ -11,7 +11,6 @@
vm.removedUserGroups = [];
vm.viewState = "manageGroups";
vm.labels = {};
vm.showNotification = false;
vm.setViewSate = setViewSate;
vm.editPermissions = editPermissions;
@@ -20,7 +19,6 @@
vm.removePermissions = removePermissions;
vm.cancelManagePermissions = cancelManagePermissions;
vm.closeDialog = closeDialog;
vm.stay = stay;
vm.discardChanges = discardChanges;
function onInit() {
@@ -95,6 +93,7 @@
function setPermissions(group) {
assignGroupPermissions(group);
setViewSate("manageGroups");
$scope.dialog.confirmDiscardChanges = true;
}
/**
@@ -164,14 +163,31 @@
});
}
function stay() {
vm.showNotification = false;
}
function closeDialog() {
// check if form has been changed. If it has show discard changes notification
if (currentForm && currentForm.$dirty) {
vm.showNotification = true;
localizationService.localizeMany(["prompt_unsavedChanges", "prompt_unsavedChangesWarning", "prompt_discardChanges", "prompt_stay"]).then(
function(values) {
var overlay = {
"view": "default",
"title": values[0],
"content": values[1],
"disableBackdropClick": true,
"disableEscKey": true,
"submitButtonLabel": values[2],
"closeButtonLabel": values[3],
submit: function () {
overlayService.close();
navigationService.hideDialog();
},
close: function () {
overlayService.close();
}
};
overlayService.open(overlay);
}
);
} else {
navigationService.hideDialog();
}
@@ -187,4 +203,4 @@
angular.module("umbraco").controller("Umbraco.Editors.Content.RightsController", ContentRightsController);
})();
})();
@@ -1,5 +1,5 @@
<div ng-controller="Umbraco.Editors.Content.CreateController">
<div class="umb-dialog-body with-footer" ng-cloak>
<div class="umb-pane">
@@ -10,16 +10,16 @@
<p class="abstract" ng-if="!hasSettingsAccess"><localize key="create_noDocumentTypesWithNoSettingsAccess"/></p>
<div ng-if="hasSettingsAccess">
<p class="abstract"><localize key="create_noDocumentTypes" /></p>
<a class="btn" href="#settings/documentTypes/edit/{{contentTypeId}}?view=permissions" ng-click="close()">
<button class="btn umb-outline" href="#settings/documentTypes/edit/{{contentTypeId}}?view=permissions" ng-click="close()">
<localize key="create_noDocumentTypesEditPermissions"/>
</a>
</button>
</div>
</div>
<ul class="umb-actions umb-actions-child" ng-if="selectContentType && allowedTypes.length > 0">
<ul class="umb-actions umb-actions-child" ng-if="selectContentType && allowedTypes.length > 0" >
<li class="umb-action" data-element="action-create-{{docType.alias}}" ng-repeat="docType in allowedTypes | orderBy:'name':false">
<a class="umb-action-link" ng-click="createOrSelectBlueprintIfAny(docType)">
<button class="umb-action-link umb-outline btn-reset" ng-click="createOrSelectBlueprintIfAny(docType)" umb-auto-focus ng-if="$index === 0">
<i class="large icon {{docType.icon}}"></i>
<span class="menu-label">
{{docType.name}}
@@ -27,28 +27,37 @@
{{docType.description}}
</small>
</span>
</a>
</button>
<button class="umb-action-link umb-outline btn-reset" ng-click="createOrSelectBlueprintIfAny(docType)" ng-if="$index !== 0">
<i class="large icon {{docType.icon}}"></i>
<span class="menu-label">
{{docType.name}}
<small>
{{docType.description}}
</small>
</span>
</button>
</li>
</ul>
<ul class="umb-actions umb-actions-child" ng-if="selectBlueprint">
<li class="umb-action" ng-repeat="blueprint in selectableBlueprints | orderBy:'name':false">
<a class="umb-action-link" ng-click="createFromBlueprint(blueprint.id)">
<button class="umb-action-link umb-outline btn-reset" ng-click="createFromBlueprint(blueprint.id)">
<i class="large icon {{docType.icon}}"></i>
<span class="menu-label">
{{blueprint.name}}
</span>
</a>
</button>
</li>
<li class="umb-action sep" ng-show="allowBlank">
<a class="umb-action-link" ng-click="createBlank(docType)">
<button class="umb-action-link umb-outline btn-reset" ng-click="createBlank(docType)">
<i class="large icon {{docType.icon}}"></i>
<span class="menu-label">
<localize key="blueprints_blankBlueprint">Blank</localize>
</span>
</a>
</button>
</li>
</ul>
@@ -57,8 +66,8 @@
</div>
<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar">
<button class="btn btn-info" ng-click="closeDialog(true)">
<localize key="buttons_somethingElse">Do something else</localize>
<button class="btn btn-info umb-outline" ng-click="closeDialog(true)">
<localize key="buttons_somethingElse">All Actions</localize>
</button>
</div>
@@ -62,24 +62,6 @@
</umb-user-group-preview>
</div>
<div class="umb-notifications" style="bottom: 0;" ng-if="vm.showNotification">
<div class="umb-notification alert alert-block alert-form umb-notifications__notification animated -half-second fadeIn -no-border -extra-padding">
<h4 style="font-size: 16px;"><localize key="prompt_unsavedChanges"></localize></h4>
<p style="line-height: 1.6em; margin-bottom: 10px;"><localize key="prompt_unsavedChangesWarning"></localize></p>
<umb-button
label-key="prompt_discardChanges"
action="vm.discardChanges();"
type="button">
</umb-button>
<umb-button
label-key="prompt_stay"
action="vm.stay()"
type="button"
button-style="action">
</umb-button>
</div>
</div>
</form>
</div>
@@ -26,6 +26,8 @@
vm.buttonLabel = "";
vm.versionRegex = /^(\d+\.)(\d+\.)(\*|\d+)$/;
const packageId = $routeParams.id;
const create = $routeParams.create;
@@ -36,7 +36,7 @@
</umb-control-group>
<umb-control-group label="Version" required="true">
<input class="umb-property-editor" name="version" type="text" ng-model="vm.package.version" val-server-field="model.Version" required />
<input class="umb-property-editor" name="version" type="text" ng-model="vm.package.version" val-server-field="model.Version" required ng-pattern="vm.versionRegex" />
<span ng-messages="editPackageForm.version.$error" show-validation-on-submit >
<span class="help-inline" ng-message="required"><localize key="general_required">Required</localize></span>
@@ -54,7 +54,7 @@
</umb-control-group>-->
<umb-control-group label="Umbraco version">
<input class="umb-property-editor" name="umbracoVersion" type="text" ng-model="vm.package.umbracoVersion" val-server-field="model.umbracoVersion" />
<input class="umb-property-editor" name="umbracoVersion" type="text" ng-model="vm.package.umbracoVersion" val-server-field="model.umbracoVersion" ng-pattern="vm.versionRegex" />
<span ng-messages="editPackageForm.umbracoVersion.$error" show-validation-on-submit >
<span class="help-inline" ng-message="valServerField">{{editPackageForm.umbracoVersion.errorMsg}}</span>
@@ -14,6 +14,12 @@
*/
function contentPickerController($scope, entityResource, editorState, iconHelper, $routeParams, angularHelper, navigationService, $location, localizationService, editorService, $q) {
var vm = {
labels: {
general_recycleBin: ""
}
};
var unsubscribe;
function subscribe() {
@@ -408,7 +414,7 @@ function contentPickerController($scope, entityResource, editorState, iconHelper
angular.forEach($scope.renderModel, function (item) {
if (item.id === entity.id) {
if (entity.trashed) {
item.url = localizationService.dictionary.general_recycleBin;
item.url = vm.labels.general_recycleBin;
} else {
item.url = data;
}
@@ -466,12 +472,17 @@ function contentPickerController($scope, entityResource, editorState, iconHelper
}
function init() {
syncRenderModel(false).then(function () {
//everything is loaded, start the watch on the model
startWatch();
subscribe();
validate();
});
localizationService.localizeMany(["general_recycleBin"])
.then(function(data) {
vm.labels.general_recycleBin = data[0];
syncRenderModel(false).then(function () {
//everything is loaded, start the watch on the model
startWatch();
subscribe();
validate();
});
});
}
init();
@@ -920,11 +920,9 @@ angular.module("umbraco")
//Localize the grid editor names
angular.forEach($scope.availableEditors, function (value, key) {
//If no translation is provided, keep using the editor name from the manifest
if (localizationService.dictionary.hasOwnProperty("grid_" + value.alias)) {
localizationService.localize("grid_" + value.alias).then(function (v) {
value.name = v;
});
}
localizationService.localize("grid_" + value.alias, undefined, value.name).then(function (v) {
value.name = v;
});
});
$scope.contentReady = true;
@@ -3,6 +3,12 @@
angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerController",
function ($scope, entityResource, mediaHelper, $timeout, userService, localizationService, editorService) {
var vm = {
labels: {
mediaPicker_deletedItem: ""
}
}
//check the pre-values for multi-picker
var multiPicker = $scope.model.config.multiPicker && $scope.model.config.multiPicker !== '0' ? true : false;
var onlyImages = $scope.model.config.onlyImages && $scope.model.config.onlyImages !== '0' ? true : false;
@@ -51,7 +57,7 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl
return found;
} else {
return {
name: localizationService.dictionary.mediaPicker_deletedItem,
name: vm.labels.mediaPicker_deletedItem,
id: $scope.model.config.idType !== "udi" ? id : null,
udi: $scope.model.config.idType === "udi" ? id : null,
icon: "icon-picture",
@@ -107,9 +113,13 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl
function init() {
userService.getCurrentUser().then(function (userData) {
localizationService.localizeMany(["mediaPicker_deletedItem"])
.then(function(data) {
vm.labels.mediaPicker_deletedItem = data[0];
if (!$scope.model.config.startNodeId) {
userService.getCurrentUser().then(function (userData) {
if (!$scope.model.config.startNodeId) {
if ($scope.model.config.ignoreUserStartNodes === true) {
$scope.model.config.startNodeId = -1;
$scope.model.config.startNodeIsVirtual = true;
@@ -120,22 +130,22 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl
}
}
// only allow users to add and edit media if they have access to the media section
var hasAccessToMedia = userData.allowedSections.indexOf("media") !== -1;
$scope.allowEditMedia = hasAccessToMedia;
$scope.allowAddMedia = hasAccessToMedia;
// only allow users to add and edit media if they have access to the media section
var hasAccessToMedia = userData.allowedSections.indexOf("media") !== -1;
$scope.allowEditMedia = hasAccessToMedia;
$scope.allowAddMedia = hasAccessToMedia;
setupViewModel();
setupViewModel();
//When the model value changes sync the view model
$scope.$watch("model.value",
function (newVal, oldVal) {
if (newVal !== oldVal) {
setupViewModel();
}
//When the model value changes sync the view model
$scope.$watch("model.value",
function (newVal, oldVal) {
if (newVal !== oldVal) {
setupViewModel();
}
});
});
});
});
}
$scope.remove = function (index) {
@@ -1,5 +1,11 @@
function multiUrlPickerController($scope, angularHelper, localizationService, entityResource, iconHelper, editorService) {
var vm = {
labels: {
general_recycleBin: ""
}
};
$scope.renderModel = [];
if ($scope.preview) {
@@ -104,7 +110,7 @@ function multiUrlPickerController($scope, angularHelper, localizationService, en
link.published = (data.metaData && data.metaData.IsPublished === false && entityType === "Document") ? false : true;
link.trashed = data.trashed;
if (link.trashed) {
item.url = localizationService.dictionary.general_recycleBin;
item.url = vm.labels.general_recycleBin;
}
});
} else {
@@ -122,6 +128,15 @@ function multiUrlPickerController($scope, angularHelper, localizationService, en
};
editorService.linkPicker(linkPicker);
};
function init() {
localizationService.localizeMany(["general_recycleBin"])
.then(function (data) {
vm.labels.general_recycleBin = data[0];
});
}
init();
}
angular.module("umbraco").controller("Umbraco.PropertyEditors.MultiUrlPickerController", multiUrlPickerController);
@@ -93,8 +93,9 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
"iconHelper",
"clipboardService",
"eventsService",
function ($scope, $interpolate, $filter, $timeout, contentResource, localizationService, iconHelper, clipboardService, eventsService) {
"overlayService",
function ($scope, $interpolate, $filter, $timeout, contentResource, localizationService, iconHelper, clipboardService, eventsService, overlayService) {
var contentTypeAliases = [];
_.each($scope.model.config.contentTypes, function (contentType) {
@@ -239,10 +240,23 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
};
$scope.requestDeleteNode = function (idx) {
if ($scope.model.config.confirmDeletes === true) {
localizationService.localize("content_nestedContentDeleteItem").then(function (value) {
if (confirm(value)) {
$scope.deleteNode(idx);
}
localizationService.localizeMany(["content_nestedContentDeleteItem", "general_delete", "general_cancel", "contentTypeEditor_yesDelete"]).then(function (data) {
const overlay = {
title: data[1],
content: data[0],
closeButtonLabel: data[2],
submitButtonLabel: data[3],
submitButtonStyle: "danger",
close: function () {
overlayService.close();
},
submit: function () {
$scope.deleteNode(idx);
overlayService.close();
}
};
overlayService.open(overlay);
});
} else {
$scope.deleteNode(idx);
@@ -14,13 +14,7 @@
function ReadOnlyValueController($rootScope, $scope, $filter) {
function formatDisplayValue() {
if ($scope.model.config &&
angular.isArray($scope.model.config) &&
$scope.model.config.length > 0 &&
$scope.model.config[0] &&
$scope.model.config.filter) {
if ($scope.model.config && $scope.model.config.filter) {
if ($scope.model.config.format) {
$scope.displayvalue = $filter($scope.model.config.filter)($scope.model.value, $scope.model.config.format);
} else {
@@ -29,12 +23,11 @@ function ReadOnlyValueController($rootScope, $scope, $filter) {
} else {
$scope.displayvalue = $scope.model.value;
}
}
//format the display value on init:
formatDisplayValue();
$scope.$watch("model.value", function (newVal, oldVal) {
//cannot just check for !newVal because it might be an empty string which we
//want to look for.
@@ -45,4 +38,4 @@ function ReadOnlyValueController($rootScope, $scope, $filter) {
});
}
angular.module('umbraco').controller("Umbraco.PropertyEditors.ReadOnlyValueController", ReadOnlyValueController);
angular.module('umbraco').controller("Umbraco.PropertyEditors.ReadOnlyValueController", ReadOnlyValueController);
@@ -71,12 +71,10 @@
sections="userGroup.sections"
content-start-node="userGroup.contentStartNode"
media-start-node="userGroup.mediaStartNode"
allow-remove="!model.user.isCurrentUser"
on-remove="model.removeSelectedItem($index, model.user.userGroups)">
</umb-user-group-preview>
<a href=""
ng-if="!model.user.isCurrentUser"
style="max-width: 100%;"
class="umb-node-preview-add"
ng-click="model.openUserGroupPicker()"
@@ -92,7 +90,6 @@
ng-repeat="node in model.user.startContentIds"
icon="node.icon"
name="node.name"
allow-remove="!model.user.isCurrentUser"
on-remove="model.removeSelectedItem($index, model.user.startContentIds)">
</umb-node-preview>
@@ -102,7 +99,6 @@
</umb-node-preview>
<a href=""
ng-if="!model.user.isCurrentUser"
class="umb-node-preview-add"
id="content-start-add"
ng-click="model.openContentPicker()"
@@ -118,7 +114,6 @@
ng-repeat="node in model.user.startMediaIds"
icon="node.icon"
name="node.name"
allow-remove="!model.user.isCurrentUser"
on-remove="model.removeSelectedItem($index, model.user.startMediaIds)">
</umb-node-preview>
@@ -128,7 +123,6 @@
</umb-node-preview>
<a href=""
ng-if="!model.user.isCurrentUser"
class="umb-node-preview-add"
ng-click="model.openMediaPicker()"
id="media-start-add"
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Models.ContentEditing;
using Umbraco.Core.Models.Membership;
@@ -23,7 +24,7 @@ namespace Umbraco.Web.ContentApps
{
Alias = "umbContent",
Name = "Content",
Icon = "icon-document",
Icon = Constants.Icons.Content,
View = "views/content/apps/content/content.html",
Weight = Weight
});
@@ -36,7 +37,7 @@ namespace Umbraco.Web.ContentApps
{
Alias = "umbContent",
Name = "Content",
Icon = "icon-document",
Icon = Constants.Icons.Content,
View = "views/media/apps/content/content.html",
Weight = Weight
});
@@ -170,12 +170,26 @@ namespace Umbraco.Web.Editors
: CultureInfo.GetCultureInfo(GlobalSettings.DefaultUILanguage)
: CultureInfo.GetCultureInfo(culture);
var textForCulture = Services.TextService.GetAllStoredValues(cultureInfo)
//the dictionary returned is fine but the delimiter between an 'area' and a 'value' is a '/' but the javascript
// in the back office requires the delimiter to be a '_' so we'll just replace it
.ToDictionary(key => key.Key.Replace("/", "_"), val => val.Value);
var allValues = Services.TextService.GetAllStoredValues(cultureInfo);
var pathedValues = allValues.Select(kv =>
{
var slashIndex = kv.Key.IndexOf('/');
var areaAlias = kv.Key.Substring(0, slashIndex);
var valueAlias = kv.Key.Substring(slashIndex+1);
return new
{
areaAlias,
valueAlias,
value = kv.Value
};
});
return new JsonNetResult { Data = textForCulture, Formatting = Formatting.Indented };
Dictionary<string, Dictionary<string, string>> nestedDictionary = pathedValues
.GroupBy(pv => pv.areaAlias)
.ToDictionary(pv => pv.Key, pv =>
pv.ToDictionary(pve => pve.valueAlias, pve => pve.value));
return new JsonNetResult { Data = nestedDictionary, Formatting = Formatting.Indented };
}
/// <summary>
@@ -373,7 +373,7 @@ namespace Umbraco.Web.Editors
else
ct = new ContentType(parentId);
ct.Icon = "icon-document";
ct.Icon = Constants.Icons.Content;
var dto = Mapper.Map<IContentType, DocumentTypeDisplay>(ct);
return dto;
@@ -135,7 +135,10 @@ namespace Umbraco.Web.Editors
}
public MediaTypeDisplay GetEmpty(int parentId)
{
var ct = new MediaType(parentId) {Icon = "icon-picture"};
var ct = new MediaType(parentId)
{
Icon = Constants.Icons.MediaImage
};
var dto = Mapper.Map<IMediaType, MediaTypeDisplay>(ct);
return dto;
@@ -102,7 +102,7 @@ namespace Umbraco.Web.Editors
public MemberTypeDisplay GetEmpty()
{
var ct = new MemberType(-1);
ct.Icon = "icon-user";
ct.Icon = Constants.Icons.Member;
var dto = Mapper.Map<IMemberType, MemberTypeDisplay>(ct);
return dto;
@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Umbraco.Web.Media.EmbedProviders
{
/// <summary>
/// Embed Provider for Giphy.com the popular online GIFs and animated sticker provider.
/// </summary>
public class Giphy : EmbedProviderBase
{
public override string ApiEndpoint => "https://giphy.com/services/oembed?url=";
public override string[] UrlSchemeRegex => new string[]
{
@"giphy\.com/*",
@"gph\.is/*"
};
public override Dictionary<string, string> RequestParams => new Dictionary<string, string>();
public override string GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
{
var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
var oembed = base.GetJsonResponse<OEmbedResponse>(requestUrl);
return oembed.GetHtml();
}
}
}
@@ -43,7 +43,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;
if (source is IContentEntitySlim contentSlim)
source.AdditionalData["ContentTypeAlias"] = contentSlim.ContentTypeAlias;
@@ -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]";
@@ -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;
@@ -128,7 +128,7 @@ namespace Umbraco.Web.Models.Mapping
{
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;
@@ -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";
@@ -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)
@@ -174,7 +174,12 @@ namespace Umbraco.Web.PropertyEditors
// more magic here ;-(
var configuration = dataTypeService.GetDataType(propertyType.DataTypeId).ConfigurationAs<ImageCropperConfiguration>();
var crops = configuration?.Crops ?? Array.Empty<ImageCropperConfiguration.Crop>();
return "{src: '" + val + "', crops: " + crops + "}";
return JsonConvert.SerializeObject(new
{
src = val,
crops = crops
});
}
}
}
@@ -8,7 +8,7 @@ namespace Umbraco.Web.PropertyEditors
/// <summary>
/// Represents a list-view editor.
/// </summary>
[DataEditor(Constants.PropertyEditors.Aliases.ListView, "List view", "listview", HideLabel = true, Group = "lists", Icon = "icon-item-arrangement")]
[DataEditor(Constants.PropertyEditors.Aliases.ListView, "List view", "listview", HideLabel = true, Group = "lists", Icon = Constants.Icons.ListView)]
public class ListViewPropertyEditor : DataEditor
{
/// <summary>
@@ -5,7 +5,7 @@ using Umbraco.Core.PropertyEditors;
namespace Umbraco.Web.PropertyEditors
{
// TODO: MacroContainerPropertyEditor is deprecated, but what's the alternative?
[DataEditor(Constants.PropertyEditors.Aliases.MacroContainer, "(Obsolete) Macro Picker", "macrocontainer", ValueType = ValueTypes.Text, Group="rich content", Icon="icon-settings-alt", IsDeprecated = true)]
[DataEditor(Constants.PropertyEditors.Aliases.MacroContainer, "(Obsolete) Macro Picker", "macrocontainer", ValueType = ValueTypes.Text, Group = "rich content", Icon = Constants.Icons.Macro, IsDeprecated = true)]
public class MacroContainerPropertyEditor : DataEditor
{
public MacroContainerPropertyEditor(ILogger logger)
@@ -8,7 +8,7 @@ namespace Umbraco.Web.PropertyEditors
/// Represents a media picker property editor.
/// </summary>
[DataEditor(Constants.PropertyEditors.Aliases.MediaPicker, EditorType.PropertyValue | EditorType.MacroParameter,
"Media Picker", "mediapicker", ValueType = ValueTypes.Text, Group = "media", Icon = "icon-picture")]
"Media Picker", "mediapicker", ValueType = ValueTypes.Text, Group = "media", Icon = Constants.Icons.MediaImage)]
public class MediaPickerPropertyEditor : DataEditor
{
/// <summary>
@@ -4,7 +4,7 @@ using Umbraco.Core.PropertyEditors;
namespace Umbraco.Web.PropertyEditors
{
[DataEditor(Constants.PropertyEditors.Aliases.MemberGroupPicker, "Member Group Picker", "membergrouppicker", ValueType = ValueTypes.Text, Group = "People", Icon = "icon-users")]
[DataEditor(Constants.PropertyEditors.Aliases.MemberGroupPicker, "Member Group Picker", "membergrouppicker", ValueType = ValueTypes.Text, Group = "People", Icon = Constants.Icons.MemberGroup)]
public class MemberGroupPickerPropertyEditor : DataEditor
{
public MemberGroupPickerPropertyEditor(ILogger logger)
@@ -4,7 +4,7 @@ using Umbraco.Core.PropertyEditors;
namespace Umbraco.Web.PropertyEditors
{
[DataEditor(Constants.PropertyEditors.Aliases.MemberPicker, "Member Picker", "memberpicker", ValueType = ValueTypes.String, Group = "People", Icon = "icon-user")]
[DataEditor(Constants.PropertyEditors.Aliases.MemberPicker, "Member Picker", "memberpicker", ValueType = ValueTypes.String, Group = "People", Icon = Constants.Icons.Member)]
public class MemberPickerPropertyEditor : DataEditor
{
public MemberPickerPropertyEditor(ILogger logger)
@@ -6,7 +6,7 @@ using Umbraco.Core.PropertyEditors;
namespace Umbraco.Web.PropertyEditors
{
[DataEditor(Constants.PropertyEditors.Aliases.UserPicker, "User picker", "entitypicker", ValueType = ValueTypes.Integer, Group = "People", Icon = "icon-user")]
[DataEditor(Constants.PropertyEditors.Aliases.UserPicker, "User picker", "entitypicker", ValueType = ValueTypes.Integer, Group = "People", Icon = Constants.Icons.User)]
public class UserPickerPropertyEditor : DataEditor
{
public UserPickerPropertyEditor(ILogger logger)
@@ -261,10 +261,22 @@ namespace Umbraco.Web.PublishedCache.NuCache
if (culture == null)
culture = _variationContextAccessor?.VariationContext?.Culture ?? "";
// _snapshot.GetAtRoot() returns all ContentNode at root
// both .Draft and .Published cannot be null at the same time
// root is already sorted by sortOrder, and does not contain nulls
var atRoot = _snapshot.GetAtRoot().Select(n => GetNodePublishedContent(n, preview));
return culture == "*" ? atRoot : atRoot.Where(x => x.IsInvariantOrHasCulture(culture));
//
// GetNodePublishedContent may return null if !preview and there is no
// published model, so we need to filter these nulls out
var atRoot = _snapshot.GetAtRoot()
.Select(n => GetNodePublishedContent(n, preview))
.WhereNotNull();
// if a culture is specified, we must ensure that it is avail/published
if (culture != "*")
atRoot = atRoot.Where(x => x.IsInvariantOrHasCulture(culture));
return atRoot;
}
private static IPublishedContent GetNodePublishedContent(ContentNode node, bool preview)
@@ -264,7 +264,9 @@ namespace Umbraco.Web.Runtime
.Append<Ted>()
.Append<Soundcloud>()
.Append<Issuu>()
.Append<Hulu>();
.Append<Hulu>()
.Append<Giphy>();
// replace with web implementation
composition.RegisterUnique<IPublishedSnapshotRebuilder, Migrations.PostMigrations.PublishedSnapshotRebuilder>();
@@ -357,9 +357,9 @@ namespace Umbraco.Web.Search
var m = _mapper.Map<SearchResultEntity>(result);
//if no icon could be mapped, it will be set to document, so change it to picture
if (m.Icon == "icon-document")
if (m.Icon == Constants.Icons.DefaultIcon)
{
m.Icon = "icon-user";
m.Icon = Constants.Icons.Member;
}
if (result.Values.ContainsKey("email") && result.Values["email"] != null)
@@ -390,9 +390,9 @@ namespace Umbraco.Web.Search
{
var m = _mapper.Map<SearchResultEntity>(result);
//if no icon could be mapped, it will be set to document, so change it to picture
if (m.Icon == "icon-document")
if (m.Icon == Constants.Icons.DefaultIcon)
{
m.Icon = "icon-picture";
m.Icon = Constants.Icons.MediaImage;
}
yield return m;
}
@@ -59,7 +59,7 @@ namespace Umbraco.Web.Trees
nodes.AddRange(docTypeEntities
.Select(entity =>
{
var treeNode = CreateTreeNode(entity, Constants.ObjectTypes.DocumentBlueprint, id, queryStrings, "icon-item-arrangement", true);
var treeNode = CreateTreeNode(entity, Constants.ObjectTypes.DocumentBlueprint, id, queryStrings, Constants.Icons.ContentType, true);
treeNode.Path = $"-1,{entity.Id}";
treeNode.NodeType = "document-type-blueprints";
// TODO: This isn't the best way to ensure a no operation process for clicking a node but it works for now.
@@ -443,18 +443,7 @@ namespace Umbraco.Web.Trees
internal IEnumerable<MenuItem> GetAllowedUserMenuItemsForNode(IUmbracoEntity dd)
{
var permission = Services.UserService.GetPermissions(Security.CurrentUser, dd.Path);
// TODO: inject
var actions = Current.Actions.FromEntityPermission(permission)
.ToList();
var actionDelete = Current.Actions.GetAction<ActionDelete>();
// A user is allowed to delete their own stuff
var tryGetCurrentUserId = Security.GetUserId();
if (tryGetCurrentUserId && dd.CreatorId == tryGetCurrentUserId.Result && actions.Contains(actionDelete) == false)
actions.Add(actionDelete);
return actions.Select(x => new MenuItem(x));
return Current.Actions.FromEntityPermission(permission).Select(x => new MenuItem(x));
}
/// <summary>
@@ -57,7 +57,7 @@ namespace Umbraco.Web.Trees
// since 7.4+ child type creation is enabled by a config option. It defaults to on, but can be disabled if we decide to.
// need this check to keep supporting sites where children have already been created.
var hasChildren = dt.HasChildren;
var node = CreateTreeNode(dt, Constants.ObjectTypes.DocumentType, id, queryStrings, "icon-item-arrangement", hasChildren);
var node = CreateTreeNode(dt, Constants.ObjectTypes.DocumentType, id, queryStrings, Constants.Icons.ContentType, hasChildren);
node.Path = dt.Path;
return node;
@@ -53,11 +53,11 @@ namespace Umbraco.Web.Trees
.OrderBy(entity => entity.Name)
.Select(dt =>
{
var node = CreateTreeNode(dt.Id.ToInvariantString(), id, queryStrings, dt.Name, "icon-autofill", false);
var node = CreateTreeNode(dt.Id.ToInvariantString(), id, queryStrings, dt.Name, Constants.Icons.DataType, false);
node.Path = dt.Path;
if (systemListViewDataTypeIds.Contains(dt.Id))
{
node.Icon = "icon-thumbnail-list";
node.Icon = Constants.Icons.ListView;
}
return node;
}));
@@ -72,7 +72,15 @@ namespace Umbraco.Web.Trees
{
var systemIds = new[]
{
Constants.System.DefaultLabelDataTypeId
Constants.DataTypes.Boolean, // Used by the Member Type: "Member"
Constants.DataTypes.Textarea, // Used by the Member Type: "Member"
Constants.DataTypes.LabelBigint, // Used by the Media Type: "Image"; Used by the Media Type: "File"
Constants.DataTypes.LabelDateTime, // Used by the Member Type: "Member"
Constants.DataTypes.LabelDecimal, // Used by the Member Type: "Member"
Constants.DataTypes.LabelInt, // Used by the Media Type: "Image"; Used by the Member Type: "Member"
Constants.DataTypes.LabelString, // Used by the Media Type: "Image"; Used by the Media Type: "File"
Constants.DataTypes.ImageCropper, // Used by the Media Type: "Image"
Constants.DataTypes.Upload, // Used by the Media Type: "File"
};
return systemIds.Concat(GetNonDeletableSystemListViewDataTypeIds());
+1 -1
View File
@@ -14,6 +14,6 @@ namespace Umbraco.Web.Trees
protected override string[] Extensions => ExtensionsStatic;
protected override string FileIcon => "icon-document";
protected override string FileIcon => Constants.Icons.MediaFile;
}
}
@@ -36,7 +36,7 @@ namespace Umbraco.Web.Trees
id,
queryStrings,
macro.Name,
"icon-settings-alt",
Constants.Icons.Macro,
false));
}
}

Some files were not shown because too many files have changed in this diff Show More