Merge branch 'temp8' into temp8-fixme-get-all-entities-with-postfilter

# Conflicts:
#	src/Umbraco.Web/Editors/EntityController.cs
This commit is contained in:
Shannon
2019-01-30 20:09:07 +11:00
958 changed files with 5274 additions and 12481 deletions
+1
View File
@@ -35,6 +35,7 @@
<dependency id="Serilog.Enrichers.Thread" version="[3.0.0,3.999999)" />
<dependency id="Serilog.Filters.Expressions" version="[2.0.0,2.999999)" />
<dependency id="Serilog.Formatting.Compact" version="[1.0.0,1.999999)" />
<dependency id="Serilog.Formatting.Compact.Reader" version="[1.0.2,1.999999)" />
<dependency id="Serilog.Settings.AppSettings" version="[2.2.2,2.999999)" />
<dependency id="Serilog.Sinks.File" version="[4.0.0,4.999999)" />
<dependency id="Umbraco.SqlServerCE" version="[4.0.0.1,4.999999)" />
+2 -4
View File
@@ -22,7 +22,7 @@
not want this to happen as the alpha of the next major is, really, the next major already.
-->
<dependency id="Microsoft.AspNet.SignalR.Core" version="[2.2.3, 2.999999)" />
<dependency id="Umbraco.ModelsBuilder.Ui" version="[8.0.0-alpha.33]" />
<dependency id="Umbraco.ModelsBuilder.Ui" version="[8.0.0-alpha.34]" />
<dependency id="ImageProcessor.Web" version="[4.9.3.25,4.999999)" />
<dependency id="ImageProcessor.Web.Config" version="[2.4.1.19,2.999999)" />
<dependency id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="[2.0.1,2.999999)" />
@@ -33,7 +33,6 @@
<!-- files -->
<file src="$BuildTmp$\Configs\**" target="Content\Config" exclude="$BuildTmp$\Configs\Web.config.transform" />
<file src="$BuildTmp$\WebApp\Views\**" target="Content\Views" exclude="$BuildTmp$\WebApp\Views\Web.config" />
<file src="$BuildTmp$\WebApp\default.aspx" target="Content\default.aspx" />
<file src="$BuildTmp$\WebApp\Global.asax" target="Content\Global.asax" />
<file src="$BuildTmp$\WebApp\config\BackOfficeTours\**" target="Content\Config\BackOfficeTours" />
<file src="$BuildTmp$\WebApp\Media\Web.config" target="Content\Media\Web.config" />
@@ -53,9 +52,8 @@
<!-- beware! config transforms not supported by PackageReference -->
<file src="tools\Web.config.install.xdt" target="Content\Web.config.install.xdt" />
<file src="tools\ClientDependency.config.install.xdt" target="Content\config\ClientDependency.config.install.xdt" />
<file src="tools\Dashboard.config.install.xdt" target="Content\config\Dashboard.config.install.xdt" />
<file src="tools\umbracoSettings.config.install.xdt" target="Content\config\umbracoSettings.config.install.xdt" />
<file src="tools\Views.Web.config.install.xdt" target="Views\Web.config.install.xdt" /> <!-- FIXME Content\ !! and then... transform?! -->
<file src="tools\Views.Web.config.install.xdt" target="Views\Web.config.install.xdt" /> <!-- FIXME: Content\ !! and then... transform?! -->
<!-- UmbracoCms props and targets -->
<file src="build\**" target="build" />
@@ -1,95 +0,0 @@
<?xml version="1.0"?>
<dashBoard xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<section alias="StartupSettingsDashboardSection" xdt:Locator="Match(alias)" xdt:Transform="InsertIfMissing">
<tab caption="Get Started" xdt:Locator="Match(caption)" xdt:Transform="Remove" />
<tab caption="Welcome" xdt:Locator="Match(caption)" xdt:Transform="InsertIfMissing">
<control panelCaption="" xdt:Transform="InsertIfMissing">
views/dashboard/settings/settingsdashboardintro.html
</control>
</tab>
</section>
<section alias="StartupFormsDashboardSection" xdt:Locator="Match(alias)" xdt:Transform="InsertIfMissing">
<areas>
<area>forms</area>
</areas>
<tab caption="Install Umbraco Forms">
<control panelCaption="">
views/dashboard/forms/formsdashboardintro.html
</control>
</tab>
</section>
<section alias="StartupDeveloperDashboardSection" xdt:Locator="Match(alias)" xdt:Transform="InsertIfMissing">
<areas xdt:Transform="InsertIfMissing">
<area xdt:Transform="InsertIfMissing">developer</area>
</areas>
</section>
<section alias="StartupDeveloperDashboardSection">
<tab caption="Get Started" xdt:Locator="Match(caption)" xdt:Transform="Replace">
<control panelCaption="">
views/dashboard/developer/developerdashboardvideos.html
</control>
</tab>
<tab caption="Examine Management" xdt:Locator="Match(caption)" xdt:Transform="Remove" />
</section>
<section alias="StartupDeveloperDashboardSection" xdt:Locator="Match(alias)" xdt:Transform="InsertIfMissing">
<tab caption="Examine Management" xdt:Locator="Match(caption)" xdt:Transform="InsertIfMissing">
<control>
views/dashboard/developer/examinemanagement.html
</control>
</tab>
</section>
<section alias="StartupMediaDashboardSection" xdt:Locator="Match(alias)" xdt:Transform="InsertIfMissing">
<tab caption="Get Started" xdt:Locator="Match(caption)" xdt:Transform="Remove" />
<tab caption="Content" xdt:Locator="Match(caption)" xdt:Transform="InsertIfMissing" />
<tab caption="Content" xdt:Locator="Match(caption)" xdt:Transform="Replace">
<control panelCaption="">
views/dashboard/media/mediafolderbrowser.html
</control>
</tab>
</section>
<section alias="StartupMemberDashboardSection" xdt:Locator="Match(alias)" xdt:Transform="InsertIfMissing">
<tab caption="Get Started" xdt:Locator="Match(caption)" xdt:Transform="Remove" />
<tab caption="Get Started" xdt:Transform="Insert">
<control panelCaption="">
views/dashboard/members/membersdashboardvideos.html
</control>
</tab>
</section>
<section alias="uGoLiveDashboardSection" xdt:Locator="Match(alias)" xdt:Transform="Remove" />
<section alias="ExamineManagement" xdt:Locator="Match(alias)" xdt:Transform="Remove" />
<section alias="StartupDashboardSection">
<tab caption="Change Password" xdt:Locator="Match(caption)" xdt:Transform="Remove" />
<tab caption="Last Edits" xdt:Locator="Match(caption)" xdt:Transform="Remove" />
</section>
<section alias="RedirectUrlManagement" xdt:Locator="Match(alias)" xdt:Transform="InsertIfMissing">
<areas>
<area>content</area>
</areas>
<tab caption="Redirect URL Management">
<control>
views/dashboard/developer/redirecturls.html
</control>
</tab>
</section>
<section alias="UmbracoHealthCheck" xdt:Locator="Match(alias)" xdt:Transform="InsertIfMissing">
<areas>
<area>developer</area>
</areas>
<tab caption="Health Check">
<control>
views/dashboard/developer/healthcheck.html
</control>
</tab>
</section>
</dashBoard>
@@ -2,7 +2,6 @@
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<configSections xdt:Transform="InsertIfMissing" />
<configSections>
<section name="FileSystemProviders" xdt:Locator="Match(name)" xdt:Transform="Remove" />
<section name="ExamineLuceneIndexSets" type="Umbraco.Examine.Config.IndexSets, Umbraco.Examine" requirePermission="false" xdt:Locator="Match(name)" xdt:Transform="SetAttributes(type,requirePermission)" />
<sectionGroup name="applicationSettings" xdt:Locator="Match(name)">
@@ -11,7 +10,6 @@
<sectionGroup name="system.web.webPages.razor" xdt:Locator="Match(name)" xdt:Transform="Remove" />
<sectionGroup name="umbracoConfiguration" xdt:Locator="Match(name)" xdt:Transform="InsertIfMissing">
<section name="settings" type="Umbraco.Core.Configuration.UmbracoSettings.UmbracoSettingsSection, Umbraco.Core" requirePermission="false" xdt:Locator="Match(name)" xdt:Transform="InsertIfMissing" />
<section name="FileSystemProviders" type="Umbraco.Core.Configuration.FileSystemProvidersSection, Umbraco.Core" requirePermission="false" xdt:Locator="Match(name)" xdt:Transform="InsertIfMissing" />
<section name="dashBoard" type="Umbraco.Core.Configuration.Dashboard.DashboardSection, Umbraco.Core" requirePermission="false" xdt:Locator="Match(name)" xdt:Transform="InsertIfMissing" />
<section name="HealthChecks" type="Umbraco.Core.Configuration.HealthChecks.HealthChecksSection, Umbraco.Core" requirePermission="false" xdt:Locator="Match(name)" xdt:Transform="InsertIfMissing" />
</sectionGroup>
@@ -27,13 +25,10 @@
<umbracoConfiguration xdt:Transform="InsertIfMissing">
<settings configSource="config\umbracoSettings.config" xdt:Locator="Match(configSource)" xdt:Transform="InsertIfMissing" />
<FileSystemProviders configSource="config\FileSystemProviders.config" xdt:Locator="Match(configSource)" xdt:Transform="InsertIfMissing" />
<dashBoard configSource="config\Dashboard.config" xdt:Locator="Match(configSource)" xdt:Transform="InsertIfMissing" />
<HealthChecks configSource="config\HealthChecks.config" xdt:Locator="Match(configSource)" xdt:Transform="InsertIfMissing" />
</umbracoConfiguration>
<FileSystemProviders xdt:Transform="Remove" />
<system.data xdt:Transform="InsertIfMissing">
<DbProviderFactories xdt:Transform="InsertIfMissing">
<remove invariant="System.Data.SqlServerCe.4.0" xdt:Locator="Match(invariant)" xdt:Transform="InsertIfMissing" />
+2 -2
View File
@@ -120,7 +120,7 @@
} finally {
Pop-Location
# fixme - should we filter the log to find errors?
# FIXME: should we filter the log to find errors?
#get-content .\build.tmp\belle.log | %{ if ($_ -match "build") { write $_}}
# restore
@@ -177,7 +177,7 @@
{
Write-Host "Prepare Tests"
# fixme - idea is to avoid rebuilding everything for tests
# FIXME: - idea is to avoid rebuilding everything for tests
# but because of our weird assembly versioning (with .* stuff)
# everything gets rebuilt all the time...
#Copy-Files "$tmp\bin" "." "$tmp\tests"
+1 -1
View File
@@ -7,7 +7,7 @@
{
public const string ApplicationsCacheKey = "ApplicationCache"; // used by SectionService
// TODO this one can probably be removed
// TODO: this one can probably be removed
public const string TemplateFrontEndCacheKey = "template";
public const string MacroContentCacheKey = "macroContent_"; // used in MacroRenderers
@@ -31,7 +31,7 @@ namespace Umbraco.Core.Cache
/// </summary>
/// <remarks>
/// <para>Will use HttpContext.Current.</para>
/// fixme/task: use IHttpContextAccessor NOT HttpContext.Current
/// TODO: https://github.com/umbraco/Umbraco-CMS/issues/4239 - use IHttpContextAccessor NOT HttpContext.Current
/// </remarks>
public HttpRequestAppCache()
{ }
@@ -9,7 +9,8 @@ using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Strings;
using Umbraco.Core.Sync;
using Umbraco.Core._Legacy.PackageActions;
using Umbraco.Core.Logging.Viewer;
using Umbraco.Core.PackageActions;
namespace Umbraco.Core.Components
{
@@ -297,6 +298,37 @@ namespace Umbraco.Core.Components
public static void SetMediaFileSystem(this Composition composition, Func<IFileSystem> filesystemFactory)
=> composition.RegisterUniqueFor<IFileSystem, IMediaFileSystem>(_ => filesystemFactory());
/// <summary>
/// Sets the log viewer.
/// </summary>
/// <typeparam name="T">The type of the log viewer.</typeparam>
/// <param name="composition">The composition.</param>
public static void SetLogViewer<T>(this Composition composition)
where T : ILogViewer
{
composition.RegisterUnique<ILogViewer, T>();
}
/// <summary>
/// Sets the log viewer.
/// </summary>
/// <param name="composition">The composition.</param>
/// <param name="factory">A function creating a log viewer.</param>
public static void SetLogViewer(this Composition composition, Func<IFactory, ILogViewer> factory)
{
composition.RegisterUnique(factory);
}
/// <summary>
/// Sets the log viewer.
/// </summary>
/// <param name="composition">A composition.</param>
/// <param name="helper">A log viewer.</param>
public static void SetLogViewer(this Composition composition, ILogViewer viewer)
{
composition.RegisterUnique(_ => viewer);
}
#endregion
}
}
@@ -5,7 +5,7 @@ using Umbraco.Core.Services.Implement;
namespace Umbraco.Core.Components
{
//TODO: This should just exist in the content service/repo!
// TODO: This should just exist in the content service/repo!
public sealed class RelateOnCopyComponent : IComponent
{
public void Initialize()
+1 -1
View File
@@ -5,6 +5,7 @@ using Umbraco.Core.Dictionary;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PackageActions;
using Umbraco.Core.Packaging;
using Umbraco.Core.Persistence;
using Umbraco.Core.PropertyEditors;
@@ -12,7 +13,6 @@ using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
using Umbraco.Core.Strings;
using Umbraco.Core.Sync;
using Umbraco.Core._Legacy.PackageActions;
namespace Umbraco.Core.Composing
{
+1 -1
View File
@@ -15,7 +15,7 @@
/// <summary>
/// One unique instance per request.
/// </summary>
// TODO - review lifetimes for LightInject vs other containers
// TODO: review lifetimes for LightInject vs other containers
// currently, corresponds to 'Request' in LightInject which is 'Transient + disposed by Scope'
// but NOT (in LightInject) a per-web-request lifetime, more a TransientScoped
//
+1 -1
View File
@@ -614,7 +614,7 @@ namespace Umbraco.Core.Composing
var type = BuildManager.GetType(typeName, false);
if (type != null) return type;
//TODO: This isn't very elegant, and will have issues since the AppDomain.CurrentDomain
// TODO: This isn't very elegant, and will have issues since the AppDomain.CurrentDomain
// doesn't actualy load in all assemblies, only the types that have been referenced so far.
// However, in a web context, the BuildManager will have executed which will force all assemblies
// to be loaded so it's fine for now.
+1 -1
View File
@@ -278,7 +278,7 @@ namespace Umbraco.Core.Composing
#region Match Type
//TODO: Need to determine if these methods should replace/combine/merge etc with IsTypeAssignableFrom, IsAssignableFromGeneric
// TODO: Need to determine if these methods should replace/combine/merge etc with IsTypeAssignableFrom, IsAssignableFromGeneric
// readings:
// http://stackoverflow.com/questions/2033912/c-sharp-variance-problem-assigning-listderived-as-listbase
@@ -2,10 +2,10 @@
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Cache;
using Umbraco.Core.PackageActions;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core._Legacy.PackageActions;
namespace Umbraco.Core.Composing
{
@@ -114,7 +114,7 @@ namespace Umbraco.Core.Composing
return list;
}
protected virtual int DefaultWeight { get; set; } = 10;
public virtual int DefaultWeight { get; set; } = 100;
protected virtual int GetWeight(Type type)
{
-5
View File
@@ -2,7 +2,6 @@
using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.Dashboard;
using Umbraco.Core.Configuration.Grid;
using Umbraco.Core.Configuration.HealthChecks;
using Umbraco.Core.Configuration.UmbracoSettings;
@@ -22,9 +21,6 @@ namespace Umbraco.Core
public static IUmbracoSettingsSection Settings(this Configs configs)
=> configs.GetConfig<IUmbracoSettingsSection>();
public static IDashboardSection Dashboards(this Configs configs)
=> configs.GetConfig<IDashboardSection>();
public static IHealthChecks HealthChecks(this Configs configs)
=> configs.GetConfig<IHealthChecks>();
@@ -40,7 +36,6 @@ namespace Umbraco.Core
configs.Add<IGlobalSettings>(() => new GlobalSettings());
configs.Add<IUmbracoSettingsSection>("umbracoConfiguration/settings");
configs.Add<IDashboardSection>("umbracoConfiguration/dashBoard");
configs.Add<IHealthChecks>("umbracoConfiguration/HealthChecks");
configs.Add(() => new CoreDebug());
@@ -1,30 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace Umbraco.Core.Configuration.Dashboard
{
internal class AccessElement : RawXmlConfigurationElement, IAccess
{
public AccessElement()
{ }
public AccessElement(XElement rawXml)
: base(rawXml)
{ }
public IEnumerable<IAccessRule> Rules
{
get
{
var result = new List<AccessRule>();
if (RawXml == null) return result;
result.AddRange(RawXml.Elements("deny").Select(x => new AccessRule {Type = AccessRuleType.Deny, Value = x.Value }));
result.AddRange(RawXml.Elements("grant").Select(x => new AccessRule { Type = AccessRuleType.Grant, Value = x.Value }));
result.AddRange(RawXml.Elements("grantBySection").Select(x => new AccessRule { Type = AccessRuleType.GrantBySection, Value = x.Value }));
return result;
}
}
}
}
@@ -1,32 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
namespace Umbraco.Core.Configuration.Dashboard
{
internal class AreaCollection : ConfigurationElementCollection, IEnumerable<IArea>
{
protected override ConfigurationElement CreateNewElement()
{
return new AreaElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((AreaElement) element).Value;
}
IEnumerator<IArea> IEnumerable<IArea>.GetEnumerator()
{
for (var i = 0; i < Count; i++)
{
yield return BaseGet(i) as IArea;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
@@ -1,12 +0,0 @@
using System.Configuration;
namespace Umbraco.Core.Configuration.Dashboard
{
internal class AreaElement : InnerTextConfigurationElement<string>, IArea
{
string IArea.AreaName
{
get { return Value; }
}
}
}
@@ -1,15 +0,0 @@
using System.Configuration;
namespace Umbraco.Core.Configuration.Dashboard
{
internal class AreasElement : ConfigurationElement
{
[ConfigurationCollection(typeof(SectionCollection), AddItemName = "area")]
[ConfigurationProperty("", IsDefaultCollection = true)]
public AreaCollection AreaCollection
{
get { return (AreaCollection)base[""]; }
set { base[""] = value; }
}
}
}
@@ -1,37 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
namespace Umbraco.Core.Configuration.Dashboard
{
internal class ControlCollection : ConfigurationElementCollection, IEnumerable<IDashboardControl>
{
internal void Add(ControlElement c)
{
BaseAdd(c);
}
protected override ConfigurationElement CreateNewElement()
{
return new ControlElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((ControlElement)element).ControlPath;
}
IEnumerator<IDashboardControl> IEnumerable<IDashboardControl>.GetEnumerator()
{
for (var i = 0; i < Count; i++)
{
yield return BaseGet(i) as IDashboardControl;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
@@ -1,44 +0,0 @@
using System.Configuration;
using System.Linq;
using System.Xml.Linq;
namespace Umbraco.Core.Configuration.Dashboard
{
internal class ControlElement : RawXmlConfigurationElement, IDashboardControl
{
public string PanelCaption
{
get
{
var panelCaption = RawXml.Attribute("panelCaption");
return panelCaption == null ? "" : panelCaption.Value;
}
}
public AccessElement Access
{
get
{
var access = RawXml.Element("access");
return access == null ? new AccessElement() : new AccessElement(access);
}
}
public string ControlPath
{
get
{
//we need to return the first (and only) text element of the children (wtf... who designed this configuration ! :P )
var txt = RawXml.Nodes().OfType<XText>().FirstOrDefault();
if (txt == null)
{
throw new ConfigurationErrorsException("The control element must contain a text node indicating the control path");
}
return txt.Value.Trim();
}
}
IAccess IDashboardControl.AccessRights => Access;
}
}
@@ -1,24 +0,0 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Text;
using System.Threading.Tasks;
namespace Umbraco.Core.Configuration.Dashboard
{
internal class DashboardSection : ConfigurationSection, IDashboardSection
{
[ConfigurationCollection(typeof(SectionCollection), AddItemName = "section")]
[ConfigurationProperty("", IsDefaultCollection = true)]
public SectionCollection SectionCollection
{
get { return (SectionCollection)base[""]; }
set { base[""] = value; }
}
IEnumerable<ISection> IDashboardSection.Sections
{
get { return SectionCollection; }
}
}
}
@@ -1,9 +0,0 @@
using System.Collections.Generic;
namespace Umbraco.Core.Configuration.Dashboard
{
public interface IAccess
{
IEnumerable<IAccessRule> Rules { get; }
}
}
@@ -1,7 +0,0 @@
namespace Umbraco.Core.Configuration.Dashboard
{
public interface IArea
{
string AreaName { get; }
}
}
@@ -1,11 +0,0 @@
namespace Umbraco.Core.Configuration.Dashboard
{
public interface IDashboardControl
{
string PanelCaption { get; }
string ControlPath { get; }
IAccess AccessRights { get; }
}
}
@@ -1,9 +0,0 @@
using System.Collections.Generic;
namespace Umbraco.Core.Configuration.Dashboard
{
public interface IDashboardSection
{
IEnumerable<ISection> Sections { get; }
}
}
@@ -1,13 +0,0 @@
using System.Collections.Generic;
namespace Umbraco.Core.Configuration.Dashboard
{
public interface IDashboardTab
{
string Caption { get; }
IEnumerable<IDashboardControl> Controls { get; }
IAccess AccessRights { get; }
}
}
@@ -1,15 +0,0 @@
using System.Collections.Generic;
namespace Umbraco.Core.Configuration.Dashboard
{
public interface ISection
{
string Alias { get; }
IEnumerable<string> Areas { get; }
IEnumerable<IDashboardTab> Tabs { get; }
IAccess AccessRights { get; }
}
}
@@ -1,37 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
namespace Umbraco.Core.Configuration.Dashboard
{
internal class SectionCollection : ConfigurationElementCollection, IEnumerable<ISection>
{
internal void Add(SectionElement c)
{
BaseAdd(c);
}
protected override ConfigurationElement CreateNewElement()
{
return new SectionElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((SectionElement)element).Alias;
}
IEnumerator<ISection> IEnumerable<ISection>.GetEnumerator()
{
for (var i = 0; i < Count; i++)
{
yield return BaseGet(i) as ISection;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
@@ -1,50 +0,0 @@
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
namespace Umbraco.Core.Configuration.Dashboard
{
internal class SectionElement : ConfigurationElement, ISection
{
[ConfigurationProperty("alias", IsRequired = true)]
public string Alias
{
get { return (string) this["alias"]; }
}
[ConfigurationProperty("areas", IsRequired = true)]
public AreasElement Areas
{
get { return (AreasElement)this["areas"]; }
}
[ConfigurationProperty("access")]
public AccessElement Access
{
get { return (AccessElement)this["access"]; }
}
[ConfigurationCollection(typeof(SectionCollection), AddItemName = "tab")]
[ConfigurationProperty("", IsDefaultCollection = true)]
public TabCollection TabCollection
{
get { return (TabCollection)base[""]; }
set { base[""] = value; }
}
IEnumerable<IDashboardTab> ISection.Tabs
{
get { return TabCollection; }
}
IEnumerable<string> ISection.Areas
{
get { return Areas.AreaCollection.Cast<AreaElement>().Select(x => x.Value); }
}
IAccess ISection.AccessRights
{
get { return Access; }
}
}
}
@@ -1,37 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
namespace Umbraco.Core.Configuration.Dashboard
{
internal class TabCollection : ConfigurationElementCollection, IEnumerable<IDashboardTab>
{
internal void Add(TabElement c)
{
BaseAdd(c);
}
protected override ConfigurationElement CreateNewElement()
{
return new TabElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((TabElement)element).Caption;
}
IEnumerator<IDashboardTab> IEnumerable<IDashboardTab>.GetEnumerator()
{
for (var i = 0; i < Count; i++)
{
yield return BaseGet(i) as IDashboardTab;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
@@ -1,38 +0,0 @@
using System.Collections.Generic;
using System.Configuration;
namespace Umbraco.Core.Configuration.Dashboard
{
internal class TabElement : ConfigurationElement, IDashboardTab
{
[ConfigurationProperty("caption", IsRequired = true)]
public string Caption
{
get { return (string)this["caption"]; }
}
[ConfigurationProperty("access")]
public AccessElement Access
{
get { return (AccessElement)this["access"]; }
}
[ConfigurationCollection(typeof(ControlCollection), AddItemName = "control")]
[ConfigurationProperty("", IsDefaultCollection = true)]
public ControlCollection ControlCollection
{
get { return (ControlCollection)base[""]; }
set { base[""] = value; }
}
IEnumerable<IDashboardControl> IDashboardTab.Controls
{
get { return ControlCollection; }
}
IAccess IDashboardTab.AccessRights
{
get { return Access; }
}
}
}
@@ -1,67 +0,0 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
namespace Umbraco.Core.Configuration
{
public class FileSystemProviderElement : ConfigurationElement, IFileSystemProviderElement
{
private const string ALIAS_KEY = "alias";
private const string TYPE_KEY = "type";
private const string PARAMETERS_KEY = "Parameters";
[ConfigurationProperty(ALIAS_KEY, IsKey = true, IsRequired = true)]
public string Alias
{
get
{
return ((string)(base[ALIAS_KEY]));
}
}
[ConfigurationProperty(TYPE_KEY, IsKey = false, IsRequired = true)]
public string Type
{
get
{
return ((string)(base[TYPE_KEY]));
}
}
[ConfigurationProperty(PARAMETERS_KEY, IsDefaultCollection = true, IsRequired = false)]
public KeyValueConfigurationCollection Parameters
{
get
{
return ((KeyValueConfigurationCollection)(base[PARAMETERS_KEY]));
}
}
string IFileSystemProviderElement.Alias
{
get { return Alias; }
}
string IFileSystemProviderElement.Type
{
get { return Type; }
}
private IDictionary<string, string> _params;
IDictionary<string, string> IFileSystemProviderElement.Parameters
{
get
{
if (_params != null) return _params;
_params = new Dictionary<string, string>();
foreach (KeyValueConfigurationElement element in Parameters)
{
_params.Add(element.Key, element.Value);
}
return _params;
}
}
}
}
@@ -1,43 +0,0 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
namespace Umbraco.Core.Configuration
{
[ConfigurationCollection(typeof(FileSystemProviderElement), AddItemName = "Provider")]
public class FileSystemProviderElementCollection : ConfigurationElementCollection, IEnumerable<IFileSystemProviderElement>
{
protected override ConfigurationElement CreateNewElement()
{
return new FileSystemProviderElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((FileSystemProviderElement)(element)).Alias;
}
public new FileSystemProviderElement this[string key]
{
get
{
return (FileSystemProviderElement)BaseGet(key);
}
}
IEnumerator<IFileSystemProviderElement> IEnumerable<IFileSystemProviderElement>.GetEnumerator()
{
for (var i = 0; i < Count; i++)
{
yield return BaseGet(i) as IFileSystemProviderElement;
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
@@ -1,30 +0,0 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
namespace Umbraco.Core.Configuration
{
public class FileSystemProvidersSection : ConfigurationSection, IFileSystemProvidersSection
{
[ConfigurationProperty("", IsDefaultCollection = true, IsRequired = true)]
public FileSystemProviderElementCollection Providers
{
get { return ((FileSystemProviderElementCollection)(base[""])); }
}
private IDictionary<string, IFileSystemProviderElement> _providers;
IDictionary<string, IFileSystemProviderElement> IFileSystemProvidersSection.Providers
{
get
{
if (_providers != null) return _providers;
_providers = Providers.ToDictionary(x => x.Alias, x => x);
return _providers;
}
}
}
}
@@ -31,8 +31,8 @@ namespace Umbraco.Core.Configuration
private static string _reservedPaths;
private static string _reservedUrls;
//ensure the built on (non-changeable) reserved paths are there at all times
internal const string StaticReservedPaths = "~/app_plugins/,~/install/,";
internal const string StaticReservedUrls = "~/config/splashes/booting.aspx,~/config/splashes/noNodes.aspx,~/VSEnterpriseHelper.axd,";
internal const string StaticReservedPaths = "~/app_plugins/,~/install/,"; //must end with a comma!
internal const string StaticReservedUrls = "~/config/splashes/noNodes.aspx,~/.well-known,"; //must end with a comma!
#endregion
/// <summary>
@@ -82,19 +82,18 @@ namespace Umbraco.Core.Configuration
public string ReservedUrls
{
get
{
if (_reservedUrls == null)
{
var urls = ConfigurationManager.AppSettings.ContainsKey("umbracoReservedUrls")
? ConfigurationManager.AppSettings["umbracoReservedUrls"]
: string.Empty;
{
if (_reservedUrls != null) return _reservedUrls;
//ensure the built on (non-changeable) reserved paths are there at all times
_reservedUrls = StaticReservedUrls + urls;
}
var urls = ConfigurationManager.AppSettings.ContainsKey("umbracoReservedUrls")
? ConfigurationManager.AppSettings["umbracoReservedUrls"]
: string.Empty;
//ensure the built on (non-changeable) reserved paths are there at all times
_reservedUrls = StaticReservedUrls + urls;
return _reservedUrls;
}
internal set { _reservedUrls = value; }
internal set => _reservedUrls = value;
}
/// <summary>
@@ -105,22 +104,20 @@ namespace Umbraco.Core.Configuration
{
get
{
if (_reservedPaths == null)
{
var reservedPaths = StaticReservedPaths;
//always add the umbraco path to the list
if (ConfigurationManager.AppSettings.ContainsKey("umbracoPath")
&& !ConfigurationManager.AppSettings["umbracoPath"].IsNullOrWhiteSpace())
{
reservedPaths += ConfigurationManager.AppSettings["umbracoPath"].EnsureEndsWith(',');
}
if (_reservedPaths != null) return _reservedPaths;
var allPaths = ConfigurationManager.AppSettings.ContainsKey("umbracoReservedPaths")
? ConfigurationManager.AppSettings["umbracoReservedPaths"]
: string.Empty;
var reservedPaths = StaticReservedPaths;
var umbPath = ConfigurationManager.AppSettings.ContainsKey("umbracoPath") && !ConfigurationManager.AppSettings["umbracoPath"].IsNullOrWhiteSpace()
? ConfigurationManager.AppSettings["umbracoPath"]
: "~/umbraco";
//always add the umbraco path to the list
reservedPaths += umbPath.EnsureEndsWith(',');
_reservedPaths = reservedPaths + allPaths;
}
var allPaths = ConfigurationManager.AppSettings.ContainsKey("umbracoReservedPaths")
? ConfigurationManager.AppSettings["umbracoReservedPaths"]
: string.Empty;
_reservedPaths = reservedPaths + allPaths;
return _reservedPaths;
}
}
@@ -260,26 +257,7 @@ namespace Umbraco.Core.Configuration
}
}
}
/// <summary>
/// Gets a value indicating whether umbraco uses directory urls.
/// </summary>
/// <value><c>true</c> if umbraco uses directory urls; otherwise, <c>false</c>.</value>
public bool UseDirectoryUrls
{
get
{
try
{
return bool.Parse(ConfigurationManager.AppSettings["umbracoUseDirectoryUrls"]);
}
catch
{
return false;
}
}
}
/// <summary>
/// Returns the number of days that should take place between version checks.
/// </summary>
@@ -31,7 +31,7 @@ namespace Umbraco.Core.Configuration.Grid
{
List<GridEditor> GetResult()
{
// TODO should use the common one somehow! + ignoring _appPlugins here!
// TODO: should use the common one somehow! + ignoring _appPlugins here!
var parser = new ManifestParser(_appCaches, Current.ManifestValidators, _logger);
var editors = new List<GridEditor>();
@@ -1,11 +0,0 @@
using System.Collections.Generic;
namespace Umbraco.Core.Configuration
{
public interface IFileSystemProviderElement
{
string Alias { get; }
string Type { get; }
IDictionary<string, string> Parameters { get; }
}
}
@@ -1,9 +0,0 @@
using System.Collections.Generic;
namespace Umbraco.Core.Configuration
{
public interface IFileSystemProvidersSection
{
IDictionary<string, IFileSystemProviderElement> Providers { get; }
}
}
@@ -34,12 +34,6 @@ namespace Umbraco.Core.Configuration
/// </summary>
int TimeOutInMinutes { get; }
/// <summary>
/// Gets a value indicating whether umbraco uses directory urls.
/// </summary>
/// <value><c>true</c> if umbraco uses directory urls; otherwise, <c>false</c>.</value>
bool UseDirectoryUrls { get; }
/// <summary>
/// Gets the default UI language.
/// </summary>
@@ -40,9 +40,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
[ConfigurationProperty("XmlContentCheckForDiskChanges")]
internal InnerTextConfigurationElement<bool> XmlContentCheckForDiskChanges => GetOptionalTextElement("XmlContentCheckForDiskChanges", false);
[ConfigurationProperty("EnableSplashWhileLoading")]
internal InnerTextConfigurationElement<bool> EnableSplashWhileLoading => GetOptionalTextElement("EnableSplashWhileLoading", false);
[ConfigurationProperty("PropertyContextHelpOption")]
internal InnerTextConfigurationElement<string> PropertyContextHelpOption => GetOptionalTextElement("PropertyContextHelpOption", "text");
@@ -110,8 +107,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
bool IContentSection.XmlContentCheckForDiskChanges => XmlContentCheckForDiskChanges;
bool IContentSection.EnableSplashWhileLoading => EnableSplashWhileLoading;
string IContentSection.PropertyContextHelpOption => PropertyContextHelpOption;
bool IContentSection.ForceSafeAliases => ForceSafeAliases;
@@ -35,8 +35,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
bool XmlContentCheckForDiskChanges { get; }
bool EnableSplashWhileLoading { get; }
string PropertyContextHelpOption { get; }
bool ForceSafeAliases { get; }
@@ -67,4 +65,4 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
string LoginBackgroundImage { get; }
}
}
}
@@ -5,13 +5,13 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
internal class TourConfigElement : UmbracoConfigurationElement, ITourSection
{
//disabled by default so that upgraders don't get it enabled by default
//TODO: we probably just want to disable the initial one from automatically loading ?
// TODO: we probably just want to disable the initial one from automatically loading ?
[ConfigurationProperty("enable", DefaultValue = false)]
public bool EnableTours
{
get { return (bool)this["enable"]; }
}
//TODO: We could have additional filters, etc... defined here
// TODO: We could have additional filters, etc... defined here
}
}
@@ -31,7 +31,7 @@ namespace Umbraco.Core.Configuration
/// <summary>
/// Gets the non-semantic version of the Umbraco code.
/// </summary>
// TODO rename to Version
// TODO: rename to Version
public static Version Current { get; }
/// <summary>
@@ -81,7 +81,7 @@ namespace Umbraco.Core.Configuration
{
try
{
// fixme/task - stop having version in web.config appSettings
// TODO: https://github.com/umbraco/Umbraco-CMS/issues/4238 - stop having version in web.config appSettings
var value = ConfigurationManager.AppSettings["umbracoConfigurationStatus"];
return value.IsNullOrWhiteSpace() ? null : SemVersion.TryParse(value, out var semver) ? semver : null;
}
+1 -1
View File
@@ -156,7 +156,7 @@
public const string ThirdParty = "thirdPartyGroup";
}
//TODO: Fill in the rest!
// TODO: Fill in the rest!
}
}
}
@@ -118,12 +118,7 @@ namespace Umbraco.Core
/// RadioButton list.
/// </summary>
public const string RadioButtonList = "Umbraco.RadioButtonList";
/// <summary>
/// Related Links.
/// </summary>
public const string RelatedLinks = "Umbraco.RelatedLinks";
/// <summary>
/// Slider.
/// </summary>
@@ -1,9 +1,9 @@
namespace Umbraco.Core.Configuration.Dashboard
namespace Umbraco.Core.Dashboards
{
/// <summary>
/// Implements <see cref="IAccessRule"/>.
/// </summary>
internal class AccessRule : IAccessRule
public class AccessRule : IAccessRule
{
/// <inheritdoc />
public AccessRuleType Type { get; set; }
@@ -1,4 +1,4 @@
namespace Umbraco.Core.Configuration.Dashboard
namespace Umbraco.Core.Dashboards
{
/// <summary>
/// Defines dashboard access rules type.
@@ -0,0 +1,12 @@
using System.Runtime.Serialization;
namespace Umbraco.Core.Dashboards
{
[DataContract(IsReference = true)]
public class DashboardSlim : IDashboardSlim
{
public string Alias { get; set; }
public string View { get; set; }
}
}
@@ -1,4 +1,7 @@
namespace Umbraco.Core.Configuration.Dashboard
using Newtonsoft.Json;
using Umbraco.Core.Manifest;
namespace Umbraco.Core.Dashboards
{
/// <summary>
/// Represents an access rule.
+38
View File
@@ -0,0 +1,38 @@
using System.Runtime.Serialization;
using Umbraco.Core.Composing;
namespace Umbraco.Core.Dashboards
{
/// <summary>
/// Represents a dashboard.
/// </summary>
public interface IDashboard : IDashboardSlim, IDiscoverable
{
/// <summary>
/// Gets the aliases of sections/applications where this dashboard appears.
/// </summary>
/// <remarks>
/// <para>This field is *not* needed by the UI and therefore we want to exclude
/// it from serialization, but it is deserialized as part of the manifest,
/// therefore we cannot plainly ignore it.</para>
/// <para>So, it has to remain a data member, plus we use our special
/// JsonDontSerialize attribute (see attribute for more details).</para>
/// </remarks>
[DataMember(Name = "sections")]
string[] Sections { get; }
/// <summary>
/// Gets the access rule determining the visibility of the dashboard.
/// </summary>
/// <remarks>
/// <para>This field is *not* needed by the UI and therefore we want to exclude
/// it from serialization, but it is deserialized as part of the manifest,
/// therefore we cannot plainly ignore it.</para>
/// <para>So, it has to remain a data member, plus we use our special
/// JsonDontSerialize attribute (see attribute for more details).</para>
/// </remarks>
[DataMember(Name = "access")]
IAccessRule[] AccessRules { get; }
}
}
@@ -0,0 +1,22 @@
using System.Runtime.Serialization;
namespace Umbraco.Core.Dashboards
{
/// <summary>
/// Represents a dashboard with only minimal data.
/// </summary>
public interface IDashboardSlim
{
/// <summary>
/// Gets the alias of the dashboard.
/// </summary>
[DataMember(Name = "alias")]
string Alias { get; }
/// <summary>
/// Gets the view used to render the dashboard.
/// </summary>
[DataMember(Name = "view")]
string View { get; }
}
}
@@ -0,0 +1,34 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Umbraco.Core.Models;
namespace Umbraco.Core.Deploy
{
/// <summary>
/// Defines methods that can convert data type configuration to / from an environment-agnostic string.
/// </summary>
/// <remarks>Configuration may contain values such as content identifiers, that would be local
/// to one environment, and need to be converted in order to be deployed.</remarks>
[SuppressMessage("ReSharper", "UnusedMember.Global", Justification = "This is actual only used by Deploy, but we don't want third parties to have references on deploy, that's why this interface is part of core.")]
public interface IDataTypeConfigurationConnector
{
/// <summary>
/// Gets the property editor aliases that the value converter supports by default.
/// </summary>
IEnumerable<string> PropertyEditorAliases { get; }
/// <summary>
/// Gets the artifact datatype configuration corresponding to the actual datatype configuration.
/// </summary>
/// <param name="dataType">The datatype.</param>
/// <param name="dependencies">The dependencies.</param>
string ToArtifact(IDataType dataType, ICollection<ArtifactDependency> dependencies);
/// <summary>
/// Gets the actual datatype configuration corresponding to the artifact configuration.
/// </summary>
/// <param name="dataType">The datatype.</param>
/// <param name="configuration">The artifact configuration.</param>
object FromArtifact(IDataType dataType, string configuration);
}
}
@@ -1,32 +0,0 @@
using System.Collections.Generic;
namespace Umbraco.Core.Deploy
{
/// <summary>
/// Defines methods that can convert a preValue to / from an environment-agnostic string.
/// </summary>
/// <remarks>PreValues may contain values such as content identifiers, that would be local
/// to one environment, and need to be converted in order to be deployed.</remarks>
public interface IPreValueConnector // fixme/task: rename to IDataTypeConfigurationConnector + kill all "preValues" name usage
{
/// <summary>
/// Gets the property editor aliases that the value converter supports by default.
/// </summary>
IEnumerable<string> PropertyEditorAliases { get; }
/// <summary>
/// Gets the environment-agnostic preValues corresponding to environment-specific preValues.
/// </summary>
/// <param name="preValues">The environment-specific preValues.</param>
/// <param name="dependencies">The dependencies.</param>
/// <returns></returns>
IDictionary<string, string> ConvertToDeploy(IDictionary<string, string> preValues, ICollection<ArtifactDependency> dependencies);
/// <summary>
/// Gets the environment-specific preValues corresponding to environment-agnostic preValues.
/// </summary>
/// <param name="preValues">The environment-agnostic preValues.</param>
/// <returns></returns>
IDictionary<string, string> ConvertToLocalEnvironment(IDictionary<string, string> preValues);
}
}
+1 -1
View File
@@ -17,7 +17,7 @@ namespace Umbraco.Core
/// </summary>
public class EmailSender : IEmailSender
{
//TODO: This should encapsulate a BackgroundTaskRunner with a queue to send these emails!
// TODO: This should encapsulate a BackgroundTaskRunner with a queue to send these emails!
private readonly bool _enableEvents;
+45
View File
@@ -0,0 +1,45 @@
using System;
namespace Umbraco.Core
{
/// <summary>
/// Provides extension methods to enums.
/// </summary>
public static class EnumExtensions
{
// note:
// - no need to HasFlagExact, that's basically an == test
// - HasFlagAll cannot be named HasFlag because ext. methods never take priority over instance methods
/// <summary>
/// Determines whether a flag enum has all the specified values.
/// </summary>
/// <remarks>
/// <para>True when all bits set in <paramref name="uses"/> are set in <paramref name="use"/>, though other bits may be set too.</para>
/// <para>This is the behavior of the original <see cref="Enum.HasFlag"/> method.</para>
/// </remarks>
public static bool HasFlagAll<T>(this T use, T uses)
where T : Enum
{
var num = Convert.ToUInt64(use);
var nums = Convert.ToUInt64(uses);
return (num & nums) == nums;
}
/// <summary>
/// Determines whether a flag enum has any of the specified values.
/// </summary>
/// <remarks>
/// <para>True when at least one of the bits set in <paramref name="uses"/> is set in <paramref name="use"/>.</para>
/// </remarks>
public static bool HasFlagAny<T>(this T use, T uses)
where T : Enum
{
var num = Convert.ToUInt64(use);
var nums = Convert.ToUInt64(uses);
return (num & nums) > 0;
}
}
}
@@ -27,7 +27,7 @@ namespace Umbraco.Core.Events
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
//TODO: MetaData for package metadata has no equality operators :/
// TODO: MetaData for package metadata has no equality operators :/
return base.Equals(other) && PackageMetaData.Equals(other.PackageMetaData);
}
@@ -34,7 +34,7 @@ namespace Umbraco.Core.Events
private IMediaFileSystem _mediaFileSystem;
// todo: inject
// TODO: inject
private IMediaFileSystem MediaFileSystem => _mediaFileSystem ?? (_mediaFileSystem = Current.MediaFileSystem);
}
}
+1 -1
View File
@@ -54,7 +54,7 @@ namespace Umbraco.Core.IO
return Path.GetFileName(fs.GetFullPath(path));
}
//TODO: Currently this is the only way to do this
// TODO: Currently this is the only way to do this
internal static void CreateFolder(this IFileSystem fs, string folderPath)
{
var path = fs.GetRelativePath(folderPath);
+1 -1
View File
@@ -132,7 +132,7 @@ namespace Umbraco.Core.IO
_scriptsFileSystem = new ShadowWrapper(scriptsFileSystem, "scripts", IsScoped);
_mvcViewsFileSystem = new ShadowWrapper(mvcViewsFileSystem, "Views", IsScoped);
// todo - do we need a lock here?
// TODO: do we need a lock here?
_shadowWrappers.Add(_macroPartialFileSystem);
_shadowWrappers.Add(_partialViewsFileSystem);
_shadowWrappers.Add(_stylesheetsFileSystem);
+1 -2
View File
@@ -155,8 +155,7 @@ namespace Umbraco.Core.IO
//
// except that for templates, filePath actually is a virtual path
//TODO
// what's below is dirty, there are too many ways to get the root dir, etc.
// 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);
+2 -2
View File
@@ -153,7 +153,7 @@ namespace Umbraco.Core.IO
if (directory == null) throw new InvalidOperationException("Could not get directory.");
Directory.CreateDirectory(directory); // ensure it exists
if (stream.CanSeek) // todo - what if we cannot?
if (stream.CanSeek) // TODO: what if we cannot?
stream.Seek(0, 0);
using (var destination = (Stream) File.Create(fullPath))
@@ -284,7 +284,7 @@ namespace Umbraco.Core.IO
var opath = path;
path = EnsureDirectorySeparatorChar(path);
// fixme - this part should go!
// FIXME: this part should go!
// not sure what we are doing here - so if input starts with a (back) slash,
// we assume it's not a FS relative path and we try to convert it... but it
// really makes little sense?
-3
View File
@@ -39,9 +39,6 @@ namespace Umbraco.Core.IO
[Obsolete("Usercontrols are obsolete and code should be removed")]
public static string UserControls => "~/usercontrols";
[Obsolete("Only used by legacy load balancing which is obsolete and should be removed")]
public static string WebServices => IOHelper.ReturnPath("umbracoWebservicesPath", Umbraco.EnsureEndsWith("/") + "webservices");
public static string Packages => Data + "/packages";
public static string Preview => Data + "/preview";
+1 -7
View File
@@ -7,14 +7,8 @@ namespace Umbraco.Core.IO
{
public class SystemFiles
{
public static string CreateUiXml => SystemDirectories.Umbraco + "/config/create/UI.xml";
public static string TinyMceConfig => SystemDirectories.Config + "/tinyMceConfig.config";
public static string NotFoundhandlersConfig => SystemDirectories.Config + "/404handlers.config";
public static string FeedProxyConfig => string.Concat(SystemDirectories.Config, "/feedProxy.config");
public static string GetContentCacheXml(IGlobalSettings globalSettings)
{
switch (globalSettings.LocalTempStorageLocation)
@@ -8,7 +8,7 @@ namespace Umbraco.Core.Logging.Viewer
{
public void Compose(Composition composition)
{
composition.RegisterUnique<ILogViewer>(_ => new JsonLogViewer());
composition.SetLogViewer(_ => new JsonLogViewer());
}
}
}
@@ -1,7 +1,7 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Core.Configuration.Dashboard;
using Umbraco.Core.Dashboards;
using Umbraco.Core.Serialization;
namespace Umbraco.Core.Manifest
@@ -1,12 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
using Umbraco.Core.IO;
using Umbraco.Core.Models;
using Umbraco.Core.Models.ContentEditing;
using Umbraco.Core.Models.Membership;
namespace Umbraco.Core.Manifest
{
@@ -30,6 +24,7 @@ namespace Umbraco.Core.Manifest
/// <summary>
/// Represents a content app definition, parsed from a manifest.
/// </summary>
/// <remarks>Is used to create an actual <see cref="ManifestContentAppFactory"/>.</remarks>
[DataContract(Name = "appdef", Namespace = "")]
public class ManifestContentAppDefinition
{
@@ -1,23 +1,20 @@
using System;
using System.ComponentModel;
using Newtonsoft.Json;
using Umbraco.Core.Configuration.Dashboard;
using Umbraco.Core.Dashboards;
using Umbraco.Core.IO;
namespace Umbraco.Core.Manifest
{
public class ManifestDashboardDefinition
public class ManifestDashboard : IDashboard
{
private string _view;
[JsonProperty("name", Required = Required.Always)]
public string Name { get; set; }
[JsonProperty("alias", Required = Required.Always)]
public string Alias { get; set; }
[JsonProperty("weight", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
[DefaultValue(100)]
[DefaultValue(100)] // must be equal to DashboardCollectionBuilder.DefaultWeight
public int Weight { get; set; }
[JsonProperty("view", Required = Required.Always)]
+182 -184
View File
@@ -1,184 +1,182 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Umbraco.Core.Cache;
using Umbraco.Core.Exceptions;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.ContentEditing;
using Umbraco.Core.Models.Trees;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Core.Manifest
{
/// <summary>
/// Parses the Main.js file and replaces all tokens accordingly.
/// </summary>
public class ManifestParser
{
private static readonly string Utf8Preamble = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
private readonly IAppPolicyCache _cache;
private readonly ILogger _logger;
private readonly ManifestValueValidatorCollection _validators;
private string _path;
/// <summary>
/// Initializes a new instance of the <see cref="ManifestParser"/> class.
/// </summary>
public ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ILogger logger)
: this(appCaches, validators, "~/App_Plugins", logger)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="ManifestParser"/> class.
/// </summary>
private ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, string path, ILogger logger)
{
if (appCaches == null) throw new ArgumentNullException(nameof(appCaches));
_cache = appCaches.RuntimeCache;
_validators = validators ?? throw new ArgumentNullException(nameof(validators));
if (string.IsNullOrWhiteSpace(path)) throw new ArgumentNullOrEmptyException(nameof(path));
Path = path;
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public string Path
{
get => _path;
set => _path = value.StartsWith("~/") ? IOHelper.MapPath(value) : value;
}
/// <summary>
/// Gets all manifests, merged into a single manifest object.
/// </summary>
/// <returns></returns>
public PackageManifest Manifest
=> _cache.GetCacheItem<PackageManifest>("Umbraco.Core.Manifest.ManifestParser::Manifests", () =>
{
var manifests = GetManifests();
return MergeManifests(manifests);
}, new TimeSpan(0, 4, 0));
/// <summary>
/// Gets all manifests.
/// </summary>
private IEnumerable<PackageManifest> GetManifests()
{
var manifests = new List<PackageManifest>();
foreach (var path in GetManifestFiles())
{
try
{
var text = File.ReadAllText(path);
text = TrimPreamble(text);
if (string.IsNullOrWhiteSpace(text))
continue;
var manifest = ParseManifest(text);
manifests.Add(manifest);
}
catch (Exception e)
{
_logger.Error<ManifestParser>(e, "Failed to parse manifest at '{Path}', ignoring.", path);
}
}
return manifests;
}
/// <summary>
/// Merges all manifests into one.
/// </summary>
private static PackageManifest MergeManifests(IEnumerable<PackageManifest> manifests)
{
var scripts = new HashSet<string>();
var stylesheets = new HashSet<string>();
var propertyEditors = new List<IDataEditor>();
var parameterEditors = new List<IDataEditor>();
var gridEditors = new List<GridEditor>();
var contentApps = new List<ManifestContentAppDefinition>();
var dashboards = new List<ManifestDashboardDefinition>();
var sections = new List<ManifestBackOfficeSection>();
foreach (var manifest in manifests)
{
if (manifest.Scripts != null) foreach (var script in manifest.Scripts) scripts.Add(script);
if (manifest.Stylesheets != null) foreach (var stylesheet in manifest.Stylesheets) stylesheets.Add(stylesheet);
if (manifest.PropertyEditors != null) propertyEditors.AddRange(manifest.PropertyEditors);
if (manifest.ParameterEditors != null) parameterEditors.AddRange(manifest.ParameterEditors);
if (manifest.GridEditors != null) gridEditors.AddRange(manifest.GridEditors);
if (manifest.ContentApps != null) contentApps.AddRange(manifest.ContentApps);
if (manifest.Dashboards != null) dashboards.AddRange(manifest.Dashboards);
if (manifest.Sections != null) sections.AddRange(manifest.Sections.DistinctBy(x => x.Alias.ToLowerInvariant()));
}
return new PackageManifest
{
Scripts = scripts.ToArray(),
Stylesheets = stylesheets.ToArray(),
PropertyEditors = propertyEditors.ToArray(),
ParameterEditors = parameterEditors.ToArray(),
GridEditors = gridEditors.ToArray(),
ContentApps = contentApps.ToArray(),
Dashboards = dashboards.ToArray(),
Sections = sections.ToArray()
};
}
// gets all manifest files (recursively)
private IEnumerable<string> GetManifestFiles()
{
if (Directory.Exists(_path) == false)
return new string[0];
return Directory.GetFiles(_path, "package.manifest", SearchOption.AllDirectories);
}
private static string TrimPreamble(string text)
{
// strangely StartsWith(preamble) would always return true
if (text.Substring(0, 1) == Utf8Preamble)
text = text.Remove(0, Utf8Preamble.Length);
return text;
}
/// <summary>
/// Parses a manifest.
/// </summary>
internal PackageManifest ParseManifest(string text)
{
if (string.IsNullOrWhiteSpace(text))
throw new ArgumentNullOrEmptyException(nameof(text));
var manifest = JsonConvert.DeserializeObject<PackageManifest>(text,
new DataEditorConverter(_logger),
new ValueValidatorConverter(_validators),
new DashboardAccessRuleConverter());
// scripts and stylesheets are raw string, must process here
for (var i = 0; i < manifest.Scripts.Length; i++)
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]);
// add property editors that are also parameter editors, to the parameter editors list
// (the manifest format is kinda legacy)
var ppEditors = manifest.PropertyEditors.Where(x => (x.Type & EditorType.MacroParameter) > 0).ToList();
if (ppEditors.Count > 0)
manifest.ParameterEditors = manifest.ParameterEditors.Union(ppEditors).ToArray();
return manifest;
}
// purely for tests
internal IEnumerable<GridEditor> ParseGridEditors(string text)
{
return JsonConvert.DeserializeObject<IEnumerable<GridEditor>>(text);
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Umbraco.Core.Cache;
using Umbraco.Core.Exceptions;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Core.Manifest
{
/// <summary>
/// Parses the Main.js file and replaces all tokens accordingly.
/// </summary>
public class ManifestParser
{
private static readonly string Utf8Preamble = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
private readonly IAppPolicyCache _cache;
private readonly ILogger _logger;
private readonly ManifestValueValidatorCollection _validators;
private string _path;
/// <summary>
/// Initializes a new instance of the <see cref="ManifestParser"/> class.
/// </summary>
public ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ILogger logger)
: this(appCaches, validators, "~/App_Plugins", logger)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="ManifestParser"/> class.
/// </summary>
private ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, string path, ILogger logger)
{
if (appCaches == null) throw new ArgumentNullException(nameof(appCaches));
_cache = appCaches.RuntimeCache;
_validators = validators ?? throw new ArgumentNullException(nameof(validators));
if (string.IsNullOrWhiteSpace(path)) throw new ArgumentNullOrEmptyException(nameof(path));
Path = path;
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public string Path
{
get => _path;
set => _path = value.StartsWith("~/") ? IOHelper.MapPath(value) : value;
}
/// <summary>
/// Gets all manifests, merged into a single manifest object.
/// </summary>
/// <returns></returns>
public PackageManifest Manifest
=> _cache.GetCacheItem<PackageManifest>("Umbraco.Core.Manifest.ManifestParser::Manifests", () =>
{
var manifests = GetManifests();
return MergeManifests(manifests);
}, new TimeSpan(0, 4, 0));
/// <summary>
/// Gets all manifests.
/// </summary>
private IEnumerable<PackageManifest> GetManifests()
{
var manifests = new List<PackageManifest>();
foreach (var path in GetManifestFiles())
{
try
{
var text = File.ReadAllText(path);
text = TrimPreamble(text);
if (string.IsNullOrWhiteSpace(text))
continue;
var manifest = ParseManifest(text);
manifests.Add(manifest);
}
catch (Exception e)
{
_logger.Error<ManifestParser>(e, "Failed to parse manifest at '{Path}', ignoring.", path);
}
}
return manifests;
}
/// <summary>
/// Merges all manifests into one.
/// </summary>
private static PackageManifest MergeManifests(IEnumerable<PackageManifest> manifests)
{
var scripts = new HashSet<string>();
var stylesheets = new HashSet<string>();
var propertyEditors = new List<IDataEditor>();
var parameterEditors = new List<IDataEditor>();
var gridEditors = new List<GridEditor>();
var contentApps = new List<ManifestContentAppDefinition>();
var dashboards = new List<ManifestDashboard>();
var sections = new List<ManifestBackOfficeSection>();
foreach (var manifest in manifests)
{
if (manifest.Scripts != null) foreach (var script in manifest.Scripts) scripts.Add(script);
if (manifest.Stylesheets != null) foreach (var stylesheet in manifest.Stylesheets) stylesheets.Add(stylesheet);
if (manifest.PropertyEditors != null) propertyEditors.AddRange(manifest.PropertyEditors);
if (manifest.ParameterEditors != null) parameterEditors.AddRange(manifest.ParameterEditors);
if (manifest.GridEditors != null) gridEditors.AddRange(manifest.GridEditors);
if (manifest.ContentApps != null) contentApps.AddRange(manifest.ContentApps);
if (manifest.Dashboards != null) dashboards.AddRange(manifest.Dashboards);
if (manifest.Sections != null) sections.AddRange(manifest.Sections.DistinctBy(x => x.Alias.ToLowerInvariant()));
}
return new PackageManifest
{
Scripts = scripts.ToArray(),
Stylesheets = stylesheets.ToArray(),
PropertyEditors = propertyEditors.ToArray(),
ParameterEditors = parameterEditors.ToArray(),
GridEditors = gridEditors.ToArray(),
ContentApps = contentApps.ToArray(),
Dashboards = dashboards.ToArray(),
Sections = sections.ToArray()
};
}
// gets all manifest files (recursively)
private IEnumerable<string> GetManifestFiles()
{
if (Directory.Exists(_path) == false)
return new string[0];
return Directory.GetFiles(_path, "package.manifest", SearchOption.AllDirectories);
}
private static string TrimPreamble(string text)
{
// strangely StartsWith(preamble) would always return true
if (text.Substring(0, 1) == Utf8Preamble)
text = text.Remove(0, Utf8Preamble.Length);
return text;
}
/// <summary>
/// Parses a manifest.
/// </summary>
internal PackageManifest ParseManifest(string text)
{
if (string.IsNullOrWhiteSpace(text))
throw new ArgumentNullOrEmptyException(nameof(text));
var manifest = JsonConvert.DeserializeObject<PackageManifest>(text,
new DataEditorConverter(_logger),
new ValueValidatorConverter(_validators),
new DashboardAccessRuleConverter());
// scripts and stylesheets are raw string, must process here
for (var i = 0; i < manifest.Scripts.Length; i++)
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]);
// add property editors that are also parameter editors, to the parameter editors list
// (the manifest format is kinda legacy)
var ppEditors = manifest.PropertyEditors.Where(x => (x.Type & EditorType.MacroParameter) > 0).ToList();
if (ppEditors.Count > 0)
manifest.ParameterEditors = manifest.ParameterEditors.Union(ppEditors).ToArray();
return manifest;
}
// purely for tests
internal IEnumerable<GridEditor> ParseGridEditors(string text)
{
return JsonConvert.DeserializeObject<IEnumerable<GridEditor>>(text);
}
}
}
+1 -1
View File
@@ -49,7 +49,7 @@ namespace Umbraco.Core.Manifest
/// Gets or sets the dashboards listed in the manifest.
/// </summary>
[JsonProperty("dashboards")]
public ManifestDashboardDefinition[] Dashboards { get; set; } = Array.Empty<ManifestDashboardDefinition>();
public ManifestDashboard[] Dashboards { get; set; } = Array.Empty<ManifestDashboard>();
/// <summary>
/// Gets or sets the sections listed in the manifest.
+1 -1
View File
@@ -1,7 +1,7 @@
namespace Umbraco.Core.Media
{
//TODO: Could definitely have done with a better name
// TODO: Could definitely have done with a better name
public class Result
{
public Status Status { get; set; }
@@ -5,7 +5,7 @@
/// </summary>
public interface IMigrationExpression
{
string Process(IMigrationContext context); // todo: remove that one?
string Process(IMigrationContext context); // TODO: remove that one?
void Execute();
}
}
@@ -283,48 +283,60 @@ namespace Umbraco.Core.Migrations.Install
if (string.IsNullOrWhiteSpace(connectionString)) throw new ArgumentNullOrEmptyException(nameof(connectionString));
if (string.IsNullOrWhiteSpace(providerName)) throw new ArgumentNullOrEmptyException(nameof(providerName));
// set the connection string for the new datalayer
var connectionStringSettings = new ConnectionStringSettings(Constants.System.UmbracoConnectionName, connectionString, providerName);
var fileSource = "web.config";
var fileName = IOHelper.MapPath(SystemDirectories.Root +"/" + fileSource);
var fileName = IOHelper.MapPath($"{SystemDirectories.Root}/web.config");
var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace);
if (xml.Root == null) throw new Exception("Invalid web.config file.");
var connectionStrings = xml.Root.DescendantsAndSelf("connectionStrings").FirstOrDefault();
if (connectionStrings == null) throw new Exception("Invalid web.config file.");
if (xml.Root == null) throw new Exception($"Invalid {fileSource} file (no root).");
// honour configSource, if its set, change the xml file we are saving the configuration
// to the one set in the configSource attribute
if (connectionStrings.Attribute("configSource") != null)
var connectionStrings = xml.Root.DescendantsAndSelf("connectionStrings").FirstOrDefault();
if (connectionStrings == null) throw new Exception($"Invalid {fileSource} file (no connection strings).");
// handle configSource
var configSourceAttribute = connectionStrings.Attribute("configSource");
if (configSourceAttribute != null)
{
var source = connectionStrings.Attribute("configSource").Value;
var configFile = IOHelper.MapPath($"{SystemDirectories.Root}/{source}");
logger.Info<DatabaseBuilder>("Storing ConnectionString in {ConfigFile}", configFile);
if (File.Exists(configFile))
{
xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace);
fileName = configFile;
}
fileSource = configSourceAttribute.Value;
fileName = IOHelper.MapPath(SystemDirectories.Root + "/" + fileSource);
if (!File.Exists(fileName))
throw new Exception($"Invalid configSource \"{fileSource}\" (no such file).");
xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace);
if (xml.Root == null) throw new Exception($"Invalid {fileSource} file (no root).");
connectionStrings = xml.Root.DescendantsAndSelf("connectionStrings").FirstOrDefault();
if (connectionStrings == null) throw new Exception("Invalid web.config file.");
if (connectionStrings == null) throw new Exception($"Invalid {fileSource} file (no connection strings).");
}
// update connectionString if it exists, or else create a new connectionString
var setting = connectionStrings.Descendants("add").FirstOrDefault(s => s.Attribute("name").Value == Constants.System.UmbracoConnectionName);
// create or update connection string
var setting = connectionStrings.Descendants("add").FirstOrDefault(s => s.Attribute("name")?.Value == Constants.System.UmbracoConnectionName);
if (setting == null)
{
connectionStrings.Add(new XElement("add",
new XAttribute("name", Constants.System.UmbracoConnectionName),
new XAttribute("connectionString", connectionStringSettings),
new XAttribute("connectionString", connectionString),
new XAttribute("providerName", providerName)));
}
else
{
setting.Attribute("connectionString").Value = connectionString;
setting.Attribute("providerName").Value = providerName;
AddOrUpdateAttribute(setting, "connectionString", connectionString);
AddOrUpdateAttribute(setting, "providerName", providerName);
}
// save
logger.Info<DatabaseBuilder>("Saving connection string to {ConfigFile}.", fileSource);
xml.Save(fileName, SaveOptions.DisableFormatting);
logger.Info<DatabaseBuilder>("Configured a new ConnectionString using the '{ProviderName}' provider.", providerName);
logger.Info<DatabaseBuilder>("Saved connection string to {ConfigFile}.", fileSource);
}
private static void AddOrUpdateAttribute(XElement element, string name, string value)
{
var attribute = element.Attribute(name);
if (attribute == null)
element.Add(new XAttribute(name, value));
else
attribute.Value = value;
}
internal bool IsConnectionStringConfigured(ConnectionStringSettings databaseSettings)
@@ -422,7 +434,7 @@ namespace Umbraco.Core.Migrations.Install
_logger.Info<DatabaseBuilder>("Database configuration status: Started");
var database = scope.Database;
var message = string.Empty;
var schemaResult = ValidateSchema();
@@ -482,7 +494,7 @@ namespace Umbraco.Core.Migrations.Install
}
_logger.Info<DatabaseBuilder>("Database upgrade started");
// upgrade
var upgrader = new UmbracoUpgrader();
upgrader.Execute(_scopeProvider, _migrationBuilder, _keyValueService, _logger, _postMigrations);
@@ -135,7 +135,7 @@ namespace Umbraco.Core.Migrations.Install
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1047, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1047", SortOrder = 2, UniqueId = new Guid("1EA2E01F-EBD8-4CE1-8D71-6B1149E63548"), Text = "Member Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1048, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1048", SortOrder = 2, UniqueId = new Guid("135D60E0-64D9-49ED-AB08-893C9BA44AE5"), Text = "Media Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1049, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1049", SortOrder = 2, UniqueId = new Guid("9DBBCBBB-2327-434A-B355-AF1B84E5010A"), Text = "Multiple Media Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1050, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1050", SortOrder = 2, UniqueId = new Guid("B4E3535A-1753-47E2-8568-602CF8CFEE6F"), Text = "Related Links", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1050, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1050", SortOrder = 2, UniqueId = new Guid("B4E3535A-1753-47E2-8568-602CF8CFEE6F"), Text = "Multi URL Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
}
private void CreateLockData()
@@ -263,7 +263,7 @@ namespace Umbraco.Core.Migrations.Install
const string listLayout = "{\"name\": \"List\",\"path\": \"views/propertyeditors/listview/layouts/list/list.html\",\"icon\": \"icon-list\", \"isSystem\": 1,\"selected\": true}";
const string layouts = "[" + cardLayout + "," + listLayout + "]";
//TODO Check which of the DataTypeIds below doesn't exist in umbracoNode, which results in a foreign key constraint errors.
// TODO: Check which of the DataTypeIds below doesn't exist in umbracoNode, which results in a foreign key constraint errors.
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -49, EditorAlias = Constants.PropertyEditors.Aliases.Boolean, DbType = "Integer" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -51, EditorAlias = Constants.PropertyEditors.Aliases.Integer, DbType = "Integer" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -87, EditorAlias = Constants.PropertyEditors.Aliases.TinyMce, DbType = "Ntext",
@@ -301,7 +301,7 @@ namespace Umbraco.Core.Migrations.Install
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1048, EditorAlias = Constants.PropertyEditors.Aliases.MediaPicker, DbType = "Ntext" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1049, EditorAlias = Constants.PropertyEditors.Aliases.MediaPicker, DbType = "Ntext",
Configuration = "{\"multiPicker\":1}" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1050, EditorAlias = Constants.PropertyEditors.Aliases.RelatedLinks, DbType = "Ntext" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1050, EditorAlias = Constants.PropertyEditors.Aliases.MultiUrlPicker, DbType = "Ntext" });
}
private void CreateRelationTypeData()
@@ -27,7 +27,7 @@ namespace Umbraco.Core.Migrations.Install
public List<TableDefinition> TableDefinitions { get; }
// todo what are these exactly? TableDefinitions are those that should be there, IndexDefinitions are those that... are in DB?
// TODO: what are these exactly? TableDefinitions are those that should be there, IndexDefinitions are those that... are in DB?
internal List<DbIndexDefinition> IndexDefinitions { get; }
public List<string> ValidTables { get; }
@@ -124,6 +124,8 @@ namespace Umbraco.Core.Migrations.Upgrade
To<MakeRedirectUrlVariant>("{64EBCE53-E1F0-463A-B40B-E98EFCCA8AE2}");
To<AddContentTypeIsElementColumn>("{0009109C-A0B8-4F3F-8FEB-C137BBDDA268}");
To<UpdateMemberGroupPickerData>("{8A027815-D5CD-4872-8B88-9A51AB5986A6}"); // from 7.14.0
To<ConvertRelatedLinksToMultiUrlPicker>("{ED28B66A-E248-4D94-8CDB-9BDF574023F0}");
To<UpdatePickerIntegerValuesToUdi>("{38C809D5-6C34-426B-9BEA-EFD39162595C}");
//FINAL
@@ -0,0 +1,139 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Dtos;
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
{
public class ConvertRelatedLinksToMultiUrlPicker : MigrationBase
{
public ConvertRelatedLinksToMultiUrlPicker(IMigrationContext context) : base(context)
{ }
public override void Migrate()
{
var sqlDataTypes = Sql()
.Select<DataTypeDto>()
.From<DataTypeDto>()
.Where<DataTypeDto>(x => x.EditorAlias == "Umbraco.RelatedLinks"
|| x.EditorAlias == "Umbraco.RelatedLinks2");
var dataTypes = Database.Fetch<DataTypeDto>(sqlDataTypes);
var dataTypeIds = dataTypes.Select(x => x.NodeId).ToList();
if (dataTypeIds.Count == 0) return;
foreach (var dataType in dataTypes)
{
dataType.EditorAlias = Constants.PropertyEditors.Aliases.MultiUrlPicker;
Database.Update(dataType);
}
var sqlPropertyTpes = Sql()
.Select<PropertyTypeDto>()
.From<PropertyTypeDto>()
.Where<PropertyTypeDto>(x => dataTypeIds.Contains(x.DataTypeId));
var propertyTypeIds = Database.Fetch<PropertyTypeDto>(sqlPropertyTpes).Select(x => x.Id).ToList();
if (propertyTypeIds.Count == 0) return;
var sqlPropertyData = Sql()
.Select<PropertyDataDto>()
.From<PropertyDataDto>()
.Where<PropertyDataDto>(x => propertyTypeIds.Contains(x.PropertyTypeId));
var properties = Database.Fetch<PropertyDataDto>(sqlPropertyData);
// Create a Multi URL Picker datatype for the converted RelatedLinks data
foreach (var property in properties)
{
var value = property.Value.ToString();
if (string.IsNullOrWhiteSpace(value))
continue;
var relatedLinks = JsonConvert.DeserializeObject<List<RelatedLink>>(value);
var links = new List<LinkDto>();
foreach (var relatedLink in relatedLinks)
{
GuidUdi udi = null;
if (relatedLink.IsInternal)
{
var linkIsUdi = GuidUdi.TryParse(relatedLink.Link, out udi);
if (linkIsUdi == false)
{
// oh no.. probably an integer, yikes!
if (int.TryParse(relatedLink.Link, out var intId))
{
var sqlNodeData = Sql()
.Select<NodeDto>()
.Where<NodeDto>(x => x.NodeId == intId);
var node = Database.Fetch<NodeDto>(sqlNodeData).FirstOrDefault();
if (node != null)
// Note: RelatedLinks did not allow for picking media items,
// so if there's a value this will be a content item - hence
// the hardcoded "document" here
udi = new GuidUdi("document", node.UniqueId);
}
}
}
var link = new LinkDto
{
Name = relatedLink.Caption,
Target = relatedLink.NewWindow ? "_blank" : null,
Udi = udi,
// Should only have a URL if it's an external link otherwise it wil be a UDI
Url = relatedLink.IsInternal == false ? relatedLink.Link : null
};
links.Add(link);
}
var json = JsonConvert.SerializeObject(links);
// Update existing data
property.TextValue = json;
Database.Update(property);
}
}
}
internal class RelatedLink
{
public int? Id { get; internal set; }
internal bool IsDeleted { get; set; }
[JsonProperty("caption")]
public string Caption { get; set; }
[JsonProperty("link")]
public string Link { get; set; }
[JsonProperty("newWindow")]
public bool NewWindow { get; set; }
[JsonProperty("isInternal")]
public bool IsInternal { get; set; }
}
[DataContract]
internal class LinkDto
{
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "target")]
public string Target { get; set; }
[DataMember(Name = "udi")]
public GuidUdi Udi { get; set; }
[DataMember(Name = "url")]
public string Url { get; set; }
}
}
@@ -16,7 +16,6 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
RenameDataType(Constants.PropertyEditors.Aliases.MediaPicker + "2", Constants.PropertyEditors.Aliases.MediaPicker);
RenameDataType(Constants.PropertyEditors.Aliases.MemberPicker + "2", Constants.PropertyEditors.Aliases.MemberPicker);
RenameDataType(Constants.PropertyEditors.Aliases.MultiNodeTreePicker + "2", Constants.PropertyEditors.Aliases.MultiNodeTreePicker);
RenameDataType(Constants.PropertyEditors.Aliases.RelatedLinks + "2", Constants.PropertyEditors.Aliases.RelatedLinks);
RenameDataType("Umbraco.TextboxMultiple", Constants.PropertyEditors.Aliases.TextArea, false);
RenameDataType("Umbraco.Textbox", Constants.PropertyEditors.Aliases.TextBox, false);
}
@@ -0,0 +1,108 @@
using System;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Dtos;
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
{
public class UpdatePickerIntegerValuesToUdi : MigrationBase
{
public UpdatePickerIntegerValuesToUdi(IMigrationContext context) : base(context)
{ }
public override void Migrate()
{
var sqlDataTypes = Sql()
.Select<DataTypeDto>()
.From<DataTypeDto>()
.Where<DataTypeDto>(x => x.EditorAlias == Constants.PropertyEditors.Aliases.ContentPicker
|| x.EditorAlias == Constants.PropertyEditors.Aliases.MediaPicker
|| x.EditorAlias == Constants.PropertyEditors.Aliases.MultiNodeTreePicker);
var dataTypes = Database.Fetch<DataTypeDto>(sqlDataTypes).ToList();
foreach (var datatype in dataTypes.Where(x => !x.Configuration.IsNullOrWhiteSpace()))
{
switch (datatype.EditorAlias)
{
case Constants.PropertyEditors.Aliases.ContentPicker:
case Constants.PropertyEditors.Aliases.MediaPicker:
{
var config = JsonConvert.DeserializeObject<JObject>(datatype.Configuration);
var startNodeId = config.Value<string>("startNodeId");
if (!startNodeId.IsNullOrWhiteSpace() && int.TryParse(startNodeId, out var intStartNode))
{
var guid = intStartNode <= 0
? null
: Context.Database.ExecuteScalar<Guid?>(
Sql().Select<NodeDto>(x => x.UniqueId).From<NodeDto>().Where<NodeDto>(x => x.NodeId == intStartNode));
if (guid.HasValue)
{
var udi = new GuidUdi(datatype.EditorAlias == Constants.PropertyEditors.Aliases.MediaPicker
? Constants.UdiEntityType.Media
: Constants.UdiEntityType.Document, guid.Value);
config["startNodeId"] = new JValue(udi.ToString());
}
else
config.Remove("startNodeId");
datatype.Configuration = JsonConvert.SerializeObject(config);
Database.Update(datatype);
}
break;
}
case Constants.PropertyEditors.Aliases.MultiNodeTreePicker:
{
var config = JsonConvert.DeserializeObject<JObject>(datatype.Configuration);
var startNodeConfig = config.Value<JObject>("startNode");
if (startNodeConfig != null)
{
var startNodeId = startNodeConfig.Value<string>("id");
var objectType = startNodeConfig.Value<string>("type");
if (!objectType.IsNullOrWhiteSpace()
&& !startNodeId.IsNullOrWhiteSpace()
&& int.TryParse(startNodeId, out var intStartNode))
{
var guid = intStartNode <= 0
? null
: Context.Database.ExecuteScalar<Guid?>(
Sql().Select<NodeDto>(x => x.UniqueId).From<NodeDto>().Where<NodeDto>(x => x.NodeId == intStartNode));
string entityType = null;
switch (objectType.ToLowerInvariant())
{
case "content":
entityType = Constants.UdiEntityType.Document;
break;
case "media":
entityType = Constants.UdiEntityType.Media;
break;
case "member":
entityType = Constants.UdiEntityType.Member;
break;
}
if (entityType != null && guid.HasValue)
{
var udi = new GuidUdi(entityType, guid.Value);
startNodeConfig["id"] = new JValue(udi.ToString());
}
else
startNodeConfig.Remove("id");
datatype.Configuration = JsonConvert.SerializeObject(config);
Database.Update(datatype);
}
}
break;
}
}
}
}
}
}
+2 -2
View File
@@ -128,14 +128,14 @@ namespace Umbraco.Core.Models
/// <summary>
/// Gets the enumeration of property groups for the entity.
/// todo - remove this proxy method
/// TODO: remove this proxy method
/// </summary>
[IgnoreDataMember]
public IEnumerable<PropertyGroup> PropertyGroups => ContentTypeBase.CompositionPropertyGroups;
/// <summary>
/// Gets the numeration of property types for the entity.
/// todo - remove this proxy method
/// TODO: remove this proxy method
/// </summary>
[IgnoreDataMember]
public IEnumerable<PropertyType> PropertyTypes => ContentTypeBase.CompositionPropertyTypes;
@@ -31,7 +31,7 @@ namespace Umbraco.Core.Models
_schedule[schedule.Culture] = changes;
}
//TODO: Below will throw if there are duplicate dates added, validate/return bool?
// TODO: Below will throw if there are duplicate dates added, validate/return bool?
changes.Add(schedule.Date, schedule);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, schedule));
@@ -62,7 +62,7 @@ namespace Umbraco.Core.Models
if (!releaseDate.HasValue && !expireDate.HasValue) return false;
//TODO: Do we allow passing in a release or expiry date that is before now?
// TODO: Do we allow passing in a release or expiry date that is before now?
if (!_schedule.TryGetValue(culture, out var changes))
{
@@ -70,7 +70,7 @@ namespace Umbraco.Core.Models
_schedule[culture] = changes;
}
//TODO: Below will throw if there are duplicate dates added, should validate/return bool?
// TODO: Below will throw if there are duplicate dates added, should validate/return bool?
// but the bool won't indicate which date was in error, maybe have 2 diff methods to schedule start/end?
if (releaseDate.HasValue)
+1 -1
View File
@@ -431,7 +431,7 @@ namespace Umbraco.Core.Models
/// PropertyTypes that are not part of a PropertyGroup
/// </summary>
[IgnoreDataMember]
//todo should we mark this as EditorBrowsable hidden since it really isn't ever used?
// TODO: should we mark this as EditorBrowsable hidden since it really isn't ever used?
internal PropertyTypeCollection PropertyTypeCollection => _noGroupPropertyTypes;
/// <summary>
@@ -48,7 +48,7 @@ namespace Umbraco.Core.Models
throw new Exception("oops");
// skip new properties
//TODO: This used to be WasPropertyDirty("HasIdentity") but i don't think that actually worked for detecting new entities this does seem to work properly
// TODO: This used to be WasPropertyDirty("HasIdentity") but i don't think that actually worked for detecting new entities this does seem to work properly
var isNewProperty = dirtyProperty.WasPropertyDirty("Id");
if (isNewProperty) return false;
+3 -3
View File
@@ -5,7 +5,7 @@ using Newtonsoft.Json.Linq;
namespace Umbraco.Core.Models
{
//TODO: Make a property value converter for this!
// TODO: Make a property value converter for this!
/// <summary>
/// A model representing the value saved for the grid
@@ -21,7 +21,7 @@ namespace Umbraco.Core.Models
public class GridSection
{
[JsonProperty("grid")]
public string Grid { get; set; } //todo: what is this?
public string Grid { get; set; } // TODO: what is this?
[JsonProperty("rows")]
public IEnumerable<GridRow> Rows { get; set; }
@@ -48,7 +48,7 @@ namespace Umbraco.Core.Models
public class GridArea
{
[JsonProperty("grid")]
public string Grid { get; set; } //todo: what is this?
public string Grid { get; set; } // TODO: what is this?
[JsonProperty("controls")]
public IEnumerable<GridControl> Controls { get; set; }
+1 -1
View File
@@ -137,7 +137,7 @@ namespace Umbraco.Core.Models
/// </summary>
IEnumerable<string> EditedCultures { get; }
// todo - these two should move to some kind of service
// TODO: these two should move to some kind of service
/// <summary>
/// Changes the <see cref="IContentType"/> for the current content object
@@ -10,7 +10,7 @@ namespace Umbraco.Core.Models
/// <summary>
/// Gets or sets the content types that compose this content type.
/// </summary>
//todo: we should be storing key references, not the object else we are caching way too much
// TODO: we should be storing key references, not the object else we are caching way too much
IEnumerable<IContentTypeComposition> ContentTypeComposition { get; set; }
/// <summary>
@@ -67,7 +67,7 @@ namespace Umbraco.Core.Models.Identity
_startContentIds = new int[] { };
_groups = new IReadOnlyUserGroup[] { };
_allowedSections = new string[] { };
_culture = Current.Configs.Global().DefaultUILanguage; //todo inject
_culture = Current.Configs.Global().DefaultUILanguage; // TODO: inject
_groups = new IReadOnlyUserGroup[0];
_roles = new ObservableCollection<IdentityUserRole<string>>();
_roles.CollectionChanged += _roles_CollectionChanged;
@@ -84,7 +84,7 @@ namespace Umbraco.Core.Models.Identity
_startContentIds = new int[] { };
_groups = new IReadOnlyUserGroup[] { };
_allowedSections = new string[] { };
_culture = Current.Configs.Global().DefaultUILanguage; //todo inject
_culture = Current.Configs.Global().DefaultUILanguage; // TODO: inject
_groups = groups.ToArray();
_roles = new ObservableCollection<IdentityUserRole<string>>(_groups.Select(x => new IdentityUserRole<string>
{
+1 -1
View File
@@ -21,7 +21,7 @@ namespace Umbraco.Core.Models
var val = media.Properties[propertyType];
if (val == null) return string.Empty;
//todo would need to be adjusted to variations, when media become variants
// TODO: would need to be adjusted to variations, when media become variants
var jsonString = val.GetValue() as string;
if (jsonString == null) return string.Empty;
+6 -6
View File
@@ -189,7 +189,7 @@ namespace Umbraco.Core.Models
[DataMember]
public IEnumerable<string> Groups { get; set; }
//TODO: When get/setting all of these properties we MUST:
// TODO: When get/setting all of these properties we MUST:
// * Check if we are using the umbraco membership provider, if so then we need to use the configured fields - not the explicit fields below
// * If any of the fields don't exist, what should we do? Currently it will throw an exception!
@@ -338,7 +338,7 @@ namespace Umbraco.Core.Models
return tryConvert.Result;
}
return false;
//TODO: Use TryConvertTo<T> instead
// TODO: Use TryConvertTo<T> instead
}
set
{
@@ -371,7 +371,7 @@ namespace Umbraco.Core.Models
return tryConvert.Result;
}
return default(DateTime);
//TODO: Use TryConvertTo<T> instead
// TODO: Use TryConvertTo<T> instead
}
set
{
@@ -404,7 +404,7 @@ namespace Umbraco.Core.Models
return tryConvert.Result;
}
return default(DateTime);
//TODO: Use TryConvertTo<T> instead
// TODO: Use TryConvertTo<T> instead
}
set
{
@@ -437,7 +437,7 @@ namespace Umbraco.Core.Models
return tryConvert.Result;
}
return default(DateTime);
//TODO: Use TryConvertTo<T> instead
// TODO: Use TryConvertTo<T> instead
}
set
{
@@ -471,7 +471,7 @@ namespace Umbraco.Core.Models
return tryConvert.Result;
}
return default(int);
//TODO: Use TryConvertTo<T> instead
// TODO: Use TryConvertTo<T> instead
}
set
{
+1 -1
View File
@@ -66,7 +66,7 @@ namespace Umbraco.Core.Models
// leading underscores which we don't want in this case.
// see : http://issues.umbraco.org/issue/U4-3968
//TODO: BUT, I'm pretty sure we could do this with regards to underscores now:
// TODO: BUT, I'm pretty sure we could do this with regards to underscores now:
// .ToCleanString(CleanStringType.Alias | CleanStringType.UmbracoCase)
// Need to ask Stephen
@@ -44,7 +44,7 @@ namespace Umbraco.Core.Models.Membership
_isLockedOut = member.IsLockedOut;
_creationDate = member.CreateDate.ToUniversalTime();
_lastLoginDate = member.LastLoginDate.ToUniversalTime();
//TODO: We currently don't really have any place to store this data!!
// TODO: We currently don't really have any place to store this data!!
_lastActivityDate = member.LastLoginDate.ToUniversalTime();
_lastPasswordChangedDate = member.LastPasswordChangeDate.ToUniversalTime();
_lastLockoutDate = member.LastLockoutDate.ToUniversalTime();
+2 -2
View File
@@ -27,7 +27,7 @@ namespace Umbraco.Core.Models.Membership
{
SessionTimeout = 60;
_userGroups = new HashSet<IReadOnlyUserGroup>();
_language = Current.Configs.Global().DefaultUILanguage; //todo inject
_language = Current.Configs.Global().DefaultUILanguage; // TODO: inject
_isApproved = true;
_isLockedOut = false;
_startContentIds = new int[] { };
@@ -242,7 +242,7 @@ namespace Umbraco.Core.Models.Membership
set { SetPropertyValueAndDetectChanges(value, ref _failedLoginAttempts, Ps.Value.FailedPasswordAttemptsSelector); }
}
//TODO: Figure out how to support all of this! - we cannot have NotImplementedExceptions because these get used by the IMembershipMemberService<IUser> service so
// TODO: Figure out how to support all of this! - we cannot have NotImplementedExceptions because these get used by the IMembershipMemberService<IUser> service so
// we'll just have them as generic get/set which don't interact with the db.
[IgnoreDataMember]
@@ -26,19 +26,19 @@ namespace Umbraco.Core.Models.Packaging
public string PackageView { get; set; }
public string IconUrl { get; set; }
public string Actions { get; set; } //todo: Should we make this strongly typed to IEnumerable<PackageAction> ?
public string Actions { get; set; } // TODO: Should we make this strongly typed to IEnumerable<PackageAction> ?
public PreInstallWarnings Warnings { get; set; } = new PreInstallWarnings();
public List<CompiledPackageFile> Files { get; set; } = new List<CompiledPackageFile>();
public IEnumerable<XElement> Macros { get; set; } //todo: make strongly typed
public IEnumerable<XElement> Templates { get; set; } //todo: make strongly typed
public IEnumerable<XElement> Stylesheets { get; set; } //todo: make strongly typed
public IEnumerable<XElement> DataTypes { get; set; } //todo: make strongly typed
public IEnumerable<XElement> Languages { get; set; } //todo: make strongly typed
public IEnumerable<XElement> DictionaryItems { get; set; } //todo: make strongly typed
public IEnumerable<XElement> DocumentTypes { get; set; } //todo: make strongly typed
public IEnumerable<XElement> Macros { get; set; } // TODO: make strongly typed
public IEnumerable<XElement> Templates { get; set; } // TODO: make strongly typed
public IEnumerable<XElement> Stylesheets { get; set; } // TODO: make strongly typed
public IEnumerable<XElement> DataTypes { get; set; } // TODO: make strongly typed
public IEnumerable<XElement> Languages { get; set; } // TODO: make strongly typed
public IEnumerable<XElement> DictionaryItems { get; set; } // TODO: make strongly typed
public IEnumerable<XElement> DocumentTypes { get; set; } // TODO: make strongly typed
public IEnumerable<CompiledPackageDocument> Documents { get; set; }
}
}
@@ -10,7 +10,7 @@ namespace Umbraco.Core.Models.Packaging
public IEnumerable<string> UnsecureFiles { get; set; } = Enumerable.Empty<string>();
public IEnumerable<string> FilesReplaced { get; set; } = Enumerable.Empty<string>();
//TODO: Shouldn't we detect other conflicting entities too ?
// TODO: Shouldn't we detect other conflicting entities too ?
public IEnumerable<IMacro> ConflictingMacros { get; set; } = Enumerable.Empty<IMacro>();
public IEnumerable<ITemplate> ConflictingTemplates { get; set; } = Enumerable.Empty<ITemplate>();
public IEnumerable<IFile> ConflictingStylesheets { get; set; } = Enumerable.Empty<IFile>();
+4 -4
View File
@@ -55,7 +55,7 @@ namespace Umbraco.Core.Models
/// </summary>
public class PropertyValue
{
//TODO: Either we allow change tracking at this class level, or we add some special change tracking collections to the Property
// 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
private string _culture;
@@ -103,7 +103,7 @@ namespace Umbraco.Core.Models
// ReSharper disable once ClassNeverInstantiated.Local
private class PropertySelectors
{
//TODO: This allows us to track changes for an entire Property, but doesn't allow us to track changes at the variant level
// TODO: This allows us to track changes for an entire Property, but doesn't allow us to track changes at the variant level
public readonly PropertyInfo ValuesSelector = ExpressionHelper.GetPropertyInfo<Property, object>(x => x.Values);
public readonly DelegateEqualityComparer<object> PropertyValueComparer = new DelegateEqualityComparer<object>(
@@ -347,7 +347,7 @@ namespace Umbraco.Core.Models
/// </summary>
internal bool IsValid(string culture = "*", string segment = "*")
{
//todo - validating values shouldn't be done here, this calls in to IsValidValue
// TODO: validating values shouldn't be done here, this calls in to IsValidValue
culture = culture.NullOrWhiteSpaceAsNull();
segment = segment.NullOrWhiteSpaceAsNull();
@@ -388,7 +388,7 @@ namespace Umbraco.Core.Models
/// <returns>True is property value is valid, otherwise false</returns>
private bool IsValidValue(object value)
{
//todo - this shouldn't exist here, the model itself shouldn't be responsible for it's own validation and this requires singleton access
// TODO: this shouldn't exist here, the model itself shouldn't be responsible for it's own validation and this requires singleton access
return PropertyType.IsPropertyValueValid(value);
}
@@ -97,7 +97,7 @@ namespace Umbraco.Core.Models
/// </summary>
internal new void Add(Property property)
{
lock (_addLocker) // todo - why are we locking here and not everywhere else?!
lock (_addLocker) // TODO: why are we locking here and not everywhere else?!
{
var key = GetKeyForItem(property);
if (key != null)
@@ -14,12 +14,12 @@ namespace Umbraco.Core.Models
/// </summary>
[Serializable]
[DataContract]
//TODO: Change this to ObservableDictionary so we can reduce the INotifyCollectionChanged implementation details
// TODO: Change this to ObservableDictionary so we can reduce the INotifyCollectionChanged implementation details
public class PropertyGroupCollection : KeyedCollection<string, PropertyGroup>, INotifyCollectionChanged, IDeepCloneable
{
private readonly ReaderWriterLockSlim _addLocker = new ReaderWriterLockSlim();
//todo: this doesn't seem to be used anywhere
// TODO: this doesn't seem to be used anywhere
internal Action OnAdd;
internal PropertyGroupCollection()
@@ -14,7 +14,7 @@ namespace Umbraco.Core.Models
/// </summary>
public static class PropertyTagsExtensions
{
// todo: inject
// TODO: inject
private static PropertyEditorCollection PropertyEditors => Current.PropertyEditors;
private static IDataTypeService DataTypeService => Current.Services.DataTypeService;
+3 -3
View File
@@ -378,14 +378,14 @@ namespace Umbraco.Core.Models
}
//todo - this and other value validation methods should be a service level (not a model) thing. Changing this to internal for now
// TODO: this and other value validation methods should be a service level (not a model) thing. Changing this to internal for now
/// <summary>
/// Determines whether a value is valid for this property type.
/// </summary>
internal bool IsPropertyValueValid(object value)
{
var editor = Current.PropertyEditors[_propertyEditorAlias]; // todo inject
var configuration = Current.Services.DataTypeService.GetDataType(_dataTypeId).Configuration; // todo inject
var editor = Current.PropertyEditors[_propertyEditorAlias]; // TODO: inject
var configuration = Current.Services.DataTypeService.GetDataType(_dataTypeId).Configuration; // TODO: inject
var valueEditor = editor.GetValueEditor(configuration);
return !valueEditor.Validate(value, Mandatory, ValidationRegExp).Any();
}

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