Merge branch 'temp8' into temp8-U4-11173

This commit is contained in:
Robert
2018-05-01 08:27:45 +02:00
524 changed files with 5130 additions and 22548 deletions
+13
View File
@@ -15,3 +15,16 @@ indent_size = 4
# Trim trailing whitespace, limited support.
# https://github.com/editorconfig/editorconfig/wiki/Property-research:-Trim-trailing-spaces
trim_trailing_whitespace = true
[*.{cs,vb}]
dotnet_style_predefined_type_for_locals_parameters_members = true:error
dotnet_naming_rule.private_members_with_underscore.symbols = private_fields
dotnet_naming_rule.private_members_with_underscore.style = prefix_underscore
dotnet_naming_rule.private_members_with_underscore.severity = suggestion
dotnet_naming_symbols.private_fields.applicable_kinds = field
dotnet_naming_symbols.private_fields.applicable_accessibilities = private
dotnet_naming_style.prefix_underscore.capitalization = camel_case
dotnet_naming_style.prefix_underscore.required_prefix = _
@@ -86,9 +86,6 @@
<add application="developer" alias="relationTypes" title="Relation Types" type="umbraco.loadRelationTypes, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="4"
xdt:Locator="Match(application,alias)"
xdt:Transform="SetAttributes()" />
<add initialize="true" sortOrder="5" alias="xslt" application="developer" iconClosed="icon-folder" iconOpen="icon-folder-open" type="Umbraco.Web.Trees.XsltTreeController, umbraco"
xdt:Locator="Match(application,alias)"
xdt:Transform="SetAttributes()" />
<add application="developer" alias="partialViewMacros" type="Umbraco.Web.Trees.PartialViewMacrosTree, umbraco"
xdt:Locator="Match(application,alias,type)"
@@ -5,4 +5,6 @@
</content>
<webservices xdt:Transform="Remove" />
<repositories xdt:Transform="Remove" />
</settings>
-2
View File
@@ -372,8 +372,6 @@
Write-Host "Add web.config transforms to NuGet package"
mv "$($this.BuildTemp)\WebApp\Views\Web.config" "$($this.BuildTemp)\WebApp\Views\Web.config.transform"
# fixme - that one does not exist in .bat build either?
#mv "$($this.BuildTemp)\WebApp\Xslt\Web.config" "$($this.BuildTemp)\WebApp\Xslt\Web.config.transform"
})
$ubuild.DefineMethod("RestoreNuGet",
+2 -44
View File
@@ -22,9 +22,7 @@ namespace Umbraco.Core.Cache
[UmbracoWillObsolete("This cache key is only used for the legacy 'library' caching, remove in v8")]
public const string MediaCacheKey = "UL_GetMedia";
public const string MacroXsltCacheKey = "macroXslt_";
[UmbracoWillObsolete("This cache key is only used for legacy business logic caching, remove in v8")]
public const string MacroCacheKey = "UmbracoMacroCache";
@@ -39,54 +37,14 @@ namespace Umbraco.Core.Cache
[UmbracoWillObsolete("This cache key is only used for legacy template business logic caching, remove in v8")]
public const string TemplateFrontEndCacheKey = "template";
[Obsolete("This is no longer used and will be removed from the codebase in the future")]
[EditorBrowsable(EditorBrowsableState.Never)]
public const string TemplateBusinessLogicCacheKey = "UmbracoTemplateCache";
[Obsolete("This is no longer used and will be removed from the codebase in the future")]
[EditorBrowsable(EditorBrowsableState.Never)]
public const string UserContextCacheKey = "UmbracoUserContext";
public const string UserContextTimeoutCacheKey = "UmbracoUserContextTimeout";
[Obsolete("This is no longer used and will be removed from the codebase in the future")]
[EditorBrowsable(EditorBrowsableState.Never)]
public const string UserCacheKey = "UmbracoUser";
[Obsolete("This is no longer used and will be removed from the codebase in the future")]
[EditorBrowsable(EditorBrowsableState.Never)]
public const string UserGroupPermissionsCacheKey = "UmbracoUserGroupPermissions";
[UmbracoWillObsolete("This cache key is only used for legacy business logic caching, remove in v8")]
public const string ContentTypeCacheKey = "UmbracoContentType";
[UmbracoWillObsolete("This cache key is only used for legacy business logic caching, remove in v8")]
public const string ContentTypePropertiesCacheKey = "ContentType_PropertyTypes_Content:";
[Obsolete("No longer used and will be removed in v8")]
public const string PropertyTypeCacheKey = "UmbracoPropertyTypeCache";
[Obsolete("This is no longer used and will be removed from the codebase in the future")]
[EditorBrowsable(EditorBrowsableState.Never)]
public const string LanguageCacheKey = "UmbracoLanguageCache";
[Obsolete("This is no longer used and will be removed from the codebase in the future")]
[EditorBrowsable(EditorBrowsableState.Never)]
public const string DomainCacheKey = "UmbracoDomainList";
[Obsolete("This is no longer used and will be removed from the codebase in the future")]
[EditorBrowsable(EditorBrowsableState.Never)]
public const string StylesheetCacheKey = "UmbracoStylesheet";
[Obsolete("This is no longer used and will be removed from the codebase in the future")]
[EditorBrowsable(EditorBrowsableState.Never)]
public const string StylesheetPropertyCacheKey = "UmbracoStylesheetProperty";
[Obsolete("This is no longer used and will be removed from the codebase in the future")]
[EditorBrowsable(EditorBrowsableState.Never)]
public const string DataTypeCacheKey = "UmbracoDataTypeDefinition";
public const string DataTypePreValuesCacheKey = "UmbracoPreVal";
public const string IdToKeyCacheKey = "UI2K__";
public const string KeyToIdCacheKey = "UK2I__";
}
@@ -76,7 +76,6 @@ namespace Umbraco.Core.Composing.CompositionRoots
container.RegisterSingleton<IPartialViewRepository, PartialViewRepository>();
container.RegisterSingleton<IScriptRepository, ScriptRepository>();
container.RegisterSingleton<IStylesheetRepository, StylesheetRepository>();
container.RegisterSingleton<IXsltFileRepository, XsltFileRepository>();
}
}
}
@@ -1,47 +0,0 @@
using System.Collections.Generic;
using System.Configuration;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class DeveloperElement : ConfigurationElement, IDeveloperSection
{
private AppCodeFileExtensionsElement _default;
[ConfigurationProperty("appCodeFileExtensions")]
internal AppCodeFileExtensionsElement AppCodeFileExtensions
{
get
{
if (_default != null)
{
return _default;
}
//here we need to check if this element is defined, if it is not then we'll setup the defaults
var prop = Properties["appCodeFileExtensions"];
var autoFill = this[prop] as ConfigurationElement;
if (autoFill != null && autoFill.ElementInformation.IsPresent == false)
{
var collection = new AppCodeFileExtensionsCollection
{
new FileExtensionElement {RawValue = "cs"},
new FileExtensionElement {RawValue = "vb"}
};
_default = new AppCodeFileExtensionsElement
{
AppCodeFileExtensionsCollection = collection
};
return _default;
}
return (AppCodeFileExtensionsElement)base["appCodeFileExtensions"];
}
}
IEnumerable<IFileExtension> IDeveloperSection.AppCodeFileExtensions
{
get { return AppCodeFileExtensions.AppCodeFileExtensionsCollection; }
}
}
}
@@ -1,48 +0,0 @@
using System.Collections.Generic;
using System.Configuration;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class DistributedCallElement : ConfigurationElement, IDistributedCallSection
{
[ConfigurationProperty("enable", DefaultValue = false)]
internal bool Enabled
{
get { return (bool)base["enable"]; }
}
[ConfigurationProperty("user")]
internal InnerTextConfigurationElement<int> UserId
{
get
{
return new OptionalInnerTextConfigurationElement<int>(
(InnerTextConfigurationElement<int>)this["user"],
//set the default
0);
}
}
[ConfigurationCollection(typeof(ServerCollection), AddItemName = "server")]
[ConfigurationProperty("servers", IsDefaultCollection = true)]
internal ServerCollection Servers
{
get { return (ServerCollection)base["servers"]; }
}
bool IDistributedCallSection.Enabled
{
get { return Enabled; }
}
int IDistributedCallSection.UserId
{
get { return UserId; }
}
IEnumerable<IServer> IDistributedCallSection.Servers
{
get { return Servers; }
}
}
}
@@ -1,9 +0,0 @@
using System.Collections.Generic;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
public interface IDeveloperSection : IUmbracoConfigurationSection
{
IEnumerable<IFileExtension> AppCodeFileExtensions { get; }
}
}
@@ -1,13 +0,0 @@
using System.Collections.Generic;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
public interface IDistributedCallSection : IUmbracoConfigurationSection
{
bool Enabled { get; }
int UserId { get; }
IEnumerable<IServer> Servers { get; }
}
}
@@ -1,20 +0,0 @@
using System;
using System.ComponentModel;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("This is no longer used and will be removed in future versions")]
public interface ILink
{
string Application { get; }
string ApplicationUrl { get; }
string Language { get; }
string UserType { get; }
string HelpUrl { get; }
}
}
@@ -1,10 +0,0 @@
using System.Collections.Generic;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
public interface IRepositoriesSection : IUmbracoConfigurationSection
{
IEnumerable<IRepository> Repositories { get; }
}
}
@@ -1,14 +0,0 @@
using System;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
public interface IRepository
{
string Name { get; }
Guid Id { get; }
string RepositoryUrl { get; }
string WebServiceUrl { get; }
bool HasCustomWebServiceUrl { get; }
string RestApiUrl { get; }
}
}
@@ -1,12 +0,0 @@
namespace Umbraco.Core.Configuration.UmbracoSettings
{
public interface IServer
{
string ForcePortnumber { get; }
string ForceProtocol { get; }
string ServerAddress { get; }
string AppId { get; }
string ServerName { get; }
}
}
@@ -4,13 +4,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
{
public interface ITemplatesSection : IUmbracoConfigurationSection
{
bool UseAspNetMasterPages { get; }
bool EnableSkinSupport { get; }
RenderingEngine DefaultRenderingEngine { get; }
[Obsolete("This has no affect and will be removed in future versions")]
bool EnableTemplateFolders { get; }
}
}
@@ -14,18 +14,11 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
IRequestHandlerSection RequestHandler { get; }
ITemplatesSection Templates { get; }
IDeveloperSection Developer { get; }
ILoggingSection Logging { get; }
IScheduledTasksSection ScheduledTasks { get; }
IDistributedCallSection DistributedCall { get; }
IRepositoriesSection PackageRepositories { get; }
IProvidersSection Providers { get; }
IWebRoutingSection WebRouting { get; }
@@ -1,36 +0,0 @@
using System.Collections.Generic;
using System.Configuration;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class RepositoriesCollection : ConfigurationElementCollection, IEnumerable<IRepository>
{
internal void Add(RepositoryElement item)
{
BaseAdd(item);
}
protected override ConfigurationElement CreateNewElement()
{
return new RepositoryElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((RepositoryElement)element).Id;
}
IEnumerator<IRepository> IEnumerable<IRepository>.GetEnumerator()
{
for (var i = 0; i < Count; i++)
{
yield return BaseGet(i) as IRepository;
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
@@ -1,23 +0,0 @@
using System;
using System.Collections.Generic;
using System.Configuration;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class RepositoriesElement : ConfigurationElement, IRepositoriesSection
{
[ConfigurationCollection(typeof(RepositoriesCollection), AddItemName = "repository")]
[ConfigurationProperty("", IsDefaultCollection = true)]
internal RepositoriesCollection Repositories
{
get { return (RepositoriesCollection) base[""]; }
set { base[""] = value; }
}
IEnumerable<IRepository> IRepositoriesSection.Repositories
{
get { return Repositories; }
}
}
}
@@ -1,19 +0,0 @@
using System;
using System.Linq;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
public static class RepositoryConfigExtensions
{
//Our package repo
private static readonly Guid RepoGuid = new Guid("65194810-1f85-11dd-bd0b-0800200c9a66");
public static IRepository GetDefault(this IRepositoriesSection repos)
{
var found = repos.Repositories.FirstOrDefault(x => x.Id == RepoGuid);
if (found == null)
throw new InvalidOperationException("No default package repository found with id " + RepoGuid);
return found;
}
}
}
@@ -1,53 +0,0 @@
using System;
using System.Configuration;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class RepositoryElement : ConfigurationElement, IRepository
{
[ConfigurationProperty("name", IsRequired = true)]
public string Name
{
get { return (string)base["name"]; }
set { base["name"] = value; }
}
[ConfigurationProperty("guid", IsRequired = true)]
public Guid Id
{
get { return (Guid)base["guid"]; }
set { base["guid"] = value; }
}
[ConfigurationProperty("repositoryurl", DefaultValue = "http://packages.umbraco.org")]
public string RepositoryUrl
{
get { return (string)base["repositoryurl"]; }
set { base["repositoryurl"] = value; }
}
[ConfigurationProperty("webserviceurl", DefaultValue = "/umbraco/webservices/api/repository.asmx")]
public string WebServiceUrl
{
get { return (string)base["webserviceurl"]; }
set { base["webserviceurl"] = value; }
}
public bool HasCustomWebServiceUrl
{
get
{
var prop = Properties["webserviceurl"];
return (string) prop.DefaultValue != (string) this[prop];
}
}
[ConfigurationProperty("restapiurl", DefaultValue = "https://our.umbraco.org/webapi/packages/v1")]
public string RestApiUrl
{
get { return (string)base["restapiurl"]; }
set { base["restapiurl"] = value; }
}
}
}
@@ -41,7 +41,7 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
[ConfigurationProperty("authCookieName")]
internal InnerTextConfigurationElement<string> AuthCookieName
{
get { return GetOptionalTextElement("authCookieName", Constants.Web.AuthCookieName); }
get { return GetOptionalTextElement("authCookieName", "UMB_UCONTEXT"); }
}
[ConfigurationProperty("authCookieDomain")]
@@ -1,31 +0,0 @@
using System.Collections.Generic;
using System.Configuration;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class ServerCollection : ConfigurationElementCollection, IEnumerable<IServer>
{
protected override ConfigurationElement CreateNewElement()
{
return new ServerElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((ServerElement)element).Value;
}
IEnumerator<IServer> IEnumerable<IServer>.GetEnumerator()
{
for (var i = 0; i < Count; i++)
{
yield return BaseGet(i) as IServer;
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
@@ -1,49 +0,0 @@
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class ServerElement : InnerTextConfigurationElement<string>, IServer
{
public string ForcePortnumber
{
get
{
return RawXml.Attribute("forcePortnumber") == null
? null
: RawXml.Attribute("forcePortnumber").Value;
}
}
public string ForceProtocol
{
get
{
return RawXml.Attribute("forceProtocol") == null
? null
: RawXml.Attribute("forceProtocol").Value;
}
}
string IServer.ServerAddress
{
get { return Value; }
}
public string AppId
{
get
{
return RawXml.Attribute("appId") == null
? null
: RawXml.Attribute("appId").Value;
}
}
public string ServerName
{
get
{
return RawXml.Attribute("serverName") == null
? null
: RawXml.Attribute("serverName").Value;
}
}
}
}
@@ -5,50 +5,16 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class TemplatesElement : UmbracoConfigurationElement, ITemplatesSection
{
[ConfigurationProperty("useAspNetMasterPages")]
internal InnerTextConfigurationElement<bool> UseAspNetMasterPages
{
get { return GetOptionalTextElement("useAspNetMasterPages", true); }
}
[ConfigurationProperty("enableSkinSupport")]
internal InnerTextConfigurationElement<bool> EnableSkinSupport
{
get { return GetOptionalTextElement("enableSkinSupport", true); }
}
[ConfigurationProperty("defaultRenderingEngine", IsRequired = true)]
internal InnerTextConfigurationElement<RenderingEngine> DefaultRenderingEngine
{
get { return GetOptionalTextElement("defaultRenderingEngine", RenderingEngine.Mvc); }
}
[Obsolete("This has no affect and will be removed in future versions")]
[ConfigurationProperty("enableTemplateFolders")]
internal InnerTextConfigurationElement<bool> EnableTemplateFolders
{
get { return GetOptionalTextElement("enableTemplateFolders", false); }
}
bool ITemplatesSection.UseAspNetMasterPages
{
get { return UseAspNetMasterPages; }
}
bool ITemplatesSection.EnableSkinSupport
{
get { return EnableSkinSupport; }
}
RenderingEngine ITemplatesSection.DefaultRenderingEngine
{
get { return DefaultRenderingEngine; }
}
[Obsolete("This has no affect and will be removed in future versions")]
bool ITemplatesSection.EnableTemplateFolders
{
get { return EnableTemplateFolders; }
}
}
}
@@ -12,7 +12,7 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
internal BackOfficeElement BackOffice
{
get { return (BackOfficeElement)this["backOffice"]; }
}
}
[ConfigurationProperty("content")]
internal ContentElement Content
@@ -37,14 +37,7 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
{
get { return (TemplatesElement)this["templates"]; }
}
[ConfigurationProperty("developer")]
internal DeveloperElement Developer
{
get { return (DeveloperElement)this["developer"]; }
}
[ConfigurationProperty("logging")]
internal LoggingElement Logging
{
@@ -57,55 +50,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
get { return (ScheduledTasksElement)this["scheduledTasks"]; }
}
[ConfigurationProperty("distributedCall")]
internal DistributedCallElement DistributedCall
{
get { return (DistributedCallElement)this["distributedCall"]; }
}
private RepositoriesElement _defaultRepositories;
[ConfigurationProperty("repositories")]
internal RepositoriesElement PackageRepositories
{
get
{
if (_defaultRepositories != null)
{
return _defaultRepositories;
}
//here we need to check if this element is defined, if it is not then we'll setup the defaults
var prop = Properties["repositories"];
var repos = this[prop] as ConfigurationElement;
if (repos != null && repos.ElementInformation.IsPresent == false)
{
var collection = new RepositoriesCollection
{
new RepositoryElement() {Name = "Umbraco package Repository", Id = new Guid("65194810-1f85-11dd-bd0b-0800200c9a66")}
};
_defaultRepositories = new RepositoriesElement()
{
Repositories = collection
};
return _defaultRepositories;
}
//now we need to ensure there is *always* our umbraco repo! its hard coded in the codebase!
var reposElement = (RepositoriesElement)base["repositories"];
if (reposElement.Repositories.All(x => x.Id != new Guid("65194810-1f85-11dd-bd0b-0800200c9a66")))
{
reposElement.Repositories.Add(new RepositoryElement() { Name = "Umbraco package Repository", Id = new Guid("65194810-1f85-11dd-bd0b-0800200c9a66") });
}
return reposElement;
}
}
[ConfigurationProperty("providers")]
internal ProvidersElement Providers
{
@@ -141,11 +85,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
IBackOfficeSection IUmbracoSettingsSection.BackOffice
{
get { return BackOffice; }
}
IDeveloperSection IUmbracoSettingsSection.Developer
{
get { return Developer; }
}
ILoggingSection IUmbracoSettingsSection.Logging
@@ -157,17 +96,7 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
{
get { return ScheduledTasks; }
}
IDistributedCallSection IUmbracoSettingsSection.DistributedCall
{
get { return DistributedCall; }
}
IRepositoriesSection IUmbracoSettingsSection.PackageRepositories
{
get { return PackageRepositories; }
}
IProvidersSection IUmbracoSettingsSection.Providers
{
get { return Providers; }
+1 -3
View File
@@ -121,9 +121,7 @@
public const string Templates = "templates";
public const string RelationTypes = "relationTypes";
public const string Xslt = "xslt";
public const string Languages = "languages";
/// <summary>
-1
View File
@@ -21,7 +21,6 @@
public const string StylesheetFileSystem = "StylesheetFileSystem";
public const string MasterpageFileSystem = "MasterpageFileSystem";
public const string ViewFileSystem = "ViewFileSystem";
public const string XsltFileSystem = "XsltFileSystem";
public const string JavascriptLibraryFileSystem = "JavascriptLibraryFileSystem";
}
}
@@ -0,0 +1,15 @@
namespace Umbraco.Core
{
public static partial class Constants
{
/// <summary>
/// Defines the constants used for the Umbraco package repository
/// </summary>
public static class PackageRepository
{
public const string RestApiBaseUrl = "https://our.umbraco.org/webapi/packages/v1";
public const string DefaultRepositoryName = "Umbraco package Repository";
public const string DefaultRepositoryId = "65194810-1f85-11dd-bd0b-0800200c9a66";
}
}
}
-7
View File
@@ -23,13 +23,6 @@ namespace Umbraco.Core
public const string InstallerCookieName = "umb_installId";
/// <summary>
/// The auth cookie name
/// </summary>
[Obsolete("DO NOT USE THIS, USE ISecuritySection.AuthCookieName, this will be removed in future versions")]
[EditorBrowsable(EditorBrowsableState.Never)]
public const string AuthCookieName = "UMB_UCONTEXT";
}
}
}
@@ -19,7 +19,7 @@ namespace Umbraco.Core.Events
/// <summary>
/// Filename, file path, fully qualified class name, or other key used by the macro engine to do it's processing of the faulting macro.
/// </summary>
public string ItemKey { get; set; }
public string MacroSource { get; set; }
/// <summary>
/// Exception raised.
+2 -15
View File
@@ -26,7 +26,6 @@ namespace Umbraco.Core.IO
private ShadowWrapper _partialViewsFileSystem;
private ShadowWrapper _stylesheetsFileSystem;
private ShadowWrapper _scriptsFileSystem;
private ShadowWrapper _xsltFileSystem;
private ShadowWrapper _masterPagesFileSystem;
private ShadowWrapper _mvcViewsFileSystem;
private ShadowWrapper _javaScriptLibraryFileSystem;
@@ -103,16 +102,7 @@ namespace Umbraco.Core.IO
return _scriptsFileSystem;
}
}
public IFileSystem XsltFileSystem
{
get
{
if (Volatile.Read(ref _wkfsInitialized) == false) EnsureWellKnownFileSystems();
return _xsltFileSystem;
}
}
public IFileSystem MasterPagesFileSystem
{
get
@@ -163,7 +153,6 @@ namespace Umbraco.Core.IO
var partialViewsFileSystem = new PhysicalFileSystem(SystemDirectories.PartialViews);
var stylesheetsFileSystem = new PhysicalFileSystem(SystemDirectories.Css);
var scriptsFileSystem = new PhysicalFileSystem(SystemDirectories.Scripts);
var xsltFileSystem = new PhysicalFileSystem(SystemDirectories.Xslt);
var masterPagesFileSystem = new PhysicalFileSystem(SystemDirectories.Masterpages);
var mvcViewsFileSystem = new PhysicalFileSystem(SystemDirectories.MvcViews);
var javaScriptLibraryFileSystem = new PhysicalFileSystem(SystemDirectories.JavaScriptLibrary);
@@ -172,7 +161,6 @@ namespace Umbraco.Core.IO
_partialViewsFileSystem = new ShadowWrapper(partialViewsFileSystem, "Views/Partials", () => IsScoped());
_stylesheetsFileSystem = new ShadowWrapper(stylesheetsFileSystem, "css", () => IsScoped());
_scriptsFileSystem = new ShadowWrapper(scriptsFileSystem, "scripts", () => IsScoped());
_xsltFileSystem = new ShadowWrapper(xsltFileSystem, "xslt", () => IsScoped());
_masterPagesFileSystem = new ShadowWrapper(masterPagesFileSystem, "masterpages", () => IsScoped());
_mvcViewsFileSystem = new ShadowWrapper(mvcViewsFileSystem, "Views", () => IsScoped());
_javascriptLibraryFileSystem = new ShadowWrapper(javaScriptLibraryFileSystem, "Lib", () => IsScoped());
@@ -366,14 +354,13 @@ namespace Umbraco.Core.IO
if (Volatile.Read(ref _wkfsInitialized) == false) EnsureWellKnownFileSystems();
var typed = _wrappers.ToArray();
var wrappers = new ShadowWrapper[typed.Length + 7];
var wrappers = new ShadowWrapper[typed.Length + 6];
var i = 0;
while (i < typed.Length) wrappers[i] = typed[i++];
wrappers[i++] = _macroPartialFileSystem;
wrappers[i++] = _partialViewsFileSystem;
wrappers[i++] = _stylesheetsFileSystem;
wrappers[i++] = _scriptsFileSystem;
wrappers[i++] = _xsltFileSystem;
wrappers[i++] = _masterPagesFileSystem;
wrappers[i] = _mvcViewsFileSystem;
+1 -7
View File
@@ -27,13 +27,7 @@ namespace Umbraco.Core.IO
{
return _masterPageFileSystem.FileExists(GetFilePath(t));
}
[Obsolete("This is only used for legacy purposes and will be removed in future versions")]
internal string GetPhysicalFilePath(ITemplate t)
{
return _masterPageFileSystem.GetFullPath(GetFilePath(t.Alias));
}
private string GetFilePath(ITemplate t)
{
return GetFilePath(t.Alias);
-2
View File
@@ -46,8 +46,6 @@ namespace Umbraco.Core.IO
public static string WebServices => IOHelper.ReturnPath("umbracoWebservicesPath", Umbraco.EnsureEndsWith("/") + "webservices");
public static string Xslt => IOHelper.ReturnPath("umbracoXsltPath", "~/xslt");
//by default the packages folder should exist in the data folder
public static string Packages => IOHelper.ReturnPath("umbracoPackagesPath", Data + IOHelper.DirSepChar + "packages");
+3 -4
View File
@@ -67,10 +67,9 @@ namespace Umbraco.Core.IO
modelNamespaceAlias = "ContentModels";
// either
// @inherits Umbraco.Web.Mvc.UmbracoTemplatePage
// @inherits Umbraco.Web.Mvc.UmbracoTemplatePage<ModelClass>
// @inherits Umbraco.Web.Mvc.UmbracoTemplatePage<ContentModels.ModelClass>
content.Append("@inherits Umbraco.Web.Mvc.UmbracoTemplatePage");
// @inherits Umbraco.Web.Mvc.UmbracoViewPage
// @inherits Umbraco.Web.Mvc.UmbracoViewPage<ModelClass>
content.Append("@inherits Umbraco.Web.Mvc.UmbracoViewPage");
if (modelClassName.IsNullOrWhiteSpace() == false)
{
content.Append("<");
@@ -1,21 +0,0 @@
// fixme - remove this file
//using log4net.Core;
//using log4net.Util;
//using System;
//using System.Collections.Concurrent;
//using System.Threading;
//using System.Threading.Tasks;
//namespace Umbraco.Core.Logging
//{
// /// <summary>
// /// An asynchronous appender based on <see cref="BlockingCollection{T}"/>
// /// </summary>
// /// <remarks>
// /// Borrowed from https://github.com/cjbhaines/Log4Net.Async - will reference Nuget packages directly in v8
// /// </remarks>
// [Obsolete("Use the Log4Net.Async.ParallelForwardingAppender instead this will be removed in future versions")]
// public class ParallelForwardingAppender : Log4Net.Async.ParallelForwardingAppender
// {
// }
//}
+1 -1
View File
@@ -179,7 +179,7 @@ namespace Umbraco.Core.Macros
// Check whether it's a single tag (<?.../>) or a tag with children (<?..>...</?...>)
if (tag.Substring(tag.Length - 2, 1) != "/" && tag.IndexOf(" ") > -1)
{
String closingTag = "</" + (tag.Substring(1, tag.IndexOf(" ") - 1)) + ">";
string closingTag = "</" + (tag.Substring(1, tag.IndexOf(" ") - 1)) + ">";
// Tag with children are only used when a macro is inserted by the umbraco-editor, in the
// following format: "<?UMBRACO_MACRO ...><IMG SRC="..."..></?UMBRACO_MACRO>", so we
// need to delete extra information inserted which is the image-tag and the closing
-17
View File
@@ -1,17 +0,0 @@
namespace Umbraco.Core.Macros
{
/// <summary>
/// Encapsulates what an xslt extension object is when used for macros
/// </summary>
internal sealed class XsltExtension
{
public XsltExtension(string ns, object extensionObject)
{
Namespace = ns;
ExtensionObject = extensionObject;
}
public string Namespace { get; private set; }
public object ExtensionObject { get; private set; }
}
}
@@ -1,33 +0,0 @@
using System;
using System.Security.Permissions;
using System.Web;
namespace Umbraco.Core.Macros
{
/// <summary>
/// Allows App_Code XSLT extensions to be declared using the [XsltExtension] class attribute.
/// </summary>
/// <remarks>
/// An optional XML namespace can be specified using [XsltExtension("MyNamespace")].
/// </remarks>
[AttributeUsage(AttributeTargets.Class)]
public class XsltExtensionAttribute : Attribute
{
public XsltExtensionAttribute()
{
Namespace = String.Empty;
}
public XsltExtensionAttribute(string ns)
{
Namespace = ns;
}
public string Namespace { get; set; }
public override string ToString()
{
return Namespace;
}
}
}
@@ -1,12 +0,0 @@
using System.Collections.Generic;
using Umbraco.Core.Composing;
namespace Umbraco.Core.Macros
{
internal class XsltExtensionCollection : BuilderCollectionBase<XsltExtension>
{
public XsltExtensionCollection(IEnumerable<XsltExtension> items)
: base(items)
{ }
}
}
@@ -1,78 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using LightInject;
using Umbraco.Core.Composing;
namespace Umbraco.Core.Macros
{
// that one is special since it's not initialized with XsltExtension types, but with Xslt extension object types,
// which are then wrapped in an XsltExtension object when the collection is created. so, cannot really inherit
// from (Lazy)CollectionBuilderBase and have to re-implement it. but almost everything is copied from CollectionBuilderBase.
internal class XsltExtensionCollectionBuilder : ICollectionBuilder<XsltExtensionCollection, XsltExtension>
{
private readonly IServiceContainer _container;
private readonly List<Func<IEnumerable<Type>>> _producers = new List<Func<IEnumerable<Type>>>();
private readonly object _locker = new object();
private ServiceRegistration[] _registrations;
public XsltExtensionCollectionBuilder(IServiceContainer container)
{
_container = container;
// register the collection
container.Register(_ => CreateCollection(), new PerContainerLifetime());
}
public static XsltExtensionCollectionBuilder Register(IServiceContainer container)
{
// register the builder - per container
var builderLifetime = new PerContainerLifetime();
container.Register<XsltExtensionCollectionBuilder>(builderLifetime);
return container.GetInstance<XsltExtensionCollectionBuilder>();
}
public XsltExtensionCollectionBuilder AddExtensionObjectProducer(Func<IEnumerable<Type>> producer)
{
lock (_locker)
{
if (_registrations != null)
throw new InvalidOperationException("Cannot configure a collection builder after its types have been resolved.");
_producers.Add(producer);
}
return this;
}
private void RegisterTypes()
{
lock (_locker)
{
if (_registrations != null) return;
var prefix = GetType().FullName + "_";
var i = 0;
foreach (var type in _producers.SelectMany(x => x()).Distinct())
{
var name = $"{prefix}{i++:00000}";
_container.Register(type, type, name);
}
_registrations = _container.AvailableServices
.Where(x => x.ServiceName.StartsWith(prefix))
.OrderBy(x => x.ServiceName)
.ToArray();
}
}
public XsltExtensionCollection CreateCollection()
{
RegisterTypes(); // will do it only once
var exts = _registrations.SelectMany(r => r.ServiceType.GetCustomAttributes<XsltExtensionAttribute>(true)
.Select(a => new XsltExtension(a.Namespace.IfNullOrWhiteSpace(r.ServiceType.FullName), _container.GetInstance(r.ServiceType, r.ServiceName))));
return new XsltExtensionCollection(exts);
}
}
}
@@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
namespace Umbraco.Core.Media
{
// note: because this interface is obsolete is is *not* IDiscoverable, and in case the
// TypeLoader is asked to find types implementing this interface it will fall back
// to a complete scan.
[Obsolete("IImageUrlProvider is no longer used and will be removed in future versions")]
public interface IImageUrlProvider // IDiscoverable
{
string Name { get; }
string GetImageUrlFromMedia(int mediaId, IDictionary<string, string> parameters);
string GetImageUrlFromFileName(string specifiedSrc, IDictionary<string, string> parameters);
}
}
@@ -1,16 +0,0 @@
using System;
namespace Umbraco.Core.Media
{
// note: because this interface is obsolete is is *not* IDiscoverable, and in case the
// TypeLoader is asked to find types implementing this interface it will fall back
// to a complete scan.
[Obsolete("Thumbnails are generated by ImageProcessor, use that instead")]
public interface IThumbnailProvider // : IDiscoverable
{
bool CanProvideThumbnail(string fileUrl);
string GetThumbnailUrl(string fileUrl);
}
}
@@ -118,9 +118,10 @@ namespace Umbraco.Core.Migrations.Upgrade
Chain<LanguageColumns>("{7F59355A-0EC9-4438-8157-EB517E6D2727}");
Chain<AddVariationTables1A>("{66B6821A-0DE3-4DF8-A6A4-65ABD211EDDE}");
Chain<AddVariationTables2>("{49506BAE-CEBB-4431-A1A6-24AD6EBBBC57}");
Chain<RefactorMacroColumns>("{083A9894-903D-41B7-B6B3-9EAF2D4CCED0}");
// must chain to v8 final state (see at end of file)
Chain("{76DF5CD7-A884-41A5-8DC6-7860D95B1DF5}");
Chain("{A7540C58-171D-462A-91C5-7A9AA5CB8BFD}");
// UPGRADE FROM 7, MORE RECENT
@@ -209,10 +210,12 @@ namespace Umbraco.Core.Migrations.Upgrade
// however, need to take care of ppl in post-AddVariationTables1 state
Add<AddVariationTables1A>("{941B2ABA-2D06-4E04-81F5-74224F1DB037}", "{76DF5CD7-A884-41A5-8DC6-7860D95B1DF5}");
Chain<RefactorMacroColumns>("{A7540C58-171D-462A-91C5-7A9AA5CB8BFD}");
// FINAL STATE - MUST MATCH LAST ONE ABOVE !
// whenever this changes, update all references in this file!
Add(string.Empty, "{76DF5CD7-A884-41A5-8DC6-7860D95B1DF5}");
Add(string.Empty, "{A7540C58-171D-462A-91C5-7A9AA5CB8BFD}");
}
}
}
@@ -1,4 +1,5 @@
using Umbraco.Core.Persistence.Dtos;
using System;
using Umbraco.Core.Persistence.Dtos;
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
{
@@ -26,7 +27,13 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
// was not used
Delete.Column("availableDate").FromTable(Constants.DatabaseSchema.Tables.ContentVersionCultureVariation).Do();
AddColumn<ContentVersionCultureVariationDto>("date");
//special trick to add the column without constraints and return the sql to add them later
AddColumn<ContentVersionCultureVariationDto>("date", out var sqls);
//now we need to update the new column with some values because this column doesn't allow NULL values
Update.Table(ContentVersionCultureVariationDto.TableName).Set(new {date = DateTime.Now}).AllRows().Do();
//now apply constraints (NOT NULL) to new table
foreach (var sql in sqls) Execute.Sql(sql).Do();
// name, languageId are now non-nullable
AlterColumn<ContentVersionCultureVariationDto>(Constants.DatabaseSchema.Tables.ContentVersionCultureVariation, "name");
@@ -0,0 +1,43 @@
using Umbraco.Core.Models;
using Umbraco.Core.Persistence.Dtos;
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
{
public class RefactorMacroColumns : MigrationBase
{
public RefactorMacroColumns(IMigrationContext context)
: base(context)
{ }
public override void Migrate()
{
if (ColumnExists(Constants.DatabaseSchema.Tables.Macro, "macroXSLT"))
{
//special trick to add the column without constraints and return the sql to add them later
AddColumn<MacroDto>("macroType", out var sqls1);
//now we need to update the new column with some values because this column doesn't allow NULL values
Update.Table(Constants.DatabaseSchema.Tables.Macro).Set(new { macroType = (int)MacroTypes.Unknown}).AllRows().Do();
//now apply constraints (NOT NULL) to new table
foreach (var sql in sqls1) Execute.Sql(sql).Do();
//special trick to add the column without constraints and return the sql to add them later
AddColumn<MacroDto>("macroSource", out var sqls2);
//populate the new macroSource column with legacy data
Execute.Sql($"UPDATE {Constants.DatabaseSchema.Tables.Macro} SET macroSource = macroXSLT, macroType = {(int)MacroTypes.Unknown} WHERE macroXSLT IS NOT NULL").Do();
Execute.Sql($"UPDATE {Constants.DatabaseSchema.Tables.Macro} SET macroSource = macroScriptAssembly, macroType = {(int)MacroTypes.Unknown} WHERE macroScriptAssembly IS NOT NULL").Do();
Execute.Sql($"UPDATE {Constants.DatabaseSchema.Tables.Macro} SET macroSource = macroScriptType, macroType = {(int)MacroTypes.UserControl} WHERE macroScriptType IS NOT NULL").Do();
Execute.Sql($"UPDATE {Constants.DatabaseSchema.Tables.Macro} SET macroSource = macroPython, macroType = {(int)MacroTypes.PartialView} WHERE macroPython IS NOT NULL").Do();
//now apply constraints (NOT NULL) to new table
foreach (var sql in sqls2) Execute.Sql(sql).Do();
//now remove these old columns
Delete.Column("macroXSLT").FromTable(Constants.DatabaseSchema.Tables.Macro).Do();
Delete.Column("macroScriptAssembly").FromTable(Constants.DatabaseSchema.Tables.Macro).Do();
Delete.Column("macroScriptType").FromTable(Constants.DatabaseSchema.Tables.Macro).Do();
Delete.Column("macroPython").FromTable(Constants.DatabaseSchema.Tables.Macro).Do();
}
}
}
}
+9 -7
View File
@@ -271,7 +271,7 @@ namespace Umbraco.Core.Models
}
/// <inheritdoc />
public IEnumerable<string> PublishedCultures => _publishInfos.Keys;
public IEnumerable<string> PublishedCultures => _publishInfos?.Keys ?? Enumerable.Empty<string>();
/// <inheritdoc />
public bool IsCultureEdited(string culture)
@@ -306,11 +306,11 @@ namespace Umbraco.Core.Models
public bool Blueprint { get; internal set; }
/// <inheritdoc />
public virtual bool PublishAllValues()
public virtual bool TryPublishAllValues()
{
// the values we want to publish should be valid
if (ValidateAll().Any())
return false;
return false; //fixme this should return an attempt with error results
// Name and PublishName are managed by the repository, but Names and PublishNames
// must be managed here as they depend on the existing / supported variations.
@@ -321,7 +321,8 @@ namespace Umbraco.Core.Models
foreach (var (culture, name) in Names)
{
if (string.IsNullOrWhiteSpace(name))
throw new InvalidOperationException($"Cannot publish {culture ?? "invariant"} culture without a name.");
return false; //fixme this should return an attempt with error results
SetPublishInfos(culture, name, now);
}
@@ -334,14 +335,14 @@ namespace Umbraco.Core.Models
}
/// <inheritdoc />
public virtual bool PublishValues(string culture = null, string segment = null)
public virtual bool TryPublishValues(string culture = null, string segment = null)
{
// the variation should be supported by the content type
ContentType.ValidateVariation(culture, segment, throwIfInvalid: true);
// the values we want to publish should be valid
if (Validate(culture, segment).Any())
return false;
return false; //fixme this should return an attempt with error results
// Name and PublishName are managed by the repository, but Names and PublishNames
// must be managed here as they depend on the existing / supported variations.
@@ -349,7 +350,8 @@ namespace Umbraco.Core.Models
{
var name = GetName(culture);
if (string.IsNullOrWhiteSpace(name))
throw new InvalidOperationException($"Cannot publish {culture ?? "invariant"} culture without a name.");
return false; //fixme this should return an attempt with error results
SetPublishInfos(culture, name, DateTime.Now);
}
+1 -1
View File
@@ -168,7 +168,7 @@ namespace Umbraco.Core.Models
public static bool HasPropertyTypeVaryingByCulture(this IContent content)
{
// fixme - what about CultureSegment? what about content.ContentType.Variations?
return content.PropertyTypes.Any(x => x.Variations == ContentVariation.CultureNeutral);
return content.PropertyTypes.Any(x => x.Variations.Has(ContentVariation.CultureNeutral));
}
#endregion
+1 -7
View File
@@ -146,13 +146,7 @@ namespace Umbraco.Core.Models
/// Gets or sets the file's virtual path (i.e. the file path relative to the root of the website)
/// </summary>
public string VirtualPath { get; set; }
[Obsolete("This is no longer used and will be removed from the codebase in future versions")]
public virtual bool IsValid()
{
return true;
}
// this exists so that class that manage name and alias differently, eg Template,
// can implement their own cloning - (though really, not sure it's even needed)
protected virtual void DeepCloneNameAndAlias(File clone)
+4 -2
View File
@@ -169,7 +169,8 @@ namespace Umbraco.Core.Models
/// <para>The document must then be published via the content service.</para>
/// <para>Values are not published if they are not valie.</para>
/// </remarks>
bool PublishAllValues();
//fixme return an Attempt with some error results if it doesn't work
bool TryPublishAllValues();
/// <summary>
/// Publishes values.
@@ -179,7 +180,8 @@ namespace Umbraco.Core.Models
/// <para>The document must then be published via the content service.</para>
/// <para>Values are not published if they are not valid.</para>
/// </remarks>
bool PublishValues(string culture = null, string segment = null);
//fixme return an Attempt with some error results if it doesn't work
bool TryPublishValues(string culture = null, string segment = null);
/// <summary>
/// Publishes the culture/any values.
+1 -3
View File
@@ -43,8 +43,6 @@ namespace Umbraco.Core.Models
/// Gets or sets the file's virtual path (i.e. the file path relative to the root of the website)
/// </summary>
string VirtualPath { get; set; }
[Obsolete("This is no longer used and will be removed from the codebase in future versions")]
bool IsValid();
}
}
+7 -23
View File
@@ -51,35 +51,19 @@ namespace Umbraco.Core.Models
/// </summary>
[DataMember]
bool DontRender { get; set; }
/// <summary>
/// Gets or sets the path to user control or the Control Type to render
/// Gets or set the path to the macro source to render
/// </summary>
[DataMember]
string ControlType { get; set; }
string MacroSource { get; set; }
/// <summary>
/// Gets or sets the name of the assembly, which should be used by the Macro
/// Gets or set the macro type
/// </summary>
/// <remarks>Will usually only be filled if the ScriptFile is a Usercontrol</remarks>
[DataMember]
[Obsolete("This is no longer used, we should remove it in v8, CustomControl macros are gone")]
string ControlAssembly { get; set; }
/// <summary>
/// Gets or set the path to the Python file in use
/// </summary>
/// <remarks>Optional: Can only be one of three Script, Python or Xslt</remarks>
[DataMember]
string ScriptPath { get; set; }
/// <summary>
/// Gets or sets the path to the Xslt file in use
/// </summary>
/// <remarks>Optional: Can only be one of three Script, Python or Xslt</remarks>
[DataMember]
string XsltPath { get; set; }
MacroTypes MacroType { get; set; }
/// <summary>
/// Gets or sets a list of Macro Properties
/// </summary>
-7
View File
@@ -1,7 +0,0 @@
namespace Umbraco.Core.Models
{
public interface IXsltFile : IFile
{
}
}
+23 -62
View File
@@ -34,14 +34,11 @@ namespace Umbraco.Core.Models
/// <param name="cacheDuration"></param>
/// <param name="alias"></param>
/// <param name="name"></param>
/// <param name="controlType"></param>
/// <param name="controlAssembly"></param>
/// <param name="xsltPath"></param>
/// <param name="cacheByPage"></param>
/// <param name="cacheByMember"></param>
/// <param name="dontRender"></param>
/// <param name="scriptPath"></param>
public Macro(int id, Guid key, bool useInEditor, int cacheDuration, string @alias, string name, string controlType, string controlAssembly, string xsltPath, bool cacheByPage, bool cacheByMember, bool dontRender, string scriptPath)
/// <param name="macroSource"></param>
public Macro(int id, Guid key, bool useInEditor, int cacheDuration, string @alias, string name, bool cacheByPage, bool cacheByMember, bool dontRender, string macroSource, MacroTypes macroType)
: this()
{
Id = id;
@@ -50,13 +47,11 @@ namespace Umbraco.Core.Models
CacheDuration = cacheDuration;
Alias = alias.ToCleanString(CleanStringType.Alias);
Name = name;
ControlType = controlType;
ControlAssembly = controlAssembly;
XsltPath = xsltPath;
CacheByPage = cacheByPage;
CacheByMember = cacheByMember;
DontRender = dontRender;
ScriptPath = scriptPath;
MacroSource = macroSource;
MacroType = macroType;
}
/// <summary>
@@ -66,18 +61,13 @@ namespace Umbraco.Core.Models
/// <param name="cacheDuration"></param>
/// <param name="alias"></param>
/// <param name="name"></param>
/// <param name="controlType"></param>
/// <param name="controlAssembly"></param>
/// <param name="xsltPath"></param>
/// <param name="cacheByPage"></param>
/// <param name="cacheByMember"></param>
/// <param name="dontRender"></param>
/// <param name="scriptPath"></param>
/// <param name="macroSource"></param>
public Macro(string @alias, string name,
string controlType = "",
string controlAssembly = "",
string xsltPath = "",
string scriptPath = "",
string macroSource,
MacroTypes macroType,
bool cacheByPage = false,
bool cacheByMember = false,
bool dontRender = true,
@@ -89,13 +79,11 @@ namespace Umbraco.Core.Models
CacheDuration = cacheDuration;
Alias = alias.ToCleanString(CleanStringType.Alias);
Name = name;
ControlType = controlType;
ControlAssembly = controlAssembly;
XsltPath = xsltPath;
CacheByPage = cacheByPage;
CacheByMember = cacheByMember;
DontRender = dontRender;
ScriptPath = scriptPath;
MacroSource = macroSource;
MacroType = macroType;
}
private string _alias;
@@ -105,10 +93,8 @@ namespace Umbraco.Core.Models
private bool _cacheByPage;
private bool _cacheByMember;
private bool _dontRender;
private string _scriptFile;
private string _scriptAssembly;
private string _scriptPath;
private string _xslt;
private string _macroSource;
private MacroTypes _macroType = MacroTypes.Unknown;
private MacroPropertyCollection _properties;
private List<string> _addedProperties;
private List<string> _removedProperties;
@@ -124,10 +110,8 @@ namespace Umbraco.Core.Models
public readonly PropertyInfo CacheByPageSelector = ExpressionHelper.GetPropertyInfo<Macro, bool>(x => x.CacheByPage);
public readonly PropertyInfo CacheByMemberSelector = ExpressionHelper.GetPropertyInfo<Macro, bool>(x => x.CacheByMember);
public readonly PropertyInfo DontRenderSelector = ExpressionHelper.GetPropertyInfo<Macro, bool>(x => x.DontRender);
public readonly PropertyInfo ControlPathSelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.ControlType);
public readonly PropertyInfo ControlAssemblySelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.ControlAssembly);
public readonly PropertyInfo ScriptPathSelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.ScriptPath);
public readonly PropertyInfo XsltPathSelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.XsltPath);
public readonly PropertyInfo ScriptPathSelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.MacroSource);
public readonly PropertyInfo MacroTypeSelector = ExpressionHelper.GetPropertyInfo<Macro, MacroTypes>(x => x.MacroType);
public readonly PropertyInfo PropertiesSelector = ExpressionHelper.GetPropertyInfo<Macro, MacroPropertyCollection>(x => x.Properties);
}
@@ -272,46 +256,23 @@ namespace Umbraco.Core.Models
}
/// <summary>
/// Gets or sets the path to user control or the Control Type to render
/// Gets or set the path to the Partial View to render
/// </summary>
[DataMember]
public string ControlType
public string MacroSource
{
get { return _scriptFile; }
set { SetPropertyValueAndDetectChanges(value, ref _scriptFile, Ps.Value.ControlPathSelector); }
}
get { return _macroSource; }
set { SetPropertyValueAndDetectChanges(value, ref _macroSource, Ps.Value.ScriptPathSelector); }
}
/// <summary>
/// Gets or sets the name of the assembly, which should be used by the Macro
/// Gets or set the path to the Partial View to render
/// </summary>
/// <remarks>Will usually only be filled if the ControlType is a Usercontrol</remarks>
[DataMember]
public string ControlAssembly
public MacroTypes MacroType
{
get { return _scriptAssembly; }
set { SetPropertyValueAndDetectChanges(value, ref _scriptAssembly, Ps.Value.ControlAssemblySelector); }
}
/// <summary>
/// Gets or set the path to the Python file in use
/// </summary>
/// <remarks>Optional: Can only be one of three Script, Python or Xslt</remarks>
[DataMember]
public string ScriptPath
{
get { return _scriptPath; }
set { SetPropertyValueAndDetectChanges(value, ref _scriptPath, Ps.Value.ScriptPathSelector); }
}
/// <summary>
/// Gets or sets the path to the Xslt file in use
/// </summary>
/// <remarks>Optional: Can only be one of three Script, Python or Xslt</remarks>
[DataMember]
public string XsltPath
{
get { return _xslt; }
set { SetPropertyValueAndDetectChanges(value, ref _xslt, Ps.Value.XsltPathSelector); }
get { return _macroType; }
set { SetPropertyValueAndDetectChanges(value, ref _macroType, Ps.Value.MacroTypeSelector); }
}
/// <summary>
-4
View File
@@ -10,15 +10,11 @@ namespace Umbraco.Core.Models
[DataContract(IsReference = true)]
public enum MacroTypes
{
[EnumMember]
Xslt = 1,
[EnumMember]
UserControl = 3,
[EnumMember]
Unknown = 4,
[EnumMember]
Script = 6,
[EnumMember]
PartialView = 7
}
}
+2 -14
View File
@@ -18,11 +18,7 @@ namespace Umbraco.Core.Models.Membership
int[] StartContentIds { get; set; }
int[] StartMediaIds { get; set; }
string Language { get; set; }
[Obsolete("This should not be used it exists for legacy reasons only, use user groups instead, it will be removed in future versions")]
[EditorBrowsable(EditorBrowsableState.Never)]
IUserType UserType { get; set; }
DateTime? EmailConfirmedDate { get; set; }
DateTime? InvitedDate { get; set; }
@@ -37,14 +33,6 @@ namespace Umbraco.Core.Models.Membership
IEnumerable<string> AllowedSections { get; }
[Obsolete("This should not be used it exists for legacy reasons only, use user groups instead, it will be removed in future versions")]
[EditorBrowsable(EditorBrowsableState.Never)]
void RemoveAllowedSection(string sectionAlias);
[Obsolete("This should not be used it exists for legacy reasons only, use user groups instead, it will be removed in future versions")]
[EditorBrowsable(EditorBrowsableState.Never)]
void AddAllowedSection(string sectionAlias);
/// <summary>
/// Exposes the basic profile data
/// </summary>
@@ -65,4 +53,4 @@ namespace Umbraco.Core.Models.Membership
/// </summary>
string TourData { get; set; }
}
}
}
@@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using Umbraco.Core.Models.Entities;
namespace Umbraco.Core.Models.Membership
{
[Obsolete("This should not be used it exists for legacy reasons only, use user groups instead, it will be removed in future versions")]
[EditorBrowsable(EditorBrowsableState.Never)]
public interface IUserType : IEntity
{
string Alias { get; set; }
string Name { get; set; }
IEnumerable<string> Permissions { get; set; }
}
}
-156
View File
@@ -284,162 +284,6 @@ namespace Umbraco.Core.Models.Membership
get { return _allowedSections ?? (_allowedSections = new List<string>(_userGroups.SelectMany(x => x.AllowedSections).Distinct())); }
}
[Obsolete("This should not be used it exists for legacy reasons only, use user groups instead, it will be removed in future versions")]
[EditorBrowsable(EditorBrowsableState.Never)]
IUserType IUser.UserType
{
get
{
//the best we can do here is to return the user's first user group as a IUserType object
//but we should attempt to return any group that is the built in ones first
var groups = Groups.ToArray();
if (groups.Length == 0)
{
//In backwards compatibility land, a user type cannot be null! so we need to return a fake one.
return new UserType
{
Alias = "temp",
Id = int.MinValue,
Key = Guid.Empty,
CreateDate = default(DateTime),
DeleteDate = null,
Name = "Temp",
Permissions = new List<string>(),
UpdateDate = default(DateTime)
};
}
var builtIns = new[] { Constants.Security.AdminGroupAlias, "writer", "editor", "translator" };
var foundBuiltIn = groups.FirstOrDefault(x => builtIns.Contains(x.Alias));
IUserGroup realGroup;
if (foundBuiltIn != null)
{
//if the group isn't IUserGroup we'll need to look it up
realGroup = foundBuiltIn as IUserGroup ?? Current.Services.UserService.GetUserGroupById(foundBuiltIn.Id);
//return a mapped version of the group
return new UserType
{
Alias = realGroup.Alias,
Id = realGroup.Id,
Key = realGroup.Key,
CreateDate = realGroup.CreateDate,
DeleteDate = realGroup.DeleteDate,
Name = realGroup.Name,
Permissions = realGroup.Permissions,
UpdateDate = realGroup.UpdateDate
};
}
//otherwise return the first
//if the group isn't IUserGroup we'll need to look it up
realGroup = groups[0] as IUserGroup ?? Current.Services.UserService.GetUserGroupById(groups[0].Id);
//return a mapped version of the group
return new UserType
{
Alias = realGroup.Alias,
Id = realGroup.Id,
Key = realGroup.Key,
CreateDate = realGroup.CreateDate,
DeleteDate = realGroup.DeleteDate,
Name = realGroup.Name,
Permissions = realGroup.Permissions,
UpdateDate = realGroup.UpdateDate
};
}
set
{
//if old APIs are still using this lets first check if the user is part of the user group with the alias specified
if (Groups.Any(x => x.Alias == value.Alias))
return;
//the only other option we have here is to lookup the group (and we'll need to use singletons here :( )
var found = Current.Services.UserService.GetUserGroupByAlias(value.Alias);
if (found == null)
throw new InvalidOperationException("No user group was found with the alias " + value.Alias + ", this API (IUser.UserType) is obsolete, use user groups instead");
//if it's found, all we can do is add it, we can't really replace them
AddGroup(found.ToReadOnlyGroup());
}
}
[Obsolete("This should not be used it exists for legacy reasons only, use user groups instead, it will be removed in future versions")]
[EditorBrowsable(EditorBrowsableState.Never)]
void IUser.RemoveAllowedSection(string sectionAlias)
{
//don't do anything if they aren't allowed it already
if (AllowedSections.Contains(sectionAlias) == false)
return;
var groups = Groups.ToArray();
//our only option here is to check if a custom group is created for this user, if so we can remove it from that group, otherwise we'll throw
//now we'll check if the user has a special 1:1 user group created for itself. This will occur if this method is used and also during an upgrade.
//this comes in the alias form of userName + 'Group'
var customUserGroup = groups.FirstOrDefault(x => x.Alias == (Username + "Group"));
if (customUserGroup != null)
{
//if the group isn't IUserGroup we'll need to look it up
var realGroup = customUserGroup as IUserGroup ?? Current.Services.UserService.GetUserGroupById(customUserGroup.Id);
realGroup.RemoveAllowedSection(sectionAlias);
//now we need to flag this for saving (hack!)
GroupsToSave.Add(realGroup);
}
else
{
throw new InvalidOperationException("Cannot remove the allowed section using this obsolete API. Modify the user's groups instead");
}
}
[Obsolete("This should not be used it exists for legacy reasons only, use user groups instead, it will be removed in future versions")]
[EditorBrowsable(EditorBrowsableState.Never)]
void IUser.AddAllowedSection(string sectionAlias)
{
//don't do anything if they are allowed it already
if (AllowedSections.Contains(sectionAlias))
return;
//This is here for backwards compat only.
//First we'll check if the user is part of the 'admin' group. If so then we can ensure that the admin group has this section available to it.
//otherwise, the only thing we can do is create a custom user group for this user and add this section.
//We are checking for admin here because if the user is an admin and an allowed section is being added, then it's assumed it's to be added
//for the whole admin group (i.e. Forms installer does this for admins)
var groups = Groups.ToArray();
var admin = groups.FirstOrDefault(x => x.Alias == Constants.Security.AdminGroupAlias);
if (admin != null)
{
//if the group isn't IUserGroup we'll need to look it up
var realGroup = admin as IUserGroup ?? Current.Services.UserService.GetUserGroupById(admin.Id);
realGroup.AddAllowedSection(sectionAlias);
//now we need to flag this for saving (hack!)
GroupsToSave.Add(realGroup);
}
else
{
//now we'll check if the user has a special 1:1 user group created for itself. This will occur if this method is used and also during an upgrade.
//this comes in the alias form of userName + 'Group'
var customUserGroup = groups.FirstOrDefault(x => x.Alias == (Username + "Group"));
if (customUserGroup != null)
{
//if the group isn't IUserGroup we'll need to look it up
var realGroup = customUserGroup as IUserGroup ?? Current.Services.UserService.GetUserGroupById(customUserGroup.Id);
realGroup.AddAllowedSection(sectionAlias);
//now we need to flag this for saving (hack!)
GroupsToSave.Add(realGroup);
}
//ok, so the user doesn't have a 1:1 group, we'll need to flag it for creation
var newUserGroup = new UserGroup
{
Alias = Username + "Group",
Name = "Group for " + Username
};
newUserGroup.AddAllowedSection(sectionAlias);
//add this user to this new group
AddGroup(newUserGroup);
GroupsToSave.Add(newUserGroup);
}
}
/// <summary>
/// This used purely for hacking backwards compatibility into this class for &lt; 7.7 compat
/// </summary>
@@ -1,78 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Models.Entities;
using Umbraco.Core.Strings;
namespace Umbraco.Core.Models.Membership
{
[Obsolete("This should not be used it exists for legacy reasons only, use user groups instead, it will be removed in future versions")]
[EditorBrowsable(EditorBrowsableState.Never)]
[Serializable]
[DataContract(IsReference = true)]
internal class UserType : EntityBase, IUserType
{
private string _alias;
private string _name;
private IEnumerable<string> _permissions;
private static readonly Lazy<PropertySelectors> Ps = new Lazy<PropertySelectors>();
private class PropertySelectors
{
public readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<UserType, string>(x => x.Name);
public readonly PropertyInfo AliasSelector = ExpressionHelper.GetPropertyInfo<UserType, string>(x => x.Alias);
public readonly PropertyInfo PermissionsSelector = ExpressionHelper.GetPropertyInfo<UserType, IEnumerable<string>>(x => x.Permissions);
}
public UserType(string name, string alias)
{
Name = name;
Alias = alias;
}
public UserType()
{
}
[DataMember]
public string Alias
{
get { return _alias; }
set
{
SetPropertyValueAndDetectChanges(
value.ToCleanString(CleanStringType.Alias | CleanStringType.UmbracoCase),
ref _alias,
Ps.Value.AliasSelector);
}
}
[DataMember]
public string Name
{
get { return _name; }
set { SetPropertyValueAndDetectChanges(value, ref _name, Ps.Value.NameSelector); }
}
/// <summary>
/// The set of default permissions for the user type
/// </summary>
/// <remarks>
/// By default each permission is simply a single char but we've made this an enumerable{string} to support a more flexible permissions structure in the future.
/// </remarks>
[DataMember]
public IEnumerable<string> Permissions
{
get { return _permissions; }
set
{
SetPropertyValueAndDetectChanges(value, ref _permissions, Ps.Value.PermissionsSelector,
//Custom comparer for enumerable
new DelegateEqualityComparer<IEnumerable<string>>(
(enum1, enum2) => enum1.UnsortedSequenceEqual(enum2),
enum1 => enum1.GetHashCode()));
}
}
}
}
@@ -3,17 +3,11 @@ using System.Collections.Generic;
namespace Umbraco.Core.Models.PublishedContent
{
/// <inheritdoc />
/// <summary>
/// Represents a cached content.
/// </summary>
/// <remarks>
/// <para>SD: A replacement for INode which needs to occur since INode doesn't contain the document type alias
/// and INode is poorly formatted with mutable properties (i.e. Lists instead of IEnumerable).</para>
/// <para>Stephan: initially, that was for cached published content only. Now, we're using it also for
/// cached preview (so, maybe unpublished) content. A better name would therefore be ICachedContent, as
/// has been suggested. However, can't change now. Maybe in v7?</para>
/// </remarks>
public interface IPublishedContent : IPublishedElement
{
#region Content
@@ -38,6 +32,8 @@ namespace Umbraco.Core.Models.PublishedContent
int Level { get; }
string Url { get; }
IReadOnlyDictionary<string, PublishedCultureName> CultureNames { get; }
/// <summary>
/// Gets a value indicating whether the content is a content (aka a document) or a media.
/// </summary>
@@ -54,7 +54,9 @@ namespace Umbraco.Core.Models.PublishedContent
public virtual int SortOrder => _content.SortOrder;
public virtual string Name => _content.Name;
public virtual string Name => _content.Name;
public virtual IReadOnlyDictionary<string, PublishedCultureName> CultureNames => _content.CultureNames;
public virtual string UrlName => _content.UrlName;
@@ -0,0 +1,19 @@
using System;
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// Contains the culture specific data for a <see cref="IPublishedContent"/> item
/// </summary>
public struct PublishedCultureName
{
public PublishedCultureName(string name, string urlName) : this()
{
Name = name ?? throw new ArgumentNullException(nameof(name));
UrlName = urlName ?? throw new ArgumentNullException(nameof(urlName));
}
public string Name { get; }
public string UrlName { get; }
}
}
+1 -19
View File
@@ -14,14 +14,6 @@ namespace Umbraco.Core.Models
/// </summary>
Unknown,
/// <summary>
/// Content Item Type
/// </summary>
[UmbracoObjectType(Constants.ObjectTypes.Strings.ContentItemType)]
[FriendlyName("Content Item Type")]
[Obsolete("This is not used and will be removed in future versions")]
[EditorBrowsable(EditorBrowsableState.Never)]
ContentItemType,
/// <summary>
/// Root
@@ -69,17 +61,7 @@ namespace Umbraco.Core.Models
[FriendlyName("Member Group")]
[UmbracoUdiType(Constants.UdiEntityType.MemberGroup)]
MemberGroup,
//TODO: What is a 'Content Item' supposed to be???
/// <summary>
/// Content Item
/// </summary>
[UmbracoObjectType(Constants.ObjectTypes.Strings.ContentItem)]
[FriendlyName("Content Item")]
[Obsolete("This is not used and will be removed in future versions")]
[EditorBrowsable(EditorBrowsableState.Never)]
ContentItem,
/// <summary>
/// "Media Type
/// </summary>
@@ -112,15 +112,6 @@ namespace Umbraco.Core.Models
}
public static void ClearAllowedSections(this IUser user)
{
var allowed = user.AllowedSections.ToArray();
foreach (var s in allowed)
{
user.RemoveAllowedSection(s);
}
}
/// <summary>
/// Returns the culture info associated with this user, based on the language they're assigned to in the back office
/// </summary>
-32
View File
@@ -1,32 +0,0 @@
using System;
using System.Runtime.Serialization;
namespace Umbraco.Core.Models
{
/// <summary>
/// Represents a XSLT file
/// </summary>
[Serializable]
[DataContract(IsReference = true)]
public class XsltFile : File, IXsltFile
{
public XsltFile(string path)
: this(path, (Func<File, string>) null)
{ }
internal XsltFile(string path, Func<File, string> getFileContent)
: base(path, getFileContent)
{ }
/// <summary>
/// Indicates whether the current entity has an identity, which in this case is a path/name.
/// </summary>
/// <remarks>
/// Overrides the default Entity identity check.
/// </remarks>
public override bool HasIdentity
{
get { return string.IsNullOrEmpty(Path) == false; }
}
}
}
@@ -16,6 +16,12 @@ namespace Umbraco.Core.Persistence.Dtos
[Column("published")]
public bool Published { get; set; }
/// <summary>
/// Stores serialized JSON representing the content item's property and culture name values
/// </summary>
/// <remarks>
/// Pretty much anything that would require a 1:M lookup is serialized here
/// </remarks>
[Column("data")]
[SpecialDbType(SpecialDbTypes.NTEXT)]
public string Data { get; set; }
@@ -9,7 +9,7 @@ namespace Umbraco.Core.Persistence.Dtos
[ExplicitColumns]
internal class ContentVersionCultureVariationDto
{
private const string TableName = Constants.DatabaseSchema.Tables.ContentVersionCultureVariation;
public const string TableName = Constants.DatabaseSchema.Tables.ContentVersionCultureVariation;
[Column("id")]
[PrimaryKeyColumn]
+7 -16
View File
@@ -34,18 +34,6 @@ namespace Umbraco.Core.Persistence.Dtos
[NullSetting(NullSetting = NullSettings.Null)]
public string Name { get; set; }
[Column("macroScriptType")]
[NullSetting(NullSetting = NullSettings.Null)]
public string ScriptType { get; set; }
[Column("macroScriptAssembly")]
[NullSetting(NullSetting = NullSettings.Null)]
public string ScriptAssembly { get; set; }
[Column("macroXSLT")]
[NullSetting(NullSetting = NullSettings.Null)]
public string Xslt { get; set; }
[Column("macroCacheByPage")]
[Constraint(Default = "1")]
public bool CacheByPage { get; set; }
@@ -58,10 +46,13 @@ namespace Umbraco.Core.Persistence.Dtos
[Constraint(Default = "0")]
public bool DontRender { get; set; }
//TODO: Rename this column! - actually please revamp all of the macros! :)
[Column("macroPython")]
[NullSetting(NullSetting = NullSettings.Null)]
public string MacroFilePath { get; set; }
[Column("macroSource")]
[NullSetting(NullSetting = NullSettings.NotNull)]
public string MacroSource { get; set; }
[Column("macroType")]
[NullSetting(NullSetting = NullSettings.NotNull)]
public int MacroType { get; set; }
[ResultColumn]
[Reference(ReferenceType.Many, ReferenceMemberName = "Macro")]
@@ -1,24 +0,0 @@
using System;
using NPoco;
using Umbraco.Core.Persistence.DatabaseAnnotations;
namespace Umbraco.Core.Persistence.Dtos
{
[Obsolete("This is no longer used and will be removed from Umbraco in future versions")]
internal class StylesheetDto
{
[Column("nodeId")]
[PrimaryKeyColumn(AutoIncrement = false)]
[ForeignKey(typeof(NodeDto))]
public int NodeId { get; set; }
[Column("filename")]
[Length(100)]
public string Filename { get; set; }
[Column("content")]
[SpecialDbType(SpecialDbTypes.NTEXT)]
[NullSetting(NullSetting = NullSettings.Null)]
public string Content { get; set; }
}
}
@@ -1,28 +0,0 @@
using System;
using NPoco;
using Umbraco.Core.Persistence.DatabaseAnnotations;
namespace Umbraco.Core.Persistence.Dtos
{
[Obsolete("This is no longer used and will be removed from Umbraco in future versions")]
internal class StylesheetPropertyDto
{
[Column("nodeId")]
[PrimaryKeyColumn(AutoIncrement = false)]
public int NodeId { get; set; }
[Column("stylesheetPropertyEditor")]
[NullSetting(NullSetting = NullSettings.Null)]
public bool? Editor { get; set; }
[Column("stylesheetPropertyAlias")]
[NullSetting(NullSetting = NullSettings.Null)]
[Length(50)]
public string Alias { get; set; }
[Column("stylesheetPropertyValue")]
[NullSetting(NullSetting = NullSettings.Null)]
[Length(400)]
public string Value { get; set; }
}
}
@@ -9,7 +9,7 @@ namespace Umbraco.Core.Persistence.Factories
{
public IMacro BuildEntity(MacroDto dto)
{
var model = new Macro(dto.Id, dto.UniqueId, dto.UseInEditor, dto.RefreshRate, dto.Alias, dto.Name, dto.ScriptType, dto.ScriptAssembly, dto.Xslt, dto.CacheByPage, dto.CachePersonalized, dto.DontRender, dto.MacroFilePath);
var model = new Macro(dto.Id, dto.UniqueId, dto.UseInEditor, dto.RefreshRate, dto.Alias, dto.Name, dto.CacheByPage, dto.CachePersonalized, dto.DontRender, dto.MacroSource, (MacroTypes)dto.MacroType);
try
{
@@ -40,13 +40,11 @@ namespace Umbraco.Core.Persistence.Factories
CachePersonalized = entity.CacheByMember,
DontRender = entity.DontRender,
Name = entity.Name,
MacroFilePath = entity.ScriptPath,
MacroSource = entity.MacroSource,
RefreshRate = entity.CacheDuration,
ScriptAssembly = entity.ControlAssembly,
ScriptType = entity.ControlType,
UseInEditor = entity.UseInEditor,
Xslt = entity.XsltPath,
MacroPropertyDtos = BuildPropertyDtos(entity)
MacroPropertyDtos = BuildPropertyDtos(entity),
MacroType = (int)entity.MacroType
};
if (entity.HasIdentity)
@@ -18,14 +18,12 @@ namespace Umbraco.Core.Persistence.Mappers
CacheMap<Macro, MacroDto>(src => src.Alias, dto => dto.Alias);
CacheMap<Macro, MacroDto>(src => src.CacheByPage, dto => dto.CacheByPage);
CacheMap<Macro, MacroDto>(src => src.CacheByMember, dto => dto.CachePersonalized);
CacheMap<Macro, MacroDto>(src => src.ControlAssembly, dto => dto.ScriptAssembly);
CacheMap<Macro, MacroDto>(src => src.ControlType, dto => dto.ScriptType);
CacheMap<Macro, MacroDto>(src => src.MacroType, dto => dto.MacroType);
CacheMap<Macro, MacroDto>(src => src.DontRender, dto => dto.DontRender);
CacheMap<Macro, MacroDto>(src => src.Name, dto => dto.Name);
CacheMap<Macro, MacroDto>(src => src.CacheDuration, dto => dto.RefreshRate);
CacheMap<Macro, MacroDto>(src => src.ScriptPath, dto => dto.MacroFilePath);
CacheMap<Macro, MacroDto>(src => src.MacroSource, dto => dto.MacroSource);
CacheMap<Macro, MacroDto>(src => src.UseInEditor, dto => dto.UseInEditor);
CacheMap<Macro, MacroDto>(src => src.XsltPath, dto => dto.Xslt);
}
}
}
@@ -544,6 +544,7 @@ namespace Umbraco.Core.Persistence
/// <returns>The Sql statement.</returns>
public static Sql<ISqlContext> SelectTop(this Sql<ISqlContext> sql, int count)
{
if (sql == null) throw new ArgumentNullException(nameof(sql));
return sql.SqlContext.SqlSyntax.SelectTop(sql, count);
}
@@ -554,6 +555,7 @@ namespace Umbraco.Core.Persistence
/// <returns>The Sql statement.</returns>
public static Sql<ISqlContext> SelectCount(this Sql<ISqlContext> sql)
{
if (sql == null) throw new ArgumentNullException(nameof(sql));
return sql.Select("COUNT(*)");
}
@@ -569,6 +571,7 @@ namespace Umbraco.Core.Persistence
/// </remarks>
public static Sql<ISqlContext> SelectCount<TDto>(this Sql<ISqlContext> sql, params Expression<Func<TDto, object>>[] fields)
{
if (sql == null) throw new ArgumentNullException(nameof(sql));
var columns = fields.Length == 0
? sql.GetColumns<TDto>(withAlias: false)
: fields.Select(x => GetFieldName(x, sql.SqlContext.SqlSyntax)).ToArray();
@@ -582,6 +585,7 @@ namespace Umbraco.Core.Persistence
/// <returns>The Sql statement.</returns>
public static Sql<ISqlContext> SelectAll(this Sql<ISqlContext> sql)
{
if (sql == null) throw new ArgumentNullException(nameof(sql));
return sql.Select("*");
}
@@ -597,6 +601,7 @@ namespace Umbraco.Core.Persistence
/// </remarks>
public static Sql<ISqlContext> Select<TDto>(this Sql<ISqlContext> sql, params Expression<Func<TDto, object>>[] fields)
{
if (sql == null) throw new ArgumentNullException(nameof(sql));
return sql.Select(sql.GetColumns(columnExpressions: fields));
}
@@ -613,6 +618,7 @@ namespace Umbraco.Core.Persistence
/// </remarks>
public static Sql<ISqlContext> Select<TDto>(this Sql<ISqlContext> sql, string tableAlias, params Expression<Func<TDto, object>>[] fields)
{
if (sql == null) throw new ArgumentNullException(nameof(sql));
return sql.Select(sql.GetColumns(tableAlias: tableAlias, columnExpressions: fields));
}
@@ -628,6 +634,7 @@ namespace Umbraco.Core.Persistence
/// </remarks>
public static Sql<ISqlContext> AndSelect<TDto>(this Sql<ISqlContext> sql, params Expression<Func<TDto, object>>[] fields)
{
if (sql == null) throw new ArgumentNullException(nameof(sql));
return sql.Append(", " + string.Join(", ", sql.GetColumns(columnExpressions: fields)));
}
@@ -645,6 +652,7 @@ namespace Umbraco.Core.Persistence
/// </remarks>
public static Sql<ISqlContext> AndSelect<TDto>(this Sql<ISqlContext> sql, string tableAlias, params Expression<Func<TDto, object>>[] fields)
{
if (sql == null) throw new ArgumentNullException(nameof(sql));
return sql.Append(", " + string.Join(", ", sql.GetColumns(tableAlias: tableAlias, columnExpressions: fields)));
}
@@ -657,6 +665,8 @@ namespace Umbraco.Core.Persistence
/// <returns>The Sql statement.</returns>
public static Sql<ISqlContext> Select<TDto>(this Sql<ISqlContext> sql, Func<SqlRef<TDto>, SqlRef<TDto>> reference)
{
if (sql == null) throw new ArgumentNullException(nameof(sql));
sql.Select(sql.GetColumns<TDto>());
reference?.Invoke(new SqlRef<TDto>(sql, null));
@@ -675,6 +685,8 @@ namespace Umbraco.Core.Persistence
/// is added, so that it is possible to add (e.g. calculated) columns to the referencing Dto.</remarks>
public static Sql<ISqlContext> Select<TDto>(this Sql<ISqlContext> sql, Func<SqlRef<TDto>, SqlRef<TDto>> reference, Func<Sql<ISqlContext>, Sql<ISqlContext>> sqlexpr)
{
if (sql == null) throw new ArgumentNullException(nameof(sql));
sql.Select(sql.GetColumns<TDto>());
sql = sqlexpr(sql);
@@ -789,6 +801,7 @@ namespace Umbraco.Core.Persistence
/// </remarks>
public static string Columns<TDto>(this Sql<ISqlContext> sql, params Expression<Func<TDto, object>>[] fields)
{
if (sql == null) throw new ArgumentNullException(nameof(sql));
return string.Join(", ", sql.GetColumns(columnExpressions: fields, withAlias: false));
}
@@ -805,6 +818,7 @@ namespace Umbraco.Core.Persistence
/// </remarks>
public static string Columns<TDto>(this Sql<ISqlContext> sql, string alias, params Expression<Func<TDto, object>>[] fields)
{
if (sql == null) throw new ArgumentNullException(nameof(sql));
return string.Join(", ", sql.GetColumns(columnExpressions: fields, withAlias: false, tableAlias: alias));
}
@@ -4,10 +4,38 @@ namespace Umbraco.Core.Persistence.Repositories
{
public interface ILanguageRepository : IReadWriteQueryRepository<int, ILanguage>
{
ILanguage GetByCultureName(string cultureName);
ILanguage GetByIsoCode(string isoCode);
/// <summary>
/// Gets a language identifier from its ISO code.
/// </summary>
/// <remarks>
/// <para>This can be optimized and bypass all deep cloning.</para>
/// </remarks>
int? GetIdByIsoCode(string isoCode);
/// <summary>
/// Gets a language ISO code from its identifier.
/// </summary>
/// <remarks>
/// <para>This can be optimized and bypass all deep cloning.</para>
/// </remarks>
string GetIsoCodeById(int? id);
/// <summary>
/// Gets the default language ISO code.
/// </summary>
/// <remarks>
/// <para>This can be optimized and bypass all deep cloning.</para>
/// </remarks>
string GetDefaultIsoCode();
/// <summary>
/// Gets the default language identifier.
/// </summary>
/// <remarks>
/// <para>This can be optimized and bypass all deep cloning.</para>
/// </remarks>
int? GetDefaultId();
}
}
@@ -1,13 +0,0 @@
using System.IO;
using Umbraco.Core.Models;
namespace Umbraco.Core.Persistence.Repositories
{
public interface IXsltFileRepository : IReadRepository<string, XsltFile>, IWriteRepository<XsltFile>
{
bool ValidateXsltFile(XsltFile xsltFile);
Stream GetFileContentStream(string filepath);
void SetFileContent(string filepath, Stream content);
long GetFileSize(string filepath);
}
}
@@ -341,10 +341,10 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
(editedCultures ?? (editedCultures = new HashSet<string>(StringComparer.OrdinalIgnoreCase))).Add(culture);
// insert content variations
Database.InsertBulk(GetContentVariationDtos(content, publishing));
Database.BulkInsertRecords(GetContentVariationDtos(content, publishing));
// insert document variations
Database.InsertBulk(GetDocumentVariationDtos(content, publishing, editedCultures));
Database.BulkInsertRecords(GetDocumentVariationDtos(content, publishing, editedCultures));
}
// refresh content
@@ -501,14 +501,14 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
var deleteDocumentVariations = Sql().Delete<DocumentCultureVariationDto>().Where<DocumentCultureVariationDto>(x => x.NodeId == content.Id);
Database.Execute(deleteDocumentVariations);
// fixme is it OK to use NPoco InsertBulk here, or should we use our own BulkInsertRecords?
// fixme is we'd like to use the native NPoco InsertBulk here but it causes problems (not sure exaclty all scenarios) but by using SQL Server and updating a variants name will cause: Unable to cast object of type 'Umbraco.Core.Persistence.FaultHandling.RetryDbConnection' to type 'System.Data.SqlClient.SqlConnection'.
// (same in PersistNewItem above)
// insert content variations
Database.InsertBulk(GetContentVariationDtos(content, publishing));
Database.BulkInsertRecords(GetContentVariationDtos(content, publishing));
// insert document variations
Database.InsertBulk(GetDocumentVariationDtos(content, publishing, editedCultures));
Database.BulkInsertRecords(GetDocumentVariationDtos(content, publishing, editedCultures));
}
// refresh content
@@ -199,14 +199,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
var entity = factory.BuildEntity(dto);
return entity;
}
public ILanguage GetByCultureName(string cultureName)
{
// use the underlying GetMany which will force cache all languages
// TODO we are cloning ALL in GetMany just to retrieve ONE, this is surely not optimized
return GetMany().FirstOrDefault(x => x.CultureName.InvariantEquals(cultureName));
}
public ILanguage GetByIsoCode(string isoCode)
{
TypedCachePolicy.GetAllCached(PerformGetAll); // ensure cache is populated, in a non-expensive way
@@ -249,5 +242,35 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
throw new ArgumentException($"Id {id} does not correspond to an existing language.", nameof(id));
return null;
}
public string GetDefaultIsoCode()
{
return GetDefault()?.IsoCode;
}
public int? GetDefaultId()
{
return GetDefault()?.Id;
}
// do NOT leak that language, it's not deep-cloned!
private ILanguage GetDefault()
{
// get all cached, non-cloned
var all = TypedCachePolicy.GetAllCached(PerformGetAll);
ILanguage first = null;
foreach (var language in all)
{
// if one language is default, return
if (language.IsDefaultVariantLanguage)
return language;
// keep track of language with lowest id
if (first == null || language.Id < first.Id)
first = language;
}
return first;
}
}
}
@@ -776,7 +776,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
}
else
{
validExts.Add(_templateConfig.UseAspNetMasterPages ? "master" : "aspx");
validExts.Add("master");
}
// validate path and extension
@@ -1,133 +0,0 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using LightInject;
using Umbraco.Core.IO;
using Umbraco.Core.Models;
namespace Umbraco.Core.Persistence.Repositories.Implement
{
/// <summary>
/// Represents the XsltFile Repository
/// </summary>
internal class XsltFileRepository : FileRepository<string, XsltFile>, IXsltFileRepository
{
public XsltFileRepository([Inject("XsltFileSystem")] IFileSystem fileSystem)
: base(fileSystem)
{ }
public override XsltFile Get(string id)
{
var path = FileSystem.GetRelativePath(id);
path = path.EnsureEndsWith(".xslt");
if (FileSystem.FileExists(path) == false)
return null;
var created = FileSystem.GetCreated(path).UtcDateTime;
var updated = FileSystem.GetLastModified(path).UtcDateTime;
var xsltFile = new XsltFile(path, file => GetFileContent(file.OriginalPath))
{
Key = path.EncodeAsGuid(),
CreateDate = created,
UpdateDate = updated,
Id = path.GetHashCode(),
VirtualPath = FileSystem.GetUrl(path)
};
// reset dirty initial properties (U4-1946)
xsltFile.ResetDirtyProperties(false);
return xsltFile;
}
public override void Save(XsltFile entity)
{
base.Save(entity);
// ensure that from now on, content is lazy-loaded
if (entity.GetFileContent == null)
entity.GetFileContent = file => GetFileContent(file.OriginalPath);
}
public override IEnumerable<XsltFile> GetMany(params string[] ids)
{
ids = ids
.Select(x => StringExtensions.EnsureEndsWith(x, ".xslt"))
.Distinct()
.ToArray();
if (ids.Any())
{
foreach (var id in ids)
{
yield return Get(id);
}
}
else
{
var files = FindAllFiles("", "*.xslt");
foreach (var file in files)
{
yield return Get(file);
}
}
}
/// <summary>
/// Gets a list of all <see cref="XsltFile"/> that exist at the relative path specified.
/// </summary>
/// <param name="rootPath">
/// If null or not specified, will return the XSLT files at the root path relative to the IFileSystem
/// </param>
/// <returns></returns>
public IEnumerable<XsltFile> GetXsltFilesAtPath(string rootPath = null)
{
return FileSystem.GetFiles(rootPath ?? string.Empty, "*.xslt").Select(Get);
}
private static readonly List<string> ValidExtensions = new List<string> { "xslt" };
public bool ValidateXsltFile(XsltFile xsltFile)
{
// get full path
string fullPath;
try
{
// may throw for security reasons
fullPath = FileSystem.GetFullPath(xsltFile.Path);
}
catch
{
return false;
}
// validate path and extension
var validDir = SystemDirectories.Xslt;
var isValidPath = IOHelper.VerifyEditPath(fullPath, validDir);
var isValidExtension = IOHelper.VerifyFileExtension(xsltFile.Path, ValidExtensions);
return isValidPath && isValidExtension;
}
public Stream GetFileContentStream(string filepath)
{
if (FileSystem.FileExists(filepath) == false) return null;
try
{
return FileSystem.OpenFile(filepath);
}
catch
{
return null; // deal with race conds
}
}
public void SetFileContent(string filepath, Stream content)
{
FileSystem.AddFile(filepath, content, true);
}
}
}
@@ -39,7 +39,7 @@ namespace Umbraco.Core.Publishing
try
{
d.ReleaseDate = null;
d.PublishValues(); // fixme variants?
d.TryPublishValues(); // fixme variants?
var result = _contentService.SaveAndPublish(d, d.GetWriterProfile().Id);
_logger.Debug<ContentService>($"Result of publish attempt: {result.Result}");
if (result.Success == false)
@@ -52,7 +52,6 @@ namespace Umbraco.Core.Runtime
composition.Container.RegisterSingleton(factory => factory.GetInstance<FileSystems>().StylesheetsFileSystem, Constants.Composing.FileSystems.StylesheetFileSystem);
composition.Container.RegisterSingleton(factory => factory.GetInstance<FileSystems>().MasterPagesFileSystem, Constants.Composing.FileSystems.MasterpageFileSystem);
composition.Container.RegisterSingleton(factory => factory.GetInstance<FileSystems>().MvcViewsFileSystem, Constants.Composing.FileSystems.ViewFileSystem);
composition.Container.RegisterSingleton(factory => factory.GetInstance<FileSystems>().XsltFileSystem, Constants.Composing.FileSystems.XsltFileSystem);
// register manifest parser, will be injected in collection builders where needed
composition.Container.RegisterSingleton<ManifestParser>();
@@ -72,12 +71,9 @@ namespace Umbraco.Core.Runtime
composition.Container.RegisterSingleton<PropertyEditorCollection>();
composition.Container.RegisterSingleton<ParameterEditorCollection>();
// register a server registrar, by default it's the db registrar unless the dev
// has the legacy dist calls enabled - fixme - should obsolete the legacy thing
// register a server registrar, by default it's the db registrar
composition.Container.RegisterSingleton<IServerRegistrar>(f =>
{
if (UmbracoConfig.For.UmbracoSettings().DistributedCall.Enabled)
return new ConfigServerRegistrar(f.GetInstance<IUmbracoSettingsSection>(), f.GetInstance<ILogger>(), f.GetInstance<IGlobalSettings>());
if ("true".InvariantEquals(ConfigurationManager.AppSettings["umbracoDisableElectionForSingleServer"]))
return new SingleServerRegistrar(f.GetInstance<IRuntimeState>());
return new DatabaseServerRegistrar(
+8 -6
View File
@@ -19,6 +19,8 @@ namespace Umbraco.Core
private readonly ILogger _logger;
private readonly Lazy<IServerRegistrar> _serverRegistrar;
private readonly Lazy<MainDom> _mainDom;
private readonly IUmbracoSettingsSection _settings;
private readonly IGlobalSettings _globalSettings;
private readonly HashSet<string> _applicationUrls = new HashSet<string>();
private RuntimeLevel _level;
@@ -28,11 +30,13 @@ namespace Umbraco.Core
/// <param name="logger">A logger.</param>
/// <param name="serverRegistrar">A (lazy) server registrar.</param>
/// <param name="mainDom">A (lazy) MainDom.</param>
public RuntimeState(ILogger logger, Lazy<IServerRegistrar> serverRegistrar, Lazy<MainDom> mainDom)
public RuntimeState(ILogger logger, Lazy<IServerRegistrar> serverRegistrar, Lazy<MainDom> mainDom, IUmbracoSettingsSection settings, IGlobalSettings globalSettings)
{
_logger = logger;
_serverRegistrar = serverRegistrar;
_mainDom = mainDom;
_settings = settings;
_globalSettings = globalSettings;
}
private IServerRegistrar ServerRegistrar => _serverRegistrar.Value;
@@ -103,15 +107,13 @@ namespace Umbraco.Core
/// <summary>
/// Ensures that the <see cref="ApplicationUrl"/> property has a value.
/// </summary>
/// <param name="globalSettings"></param>
/// <param name="request"></param>
/// <param name="settings"></param>
internal void EnsureApplicationUrl(IUmbracoSettingsSection settings, IGlobalSettings globalSettings, HttpRequestBase request = null)
internal void EnsureApplicationUrl(HttpRequestBase request = null)
{
// see U4-10626 - in some cases we want to reset the application url
// (this is a simplified version of what was in 7.x)
// note: should this be optional? is it expensive?
var url = request == null ? null : ApplicationUrlHelper.GetApplicationUrlFromCurrentRequest(request, globalSettings);
var url = request == null ? null : ApplicationUrlHelper.GetApplicationUrlFromCurrentRequest(request, _globalSettings);
var change = url != null && !_applicationUrls.Contains(url);
if (change)
{
@@ -120,7 +122,7 @@ namespace Umbraco.Core
}
if (ApplicationUrl != null && !change) return;
ApplicationUrl = new Uri(ApplicationUrlHelper.GetApplicationUrl(_logger, globalSettings, settings, request));
ApplicationUrl = new Uri(ApplicationUrlHelper.GetApplicationUrl(_logger, _globalSettings, _settings, ServerRegistrar, request));
}
private readonly ManualResetEventSlim _runLevel = new ManualResetEventSlim(false);
@@ -295,10 +295,8 @@ namespace Umbraco.Core.Services
var xml = new XElement("macro");
xml.Add(new XElement("name", macro.Name));
xml.Add(new XElement("alias", macro.Alias));
xml.Add(new XElement("scriptType", macro.ControlType));
xml.Add(new XElement("scriptAssembly", macro.ControlAssembly));
xml.Add(new XElement("scriptingFile", macro.ScriptPath));
xml.Add(new XElement("xslt", macro.XsltPath));
xml.Add(new XElement("macroType", macro.MacroType));
xml.Add(new XElement("macroSource", macro.MacroSource));
xml.Add(new XElement("useInEditor", macro.UseInEditor.ToString()));
xml.Add(new XElement("dontRender", macro.DontRender.ToString()));
xml.Add(new XElement("refreshRate", macro.CacheDuration.ToString(CultureInfo.InvariantCulture)));
-23
View File
@@ -18,8 +18,6 @@ namespace Umbraco.Core.Services
IPartialView GetPartialView(string path);
IPartialView GetPartialViewMacro(string path);
IEnumerable<IPartialView> GetPartialViewMacros(params string[] names);
IXsltFile GetXsltFile(string path);
IEnumerable<IXsltFile> GetXsltFiles(params string[] names);
Attempt<IPartialView> CreatePartialView(IPartialView partialView, string snippetName = null, int userId = 0);
Attempt<IPartialView> CreatePartialViewMacro(IPartialView partialView, string snippetName = null, int userId = 0);
bool DeletePartialView(string path, int userId = 0);
@@ -305,27 +303,6 @@ namespace Umbraco.Core.Services
/// <returns>The size of the script file.</returns>
long GetScriptFileSize(string filepath);
/// <summary>
/// Gets the content of a XSLT file as a stream.
/// </summary>
/// <param name="filepath">The filesystem path to the XSLT file.</param>
/// <returns>The content of the XSLT file.</returns>
Stream GetXsltFileContentStream(string filepath);
/// <summary>
/// Sets the content of a XSLT file.
/// </summary>
/// <param name="filepath">The filesystem path to the XSLT file.</param>
/// <param name="content">The content of the XSLT file.</param>
void SetXsltFileContent(string filepath, Stream content);
/// <summary>
/// Gets the size of a XSLT file.
/// </summary>
/// <param name="filepath">The filesystem path to the XSLT file.</param>
/// <returns>The size of the XSLT file.</returns>
long GetXsltFileSize(string filepath);
/// <summary>
/// Gets the content of a macro partial view as a stream.
/// </summary>
@@ -102,14 +102,7 @@ namespace Umbraco.Core.Services
/// <param name="id">Id of the <see cref="ILanguage"/></param>
/// <returns><see cref="ILanguage"/></returns>
ILanguage GetLanguageById(int id);
/// <summary>
/// Gets a <see cref="ILanguage"/> by its culture code
/// </summary>
/// <param name="cultureName">Culture Code - also refered to as the Friendly name</param>
/// <returns><see cref="ILanguage"/></returns>
ILanguage GetLanguageByCultureCode(string cultureName);
/// <summary>
/// Gets a <see cref="Language"/> by its iso code
/// </summary>
@@ -118,10 +111,37 @@ namespace Umbraco.Core.Services
ILanguage GetLanguageByIsoCode(string isoCode);
/// <summary>
/// Gets a language identifier by its iso code.
/// Gets a language identifier from its ISO code.
/// </summary>
int? GetLanguageIdByIsoCode(string isoCode);
/// <remarks>
/// <para>This can be optimized and bypass all deep cloning.</para>
/// </remarks>
int? GetLanguageIdByIsoCode(string isoCode);
/// <summary>
/// Gets a language ISO code from its identifier.
/// </summary>
/// <remarks>
/// <para>This can be optimized and bypass all deep cloning.</para>
/// </remarks>
string GetLanguageIsoCodeById(int id);
/// <summary>
/// Gets the default language ISO code.
/// </summary>
/// <remarks>
/// <para>This can be optimized and bypass all deep cloning.</para>
/// </remarks>
string GetDefaultLanguageIsoCode();
/// <summary>
/// Gets the default language identifier.
/// </summary>
/// <remarks>
/// <para>This can be optimized and bypass all deep cloning.</para>
/// </remarks>
int? GetDefaultLanguageId();
/// <summary>
/// Gets all available languages
/// </summary>
@@ -1070,7 +1070,7 @@ namespace Umbraco.Core.Services.Implement
try
{
d.ReleaseDate = null;
d.PublishValues(); // fixme variants?
d.TryPublishValues(); // fixme variants?
result = SaveAndPublish(d, d.WriterId);
if (result.Success == false)
Logger.Error<ContentService>($"Failed to publish document id={d.Id}, reason={result.Result}.");
@@ -1110,7 +1110,7 @@ namespace Umbraco.Core.Services.Implement
bool IsEditing(IContent c, string l, string s)
=> c.Properties.Any(x => x.Values.Where(y => y.Culture == l && y.Segment == s).Any(y => y.EditedValue != y.PublishedValue));
return SaveAndPublishBranch(content, force, document => IsEditing(document, culture, segment), document => document.PublishValues(culture, segment), userId);
return SaveAndPublishBranch(content, force, document => IsEditing(document, culture, segment), document => document.TryPublishValues(culture, segment), userId);
}
/// <inheritdoc />
@@ -24,16 +24,15 @@ namespace Umbraco.Core.Services.Implement
private readonly ITemplateRepository _templateRepository;
private readonly IPartialViewRepository _partialViewRepository;
private readonly IPartialViewMacroRepository _partialViewMacroRepository;
private readonly IXsltFileRepository _xsltRepository;
private readonly IAuditRepository _auditRepository;
private const string PartialViewHeader = "@inherits Umbraco.Web.Mvc.UmbracoTemplatePage";
private const string PartialViewHeader = "@inherits Umbraco.Web.Mvc.UmbracoViewPage";
private const string PartialViewMacroHeader = "@inherits Umbraco.Web.Macros.PartialViewMacroPage";
public FileService(IScopeProvider uowProvider, ILogger logger, IEventMessagesFactory eventMessagesFactory,
IStylesheetRepository stylesheetRepository, IScriptRepository scriptRepository, ITemplateRepository templateRepository,
IPartialViewRepository partialViewRepository, IPartialViewMacroRepository partialViewMacroRepository,
IXsltFileRepository xsltRepository, IAuditRepository auditRepository)
IAuditRepository auditRepository)
: base(uowProvider, logger, eventMessagesFactory)
{
_stylesheetRepository = stylesheetRepository;
@@ -41,7 +40,6 @@ namespace Umbraco.Core.Services.Implement
_templateRepository = templateRepository;
_partialViewRepository = partialViewRepository;
_partialViewMacroRepository = partialViewMacroRepository;
_xsltRepository = xsltRepository;
_auditRepository = auditRepository;
}
@@ -724,22 +722,6 @@ namespace Umbraco.Core.Services.Implement
}
}
public IXsltFile GetXsltFile(string path)
{
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
{
return _xsltRepository.Get(path);
}
}
public IEnumerable<IXsltFile> GetXsltFiles(params string[] names)
{
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
{
return _xsltRepository.GetMany(names).OrderBy(x => x.Name);
}
}
public Attempt<IPartialView> CreatePartialView(IPartialView partialView, string snippetName = null, int userId = 0)
{
return CreatePartialViewMacro(partialView, PartialViewType.PartialView, snippetName, userId);
@@ -1051,36 +1033,7 @@ namespace Umbraco.Core.Services.Implement
}
#endregion
#region Xslt
public Stream GetXsltFileContentStream(string filepath)
{
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
{
return _xsltRepository.GetFileContentStream(filepath);
}
}
public void SetXsltFileContent(string filepath, Stream content)
{
using (var scope = ScopeProvider.CreateScope())
{
_xsltRepository.SetFileContent(filepath, content);
scope.Complete();
}
}
public long GetXsltFileSize(string filepath)
{
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
{
return _xsltRepository.GetFileSize(filepath);
}
}
#endregion
private void Audit(AuditType type, string message, int userId, int objectId)
{
_auditRepository.Save(new AuditItem(objectId, message, type, userId));
@@ -1182,4 +1135,4 @@ namespace Umbraco.Core.Services.Implement
#endregion
}
}
}
@@ -290,19 +290,6 @@ namespace Umbraco.Core.Services.Implement
}
}
/// <summary>
/// Gets a <see cref="Language"/> by its culture code
/// </summary>
/// <param name="cultureName">Culture Name - also refered to as the Friendly name</param>
/// <returns><see cref="Language"/></returns>
public ILanguage GetLanguageByCultureCode(string cultureName)
{
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
{
return _languageRepository.GetByCultureName(cultureName);
}
}
/// <summary>
/// Gets a <see cref="Language"/> by its iso code
/// </summary>
@@ -325,6 +312,33 @@ namespace Umbraco.Core.Services.Implement
}
}
/// <inheritdoc />
public string GetLanguageIsoCodeById(int id)
{
using (ScopeProvider.CreateScope(autoComplete: true))
{
return _languageRepository.GetIsoCodeById(id);
}
}
/// <inheritdoc />
public string GetDefaultLanguageIsoCode()
{
using (ScopeProvider.CreateScope(autoComplete: true))
{
return _languageRepository.GetDefaultIsoCode();
}
}
/// <inheritdoc />
public int? GetDefaultLanguageId()
{
using (ScopeProvider.CreateScope(autoComplete: true))
{
return _languageRepository.GetDefaultId();
}
}
/// <summary>
/// Gets all available languages
/// </summary>
@@ -25,24 +25,6 @@ namespace Umbraco.Core.Services.Implement
_auditRepository = auditRepository;
}
/// <summary>
/// Returns an enum <see cref="MacroTypes"/> based on the properties on the Macro
/// </summary>
/// <returns><see cref="MacroTypes"/></returns>
internal static MacroTypes GetMacroType(IMacro macro)
{
if (string.IsNullOrEmpty(macro.XsltPath) == false)
return MacroTypes.Xslt;
if (string.IsNullOrEmpty(macro.ScriptPath) == false)
return MacroTypes.PartialView;
if (string.IsNullOrEmpty(macro.ControlType) == false && macro.ControlType.InvariantContains(".ascx"))
return MacroTypes.UserControl;
return MacroTypes.Unknown;
}
/// <summary>
/// Gets an <see cref="IMacro"/> object by its alias
/// </summary>
@@ -1270,10 +1270,8 @@ namespace Umbraco.Core.Services.Implement
{
var macroName = macroElement.Element("name").Value;
var macroAlias = macroElement.Element("alias").Value;
var controlType = macroElement.Element("scriptType").Value;
var controlAssembly = macroElement.Element("scriptAssembly").Value;
var xsltPath = macroElement.Element("xslt").Value;
var scriptPath = macroElement.Element("scriptingFile").Value;
var macroType = Enum<MacroTypes>.Parse(macroElement.Element("macroType").Value);
var macroSource = macroElement.Element("macroSource").Value;
//Following xml elements are treated as nullable properties
var useInEditorElement = macroElement.Element("useInEditor");
@@ -1308,7 +1306,7 @@ namespace Umbraco.Core.Services.Implement
}
var existingMacro = _macroService.GetByAlias(macroAlias) as Macro;
var macro = existingMacro ?? new Macro(macroAlias, macroName, controlType, controlAssembly, xsltPath, scriptPath,
var macro = existingMacro ?? new Macro(macroAlias, macroName, macroSource, macroType,
cacheByPage, cacheByMember, dontRender, useInEditor, cacheDuration);
var properties = macroElement.Element("properties");
@@ -1450,13 +1448,11 @@ namespace Umbraco.Core.Services.Implement
/// <returns></returns>
public string FetchPackageFile(Guid packageId, Version umbracoVersion, int userId)
{
var packageRepo = UmbracoConfig.For.UmbracoSettings().PackageRepositories.GetDefault();
using (var httpClient = new HttpClient())
using (var scope = _scopeProvider.CreateScope())
{
//includeHidden = true because we don't care if it's hidden we want to get the file regardless
var url = $"{packageRepo.RestApiUrl}/{packageId}?version={umbracoVersion.ToString(3)}&includeHidden=true&asFile=true";
var url = $"{Constants.PackageRepository.RestApiBaseUrl}/{packageId}?version={umbracoVersion.ToString(3)}&includeHidden=true&asFile=true";
byte[] bytes;
try
{
@@ -1485,7 +1481,7 @@ namespace Umbraco.Core.Services.Implement
}
}
Audit(AuditType.PackagerInstall, $"Package {packageId} fetched from {packageRepo.Id}", userId, -1);
Audit(AuditType.PackagerInstall, $"Package {packageId} fetched from {Constants.PackageRepository.DefaultRepositoryId}", userId, -1);
return null;
}
}
@@ -1,36 +0,0 @@
using System.Linq;
using Umbraco.Core.Models;
namespace Umbraco.Core.Services
{
public static class LocalizationServiceExtensions
{
/// <summary>
/// Returns the configured default variant language
/// </summary>
/// <param name="service"></param>
/// <returns></returns>
public static ILanguage GetDefaultVariantLanguage(this ILocalizationService service)
{
var langs = service.GetAllLanguages().OrderBy(x => x.Id).ToList();
if (langs.Count == 0) return null;
//if there's only one language, by default it is the default
if (langs.Count == 1)
{
langs[0].IsDefaultVariantLanguage = true;
langs[0].Mandatory = true;
return langs[0];
}
var foundDefault = langs.FirstOrDefault(x => x.IsDefaultVariantLanguage);
if (foundDefault != null) return foundDefault;
//if no language has the default flag, then the defaul language is the one with the lowest id
langs[0].IsDefaultVariantLanguage = true;
langs[0].Mandatory = true;
return langs[0];
}
}
}
+24 -4
View File
@@ -1051,7 +1051,14 @@ namespace Umbraco.Core
/// <returns>The filtered string.</returns>
public static string ReplaceMany(this string text, IDictionary<string, string> replacements)
{
return Current.ShortStringHelper.ReplaceMany(text, replacements);
if (text == null) throw new ArgumentNullException(nameof(text));
if (replacements == null) throw new ArgumentNullException(nameof(replacements));
foreach (KeyValuePair<string, string> item in replacements)
text = text.Replace(item.Key, item.Value);
return text;
}
/// <summary>
@@ -1062,9 +1069,16 @@ namespace Umbraco.Core
/// <param name="replacement">The replacement character.</param>
/// <returns>The filtered string.</returns>
public static string ReplaceMany(this string text, char[] chars, char replacement)
{
return Current.ShortStringHelper.ReplaceMany(text, chars, replacement);
}
{
if (text == null) throw new ArgumentNullException(nameof(text));
if (chars == null) throw new ArgumentNullException(nameof(chars));
for (int i = 0; i < chars.Length; i++)
text = text.Replace(chars[i], replacement);
return text;
}
// FORMAT STRINGS
@@ -1473,5 +1487,11 @@ namespace Umbraco.Core
guid[left] = guid[right];
guid[right] = temp;
}
/// <summary>
/// Turns an null-or-whitespace string into a null string.
/// </summary>
public static string NullEmpty(this string text)
=> string.IsNullOrWhiteSpace(text) ? null : text;
}
}
@@ -670,45 +670,6 @@ function validateSafeAlias(input, value, immediate, callback) {{
#endregion
#region ReplaceMany
/// <summary>
/// Returns a new string in which all occurences of specified strings are replaced by other specified strings.
/// </summary>
/// <param name="text">The string to filter.</param>
/// <param name="replacements">The replacements definition.</param>
/// <returns>The filtered string.</returns>
public virtual string ReplaceMany(string text, IDictionary<string, string> replacements)
{
if (text == null) throw new ArgumentNullException(nameof(text));
if (replacements == null) throw new ArgumentNullException(nameof(replacements));
foreach (KeyValuePair<string, string> item in replacements)
text = text.Replace(item.Key, item.Value);
return text;
}
/// <summary>
/// Returns a new string in which all occurences of specified characters are replaced by a specified character.
/// </summary>
/// <param name="text">The string to filter.</param>
/// <param name="chars">The characters to replace.</param>
/// <param name="replacement">The replacement character.</param>
/// <returns>The filtered string.</returns>
public virtual string ReplaceMany(string text, char[] chars, char replacement)
{
if (text == null) throw new ArgumentNullException(nameof(text));
if (chars == null) throw new ArgumentNullException(nameof(chars));
for (int i = 0; i < chars.Length; i++)
text = text.Replace(chars[i], replacement);
return text;
}
#endregion
}
}
@@ -77,23 +77,6 @@ namespace Umbraco.Core.Strings
/// <remarks>Supports Utf8 and Ascii strings, not Unicode strings.</remarks>
string SplitPascalCasing(string text, char separator);
/// <summary>
/// Returns a new string in which all occurences of specified strings are replaced by other specified strings.
/// </summary>
/// <param name="text">The string to filter.</param>
/// <param name="replacements">The replacements definition.</param>
/// <returns>The filtered string.</returns>
string ReplaceMany(string text, IDictionary<string, string> replacements);
/// <summary>
/// Returns a new string in which all occurences of specified characters are replaced by a specified character.
/// </summary>
/// <param name="text">The string to filter.</param>
/// <param name="chars">The characters to replace.</param>
/// <param name="replacement">The replacement character.</param>
/// <returns>The filtered string.</returns>
string ReplaceMany(string text, char[] chars, char replacement);
/// <summary>
/// Cleans a string.
/// </summary>
@@ -29,9 +29,9 @@ namespace Umbraco.Core.Sync
// FIXME need another way to do it, eg an interface, injected!
public static Func<HttpRequestBase, string> ApplicationUrlProvider { get; set; }
internal static string GetApplicationUrl(ILogger logger, IGlobalSettings globalSettings, IUmbracoSettingsSection settings, HttpRequestBase request = null)
internal static string GetApplicationUrl(ILogger logger, IGlobalSettings globalSettings, IUmbracoSettingsSection settings, IServerRegistrar serverRegistrar, HttpRequestBase request = null)
{
var umbracoApplicationUrl = TryGetApplicationUrl(settings, logger, globalSettings);
var umbracoApplicationUrl = TryGetApplicationUrl(settings, logger, globalSettings, serverRegistrar);
if (umbracoApplicationUrl != null)
return umbracoApplicationUrl;
@@ -50,7 +50,7 @@ namespace Umbraco.Core.Sync
return umbracoApplicationUrl;
}
internal static string TryGetApplicationUrl(IUmbracoSettingsSection settings, ILogger logger, IGlobalSettings globalSettings)
internal static string TryGetApplicationUrl(IUmbracoSettingsSection settings, ILogger logger, IGlobalSettings globalSettings, IServerRegistrar serverRegistrar)
{
// try umbracoSettings:settings/web.routing/@umbracoApplicationUrl
// which is assumed to:
@@ -88,7 +88,7 @@ namespace Umbraco.Core.Sync
// - contain a scheme
// - end or not with a slash, it will be taken care of
// eg "http://www.mysite.com/umbraco"
url = Current.ServerRegistrar.GetCurrentServerUmbracoApplicationUrl();
url = serverRegistrar.GetCurrentServerUmbracoApplicationUrl();
if (url.IsNullOrWhiteSpace() == false)
{
var umbracoApplicationUrl = url.TrimEnd('/');
@@ -1,81 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Cache;
namespace Umbraco.Core.Sync
{
/// <summary>
/// An <see cref="IServerMessenger"/> that works by messaging servers via web services.
/// </summary>
/// <remarks>
/// Abstract because it needs to be inherited by a class that will
/// - implement ProcessBatch()
/// - trigger FlushBatch() when appropriate
/// </remarks>
internal abstract class BatchedWebServiceServerMessenger : WebServiceServerMessenger
{
internal BatchedWebServiceServerMessenger()
{
}
internal BatchedWebServiceServerMessenger(string login, string password)
: base(login, password)
{
}
internal BatchedWebServiceServerMessenger(string login, string password, bool useDistributedCalls)
: base(login, password, useDistributedCalls)
{
}
protected BatchedWebServiceServerMessenger(Func<Tuple<string, string>> getLoginAndPassword)
: base(getLoginAndPassword)
{
}
protected abstract ICollection<RefreshInstructionEnvelope> GetBatch(bool ensureHttpContext);
protected void FlushBatch()
{
var batch = GetBatch(false);
if (batch == null) return;
var batcha = batch.ToArray();
batch.Clear();
if (batcha.Length == 0) return;
ProcessBatch(batcha);
}
// needs to be overriden to actually do something
protected abstract void ProcessBatch(RefreshInstructionEnvelope[] batch);
protected override void DeliverRemote(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, MessageType messageType, IEnumerable<object> ids = null, string json = null)
{
var idsA = ids == null ? null : ids.ToArray();
Type arrayType;
if (GetArrayType(idsA, out arrayType) == false)
throw new ArgumentException("All items must be of the same type, either int or Guid.", "ids");
BatchMessage(servers, refresher, messageType, idsA, arrayType, json);
}
protected void BatchMessage(
IEnumerable<IServerAddress> servers,
ICacheRefresher refresher,
MessageType messageType,
IEnumerable<object> ids = null,
Type idType = null,
string json = null)
{
var batch = GetBatch(true);
if (batch == null)
throw new Exception("Failed to get a batch.");
batch.Add(new RefreshInstructionEnvelope(servers, refresher,
RefreshInstruction.GetInstructions(refresher, messageType, ids, idType, json)));
}
}
}
@@ -1,32 +0,0 @@
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.IO;
namespace Umbraco.Core.Sync
{
/// <summary>
/// Provides the address of a server based on the Xml configuration.
/// </summary>
internal class ConfigServerAddress : IServerAddress
{
public ConfigServerAddress(IServer n, IGlobalSettings globalSettings)
{
var webServicesUrl = IOHelper.ResolveUrl(SystemDirectories.WebServices);
var protocol = globalSettings.UseHttps ? "https" : "http";
if (n.ForceProtocol.IsNullOrWhiteSpace() == false)
protocol = n.ForceProtocol;
var domain = n.ServerAddress;
if (n.ForcePortnumber.IsNullOrWhiteSpace() == false)
domain += $":{n.ForcePortnumber}";
ServerAddress = $"{protocol}://{domain}{webServicesUrl}/cacheRefresher.asmx";
}
public string ServerAddress { get; private set; }
public override string ToString()
{
return ServerAddress;
}
}
}
@@ -1,93 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
namespace Umbraco.Core.Sync
{
/// <summary>
/// Provides server registrations to the distributed cache by reading the legacy Xml configuration
/// in umbracoSettings to get the list of (manually) configured server nodes.
/// </summary>
internal class ConfigServerRegistrar : IServerRegistrar
{
private readonly List<IServerAddress> _addresses;
private readonly ServerRole _serverRole;
private readonly string _umbracoApplicationUrl;
public ConfigServerRegistrar(IUmbracoSettingsSection settings, ILogger logger, IGlobalSettings globalSettings)
: this(settings.DistributedCall, logger, globalSettings)
{ }
// for tests
internal ConfigServerRegistrar(IDistributedCallSection settings, ILogger logger, IGlobalSettings globalSettings)
{
if (settings.Enabled == false)
{
_addresses = new List<IServerAddress>();
_serverRole = ServerRole.Single;
_umbracoApplicationUrl = null; // unspecified
return;
}
var serversA = settings.Servers.ToArray();
_addresses = serversA
.Select(x => new ConfigServerAddress(x, globalSettings))
.Cast<IServerAddress>()
.ToList();
if (serversA.Length == 0)
{
_serverRole = ServerRole.Unknown; // config error, actually
logger.Debug<ConfigServerRegistrar>("Server Role Unknown: DistributedCalls are enabled but no servers are listed.");
}
else
{
var master = serversA[0]; // first one is master
var appId = master.AppId;
var serverName = master.ServerName;
if (appId.IsNullOrWhiteSpace() && serverName.IsNullOrWhiteSpace())
{
_serverRole = ServerRole.Unknown; // config error, actually
logger.Debug<ConfigServerRegistrar>("Server Role Unknown: Server Name or AppId missing from Server configuration in DistributedCalls settings.");
}
else
{
_serverRole = IsCurrentServer(appId, serverName)
? ServerRole.Master
: ServerRole.Slave;
}
}
var currentServer = serversA.FirstOrDefault(x => IsCurrentServer(x.AppId, x.ServerName));
if (currentServer != null)
{
// match, use the configured url
// ReSharper disable once UseStringInterpolation
_umbracoApplicationUrl = string.Format("{0}://{1}:{2}/{3}",
currentServer.ForceProtocol.IsNullOrWhiteSpace() ? "http" : currentServer.ForceProtocol,
currentServer.ServerAddress,
currentServer.ForcePortnumber.IsNullOrWhiteSpace() ? "80" : currentServer.ForcePortnumber,
IOHelper.ResolveUrl(SystemDirectories.Umbraco).TrimStart('/'));
}
}
private static bool IsCurrentServer(string appId, string serverName)
{
// match by appId or computer name
return (appId.IsNullOrWhiteSpace() == false && appId.Trim().InvariantEquals(HttpRuntime.AppDomainAppId))
|| (serverName.IsNullOrWhiteSpace() == false && serverName.Trim().InvariantEquals(NetworkHelper.MachineName));
}
public IEnumerable<IServerAddress> Registrations => _addresses;
public ServerRole GetCurrentServerRole() => _serverRole;
public string GetCurrentServerUmbracoApplicationUrl() => _umbracoApplicationUrl;
}
}
@@ -71,7 +71,7 @@ namespace Umbraco.Core.Sync
#region Messenger
protected override bool RequiresDistributed(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, MessageType dispatchType)
protected override bool RequiresDistributed(ICacheRefresher refresher, MessageType dispatchType)
{
// we don't care if there's servers listed or not,
// if distributed call is enabled we will make the call
@@ -79,7 +79,6 @@ namespace Umbraco.Core.Sync
}
protected override void DeliverRemote(
IEnumerable<IServerAddress> servers,
ICacheRefresher refresher,
MessageType messageType,
IEnumerable<object> ids = null,
@@ -14,14 +14,9 @@ namespace Umbraco.Core.Sync
public DatabaseServerRegistrarOptions()
{
StaleServerTimeout = TimeSpan.FromMinutes(2); // 2 minutes
ThrottleSeconds = 30; // 30 seconds
RecurringSeconds = 60; // do it every minute
}
[Obsolete("This is no longer used")]
[EditorBrowsable(EditorBrowsableState.Never)]
public int ThrottleSeconds { get; set; }
/// <summary>
/// The amount of seconds to wait between calls to the database on the background thread
/// </summary>
+9 -18
View File
@@ -13,78 +13,69 @@ namespace Umbraco.Core.Sync
/// <summary>
/// Notifies the distributed cache, for a specified <see cref="ICacheRefresher"/>.
/// </summary>
/// <param name="servers">The servers that compose the load balanced environment.</param>
/// <param name="refresher">The ICacheRefresher.</param>
/// <param name="payload">The notification content.</param>
void PerformRefresh<TPayload>(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, TPayload[] payload);
void PerformRefresh<TPayload>(ICacheRefresher refresher, TPayload[] payload);
/// <summary>
/// Notifies the distributed cache, for a specified <see cref="ICacheRefresher"/>.
/// </summary>
/// <param name="servers">The servers that compose the load balanced environment.</param>
/// <param name="refresher">The ICacheRefresher.</param>
/// <param name="jsonPayload">The notification content.</param>
void PerformRefresh(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, string jsonPayload);
void PerformRefresh(ICacheRefresher refresher, string jsonPayload);
/// <summary>
/// Notifies the distributed cache of specifieds item invalidation, for a specified <see cref="ICacheRefresher"/>.
/// </summary>
/// <typeparam name="T">The type of the invalidated items.</typeparam>
/// <param name="servers">The servers that compose the load balanced environment.</param>
/// <param name="refresher">The ICacheRefresher.</param>
/// <param name="getNumericId">A function returning the unique identifier of items.</param>
/// <param name="instances">The invalidated items.</param>
void PerformRefresh<T>(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, Func<T, int> getNumericId, params T[] instances);
void PerformRefresh<T>(ICacheRefresher refresher, Func<T, int> getNumericId, params T[] instances);
/// <summary>
/// Notifies the distributed cache of specifieds item invalidation, for a specified <see cref="ICacheRefresher"/>.
/// </summary>
/// <typeparam name="T">The type of the invalidated items.</typeparam>
/// <param name="servers">The servers that compose the load balanced environment.</param>
/// <param name="refresher">The ICacheRefresher.</param>
/// <param name="getGuidId">A function returning the unique identifier of items.</param>
/// <param name="instances">The invalidated items.</param>
void PerformRefresh<T>(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, Func<T, Guid> getGuidId, params T[] instances);
void PerformRefresh<T>(ICacheRefresher refresher, Func<T, Guid> getGuidId, params T[] instances);
/// <summary>
/// Notifies all servers of specified items removal, for a specified <see cref="ICacheRefresher"/>.
/// </summary>
/// <typeparam name="T">The type of the removed items.</typeparam>
/// <param name="servers">The servers that compose the load balanced environment.</param>
/// <param name="refresher">The ICacheRefresher.</param>
/// <param name="getNumericId">A function returning the unique identifier of items.</param>
/// <param name="instances">The removed items.</param>
void PerformRemove<T>(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, Func<T, int> getNumericId, params T[] instances);
void PerformRemove<T>(ICacheRefresher refresher, Func<T, int> getNumericId, params T[] instances);
/// <summary>
/// Notifies all servers of specified items removal, for a specified <see cref="ICacheRefresher"/>.
/// </summary>
/// <param name="servers">The servers that compose the load balanced environment.</param>
/// <param name="refresher">The ICacheRefresher.</param>
/// <param name="numericIds">The unique identifiers of the removed items.</param>
void PerformRemove(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, params int[] numericIds);
void PerformRemove(ICacheRefresher refresher, params int[] numericIds);
/// <summary>
/// Notifies all servers of specified items invalidation, for a specified <see cref="ICacheRefresher"/>.
/// </summary>
/// <param name="servers">The servers that compose the load balanced environment.</param>
/// <param name="refresher">The ICacheRefresher.</param>
/// <param name="numericIds">The unique identifiers of the invalidated items.</param>
void PerformRefresh(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, params int[] numericIds);
void PerformRefresh(ICacheRefresher refresher, params int[] numericIds);
/// <summary>
/// Notifies all servers of specified items invalidation, for a specified <see cref="ICacheRefresher"/>.
/// </summary>
/// <param name="servers">The servers that compose the load balanced environment.</param>
/// <param name="refresher">The ICacheRefresher.</param>
/// <param name="guidIds">The unique identifiers of the invalidated items.</param>
void PerformRefresh(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, params Guid[] guidIds);
void PerformRefresh(ICacheRefresher refresher, params Guid[] guidIds);
/// <summary>
/// Notifies all servers of a global invalidation for a specified <see cref="ICacheRefresher"/>.
/// </summary>
/// <param name="servers">The servers that compose the load balanced environment.</param>
/// <param name="refresher">The ICacheRefresher.</param>
void PerformRefreshAll(IEnumerable<IServerAddress> servers, ICacheRefresher refresher);
void PerformRefreshAll(ICacheRefresher refresher);
}
}

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