diff --git a/src/Umbraco.Abstractions/Collections/DeepCloneableList.cs b/src/Umbraco.Abstractions/Collections/DeepCloneableList.cs index a21c7aae56..cc57b96f1b 100644 --- a/src/Umbraco.Abstractions/Collections/DeepCloneableList.cs +++ b/src/Umbraco.Abstractions/Collections/DeepCloneableList.cs @@ -47,8 +47,7 @@ namespace Umbraco.Core.Collections var newList = new DeepCloneableList(ListCloneBehavior.None); foreach (var item in this) { - var dc = item as IDeepCloneable; - if (dc != null) + if (item is IDeepCloneable dc) { newList.Add((T)dc.DeepClone()); } @@ -66,8 +65,7 @@ namespace Umbraco.Core.Collections var newList2 = new DeepCloneableList(ListCloneBehavior.Always); foreach (var item in this) { - var dc = item as IDeepCloneable; - if (dc != null) + if (item is IDeepCloneable dc) { newList2.Add((T)dc.DeepClone()); } @@ -121,6 +119,16 @@ namespace Umbraco.Core.Collections } } + public void DisableChangeTracking() + { + // noop + } + + public void EnableChangeTracking() + { + // noop + } + public void ResetWereDirtyProperties() { foreach (var dc in this.OfType()) diff --git a/src/Umbraco.Abstractions/Configuration/IGlobalSettings.cs b/src/Umbraco.Abstractions/Configuration/IGlobalSettings.cs index b96434c30c..48371bd11b 100644 --- a/src/Umbraco.Abstractions/Configuration/IGlobalSettings.cs +++ b/src/Umbraco.Abstractions/Configuration/IGlobalSettings.cs @@ -1,7 +1,7 @@ namespace Umbraco.Core.Configuration { /// - /// Contains general settings information for the entire Umbraco instance based on information from web.config appsettings + /// Contains general settings information for the entire Umbraco instance based on information from web.config appsettings /// public interface IGlobalSettings { @@ -21,7 +21,7 @@ /// Gets the path to umbraco's root directory (/umbraco by default). /// string Path { get; } - + /// /// Gets or sets the configuration status. This will return the version number of the currently installed umbraco instance. /// @@ -67,5 +67,10 @@ /// Gets the location of temporary files. /// string LocalTempPath { get; } + + string UmbracoPath { get; } + string UmbracoCssPath { get; } + string UmbracoScriptsPath { get; } + string UmbracoMediaPath { get; } } } diff --git a/src/Umbraco.Abstractions/Constants-AppSettings.cs b/src/Umbraco.Abstractions/Constants-AppSettings.cs index 509be46b61..beaffef5b4 100644 --- a/src/Umbraco.Abstractions/Constants-AppSettings.cs +++ b/src/Umbraco.Abstractions/Constants-AppSettings.cs @@ -46,6 +46,26 @@ namespace Umbraco.Core /// public const string ReservedUrls = "Umbraco.Core.ReservedUrls"; + /// + /// The path of backoffice. + /// + public const string UmbracoPath = "umbracoPath"; + + /// + /// The path of the stylesheet folder. + /// + public const string UmbracoCssPath = "umbracoCssPath"; + + /// + /// The path of script folder. + /// + public const string UmbracoScriptsPath = "umbracoScriptsPath"; + + /// + /// The path of media folder. + /// + public const string UmbracoMediaPath = "umbracoMediaPath"; + /// /// The reserved paths from web.config /// diff --git a/src/Umbraco.Abstractions/Constants-SystemDirectories.cs b/src/Umbraco.Abstractions/Constants-SystemDirectories.cs new file mode 100644 index 0000000000..e33247be63 --- /dev/null +++ b/src/Umbraco.Abstractions/Constants-SystemDirectories.cs @@ -0,0 +1,36 @@ +namespace Umbraco.Core +{ + public static partial class Constants + { + public static class SystemDirectories + { + public const string Bin = "~/bin"; + + public const string Config = "~/config"; + + public const string Data = "~/App_Data"; + + public const string TempData = Data + "/TEMP"; + + public const string TempFileUploads = TempData + "/FileUploads"; + + public const string TempImageUploads = TempFileUploads + "/rte"; + + public const string Install = "~/install"; + + public const string AppCode = "~/App_Code"; + + public const string AppPlugins = "~/App_Plugins"; + + public const string MvcViews = "~/Views"; + + public const string PartialViews = MvcViews + "/Partials/"; + + public const string MacroPartials = MvcViews + "/MacroPartials/"; + + public const string Packages = Data + "/packages"; + + public const string Preview = Data + "/preview"; + } + } +} diff --git a/src/Umbraco.Abstractions/IO/IIOHelper.cs b/src/Umbraco.Abstractions/IO/IIOHelper.cs index c66e6137be..735aed4813 100644 --- a/src/Umbraco.Abstractions/IO/IIOHelper.cs +++ b/src/Umbraco.Abstractions/IO/IIOHelper.cs @@ -5,7 +5,7 @@ namespace Umbraco.Core.IO public interface IIOHelper { bool ForceNotHosted { get; set; } - + /// /// Gets a value indicating whether Umbraco is hosted. /// @@ -18,8 +18,6 @@ namespace Umbraco.Core.IO Attempt TryResolveUrl(string virtualPath); string MapPath(string path, bool useHttpContext); string MapPath(string path); - string ReturnPath(string settingsKey, string standardPath, bool useTilde); - string ReturnPath(string settingsKey, string standardPath); /// /// Verifies that the current filepath matches a directory where the user is allowed to edit a file. @@ -80,5 +78,14 @@ namespace Umbraco.Core.IO /// /// string GetRelativePath(string path); + + /// + /// Gets the root path of the application + /// + string Root + { + get; + set; //Only required for unit tests + } } } diff --git a/src/Umbraco.Core/Manifest/IManifestFilter.cs b/src/Umbraco.Abstractions/Manifest/IManifestFilter.cs similarity index 99% rename from src/Umbraco.Core/Manifest/IManifestFilter.cs rename to src/Umbraco.Abstractions/Manifest/IManifestFilter.cs index 505f13d385..88e00a3966 100644 --- a/src/Umbraco.Core/Manifest/IManifestFilter.cs +++ b/src/Umbraco.Abstractions/Manifest/IManifestFilter.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; + namespace Umbraco.Core.Manifest { /// diff --git a/src/Umbraco.Abstractions/Manifest/IManifestParser.cs b/src/Umbraco.Abstractions/Manifest/IManifestParser.cs new file mode 100644 index 0000000000..eeb0c756f6 --- /dev/null +++ b/src/Umbraco.Abstractions/Manifest/IManifestParser.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using Umbraco.Core.PropertyEditors; + +namespace Umbraco.Core.Manifest +{ + public interface IManifestParser + { + string Path { get; set; } + + /// + /// Gets all manifests, merged into a single manifest object. + /// + /// + PackageManifest Manifest { get; } + + /// + /// Parses a manifest. + /// + PackageManifest ParseManifest(string text); + + IEnumerable ParseGridEditors(string text); + } +} diff --git a/src/Umbraco.Core/Manifest/ManifestContentAppDefinition.cs b/src/Umbraco.Abstractions/Manifest/ManifestContentAppDefinition.cs similarity index 92% rename from src/Umbraco.Core/Manifest/ManifestContentAppDefinition.cs rename to src/Umbraco.Abstractions/Manifest/ManifestContentAppDefinition.cs index 2aafcd8b74..35293a6377 100644 --- a/src/Umbraco.Core/Manifest/ManifestContentAppDefinition.cs +++ b/src/Umbraco.Abstractions/Manifest/ManifestContentAppDefinition.cs @@ -1,7 +1,5 @@ using System; using System.Runtime.Serialization; -using Umbraco.Core.Composing; -using Umbraco.Core.IO; namespace Umbraco.Core.Manifest { @@ -65,11 +63,7 @@ namespace Umbraco.Core.Manifest /// Gets or sets the view for rendering the content app. /// [DataMember(Name = "view")] - public string View - { - get => _view; - set => _view = Current.IOHelper.ResolveVirtualUrl(value); - } + public string View { get; set; } /// /// Gets or sets the list of 'show' conditions for the content app. diff --git a/src/Umbraco.Abstractions/Manifest/ManifestDashboard.cs b/src/Umbraco.Abstractions/Manifest/ManifestDashboard.cs new file mode 100644 index 0000000000..2d6f96b5c2 --- /dev/null +++ b/src/Umbraco.Abstractions/Manifest/ManifestDashboard.cs @@ -0,0 +1,26 @@ +using System; +using System.ComponentModel; +using System.Runtime.Serialization; +using Umbraco.Core.Dashboards; + +namespace Umbraco.Core.Manifest +{ + [DataContract] + public class ManifestDashboard : IDashboard + { + [DataMember(Name = "alias", IsRequired = true)] + public string Alias { get; set; } + + [DataMember(Name = "weight")] + public int Weight { get; set; } = 100; + + [DataMember(Name = "view", IsRequired = true)] + public string View { get; set; } + + [DataMember(Name = "sections")] + public string[] Sections { get; set; } = Array.Empty(); + + [DataMember(Name = "access")] + public IAccessRule[] AccessRules { get; set; } = Array.Empty(); + } +} diff --git a/src/Umbraco.Core/Manifest/ManifestFilterCollection.cs b/src/Umbraco.Abstractions/Manifest/ManifestFilterCollection.cs similarity index 100% rename from src/Umbraco.Core/Manifest/ManifestFilterCollection.cs rename to src/Umbraco.Abstractions/Manifest/ManifestFilterCollection.cs diff --git a/src/Umbraco.Core/Manifest/ManifestFilterCollectionBuilder.cs b/src/Umbraco.Abstractions/Manifest/ManifestFilterCollectionBuilder.cs similarity index 100% rename from src/Umbraco.Core/Manifest/ManifestFilterCollectionBuilder.cs rename to src/Umbraco.Abstractions/Manifest/ManifestFilterCollectionBuilder.cs diff --git a/src/Umbraco.Core/Manifest/ManifestSection.cs b/src/Umbraco.Abstractions/Manifest/ManifestSection.cs similarity index 100% rename from src/Umbraco.Core/Manifest/ManifestSection.cs rename to src/Umbraco.Abstractions/Manifest/ManifestSection.cs diff --git a/src/Umbraco.Core/Manifest/PackageManifest.cs b/src/Umbraco.Abstractions/Manifest/PackageManifest.cs similarity index 83% rename from src/Umbraco.Core/Manifest/PackageManifest.cs rename to src/Umbraco.Abstractions/Manifest/PackageManifest.cs index e50eb69467..5e10030693 100644 --- a/src/Umbraco.Core/Manifest/PackageManifest.cs +++ b/src/Umbraco.Abstractions/Manifest/PackageManifest.cs @@ -1,70 +1,71 @@ -using System; -using Newtonsoft.Json; -using Umbraco.Core.PropertyEditors; - -namespace Umbraco.Core.Manifest -{ - /// - /// Represents the content of a package manifest. - /// - public class PackageManifest - { - /// - /// Gets the source path of the manifest. - /// - /// - /// Gets the full absolute file path of the manifest, - /// using system directory separators. - /// - [JsonIgnore] - public string Source { get; set; } - - /// - /// Gets or sets the scripts listed in the manifest. - /// - [JsonProperty("javascript")] - public string[] Scripts { get; set; } = Array.Empty(); - - /// - /// Gets or sets the stylesheets listed in the manifest. - /// - [JsonProperty("css")] - public string[] Stylesheets { get; set; } = Array.Empty(); - - /// - /// Gets or sets the property editors listed in the manifest. - /// - [JsonProperty("propertyEditors")] - public IDataEditor[] PropertyEditors { get; set; } = Array.Empty(); - - /// - /// Gets or sets the parameter editors listed in the manifest. - /// - [JsonProperty("parameterEditors")] - public IDataEditor[] ParameterEditors { get; set; } = Array.Empty(); - - /// - /// Gets or sets the grid editors listed in the manifest. - /// - [JsonProperty("gridEditors")] - public GridEditor[] GridEditors { get; set; } = Array.Empty(); - - /// - /// Gets or sets the content apps listed in the manifest. - /// - [JsonProperty("contentApps")] - public ManifestContentAppDefinition[] ContentApps { get; set; } = Array.Empty(); - - /// - /// Gets or sets the dashboards listed in the manifest. - /// - [JsonProperty("dashboards")] - public ManifestDashboard[] Dashboards { get; set; } = Array.Empty(); - - /// - /// Gets or sets the sections listed in the manifest. - /// - [JsonProperty("sections")] - public ManifestSection[] Sections { get; set; } = Array.Empty(); - } -} +using System; +using System.Runtime.Serialization; +using Umbraco.Core.PropertyEditors; + +namespace Umbraco.Core.Manifest +{ + /// + /// Represents the content of a package manifest. + /// + [DataContract] + public class PackageManifest + { + /// + /// Gets the source path of the manifest. + /// + /// + /// Gets the full absolute file path of the manifest, + /// using system directory separators. + /// + [IgnoreDataMember] + public string Source { get; set; } + + /// + /// Gets or sets the scripts listed in the manifest. + /// + [DataMember(Name = "javascript")] + public string[] Scripts { get; set; } = Array.Empty(); + + /// + /// Gets or sets the stylesheets listed in the manifest. + /// + [DataMember(Name = "css")] + public string[] Stylesheets { get; set; } = Array.Empty(); + + /// + /// Gets or sets the property editors listed in the manifest. + /// + [DataMember(Name = "propertyEditors")] + public IDataEditor[] PropertyEditors { get; set; } = Array.Empty(); + + /// + /// Gets or sets the parameter editors listed in the manifest. + /// + [DataMember(Name = "parameterEditors")] + public IDataEditor[] ParameterEditors { get; set; } = Array.Empty(); + + /// + /// Gets or sets the grid editors listed in the manifest. + /// + [DataMember(Name = "gridEditors")] + public GridEditor[] GridEditors { get; set; } = Array.Empty(); + + /// + /// Gets or sets the content apps listed in the manifest. + /// + [DataMember(Name = "contentApps")] + public ManifestContentAppDefinition[] ContentApps { get; set; } = Array.Empty(); + + /// + /// Gets or sets the dashboards listed in the manifest. + /// + [DataMember(Name = "dashboards")] + public ManifestDashboard[] Dashboards { get; set; } = Array.Empty(); + + /// + /// Gets or sets the sections listed in the manifest. + /// + [DataMember(Name = "sections")] + public ManifestSection[] Sections { get; set; } = Array.Empty(); + } +} diff --git a/src/Umbraco.Core/Models/ContentEditing/ContentApp.cs b/src/Umbraco.Abstractions/Models/ContentEditing/ContentApp.cs similarity index 100% rename from src/Umbraco.Core/Models/ContentEditing/ContentApp.cs rename to src/Umbraco.Abstractions/Models/ContentEditing/ContentApp.cs diff --git a/src/Umbraco.Core/Models/ContentEditing/ContentAppBadge.cs b/src/Umbraco.Abstractions/Models/ContentEditing/ContentAppBadge.cs similarity index 90% rename from src/Umbraco.Core/Models/ContentEditing/ContentAppBadge.cs rename to src/Umbraco.Abstractions/Models/ContentEditing/ContentAppBadge.cs index ba11fd338d..19dbd2b8e7 100644 --- a/src/Umbraco.Core/Models/ContentEditing/ContentAppBadge.cs +++ b/src/Umbraco.Abstractions/Models/ContentEditing/ContentAppBadge.cs @@ -1,9 +1,7 @@ -namespace Umbraco.Core.Models.ContentEditing +using System.Runtime.Serialization; + +namespace Umbraco.Core.Models.ContentEditing { - using System.Runtime.Serialization; - - using Umbraco.Core.Events; - /// /// Represents a content app badge /// diff --git a/src/Umbraco.Abstractions/Models/ContentEditing/ContentAppBadgeType.cs b/src/Umbraco.Abstractions/Models/ContentEditing/ContentAppBadgeType.cs new file mode 100644 index 0000000000..a46fa7d3a9 --- /dev/null +++ b/src/Umbraco.Abstractions/Models/ContentEditing/ContentAppBadgeType.cs @@ -0,0 +1,25 @@ +using System.Runtime.Serialization; + +namespace Umbraco.Core.Models.ContentEditing +{ + // TODO: This was marked with `[StringEnumConverter]` to inform the serializer + // to serialize the values to string instead of INT (which is the default) + // so we need to either invent our own attribute and make the implementation aware of it + // or ... something else? + + /// + /// Represent the content app badge types + /// + [DataContract(Name = "contentAppBadgeType")] + public enum ContentAppBadgeType + { + [EnumMember(Value = "default")] + Default = 0, + + [EnumMember(Value = "warning")] + Warning = 1, + + [EnumMember(Value = "alert")] + Alert = 2 + } +} diff --git a/src/Umbraco.Core/Models/ContentEditing/IContentAppFactory.cs b/src/Umbraco.Abstractions/Models/ContentEditing/IContentAppFactory.cs similarity index 100% rename from src/Umbraco.Core/Models/ContentEditing/IContentAppFactory.cs rename to src/Umbraco.Abstractions/Models/ContentEditing/IContentAppFactory.cs diff --git a/src/Umbraco.Core/Models/ContentSchedule.cs b/src/Umbraco.Abstractions/Models/ContentSchedule.cs similarity index 98% rename from src/Umbraco.Core/Models/ContentSchedule.cs rename to src/Umbraco.Abstractions/Models/ContentSchedule.cs index cac4a0fd1c..4dba0456b0 100644 --- a/src/Umbraco.Core/Models/ContentSchedule.cs +++ b/src/Umbraco.Abstractions/Models/ContentSchedule.cs @@ -36,7 +36,7 @@ namespace Umbraco.Core.Models /// Gets the unique identifier of the document targeted by the scheduled action. /// [DataMember] - public Guid Id { get; internal set; } + public Guid Id { get; set; } /// /// Gets the culture of the scheduled action. diff --git a/src/Umbraco.Core/Models/ContentScheduleAction.cs b/src/Umbraco.Abstractions/Models/ContentScheduleAction.cs similarity index 100% rename from src/Umbraco.Core/Models/ContentScheduleAction.cs rename to src/Umbraco.Abstractions/Models/ContentScheduleAction.cs diff --git a/src/Umbraco.Core/Models/ContentScheduleCollection.cs b/src/Umbraco.Abstractions/Models/ContentScheduleCollection.cs similarity index 100% rename from src/Umbraco.Core/Models/ContentScheduleCollection.cs rename to src/Umbraco.Abstractions/Models/ContentScheduleCollection.cs diff --git a/src/Umbraco.Core/Models/DictionaryItem.cs b/src/Umbraco.Abstractions/Models/DictionaryItem.cs similarity index 100% rename from src/Umbraco.Core/Models/DictionaryItem.cs rename to src/Umbraco.Abstractions/Models/DictionaryItem.cs diff --git a/src/Umbraco.Core/Models/DictionaryItemExtensions.cs b/src/Umbraco.Abstractions/Models/DictionaryItemExtensions.cs similarity index 100% rename from src/Umbraco.Core/Models/DictionaryItemExtensions.cs rename to src/Umbraco.Abstractions/Models/DictionaryItemExtensions.cs diff --git a/src/Umbraco.Core/Models/DictionaryTranslation.cs b/src/Umbraco.Abstractions/Models/DictionaryTranslation.cs similarity index 93% rename from src/Umbraco.Core/Models/DictionaryTranslation.cs rename to src/Umbraco.Abstractions/Models/DictionaryTranslation.cs index afb4063b97..a00f9e887f 100644 --- a/src/Umbraco.Core/Models/DictionaryTranslation.cs +++ b/src/Umbraco.Abstractions/Models/DictionaryTranslation.cs @@ -11,7 +11,7 @@ namespace Umbraco.Core.Models [DataContract(IsReference = true)] public class DictionaryTranslation : EntityBase, IDictionaryTranslation { - internal Func GetLanguage { get; set; } + public Func GetLanguage { get; set; } private ILanguage _language; private string _value; @@ -35,13 +35,13 @@ namespace Umbraco.Core.Models Key = uniqueId; } - internal DictionaryTranslation(int languageId, string value) + public DictionaryTranslation(int languageId, string value) { _languageId = languageId; _value = value; } - internal DictionaryTranslation(int languageId, string value, Guid uniqueId) + public DictionaryTranslation(int languageId, string value, Guid uniqueId) { _languageId = languageId; _value = value; diff --git a/src/Umbraco.Abstractions/Models/Entities/EntityBase.cs b/src/Umbraco.Abstractions/Models/Entities/EntityBase.cs index 3d312eea4f..d848d3f404 100644 --- a/src/Umbraco.Abstractions/Models/Entities/EntityBase.cs +++ b/src/Umbraco.Abstractions/Models/Entities/EntityBase.cs @@ -80,37 +80,7 @@ namespace Umbraco.Core.Models.Entities _id = default; _key = Guid.Empty; _hasIdentity = false; - } - - /// - /// Updates the entity when it is being saved for the first time. - /// - 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; - } - - /// - /// Updates the entity when it is being saved. - /// - 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) { diff --git a/src/Umbraco.Core/Models/Entities/EntityExtensions.cs b/src/Umbraco.Abstractions/Models/Entities/EntityExtensions.cs similarity index 88% rename from src/Umbraco.Core/Models/Entities/EntityExtensions.cs rename to src/Umbraco.Abstractions/Models/Entities/EntityExtensions.cs index 2ee6a2d5ed..1e51f81d88 100644 --- a/src/Umbraco.Core/Models/Entities/EntityExtensions.cs +++ b/src/Umbraco.Abstractions/Models/Entities/EntityExtensions.cs @@ -2,12 +2,12 @@ namespace Umbraco.Core.Models.Entities { - internal static class EntityExtensions + public static class EntityExtensions { /// /// Updates the entity when it is being saved. /// - internal static void UpdatingEntity(this IEntity entity) + public static void UpdatingEntity(this IEntity entity) { var now = DateTime.Now; @@ -27,7 +27,7 @@ namespace Umbraco.Core.Models.Entities /// /// Updates the entity when it is being saved for the first time. /// - internal static void AddingEntity(this IEntity entity) + public static void AddingEntity(this IEntity entity) { var now = DateTime.Now; var canBeDirty = entity as ICanBeDirty; diff --git a/src/Umbraco.Abstractions/Models/Entities/EntitySlim.cs b/src/Umbraco.Abstractions/Models/Entities/EntitySlim.cs index b095965056..77611ebc3d 100644 --- a/src/Umbraco.Abstractions/Models/Entities/EntitySlim.cs +++ b/src/Umbraco.Abstractions/Models/Entities/EntitySlim.cs @@ -146,6 +146,16 @@ namespace Umbraco.Core.Models.Entities throw new WontImplementException(); } + public void DisableChangeTracking() + { + // noop + } + + public void EnableChangeTracking() + { + // noop + } + public bool WasDirty() { throw new WontImplementException(); diff --git a/src/Umbraco.Abstractions/Models/Entities/ICanBeDirty.cs b/src/Umbraco.Abstractions/Models/Entities/ICanBeDirty.cs index fc95161d7e..57a8a581f0 100644 --- a/src/Umbraco.Abstractions/Models/Entities/ICanBeDirty.cs +++ b/src/Umbraco.Abstractions/Models/Entities/ICanBeDirty.cs @@ -26,5 +26,15 @@ namespace Umbraco.Core.Models.Entities /// Resets dirty properties. /// void ResetDirtyProperties(); + + /// + /// Disables change tracking. + /// + void DisableChangeTracking(); + + /// + /// Enables change tracking. + /// + void EnableChangeTracking(); } } diff --git a/src/Umbraco.Core/Models/Entities/IMediaEntitySlim.cs b/src/Umbraco.Abstractions/Models/Entities/IMediaEntitySlim.cs similarity index 100% rename from src/Umbraco.Core/Models/Entities/IMediaEntitySlim.cs rename to src/Umbraco.Abstractions/Models/Entities/IMediaEntitySlim.cs diff --git a/src/Umbraco.Core/Models/Entities/IMemberEntitySlim.cs b/src/Umbraco.Abstractions/Models/Entities/IMemberEntitySlim.cs similarity index 100% rename from src/Umbraco.Core/Models/Entities/IMemberEntitySlim.cs rename to src/Umbraco.Abstractions/Models/Entities/IMemberEntitySlim.cs diff --git a/src/Umbraco.Core/Models/Entities/MediaEntitySlim.cs b/src/Umbraco.Abstractions/Models/Entities/MediaEntitySlim.cs similarity index 100% rename from src/Umbraco.Core/Models/Entities/MediaEntitySlim.cs rename to src/Umbraco.Abstractions/Models/Entities/MediaEntitySlim.cs diff --git a/src/Umbraco.Core/Models/Entities/MemberEntitySlim.cs b/src/Umbraco.Abstractions/Models/Entities/MemberEntitySlim.cs similarity index 100% rename from src/Umbraco.Core/Models/Entities/MemberEntitySlim.cs rename to src/Umbraco.Abstractions/Models/Entities/MemberEntitySlim.cs diff --git a/src/Umbraco.Core/Models/EntityExtensions.cs b/src/Umbraco.Abstractions/Models/EntityExtensions.cs similarity index 100% rename from src/Umbraco.Core/Models/EntityExtensions.cs rename to src/Umbraco.Abstractions/Models/EntityExtensions.cs diff --git a/src/Umbraco.Core/Models/IContent.cs b/src/Umbraco.Abstractions/Models/IContent.cs similarity index 100% rename from src/Umbraco.Core/Models/IContent.cs rename to src/Umbraco.Abstractions/Models/IContent.cs diff --git a/src/Umbraco.Core/Models/IContentBase.cs b/src/Umbraco.Abstractions/Models/IContentBase.cs similarity index 99% rename from src/Umbraco.Core/Models/IContentBase.cs rename to src/Umbraco.Abstractions/Models/IContentBase.cs index 0f660181fb..1864996379 100644 --- a/src/Umbraco.Core/Models/IContentBase.cs +++ b/src/Umbraco.Abstractions/Models/IContentBase.cs @@ -98,7 +98,7 @@ namespace Umbraco.Core.Models /// List of properties, which make up all the data available for this Content object /// /// Properties are loaded as part of the Content object graph - PropertyCollection Properties { get; set; } + IPropertyCollection Properties { get; set; } /// /// Gets a value indicating whether the content entity has a property with the supplied alias. diff --git a/src/Umbraco.Core/Models/IDataValueEditor.cs b/src/Umbraco.Abstractions/Models/IDataValueEditor.cs similarity index 81% rename from src/Umbraco.Core/Models/IDataValueEditor.cs rename to src/Umbraco.Abstractions/Models/IDataValueEditor.cs index cb68531cc7..e095f3aa31 100644 --- a/src/Umbraco.Core/Models/IDataValueEditor.cs +++ b/src/Umbraco.Abstractions/Models/IDataValueEditor.cs @@ -3,7 +3,6 @@ using System.ComponentModel.DataAnnotations; using System.Xml.Linq; using Umbraco.Core.Models; using Umbraco.Core.Models.Editors; -using Umbraco.Core.Services; namespace Umbraco.Core.PropertyEditors { @@ -59,12 +58,12 @@ namespace Umbraco.Core.PropertyEditors /// /// Converts a property value to a value for the editor. /// - object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null); + object ToEditor(IProperty property, string culture = null, string segment = null); // TODO: / deal with this when unplugging the xml cache // why property vs propertyType? services should be injected! etc... - IEnumerable ConvertDbToXml(Property property, IDataTypeService dataTypeService, ILocalizationService localizationService, bool published); - XNode ConvertDbToXml(PropertyType propertyType, object value, IDataTypeService dataTypeService); - string ConvertDbToString(PropertyType propertyType, object value, IDataTypeService dataTypeService); + IEnumerable ConvertDbToXml(IProperty property, bool published); + XNode ConvertDbToXml(IPropertyType propertyType, object value); + string ConvertDbToString(IPropertyType propertyType, object value); } } diff --git a/src/Umbraco.Core/Models/IMedia.cs b/src/Umbraco.Abstractions/Models/IMedia.cs similarity index 100% rename from src/Umbraco.Core/Models/IMedia.cs rename to src/Umbraco.Abstractions/Models/IMedia.cs diff --git a/src/Umbraco.Abstractions/Models/IProperty.cs b/src/Umbraco.Abstractions/Models/IProperty.cs new file mode 100644 index 0000000000..35a151af10 --- /dev/null +++ b/src/Umbraco.Abstractions/Models/IProperty.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using Umbraco.Core.Models.Entities; + +namespace Umbraco.Core.Models +{ + public interface IProperty : IEntity, IRememberBeingDirty + { + + ValueStorageType ValueStorageType { get; } + /// + /// Returns the PropertyType, which this Property is based on + /// + IPropertyType PropertyType { get; } + + /// + /// Gets the list of values. + /// + IReadOnlyCollection Values { get; set; } + + /// + /// Returns the Alias of the PropertyType, which this Property is based on + /// + string Alias { get; } + + /// + /// Gets the value. + /// + object GetValue(string culture = null, string segment = null, bool published = false); + + /// + /// Sets a value. + /// + void SetValue(object value, string culture = null, string segment = null); + + /// + /// Resets the entity identity. + /// + void ResetIdentity(); + + int PropertyTypeId { get; } + void PublishValues(string culture = "*", string segment = "*"); + void UnpublishValues(string culture = "*", string segment = "*"); + } +} diff --git a/src/Umbraco.Abstractions/Models/IPropertyCollection.cs b/src/Umbraco.Abstractions/Models/IPropertyCollection.cs new file mode 100644 index 0000000000..c0a9622e6e --- /dev/null +++ b/src/Umbraco.Abstractions/Models/IPropertyCollection.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; +using System.Collections.Specialized; + +namespace Umbraco.Core.Models +{ + public interface IPropertyCollection : IEnumerable, IDeepCloneable, INotifyCollectionChanged + { + bool TryGetValue(string propertyTypeAlias, out IProperty property); + bool Contains(string key); + + /// + /// Ensures that the collection contains properties for the specified property types. + /// + void EnsurePropertyTypes(IEnumerable propertyTypes); + + /// + /// Ensures that the collection does not contain properties not in the specified property types. + /// + void EnsureCleanPropertyTypes(IEnumerable propertyTypes); + + /// + /// Gets the property with the specified alias. + /// + IProperty this[string name] { get; } + + /// + /// Gets the property at the specified index. + /// + IProperty this[int index] { get; } + + /// + /// Adds or updates a property. + /// + void Add(IProperty property); + + int Count { get; } + } +} diff --git a/src/Umbraco.Abstractions/Models/IPropertyType.cs b/src/Umbraco.Abstractions/Models/IPropertyType.cs new file mode 100644 index 0000000000..e70ee39933 --- /dev/null +++ b/src/Umbraco.Abstractions/Models/IPropertyType.cs @@ -0,0 +1,87 @@ +using System; +using System.Runtime.Serialization; +using Umbraco.Core.Models.Entities; + +namespace Umbraco.Core.Models +{ + public interface IPropertyType : IEntity, IRememberBeingDirty + { + /// + /// Gets of sets the name of the property type. + /// + string Name { get; } + + /// + /// Gets of sets the alias of the property type. + /// + string Alias { get; } + + /// + /// Gets of sets the description of the property type. + /// + string Description { get; } + + /// + /// Gets or sets the identifier of the datatype for this property type. + /// + int DataTypeId { get; } + + Guid DataTypeKey { get; } + + /// + /// Gets or sets the alias of the property editor for this property type. + /// + string PropertyEditorAlias { get; } + + /// + /// Gets or sets the database type for storing value for this property type. + /// + ValueStorageType ValueStorageType { get; } + + /// + /// Gets or sets the identifier of the property group this property type belongs to. + /// + /// For generic properties, the value is null. + Lazy PropertyGroupId { get; } + + /// + /// Gets of sets a value indicating whether a value for this property type is required. + /// + bool Mandatory { get; } + + /// + /// Gets of sets the sort order of the property type. + /// + int SortOrder { get; } + + /// + /// Gets or sets the regular expression validating the property values. + /// + string ValidationRegExp { get; } + + bool SupportsPublishing { get; } + + /// + /// Gets or sets the content variation of the property type. + /// + ContentVariation Variations { get; } + + /// + /// Determines whether the property type supports a combination of culture and segment. + /// + /// The culture. + /// The segment. + /// A value indicating whether wildcards are valid. + bool SupportsVariation(string culture, string segment, bool wildcards = false); + + /// + /// Converts a value assigned to a property. + /// + /// + /// The input value can be pretty much anything, and is converted to the actual CLR type + /// expected by the property (eg an integer if the property values are integers). + /// Throws if the value cannot be converted. + /// + object ConvertAssignedValue(object value); + } +} diff --git a/src/Umbraco.Abstractions/Models/IPropertyValue.cs b/src/Umbraco.Abstractions/Models/IPropertyValue.cs new file mode 100644 index 0000000000..abc459a72f --- /dev/null +++ b/src/Umbraco.Abstractions/Models/IPropertyValue.cs @@ -0,0 +1,34 @@ +namespace Umbraco.Core.Models +{ + public interface IPropertyValue + { + /// + /// Gets or sets the culture of the property. + /// + /// The culture is either null (invariant) or a non-empty string. If the property is + /// set with an empty or whitespace value, its value is converted to null. + string Culture { get; set; } + + /// + /// Gets or sets the segment of the property. + /// + /// The segment is either null (neutral) or a non-empty string. If the property is + /// set with an empty or whitespace value, its value is converted to null. + string Segment { get; set; } + + /// + /// Gets or sets the edited value of the property. + /// + object EditedValue { get; set; } + + /// + /// Gets or sets the published value of the property. + /// + object PublishedValue { get; set; } + + /// + /// Clones the property value. + /// + IPropertyValue Clone(); + } +} diff --git a/src/Umbraco.Core/Models/MacroProperty.cs b/src/Umbraco.Abstractions/Models/MacroProperty.cs similarity index 97% rename from src/Umbraco.Core/Models/MacroProperty.cs rename to src/Umbraco.Abstractions/Models/MacroProperty.cs index 62ba6a7a7d..9dfb81cf71 100644 --- a/src/Umbraco.Core/Models/MacroProperty.cs +++ b/src/Umbraco.Abstractions/Models/MacroProperty.cs @@ -41,7 +41,7 @@ namespace Umbraco.Core.Models /// /// /// - internal MacroProperty(int id, Guid key, string @alias, string name, int sortOrder, string editorAlias) + public MacroProperty(int id, Guid key, string @alias, string name, int sortOrder, string editorAlias) { _id = id; _alias = alias; diff --git a/src/Umbraco.Core/Models/MemberGroup.cs b/src/Umbraco.Abstractions/Models/MemberGroup.cs similarity index 100% rename from src/Umbraco.Core/Models/MemberGroup.cs rename to src/Umbraco.Abstractions/Models/MemberGroup.cs diff --git a/src/Umbraco.Core/Models/MemberTypePropertyProfileAccess.cs b/src/Umbraco.Abstractions/Models/MemberTypePropertyProfileAccess.cs similarity index 91% rename from src/Umbraco.Core/Models/MemberTypePropertyProfileAccess.cs rename to src/Umbraco.Abstractions/Models/MemberTypePropertyProfileAccess.cs index 386fdf560b..0be9080841 100644 --- a/src/Umbraco.Core/Models/MemberTypePropertyProfileAccess.cs +++ b/src/Umbraco.Abstractions/Models/MemberTypePropertyProfileAccess.cs @@ -3,7 +3,7 @@ /// /// Used to track the property types that are visible/editable on member profiles /// - internal class MemberTypePropertyProfileAccess + public class MemberTypePropertyProfileAccess { public MemberTypePropertyProfileAccess(bool isVisible, bool isEditable, bool isSenstive) { diff --git a/src/Umbraco.Core/Models/Membership/ContentPermissionSet.cs b/src/Umbraco.Abstractions/Models/Membership/ContentPermissionSet.cs similarity index 100% rename from src/Umbraco.Core/Models/Membership/ContentPermissionSet.cs rename to src/Umbraco.Abstractions/Models/Membership/ContentPermissionSet.cs diff --git a/src/Umbraco.Abstractions/Models/Membership/MembershipScenario.cs b/src/Umbraco.Abstractions/Models/Membership/MembershipScenario.cs index ec092f83c1..6fe587e1ce 100644 --- a/src/Umbraco.Abstractions/Models/Membership/MembershipScenario.cs +++ b/src/Umbraco.Abstractions/Models/Membership/MembershipScenario.cs @@ -6,6 +6,8 @@ /// public enum MembershipScenario { + //TODO: This will become obsolete when we get asp.net identity members in place + /// /// The member is based on the native Umbraco members (IMember + Umbraco membership provider) /// diff --git a/src/Umbraco.Core/Models/Packaging/CompiledPackage.cs b/src/Umbraco.Abstractions/Models/Packaging/CompiledPackage.cs similarity index 100% rename from src/Umbraco.Core/Models/Packaging/CompiledPackage.cs rename to src/Umbraco.Abstractions/Models/Packaging/CompiledPackage.cs diff --git a/src/Umbraco.Core/Models/Packaging/CompiledPackageDocument.cs b/src/Umbraco.Abstractions/Models/Packaging/CompiledPackageDocument.cs similarity index 100% rename from src/Umbraco.Core/Models/Packaging/CompiledPackageDocument.cs rename to src/Umbraco.Abstractions/Models/Packaging/CompiledPackageDocument.cs diff --git a/src/Umbraco.Core/Models/Packaging/CompiledPackageFile.cs b/src/Umbraco.Abstractions/Models/Packaging/CompiledPackageFile.cs similarity index 100% rename from src/Umbraco.Core/Models/Packaging/CompiledPackageFile.cs rename to src/Umbraco.Abstractions/Models/Packaging/CompiledPackageFile.cs diff --git a/src/Umbraco.Core/Models/Packaging/PreInstallWarnings.cs b/src/Umbraco.Abstractions/Models/Packaging/PreInstallWarnings.cs similarity index 100% rename from src/Umbraco.Core/Models/Packaging/PreInstallWarnings.cs rename to src/Umbraco.Abstractions/Models/Packaging/PreInstallWarnings.cs diff --git a/src/Umbraco.Core/Models/PagedResultOfT.cs b/src/Umbraco.Abstractions/Models/PagedResultOfT.cs similarity index 100% rename from src/Umbraco.Core/Models/PagedResultOfT.cs rename to src/Umbraco.Abstractions/Models/PagedResultOfT.cs diff --git a/src/Umbraco.Core/Models/PublicAccessEntry.cs b/src/Umbraco.Abstractions/Models/PublicAccessEntry.cs similarity index 98% rename from src/Umbraco.Core/Models/PublicAccessEntry.cs rename to src/Umbraco.Abstractions/Models/PublicAccessEntry.cs index cfb30de147..b7f9caed44 100644 --- a/src/Umbraco.Core/Models/PublicAccessEntry.cs +++ b/src/Umbraco.Abstractions/Models/PublicAccessEntry.cs @@ -77,7 +77,7 @@ namespace Umbraco.Core.Models } } - internal IEnumerable RemovedRules => _removedRules; + public IEnumerable RemovedRules => _removedRules; public IEnumerable Rules => _ruleCollection; diff --git a/src/Umbraco.Core/Models/PublishedContent/ILivePublishedModelFactory.cs b/src/Umbraco.Abstractions/Models/PublishedContent/ILivePublishedModelFactory.cs similarity index 100% rename from src/Umbraco.Core/Models/PublishedContent/ILivePublishedModelFactory.cs rename to src/Umbraco.Abstractions/Models/PublishedContent/ILivePublishedModelFactory.cs diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedContent.cs b/src/Umbraco.Abstractions/Models/PublishedContent/IPublishedContent.cs similarity index 100% rename from src/Umbraco.Core/Models/PublishedContent/IPublishedContent.cs rename to src/Umbraco.Abstractions/Models/PublishedContent/IPublishedContent.cs diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedContentType.cs b/src/Umbraco.Abstractions/Models/PublishedContent/IPublishedContentType.cs similarity index 100% rename from src/Umbraco.Core/Models/PublishedContent/IPublishedContentType.cs rename to src/Umbraco.Abstractions/Models/PublishedContent/IPublishedContentType.cs diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedElement.cs b/src/Umbraco.Abstractions/Models/PublishedContent/IPublishedElement.cs similarity index 100% rename from src/Umbraco.Core/Models/PublishedContent/IPublishedElement.cs rename to src/Umbraco.Abstractions/Models/PublishedContent/IPublishedElement.cs diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedModelFactory.cs b/src/Umbraco.Abstractions/Models/PublishedContent/IPublishedModelFactory.cs similarity index 100% rename from src/Umbraco.Core/Models/PublishedContent/IPublishedModelFactory.cs rename to src/Umbraco.Abstractions/Models/PublishedContent/IPublishedModelFactory.cs diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedProperty.cs b/src/Umbraco.Abstractions/Models/PublishedContent/IPublishedProperty.cs similarity index 100% rename from src/Umbraco.Core/Models/PublishedContent/IPublishedProperty.cs rename to src/Umbraco.Abstractions/Models/PublishedContent/IPublishedProperty.cs diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedPropertyType.cs b/src/Umbraco.Abstractions/Models/PublishedContent/IPublishedPropertyType.cs similarity index 100% rename from src/Umbraco.Core/Models/PublishedContent/IPublishedPropertyType.cs rename to src/Umbraco.Abstractions/Models/PublishedContent/IPublishedPropertyType.cs diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedValueFallback.cs b/src/Umbraco.Abstractions/Models/PublishedContent/IPublishedValueFallback.cs similarity index 100% rename from src/Umbraco.Core/Models/PublishedContent/IPublishedValueFallback.cs rename to src/Umbraco.Abstractions/Models/PublishedContent/IPublishedValueFallback.cs diff --git a/src/Umbraco.Core/Models/PublishedContent/NoopPublishedModelFactory.cs b/src/Umbraco.Abstractions/Models/PublishedContent/NoopPublishedModelFactory.cs similarity index 100% rename from src/Umbraco.Core/Models/PublishedContent/NoopPublishedModelFactory.cs rename to src/Umbraco.Abstractions/Models/PublishedContent/NoopPublishedModelFactory.cs diff --git a/src/Umbraco.Core/Models/PublishedContent/NoopPublishedValueFallback.cs b/src/Umbraco.Abstractions/Models/PublishedContent/NoopPublishedValueFallback.cs similarity index 100% rename from src/Umbraco.Core/Models/PublishedContent/NoopPublishedValueFallback.cs rename to src/Umbraco.Abstractions/Models/PublishedContent/NoopPublishedValueFallback.cs diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeConverter.cs b/src/Umbraco.Abstractions/Models/PublishedContent/PublishedContentTypeConverter.cs similarity index 100% rename from src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeConverter.cs rename to src/Umbraco.Abstractions/Models/PublishedContent/PublishedContentTypeConverter.cs diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs b/src/Umbraco.Abstractions/Models/PublishedContent/PublishedContentWrapped.cs similarity index 100% rename from src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs rename to src/Umbraco.Abstractions/Models/PublishedContent/PublishedContentWrapped.cs diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedElementModel.cs b/src/Umbraco.Abstractions/Models/PublishedContent/PublishedElementModel.cs similarity index 100% rename from src/Umbraco.Core/Models/PublishedContent/PublishedElementModel.cs rename to src/Umbraco.Abstractions/Models/PublishedContent/PublishedElementModel.cs diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedElementWrapped.cs b/src/Umbraco.Abstractions/Models/PublishedContent/PublishedElementWrapped.cs similarity index 100% rename from src/Umbraco.Core/Models/PublishedContent/PublishedElementWrapped.cs rename to src/Umbraco.Abstractions/Models/PublishedContent/PublishedElementWrapped.cs diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedModelAttribute.cs b/src/Umbraco.Abstractions/Models/PublishedContent/PublishedModelAttribute.cs similarity index 100% rename from src/Umbraco.Core/Models/PublishedContent/PublishedModelAttribute.cs rename to src/Umbraco.Abstractions/Models/PublishedContent/PublishedModelAttribute.cs diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyBase.cs b/src/Umbraco.Abstractions/Models/PublishedContent/PublishedPropertyBase.cs similarity index 97% rename from src/Umbraco.Core/Models/PublishedContent/PublishedPropertyBase.cs rename to src/Umbraco.Abstractions/Models/PublishedContent/PublishedPropertyBase.cs index e11d2391ec..33f8e94139 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyBase.cs +++ b/src/Umbraco.Abstractions/Models/PublishedContent/PublishedPropertyBase.cs @@ -7,7 +7,7 @@ namespace Umbraco.Core.Models.PublishedContent /// Provides a base class for IPublishedProperty implementations which converts and caches /// the value source to the actual value to use when rendering content. /// - internal abstract class PublishedPropertyBase : IPublishedProperty + public abstract class PublishedPropertyBase : IPublishedProperty { /// /// Initializes a new instance of the class. diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedSearchResult.cs b/src/Umbraco.Abstractions/Models/PublishedContent/PublishedSearchResult.cs similarity index 100% rename from src/Umbraco.Core/Models/PublishedContent/PublishedSearchResult.cs rename to src/Umbraco.Abstractions/Models/PublishedContent/PublishedSearchResult.cs diff --git a/src/Umbraco.Core/Models/PublishedContent/RawValueProperty.cs b/src/Umbraco.Abstractions/Models/PublishedContent/RawValueProperty.cs similarity index 97% rename from src/Umbraco.Core/Models/PublishedContent/RawValueProperty.cs rename to src/Umbraco.Abstractions/Models/PublishedContent/RawValueProperty.cs index 10f999532f..596840cf6a 100644 --- a/src/Umbraco.Core/Models/PublishedContent/RawValueProperty.cs +++ b/src/Umbraco.Abstractions/Models/PublishedContent/RawValueProperty.cs @@ -14,7 +14,7 @@ namespace Umbraco.Core.Models.PublishedContent /// Does not support variations: the ctor throws if the property type /// supports variations. /// - internal class RawValueProperty : PublishedPropertyBase + public class RawValueProperty : PublishedPropertyBase { private readonly object _sourceValue; //the value in the db private readonly Lazy _objectValue; diff --git a/src/Umbraco.Core/Models/PublishedContent/UrlMode.cs b/src/Umbraco.Abstractions/Models/PublishedContent/UrlMode.cs similarity index 100% rename from src/Umbraco.Core/Models/PublishedContent/UrlMode.cs rename to src/Umbraco.Abstractions/Models/PublishedContent/UrlMode.cs diff --git a/src/Umbraco.Core/Models/UmbracoDomain.cs b/src/Umbraco.Abstractions/Models/UmbracoDomain.cs similarity index 95% rename from src/Umbraco.Core/Models/UmbracoDomain.cs rename to src/Umbraco.Abstractions/Models/UmbracoDomain.cs index 093acef5b5..c4a49de5d3 100644 --- a/src/Umbraco.Core/Models/UmbracoDomain.cs +++ b/src/Umbraco.Abstractions/Models/UmbracoDomain.cs @@ -49,6 +49,6 @@ namespace Umbraco.Core.Models /// /// Readonly value of the language ISO code for the domain /// - public string LanguageIsoCode { get; internal set; } + public string LanguageIsoCode { get; set; } } } diff --git a/src/Umbraco.Abstractions/Models/UmbracoUserExtensions.cs b/src/Umbraco.Abstractions/Models/UmbracoUserExtensions.cs new file mode 100644 index 0000000000..6ed3e6279b --- /dev/null +++ b/src/Umbraco.Abstractions/Models/UmbracoUserExtensions.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using Umbraco.Core.Configuration; +using Umbraco.Core.Models.Membership; +using Umbraco.Core.Services; + +namespace Umbraco.Core.Models +{ + public static class UmbracoUserExtensions + { + public static IEnumerable GetPermissions(this IUser user, string path, IUserService userService) + { + return userService.GetPermissionsForPath(user, path).GetAllPermissions(); + } + + public static bool HasSectionAccess(this IUser user, string app) + { + var apps = user.AllowedSections; + return apps.Any(uApp => uApp.InvariantEquals(app)); + } + + /// + /// Determines whether this user is the 'super' user. + /// + public static bool IsSuper(this IUser user) + { + if (user == null) throw new ArgumentNullException(nameof(user)); + return user.Id == Constants.Security.SuperUserId; + } + + /// + /// Determines whether this user belongs to the administrators group. + /// + /// The 'super' user does not automatically belongs to the administrators group. + public static bool IsAdmin(this IUser user) + { + if (user == null) throw new ArgumentNullException(nameof(user)); + return user.Groups != null && user.Groups.Any(x => x.Alias == Constants.Security.AdminGroupAlias); + } + + /// + /// Returns the culture info associated with this user, based on the language they're assigned to in the back office + /// + /// + /// + /// + /// + public static CultureInfo GetUserCulture(this IUser user, ILocalizedTextService textService, IGlobalSettings globalSettings) + { + if (user == null) throw new ArgumentNullException(nameof(user)); + if (textService == null) throw new ArgumentNullException(nameof(textService)); + return GetUserCulture(user.Language, textService, globalSettings); + } + + public static CultureInfo GetUserCulture(string userLanguage, ILocalizedTextService textService, IGlobalSettings globalSettings) + { + try + { + var culture = CultureInfo.GetCultureInfo(userLanguage.Replace("_", "-")); + // TODO: This is a hack because we store the user language as 2 chars instead of the full culture + // which is actually stored in the language files (which are also named with 2 chars!) so we need to attempt + // to convert to a supported full culture + var result = textService.ConvertToSupportedCultureWithRegionCode(culture); + return result; + } + catch (CultureNotFoundException) + { + //return the default one + return CultureInfo.GetCultureInfo(globalSettings.DefaultUILanguage); + } + } + } +} diff --git a/src/Umbraco.Core/Models/Validation/RequiredForPersistenceAttribute.cs b/src/Umbraco.Abstractions/Models/Validation/RequiredForPersistenceAttribute.cs similarity index 94% rename from src/Umbraco.Core/Models/Validation/RequiredForPersistenceAttribute.cs rename to src/Umbraco.Abstractions/Models/Validation/RequiredForPersistenceAttribute.cs index f54741e489..feb889e962 100644 --- a/src/Umbraco.Core/Models/Validation/RequiredForPersistenceAttribute.cs +++ b/src/Umbraco.Abstractions/Models/Validation/RequiredForPersistenceAttribute.cs @@ -19,7 +19,7 @@ namespace Umbraco.Core.Models.Validation /// /// Determines whether an object has all required values for persistence. /// - internal static bool HasRequiredValuesForPersistence(object model) + public static bool HasRequiredValuesForPersistence(object model) { return model.GetType().GetProperties().All(x => { diff --git a/src/Umbraco.Core/PackageActions/IPackageAction.cs b/src/Umbraco.Abstractions/PackageActions/IPackageAction.cs similarity index 100% rename from src/Umbraco.Core/PackageActions/IPackageAction.cs rename to src/Umbraco.Abstractions/PackageActions/IPackageAction.cs diff --git a/src/Umbraco.Core/PackageActions/PackageActionCollection.cs b/src/Umbraco.Abstractions/PackageActions/PackageActionCollection.cs similarity index 100% rename from src/Umbraco.Core/PackageActions/PackageActionCollection.cs rename to src/Umbraco.Abstractions/PackageActions/PackageActionCollection.cs diff --git a/src/Umbraco.Core/PackageActions/PackageActionCollectionBuilder.cs b/src/Umbraco.Abstractions/PackageActions/PackageActionCollectionBuilder.cs similarity index 51% rename from src/Umbraco.Core/PackageActions/PackageActionCollectionBuilder.cs rename to src/Umbraco.Abstractions/PackageActions/PackageActionCollectionBuilder.cs index fdb118ae06..d30fb92cf9 100644 --- a/src/Umbraco.Core/PackageActions/PackageActionCollectionBuilder.cs +++ b/src/Umbraco.Abstractions/PackageActions/PackageActionCollectionBuilder.cs @@ -2,7 +2,7 @@ namespace Umbraco.Core.PackageActions { - internal class PackageActionCollectionBuilder : LazyCollectionBuilderBase + public class PackageActionCollectionBuilder : LazyCollectionBuilderBase { protected override PackageActionCollectionBuilder This => this; } diff --git a/src/Umbraco.Core/Packaging/ConflictingPackageData.cs b/src/Umbraco.Abstractions/Packaging/ConflictingPackageData.cs similarity index 98% rename from src/Umbraco.Core/Packaging/ConflictingPackageData.cs rename to src/Umbraco.Abstractions/Packaging/ConflictingPackageData.cs index 82693677fb..7425f64727 100644 --- a/src/Umbraco.Core/Packaging/ConflictingPackageData.cs +++ b/src/Umbraco.Abstractions/Packaging/ConflictingPackageData.cs @@ -7,7 +7,7 @@ using Umbraco.Core.Services; namespace Umbraco.Core.Packaging { - internal class ConflictingPackageData + public class ConflictingPackageData { private readonly IMacroService _macroService; private readonly IFileService _fileService; diff --git a/src/Umbraco.Core/Packaging/IPackageActionRunner.cs b/src/Umbraco.Abstractions/Packaging/IPackageActionRunner.cs similarity index 100% rename from src/Umbraco.Core/Packaging/IPackageActionRunner.cs rename to src/Umbraco.Abstractions/Packaging/IPackageActionRunner.cs diff --git a/src/Umbraco.Core/Packaging/PackageActionRunner.cs b/src/Umbraco.Abstractions/Packaging/PackageActionRunner.cs similarity index 97% rename from src/Umbraco.Core/Packaging/PackageActionRunner.cs rename to src/Umbraco.Abstractions/Packaging/PackageActionRunner.cs index 8434f52f30..42a1a7042d 100644 --- a/src/Umbraco.Core/Packaging/PackageActionRunner.cs +++ b/src/Umbraco.Abstractions/Packaging/PackageActionRunner.cs @@ -9,7 +9,7 @@ namespace Umbraco.Core.Packaging /// /// Package actions are executed on package install / uninstall. /// - internal class PackageActionRunner : IPackageActionRunner + public class PackageActionRunner : IPackageActionRunner { private readonly ILogger _logger; private readonly PackageActionCollection _packageActions; diff --git a/src/Umbraco.Core/Packaging/PackageExtraction.cs b/src/Umbraco.Abstractions/Packaging/PackageExtraction.cs similarity index 99% rename from src/Umbraco.Core/Packaging/PackageExtraction.cs rename to src/Umbraco.Abstractions/Packaging/PackageExtraction.cs index d3150f4409..4e3ba929dc 100644 --- a/src/Umbraco.Core/Packaging/PackageExtraction.cs +++ b/src/Umbraco.Abstractions/Packaging/PackageExtraction.cs @@ -6,7 +6,7 @@ using System.IO.Compression; namespace Umbraco.Core.Packaging { - internal class PackageExtraction + public class PackageExtraction { public string ReadTextFileFromArchive(FileInfo packageFile, string fileToRead, out string directoryInPackage) { diff --git a/src/Umbraco.Core/Packaging/PackageInstallType.cs b/src/Umbraco.Abstractions/Packaging/PackageInstallType.cs similarity index 100% rename from src/Umbraco.Core/Packaging/PackageInstallType.cs rename to src/Umbraco.Abstractions/Packaging/PackageInstallType.cs diff --git a/src/Umbraco.Core/PropertyEditors/ConfigurationField.cs b/src/Umbraco.Abstractions/PropertyEditors/ConfigurationField.cs similarity index 83% rename from src/Umbraco.Core/PropertyEditors/ConfigurationField.cs rename to src/Umbraco.Abstractions/PropertyEditors/ConfigurationField.cs index bf692d1c98..52df839712 100644 --- a/src/Umbraco.Core/PropertyEditors/ConfigurationField.cs +++ b/src/Umbraco.Abstractions/PropertyEditors/ConfigurationField.cs @@ -1,15 +1,15 @@ using System; using System.Collections.Generic; using System.Linq; -using Newtonsoft.Json; -using Umbraco.Core.Composing; -using Umbraco.Core.IO; +using System.Reflection; +using System.Runtime.Serialization; namespace Umbraco.Core.PropertyEditors { /// /// Represents a datatype configuration field for editing. /// + [DataContract] public class ConfigurationField { private string _view; @@ -50,37 +50,35 @@ namespace Umbraco.Core.PropertyEditors /// /// Gets or sets the key of the field. /// - [JsonProperty("key", Required = Required.Always)] + [DataMember(Name = "key", IsRequired = true)] public string Key { get; set; } /// /// Gets or sets the name of the field. /// - [JsonProperty("label", Required = Required.Always)] + [DataMember(Name = "label", IsRequired = true)] public string Name { get; set; } /// /// Gets or sets the property name of the field. /// - [JsonIgnore] public string PropertyName { get; set; } /// /// Gets or sets the property CLR type of the field. /// - [JsonIgnore] public Type PropertyType { get; set; } /// /// Gets or sets the description of the field. /// - [JsonProperty("description")] + [DataMember(Name = "description")] public string Description { get; set; } /// /// Gets or sets a value indicating whether to hide the label of the field. /// - [JsonProperty("hideLabel")] + [DataMember(Name = "hideLabel")] public bool HideLabel { get; set; } /// @@ -90,23 +88,19 @@ namespace Umbraco.Core.PropertyEditors /// Can be the full virtual path, or the relative path to the Umbraco folder, /// or a simple view name which will map to ~/Views/PreValueEditors/{view}.html. /// - [JsonProperty("view", Required = Required.Always)] - public string View - { - get => _view; - set => _view = Current.Factory.GetInstance().ResolveVirtualUrl(value); - } + [DataMember(Name = "view", IsRequired = true)] + public string View { get; set; } /// /// Gets the validators of the field. /// - [JsonProperty("validation")] + [DataMember(Name = "validation")] public List Validators { get; } /// /// Gets or sets extra configuration properties for the editor. /// - [JsonProperty("config")] + [DataMember(Name = "config")] public IDictionary Config { get; set; } } } diff --git a/src/Umbraco.Core/PropertyEditors/ConfigurationFieldAttribute.cs b/src/Umbraco.Abstractions/PropertyEditors/ConfigurationFieldAttribute.cs similarity index 100% rename from src/Umbraco.Core/PropertyEditors/ConfigurationFieldAttribute.cs rename to src/Umbraco.Abstractions/PropertyEditors/ConfigurationFieldAttribute.cs diff --git a/src/Umbraco.Core/PropertyEditors/GridEditor.cs b/src/Umbraco.Abstractions/PropertyEditors/GridEditor.cs similarity index 66% rename from src/Umbraco.Core/PropertyEditors/GridEditor.cs rename to src/Umbraco.Abstractions/PropertyEditors/GridEditor.cs index 869e427e49..074aa7c6eb 100644 --- a/src/Umbraco.Core/PropertyEditors/GridEditor.cs +++ b/src/Umbraco.Abstractions/PropertyEditors/GridEditor.cs @@ -1,50 +1,38 @@ using System.Collections.Generic; -using Newtonsoft.Json; -using Umbraco.Core.Composing; +using System.Runtime.Serialization; using Umbraco.Core.Configuration.Grid; -using Umbraco.Core.IO; namespace Umbraco.Core.PropertyEditors { + + [DataContract] public class GridEditor : IGridEditorConfig { - private readonly IIOHelper _ioHelper; - private string _view; - private string _render; - - public GridEditor(IIOHelper ioHelper) + public GridEditor() { _ioHelper = ioHelper; Config = new Dictionary(); } - [JsonProperty("name", Required = Required.Always)] + [DataMember(Name = "name", IsRequired = true)] public string Name { get; set; } - [JsonProperty("nameTemplate")] + [DataMember(Name = "nameTemplate")] public string NameTemplate { get; set; } - [JsonProperty("alias", Required = Required.Always)] + [DataMember(Name = "alias", IsRequired = true)] public string Alias { get; set; } - [JsonProperty("view", Required = Required.Always)] - public string View - { - get => _view; - set => _view = _ioHelper.ResolveVirtualUrl(value); - } + [DataMember(Name = "view", IsRequired = true)] + public string View{ get; set; } - [JsonProperty("render")] - public string Render - { - get => _render; - set => _render = _ioHelper.ResolveVirtualUrl(value); - } + [DataMember(Name = "render")] + public string Render { get; set; } - [JsonProperty("icon", Required = Required.Always)] + [DataMember(Name = "icon", IsRequired = true)] public string Icon { get; set; } - [JsonProperty("config")] + [DataMember(Name = "config")] public IDictionary Config { get; set; } protected bool Equals(GridEditor other) diff --git a/src/Umbraco.Core/PropertyEditors/IConfigurationEditor.cs b/src/Umbraco.Abstractions/PropertyEditors/IConfigurationEditor.cs similarity index 100% rename from src/Umbraco.Core/PropertyEditors/IConfigurationEditor.cs rename to src/Umbraco.Abstractions/PropertyEditors/IConfigurationEditor.cs diff --git a/src/Umbraco.Core/PropertyEditors/IDataEditor.cs b/src/Umbraco.Abstractions/PropertyEditors/IDataEditor.cs similarity index 100% rename from src/Umbraco.Core/PropertyEditors/IDataEditor.cs rename to src/Umbraco.Abstractions/PropertyEditors/IDataEditor.cs diff --git a/src/Umbraco.Core/PropertyEditors/IManifestValueValidator.cs b/src/Umbraco.Abstractions/PropertyEditors/IManifestValueValidator.cs similarity index 100% rename from src/Umbraco.Core/PropertyEditors/IManifestValueValidator.cs rename to src/Umbraco.Abstractions/PropertyEditors/IManifestValueValidator.cs diff --git a/src/Umbraco.Core/PropertyEditors/IPropertyIndexValueFactory.cs b/src/Umbraco.Abstractions/PropertyEditors/IPropertyIndexValueFactory.cs similarity index 92% rename from src/Umbraco.Core/PropertyEditors/IPropertyIndexValueFactory.cs rename to src/Umbraco.Abstractions/PropertyEditors/IPropertyIndexValueFactory.cs index fd4e272f08..26552afc6f 100644 --- a/src/Umbraco.Core/PropertyEditors/IPropertyIndexValueFactory.cs +++ b/src/Umbraco.Abstractions/PropertyEditors/IPropertyIndexValueFactory.cs @@ -19,6 +19,6 @@ namespace Umbraco.Core.PropertyEditors /// values. By default, there would be only one object: the property value. But some implementations may return /// more than one value for a given field. /// - IEnumerable>> GetIndexValues(Property property, string culture, string segment, bool published); + IEnumerable>> GetIndexValues(IProperty property, string culture, string segment, bool published); } } diff --git a/src/Umbraco.Core/PropertyEditors/IValueFormatValidator.cs b/src/Umbraco.Abstractions/PropertyEditors/IValueFormatValidator.cs similarity index 100% rename from src/Umbraco.Core/PropertyEditors/IValueFormatValidator.cs rename to src/Umbraco.Abstractions/PropertyEditors/IValueFormatValidator.cs diff --git a/src/Umbraco.Core/PropertyEditors/IValueRequiredValidator.cs b/src/Umbraco.Abstractions/PropertyEditors/IValueRequiredValidator.cs similarity index 100% rename from src/Umbraco.Core/PropertyEditors/IValueRequiredValidator.cs rename to src/Umbraco.Abstractions/PropertyEditors/IValueRequiredValidator.cs diff --git a/src/Umbraco.Core/PropertyEditors/IValueValidator.cs b/src/Umbraco.Abstractions/PropertyEditors/IValueValidator.cs similarity index 100% rename from src/Umbraco.Core/PropertyEditors/IValueValidator.cs rename to src/Umbraco.Abstractions/PropertyEditors/IValueValidator.cs diff --git a/src/Umbraco.Core/PropertyEditors/ManifestValueValidatorCollection.cs b/src/Umbraco.Abstractions/PropertyEditors/ManifestValueValidatorCollection.cs similarity index 100% rename from src/Umbraco.Core/PropertyEditors/ManifestValueValidatorCollection.cs rename to src/Umbraco.Abstractions/PropertyEditors/ManifestValueValidatorCollection.cs diff --git a/src/Umbraco.Abstractions/PropertyEditors/ManifestValueValidatorCollectionBuilder.cs b/src/Umbraco.Abstractions/PropertyEditors/ManifestValueValidatorCollectionBuilder.cs new file mode 100644 index 0000000000..0ebda864f6 --- /dev/null +++ b/src/Umbraco.Abstractions/PropertyEditors/ManifestValueValidatorCollectionBuilder.cs @@ -0,0 +1,9 @@ +using Umbraco.Core.Composing; + +namespace Umbraco.Core.PropertyEditors +{ + public class ManifestValueValidatorCollectionBuilder : LazyCollectionBuilderBase + { + protected override ManifestValueValidatorCollectionBuilder This => this; + } +} diff --git a/src/Umbraco.Core/PropertyEditors/Validators/DecimalValidator.cs b/src/Umbraco.Abstractions/PropertyEditors/Validators/DecimalValidator.cs similarity index 92% rename from src/Umbraco.Core/PropertyEditors/Validators/DecimalValidator.cs rename to src/Umbraco.Abstractions/PropertyEditors/Validators/DecimalValidator.cs index 86db995566..f464044923 100644 --- a/src/Umbraco.Core/PropertyEditors/Validators/DecimalValidator.cs +++ b/src/Umbraco.Abstractions/PropertyEditors/Validators/DecimalValidator.cs @@ -6,7 +6,7 @@ namespace Umbraco.Core.PropertyEditors.Validators /// /// A validator that validates that the value is a valid decimal /// - internal sealed class DecimalValidator : IManifestValueValidator + public sealed class DecimalValidator : IManifestValueValidator { /// public string ValidationName => "Decimal"; diff --git a/src/Umbraco.Core/PropertyEditors/Validators/EmailValidator.cs b/src/Umbraco.Abstractions/PropertyEditors/Validators/EmailValidator.cs similarity index 92% rename from src/Umbraco.Core/PropertyEditors/Validators/EmailValidator.cs rename to src/Umbraco.Abstractions/PropertyEditors/Validators/EmailValidator.cs index 4df11e4f60..8fb6d0c31b 100644 --- a/src/Umbraco.Core/PropertyEditors/Validators/EmailValidator.cs +++ b/src/Umbraco.Abstractions/PropertyEditors/Validators/EmailValidator.cs @@ -6,7 +6,7 @@ namespace Umbraco.Core.PropertyEditors.Validators /// /// A validator that validates an email address /// - internal sealed class EmailValidator : IManifestValueValidator + public sealed class EmailValidator : IManifestValueValidator { /// public string ValidationName => "Email"; diff --git a/src/Umbraco.Core/PropertyEditors/Validators/IntegerValidator.cs b/src/Umbraco.Abstractions/PropertyEditors/Validators/IntegerValidator.cs similarity index 92% rename from src/Umbraco.Core/PropertyEditors/Validators/IntegerValidator.cs rename to src/Umbraco.Abstractions/PropertyEditors/Validators/IntegerValidator.cs index 335ddf7724..5274ff484b 100644 --- a/src/Umbraco.Core/PropertyEditors/Validators/IntegerValidator.cs +++ b/src/Umbraco.Abstractions/PropertyEditors/Validators/IntegerValidator.cs @@ -6,7 +6,7 @@ namespace Umbraco.Core.PropertyEditors.Validators /// /// A validator that validates that the value is a valid integer /// - internal sealed class IntegerValidator : IManifestValueValidator + public sealed class IntegerValidator : IManifestValueValidator { /// public string ValidationName => "Integer"; diff --git a/src/Umbraco.Abstractions/Services/ILocalizationService.cs b/src/Umbraco.Abstractions/Services/ILocalizationService.cs index 4ab71f8ea6..b8c4e21f2a 100644 --- a/src/Umbraco.Abstractions/Services/ILocalizationService.cs +++ b/src/Umbraco.Abstractions/Services/ILocalizationService.cs @@ -19,7 +19,7 @@ namespace Umbraco.Core.Services /// Adds or updates a translation for a dictionary item and language /// /// - /// + /// /// void AddOrUpdateDictionaryValue(IDictionaryItem item, ILanguage language, string value); diff --git a/src/Umbraco.Core/Services/IMembershipUserService.cs b/src/Umbraco.Abstractions/Services/IMembershipUserService.cs similarity index 100% rename from src/Umbraco.Core/Services/IMembershipUserService.cs rename to src/Umbraco.Abstractions/Services/IMembershipUserService.cs diff --git a/src/Umbraco.Core/Services/IUserService.cs b/src/Umbraco.Abstractions/Services/IUserService.cs similarity index 99% rename from src/Umbraco.Core/Services/IUserService.cs rename to src/Umbraco.Abstractions/Services/IUserService.cs index 35a3be9eac..950b4f548d 100644 --- a/src/Umbraco.Core/Services/IUserService.cs +++ b/src/Umbraco.Abstractions/Services/IUserService.cs @@ -1,9 +1,6 @@ using System; using System.Collections.Generic; -using System.Linq; -using Umbraco.Core.Models; using Umbraco.Core.Models.Membership; -using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.Querying; namespace Umbraco.Core.Services diff --git a/src/Umbraco.Abstractions/Umbraco.Abstractions.csproj b/src/Umbraco.Abstractions/Umbraco.Abstractions.csproj index a5e5a94520..b3a1b4fa25 100644 --- a/src/Umbraco.Abstractions/Umbraco.Abstractions.csproj +++ b/src/Umbraco.Abstractions/Umbraco.Abstractions.csproj @@ -7,6 +7,7 @@ + diff --git a/src/Umbraco.Core/Composing/CompositionExtensions/Services.cs b/src/Umbraco.Core/Composing/CompositionExtensions/Services.cs index 04028e4f31..b79e957c9c 100644 --- a/src/Umbraco.Core/Composing/CompositionExtensions/Services.cs +++ b/src/Umbraco.Core/Composing/CompositionExtensions/Services.cs @@ -89,11 +89,9 @@ namespace Umbraco.Core.Composing.CompositionExtensions private static LocalizedTextServiceFileSources SourcesFactory(IFactory container) { - var ioHelper = container.GetInstance(); - - var mainLangFolder = new DirectoryInfo(ioHelper.MapPath(SystemDirectories.Umbraco + "/config/lang/")); - var appPlugins = new DirectoryInfo(ioHelper.MapPath(SystemDirectories.AppPlugins)); - var configLangFolder = new DirectoryInfo(ioHelper.MapPath(SystemDirectories.Config + "/lang/")); + var mainLangFolder = new DirectoryInfo(Current.IOHelper.MapPath(Current.Configs.Global().UmbracoPath + "/config/lang/")); + var appPlugins = new DirectoryInfo(Current.IOHelper.MapPath(Constants.SystemDirectories.AppPlugins)); + var configLangFolder = new DirectoryInfo(Current.IOHelper.MapPath(Constants.SystemDirectories.Config + "/lang/")); var pluginLangFolders = appPlugins.Exists == false ? Enumerable.Empty() diff --git a/src/Umbraco.Core/Composing/Current.cs b/src/Umbraco.Core/Composing/Current.cs index 2b3cf30301..afc2a93ea0 100644 --- a/src/Umbraco.Core/Composing/Current.cs +++ b/src/Umbraco.Core/Composing/Current.cs @@ -205,8 +205,7 @@ namespace Umbraco.Core.Composing public static IVariationContextAccessor VariationContextAccessor => Factory.GetInstance(); - [Obsolete("being removed...", true)] - public static readonly IIOHelper IOHelper = new IOHelper(); + public static readonly IIOHelper IOHelper = Umbraco.Core.IO.IOHelper.Default; #endregion } diff --git a/src/Umbraco.Core/ConfigsExtensions.cs b/src/Umbraco.Core/ConfigsExtensions.cs index 87f0216b51..a75972bba5 100644 --- a/src/Umbraco.Core/ConfigsExtensions.cs +++ b/src/Umbraco.Core/ConfigsExtensions.cs @@ -33,9 +33,7 @@ namespace Umbraco.Core public static void AddCoreConfigs(this Configs configs) { - var ioHelper = Current.Factory.GetInstance(); - - var configDir = new DirectoryInfo(ioHelper.MapPath(SystemDirectories.Config)); + var configDir = new DirectoryInfo(Current.IOHelper.MapPath(Constants.SystemDirectories.Config)); configs.Add(() => new GlobalSettings(ioHelper)); configs.Add("umbracoConfiguration/settings"); diff --git a/src/Umbraco.Core/Configuration/GlobalSettings.cs b/src/Umbraco.Core/Configuration/GlobalSettings.cs index a0cf20b2e1..9f471c9704 100644 --- a/src/Umbraco.Core/Configuration/GlobalSettings.cs +++ b/src/Umbraco.Core/Configuration/GlobalSettings.cs @@ -177,9 +177,7 @@ namespace Umbraco.Core.Configuration /// Value of the setting to be saved. internal static void SaveSetting(string key, string value) { - var ioHelper = Current.Factory.GetInstance(); - - var fileName = ioHelper.MapPath(string.Format("{0}/web.config", SystemDirectories.Root)); + var fileName = Current.IOHelper.MapPath(string.Format("{0}/web.config", Current.IOHelper.Root)); var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace); var appSettings = xml.Root.DescendantsAndSelf("appSettings").Single(); @@ -201,7 +199,7 @@ namespace Umbraco.Core.Configuration /// Key of the setting to be removed. internal static void RemoveSetting(string key, IIOHelper ioHelper) { - var fileName = ioHelper.MapPath(string.Format("{0}/web.config", SystemDirectories.Root)); + var fileName = Current.IOHelper.MapPath(string.Format("{0}/web.config", Current.IOHelper.Root)); var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace); var appSettings = xml.Root.DescendantsAndSelf("appSettings").Single(); @@ -386,5 +384,43 @@ namespace Umbraco.Core.Configuration } } } + + private string _umbracoMediaPath = null; + public string UmbracoMediaPath => GetterWithDefaultValue(Constants.AppSettings.UmbracoMediaPath, "~/media", ref _umbracoMediaPath); + + private string _umbracoScriptsPath = null; + public string UmbracoScriptsPath => GetterWithDefaultValue(Constants.AppSettings.UmbracoScriptsPath, "~/scripts", ref _umbracoScriptsPath); + + private string _umbracoCssPath = null; + public string UmbracoCssPath => GetterWithDefaultValue(Constants.AppSettings.UmbracoCssPath, "~/css", ref _umbracoCssPath); + + private string _umbracoPath = null; + public string UmbracoPath => GetterWithDefaultValue(Constants.AppSettings.UmbracoPath, "~/umbraco", ref _umbracoPath); + + private T GetterWithDefaultValue(string appSettingKey, T defaultValue, ref T backingField) + { + if (backingField != null) return backingField; + + if (ConfigurationManager.AppSettings.ContainsKey(appSettingKey)) + { + try + { + var value = ConfigurationManager.AppSettings[appSettingKey]; + + backingField = (T)Convert.ChangeType(value, typeof(T)); + } + catch + { + /* ignore and use default value */ + backingField = defaultValue; + } + } + else + { + backingField = defaultValue; + } + + return backingField; + } } } diff --git a/src/Umbraco.Core/Configuration/GlobalSettingsExtensions.cs b/src/Umbraco.Core/Configuration/GlobalSettingsExtensions.cs index bc76caacee..5c45b41f43 100644 --- a/src/Umbraco.Core/Configuration/GlobalSettingsExtensions.cs +++ b/src/Umbraco.Core/Configuration/GlobalSettingsExtensions.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Threading; using System.Web; using System.Web.Routing; +using Umbraco.Core.Composing; using Umbraco.Core.IO; namespace Umbraco.Core.Configuration @@ -42,8 +43,8 @@ namespace Umbraco.Core.Configuration } var path = globalSettings.Path; - if (path.StartsWith(SystemDirectories.Root)) // beware of TrimStart, see U4-2518 - path = path.Substring(SystemDirectories.Root.Length); + if (path.StartsWith(Current.IOHelper.Root)) // beware of TrimStart, see U4-2518 + path = path.Substring(Current.IOHelper.Root.Length); return path.TrimStart('~').TrimStart('/').Replace('/', '-').Trim().ToLower(); } diff --git a/src/Umbraco.Core/ContentExtensions.cs b/src/Umbraco.Core/ContentExtensions.cs index 6195d68a13..07fc2757ea 100644 --- a/src/Umbraco.Core/ContentExtensions.cs +++ b/src/Umbraco.Core/ContentExtensions.cs @@ -108,7 +108,7 @@ namespace Umbraco.Core /// /// /// - public static IEnumerable GetNonGroupedProperties(this IContentBase content) + public static IEnumerable GetNonGroupedProperties(this IContentBase content) { return content.Properties .Where(x => x.PropertyType.PropertyGroupId == null) @@ -121,7 +121,7 @@ namespace Umbraco.Core /// /// /// - public static IEnumerable GetPropertiesForGroup(this IContentBase content, PropertyGroup propertyGroup) + public static IEnumerable GetPropertiesForGroup(this IContentBase content, PropertyGroup propertyGroup) { //get the properties for the current tab return content.Properties @@ -180,7 +180,7 @@ namespace Umbraco.Core } // gets or creates a property for a content item. - private static Property GetProperty(IContentBase content, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, string propertyTypeAlias) + private static IProperty GetProperty(IContentBase content, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, string propertyTypeAlias) { var property = content.Properties.FirstOrDefault(x => x.Alias.InvariantEquals(propertyTypeAlias)); if (property != null) return property; diff --git a/src/Umbraco.Core/ContentVariationExtensions.cs b/src/Umbraco.Core/ContentVariationExtensions.cs index 5b157307ab..bdcf300f3f 100644 --- a/src/Umbraco.Core/ContentVariationExtensions.cs +++ b/src/Umbraco.Core/ContentVariationExtensions.cs @@ -50,18 +50,18 @@ namespace Umbraco.Core /// Determines whether the property type varies by culture. /// /// And then it could also vary by segment. - public static bool VariesByCulture(this PropertyType propertyType) => propertyType.Variations.VariesByCulture(); + public static bool VariesByCulture(this IPropertyType propertyType) => propertyType.Variations.VariesByCulture(); /// /// Determines whether the property type varies by segment. /// /// And then it could also vary by culture. - public static bool VariesBySegment(this PropertyType propertyType) => propertyType.Variations.VariesBySegment(); + public static bool VariesBySegment(this IPropertyType propertyType) => propertyType.Variations.VariesBySegment(); /// /// Determines whether the property type varies by culture and segment. /// - public static bool VariesByCultureAndSegment(this PropertyType propertyType) => propertyType.Variations.VariesByCultureAndSegment(); + public static bool VariesByCultureAndSegment(this IPropertyType propertyType) => propertyType.Variations.VariesByCultureAndSegment(); /// /// Determines whether the content type is invariant. @@ -161,13 +161,13 @@ namespace Umbraco.Core if (variation.VariesByCulture()) { // varies by culture - // in exact mode, the culture cannot be null + // in exact mode, the culture cannot be null if (exact && culture == null) { if (throwIfInvalid) throw new NotSupportedException($"Culture may not be null because culture variation is enabled."); return false; - } + } } else { @@ -180,7 +180,7 @@ namespace Umbraco.Core throw new NotSupportedException($"Culture \"{culture}\" is invalid because culture variation is disabled."); return false; } - } + } // if it does not vary by segment // the segment cannot have a value diff --git a/src/Umbraco.Core/IO/IMediaFileSystem.cs b/src/Umbraco.Core/IO/IMediaFileSystem.cs index ed88516135..8ed0ba60ca 100644 --- a/src/Umbraco.Core/IO/IMediaFileSystem.cs +++ b/src/Umbraco.Core/IO/IMediaFileSystem.cs @@ -52,7 +52,7 @@ namespace Umbraco.Core.IO /// If an is provided then that file (and associated thumbnails if any) is deleted /// before the new file is saved, and depending on the media path scheme, the folder may be reused for the new file. /// - string StoreFile(IContentBase content, PropertyType propertyType, string filename, Stream filestream, string oldpath); + string StoreFile(IContentBase content, IPropertyType propertyType, string filename, Stream filestream, string oldpath); /// /// Copies a media file as a new media file, associated to a property of a content item. @@ -61,6 +61,6 @@ namespace Umbraco.Core.IO /// The property type owning the copy of the media file. /// The filesystem-relative path to the source media file. /// The filesystem-relative path to the copy of the media file. - string CopyFile(IContentBase content, PropertyType propertyType, string sourcepath); + string CopyFile(IContentBase content, IPropertyType propertyType, string sourcepath); } } diff --git a/src/Umbraco.Core/IO/IOHelper.cs b/src/Umbraco.Core/IO/IOHelper.cs index 36215b267c..c4fa57dd28 100644 --- a/src/Umbraco.Core/IO/IOHelper.cs +++ b/src/Umbraco.Core/IO/IOHelper.cs @@ -3,11 +3,10 @@ using System.Collections.Generic; using System.Globalization; using System.Reflection; using System.IO; -using System.Configuration; using System.Linq; using System.Web; using System.Web.Hosting; -using System.IO.Compression; +using Umbraco.Core.Configuration; namespace Umbraco.Core.IO { @@ -15,6 +14,7 @@ namespace Umbraco.Core.IO { internal static IIOHelper Default { get; } = new IOHelper(); + /// /// Gets or sets a value forcing Umbraco to consider it is non-hosted. /// @@ -39,10 +39,10 @@ namespace Umbraco.Core.IO string retval = virtualPath; if (virtualPath.StartsWith("~")) - retval = virtualPath.Replace("~", SystemDirectories.Root); + retval = virtualPath.Replace("~", Root); - if (virtualPath.StartsWith("/") && virtualPath.StartsWith(SystemDirectories.Root) == false) - retval = SystemDirectories.Root + "/" + virtualPath.TrimStart('/'); + if (virtualPath.StartsWith("/") && virtualPath.StartsWith(Root) == false) + retval = Root + "/" + virtualPath.TrimStart('/'); return retval; } @@ -57,11 +57,11 @@ namespace Umbraco.Core.IO public string ResolveUrl(string virtualPath) { if (virtualPath.StartsWith("~")) - return virtualPath.Replace("~", SystemDirectories.Root).Replace("//", "/"); + return virtualPath.Replace("~", Root).Replace("//", "/"); else if (Uri.IsWellFormedUriString(virtualPath, UriKind.Absolute)) return virtualPath; else - return VirtualPathUtility.ToAbsolute(virtualPath, SystemDirectories.Root); + return VirtualPathUtility.ToAbsolute(virtualPath, Root); } public Attempt TryResolveUrl(string virtualPath) @@ -69,10 +69,10 @@ namespace Umbraco.Core.IO try { if (virtualPath.StartsWith("~")) - return Attempt.Succeed(virtualPath.Replace("~", SystemDirectories.Root).Replace("//", "/")); + return Attempt.Succeed(virtualPath.Replace("~", Root).Replace("//", "/")); if (Uri.IsWellFormedUriString(virtualPath, UriKind.Absolute)) return Attempt.Succeed(virtualPath); - return Attempt.Succeed(VirtualPathUtility.ToAbsolute(virtualPath, SystemDirectories.Root)); + return Attempt.Succeed(VirtualPathUtility.ToAbsolute(virtualPath, Root)); } catch (Exception ex) { @@ -97,7 +97,7 @@ namespace Umbraco.Core.IO if (useHttpContext && HttpContext.Current != null) { //string retval; - if (String.IsNullOrEmpty(path) == false && (path.StartsWith("~") || path.StartsWith(SystemDirectories.Root))) + if (String.IsNullOrEmpty(path) == false && (path.StartsWith("~") || path.StartsWith(Root))) return HostingEnvironment.MapPath(path); else return HostingEnvironment.MapPath("~/" + path.TrimStart('/')); @@ -115,22 +115,7 @@ namespace Umbraco.Core.IO return MapPath(path, true); } - //use a tilde character instead of the complete path - public string ReturnPath(string settingsKey, string standardPath, bool useTilde) - { - var retval = ConfigurationManager.AppSettings[settingsKey]; - if (string.IsNullOrEmpty(retval)) - retval = standardPath; - - return retval.TrimEnd('/'); - } - - public string ReturnPath(string settingsKey, string standardPath) - { - return ReturnPath(settingsKey, standardPath, false); - - } /// /// Verifies that the current filepath matches a directory where the user is allowed to edit a file. @@ -160,7 +145,7 @@ namespace Umbraco.Core.IO // TODO: what's below is dirty, there are too many ways to get the root dir, etc. // not going to fix everything today - var mappedRoot = MapPath(SystemDirectories.Root); + var mappedRoot = MapPath(Root); if (filePath.StartsWith(mappedRoot) == false) filePath = MapPath(filePath); @@ -304,5 +289,27 @@ namespace Umbraco.Core.IO return path.EnsurePathIsApplicationRootPrefixed(); } + private string _root; + + /// + /// Gets the root path of the application + /// + public string Root + { + get + { + if (_root != null) return _root; + + var appPath = HttpRuntime.AppDomainAppVirtualPath; + // ReSharper disable once ConditionIsAlwaysTrueOrFalse + if (appPath == null || appPath == "/") appPath = string.Empty; + + _root = appPath; + + return _root; + } + //Only required for unit tests + set => _root = value; + } } } diff --git a/src/Umbraco.Core/IO/MediaFileSystem.cs b/src/Umbraco.Core/IO/MediaFileSystem.cs index 4ac9ca99b0..d2d04204a1 100644 --- a/src/Umbraco.Core/IO/MediaFileSystem.cs +++ b/src/Umbraco.Core/IO/MediaFileSystem.cs @@ -90,7 +90,7 @@ namespace Umbraco.Core.IO #region Associated Media Files /// - public string StoreFile(IContentBase content, PropertyType propertyType, string filename, Stream filestream, string oldpath) + public string StoreFile(IContentBase content, IPropertyType propertyType, string filename, Stream filestream, string oldpath) { if (content == null) throw new ArgumentNullException(nameof(content)); if (propertyType == null) throw new ArgumentNullException(nameof(propertyType)); @@ -109,7 +109,7 @@ namespace Umbraco.Core.IO } /// - public string CopyFile(IContentBase content, PropertyType propertyType, string sourcepath) + public string CopyFile(IContentBase content, IPropertyType propertyType, string sourcepath) { if (content == null) throw new ArgumentNullException(nameof(content)); if (propertyType == null) throw new ArgumentNullException(nameof(propertyType)); diff --git a/src/Umbraco.Core/IO/ShadowWrapper.cs b/src/Umbraco.Core/IO/ShadowWrapper.cs index 641e3845b6..54e7c2959f 100644 --- a/src/Umbraco.Core/IO/ShadowWrapper.cs +++ b/src/Umbraco.Core/IO/ShadowWrapper.cs @@ -8,7 +8,7 @@ namespace Umbraco.Core.IO { internal class ShadowWrapper : IFileSystem { - private static readonly string ShadowFsPath = SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs"; + private static readonly string ShadowFsPath = Constants.SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs"; private readonly Func _isScoped; private readonly IFileSystem _innerFileSystem; diff --git a/src/Umbraco.Core/IO/SystemDirectories.cs b/src/Umbraco.Core/IO/SystemDirectories.cs index d6c9e961b9..bfdd3f33ed 100644 --- a/src/Umbraco.Core/IO/SystemDirectories.cs +++ b/src/Umbraco.Core/IO/SystemDirectories.cs @@ -6,65 +6,7 @@ namespace Umbraco.Core.IO //all paths has a starting but no trailing / public class SystemDirectories { - private static IIOHelper IOHelper => Current.Factory.GetInstance(); - public static string Bin => "~/bin"; - public static string Config => "~/config"; - - public static string Data => "~/App_Data"; - - public static string TempData => Data + "/TEMP"; - - public static string TempFileUploads => TempData + "/FileUploads"; - - public static string TempImageUploads => TempFileUploads + "/rte"; - - public static string Install => "~/install"; - - public static string AppCode => "~/App_Code"; - - public static string AppPlugins => "~/App_Plugins"; - - public static string MvcViews => "~/Views"; - - public static string PartialViews => MvcViews + "/Partials/"; - - public static string MacroPartials => MvcViews + "/MacroPartials/"; - - public static string Media => IOHelper.ReturnPath("umbracoMediaPath", "~/media"); - - public static string Scripts => IOHelper.ReturnPath("umbracoScriptsPath", "~/scripts"); - - public static string Css => IOHelper.ReturnPath("umbracoCssPath", "~/css"); - - public static string Umbraco => IOHelper.ReturnPath("umbracoPath", "~/umbraco"); - - public static string Packages => Data + "/packages"; - - public static string Preview => Data + "/preview"; - - private static string _root; - - /// - /// Gets the root path of the application - /// - public static string Root - { - get - { - if (_root != null) return _root; - - var appPath = HttpRuntime.AppDomainAppVirtualPath; - // ReSharper disable once ConditionIsAlwaysTrueOrFalse - if (appPath == null || appPath == "/") appPath = string.Empty; - - _root = appPath; - - return _root; - } - //Only required for unit tests - internal set => _root = value; - } } } diff --git a/src/Umbraco.Core/IO/SystemFiles.cs b/src/Umbraco.Core/IO/SystemFiles.cs index 12e3f57d99..132945d130 100644 --- a/src/Umbraco.Core/IO/SystemFiles.cs +++ b/src/Umbraco.Core/IO/SystemFiles.cs @@ -1,11 +1,12 @@ using System.IO; +using Umbraco.Core.Composing; using Umbraco.Core.Configuration; namespace Umbraco.Core.IO { public class SystemFiles { - public static string TinyMceConfig => SystemDirectories.Config + "/tinyMceConfig.config"; + public static string TinyMceConfig => Constants.SystemDirectories.Config + "/tinyMceConfig.config"; // TODO: Kill this off we don't have umbraco.config XML cache we now have NuCache public static string GetContentCacheXml(IGlobalSettings globalSettings) diff --git a/src/Umbraco.Core/Manifest/DataEditorConverter.cs b/src/Umbraco.Core/Manifest/DataEditorConverter.cs index 86982e17f2..437d1eb159 100644 --- a/src/Umbraco.Core/Manifest/DataEditorConverter.cs +++ b/src/Umbraco.Core/Manifest/DataEditorConverter.cs @@ -1,9 +1,12 @@ using System; using Newtonsoft.Json; using Newtonsoft.Json.Linq; +using Umbraco.Core.Composing; +using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Serialization; +using Umbraco.Core.Services; namespace Umbraco.Core.Manifest { @@ -13,13 +16,19 @@ namespace Umbraco.Core.Manifest internal class DataEditorConverter : JsonReadConverter { private readonly ILogger _logger; + private readonly IIOHelper _ioHelper; + private readonly IDataTypeService _dataTypeService; + private readonly ILocalizationService _localizationService; /// /// Initializes a new instance of the class. /// - public DataEditorConverter(ILogger logger) + public DataEditorConverter(ILogger logger, IIOHelper ioHelper, IDataTypeService dataTypeService, ILocalizationService localizationService) { _logger = logger; + _ioHelper = ioHelper; + _dataTypeService = dataTypeService; + _localizationService = localizationService; } /// @@ -62,11 +71,11 @@ namespace Umbraco.Core.Manifest PrepareForPropertyEditor(jobject, dataEditor); else PrepareForParameterEditor(jobject, dataEditor); - + base.Deserialize(jobject, target, serializer); } - private static void PrepareForPropertyEditor(JObject jobject, DataEditor target) + private void PrepareForPropertyEditor(JObject jobject, DataEditor target) { if (jobject["editor"] == null) throw new InvalidOperationException("Missing 'editor' value."); @@ -74,7 +83,7 @@ namespace Umbraco.Core.Manifest // explicitly assign a value editor of type ValueEditor // (else the deserializer will try to read it before setting it) // (and besides it's an interface) - target.ExplicitValueEditor = new DataValueEditor(); + target.ExplicitValueEditor = new DataValueEditor(_dataTypeService, _localizationService); // in the manifest, validators are a simple dictionary eg // { @@ -86,6 +95,9 @@ namespace Umbraco.Core.Manifest if (jobject["editor"]["validation"] is JObject validation) jobject["editor"]["validation"] = RewriteValidators(validation); + if(jobject["editor"]["view"] is JValue view) + jobject["editor"]["view"] = RewriteVirtualUrl(view); + if (jobject["prevalues"] is JObject config) { // explicitly assign a configuration editor of type ConfigurationEditor @@ -100,6 +112,9 @@ namespace Umbraco.Core.Manifest { if (field["validation"] is JObject fvalidation) field["validation"] = RewriteValidators(fvalidation); + + if(field["view"] is JValue fview) + field["view"] = RewriteVirtualUrl(fview); } } @@ -118,7 +133,12 @@ namespace Umbraco.Core.Manifest } } - private static void PrepareForParameterEditor(JObject jobject, DataEditor target) + private string RewriteVirtualUrl(JValue view) + { + return _ioHelper.ResolveVirtualUrl(view.Value as string); + } + + private void PrepareForParameterEditor(JObject jobject, DataEditor target) { // in a manifest, a parameter editor looks like: // @@ -135,7 +155,7 @@ namespace Umbraco.Core.Manifest if (jobject.Property("view") != null) { // explicitly assign a value editor of type ParameterValueEditor - target.ExplicitValueEditor = new DataValueEditor(); + target.ExplicitValueEditor = new DataValueEditor(_dataTypeService, _localizationService); // move the 'view' property jobject["editor"] = new JObject { ["view"] = jobject["view"] }; @@ -148,6 +168,9 @@ namespace Umbraco.Core.Manifest jobject["defaultConfig"] = config; jobject.Remove("config"); } + + if(jobject["editor"]?["view"] is JValue view) // We need to null check, if view do not exists, then editor do not exists + jobject["editor"]["view"] = RewriteVirtualUrl(view); } private static JArray RewriteValidators(JObject validation) diff --git a/src/Umbraco.Core/Manifest/ManifestContentAppFactory.cs b/src/Umbraco.Core/Manifest/ManifestContentAppFactory.cs index 1c50a4b895..e2c3ee48fa 100644 --- a/src/Umbraco.Core/Manifest/ManifestContentAppFactory.cs +++ b/src/Umbraco.Core/Manifest/ManifestContentAppFactory.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; +using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.Models.ContentEditing; using Umbraco.Core.Models.Membership; @@ -31,10 +32,12 @@ namespace Umbraco.Core.Manifest public class ManifestContentAppFactory : IContentAppFactory { private readonly ManifestContentAppDefinition _definition; + private readonly IIOHelper _ioHelper; - public ManifestContentAppFactory(ManifestContentAppDefinition definition) + public ManifestContentAppFactory(ManifestContentAppDefinition definition, IIOHelper ioHelper) { _definition = definition; + _ioHelper = ioHelper; } private ContentApp _app; @@ -132,7 +135,7 @@ namespace Umbraco.Core.Manifest Alias = _definition.Alias, Name = _definition.Name, Icon = _definition.Icon, - View = _definition.View, + View = _ioHelper.ResolveVirtualUrl(_definition.View), Weight = _definition.Weight }); } diff --git a/src/Umbraco.Core/Manifest/ManifestDashboard.cs b/src/Umbraco.Core/Manifest/ManifestDashboard.cs deleted file mode 100644 index 33af12e3cd..0000000000 --- a/src/Umbraco.Core/Manifest/ManifestDashboard.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.ComponentModel; -using Newtonsoft.Json; -using Umbraco.Core.Composing; -using Umbraco.Core.Dashboards; -using Umbraco.Core.IO; - -namespace Umbraco.Core.Manifest -{ - public class ManifestDashboard : IDashboard - { - private string _view; - - [JsonProperty("alias", Required = Required.Always)] - public string Alias { get; set; } - - [JsonProperty("weight", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - [DefaultValue(100)] // must be equal to DashboardCollectionBuilder.DefaultWeight - public int Weight { get; set; } - - [JsonProperty("view", Required = Required.Always)] - public string View - { - get => _view; - set => _view = Current.IOHelper.ResolveVirtualUrl(value); - } - - [JsonProperty("sections")] - public string[] Sections { get; set; } = Array.Empty(); - - [JsonProperty("access")] - public IAccessRule[] AccessRules { get; set; } = Array.Empty(); - } -} diff --git a/src/Umbraco.Core/Manifest/ManifestParser.cs b/src/Umbraco.Core/Manifest/ManifestParser.cs index 9a34735987..75fdde487c 100644 --- a/src/Umbraco.Core/Manifest/ManifestParser.cs +++ b/src/Umbraco.Core/Manifest/ManifestParser.cs @@ -5,24 +5,28 @@ using System.Linq; using System.Text; using Newtonsoft.Json; using Umbraco.Core.Cache; -using Umbraco.Core.Composing; using Umbraco.Core.Exceptions; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Serialization; +using Umbraco.Core.Services; namespace Umbraco.Core.Manifest { /// /// Parses the Main.js file and replaces all tokens accordingly. /// - public class ManifestParser + public class ManifestParser : IManifestParser { + private readonly IJsonSerializer _jsonSerializer; private static readonly string Utf8Preamble = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble()); private readonly IAppPolicyCache _cache; private readonly ILogger _logger; private readonly IIOHelper _ioHelper; + private readonly IDataTypeService _dataTypeService; + private readonly ILocalizationService _localizationService; private readonly ManifestValueValidatorCollection _validators; private readonly ManifestFilterCollection _filters; @@ -31,23 +35,29 @@ namespace Umbraco.Core.Manifest /// /// Initializes a new instance of the class. /// - public ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ManifestFilterCollection filters, ILogger logger, IIOHelper ioHelper) - : this(appCaches, validators, filters, "~/App_Plugins", logger, ioHelper) - { } + public ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ManifestFilterCollection filters, ILogger logger, IIOHelper ioHelper, IDataTypeService dataTypeService, ILocalizationService localizationService, IJsonSerializer jsonSerializer) + : this(appCaches, validators, filters, "~/App_Plugins", logger, ioHelper, dataTypeService, localizationService) + { + _jsonSerializer = jsonSerializer; + } /// /// Initializes a new instance of the class. /// - private ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ManifestFilterCollection filters, string path, ILogger logger, IIOHelper ioHelper) + private ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ManifestFilterCollection filters, string path, ILogger logger, IIOHelper ioHelper, IDataTypeService dataTypeService, ILocalizationService localizationService) { if (appCaches == null) throw new ArgumentNullException(nameof(appCaches)); _cache = appCaches.RuntimeCache; + _ioHelper = ioHelper; + _dataTypeService = dataTypeService; + _localizationService = localizationService; _validators = validators ?? throw new ArgumentNullException(nameof(validators)); _filters = filters ?? throw new ArgumentNullException(nameof(filters)); if (string.IsNullOrWhiteSpace(path)) throw new ArgumentNullOrEmptyException(nameof(path)); + Path = path; _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - _ioHelper = ioHelper; + } public string Path @@ -156,13 +166,13 @@ namespace Umbraco.Core.Manifest /// /// Parses a manifest. /// - internal PackageManifest ParseManifest(string text) + public PackageManifest ParseManifest(string text) { if (string.IsNullOrWhiteSpace(text)) throw new ArgumentNullOrEmptyException(nameof(text)); var manifest = JsonConvert.DeserializeObject(text, - new DataEditorConverter(_logger), + new DataEditorConverter(_logger, _ioHelper, _dataTypeService, _localizationService), new ValueValidatorConverter(_validators), new DashboardAccessRuleConverter()); @@ -171,6 +181,19 @@ namespace Umbraco.Core.Manifest manifest.Scripts[i] = _ioHelper.ResolveVirtualUrl(manifest.Scripts[i]); for (var i = 0; i < manifest.Stylesheets.Length; i++) manifest.Stylesheets[i] = _ioHelper.ResolveVirtualUrl(manifest.Stylesheets[i]); + foreach (var contentApp in manifest.ContentApps) + { + contentApp.View = _ioHelper.ResolveVirtualUrl(contentApp.View); + } + foreach (var dashboard in manifest.Dashboards) + { + dashboard.View = _ioHelper.ResolveVirtualUrl(dashboard.View); + } + foreach (var gridEditor in manifest.GridEditors) + { + gridEditor.View = _ioHelper.ResolveVirtualUrl(gridEditor.View); + gridEditor.Render = _ioHelper.ResolveVirtualUrl(gridEditor.Render); + } // add property editors that are also parameter editors, to the parameter editors list // (the manifest format is kinda legacy) @@ -182,9 +205,9 @@ namespace Umbraco.Core.Manifest } // purely for tests - internal IEnumerable ParseGridEditors(string text) + public IEnumerable ParseGridEditors(string text) { - return JsonConvert.DeserializeObject>(text); + return _jsonSerializer.Deserialize>(text); } } } diff --git a/src/Umbraco.Core/Models/ContentBase.cs b/src/Umbraco.Core/Models/ContentBase.cs index fbb68194b7..c87cb0a370 100644 --- a/src/Umbraco.Core/Models/ContentBase.cs +++ b/src/Umbraco.Core/Models/ContentBase.cs @@ -20,7 +20,7 @@ namespace Umbraco.Core.Models { private int _contentTypeId; private int _writerId; - private PropertyCollection _properties; + private IPropertyCollection _properties; private ContentCultureInfosCollection _cultureInfos; internal IReadOnlyList AllPropertyTypes { get; } @@ -135,7 +135,7 @@ namespace Umbraco.Core.Models /// [DataMember] [DoNotClone] - public PropertyCollection Properties + public IPropertyCollection Properties { get => _properties; set @@ -490,7 +490,7 @@ namespace Umbraco.Core.Models if (clonedContent._properties != null) { clonedContent._properties.CollectionChanged -= PropertiesChanged; //clear this event handler if any - clonedContent._properties = (PropertyCollection)_properties.DeepClone(); //manually deep clone + clonedContent._properties = (IPropertyCollection)_properties.DeepClone(); //manually deep clone clonedContent._properties.CollectionChanged += clonedContent.PropertiesChanged; //re-assign correct event handler } diff --git a/src/Umbraco.Core/Models/ContentEditing/ContentAppBadgeType.cs b/src/Umbraco.Core/Models/ContentEditing/ContentAppBadgeType.cs deleted file mode 100644 index c3217099b6..0000000000 --- a/src/Umbraco.Core/Models/ContentEditing/ContentAppBadgeType.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace Umbraco.Core.Models.ContentEditing -{ - using System.Runtime.Serialization; - - using Newtonsoft.Json; - using Newtonsoft.Json.Converters; - - /// - /// Represent the content app badge types - /// - [DataContract(Name = "contentAppBadgeType")] - [JsonConverter(typeof(StringEnumConverter))] - public enum ContentAppBadgeType - { - [EnumMember(Value = "default")] - Default = 0, - - [EnumMember(Value = "warning")] - Warning = 1, - - [EnumMember(Value = "alert")] - Alert = 2 - } -} diff --git a/src/Umbraco.Core/Models/ContentTagsExtensions.cs b/src/Umbraco.Core/Models/ContentTagsExtensions.cs index dd7a716520..7f9c012722 100644 --- a/src/Umbraco.Core/Models/ContentTagsExtensions.cs +++ b/src/Umbraco.Core/Models/ContentTagsExtensions.cs @@ -34,7 +34,7 @@ namespace Umbraco.Core.Models } // gets and validates the property - private static Property GetTagProperty(this IContentBase content, string propertyTypeAlias) + private static IProperty GetTagProperty(this IContentBase content, string propertyTypeAlias) { if (content == null) throw new ArgumentNullException(nameof(content)); diff --git a/src/Umbraco.Core/Models/Membership/MembershipUserExtensions.cs b/src/Umbraco.Core/Models/Membership/MembershipUserExtensions.cs index 831300051b..5100380ead 100644 --- a/src/Umbraco.Core/Models/Membership/MembershipUserExtensions.cs +++ b/src/Umbraco.Core/Models/Membership/MembershipUserExtensions.cs @@ -30,7 +30,7 @@ namespace Umbraco.Core.Models.Membership /// Returns the currently configured membership scenario for members in umbraco /// /// - internal static MembershipScenario GetMembershipScenario(this IMemberService memberService) + internal static MembershipScenario GetMembershipScenario(this IMemberTypeService memberTypeService) { if (_scenario.HasValue == false) { @@ -39,7 +39,7 @@ namespace Umbraco.Core.Models.Membership { return MembershipScenario.NativeUmbraco; } - var memberType = Current.Services.MemberTypeService.Get(Constants.Conventions.MemberTypes.DefaultAlias); + var memberType = memberTypeService.Get(Constants.Conventions.MemberTypes.DefaultAlias); return memberType != null ? MembershipScenario.CustomProviderWithUmbracoLink : MembershipScenario.StandaloneCustomProvider; diff --git a/src/Umbraco.Core/Models/Property.cs b/src/Umbraco.Core/Models/Property.cs index 76349823ac..9aa9ab4d74 100644 --- a/src/Umbraco.Core/Models/Property.cs +++ b/src/Umbraco.Core/Models/Property.cs @@ -13,16 +13,16 @@ namespace Umbraco.Core.Models /// [Serializable] [DataContract(IsReference = true)] - public class Property : EntityBase + public class Property : EntityBase, IProperty { // _values contains all property values, including the invariant-neutral value - private List _values = new List(); + private List _values = new List(); // _pvalue contains the invariant-neutral property value - private PropertyValue _pvalue; + private IPropertyValue _pvalue; // _vvalues contains the (indexed) variant property values - private Dictionary _vvalues; + private Dictionary _vvalues; /// /// Initializes a new instance of the class. @@ -33,7 +33,7 @@ namespace Umbraco.Core.Models /// /// Initializes a new instance of the class. /// - public Property(PropertyType propertyType) + public Property(IPropertyType propertyType) { PropertyType = propertyType; } @@ -41,7 +41,7 @@ namespace Umbraco.Core.Models /// /// Initializes a new instance of the class. /// - public Property(int id, PropertyType propertyType) + public Property(int id, IPropertyType propertyType) { Id = id; PropertyType = propertyType; @@ -50,7 +50,7 @@ namespace Umbraco.Core.Models /// /// Represents a property value. /// - public class PropertyValue + public class PropertyValue : IPropertyValue { // TODO: Either we allow change tracking at this class level, or we add some special change tracking collections to the Property // class to deal with change tracking which variants have changed @@ -66,7 +66,7 @@ namespace Umbraco.Core.Models public string Culture { get => _culture; - internal set => _culture = value.IsNullOrWhiteSpace() ? null : value.ToLowerInvariant(); + set => _culture = value.IsNullOrWhiteSpace() ? null : value.ToLowerInvariant(); } /// @@ -77,23 +77,23 @@ namespace Umbraco.Core.Models public string Segment { get => _segment; - internal set => _segment = value?.ToLowerInvariant(); + set => _segment = value?.ToLowerInvariant(); } /// /// Gets or sets the edited value of the property. /// - public object EditedValue { get; internal set; } + public object EditedValue { get; set; } /// /// Gets or sets the published value of the property. /// - public object PublishedValue { get; internal set; } + public object PublishedValue { get; set; } /// /// Clones the property value. /// - public PropertyValue Clone() + public IPropertyValue Clone() => new PropertyValue { _culture = _culture, _segment = _segment, PublishedValue = PublishedValue, EditedValue = EditedValue }; } @@ -121,13 +121,13 @@ namespace Umbraco.Core.Models /// Returns the PropertyType, which this Property is based on /// [IgnoreDataMember] - public PropertyType PropertyType { get; private set; } + public IPropertyType PropertyType { get; private set; } /// /// Gets the list of values. /// [DataMember] - public IReadOnlyCollection Values + public IReadOnlyCollection Values { get => _values; set @@ -152,7 +152,7 @@ namespace Umbraco.Core.Models /// Returns the Id of the PropertyType, which this Property is based on /// [IgnoreDataMember] - internal int PropertyTypeId => PropertyType.Id; + public int PropertyTypeId => PropertyType.Id; /// /// Returns the DatabaseType that the underlaying DataType is using to store its values @@ -161,7 +161,7 @@ namespace Umbraco.Core.Models /// Only used internally when saving the property value. /// [IgnoreDataMember] - internal ValueStorageType ValueStorageType => PropertyType.ValueStorageType; + public ValueStorageType ValueStorageType => PropertyType.ValueStorageType; /// /// Gets the value. @@ -180,7 +180,7 @@ namespace Umbraco.Core.Models : null; } - private object GetPropertyValue(PropertyValue pvalue, bool published) + private object GetPropertyValue(IPropertyValue pvalue, bool published) { if (pvalue == null) return null; @@ -191,7 +191,7 @@ namespace Umbraco.Core.Models // internal - must be invoked by the content item // does *not* validate the value - content item must validate first - internal void PublishValues(string culture = "*", string segment = "*") + public void PublishValues(string culture = "*", string segment = "*") { culture = culture.NullOrWhiteSpaceAsNull(); segment = segment.NullOrWhiteSpaceAsNull(); @@ -216,7 +216,7 @@ namespace Umbraco.Core.Models } // internal - must be invoked by the content item - internal void UnpublishValues(string culture = "*", string segment = "*") + public void UnpublishValues(string culture = "*", string segment = "*") { culture = culture.NullOrWhiteSpaceAsNull(); segment = segment.NullOrWhiteSpaceAsNull(); @@ -240,7 +240,7 @@ namespace Umbraco.Core.Models UnpublishValue(pvalue); } - private void PublishValue(PropertyValue pvalue) + private void PublishValue(IPropertyValue pvalue) { if (pvalue == null) return; @@ -251,7 +251,7 @@ namespace Umbraco.Core.Models DetectChanges(pvalue.EditedValue, origValue, nameof(Values), PropertyValueComparer, false); } - private void UnpublishValue(PropertyValue pvalue) + private void UnpublishValue(IPropertyValue pvalue) { if (pvalue == null) return; @@ -294,7 +294,7 @@ namespace Umbraco.Core.Models pvalue.EditedValue = value; } - private (PropertyValue, bool) GetPValue(bool create) + private (IPropertyValue, bool) GetPValue(bool create) { var change = false; if (_pvalue == null) @@ -307,7 +307,7 @@ namespace Umbraco.Core.Models return (_pvalue, change); } - private (PropertyValue, bool) GetPValue(string culture, string segment, bool create) + private (IPropertyValue, bool) GetPValue(string culture, string segment, bool create) { if (culture == null && segment == null) return GetPValue(create); @@ -316,7 +316,7 @@ namespace Umbraco.Core.Models if (_vvalues == null) { if (!create) return (null, false); - _vvalues = new Dictionary(); + _vvalues = new Dictionary(); change = true; } var k = new CompositeNStringNStringKey(culture, segment); diff --git a/src/Umbraco.Core/Models/PropertyCollection.cs b/src/Umbraco.Core/Models/PropertyCollection.cs index c587a45424..b82fd71eaf 100644 --- a/src/Umbraco.Core/Models/PropertyCollection.cs +++ b/src/Umbraco.Core/Models/PropertyCollection.cs @@ -12,11 +12,9 @@ namespace Umbraco.Core.Models /// [Serializable] [DataContract(IsReference = true)] - public class PropertyCollection : KeyedCollection, INotifyCollectionChanged, IDeepCloneable + public class PropertyCollection : KeyedCollection, IPropertyCollection { private readonly object _addLocker = new object(); - - internal Func AdditionValidator { get; set; } /// /// Initializes a new instance of the class. @@ -25,16 +23,6 @@ namespace Umbraco.Core.Models : base(StringComparer.InvariantCultureIgnoreCase) { } - /// - /// Initializes a new instance of the class. - /// - /// A function validating added properties. - internal PropertyCollection(Func additionValidator) - : this() - { - AdditionValidator = additionValidator; - } - /// /// Initializes a new instance of the class. /// @@ -47,7 +35,7 @@ namespace Umbraco.Core.Models /// /// Replaces all properties, whilst maintaining validation delegates. /// - internal void Reset(IEnumerable properties) + private void Reset(IEnumerable properties) { //collection events will be raised in each of these calls Clear(); @@ -60,7 +48,7 @@ namespace Umbraco.Core.Models /// /// Replaces the property at the specified index with the specified property. /// - protected override void SetItem(int index, Property property) + protected override void SetItem(int index, IProperty property) { var oldItem = index >= 0 ? this[index] : property; base.SetItem(index, property); @@ -80,7 +68,7 @@ namespace Umbraco.Core.Models /// /// Inserts the specified property at the specified index. /// - protected override void InsertItem(int index, Property property) + protected override void InsertItem(int index, IProperty property) { base.InsertItem(index, property); OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, property)); @@ -95,10 +83,8 @@ namespace Umbraco.Core.Models OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } - /// - /// Adds or updates a property. - /// - internal new void Add(Property property) + /// + public new void Add(IProperty property) { lock (_addLocker) // TODO: why are we locking here and not everywhere else?! { @@ -131,7 +117,7 @@ namespace Umbraco.Core.Models /// /// Gets the index for a specified property alias. /// - public int IndexOfKey(string key) + private int IndexOfKey(string key) { for (var i = 0; i < Count; i++) { @@ -141,7 +127,7 @@ namespace Umbraco.Core.Models return -1; } - protected override string GetKeyForItem(Property item) + protected override string GetKeyForItem(IProperty item) { return item.Alias; } @@ -149,7 +135,7 @@ namespace Umbraco.Core.Models /// /// Gets the property with the specified PropertyType. /// - internal Property this[PropertyType propertyType] + internal IProperty this[IPropertyType propertyType] { get { @@ -157,7 +143,7 @@ namespace Umbraco.Core.Models } } - public bool TryGetValue(string propertyTypeAlias, out Property property) + public bool TryGetValue(string propertyTypeAlias, out IProperty property) { property = this.FirstOrDefault(x => x.Alias.InvariantEquals(propertyTypeAlias)); return property != null; @@ -173,10 +159,9 @@ namespace Umbraco.Core.Models CollectionChanged?.Invoke(this, args); } - /// - /// Ensures that the collection contains properties for the specified property types. - /// - protected internal void EnsurePropertyTypes(IEnumerable propertyTypes) + + /// + public void EnsurePropertyTypes(IEnumerable propertyTypes) { if (propertyTypes == null) return; @@ -185,10 +170,9 @@ namespace Umbraco.Core.Models Add(new Property(propertyType)); } - /// - /// Ensures that the collection does not contain properties not in the specified property types. - /// - protected internal void EnsureCleanPropertyTypes(IEnumerable propertyTypes) + + /// + public void EnsureCleanPropertyTypes(IEnumerable propertyTypes) { if (propertyTypes == null) return; diff --git a/src/Umbraco.Core/Models/PropertyTagsExtensions.cs b/src/Umbraco.Core/Models/PropertyTagsExtensions.cs index 63cf870221..1bac5c98f1 100644 --- a/src/Umbraco.Core/Models/PropertyTagsExtensions.cs +++ b/src/Umbraco.Core/Models/PropertyTagsExtensions.cs @@ -20,7 +20,7 @@ namespace Umbraco.Core.Models // gets the tag configuration for a property // from the datatype configuration, and the editor tag configuration attribute - internal static TagConfiguration GetTagConfiguration(this Property property) + internal static TagConfiguration GetTagConfiguration(this IProperty property) { if (property == null) throw new ArgumentNullException(nameof(property)); @@ -44,7 +44,7 @@ namespace Umbraco.Core.Models /// The tags. /// A value indicating whether to merge the tags with existing tags instead of replacing them. /// A culture, for multi-lingual properties. - public static void AssignTags(this Property property, IEnumerable tags, bool merge = false, string culture = null) + public static void AssignTags(this IProperty property, IEnumerable tags, bool merge = false, string culture = null) { if (property == null) throw new ArgumentNullException(nameof(property)); @@ -56,7 +56,7 @@ namespace Umbraco.Core.Models } // assumes that parameters are consistent with the datatype configuration - private static void AssignTags(this Property property, IEnumerable tags, bool merge, TagsStorageType storageType, char delimiter, string culture) + private static void AssignTags(this IProperty property, IEnumerable tags, bool merge, TagsStorageType storageType, char delimiter, string culture) { // set the property value var trimmedTags = tags.Select(x => x.Trim()).ToArray(); @@ -97,7 +97,7 @@ namespace Umbraco.Core.Models /// The property. /// The tags. /// A culture, for multi-lingual properties. - public static void RemoveTags(this Property property, IEnumerable tags, string culture = null) + public static void RemoveTags(this IProperty property, IEnumerable tags, string culture = null) { if (property == null) throw new ArgumentNullException(nameof(property)); @@ -109,7 +109,7 @@ namespace Umbraco.Core.Models } // assumes that parameters are consistent with the datatype configuration - private static void RemoveTags(this Property property, IEnumerable tags, TagsStorageType storageType, char delimiter, string culture) + private static void RemoveTags(this IProperty property, IEnumerable tags, TagsStorageType storageType, char delimiter, string culture) { // already empty = nothing to do var value = property.GetValue(culture)?.ToString(); @@ -131,7 +131,7 @@ namespace Umbraco.Core.Models } // used by ContentRepositoryBase - internal static IEnumerable GetTagsValue(this Property property, string culture = null) + internal static IEnumerable GetTagsValue(this IProperty property, string culture = null) { if (property == null) throw new ArgumentNullException(nameof(property)); @@ -142,7 +142,7 @@ namespace Umbraco.Core.Models return property.GetTagsValue(configuration.StorageType, configuration.Delimiter, culture); } - private static IEnumerable GetTagsValue(this Property property, TagsStorageType storageType, char delimiter, string culture = null) + private static IEnumerable GetTagsValue(this IProperty property, TagsStorageType storageType, char delimiter, string culture = null) { if (property == null) throw new ArgumentNullException(nameof(property)); @@ -182,7 +182,7 @@ namespace Umbraco.Core.Models /// This is used both by the content repositories to initialize a property with some tag values, and by the /// content controllers to update a property with values received from the property editor. /// - internal static void SetTagsValue(this Property property, object value, TagConfiguration tagConfiguration, string culture) + internal static void SetTagsValue(this IProperty property, object value, TagConfiguration tagConfiguration, string culture) { if (property == null) throw new ArgumentNullException(nameof(property)); if (tagConfiguration == null) throw new ArgumentNullException(nameof(tagConfiguration)); @@ -195,7 +195,7 @@ namespace Umbraco.Core.Models // assumes that parameters are consistent with the datatype configuration // value can be an enumeration of string, or a serialized value using storageType format - private static void SetTagsValue(Property property, object value, TagsStorageType storageType, char delimiter, string culture) + private static void SetTagsValue(IProperty property, object value, TagsStorageType storageType, char delimiter, string culture) { if (value == null) value = Enumerable.Empty(); diff --git a/src/Umbraco.Core/Models/PropertyType.cs b/src/Umbraco.Core/Models/PropertyType.cs index 40af478ab8..3cbe1ab70b 100644 --- a/src/Umbraco.Core/Models/PropertyType.cs +++ b/src/Umbraco.Core/Models/PropertyType.cs @@ -13,7 +13,7 @@ namespace Umbraco.Core.Models [Serializable] [DataContract(IsReference = true)] [DebuggerDisplay("Id: {Id}, Name: {Name}, Alias: {Alias}")] - public class PropertyType : EntityBase, IEquatable + public class PropertyType : EntityBase, IPropertyType, IEquatable { private readonly bool _forceValueStorageType; private string _name; @@ -36,7 +36,7 @@ namespace Umbraco.Core.Models { if (dataType == null) throw new ArgumentNullException(nameof(dataType)); - if(dataType.HasIdentity) + if (dataType.HasIdentity) _dataTypeId = dataType.Id; _propertyEditorAlias = dataType.EditorAlias; @@ -58,14 +58,16 @@ namespace Umbraco.Core.Models /// public PropertyType(string propertyEditorAlias, ValueStorageType valueStorageType) : this(propertyEditorAlias, valueStorageType, false) - { } + { + } /// /// Initializes a new instance of the class. /// public PropertyType(string propertyEditorAlias, ValueStorageType valueStorageType, string propertyTypeAlias) : this(propertyEditorAlias, valueStorageType, false, propertyTypeAlias) - { } + { + } /// /// Initializes a new instance of the class. @@ -99,9 +101,7 @@ namespace Umbraco.Core.Models /// public bool SupportsPublishing { get; internal set; } - /// - /// Gets of sets the name of the property type. - /// + /// [DataMember] public string Name { @@ -109,9 +109,7 @@ namespace Umbraco.Core.Models set => SetPropertyValueAndDetectChanges(value, ref _name, nameof(Name)); } - /// - /// Gets of sets the alias of the property type. - /// + /// [DataMember] public virtual string Alias { @@ -119,9 +117,7 @@ namespace Umbraco.Core.Models set => SetPropertyValueAndDetectChanges(SanitizeAlias(value), ref _alias, nameof(Alias)); } - /// - /// Gets of sets the description of the property type. - /// + /// [DataMember] public string Description { @@ -129,9 +125,7 @@ namespace Umbraco.Core.Models set => SetPropertyValueAndDetectChanges(value, ref _description, nameof(Description)); } - /// - /// Gets or sets the identifier of the datatype for this property type. - /// + /// [DataMember] public int DataTypeId { @@ -146,9 +140,7 @@ namespace Umbraco.Core.Models set => SetPropertyValueAndDetectChanges(value, ref _dataTypeKey, nameof(DataTypeKey)); } - /// - /// Gets or sets the alias of the property editor for this property type. - /// + /// [DataMember] public string PropertyEditorAlias { @@ -156,11 +148,9 @@ namespace Umbraco.Core.Models set => SetPropertyValueAndDetectChanges(value, ref _propertyEditorAlias, nameof(PropertyEditorAlias)); } - /// - /// Gets or sets the database type for storing value for this property type. - /// + /// [DataMember] - internal ValueStorageType ValueStorageType + public ValueStorageType ValueStorageType { get => _valueStorageType; set @@ -170,20 +160,16 @@ namespace Umbraco.Core.Models } } - /// - /// Gets or sets the identifier of the property group this property type belongs to. - /// - /// For generic properties, the value is null. + /// [DataMember] - internal Lazy PropertyGroupId + public Lazy PropertyGroupId { get => _propertyGroupId; set => SetPropertyValueAndDetectChanges(value, ref _propertyGroupId, nameof(PropertyGroupId)); } - /// - /// Gets of sets a value indicating whether a value for this property type is required. - /// + + /// [DataMember] public bool Mandatory { @@ -191,9 +177,8 @@ namespace Umbraco.Core.Models set => SetPropertyValueAndDetectChanges(value, ref _mandatory, nameof(Mandatory)); } - /// - /// Gets of sets the sort order of the property type. - /// + + /// [DataMember] public int SortOrder { @@ -201,9 +186,7 @@ namespace Umbraco.Core.Models set => SetPropertyValueAndDetectChanges(value, ref _sortOrder, nameof(SortOrder)); } - /// - /// Gets or sets the regular expression validating the property values. - /// + /// [DataMember] public string ValidationRegExp { @@ -211,21 +194,14 @@ namespace Umbraco.Core.Models set => SetPropertyValueAndDetectChanges(value, ref _validationRegExp, nameof(ValidationRegExp)); } - /// - /// Gets or sets the content variation of the property type. - /// + /// public ContentVariation Variations { get => _variations; set => SetPropertyValueAndDetectChanges(value, ref _variations, nameof(Variations)); } - /// - /// Determines whether the property type supports a combination of culture and segment. - /// - /// The culture. - /// The segment. - /// A value indicating whether wildcards are valid. + /// public bool SupportsVariation(string culture, string segment, bool wildcards = false) { // exact validation: cannot accept a 'null' culture if the property type varies @@ -249,7 +225,7 @@ namespace Umbraco.Core.Models /// If the value is of the expected type, it can be directly assigned to the property. /// Otherwise, some conversion is required. /// - public bool IsOfExpectedPropertyType(object value) + private bool IsOfExpectedPropertyType(object value) { // null values are assumed to be ok if (value == null) @@ -275,19 +251,7 @@ namespace Umbraco.Core.Models } } - /// - /// Determines whether a value can be assigned to a property. - /// - public bool IsValueAssignable(object value) => TryConvertAssignedValue(value, false, out _); - - /// - /// Converts a value assigned to a property. - /// - /// - /// The input value can be pretty much anything, and is converted to the actual CLR type - /// expected by the property (eg an integer if the property values are integers). - /// Throws if the value cannot be converted. - /// + /// public object ConvertAssignedValue(object value) => TryConvertAssignedValue(value, true, out var converted) ? converted : null; /// @@ -296,8 +260,6 @@ namespace Umbraco.Core.Models /// /// /// - public bool TryConvertAssignedValue(object value, out object converted) => TryConvertAssignedValue(value, false, out converted); - private bool TryConvertAssignedValue(object value, bool throwOnError, out object converted) { var isOfExpectedType = IsOfExpectedPropertyType(value); @@ -332,6 +294,7 @@ namespace Umbraco.Core.Models converted = convInt.Result; return true; } + if (throwOnError) ThrowTypeException(value, typeof(int), Alias); return false; @@ -347,6 +310,7 @@ namespace Umbraco.Core.Models converted = convDecimal.Result.Normalize(); return true; } + if (throwOnError) ThrowTypeException(value, typeof(decimal), Alias); return false; @@ -360,6 +324,7 @@ namespace Umbraco.Core.Models converted = convDateTime.Result; return true; } + if (throwOnError) ThrowTypeException(value, typeof(DateTime), Alias); return false; @@ -413,7 +378,7 @@ namespace Umbraco.Core.Models { base.PerformDeepClone(clone); - var clonedEntity = (PropertyType)clone; + var clonedEntity = (PropertyType) clone; //need to manually assign the Lazy value as it will not be automatically mapped if (PropertyGroupId != null) diff --git a/src/Umbraco.Core/Models/SimpleContentType.cs b/src/Umbraco.Core/Models/SimpleContentType.cs index 5c81017ec8..fc84d15529 100644 --- a/src/Umbraco.Core/Models/SimpleContentType.cs +++ b/src/Umbraco.Core/Models/SimpleContentType.cs @@ -105,6 +105,7 @@ namespace Umbraco.Core.Models // we have to have all this, because we're an IUmbracoEntity, because that is // required by the query expression visitor / SimpleContentTypeMapper + // TODO: Make the query expression visitor use a different common interface, or investigate removing IRememberBeingDirty from being a requirement on that interface and expliclty checking for that throughout the code? string ITreeEntity.Name { get => this.Name; set => throw new NotImplementedException(); } int IEntity.Id { get => this.Id; set => throw new NotImplementedException(); } @@ -130,5 +131,7 @@ namespace Umbraco.Core.Models bool ICanBeDirty.IsPropertyDirty(string propName) => throw new NotImplementedException(); IEnumerable ICanBeDirty.GetDirtyProperties() => throw new NotImplementedException(); void ICanBeDirty.ResetDirtyProperties() => throw new NotImplementedException(); + public void DisableChangeTracking() => throw new NotImplementedException(); + public void EnableChangeTracking() => throw new NotImplementedException(); } } diff --git a/src/Umbraco.Core/Models/UserExtensions.cs b/src/Umbraco.Core/Models/UserExtensions.cs index 6e77ee456d..d5dda1a49a 100644 --- a/src/Umbraco.Core/Models/UserExtensions.cs +++ b/src/Umbraco.Core/Models/UserExtensions.cs @@ -16,35 +16,7 @@ namespace Umbraco.Core.Models { public static class UserExtensions { - public static IEnumerable GetPermissions(this IUser user, string path, IUserService userService) - { - return userService.GetPermissionsForPath(user, path).GetAllPermissions(); - } - - public static bool HasSectionAccess(this IUser user, string app) - { - var apps = user.AllowedSections; - return apps.Any(uApp => uApp.InvariantEquals(app)); - } - - /// - /// Determines whether this user is the 'super' user. - /// - public static bool IsSuper(this IUser user) - { - if (user == null) throw new ArgumentNullException(nameof(user)); - return user.Id == Constants.Security.SuperUserId; - } - - /// - /// Determines whether this user belongs to the administrators group. - /// - /// The 'super' user does not automatically belongs to the administrators group. - public static bool IsAdmin(this IUser user) - { - if (user == null) throw new ArgumentNullException(nameof(user)); - return user.Groups != null && user.Groups.Any(x => x.Alias == Constants.Security.AdminGroupAlias); - } + /// /// Tries to lookup the user's Gravatar to see if the endpoint can be reached, if so it returns the valid URL @@ -117,37 +89,7 @@ namespace Umbraco.Core.Models } - /// - /// Returns the culture info associated with this user, based on the language they're assigned to in the back office - /// - /// - /// - /// - /// - public static CultureInfo GetUserCulture(this IUser user, ILocalizedTextService textService, IGlobalSettings globalSettings) - { - if (user == null) throw new ArgumentNullException(nameof(user)); - if (textService == null) throw new ArgumentNullException(nameof(textService)); - return GetUserCulture(user.Language, textService, globalSettings); - } - - internal static CultureInfo GetUserCulture(string userLanguage, ILocalizedTextService textService, IGlobalSettings globalSettings) - { - try - { - var culture = CultureInfo.GetCultureInfo(userLanguage.Replace("_", "-")); - // TODO: This is a hack because we store the user language as 2 chars instead of the full culture - // which is actually stored in the language files (which are also named with 2 chars!) so we need to attempt - // to convert to a supported full culture - var result = textService.ConvertToSupportedCultureWithRegionCode(culture); - return result; - } - catch (CultureNotFoundException) - { - //return the default one - return CultureInfo.GetCultureInfo(globalSettings.DefaultUILanguage); - } - } + internal static bool HasContentRootAccess(this IUser user, IEntityService entityService) { diff --git a/src/Umbraco.Core/Packaging/CompiledPackageXmlParser.cs b/src/Umbraco.Core/Packaging/CompiledPackageXmlParser.cs index 83034a7e1b..c8b5720c21 100644 --- a/src/Umbraco.Core/Packaging/CompiledPackageXmlParser.cs +++ b/src/Umbraco.Core/Packaging/CompiledPackageXmlParser.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Xml.Linq; +using Umbraco.Core.Composing; using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.Models.Packaging; @@ -131,15 +132,15 @@ namespace Umbraco.Core.Packaging { return pathElement.TrimStart(new[] { '\\', '/', '~' }).Replace("/", "\\"); } - + private static string UpdatePathPlaceholders(string path) { if (path.Contains("[$")) { //this is experimental and undocumented... - path = path.Replace("[$UMBRACO]", SystemDirectories.Umbraco); - path = path.Replace("[$CONFIG]", SystemDirectories.Config); - path = path.Replace("[$DATA]", SystemDirectories.Data); + path = path.Replace("[$UMBRACO]", Current.Configs.Global().UmbracoPath); + path = path.Replace("[$CONFIG]", Constants.SystemDirectories.Config); + path = path.Replace("[$DATA]", Constants.SystemDirectories.Data); } return path; } diff --git a/src/Umbraco.Core/Packaging/PackageDataInstallation.cs b/src/Umbraco.Core/Packaging/PackageDataInstallation.cs index 281cc2c396..3a87b28d0e 100644 --- a/src/Umbraco.Core/Packaging/PackageDataInstallation.cs +++ b/src/Umbraco.Core/Packaging/PackageDataInstallation.cs @@ -6,6 +6,7 @@ using System.Web; using System.Xml.Linq; using System.Xml.XPath; using Umbraco.Core.Collections; +using Umbraco.Core.Composing; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -1317,7 +1318,7 @@ namespace Umbraco.Core.Packaging private string ViewPath(string alias) { - return SystemDirectories.MvcViews + "/" + alias.Replace(" ", "") + ".cshtml"; + return Constants.SystemDirectories.MvcViews + "/" + alias.Replace(" ", "") + ".cshtml"; } #endregion diff --git a/src/Umbraco.Core/Packaging/PackagesRepository.cs b/src/Umbraco.Core/Packaging/PackagesRepository.cs index 7ae3462b87..4de7f32737 100644 --- a/src/Umbraco.Core/Packaging/PackagesRepository.cs +++ b/src/Umbraco.Core/Packaging/PackagesRepository.cs @@ -74,9 +74,9 @@ namespace Umbraco.Core.Packaging _ioHelper = ioHelper; _packageRepositoryFileName = packageRepositoryFileName; - _tempFolderPath = tempFolderPath ?? SystemDirectories.TempData.EnsureEndsWith('/') + "PackageFiles"; - _packagesFolderPath = packagesFolderPath ?? SystemDirectories.Packages; - _mediaFolderPath = mediaFolderPath ?? SystemDirectories.Media + "/created-packages"; + _tempFolderPath = tempFolderPath ?? Constants.SystemDirectories.TempData.EnsureEndsWith('/') + "PackageFiles"; + _packagesFolderPath = packagesFolderPath ?? Constants.SystemDirectories.Packages; + _mediaFolderPath = mediaFolderPath ?? Current.Configs.Global().UmbracoMediaPath + "/created-packages"; _parser = new PackageDefinitionXmlParser(logger); } diff --git a/src/Umbraco.Core/Persistence/Factories/PropertyFactory.cs b/src/Umbraco.Core/Persistence/Factories/PropertyFactory.cs index 9d9482fedb..fc31f61763 100644 --- a/src/Umbraco.Core/Persistence/Factories/PropertyFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/PropertyFactory.cs @@ -46,7 +46,7 @@ namespace Umbraco.Core.Persistence.Factories return properties; } - private static PropertyDataDto BuildDto(int versionId, Property property, int? languageId, string segment, object value) + private static PropertyDataDto BuildDto(int versionId, IProperty property, int? languageId, string segment, object value) { var dto = new PropertyDataDto { VersionId = versionId, PropertyTypeId = property.PropertyTypeId }; @@ -109,7 +109,7 @@ namespace Umbraco.Core.Persistence.Factories /// The value of this will be used to populate the edited cultures in the umbracoDocumentCultureVariation table. /// /// - public static IEnumerable BuildDtos(ContentVariation contentVariation, int currentVersionId, int publishedVersionId, IEnumerable properties, + public static IEnumerable BuildDtos(ContentVariation contentVariation, int currentVersionId, int publishedVersionId, IEnumerable properties, ILanguageRepository languageRepository, out bool edited, out HashSet editedCultures) { diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/MemberTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/MemberTypeRepository.cs index 5ee9c9be08..741c5922ea 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/MemberTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/MemberTypeRepository.cs @@ -225,8 +225,17 @@ namespace Umbraco.Core.Persistence.Repositories.Implement if (builtinProperties.ContainsKey(propertyType.Alias)) { //this reset's its current data type reference which will be re-assigned based on the property editor assigned on the next line - propertyType.DataTypeId = 0; - propertyType.DataTypeKey = default; + var propDefinition = builtinProperties[propertyType.Alias]; + if (propDefinition != null) + { + propertyType.DataTypeId = propDefinition.DataTypeId; + propertyType.DataTypeKey = propDefinition.DataTypeKey; + } + else + { + propertyType.DataTypeId = 0; + propertyType.DataTypeKey = default; + } } } } diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/PartialViewRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/PartialViewRepository.cs index 1d5cd15ce8..238f121964 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/PartialViewRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/PartialViewRepository.cs @@ -109,9 +109,9 @@ namespace Umbraco.Core.Persistence.Repositories.Implement } // validate path & extension - var validDir = SystemDirectories.MvcViews; - var isValidPath = _ioHelper.VerifyEditPath(fullPath, validDir); - var isValidExtension = _ioHelper.VerifyFileExtension(fullPath, ValidExtensions); + var validDir = Constants.SystemDirectories.MvcViews; + var isValidPath = Current.IOHelper.VerifyEditPath(fullPath, validDir); + var isValidExtension = Current.IOHelper.VerifyFileExtension(fullPath, ValidExtensions); return isValidPath && isValidExtension; } diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/ScriptRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/ScriptRepository.cs index 491dafe577..22c3ff3067 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/ScriptRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/ScriptRepository.cs @@ -104,7 +104,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement } // validate path & extension - var validDir = SystemDirectories.Scripts; + var validDir = Current.Configs.Global().UmbracoScriptsPath; var isValidPath = _ioHelper.VerifyEditPath(fullPath, validDir); var validExts = new[] {"js"}; var isValidExtension = _ioHelper.VerifyFileExtension(script.Path, validExts); diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/StylesheetRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/StylesheetRepository.cs index 94737b5620..dc60c332cd 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/StylesheetRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/StylesheetRepository.cs @@ -121,7 +121,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement } // validate path and extension - var validDir = SystemDirectories.Css; + var validDir = Current.Configs.Global().UmbracoCssPath; var isValidPath = _ioHelper.VerifyEditPath(fullPath, validDir); var isValidExtension = _ioHelper.VerifyFileExtension(stylesheet.Path, ValidExtensions); return isValidPath && isValidExtension; diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/TemplateRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/TemplateRepository.cs index 3d1d7aa786..aa3d02bd30 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/TemplateRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/TemplateRepository.cs @@ -587,7 +587,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement var path = template.VirtualPath; // get valid paths - var validDirs = new[] { SystemDirectories.MvcViews }; + var validDirs = new[] { Constants.SystemDirectories.MvcViews }; // get valid extensions var validExts = new List(); diff --git a/src/Umbraco.Core/PropertyEditors/ConfigurationEditorOfTConfiguration.cs b/src/Umbraco.Core/PropertyEditors/ConfigurationEditorOfTConfiguration.cs index 7008c73433..bee923b50e 100644 --- a/src/Umbraco.Core/PropertyEditors/ConfigurationEditorOfTConfiguration.cs +++ b/src/Umbraco.Core/PropertyEditors/ConfigurationEditorOfTConfiguration.cs @@ -35,6 +35,7 @@ namespace Umbraco.Core.PropertyEditors ConfigurationField field; + var attributeView = Current.IOHelper.ResolveVirtualUrl(attribute.View); // if the field does not have its own type, use the base type if (attribute.Type == null) { @@ -47,7 +48,7 @@ namespace Umbraco.Core.PropertyEditors PropertyType = property.PropertyType, Description = attribute.Description, HideLabel = attribute.HideLabel, - View = attribute.View + View = attributeView }; fields.Add(field); @@ -81,7 +82,7 @@ namespace Umbraco.Core.PropertyEditors field.Name = attribute.Name; if (!string.IsNullOrWhiteSpace(attribute.View)) - field.View = attribute.View; + field.View = attributeView; if (!string.IsNullOrWhiteSpace(attribute.Description)) field.Description = attribute.Description; diff --git a/src/Umbraco.Core/PropertyEditors/ConfigurationFieldsExtensions.cs b/src/Umbraco.Core/PropertyEditors/ConfigurationFieldsExtensions.cs deleted file mode 100644 index 25fba622d5..0000000000 --- a/src/Umbraco.Core/PropertyEditors/ConfigurationFieldsExtensions.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Collections.Generic; - -namespace Umbraco.Core.PropertyEditors -{ - public static partial class ConfigurationFieldsExtensions - { - /// - /// Adds a configuration field. - /// - /// The list of configuration fields. - /// The key (alias) of the field. - /// The name (label) of the field. - /// The description for the field. - /// The path to the editor view to be used for the field. - /// Optional configuration used for field's editor. - public static void Add( - this List fields, - string key, - string name, - string description, - string view, - IDictionary config = null) - { - fields.Add(new ConfigurationField - { - Key = key, - Name = name, - Description = description, - View = view, - Config = config, - }); - } - } -} diff --git a/src/Umbraco.Core/PropertyEditors/DataEditor.cs b/src/Umbraco.Core/PropertyEditors/DataEditor.cs index dbb2fc467e..047c0f0683 100644 --- a/src/Umbraco.Core/PropertyEditors/DataEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/DataEditor.cs @@ -165,7 +165,7 @@ namespace Umbraco.Core.PropertyEditors if (Attribute == null) throw new InvalidOperationException("The editor does not specify a view."); - return new DataValueEditor(Attribute); + return new DataValueEditor(Current.Services.DataTypeService, Current.Services.LocalizationService, Attribute); } /// diff --git a/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs b/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs index a9ce27d964..afd77a3479 100644 --- a/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs @@ -7,7 +7,6 @@ using System.Xml.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Umbraco.Core.Composing; -using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.Editors; @@ -21,32 +20,24 @@ namespace Umbraco.Core.PropertyEditors /// public class DataValueEditor : IDataValueEditor { - private string _view; + protected IDataTypeService DataTypeService { get; } + protected ILocalizationService LocalizationService { get; } /// /// Initializes a new instance of the class. /// - public DataValueEditor() // for tests, and manifest + public DataValueEditor(IDataTypeService dataTypeService, ILocalizationService localizationService) // for tests, and manifest { ValueType = ValueTypes.String; Validators = new List(); + DataTypeService = dataTypeService; + LocalizationService = localizationService; } /// /// Initializes a new instance of the class. /// - public DataValueEditor(string view, params IValueValidator[] validators) // not used - : this() - { - View = view; - Validators.AddRange(validators); - } - - /// - /// Initializes a new instance of the class. - /// - public DataValueEditor(DataEditorAttribute attribute) - : this() + public DataValueEditor(IDataTypeService dataTypeService, ILocalizationService localizationService, DataEditorAttribute attribute) { if (attribute == null) throw new ArgumentNullException(nameof(attribute)); @@ -57,6 +48,9 @@ namespace Umbraco.Core.PropertyEditors View = view; ValueType = attribute.ValueType; HideLabel = attribute.HideLabel; + + DataTypeService = dataTypeService; + LocalizationService = localizationService; } /// @@ -72,11 +66,7 @@ namespace Umbraco.Core.PropertyEditors /// folder, or (3) a view name which maps to views/propertyeditors/{view}/{view}.html. /// [JsonProperty("view", Required = Required.Always)] - public string View - { - get => _view; - set => _view = Current.IOHelper.ResolveVirtualUrl(value); - } + public string View { get; set; } /// /// The value type which reflects how it is validated and stored in the database @@ -115,17 +105,17 @@ namespace Umbraco.Core.PropertyEditors /// A collection of validators for the pre value editor /// [JsonProperty("validation")] - public List Validators { get; private set; } + public List Validators { get; private set; } = new List(); /// /// Gets the validator used to validate the special property type -level "required". /// - public virtual IValueRequiredValidator RequiredValidator => new RequiredValidator(); + public virtual IValueRequiredValidator RequiredValidator => new RequiredValidator(); //TODO: Pass in the ILocalizedTextService here and not rely on Current! /// /// Gets the validator used to validate the special property type -level "format". /// - public virtual IValueFormatValidator FormatValidator => new RegexValidator(); + public virtual IValueFormatValidator FormatValidator => new RegexValidator(); //TODO: Pass in the ILocalizedTextService here and not rely on Current! /// /// If this is true than the editor will be displayed full width without a label @@ -237,7 +227,7 @@ namespace Umbraco.Core.PropertyEditors /// The object returned will automatically be serialized into json notation. For most property editors /// the value returned is probably just a string but in some cases a json structure will be returned. /// - public virtual object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public virtual object ToEditor(IProperty property, string culture = null, string segment = null) { var val = property.GetValue(culture, segment); if (val == null) return string.Empty; @@ -288,7 +278,7 @@ namespace Umbraco.Core.PropertyEditors /// /// Converts a property to Xml fragments. /// - public IEnumerable ConvertDbToXml(Property property, IDataTypeService dataTypeService, ILocalizationService localizationService, bool published) + public IEnumerable ConvertDbToXml(IProperty property, bool published) { published &= property.PropertyType.SupportsPublishing; @@ -306,7 +296,7 @@ namespace Umbraco.Core.PropertyEditors if (pvalue.Segment != null) xElement.Add(new XAttribute("segment", pvalue.Segment)); - var xValue = ConvertDbToXml(property.PropertyType, value, dataTypeService); + var xValue = ConvertDbToXml(property.PropertyType, value); xElement.Add(xValue); yield return xElement; @@ -322,12 +312,12 @@ namespace Umbraco.Core.PropertyEditors /// Returns an XText or XCData instance which must be wrapped in a element. /// If the value is empty we will not return as CDATA since that will just take up more space in the file. /// - public XNode ConvertDbToXml(PropertyType propertyType, object value, IDataTypeService dataTypeService) + public XNode ConvertDbToXml(IPropertyType propertyType, object value) { //check for null or empty value, we don't want to return CDATA if that is the case if (value == null || value.ToString().IsNullOrWhiteSpace()) { - return new XText(ConvertDbToString(propertyType, value, dataTypeService)); + return new XText(ConvertDbToString(propertyType, value)); } switch (ValueTypes.ToStorageType(ValueType)) @@ -335,11 +325,11 @@ namespace Umbraco.Core.PropertyEditors case ValueStorageType.Date: case ValueStorageType.Integer: case ValueStorageType.Decimal: - return new XText(ConvertDbToString(propertyType, value, dataTypeService)); + return new XText(ConvertDbToString(propertyType, value)); case ValueStorageType.Nvarchar: case ValueStorageType.Ntext: //put text in cdata - return new XCData(ConvertDbToString(propertyType, value, dataTypeService)); + return new XCData(ConvertDbToString(propertyType, value)); default: throw new ArgumentOutOfRangeException(); } @@ -348,7 +338,7 @@ namespace Umbraco.Core.PropertyEditors /// /// Converts a property value to a string. /// - public virtual string ConvertDbToString(PropertyType propertyType, object value, IDataTypeService dataTypeService) + public virtual string ConvertDbToString(IPropertyType propertyType, object value) { if (value == null) return string.Empty; diff --git a/src/Umbraco.Core/PropertyEditors/DefaultPropertyIndexValueFactory.cs b/src/Umbraco.Core/PropertyEditors/DefaultPropertyIndexValueFactory.cs index 413f31d79e..0d06b59a9c 100644 --- a/src/Umbraco.Core/PropertyEditors/DefaultPropertyIndexValueFactory.cs +++ b/src/Umbraco.Core/PropertyEditors/DefaultPropertyIndexValueFactory.cs @@ -9,7 +9,7 @@ namespace Umbraco.Core.PropertyEditors public class DefaultPropertyIndexValueFactory : IPropertyIndexValueFactory { /// - public IEnumerable>> GetIndexValues(Property property, string culture, string segment, bool published) + public IEnumerable>> GetIndexValues(IProperty property, string culture, string segment, bool published) { yield return new KeyValuePair>( property.Alias, diff --git a/src/Umbraco.Core/PropertyEditors/LabelPropertyEditor.cs b/src/Umbraco.Core/PropertyEditors/LabelPropertyEditor.cs index 60b7d55c01..e47d35107a 100644 --- a/src/Umbraco.Core/PropertyEditors/LabelPropertyEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/LabelPropertyEditor.cs @@ -1,4 +1,6 @@ -using Umbraco.Core.Logging; +using Umbraco.Core.Composing; +using Umbraco.Core.Logging; +using Umbraco.Core.Services; namespace Umbraco.Core.PropertyEditors { @@ -20,7 +22,7 @@ namespace Umbraco.Core.PropertyEditors { } /// - protected override IDataValueEditor CreateValueEditor() => new LabelPropertyValueEditor(Attribute); + protected override IDataValueEditor CreateValueEditor() => new LabelPropertyValueEditor(Current.Services.DataTypeService, Current.Services.LocalizationService, Attribute); /// protected override IConfigurationEditor CreateConfigurationEditor() => new LabelConfigurationEditor(); @@ -28,8 +30,8 @@ namespace Umbraco.Core.PropertyEditors // provides the property value editor internal class LabelPropertyValueEditor : DataValueEditor { - public LabelPropertyValueEditor(DataEditorAttribute attribute) - : base(attribute) + public LabelPropertyValueEditor(IDataTypeService dataTypeService, ILocalizationService localizationService, DataEditorAttribute attribute) + : base(dataTypeService, localizationService, attribute) { } /// diff --git a/src/Umbraco.Core/PropertyEditors/ManifestValueValidatorCollectionBuilder.cs b/src/Umbraco.Core/PropertyEditors/ManifestValueValidatorCollectionBuilder.cs deleted file mode 100644 index 8f7c68c813..0000000000 --- a/src/Umbraco.Core/PropertyEditors/ManifestValueValidatorCollectionBuilder.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Umbraco.Core.Composing; - -namespace Umbraco.Core.PropertyEditors -{ - internal class ManifestValueValidatorCollectionBuilder : LazyCollectionBuilderBase - { - protected override ManifestValueValidatorCollectionBuilder This => this; - } -} diff --git a/src/Umbraco.Core/PropertyEditors/Validators/RegexValidator.cs b/src/Umbraco.Core/PropertyEditors/Validators/RegexValidator.cs index e405fa3a3e..2bd3e0ab40 100644 --- a/src/Umbraco.Core/PropertyEditors/Validators/RegexValidator.cs +++ b/src/Umbraco.Core/PropertyEditors/Validators/RegexValidator.cs @@ -11,11 +11,13 @@ namespace Umbraco.Core.PropertyEditors.Validators /// /// A validator that validates that the value against a regular expression. /// - internal sealed class RegexValidator : IValueFormatValidator, IManifestValueValidator + public sealed class RegexValidator : IValueFormatValidator, IManifestValueValidator { private readonly ILocalizedTextService _textService; private string _regex; + const string ValueIsInvalid = "Value is invalid, it does not match the correct pattern"; + /// public string ValidationName => "Regex"; @@ -26,7 +28,7 @@ namespace Umbraco.Core.PropertyEditors.Validators /// and the regular expression is supplied at validation time. This constructor is also used when /// the validator is used as an and the regular expression /// is supplied via the method. - public RegexValidator() : this(Current.Services.TextService, null) + public RegexValidator() : this(Current.HasFactory ? Current.Services.TextService : null, null) { } /// @@ -68,7 +70,9 @@ namespace Umbraco.Core.PropertyEditors.Validators { if (string.IsNullOrWhiteSpace(format)) throw new ArgumentNullOrEmptyException(nameof(format)); if (value == null || !new Regex(format).IsMatch(value.ToString())) - yield return new ValidationResult(_textService.Localize("validation", "invalidPattern"), new[] { "value" }); + { + yield return new ValidationResult(_textService?.Localize("validation", "invalidPattern") ?? ValueIsInvalid, new[] { "value" }); + } } } } diff --git a/src/Umbraco.Core/PropertyEditors/Validators/RequiredValidator.cs b/src/Umbraco.Core/PropertyEditors/Validators/RequiredValidator.cs index c51f572817..30342fbf2d 100644 --- a/src/Umbraco.Core/PropertyEditors/Validators/RequiredValidator.cs +++ b/src/Umbraco.Core/PropertyEditors/Validators/RequiredValidator.cs @@ -8,11 +8,13 @@ namespace Umbraco.Core.PropertyEditors.Validators /// /// A validator that validates that the value is not null or empty (if it is a string) /// - internal sealed class RequiredValidator : IValueRequiredValidator, IManifestValueValidator + public sealed class RequiredValidator : IValueRequiredValidator, IManifestValueValidator { private readonly ILocalizedTextService _textService; + const string ValueCannotBeNull = "Value cannot be null"; + const string ValueCannotBeEmpty = "Value cannot be empty"; - public RequiredValidator() : this(Current.Services.TextService) + public RequiredValidator() : this(Current.HasFactory ? Current.Services.TextService : null) { } @@ -35,20 +37,24 @@ namespace Umbraco.Core.PropertyEditors.Validators { if (value == null) { - yield return new ValidationResult(_textService.Localize("validation", "invalidNull"), new[] {"value"}); + yield return new ValidationResult(_textService?.Localize("validation", "invalidNull") ?? ValueCannotBeNull, new[] {"value"}); yield break; } if (valueType.InvariantEquals(ValueTypes.Json)) { if (value.ToString().DetectIsEmptyJson()) - yield return new ValidationResult(_textService.Localize("validation", "invalidEmpty"), new[] { "value" }); + { + + yield return new ValidationResult(_textService?.Localize("validation", "invalidEmpty") ?? ValueCannotBeEmpty, new[] { "value" }); + } + yield break; } if (value.ToString().IsNullOrWhiteSpace()) { - yield return new ValidationResult(_textService.Localize("validation", "invalidEmpty"), new[] { "value" }); + yield return new ValidationResult(_textService?.Localize("validation", "invalidEmpty") ?? ValueCannotBeEmpty, new[] { "value" }); } } } diff --git a/src/Umbraco.Core/Runtime/CoreInitialComponent.cs b/src/Umbraco.Core/Runtime/CoreInitialComponent.cs index e90ad41155..40dd4575dc 100644 --- a/src/Umbraco.Core/Runtime/CoreInitialComponent.cs +++ b/src/Umbraco.Core/Runtime/CoreInitialComponent.cs @@ -16,11 +16,11 @@ namespace Umbraco.Core.Runtime { // ensure we have some essential directories // every other component can then initialize safely - _ioHelper.EnsurePathExists("~/App_Data"); - _ioHelper.EnsurePathExists(SystemDirectories.Media); - _ioHelper.EnsurePathExists(SystemDirectories.MvcViews); - _ioHelper.EnsurePathExists(SystemDirectories.MvcViews + "/Partials"); - _ioHelper.EnsurePathExists(SystemDirectories.MvcViews + "/MacroPartials"); + _ioHelper.EnsurePathExists(Constants.SystemDirectories.Data); + _ioHelper.EnsurePathExists(Current.Configs.Global().UmbracoMediaPath); + _ioHelper.EnsurePathExists(Constants.SystemDirectories.MvcViews); + _ioHelper.EnsurePathExists(Constants.SystemDirectories.PartialViews); + _ioHelper.EnsurePathExists(Constants.SystemDirectories.MacroPartials); } public void Terminate() diff --git a/src/Umbraco.Core/Serialization/JsonNetSerializer.cs b/src/Umbraco.Core/Serialization/JsonNetSerializer.cs index a2a5f19082..16d8668394 100644 --- a/src/Umbraco.Core/Serialization/JsonNetSerializer.cs +++ b/src/Umbraco.Core/Serialization/JsonNetSerializer.cs @@ -4,19 +4,25 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Newtonsoft.Json; +using Newtonsoft.Json.Converters; namespace Umbraco.Core.Serialization { public class JsonNetSerializer : IJsonSerializer { + private static readonly JsonConverter[] _defaultConverters = new JsonConverter[] + { + new StringEnumConverter() + }; + public string Serialize(object input) { - return JsonConvert.SerializeObject(input); + return JsonConvert.SerializeObject(input, _defaultConverters); } public T Deserialize(string input) { - return JsonConvert.DeserializeObject(input); + return JsonConvert.DeserializeObject(input, _defaultConverters); } } } diff --git a/src/Umbraco.Core/Services/Implement/ContentService.cs b/src/Umbraco.Core/Services/Implement/ContentService.cs index 5a43738230..2fa75e2f3f 100644 --- a/src/Umbraco.Core/Services/Implement/ContentService.cs +++ b/src/Umbraco.Core/Services/Implement/ContentService.cs @@ -1402,7 +1402,7 @@ namespace Umbraco.Core.Services.Implement if (d.Trashed) continue; // won't publish //publish the culture values and validate the property values, if validation fails, log the invalid properties so the develeper has an idea of what has failed - Property[] invalidProperties = null; + IProperty[] invalidProperties = null; var impact = CultureImpact.Explicit(culture, IsDefaultCulture(allLangs, culture)); var tryPublish = d.PublishCulture(impact) && _propertyValidationService.Value.IsPropertyDataValid(d, out invalidProperties, impact); if (invalidProperties != null && invalidProperties.Length > 0) @@ -2602,7 +2602,7 @@ namespace Umbraco.Core.Services.Implement return new PublishResult(PublishResultType.FailedPublishContentInvalid, evtMsgs, content); //validate the property values - Property[] invalidProperties = null; + IProperty[] invalidProperties = null; if (!impactsToPublish.All(x => _propertyValidationService.Value.IsPropertyDataValid(content, out invalidProperties, x))) return new PublishResult(PublishResultType.FailedPublishContentInvalid, evtMsgs, content) { diff --git a/src/Umbraco.Core/Services/Implement/EntityXmlSerializer.cs b/src/Umbraco.Core/Services/Implement/EntityXmlSerializer.cs index bc21da15a7..f488c12657 100644 --- a/src/Umbraco.Core/Services/Implement/EntityXmlSerializer.cs +++ b/src/Umbraco.Core/Services/Implement/EntityXmlSerializer.cs @@ -77,7 +77,7 @@ namespace Umbraco.Core.Services.Implement var children = _contentService.GetPagedChildren(content.Id, page++, pageSize, out total); SerializeChildren(children, xml, published); } - + } return xml; @@ -552,7 +552,7 @@ namespace Umbraco.Core.Services.Implement } // exports a property as XElements. - private IEnumerable SerializeProperty(Property property, bool published) + private IEnumerable SerializeProperty(IProperty property, bool published) { var propertyType = property.PropertyType; @@ -560,7 +560,7 @@ namespace Umbraco.Core.Services.Implement var propertyEditor = Current.PropertyEditors[propertyType.PropertyEditorAlias]; return propertyEditor == null ? Array.Empty() - : propertyEditor.GetValueEditor().ConvertDbToXml(property, _dataTypeService, _localizationService, published); + : propertyEditor.GetValueEditor().ConvertDbToXml(property, published); } // exports an IContent item descendants. diff --git a/src/Umbraco.Core/Services/Implement/NotificationService.cs b/src/Umbraco.Core/Services/Implement/NotificationService.cs index 3a42e576de..c89cb27623 100644 --- a/src/Umbraco.Core/Services/Implement/NotificationService.cs +++ b/src/Umbraco.Core/Services/Implement/NotificationService.cs @@ -386,7 +386,7 @@ namespace Umbraco.Core.Services.Implement var protocol = _globalSettings.UseHttps ? "https" : "http"; var subjectVars = new NotificationEmailSubjectParams( - string.Concat(siteUri.Authority, _ioHelper.ResolveUrl(SystemDirectories.Umbraco)), + string.Concat(siteUri.Authority, _ioHelper.ResolveUrl(Current.Configs.Global().UmbracoPath)), actionName, content.Name); @@ -402,7 +402,7 @@ namespace Umbraco.Core.Services.Implement string.Concat(content.Id, ".aspx"), protocol), performingUser.Name, - string.Concat(siteUri.Authority, _ioHelper.ResolveUrl(SystemDirectories.Umbraco)), + string.Concat(siteUri.Authority, _ioHelper.ResolveUrl(Current.Configs.Global().UmbracoPath)), summary.ToString()); // create the mail message diff --git a/src/Umbraco.Core/Services/PropertyValidationService.cs b/src/Umbraco.Core/Services/PropertyValidationService.cs index a037a83920..1704d52206 100644 --- a/src/Umbraco.Core/Services/PropertyValidationService.cs +++ b/src/Umbraco.Core/Services/PropertyValidationService.cs @@ -31,7 +31,7 @@ namespace Umbraco.Core.Services /// /// Validates the content item's properties pass validation rules /// - public bool IsPropertyDataValid(IContent content, out Property[] invalidProperties, CultureImpact impact) + public bool IsPropertyDataValid(IContent content, out IProperty[] invalidProperties, CultureImpact impact) { // select invalid properties invalidProperties = content.Properties.Where(x => @@ -66,7 +66,7 @@ namespace Umbraco.Core.Services /// /// Gets a value indicating whether the property has valid values. /// - public bool IsPropertyValid(Property property, string culture = "*", string segment = "*") + public bool IsPropertyValid(IProperty property, string culture = "*", string segment = "*") { //NOTE - the pvalue and vvalues logic in here is borrowed directly from the Property.Values setter so if you are wondering what that's all about, look there. // The underlying Property._pvalue and Property._vvalues are not exposed but we can re-create these values ourselves which is what it's doing. @@ -74,7 +74,7 @@ namespace Umbraco.Core.Services culture = culture.NullOrWhiteSpaceAsNull(); segment = segment.NullOrWhiteSpaceAsNull(); - Property.PropertyValue pvalue = null; + IPropertyValue pvalue = null; // if validating invariant/neutral, and it is supported, validate // (including ensuring that the value exists, if mandatory) @@ -120,7 +120,7 @@ namespace Umbraco.Core.Services /// /// /// True is property value is valid, otherwise false - private bool IsValidPropertyValue(Property property, object value) + private bool IsValidPropertyValue(IProperty property, object value) { return IsPropertyValueValid(property.PropertyType, value); } @@ -128,7 +128,7 @@ namespace Umbraco.Core.Services /// /// Determines whether a value is valid for this property type. /// - private bool IsPropertyValueValid(PropertyType propertyType, object value) + private bool IsPropertyValueValid(IPropertyType propertyType, object value) { var editor = _propertyEditors[propertyType.PropertyEditorAlias]; if (editor == null) diff --git a/src/Umbraco.Core/Services/PublishResult.cs b/src/Umbraco.Core/Services/PublishResult.cs index 4f1ff776a2..fe11d77cf3 100644 --- a/src/Umbraco.Core/Services/PublishResult.cs +++ b/src/Umbraco.Core/Services/PublishResult.cs @@ -32,6 +32,6 @@ namespace Umbraco.Core.Services /// /// Gets or sets the invalid properties, if the status failed due to validation. /// - public IEnumerable InvalidProperties { get; set; } + public IEnumerable InvalidProperties { get; set; } } } diff --git a/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs b/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs index b7afc1048b..1b451e80d5 100644 --- a/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs +++ b/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs @@ -98,7 +98,7 @@ namespace Umbraco.Core.Sync : ""; var ssl = globalSettings.UseHttps ? "s" : ""; // force, whatever the first request - var url = "http" + ssl + "://" + request.ServerVariables["SERVER_NAME"] + port + Current.IOHelper.ResolveUrl(SystemDirectories.Umbraco); + var url = "http" + ssl + "://" + request.ServerVariables["SERVER_NAME"] + port + Current.IOHelper.ResolveUrl(Current.Configs.Global().UmbracoPath); return url.TrimEnd('/'); } diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index ab5198f677..eae73c28bc 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -36,7 +36,6 @@ - @@ -65,11 +64,14 @@ all - 1.3.0 + 1.4.0 1.0.0 + + 4.6.0 + 1.0.5 runtime; build; native; contentfiles; analyzers @@ -91,19 +93,19 @@ - 2.8.0 + 2.9.0 2.0.1 - 3.0.0 + 3.1.0 2.0.0 - 1.0.0 + 1.1.0 1.0.3 @@ -112,7 +114,7 @@ 2.2.2 - 4.0.0 + 4.1.0 @@ -182,9 +184,7 @@ - - - + @@ -202,11 +202,6 @@ - - - - - @@ -218,67 +213,45 @@ - - + - + - - - - - - - - - - + - - - - - - - - - - + + + + - - - - - - @@ -380,10 +353,7 @@ - - - @@ -419,32 +389,21 @@ - - - - - - - - - - - @@ -470,11 +429,7 @@ - - - - @@ -548,10 +503,8 @@ - - @@ -567,45 +520,28 @@ - - - - - - - - - - - - - - - - - @@ -653,15 +589,11 @@ - - - - @@ -957,22 +889,13 @@ - - - - - - - - - @@ -1060,11 +983,9 @@ - - @@ -1101,9 +1022,6 @@ - - - Component diff --git a/src/Umbraco.Examine/BaseValueSetBuilder.cs b/src/Umbraco.Examine/BaseValueSetBuilder.cs index 93cee88231..4a306aa5ff 100644 --- a/src/Umbraco.Examine/BaseValueSetBuilder.cs +++ b/src/Umbraco.Examine/BaseValueSetBuilder.cs @@ -24,7 +24,7 @@ namespace Umbraco.Examine /// public abstract IEnumerable GetValueSets(params TContent[] content); - protected void AddPropertyValue(Property property, string culture, string segment, IDictionary> values) + protected void AddPropertyValue(IProperty property, string culture, string segment, IDictionary> values) { var editor = _propertyEditors[property.PropertyType.PropertyEditorAlias]; if (editor == null) return; @@ -61,7 +61,7 @@ namespace Umbraco.Examine else values.Add($"{keyVal.Key}{cultureSuffix}", val.Yield()); } - + break; } } diff --git a/src/Umbraco.Examine/LuceneIndexCreator.cs b/src/Umbraco.Examine/LuceneIndexCreator.cs index 3834c1476e..d6bf8c262c 100644 --- a/src/Umbraco.Examine/LuceneIndexCreator.cs +++ b/src/Umbraco.Examine/LuceneIndexCreator.cs @@ -36,7 +36,7 @@ namespace Umbraco.Examine public virtual Lucene.Net.Store.Directory CreateFileSystemLuceneDirectory(string folderName) { - var dirInfo = new DirectoryInfo(Path.Combine(Current.IOHelper.MapPath(SystemDirectories.TempData), "ExamineIndexes", folderName)); + var dirInfo = new DirectoryInfo(Path.Combine(Current.IOHelper.MapPath(Constants.SystemDirectories.TempData), "ExamineIndexes", folderName)); if (!dirInfo.Exists) System.IO.Directory.CreateDirectory(dirInfo.FullName); diff --git a/src/Umbraco.Examine/LuceneIndexDiagnostics.cs b/src/Umbraco.Examine/LuceneIndexDiagnostics.cs index 7a91552c81..3b23b57709 100644 --- a/src/Umbraco.Examine/LuceneIndexDiagnostics.cs +++ b/src/Umbraco.Examine/LuceneIndexDiagnostics.cs @@ -11,10 +11,13 @@ namespace Umbraco.Examine { public class LuceneIndexDiagnostics : IIndexDiagnostics { + private IIOHelper _ioHelper; + public LuceneIndexDiagnostics(LuceneIndex index, ILogger logger) { Index = index; Logger = logger; + _ioHelper = Current.IOHelper; } public LuceneIndex Index { get; } @@ -72,7 +75,7 @@ namespace Umbraco.Examine if (luceneDir is FSDirectory fsDir) { - d[nameof(UmbracoExamineIndex.LuceneIndexFolder)] = fsDir.Directory.ToString().ToLowerInvariant().TrimStart(Current.IOHelper.MapPath(SystemDirectories.Root).ToLowerInvariant()).Replace("\\", "/").EnsureStartsWith('/'); + d[nameof(UmbracoExamineIndex.LuceneIndexFolder)] = fsDir.Directory.ToString().ToLowerInvariant().TrimStart(_ioHelper.MapPath(_ioHelper.Root).ToLowerInvariant()).Replace("\\", "/").EnsureStartsWith('/'); } return d; diff --git a/src/Umbraco.Examine/MediaValueSetBuilder.cs b/src/Umbraco.Examine/MediaValueSetBuilder.cs index 3839d008b3..03e7f4944b 100644 --- a/src/Umbraco.Examine/MediaValueSetBuilder.cs +++ b/src/Umbraco.Examine/MediaValueSetBuilder.cs @@ -1,9 +1,13 @@ -using Examine; +using System; +using Examine; using System.Collections.Generic; using System.Linq; +using Newtonsoft.Json; using Umbraco.Core; +using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.PropertyEditors.ValueConverters; using Umbraco.Core.Services; using Umbraco.Core.Strings; @@ -13,14 +17,16 @@ namespace Umbraco.Examine { private readonly UrlSegmentProviderCollection _urlSegmentProviders; private readonly IUserService _userService; + private readonly ILogger _logger; public MediaValueSetBuilder(PropertyEditorCollection propertyEditors, UrlSegmentProviderCollection urlSegmentProviders, - IUserService userService) + IUserService userService, ILogger logger) : base(propertyEditors, false) { _urlSegmentProviders = urlSegmentProviders; _userService = userService; + _logger = logger; } /// @@ -29,6 +35,42 @@ namespace Umbraco.Examine foreach (var m in media) { var urlValue = m.GetUrlSegment(_urlSegmentProviders); + + var umbracoFilePath = string.Empty; + var umbracoFile = string.Empty; + + var umbracoFileSource = m.GetValue(Constants.Conventions.Media.File); + + if (umbracoFileSource.DetectIsJson()) + { + ImageCropperValue cropper = null; + try + { + cropper = JsonConvert.DeserializeObject( + m.GetValue(Constants.Conventions.Media.File)); + } + catch (Exception ex) + { + _logger.Error(ex, $"Could not Deserialize ImageCropperValue for item with key {m.Key} "); + } + + if (cropper != null) + { + umbracoFilePath = cropper.Src; + } + } + else + { + umbracoFilePath = umbracoFileSource; + } + + if (!string.IsNullOrEmpty(umbracoFilePath)) + { + // intentional dummy Uri + var uri = new Uri("https://localhost/" + umbracoFilePath); + umbracoFile = uri.Segments.Last(); + } + var values = new Dictionary> { {"icon", m.ContentType.Icon?.Yield() ?? Enumerable.Empty()}, @@ -44,7 +86,8 @@ namespace Umbraco.Examine {"urlName", urlValue?.Yield() ?? Enumerable.Empty()}, {"path", m.Path?.Yield() ?? Enumerable.Empty()}, {"nodeType", m.ContentType.Id.ToString().Yield() }, - {"creatorName", (m.GetCreatorProfile(_userService)?.Name ?? "??").Yield()} + {"creatorName", (m.GetCreatorProfile(_userService)?.Name ?? "??").Yield()}, + {UmbracoExamineIndex.UmbracoFileFieldName, umbracoFile.Yield()} }; foreach (var property in m.Properties) diff --git a/src/Umbraco.Examine/Umbraco.Examine.csproj b/src/Umbraco.Examine/Umbraco.Examine.csproj index e99fbd8ff1..3b77b20d42 100644 --- a/src/Umbraco.Examine/Umbraco.Examine.csproj +++ b/src/Umbraco.Examine/Umbraco.Examine.csproj @@ -49,7 +49,7 @@ - + 1.0.0-beta2-19324-01 runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/Umbraco.Examine/UmbracoExamineIndex.cs b/src/Umbraco.Examine/UmbracoExamineIndex.cs index 24952050da..e1dd77b994 100644 --- a/src/Umbraco.Examine/UmbracoExamineIndex.cs +++ b/src/Umbraco.Examine/UmbracoExamineIndex.cs @@ -32,6 +32,7 @@ namespace Umbraco.Examine /// public const string IndexPathFieldName = SpecialFieldPrefix + "Path"; public const string NodeKeyFieldName = SpecialFieldPrefix + "Key"; + public const string UmbracoFileFieldName = "umbracoFileSrc"; public const string IconFieldName = SpecialFieldPrefix + "Icon"; public const string PublishedFieldName = SpecialFieldPrefix + "Published"; diff --git a/src/Umbraco.ModelsBuilder.Embedded/Umbraco.ModelsBuilder.Embedded.csproj b/src/Umbraco.ModelsBuilder.Embedded/Umbraco.ModelsBuilder.Embedded.csproj index 67919834ac..eb61e2a2c8 100644 --- a/src/Umbraco.ModelsBuilder.Embedded/Umbraco.ModelsBuilder.Embedded.csproj +++ b/src/Umbraco.ModelsBuilder.Embedded/Umbraco.ModelsBuilder.Embedded.csproj @@ -34,7 +34,6 @@ - @@ -97,6 +96,9 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all + + 4.6.0 + diff --git a/src/Umbraco.Tests/App.config b/src/Umbraco.Tests/App.config index 91047ba6a2..9eeb93384d 100644 --- a/src/Umbraco.Tests/App.config +++ b/src/Umbraco.Tests/App.config @@ -94,6 +94,10 @@ + + + + diff --git a/src/Umbraco.Tests/Components/ComponentTests.cs b/src/Umbraco.Tests/Components/ComponentTests.cs index 365a10224b..232d74ba6a 100644 --- a/src/Umbraco.Tests/Components/ComponentTests.cs +++ b/src/Umbraco.Tests/Components/ComponentTests.cs @@ -13,6 +13,7 @@ using Umbraco.Core.Logging; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Scoping; +using Umbraco.Tests.TestHelpers; [assembly:DisableComposer(typeof(Umbraco.Tests.Components.ComponentTests.Composer26))] @@ -32,10 +33,9 @@ namespace Umbraco.Tests.Components var mock = new Mock(); var logger = Mock.Of(); - var ioHelper = Mock.Of(); var typeFinder = new TypeFinder(logger); var f = new UmbracoDatabaseFactory(logger, new Lazy(() => new MapperCollection(Enumerable.Empty()))); - var fs = new FileSystems(mock.Object, logger, ioHelper); + var fs = new FileSystems(mock.Object, logger, IOHelper.Default, SettingsForTests.GenerateMockGlobalSettings()); var p = new ScopeProvider(f, fs, logger, typeFinder); mock.Setup(x => x.GetInstance(typeof (ILogger))).Returns(logger); diff --git a/src/Umbraco.Tests/Configurations/GlobalSettingsTests.cs b/src/Umbraco.Tests/Configurations/GlobalSettingsTests.cs index 69a9613a38..2b5611deec 100644 --- a/src/Umbraco.Tests/Configurations/GlobalSettingsTests.cs +++ b/src/Umbraco.Tests/Configurations/GlobalSettingsTests.cs @@ -17,13 +17,13 @@ namespace Umbraco.Tests.Configurations public override void SetUp() { base.SetUp(); - _root = SystemDirectories.Root; + _root = Current.IOHelper.Root; } public override void TearDown() { base.TearDown(); - SystemDirectories.Root = _root; + Current.IOHelper.Root = _root; } [Test] @@ -51,7 +51,7 @@ namespace Umbraco.Tests.Configurations var globalSettingsMock = Mock.Get(globalSettings); globalSettingsMock.Setup(x => x.Path).Returns(() => Current.IOHelper.ResolveUrl(path)); - SystemDirectories.Root = rootPath; + Current.IOHelper.Root = rootPath; Assert.AreEqual(outcome, globalSettings.GetUmbracoMvcAreaNoCache()); } diff --git a/src/Umbraco.Tests/CoreThings/ObjectExtensionsTests.cs b/src/Umbraco.Tests/CoreThings/ObjectExtensionsTests.cs index 486d35540c..544c6335e1 100644 --- a/src/Umbraco.Tests/CoreThings/ObjectExtensionsTests.cs +++ b/src/Umbraco.Tests/CoreThings/ObjectExtensionsTests.cs @@ -7,6 +7,7 @@ using System.Web.UI.WebControls; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.PropertyEditors; +using Umbraco.Tests.TestHelpers; namespace Umbraco.Tests.CoreThings { @@ -300,10 +301,7 @@ namespace Umbraco.Tests.CoreThings [Test] public void Value_Editor_Can_Convert_Decimal_To_Decimal_Clr_Type() { - var valueEditor = new DataValueEditor - { - ValueType = ValueTypes.Decimal - }; + var valueEditor = TestHelper.CreateDataValueEditor(ValueTypes.Decimal); var result = valueEditor.TryConvertValueToCrlType(12.34d); Assert.IsTrue(result.Success); diff --git a/src/Umbraco.Tests/CoreThings/UriExtensionsTests.cs b/src/Umbraco.Tests/CoreThings/UriExtensionsTests.cs index be7aec631e..780e204aad 100644 --- a/src/Umbraco.Tests/CoreThings/UriExtensionsTests.cs +++ b/src/Umbraco.Tests/CoreThings/UriExtensionsTests.cs @@ -1,6 +1,7 @@ using System; using NUnit.Framework; using Umbraco.Core; +using Umbraco.Core.Composing; using Umbraco.Core.IO; using Umbraco.Tests.TestHelpers; @@ -14,13 +15,13 @@ namespace Umbraco.Tests.CoreThings [SetUp] public void SetUp() { - _root = SystemDirectories.Root; + _root = Current.IOHelper.Root; } [TearDown] public void TearDown() { - SystemDirectories.Root = _root; + Current.IOHelper.Root = _root; } [TestCase("http://www.domain.com/umbraco", "", true)] @@ -32,7 +33,7 @@ namespace Umbraco.Tests.CoreThings [TestCase("http://www.domain.com/umbraco/test/test.js", "", true)] [TestCase("http://www.domain.com/umbrac", "", false)] [TestCase("http://www.domain.com/test", "", false)] - [TestCase("http://www.domain.com/test/umbraco", "", false)] + [TestCase("http://www.domain.com/test/umbraco", "", false)] [TestCase("http://www.domain.com/Umbraco/Backoffice/blah", "", true)] [TestCase("http://www.domain.com/Umbraco/anything", "", true)] [TestCase("http://www.domain.com/Umbraco/anything/", "", true)] @@ -44,7 +45,7 @@ namespace Umbraco.Tests.CoreThings [TestCase("http://www.domain.com/umbraco/test/legacyAjaxCalls.ashx?some=query&blah=js", "", true)] public void Is_Back_Office_Request(string input, string virtualPath, bool expected) { - SystemDirectories.Root = virtualPath; + Current.IOHelper.Root = virtualPath; var globalConfig = SettingsForTests.GenerateMockGlobalSettings(); var source = new Uri(input); Assert.AreEqual(expected, source.IsBackOfficeRequest(virtualPath, globalConfig)); @@ -58,7 +59,7 @@ namespace Umbraco.Tests.CoreThings [TestCase("http://www.domain.com/install/test/test.js", true)] [TestCase("http://www.domain.com/instal", false)] [TestCase("http://www.domain.com/umbraco", false)] - [TestCase("http://www.domain.com/umbraco/umbraco", false)] + [TestCase("http://www.domain.com/umbraco/umbraco", false)] public void Is_Installer_Request(string input, bool expected) { var source = new Uri(input); diff --git a/src/Umbraco.Tests/IO/FileSystemsTests.cs b/src/Umbraco.Tests/IO/FileSystemsTests.cs index 254371ae32..a7d4bd7c3b 100644 --- a/src/Umbraco.Tests/IO/FileSystemsTests.cs +++ b/src/Umbraco.Tests/IO/FileSystemsTests.cs @@ -34,6 +34,7 @@ namespace Umbraco.Tests.IO composition.Register(_ => Mock.Of()); composition.Register(_ => Mock.Of()); composition.RegisterUnique(); + composition.RegisterUnique(IOHelper.Default); composition.Configs.Add(SettingsForTests.GetDefaultGlobalSettings); composition.Configs.Add(SettingsForTests.GetDefaultUmbracoSettings); diff --git a/src/Umbraco.Tests/IO/IoHelperTests.cs b/src/Umbraco.Tests/IO/IoHelperTests.cs index 2a7e633e4f..6c45f416b9 100644 --- a/src/Umbraco.Tests/IO/IoHelperTests.cs +++ b/src/Umbraco.Tests/IO/IoHelperTests.cs @@ -3,12 +3,16 @@ using NUnit.Framework; using Umbraco.Core.IO; using Umbraco.Core; using Umbraco.Core.Composing; +using Umbraco.Core.Configuration; +using Umbraco.Tests.TestHelpers; namespace Umbraco.Tests.IO { [TestFixture] public class IoHelperTests { + private IIOHelper _ioHelper => IOHelper.Default; + [TestCase("~/Scripts", "/Scripts", null)] [TestCase("/Scripts", "/Scripts", null)] [TestCase("../Scripts", "/Scripts", typeof(ArgumentException))] @@ -32,18 +36,19 @@ namespace Umbraco.Tests.IO public void IOHelper_MapPathTestVDirTraversal() { //System.Diagnostics.Debugger.Break(); + var globalSettings = SettingsForTests.GenerateMockGlobalSettings(); - Assert.AreEqual(Current.IOHelper.MapPath(SystemDirectories.Bin, true), Current.IOHelper.MapPath(SystemDirectories.Bin, false)); - Assert.AreEqual(Current.IOHelper.MapPath(SystemDirectories.Config, true), Current.IOHelper.MapPath(SystemDirectories.Config, false)); - Assert.AreEqual(Current.IOHelper.MapPath(SystemDirectories.Css, true), Current.IOHelper.MapPath(SystemDirectories.Css, false)); - Assert.AreEqual(Current.IOHelper.MapPath(SystemDirectories.Data, true), Current.IOHelper.MapPath(SystemDirectories.Data, false)); - Assert.AreEqual(Current.IOHelper.MapPath(SystemDirectories.Install, true), Current.IOHelper.MapPath(SystemDirectories.Install, false)); - Assert.AreEqual(Current.IOHelper.MapPath(SystemDirectories.Media, true), Current.IOHelper.MapPath(SystemDirectories.Media, false)); - Assert.AreEqual(Current.IOHelper.MapPath(SystemDirectories.Packages, true), Current.IOHelper.MapPath(SystemDirectories.Packages, false)); - Assert.AreEqual(Current.IOHelper.MapPath(SystemDirectories.Preview, true), Current.IOHelper.MapPath(SystemDirectories.Preview, false)); - Assert.AreEqual(Current.IOHelper.MapPath(SystemDirectories.Root, true), Current.IOHelper.MapPath(SystemDirectories.Root, false)); - Assert.AreEqual(Current.IOHelper.MapPath(SystemDirectories.Scripts, true), Current.IOHelper.MapPath(SystemDirectories.Scripts, false)); - Assert.AreEqual(Current.IOHelper.MapPath(SystemDirectories.Umbraco, true), Current.IOHelper.MapPath(SystemDirectories.Umbraco, false)); + Assert.AreEqual(Current.IOHelper.MapPath(Constants.SystemDirectories.Bin, true), Current.IOHelper.MapPath(Constants.SystemDirectories.Bin, false)); + Assert.AreEqual(Current.IOHelper.MapPath(Constants.SystemDirectories.Config, true), Current.IOHelper.MapPath(Constants.SystemDirectories.Config, false)); + Assert.AreEqual(Current.IOHelper.MapPath(globalSettings.UmbracoCssPath, true), Current.IOHelper.MapPath(globalSettings.UmbracoCssPath, false)); + Assert.AreEqual(Current.IOHelper.MapPath(Constants.SystemDirectories.Data, true), Current.IOHelper.MapPath(Constants.SystemDirectories.Data, false)); + Assert.AreEqual(Current.IOHelper.MapPath(Constants.SystemDirectories.Install, true), Current.IOHelper.MapPath(Constants.SystemDirectories.Install, false)); + Assert.AreEqual(Current.IOHelper.MapPath(globalSettings.UmbracoMediaPath, true), Current.IOHelper.MapPath(globalSettings.UmbracoMediaPath, false)); + Assert.AreEqual(Current.IOHelper.MapPath(Constants.SystemDirectories.Packages, true), Current.IOHelper.MapPath(Constants.SystemDirectories.Packages, false)); + Assert.AreEqual(Current.IOHelper.MapPath(Constants.SystemDirectories.Preview, true), Current.IOHelper.MapPath(Constants.SystemDirectories.Preview, false)); + Assert.AreEqual(Current.IOHelper.MapPath(_ioHelper.Root, true), Current.IOHelper.MapPath(_ioHelper.Root, false)); + Assert.AreEqual(Current.IOHelper.MapPath(globalSettings.UmbracoScriptsPath, true), Current.IOHelper.MapPath(globalSettings.UmbracoScriptsPath, false)); + Assert.AreEqual(Current.IOHelper.MapPath(globalSettings.UmbracoPath, true), Current.IOHelper.MapPath(globalSettings.UmbracoPath, false)); } [Test] diff --git a/src/Umbraco.Tests/IO/ShadowFileSystemTests.cs b/src/Umbraco.Tests/IO/ShadowFileSystemTests.cs index ef5bf33824..ee24f68956 100644 --- a/src/Umbraco.Tests/IO/ShadowFileSystemTests.cs +++ b/src/Umbraco.Tests/IO/ShadowFileSystemTests.cs @@ -26,7 +26,7 @@ namespace Umbraco.Tests.IO public void SetUp() { SafeCallContext.Clear(); - ClearFiles(); + ClearFiles(IOHelper.Default); FileSystems.ResetShadowId(); } @@ -34,15 +34,14 @@ namespace Umbraco.Tests.IO public void TearDown() { SafeCallContext.Clear(); - ClearFiles(); + ClearFiles(IOHelper.Default); FileSystems.ResetShadowId(); } - private static void ClearFiles() + private static void ClearFiles(IIOHelper ioHelper) { - var ioHelper = new IOHelper(); TestHelper.DeleteDirectory(ioHelper.MapPath("FileSysTests")); - TestHelper.DeleteDirectory(ioHelper.MapPath(SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs")); + TestHelper.DeleteDirectory(ioHelper.MapPath(Constants.SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs")); } private static string NormPath(string path) @@ -53,7 +52,7 @@ namespace Umbraco.Tests.IO [Test] public void ShadowDeleteDirectory() { - var ioHelper = new IOHelper(); + var ioHelper = IOHelper.Default; var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); @@ -89,7 +88,7 @@ namespace Umbraco.Tests.IO [Test] public void ShadowDeleteDirectoryInDir() { - var ioHelper = new IOHelper(); + var ioHelper = IOHelper.Default; var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); @@ -140,7 +139,7 @@ namespace Umbraco.Tests.IO [Test] public void ShadowDeleteFile() { - var ioHelper = new IOHelper(); + var ioHelper = IOHelper.Default; var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); @@ -181,7 +180,7 @@ namespace Umbraco.Tests.IO [Test] public void ShadowDeleteFileInDir() { - var ioHelper = new IOHelper(); + var ioHelper = IOHelper.Default; var path = ioHelper.MapPath("FileSysTests"); @@ -239,7 +238,7 @@ namespace Umbraco.Tests.IO [Test] public void ShadowCantCreateFile() { - var ioHelper = new IOHelper(); + var ioHelper = IOHelper.Default; var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); @@ -260,7 +259,7 @@ namespace Umbraco.Tests.IO [Test] public void ShadowCreateFile() { - var ioHelper = new IOHelper(); + var ioHelper = IOHelper.Default; var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); @@ -301,7 +300,7 @@ namespace Umbraco.Tests.IO [Test] public void ShadowCreateFileInDir() { - var ioHelper = new IOHelper(); + var ioHelper = IOHelper.Default; var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); @@ -343,7 +342,7 @@ namespace Umbraco.Tests.IO [Test] public void ShadowAbort() { - var ioHelper = new IOHelper(); + var ioHelper = IOHelper.Default; var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); @@ -367,7 +366,7 @@ namespace Umbraco.Tests.IO [Test] public void ShadowComplete() { - var ioHelper = new IOHelper(); + var ioHelper = IOHelper.Default; var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); @@ -406,10 +405,10 @@ namespace Umbraco.Tests.IO public void ShadowScopeComplete() { var logger = Mock.Of(); - var ioHelper = new IOHelper(); + var ioHelper = IOHelper.Default; var path = ioHelper.MapPath("FileSysTests"); - var shadowfs = ioHelper.MapPath(SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs"); + var shadowfs = ioHelper.MapPath(Constants.SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs"); Directory.CreateDirectory(path); Directory.CreateDirectory(shadowfs); @@ -418,7 +417,7 @@ namespace Umbraco.Tests.IO var phy = new PhysicalFileSystem(path, "ignore", ioHelper); var container = Mock.Of(); - var fileSystems = new FileSystems(container, logger, ioHelper) { IsScoped = () => scopedFileSystems }; + var fileSystems = new FileSystems(container, logger, ioHelper, SettingsForTests.GenerateMockGlobalSettings()) { IsScoped = () => scopedFileSystems }; var fs = fileSystems.GetFileSystem(phy); var sw = (ShadowWrapper) fs.InnerFileSystem; @@ -502,10 +501,10 @@ namespace Umbraco.Tests.IO public void ShadowScopeCompleteWithFileConflict() { var logger = Mock.Of(); - var ioHelper = new IOHelper(); + var ioHelper = IOHelper.Default; var path = ioHelper.MapPath("FileSysTests"); - var shadowfs = ioHelper.MapPath(SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs"); + var shadowfs = ioHelper.MapPath(Constants.SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs"); Directory.CreateDirectory(path); var scopedFileSystems = false; @@ -513,7 +512,7 @@ namespace Umbraco.Tests.IO var phy = new PhysicalFileSystem(path, "ignore", ioHelper); var container = Mock.Of(); - var fileSystems = new FileSystems(container, logger, ioHelper) { IsScoped = () => scopedFileSystems }; + var fileSystems = new FileSystems(container, logger, ioHelper, SettingsForTests.GenerateMockGlobalSettings()) { IsScoped = () => scopedFileSystems }; var fs = fileSystems.GetFileSystem( phy); var sw = (ShadowWrapper) fs.InnerFileSystem; @@ -556,10 +555,10 @@ namespace Umbraco.Tests.IO public void ShadowScopeCompleteWithDirectoryConflict() { var logger = Mock.Of(); - var ioHelper = new IOHelper(); + var ioHelper = IOHelper.Default; var path = ioHelper.MapPath("FileSysTests"); - var shadowfs = ioHelper.MapPath(SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs"); + var shadowfs = ioHelper.MapPath(Constants.SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs"); Directory.CreateDirectory(path); var scopedFileSystems = false; @@ -567,7 +566,7 @@ namespace Umbraco.Tests.IO var phy = new PhysicalFileSystem(path, "ignore", ioHelper); var container = Mock.Of(); - var fileSystems = new FileSystems(container, logger, ioHelper) { IsScoped = () => scopedFileSystems }; + var fileSystems = new FileSystems(container, logger, ioHelper, SettingsForTests.GenerateMockGlobalSettings()) { IsScoped = () => scopedFileSystems }; var fs = fileSystems.GetFileSystem( phy); var sw = (ShadowWrapper)fs.InnerFileSystem; @@ -626,7 +625,7 @@ namespace Umbraco.Tests.IO [Test] public void GetFilesReturnsChildrenOnly() { - var ioHelper = new IOHelper(); + var ioHelper = IOHelper.Default; var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); @@ -650,7 +649,7 @@ namespace Umbraco.Tests.IO [Test] public void DeleteDirectoryAndFiles() { - var ioHelper = new IOHelper(); + var ioHelper = IOHelper.Default; var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); @@ -673,7 +672,7 @@ namespace Umbraco.Tests.IO public void ShadowGetFiles() { // Arrange - var ioHelper = new IOHelper(); + var ioHelper = IOHelper.Default; var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); @@ -707,7 +706,7 @@ namespace Umbraco.Tests.IO public void ShadowGetFilesUsingEmptyFilter() { // Arrange - var ioHelper = new IOHelper(); + var ioHelper = IOHelper.Default; var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); @@ -744,7 +743,7 @@ namespace Umbraco.Tests.IO public void ShadowGetFilesUsingNullFilter() { // Arrange - var ioHelper = new IOHelper(); + var ioHelper = IOHelper.Default; var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); @@ -778,7 +777,7 @@ namespace Umbraco.Tests.IO public void ShadowGetFilesUsingWildcardFilter() { // Arrange - var ioHelper = new IOHelper(); + var ioHelper = IOHelper.Default; var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); @@ -815,7 +814,7 @@ namespace Umbraco.Tests.IO public void ShadowGetFilesUsingSingleCharacterFilter() { // Arrange - var ioHelper = new IOHelper(); + var ioHelper = IOHelper.Default; var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); @@ -864,7 +863,7 @@ namespace Umbraco.Tests.IO public void ShadowGetFullPath() { // Arrange - var ioHelper = new IOHelper(); + var ioHelper = IOHelper.Default; var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); @@ -900,7 +899,7 @@ namespace Umbraco.Tests.IO public void ShadowGetRelativePath() { // Arrange - var ioHelper = new IOHelper(); + var ioHelper = IOHelper.Default; var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); @@ -941,7 +940,7 @@ namespace Umbraco.Tests.IO public void ShadowGetUrl() { // Arrange - var ioHelper = new IOHelper(); + var ioHelper = IOHelper.Default; var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); diff --git a/src/Umbraco.Tests/LegacyXmlPublishedCache/PreviewContent.cs b/src/Umbraco.Tests/LegacyXmlPublishedCache/PreviewContent.cs index adbd15b16a..5812fde11c 100644 --- a/src/Umbraco.Tests/LegacyXmlPublishedCache/PreviewContent.cs +++ b/src/Umbraco.Tests/LegacyXmlPublishedCache/PreviewContent.cs @@ -108,7 +108,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache _previewXml = _xmlStore.GetPreviewXml(contentId, includeSubs); // make sure the preview folder exists - var dir = new DirectoryInfo(Current.IOHelper.MapPath(SystemDirectories.Preview)); + var dir = new DirectoryInfo(Current.IOHelper.MapPath(Constants.SystemDirectories.Preview)); if (dir.Exists == false) dir.Create(); @@ -122,7 +122,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache // get the full path to the preview set private static string GetPreviewSetPath(int userId, Guid previewSet) { - return Current.IOHelper.MapPath(Path.Combine(SystemDirectories.Preview, userId + "_" + previewSet + ".config")); + return Current.IOHelper.MapPath(Path.Combine(Constants.SystemDirectories.Preview, userId + "_" + previewSet + ".config")); } // deletes files for the user, and files accessed more than one hour ago diff --git a/src/Umbraco.Tests/Manifest/ManifestContentAppTests.cs b/src/Umbraco.Tests/Manifest/ManifestContentAppTests.cs index 1e02f562e3..fe3e8a6bdf 100644 --- a/src/Umbraco.Tests/Manifest/ManifestContentAppTests.cs +++ b/src/Umbraco.Tests/Manifest/ManifestContentAppTests.cs @@ -3,9 +3,11 @@ using System.Linq; using Moq; using Newtonsoft.Json; using NUnit.Framework; +using Umbraco.Core.IO; using Umbraco.Core.Manifest; using Umbraco.Core.Models; using Umbraco.Core.Models.Membership; +using Umbraco.Web.Composing; namespace Umbraco.Tests.Manifest { @@ -67,7 +69,7 @@ namespace Umbraco.Tests.Manifest private void AssertDefinition(object source, bool expected, string[] show, IReadOnlyUserGroup[] groups) { var definition = JsonConvert.DeserializeObject("{" + (show.Length == 0 ? "" : " \"show\": [" + string.Join(",", show.Select(x => "\"" + x + "\"")) + "] ") + "}"); - var factory = new ManifestContentAppFactory(definition); + var factory = new ManifestContentAppFactory(definition, IOHelper.Default); var app = factory.GetContentAppFor(source, groups); if (expected) Assert.IsNotNull(app); diff --git a/src/Umbraco.Tests/Manifest/ManifestParserTests.cs b/src/Umbraco.Tests/Manifest/ManifestParserTests.cs index dff37edc74..955c7ba776 100644 --- a/src/Umbraco.Tests/Manifest/ManifestParserTests.cs +++ b/src/Umbraco.Tests/Manifest/ManifestParserTests.cs @@ -14,6 +14,7 @@ using Umbraco.Core.PropertyEditors.Validators; using Umbraco.Core.Services; using Umbraco.Core.Dashboards; using Umbraco.Core.IO; +using Umbraco.Core.Serialization; namespace Umbraco.Tests.Manifest { @@ -25,27 +26,12 @@ namespace Umbraco.Tests.Manifest [SetUp] public void Setup() { - Current.Reset(); - var factory = Mock.Of(); - Current.Factory = factory; - - var serviceContext = ServiceContext.CreatePartial( - localizedTextService: Mock.Of()); - - Mock.Get(factory) - .Setup(x => x.GetInstance(It.IsAny())) - .Returns(x => - { - if (x == typeof(ServiceContext)) return serviceContext; - throw new Exception("oops"); - }); - var validators = new IManifestValueValidator[] { new RequiredValidator(Mock.Of()), new RegexValidator(Mock.Of(), null) }; - _parser = new ManifestParser(AppCaches.Disabled, new ManifestValueValidatorCollection(validators), new ManifestFilterCollection(Array.Empty()), Mock.Of(), Mock.Of()); + _parser = new ManifestParser(AppCaches.Disabled, new ManifestValueValidatorCollection(validators), new ManifestFilterCollection(Array.Empty()), Mock.Of(), IOHelper.Default, Mock.Of(), Mock.Of(), new JsonNetSerializer()); } [Test] diff --git a/src/Umbraco.Tests/Mapping/MappingTests.cs b/src/Umbraco.Tests/Mapping/MappingTests.cs index e6a382692c..ad336168c6 100644 --- a/src/Umbraco.Tests/Mapping/MappingTests.cs +++ b/src/Umbraco.Tests/Mapping/MappingTests.cs @@ -285,10 +285,10 @@ namespace Umbraco.Tests.Mapping { public void DefineMaps(UmbracoMapper mapper) { - mapper.Define((source, context) => new ContentPropertyDto(), Map); + mapper.Define((source, context) => new ContentPropertyDto(), Map); } - private static void Map(Property source, ContentPropertyDto target, MapperContext context) + private static void Map(IProperty source, ContentPropertyDto target, MapperContext context) { } } diff --git a/src/Umbraco.Tests/Models/Collections/Item.cs b/src/Umbraco.Tests/Models/Collections/Item.cs index 5d1ab24fb0..7c7f207aa2 100644 --- a/src/Umbraco.Tests/Models/Collections/Item.cs +++ b/src/Umbraco.Tests/Models/Collections/Item.cs @@ -11,6 +11,7 @@ namespace Umbraco.Tests.Models.Collections { public abstract class Item : IEntity, ICanBeDirty { + private bool _withChanges = true; // should we track changes? private bool _hasIdentity; private int _id; private Guid _key; @@ -26,10 +27,7 @@ namespace Umbraco.Tests.Models.Collections [DataMember] public int Id { - get - { - return _id; - } + get => _id; set { _id = value; @@ -45,14 +43,8 @@ namespace Umbraco.Tests.Models.Collections [DataMember] public Guid Key { - get - { - if (_key == Guid.Empty) - return _id.ToGuid(); - - return _key; - } - set { _key = value; } + get => _key == Guid.Empty ? _id.ToGuid() : _key; + set => _key = value; } /// @@ -93,12 +85,12 @@ namespace Umbraco.Tests.Models.Collections /// The property info. protected virtual void OnPropertyChanged(PropertyInfo propertyInfo) { + if (_withChanges == false) + return; + _propertyChangedInfo[propertyInfo.Name] = true; - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyInfo.Name)); - } + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyInfo.Name)); } internal virtual void ResetIdentity() @@ -128,7 +120,7 @@ namespace Umbraco.Tests.Models.Collections /// Tracks the properties that have changed /// //private readonly IDictionary _propertyChangedInfo = new Dictionary(); - private IDictionary _propertyChangedInfo; + private readonly IDictionary _propertyChangedInfo; /// /// Indicates whether a specific property on the current entity is dirty. @@ -166,19 +158,29 @@ namespace Umbraco.Tests.Models.Collections _propertyChangedInfo.Clear(); } + /// + /// Disables change tracking. + /// + public void DisableChangeTracking() + { + _withChanges = false; + } + + /// + /// Enables change tracking. + /// + public void EnableChangeTracking() + { + _withChanges = true; + } + /// /// Indicates whether the current entity has an identity, eg. Id. /// public virtual bool HasIdentity { - get - { - return _hasIdentity; - } - protected set - { - _hasIdentity = value; - } + get => _hasIdentity; + protected set => _hasIdentity = value; } public static bool operator ==(Item left, Item right) diff --git a/src/Umbraco.Tests/Models/ContentExtensionsTests.cs b/src/Umbraco.Tests/Models/ContentExtensionsTests.cs index 42d7f0e01b..52cf5ddef5 100644 --- a/src/Umbraco.Tests/Models/ContentExtensionsTests.cs +++ b/src/Umbraco.Tests/Models/ContentExtensionsTests.cs @@ -32,7 +32,7 @@ namespace Umbraco.Tests.Models Composition.Register(_ => Mock.Of()); // all this is required so we can validate properties... - var editor = new TextboxPropertyEditor(Mock.Of()) { Alias = "test" }; + var editor = new TextboxPropertyEditor(Mock.Of(), Mock.Of(), Mock.Of()) { Alias = "test" }; Composition.Register(_ => new DataEditorCollection(new[] { editor })); Composition.Register(); var dataType = Mock.Of(); diff --git a/src/Umbraco.Tests/Models/ContentTests.cs b/src/Umbraco.Tests/Models/ContentTests.cs index ffbf462b8e..ee6649dd2b 100644 --- a/src/Umbraco.Tests/Models/ContentTests.cs +++ b/src/Umbraco.Tests/Models/ContentTests.cs @@ -43,7 +43,7 @@ namespace Umbraco.Tests.Models Composition.Register(_ => Mock.Of()); // all this is required so we can validate properties... - var editor = new TextboxPropertyEditor(Mock.Of()) { Alias = "test" }; + var editor = new TextboxPropertyEditor(Mock.Of(), Mock.Of(), Mock.Of()) { Alias = "test" }; Composition.Register(_ => new DataEditorCollection(new [] { editor })); Composition.Register(); var dataType = Mock.Of(); @@ -57,7 +57,7 @@ namespace Umbraco.Tests.Models var mediaTypeService = Mock.Of(); var memberTypeService = Mock.Of(); Composition.Register(_ => ServiceContext.CreatePartial(dataTypeService: dataTypeService, contentTypeBaseServiceProvider: new ContentTypeBaseServiceProvider(_contentTypeService, mediaTypeService, memberTypeService))); - + } [Test] diff --git a/src/Umbraco.Tests/Models/Mapping/ContentTypeModelMappingTests.cs b/src/Umbraco.Tests/Models/Mapping/ContentTypeModelMappingTests.cs index 21180ce51b..968e51ab97 100644 --- a/src/Umbraco.Tests/Models/Mapping/ContentTypeModelMappingTests.cs +++ b/src/Umbraco.Tests/Models/Mapping/ContentTypeModelMappingTests.cs @@ -24,6 +24,7 @@ namespace Umbraco.Tests.Models.Mapping private readonly Mock _dataTypeService = new Mock(); private readonly Mock _entityService = new Mock(); private readonly Mock _fileService = new Mock(); + private readonly Mock _localizationService = new Mock(); private Mock _editorsMock; protected override void Compose() @@ -31,7 +32,7 @@ namespace Umbraco.Tests.Models.Mapping base.Compose(); // create and register a fake property editor collection to return fake property editors - var editors = new DataEditor[] { new TextboxPropertyEditor(Mock.Of()), }; + var editors = new DataEditor[] { new TextboxPropertyEditor(Mock.Of(), _dataTypeService.Object, _localizationService.Object), }; var dataEditors = new DataEditorCollection(editors); _editorsMock = new Mock(dataEditors); _editorsMock.Setup(x => x[It.IsAny()]).Returns(editors[0]); diff --git a/src/Umbraco.Tests/Models/Mapping/ContentWebModelMappingTests.cs b/src/Umbraco.Tests/Models/Mapping/ContentWebModelMappingTests.cs index 6a4054d5ae..9a47ad1b4a 100644 --- a/src/Umbraco.Tests/Models/Mapping/ContentWebModelMappingTests.cs +++ b/src/Umbraco.Tests/Models/Mapping/ContentWebModelMappingTests.cs @@ -40,7 +40,7 @@ namespace Umbraco.Tests.Models.Mapping Composition.Register(_ => Mock.Of()); // all this is required so we can validate properties... - var editor = new TextboxPropertyEditor(Mock.Of()) { Alias = "test" }; + var editor = new TextboxPropertyEditor(Mock.Of(), Mock.Of(), Mock.Of()) { Alias = "test" }; Composition.Register(_ => new DataEditorCollection(new[] { editor })); Composition.Register(); var dataType = Mock.Of(); @@ -261,7 +261,7 @@ namespace Umbraco.Tests.Models.Mapping #region Assertions - private void AssertDisplayProperty(IContentProperties result, Property p) + private void AssertDisplayProperty(IContentProperties result, IProperty p) where T : ContentPropertyBasic { var pDto = result.Properties.SingleOrDefault(x => x.Alias == p.Alias); @@ -325,7 +325,7 @@ namespace Umbraco.Tests.Models.Mapping Assert.AreEqual(content.Properties.Count(), result.Properties.Count(x => x.Alias.StartsWith("_umb_") == false)); } - private void AssertBasicProperty(IContentProperties result, Property p) + private void AssertBasicProperty(IContentProperties result, IProperty p) where T : ContentPropertyBasic { var pDto = result.Properties.SingleOrDefault(x => x.Alias == p.Alias); @@ -341,7 +341,7 @@ namespace Umbraco.Tests.Models.Mapping Assert.AreEqual(pDto.Value, p.GetValue().ToString()); } - private void AssertProperty(IContentProperties result, Property p) + private void AssertProperty(IContentProperties result, IProperty p) { AssertBasicProperty(result, p); diff --git a/src/Umbraco.Tests/Models/MediaXmlTest.cs b/src/Umbraco.Tests/Models/MediaXmlTest.cs index d7daf35865..b4eb0efb73 100644 --- a/src/Umbraco.Tests/Models/MediaXmlTest.cs +++ b/src/Umbraco.Tests/Models/MediaXmlTest.cs @@ -33,6 +33,8 @@ namespace Umbraco.Tests.Models var logger = Mock.Of(); var scheme = Mock.Of(); var config = Mock.Of(); + var dataTypeService = Mock.Of(); + var localizationService = Mock.Of(); var ioHelper = Mock.Of(); var mediaFileSystem = new MediaFileSystem(Mock.Of(), config, scheme, logger, ioHelper); diff --git a/src/Umbraco.Tests/Models/PropertyTypeTests.cs b/src/Umbraco.Tests/Models/PropertyTypeTests.cs index 1bc99162af..b4d14e7bb5 100644 --- a/src/Umbraco.Tests/Models/PropertyTypeTests.cs +++ b/src/Umbraco.Tests/Models/PropertyTypeTests.cs @@ -54,7 +54,15 @@ namespace Umbraco.Tests.Models var allProps = clone.GetType().GetProperties(); foreach (var propertyInfo in allProps) { - Assert.AreEqual(propertyInfo.GetValue(clone, null), propertyInfo.GetValue(pt, null)); + var expected = propertyInfo.GetValue(pt, null); + var actual = propertyInfo.GetValue(clone, null); + if (propertyInfo.PropertyType == typeof(Lazy)) + { + expected = ((Lazy) expected).Value; + actual = ((Lazy) actual).Value; + } + + Assert.AreEqual(expected, actual, $"Value of propery: '{propertyInfo.Name}': {expected} != {actual}"); } } diff --git a/src/Umbraco.Tests/Models/VariationTests.cs b/src/Umbraco.Tests/Models/VariationTests.cs index ab5f726894..c7ebb9ef71 100644 --- a/src/Umbraco.Tests/Models/VariationTests.cs +++ b/src/Umbraco.Tests/Models/VariationTests.cs @@ -8,6 +8,7 @@ using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; +using Umbraco.Core.Services.Implement; using Umbraco.Tests.TestHelpers; namespace Umbraco.Tests.Models @@ -35,9 +36,12 @@ namespace Umbraco.Tests.Models var factory = Mock.Of(); Current.Factory = factory; + var dataTypeService = Mock.Of(); + var localizationService = Mock.Of(); + var dataEditors = new DataEditorCollection(new IDataEditor[] { - new DataEditor(Mock.Of()) { Alias = "editor", ExplicitValueEditor = new DataValueEditor("view") } + new DataEditor(Mock.Of()) { Alias = "editor", ExplicitValueEditor = TestHelper.CreateDataValueEditor("view") } }); var propertyEditors = new PropertyEditorCollection(dataEditors); @@ -46,7 +50,6 @@ namespace Umbraco.Tests.Models .Setup(x => x.Configuration) .Returns(null); - var dataTypeService = Mock.Of(); Mock.Get(dataTypeService) .Setup(x => x.GetDataType(It.IsAny())) .Returns(x => dataType); @@ -75,7 +78,7 @@ namespace Umbraco.Tests.Models // 1. if exact is set to true: culture cannot be null when the ContentVariation.Culture flag is set // 2. if wildcards is set to false: fail when "*" is passed in as either culture or segment. // 3. ContentVariation flag is ignored when wildcards are used. - // 4. Empty string is considered the same as null + // 4. Empty string is considered the same as null #region Nothing @@ -141,7 +144,7 @@ namespace Umbraco.Tests.Models #endregion #region CultureAndSegment - + Assert4B(ContentVariation.CultureAndSegment, null, null, false, true, false, true); Assert4B(ContentVariation.CultureAndSegment, null, "", false, true, false, true); Assert4B(ContentVariation.CultureAndSegment, null, "*", false, false, false, true); @@ -163,7 +166,7 @@ namespace Umbraco.Tests.Models } /// - /// Asserts the result of + /// Asserts the result of /// /// /// diff --git a/src/Umbraco.Tests/Persistence/Repositories/PartialViewRepositoryTests.cs b/src/Umbraco.Tests/Persistence/Repositories/PartialViewRepositoryTests.cs index 970e078d41..9fa5488815 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/PartialViewRepositoryTests.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/PartialViewRepositoryTests.cs @@ -1,6 +1,8 @@ using System.Linq; using Moq; using NUnit.Framework; +using Umbraco.Core; +using Umbraco.Core.Composing; using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; @@ -20,7 +22,7 @@ namespace Umbraco.Tests.Persistence.Repositories { base.SetUp(); - _fileSystem = new PhysicalFileSystem(SystemDirectories.MvcViews + "/Partials/", new IOHelper()); + _fileSystem = new PhysicalFileSystem(Constants.SystemDirectories.MvcViews + "/Partials/", IOHelper); } protected override void Compose() diff --git a/src/Umbraco.Tests/Persistence/Repositories/ScriptRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/ScriptRepositoryTest.cs index d1aa20db66..1c82287842 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/ScriptRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/ScriptRepositoryTest.cs @@ -3,6 +3,9 @@ using System.Linq; using System.Text; using Moq; using NUnit.Framework; +using Umbraco.Core; +using Umbraco.Core.Composing; +using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.IO; using Umbraco.Core.Models; @@ -26,7 +29,7 @@ namespace Umbraco.Tests.Persistence.Repositories base.SetUp(); _fileSystems = Mock.Of(); - _fileSystem = new PhysicalFileSystem(SystemDirectories.Scripts, new IOHelper()); + _fileSystem = new PhysicalFileSystem(new GlobalSettings().UmbracoScriptsPath); Mock.Get(_fileSystems).Setup(x => x.ScriptsFileSystem).Returns(_fileSystem); using (var stream = CreateStream("Umbraco.Sys.registerNamespace(\"Umbraco.Utils\");")) { @@ -36,7 +39,7 @@ namespace Umbraco.Tests.Persistence.Repositories private IScriptRepository CreateRepository() { - return new ScriptRepository(_fileSystems, new IOHelper()); + return new ScriptRepository(_fileSystems, IOHelper); } protected override void Compose() diff --git a/src/Umbraco.Tests/Persistence/Repositories/StylesheetRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/StylesheetRepositoryTest.cs index 5443ca52ec..ef28b42f05 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/StylesheetRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/StylesheetRepositoryTest.cs @@ -4,6 +4,9 @@ using System.Linq; using System.Text; using Moq; using NUnit.Framework; +using Umbraco.Core; +using Umbraco.Core.Composing; +using Umbraco.Core.Configuration; using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Repositories; @@ -25,7 +28,7 @@ namespace Umbraco.Tests.Persistence.Repositories base.SetUp(); _fileSystems = Mock.Of(); - _fileSystem = new PhysicalFileSystem(SystemDirectories.Css, new IOHelper()); + _fileSystem = new PhysicalFileSystem(new GlobalSettings().UmbracoCssPath); Mock.Get(_fileSystems).Setup(x => x.StylesheetsFileSystem).Returns(_fileSystem); var stream = CreateStream("body {background:#EE7600; color:#FFF;}"); _fileSystem.AddFile("styles.css", stream); @@ -33,7 +36,7 @@ namespace Umbraco.Tests.Persistence.Repositories private IStylesheetRepository CreateRepository() { - return new StylesheetRepository(_fileSystems, new IOHelper()); + return new StylesheetRepository(_fileSystems, IOHelper); } [Test] diff --git a/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs index 2d6c42ef06..200a1c8687 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs @@ -7,6 +7,7 @@ using Moq; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Cache; +using Umbraco.Core.Composing; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.IO; using Umbraco.Core.Models; @@ -35,7 +36,7 @@ namespace Umbraco.Tests.Persistence.Repositories base.SetUp(); _fileSystems = Mock.Of(); - var viewsFileSystem = new PhysicalFileSystem(SystemDirectories.MvcViews, IOHelper); + var viewsFileSystem = new PhysicalFileSystem(Constants.SystemDirectories.MvcViews); Mock.Get(_fileSystems).Setup(x => x.MvcViewsFileSystem).Returns(viewsFileSystem); } @@ -63,7 +64,7 @@ namespace Umbraco.Tests.Persistence.Repositories // Act var template = new Template("test", "test"); repository.Save(template); - + //Assert Assert.That(repository.Get("test"), Is.Not.Null); @@ -526,7 +527,7 @@ namespace Umbraco.Tests.Persistence.Repositories _fileSystems = null; //Delete all files - var fsViews = new PhysicalFileSystem(SystemDirectories.MvcViews, new IOHelper()); + var fsViews = new PhysicalFileSystem(Constants.SystemDirectories.MvcViews); var views = fsViews.GetFiles("", "*.cshtml"); foreach (var file in views) fsViews.DeleteFile(file); @@ -615,7 +616,7 @@ namespace Umbraco.Tests.Persistence.Repositories repository.Save(toddler4); repository.Save(baby1); repository.Save(baby2); - + return new[] {parent, child1, child2, toddler1, toddler2, toddler3, toddler4, baby1, baby2}; } diff --git a/src/Umbraco.Tests/PropertyEditors/ImageCropperTest.cs b/src/Umbraco.Tests/PropertyEditors/ImageCropperTest.cs index 01486d70c8..5752219a93 100644 --- a/src/Umbraco.Tests/PropertyEditors/ImageCropperTest.cs +++ b/src/Umbraco.Tests/PropertyEditors/ImageCropperTest.cs @@ -84,7 +84,7 @@ namespace Umbraco.Tests.PropertyEditors var mediaFileSystem = new MediaFileSystem(Mock.Of(), config, scheme, logger, ioHelper); var dataTypeService = new TestObjects.TestDataTypeService( - new DataType(new ImageCropperPropertyEditor(Mock.Of(), mediaFileSystem, Mock.Of(), Mock.Of())) { Id = 1 }); + new DataType(new ImageCropperPropertyEditor(Mock.Of(), mediaFileSystem, Mock.Of(), Mock.Of(), Mock.Of())) { Id = 1 }); var factory = new PublishedContentTypeFactory(Mock.Of(), new PropertyValueConverterCollection(Array.Empty()), dataTypeService); diff --git a/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs b/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs index b7037eb192..5579395b7e 100644 --- a/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs +++ b/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs @@ -25,12 +25,12 @@ namespace Umbraco.Tests.PropertyEditors /// to cache. Now we always just deal with strings and we'll keep the tests that show that. /// [TestFixture] - public class MultiValuePropertyEditorTests + public class MultiValuePropertyEditorTests { [Test] public void DropDownMultipleValueEditor_Format_Data_For_Cache() { - var dataType = new DataType(new CheckBoxListPropertyEditor(Mock.Of(), Mock.Of())) + var dataType = new DataType(new CheckBoxListPropertyEditor(Mock.Of(), Mock.Of(), Mock.Of(), Mock.Of())) { Configuration = new ValueListConfiguration { @@ -51,7 +51,7 @@ namespace Umbraco.Tests.PropertyEditors var valueEditor = dataType.Editor.GetValueEditor(); ((DataValueEditor) valueEditor).Configuration = dataType.Configuration; - var result = valueEditor.ConvertDbToString(prop.PropertyType, prop.GetValue(), dataTypeService); + var result = valueEditor.ConvertDbToString(prop.PropertyType, prop.GetValue()); Assert.AreEqual("Value 1,Value 2,Value 3", result); } @@ -59,7 +59,7 @@ namespace Umbraco.Tests.PropertyEditors [Test] public void DropDownValueEditor_Format_Data_For_Cache() { - var dataType = new DataType(new CheckBoxListPropertyEditor(Mock.Of(), Mock.Of())) + var dataType = new DataType(new CheckBoxListPropertyEditor(Mock.Of(), Mock.Of(), Mock.Of(), Mock.Of())) { Configuration = new ValueListConfiguration { @@ -78,7 +78,7 @@ namespace Umbraco.Tests.PropertyEditors var prop = new Property(1, new PropertyType(dataType)); prop.SetValue("Value 2"); - var result = dataType.Editor.GetValueEditor().ConvertDbToString(prop.PropertyType, prop.GetValue(), dataTypeService); + var result = dataType.Editor.GetValueEditor().ConvertDbToString(prop.PropertyType, prop.GetValue()); Assert.AreEqual("Value 2", result); } diff --git a/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueEditorTests.cs b/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueEditorTests.cs index eda6d4f5bb..bb1b0e4b10 100644 --- a/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueEditorTests.cs +++ b/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueEditorTests.cs @@ -47,12 +47,9 @@ namespace Umbraco.Tests.PropertyEditors var prop = new Property(1, new PropertyType("test", ValueStorageType.Nvarchar)); prop.SetValue(value); - var valueEditor = new DataValueEditor - { - ValueType = ValueTypes.String - }; + var valueEditor = TestHelper.CreateDataValueEditor(ValueTypes.String); - var result = valueEditor.ToEditor(prop, new Mock().Object); + var result = valueEditor.ToEditor(prop); Assert.AreEqual(isOk, !(result is string)); } @@ -63,10 +60,7 @@ namespace Umbraco.Tests.PropertyEditors [TestCase("DATETIME", "", null)] //test empty string for date public void Value_Editor_Can_Convert_To_Clr_Type(string valueType, string val, object expected) { - var valueEditor = new DataValueEditor - { - ValueType = valueType - }; + var valueEditor = TestHelper.CreateDataValueEditor(valueType); var result = valueEditor.TryConvertValueToCrlType(val); Assert.IsTrue(result.Success); @@ -78,10 +72,7 @@ namespace Umbraco.Tests.PropertyEditors [Test] public void Value_Editor_Can_Convert_To_Decimal_Clr_Type() { - var valueEditor = new DataValueEditor - { - ValueType = ValueTypes.Decimal - }; + var valueEditor = TestHelper.CreateDataValueEditor(ValueTypes.Decimal); var result = valueEditor.TryConvertValueToCrlType("12.34"); Assert.IsTrue(result.Success); @@ -91,10 +82,7 @@ namespace Umbraco.Tests.PropertyEditors [Test] public void Value_Editor_Can_Convert_To_Decimal_Clr_Type_With_Other_Separator() { - var valueEditor = new DataValueEditor - { - ValueType = ValueTypes.Decimal - }; + var valueEditor = TestHelper.CreateDataValueEditor(ValueTypes.Decimal); var result = valueEditor.TryConvertValueToCrlType("12,34"); Assert.IsTrue(result.Success); @@ -104,10 +92,7 @@ namespace Umbraco.Tests.PropertyEditors [Test] public void Value_Editor_Can_Convert_To_Decimal_Clr_Type_With_Empty_String() { - var valueEditor = new DataValueEditor - { - ValueType = ValueTypes.Decimal - }; + var valueEditor = TestHelper.CreateDataValueEditor(ValueTypes.Decimal); var result = valueEditor.TryConvertValueToCrlType(string.Empty); Assert.IsTrue(result.Success); @@ -117,10 +102,7 @@ namespace Umbraco.Tests.PropertyEditors [Test] public void Value_Editor_Can_Convert_To_Date_Clr_Type() { - var valueEditor = new DataValueEditor - { - ValueType = ValueTypes.Date - }; + var valueEditor = TestHelper.CreateDataValueEditor(ValueTypes.Date); var result = valueEditor.TryConvertValueToCrlType("2010-02-05"); Assert.IsTrue(result.Success); @@ -137,12 +119,9 @@ namespace Umbraco.Tests.PropertyEditors var prop = new Property(1, new PropertyType("test", ValueStorageType.Nvarchar)); prop.SetValue(val); - var valueEditor = new DataValueEditor - { - ValueType = valueType - }; + var valueEditor = TestHelper.CreateDataValueEditor(valueType); - var result = valueEditor.ToEditor(prop, new Mock().Object); + var result = valueEditor.ToEditor(prop); Assert.AreEqual(expected, result); } @@ -150,30 +129,24 @@ namespace Umbraco.Tests.PropertyEditors public void Value_Editor_Can_Serialize_Decimal_Value() { var value = 12.34M; - var valueEditor = new DataValueEditor - { - ValueType = ValueTypes.Decimal - }; + var valueEditor = TestHelper.CreateDataValueEditor(ValueTypes.Decimal); var prop = new Property(1, new PropertyType("test", ValueStorageType.Decimal)); prop.SetValue(value); - var result = valueEditor.ToEditor(prop, new Mock().Object); + var result = valueEditor.ToEditor(prop); Assert.AreEqual("12.34", result); } [Test] public void Value_Editor_Can_Serialize_Decimal_Value_With_Empty_String() { - var valueEditor = new DataValueEditor - { - ValueType = ValueTypes.Decimal - }; + var valueEditor = TestHelper.CreateDataValueEditor(ValueTypes.Decimal); var prop = new Property(1, new PropertyType("test", ValueStorageType.Decimal)); prop.SetValue(string.Empty); - var result = valueEditor.ToEditor(prop, new Mock().Object); + var result = valueEditor.ToEditor(prop); Assert.AreEqual(string.Empty, result); } @@ -181,15 +154,12 @@ namespace Umbraco.Tests.PropertyEditors public void Value_Editor_Can_Serialize_Date_Value() { var now = DateTime.Now; - var valueEditor = new DataValueEditor - { - ValueType = ValueTypes.Date - }; + var valueEditor = TestHelper.CreateDataValueEditor(ValueTypes.Date); var prop = new Property(1, new PropertyType("test", ValueStorageType.Date)); prop.SetValue(now); - var result = valueEditor.ToEditor(prop, new Mock().Object); + var result = valueEditor.ToEditor(prop); Assert.AreEqual(now.ToIsoString(), result); } } diff --git a/src/Umbraco.Tests/Published/NestedContentTests.cs b/src/Umbraco.Tests/Published/NestedContentTests.cs index 9385b8955a..4d99aa86d8 100644 --- a/src/Umbraco.Tests/Published/NestedContentTests.cs +++ b/src/Umbraco.Tests/Published/NestedContentTests.cs @@ -11,6 +11,7 @@ using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; using Umbraco.Tests.PublishedContent; using Umbraco.Tests.TestHelpers; using Umbraco.Web; @@ -31,9 +32,10 @@ namespace Umbraco.Tests.Published var logger = Mock.Of(); var profiler = Mock.Of(); var proflog = new ProfilingLogger(logger, profiler); + var localizationService = Mock.Of(); PropertyEditorCollection editors = null; - var editor = new NestedContentPropertyEditor(logger, new Lazy(() => editors)); + var editor = new NestedContentPropertyEditor(logger, new Lazy(() => editors), Mock.Of(), localizationService); editors = new PropertyEditorCollection(new DataEditorCollection(new DataEditor[] { editor })); var dataType1 = new DataType(editor) @@ -64,7 +66,7 @@ namespace Umbraco.Tests.Published } }; - var dataType3 = new DataType(new TextboxPropertyEditor(logger)) + var dataType3 = new DataType(new TextboxPropertyEditor(logger, Mock.Of(), localizationService)) { Id = 3 }; diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs index f1e2bf20d6..bf55f1783f 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs @@ -40,7 +40,13 @@ namespace Umbraco.Tests.PublishedContent var converters = Factory.GetInstance(); var dataTypeService = new TestObjects.TestDataTypeService( - new DataType(new RichTextPropertyEditor(Mock.Of(), Mock.Of(), Mock.Of(), Mock.Of())) { Id = 1 }); + new DataType(new RichTextPropertyEditor( + Mock.Of(), + Mock.Of(), + Mock.Of(), + Mock.Of(), + Mock.Of(), + Mock.Of())) { Id = 1 }); var publishedContentTypeFactory = new PublishedContentTypeFactory(Mock.Of(), converters, dataTypeService); diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs index b42dc32b24..7c70e82047 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs @@ -47,13 +47,14 @@ namespace Umbraco.Tests.PublishedContent var mediaService = Mock.Of(); var contentTypeBaseServiceProvider = Mock.Of(); var umbracoContextAccessor = Mock.Of(); + var localizationService = Mock.Of(); var dataTypeService = new TestObjects.TestDataTypeService( new DataType(new VoidEditor(logger)) { Id = 1 }, new DataType(new TrueFalsePropertyEditor(logger)) { Id = 1001 }, - new DataType(new RichTextPropertyEditor(logger, mediaService, contentTypeBaseServiceProvider, umbracoContextAccessor)) { Id = 1002 }, + new DataType(new RichTextPropertyEditor(logger, mediaService, contentTypeBaseServiceProvider, umbracoContextAccessor, Mock.Of(), localizationService)) { Id = 1002 }, new DataType(new IntegerPropertyEditor(logger)) { Id = 1003 }, - new DataType(new TextboxPropertyEditor(logger)) { Id = 1004 }, + new DataType(new TextboxPropertyEditor(logger, Mock.Of(), localizationService)) { Id = 1004 }, new DataType(new MediaPickerPropertyEditor(logger)) { Id = 1005 }); Composition.RegisterUnique(f => dataTypeService); } diff --git a/src/Umbraco.Tests/Scoping/ScopeEventDispatcherTests.cs b/src/Umbraco.Tests/Scoping/ScopeEventDispatcherTests.cs index 2ede62f81e..44984047f1 100644 --- a/src/Umbraco.Tests/Scoping/ScopeEventDispatcherTests.cs +++ b/src/Umbraco.Tests/Scoping/ScopeEventDispatcherTests.cs @@ -36,7 +36,7 @@ namespace Umbraco.Tests.Scoping _testObjects = new TestObjects(register); - composition.RegisterUnique(factory => new FileSystems(factory, factory.TryGetInstance(), factory.TryGetInstance())); + composition.RegisterUnique(factory => new FileSystems(factory, factory.TryGetInstance(), IOHelper.Default, SettingsForTests.GenerateMockGlobalSettings())); composition.WithCollectionBuilder(); composition.Configs.Add(SettingsForTests.GetDefaultGlobalSettings); diff --git a/src/Umbraco.Tests/Scoping/ScopeFileSystemsTests.cs b/src/Umbraco.Tests/Scoping/ScopeFileSystemsTests.cs index 7abf8eece3..b5c441a280 100644 --- a/src/Umbraco.Tests/Scoping/ScopeFileSystemsTests.cs +++ b/src/Umbraco.Tests/Scoping/ScopeFileSystemsTests.cs @@ -46,7 +46,7 @@ namespace Umbraco.Tests.Scoping { TestHelper.DeleteDirectory(ioHelper.MapPath("media")); TestHelper.DeleteDirectory(ioHelper.MapPath("FileSysTests")); - TestHelper.DeleteDirectory(ioHelper.MapPath(SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs")); + TestHelper.DeleteDirectory(ioHelper.MapPath(Constants.SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs")); } [TestCase(true)] diff --git a/src/Umbraco.Tests/Services/PropertyValidationServiceTests.cs b/src/Umbraco.Tests/Services/PropertyValidationServiceTests.cs index 425c03a9b4..746190d67f 100644 --- a/src/Umbraco.Tests/Services/PropertyValidationServiceTests.cs +++ b/src/Umbraco.Tests/Services/PropertyValidationServiceTests.cs @@ -32,7 +32,7 @@ namespace Umbraco.Tests.Services x => x.Type == EditorType.PropertyValue && x.Alias == Constants.PropertyEditors.Aliases.TextBox); Mock.Get(dataEditor).Setup(x => x.GetValueEditor(It.IsAny())) - .Returns(new CustomTextOnlyValueEditor(new DataEditorAttribute(Constants.PropertyEditors.Aliases.TextBox, "Test Textbox", "textbox"), textService.Object)); + .Returns(new CustomTextOnlyValueEditor(Mock.Of(), Mock.Of(), new DataEditorAttribute(Constants.PropertyEditors.Aliases.TextBox, "Test Textbox", "textbox"), textService.Object)); var propEditors = new PropertyEditorCollection(new DataEditorCollection(new[] { dataEditor })); @@ -164,7 +164,7 @@ namespace Umbraco.Tests.Services { private readonly ILocalizedTextService _textService; - public CustomTextOnlyValueEditor(DataEditorAttribute attribute, ILocalizedTextService textService) : base(attribute) + public CustomTextOnlyValueEditor(IDataTypeService dataTypeService, ILocalizationService localizationService, DataEditorAttribute attribute, ILocalizedTextService textService) : base(dataTypeService, localizationService, attribute) { _textService = textService; } diff --git a/src/Umbraco.Tests/TestHelpers/SettingsForTests.cs b/src/Umbraco.Tests/TestHelpers/SettingsForTests.cs index 98ae816317..d04ad98f6d 100644 --- a/src/Umbraco.Tests/TestHelpers/SettingsForTests.cs +++ b/src/Umbraco.Tests/TestHelpers/SettingsForTests.cs @@ -24,7 +24,15 @@ namespace Umbraco.Tests.TestHelpers settings.LocalTempStorageLocation == LocalTempStorage.Default && settings.LocalTempPath == Current.IOHelper.MapPath("~/App_Data/TEMP") && settings.ReservedPaths == (GlobalSettings.StaticReservedPaths + "~/umbraco") && - settings.ReservedUrls == GlobalSettings.StaticReservedUrls); + settings.ReservedUrls == GlobalSettings.StaticReservedUrls && + settings.UmbracoPath == "~/umbraco" && + settings.UmbracoMediaPath == "~/media" && + settings.UmbracoCssPath == "~/css" && + settings.UmbracoScriptsPath == "~/scripts" + ); + + + return config; } diff --git a/src/Umbraco.Tests/TestHelpers/TestHelper.cs b/src/Umbraco.Tests/TestHelpers/TestHelper.cs index e07dbe1e5a..975cf72bfb 100644 --- a/src/Umbraco.Tests/TestHelpers/TestHelper.cs +++ b/src/Umbraco.Tests/TestHelpers/TestHelper.cs @@ -12,11 +12,13 @@ using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Composing; +using Umbraco.Core.Configuration; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.Entities; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; using File = System.IO.File; namespace Umbraco.Tests.TestHelpers @@ -62,12 +64,12 @@ namespace Umbraco.Tests.TestHelpers public static void InitializeContentDirectories() { - CreateDirectories(new[] { SystemDirectories.MvcViews, SystemDirectories.Media, SystemDirectories.AppPlugins }); + CreateDirectories(new[] { Constants.SystemDirectories.MvcViews, new GlobalSettings().UmbracoMediaPath, Constants.SystemDirectories.AppPlugins }); } public static void CleanContentDirectories() { - CleanDirectories(new[] { SystemDirectories.MvcViews, SystemDirectories.Media }); + CleanDirectories(new[] { Constants.SystemDirectories.MvcViews, new GlobalSettings().UmbracoMediaPath }); } public static void CreateDirectories(string[] directories) @@ -84,7 +86,7 @@ namespace Umbraco.Tests.TestHelpers { var preserves = new Dictionary { - { SystemDirectories.MvcViews, new[] {"dummy.txt"} } + { Constants.SystemDirectories.MvcViews, new[] {"dummy.txt"} } }; foreach (var directory in directories) { @@ -247,5 +249,20 @@ namespace Umbraco.Tests.TestHelpers } } } + + public static DataValueEditor CreateDataValueEditor(string name) + { + var valueType = (ValueTypes.IsValue(name)) ? name : ValueTypes.String; + + return new DataValueEditor( + Mock.Of(), + Mock.Of(), + new DataEditorAttribute(name, name, name) + { + ValueType = valueType + } + + ); + } } } diff --git a/src/Umbraco.Tests/TestHelpers/TestObjects.cs b/src/Umbraco.Tests/TestHelpers/TestObjects.cs index eaade28c2e..29c0a7328a 100644 --- a/src/Umbraco.Tests/TestHelpers/TestObjects.cs +++ b/src/Umbraco.Tests/TestHelpers/TestObjects.cs @@ -78,6 +78,7 @@ namespace Umbraco.Tests.TestHelpers /// /// A cache. /// A logger. + /// An io helper. /// /// /// An event messages factory. @@ -92,6 +93,7 @@ namespace Umbraco.Tests.TestHelpers IScopeProvider scopeProvider, IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger, + IIOHelper ioHelper, IGlobalSettings globalSettings, IUmbracoSettingsSection umbracoSettings, IEventMessagesFactory eventMessagesFactory, @@ -107,7 +109,6 @@ namespace Umbraco.Tests.TestHelpers var scheme = Mock.Of(); var config = Mock.Of(); - var ioHelper = Mock.Of(); var mediaFileSystem = new MediaFileSystem(Mock.Of(), config, scheme, logger, ioHelper); @@ -243,7 +244,7 @@ namespace Umbraco.Tests.TestHelpers } typeFinder = typeFinder ?? new TypeFinder(logger); - fileSystems = fileSystems ?? new FileSystems(Current.Factory, logger, new IOHelper()); + fileSystems = fileSystems ?? new FileSystems(Current.Factory, logger, IOHelper.Default, SettingsForTests.GenerateMockGlobalSettings()); var scopeProvider = new ScopeProvider(databaseFactory, fileSystems, logger, typeFinder); return scopeProvider; } diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index de76b94ff1..75abcc4d88 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -56,7 +56,6 @@ - @@ -79,7 +78,7 @@ - + 1.8.14 @@ -107,6 +106,7 @@ + diff --git a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs index f7b1799d63..1653de827d 100644 --- a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs +++ b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs @@ -7,6 +7,7 @@ using Lucene.Net.Analysis; using Lucene.Net.Analysis.Standard; using Lucene.Net.Store; using Moq; +using Umbraco.Core; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.Membership; @@ -44,11 +45,10 @@ namespace Umbraco.Tests.UmbracoExamine public static MediaIndexPopulator GetMediaIndexRebuilder(PropertyEditorCollection propertyEditors, IMediaService mediaService) { - var mediaValueSetBuilder = new MediaValueSetBuilder(propertyEditors, new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }), GetMockUserService()); + var mediaValueSetBuilder = new MediaValueSetBuilder(propertyEditors, new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }), GetMockUserService(), GetMockLogger()); var mediaIndexDataSource = new MediaIndexPopulator(null, mediaService, mediaValueSetBuilder); return mediaIndexDataSource; } - public static IContentService GetMockContentService() { long longTotalRecs; @@ -146,6 +146,11 @@ namespace Umbraco.Tests.UmbracoExamine return mediaTypeServiceMock.Object; } + public static IProfilingLogger GetMockLogger() + { + return new ProfilingLogger(Mock.Of(), Mock.Of()); + } + public static UmbracoContentIndex GetUmbracoIndexer( IProfilingLogger profilingLogger, Directory luceneDir, diff --git a/src/Umbraco.Web.UI.Client/gulp/tasks/dependencies.js b/src/Umbraco.Web.UI.Client/gulp/tasks/dependencies.js index a9d77b03c6..def956ac9f 100644 --- a/src/Umbraco.Web.UI.Client/gulp/tasks/dependencies.js +++ b/src/Umbraco.Web.UI.Client/gulp/tasks/dependencies.js @@ -259,19 +259,18 @@ function dependencies() { //css, fonts and image files var assetsTask = gulp.src(config.sources.globs.assets, { allowEmpty: true }); - if (global.isProd === true) { - assetsTask = assetsTask.pipe(imagemin([ - imagemin.gifsicle({interlaced: true}), - imagemin.jpegtran({progressive: true}), - imagemin.optipng({optimizationLevel: 5}), - imagemin.svgo({ - plugins: [ - {removeViewBox: true}, - {cleanupIDs: false} - ] - }) - ])); - } + assetsTask = assetsTask.pipe(imagemin([ + imagemin.gifsicle({interlaced: true}), + imagemin.jpegtran({progressive: true}), + imagemin.optipng({optimizationLevel: 5}), + imagemin.svgo({ + plugins: [ + {removeViewBox: true}, + {cleanupIDs: false} + ] + }) + ])); + assetsTask = assetsTask.pipe(gulp.dest(config.root + config.targets.assets)); stream.add(assetsTask); diff --git a/src/Umbraco.Web.UI.Client/gulp/tasks/removeProductionMode.js b/src/Umbraco.Web.UI.Client/gulp/tasks/removeProductionMode.js deleted file mode 100644 index 3481d84e39..0000000000 --- a/src/Umbraco.Web.UI.Client/gulp/tasks/removeProductionMode.js +++ /dev/null @@ -1,22 +0,0 @@ -'use strict'; - -var gulp = require('gulp'); -var through2 = require('through2'); - -function createEmptyStream() { - var pass = through2.obj(); - process.nextTick(pass.end.bind(pass)); - return pass; -} - -/************************** - * Copies all angular JS files into their separate umbraco.*.js file - **************************/ -function removeProductionMode() { - - global.isProd = false; - - return createEmptyStream(); -}; - -module.exports = { removeProductionMode: removeProductionMode }; diff --git a/src/Umbraco.Web.UI.Client/gulp/util/processJs.js b/src/Umbraco.Web.UI.Client/gulp/util/processJs.js index d8e4ca61d1..e3e393b661 100644 --- a/src/Umbraco.Web.UI.Client/gulp/util/processJs.js +++ b/src/Umbraco.Web.UI.Client/gulp/util/processJs.js @@ -23,11 +23,10 @@ module.exports = function (files, out) { // sort files in stream by path or any custom sort comparator task = task.pipe(babel()) .pipe(sort()); - - if (global.isProd === true) { - //in production, embed the templates - task = task.pipe(embedTemplates({ basePath: "./src/", minimize: { loose: true } })) - } + + //in production, embed the templates + task = task.pipe(embedTemplates({ basePath: "./src/", minimize: { loose: true } })) + task = task.pipe(concat(out)) .pipe(wrap('(function(){\n%= body %\n})();')) .pipe(gulp.dest(config.root + config.targets.js)); diff --git a/src/Umbraco.Web.UI.Client/gulpfile.js b/src/Umbraco.Web.UI.Client/gulpfile.js index 3c1c8646fd..1e4dc591ca 100644 --- a/src/Umbraco.Web.UI.Client/gulpfile.js +++ b/src/Umbraco.Web.UI.Client/gulpfile.js @@ -10,8 +10,6 @@ * and then add the exports command to add the new item into the task menu. */ -global.isProd = true; - const { src, dest, series, parallel, lastRun } = require('gulp'); const { dependencies } = require('./gulp/tasks/dependencies'); @@ -20,7 +18,6 @@ const { less } = require('./gulp/tasks/less'); const { testE2e, testUnit } = require('./gulp/tasks/test'); const { views } = require('./gulp/tasks/views'); const { watchTask } = require('./gulp/tasks/watchTask'); -const { removeProductionMode } = require('./gulp/tasks/removeProductionMode'); // Load local overwrites, can be used to overwrite paths in your local setup. var fs = require('fs'); @@ -41,7 +38,6 @@ try { // *********************************************************** exports.build = series(parallel(dependencies, js, less, views), testUnit); exports.dev = series(parallel(dependencies, js, less, views), watchTask); -exports.fastdev = series(removeProductionMode, parallel(dependencies, js, less, views), watchTask); exports.watch = series(watchTask); // exports.runTests = series(js, testUnit); diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js index efe65de8bf..6559e16206 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js @@ -195,6 +195,7 @@ Use this directive to construct a header inside the main editor window. @param {string=} icon Show and edit the content icon. Opens an overlay to change the icon. @param {boolean=} hideIcon Set to true to hide icon. @param {string=} alias show and edit the content alias. +@param {boolean=} aliasLocked Set to true to lock the alias. @param {boolean=} hideAlias Set to true to hide alias. @param {string=} description Add a description to the content. @param {boolean=} hideDescription Set to true to hide description. @@ -347,6 +348,7 @@ Use this directive to construct a header inside the main editor window. icon: "=", hideIcon: "@", alias: "=", + aliasLocked: "<", hideAlias: "=", description: "=", hideDescription: "@", diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbconfirm.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbconfirm.directive.js index 1ddd09357a..9114cfb1c1 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbconfirm.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbconfirm.directive.js @@ -56,6 +56,7 @@ function confirmDirective() { onCancel: '=', caption: '@', confirmButtonStyle: '@', + confirmDisabled: ' - + diff --git a/src/Umbraco.Web.UI.Client/src/views/components/umb-confirm.html b/src/Umbraco.Web.UI.Client/src/views/components/umb-confirm.html index 384c5ccaf7..d8e4f09b8a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/umb-confirm.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/umb-confirm.html @@ -14,6 +14,7 @@ action="confirm()" button-style="{{confirmButtonStyle || 'primary'}}" state="confirmButtonState" + disabled="confirmDisabled === true" label-key="{{confirmLabelKey || 'general_ok'}}"> diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/settings/settingsdashboardintro.html b/src/Umbraco.Web.UI.Client/src/views/dashboard/settings/settingsdashboardintro.html index cc3e57bdc4..0ad88b9894 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dashboard/settings/settingsdashboardintro.html +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/settings/settingsdashboardintro.html @@ -1,14 +1,30 @@ -

Start here

-

This section contains the building blocks for your Umbraco site. Follow the below links to find out more about working with the items in the Settings section:

-
Find out more:
+

+ Start here +

+ +

This section contains the building blocks for your Umbraco site. Follow the below links to find out more about working with the items in the Settings section:

+
: +
+ Find out more: +
diff --git a/src/Umbraco.Web.UI.Client/src/views/datatypes/datatype.delete.controller.js b/src/Umbraco.Web.UI.Client/src/views/datatypes/datatype.delete.controller.js index c6c58d9fa6..4542cde343 100644 --- a/src/Umbraco.Web.UI.Client/src/views/datatypes/datatype.delete.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/datatypes/datatype.delete.controller.js @@ -51,6 +51,12 @@ function DataTypeDeleteController($scope, dataTypeResource, treeService, navigat navigationService.hideDialog(); }; + vm.onReferenceClicked = function(event) { + if (event.metaKey !== true) { + navigationService.hideDialog(); + } + }; + vm.labels = {}; localizationService .localize("editdatatype_acceptDeleteConsequence", [$scope.currentNode.name]) diff --git a/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html b/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html index bc201e2c39..bdce1723a0 100644 --- a/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html +++ b/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html @@ -50,7 +50,7 @@ - {{::relation.name}} + {{::relation.name}}

{{::property.name}}

@@ -74,7 +74,7 @@ - {{::relation.name}} + {{::relation.name}}

{{::property.name}}

@@ -98,7 +98,7 @@ - {{::relation.name}} + {{::relation.name}}

{{::property.name}}

diff --git a/src/Umbraco.Web.UI.Client/src/views/datatypes/views/datatype.references.html b/src/Umbraco.Web.UI.Client/src/views/datatypes/views/datatype.references.html index dfa633ad16..6c9fabc848 100644 --- a/src/Umbraco.Web.UI.Client/src/views/datatypes/views/datatype.references.html +++ b/src/Umbraco.Web.UI.Client/src/views/datatypes/views/datatype.references.html @@ -68,7 +68,7 @@
{{::reference.name}}
{{::reference.alias}}
{{::reference.properties | umbCmsJoinArray:', ':'name'}}
- + @@ -98,7 +98,7 @@
{{::reference.name}}
{{::reference.alias}}
{{::reference.properties | umbCmsJoinArray:', ':'name'}}
- + diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js index 7921da9c22..3db1221f5e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js @@ -673,6 +673,7 @@ angular.module("umbraco") return ((spans / $scope.model.config.items.columns) * 100).toFixed(8); }; + $scope.clearPrompt = function (scopedObject, e) { scopedObject.deletePrompt = false; e.preventDefault(); @@ -692,8 +693,15 @@ angular.module("umbraco") }; $scope.getTemplateName = function (control) { - if (control.editor.nameExp) return control.editor.nameExp(control) - return control.editor.name; + var templateName = control.editor.name; + if (control.editor.nameExp) { + var valueOfTemplate = control.editor.nameExp(control); + if (valueOfTemplate != "") { + templateName += ": "; + templateName += valueOfTemplate; + } + } + return templateName; } // ********************************************* diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html index 3995ed703d..e889067321 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html @@ -95,7 +95,7 @@
- +
- + - @@ -85,9 +84,9 @@ - - - + + + @@ -110,6 +109,7 @@ runtime; build; native; contentfiles; analyzers all + @@ -351,6 +351,9 @@ 9000 / http://localhost:9000/ + 8600 + / + http://localhost:8600/ False False @@ -432,4 +435,4 @@ - + \ No newline at end of file diff --git a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/RegisterMember.cshtml b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/RegisterMember.cshtml index ca6f09bd97..17ed95ea31 100644 --- a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/RegisterMember.cshtml +++ b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/RegisterMember.cshtml @@ -85,7 +85,7 @@ else easily change it. For example, if you wanted to render a custom editor for this field called "MyEditor" you would create a file at ~/Views/Shared/EditorTemplates/MyEditor.cshtml", then you will change the next line of code to render your specific editor template like: - @Html.EditorFor(m => profileModel.MemberProperties[i].Value, "MyEditor") + @Html.EditorFor(m => registerModel.MemberProperties[i].Value, "MyEditor") *@ @Html.EditorFor(m => registerModel.MemberProperties[i].Value) @Html.HiddenFor(m => registerModel.MemberProperties[i].Alias) diff --git a/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml b/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml index 59568b508e..2eca580097 100644 --- a/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml +++ b/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml @@ -33,7 +33,7 @@ Umbraco @Html.RenderCssHere( - new BasicPath("Umbraco", Current.IOHelper.ResolveUrl(SystemDirectories.Umbraco))) + new BasicPath("Umbraco", Current.IOHelper.ResolveUrl(Current.Configs.Global().UmbracoPath))) @*Because we're lazy loading angular js, the embedded cloak style will not be loaded initially, but we need it*@ - - - - -
- - - - - -
- -
- -
-
- - - - - - -
-
-
- - - - -
- - - - -
-

- Password reset requested -

-

- Your username to login to the Umbraco back-office is: %0% -

-

- - - - - - -
- - Click this link to reset your password - -
-

-

If you cannot click on the link, copy and paste this URL into your browser window:

- - - - -
- - %1% - -
-

-
-
-


-
-
- - - ]]> - - - Dashboard - Sections - Content - - - Choose page above... - %0% has been copied to %1% - Select where the document %0% should be copied to below - %0% has been moved to %1% - Select where the document %0% should be moved to below - has been selected as the root of your new content, click 'ok' below. - No node selected yet, please select a node in the list above before clicking 'ok' - The current node is not allowed under the chosen node because of its type - The current node cannot be moved to one of its subpages - The current node cannot exist at the root - The action isn't allowed since you have insufficient permissions on 1 or more child documents. - Relate copied items to original - - - %0%]]> - Notification settings saved for - - The following languages have been modified %0% - - - - - - - - - - - -
- - - - - -
- -
- -
-
- - - - - - -
-
-
- - - - -
- - - - -
-

- Hi %0%, -

-

- This is an automated mail to inform you that the task '%1%' has been performed on the page '%2%' by the user '%3%' -

- - - - - - -
- -
- EDIT
-
-

-

Update summary:

- %6% -

-

- Have a nice day!

- Cheers from the Umbraco robot -

-
-
-


-
-
- - - ]]>
- The following languages have been modified:

- %0% - ]]>
- [%0%] Notification about %1% performed on %2% - Notifications - - - Actions - Created - Create package - - button and locating the package. Umbraco packages usually have a ".umb" or ".zip" extension. - ]]> - This will delete the package - Drop to upload - Include all child nodes - or click here to choose package file - Upload package - Install a local package by selecting it from your machine. Only install packages from sources you know and trust - Upload another package - Cancel and upload another package - I accept - terms of use - Path to file - Absolute path to file (ie: /bin/umbraco.bin) - Installed - Installed packages - Install local - Finish - This package has no configuration view - No packages have been created yet - You don’t have any packages installed - 'Packages' icon in the top right of your screen]]> - Package Actions - Author URL - Package Content - Package Files - Icon URL - Install package - License - License URL - Package Properties - Search for packages - Results for - We couldn’t find anything for - Please try searching for another package or browse through the categories - Popular - New releases - has - karma points - Information - Owner - Contributors - Created - Current version - .NET version - Downloads - Likes - Compatibility - This package is compatible with the following versions of Umbraco, as reported by community members. Full compatability cannot be guaranteed for versions reported below 100% - External sources - Author - Documentation - Package meta data - Package name - Package doesn't contain any items -
- You can safely remove this from the system by clicking "uninstall package" below.]]>
- Package options - Package readme - Package repository - Confirm package uninstall - Package was uninstalled - The package was successfully uninstalled - Uninstall package - - Notice: any documents, media etc depending on the items you remove, will stop working, and could lead to system instability, - so uninstall with caution. If in doubt, contact the package author.]]> - Package version - Upgrading from version - Package already installed - This package cannot be installed, it requires a minimum Umbraco version of - Uninstalling... - Downloading... - Importing... - Installing... - Restarting, please wait... - All done, your browser will now refresh, please wait... - Please click 'Finish' to complete installation and reload the page. - Uploading package... - - - Paste with full formatting (Not recommended) - The text you're trying to paste contains special characters or formatting. This could be caused by copying text from Microsoft Word. Umbraco can remove special characters or formatting automatically, so the pasted content will be more suitable for the web. - Paste as raw text without any formatting at all - Paste, but remove formatting (Recommended) - - - Group based protection - If you want to grant access to all members of specific member groups - You need to create a member group before you can use group based authentication - Error Page - Used when people are logged on, but do not have access - %0%]]> - %0% is now protected]]> - %0%]]> - Login Page - Choose the page that contains the login form - Remove protection... - %0%?]]> - Select the pages that contain login form and error messages - %0%]]> - %0%]]> - Specific members protection - If you wish to grant access to specific members - - - Insufficient user permissions to publish all descendant documents - - - - - - - - Validation failed for required language '%0%'. This language was saved but not published. - Publishing in progress - please wait... - %0% out of %1% pages have been published... - %0% has been published - %0% and subpages have been published - Publish %0% and all its subpages - Publish to publish %0% and thereby making its content publicly available.

- You can publish this page and all its subpages by checking Include unpublished subpages below. - ]]>
- - - You have not configured any approved colors - - - You can only select items of type(s): %0% - You have picked a content item currently deleted or in the recycle bin - You have picked content items currently deleted or in the recycle bin - - - Deleted item - You have picked a media item currently deleted or in the recycle bin - You have picked media items currently deleted or in the recycle bin - Trashed - - - enter external link - choose internal page - Caption - Link - Open in new window - enter the display caption - Enter the link - - - Reset crop - Save crop - Add new crop - Done - Undo edits - - - Select a version to compare with the current version - Current version - Red text will not be shown in the selected version. , green means added]]> - Document has been rolled back - This displays the selected version as HTML, if you wish to see the difference between 2 versions at the same time, use the diff view - Rollback to - Select version - View - - - Edit script file - - - Content - Forms - Media - Members - Packages - Settings - Translation - Users - - - The best Umbraco video tutorials - - - Default template - To import a document type, find the ".udt" file on your computer by clicking the "Browse" button and click "Import" (you'll be asked for confirmation on the next screen) - New Tab Title - Node type - Type - Stylesheet - Script - Tab - Tab Title - Tabs - Master Content Type enabled - This Content Type uses - as a Master Content Type. Tabs from Master Content Types are not shown and can only be edited on the Master Content Type itself - No properties defined on this tab. Click on the "add a new property" link at the top to create a new property. - Create matching template - Add icon - - - Sort order - Creation date - Sorting complete. - Drag the different items up or down below to set how they should be arranged. Or click the column headers to sort the entire collection of items - - This node has no child nodes to sort - - - Validation - Validation errors must be fixed before the item can be saved - Failed - Saved - Insufficient user permissions, could not complete the operation - Cancelled - Operation was cancelled by a 3rd party add-in - Property type already exists - Property type created - DataType: %1%]]> - Propertytype deleted - Document Type saved - Tab created - Tab deleted - Tab with id: %0% deleted - Stylesheet not saved - Stylesheet saved - Stylesheet saved without any errors - Datatype saved - Dictionary item saved - Content published - and is visible on the website - %0% documents published and visible on the website - %0% published and visible on the website - %0% documents published for languages %1% and visible on the website - Content saved - Remember to publish to make changes visible - A schedule for publishing has been updated - %0% saved - Sent For Approval - Changes have been sent for approval - %0% changes have been sent for approval - Media saved - Media saved without any errors - Member saved - Member group saved - Stylesheet Property Saved - Stylesheet saved - Template saved - Error saving user (check log) - User Saved - User type saved - User group saved - File not saved - file could not be saved. Please check file permissions - File saved - File saved without any errors - Language saved - Media Type saved - Member Type saved - Member Group saved - Template not saved - Please make sure that you do not have 2 templates with the same alias - Template saved - Template saved without any errors! - Content unpublished - Content variation %0% unpublished - The mandatory language '%0%' was unpublished. All languages for this content item are now unpublished. - Partial view saved - Partial view saved without any errors! - Partial view not saved - An error occurred saving the file. - Permissions saved for - Deleted %0% user groups - %0% was deleted - Enabled %0% users - Disabled %0% users - %0% is now enabled - %0% is now disabled - User groups have been set - Unlocked %0% users - %0% is now unlocked - Member was exported to file - An error occurred while exporting the member - User %0% was deleted - Invite user - Invitation has been re-sent to %0% - Cannot publish the document since the required '%0%' is not published - Validation failed for language '%0%' - Document type was exported to file - An error occurred while exporting the document type - The release date cannot be in the past - Cannot schedule the document for publishing since the required '%0%' is not published - Cannot schedule the document for publishing since the required '%0%' has a publish date later than a non mandatory language - The expire date cannot be in the past - The expire date cannot be before the release date - - - Add style - Edit style - Rich text editor styles - Define the styles that should be available in the rich text editor for this stylesheet - Edit stylesheet - Edit stylesheet property - The name displayed in the editor style selector - Preview - How the text will look like in the rich text editor. - Selector - Uses CSS syntax, e.g. "h1" or ".redHeader" - Styles - The CSS that should be applied in the rich text editor, e.g. "color:red;" - Code - Rich Text Editor - - - Failed to delete template with ID %0% - Edit template - Sections - Insert content area - Insert content area placeholder - Insert - Choose what to insert into your template - Dictionary item - A dictionary item is a placeholder for a translatable piece of text, which makes it easy to create designs for multilingual websites. - Macro - - A Macro is a configurable component which is great for - reusable parts of your design, where you need the option to provide parameters, - such as galleries, forms and lists. - - Value - Displays the value of a named field from the current page, with options to modify the value or fallback to alternative values. - Partial view - - A partial view is a separate template file which can be rendered inside another - template, it's great for reusing markup or for separating complex templates into separate files. - - Master template - No master - Render child template - @RenderBody() placeholder. - ]]> - Define a named section - @section { ... }. This can be rendered in a - specific area of the parent of this template, by using @RenderSection. - ]]> - Render a named section - @RenderSection(name) placeholder. - This renders an area of a child template which is wrapped in a corresponding @section [name]{ ... } definition. - ]]> - Section Name - Section is mandatory - - If mandatory, the child template must contain a @section definition, otherwise an error is shown. - - Query builder - items returned, in - copy to clipboard - I want - all content - content of type "%0%" - from - my website - where - and - is - is not - before - before (including selected date) - after - after (including selected date) - equals - does not equal - contains - does not contain - greater than - greater than or equal to - less than - less than or equal to - Id - Name - Created Date - Last Updated Date - order by - ascending - descending - Template - - - Image - Macro - Choose type of content - Choose a layout - Add a row - Add content - Drop content - Settings applied - This content is not allowed here - This content is allowed here - Click to embed - Click to insert image - Image caption... - Write here... - Grid Layouts - Layouts are the overall work area for the grid editor, usually you only need one or two different layouts - Add Grid Layout - Adjust the layout by setting column widths and adding additional sections - Row configurations - Rows are predefined cells arranged horizontally - Add row configuration - Adjust the row by setting cell widths and adding additional cells - Columns - Total combined number of columns in the grid layout - Settings - Configure what settings editors can change - Styles - Configure what styling editors can change - Allow all editors - Allow all row configurations - Maximum items - Leave blank or set to 0 for unlimited - Set as default - Choose extra - Choose default - are added - - - Compositions - Group - You have not added any groups - Add group - Inherited from - Add property - Required label - Enable list view - Configures the content item to show a sortable and searchable list of its children, the children will not be shown in the tree - Allowed Templates - Choose which templates editors are allowed to use on content of this type - Allow as root - Allow editors to create content of this type in the root of the content tree. - Allowed child node types - Allow content of the specified types to be created underneath content of this type. - Choose child node - Inherit tabs and properties from an existing document type. New tabs will be added to the current document type or merged if a tab with an identical name exists. - This content type is used in a composition, and therefore cannot be composed itself. - There are no content types available to use as a composition. - Removing a composition will delete all the associated property data. Once you save the document type there's no way back. - Create new - Use existing - Editor settings - Configuration - Yes, delete - was moved underneath - was copied underneath - Select the folder to move - Select the folder to copy - to in the tree structure below - All Document types - All Documents - All media items - using this document type will be deleted permanently, please confirm you want to delete these as well. - using this media type will be deleted permanently, please confirm you want to delete these as well. - using this member type will be deleted permanently, please confirm you want to delete these as well - and all documents using this type - and all media items using this type - and all members using this type - Member can edit - Allow this property value to be edited by the member on their profile page - Is sensitive data - Hide this property value from content editors that don't have access to view sensitive information - Show on member profile - Allow this property value to be displayed on the member profile page - tab has no sort order - Where is this composition used? - This composition is currently used in the composition of the following content types: - Allow varying by culture - Allow editors to create content of this type in different languages. - Allow varying by culture - Element type - Is an Element type - An Element type is meant to be used for instance in Nested Content, and not in the tree. - This is not applicable for an Element type - You have made changes to this property. Are you sure you want to discard them? - - - Add language - Mandatory language - Properties on this language have to be filled out before the node can be published. - Default language - An Umbraco site can only have one default language set. - Switching default language may result in default content missing. - Falls back to - No fall back language - To allow multi-lingual content to fall back to another language if not present in the requested language, select it here. - Fall back language - none - - - Add parameter - Edit parameter - Enter macro name - Parameters - Define the parameters that should be available when using this macro. - Select partial view macro file - - - Building models - this can take a bit of time, don't worry - Models generated - Models could not be generated - Models generation has failed, see exception in U log - - - Add fallback field - Fallback field - Add default value - Default value - Fallback field - Default value - Casing - Encoding - Choose field - Convert line breaks - Yes, convert line breaks - Replaces line breaks with 'br' html tag - Custom Fields - Date only - Format and encoding - Format as date - Format the value as a date, or a date with time, according to the active culture - HTML encode - Will replace special characters by their HTML equivalent. - Will be inserted after the field value - Will be inserted before the field value - Lowercase - Modify output - None - Output sample - Insert after field - Insert before field - Recursive - Yes, make it recursive - Separator - Standard Fields - Uppercase - URL encode - Will format special characters in URLs - Will only be used when the field values above are empty - This field will only be used if the primary field is empty - Date and time - - - Translation details - Download XML DTD - Fields - Include subpages - - No translator users found. Please create a translator user before you start sending content to translation - The page '%0%' has been send to translation - Send the page '%0%' to translation - Total words - Translate to - Translation completed. - You can preview the pages, you've just translated, by clicking below. If the original page is found, you will get a comparison of the 2 pages. - Translation failed, the XML file might be corrupt - Translation options - Translator - Upload translation XML - - - Content - Content Templates - Media - Cache Browser - Recycle Bin - Created packages - Data Types - Dictionary - Installed packages - Install skin - Install starter kit - Languages - Install local package - Macros - Media Types - Members - Member Groups - Member Roles - Member Types - Document Types - Relation Types - Packages - Packages - Partial Views - Partial View Macro Files - Install from repository - Install Runway - Runway modules - Scripting Files - Scripts - Stylesheets - Templates - Log Viewer - Users - Settings - Templating - Third Party - - - New update ready - %0% is ready, click here for download - No connection to server - Error checking for update. Please review trace-stack for further information - - - Access - Based on the assigned groups and start nodes, the user has access to the following nodes - Assign access - Administrator - Category field - User created - Change Your Password - Change photo - New password - hasn't been locked out - The password hasn't been changed - Confirm new password - You can change your password for accessing the Umbraco Back Office by filling out the form below and click the 'Change Password' button - Content Channel - Create another user - Create new users to give them access to Umbraco. When a new user is created a password will be generated that you can share with the user. - Description field - Disable User - Document Type - Editor - Excerpt field - Failed login attempts - Go to user profile - Add groups to assign access and permissions - Invite another user - Invite new users to give them access to Umbraco. An invite email will be sent to the user with information on how to log in to Umbraco. Invites last for 72 hours. - Language - Set the language you will see in menus and dialogs - Last lockout date - Last login - Password last changed - Username - Media start node - Limit the media library to a specific start node - Media start nodes - Limit the media library to specific start nodes - Sections - Disable Umbraco Access - has not logged in yet - Old password - Password - Reset password - Your password has been changed! - Please confirm the new password - Enter your new password - Your new password cannot be blank! - Current password - Invalid current password - There was a difference between the new password and the confirmed password. Please try again! - The confirmed password doesn't match the new password! - Replace child node permissions - You are currently modifying permissions for the pages: - Select pages to modify their permissions - Remove photo - Default permissions - Granular permissions - Set permissions for specific nodes - Profile - Search all children - Add sections to give users access - Select user groups - No start node selected - No start nodes selected - Content start node - Limit the content tree to a specific start node - Content start nodes - Limit the content tree to specific start nodes - User last updated - has been created - The new user has successfully been created. To log in to Umbraco use the password below. - User management - Name - User permissions - User group - has been invited - An invitation has been sent to the new user with details about how to log in to Umbraco. - Hello there and welcome to Umbraco! In just 1 minute you’ll be good to go, we just need you to setup a password and add a picture for your avatar. - Welcome to Umbraco! Unfortunately your invite has expired. Please contact your administrator and ask them to resend it. - Uploading a photo of yourself will make it easy for other users to recognize you. Click the circle above to upload your photo. - Writer - Change - Your profile - Your recent history - Session expires in - Invite user - Create user - Send invite - Back to users - Umbraco: Invitation - - - - - - - - - - - -
- - - - - -
- -
- -
-
- - - - - - -
-
-
- - - - -
- - - - -
-

- Hi %0%, -

-

- You have been invited by %1% to the Umbraco Back Office. -

-

- Message from %1%: -
- %2% -

- - - - - - -
- - - - - - -
- - Click this link to accept the invite - -
-
-

If you cannot click on the link, copy and paste this URL into your browser window:

- - - - -
- - %3% - -
-

-
-
-


-
-
- - ]]>
- Invite - Resending invitation... - Delete User - Are you sure you wish to delete this user account? - All - Active - Disabled - Locked out - Invited - Inactive - Name (A-Z) - Name (Z-A) - Newest - Oldest - Last login - - - Validation - Validate as an email address - Validate as a number - Validate as a URL - ...or enter a custom validation - Field is mandatory - Enter a regular expression - You need to add at least - You can only have - items - items selected - Invalid date - Not a number - Invalid email - Value cannot be null - Value cannot be empty - Value is invalid, it does not match the correct pattern - Custom validation - %1% more.]]> - %1% too many.]]> - - - - Value is set to the recommended value: '%0%'. - Value was set to '%1%' for XPath '%2%' in configuration file '%3%'. - Expected value '%1%' for '%2%' in configuration file '%3%', but found '%0%'. - Found unexpected value '%0%' for '%2%' in configuration file '%3%'. - - Custom errors are set to '%0%'. - Custom errors are currently set to '%0%'. It is recommended to set this to '%1%' before go live. - Custom errors successfully set to '%0%'. - MacroErrors are set to '%0%'. - MacroErrors are set to '%0%' which will prevent some or all pages in your site from loading completely if there are any errors in macros. Rectifying this will set the value to '%1%'. - MacroErrors are now set to '%0%'. - - Try Skip IIS Custom Errors is set to '%0%' and you're using IIS version '%1%'. - Try Skip IIS Custom Errors is currently '%0%'. It is recommended to set this to '%1%' for your IIS version (%2%). - Try Skip IIS Custom Errors successfully set to '%0%'. - - File does not exist: '%0%'. - '%0%' in config file '%1%'.]]> - There was an error, check log for full error: %0%. - Database - The database schema is correct for this version of Umbraco - %0% problems were detected with your database schema (Check the log for details) - Some errors were detected while validating the database schema against the current version of Umbraco. - Your website's certificate is valid. - Certificate validation error: '%0%' - Your website's SSL certificate has expired. - Your website's SSL certificate is expiring in %0% days. - Error pinging the URL %0% - '%1%' - You are currently %0% viewing the site using the HTTPS scheme. - The appSetting 'Umbraco.Core.UseHttps' is set to 'false' in your web.config file. Once you access this site using the HTTPS scheme, that should be set to 'true'. - The appSetting 'Umbraco.Core.UseHttps' is set to '%0%' in your web.config file, your cookies are %1% marked as secure. - Could not update the 'Umbraco.Core.UseHttps' setting in your web.config file. Error: %0% - - Enable HTTPS - Sets umbracoSSL setting to true in the appSettings of the web.config file. - The appSetting 'Umbraco.Core.UseHttps' is now set to 'true' in your web.config file, your cookies will be marked as secure. - Fix - Cannot fix a check with a value comparison type of 'ShouldNotEqual'. - Cannot fix a check with a value comparison type of 'ShouldEqual' with a provided value. - Value to fix check not provided. - Debug compilation mode is disabled. - Debug compilation mode is currently enabled. It is recommended to disable this setting before go live. - Debug compilation mode successfully disabled. - Trace mode is disabled. - Trace mode is currently enabled. It is recommended to disable this setting before go live. - Trace mode successfully disabled. - All folders have the correct permissions set. - - %0%.]]> - %0%. If they aren't being written to no action need be taken.]]> - All files have the correct permissions set. - - %0%.]]> - %0%. If they aren't being written to no action need be taken.]]> - X-Frame-Options used to control whether a site can be IFRAMEd by another was found.]]> - X-Frame-Options used to control whether a site can be IFRAMEd by another was not found.]]> - Set Header in Config - Adds a value to the httpProtocol/customHeaders section of web.config to prevent the site being IFRAMEd by other websites. - A setting to create a header preventing IFRAMEing of the site by other websites has been added to your web.config file. - Could not update web.config file. Error: %0% - X-Content-Type-Options used to protect against MIME sniffing vulnerabilities was found.]]> - X-Content-Type-Options used to protect against MIME sniffing vulnerabilities was not found.]]> - Adds a value to the httpProtocol/customHeaders section of web.config to protect against MIME sniffing vulnerabilities. - A setting to create a header protecting against MIME sniffing vulnerabilities has been added to your web.config file. - Strict-Transport-Security, also known as the HSTS-header, was found.]]> - Strict-Transport-Security was not found.]]> - Adds the header 'Strict-Transport-Security' with the value 'max-age=10886400' to the httpProtocol/customHeaders section of web.config. Use this fix only if you will have your domains running with https for the next 18 weeks (minimum). - The HSTS header has been added to your web.config file. - X-XSS-Protection was found.]]> - X-XSS-Protection was not found.]]> - Adds the header 'X-XSS-Protection' with the value '1; mode=block' to the httpProtocol/customHeaders section of web.config. - The X-XSS-Protection header has been added to your web.config file. - - %0%.]]> - No headers revealing information about the website technology were found. - In the Web.config file, system.net/mailsettings could not be found. - In the Web.config file system.net/mailsettings section, the host is not configured. - SMTP settings are configured correctly and the service is operating as expected. - The SMTP server configured with host '%0%' and port '%1%' could not be reached. Please check to ensure the SMTP settings in the Web.config file system.net/mailsettings are correct. - %0%.]]> - %0%.]]> -

Results of the scheduled Umbraco Health Checks run on %0% at %1% are as follows:

%2%]]>
- Umbraco Health Check Status: %0% - - - Disable URL tracker - Enable URL tracker - Culture - Original URL - Redirected To - Redirect Url Management - The following URLs redirect to this content item: - No redirects have been made - When a published page gets renamed or moved a redirect will automatically be made to the new page. - Are you sure you want to remove the redirect from '%0%' to '%1%'? - Redirect URL removed. - Error removing redirect URL. - This will remove the redirect - Are you sure you want to disable the URL tracker? - URL tracker has now been disabled. - Error disabling the URL tracker, more information can be found in your log file. - URL tracker has now been enabled. - Error enabling the URL tracker, more information can be found in your log file. - - - No Dictionary items to choose from - - - %0% characters left.]]> - %1% too many.]]> - - - Trashed content with Id: {0} related to original parent content with Id: {1} - Trashed media with Id: {0} related to original parent media item with Id: {1} - Cannot automatically restore this item - There is no location where this item can be automatically restored. You can move the item manually using the tree below. - was restored under - - - Direction - Parent to child - Bidirectional - Parent - Child - Count - Relations - Created - Comment - Name - No relations for this relation type. - Relation Type - Relations - - - Getting Started - Redirect URL Management - Content - Welcome - Examine Management - Published Status - Models Builder - Health Check - Profiling - Getting Started - Install Umbraco Forms - - - Go back - Active layout: - Jump to - group - passed - warning - failed - suggestion - Check passed - Check failed - Open backoffice search - Open/Close backoffice help - Open/Close your profile options - Open context menu for - Current language - Switch language to - Create new folder - Partial View - Partial View Macro - Member - - - References - This Data Type has no references. - Used in Document Types - No references to Document Types. - Used in Media Types - No references to Media Types. - Used in Member Types - No references to Member Types. - Used by - - - Log Levels - Saved Searches - Total Items - Timestamp - Level - Machine - Message - Exception - Properties - Search With Google - Search this message with Google - Search With Bing - Search this message with Bing - Search Our Umbraco - Search this message on Our Umbraco forums and docs - Search Our Umbraco with Google - Search Our Umbraco forums using Google - Search Umbraco Source - Search within Umbraco source code on Github - Search Umbraco Issues - Search Umbraco Issues on Github - Delete this search - Find Logs with Request ID - Find Logs with Namespace - Find Logs with Machine Name - Open - - - Copy %0% - %0% from %1% - - - Open Property Actions - - - Wait - Refresh status - Memory Cache - - - - Reload - Database Cache - - Rebuilding can be expensive. - Use it when reloading is not enough, and you think that the database cache has not been - properly generated—which would indicate some critical Umbraco issue. - ]]> - - Rebuild - Internals - - not need to use it. - ]]> - - Collect - Published Cache Status - Caches - - - Performance profiling - - - Umbraco currently runs in debug mode. This means you can use the built-in performance profiler to assess the performance when rendering pages. -

-

- If you want to activate the profiler for a specific page rendering, simply add umbDebug=true to the querystring when requesting the page. -

-

- If you want the profiler to be activated by default for all page renderings, you can use the toggle below. - It will set a cookie in your browser, which then activates the profiler automatically. - In other words, the profiler will only be active by default in your browser - not everyone else's. -

- ]]> -
- Activate the profiler by default - Friendly reminder - - - You should never let a production site run in debug mode. Debug mode is turned off by setting debug="false" on the <compilation /> element in web.config. -

- ]]> -
- - - Umbraco currently does not run in debug mode, so you can't use the built-in profiler. This is how it should be for a production site. -

-

- Debug mode is turned on by setting debug="true" on the <compilation /> element in web.config. -

- ]]> -
- - - Hours of Umbraco training videos are only a click away - - Want to master Umbraco? Spend a couple of minutes learning some best practices by watching one of these videos about using Umbraco. And visit umbraco.tv for even more Umbraco videos

- ]]> -
- To get you started - - + + + + The Umbraco community + https://our.umbraco.com/documentation/Extending-Umbraco/Language-Files + + + Culture and Hostnames + Audit Trail + Browse Node + Change Document Type + Copy + Create + Export + Create Package + Create group + Delete + Disable + Empty recycle bin + Enable + Export Document Type + Import Document Type + Import Package + Edit in Canvas + Exit + Move + Notifications + Public access + Publish + Unpublish + Reload + Republish entire site + Rename + Restore + Set permissions for the page %0% + Choose where to copy + Choose where to move + to in the tree structure below + was moved to + was copied to + was deleted + Permissions + Rollback + Send To Publish + Send To Translation + Set group + Sort + Translate + Update + Set permissions + Unlock + Create Content Template + Resend Invitation + + + Content + Administration + Structure + Other + + + Allow access to assign culture and hostnames + Allow access to view a node's history log + Allow access to view a node + Allow access to change document type for a node + Allow access to copy a node + Allow access to create nodes + Allow access to delete nodes + Allow access to move a node + Allow access to set and change public access for a node + Allow access to publish a node + Allow access to unpublish a node + Allow access to change permissions for a node + Allow access to roll back a node to a previous state + Allow access to send a node for approval before publishing + Allow access to send a node for translation + Allow access to change the sort order for nodes + Allow access to translate a node + Allow access to save a node + Allow access to create a Content Template + + + Content + Info + + + Permission denied. + Add new Domain + remove + Invalid node. + One or more domains have an invalid format. + Domain has already been assigned. + Language + Domain + New domain '%0%' has been created + Domain '%0%' is deleted + Domain '%0%' has already been assigned + Domain '%0%' has been updated + Edit Current Domains + + + Inherit + Culture + or inherit culture from parent nodes. Will also apply
+ to the current node, unless a domain below applies too.]]>
+ Domains + + + Clear selection + Select + Do something else + Bold + Cancel Paragraph Indent + Insert form field + Insert graphic headline + Edit Html + Indent Paragraph + Italic + Center + Justify Left + Justify Right + Insert Link + Insert local link (anchor) + Bullet List + Numeric List + Insert macro + Insert picture + Publish and close + Publish with descendants + Edit relations + Return to list + Save + Save and close + Save and publish + Save and schedule + Send for approval + Save list view + Schedule + Preview + Preview is disabled because there's no template assigned + Choose style + Show styles + Insert table + Generate models and close + Save and generate models + Undo + Redo + Rollback + Delete tag + Cancel + Confirm + More publishing options + + + Viewing for + Content deleted + Content unpublished + Content unpublished for languages: %0% + Content published + Content published for languages: %0% + Content saved + Content saved for languages: %0% + Content moved + Content copied + Content rolled back + Content sent for publishing + Content sent for publishing for languages: %0% + Sort child items performed by user + Copy + Publish + Publish + Move + Save + Save + Delete + Unpublish + Unpublish + Rollback + Send To Publish + Send To Publish + Sort + History (all variants) + + + To change the document type for the selected content, first select from the list of valid types for this location. + Then confirm and/or amend the mapping of properties from the current type to the new, and click Save. + The content has been re-published. + Current Property + Current type + The document type cannot be changed, as there are no alternatives valid for this location. An alternative will be valid if it is allowed under the parent of the selected content item and that all existing child content items are allowed to be created under it. + Document Type Changed + Map Properties + Map to Property + New Template + New Type + none + Content + Select New Document Type + The document type of the selected content has been successfully changed to [new type] and the following properties mapped: + to + Could not complete property mapping as one or more properties have more than one mapping defined. + Only alternate types valid for the current location are displayed. + + + Failed to create a folder under parent with ID %0% + Failed to create a folder under parent with name %0% + The folder name cannot contain illegal characters. + Failed to delete item: %0% + + + Is Published + About this page + Alias + (how would you describe the picture over the phone) + Alternative Links + Click to edit this item + Created by + Original author + Updated by + Created + Date/time this document was created + Document Type + Editing + Remove at + This item has been changed after publication + This item is not published + Last published + There are no items to show + There are no items to show in the list. + No child items have been added + No members have been added + Media Type + Link to media item(s) + Member Group + Role + Member Type + No changes have been made + No date chosen + Page title + This media item has no link + No content can be added for this item + Properties + This document is published but is not visible because the parent '%0%' is unpublished + This culture is published but is not visible because it is unpublished on parent '%0%' + This document is published but is not in the cache + Could not get the url + This document is published but its url would collide with content %0% + This document is published but its url cannot be routed + Publish + Published + Published (pending changes)> + Publication Status + Publish with descendants to publish %0% and all content items underneath and thereby making their content publicly available.]]> + Publish with descendants to publish the selected languages and the same languages of content items underneath and thereby making their content publicly available.]]> + Publish at + Unpublish at + Clear Date + Set date + Sortorder is updated + To sort the nodes, simply drag the nodes or click one of the column headers. You can select multiple nodes by holding the "shift" or "control" key while selecting + Statistics + Title (optional) + Alternative text (optional) + Type + Unpublish + Draft + Not created + Last edited + Date/time this document was edited + Remove file(s) + Link to document + Member of group(s) + Not a member of group(s) + Child items + Target + This translates to the following time on the server: + What does this mean?]]> + Are you sure you want to delete this item? + Property %0% uses editor %1% which is not supported by Nested Content. + No content types are configured for this property. + Add element type + Select element type + Add another text box + Remove this text box + Content root + Include drafts: also publish unpublished content items. + This value is hidden. If you need access to view this value please contact your website administrator. + This value is hidden. + What languages would you like to publish? All languages with content are saved! + What languages would you like to publish? + What languages would you like to save? + All languages with content are saved on creation! + What languages would you like to send for approval? + What languages would you like to schedule? + Select the languages to unpublish. Unpublishing a mandatory language will unpublish all languages. + Published Languages + Unpublished Languages + Unmodified Languages + These languages haven't been created + Ready to Publish? + Ready to Save? + Send for approval + Select the date and time to publish and/or unpublish the content item. + Create new + Paste from clipboard + + + Create a new Content Template from '%0%' + Blank + Select a Content Template + Content Template created + A Content Template was created from '%0%' + Another Content Template with the same name already exists + A Content Template is predefined content that an editor can select to use as the basis for creating new content + + + Click to upload + or click here to choose files + You can drag files here to upload. + Cannot upload this file, it does not have an approved file type + Max file size is + Media root + Failed to move media + Parent and destination folders cannot be the same + Failed to copy media + Failed to create a folder under parent id %0% + Failed to rename the folder with id %0% + Drag and drop your file(s) into the area + + + Create a new member + All Members + Member groups have no additional properties for editing. + + + Where do you want to create the new %0% + Create an item under + Select the document type you want to make a content template for + Enter a folder name + Choose a type and a title + Document Types within the Settings section, by editing the Allowed child node types under Permissions.]]> + Document Types within the Settings section.]]> + The selected page in the content tree doesn't allow for any pages to be created below it. + Edit permissions for this document type + Create a new document type + Document Types within the Settings section, by changing the Allow as root option under Permissions.]]> + Media Types Types within the Settings section, by editing the Allowed child node types under Permissions.]]> + The selected media in the tree doesn't allow for any other media to be created below it. + Edit permissions for this media type Document Type without a template + New folder + New data type + New JavaScript file + New empty partial view + New partial view macro + New partial view from snippet + New partial view macro from snippet + New partial view macro (without macro) + New style sheet file + New Rich Text Editor style sheet file + + + Browse your website + - Hide + If Umbraco isn't opening, you might need to allow popups from this site + has opened in a new window + Restart + Visit + Welcome + + + Stay + Discard changes + You have unsaved changes + Are you sure you want to navigate away from this page? - you have unsaved changes + Publishing will make the selected items visible on the site. + Unpublishing will remove the selected items and all their descendants from the site. + Unpublishing will remove this page and all its descendants from the site. + You have unsaved changes. Making changes to the Document Type will discard the changes. + + + Done + Deleted %0% item + Deleted %0% items + Deleted %0% out of %1% item + Deleted %0% out of %1% items + Published %0% item + Published %0% items + Published %0% out of %1% item + Published %0% out of %1% items + Unpublished %0% item + Unpublished %0% items + Unpublished %0% out of %1% item + Unpublished %0% out of %1% items + Moved %0% item + Moved %0% items + Moved %0% out of %1% item + Moved %0% out of %1% items + Copied %0% item + Copied %0% items + Copied %0% out of %1% item + Copied %0% out of %1% items + + + Link title + Link + Anchor / querystring + Name + Close this window + Are you sure you want to delete + Are you sure you want to disable + Are you sure? + Are you sure? + Cut + Edit Dictionary Item + Edit Language + Edit selected media + Insert local link + Insert character + Insert graphic headline + Insert picture + Insert link + Click to add a Macro + Insert table + This will delete the language + Changing the culture for a language may be an expensive operation and will result in the content cache and indexes being rebuilt + Last Edited + Link + Internal link: + When using local links, insert "#" in front of link + Open in new window? + Macro Settings + This macro does not contain any properties you can edit + Paste + Edit permissions for + Set permissions for + Set permissions for %0% for user group %1% + Select the users groups you want to set permissions for + The items in the recycle bin are now being deleted. Please do not close this window while this operation takes place + The recycle bin is now empty + When items are deleted from the recycle bin, they will be gone forever + regexlib.com's webservice is currently experiencing some problems, which we have no control over. We are very sorry for this inconvenience.]]> + Search for a regular expression to add validation to a form field. Example: 'email, 'zip-code' 'url' + Remove Macro + Required Field + Site is reindexed + The website cache has been refreshed. All publish content is now up to date. While all unpublished content is still unpublished + The website cache will be refreshed. All published content will be updated, while unpublished content will stay unpublished. + Number of columns + Number of rows + Click on the image to see full size + Pick item + View Cache Item + Relate to original + Include descendants + The friendliest community + Link to page + Opens the linked document in a new window or tab + Link to media + Select content start node + Select media + Select media type + Select icon + Select item + Select link + Select macro + Select content + Select content type + Select media start node + Select member + Select member group + Select member type + Select node + Select sections + Select users + No icons were found + There are no parameters for this macro + There are no macros available to insert + External login providers + Exception Details + Stacktrace + Inner Exception + Link your + Un-link your + account + Select editor + Select snippet + This will delete the node and all its languages. If you only want to delete one language, you should unpublish the node in that language instead. + + + There are no dictionary items. + + + %0%' below + ]]> + Culture Name + + Dictionary overview + + + Configured Searchers + Shows properties and tools for any configured Searcher (i.e. such as a multi-index searcher) + Field values + Health status + The health status of the index and if it can be read + Indexers + Index info + Lists the properties of the index + Manage Examine's indexes + Allows you to view the details of each index and provides some tools for managing the indexes + Rebuild index + + Depending on how much content there is in your site this could take a while.
+ It is not recommended to rebuild an index during times of high website traffic or when editors are editing content. + ]]> +
+ Searchers + Search the index and view the results + Tools + Tools to manage the index + fields + The index cannot be read and will need to be rebuilt + The process is taking longer than expected, check the umbraco log to see if there have been any errors during this operation + This index cannot be rebuilt because it has no assigned + IIndexPopulator + + + Enter your username + Enter your password + Confirm your password + Name the %0%... + Enter a name... + Enter an email... + Enter a username... + Label... + Enter a description... + Type to search... + Type to filter... + Type to add tags (press enter after each tag)... + Enter your email + Enter a message... + Your username is usually your email + #value or ?key=value + Enter alias... + Generating alias... + Create item + Create + Edit + Name + + + Create custom list view + Remove custom list view + A content type, media type or member type with this alias already exists + + + Renamed + Enter a new folder name here + %0% was renamed to %1% + + + Add prevalue + Database datatype + Property editor GUID + Property editor + Buttons + Enable advanced settings for + Enable context menu + Maximum default size of inserted images + Related stylesheets + Show label + Width and height + All property types & property data + using this data type will be deleted permanently, please confirm you want to delete these as well + Yes, delete + and all property types & property data using this data type + Select the folder to move + to in the tree structure below + was moved underneath + %0% will delete the properties and their data from the following items]]> + I understand this action will delete the properties and data based on this Data Type + + + Your data has been saved, but before you can publish this page there are some errors you need to fix first: + The current membership provider does not support changing password (EnablePasswordRetrieval need to be true) + %0% already exists + There were errors: + There were errors: + The password should be a minimum of %0% characters long and contain at least %1% non-alpha numeric character(s) + %0% must be an integer + The %0% field in the %1% tab is mandatory + %0% is a mandatory field + %0% at %1% is not in a correct format + %0% is not in a correct format + + + Received an error from the server + The specified file type has been disallowed by the administrator + NOTE! Even though CodeMirror is enabled by configuration, it is disabled in Internet Explorer because it's not stable enough. + Please fill both alias and name on the new property type! + There is a problem with read/write access to a specific file or folder + Error loading Partial View script (file: %0%) + Please enter a title + Please choose a type + You're about to make the picture larger than the original size. Are you sure that you want to proceed? + Startnode deleted, please contact your administrator + Please mark content before changing style + No active styles available + Please place cursor at the left of the two cells you wish to merge + You cannot split a cell that hasn't been merged. + This property is invalid + + + Options + About + Action + Actions + Add + Alias + All + Are you sure? + Back + Back to overview + Border + by + Cancel + Cell margin + Choose + Close + Close Window + Comment + Confirm + Constrain + Constrain proportions + Content + Continue + Copy + Create + Database + Date + Default + Delete + Deleted + Deleting... + Design + Dictionary + Dimensions + Down + Download + Edit + Edited + Elements + Email + Error + Field + Find + First + Focal point + General + Groups + Group + Height + Help + Hide + History + Icon + Id + Import + Include subfolders in search + Info + Inner margin + Insert + Install + Invalid + Justify + Label + Language + Last + Layout + Links + Loading + Locked + Login + Log off + Logout + Macro + Mandatory + Message + Move + Name + New + Next + No + of + Off + OK + Open + On + or + Order by + Password + Path + One moment please... + Previous + Properties + Rebuild + Email to receive form data + Recycle Bin + Your recycle bin is empty + Reload + Remaining + Remove + Rename + Renew + Required + Retrieve + Retry + Permissions + Scheduled Publishing + Search + Sorry, we can not find what you are looking for. + No items have been added + Server + Settings + Show + Show page on Send + Size + Sort + Status + Submit + Type + Type to search... + under + Up + Update + Upgrade + Upload + Url + User + Username + Value + View + Welcome... + Width + Yes + Folder + Search results + Reorder + I am done reordering + Preview + Change password + to + List view + Saving... + current + Embed + selected + + + Blue + + + Add group + Add property + Add editor + Add template + Add child node + Add child + Edit data type + Navigate sections + Shortcuts + show shortcuts + Toggle list view + Toggle allow as root + Comment/Uncomment lines + Remove line + Copy Lines Up + Copy Lines Down + Move Lines Up + Move Lines Down + General + Editor + Toggle allow culture variants + + + Background color + Bold + Text color + Font + Text + + + Page + + + The installer cannot connect to the database. + Could not save the web.config file. Please modify the connection string manually. + Your database has been found and is identified as + Database configuration + install button to install the Umbraco %0% database + ]]> + Next to proceed.]]> + Database not found! Please check that the information in the "connection string" of the "web.config" file is correct.

+

To proceed, please edit the "web.config" file (using Visual Studio or your favourite text editor), scroll to the bottom, add the connection string for your database in the key named "UmbracoDbDSN" and save the file.

+

+ Click the retry button when + done.
+ More information on editing web.config here.

]]>
+ + Please contact your ISP if necessary. + If you're installing on a local machine or server you might need information from your system administrator.]]> + + Press the upgrade button to upgrade your database to Umbraco %0%

+

+ Don't worry - no content will be deleted and everything will continue working afterwards! +

+ ]]>
+ Press Next to + proceed. ]]> + next to continue the configuration wizard]]> + The Default users' password needs to be changed!]]> + The Default user has been disabled or has no access to Umbraco!

No further actions needs to be taken. Click Next to proceed.]]> + The Default user's password has been successfully changed since the installation!

No further actions needs to be taken. Click Next to proceed.]]> + The password is changed! + Get a great start, watch our introduction videos + By clicking the next button (or modifying the umbracoConfigurationStatus in web.config), you accept the license for this software as specified in the box below. Notice that this Umbraco distribution consists of two different licenses, the open source MIT license for the framework and the Umbraco freeware license that covers the UI. + Not installed yet. + Affected files and folders + More information on setting up permissions for Umbraco here + You need to grant ASP.NET modify permissions to the following files/folders + Your permission settings are almost perfect!

+ You can run Umbraco without problems, but you will not be able to install packages which are recommended to take full advantage of Umbraco.]]>
+ How to Resolve + Click here to read the text version + video tutorial on setting up folder permissions for Umbraco or read the text version.]]> + Your permission settings might be an issue! +

+ You can run Umbraco without problems, but you will not be able to create folders or install packages which are recommended to take full advantage of Umbraco.]]>
+ Your permission settings are not ready for Umbraco! +

+ In order to run Umbraco, you'll need to update your permission settings.]]>
+ Your permission settings are perfect!

+ You are ready to run Umbraco and install packages!]]>
+ Resolving folder issue + Follow this link for more information on problems with ASP.NET and creating folders + Setting up folder permissions + + I want to start from scratch + learn how) + You can still choose to install Runway later on. Please go to the Developer section and choose Packages. + ]]> + You've just set up a clean Umbraco platform. What do you want to do next? + Runway is installed + + This is our list of recommended modules, check off the ones you would like to install, or view the full list of modules + ]]> + Only recommended for experienced users + I want to start with a simple website + + "Runway" is a simple website providing some basic document types and templates. The installer can set up Runway for you automatically, + but you can easily edit, extend or remove it. It's not necessary and you can perfectly use Umbraco without it. However, + Runway offers an easy foundation based on best practices to get you started faster than ever. + If you choose to install Runway, you can optionally select basic building blocks called Runway Modules to enhance your Runway pages. +

+ + Included with Runway: Home page, Getting Started page, Installing Modules page.
+ Optional Modules: Top Navigation, Sitemap, Contact, Gallery. +
+ ]]>
+ What is Runway + Step 1/5 Accept license + Step 2/5: Database configuration + Step 3/5: Validating File Permissions + Step 4/5: Check Umbraco security + Step 5/5: Umbraco is ready to get you started + Thank you for choosing Umbraco + Browse your new site +You installed Runway, so why not see how your new website looks.]]> + Further help and information +Get help from our award winning community, browse the documentation or watch some free videos on how to build a simple site, how to use packages and a quick guide to the Umbraco terminology]]> + Umbraco %0% is installed and ready for use + /web.config file and update the AppSetting key UmbracoConfigurationStatus in the bottom to the value of '%0%'.]]> + started instantly by clicking the "Launch Umbraco" button below.
If you are new to Umbraco, +you can find plenty of resources on our getting started pages.]]>
+ Launch Umbraco +To manage your website, simply open the Umbraco back office and start adding content, updating the templates and stylesheets or add new functionality]]> + Connection to database failed. + Umbraco Version 3 + Umbraco Version 4 + Watch + Umbraco %0% for a fresh install or upgrading from version 3.0. +

+ Press "next" to start the wizard.]]>
+ + + Culture Code + Culture Name + + + You've been idle and logout will automatically occur in + Renew now to save your work + + + Happy super Sunday + Happy manic Monday + Happy tubular Tuesday + Happy wonderful Wednesday + Happy thunderous Thursday + Happy funky Friday + Happy Caturday + Log in below + Sign in with + Session timed out + © 2001 - %0%
Umbraco.com

]]>
+ Forgotten password? + An email will be sent to the address specified with a link to reset your password + An email with password reset instructions will be sent to the specified address if it matched our records + Show password + Hide password + Return to login form + Please provide a new password + Your Password has been updated + The link you have clicked on is invalid or has expired + Umbraco: Reset Password + + + + + + + + + + + +
+ + + + + +
+ +
+ +
+
+ + + + + + +
+
+
+ + + + +
+ + + + +
+

+ Password reset requested +

+

+ Your username to login to the Umbraco back-office is: %0% +

+

+ + + + + + +
+ + Click this link to reset your password + +
+

+

If you cannot click on the link, copy and paste this URL into your browser window:

+ + + + +
+ + %1% + +
+

+
+
+


+
+
+ + + ]]>
+ + + Dashboard + Sections + Content + + + Choose page above... + %0% has been copied to %1% + Select where the document %0% should be copied to below + %0% has been moved to %1% + Select where the document %0% should be moved to below + has been selected as the root of your new content, click 'ok' below. + No node selected yet, please select a node in the list above before clicking 'ok' + The current node is not allowed under the chosen node because of its type + The current node cannot be moved to one of its subpages + The current node cannot exist at the root + The action isn't allowed since you have insufficient permissions on 1 or more child documents. + Relate copied items to original + + + %0%]]> + Notification settings saved for + + The following languages have been modified %0% + + + + + + + + + + + +
+ + + + + +
+ +
+ +
+
+ + + + + + +
+
+
+ + + + +
+ + + + +
+

+ Hi %0%, +

+

+ This is an automated mail to inform you that the task '%1%' has been performed on the page '%2%' by the user '%3%' +

+ + + + + + +
+ +
+ EDIT
+
+

+

Update summary:

+ %6% +

+

+ Have a nice day!

+ Cheers from the Umbraco robot +

+
+
+


+
+
+ + + ]]>
+ The following languages have been modified:

+ %0% + ]]>
+ [%0%] Notification about %1% performed on %2% + Notifications + + + Actions + Created + Create package + + button and locating the package. Umbraco packages usually have a ".umb" or ".zip" extension. + ]]> + This will delete the package + Drop to upload + Include all child nodes + or click here to choose package file + Upload package + Install a local package by selecting it from your machine. Only install packages from sources you know and trust + Upload another package + Cancel and upload another package + I accept + terms of use + Path to file + Absolute path to file (ie: /bin/umbraco.bin) + Installed + Installed packages + Install local + Finish + This package has no configuration view + No packages have been created yet + You don’t have any packages installed + 'Packages' icon in the top right of your screen]]> + Package Actions + Author URL + Package Content + Package Files + Icon URL + Install package + License + License URL + Package Properties + Search for packages + Results for + We couldn’t find anything for + Please try searching for another package or browse through the categories + Popular + New releases + has + karma points + Information + Owner + Contributors + Created + Current version + .NET version + Downloads + Likes + Compatibility + This package is compatible with the following versions of Umbraco, as reported by community members. Full compatability cannot be guaranteed for versions reported below 100% + External sources + Author + Documentation + Package meta data + Package name + Package doesn't contain any items +
+ You can safely remove this from the system by clicking "uninstall package" below.]]>
+ Package options + Package readme + Package repository + Confirm package uninstall + Package was uninstalled + The package was successfully uninstalled + Uninstall package + + Notice: any documents, media etc depending on the items you remove, will stop working, and could lead to system instability, + so uninstall with caution. If in doubt, contact the package author.]]> + Package version + Upgrading from version + Package already installed + This package cannot be installed, it requires a minimum Umbraco version of + Uninstalling... + Downloading... + Importing... + Installing... + Restarting, please wait... + All done, your browser will now refresh, please wait... + Please click 'Finish' to complete installation and reload the page. + Uploading package... + + + Paste with full formatting (Not recommended) + The text you're trying to paste contains special characters or formatting. This could be caused by copying text from Microsoft Word. Umbraco can remove special characters or formatting automatically, so the pasted content will be more suitable for the web. + Paste as raw text without any formatting at all + Paste, but remove formatting (Recommended) + + + Group based protection + If you want to grant access to all members of specific member groups + You need to create a member group before you can use group based authentication + Error Page + Used when people are logged on, but do not have access + %0%]]> + %0% is now protected]]> + %0%]]> + Login Page + Choose the page that contains the login form + Remove protection... + %0%?]]> + Select the pages that contain login form and error messages + %0%]]> + %0%]]> + Specific members protection + If you wish to grant access to specific members + + + Insufficient user permissions to publish all descendant documents + + + + + + + + Validation failed for required language '%0%'. This language was saved but not published. + Publishing in progress - please wait... + %0% out of %1% pages have been published... + %0% has been published + %0% and subpages have been published + Publish %0% and all its subpages + Publish to publish %0% and thereby making its content publicly available.

+ You can publish this page and all its subpages by checking Include unpublished subpages below. + ]]>
+ + + You have not configured any approved colors + + + You can only select items of type(s): %0% + You have picked a content item currently deleted or in the recycle bin + You have picked content items currently deleted or in the recycle bin + + + Deleted item + You have picked a media item currently deleted or in the recycle bin + You have picked media items currently deleted or in the recycle bin + Trashed + + + enter external link + choose internal page + Caption + Link + Open in new window + enter the display caption + Enter the link + + + Reset crop + Save crop + Add new crop + Done + Undo edits + + + Select a version to compare with the current version + Current version + Red text will not be shown in the selected version. , green means added]]> + Document has been rolled back + This displays the selected version as HTML, if you wish to see the difference between 2 versions at the same time, use the diff view + Rollback to + Select version + View + + + Edit script file + + + Content + Forms + Media + Members + Packages + Settings + Translation + Users + + + The best Umbraco video tutorials + + + Default template + To import a document type, find the ".udt" file on your computer by clicking the "Browse" button and click "Import" (you'll be asked for confirmation on the next screen) + New Tab Title + Node type + Type + Stylesheet + Script + Tab + Tab Title + Tabs + Master Content Type enabled + This Content Type uses + as a Master Content Type. Tabs from Master Content Types are not shown and can only be edited on the Master Content Type itself + No properties defined on this tab. Click on the "add a new property" link at the top to create a new property. + Create matching template + Add icon + + + Sort order + Creation date + Sorting complete. + Drag the different items up or down below to set how they should be arranged. Or click the column headers to sort the entire collection of items + + This node has no child nodes to sort + + + Validation + Validation errors must be fixed before the item can be saved + Failed + Saved + Insufficient user permissions, could not complete the operation + Cancelled + Operation was cancelled by a 3rd party add-in + Property type already exists + Property type created + DataType: %1%]]> + Propertytype deleted + Document Type saved + Tab created + Tab deleted + Tab with id: %0% deleted + Stylesheet not saved + Stylesheet saved + Stylesheet saved without any errors + Datatype saved + Dictionary item saved + Content published + and is visible on the website + %0% documents published and visible on the website + %0% published and visible on the website + %0% documents published for languages %1% and visible on the website + Content saved + Remember to publish to make changes visible + A schedule for publishing has been updated + %0% saved + Sent For Approval + Changes have been sent for approval + %0% changes have been sent for approval + Media saved + Media saved without any errors + Member saved + Member group saved + Stylesheet Property Saved + Stylesheet saved + Template saved + Error saving user (check log) + User Saved + User type saved + User group saved + File not saved + file could not be saved. Please check file permissions + File saved + File saved without any errors + Language saved + Media Type saved + Member Type saved + Member Group saved + Template not saved + Please make sure that you do not have 2 templates with the same alias + Template saved + Template saved without any errors! + Content unpublished + Content variation %0% unpublished + The mandatory language '%0%' was unpublished. All languages for this content item are now unpublished. + Partial view saved + Partial view saved without any errors! + Partial view not saved + An error occurred saving the file. + Permissions saved for + Deleted %0% user groups + %0% was deleted + Enabled %0% users + Disabled %0% users + %0% is now enabled + %0% is now disabled + User groups have been set + Unlocked %0% users + %0% is now unlocked + Member was exported to file + An error occurred while exporting the member + User %0% was deleted + Invite user + Invitation has been re-sent to %0% + Cannot publish the document since the required '%0%' is not published + Validation failed for language '%0%' + Document type was exported to file + An error occurred while exporting the document type + The release date cannot be in the past + Cannot schedule the document for publishing since the required '%0%' is not published + Cannot schedule the document for publishing since the required '%0%' has a publish date later than a non mandatory language + The expire date cannot be in the past + The expire date cannot be before the release date + + + Add style + Edit style + Rich text editor styles + Define the styles that should be available in the rich text editor for this stylesheet + Edit stylesheet + Edit stylesheet property + The name displayed in the editor style selector + Preview + How the text will look like in the rich text editor. + Selector + Uses CSS syntax, e.g. "h1" or ".redHeader" + Styles + The CSS that should be applied in the rich text editor, e.g. "color:red;" + Code + Rich Text Editor + + + Failed to delete template with ID %0% + Edit template + Sections + Insert content area + Insert content area placeholder + Insert + Choose what to insert into your template + Dictionary item + A dictionary item is a placeholder for a translatable piece of text, which makes it easy to create designs for multilingual websites. + Macro + + A Macro is a configurable component which is great for + reusable parts of your design, where you need the option to provide parameters, + such as galleries, forms and lists. + + Value + Displays the value of a named field from the current page, with options to modify the value or fallback to alternative values. + Partial view + + A partial view is a separate template file which can be rendered inside another + template, it's great for reusing markup or for separating complex templates into separate files. + + Master template + No master + Render child template + @RenderBody() placeholder. + ]]> + Define a named section + @section { ... }. This can be rendered in a + specific area of the parent of this template, by using @RenderSection. + ]]> + Render a named section + @RenderSection(name) placeholder. + This renders an area of a child template which is wrapped in a corresponding @section [name]{ ... } definition. + ]]> + Section Name + Section is mandatory + + If mandatory, the child template must contain a @section definition, otherwise an error is shown. + + Query builder + items returned, in + copy to clipboard + I want + all content + content of type "%0%" + from + my website + where + and + is + is not + before + before (including selected date) + after + after (including selected date) + equals + does not equal + contains + does not contain + greater than + greater than or equal to + less than + less than or equal to + Id + Name + Created Date + Last Updated Date + order by + ascending + descending + Template + + + Image + Macro + Choose type of content + Choose a layout + Add a row + Add content + Drop content + Settings applied + This content is not allowed here + This content is allowed here + Click to embed + Click to insert image + Image caption... + Write here... + Grid Layouts + Layouts are the overall work area for the grid editor, usually you only need one or two different layouts + Add Grid Layout + Adjust the layout by setting column widths and adding additional sections + Row configurations + Rows are predefined cells arranged horizontally + Add row configuration + Adjust the row by setting cell widths and adding additional cells + Columns + Total combined number of columns in the grid layout + Settings + Configure what settings editors can change + Styles + Configure what styling editors can change + Allow all editors + Allow all row configurations + Maximum items + Leave blank or set to 0 for unlimited + Set as default + Choose extra + Choose default + are added + + + Compositions + Group + You have not added any groups + Add group + Inherited from + Add property + Required label + Enable list view + Configures the content item to show a sortable and searchable list of its children, the children will not be shown in the tree + Allowed Templates + Choose which templates editors are allowed to use on content of this type + Allow as root + Allow editors to create content of this type in the root of the content tree. + Allowed child node types + Allow content of the specified types to be created underneath content of this type. + Choose child node + Inherit tabs and properties from an existing document type. New tabs will be added to the current document type or merged if a tab with an identical name exists. + This content type is used in a composition, and therefore cannot be composed itself. + There are no content types available to use as a composition. + Removing a composition will delete all the associated property data. Once you save the document type there's no way back. + Create new + Use existing + Editor settings + Configuration + Yes, delete + was moved underneath + was copied underneath + Select the folder to move + Select the folder to copy + to in the tree structure below + All Document types + All Documents + All media items + using this document type will be deleted permanently, please confirm you want to delete these as well. + using this media type will be deleted permanently, please confirm you want to delete these as well. + using this member type will be deleted permanently, please confirm you want to delete these as well + and all documents using this type + and all media items using this type + and all members using this type + Member can edit + Allow this property value to be edited by the member on their profile page + Is sensitive data + Hide this property value from content editors that don't have access to view sensitive information + Show on member profile + Allow this property value to be displayed on the member profile page + tab has no sort order + Where is this composition used? + This composition is currently used in the composition of the following content types: + Allow varying by culture + Allow editors to create content of this type in different languages. + Allow varying by culture + Element type + Is an Element type + An Element type is meant to be used for instance in Nested Content, and not in the tree. + This is not applicable for an Element type + You have made changes to this property. Are you sure you want to discard them? + + + Add language + Mandatory language + Properties on this language have to be filled out before the node can be published. + Default language + An Umbraco site can only have one default language set. + Switching default language may result in default content missing. + Falls back to + No fall back language + To allow multi-lingual content to fall back to another language if not present in the requested language, select it here. + Fall back language + none + + + Add parameter + Edit parameter + Enter macro name + Parameters + Define the parameters that should be available when using this macro. + Select partial view macro file + + + Building models + this can take a bit of time, don't worry + Models generated + Models could not be generated + Models generation has failed, see exception in U log + + + Add fallback field + Fallback field + Add default value + Default value + Fallback field + Default value + Casing + Encoding + Choose field + Convert line breaks + Yes, convert line breaks + Replaces line breaks with 'br' html tag + Custom Fields + Date only + Format and encoding + Format as date + Format the value as a date, or a date with time, according to the active culture + HTML encode + Will replace special characters by their HTML equivalent. + Will be inserted after the field value + Will be inserted before the field value + Lowercase + Modify output + None + Output sample + Insert after field + Insert before field + Recursive + Yes, make it recursive + Separator + Standard Fields + Uppercase + URL encode + Will format special characters in URLs + Will only be used when the field values above are empty + This field will only be used if the primary field is empty + Date and time + + + Translation details + Download XML DTD + Fields + Include subpages + + No translator users found. Please create a translator user before you start sending content to translation + The page '%0%' has been send to translation + Send the page '%0%' to translation + Total words + Translate to + Translation completed. + You can preview the pages, you've just translated, by clicking below. If the original page is found, you will get a comparison of the 2 pages. + Translation failed, the XML file might be corrupt + Translation options + Translator + Upload translation XML + + + Content + Content Templates + Media + Cache Browser + Recycle Bin + Created packages + Data Types + Dictionary + Installed packages + Install skin + Install starter kit + Languages + Install local package + Macros + Media Types + Members + Member Groups + Member Roles + Member Types + Document Types + Relation Types + Packages + Packages + Partial Views + Partial View Macro Files + Install from repository + Install Runway + Runway modules + Scripting Files + Scripts + Stylesheets + Templates + Log Viewer + Users + Settings + Templating + Third Party + + + New update ready + %0% is ready, click here for download + No connection to server + Error checking for update. Please review trace-stack for further information + + + Access + Based on the assigned groups and start nodes, the user has access to the following nodes + Assign access + Administrator + Category field + User created + Change Your Password + Change photo + New password + hasn't been locked out + The password hasn't been changed + Confirm new password + You can change your password for accessing the Umbraco Back Office by filling out the form below and click the 'Change Password' button + Content Channel + Create another user + Create new users to give them access to Umbraco. When a new user is created a password will be generated that you can share with the user. + Description field + Disable User + Document Type + Editor + Excerpt field + Failed login attempts + Go to user profile + Add groups to assign access and permissions + Invite another user + Invite new users to give them access to Umbraco. An invite email will be sent to the user with information on how to log in to Umbraco. Invites last for 72 hours. + Language + Set the language you will see in menus and dialogs + Last lockout date + Last login + Password last changed + Username + Media start node + Limit the media library to a specific start node + Media start nodes + Limit the media library to specific start nodes + Sections + Disable Umbraco Access + has not logged in yet + Old password + Password + Reset password + Your password has been changed! + Please confirm the new password + Enter your new password + Your new password cannot be blank! + Current password + Invalid current password + There was a difference between the new password and the confirmed password. Please try again! + The confirmed password doesn't match the new password! + Replace child node permissions + You are currently modifying permissions for the pages: + Select pages to modify their permissions + Remove photo + Default permissions + Granular permissions + Set permissions for specific nodes + Profile + Search all children + Add sections to give users access + Select user groups + No start node selected + No start nodes selected + Content start node + Limit the content tree to a specific start node + Content start nodes + Limit the content tree to specific start nodes + User last updated + has been created + The new user has successfully been created. To log in to Umbraco use the password below. + User management + Name + User permissions + User group + has been invited + An invitation has been sent to the new user with details about how to log in to Umbraco. + Hello there and welcome to Umbraco! In just 1 minute you’ll be good to go, we just need you to setup a password and add a picture for your avatar. + Welcome to Umbraco! Unfortunately your invite has expired. Please contact your administrator and ask them to resend it. + Uploading a photo of yourself will make it easy for other users to recognize you. Click the circle above to upload your photo. + Writer + Change + Your profile + Your recent history + Session expires in + Invite user + Create user + Send invite + Back to users + Umbraco: Invitation + + + + + + + + + + + +
+ + + + + +
+ +
+ +
+
+ + + + + + +
+
+
+ + + + +
+ + + + +
+

+ Hi %0%, +

+

+ You have been invited by %1% to the Umbraco Back Office. +

+

+ Message from %1%: +
+ %2% +

+ + + + + + +
+ + + + + + +
+ + Click this link to accept the invite + +
+
+

If you cannot click on the link, copy and paste this URL into your browser window:

+ + + + +
+ + %3% + +
+

+
+
+


+
+
+ + ]]>
+ Invite + Resending invitation... + Delete User + Are you sure you wish to delete this user account? + All + Active + Disabled + Locked out + Invited + Inactive + Name (A-Z) + Name (Z-A) + Newest + Oldest + Last login + + + Validation + Validate as an email address + Validate as a number + Validate as a URL + ...or enter a custom validation + Field is mandatory + Enter a regular expression + You need to add at least + You can only have + items + items selected + Invalid date + Not a number + Invalid email + Value cannot be null + Value cannot be empty + Value is invalid, it does not match the correct pattern + Custom validation + %1% more.]]> + %1% too many.]]> + + + + Value is set to the recommended value: '%0%'. + Value was set to '%1%' for XPath '%2%' in configuration file '%3%'. + Expected value '%1%' for '%2%' in configuration file '%3%', but found '%0%'. + Found unexpected value '%0%' for '%2%' in configuration file '%3%'. + + Custom errors are set to '%0%'. + Custom errors are currently set to '%0%'. It is recommended to set this to '%1%' before go live. + Custom errors successfully set to '%0%'. + MacroErrors are set to '%0%'. + MacroErrors are set to '%0%' which will prevent some or all pages in your site from loading completely if there are any errors in macros. Rectifying this will set the value to '%1%'. + MacroErrors are now set to '%0%'. + + Try Skip IIS Custom Errors is set to '%0%' and you're using IIS version '%1%'. + Try Skip IIS Custom Errors is currently '%0%'. It is recommended to set this to '%1%' for your IIS version (%2%). + Try Skip IIS Custom Errors successfully set to '%0%'. + + File does not exist: '%0%'. + '%0%' in config file '%1%'.]]> + There was an error, check log for full error: %0%. + Database - The database schema is correct for this version of Umbraco + %0% problems were detected with your database schema (Check the log for details) + Some errors were detected while validating the database schema against the current version of Umbraco. + Your website's certificate is valid. + Certificate validation error: '%0%' + Your website's SSL certificate has expired. + Your website's SSL certificate is expiring in %0% days. + Error pinging the URL %0% - '%1%' + You are currently %0% viewing the site using the HTTPS scheme. + The appSetting 'Umbraco.Core.UseHttps' is set to 'false' in your web.config file. Once you access this site using the HTTPS scheme, that should be set to 'true'. + The appSetting 'Umbraco.Core.UseHttps' is set to '%0%' in your web.config file, your cookies are %1% marked as secure. + Could not update the 'Umbraco.Core.UseHttps' setting in your web.config file. Error: %0% + + Enable HTTPS + Sets umbracoSSL setting to true in the appSettings of the web.config file. + The appSetting 'Umbraco.Core.UseHttps' is now set to 'true' in your web.config file, your cookies will be marked as secure. + Fix + Cannot fix a check with a value comparison type of 'ShouldNotEqual'. + Cannot fix a check with a value comparison type of 'ShouldEqual' with a provided value. + Value to fix check not provided. + Debug compilation mode is disabled. + Debug compilation mode is currently enabled. It is recommended to disable this setting before go live. + Debug compilation mode successfully disabled. + Trace mode is disabled. + Trace mode is currently enabled. It is recommended to disable this setting before go live. + Trace mode successfully disabled. + All folders have the correct permissions set. + + %0%.]]> + %0%. If they aren't being written to no action need be taken.]]> + All files have the correct permissions set. + + %0%.]]> + %0%. If they aren't being written to no action need be taken.]]> + X-Frame-Options used to control whether a site can be IFRAMEd by another was found.]]> + X-Frame-Options used to control whether a site can be IFRAMEd by another was not found.]]> + Set Header in Config + Adds a value to the httpProtocol/customHeaders section of web.config to prevent the site being IFRAMEd by other websites. + A setting to create a header preventing IFRAMEing of the site by other websites has been added to your web.config file. + Could not update web.config file. Error: %0% + X-Content-Type-Options used to protect against MIME sniffing vulnerabilities was found.]]> + X-Content-Type-Options used to protect against MIME sniffing vulnerabilities was not found.]]> + Adds a value to the httpProtocol/customHeaders section of web.config to protect against MIME sniffing vulnerabilities. + A setting to create a header protecting against MIME sniffing vulnerabilities has been added to your web.config file. + Strict-Transport-Security, also known as the HSTS-header, was found.]]> + Strict-Transport-Security was not found.]]> + Adds the header 'Strict-Transport-Security' with the value 'max-age=10886400' to the httpProtocol/customHeaders section of web.config. Use this fix only if you will have your domains running with https for the next 18 weeks (minimum). + The HSTS header has been added to your web.config file. + X-XSS-Protection was found.]]> + X-XSS-Protection was not found.]]> + Adds the header 'X-XSS-Protection' with the value '1; mode=block' to the httpProtocol/customHeaders section of web.config. + The X-XSS-Protection header has been added to your web.config file. + + %0%.]]> + No headers revealing information about the website technology were found. + In the Web.config file, system.net/mailsettings could not be found. + In the Web.config file system.net/mailsettings section, the host is not configured. + SMTP settings are configured correctly and the service is operating as expected. + The SMTP server configured with host '%0%' and port '%1%' could not be reached. Please check to ensure the SMTP settings in the Web.config file system.net/mailsettings are correct. + %0%.]]> + %0%.]]> +

Results of the scheduled Umbraco Health Checks run on %0% at %1% are as follows:

%2%]]>
+ Umbraco Health Check Status: %0% + + + Disable URL tracker + Enable URL tracker + Culture + Original URL + Redirected To + Redirect Url Management + The following URLs redirect to this content item: + No redirects have been made + When a published page gets renamed or moved a redirect will automatically be made to the new page. + Are you sure you want to remove the redirect from '%0%' to '%1%'? + Redirect URL removed. + Error removing redirect URL. + This will remove the redirect + Are you sure you want to disable the URL tracker? + URL tracker has now been disabled. + Error disabling the URL tracker, more information can be found in your log file. + URL tracker has now been enabled. + Error enabling the URL tracker, more information can be found in your log file. + + + No Dictionary items to choose from + + + %0% characters left.]]> + %1% too many.]]> + + + Trashed content with Id: {0} related to original parent content with Id: {1} + Trashed media with Id: {0} related to original parent media item with Id: {1} + Cannot automatically restore this item + There is no location where this item can be automatically restored. You can move the item manually using the tree below. + was restored under + + + Direction + Parent to child + Bidirectional + Parent + Child + Count + Relations + Created + Comment + Name + No relations for this relation type. + Relation Type + Relations + + + Getting Started + Redirect URL Management + Content + Welcome + Examine Management + Published Status + Models Builder + Health Check + Profiling + Getting Started + Install Umbraco Forms + + + Go back + Active layout: + Jump to + group + passed + warning + failed + suggestion + Check passed + Check failed + Open backoffice search + Open/Close backoffice help + Open/Close your profile options + Open context menu for + Current language + Switch language to + Create new folder + Partial View + Partial View Macro + Member + + + References + This Data Type has no references. + Used in Document Types + No references to Document Types. + Used in Media Types + No references to Media Types. + Used in Member Types + No references to Member Types. + Used by + + + Log Levels + Saved Searches + Total Items + Timestamp + Level + Machine + Message + Exception + Properties + Search With Google + Search this message with Google + Search With Bing + Search this message with Bing + Search Our Umbraco + Search this message on Our Umbraco forums and docs + Search Our Umbraco with Google + Search Our Umbraco forums using Google + Search Umbraco Source + Search within Umbraco source code on Github + Search Umbraco Issues + Search Umbraco Issues on Github + Delete this search + Find Logs with Request ID + Find Logs with Namespace + Find Logs with Machine Name + Open + + + Copy %0% + %0% from %1% + + + Open Property Actions + + + Wait + Refresh status + Memory Cache + + + + Reload + Database Cache + + Rebuilding can be expensive. + Use it when reloading is not enough, and you think that the database cache has not been + properly generated—which would indicate some critical Umbraco issue. + ]]> + + Rebuild + Internals + + not need to use it. + ]]> + + Collect + Published Cache Status + Caches + + + Performance profiling + + + Umbraco currently runs in debug mode. This means you can use the built-in performance profiler to assess the performance when rendering pages. +

+

+ If you want to activate the profiler for a specific page rendering, simply add umbDebug=true to the querystring when requesting the page. +

+

+ If you want the profiler to be activated by default for all page renderings, you can use the toggle below. + It will set a cookie in your browser, which then activates the profiler automatically. + In other words, the profiler will only be active by default in your browser - not everyone else's. +

+ ]]> +
+ Activate the profiler by default + Friendly reminder + + + You should never let a production site run in debug mode. Debug mode is turned off by setting debug="false" on the <compilation /> element in web.config. +

+ ]]> +
+ + + Umbraco currently does not run in debug mode, so you can't use the built-in profiler. This is how it should be for a production site. +

+

+ Debug mode is turned on by setting debug="true" on the <compilation /> element in web.config. +

+ ]]> +
+ + + Hours of Umbraco training videos are only a click away + + Want to master Umbraco? Spend a couple of minutes learning some best practices by watching one of these videos about using Umbraco. And visit umbraco.tv for even more Umbraco videos

+ ]]> +
+ To get you started + + + Start here + This section contains the building blocks for your Umbraco site. Follow the below links to find out more about working with the items in the Settings section + Find out more + + in the Documentation section of Our Umbraco + ]]> + + + Community Forum + ]]> + + + tutorial videos (some are free, some require a subscription) + ]]> + + + productivity boosting tools and commercial support + ]]> + + + training and certification opportunities + ]]> + + +
diff --git a/src/Umbraco.Web.UI/config/grid.editors.config.js b/src/Umbraco.Web.UI/config/grid.editors.config.js index 49b843689b..210d167f9e 100644 --- a/src/Umbraco.Web.UI/config/grid.editors.config.js +++ b/src/Umbraco.Web.UI/config/grid.editors.config.js @@ -7,14 +7,14 @@ }, { "name": "Image", - "nameTemplate": "{{ 'Image: ' + (value.udi | ncNodeName) }}", + "nameTemplate": "{{ value && value.udi ? (value.udi | ncNodeName) : '' }}", "alias": "media", "view": "media", "icon": "icon-picture" }, { "name": "Macro", - "nameTemplate": "{{ 'Macro: ' + value.macroAlias }}", + "nameTemplate": "{{ value && value.macroAlias ? value.macroAlias : '' }}", "alias": "macro", "view": "macro", "icon": "icon-settings-alt" @@ -27,7 +27,7 @@ }, { "name": "Headline", - "nameTemplate": "{{ 'Headline: ' + value }}", + "nameTemplate": "{{ value }}", "alias": "headline", "view": "textstring", "icon": "icon-coin", @@ -38,6 +38,7 @@ }, { "name": "Quote", + "nameTemplate": "{{ value ? value.substring(0,32) + (value.length > 32 ? '...' : '') : '' }}", "alias": "quote", "view": "textstring", "icon": "icon-quote", diff --git a/src/Umbraco.Web.UI/config/splashes/noNodes.aspx b/src/Umbraco.Web.UI/config/splashes/noNodes.aspx index 87218ae30d..b0aa3d7837 100644 --- a/src/Umbraco.Web.UI/config/splashes/noNodes.aspx +++ b/src/Umbraco.Web.UI/config/splashes/noNodes.aspx @@ -1,4 +1,5 @@ <%@ Page Language="C#" AutoEventWireup="True" Inherits="Umbraco.Web.UI.Config.Splashes.NoNodes" CodeBehind="NoNodes.aspx.cs" %> +<%@ Import Namespace="Umbraco.Core" %> <%@ Import Namespace="Umbraco.Core.Composing" %> <%@ Import Namespace="Umbraco.Core.Configuration" %> <%@ Import Namespace="Umbraco.Core.IO" %> @@ -31,7 +32,7 @@

You're seeing this wonderful page because your website doesn't contain any published content yet.

diff --git a/src/Umbraco.Web.UI/web.Template.Debug.config b/src/Umbraco.Web.UI/web.Template.Debug.config index ff42f098f7..ad76664924 100644 --- a/src/Umbraco.Web.UI/web.Template.Debug.config +++ b/src/Umbraco.Web.UI/web.Template.Debug.config @@ -91,6 +91,13 @@ + + + + + + diff --git a/src/Umbraco.Web.UI/web.Template.config b/src/Umbraco.Web.UI/web.Template.config index 6d68ea845a..91faf2c8c7 100644 --- a/src/Umbraco.Web.UI/web.Template.config +++ b/src/Umbraco.Web.UI/web.Template.config @@ -257,6 +257,11 @@ + + + + + diff --git a/src/Umbraco.Web/ContentApps/ContentAppFactoryCollectionBuilder.cs b/src/Umbraco.Web/ContentApps/ContentAppFactoryCollectionBuilder.cs index 170b9169ef..4e86b407b5 100644 --- a/src/Umbraco.Web/ContentApps/ContentAppFactoryCollectionBuilder.cs +++ b/src/Umbraco.Web/ContentApps/ContentAppFactoryCollectionBuilder.cs @@ -2,6 +2,7 @@ using System.Linq; using Umbraco.Core; using Umbraco.Core.Composing; +using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Manifest; using Umbraco.Core.Models.ContentEditing; @@ -28,7 +29,7 @@ namespace Umbraco.Web.ContentApps // its dependencies too, and that can create cycles or other oddities var manifestParser = factory.GetInstance(); - return base.CreateItems(factory).Concat(manifestParser.Manifest.ContentApps.Select(x => new ManifestContentAppFactory(x))); + return base.CreateItems(factory).Concat(manifestParser.Manifest.ContentApps.Select(x => new ManifestContentAppFactory(x, Current.IOHelper))); } } } diff --git a/src/Umbraco.Web/Editors/AuthenticationController.cs b/src/Umbraco.Web/Editors/AuthenticationController.cs index c2c481e8e4..a2d6a594b2 100644 --- a/src/Umbraco.Web/Editors/AuthenticationController.cs +++ b/src/Umbraco.Web/Editors/AuthenticationController.cs @@ -305,13 +305,13 @@ namespace Umbraco.Web.Editors var message = Services.TextService.Localize("resetPasswordEmailCopyFormat", // Ensure the culture of the found user is used for the email! - UserExtensions.GetUserCulture(identityUser.Culture, Services.TextService, GlobalSettings), + UmbracoUserExtensions.GetUserCulture(identityUser.Culture, Services.TextService, GlobalSettings), new[] { identityUser.UserName, callbackUrl }); await UserManager.SendEmailAsync(identityUser.Id, Services.TextService.Localize("login/resetPasswordEmailCopySubject", // Ensure the culture of the found user is used for the email! - UserExtensions.GetUserCulture(identityUser.Culture, Services.TextService, GlobalSettings)), + UmbracoUserExtensions.GetUserCulture(identityUser.Culture, Services.TextService, GlobalSettings)), message); UserManager.RaiseForgotPasswordRequestedEvent(user.Id); diff --git a/src/Umbraco.Web/Editors/BackOfficeAssetsController.cs b/src/Umbraco.Web/Editors/BackOfficeAssetsController.cs index e1302d7e5a..53ba7e08ef 100644 --- a/src/Umbraco.Web/Editors/BackOfficeAssetsController.cs +++ b/src/Umbraco.Web/Editors/BackOfficeAssetsController.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Web.Http; +using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.IO; using Umbraco.Web.Mvc; @@ -11,14 +12,7 @@ namespace Umbraco.Web.Editors [PluginController("UmbracoApi")] public class BackOfficeAssetsController : UmbracoAuthorizedJsonController { - private readonly IIOHelper _ioHelper; - private readonly IFileSystem _jsLibFileSystem; - - public BackOfficeAssetsController(IFileSystem jsLibFileSystem, IIOHelper ioHelper) - { - _ioHelper = ioHelper; - _jsLibFileSystem = new PhysicalFileSystem(SystemDirectories.Umbraco + _ioHelper.DirSepChar + "lib", _ioHelper); - } + private readonly IFileSystem _jsLibFileSystem = new PhysicalFileSystem(Current.Configs.Global().UmbracoPath + Current.IOHelper.DirSepChar + "lib"); [HttpGet] public object GetSupportedLocales() diff --git a/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs b/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs index 45f5d52297..43d0bd3b6b 100644 --- a/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs +++ b/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs @@ -320,8 +320,8 @@ namespace Umbraco.Web.Editors "umbracoSettings", new Dictionary { {"umbracoPath", _globalSettings.Path}, - {"mediaPath", Current.IOHelper.ResolveUrl(SystemDirectories.Media).TrimEnd('/')}, - {"appPluginsPath", Current.IOHelper.ResolveUrl(SystemDirectories.AppPlugins).TrimEnd('/')}, + {"mediaPath", Current.IOHelper.ResolveUrl(Current.Configs.Global().UmbracoMediaPath).TrimEnd('/')}, + {"appPluginsPath", Current.IOHelper.ResolveUrl(Constants.SystemDirectories.AppPlugins).TrimEnd('/')}, { "imageFileTypes", string.Join(",", Current.Configs.Settings().Content.ImageFileTypes) @@ -340,7 +340,7 @@ namespace Umbraco.Web.Editors }, {"keepUserLoggedIn", Current.Configs.Settings().Security.KeepUserLoggedIn}, {"usernameIsEmail", Current.Configs.Settings().Security.UsernameIsEmail}, - {"cssPath", Current.IOHelper.ResolveUrl(SystemDirectories.Css).TrimEnd('/')}, + {"cssPath", Current.IOHelper.ResolveUrl(Current.Configs.Global().UmbracoCssPath).TrimEnd('/')}, {"allowPasswordReset", Current.Configs.Settings().Security.AllowPasswordReset}, {"loginBackgroundImage", Current.Configs.Settings().Content.LoginBackgroundImage}, {"showUserInvite", EmailSender.CanSendRequiredEmail}, diff --git a/src/Umbraco.Web/Editors/Binders/ContentModelBinderHelper.cs b/src/Umbraco.Web/Editors/Binders/ContentModelBinderHelper.cs index 6fc0e123a5..04dcfab665 100644 --- a/src/Umbraco.Web/Editors/Binders/ContentModelBinderHelper.cs +++ b/src/Umbraco.Web/Editors/Binders/ContentModelBinderHelper.cs @@ -3,6 +3,7 @@ using System.Net.Http; using System.Web.Http; using System.Web.Http.Controllers; using Umbraco.Core; +using Umbraco.Core.Composing; using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.Models.Editors; @@ -20,7 +21,7 @@ namespace Umbraco.Web.Editors.Binders public TModelSave BindModelFromMultipartRequest(HttpActionContext actionContext, ModelBindingContext bindingContext) where TModelSave : IHaveUploadedFiles { - var result = actionContext.ReadAsMultipart(SystemDirectories.TempFileUploads); + var result = actionContext.ReadAsMultipart(Constants.SystemDirectories.TempFileUploads); var model = actionContext.GetModelFromMultipartRequest(result, "contentItem"); diff --git a/src/Umbraco.Web/Editors/Binders/MemberBinder.cs b/src/Umbraco.Web/Editors/Binders/MemberBinder.cs index 3ba7d32560..21810272ea 100644 --- a/src/Umbraco.Web/Editors/Binders/MemberBinder.cs +++ b/src/Umbraco.Web/Editors/Binders/MemberBinder.cs @@ -66,7 +66,7 @@ namespace Umbraco.Web.Editors.Binders /// private IMember GetExisting(MemberSave model) { - var scenario = _services.MemberService.GetMembershipScenario(); + var scenario = _services.MemberTypeService.GetMembershipScenario(); var provider = Core.Security.MembershipProviderExtensions.GetMembersMembershipProvider(); switch (scenario) { diff --git a/src/Umbraco.Web/Editors/CodeFileController.cs b/src/Umbraco.Web/Editors/CodeFileController.cs index a4e89c25f2..037e7f1702 100644 --- a/src/Umbraco.Web/Editors/CodeFileController.cs +++ b/src/Umbraco.Web/Editors/CodeFileController.cs @@ -110,19 +110,19 @@ namespace Umbraco.Web.Editors switch (type) { case Core.Constants.Trees.PartialViews: - virtualPath = NormalizeVirtualPath(name, SystemDirectories.PartialViews); + virtualPath = NormalizeVirtualPath(name, Core.Constants.SystemDirectories.PartialViews); Services.FileService.CreatePartialViewFolder(virtualPath); break; case Core.Constants.Trees.PartialViewMacros: - virtualPath = NormalizeVirtualPath(name, SystemDirectories.MacroPartials); + virtualPath = NormalizeVirtualPath(name, Core.Constants.SystemDirectories.MacroPartials); Services.FileService.CreatePartialViewMacroFolder(virtualPath); break; case Core.Constants.Trees.Scripts: - virtualPath = NormalizeVirtualPath(name, SystemDirectories.Scripts); + virtualPath = NormalizeVirtualPath(name, Current.Configs.Global().UmbracoScriptsPath); Services.FileService.CreateScriptFolder(virtualPath); break; case Core.Constants.Trees.Stylesheets: - virtualPath = NormalizeVirtualPath(name, SystemDirectories.Css); + virtualPath = NormalizeVirtualPath(name, Current.Configs.Global().UmbracoCssPath); Services.FileService.CreateStyleSheetFolder(virtualPath); break; @@ -250,23 +250,23 @@ namespace Umbraco.Web.Editors { case Core.Constants.Trees.PartialViews: codeFileDisplay = Mapper.Map(new PartialView(PartialViewType.PartialView, string.Empty)); - codeFileDisplay.VirtualPath = SystemDirectories.PartialViews; + codeFileDisplay.VirtualPath = Core.Constants.SystemDirectories.PartialViews; if (snippetName.IsNullOrWhiteSpace() == false) codeFileDisplay.Content = Services.FileService.GetPartialViewSnippetContent(snippetName); break; case Core.Constants.Trees.PartialViewMacros: codeFileDisplay = Mapper.Map(new PartialView(PartialViewType.PartialViewMacro, string.Empty)); - codeFileDisplay.VirtualPath = SystemDirectories.MacroPartials; + codeFileDisplay.VirtualPath = Core.Constants.SystemDirectories.MacroPartials; if (snippetName.IsNullOrWhiteSpace() == false) codeFileDisplay.Content = Services.FileService.GetPartialViewMacroSnippetContent(snippetName); break; case Core.Constants.Trees.Scripts: codeFileDisplay = Mapper.Map(new Script(string.Empty)); - codeFileDisplay.VirtualPath = SystemDirectories.Scripts; + codeFileDisplay.VirtualPath = Current.Configs.Global().UmbracoScriptsPath; break; case Core.Constants.Trees.Stylesheets: codeFileDisplay = Mapper.Map(new Stylesheet(string.Empty)); - codeFileDisplay.VirtualPath = SystemDirectories.Css; + codeFileDisplay.VirtualPath = Current.Configs.Global().UmbracoCssPath; break; default: throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Unsupported editortype")); @@ -305,7 +305,7 @@ namespace Umbraco.Web.Editors switch (type) { case Core.Constants.Trees.PartialViews: - if (IsDirectory(virtualPath, SystemDirectories.PartialViews)) + if (IsDirectory(virtualPath, Core.Constants.SystemDirectories.PartialViews)) { Services.FileService.DeletePartialViewFolder(virtualPath); return Request.CreateResponse(HttpStatusCode.OK); @@ -317,7 +317,7 @@ namespace Umbraco.Web.Editors return Request.CreateErrorResponse(HttpStatusCode.NotFound, "No Partial View or folder found with the specified path"); case Core.Constants.Trees.PartialViewMacros: - if (IsDirectory(virtualPath, SystemDirectories.MacroPartials)) + if (IsDirectory(virtualPath, Core.Constants.SystemDirectories.MacroPartials)) { Services.FileService.DeletePartialViewMacroFolder(virtualPath); return Request.CreateResponse(HttpStatusCode.OK); @@ -329,7 +329,7 @@ namespace Umbraco.Web.Editors return Request.CreateErrorResponse(HttpStatusCode.NotFound, "No Partial View Macro or folder found with the specified path"); case Core.Constants.Trees.Scripts: - if (IsDirectory(virtualPath, SystemDirectories.Scripts)) + if (IsDirectory(virtualPath, Current.Configs.Global().UmbracoScriptsPath)) { Services.FileService.DeleteScriptFolder(virtualPath); return Request.CreateResponse(HttpStatusCode.OK); @@ -342,7 +342,7 @@ namespace Umbraco.Web.Editors return Request.CreateErrorResponse(HttpStatusCode.NotFound, "No Script or folder found with the specified path"); case Core.Constants.Trees.Stylesheets: - if (IsDirectory(virtualPath, SystemDirectories.Css)) + if (IsDirectory(virtualPath, Current.Configs.Global().UmbracoCssPath)) { Services.FileService.DeleteStyleSheetFolder(virtualPath); return Request.CreateResponse(HttpStatusCode.OK); @@ -561,13 +561,13 @@ namespace Umbraco.Web.Editors private Attempt CreateOrUpdatePartialView(CodeFileDisplay display) { - return CreateOrUpdatePartialView(display, SystemDirectories.PartialViews, + return CreateOrUpdatePartialView(display, Core.Constants.SystemDirectories.PartialViews, Services.FileService.GetPartialView, Services.FileService.SavePartialView, Services.FileService.CreatePartialView); } private Attempt CreateOrUpdatePartialViewMacro(CodeFileDisplay display) { - return CreateOrUpdatePartialView(display, SystemDirectories.MacroPartials, + return CreateOrUpdatePartialView(display, Core.Constants.SystemDirectories.MacroPartials, Services.FileService.GetPartialViewMacro, Services.FileService.SavePartialViewMacro, Services.FileService.CreatePartialViewMacro); } diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs index 5c8e6fc2b5..9c2cc399fa 100644 --- a/src/Umbraco.Web/Editors/ContentController.cs +++ b/src/Umbraco.Web/Editors/ContentController.cs @@ -1837,7 +1837,7 @@ namespace Umbraco.Web.Editors private void MapValuesForPersistence(ContentItemSave contentSave) { // inline method to determine if a property type varies - bool Varies(Property property) => property.PropertyType.VariesByCulture(); + bool Varies(IProperty property) => property.PropertyType.VariesByCulture(); var variantIndex = 0; @@ -2310,7 +2310,7 @@ namespace Umbraco.Web.Editors .Select(rule => rule.RuleValue).ToArray(); MemberDisplay[] members; - switch (Services.MemberService.GetMembershipScenario()) + switch (Services.MemberTypeService.GetMembershipScenario()) { case MembershipScenario.NativeUmbraco: members = usernames diff --git a/src/Umbraco.Web/Editors/ContentControllerBase.cs b/src/Umbraco.Web/Editors/ContentControllerBase.cs index 300c777b3a..83167eb9ae 100644 --- a/src/Umbraco.Web/Editors/ContentControllerBase.cs +++ b/src/Umbraco.Web/Editors/ContentControllerBase.cs @@ -50,8 +50,8 @@ namespace Umbraco.Web.Editors internal void MapPropertyValuesForPersistence( TSaved contentItem, ContentPropertyCollectionDto dto, - Func getPropertyValue, - Action savePropertyValue, + Func getPropertyValue, + Action savePropertyValue, string culture) where TPersisted : IContentBase where TSaved : IContentSave diff --git a/src/Umbraco.Web/Editors/ContentTypeController.cs b/src/Umbraco.Web/Editors/ContentTypeController.cs index e01fe251cb..dc95e1e74e 100644 --- a/src/Umbraco.Web/Editors/ContentTypeController.cs +++ b/src/Umbraco.Web/Editors/ContentTypeController.cs @@ -515,7 +515,7 @@ namespace Umbraco.Web.Editors [HttpPost] public HttpResponseMessage Import(string file) { - var filePath = Path.Combine(Current.IOHelper.MapPath(SystemDirectories.Data), file); + var filePath = Path.Combine(Current.IOHelper.MapPath(Core.Constants.SystemDirectories.Data), file); if (string.IsNullOrEmpty(file) || !System.IO.File.Exists(filePath)) { return Request.CreateResponse(HttpStatusCode.NotFound); @@ -553,7 +553,7 @@ namespace Umbraco.Web.Editors throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); } - var root = Current.IOHelper.MapPath(SystemDirectories.TempData.EnsureEndsWith('/') + "FileUploads"); + var root = Current.IOHelper.MapPath(Constants.SystemDirectories.TempData.EnsureEndsWith('/') + "FileUploads"); //ensure it exists Directory.CreateDirectory(root); var provider = new MultipartFormDataStreamProvider(root); diff --git a/src/Umbraco.Web/Editors/Filters/ContentModelValidator.cs b/src/Umbraco.Web/Editors/Filters/ContentModelValidator.cs index 4acf0c948e..14531227e1 100644 --- a/src/Umbraco.Web/Editors/Filters/ContentModelValidator.cs +++ b/src/Umbraco.Web/Editors/Filters/ContentModelValidator.cs @@ -46,7 +46,7 @@ namespace Umbraco.Web.Editors.Filters protected ContentModelValidator(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor) : base(logger, umbracoContextAccessor) { } - + /// /// Ensure the content exists /// @@ -85,7 +85,7 @@ namespace Umbraco.Web.Editors.Filters /// /// /// - protected bool ValidateProperties(List postedProperties, List persistedProperties, HttpActionContext actionContext) + protected bool ValidateProperties(List postedProperties, List persistedProperties, HttpActionContext actionContext) { foreach (var p in postedProperties) { @@ -142,7 +142,7 @@ namespace Umbraco.Web.Editors.Filters var postedValue = postedProp.Value; ValidatePropertyValue(model, modelWithProperties, editor, p, postedValue, modelState); - + } return modelState.IsValid; diff --git a/src/Umbraco.Web/Editors/MacrosController.cs b/src/Umbraco.Web/Editors/MacrosController.cs index 0df685dea7..06c33d503a 100644 --- a/src/Umbraco.Web/Editors/MacrosController.cs +++ b/src/Umbraco.Web/Editors/MacrosController.cs @@ -311,12 +311,12 @@ namespace Umbraco.Web.Editors /// private IEnumerable FindPartialViewFilesInViewsFolder() { - var partialsDir = Current.IOHelper.MapPath(SystemDirectories.MacroPartials); + var partialsDir = Current.IOHelper.MapPath(Constants.SystemDirectories.MacroPartials); return this.FindPartialViewFilesInFolder( partialsDir, partialsDir, - SystemDirectories.MacroPartials); + Constants.SystemDirectories.MacroPartials); } /// @@ -329,7 +329,7 @@ namespace Umbraco.Web.Editors { var files = new List(); - var appPluginsFolder = new DirectoryInfo(Current.IOHelper.MapPath(SystemDirectories.AppPlugins)); + var appPluginsFolder = new DirectoryInfo(Current.IOHelper.MapPath(Constants.SystemDirectories.AppPlugins)); if (!appPluginsFolder.Exists) { @@ -344,7 +344,7 @@ namespace Umbraco.Web.Editors var macroPartials = viewsFolder.First().GetDirectories("MacroPartials"); if (macroPartials.Any()) { - files.AddRange(this.FindPartialViewFilesInFolder(macroPartials.First().FullName, macroPartials.First().FullName, SystemDirectories.AppPlugins + "/" + directory.Name + "/Views/MacroPartials")); + files.AddRange(this.FindPartialViewFilesInFolder(macroPartials.First().FullName, macroPartials.First().FullName, Constants.SystemDirectories.AppPlugins + "/" + directory.Name + "/Views/MacroPartials")); } } } diff --git a/src/Umbraco.Web/Editors/MediaController.cs b/src/Umbraco.Web/Editors/MediaController.cs index 315abaa8ce..ba5d64cde7 100644 --- a/src/Umbraco.Web/Editors/MediaController.cs +++ b/src/Umbraco.Web/Editors/MediaController.cs @@ -620,7 +620,7 @@ namespace Umbraco.Web.Editors throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); } - var root = Current.IOHelper.MapPath(SystemDirectories.TempFileUploads); + var root = Current.IOHelper.MapPath(Constants.SystemDirectories.TempFileUploads); //ensure it exists Directory.CreateDirectory(root); var provider = new MultipartFormDataStreamProvider(root); diff --git a/src/Umbraco.Web/Editors/MemberController.cs b/src/Umbraco.Web/Editors/MemberController.cs index 13f0ed86c4..7fd293d9b5 100644 --- a/src/Umbraco.Web/Editors/MemberController.cs +++ b/src/Umbraco.Web/Editors/MemberController.cs @@ -57,7 +57,7 @@ namespace Umbraco.Web.Editors /// protected MembershipScenario MembershipScenario { - get { return Services.MemberService.GetMembershipScenario(); } + get { return Services.MemberTypeService.GetMembershipScenario(); } } public PagedResult GetPagedResults( diff --git a/src/Umbraco.Web/Editors/PackageInstallController.cs b/src/Umbraco.Web/Editors/PackageInstallController.cs index 51007b1970..7dc4008d91 100644 --- a/src/Umbraco.Web/Editors/PackageInstallController.cs +++ b/src/Umbraco.Web/Editors/PackageInstallController.cs @@ -90,7 +90,7 @@ namespace Umbraco.Web.Editors private void PopulateFromPackageData(LocalPackageInstallModel model) { - var zipFile = new FileInfo(Path.Combine(Current.IOHelper.MapPath(SystemDirectories.Packages), model.ZipFileName)); + var zipFile = new FileInfo(Path.Combine(Current.IOHelper.MapPath(Core.Constants.SystemDirectories.Packages), model.ZipFileName)); var ins = Services.PackagingService.GetCompiledPackageInfo(zipFile); @@ -132,7 +132,7 @@ namespace Umbraco.Web.Editors if (Request.Content.IsMimeMultipartContent() == false) throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); - var root = Current.IOHelper.MapPath(SystemDirectories.TempFileUploads); + var root = Current.IOHelper.MapPath(Core.Constants.SystemDirectories.TempFileUploads); //ensure it exists Directory.CreateDirectory(root); var provider = new MultipartFormDataStreamProvider(root); @@ -159,7 +159,7 @@ namespace Umbraco.Web.Editors { //we always save package files to /App_Data/packages/package-guid.umb for processing as a standard so lets copy. - var packagesFolder = Current.IOHelper.MapPath(SystemDirectories.Packages); + var packagesFolder = Current.IOHelper.MapPath(Core.Constants.SystemDirectories.Packages); Directory.CreateDirectory(packagesFolder); var packageFile = Path.Combine(packagesFolder, model.PackageGuid + ".umb"); File.Copy(file.LocalFileName, packageFile); @@ -211,7 +211,7 @@ namespace Umbraco.Web.Editors { //Default path string fileName = packageGuid + ".umb"; - if (File.Exists(Path.Combine(Current.IOHelper.MapPath(SystemDirectories.Packages), fileName)) == false) + if (File.Exists(Path.Combine(Current.IOHelper.MapPath(Core.Constants.SystemDirectories.Packages), fileName)) == false) { var packageFile = await Services.PackagingService.FetchPackageFileAsync( Guid.Parse(packageGuid), @@ -251,7 +251,7 @@ namespace Umbraco.Web.Editors [HttpPost] public PackageInstallModel Import(PackageInstallModel model) { - var zipFile = new FileInfo(Path.Combine(Current.IOHelper.MapPath(SystemDirectories.Packages), model.ZipFileName)); + var zipFile = new FileInfo(Path.Combine(Current.IOHelper.MapPath(Core.Constants.SystemDirectories.Packages), model.ZipFileName)); var packageInfo = Services.PackagingService.GetCompiledPackageInfo(zipFile); diff --git a/src/Umbraco.Web/Editors/TinyMceController.cs b/src/Umbraco.Web/Editors/TinyMceController.cs index 3d03977883..9f9cc23e08 100644 --- a/src/Umbraco.Web/Editors/TinyMceController.cs +++ b/src/Umbraco.Web/Editors/TinyMceController.cs @@ -45,10 +45,10 @@ namespace Umbraco.Web.Editors } // Create an unique folder path to help with concurrent users to avoid filename clash - var imageTempPath = Current.IOHelper.MapPath(SystemDirectories.TempImageUploads + "/" + Guid.NewGuid().ToString()); + var imageTempPath = Current.IOHelper.MapPath(Constants.SystemDirectories.TempImageUploads + "/" + Guid.NewGuid().ToString()); // Temp folderpath (Files come in as bodypart & will need to move/saved into imgTempPath - var folderPath = Current.IOHelper.MapPath(SystemDirectories.TempFileUploads); + var folderPath = Current.IOHelper.MapPath(Constants.SystemDirectories.TempFileUploads); // Ensure image temp path exists if(Directory.Exists(imageTempPath) == false) diff --git a/src/Umbraco.Web/Editors/TourController.cs b/src/Umbraco.Web/Editors/TourController.cs index e3d42b6753..c7c60c502d 100644 --- a/src/Umbraco.Web/Editors/TourController.cs +++ b/src/Umbraco.Web/Editors/TourController.cs @@ -41,7 +41,7 @@ namespace Umbraco.Web.Editors var nonPluginFilters = _filters.Where(x => x.PluginName == null).ToList(); //add core tour files - var coreToursPath = Path.Combine(Current.IOHelper.MapPath(SystemDirectories.Config), "BackOfficeTours"); + var coreToursPath = Path.Combine(Current.IOHelper.MapPath(Core.Constants.SystemDirectories.Config), "BackOfficeTours"); if (Directory.Exists(coreToursPath)) { foreach (var tourFile in Directory.EnumerateFiles(coreToursPath, "*.json")) @@ -51,7 +51,7 @@ namespace Umbraco.Web.Editors } //collect all tour files in packages - var appPlugins = Current.IOHelper.MapPath(SystemDirectories.AppPlugins); + var appPlugins = Current.IOHelper.MapPath(Core.Constants.SystemDirectories.AppPlugins); if (Directory.Exists(appPlugins)) { foreach (var plugin in Directory.EnumerateDirectories(appPlugins)) diff --git a/src/Umbraco.Web/Editors/UsersController.cs b/src/Umbraco.Web/Editors/UsersController.cs index 3024583fba..e30054df78 100644 --- a/src/Umbraco.Web/Editors/UsersController.cs +++ b/src/Umbraco.Web/Editors/UsersController.cs @@ -75,7 +75,7 @@ namespace Umbraco.Web.Editors throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); } - var root = Current.IOHelper.MapPath(SystemDirectories.TempFileUploads); + var root = Current.IOHelper.MapPath(Constants.SystemDirectories.TempFileUploads); //ensure it exists Directory.CreateDirectory(root); var provider = new MultipartFormDataStreamProvider(root); @@ -466,10 +466,10 @@ namespace Umbraco.Web.Editors var emailSubject = Services.TextService.Localize("user/inviteEmailCopySubject", //Ensure the culture of the found user is used for the email! - UserExtensions.GetUserCulture(to.Language, Services.TextService, GlobalSettings)); + UmbracoUserExtensions.GetUserCulture(to.Language, Services.TextService, GlobalSettings)); var emailBody = Services.TextService.Localize("user/inviteEmailCopyFormat", //Ensure the culture of the found user is used for the email! - UserExtensions.GetUserCulture(to.Language, Services.TextService, GlobalSettings), + UmbracoUserExtensions.GetUserCulture(to.Language, Services.TextService, GlobalSettings), new[] { userDisplay.Name, from, message, inviteUri.ToString(), fromEmail }); await UserManager.EmailService.SendAsync( diff --git a/src/Umbraco.Web/HealthCheck/Checks/Permissions/FolderAndFilePermissionsCheck.cs b/src/Umbraco.Web/HealthCheck/Checks/Permissions/FolderAndFilePermissionsCheck.cs index 577d22fe67..b9604b48f3 100644 --- a/src/Umbraco.Web/HealthCheck/Checks/Permissions/FolderAndFilePermissionsCheck.cs +++ b/src/Umbraco.Web/HealthCheck/Checks/Permissions/FolderAndFilePermissionsCheck.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.IO; using Umbraco.Core.Services; @@ -60,24 +61,24 @@ namespace Umbraco.Web.HealthCheck.Checks.Permissions // in ALL circumstances or just some var pathsToCheck = new Dictionary { - { SystemDirectories.Data, PermissionCheckRequirement.Required }, - { SystemDirectories.Packages, PermissionCheckRequirement.Required}, - { SystemDirectories.Preview, PermissionCheckRequirement.Required }, - { SystemDirectories.AppPlugins, PermissionCheckRequirement.Required }, - { SystemDirectories.Config, PermissionCheckRequirement.Optional }, - { SystemDirectories.Css, PermissionCheckRequirement.Optional }, - { SystemDirectories.Media, PermissionCheckRequirement.Optional }, - { SystemDirectories.Scripts, PermissionCheckRequirement.Optional }, - { SystemDirectories.Umbraco, PermissionCheckRequirement.Optional }, - { SystemDirectories.MvcViews, PermissionCheckRequirement.Optional } + { Constants.SystemDirectories.Data, PermissionCheckRequirement.Required }, + { Constants.SystemDirectories.Packages, PermissionCheckRequirement.Required}, + { Constants.SystemDirectories.Preview, PermissionCheckRequirement.Required }, + { Constants.SystemDirectories.AppPlugins, PermissionCheckRequirement.Required }, + { Constants.SystemDirectories.Config, PermissionCheckRequirement.Optional }, + { Current.Configs.Global().UmbracoCssPath, PermissionCheckRequirement.Optional }, + { Current.Configs.Global().UmbracoMediaPath, PermissionCheckRequirement.Optional }, + { Current.Configs.Global().UmbracoScriptsPath, PermissionCheckRequirement.Optional }, + { Current.Configs.Global().UmbracoPath, PermissionCheckRequirement.Optional }, + { Constants.SystemDirectories.MvcViews, PermissionCheckRequirement.Optional } }; //These are special paths to check that will restart an app domain if a file is written to them, //so these need to be tested differently var pathsToCheckWithRestarts = new Dictionary { - { SystemDirectories.AppCode, PermissionCheckRequirement.Optional }, - { SystemDirectories.Bin, PermissionCheckRequirement.Optional } + { Constants.SystemDirectories.AppCode, PermissionCheckRequirement.Optional }, + { Constants.SystemDirectories.Bin, PermissionCheckRequirement.Optional } }; // Run checks for required and optional paths for modify permission diff --git a/src/Umbraco.Web/HtmlHelperRenderExtensions.cs b/src/Umbraco.Web/HtmlHelperRenderExtensions.cs index a68ba96327..ee906ab0db 100644 --- a/src/Umbraco.Web/HtmlHelperRenderExtensions.cs +++ b/src/Umbraco.Web/HtmlHelperRenderExtensions.cs @@ -67,7 +67,7 @@ namespace Umbraco.Web { var htmlBadge = String.Format(Current.Configs.Settings().Content.PreviewBadge, - Current.IOHelper.ResolveUrl(SystemDirectories.Umbraco), + Current.IOHelper.ResolveUrl(Current.Configs.Global().UmbracoPath), Current.UmbracoContext.HttpContext.Server.UrlEncode(Current.UmbracoContext.HttpContext.Request.Path)); return new MvcHtmlString(htmlBadge); } diff --git a/src/Umbraco.Web/Install/Controllers/InstallController.cs b/src/Umbraco.Web/Install/Controllers/InstallController.cs index dc71125f15..4b99c2ccba 100644 --- a/src/Umbraco.Web/Install/Controllers/InstallController.cs +++ b/src/Umbraco.Web/Install/Controllers/InstallController.cs @@ -41,7 +41,7 @@ namespace Umbraco.Web.Install.Controllers public ActionResult Index() { if (_runtime.Level == RuntimeLevel.Run) - return Redirect(SystemDirectories.Umbraco.EnsureEndsWith('/')); + return Redirect(Current.Configs.Global().UmbracoPath.EnsureEndsWith('/')); if (_runtime.Level == RuntimeLevel.Upgrade) { @@ -58,7 +58,7 @@ namespace Umbraco.Web.Install.Controllers { case ValidateRequestAttempt.FailedNoPrivileges: case ValidateRequestAttempt.FailedNoContextId: - return Redirect(SystemDirectories.Umbraco + "/AuthorizeUpgrade?redir=" + Server.UrlEncode(Request.RawUrl)); + return Redirect(Current.Configs.Global().UmbracoPath + "/AuthorizeUpgrade?redir=" + Server.UrlEncode(Request.RawUrl)); } } @@ -66,7 +66,7 @@ namespace Umbraco.Web.Install.Controllers ViewData.SetInstallApiBaseUrl(Url.GetUmbracoApiService("GetSetup", "InstallApi", "UmbracoInstall").TrimEnd("GetSetup")); // get the base umbraco folder - ViewData.SetUmbracoBaseFolder(Current.IOHelper.ResolveUrl(SystemDirectories.Umbraco)); + ViewData.SetUmbracoBaseFolder(Current.IOHelper.ResolveUrl(Current.Configs.Global().UmbracoPath)); _installHelper.InstallStatus(false, ""); diff --git a/src/Umbraco.Web/Install/FilePermissionHelper.cs b/src/Umbraco.Web/Install/FilePermissionHelper.cs index 2d48fe8974..53b0f953b9 100644 --- a/src/Umbraco.Web/Install/FilePermissionHelper.cs +++ b/src/Umbraco.Web/Install/FilePermissionHelper.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.IO; using System.Security.AccessControl; +using Umbraco.Core; using Umbraco.Core.IO; using Umbraco.Web.Composing; @@ -11,8 +12,8 @@ namespace Umbraco.Web.Install internal class FilePermissionHelper { // ensure that these directories exist and Umbraco can write to them - private static readonly string[] PermissionDirs = { SystemDirectories.Css, SystemDirectories.Config, SystemDirectories.Data, SystemDirectories.Media, SystemDirectories.Preview }; - private static readonly string[] PackagesPermissionsDirs = { SystemDirectories.Bin, SystemDirectories.Umbraco, SystemDirectories.Packages }; + private static readonly string[] PermissionDirs = { Current.Configs.Global().UmbracoCssPath, Constants.SystemDirectories.Config, Constants.SystemDirectories.Data, Current.Configs.Global().UmbracoMediaPath, Constants.SystemDirectories.Preview }; + private static readonly string[] PackagesPermissionsDirs = { Constants.SystemDirectories.Bin, Current.Configs.Global().UmbracoPath, Constants.SystemDirectories.Packages }; // ensure Umbraco can write to these files (the directories must exist) private static readonly string[] PermissionFiles = { }; @@ -35,7 +36,7 @@ namespace Umbraco.Web.Install if (TestPublishedSnapshotService(out errors) == false) report["Published snapshot environment check failed"] = errors.ToList(); - if (EnsureCanCreateSubDirectory(SystemDirectories.Media, out errors) == false) + if (EnsureCanCreateSubDirectory(Current.Configs.Global().UmbracoMediaPath, out errors) == false) report["Media folder creation failed"] = errors.ToList(); } diff --git a/src/Umbraco.Web/Install/InstallAuthorizeAttribute.cs b/src/Umbraco.Web/Install/InstallAuthorizeAttribute.cs index ce45ef652b..da2f2bab57 100644 --- a/src/Umbraco.Web/Install/InstallAuthorizeAttribute.cs +++ b/src/Umbraco.Web/Install/InstallAuthorizeAttribute.cs @@ -66,7 +66,7 @@ namespace Umbraco.Web.Install /// protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { - filterContext.Result = new RedirectResult(SystemDirectories.Umbraco.EnsureEndsWith('/')); + filterContext.Result = new RedirectResult(Current.Configs.Global().UmbracoPath.EnsureEndsWith('/')); } } } diff --git a/src/Umbraco.Web/Install/InstallStatusTracker.cs b/src/Umbraco.Web/Install/InstallStatusTracker.cs index 3c968ca696..6a9482ad6d 100644 --- a/src/Umbraco.Web/Install/InstallStatusTracker.cs +++ b/src/Umbraco.Web/Install/InstallStatusTracker.cs @@ -25,10 +25,10 @@ namespace Umbraco.Web.Install private static string GetFile(Guid installId) { - var file = Current.IOHelper.MapPath(SystemDirectories.TempData.EnsureEndsWith('/') + "Install/" - + "install_" - + installId.ToString("N") - + ".txt"); + var file = Current.IOHelper.MapPath(Constants.SystemDirectories.TempData.EnsureEndsWith('/') + "Install/" + + "install_" + + installId.ToString("N") + + ".txt"); return file; } @@ -40,7 +40,7 @@ namespace Umbraco.Web.Install public static void ClearFiles() { - var dir = Current.IOHelper.MapPath(SystemDirectories.TempData.EnsureEndsWith('/') + "Install/"); + var dir = Current.IOHelper.MapPath(Constants.SystemDirectories.TempData.EnsureEndsWith('/') + "Install/"); if (Directory.Exists(dir)) { var files = Directory.GetFiles(dir); diff --git a/src/Umbraco.Web/Install/InstallSteps/ConfigureMachineKey.cs b/src/Umbraco.Web/Install/InstallSteps/ConfigureMachineKey.cs index a084805a2c..7ea8f088fe 100644 --- a/src/Umbraco.Web/Install/InstallSteps/ConfigureMachineKey.cs +++ b/src/Umbraco.Web/Install/InstallSteps/ConfigureMachineKey.cs @@ -37,7 +37,7 @@ namespace Umbraco.Web.Install.InstallSteps if (model.HasValue && model.Value == false) return Task.FromResult(null); //install the machine key - var fileName = Current.IOHelper.MapPath($"{SystemDirectories.Root}/web.config"); + var fileName = Current.IOHelper.MapPath($"{Current.IOHelper.Root}/web.config"); var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace); // we only want to get the element that is under the root, (there may be more under tags we don't want them) diff --git a/src/Umbraco.Web/Install/InstallSteps/StarterKitCleanupStep.cs b/src/Umbraco.Web/Install/InstallSteps/StarterKitCleanupStep.cs index 352a2cace9..f56db4c91c 100644 --- a/src/Umbraco.Web/Install/InstallSteps/StarterKitCleanupStep.cs +++ b/src/Umbraco.Web/Install/InstallSteps/StarterKitCleanupStep.cs @@ -27,7 +27,7 @@ namespace Umbraco.Web.Install.InstallSteps private void CleanupInstallation(int packageId, string packageFile) { - var zipFile = new FileInfo(Path.Combine(Current.IOHelper.MapPath(SystemDirectories.Packages), HttpUtility.UrlDecode(packageFile))); + var zipFile = new FileInfo(Path.Combine(Current.IOHelper.MapPath(Core.Constants.SystemDirectories.Packages), HttpUtility.UrlDecode(packageFile))); if (zipFile.Exists) zipFile.Delete(); diff --git a/src/Umbraco.Web/JavaScript/ClientDependencyConfiguration.cs b/src/Umbraco.Web/JavaScript/ClientDependencyConfiguration.cs index c64318a68d..6a2e0b16cb 100644 --- a/src/Umbraco.Web/JavaScript/ClientDependencyConfiguration.cs +++ b/src/Umbraco.Web/JavaScript/ClientDependencyConfiguration.cs @@ -27,7 +27,7 @@ namespace Umbraco.Web.JavaScript { if (logger == null) throw new ArgumentNullException("logger"); _logger = logger; - _fileName = Current.IOHelper.MapPath(string.Format("{0}/ClientDependency.config", SystemDirectories.Config)); + _fileName = Current.IOHelper.MapPath(string.Format("{0}/ClientDependency.config", Core.Constants.SystemDirectories.Config)); } /// diff --git a/src/Umbraco.Web/JavaScript/JsInitialization.cs b/src/Umbraco.Web/JavaScript/JsInitialization.cs index 24c09dfd03..c2fe6b7631 100644 --- a/src/Umbraco.Web/JavaScript/JsInitialization.cs +++ b/src/Umbraco.Web/JavaScript/JsInitialization.cs @@ -6,6 +6,7 @@ using System.Web; using ClientDependency.Core; using Newtonsoft.Json; using Newtonsoft.Json.Linq; +using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.IO; using Umbraco.Core.Manifest; @@ -58,7 +59,7 @@ namespace Umbraco.Web.JavaScript } jarray.Append("]"); - return WriteScript(jarray.ToString(), Current.IOHelper.ResolveUrl(SystemDirectories.Umbraco), angularModule); + return WriteScript(jarray.ToString(), Current.IOHelper.ResolveUrl(Current.Configs.Global().UmbracoPath), angularModule); } /// diff --git a/src/Umbraco.Web/JavaScript/UmbracoClientDependencyLoader.cs b/src/Umbraco.Web/JavaScript/UmbracoClientDependencyLoader.cs index 82ae027c8d..135d1acc80 100644 --- a/src/Umbraco.Web/JavaScript/UmbracoClientDependencyLoader.cs +++ b/src/Umbraco.Web/JavaScript/UmbracoClientDependencyLoader.cs @@ -1,6 +1,7 @@ using System.Web.UI; using ClientDependency.Core.Controls; using ClientDependency.Core.FileRegistration.Providers; +using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.IO; @@ -18,7 +19,7 @@ namespace Umbraco.Web.JavaScript public UmbracoClientDependencyLoader() : base() { - this.AddPath("UmbracoRoot", Current.IOHelper.ResolveUrl(SystemDirectories.Umbraco)); + this.AddPath("UmbracoRoot", Current.IOHelper.ResolveUrl(Current.Configs.Global().UmbracoPath)); this.ProviderName = LoaderControlProvider.DefaultName; } diff --git a/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs b/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs index 41f0e2fb65..cab20926ff 100644 --- a/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs +++ b/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs @@ -147,7 +147,7 @@ namespace Umbraco.Web.Macros _content = content; } - public PagePublishedProperty(IPublishedPropertyType propertyType, IPublishedContent content, Umbraco.Core.Models.Property property) + public PagePublishedProperty(IPublishedPropertyType propertyType, IPublishedContent content, IProperty property) : base(propertyType, PropertyCacheLevel.Unknown) // cache level is ignored { _sourceValue = property.GetValue(); diff --git a/src/Umbraco.Web/Models/Mapping/ContentMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/ContentMapDefinition.cs index dc0df4ca96..d3b4353f2f 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentMapDefinition.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentMapDefinition.cs @@ -64,7 +64,7 @@ namespace Umbraco.Web.Models.Mapping // Umbraco.Code.MapAll private static void Map(IContent source, ContentPropertyCollectionDto target, MapperContext context) { - target.Properties = context.MapEnumerable(source.Properties); + target.Properties = context.MapEnumerable(source.Properties); } // Umbraco.Code.MapAll -AllowPreview -Errors -PersistedContent @@ -99,7 +99,7 @@ namespace Umbraco.Web.Models.Mapping target.Variants = _contentVariantMapper.Map(source, context); target.ContentDto = new ContentPropertyCollectionDto(); - target.ContentDto.Properties = context.MapEnumerable(source.Properties); + target.ContentDto.Properties = context.MapEnumerable(source.Properties); } // Umbraco.Code.MapAll -Segment -Language @@ -129,7 +129,7 @@ namespace Umbraco.Web.Models.Mapping target.Owner = _commonMapper.GetOwner(source, context); target.ParentId = source.ParentId; target.Path = source.Path; - target.Properties = context.MapEnumerable(source.Properties); + target.Properties = context.MapEnumerable(source.Properties); target.SortOrder = source.SortOrder; target.State = _basicStateMapper.Map(source, context); target.Trashed = source.Trashed; diff --git a/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicMapper.cs b/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicMapper.cs index 36c1b360b2..cddcfc6d1c 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicMapper.cs @@ -33,7 +33,7 @@ namespace Umbraco.Web.Models.Mapping /// Assigns the PropertyEditor, Id, Alias and Value to the property /// /// - public virtual void Map(Property property, TDestination dest, MapperContext context) + public virtual void Map(IProperty property, TDestination dest, MapperContext context) { var editor = _propertyEditors[property.PropertyType.PropertyEditorAlias]; if (editor == null) @@ -71,7 +71,7 @@ namespace Umbraco.Web.Models.Mapping dest.Culture = culture; // if no 'IncludeProperties' were specified or this property is set to be included - we will map the value and return. - dest.Value = editor.GetValueEditor().ToEditor(property, DataTypeService, culture); + dest.Value = editor.GetValueEditor().ToEditor(property, culture); } } } diff --git a/src/Umbraco.Web/Models/Mapping/ContentPropertyDisplayMapper.cs b/src/Umbraco.Web/Models/Mapping/ContentPropertyDisplayMapper.cs index f68c5d8b44..12278e97ea 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentPropertyDisplayMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentPropertyDisplayMapper.cs @@ -19,7 +19,7 @@ namespace Umbraco.Web.Models.Mapping { _textService = textService; } - public override void Map(Property originalProp, ContentPropertyDisplay dest, MapperContext context) + public override void Map(IProperty originalProp, ContentPropertyDisplay dest, MapperContext context) { base.Map(originalProp, dest, context); diff --git a/src/Umbraco.Web/Models/Mapping/ContentPropertyDtoMapper.cs b/src/Umbraco.Web/Models/Mapping/ContentPropertyDtoMapper.cs index 72107c6201..f481ad445c 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentPropertyDtoMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentPropertyDtoMapper.cs @@ -16,7 +16,7 @@ namespace Umbraco.Web.Models.Mapping : base(dataTypeService, entityService, logger, propertyEditors) { } - public override void Map(Property property, ContentPropertyDto dest, MapperContext context) + public override void Map(IProperty property, ContentPropertyDto dest, MapperContext context) { base.Map(property, dest, context); diff --git a/src/Umbraco.Web/Models/Mapping/ContentPropertyMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/ContentPropertyMapDefinition.cs index e6290cc19e..5d659fbf9e 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentPropertyMapDefinition.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentPropertyMapDefinition.cs @@ -27,9 +27,9 @@ namespace Umbraco.Web.Models.Mapping public void DefineMaps(UmbracoMapper mapper) { mapper.Define>((source, context) => new Tab(), Map); - mapper.Define((source, context) => new ContentPropertyBasic(), Map); - mapper.Define((source, context) => new ContentPropertyDto(), Map); - mapper.Define((source, context) => new ContentPropertyDisplay(), Map); + mapper.Define((source, context) => new ContentPropertyBasic(), Map); + mapper.Define((source, context) => new ContentPropertyDto(), Map); + mapper.Define((source, context) => new ContentPropertyDisplay(), Map); } // Umbraco.Code.MapAll -Properties -Alias -Expanded @@ -40,19 +40,19 @@ namespace Umbraco.Web.Models.Mapping target.Label = source.Name; } - private void Map(Property source, ContentPropertyBasic target, MapperContext context) + private void Map(IProperty source, ContentPropertyBasic target, MapperContext context) { // assume this is mapping everything and no MapAll is required _contentPropertyBasicConverter.Map(source, target, context); } - private void Map(Property source, ContentPropertyDto target, MapperContext context) + private void Map(IProperty source, ContentPropertyDto target, MapperContext context) { // assume this is mapping everything and no MapAll is required _contentPropertyDtoConverter.Map(source, target, context); } - private void Map(Property source, ContentPropertyDisplay target, MapperContext context) + private void Map(IProperty source, ContentPropertyDisplay target, MapperContext context) { // assume this is mapping everything and no MapAll is required _contentPropertyDisplayMapper.Map(source, target, context); diff --git a/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs index 2e44f1327b..f2099f2554 100644 --- a/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs +++ b/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs @@ -177,6 +177,14 @@ namespace Umbraco.Web.Models.Mapping target.Name = source.Values.ContainsKey("nodeName") ? source.Values["nodeName"] : "[no name]"; + if (source.Values.TryGetValue(UmbracoExamineIndex.UmbracoFileFieldName, out var umbracoFile)) + { + if (umbracoFile != null) + { + target.Name = $"{target.Name} ({umbracoFile})"; + } + } + if (source.Values.ContainsKey(UmbracoExamineIndex.NodeKeyFieldName)) { if (Guid.TryParse(source.Values[UmbracoExamineIndex.NodeKeyFieldName], out var key)) diff --git a/src/Umbraco.Web/Models/Mapping/MediaMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/MediaMapDefinition.cs index 05c006ec41..80bdc7ade4 100644 --- a/src/Umbraco.Web/Models/Mapping/MediaMapDefinition.cs +++ b/src/Umbraco.Web/Models/Mapping/MediaMapDefinition.cs @@ -42,7 +42,7 @@ namespace Umbraco.Web.Models.Mapping // Umbraco.Code.MapAll private static void Map(IMedia source, ContentPropertyCollectionDto target, MapperContext context) { - target.Properties = context.MapEnumerable(source.Properties); + target.Properties = context.MapEnumerable(source.Properties); } // Umbraco.Code.MapAll -Properties -Errors -Edited -Updater -Alias -IsContainer @@ -86,7 +86,7 @@ namespace Umbraco.Web.Models.Mapping target.Owner = _commonMapper.GetOwner(source, context); target.ParentId = source.ParentId; target.Path = source.Path; - target.Properties = context.MapEnumerable(source.Properties); + target.Properties = context.MapEnumerable(source.Properties); target.SortOrder = source.SortOrder; target.State = null; target.Trashed = source.Trashed; diff --git a/src/Umbraco.Web/Models/Mapping/MemberMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/MemberMapDefinition.cs index 8671bfe538..fd295803c1 100644 --- a/src/Umbraco.Web/Models/Mapping/MemberMapDefinition.cs +++ b/src/Umbraco.Web/Models/Mapping/MemberMapDefinition.cs @@ -113,7 +113,7 @@ namespace Umbraco.Web.Models.Mapping target.Owner = _commonMapper.GetOwner(source, context); target.ParentId = source.ParentId; target.Path = source.Path; - target.Properties = context.MapEnumerable(source.Properties); + target.Properties = context.MapEnumerable(source.Properties); target.SortOrder = source.SortOrder; target.State = null; target.Udi = Udi.Create(Constants.UdiEntityType.Member, source.Key); @@ -151,7 +151,7 @@ namespace Umbraco.Web.Models.Mapping // Umbraco.Code.MapAll private static void Map(IMember source, ContentPropertyCollectionDto target, MapperContext context) { - target.Properties = context.MapEnumerable(source.Properties); + target.Properties = context.MapEnumerable(source.Properties); } private MembershipScenario GetMembershipScenario() diff --git a/src/Umbraco.Web/Models/Mapping/MemberTabsAndPropertiesMapper.cs b/src/Umbraco.Web/Models/Mapping/MemberTabsAndPropertiesMapper.cs index 8744b068a7..4173e9a943 100644 --- a/src/Umbraco.Web/Models/Mapping/MemberTabsAndPropertiesMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/MemberTabsAndPropertiesMapper.cs @@ -126,7 +126,7 @@ namespace Umbraco.Web.Models.Mapping Value = _localizedTextService.UmbracoDictionaryTranslate(member.ContentType.Name), View = Current.PropertyEditors[Constants.PropertyEditors.Aliases.Label].GetValueEditor().View }, - GetLoginProperty(_memberService, member, _localizedTextService), + GetLoginProperty(_memberTypeService, member, _localizedTextService), new ContentPropertyDisplay { Alias = $"{Constants.PropertyEditors.InternalGenericPropertiesPrefix}email", @@ -176,7 +176,7 @@ namespace Umbraco.Web.Models.Mapping /// /// /// - protected override List MapProperties(IContentBase content, List properties, MapperContext context) + protected override List MapProperties(IContentBase content, List properties, MapperContext context) { var result = base.MapProperties(content, properties, context); var member = (IMember)content; @@ -208,7 +208,7 @@ namespace Umbraco.Web.Models.Mapping /// /// Returns the login property display field /// - /// + /// /// /// /// @@ -218,7 +218,7 @@ namespace Umbraco.Web.Models.Mapping /// the membership provider is a custom one, we cannot allow changing the username because MembershipProvider's do not actually natively /// allow that. /// - internal static ContentPropertyDisplay GetLoginProperty(IMemberService memberService, IMember member, ILocalizedTextService localizedText) + internal static ContentPropertyDisplay GetLoginProperty(IMemberTypeService memberTypeService, IMember member, ILocalizedTextService localizedText) { var prop = new ContentPropertyDisplay { @@ -227,7 +227,7 @@ namespace Umbraco.Web.Models.Mapping Value = member.Username }; - var scenario = memberService.GetMembershipScenario(); + var scenario = memberTypeService.GetMembershipScenario(); // only allow editing if this is a new member, or if the membership provider is the Umbraco one if (member.HasIdentity == false || scenario == MembershipScenario.NativeUmbraco) diff --git a/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesMapper.cs b/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesMapper.cs index b8d76572fb..70a001735a 100644 --- a/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesMapper.cs @@ -103,9 +103,9 @@ namespace Umbraco.Web.Models.Mapping /// /// /// - protected virtual List MapProperties(IContentBase content, List properties, MapperContext context) + protected virtual List MapProperties(IContentBase content, List properties, MapperContext context) { - return context.MapEnumerable(properties.OrderBy(x => x.PropertyType.SortOrder)); + return context.MapEnumerable(properties.OrderBy(x => x.PropertyType.SortOrder)); } } @@ -132,7 +132,7 @@ namespace Umbraco.Web.Models.Mapping var groupsGroupsByName = contentType.CompositionPropertyGroups.OrderBy(x => x.SortOrder).GroupBy(x => x.Name); foreach (var groupsByName in groupsGroupsByName) { - var properties = new List(); + var properties = new List(); // merge properties for groups with the same name foreach (var group in groupsByName) diff --git a/src/Umbraco.Web/Mvc/PluginViewEngine.cs b/src/Umbraco.Web/Mvc/PluginViewEngine.cs index e83980a5d8..fcdddbfbf1 100644 --- a/src/Umbraco.Web/Mvc/PluginViewEngine.cs +++ b/src/Umbraco.Web/Mvc/PluginViewEngine.cs @@ -35,16 +35,16 @@ namespace Umbraco.Web.Mvc var viewLocationsArray = new[] { - string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/{1}/{0}.cshtml"), - string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/{1}/{0}.vbhtml") + string.Concat(Core.Constants.SystemDirectories.AppPlugins, "/{2}/Views/{1}/{0}.cshtml"), + string.Concat(Core.Constants.SystemDirectories.AppPlugins, "/{2}/Views/{1}/{0}.vbhtml") }; //set all of the area view locations to the plugin folder AreaViewLocationFormats = viewLocationsArray .Concat(new[] { - string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/Shared/{0}.cshtml"), - string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/Shared/{0}.vbhtml") + string.Concat(Core.Constants.SystemDirectories.AppPlugins, "/{2}/Views/Shared/{0}.cshtml"), + string.Concat(Core.Constants.SystemDirectories.AppPlugins, "/{2}/Views/Shared/{0}.vbhtml") }) .ToArray(); @@ -53,15 +53,15 @@ namespace Umbraco.Web.Mvc AreaPartialViewLocationFormats = new[] { //will be used when we have partial view and child action macros - string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/Partials/{0}.cshtml"), - string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/Partials/{0}.vbhtml"), - string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/MacroPartials/{0}.cshtml"), - string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/MacroPartials/{0}.vbhtml"), - //for partials - string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/{1}/{0}.cshtml"), - string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/{1}/{0}.vbhtml"), - string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/Shared/{0}.cshtml"), - string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/Shared/{0}.vbhtml") + string.Concat(Core.Constants.SystemDirectories.AppPlugins, "/{2}/Views/Partials/{0}.cshtml"), + string.Concat(Core.Constants.SystemDirectories.AppPlugins, "/{2}/Views/Partials/{0}.vbhtml"), + string.Concat(Core.Constants.SystemDirectories.AppPlugins, "/{2}/Views/MacroPartials/{0}.cshtml"), + string.Concat(Core.Constants.SystemDirectories.AppPlugins, "/{2}/Views/MacroPartials/{0}.vbhtml"), + //for partialsCurrent. + string.Concat(Core.Constants.SystemDirectories.AppPlugins, "/{2}/Views/{1}/{0}.cshtml"), + string.Concat(Core.Constants.SystemDirectories.AppPlugins, "/{2}/Views/{1}/{0}.vbhtml"), + string.Concat(Core.Constants.SystemDirectories.AppPlugins, "/{2}/Views/Shared/{0}.cshtml"), + string.Concat(Core.Constants.SystemDirectories.AppPlugins, "/{2}/Views/Shared/{0}.vbhtml") }; } diff --git a/src/Umbraco.Web/Mvc/UmbracoViewPageOfTModel.cs b/src/Umbraco.Web/Mvc/UmbracoViewPageOfTModel.cs index 26dee405ee..8664f0a13c 100644 --- a/src/Umbraco.Web/Mvc/UmbracoViewPageOfTModel.cs +++ b/src/Umbraco.Web/Mvc/UmbracoViewPageOfTModel.cs @@ -214,7 +214,7 @@ namespace Umbraco.Web.Mvc // creating previewBadge markup markupToInject = string.Format(Current.Configs.Settings().Content.PreviewBadge, - Current.IOHelper.ResolveUrl(SystemDirectories.Umbraco), + Current.IOHelper.ResolveUrl(Current.Configs.Global().UmbracoPath), Server.UrlEncode(Current.UmbracoContext.HttpContext.Request.Url?.PathAndQuery)); } else diff --git a/src/Umbraco.Web/PropertyEditors/CheckBoxListPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/CheckBoxListPropertyEditor.cs index d81b63f2ad..f28acd5e90 100644 --- a/src/Umbraco.Web/PropertyEditors/CheckBoxListPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/CheckBoxListPropertyEditor.cs @@ -17,20 +17,24 @@ namespace Umbraco.Web.PropertyEditors public class CheckBoxListPropertyEditor : DataEditor { private readonly ILocalizedTextService _textService; + private readonly IDataTypeService _dataTypeService; + private readonly ILocalizationService _localizationService; /// /// The constructor will setup the property editor based on the attribute if one is found /// - public CheckBoxListPropertyEditor(ILogger logger, ILocalizedTextService textService) + public CheckBoxListPropertyEditor(ILogger logger, ILocalizedTextService textService, IDataTypeService dataTypeService, ILocalizationService localizationService) : base(logger) { _textService = textService; + _dataTypeService = dataTypeService; + _localizationService = localizationService; } /// protected override IConfigurationEditor CreateConfigurationEditor() => new ValueListConfigurationEditor(_textService); /// - protected override IDataValueEditor CreateValueEditor() => new MultipleValueEditor(Logger, Attribute); + protected override IDataValueEditor CreateValueEditor() => new MultipleValueEditor(Logger, _dataTypeService, _localizationService, Attribute); } } diff --git a/src/Umbraco.Web/PropertyEditors/DateValueEditor.cs b/src/Umbraco.Web/PropertyEditors/DateValueEditor.cs index a03ad4aa00..b8dada173f 100644 --- a/src/Umbraco.Web/PropertyEditors/DateValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DateValueEditor.cs @@ -12,13 +12,13 @@ namespace Umbraco.Web.PropertyEditors /// internal class DateValueEditor : DataValueEditor { - public DateValueEditor(DataEditorAttribute attribute) - : base(attribute) + public DateValueEditor(IDataTypeService dataTypeService, ILocalizationService localizationService, DataEditorAttribute attribute) + : base(dataTypeService, localizationService, attribute) { Validators.Add(new DateTimeValidator()); } - public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture= null, string segment = null) + public override object ToEditor(IProperty property, string culture= null, string segment = null) { var date = property.GetValue(culture, segment).TryConvertTo(); if (date.Success == false || date.Result == null) diff --git a/src/Umbraco.Web/PropertyEditors/DropDownFlexiblePropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownFlexiblePropertyEditor.cs index 98a19f39ad..0b0a0f6d06 100644 --- a/src/Umbraco.Web/PropertyEditors/DropDownFlexiblePropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DropDownFlexiblePropertyEditor.cs @@ -14,16 +14,20 @@ namespace Umbraco.Web.PropertyEditors public class DropDownFlexiblePropertyEditor : DataEditor { private readonly ILocalizedTextService _textService; + private readonly IDataTypeService _dataTypeService; + private readonly ILocalizationService _localizationService; - public DropDownFlexiblePropertyEditor(ILocalizedTextService textService, ILogger logger) + public DropDownFlexiblePropertyEditor(ILocalizedTextService textService, ILogger logger, IDataTypeService dataTypeService, ILocalizationService localizationService) : base(logger) { _textService = textService; + _dataTypeService = dataTypeService; + _localizationService = localizationService; } protected override IDataValueEditor CreateValueEditor() { - return new MultipleValueEditor(Logger, Attribute); + return new MultipleValueEditor(Logger, _dataTypeService, _localizationService, Attribute); } protected override IConfigurationEditor CreateConfigurationEditor() => new DropDownFlexibleConfigurationEditor(_textService); diff --git a/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs index a3396a5fb3..366f3938a6 100644 --- a/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs @@ -8,6 +8,7 @@ using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; +using Umbraco.Core.Services.Implement; using Umbraco.Web.Media; namespace Umbraco.Web.PropertyEditors @@ -23,12 +24,16 @@ namespace Umbraco.Web.PropertyEditors private readonly IMediaFileSystem _mediaFileSystem; private readonly IContentSection _contentSection; private readonly UploadAutoFillProperties _uploadAutoFillProperties; + private readonly IDataTypeService _dataTypeService; + private readonly ILocalizationService _localizationService; - public FileUploadPropertyEditor(ILogger logger, IMediaFileSystem mediaFileSystem, IContentSection contentSection) + public FileUploadPropertyEditor(ILogger logger, IMediaFileSystem mediaFileSystem, IContentSection contentSection, IDataTypeService dataTypeService, ILocalizationService localizationService) : base(logger) { _mediaFileSystem = mediaFileSystem ?? throw new ArgumentNullException(nameof(mediaFileSystem)); _contentSection = contentSection; + _dataTypeService = dataTypeService; + _localizationService = localizationService; _uploadAutoFillProperties = new UploadAutoFillProperties(_mediaFileSystem, logger, contentSection); } @@ -38,7 +43,7 @@ namespace Umbraco.Web.PropertyEditors /// The corresponding property value editor. protected override IDataValueEditor CreateValueEditor() { - var editor = new FileUploadPropertyValueEditor(Attribute, _mediaFileSystem); + var editor = new FileUploadPropertyValueEditor(Attribute, _mediaFileSystem, _dataTypeService, _localizationService); editor.Validators.Add(new UploadFileTypeValidator()); return editor; } @@ -48,7 +53,7 @@ namespace Umbraco.Web.PropertyEditors /// /// The property. /// A value indicating whether a property is an upload field, and (optionally) has a non-empty value. - private static bool IsUploadField(Property property) + private static bool IsUploadField(IProperty property) { return property.PropertyType.PropertyEditorAlias == Constants.PropertyEditors.Aliases.UploadField; } @@ -70,7 +75,7 @@ namespace Umbraco.Web.PropertyEditors /// /// /// - private IEnumerable GetFilePathsFromPropertyValues(Property prop) + private IEnumerable GetFilePathsFromPropertyValues(IProperty prop) { var propVals = prop.Values; foreach (var propertyValue in propVals) diff --git a/src/Umbraco.Web/PropertyEditors/FileUploadPropertyValueEditor.cs b/src/Umbraco.Web/PropertyEditors/FileUploadPropertyValueEditor.cs index 942f53b561..172d8070af 100644 --- a/src/Umbraco.Web/PropertyEditors/FileUploadPropertyValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/FileUploadPropertyValueEditor.cs @@ -7,6 +7,7 @@ using Umbraco.Core; using Umbraco.Core.IO; using Umbraco.Core.Models.Editors; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; namespace Umbraco.Web.PropertyEditors { @@ -17,8 +18,8 @@ namespace Umbraco.Web.PropertyEditors { private readonly IMediaFileSystem _mediaFileSystem; - public FileUploadPropertyValueEditor(DataEditorAttribute attribute, IMediaFileSystem mediaFileSystem) - : base(attribute) + public FileUploadPropertyValueEditor(DataEditorAttribute attribute, IMediaFileSystem mediaFileSystem, IDataTypeService dataTypeService, ILocalizationService localizationService) + : base(dataTypeService, localizationService, attribute) { _mediaFileSystem = mediaFileSystem ?? throw new ArgumentNullException(nameof(mediaFileSystem)); } @@ -92,7 +93,7 @@ namespace Umbraco.Web.PropertyEditors if (editorFile == null) return null; return filepath == null ? string.Empty : _mediaFileSystem.GetUrl(filepath); - + } private string ProcessFile(ContentPropertyData editorValue, ContentPropertyFile file, string currentPath, Guid cuid, Guid puid) diff --git a/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs index 24e2fc29a5..6f6f1d911d 100644 --- a/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs @@ -28,14 +28,18 @@ namespace Umbraco.Web.PropertyEditors private IMediaService _mediaService; private IContentTypeBaseServiceProvider _contentTypeBaseServiceProvider; private IUmbracoContextAccessor _umbracoContextAccessor; + private readonly IDataTypeService _dataTypeService; + private readonly ILocalizationService _localizationService; private ILogger _logger; - public GridPropertyEditor(ILogger logger, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor) + public GridPropertyEditor(ILogger logger, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor, IDataTypeService dataTypeService, ILocalizationService localizationService) : base(logger) { _mediaService = mediaService; _contentTypeBaseServiceProvider = contentTypeBaseServiceProvider; _umbracoContextAccessor = umbracoContextAccessor; + _dataTypeService = dataTypeService; + _localizationService = localizationService; _logger = logger; } @@ -45,7 +49,7 @@ namespace Umbraco.Web.PropertyEditors /// Overridden to ensure that the value is validated /// /// - protected override IDataValueEditor CreateValueEditor() => new GridPropertyValueEditor(Attribute, _mediaService, _contentTypeBaseServiceProvider, _umbracoContextAccessor, _logger); + protected override IDataValueEditor CreateValueEditor() => new GridPropertyValueEditor(Attribute, _mediaService, _contentTypeBaseServiceProvider, _umbracoContextAccessor, _logger, _dataTypeService, _localizationService); protected override IConfigurationEditor CreateConfigurationEditor() => new GridConfigurationEditor(); @@ -56,8 +60,8 @@ namespace Umbraco.Web.PropertyEditors private IUmbracoContextAccessor _umbracoContextAccessor; private ILogger _logger; - public GridPropertyValueEditor(DataEditorAttribute attribute, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor, ILogger logger) - : base(attribute) + public GridPropertyValueEditor(DataEditorAttribute attribute, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor, ILogger logger, IDataTypeService dataTypeService, ILocalizationService localizationService) + : base(dataTypeService, localizationService, attribute) { _mediaService = mediaService; _contentTypeBaseServiceProvider = contentTypeBaseServiceProvider; @@ -115,7 +119,7 @@ namespace Umbraco.Web.PropertyEditors /// /// /// - public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public override object ToEditor(IProperty property, string culture = null, string segment = null) { var val = property.GetValue(culture, segment); if (val == null) return string.Empty; diff --git a/src/Umbraco.Web/PropertyEditors/GridPropertyIndexValueFactory.cs b/src/Umbraco.Web/PropertyEditors/GridPropertyIndexValueFactory.cs index 0cf36122d7..af72f0b819 100644 --- a/src/Umbraco.Web/PropertyEditors/GridPropertyIndexValueFactory.cs +++ b/src/Umbraco.Web/PropertyEditors/GridPropertyIndexValueFactory.cs @@ -18,7 +18,7 @@ namespace Umbraco.Web.PropertyEditors /// public class GridPropertyIndexValueFactory : IPropertyIndexValueFactory { - public IEnumerable>> GetIndexValues(Property property, string culture, string segment, bool published) + public IEnumerable>> GetIndexValues(IProperty property, string culture, string segment, bool published) { var result = new List>>(); diff --git a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs index 1d7c1eef65..fe1f026417 100644 --- a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs @@ -32,17 +32,19 @@ namespace Umbraco.Web.PropertyEditors private readonly IMediaFileSystem _mediaFileSystem; private readonly IContentSection _contentSettings; private readonly IDataTypeService _dataTypeService; + private readonly ILocalizationService _localizationService; private readonly UploadAutoFillProperties _autoFillProperties; /// /// Initializes a new instance of the class. /// - public ImageCropperPropertyEditor(ILogger logger, IMediaFileSystem mediaFileSystem, IContentSection contentSettings, IDataTypeService dataTypeService) + public ImageCropperPropertyEditor(ILogger logger, IMediaFileSystem mediaFileSystem, IContentSection contentSettings, IDataTypeService dataTypeService, ILocalizationService localizationService) : base(logger) { _mediaFileSystem = mediaFileSystem ?? throw new ArgumentNullException(nameof(mediaFileSystem)); _contentSettings = contentSettings ?? throw new ArgumentNullException(nameof(contentSettings)); _dataTypeService = dataTypeService; + _localizationService = localizationService; // TODO: inject? _autoFillProperties = new UploadAutoFillProperties(_mediaFileSystem, logger, _contentSettings); @@ -52,7 +54,7 @@ namespace Umbraco.Web.PropertyEditors /// Creates the corresponding property value editor. /// /// The corresponding property value editor. - protected override IDataValueEditor CreateValueEditor() => new ImageCropperPropertyValueEditor(Attribute, Logger, _mediaFileSystem); + protected override IDataValueEditor CreateValueEditor() => new ImageCropperPropertyValueEditor(Attribute, Logger, _mediaFileSystem, _dataTypeService, _localizationService); /// /// Creates the corresponding preValue editor. @@ -65,7 +67,7 @@ namespace Umbraco.Web.PropertyEditors /// /// The property. /// A value indicating whether a property is an image cropper field, and (optionally) has a non-empty value. - private static bool IsCropperField(Property property) + private static bool IsCropperField(IProperty property) { return property.PropertyType.PropertyEditorAlias == Constants.PropertyEditors.Aliases.ImageCropper; } @@ -111,7 +113,7 @@ namespace Umbraco.Web.PropertyEditors /// /// /// - private IEnumerable GetFilePathsFromPropertyValues(Property prop) + private IEnumerable GetFilePathsFromPropertyValues(IProperty prop) { //parses out the src from a json string diff --git a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs index 4aac8f54aa..1dab41d4e6 100644 --- a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs @@ -21,8 +21,8 @@ namespace Umbraco.Web.PropertyEditors private readonly ILogger _logger; private readonly IMediaFileSystem _mediaFileSystem; - public ImageCropperPropertyValueEditor(DataEditorAttribute attribute, ILogger logger, IMediaFileSystem mediaFileSystem) - : base(attribute) + public ImageCropperPropertyValueEditor(DataEditorAttribute attribute, ILogger logger, IMediaFileSystem mediaFileSystem, IDataTypeService dataTypeService, ILocalizationService localizationService) + : base(dataTypeService, localizationService, attribute) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _mediaFileSystem = mediaFileSystem ?? throw new ArgumentNullException(nameof(mediaFileSystem)); @@ -32,7 +32,7 @@ namespace Umbraco.Web.PropertyEditors /// This is called to merge in the prevalue crops with the value that is saved - similar to the property value converter for the front-end /// - public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public override object ToEditor(IProperty property, string culture = null, string segment = null) { var val = property.GetValue(culture, segment); if (val == null) return null; @@ -47,7 +47,7 @@ namespace Umbraco.Web.PropertyEditors value = new ImageCropperValue { Src = val.ToString() }; } - var dataType = dataTypeService.GetDataType(property.PropertyType.DataTypeId); + var dataType = DataTypeService.GetDataType(property.PropertyType.DataTypeId); if (dataType?.Configuration != null) value.ApplyConfiguration(dataType.ConfigurationAs()); @@ -161,7 +161,7 @@ namespace Umbraco.Web.PropertyEditors } - public override string ConvertDbToString(PropertyType propertyType, object value, IDataTypeService dataTypeService) + public override string ConvertDbToString(IPropertyType propertyType, object value) { if (value == null || string.IsNullOrEmpty(value.ToString())) return null; @@ -172,7 +172,7 @@ namespace Umbraco.Web.PropertyEditors return val; // more magic here ;-( - var configuration = dataTypeService.GetDataType(propertyType.DataTypeId).ConfigurationAs(); + var configuration = DataTypeService.GetDataType(propertyType.DataTypeId).ConfigurationAs(); var crops = configuration?.Crops ?? Array.Empty(); return JsonConvert.SerializeObject(new diff --git a/src/Umbraco.Web/PropertyEditors/MultiUrlPickerPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/MultiUrlPickerPropertyEditor.cs index 95ac809576..a5da833501 100644 --- a/src/Umbraco.Web/PropertyEditors/MultiUrlPickerPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MultiUrlPickerPropertyEditor.cs @@ -19,15 +19,19 @@ namespace Umbraco.Web.PropertyEditors { private readonly IEntityService _entityService; private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor; + private readonly IDataTypeService _dataTypeService; + private readonly ILocalizationService _localizationService; - public MultiUrlPickerPropertyEditor(ILogger logger, IEntityService entityService, IPublishedSnapshotAccessor publishedSnapshotAccessor) : base(logger, EditorType.PropertyValue) + public MultiUrlPickerPropertyEditor(ILogger logger, IEntityService entityService, IPublishedSnapshotAccessor publishedSnapshotAccessor, IDataTypeService dataTypeService, ILocalizationService localizationService) : base(logger, EditorType.PropertyValue) { _entityService = entityService ?? throw new ArgumentNullException(nameof(entityService)); _publishedSnapshotAccessor = publishedSnapshotAccessor ?? throw new ArgumentNullException(nameof(publishedSnapshotAccessor)); + _dataTypeService = dataTypeService; + _localizationService = localizationService; } protected override IConfigurationEditor CreateConfigurationEditor() => new MultiUrlPickerConfigurationEditor(); - protected override IDataValueEditor CreateValueEditor() => new MultiUrlPickerValueEditor(_entityService, _publishedSnapshotAccessor, Logger, Attribute); + protected override IDataValueEditor CreateValueEditor() => new MultiUrlPickerValueEditor(_entityService, _publishedSnapshotAccessor, Logger, _dataTypeService, _localizationService, Attribute); } } diff --git a/src/Umbraco.Web/PropertyEditors/MultiUrlPickerValueEditor.cs b/src/Umbraco.Web/PropertyEditors/MultiUrlPickerValueEditor.cs index aa8fa73c7a..97d787dbba 100644 --- a/src/Umbraco.Web/PropertyEditors/MultiUrlPickerValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MultiUrlPickerValueEditor.cs @@ -21,14 +21,14 @@ namespace Umbraco.Web.PropertyEditors private readonly ILogger _logger; private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor; - public MultiUrlPickerValueEditor(IEntityService entityService, IPublishedSnapshotAccessor publishedSnapshotAccessor, ILogger logger, DataEditorAttribute attribute) : base(attribute) + public MultiUrlPickerValueEditor(IEntityService entityService, IPublishedSnapshotAccessor publishedSnapshotAccessor, ILogger logger, IDataTypeService dataTypeService, ILocalizationService localizationService, DataEditorAttribute attribute) : base(dataTypeService, localizationService, attribute) { _entityService = entityService ?? throw new ArgumentNullException(nameof(entityService)); _publishedSnapshotAccessor = publishedSnapshotAccessor ?? throw new ArgumentNullException(nameof(publishedSnapshotAccessor)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } - public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public override object ToEditor(IProperty property, string culture = null, string segment = null) { var value = property.GetValue(culture, segment)?.ToString(); @@ -118,7 +118,7 @@ namespace Umbraco.Web.PropertyEditors _logger.Error("Error getting links", ex); } - return base.ToEditor(property, dataTypeService, culture, segment); + return base.ToEditor(property, culture, segment); } diff --git a/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs index fa82bc555c..29ec8530d9 100644 --- a/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs @@ -4,6 +4,7 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using Newtonsoft.Json.Linq; using Umbraco.Core; +using Umbraco.Core.Composing; using Umbraco.Core.Exceptions; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -34,7 +35,7 @@ namespace Umbraco.Web.PropertyEditors { } /// - protected override IDataValueEditor CreateValueEditor() => new MultipleTextStringPropertyValueEditor(Attribute); + protected override IDataValueEditor CreateValueEditor() => new MultipleTextStringPropertyValueEditor(Current.Services.DataTypeService, Current.Services.LocalizationService,Attribute); /// protected override IConfigurationEditor CreateConfigurationEditor() => new MultipleTextStringConfigurationEditor(); @@ -44,8 +45,8 @@ namespace Umbraco.Web.PropertyEditors /// internal class MultipleTextStringPropertyValueEditor : DataValueEditor { - public MultipleTextStringPropertyValueEditor(DataEditorAttribute attribute) - : base(attribute) + public MultipleTextStringPropertyValueEditor(IDataTypeService dataTypeService, ILocalizationService localizationService, DataEditorAttribute attribute) + : base(dataTypeService, localizationService, attribute) { } /// @@ -95,7 +96,7 @@ namespace Umbraco.Web.PropertyEditors /// /// The legacy property editor saved this data as new line delimited! strange but we have to maintain that. /// - public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public override object ToEditor(IProperty property, string culture = null, string segment = null) { var val = property.GetValue(culture, segment); return val?.ToString().Split(new[] {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries) diff --git a/src/Umbraco.Web/PropertyEditors/MultipleValueEditor.cs b/src/Umbraco.Web/PropertyEditors/MultipleValueEditor.cs index bbeaff184e..f5ca6c5cfe 100644 --- a/src/Umbraco.Web/PropertyEditors/MultipleValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MultipleValueEditor.cs @@ -19,8 +19,8 @@ namespace Umbraco.Web.PropertyEditors { private readonly ILogger _logger; - internal MultipleValueEditor(ILogger logger, DataEditorAttribute attribute) - : base(attribute) + internal MultipleValueEditor(ILogger logger, IDataTypeService dataTypeService, ILocalizationService localizationService, DataEditorAttribute attribute) + : base(dataTypeService, localizationService, attribute) { _logger = logger; } @@ -33,9 +33,9 @@ namespace Umbraco.Web.PropertyEditors /// /// /// - public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public override object ToEditor(IProperty property, string culture = null, string segment = null) { - var json = base.ToEditor(property, dataTypeService, culture, segment).ToString(); + var json = base.ToEditor(property, culture, segment).ToString(); return JsonConvert.DeserializeObject(json) ?? Array.Empty(); } diff --git a/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs index f511a97cac..45083a12a1 100644 --- a/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs @@ -28,13 +28,17 @@ namespace Umbraco.Web.PropertyEditors public class NestedContentPropertyEditor : DataEditor { private readonly Lazy _propertyEditors; + private readonly IDataTypeService _dataTypeService; + private readonly ILocalizationService _localizationService; internal const string ContentTypeAliasPropertyKey = "ncContentTypeAlias"; - public NestedContentPropertyEditor(ILogger logger, Lazy propertyEditors) + public NestedContentPropertyEditor(ILogger logger, Lazy propertyEditors, IDataTypeService dataTypeService, ILocalizationService localizationService) : base (logger) { _propertyEditors = propertyEditors; + _dataTypeService = dataTypeService; + _localizationService = localizationService; } // has to be lazy else circular dep in ctor @@ -48,7 +52,7 @@ namespace Umbraco.Web.PropertyEditors #region Value Editor - protected override IDataValueEditor CreateValueEditor() => new NestedContentPropertyValueEditor(Attribute, PropertyEditors); + protected override IDataValueEditor CreateValueEditor() => new NestedContentPropertyValueEditor(_dataTypeService, _localizationService, Attribute, PropertyEditors); internal class NestedContentPropertyValueEditor : DataValueEditor { @@ -58,8 +62,8 @@ namespace Umbraco.Web.PropertyEditors Current.Services.ContentTypeService.GetAll().ToDictionary(c => c.Alias) ); - public NestedContentPropertyValueEditor(DataEditorAttribute attribute, PropertyEditorCollection propertyEditors) - : base(attribute) + public NestedContentPropertyValueEditor(IDataTypeService dataTypeService, ILocalizationService localizationService, DataEditorAttribute attribute, PropertyEditorCollection propertyEditors) + : base(dataTypeService, localizationService, attribute) { _propertyEditors = propertyEditors; Validators.Add(new NestedContentValidator(propertyEditors, GetElementType)); @@ -92,7 +96,7 @@ namespace Umbraco.Web.PropertyEditors #region DB to String - public override string ConvertDbToString(PropertyType propertyType, object propertyValue, IDataTypeService dataTypeService) + public override string ConvertDbToString(IPropertyType propertyType, object propertyValue) { if (propertyValue == null || string.IsNullOrWhiteSpace(propertyValue.ToString())) return string.Empty; @@ -129,9 +133,9 @@ namespace Umbraco.Web.PropertyEditors { continue; } - var tempConfig = dataTypeService.GetDataType(propType.DataTypeId).Configuration; + var tempConfig = DataTypeService.GetDataType(propType.DataTypeId).Configuration; var valEditor = propEditor.GetValueEditor(tempConfig); - var convValue = valEditor.ConvertDbToString(propType, propValues[propAlias]?.ToString(), dataTypeService); + var convValue = valEditor.ConvertDbToString(propType, propValues[propAlias]?.ToString()); propValues[propAlias] = convValue; } catch (InvalidOperationException) @@ -152,7 +156,7 @@ namespace Umbraco.Web.PropertyEditors // note: there is NO variant support here - public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public override object ToEditor(IProperty property, string culture = null, string segment = null) { var val = property.GetValue(culture, segment); if (val == null || string.IsNullOrWhiteSpace(val.ToString())) @@ -197,9 +201,9 @@ namespace Umbraco.Web.PropertyEditors propValues[propAlias] = tempProp.GetValue()?.ToString(); continue; } - var tempConfig = dataTypeService.GetDataType(propType.DataTypeId).Configuration; + var tempConfig = DataTypeService.GetDataType(propType.DataTypeId).Configuration; var valEditor = propEditor.GetValueEditor(tempConfig); - var convValue = valEditor.ToEditor(tempProp, dataTypeService); + var convValue = valEditor.ToEditor(tempProp); propValues[propAlias] = convValue == null ? null : JToken.FromObject(convValue); } catch (InvalidOperationException) diff --git a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs index 5743e9c1d5..aa6876df39 100644 --- a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs @@ -27,16 +27,26 @@ namespace Umbraco.Web.PropertyEditors private IMediaService _mediaService; private IContentTypeBaseServiceProvider _contentTypeBaseServiceProvider; private IUmbracoContextAccessor _umbracoContextAccessor; + private readonly IDataTypeService _dataTypeService; + private readonly ILocalizationService _localizationService; private ILogger _logger; /// /// The constructor will setup the property editor based on the attribute if one is found /// - public RichTextPropertyEditor(ILogger logger, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor) : base(logger) + public RichTextPropertyEditor( + ILogger logger, + IMediaService mediaService, + IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, + IUmbracoContextAccessor umbracoContextAccessor, + IDataTypeService dataTypeService, + ILocalizationService localizationService) : base(logger) { _mediaService = mediaService; _contentTypeBaseServiceProvider = contentTypeBaseServiceProvider; _umbracoContextAccessor = umbracoContextAccessor; + _dataTypeService = dataTypeService; + _localizationService = localizationService; _logger = logger; } @@ -44,7 +54,7 @@ namespace Umbraco.Web.PropertyEditors /// Create a custom value editor /// /// - protected override IDataValueEditor CreateValueEditor() => new RichTextPropertyValueEditor(Attribute, _mediaService, _contentTypeBaseServiceProvider, _umbracoContextAccessor, _logger); + protected override IDataValueEditor CreateValueEditor() => new RichTextPropertyValueEditor(Attribute, _mediaService, _contentTypeBaseServiceProvider, _umbracoContextAccessor, _logger, _dataTypeService, _localizationService); protected override IConfigurationEditor CreateConfigurationEditor() => new RichTextConfigurationEditor(); @@ -60,8 +70,8 @@ namespace Umbraco.Web.PropertyEditors private IUmbracoContextAccessor _umbracoContextAccessor; private ILogger _logger; - public RichTextPropertyValueEditor(DataEditorAttribute attribute, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor, ILogger logger) - : base(attribute) + public RichTextPropertyValueEditor(DataEditorAttribute attribute, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor, ILogger logger, IDataTypeService dataTypeService, ILocalizationService localizationService) + : base(dataTypeService, localizationService, attribute) { _mediaService = mediaService; _contentTypeBaseServiceProvider = contentTypeBaseServiceProvider; @@ -92,7 +102,7 @@ namespace Umbraco.Web.PropertyEditors /// /// /// - public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public override object ToEditor(IProperty property, string culture = null, string segment = null) { var val = property.GetValue(culture, segment); if (val == null) @@ -130,7 +140,7 @@ namespace Umbraco.Web.PropertyEditors internal class RichTextPropertyIndexValueFactory : IPropertyIndexValueFactory { - public IEnumerable>> GetIndexValues(Property property, string culture, string segment, bool published) + public IEnumerable>> GetIndexValues(IProperty property, string culture, string segment, bool published) { var val = property.GetValue(culture, segment, published); diff --git a/src/Umbraco.Web/PropertyEditors/TagsPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/TagsPropertyEditor.cs index fd7e8694a3..74338ba3fa 100644 --- a/src/Umbraco.Web/PropertyEditors/TagsPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/TagsPropertyEditor.cs @@ -4,10 +4,12 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using Newtonsoft.Json.Linq; using Umbraco.Core; +using Umbraco.Core.Composing; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.Editors; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; namespace Umbraco.Web.PropertyEditors { @@ -30,14 +32,14 @@ namespace Umbraco.Web.PropertyEditors _validators = validators; } - protected override IDataValueEditor CreateValueEditor() => new TagPropertyValueEditor(Attribute); + protected override IDataValueEditor CreateValueEditor() => new TagPropertyValueEditor(Current.Services.DataTypeService, Current.Services.LocalizationService, Attribute); protected override IConfigurationEditor CreateConfigurationEditor() => new TagConfigurationEditor(_validators); internal class TagPropertyValueEditor : DataValueEditor { - public TagPropertyValueEditor(DataEditorAttribute attribute) - : base(attribute) + public TagPropertyValueEditor(IDataTypeService dataTypeService, ILocalizationService localizationService, DataEditorAttribute attribute) + : base(dataTypeService, localizationService, attribute) { } /// diff --git a/src/Umbraco.Web/PropertyEditors/TextAreaPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/TextAreaPropertyEditor.cs index c7bc2efbda..28698e2c5c 100644 --- a/src/Umbraco.Web/PropertyEditors/TextAreaPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/TextAreaPropertyEditor.cs @@ -1,6 +1,7 @@ using Umbraco.Core; using Umbraco.Core.Logging; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; namespace Umbraco.Web.PropertyEditors { @@ -16,15 +17,21 @@ namespace Umbraco.Web.PropertyEditors Icon = "icon-application-window-alt")] public class TextAreaPropertyEditor : DataEditor { + private readonly IDataTypeService _dataTypeService; + private readonly ILocalizationService _localizationService; + /// /// Initializes a new instance of the class. /// - public TextAreaPropertyEditor(ILogger logger) + public TextAreaPropertyEditor(ILogger logger, IDataTypeService dataTypeService, ILocalizationService localizationService) : base(logger) - { } + { + _dataTypeService = dataTypeService; + _localizationService = localizationService; + } /// - protected override IDataValueEditor CreateValueEditor() => new TextOnlyValueEditor(Attribute); + protected override IDataValueEditor CreateValueEditor() => new TextOnlyValueEditor(_dataTypeService, _localizationService, Attribute); /// protected override IConfigurationEditor CreateConfigurationEditor() => new TextAreaConfigurationEditor(); diff --git a/src/Umbraco.Web/PropertyEditors/TextOnlyValueEditor.cs b/src/Umbraco.Web/PropertyEditors/TextOnlyValueEditor.cs index 754cef1f31..782e19e42d 100644 --- a/src/Umbraco.Web/PropertyEditors/TextOnlyValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/TextOnlyValueEditor.cs @@ -11,8 +11,8 @@ namespace Umbraco.Web.PropertyEditors /// public class TextOnlyValueEditor : DataValueEditor { - public TextOnlyValueEditor(DataEditorAttribute attribute) - : base(attribute) + public TextOnlyValueEditor(IDataTypeService dataTypeService, ILocalizationService localizationService, DataEditorAttribute attribute) + : base(dataTypeService, localizationService, attribute) { } /// @@ -26,7 +26,7 @@ namespace Umbraco.Web.PropertyEditors /// /// The object returned will always be a string and if the database type is not a valid string type an exception is thrown /// - public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public override object ToEditor(IProperty property, string culture = null, string segment = null) { var val = property.GetValue(culture, segment); diff --git a/src/Umbraco.Web/PropertyEditors/TextboxPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/TextboxPropertyEditor.cs index 18f8155198..c7c13b4caf 100644 --- a/src/Umbraco.Web/PropertyEditors/TextboxPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/TextboxPropertyEditor.cs @@ -1,6 +1,7 @@ using Umbraco.Core; using Umbraco.Core.Logging; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; namespace Umbraco.Web.PropertyEditors { @@ -15,15 +16,21 @@ namespace Umbraco.Web.PropertyEditors Group = Constants.PropertyEditors.Groups.Common)] public class TextboxPropertyEditor : DataEditor { + private readonly IDataTypeService _dataTypeService; + private readonly ILocalizationService _localizationService; + /// /// Initializes a new instance of the class. /// - public TextboxPropertyEditor(ILogger logger) + public TextboxPropertyEditor(ILogger logger, IDataTypeService dataTypeService, ILocalizationService localizationService) : base(logger) - { } + { + _dataTypeService = dataTypeService; + _localizationService = localizationService; + } /// - protected override IDataValueEditor CreateValueEditor() => new TextOnlyValueEditor(Attribute); + protected override IDataValueEditor CreateValueEditor() => new TextOnlyValueEditor(_dataTypeService, _localizationService, Attribute); /// protected override IConfigurationEditor CreateConfigurationEditor() => new TextboxConfigurationEditor(); diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs index bf4975714d..6d34a2af42 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs @@ -4,6 +4,7 @@ using System.Linq; using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Exceptions; +using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Web.Composing; using Umbraco.Web.Models; diff --git a/src/Umbraco.Web/Runtime/WebInitialComponent.cs b/src/Umbraco.Web/Runtime/WebInitialComponent.cs index 5210232f67..3b29212598 100644 --- a/src/Umbraco.Web/Runtime/WebInitialComponent.cs +++ b/src/Umbraco.Web/Runtime/WebInitialComponent.cs @@ -112,7 +112,7 @@ namespace Umbraco.Web.Runtime private static void ConfigureClientDependency(IGlobalSettings globalSettings) { // Backwards compatibility - set the path and URL type for ClientDependency 1.5.1 [LK] - XmlFileMapper.FileMapDefaultFolder = SystemDirectories.TempData.EnsureEndsWith('/') + "ClientDependency"; + XmlFileMapper.FileMapDefaultFolder = Core.Constants.SystemDirectories.TempData.EnsureEndsWith('/') + "ClientDependency"; BaseCompositeFileProcessingProvider.UrlTypeDefault = CompositeUrlType.Base64QueryStrings; // Now we need to detect if we are running 'Umbraco.Core.LocalTempStorage' as EnvironmentTemp and in that case we want to change the CDF file diff --git a/src/Umbraco.Web/Scheduling/SchedulerComponent.cs b/src/Umbraco.Web/Scheduling/SchedulerComponent.cs index ee3fce50c8..7ca58f667a 100644 --- a/src/Umbraco.Web/Scheduling/SchedulerComponent.cs +++ b/src/Umbraco.Web/Scheduling/SchedulerComponent.cs @@ -170,7 +170,7 @@ namespace Umbraco.Web.Scheduling // temp file cleanup, will run on all servers - even though file upload should only be handled on the master, this will // ensure that in the case it happes on replicas that they are cleaned up. var task = new TempFileCleanup(_fileCleanupRunner, DefaultDelayMilliseconds, OneHourMilliseconds, - new[] { new DirectoryInfo(Current.IOHelper.MapPath(SystemDirectories.TempFileUploads)) }, + new[] { new DirectoryInfo(Current.IOHelper.MapPath(Constants.SystemDirectories.TempFileUploads)) }, TimeSpan.FromDays(1), //files that are over a day old _runtime, _logger); _scrubberRunner.TryAdd(task); diff --git a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs index c1844655a9..cf9d390768 100644 --- a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs +++ b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs @@ -67,7 +67,7 @@ namespace Umbraco.Web.Search string type; var indexName = Constants.UmbracoIndexes.InternalIndexName; - var fields = new[] { "id", "__NodeId", "__Key" }; + var fields = new List { "id", "__NodeId", "__Key" }; // TODO: WE should try to allow passing in a lucene raw query, however we will still need to do some manual string // manipulation for things like start paths, member types, etc... @@ -87,7 +87,7 @@ namespace Umbraco.Web.Search case UmbracoEntityTypes.Member: indexName = Constants.UmbracoIndexes.MembersIndexName; type = "member"; - fields = new[] { "id", "__NodeId", "__Key", "email", "loginName" }; + fields.AddRange(new[]{ "email", "loginName"}); if (searchFrom != null && searchFrom != Constants.Conventions.MemberTypes.AllMembersListId && searchFrom.Trim() != "-1") { sb.Append("+__NodeTypeAlias:"); @@ -97,6 +97,7 @@ namespace Umbraco.Web.Search break; case UmbracoEntityTypes.Media: type = "media"; + fields.AddRange(new[] { UmbracoExamineIndex.UmbracoFileFieldName }); var allMediaStartNodes = _umbracoContext.Security.CurrentUser.CalculateMediaStartNodeIds(_entityService); AppendPath(sb, UmbracoObjectTypes.Media, allMediaStartNodes, searchFrom, ignoreUserStartNodes, _entityService); break; @@ -161,7 +162,7 @@ namespace Umbraco.Web.Search return _mapper.MapEnumerable(results); } - private bool BuildQuery(StringBuilder sb, string query, string searchFrom, string[] fields, string type) + private bool BuildQuery(StringBuilder sb, string query, string searchFrom, List fields, string type) { //build a lucene query: // the nodeName will be boosted 10x without wildcards @@ -234,11 +235,26 @@ namespace Umbraco.Web.Search foreach (var f in fields) { + var queryWordsReplaced = new string[querywords.Length]; + + // when searching file names containing hyphens we need to replace the hyphens with spaces + if (f.Equals(UmbracoExamineIndex.UmbracoFileFieldName)) + { + for (var index = 0; index < querywords.Length; index++) + { + queryWordsReplaced[index] = querywords[index].Replace("\\-", " ").Replace("_", " ").Trim(" "); + } + } + else + { + queryWordsReplaced = querywords; + } + //additional fields normally sb.Append(f); sb.Append(":"); sb.Append("("); - foreach (var w in querywords) + foreach (var w in queryWordsReplaced) { sb.Append(w.ToLower()); sb.Append("* "); diff --git a/src/Umbraco.Web/Security/WebSecurity.cs b/src/Umbraco.Web/Security/WebSecurity.cs index 6b66becedb..256238ae9b 100644 --- a/src/Umbraco.Web/Security/WebSecurity.cs +++ b/src/Umbraco.Web/Security/WebSecurity.cs @@ -209,7 +209,7 @@ namespace Umbraco.Web.Security private static bool RequestIsInUmbracoApplication(HttpContextBase context) { - return context.Request.Path.ToLower().IndexOf(Current.IOHelper.ResolveUrl(SystemDirectories.Umbraco).ToLower(), StringComparison.Ordinal) > -1; + return context.Request.Path.ToLower().IndexOf(Current.IOHelper.ResolveUrl(Current.Configs.Global().UmbracoPath).ToLower(), StringComparison.Ordinal) > -1; } /// diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 79b0fe8744..b5478d4d38 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -41,7 +41,6 @@ - @@ -61,9 +60,9 @@ - + - + 2.7.0.100 @@ -1284,4 +1283,4 @@ - \ No newline at end of file + diff --git a/src/Umbraco.Web/UmbracoInjectedModule.cs b/src/Umbraco.Web/UmbracoInjectedModule.cs index 6dc41d39ee..d8e0729552 100644 --- a/src/Umbraco.Web/UmbracoInjectedModule.cs +++ b/src/Umbraco.Web/UmbracoInjectedModule.cs @@ -180,7 +180,7 @@ namespace Umbraco.Web return Attempt.If(reason == EnsureRoutableOutcome.IsRoutable, reason); } - + private bool EnsureRuntime(HttpContextBase httpContext, Uri uri) { @@ -205,7 +205,7 @@ namespace Umbraco.Web case RuntimeLevel.Upgrade: // redirect to install ReportRuntime(level, "Umbraco must install or upgrade."); - var installPath = UriUtility.ToAbsolute(SystemDirectories.Install); + var installPath = UriUtility.ToAbsolute(Constants.SystemDirectories.Install); var installUrl = $"{installPath}/?redir=true&url={HttpUtility.UrlEncode(uri.ToString())}"; httpContext.Response.Redirect(installUrl, true); return false; // cannot serve content @@ -436,6 +436,6 @@ namespace Umbraco.Web #endregion - + } } diff --git a/src/Umbraco.Web/WebApi/Filters/CheckIfUserTicketDataIsStaleAttribute.cs b/src/Umbraco.Web/WebApi/Filters/CheckIfUserTicketDataIsStaleAttribute.cs index 2a57ec10b2..c3070fcf53 100644 --- a/src/Umbraco.Web/WebApi/Filters/CheckIfUserTicketDataIsStaleAttribute.cs +++ b/src/Umbraco.Web/WebApi/Filters/CheckIfUserTicketDataIsStaleAttribute.cs @@ -11,7 +11,7 @@ using Umbraco.Core.Models.Membership; using Umbraco.Core.Security; using Umbraco.Web.Security; using Umbraco.Core.Mapping; -using UserExtensions = Umbraco.Core.Models.UserExtensions; +using Umbraco.Core.Models; namespace Umbraco.Web.WebApi.Filters { @@ -78,19 +78,19 @@ namespace Umbraco.Web.WebApi.Filters () => user.Username != identity.Username, () => { - var culture = UserExtensions.GetUserCulture(user, Current.Services.TextService, Current.Configs.Global()); + var culture = user.GetUserCulture(Current.Services.TextService, Current.Configs.Global()); return culture != null && culture.ToString() != identity.Culture; }, () => user.AllowedSections.UnsortedSequenceEqual(identity.AllowedApplications) == false, () => user.Groups.Select(x => x.Alias).UnsortedSequenceEqual(identity.Roles) == false, () => { - var startContentIds = UserExtensions.CalculateContentStartNodeIds(user, Current.Services.EntityService); + var startContentIds = user.CalculateContentStartNodeIds(Current.Services.EntityService); return startContentIds.UnsortedSequenceEqual(identity.StartContentNodes) == false; }, () => { - var startMediaIds = UserExtensions.CalculateMediaStartNodeIds(user, Current.Services.EntityService); + var startMediaIds = user.CalculateMediaStartNodeIds(Current.Services.EntityService); return startMediaIds.UnsortedSequenceEqual(identity.StartMediaNodes) == false; } };