Compare commits

..

1 Commits

Author SHA1 Message Date
Sebastiaan Janssen 5bc66c5b7f Bumps the version 2016-12-07 14:18:27 +01:00
99 changed files with 981 additions and 1683 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
Umbraco CMS
===========
The friendliest, most flexible and fastest growing ASP.NET CMS used by more than 390,000 websites worldwide: [https://umbraco.com](https://umbraco.com)
The friendliest, most flexible and fastest growing ASP.NET CMS used by more than 350,000 websites worldwide: [https://umbraco.com](https://umbraco.com)
[![ScreenShot](vimeo.png)](https://vimeo.com/172382998/)
+3 -3
View File
@@ -33,8 +33,8 @@
<dependency id="AutoMapper" version="[3.3.1, 4.0.0)" />
<dependency id="Newtonsoft.Json" version="[6.0.8, 10.0.0)" />
<dependency id="Examine" version="[0.1.70, 1.0.0)" />
<dependency id="ImageProcessor" version="[2.5.1, 3.0.0)" />
<dependency id="ImageProcessor.Web" version="[4.7.2, 5.0.0)" />
<dependency id="ImageProcessor" version="[2.4.5, 3.0.0)" />
<dependency id="ImageProcessor.Web" version="[4.6.6, 5.0.0)" />
<dependency id="semver" version="[1.1.2, 2.0.0)" />
<dependency id="UrlRewritingNet" version="[2.0.7, 3.0.0)" />
<!-- Markdown can not be updated due to: https://github.com/hey-red/markdownsharp/issues/71#issuecomment-233585487 -->
@@ -103,4 +103,4 @@
<file src="..\_BuildOutput\bin\UmbracoExamine.pdb" target="lib" />
<file src="..\..\src\UmbracoExamine\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\UmbracoExamine" />
</files>
</package>
</package>
-2
View File
@@ -18,7 +18,6 @@
<dependency id="UmbracoCms.Core" version="[$version$]" />
<dependency id="Newtonsoft.Json" version="[6.0.8, 10.0.0)" />
<dependency id="Umbraco.ModelsBuilder" version="[3.0.5, 4.0.0)" />
<dependency id="ImageProcessor.Web.Config" version="[2.3.0, 3.0.0)" />
</dependencies>
</metadata>
<files>
@@ -44,7 +43,6 @@
<file src="tools\trees.config.install.xdt" target="Content\config\trees.config.install.xdt" />
<file src="tools\umbracoSettings.config.install.xdt" target="Content\config\umbracoSettings.config.install.xdt" />
<file src="tools\Views.Web.config.install.xdt" target="Views\Web.config.install.xdt" />
<file src="tools\processing.config.install.xdt" target="Content\Config\imageprocessor\processing.config.install.xdt" />
<file src="build\**" target="build" />
</files>
</package>
-1
View File
@@ -71,7 +71,6 @@ if ($project) {
if(Test-Path $umbracoBinFolder\ImageProcessor.dll) { Remove-Item $umbracoBinFolder\ImageProcessor.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\ImageProcessor.Web.dll) { Remove-Item $umbracoBinFolder\ImageProcessor.Web.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Lucene.Net.dll) { Remove-Item $umbracoBinFolder\Lucene.Net.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Microsoft.IO.RecyclableMemoryStream.dll) { Remove-Item $umbracoBinFolder\Microsoft.IO.RecyclableMemoryStream.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Microsoft.AspNet.Identity.Core.dll) { Remove-Item $umbracoBinFolder\Microsoft.AspNet.Identity.Core.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Microsoft.AspNet.Identity.Owin.dll) { Remove-Item $umbracoBinFolder\Microsoft.AspNet.Identity.Owin.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Microsoft.CodeAnalysis.CSharp.dll) { Remove-Item $umbracoBinFolder\Microsoft.CodeAnalysis.CSharp.dll -Force -Confirm:$false }
@@ -1 +0,0 @@
<processing xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform" xdt:Transform="SetAttributes(preserveExifMetaData)" preserveExifMetaData="true" />
+1 -1
View File
@@ -1,2 +1,2 @@
# Usage: on line 2 put the release version, on line 3 put the version comment (example: beta)
7.5.7
7.5.6
+4
View File
@@ -49,9 +49,13 @@
<Reference Include="System.Core" />
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Private>False</Private>
</Reference>
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.Entity.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Private>False</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
+3 -3
View File
@@ -2,7 +2,7 @@
using System.Resources;
[assembly: AssemblyCompany("Umbraco")]
[assembly: AssemblyCopyright("Copyright © Umbraco 2017")]
[assembly: AssemblyCopyright("Copyright © Umbraco 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -11,5 +11,5 @@ using System.Resources;
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("7.5.7")]
[assembly: AssemblyInformationalVersion("7.5.7")]
[assembly: AssemblyFileVersion("7.5.6")]
[assembly: AssemblyInformationalVersion("7.5.6")]
@@ -4,7 +4,8 @@ using System.Configuration;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class ContentElement : UmbracoConfigurationElement, IContentSection
internal class ContentElement : ConfigurationElement, IContentSection
{
[ConfigurationProperty("imaging")]
internal ContentImagingElement Imaging
@@ -21,13 +22,25 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
[ConfigurationProperty("ResolveUrlsFromTextString")]
internal InnerTextConfigurationElement<bool> ResolveUrlsFromTextString
{
get { return GetOptionalTextElement<bool>("ResolveUrlsFromTextString", false); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["ResolveUrlsFromTextString"],
//set the default
false);
}
}
[ConfigurationProperty("UploadAllowDirectories")]
internal InnerTextConfigurationElement<bool> UploadAllowDirectories
{
get { return GetOptionalTextElement("UploadAllowDirectories", true); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["UploadAllowDirectories"],
//set the default
true);
}
}
public IEnumerable<IContentErrorPage> Error404Collection
@@ -50,61 +63,121 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
[ConfigurationProperty("ensureUniqueNaming")]
internal InnerTextConfigurationElement<bool> EnsureUniqueNaming
{
get { return GetOptionalTextElement("ensureUniqueNaming", true); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["ensureUniqueNaming"],
//set the default
true);
}
}
[ConfigurationProperty("TidyEditorContent")]
internal InnerTextConfigurationElement<bool> TidyEditorContent
{
get { return GetOptionalTextElement("TidyEditorContent", false); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["TidyEditorContent"],
//set the default
false);
}
}
[ConfigurationProperty("TidyCharEncoding")]
internal InnerTextConfigurationElement<string> TidyCharEncoding
{
get { return GetOptionalTextElement("TidyCharEncoding", "UTF8"); }
get
{
return new OptionalInnerTextConfigurationElement<string>(
(InnerTextConfigurationElement<string>)this["TidyCharEncoding"],
//set the default
"UTF8");
}
}
[ConfigurationProperty("XmlCacheEnabled")]
internal InnerTextConfigurationElement<bool> XmlCacheEnabled
{
get { return GetOptionalTextElement("XmlCacheEnabled", true); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["XmlCacheEnabled"],
//set the default
true);
}
}
[ConfigurationProperty("ContinouslyUpdateXmlDiskCache")]
internal InnerTextConfigurationElement<bool> ContinouslyUpdateXmlDiskCache
{
get { return GetOptionalTextElement("ContinouslyUpdateXmlDiskCache", true); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["ContinouslyUpdateXmlDiskCache"],
//set the default
true);
}
}
[ConfigurationProperty("XmlContentCheckForDiskChanges")]
internal InnerTextConfigurationElement<bool> XmlContentCheckForDiskChanges
{
get { return GetOptionalTextElement("XmlContentCheckForDiskChanges", false); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["XmlContentCheckForDiskChanges"],
//set the default
false);
}
}
[ConfigurationProperty("EnableSplashWhileLoading")]
internal InnerTextConfigurationElement<bool> EnableSplashWhileLoading
{
get { return GetOptionalTextElement("EnableSplashWhileLoading", false); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["EnableSplashWhileLoading"],
//set the default
false);
}
}
[ConfigurationProperty("PropertyContextHelpOption")]
internal InnerTextConfigurationElement<string> PropertyContextHelpOption
{
get { return GetOptionalTextElement("PropertyContextHelpOption", "text"); }
get
{
return new OptionalInnerTextConfigurationElement<string>(
(InnerTextConfigurationElement<string>)this["PropertyContextHelpOption"],
//set the default
"text");
}
}
[ConfigurationProperty("UseLegacyXmlSchema")]
internal InnerTextConfigurationElement<bool> UseLegacyXmlSchema
{
get { return GetOptionalTextElement("UseLegacyXmlSchema", false); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["UseLegacyXmlSchema"],
//set the default
false);
}
}
[ConfigurationProperty("ForceSafeAliases")]
internal InnerTextConfigurationElement<bool> ForceSafeAliases
{
get { return GetOptionalTextElement("ForceSafeAliases", true); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["ForceSafeAliases"],
//set the default
true);
}
}
[ConfigurationProperty("PreviewBadge")]
@@ -112,63 +185,123 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
{
get
{
return GetOptionalTextElement("PreviewBadge", @"<a id=""umbracoPreviewBadge"" style=""position: absolute; top: 0; right: 0; border: 0; width: 149px; height: 149px; background: url('{1}/preview/previewModeBadge.png') no-repeat;"" href=""{0}/endPreview.aspx?redir={2}""><span style=""display:none;"">In Preview Mode - click to end</span></a>");
return new OptionalInnerTextConfigurationElement<string>(
(InnerTextConfigurationElement<string>)this["PreviewBadge"],
//set the default
@"<a id=""umbracoPreviewBadge"" style=""position: absolute; top: 0; right: 0; border: 0; width: 149px; height: 149px; background: url('{1}/preview/previewModeBadge.png') no-repeat;"" href=""{0}/endPreview.aspx?redir={2}""><span style=""display:none;"">In Preview Mode - click to end</span></a>");
}
}
[ConfigurationProperty("UmbracoLibraryCacheDuration")]
internal InnerTextConfigurationElement<int> UmbracoLibraryCacheDuration
{
get { return GetOptionalTextElement("UmbracoLibraryCacheDuration", 1800); }
get
{
return new OptionalInnerTextConfigurationElement<int>(
(InnerTextConfigurationElement<int>)this["UmbracoLibraryCacheDuration"],
//set the default
1800);
}
}
[ConfigurationProperty("MacroErrors")]
internal InnerTextConfigurationElement<MacroErrorBehaviour> MacroErrors
{
get { return GetOptionalTextElement("MacroErrors", MacroErrorBehaviour.Inline); }
get
{
return new OptionalInnerTextConfigurationElement<MacroErrorBehaviour>(
(InnerTextConfigurationElement<MacroErrorBehaviour>)this["MacroErrors"],
//set the default
MacroErrorBehaviour.Inline);
}
}
[Obsolete("This is here so that if this config element exists we won't get a YSOD, it is not used whatsoever and will be removed in future versions")]
[ConfigurationProperty("DocumentTypeIconList")]
internal InnerTextConfigurationElement<IconPickerBehaviour> DocumentTypeIconList
{
get { return GetOptionalTextElement("DocumentTypeIconList", IconPickerBehaviour.HideFileDuplicates); }
get
{
return new OptionalInnerTextConfigurationElement<IconPickerBehaviour>(
(InnerTextConfigurationElement<IconPickerBehaviour>)this["DocumentTypeIconList"],
//set the default
IconPickerBehaviour.HideFileDuplicates);
}
}
[ConfigurationProperty("disallowedUploadFiles")]
internal CommaDelimitedConfigurationElement DisallowedUploadFiles
{
get { return GetOptionalDelimitedElement("disallowedUploadFiles", new[] {"ashx", "aspx", "ascx", "config", "cshtml", "vbhtml", "asmx", "air", "axd"}); }
get
{
return new OptionalCommaDelimitedConfigurationElement(
(CommaDelimitedConfigurationElement)this["disallowedUploadFiles"],
//set the default
new[] { "ashx", "aspx", "ascx", "config", "cshtml", "vbhtml", "asmx", "air", "axd" });
}
}
[ConfigurationProperty("cloneXmlContent")]
internal InnerTextConfigurationElement<bool> CloneXmlContent
{
get { return GetOptionalTextElement("cloneXmlContent", true); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["cloneXmlContent"],
//set the default
true);
}
}
[ConfigurationProperty("GlobalPreviewStorageEnabled")]
internal InnerTextConfigurationElement<bool> GlobalPreviewStorageEnabled
{
get { return GetOptionalTextElement("GlobalPreviewStorageEnabled", false); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["GlobalPreviewStorageEnabled"],
//set the default
false);
}
}
[ConfigurationProperty("defaultDocumentTypeProperty")]
internal InnerTextConfigurationElement<string> DefaultDocumentTypeProperty
{
get { return GetOptionalTextElement("defaultDocumentTypeProperty", "Textstring"); }
get
{
return new OptionalInnerTextConfigurationElement<string>(
(InnerTextConfigurationElement<string>)this["defaultDocumentTypeProperty"],
//set the default
"Textstring");
}
}
[ConfigurationProperty("EnableInheritedDocumentTypes")]
internal InnerTextConfigurationElement<bool> EnableInheritedDocumentTypes
{
get { return GetOptionalTextElement("EnableInheritedDocumentTypes", true); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>) this["EnableInheritedDocumentTypes"],
//set the default
true);
}
}
[ConfigurationProperty("EnableInheritedMediaTypes")]
internal InnerTextConfigurationElement<bool> EnableInheritedMediaTypes
{
get { return GetOptionalTextElement("EnableInheritedMediaTypes", true); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["EnableInheritedMediaTypes"],
//set the default
true);
}
}
string IContentSection.NotificationEmailAddress
@@ -3,24 +3,42 @@ using System.Configuration;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class ContentScriptEditorElement : UmbracoConfigurationElement
internal class ContentScriptEditorElement : ConfigurationElement
{
[ConfigurationProperty("scriptFolderPath")]
internal InnerTextConfigurationElement<string> ScriptFolderPath
{
get { return GetOptionalTextElement("scriptFolderPath", "/scripts"); }
get
{
return new OptionalInnerTextConfigurationElement<string>(
(InnerTextConfigurationElement<string>)this["scriptFolderPath"],
//set the default
"/scripts");
}
}
[ConfigurationProperty("scriptFileTypes")]
internal OptionalCommaDelimitedConfigurationElement ScriptFileTypes
{
get { return GetOptionalDelimitedElement("scriptFileTypes", new[] {"js", "xml"}); }
get
{
return new OptionalCommaDelimitedConfigurationElement(
(OptionalCommaDelimitedConfigurationElement)this["scriptFileTypes"],
//set the default
new[] { "js", "xml" });
}
}
[ConfigurationProperty("scriptDisableEditor")]
internal InnerTextConfigurationElement<bool> ScriptEditorDisable
{
get { return GetOptionalTextElement("scriptDisableEditor", false); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>) this["scriptDisableEditor"],
//set the default
false);
}
}
}
@@ -2,7 +2,7 @@
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class ImagingAutoFillUploadFieldElement : UmbracoConfigurationElement, IImagingAutoFillUploadField
internal class ImagingAutoFillUploadFieldElement : ConfigurationElement, IImagingAutoFillUploadField
{
/// <summary>
/// Allow setting internally so we can create a default
@@ -17,25 +17,49 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
[ConfigurationProperty("widthFieldAlias")]
internal InnerTextConfigurationElement<string> WidthFieldAlias
{
get { return GetOptionalTextElement("widthFieldAlias", "umbracoWidth"); }
get
{
return new OptionalInnerTextConfigurationElement<string>(
(InnerTextConfigurationElement<string>)this["widthFieldAlias"],
//set the default
"umbracoWidth");
}
}
[ConfigurationProperty("heightFieldAlias")]
internal InnerTextConfigurationElement<string> HeightFieldAlias
{
get { return GetOptionalTextElement("heightFieldAlias", "umbracoHeight"); }
get
{
return new OptionalInnerTextConfigurationElement<string>(
(InnerTextConfigurationElement<string>)this["heightFieldAlias"],
//set the default
"umbracoHeight");
}
}
[ConfigurationProperty("lengthFieldAlias")]
internal InnerTextConfigurationElement<string> LengthFieldAlias
{
get { return GetOptionalTextElement("lengthFieldAlias", "umbracoBytes"); }
get
{
return new OptionalInnerTextConfigurationElement<string>(
(InnerTextConfigurationElement<string>)this["lengthFieldAlias"],
//set the default
"umbracoBytes");
}
}
[ConfigurationProperty("extensionFieldAlias")]
internal InnerTextConfigurationElement<string> ExtensionFieldAlias
{
get { return GetOptionalTextElement("extensionFieldAlias", "umbracoExtension"); }
get
{
return new OptionalInnerTextConfigurationElement<string>(
(InnerTextConfigurationElement<string>)this["extensionFieldAlias"],
//set the default
"umbracoExtension");
}
}
string IImagingAutoFillUploadField.Alias
@@ -3,37 +3,67 @@ using System.Configuration;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class LoggingElement : UmbracoConfigurationElement, ILoggingSection
internal class LoggingElement : ConfigurationElement, ILoggingSection
{
[ConfigurationProperty("autoCleanLogs")]
internal InnerTextConfigurationElement<bool> AutoCleanLogs
{
get { return GetOptionalTextElement("autoCleanLogs", false); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["autoCleanLogs"],
//set the default
false);
}
}
[ConfigurationProperty("enableLogging")]
internal InnerTextConfigurationElement<bool> EnableLogging
{
get { return GetOptionalTextElement("enableLogging", true); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["enableLogging"],
//set the default
true);
}
}
[ConfigurationProperty("enableAsyncLogging")]
internal InnerTextConfigurationElement<bool> EnableAsyncLogging
{
get { return GetOptionalTextElement("enableAsyncLogging", true); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["enableAsyncLogging"],
//set the default
true);
}
}
[ConfigurationProperty("cleaningMiliseconds")]
internal InnerTextConfigurationElement<int> CleaningMiliseconds
{
get { return GetOptionalTextElement("cleaningMiliseconds", -1); }
get
{
return new OptionalInnerTextConfigurationElement<int>(
(InnerTextConfigurationElement<int>)this["cleaningMiliseconds"],
//set the default
-1);
}
}
[ConfigurationProperty("maxLogAge")]
internal InnerTextConfigurationElement<int> MaxLogAge
{
get { return GetOptionalTextElement("maxLogAge", -1); }
get
{
return new OptionalInnerTextConfigurationElement<int>(
(InnerTextConfigurationElement<int>)this["maxLogAge"],
//set the default
-1);
}
}
[ConfigurationCollection(typeof(DisabledLogTypesCollection), AddItemName = "logTypeAlias")]
@@ -2,7 +2,7 @@
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class NotificationsElement : UmbracoConfigurationElement
internal class NotificationsElement : ConfigurationElement
{
[ConfigurationProperty("email")]
internal InnerTextConfigurationElement<string> NotificationEmailAddress
@@ -13,7 +13,13 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
[ConfigurationProperty("disableHtmlEmail")]
internal InnerTextConfigurationElement<bool> DisableHtmlEmail
{
get { return GetOptionalTextElement("disableHtmlEmail", false); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>) this["disableHtmlEmail"],
//set the default
false);
}
}
}
@@ -5,18 +5,30 @@ using System.Collections.Generic;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class RequestHandlerElement : UmbracoConfigurationElement, IRequestHandlerSection
internal class RequestHandlerElement : ConfigurationElement, IRequestHandlerSection
{
[ConfigurationProperty("useDomainPrefixes")]
public InnerTextConfigurationElement<bool> UseDomainPrefixes
{
get { return GetOptionalTextElement("useDomainPrefixes", false); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["useDomainPrefixes"],
//set the default
false);
}
}
[ConfigurationProperty("addTrailingSlash")]
public InnerTextConfigurationElement<bool> AddTrailingSlash
{
get { return GetOptionalTextElement("addTrailingSlash", true); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["addTrailingSlash"],
//set the default
true);
}
}
private UrlReplacingElement _defaultUrlReplacing;
@@ -2,36 +2,66 @@
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class SecurityElement : UmbracoConfigurationElement, ISecuritySection
internal class SecurityElement : ConfigurationElement, ISecuritySection
{
[ConfigurationProperty("keepUserLoggedIn")]
internal InnerTextConfigurationElement<bool> KeepUserLoggedIn
{
get { return GetOptionalTextElement("keepUserLoggedIn", true); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["keepUserLoggedIn"],
//set the default
true);
}
}
[ConfigurationProperty("hideDisabledUsersInBackoffice")]
internal InnerTextConfigurationElement<bool> HideDisabledUsersInBackoffice
{
get { return GetOptionalTextElement("hideDisabledUsersInBackoffice", false); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["hideDisabledUsersInBackoffice"],
//set the default
false);
}
}
[ConfigurationProperty("allowPasswordReset")]
internal InnerTextConfigurationElement<bool> AllowPasswordReset
{
get { return GetOptionalTextElement("allowPasswordReset", true); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["allowPasswordReset"],
//set the default
true);
}
}
[ConfigurationProperty("authCookieName")]
internal InnerTextConfigurationElement<string> AuthCookieName
{
get { return GetOptionalTextElement("authCookieName", Constants.Web.AuthCookieName); }
get
{
return new OptionalInnerTextConfigurationElement<string>(
(InnerTextConfigurationElement<string>)this["authCookieName"],
//set the default
Constants.Web.AuthCookieName);
}
}
[ConfigurationProperty("authCookieDomain")]
internal InnerTextConfigurationElement<string> AuthCookieDomain
{
get { return GetOptionalTextElement<string>("authCookieDomain", null); }
get
{
return new OptionalInnerTextConfigurationElement<string>(
(InnerTextConfigurationElement<string>)this["authCookieDomain"],
//set the default
null);
}
}
bool ISecuritySection.KeepUserLoggedIn
@@ -3,31 +3,55 @@ using System.Configuration;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class TemplatesElement : UmbracoConfigurationElement, ITemplatesSection
internal class TemplatesElement : ConfigurationElement, ITemplatesSection
{
[ConfigurationProperty("useAspNetMasterPages")]
internal InnerTextConfigurationElement<bool> UseAspNetMasterPages
{
get { return GetOptionalTextElement("useAspNetMasterPages", true); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["useAspNetMasterPages"],
//set the default
true);
}
}
[ConfigurationProperty("enableSkinSupport")]
internal InnerTextConfigurationElement<bool> EnableSkinSupport
{
get { return GetOptionalTextElement("enableSkinSupport", true); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["enableSkinSupport"],
//set the default
true);
}
}
[ConfigurationProperty("defaultRenderingEngine", IsRequired = true)]
internal InnerTextConfigurationElement<RenderingEngine> DefaultRenderingEngine
{
get { return GetOptionalTextElement("defaultRenderingEngine", RenderingEngine.Mvc); }
get
{
return new OptionalInnerTextConfigurationElement<RenderingEngine>(
(InnerTextConfigurationElement<RenderingEngine>)this["defaultRenderingEngine"],
//set the default
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); }
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["enableTemplateFolders"],
//set the default
false);
}
}
bool ITemplatesSection.UseAspNetMasterPages
@@ -1,36 +0,0 @@
using System.Collections.Concurrent;
using System.Configuration;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
/// <summary>
/// Base class with shared helper methods
/// </summary>
internal class UmbracoConfigurationElement : ConfigurationElement
{
/// <summary>
/// Used so the RawElement types are not re-created every time they are accessed
/// </summary>
private readonly ConcurrentDictionary<string, RawXmlConfigurationElement> _rawElements = new ConcurrentDictionary<string, RawXmlConfigurationElement>();
protected OptionalInnerTextConfigurationElement<T> GetOptionalTextElement<T>(string name, T defaultVal)
{
return (OptionalInnerTextConfigurationElement<T>) _rawElements.GetOrAdd(
name,
s => new OptionalInnerTextConfigurationElement<T>(
(InnerTextConfigurationElement<T>) this[s],
//set the default
defaultVal));
}
protected OptionalCommaDelimitedConfigurationElement GetOptionalDelimitedElement(string name, string[] defaultVal)
{
return (OptionalCommaDelimitedConfigurationElement) _rawElements.GetOrAdd(
name,
s => new OptionalCommaDelimitedConfigurationElement(
(CommaDelimitedConfigurationElement) this[name],
//set the default
defaultVal));
}
}
}
@@ -6,7 +6,7 @@ namespace Umbraco.Core.Configuration
{
public class UmbracoVersion
{
private static readonly Version Version = new Version("7.5.7");
private static readonly Version Version = new Version("7.5.6");
/// <summary>
/// Gets the current version of Umbraco.
+4 -25
View File
@@ -34,12 +34,6 @@ namespace Umbraco.Core
private string _connectionString;
private string _providerName;
private DatabaseSchemaResult _result;
private DateTime? _connectionLastChecked = null;
/// <summary>
/// The number of minutes to throttle the checks to CanConnect
/// </summary>
private const int ConnectionCheckMinutes = 1;
[Obsolete("Use the constructor specifying all dependencies instead")]
public DatabaseContext(IDatabaseFactory factory)
@@ -116,28 +110,13 @@ namespace Umbraco.Core
{
get
{
if (IsDatabaseConfigured == false)
return false;
//Don't check again if the timeout period hasn't elapsed
//this ensures we don't keep checking the connection too many times in a row like during startup.
//Do check if the _connectionLastChecked is null which means we're just initializing or it could
//not connect last time it was checked.
if ((_connectionLastChecked.HasValue && (DateTime.Now - _connectionLastChecked.Value).TotalMinutes > ConnectionCheckMinutes)
|| _connectionLastChecked.HasValue == false)
{
var canConnect = DbConnectionExtensions.IsConnectionAvailable(ConnectionString, DatabaseProvider);
LogHelper.Info<DatabaseContext>("CanConnect = " + canConnect);
_connectionLastChecked = canConnect == false ? null : (DateTime?) DateTime.Now;
return canConnect;
}
return _connectionLastChecked.HasValue;
if (IsDatabaseConfigured == false) return false;
var canConnect = DbConnectionExtensions.IsConnectionAvailable(ConnectionString, DatabaseProvider);
LogHelper.Info<DatabaseContext>("CanConnect = " + canConnect);
return canConnect;
}
}
/// <summary>
/// Gets the configured umbraco db connection string.
/// </summary>
@@ -1,9 +1,9 @@
using System;
using System.Runtime.CompilerServices;
using ImageProcessor.Common.Exceptions;
namespace Umbraco.Core.Logging
{
using System;
using System.Runtime.CompilerServices;
namespace Umbraco.Core.Logging
{
using ImageProcessor.Common.Exceptions;
/// <summary>
/// A logger for explicitly logging ImageProcessor exceptions.
+2 -1
View File
@@ -404,7 +404,8 @@ namespace Umbraco.Core.Models
return content.Properties
.Where(property => propertyGroup.PropertyTypes
.Select(propertyType => propertyType.Id)
.Contains(property.PropertyTypeId));
.Contains(property.PropertyTypeId))
.OrderBy(x => x.PropertyType.SortOrder);
}
/// <summary>
@@ -1,117 +1,15 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.UI.WebControls;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Rdbms;
namespace Umbraco.Core.Models
{
internal static class UmbracoEntityExtensions
{
/// <summary>
/// Does a quick check on the entity's set path to ensure that it's valid and consistent
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public static void ValidatePathWithException(this NodeDto entity)
{
//don't validate if it's empty and it has no id
if (entity.NodeId == default(int) && entity.Path.IsNullOrWhiteSpace())
return;
if (entity.Path.IsNullOrWhiteSpace())
throw new InvalidDataException(string.Format("The content item {0} has an empty path: {1} with parentID: {2}", entity.NodeId, entity.Path, entity.ParentId));
var pathParts = entity.Path.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
if (pathParts.Length < 2)
{
//a path cannot be less than 2 parts, at a minimum it must be root (-1) and it's own id
throw new InvalidDataException(string.Format("The content item {0} has an invalid path: {1} with parentID: {2}", entity.NodeId, entity.Path, entity.ParentId));
}
if (entity.ParentId != default(int) && pathParts[pathParts.Length - 2] != entity.ParentId.ToInvariantString())
{
//the 2nd last id in the path must be it's parent id
throw new InvalidDataException(string.Format("The content item {0} has an invalid path: {1} with parentID: {2}", entity.NodeId, entity.Path, entity.ParentId));
}
}
/// <summary>
/// Does a quick check on the entity's set path to ensure that it's valid and consistent
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public static bool ValidatePath(this IUmbracoEntity entity)
{
//don't validate if it's empty and it has no id
if (entity.HasIdentity == false && entity.Path.IsNullOrWhiteSpace())
return true;
if (entity.Path.IsNullOrWhiteSpace())
return false;
var pathParts = entity.Path.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
if (pathParts.Length < 2)
{
//a path cannot be less than 2 parts, at a minimum it must be root (-1) and it's own id
return false;
}
if (entity.ParentId != default(int) && pathParts[pathParts.Length - 2] != entity.ParentId.ToInvariantString())
{
//the 2nd last id in the path must be it's parent id
return false;
}
return true;
}
/// <summary>
/// This will validate the entity's path and if it's invalid it will fix it, if fixing is required it will recursively
/// check and fix all ancestors if required.
/// </summary>
/// <param name="entity"></param>
/// <param name="logger"></param>
/// <param name="getParent">A callback specified to retrieve the parent entity of the entity</param>
/// <param name="update">A callback specified to update a fixed entity</param>
public static void EnsureValidPath<T>(this T entity,
ILogger logger,
Func<T, T> getParent,
Action<T> update)
where T: IUmbracoEntity
{
if (entity.HasIdentity == false)
throw new InvalidOperationException("Could not ensure the entity path, the entity has not been assigned an identity");
if (entity.ValidatePath() == false)
{
logger.Warn(typeof(UmbracoEntityExtensions), string.Format("The content item {0} has an invalid path: {1} with parentID: {2}", entity.Id, entity.Path, entity.ParentId));
if (entity.ParentId == -1)
{
entity.Path = string.Concat("-1,", entity.Id);
//path changed, update it
update(entity);
}
else
{
var parent = getParent(entity);
if (parent == null)
throw new NullReferenceException("Could not ensure path for entity " + entity.Id + " could not resolve it's parent " + entity.ParentId);
//the parent must also be valid!
parent.EnsureValidPath(logger, getParent, update);
entity.Path = string.Concat(parent.Path, ",", entity.Id);
//path changed, update it
update(entity);
}
}
}
public static bool HasChildren(this IUmbracoEntity entity)
{
@@ -4,11 +4,9 @@ using System.Configuration;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Data.SqlServerCe;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MySql.Data.MySqlClient;
using Umbraco.Core.Logging;
namespace Umbraco.Core.Persistence
@@ -71,38 +69,6 @@ namespace Umbraco.Core.Persistence
}
}
public static string GetConnStringExSecurityInfo(this IDbConnection connection)
{
try
{
if (connection is SqlConnection)
{
var builder = new SqlConnectionStringBuilder(connection.ConnectionString);
return string.Format("DataSource: {0}, InitialCatalog: {1}", builder.DataSource, builder.InitialCatalog);
}
if (connection is SqlCeConnection)
{
var builder = new SqlCeConnectionStringBuilder(connection.ConnectionString);
return string.Format("DataSource: {0}", builder.DataSource);
}
if (connection is MySqlConnection)
{
var builder = new MySqlConnectionStringBuilder(connection.ConnectionString);
return string.Format("Server: {0}, Database: {1}", builder.Server, builder.Database);
}
}
catch (Exception ex)
{
LogHelper.WarnWithException(typeof(DbConnectionExtensions),
"Could not resolve connection string parameters", ex);
return "(Could not resolve)";
}
throw new ArgumentException(string.Format("The connection type {0} is not supported", connection.GetType()));
}
public static bool IsAvailable(this IDbConnection connection)
{
try
@@ -113,8 +79,7 @@ namespace Umbraco.Core.Persistence
catch (DbException exc)
{
// Don't swallow this error, the exception is super handy for knowing "why" its not available
LogHelper.WarnWithException(typeof(DbConnectionExtensions),
"Configured database is reporting as not being available! {0}", exc, connection.GetConnStringExSecurityInfo);
LogHelper.WarnWithException<IDbConnection>("Configured database is reporting as not being available!", exc);
return false;
}
@@ -27,7 +27,6 @@ namespace Umbraco.Core.Persistence
return sql.From(sqlSyntax.GetQuotedTableName(tableName));
}
[Obsolete("Use the overload specifying ISqlSyntaxProvider instead")]
public static Sql Where<T>(this Sql sql, Expression<Func<T, bool>> predicate)
{
var expresionist = new PocoToSqlExpressionVisitor<T>();
@@ -35,13 +34,6 @@ namespace Umbraco.Core.Persistence
return sql.Where(whereExpression, expresionist.GetSqlParameters());
}
public static Sql Where<T>(this Sql sql, Expression<Func<T, bool>> predicate, ISqlSyntaxProvider sqlSyntax)
{
var expresionist = new PocoToSqlExpressionVisitor<T>(sqlSyntax);
var whereExpression = expresionist.Visit(predicate);
return sql.Where(whereExpression, expresionist.GetSqlParameters());
}
private static string GetFieldName<T>(Expression<Func<T, object>> fieldSelector, ISqlSyntaxProvider sqlSyntax)
{
var field = ExpressionHelper.FindProperty(fieldSelector) as PropertyInfo;
@@ -14,14 +14,6 @@ namespace Umbraco.Core.Persistence.Querying
{
private readonly Database.PocoData _pd;
public PocoToSqlExpressionVisitor(ISqlSyntaxProvider syntaxProvider)
: base(syntaxProvider)
{
}
[Obsolete("Use the overload the specifies a SqlSyntaxProvider")]
public PocoToSqlExpressionVisitor()
: base(SqlSyntaxContext.SqlSyntaxProvider)
{
@@ -94,7 +94,13 @@ namespace Umbraco.Core.Persistence.Repositories
return ProcessQuery(sql);
}
#endregion
#endregion
#region Static Queries
private readonly IQuery<IContent> _publishedQuery = Query<IContent>.Builder.Where(x => x.Published == true);
#endregion
#region Overrides of PetaPocoRepositoryBase<IContent>
@@ -342,7 +348,6 @@ namespace Umbraco.Core.Persistence.Repositories
//Update with new correct path
nodeDto.Path = string.Concat(parent.Path, ",", nodeDto.NodeId);
nodeDto.ValidatePathWithException();
Database.Update(nodeDto);
//Update entity with correct values
@@ -480,7 +485,6 @@ namespace Umbraco.Core.Persistence.Repositories
//Updates the (base) node data - umbracoNode
var nodeDto = dto.ContentVersionDto.ContentDto.NodeDto;
nodeDto.ValidatePathWithException();
var o = Database.Update(nodeDto);
//Only update this DTO if the contentType has actually changed
@@ -853,8 +857,7 @@ order by umbracoNode.level, umbracoNode.parentID, umbracoNode.sortOrder";
if (withCache)
{
var cached = RuntimeCache.GetCacheItem<IContent>(GetCacheIdKey<IContent>(dto.NodeId));
//only use this cached version if the dto returned is also the publish version, they must match
if (cached != null && cached.Published && dto.Published)
if (cached != null && cached.Published)
{
content[i] = cached;
continue;
@@ -324,7 +324,6 @@ namespace Umbraco.Core.Persistence.Repositories
//Update with new correct path
nodeDto.Path = string.Concat(parent.Path, ",", nodeDto.NodeId);
nodeDto.ValidatePathWithException();
Database.Update(nodeDto);
//Update entity with correct values
@@ -398,7 +397,6 @@ namespace Umbraco.Core.Persistence.Repositories
//Updates the (base) node data - umbracoNode
var nodeDto = dto.ContentDto.NodeDto;
nodeDto.ValidatePathWithException();
var o = Database.Update(nodeDto);
//Only update this DTO if the contentType has actually changed
@@ -241,12 +241,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
entity.Path = string.Concat(parent.Path, ",", entity.Id);
}
else
{
//this means that the master template has been removed, so we need to reset the template's
//path to be at the root
entity.Path = string.Concat("-1,", entity.Id);
}
}
//Get TemplateDto from db to get the Primary key of the entity
+5 -43
View File
@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;
using System.Xml;
@@ -12,7 +11,6 @@ using Umbraco.Core.Configuration;
using Umbraco.Core.Events;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence;
@@ -60,7 +58,7 @@ namespace Umbraco.Core.Services
#region Static Queries
private IQuery<IContent> _notTrashedQuery;
private readonly IQuery<IContent> _notTrashedQuery = Query<IContent>.Builder.Where(x => x.Trashed == false);
#endregion
@@ -716,12 +714,7 @@ namespace Umbraco.Core.Services
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
public IEnumerable<IContent> GetDescendants(IContent content)
{
//This is a check to ensure that the path is correct for this entity to avoid problems like: http://issues.umbraco.org/issue/U4-9336 due to data corruption
if (content.ValidatePath() == false)
throw new InvalidDataException(string.Format("The content item {0} has an invalid path: {1} with parentID: {2}", content.Id, content.Path, content.ParentId));
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateContentRepository(uow))
using (var repository = RepositoryFactory.CreateContentRepository(UowProvider.GetUnitOfWork()))
{
var pathMatch = content.Path + ",";
var query = Query<IContent>.Builder.Where(x => x.Path.StartsWith(pathMatch) && x.Id != content.Id);
@@ -800,12 +793,6 @@ namespace Umbraco.Core.Services
/// <returns></returns>
internal IEnumerable<IContent> GetAllPublished()
{
//create it once if it is needed (no need for locking here)
if (_notTrashedQuery == null)
{
_notTrashedQuery = Query<IContent>.Builder.Where(x => x.Trashed == false);
}
using (var repository = RepositoryFactory.CreateContentRepository(UowProvider.GetUnitOfWork()))
{
return repository.GetByPublishedVersion(_notTrashedQuery);
@@ -1003,10 +990,6 @@ namespace Umbraco.Core.Services
using (new WriteLock(Locker))
{
//Hack: this ensures that the entity's path is valid and if not it fixes/persists it
//see: http://issues.umbraco.org/issue/U4-9336
content.EnsureValidPath(Logger, entity => GetById(entity.ParentId), QuickUpdate);
var originalPath = content.Path;
if (Trashing.IsRaisedEventCancelled(
@@ -1694,16 +1677,16 @@ namespace Umbraco.Core.Services
/// <returns>True if sorting succeeded, otherwise False</returns>
public bool Sort(IEnumerable<IContent> items, int userId = 0, bool raiseEvents = true)
{
var asArray = items.ToArray();
if (raiseEvents)
{
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IContent>(asArray), this))
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IContent>(items), this))
return false;
}
var shouldBePublished = new List<IContent>();
var shouldBeSaved = new List<IContent>();
var asArray = items.ToArray();
using (new WriteLock(Locker))
{
var uow = UowProvider.GetUnitOfWork();
@@ -1823,23 +1806,6 @@ namespace Umbraco.Core.Services
#region Private Methods
/// <summary>
/// Hack: This is used to fix some data if an entity's properties are invalid/corrupt
/// </summary>
/// <param name="content"></param>
private void QuickUpdate(IContent content)
{
if (content == null) throw new ArgumentNullException("content");
if (content.HasIdentity == false) throw new InvalidOperationException("Cannot update an entity without an Identity");
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateContentRepository(uow))
{
repository.AddOrUpdate(content);
uow.Commit();
}
}
private void Audit(AuditType type, string message, int userId, int objectId)
{
var uow = UowProvider.GetUnitOfWork();
@@ -1947,10 +1913,6 @@ namespace Umbraco.Core.Services
using (new WriteLock(Locker))
{
//Hack: this ensures that the entity's path is valid and if not it fixes/persists it
//see: http://issues.umbraco.org/issue/U4-9336
content.EnsureValidPath(Logger, entity => GetById(entity.ParentId), QuickUpdate);
var result = new List<Attempt<PublishStatus>>();
//Check if parent is published (although not if its a root node) - if parent isn't published this Content cannot be published
+1 -7
View File
@@ -64,7 +64,7 @@ namespace Umbraco.Core.Services
#region Static Queries
private IQuery<IUmbracoEntity> _rootEntityQuery;
private readonly IQuery<IUmbracoEntity> _rootEntityQuery = Query<IUmbracoEntity>.Builder.Where(x => x.ParentId == -1);
#endregion
@@ -392,12 +392,6 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of <see cref="IUmbracoEntity"/> objects</returns>
public virtual IEnumerable<IUmbracoEntity> GetRootEntities(UmbracoObjectTypes umbracoObjectType)
{
//create it once if it is needed (no need for locking here)
if (_rootEntityQuery == null)
{
_rootEntityQuery = Query<IUmbracoEntity>.Builder.Where(x => x.ParentId == -1);
}
var objectTypeId = umbracoObjectType.GetGuid();
using (var repository = RepositoryFactory.CreateEntityRepository(UowProvider.GetUnitOfWork()))
{
+50 -76
View File
@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
@@ -528,10 +527,6 @@ namespace Umbraco.Core.Services
/// <returns>An Enumerable flat list of <see cref="IMedia"/> objects</returns>
public IEnumerable<IMedia> GetDescendants(IMedia media)
{
//This is a check to ensure that the path is correct for this entity to avoid problems like: http://issues.umbraco.org/issue/U4-9336 due to data corruption
if (media.ValidatePath() == false)
throw new InvalidDataException(string.Format("The content item {0} has an invalid path: {1} with parentID: {2}", media.Id, media.Path, media.ParentId));
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateMediaRepository(uow))
{
@@ -624,7 +619,7 @@ namespace Umbraco.Core.Services
public IMedia GetMediaByPath(string mediaPath)
{
var umbracoFileValue = mediaPath;
const string Pattern = ".*[_][0-9]+[x][0-9]+[.].*";
var isResized = Regex.IsMatch(mediaPath, Pattern);
@@ -1003,63 +998,56 @@ namespace Umbraco.Core.Services
{
if (media == null) throw new ArgumentNullException("media");
var originalPath = media.Path;
var evtMsgs = EventMessagesFactory.Get();
using (new WriteLock(Locker))
if (Trashing.IsRaisedEventCancelled(
new MoveEventArgs<IMedia>(new MoveEventInfo<IMedia>(media, originalPath, Constants.System.RecycleBinMedia)), this))
{
//Hack: this ensures that the entity's path is valid and if not it fixes/persists it
//see: http://issues.umbraco.org/issue/U4-9336
media.EnsureValidPath(Logger, entity => GetById(entity.ParentId), QuickUpdate);
var originalPath = media.Path;
if (Trashing.IsRaisedEventCancelled(
new MoveEventArgs<IMedia>(new MoveEventInfo<IMedia>(media, originalPath, Constants.System.RecycleBinMedia)), this))
{
return OperationStatus.Cancelled(evtMsgs);
}
var moveInfo = new List<MoveEventInfo<IMedia>>
{
new MoveEventInfo<IMedia>(media, originalPath, Constants.System.RecycleBinMedia)
};
//Find Descendants, which will be moved to the recycle bin along with the parent/grandparent.
var descendants = GetDescendants(media).OrderBy(x => x.Level).ToList();
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateMediaRepository(uow))
{
//TODO: This should be part of the repo!
//Remove 'published' xml from the cmsContentXml table for the unpublished media
uow.Database.Delete<ContentXmlDto>("WHERE nodeId = @Id", new { Id = media.Id });
media.ChangeTrashedState(true, Constants.System.RecycleBinMedia);
repository.AddOrUpdate(media);
//Loop through descendants to update their trash state, but ensuring structure by keeping the ParentId
foreach (var descendant in descendants)
{
//Remove 'published' xml from the cmsContentXml table for the unpublished media
uow.Database.Delete<ContentXmlDto>("WHERE nodeId = @Id", new { Id = descendant.Id });
descendant.ChangeTrashedState(true, descendant.ParentId);
repository.AddOrUpdate(descendant);
moveInfo.Add(new MoveEventInfo<IMedia>(descendant, descendant.Path, descendant.ParentId));
}
uow.Commit();
}
Trashed.RaiseEvent(
new MoveEventArgs<IMedia>(false, evtMsgs, moveInfo.ToArray()), this);
Audit(AuditType.Move, "Move Media to Recycle Bin performed by user", userId, media.Id);
return OperationStatus.Success(evtMsgs);
return OperationStatus.Cancelled(evtMsgs);
}
var moveInfo = new List<MoveEventInfo<IMedia>>
{
new MoveEventInfo<IMedia>(media, originalPath, Constants.System.RecycleBinMedia)
};
//Find Descendants, which will be moved to the recycle bin along with the parent/grandparent.
var descendants = GetDescendants(media).OrderBy(x => x.Level).ToList();
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateMediaRepository(uow))
{
//TODO: This should be part of the repo!
//Remove 'published' xml from the cmsContentXml table for the unpublished media
uow.Database.Delete<ContentXmlDto>("WHERE nodeId = @Id", new { Id = media.Id });
media.ChangeTrashedState(true, Constants.System.RecycleBinMedia);
repository.AddOrUpdate(media);
//Loop through descendants to update their trash state, but ensuring structure by keeping the ParentId
foreach (var descendant in descendants)
{
//Remove 'published' xml from the cmsContentXml table for the unpublished media
uow.Database.Delete<ContentXmlDto>("WHERE nodeId = @Id", new { Id = descendant.Id });
descendant.ChangeTrashedState(true, descendant.ParentId);
repository.AddOrUpdate(descendant);
moveInfo.Add(new MoveEventInfo<IMedia>(descendant, descendant.Path, descendant.ParentId));
}
uow.Commit();
}
Trashed.RaiseEvent(
new MoveEventArgs<IMedia>(false, evtMsgs, moveInfo.ToArray()), this);
Audit(AuditType.Move, "Move Media to Recycle Bin performed by user", userId, media.Id);
return OperationStatus.Success(evtMsgs);
}
/// <summary>
@@ -1076,6 +1064,8 @@ namespace Umbraco.Core.Services
((IMediaServiceOperations)this).Delete(media, userId);
}
/// <summary>
/// Permanently deletes versions from an <see cref="IMedia"/> object prior to a specific date.
/// This method will never delete the latest version of a content item.
@@ -1164,6 +1154,7 @@ namespace Umbraco.Core.Services
public bool Sort(IEnumerable<IMedia> items, int userId = 0, bool raiseEvents = true)
{
var asArray = items.ToArray();
if (raiseEvents)
{
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMedia>(asArray), this))
@@ -1325,23 +1316,6 @@ namespace Umbraco.Core.Services
}
}
/// <summary>
/// Hack: This is used to fix some data if an entity's properties are invalid/corrupt
/// </summary>
/// <param name="media"></param>
private void QuickUpdate(IMedia media)
{
if (media == null) throw new ArgumentNullException("media");
if (media.HasIdentity == false) throw new InvalidOperationException("Cannot update an entity without an Identity");
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateMediaRepository(uow))
{
repository.AddOrUpdate(media);
uow.Commit();
}
}
#region Event Handlers
/// <summary>
-24
View File
@@ -1,24 +0,0 @@
namespace Umbraco.Core.Sync
{
/// <summary>
/// The type of Cold Boot taking place
/// </summary>
public enum ColdBootType
{
/// <summary>
/// Indicates there was no cold boot
/// </summary>
NoColdBoot,
/// <summary>
/// This indicates that there is no lasysynced file for the current machine/appid
/// </summary>
NeverSynced,
/// <summary>
/// This indicates that the number of instructions needing to be processed exceeds the value stored
/// for the <see cref="DatabaseServerMessengerOptions.MaxProcessingInstructionCount"/>
/// </summary>
ExceedsMaxProcessingInstructionCount
}
}
@@ -43,11 +43,6 @@ namespace Umbraco.Core.Sync
protected DatabaseServerMessengerOptions Options { get; private set; }
protected ApplicationContext ApplicationContext { get { return _appContext; } }
/// <summary>
/// Returns the cold boot type detected for the current app domain
/// </summary>
public ColdBootType ColdBootType { get; private set; }
public DatabaseServerMessenger(ApplicationContext appContext, bool distributedEnabled, DatabaseServerMessengerOptions options)
: base(distributedEnabled)
{
@@ -151,12 +146,11 @@ namespace Umbraco.Core.Sync
/// </remarks>
private void Initialize()
{
ColdBootType = ColdBootType.NoColdBoot;
lock (_locko)
{
if (_released) return;
var coldboot = false;
if (_lastId < 0) // never synced before
{
// we haven't synced - in this case we aren't going to sync the whole thing, we will assume this is a new
@@ -165,7 +159,7 @@ namespace Umbraco.Core.Sync
+ " The server will build its caches and indexes, and then adjust its last synced Id to the latest found in"
+ " the database and maintain cache updates based on that Id.");
ColdBootType = ColdBootType.NeverSynced;
coldboot = true;
}
else
{
@@ -181,11 +175,11 @@ namespace Umbraco.Core.Sync
+ " to the latest found in the database and maintain cache updates based on that Id.",
() => count, () => Options.MaxProcessingInstructionCount);
ColdBootType = ColdBootType.ExceedsMaxProcessingInstructionCount;
coldboot = true;
}
}
if (ColdBootType != ColdBootType.NoColdBoot)
if (coldboot)
{
// go get the last id in the db and store it
// note: do it BEFORE initializing otherwise some instructions might get lost
+26 -11
View File
@@ -21,7 +21,7 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG</DefineConstants>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
@@ -39,54 +39,67 @@
<ItemGroup>
<Reference Include="AutoMapper, Version=3.3.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="AutoMapper.Net4, Version=3.3.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.Net4.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="HtmlAgilityPack, Version=1.4.9.0, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\HtmlAgilityPack.1.4.9\lib\Net45\HtmlAgilityPack.dll</HintPath>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<Reference Include="ICSharpCode.SharpZipLib">
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
<Reference Include="ImageProcessor, Version=2.5.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ImageProcessor.2.5.1\lib\net45\ImageProcessor.dll</HintPath>
<Reference Include="ImageProcessor, Version=2.4.5.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ImageProcessor.2.4.5.0\lib\net45\ImageProcessor.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="log4net, Version=1.2.11.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\log4net-mediumtrust.2.0.0\lib\log4net.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AspNet.Identity.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AspNet.Identity.Owin, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.AspNet.Identity.Owin.2.2.1\lib\net45\Microsoft.AspNet.Identity.Owin.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Security, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="Microsoft.Owin.Security">
<HintPath>..\packages\Microsoft.Owin.Security.3.0.1\lib\net45\Microsoft.Owin.Security.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.Security.Cookies, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.Owin.Security.Cookies.3.0.1\lib\net45\Microsoft.Owin.Security.Cookies.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Security.OAuth, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.Owin.Security.OAuth.3.0.1\lib\net45\Microsoft.Owin.Security.OAuth.dll</HintPath>
</Reference>
<Reference Include="MiniProfiler, Version=2.1.0.0, Culture=neutral, PublicKeyToken=b44f9351044011a3, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\MiniProfiler.2.1.0\lib\net40\MiniProfiler.dll</HintPath>
</Reference>
<Reference Include="MySql.Data, Version=6.9.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
<Reference Include="MySql.Data">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<Reference Include="Owin">
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
</Reference>
<Reference Include="Semver, Version=1.1.2.0, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="Semver">
<HintPath>..\packages\semver.1.1.2\lib\net45\Semver.dll</HintPath>
</Reference>
<Reference Include="System" />
@@ -94,9 +107,11 @@
<Reference Include="System.Configuration" />
<Reference Include="System.Data.Entity" />
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.dll</HintPath>
</Reference>
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.Entity.dll</HintPath>
</Reference>
<Reference Include="System.DirectoryServices.AccountManagement" />
@@ -281,7 +296,6 @@
<Compile Include="Configuration\UmbracoSettings\ServerCollection.cs" />
<Compile Include="Configuration\UmbracoSettings\ServerElement.cs" />
<Compile Include="Configuration\UmbracoSettings\TemplatesElement.cs" />
<Compile Include="Configuration\UmbracoSettings\UmbracoConfigurationElement.cs" />
<Compile Include="Configuration\UmbracoSettings\UmbracoSettingsSection.cs" />
<Compile Include="Configuration\UmbracoSettings\UrlReplacingElement.cs" />
<Compile Include="Configuration\UmbracoSettings\UserProviderElement.cs" />
@@ -1311,7 +1325,6 @@
<Compile Include="Strings\ContentBaseExtensions.cs" />
<Compile Include="Strings\Diff.cs" />
<Compile Include="Sync\BatchedWebServiceServerMessenger.cs" />
<Compile Include="Sync\ColdBootType.cs" />
<Compile Include="Sync\IServerRegistrar2.cs" />
<Compile Include="Sync\ServerRole.cs" />
<Compile Include="Sync\DatabaseServerMessenger.cs" />
@@ -1427,7 +1440,9 @@
<ItemGroup>
<None Include="app.config" />
<None Include="FileResources\BlockingWeb.config" />
<None Include="packages.config" />
<None Include="packages.config">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\umbraco.interfaces\umbraco.interfaces.csproj">
+3 -3
View File
@@ -2,8 +2,8 @@
<packages>
<package id="AutoMapper" version="3.3.1" targetFramework="net45" />
<package id="HtmlAgilityPack" version="1.4.9" targetFramework="net45" />
<package id="ImageProcessor" version="2.5.1" targetFramework="net45" />
<package id="log4net-mediumtrust" version="2.0.0" targetFramework="net45" />
<package id="ImageProcessor" version="2.4.5.0" targetFramework="net45" />
<package id="log4net-mediumtrust" version="2.0.0" targetFramework="net4" />
<package id="Microsoft.AspNet.Identity.Core" version="2.2.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Identity.Owin" version="2.2.1" targetFramework="net45" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" />
@@ -15,6 +15,6 @@
<package id="Newtonsoft.Json" version="6.0.8" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
<package id="semver" version="1.1.2" targetFramework="net45" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net45" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net4" />
<package id="SqlServerCE" version="4.0.0.1" targetFramework="net45" />
</packages>
@@ -1,58 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Diagnostics.Windows;
namespace Umbraco.Tests.Benchmarks
{
/// <summary>
/// Want to check what is faster OfType or Cast when a enurable all has the same items
/// </summary>
[Config(typeof(Config))]
public class LinqCastBenchmarks
{
private class Config : ManualConfig
{
public Config()
{
Add(new MemoryDiagnoser());
}
}
public LinqCastBenchmarks()
{
_array = new List<object>();
_array.AddRange(Enumerable.Range(0, 10000).Select(x => x.ToString()));
}
private readonly List<object> _array;
[Benchmark(Baseline = true)]
public void OfType()
{
foreach (var i in _array.OfType<string>())
{
var a = i;
}
}
[Benchmark()]
public void Cast()
{
foreach (var i in _array.Cast<string>())
{
var a = i;
}
}
[Benchmark()]
public void ExplicitCast()
{
foreach (var i in _array)
{
var a = (string)i;
}
}
}
}
+16 -7
View File
@@ -8,14 +8,23 @@ namespace Umbraco.Tests.Benchmarks
{
public static void Main(string[] args)
{
var switcher = new BenchmarkSwitcher(new[]
if (args.Length == 1)
{
typeof(BulkInsertBenchmarks),
typeof(ModelToSqlExpressionHelperBenchmarks),
typeof(XmlBenchmarks),
typeof(LinqCastBenchmarks)
});
switcher.Run(args);
var type = Assembly.GetExecutingAssembly().GetType("Umbraco.Tests.Benchmarks." +args[0]);
if (type == null)
{
Console.WriteLine("Unknown benchmark.");
}
else
{
var summary = BenchmarkRunner.Run(type);
Console.ReadLine();
}
}
else
{
Console.WriteLine("?");
}
}
}
}
@@ -39,24 +39,31 @@
<ItemGroup>
<Reference Include="BenchmarkDotNet, Version=0.9.9.0, Culture=neutral, PublicKeyToken=aa0ca2f9092cefc4, processorArchitecture=MSIL">
<HintPath>..\packages\BenchmarkDotNet.0.9.9\lib\net45\BenchmarkDotNet.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="BenchmarkDotNet.Core, Version=0.9.9.0, Culture=neutral, PublicKeyToken=aa0ca2f9092cefc4, processorArchitecture=MSIL">
<HintPath>..\packages\BenchmarkDotNet.Core.0.9.9\lib\net45\BenchmarkDotNet.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="BenchmarkDotNet.Diagnostics.Windows, Version=0.9.9.0, Culture=neutral, PublicKeyToken=aa0ca2f9092cefc4, processorArchitecture=MSIL">
<HintPath>..\packages\BenchmarkDotNet.Diagnostics.Windows.0.9.9\lib\net45\BenchmarkDotNet.Diagnostics.Windows.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="BenchmarkDotNet.Toolchains.Roslyn, Version=0.9.9.0, Culture=neutral, PublicKeyToken=aa0ca2f9092cefc4, processorArchitecture=MSIL">
<HintPath>..\packages\BenchmarkDotNet.Toolchains.Roslyn.0.9.9\lib\net45\BenchmarkDotNet.Toolchains.Roslyn.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.CodeAnalysis, Version=1.3.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeAnalysis.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.CodeAnalysis.CSharp, Version=1.3.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeAnalysis.CSharp.1.3.2\lib\net45\Microsoft.CodeAnalysis.CSharp.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Diagnostics.Tracing.TraceEvent, Version=1.0.41.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Diagnostics.Tracing.TraceEvent.1.0.41\lib\net40\Microsoft.Diagnostics.Tracing.TraceEvent.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Collections.Immutable, Version=1.1.37.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
@@ -66,16 +73,20 @@
<Reference Include="System.Core" />
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.Entity.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Management" />
<Reference Include="System.Reflection.Metadata, Version=1.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Reflection.Metadata.1.2.0\lib\portable-net45+win8\System.Reflection.Metadata.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.0.0\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
@@ -85,7 +96,6 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="LinqCastBenchmarks.cs" />
<Compile Include="ModelToSqlExpressionHelperBenchmarks.cs" />
<Compile Include="BulkInsertBenchmarks.cs" />
<Compile Include="Program.cs" />
@@ -96,6 +106,10 @@
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.1.1.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.Analyzers.dll" />
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.1.1.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.Analyzers.dll" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Umbraco.Core\Umbraco.Core.csproj">
<Project>{31785bc3-256c-4613-b2f5-a1b0bdded8c1}</Project>
@@ -106,22 +120,7 @@
<Name>Umbraco.Tests</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.1.1.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.Analyzers.dll" />
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.1.1.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.Analyzers.dll" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>
if not exist "$(TargetDir)x86" md "$(TargetDir)x86"
xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8854.1\NativeBinaries\x86\*.*" "$(TargetDir)x86"
if not exist "$(TargetDir)amd64" md "$(TargetDir)amd64"
xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8854.1\NativeBinaries\amd64\*.*" "$(TargetDir)amd64"</PostBuildEvent>
</PropertyGroup>
<PropertyGroup>
<PreBuildEvent>xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\amd64\*.* "$(TargetDir)amd64\" /Y /F /E /I /C /D
xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\" /Y /F /E /I /C /D</PreBuildEvent>
</PropertyGroup>
<Import Project="..\packages\Microsoft.Diagnostics.Tracing.TraceEvent.1.0.41\build\Microsoft.Diagnostics.Tracing.TraceEvent.targets" Condition="Exists('..\packages\Microsoft.Diagnostics.Tracing.TraceEvent.1.0.41\build\Microsoft.Diagnostics.Tracing.TraceEvent.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
@@ -129,6 +128,14 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\"
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Diagnostics.Tracing.TraceEvent.1.0.41\build\Microsoft.Diagnostics.Tracing.TraceEvent.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Diagnostics.Tracing.TraceEvent.1.0.41\build\Microsoft.Diagnostics.Tracing.TraceEvent.targets'))" />
</Target>
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
<PropertyGroup>
<PreBuildEvent>xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\amd64\*.* "$(TargetDir)amd64\" /Y /F /E /I /C /D
xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\" /Y /F /E /I /C /D</PreBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
@@ -1,10 +1,7 @@
using System;
using System.Diagnostics;
using Moq;
using NUnit.Framework;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Serialization;
namespace Umbraco.Tests.Models
@@ -12,132 +9,6 @@ namespace Umbraco.Tests.Models
[TestFixture]
public class UmbracoEntityTests
{
[Test]
public void Validate_Path()
{
var entity = new UmbracoEntity();
//it's empty with no id so we need to allow it
Assert.IsTrue(entity.ValidatePath());
entity.Id = 1234;
//it has an id but no path, so we can't allow it
Assert.IsFalse(entity.ValidatePath());
entity.Path = "-1";
//invalid path
Assert.IsFalse(entity.ValidatePath());
entity.Path = string.Concat("-1,", entity.Id);
//valid path
Assert.IsTrue(entity.ValidatePath());
}
[Test]
public void Ensure_Path_Throws_Without_Id()
{
var entity = new UmbracoEntity();
//no id assigned
Assert.Throws<InvalidOperationException>(() => entity.EnsureValidPath(Mock.Of<ILogger>(), umbracoEntity => new UmbracoEntity(), umbracoEntity => { }));
}
[Test]
public void Ensure_Path_Throws_Without_Parent()
{
var entity = new UmbracoEntity {Id = 1234};
//no parent found
Assert.Throws<NullReferenceException>(() => entity.EnsureValidPath(Mock.Of<ILogger>(), umbracoEntity => null, umbracoEntity => { }));
}
[Test]
public void Ensure_Path_Entity_At_Root()
{
var entity = new UmbracoEntity
{
Id = 1234,
ParentId = -1
};
entity.EnsureValidPath(Mock.Of<ILogger>(), umbracoEntity => null, umbracoEntity => { });
//works because it's under the root
Assert.AreEqual("-1,1234", entity.Path);
}
[Test]
public void Ensure_Path_Entity_Valid_Parent()
{
var entity = new UmbracoEntity
{
Id = 1234,
ParentId = 888
};
entity.EnsureValidPath(Mock.Of<ILogger>(), umbracoEntity => umbracoEntity.ParentId == 888 ? new UmbracoEntity{Id = 888, Path = "-1,888"} : null, umbracoEntity => { });
//works because the parent was found
Assert.AreEqual("-1,888,1234", entity.Path);
}
[Test]
public void Ensure_Path_Entity_Valid_Recursive_Parent()
{
var parentA = new UmbracoEntity
{
Id = 999,
ParentId = -1
};
var parentB = new UmbracoEntity
{
Id = 888,
ParentId = 999
};
var parentC = new UmbracoEntity
{
Id = 777,
ParentId = 888
};
var entity = new UmbracoEntity
{
Id = 1234,
ParentId = 777
};
Func<IUmbracoEntity, IUmbracoEntity> getParent = umbracoEntity =>
{
switch (umbracoEntity.ParentId)
{
case 999:
return parentA;
case 888:
return parentB;
case 777:
return parentC;
case 1234:
return entity;
default:
return null;
}
};
//this will recursively fix all paths
entity.EnsureValidPath(Mock.Of<ILogger>(), getParent, umbracoEntity => { });
Assert.AreEqual("-1,999", parentA.Path);
Assert.AreEqual("-1,999,888", parentB.Path);
Assert.AreEqual("-1,999,888,777", parentC.Path);
Assert.AreEqual("-1,999,888,777,1234", entity.Path);
}
[Test]
public void UmbracoEntity_Can_Be_Initialized_From_Dynamic()
{
@@ -707,35 +707,6 @@ namespace Umbraco.Tests.Persistence.Repositories
}
}
[Test]
public void Path_Is_Set_Correctly_On_Update_With_Master_Template_Removal()
{
// Arrange
var provider = new PetaPocoUnitOfWorkProvider(Logger);
var unitOfWork = provider.GetUnitOfWork();
using (var repository = CreateRepository(unitOfWork))
{
var parent = new Template("parent", "parent");
var child1 = new Template("child1", "child1");
child1.MasterTemplateAlias = parent.Alias;
child1.MasterTemplateId = new Lazy<int>(() => parent.Id);
repository.AddOrUpdate(parent);
repository.AddOrUpdate(child1);
unitOfWork.Commit();
//Act
child1.SetMasterTemplate(null);
repository.AddOrUpdate(child1);
unitOfWork.Commit();
//Assert
Assert.AreEqual(string.Format("-1,{0}", child1.Id), child1.Path);
}
}
[TearDown]
public override void TearDown()
@@ -32,7 +32,7 @@ namespace Umbraco.Tests.Routing
}
/// <summary>
/// This checks that when we retrieve a NiceUrl for multiple items that there are no issues with cache overlap
/// This checks that when we retrieve a NiceUrl for multiple items that there are no issues with cache overlap
/// and that they are all cached correctly.
/// </summary>
[Test]
@@ -71,19 +71,25 @@ namespace Umbraco.Tests.Routing
var cache = routingContext.UmbracoContext.ContentCache.InnerCache as PublishedContentCache;
if (cache == null) throw new Exception("Unsupported IPublishedContentCache, only the Xml one is supported.");
var cachedRoutes = cache.RoutesCache.GetCachedRoutes();
Assert.AreEqual(8, cachedRoutes.Count);
Assert.AreEqual(8, cachedRoutes.Count);
foreach (var sample in samples)
{
Assert.IsTrue(cachedRoutes.ContainsKey(sample.Key));
Assert.AreEqual(sample.Value, cachedRoutes[sample.Key]);
}
foreach (var sample in samples)
{
Assert.IsTrue(cachedRoutes.ContainsKey(sample.Key));
Assert.AreEqual(sample.Value, cachedRoutes[sample.Key]);
}
var cachedIds = cache.RoutesCache.GetCachedIds();
Assert.AreEqual(0, cachedIds.Count);
}
var cachedIds = cache.RoutesCache.GetCachedIds();
Assert.AreEqual(8, cachedIds.Count);
foreach (var sample in samples)
{
var key = sample.Value;
Assert.IsTrue(cachedIds.ContainsKey(key));
Assert.AreEqual(sample.Key, cachedIds[key]);
}
}
// test hideTopLevelNodeFromPath false
[TestCase(1046, "/home/")]
@@ -141,10 +147,10 @@ namespace Umbraco.Tests.Routing
var routingContext = GetRoutingContext("http://example.com/test", 1111, umbracoSettings: _umbracoSettings);
Assert.AreEqual("/home/sub1/custom-sub-1/", routingContext.UrlProvider.GetUrl(1177));
requestMock.Setup(x => x.UseDomainPrefixes).Returns(true);
Assert.AreEqual("http://example.com/home/sub1/custom-sub-1/", routingContext.UrlProvider.GetUrl(1177));
@@ -167,14 +173,14 @@ namespace Umbraco.Tests.Routing
Assert.AreEqual("#", routingContext.UrlProvider.GetUrl(999999));
requestMock.Setup(x => x.UseDomainPrefixes).Returns(true);
requestMock.Setup(x => x.UseDomainPrefixes).Returns(true);
Assert.AreEqual("#", routingContext.UrlProvider.GetUrl(999999));
requestMock.Setup(x => x.UseDomainPrefixes).Returns(false);
routingContext.UrlProvider.Mode = UrlProviderMode.Absolute;
Assert.AreEqual("#", routingContext.UrlProvider.GetUrl(999999));
}
}
@@ -1,325 +0,0 @@
using System;
using NUnit.Framework;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web.PublishedCache.XmlPublishedCache;
using Umbraco.Web.Routing;
namespace Umbraco.Tests.Routing
{
// purpose: test the values returned by PublishedContentCache.GetRouteById
// and .GetByRoute (no caching at all, just routing nice urls) including all
// the quirks due to hideTopLevelFromPath and backward compatibility.
[DatabaseTestBehavior(DatabaseBehavior.NewDbFileAndSchemaPerFixture)]
[TestFixture]
public class NiceUrlRoutesTests : BaseRoutingTest
{
#region Test Setup
protected override void FreezeResolution()
{
SiteDomainHelperResolver.Current = new SiteDomainHelperResolver(new SiteDomainHelper());
base.FreezeResolution();
}
private IUmbracoSettingsSection _umbracoSettings;
public override void Initialize()
{
base.Initialize();
//generate new mock settings and assign so we can configure in individual tests
_umbracoSettings = SettingsForTests.GenerateMockSettings();
SettingsForTests.ConfigureSettings(_umbracoSettings);
}
protected override string GetXmlContent(int templateId)
{
return @"<?xml version=""1.0"" encoding=""utf-8""?>
<!DOCTYPE root[
<!ELEMENT Doc ANY>
<!ATTLIST Doc id ID #REQUIRED>
]>
<root id=""-1"">
<Doc id=""1000"" parentID=""-1"" level=""1"" path=""-1,1000"" nodeName=""A"" urlName=""a"" sortOrder=""1"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" createDate=""2012-06-12T14:13:17"" updateDate=""2012-07-20T18:50:43"" writerName=""admin"" creatorName=""admin"" isDoc="""">
<Doc id=""1001"" parentID=""1000"" level=""2"" path=""-1,1000,1001"" nodeName=""B"" urlName=""b"" sortOrder=""1"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" createDate=""2012-07-20T18:06:45"" updateDate=""2012-07-20T19:07:31"" writerName=""admin"" creatorName=""admin"" isDoc="""">
<Doc id=""1002"" parentID=""1001"" level=""3"" path=""-1,1000,1001,1002"" nodeName=""C"" urlName=""c"" sortOrder=""1"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" createDate=""2012-07-20T18:06:45"" updateDate=""2012-07-20T19:07:31"" writerName=""admin"" creatorName=""admin"" isDoc="""">
<Doc id=""1003"" parentID=""1002"" level=""4"" path=""-1,1000,1001,1002,1003"" nodeName=""D"" urlName=""d"" sortOrder=""1"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" createDate=""2012-07-20T18:06:45"" updateDate=""2012-07-20T19:07:31"" writerName=""admin"" creatorName=""admin"" isDoc="""">
</Doc>
</Doc>
</Doc>
</Doc>
<Doc id=""2000"" parentID=""-1"" level=""1"" path=""-1,2000"" nodeName=""X"" urlName=""x"" sortOrder=""1"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" createDate=""2012-06-12T14:13:17"" updateDate=""2012-07-20T18:50:43"" writerName=""admin"" creatorName=""admin"" isDoc="""">
<Doc id=""2001"" parentID=""2000"" level=""2"" path=""-1,2000,2001"" nodeName=""Y"" urlName=""y"" sortOrder=""1"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" createDate=""2012-06-12T14:13:17"" updateDate=""2012-07-20T18:50:43"" writerName=""admin"" creatorName=""admin"" isDoc="""">
<Doc id=""2002"" parentID=""2001"" level=""3"" path=""-1,2000,2001,2002"" nodeName=""Z"" urlName=""z"" sortOrder=""1"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" createDate=""2012-06-12T14:13:17"" updateDate=""2012-07-20T18:50:43"" writerName=""admin"" creatorName=""admin"" isDoc="""">
</Doc>
</Doc>
<Doc id=""2003"" parentID=""2000"" level=""2"" path=""-1,2000,2003"" nodeName=""A"" urlName=""a"" sortOrder=""2"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" createDate=""2012-06-12T14:13:17"" updateDate=""2012-07-20T18:50:43"" writerName=""admin"" creatorName=""admin"" isDoc="""">
</Doc>
<Doc id=""2004"" parentID=""2000"" level=""2"" path=""-1,2000,2004"" nodeName=""B"" urlName=""b"" sortOrder=""3"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" createDate=""2012-06-12T14:13:17"" updateDate=""2012-07-20T18:50:43"" writerName=""admin"" creatorName=""admin"" isDoc="""">
<Doc id=""2005"" parentID=""2004"" level=""3"" path=""-1,2000,2004,2005"" nodeName=""C"" urlName=""c"" sortOrder=""1"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" createDate=""2012-06-12T14:13:17"" updateDate=""2012-07-20T18:50:43"" writerName=""admin"" creatorName=""admin"" isDoc="""">
</Doc>
<Doc id=""2006"" parentID=""2004"" level=""3"" path=""-1,2000,2004,2006"" nodeName=""E"" urlName=""e"" sortOrder=""1"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" createDate=""2012-06-12T14:13:17"" updateDate=""2012-07-20T18:50:43"" writerName=""admin"" creatorName=""admin"" isDoc="""">
</Doc>
</Doc>
</Doc>
</root>";
}
#endregion
/*
* Just so it's documented somewhere, as of jan. 2017, routes obey the following pseudo-code:
GetByRoute(route, hide = null):
route is "[id]/[path]"
hide = hide ?? global.hide
root = id ? node(id) : document
content = cached(route) ?? DetermineIdByRoute(route, hide)
# route is "1234/path/to/content", finds "content"
# but if there is domain 5678 on "to", the *true* route of "content" is "5678/content"
# so although the route does match, we don't cache it
# there are not other reason not to cache it
if content and no domain between root and content:
cache route (as trusted)
return content
DetermineIdByRoute(route, hide):
route is "[id]/[path]"
try return NavigateRoute(id ?? 0, path, hide:hide)
return null
NavigateRoute(id, path, hide):
if path:
if id:
start = node(id)
else:
start = document
# 'navigate ... from ...' uses lowest sortOrder in case of collision
if hide and ![id]:
# if hiding, then for "/foo" we want to look for "/[any]/foo"
for each child of start:
try return navigate path from child
# but if it fails, we also want to try "/foo"
# fail now if more than one part eg "/foo/bar"
if path is "/[any]/...":
fail
try return navigate path from start
else:
if id:
return node(id)
else:
return root node with lowest sortOrder
GetRouteById(id):
route = cached(id)
if route:
return route
# never cache the route, it may be colliding
route = DetermineRouteById(id)
if route:
cache route (as not trusted)
return route
DetermineRouteById(id):
node = node(id)
walk up from node to domain or root, assemble parts = url segments
if !domain and global.hide:
if id.parent:
# got /top/[path]content, can remove /top
remove top part
else:
# got /content, should remove only if it is the
# node with lowest sort order
root = root node with lowest sortOrder
if root == node:
remove top part
compose path from parts
route = assemble "[domain.id]/[path]"
return route
*/
/*
* The Xml structure for the following tests is:
*
* root
* A 1000
* B 1001
* C 1002
* D 1003
* X 2000
* Y 2001
* Z 2002
* A 2003
* B 2004
* C 2005
* E 2006
*
*/
[TestCase(1000, false, "/a")]
[TestCase(1001, false, "/a/b")]
[TestCase(1002, false, "/a/b/c")]
[TestCase(1003, false, "/a/b/c/d")]
[TestCase(2000, false, "/x")]
[TestCase(2001, false, "/x/y")]
[TestCase(2002, false, "/x/y/z")]
[TestCase(2003, false, "/x/a")]
[TestCase(2004, false, "/x/b")]
[TestCase(2005, false, "/x/b/c")]
[TestCase(2006, false, "/x/b/e")]
[TestCase(1000, true, "/")]
[TestCase(1001, true, "/b")]
[TestCase(1002, true, "/b/c")]
[TestCase(1003, true, "/b/c/d")]
[TestCase(2000, true, "/x")]
[TestCase(2001, true, "/y")]
[TestCase(2002, true, "/y/z")]
[TestCase(2003, true, "/a")]
[TestCase(2004, true, "/b")] // collision!
[TestCase(2005, true, "/b/c")] // collision!
[TestCase(2006, true, "/b/e")] // risky!
public void GetRouteById(int id, bool hide, string expected)
{
var umbracoContext = GetUmbracoContext("/test", 0);
var cache = umbracoContext.ContentCache.InnerCache as PublishedContentCache;
if (cache == null) throw new Exception("Unsupported IPublishedContentCache, only the Xml one is supported.");
SettingsForTests.HideTopLevelNodeFromPath = hide;
const bool preview = true; // make sure we don't cache
var route = cache.GetRouteById(umbracoContext, preview, id);
Assert.AreEqual(expected, route);
}
[Test]
public void GetRouteByIdCache()
{
var umbracoContext = GetUmbracoContext("/test", 0);
var cache = umbracoContext.ContentCache.InnerCache as PublishedContentCache;
if (cache == null) throw new Exception("Unsupported IPublishedContentCache, only the Xml one is supported.");
SettingsForTests.HideTopLevelNodeFromPath = false;
// make sure we cache
PublishedContentCache.UnitTesting = false;
const bool preview = false;
var route = cache.GetRouteById(umbracoContext, preview, 1000);
Assert.AreEqual("/a", route);
// GetRouteById registers a non-trusted route, which is cached for
// id -> route queries (fast GetUrl) but *not* for route -> id
// queries (safe inbound routing)
var cachedRoutes = cache.RoutesCache.GetCachedRoutes();
Assert.AreEqual(1, cachedRoutes.Count);
Assert.IsTrue(cachedRoutes.ContainsKey(1000));
Assert.AreEqual("/a", cachedRoutes[1000]);
var cachedIds = cache.RoutesCache.GetCachedIds();
Assert.AreEqual(0, cachedIds.Count);
}
[TestCase("/", false, 1000)]
[TestCase("/a", false, 1000)] // yes!
[TestCase("/a/b", false, 1001)]
[TestCase("/a/b/c", false, 1002)]
[TestCase("/a/b/c/d", false, 1003)]
[TestCase("/x", false, 2000)]
[TestCase("/", true, 1000)]
[TestCase("/a", true, 2003)]
[TestCase("/a/b", true, -1)]
[TestCase("/x", true, 2000)] // oops!
[TestCase("/x/y", true, -1)] // yes!
[TestCase("/y", true, 2001)]
[TestCase("/y/z", true, 2002)]
[TestCase("/b", true, 1001)] // (hence the 2004 collision)
[TestCase("/b/c", true, 1002)] // (hence the 2005 collision)
public void GetByRoute(string route, bool hide, int expected)
{
var umbracoContext = GetUmbracoContext("/test", 0);
var cache = umbracoContext.ContentCache.InnerCache as PublishedContentCache;
if (cache == null) throw new Exception("Unsupported IPublishedContentCache, only the Xml one is supported.");
SettingsForTests.HideTopLevelNodeFromPath = hide;
const bool preview = true; // make sure we don't cache
var content = cache.GetByRoute(umbracoContext, preview, route);
if (expected < 0)
{
Assert.IsNull(content);
}
else
{
Assert.IsNotNull(content);
Assert.AreEqual(expected, content.Id);
}
}
[Test]
public void GetByRouteCache()
{
var umbracoContext = GetUmbracoContext("/test", 0);
var cache = umbracoContext.ContentCache.InnerCache as PublishedContentCache;
if (cache == null) throw new Exception("Unsupported IPublishedContentCache, only the Xml one is supported.");
SettingsForTests.HideTopLevelNodeFromPath = false;
// make sure we cache
PublishedContentCache.UnitTesting = false;
const bool preview = false;
var content = cache.GetByRoute(umbracoContext, preview, "/a/b/c");
Assert.IsNotNull(content);
Assert.AreEqual(1002, content.Id);
// GetByRoute registers a trusted route, which is cached both for
// id -> route queries (fast GetUrl) and for route -> id queries
// (fast inbound routing)
var cachedRoutes = cache.RoutesCache.GetCachedRoutes();
Assert.AreEqual(1, cachedRoutes.Count);
Assert.IsTrue(cachedRoutes.ContainsKey(1002));
Assert.AreEqual("/a/b/c", cachedRoutes[1002]);
var cachedIds = cache.RoutesCache.GetCachedIds();
Assert.AreEqual(1, cachedIds.Count);
Assert.IsTrue(cachedIds.ContainsKey("/a/b/c"));
Assert.AreEqual(1002, cachedIds["/a/b/c"]);
}
}
}
@@ -79,7 +79,7 @@ namespace Umbraco.Tests.Routing
protected override string GetXmlContent(int templateId)
{
return @"<?xml version=""1.0"" encoding=""utf-8""?>
<!DOCTYPE root[
<!DOCTYPE root[
<!ELEMENT Doc ANY>
<!ATTLIST Doc id ID #REQUIRED>
]>
@@ -302,12 +302,11 @@ namespace Umbraco.Tests.Routing
var cache = routingContext.UmbracoContext.ContentCache.InnerCache as PublishedContentCache;
if (cache == null) throw new Exception("Unsupported IPublishedContentCache, only the Xml one is supported.");
var cachedRoutes = cache.RoutesCache.GetCachedRoutes();
Assert.AreEqual(7, cachedRoutes.Count);
var cachedIds = cache.RoutesCache.GetCachedIds();
Assert.AreEqual(0, cachedIds.Count);
Assert.AreEqual(7, cachedIds.Count);
CheckRoute(cachedRoutes, cachedIds, 1001, "1001/");
CheckRoute(cachedRoutes, cachedIds, 10011, "10011/");
@@ -329,11 +328,12 @@ namespace Umbraco.Tests.Routing
Assert.AreEqual("http://domain1.com/fr/1001-2-1/", routingContext.UrlProvider.GetUrl(100121, new Uri("http://domain2.com"), false));
}
private static void CheckRoute(IDictionary<int, string> routes, IDictionary<string, int> ids, int id, string route)
void CheckRoute(IDictionary<int, string> routes, IDictionary<string, int> ids, int id, string route)
{
Assert.IsTrue(routes.ContainsKey(id));
Assert.AreEqual(route, routes[id]);
Assert.IsFalse(ids.ContainsKey(route));
Assert.IsTrue(ids.ContainsKey(route));
Assert.AreEqual(id, ids[route]);
}
[Test]
@@ -26,7 +26,7 @@ namespace Umbraco.Tests.Routing
public void DoNotPolluteCache()
{
SettingsForTests.UseDirectoryUrls = true;
SettingsForTests.HideTopLevelNodeFromPath = false; // ignored w/domains
SettingsForTests.HideTopLevelNodeFromPath = false; // ignored w/domains
var settings = SettingsForTests.GenerateMockSettings();
var request = Mock.Get(settings.RequestHandler);
@@ -36,7 +36,7 @@ namespace Umbraco.Tests.Routing
RoutingContext routingContext;
string url = "http://domain1.com/1001-1/1001-1-1";
// get the nice url for 100111
routingContext = GetRoutingContext(url, 9999, umbracoSettings: settings);
Assert.AreEqual("http://domain2.com/1001-1-1/", routingContext.UrlProvider.GetUrl(100111, true));
@@ -89,7 +89,7 @@ namespace Umbraco.Tests.Routing
protected override string GetXmlContent(int templateId)
{
return @"<?xml version=""1.0"" encoding=""utf-8""?>
<!DOCTYPE root[
<!DOCTYPE root[
<!ELEMENT Doc ANY>
<!ATTLIST Doc id ID #REQUIRED>
]>
+80 -126
View File
@@ -35,64 +35,18 @@ namespace Umbraco.Tests.Services
[SetUp]
public override void Initialize()
{
base.Initialize();
}
[TearDown]
public override void TearDown()
{
base.TearDown();
base.Initialize();
}
[TearDown]
public override void TearDown()
{
base.TearDown();
}
//TODO Add test to verify there is only ONE newest document/content in cmsDocument table after updating.
//TODO Add test to delete specific version (with and without deleting prior versions) and versions by date.
/// <summary>
/// Ensures that we don't unpublish all nodes when a node is deleted that has an invalid path of -1
/// Note: it is actually the MoveToRecycleBin happening on the initial deletion of a node through the UI
/// that causes the issue.
/// Regression test: http://issues.umbraco.org/issue/U4-9336
/// </summary>
[Test]
public void Moving_Node_To_Recycle_Bin_With_Invalid_Path()
{
var contentService = ServiceContext.ContentService;
var root = ServiceContext.ContentService.GetById(NodeDto.NodeIdSeed + 1);
Assert.IsTrue(contentService.PublishWithStatus(root).Success);
var content = contentService.CreateContentWithIdentity("Test", -1, "umbTextpage", 0);
Assert.IsTrue(contentService.PublishWithStatus(content).Success);
var hierarchy = CreateContentHierarchy().OrderBy(x => x.Level).ToArray();
contentService.Save(hierarchy, 0);
foreach (var c in hierarchy)
{
Assert.IsTrue(contentService.PublishWithStatus(c).Success);
}
//now make the data corrupted :/
DatabaseContext.Database.Execute("UPDATE umbracoNode SET path = '-1' WHERE id = @id", new {id = content.Id});
//re-get with the corrupt path
content = contentService.GetById(content.Id);
// here we get all descendants by the path of the node being moved to bin, and unpublish all of them.
// since the path is invalid, there's logic in here to fix that if it's possible and re-persist the entity.
var moveResult = ServiceContext.ContentService.WithResult().MoveToRecycleBin(content);
Assert.IsTrue(moveResult.Success);
//re-get with the fixed/moved path
content = contentService.GetById(content.Id);
Assert.AreEqual("-1,-20," + content.Id, content.Path);
//re-get
hierarchy = contentService.GetByIds(hierarchy.Select(x => x.Id).ToArray()).OrderBy(x => x.Level).ToArray();
Assert.That(hierarchy.All(c => c.Trashed == false), Is.True);
Assert.That(hierarchy.All(c => c.Path.StartsWith("-1,-20") == false), Is.True);
}
[Test]
public void Remove_Scheduled_Publishing_Date()
{
@@ -150,7 +104,7 @@ namespace Umbraco.Tests.Services
results.Add(contentService.CreateContentWithIdentity("Test", -1, "umbTextpage", 0));
}
var sortedGet = contentService.GetByIds(new[] { results[10].Id, results[5].Id, results[12].Id }).ToArray();
var sortedGet = contentService.GetByIds(new[] {results[10].Id, results[5].Id, results[12].Id}).ToArray();
// Assert
Assert.AreEqual(sortedGet[0].Id, results[10].Id);
@@ -167,7 +121,7 @@ namespace Umbraco.Tests.Services
// Act
for (int i = 0; i < 20; i++)
{
contentService.CreateContentWithIdentity("Test", -1, "umbTextpage", 0);
contentService.CreateContentWithIdentity("Test", -1, "umbTextpage", 0);
}
// Assert
@@ -276,7 +230,7 @@ namespace Umbraco.Tests.Services
// Assert
//there should be no tags for this entity
var tags = tagService.GetTagsForEntity(content1.Id);
var tags = tagService.GetTagsForEntity(content1.Id);
Assert.AreEqual(0, tags.Count());
//these tags should still be returned since they still have actively published content assigned
@@ -311,7 +265,7 @@ namespace Umbraco.Tests.Services
contentService.MoveToRecycleBin(content2);
// Assert
//there should be no exposed content tags now that nothing is published.
var allTags = tagService.GetAllContentTags();
Assert.AreEqual(0, allTags.Count());
@@ -441,7 +395,7 @@ namespace Umbraco.Tests.Services
new PropertyType("test", DataTypeDatabaseType.Ntext, "tags")
{
DataTypeDefinitionId = 1041
});
});
contentTypeService.Save(contentType);
contentType.AllowedContentTypes = new[] { new ContentTypeSort(new Lazy<int>(() => contentType.Id), 0, contentType.Alias) };
@@ -456,7 +410,7 @@ namespace Umbraco.Tests.Services
var child2 = MockedContent.CreateSimpleContent(contentType, "child 2 content", content.Id);
child2.SetTags("tags", new[] { "hello2", "world2" }, true);
contentService.Save(child2);
// Act
contentService.PublishWithChildrenWithStatus(content, includeUnpublished: true);
@@ -507,34 +461,34 @@ namespace Umbraco.Tests.Services
new { nodeId = content.Id, propTypeId = propertyTypeId }));
}
[Test]
public void Can_Replace_Tag_Data_To_Published_Content()
{
[Test]
public void Can_Replace_Tag_Data_To_Published_Content()
{
//Arrange
var contentService = ServiceContext.ContentService;
var contentTypeService = ServiceContext.ContentTypeService;
var contentType = MockedContentTypes.CreateSimpleContentType("umbMandatory", "Mandatory Doc Type", true);
contentType.PropertyGroups.First().PropertyTypes.Add(
new PropertyType("test", DataTypeDatabaseType.Ntext, "tags")
{
DataTypeDefinitionId = 1041
});
{
DataTypeDefinitionId = 1041
});
contentTypeService.Save(contentType);
var content = MockedContent.CreateSimpleContent(contentType, "Tagged content", -1);
// Act
content.SetTags("tags", new[] { "hello", "world", "some", "tags" }, true);
contentService.Publish(content);
// Assert
Assert.AreEqual(4, content.Properties["tags"].Value.ToString().Split(',').Distinct().Count());
var propertyTypeId = contentType.PropertyTypes.Single(x => x.Alias == "tags").Id;
Assert.AreEqual(4, DatabaseContext.Database.ExecuteScalar<int>(
"SELECT COUNT(*) FROM cmsTagRelationship WHERE nodeId=@nodeId AND propertyTypeId=@propTypeId",
new { nodeId = content.Id, propTypeId = propertyTypeId }));
}
var propertyTypeId = contentType.PropertyTypes.Single(x => x.Alias == "tags").Id;
Assert.AreEqual(4, DatabaseContext.Database.ExecuteScalar<int>(
"SELECT COUNT(*) FROM cmsTagRelationship WHERE nodeId=@nodeId AND propertyTypeId=@propTypeId",
new {nodeId = content.Id, propTypeId = propertyTypeId}));
}
[Test]
public void Can_Append_Tag_Data_To_Published_Content()
@@ -552,7 +506,7 @@ namespace Umbraco.Tests.Services
var content = MockedContent.CreateSimpleContent(contentType, "Tagged content", -1);
content.SetTags("tags", new[] { "hello", "world", "some", "tags" }, true);
contentService.PublishWithStatus(content);
// Act
content.SetTags("tags", new[] { "another", "world" }, false);
contentService.PublishWithStatus(content);
@@ -594,9 +548,9 @@ namespace Umbraco.Tests.Services
new { nodeId = content.Id, propTypeId = propertyTypeId }));
}
[Test]
public void Can_Remove_Property_Type()
{
[Test]
public void Can_Remove_Property_Type()
{
// Arrange
var contentService = ServiceContext.ContentService;
@@ -606,9 +560,9 @@ namespace Umbraco.Tests.Services
// Assert
Assert.That(content, Is.Not.Null);
Assert.That(content.HasIdentity, Is.False);
}
}
[Test]
[Test]
public void Can_Create_Content()
{
// Arrange
@@ -621,7 +575,7 @@ namespace Umbraco.Tests.Services
Assert.That(content, Is.Not.Null);
Assert.That(content.HasIdentity, Is.False);
}
[Test]
public void Can_Create_Content_Without_Explicitly_Set_User()
{
@@ -641,12 +595,12 @@ namespace Umbraco.Tests.Services
public void Can_Save_New_Content_With_Explicit_User()
{
var user = new User(ServiceContext.UserService.GetUserTypeByAlias("admin"))
{
Name = "Test",
Email = "test@test.com",
Username = "test",
{
Name = "Test",
Email = "test@test.com",
Username = "test",
RawPasswordValue = "test"
};
};
ServiceContext.UserService.Save(user);
var content = new Content("Test", -1, ServiceContext.ContentTypeService.GetContentType("umbTextpage"));
@@ -903,14 +857,14 @@ namespace Umbraco.Tests.Services
var provider = new PetaPocoUnitOfWorkProvider(Logger);
using (var uow = provider.GetUnitOfWork())
{
uow.Database.TruncateTable("cmsContentXml");
uow.Database.TruncateTable("cmsContentXml");
}
//for this test we are also going to save a revision for a content item that is not published, this is to ensure
//that it's published version still makes it into the cmsContentXml table!
contentService.Save(allContent.Last());
// Act
var published = contentService.RePublishAll(0);
@@ -918,7 +872,7 @@ namespace Umbraco.Tests.Services
Assert.IsTrue(published);
using (var uow = provider.GetUnitOfWork())
{
Assert.AreEqual(allContent.Count(), uow.Database.ExecuteScalar<int>("select count(*) from cmsContentXml"));
Assert.AreEqual(allContent.Count(), uow.Database.ExecuteScalar<int>("select count(*) from cmsContentXml"));
}
}
@@ -935,7 +889,7 @@ namespace Umbraco.Tests.Services
var allContent = rootContent.Concat(rootContent.SelectMany(x => x.Descendants())).ToList();
//for testing we need to clear out the contentXml table so we can see if it worked
var provider = new PetaPocoUnitOfWorkProvider(Logger);
using (var uow = provider.GetUnitOfWork())
{
uow.Database.TruncateTable("cmsContentXml");
@@ -945,7 +899,7 @@ namespace Umbraco.Tests.Services
contentService.Save(allContent.Last());
// Act
contentService.RePublishAll(new int[] { allContent.Last().ContentTypeId });
contentService.RePublishAll(new int[]{allContent.Last().ContentTypeId});
// Assert
using (var uow = provider.GetUnitOfWork())
@@ -1131,7 +1085,7 @@ namespace Umbraco.Tests.Services
{
// Arrange
var contentService = ServiceContext.ContentService;
var content = contentService.CreateContent("Home US", -1, "umbTextpage", 0);
var content = contentService.CreateContent("Home US", - 1, "umbTextpage", 0);
content.SetValue("author", "Barack Obama");
// Act
@@ -1162,7 +1116,7 @@ namespace Umbraco.Tests.Services
var savedVersion = content.Version;
// Act
var publishedDescendants = ((ContentService)contentService).GetPublishedDescendants(root).ToList();
var publishedDescendants = ((ContentService) contentService).GetPublishedDescendants(root).ToList();
// Assert
Assert.That(rootPublished, Is.True);
@@ -1192,7 +1146,7 @@ namespace Umbraco.Tests.Services
{
// Arrange
var contentService = ServiceContext.ContentService;
var content = contentService.CreateContent("Home US", -1, "umbTextpage", 0);
var content = contentService.CreateContent("Home US", - 1, "umbTextpage", 0);
content.SetValue("author", "Barack Obama");
// Act
@@ -1212,7 +1166,7 @@ namespace Umbraco.Tests.Services
var contentType = contentTypeService.GetContentType("umbTextpage");
Content subpage = MockedContent.CreateSimpleContent(contentType, "Text Subpage 1", NodeDto.NodeIdSeed + 2);
Content subpage2 = MockedContent.CreateSimpleContent(contentType, "Text Subpage 2", NodeDto.NodeIdSeed + 2);
var list = new List<IContent> { subpage, subpage2 };
var list = new List<IContent> {subpage, subpage2};
// Act
contentService.Save(list, 0);
@@ -1232,9 +1186,9 @@ namespace Umbraco.Tests.Services
contentService.Save(hierarchy, 0);
Assert.That(hierarchy.Any(), Is.True);
Assert.That(hierarchy.Any(x => x.HasIdentity == false), Is.False);
//all parent id's should be ok, they are lazy and if they equal zero an exception will be thrown
Assert.DoesNotThrow(() => hierarchy.Any(x => x.ParentId != 0));
Assert.That(hierarchy.Any(x => x.HasIdentity == false), Is.False);
//all parent id's should be ok, they are lazy and if they equal zero an exception will be thrown
Assert.DoesNotThrow(() => hierarchy.Any(x => x.ParentId != 0));
}
@@ -1421,7 +1375,7 @@ namespace Umbraco.Tests.Services
var contentType = ServiceContext.ContentTypeService.GetContentType("umbTextpage");
var temp = MockedContent.CreateSimpleContent(contentType, "Simple Text Page", -1);
var prop = temp.Properties.First();
temp.SetTags(prop.Alias, new[] { "hello", "world" }, true);
temp.SetTags(prop.Alias, new[] {"hello", "world"}, true);
var status = contentService.PublishWithStatus(temp);
// Act
@@ -1464,14 +1418,14 @@ namespace Umbraco.Tests.Services
[Test]
public void Can_Save_Lazy_Content()
{
var unitOfWork = PetaPocoUnitOfWorkProvider.CreateUnitOfWork(Mock.Of<ILogger>());
{
var unitOfWork = PetaPocoUnitOfWorkProvider.CreateUnitOfWork(Mock.Of<ILogger>());
var contentType = ServiceContext.ContentTypeService.GetContentType("umbTextpage");
var root = ServiceContext.ContentService.GetById(NodeDto.NodeIdSeed + 1);
var c = new Lazy<IContent>(() => MockedContent.CreateSimpleContent(contentType, "Hierarchy Simple Text Page", root.Id));
var c2 = new Lazy<IContent>(() => MockedContent.CreateSimpleContent(contentType, "Hierarchy Simple Text Subpage", c.Value.Id));
var list = new List<Lazy<IContent>> { c, c2 };
var list = new List<Lazy<IContent>> {c, c2};
ContentTypeRepository contentTypeRepository;
using (var repository = CreateRepository(unitOfWork, out contentTypeRepository))
@@ -1489,9 +1443,9 @@ namespace Umbraco.Tests.Services
Assert.That(c2.Value.Id > 0, Is.True);
Assert.That(c.Value.ParentId > 0, Is.True);
Assert.That(c2.Value.ParentId > 0, Is.True);
Assert.That(c2.Value.ParentId > 0, Is.True);
}
}
[Test]
@@ -1514,20 +1468,20 @@ namespace Umbraco.Tests.Services
Assert.That(hasPublishedVersion, Is.True);
}
[Test]
public void Can_Verify_Property_Types_On_Content()
{
[Test]
public void Can_Verify_Property_Types_On_Content()
{
// Arrange
var contentTypeService = ServiceContext.ContentTypeService;
var contentTypeService = ServiceContext.ContentTypeService;
var contentType = MockedContentTypes.CreateAllTypesContentType("allDataTypes", "All DataTypes");
contentTypeService.Save(contentType);
var contentService = ServiceContext.ContentService;
var content = MockedContent.CreateAllTypesContent(contentType, "Random Content", -1);
var contentService = ServiceContext.ContentService;
var content = MockedContent.CreateAllTypesContent(contentType, "Random Content", -1);
contentService.Save(content);
var id = content.Id;
var id = content.Id;
// Act
var sut = contentService.GetById(id);
var sut = contentService.GetById(id);
// Arrange
Assert.That(sut.GetValue<bool>("isTrue"), Is.True);
@@ -1542,7 +1496,7 @@ namespace Umbraco.Tests.Services
Assert.That(sut.GetValue<DateTime>("dateTime").ToString("G"), Is.EqualTo(content.GetValue<DateTime>("dateTime").ToString("G")));
Assert.That(sut.GetValue<string>("colorPicker"), Is.EqualTo("black"));
//that one is gone in 7.4
//Assert.That(sut.GetValue<string>("folderBrowser"), Is.Null);
//Assert.That(sut.GetValue<string>("folderBrowser"), Is.Null);
Assert.That(sut.GetValue<string>("ddlMultiple"), Is.EqualTo("1234,1235"));
Assert.That(sut.GetValue<string>("rbList"), Is.EqualTo("random"));
Assert.That(sut.GetValue<DateTime>("date").ToString("G"), Is.EqualTo(content.GetValue<DateTime>("date").ToString("G")));
@@ -1553,23 +1507,23 @@ namespace Umbraco.Tests.Services
Assert.That(sut.GetValue<int>("memberPicker"), Is.EqualTo(1092));
Assert.That(sut.GetValue<string>("relatedLinks"), Is.EqualTo("<links><link title=\"google\" link=\"http://google.com\" type=\"external\" newwindow=\"0\" /></links>"));
Assert.That(sut.GetValue<string>("tags"), Is.EqualTo("this,is,tags"));
}
}
[Test]
public void Can_Delete_Previous_Versions_Not_Latest()
{
[Test]
public void Can_Delete_Previous_Versions_Not_Latest()
{
// Arrange
var contentService = ServiceContext.ContentService;
var content = contentService.GetById(NodeDto.NodeIdSeed + 4);
var version = content.Version;
var version = content.Version;
// Act
// Act
contentService.DeleteVersion(NodeDto.NodeIdSeed + 4, version, true, 0);
var sut = contentService.GetById(NodeDto.NodeIdSeed + 4);
// Assert
Assert.That(sut.Version, Is.EqualTo(version));
}
}
[Test]
public void Ensure_Content_Xml_Created()
@@ -1588,7 +1542,7 @@ namespace Umbraco.Tests.Services
}
contentService.Publish(content);
using (var uow = provider.GetUnitOfWork())
{
Assert.IsTrue(uow.Database.Exists<ContentXmlDto>(content.Id));
@@ -1605,10 +1559,10 @@ namespace Umbraco.Tests.Services
contentService.Save(content);
var provider = new PetaPocoUnitOfWorkProvider(Logger);
using (var uow = provider.GetUnitOfWork())
{
Assert.IsTrue(uow.Database.SingleOrDefault<PreviewXmlDto>("WHERE nodeId=@nodeId AND versionId = @versionId", new { nodeId = content.Id, versionId = content.Version }) != null);
Assert.IsTrue(uow.Database.SingleOrDefault<PreviewXmlDto>("WHERE nodeId=@nodeId AND versionId = @versionId", new{nodeId = content.Id, versionId = content.Version}) != null);
}
}
@@ -1711,11 +1665,11 @@ namespace Umbraco.Tests.Services
var contentType = ServiceContext.ContentTypeService.GetContentType("umbTextpage");
var root = ServiceContext.ContentService.GetById(NodeDto.NodeIdSeed + 1);
var list = new List<IContent>();
var list = new List<IContent>();
for (int i = 0; i < 10; i++)
{
var content = MockedContent.CreateSimpleContent(contentType, "Hierarchy Simple Text Page " + i, root);
var content = MockedContent.CreateSimpleContent(contentType, "Hierarchy Simple Text Page " + i, root);
list.Add(content);
list.AddRange(CreateChildrenOf(contentType, content, 4));
@@ -1726,12 +1680,12 @@ namespace Umbraco.Tests.Services
return list;
}
private IEnumerable<IContent> CreateChildrenOf(IContentType contentType, IContent content, int depth)
private IEnumerable<IContent> CreateChildrenOf(IContentType contentType, IContent content, int depth)
{
var list = new List<IContent>();
for (int i = 0; i < depth; i++)
{
var c = MockedContent.CreateSimpleContent(contentType, "Hierarchy Simple Text Subpage " + i, content);
var c = MockedContent.CreateSimpleContent(contentType, "Hierarchy Simple Text Subpage " + i, content);
list.Add(c);
Debug.Print("Created: 'Hierarchy Simple Text Subpage {0}' - Depth: {1}", i, depth);
+26 -6
View File
@@ -53,32 +53,41 @@
<ItemGroup>
<Reference Include="AutoMapper, Version=3.3.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="AutoMapper.Net4, Version=3.3.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.Net4.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Examine, Version=0.1.70.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Examine.0.1.70.0\lib\Examine.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
<Reference Include="log4net, Version=1.2.11.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\log4net-mediumtrust.2.0.0\lib\log4net.dll</HintPath>
</Reference>
<Reference Include="Lucene.Net, Version=2.9.4.1, Culture=neutral, PublicKeyToken=85089178b9ac3181, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Lucene.Net.2.9.4.1\lib\net40\Lucene.Net.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
</Reference>
<Reference Include="MiniProfiler, Version=2.1.0.0, Culture=neutral, PublicKeyToken=b44f9351044011a3, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\MiniProfiler.2.1.0\lib\net40\MiniProfiler.dll</HintPath>
</Reference>
<Reference Include="Moq, Version=4.1.1309.919, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
<Reference Include="Moq">
<HintPath>..\packages\Moq.4.1.1309.0919\lib\net40\Moq.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
@@ -86,12 +95,14 @@
<Private>True</Private>
</Reference>
<Reference Include="nunit.framework, Version=2.6.2.12296, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\NUnit.2.6.2\lib\nunit.framework.dll</HintPath>
</Reference>
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Semver, Version=1.1.2.0, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="Semver">
<HintPath>..\packages\semver.1.1.2\lib\net45\Semver.dll</HintPath>
</Reference>
<Reference Include="System" />
@@ -100,14 +111,17 @@
<Reference Include="System.Core" />
<Reference Include="System.Data.Entity.Design" />
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<Private>True</Private>
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.dll</HintPath>
</Reference>
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<Private>True</Private>
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.Entity.dll</HintPath>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http.WebRequest" />
@@ -117,39 +131,46 @@
<Reference Include="System.Web.ApplicationServices" />
<Reference Include="System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http.SelfHost, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.SelfHost.4.0.30506.0\lib\net40\System.Web.Http.SelfHost.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Http.WebHost, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll</HintPath>
</Reference>
<Reference Include="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Services" />
<Reference Include="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.WebPages.Deployment, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="WebDriver, Version=2.32.0.0, Culture=neutral, PublicKeyToken=1c2bd1631853048f, processorArchitecture=MSIL">
<Reference Include="WebDriver">
<HintPath>..\packages\Selenium.WebDriver.2.32.0\lib\net40\WebDriver.dll</HintPath>
</Reference>
</ItemGroup>
@@ -160,7 +181,6 @@
<Compile Include="Persistence\PetaPocoCachesTest.cs" />
<Compile Include="Persistence\PetaPocoExpressionsTests.cs" />
<Compile Include="Persistence\Repositories\RedirectUrlRepositoryTests.cs" />
<Compile Include="Routing\NiceUrlRoutesTests.cs" />
<Compile Include="TestHelpers\Entities\MockedPropertyTypes.cs" />
<Compile Include="TryConvertToTests.cs" />
<Compile Include="Web\AngularIntegration\AngularAntiForgeryTests.cs" />
@@ -592,9 +612,9 @@
<SubType>Designer</SubType>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="packages.config" />
<EmbeddedResource Include="TreesAndSections\applications.config" />
<EmbeddedResource Include="TreesAndSections\trees.config" />
<None Include="packages.config" />
<None Include="Packaging\Packages\Document_Type_Picker_1.1.umb" />
<None Include="UmbracoExamine\TestFiles\umbraco-sort.config">
<SubType>Designer</SubType>
@@ -69,6 +69,22 @@
};
}
if (!String.prototype.htmlEncode) {
/** htmlEncode extension method for string */
String.prototype.htmlEncode = function () {
//create a in-memory div, set it's inner text(which jQuery automatically encodes)
//then grab the encoded contents back out. The div never exists on the page.
return $('<div/>').text(this).html();
};
}
if (!String.prototype.htmlDecode) {
/** htmlDecode extension method for string */
String.prototype.htmlDecode = function () {
return $('<div/>').html(this).text();
};
}
if (!String.prototype.startsWith) {
/** startsWith extension method for string */
String.prototype.startsWith = function (str) {
@@ -172,55 +172,6 @@ angular.module("umbraco.directives")
});
// pin toolbar to top of screen if we have focus and it scrolls off the screen
var pinToolbar = function () {
var _toolbar = $(editor.editorContainer).find(".mce-toolbar");
var toolbarHeight = _toolbar.height();
var _tinyMce = $(editor.editorContainer);
var tinyMceRect = _tinyMce[0].getBoundingClientRect();
var tinyMceTop = tinyMceRect.top;
var tinyMceBottom = tinyMceRect.bottom;
var tinyMceWidth = tinyMceRect.width;
var _tinyMceEditArea = _tinyMce.find(".mce-edit-area");
// set padding in top of mce so the content does not "jump" up
_tinyMceEditArea.css("padding-top", toolbarHeight);
if (tinyMceTop < 160 && ((160 + toolbarHeight) < tinyMceBottom)) {
_toolbar
.css("visibility", "visible")
.css("position", "fixed")
.css("top", "160px")
.css("margin-top", "0")
.css("width", tinyMceWidth);
} else {
_toolbar
.css("visibility", "visible")
.css("position", "absolute")
.css("top", "auto")
.css("margin-top", "0")
.css("width", tinyMceWidth);
}
};
// unpin toolbar to top of screen
var unpinToolbar = function() {
var _toolbar = $(editor.editorContainer).find(".mce-toolbar");
var _tinyMce = $(editor.editorContainer);
var _tinyMceEditArea = _tinyMce.find(".mce-edit-area");
// reset padding in top of mce so the content does not "jump" up
_tinyMceEditArea.css("padding-top", "0");
_toolbar.css("position", "static");
};
//when we leave the editor (maybe)
editor.on('blur', function (e) {
editor.save();
@@ -234,9 +185,6 @@ angular.module("umbraco.directives")
scope.onBlur();
}
unpinToolbar();
$('.umb-panel-body').off('scroll', pinToolbar);
});
});
@@ -248,9 +196,6 @@ angular.module("umbraco.directives")
scope.onFocus();
}
pinToolbar();
$('.umb-panel-body').on('scroll', pinToolbar);
});
});
@@ -262,9 +207,6 @@ angular.module("umbraco.directives")
scope.onClick();
}
pinToolbar();
$('.umb-panel-body').on('scroll', pinToolbar);
});
});
@@ -103,15 +103,15 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ
* @description
* This returns a promise with an underlying http call, it is a helper method to reduce
* the amount of duplicate code needed to query http resources and automatically handle any
* 500 Http server errors.
* Http errors. See /docs/source/using-promises-resources.md
*
* @param {object} opts A mixed object which can either be a `string` representing the error message to be
* returned OR an `object` containing either:
* @param {object} opts A mixed object which can either be a string representing the error message to be
* returned OR an object containing either:
* { success: successCallback, errorMsg: errorMessage }
* OR
* { success: successCallback, error: errorCallback }
* In both of the above, the successCallback must accept these parameters: `data`, `status`, `headers`, `config`
* If using the errorCallback it must accept these parameters: `data`, `status`, `headers`, `config`
* In both of the above, the successCallback must accept these parameters: data, status, headers, config
* If using the errorCallback it must accept these parameters: data, status, headers, config
* The success callback must return the data which will be resolved by the deferred object.
* The error callback must return an object containing: {errorMsg: errorMessage, data: originalData, status: status }
*/
@@ -2,6 +2,6 @@
<h4><localize key="prompt_unsavedChanges">You have unsaved changes</localize></h4>
<p><localize key="prompt_unsavedChangesWarning">Are you sure you want to navigate away from this page? - you have unsaved changes</localize></p>
<button class="btn" ng-click="discard(notification)"><localize key="prompt_discardChanges">Discard changes</localize></button>
<button class="btn btn-success" ng-click="stay(notification)" umb-auto-focus><localize key="prompt_stay">Stay</localize></button>
</div>
<button class="btn btn-warning" ng-click="discard(notification)"><localize key="prompt_discardChanges">Discard changes</localize></button>
<button class="btn" ng-click="stay(notification)" umb-auto-focus><localize key="prompt_stay">Stay</localize></button>
</div>
@@ -178,6 +178,8 @@ function DataTypeEditController($scope, $routeParams, $location, appState, navig
//share state
editorState.set($scope.content);
dataTypeHelper.rebindChangedProperties($scope.content, data);
});
}
@@ -1,6 +1,6 @@
angular.module("umbraco")
.controller("Umbraco.PropertyEditors.TagsController",
function ($rootScope, $scope, $log, assetsService, umbRequestHelper, angularHelper, $timeout, $element) {
function ($rootScope, $scope, $log, assetsService, umbRequestHelper, angularHelper, $timeout, $element, $sanitize) {
var $typeahead;
@@ -41,6 +41,7 @@ angular.module("umbraco")
//Helper method to add a tag on enter or on typeahead select
function addTag(tagToAdd) {
tagToAdd = String(tagToAdd).htmlEncode();
if (tagToAdd != null && tagToAdd.length > 0) {
if ($scope.model.value.indexOf(tagToAdd) < 0) {
$scope.model.value.push(tagToAdd);
+12 -18
View File
@@ -41,9 +41,9 @@
<TargetFrameworkProfile />
<UseIISExpress>true</UseIISExpress>
<IISExpressSSLPort>44319</IISExpressSSLPort>
<IISExpressAnonymousAuthentication>enabled</IISExpressAnonymousAuthentication>
<IISExpressWindowsAuthentication>disabled</IISExpressWindowsAuthentication>
<IISExpressUseClassicPipelineMode>false</IISExpressUseClassicPipelineMode>
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
<MvcProjectUpgradeChecked>true</MvcProjectUpgradeChecked>
@@ -56,7 +56,7 @@
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
<ConfigurationOverrideFile>
</ConfigurationOverrideFile>
<DefineConstants>TRACE;DEBUG</DefineConstants>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DocumentationFile>
</DocumentationFile>
<DebugSymbols>true</DebugSymbols>
@@ -135,11 +135,13 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
<Reference Include="ImageProcessor, Version=2.5.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ImageProcessor.2.5.1\lib\net45\ImageProcessor.dll</HintPath>
<Reference Include="ImageProcessor, Version=2.4.5.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ImageProcessor.2.4.5.0\lib\net45\ImageProcessor.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="ImageProcessor.Web, Version=4.7.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ImageProcessor.Web.4.7.2\lib\net45\ImageProcessor.Web.dll</HintPath>
<Reference Include="ImageProcessor.Web, Version=4.6.6.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ImageProcessor.Web.4.6.6.0\lib\net45\ImageProcessor.Web.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="log4net, Version=1.2.11.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@@ -166,9 +168,6 @@
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.IO.RecyclableMemoryStream, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IO.RecyclableMemoryStream.1.2.0\lib\net45\Microsoft.IO.RecyclableMemoryStream.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin">
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
<Private>True</Private>
@@ -652,11 +651,6 @@
<None Include="Config\BaseRestExtensions.Release.config">
<DependentUpon>BaseRestExtensions.config</DependentUpon>
</None>
<Content Include="Config\imageprocessor\security.config" />
<Content Include="Config\imageprocessor\processing.config" />
<Content Include="Config\imageprocessor\cache.config">
<SubType>Designer</SubType>
</Content>
<None Include="Config\log4net.Release.config">
<DependentUpon>log4net.config</DependentUpon>
</None>
@@ -2421,9 +2415,9 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\"
<WebProjectProperties>
<UseIIS>True</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>7570</DevelopmentServerPort>
<DevelopmentServerPort>7560</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:7570</IISUrl>
<IISUrl>http://localhost:7560</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
@@ -66,7 +66,7 @@
if(cfg != null)
foreach (JProperty property in cfg.Properties())
{
var propertyValue = HttpUtility.HtmlAttributeEncode(property.Value.ToString());
var propertyValue = TemplateUtilities.CleanForXss(property.Value.ToString());
attrs.Add(property.Name + "=\"" + propertyValue + "\"");
}
@@ -76,7 +76,7 @@
var cssVals = new List<string>();
foreach (JProperty property in style.Properties())
{
var propertyValue = property.Value.ToString();
var propertyValue = TemplateUtilities.CleanForXss(property.Value.ToString());
if (string.IsNullOrWhiteSpace(propertyValue) == false)
{
cssVals.Add(property.Name + ":" + propertyValue + ";");
@@ -84,7 +84,7 @@
}
if (cssVals.Any())
attrs.Add("style='" + HttpUtility.HtmlAttributeEncode(string.Join(" ", cssVals)) + "'");
attrs.Add("style='" + string.Join(" ", cssVals) + "'");
}
return new MvcHtmlString(string.Join(" ", attrs));
@@ -66,7 +66,7 @@
if(cfg != null)
foreach (JProperty property in cfg.Properties())
{
var propertyValue = HttpUtility.HtmlAttributeEncode(property.Value.ToString());
var propertyValue = TemplateUtilities.CleanForXss(property.Value.ToString());
attrs.Add(property.Name + "=\"" + propertyValue + "\"");
}
@@ -76,7 +76,7 @@
var cssVals = new List<string>();
foreach (JProperty property in style.Properties())
{
var propertyValue = property.Value.ToString();
var propertyValue = TemplateUtilities.CleanForXss(property.Value.ToString());
if (string.IsNullOrWhiteSpace(propertyValue) == false)
{
cssVals.Add(property.Name + ":" + propertyValue + ";");
@@ -84,7 +84,7 @@
}
if (cssVals.Any())
attrs.Add("style=\"" + HttpUtility.HtmlAttributeEncode(string.Join(" ", cssVals)) + "\"");
attrs.Add("style=\"" + string.Join(" ", cssVals) + "\"");
}
return new MvcHtmlString(string.Join(" ", attrs));
@@ -62,7 +62,7 @@
if(cfg != null)
foreach (JProperty property in cfg.Properties())
{
var propertyValue = HttpUtility.HtmlAttributeEncode(property.Value.ToString());
var propertyValue = TemplateUtilities.CleanForXss(property.Value.ToString());
attrs.Add(property.Name + "=\"" + propertyValue + "\"");
}
@@ -72,7 +72,7 @@
var cssVals = new List<string>();
foreach (JProperty property in style.Properties())
{
var propertyValue = property.Value.ToString();
var propertyValue = TemplateUtilities.CleanForXss(property.Value.ToString());
if (string.IsNullOrWhiteSpace(propertyValue) == false)
{
cssVals.Add(property.Name + ":" + propertyValue + ";");
@@ -80,7 +80,7 @@
}
if (cssVals.Any())
attrs.Add("style='" + HttpUtility.HtmlAttributeEncode(string.Join(" ", cssVals)) + "'");
attrs.Add("style='" + string.Join(" ", cssVals) + "'");
}
return new MvcHtmlString(string.Join(" ", attrs));
@@ -66,17 +66,17 @@
if(cfg != null)
foreach (JProperty property in cfg.Properties())
{
var propertyValue = HttpUtility.HtmlAttributeEncode(property.Value.ToString());
var propertyValue = TemplateUtilities.CleanForXss(property.Value.ToString());
attrs.Add(property.Name + "=\"" + propertyValue + "\"");
}
JObject style = contentItem.styles;
if (style != null) {
var cssVals = new List<string>();
foreach (JProperty property in style.Properties())
{
var propertyValue = property.Value.ToString();
var propertyValue = TemplateUtilities.CleanForXss(property.Value.ToString());
if (string.IsNullOrWhiteSpace(propertyValue) == false)
{
cssVals.Add(property.Name + ":" + propertyValue + ";");
@@ -84,7 +84,7 @@
}
if (cssVals.Any())
attrs.Add("style=\"" + HttpUtility.HtmlAttributeEncode(string.Join(" ", cssVals)) + "\"");
attrs.Add("style=\"" + string.Join(" ", cssVals) + "\"");
}
return new MvcHtmlString(string.Join(" ", attrs));
@@ -4,9 +4,9 @@
@if (Model.editor.config.markup != null)
{
string markup = Model.editor.config.markup.ToString();
var umbracoHelper = new UmbracoHelper(UmbracoContext.Current);
var UmbracoHelper = new UmbracoHelper(UmbracoContext.Current);
markup = markup.Replace("#value#", umbracoHelper.ReplaceLineBreaksForHtml(HttpUtility.HtmlEncode(Model.value.ToString())));
markup = markup.Replace("#value#", UmbracoHelper.ReplaceLineBreaksForHtml(TemplateUtilities.CleanForXss(Model.value.ToString())));
markup = markup.Replace("#style#", Model.editor.config.style.ToString());
<text>
@@ -8,10 +8,10 @@ More information and documentation can be found on GitHub: https://github.com/Sh
-->
<ExamineLuceneIndexSets>
<!-- The internal index set used by Umbraco back-office - DO NOT REMOVE -->
<IndexSet SetName="InternalIndexSet" IndexPath="~/App_Data/TEMP/ExamineIndexes/Internal/"/>
<IndexSet SetName="InternalIndexSet" IndexPath="~/App_Data/TEMP/ExamineIndexes/{machinename}/Internal/"/>
<!-- The internal index set used by Umbraco back-office for indexing members - DO NOT REMOVE -->
<IndexSet SetName="InternalMemberIndexSet" IndexPath="~/App_Data/TEMP/ExamineIndexes/InternalMember/">
<IndexSet SetName="InternalMemberIndexSet" IndexPath="~/App_Data/TEMP/ExamineIndexes/{machinename}/InternalMember/">
<IndexAttributeFields>
<add Name="id" />
<add Name="nodeName"/>
@@ -24,5 +24,5 @@ More information and documentation can be found on GitHub: https://github.com/Sh
</IndexSet>
<!-- Default Indexset for external searches, this indexes all fields on all types of nodes-->
<IndexSet SetName="ExternalIndexSet" IndexPath="~/App_Data/TEMP/ExamineIndexes/External/" />
<IndexSet SetName="ExternalIndexSet" IndexPath="~/App_Data/TEMP/ExamineIndexes/{machinename}/External/" />
</ExamineLuceneIndexSets>
@@ -12,15 +12,18 @@ More information and documentation can be found on GitHub: https://github.com/Sh
<add name="InternalIndexer" type="UmbracoExamine.UmbracoContentIndexer, UmbracoExamine"
supportUnpublished="true"
supportProtected="true"
analyzer="Lucene.Net.Analysis.WhitespaceAnalyzer, Lucene.Net"/>
analyzer="Lucene.Net.Analysis.WhitespaceAnalyzer, Lucene.Net"
useTempStorage="Sync"/>
<add name="InternalMemberIndexer" type="UmbracoExamine.UmbracoMemberIndexer, UmbracoExamine"
supportUnpublished="true"
supportProtected="true"
analyzer="Lucene.Net.Analysis.Standard.StandardAnalyzer, Lucene.Net"/>
analyzer="Lucene.Net.Analysis.Standard.StandardAnalyzer, Lucene.Net"
useTempStorage="Sync"/>
<!-- default external indexer, which excludes protected and unpublished pages-->
<add name="ExternalIndexer" type="UmbracoExamine.UmbracoContentIndexer, UmbracoExamine"/>
<add name="ExternalIndexer" type="UmbracoExamine.UmbracoContentIndexer, UmbracoExamine"
useTempStorage="Sync"/>
</providers>
</ExamineIndexProviders>
@@ -28,13 +31,16 @@ More information and documentation can be found on GitHub: https://github.com/Sh
<ExamineSearchProviders defaultProvider="ExternalSearcher">
<providers>
<add name="InternalSearcher" type="UmbracoExamine.UmbracoExamineSearcher, UmbracoExamine"
analyzer="Lucene.Net.Analysis.WhitespaceAnalyzer, Lucene.Net"/>
analyzer="Lucene.Net.Analysis.WhitespaceAnalyzer, Lucene.Net"
useTempStorage="Sync"/>
<add name="ExternalSearcher" type="UmbracoExamine.UmbracoExamineSearcher, UmbracoExamine"/>
<add name="ExternalSearcher" type="UmbracoExamine.UmbracoExamineSearcher, UmbracoExamine"
useTempStorage="Sync"/>
<add name="InternalMemberSearcher" type="UmbracoExamine.UmbracoExamineSearcher, UmbracoExamine"
analyzer="Lucene.Net.Analysis.Standard.StandardAnalyzer, Lucene.Net"
enableLeadingWildcard="true"/>
enableLeadingWildcard="true"
useTempStorage="Sync"/>
</providers>
</ExamineSearchProviders>
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<caching currentCache="DiskCache">
<caches>
<cache name="DiskCache" type="ImageProcessor.Web.Caching.DiskCache, ImageProcessor.Web" maxDays="365" browserMaxDays="7">
<settings>
<setting key="VirtualCachePath" value="~/app_data/cache" />
</settings>
</cache>
</caches>
</caching>
@@ -1,61 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<processing preserveExifMetaData="true" fixGamma="false" interceptAllRequests="false" allowCacheBuster="true">
<presets>
</presets>
<plugins>
<plugin name="Alpha" type="ImageProcessor.Web.Processors.Alpha, ImageProcessor.Web" />
<plugin name="AutoRotate" type="ImageProcessor.Web.Processors.AutoRotate, ImageProcessor.Web" enabled="true" />
<plugin name="BackgroundColor" type="ImageProcessor.Web.Processors.BackgroundColor, ImageProcessor.Web" enabled="true" />
<plugin name="Brightness" type="ImageProcessor.Web.Processors.Brightness, ImageProcessor.Web" />
<plugin name="Contrast" type="ImageProcessor.Web.Processors.Contrast, ImageProcessor.Web" />
<plugin name="Crop" type="ImageProcessor.Web.Processors.Crop, ImageProcessor.Web" enabled="true" />
<plugin name="DetectEdges" type="ImageProcessor.Web.Processors.DetectEdges, ImageProcessor.Web" />
<plugin name="EntropyCrop" type="ImageProcessor.Web.Processors.EntropyCrop, ImageProcessor.Web" />
<plugin name="Filter" type="ImageProcessor.Web.Processors.Filter, ImageProcessor.Web" />
<plugin name="Flip" type="ImageProcessor.Web.Processors.Flip, ImageProcessor.Web" />
<plugin name="Format" type="ImageProcessor.Web.Processors.Format, ImageProcessor.Web" enabled="true" />
<plugin name="GaussianBlur" type="ImageProcessor.Web.Processors.GaussianBlur, ImageProcessor.Web">
<settings>
<setting key="MaxSize" value="22" />
<setting key="MaxSigma" value="5.1" />
<setting key="MaxThreshold" value="100" />
</settings>
</plugin>
<plugin name="GaussianSharpen" type="ImageProcessor.Web.Processors.GaussianSharpen, ImageProcessor.Web">
<settings>
<setting key="MaxSize" value="22" />
<setting key="MaxSigma" value="5.1" />
<setting key="MaxThreshold" value="100" />
</settings>
</plugin>
<plugin name="Halftone" type="ImageProcessor.Web.Processors.Halftone, ImageProcessor.Web" />
<plugin name="Hue" type="ImageProcessor.Web.Processors.Hue, ImageProcessor.Web" />
<plugin name="Mask" type="ImageProcessor.Web.Processors.Mask, ImageProcessor.Web">
<settings>
<setting key="VirtualPath" value="~/images/imageprocessor/mask/" />
</settings>
</plugin>
<plugin name="Meta" type="ImageProcessor.Web.Processors.Meta, ImageProcessor.Web" />
<plugin name="Overlay" type="ImageProcessor.Web.Processors.Overlay, ImageProcessor.Web">
<settings>
<setting key="VirtualPath" value="~/images/imageprocessor/overlay/" />
</settings>
</plugin>
<plugin name="Pixelate" type="ImageProcessor.Web.Processors.Pixelate, ImageProcessor.Web" />
<plugin name="Quality" type="ImageProcessor.Web.Processors.Quality, ImageProcessor.Web" enabled="true" />
<plugin name="ReplaceColor" type="ImageProcessor.Web.Processors.ReplaceColor, ImageProcessor.Web" />
<plugin name="Resize" type="ImageProcessor.Web.Processors.Resize, ImageProcessor.Web" enabled="true">
<settings>
<setting key="MaxWidth" value="5000" />
<setting key="MaxHeight" value="5000" />
</settings>
</plugin>
<plugin name="Rotate" type="ImageProcessor.Web.Processors.Rotate, ImageProcessor.Web" />
<plugin name="RotateBounded" type="ImageProcessor.Web.Processors.RotateBounded, ImageProcessor.Web" />
<plugin name="RoundedCorners" type="ImageProcessor.Web.Processors.RoundedCorners, ImageProcessor.Web" />
<plugin name="Saturation" type="ImageProcessor.Web.Processors.Saturation, ImageProcessor.Web" />
<plugin name="Tint" type="ImageProcessor.Web.Processors.Tint, ImageProcessor.Web" />
<plugin name="Vignette" type="ImageProcessor.Web.Processors.Vignette, ImageProcessor.Web" />
<plugin name="Watermark" type="ImageProcessor.Web.Processors.Watermark, ImageProcessor.Web" />
</plugins>
</processing>
@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<security>
<services>
<service name="LocalFileImageService" type="ImageProcessor.Web.Services.LocalFileImageService, ImageProcessor.Web" />
<!--Disable the LocalFileImageService and enable this one when using virtual paths. -->
<!--<service name="CloudImageService" type="ImageProcessor.Web.Services.CloudImageService, ImageProcessor.Web">
<settings>
<setting key="Container" value=""/>
<setting key="MaxBytes" value="8194304"/>
<setting key="Timeout" value="30000"/>
<setting key="Host" value="http://yourhost.com/"/>
</settings>
</service>-->
<service prefix="remote.axd" name="RemoteImageService" type="ImageProcessor.Web.Services.RemoteImageService, ImageProcessor.Web">
<settings>
<setting key="MaxBytes" value="4194304" />
<setting key="Timeout" value="3000" />
<setting key="Protocol" value="http" />
</settings>
<whitelist>
</whitelist>
</service>
</services>
</security>
@@ -44,7 +44,7 @@
<div class="col">
<h2>Be a part of the community</h2>
<p>The Umbraco community is the best of its kind, be sure to visit, and if you have any questions, we're sure that you can get your answers from the community.</p>
<p>The Umbraco community is the best of its kind, be sure to visit, and if you have any questions, were sure that you can get your answers from the community.</p>
<a href="http://our.umbraco.org?ref=ourFromInstaller" target="_blank">our.Umbraco &rarr;</a>
</div>
+2 -4
View File
@@ -5,9 +5,8 @@
<package id="ClientDependency-Mvc5" version="1.8.0.0" targetFramework="net45" />
<package id="dotless" version="1.4.1.0" targetFramework="net45" />
<package id="Examine" version="0.1.70.0" targetFramework="net45" />
<package id="ImageProcessor" version="2.5.1" targetFramework="net45" />
<package id="ImageProcessor.Web" version="4.7.2" targetFramework="net45" />
<package id="ImageProcessor.Web.Config" version="2.3.0" targetFramework="net45" />
<package id="ImageProcessor" version="2.4.5.0" targetFramework="net45" />
<package id="ImageProcessor.Web" version="4.6.6.0" targetFramework="net45" />
<package id="log4net-mediumtrust" version="2.0.0" targetFramework="net45" />
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Identity.Core" version="2.2.1" targetFramework="net45" />
@@ -22,7 +21,6 @@
<package id="Microsoft.CodeAnalysis.Analyzers" version="1.0.0" targetFramework="net45" />
<package id="Microsoft.CodeAnalysis.Common" version="1.0.0" targetFramework="net45" />
<package id="Microsoft.CodeAnalysis.CSharp" version="1.0.0" targetFramework="net45" />
<package id="Microsoft.IO.RecyclableMemoryStream" version="1.2.0" targetFramework="net45" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Host.SystemWeb" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Security" version="3.0.1" targetFramework="net45" />
+2 -13
View File
@@ -14,13 +14,7 @@
<section name="FileSystemProviders" type="Umbraco.Core.Configuration.FileSystemProvidersSection, Umbraco.Core" requirePermission="false" />
<section name="dashBoard" type="Umbraco.Core.Configuration.Dashboard.DashboardSection, Umbraco.Core" requirePermission="false" />
</sectionGroup>
<sectionGroup name="imageProcessor">
<section name="security" requirePermission="false" type="ImageProcessor.Web.Configuration.ImageSecuritySection, ImageProcessor.Web" />
<section name="processing" requirePermission="false" type="ImageProcessor.Web.Configuration.ImageProcessingSection, ImageProcessor.Web" />
<section name="caching" requirePermission="false" type="ImageProcessor.Web.Configuration.ImageCacheSection, ImageProcessor.Web" />
</sectionGroup>
</configSections>
</configSections>
<umbracoConfiguration>
<settings configSource="config\umbracoSettings.config" />
@@ -125,7 +119,7 @@
<add verb="*" path="DependencyHandler.axd" type="ClientDependency.Core.CompositeFiles.CompositeDependencyHandler, ClientDependency.Core " />
</httpHandlers>
<compilation defaultLanguage="c#" debug="false" batch="false" targetFramework="4.5" numRecompilesBeforeAppRestart="50">
<compilation defaultLanguage="c#" debug="false" batch="false" targetFramework="4.5">
<assemblies>
<remove assembly="System.Web.Http" />
<remove assembly="System.Net.Http" />
@@ -440,9 +434,4 @@
</system.webServer>
</location>
<imageProcessor>
<security configSource="config\imageprocessor\security.config" />
<caching configSource="config\imageprocessor\cache.config" />
<processing configSource="config\imageprocessor\processing.config" />
</imageProcessor>
</configuration>
@@ -11,11 +11,11 @@ namespace Umbraco.Web.Controllers
public class UmbLoginController : SurfaceController
{
[HttpPost]
public ActionResult HandleLogin([Bind(Prefix = "loginModel")]LoginModel model)
public ActionResult HandleLogin([Bind(Prefix="loginModel")]LoginModel model)
{
if (ModelState.IsValid == false)
{
return CurrentUmbracoPage();
return CurrentUmbracoPage();
}
if (Members.Login(model.Username, model.Password) == false)
@@ -30,20 +30,11 @@ namespace Umbraco.Web.Controllers
//if there is a specified path to redirect to then use it
if (model.RedirectUrl.IsNullOrWhiteSpace() == false)
{
// validate the redirect url
if (Url.IsLocalUrl(model.RedirectUrl))
{
return Redirect(model.RedirectUrl);
}
else
{
// if it's not a local url we'll redirect to the root of the current site
return Redirect(base.CurrentPage.Site().Url);
}
return Redirect(model.RedirectUrl);
}
//redirect to current page by default
return RedirectToCurrentUmbracoPage();
//return RedirectToCurrentUmbracoUrl();
}
@@ -137,7 +137,7 @@ namespace Umbraco.Web.Dictionary
{
//ensure it's stored/retrieved from request cache
//NOTE: This is no longer necessary since these are cached at the runtime level, but we can leave it here for now.
return _requestCacheProvider.GetCacheItem<ILanguage>(typeof (DefaultCultureDictionary).Name + "Culture" + Culture.Name,
return _requestCacheProvider.GetCacheItem<ILanguage>(typeof (DefaultCultureDictionary).Name + "Culture",
() => _localizationService.GetLanguageByIsoCode(Culture.Name));
}
}
@@ -88,37 +88,35 @@ namespace Umbraco.Web.Editors
where TPersisted : IContentBase
{
//Map the property values
foreach (var property in contentItem.ContentDto.Properties)
foreach (var p in contentItem.ContentDto.Properties)
{
//get the dbo property
var dboProperty = contentItem.PersistedContent.Properties[property.Alias];
var dboProperty = contentItem.PersistedContent.Properties[p.Alias];
//create the property data to send to the property editor
var dictionary = new Dictionary<string, object>();
var d = new Dictionary<string, object>();
//add the files if any
var files = contentItem.UploadedFiles.Where(x => x.PropertyAlias == property.Alias).ToArray();
foreach (var file in files)
file.FileName = file.FileName.ToSafeFileName();
if (files.Any())
dictionary.Add("files", files);
var files = contentItem.UploadedFiles.Where(x => x.PropertyAlias == p.Alias).ToArray();
if (files.Length > 0)
{
d.Add("files", files);
}
var data = new ContentPropertyData(property.Value, property.PreValues, dictionary);
var data = new ContentPropertyData(p.Value, p.PreValues, d);
//get the deserialized value from the property editor
if (property.PropertyEditor == null)
if (p.PropertyEditor == null)
{
LogHelper.Warn<ContentController>("No property editor found for property " + property.Alias);
LogHelper.Warn<ContentController>("No property editor found for property " + p.Alias);
}
else
{
var valueEditor = property.PropertyEditor.ValueEditor;
var valueEditor = p.PropertyEditor.ValueEditor;
//don't persist any bound value if the editor is readonly
if (valueEditor.IsReadOnly == false)
{
var propVal = property.PropertyEditor.ValueEditor.ConvertEditorToDb(data, dboProperty.Value);
var supportTagsAttribute = TagExtractor.GetAttribute(property.PropertyEditor);
var propVal = p.PropertyEditor.ValueEditor.ConvertEditorToDb(data, dboProperty.Value);
var supportTagsAttribute = TagExtractor.GetAttribute(p.PropertyEditor);
if (supportTagsAttribute != null)
{
TagExtractor.SetPropertyTags(dboProperty, data, propVal, supportTagsAttribute);
+1 -2
View File
@@ -525,8 +525,7 @@ namespace Umbraco.Web.Editors
foreach (var file in result.FileData)
{
var fileName = file.Headers.ContentDisposition.FileName.Trim(new[] { '\"' }).TrimEnd();
var safeFileName = fileName.ToSafeFileName();
var ext = safeFileName.Substring(safeFileName.LastIndexOf('.') + 1).ToLower();
var ext = fileName.Substring(fileName.LastIndexOf('.') + 1).ToLower();
if (UmbracoConfig.For.UmbracoSettings().Content.DisallowedUploadFiles.Contains(ext) == false)
{
+5 -5
View File
@@ -9,12 +9,12 @@ using Umbraco.Web.PublishedCache;
namespace Umbraco.Web
{
/// <summary>
/// Extension methods for Examine
/// </summary>
public static class ExamineExtensions
/// <summary>
/// Extension methods for Examine
/// </summary>
internal static class ExamineExtensions
{
public static PublishedContentSet<IPublishedContent> ConvertSearchResultToPublishedContent(this IEnumerable<SearchResult> results,
internal static PublishedContentSet<IPublishedContent> ConvertSearchResultToPublishedContent(this IEnumerable<SearchResult> results,
ContextualPublishedCache cache)
{
//TODO: The search result has already returned a result which SHOULD include all of the data to create an IPublishedContent,
@@ -81,7 +81,7 @@ namespace Umbraco.Web.Install.InstallSteps
{
var client = new System.Net.WebClient();
var values = new NameValueCollection { { "name", admin.Name }, { "email", admin.Email} };
client.UploadValues("https://umbraco.com/base/Ecom/SubmitEmail/installer.aspx", values);
client.UploadValues("http://umbraco.org/base/Ecom/SubmitEmail/installer.aspx", values);
}
catch { /* fail in silence */ }
}
@@ -1,10 +1,8 @@
using System;
using System.Text;
using System.Text;
using System.Xml;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Web;
using Newtonsoft.Json;
using Umbraco.Core.Media;
@@ -29,13 +27,10 @@ namespace Umbraco.Web.Media.EmbedProviders
public virtual string BuildFullUrl(string url, int maxWidth, int maxHeight)
{
if (Uri.IsWellFormedUriString(url, UriKind.RelativeOrAbsolute) == false)
throw new ArgumentException("Not a valid Url");
var fullUrl = new StringBuilder();
fullUrl.Append(APIEndpoint);
fullUrl.Append("?url=" + HttpUtility.UrlEncode(url));
fullUrl.Append("?url=" + url);
foreach (var p in RequestParams)
fullUrl.Append(string.Format("&{0}={1}", p.Key, p.Value));
+4 -2
View File
@@ -46,7 +46,9 @@ namespace Umbraco.Web.Models
{
var route = umbracoContext == null
? null // for tests only
: umbracoContext.ContentCache.GetRouteById(contentId); // may be cached
: umbracoContext.ContentCache.GetRouteById(contentId); // cached
if (route != null && route.StartsWith("err/")) route = null;
var domainHelper = new DomainHelper(domainService);
IDomain domain;
@@ -71,7 +73,7 @@ namespace Umbraco.Web.Models
}
else
{
// if content is published then we have a route
// if content is published then we have a (cached) route
// from which we can figure out the domain
var pos = route.IndexOf('/');
@@ -229,7 +229,7 @@ namespace Umbraco.Web.Models.Mapping
var groupsGroupsByName = content.PropertyGroups.OrderBy(x => x.SortOrder).GroupBy(x => x.Name);
foreach (var groupsByName in groupsGroupsByName)
{
var properties = new List<Property>();
var properties = new List<ContentPropertyDisplay>();
// merge properties for groups with the same name
foreach (var group in groupsByName)
@@ -237,16 +237,13 @@ namespace Umbraco.Web.Models.Mapping
var groupProperties = content.GetPropertiesForGroup(group)
.Where(x => IgnoreProperties.Contains(x.Alias) == false); // skip ignored
properties.AddRange(groupProperties);
properties.AddRange(Mapper.Map<IEnumerable<Property>, IEnumerable<ContentPropertyDisplay>>(groupProperties));
}
if (properties.Count == 0)
continue;
// Sort properties so items from different compositions appear in correct order (see U4-9298). Map sorted properties.
var mappedProperties = Mapper.Map<IEnumerable<Property>, IEnumerable<ContentPropertyDisplay>>(properties.OrderBy(prop => prop.PropertyType.SortOrder));
TranslateProperties(mappedProperties);
TranslateProperties(properties);
// add the tab
// we need to pick an identifier... there is no "right" way...
@@ -259,7 +256,7 @@ namespace Umbraco.Web.Models.Mapping
Id = groupId,
Alias = groupName,
Label = _localizedTextService.UmbracoDictionaryTranslate(groupName),
Properties = mappedProperties,
Properties = properties,
IsActive = false
});
}
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using Newtonsoft.Json.Linq;
using Umbraco.Core;
@@ -60,7 +61,14 @@ namespace Umbraco.Web.PropertyEditors
public override object ConvertEditorToDb(ContentPropertyData editorValue, object currentValue)
{
var json = editorValue.Value as JArray;
return json == null ? null : json.Select(x => x.Value<string>());
return json == null
? null
: json.Select(x => x.Value<string>()).Where(x => x.IsNullOrWhiteSpace() == false)
//First we will decode it as html because we know that if this is not a malicious post that the value is
// already Html encoded by the tags JavaScript controller. Then we'll re-Html Encode it to ensure that in case this
// is a malicious post (i.e. someone is submitting data manually by modifying the request).
.Select(WebUtility.HtmlDecode)
.Select(WebUtility.HtmlEncode);
}
/// <summary>
@@ -2,9 +2,11 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Text;
using System.Xml;
using System.Xml.XPath;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
@@ -16,6 +18,7 @@ using umbraco.BusinessLogic;
using umbraco.presentation.preview;
using Umbraco.Core.Services;
using GlobalSettings = umbraco.GlobalSettings;
using Task = System.Threading.Tasks.Task;
namespace Umbraco.Web.PublishedCache.XmlPublishedCache
{
@@ -80,7 +83,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
&& DomainHelper.ExistsDomainInPath(umbracoContext.Application.Services.DomainService.GetAll(false), content.Path, domainRootNodeId) == false;
if (deepest)
_routesCache.Store(content.Id, route, true); // trusted route
_routesCache.Store(content.Id, route);
}
public virtual string GetRouteById(UmbracoContext umbracoContext, bool preview, int contentId)
@@ -99,13 +102,38 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
if (route == null)
return null;
// cache the route BUT do NOT trust it as it can be a colliding route
// meaning if we GetRouteById again, we'll get it from cache, but it
// won't be used for inbound routing
if (preview == false)
_routesCache.Store(contentId, route, false);
// find the content back, detect routes collisions: we should find ourselves back,
// else it means that another content with "higher priority" is sharing the same route.
// perf impact:
// - non-colliding, adds one complete "by route" lookup, only on the first time a url is computed (then it's cached anyways)
// - colliding, adds one "by route" lookup, the first time the url is computed, then one dictionary looked each time it is computed again
// assuming no collisions, the impact is one complete "by route" lookup the first time each url is computed
//
// U4-9121 - this lookup is too expensive when computing a large amount of urls on a front-end (eg menu)
// ... thinking about moving the lookup out of the path into its own async task, so we are not reporting errors
// in the back-office anymore, but at least we are not polluting the cache
// instead, refactored DeterminedIdByRoute to stop using XPath, with a 16x improvement according to benchmarks
// will it be enough?
return route;
var loopId = preview ? 0 : _routesCache.GetNodeId(route); // might be cached already in case of collision
if (loopId == 0)
{
var content = DetermineIdByRoute(umbracoContext, preview, route, GlobalSettings.HideTopLevelNodeFromPath);
// add the other route to cache so next time we have it already
if (content != null && preview == false)
AddToCacheIfDeepestRoute(umbracoContext, content, route);
loopId = content == null ? 0 : content.Id; // though... 0 here would be quite weird?
}
// cache if we have a route and not previewing and it's not a colliding route
// (the result of DetermineRouteById is always the deepest route)
if (/*route != null &&*/ preview == false && loopId == contentId)
_routesCache.Store(contentId, route);
// return route if no collision, else report collision
return loopId == contentId ? route : ("err/" + loopId);
}
IPublishedContent DetermineIdByRoute(UmbracoContext umbracoContext, bool preview, string route, bool hideTopLevelNode)
@@ -121,25 +149,18 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
//check if we can find the node in our xml cache
var id = NavigateRoute(umbracoContext, preview, startNodeId, path, hideTopLevelNode);
return id > 0 ? GetById(umbracoContext, preview, id) : null;
}
if (id > 0) return GetById(umbracoContext, preview, id);
private static XmlElement GetXmlElementChildWithLowestSortOrder(XmlNode element)
{
XmlElement elt = null;
var min = int.MaxValue;
foreach (var n in element.ChildNodes)
// if hideTopLevelNodePath is true then for url /foo we looked for /*/foo
// but maybe that was the url of a non-default top-level node, so we also
// have to look for /foo (see note in ApplyHideTopLevelNodeFromPath).
if (hideTopLevelNode && path.Length > 1 && path.IndexOf('/', 1) < 0)
{
var e = n as XmlElement;
if (e == null) continue;
var sortOrder = int.Parse(e.GetAttribute("sortOrder"));
if (sortOrder >= min) continue;
min = sortOrder;
elt = e;
var id2 = NavigateRoute(umbracoContext, preview, startNodeId, path, false);
if (id2 > 0) return GetById(umbracoContext, preview, id2);
}
return elt;
return null;
}
private int NavigateRoute(UmbracoContext umbracoContext, bool preview, int startNodeId, string path, bool hideTopLevelNode)
@@ -156,7 +177,17 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
return elt == null ? -1 : startNodeId;
}
elt = GetXmlElementChildWithLowestSortOrder(xml.DocumentElement);
elt = null;
var min = int.MaxValue;
foreach (var e in xml.DocumentElement.ChildNodes.OfType<XmlElement>())
{
var sortOrder = int.Parse(e.GetAttribute("sortOrder"));
if (sortOrder < min)
{
min = sortOrder;
elt = e;
}
}
return elt == null ? -1 : int.Parse(elt.GetAttribute("id"));
}
@@ -170,19 +201,12 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
if (hideTopLevelNode && startNodeId <= 0)
{
//Don't use OfType<T> or Cast<T>, this is critical code, all ChildNodes are XmlElement so explicitly cast
// https://gist.github.com/Shazwazza/04e2e5642a316f4a87e52dada2901198
foreach (var n in elt.ChildNodes)
foreach (var e in elt.ChildNodes.OfType<XmlElement>())
{
var e = n as XmlElement;
if (e == null) continue;
var id = NavigateElementRoute(e, urlParts);
if (id > 0) return id;
}
if (urlParts.Length > 1)
return -1;
return -1;
}
return NavigateElementRoute(elt, urlParts);
@@ -200,14 +224,8 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
while (found && i < urlParts.Length)
{
found = false;
//Don't use OfType<T> or Cast<T>, this is critical code, all ChildNodes are XmlElement so explicitly cast
// https://gist.github.com/Shazwazza/04e2e5642a316f4a87e52dada2901198
var sortOrder = -1;
foreach (var o in elt.ChildNodes)
foreach (var child in elt.ChildNodes.OfType<XmlElement>())
{
var child = o as XmlElement;
if (child == null) continue;
var noNode = UseLegacySchema
? child.Name != "node"
: child.GetAttributeNode("isDoc") == null;
@@ -215,12 +233,8 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
if (child.GetAttribute("urlName") != urlParts[i]) continue;
found = true;
var so = int.Parse(child.GetAttribute("sortOrder"));
if (sortOrder >= 0 && so >= sortOrder) continue;
sortOrder = so;
elt = child;
break;
}
i++;
}
@@ -229,8 +243,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
string DetermineRouteById(UmbracoContext umbracoContext, bool preview, int contentId)
{
var xml = GetXml(umbracoContext, preview);
var elt = xml.GetElementById(contentId.ToString(CultureInfo.InvariantCulture));
var elt = GetXml(umbracoContext, preview).GetElementById(contentId.ToString(CultureInfo.InvariantCulture));
if (elt == null) return null;
var domainHelper = GetDomainHelper(umbracoContext.Application.Services.DomainService);
@@ -257,18 +270,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
// no domain, respect HideTopLevelNodeFromPath for legacy purposes
if (hasDomains == false && GlobalSettings.HideTopLevelNodeFromPath)
{
if (eltParentId == -1)
{
var rootNode = GetXmlElementChildWithLowestSortOrder(xml.DocumentElement);
if (rootNode != null && rootNode == elt)
pathParts.RemoveAt(pathParts.Count - 1);
}
else
{
pathParts.RemoveAt(pathParts.Count - 1);
}
}
ApplyHideTopLevelNodeFromPath(umbracoContext, eltId, eltParentId, pathParts);
// assemble the route
pathParts.Reverse();
@@ -278,6 +280,30 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
return route;
}
static void ApplyHideTopLevelNodeFromPath(UmbracoContext umbracoContext, int nodeId, int parentId, IList<string> pathParts)
{
// in theory if hideTopLevelNodeFromPath is true, then there should be only once
// top-level node, or else domains should be assigned. but for backward compatibility
// we add this check - we look for the document matching "/" and if it's not us, then
// we do not hide the top level path
// it has to be taken care of in GetByRoute too so if
// "/foo" fails (looking for "/*/foo") we try also "/foo".
// this does not make much sense anyway esp. if both "/foo/" and "/bar/foo" exist, but
// that's the way it works pre-4.10 and we try to be backward compat for the time being
if (parentId == -1)
{
var rootNode = umbracoContext.ContentCache.GetByRoute("/", true);
if (rootNode == null)
throw new Exception("Failed to get node at /.");
if (rootNode.Id == nodeId) // remove only if we're the default node
pathParts.RemoveAt(pathParts.Count - 1);
}
else
{
pathParts.RemoveAt(pathParts.Count - 1);
}
}
#endregion
#region XPath Strings
@@ -83,12 +83,10 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
/// </summary>
/// <param name="nodeId">The node identified.</param>
/// <param name="route">The route.</param>
/// <param name="trust">A value indicating whether the value can be trusted for inbound routing.</param>
public void Store(int nodeId, string route, bool trust)
public void Store(int nodeId, string route)
{
_routes.AddOrUpdate(nodeId, i => route, (i, s) => route);
if (trust)
_nodeIds.AddOrUpdate(route, i => nodeId, (i, s) => nodeId);
_nodeIds.AddOrUpdate(route, i => nodeId, (i, s) => nodeId);
}
/// <summary>
@@ -121,12 +119,15 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
/// <param name="nodeId">The node identifier.</param>
public void ClearNode(int nodeId)
{
string route;
if (_routes.TryRemove(nodeId, out route))
{
int id;
_nodeIds.TryRemove(route, out id);
}
if (!_routes.ContainsKey(nodeId)) return;
string key;
if (!_routes.TryGetValue(nodeId, out key)) return;
int val;
_nodeIds.TryRemove(key, out val);
string val2;
_routes.TryRemove(nodeId, out val2);
}
/// <summary>
@@ -65,6 +65,14 @@ namespace Umbraco.Web.Routing
return null;
}
if (route.StartsWith("err/"))
{
LogHelper.Debug<DefaultUrlProvider>(
"Page with nodeId={0} has a colliding url with page with nodeId={1}.",
() => id, () => route.Substring(4));
return "#err-" + route.Substring(4);
}
var domainHelper = new DomainHelper(umbracoContext.Application.Services.DomainService);
// extract domainUri and path
@@ -107,6 +115,9 @@ namespace Umbraco.Web.Routing
return null;
}
if (route.StartsWith("err/"))
return null;
var domainHelper = new DomainHelper(umbracoContext.Application.Services.DomainService);
// extract domainUri and path
@@ -67,32 +67,6 @@ namespace Umbraco.Web.Routing
#region Public
/// <summary>
/// Tries to route the request.
/// </summary>
internal bool TryRouteRequest()
{
// disabled - is it going to change the routing?
//_pcr.OnPreparing();
FindDomain();
if (_pcr.IsRedirect) return false;
if (_pcr.HasPublishedContent) return true;
FindPublishedContent();
if (_pcr.IsRedirect) return false;
// don't handle anything - we just want to ensure that we find the content
//HandlePublishedContent();
//FindTemplate();
//FollowExternalRedirect();
//HandleWildcardDomains();
// disabled - we just want to ensure that we find the content
//_pcr.OnPrepared();
return _pcr.HasPublishedContent;
}
/// <summary>
/// Prepares the request.
/// </summary>
@@ -295,7 +295,8 @@ namespace Umbraco.Web.Routing
private static bool IsNotRoute(string route)
{
// null if content not found
return route == null;
// err/- if collision or anomaly or ...
return route == null || route.StartsWith("err/");
}
// gets a value indicating whether server is 'slave'
@@ -1,10 +1,7 @@
using System;
using System.Collections.Generic;
using System.Web.Security;
using Umbraco.Core.Models;
using umbraco;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
namespace Umbraco.Web.Routing
@@ -65,45 +62,34 @@ namespace Umbraco.Web.Routing
{
urls.Add(ui.Text("content", "getUrlException", umbracoContext.Security.CurrentUser));
}
else
else if (url.StartsWith("#err-"))
{
// test for collisions
var uri = new Uri(url.TrimEnd('/'), UriKind.RelativeOrAbsolute);
if (uri.IsAbsoluteUri == false) uri = uri.MakeAbsolute(UmbracoContext.Current.CleanedUmbracoUrl);
var pcr = new PublishedContentRequest(uri, UmbracoContext.Current.RoutingContext, UmbracoConfig.For.UmbracoSettings().WebRouting, s => Roles.Provider.GetRolesForUser(s));
pcr.Engine.TryRouteRequest();
if (pcr.HasPublishedContent == false)
// route error, report
var id = int.Parse(url.Substring(5));
var o = umbracoContext.ContentCache.GetById(id);
string s;
if (o == null)
{
urls.Add(ui.Text("content", "routeError", "(error)", umbracoContext.Security.CurrentUser));
}
else if (pcr.PublishedContent.Id != content.Id)
{
var o = pcr.PublishedContent;
string s;
if (o == null)
{
s = "(unknown)";
}
else
{
var l = new List<string>();
while (o != null)
{
l.Add(o.Name);
o = o.Parent;
}
l.Reverse();
s = "/" + string.Join("/", l) + " (id=" + pcr.PublishedContent.Id + ")";
}
urls.Add(ui.Text("content", "routeError", s, umbracoContext.Security.CurrentUser));
s = "(unknown)";
}
else
{
urls.Add(url);
urls.AddRange(urlProvider.GetOtherUrls(content.Id));
var l = new List<string>();
while (o != null)
{
l.Add(o.Name);
o = o.Parent;
}
l.Reverse();
s = "/" + string.Join("/", l) + " (id=" + id + ")";
}
urls.Add(ui.Text("content", "routeError", s, umbracoContext.Security.CurrentUser));
}
else
{
urls.Add(url);
urls.AddRange(urlProvider.GetOtherUrls(content.Id));
}
return urls;
}
+1 -2
View File
@@ -428,8 +428,7 @@ namespace Umbraco.Web.Security
var viewProperties = new List<UmbracoProperty>();
foreach (var prop in memberType.PropertyTypes
.Where(x => builtIns.Contains(x.Alias) == false && memberType.MemberCanEditProperty(x.Alias))
.OrderBy(p => p.SortOrder))
.Where(x => builtIns.Contains(x.Alias) == false && memberType.MemberCanEditProperty(x.Alias)))
{
var value = string.Empty;
if (member != null)
+43 -3
View File
@@ -99,70 +99,92 @@
</ProjectReference>
<Reference Include="AutoMapper, Version=3.3.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="AutoMapper.Net4, Version=3.3.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.Net4.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="ClientDependency.Core, Version=1.9.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ClientDependency.1.9.2\lib\net45\ClientDependency.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="CookComputing.XmlRpcV2, Version=2.5.0.0, Culture=neutral, PublicKeyToken=a7d6e17aa302004d, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\xmlrpcnet.2.5.0\lib\net20\CookComputing.XmlRpcV2.dll</HintPath>
</Reference>
<Reference Include="dotless.Core, Version=1.4.1.0, Culture=neutral, PublicKeyToken=96b446c9e63eae34, processorArchitecture=MSIL">
<Reference Include="dotless.Core">
<HintPath>..\packages\dotless.1.4.1.0\lib\dotless.Core.dll</HintPath>
</Reference>
<Reference Include="Examine, Version=0.1.70.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Examine.0.1.70.0\lib\Examine.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="HtmlAgilityPack, Version=1.4.9.0, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\HtmlAgilityPack.1.4.9\lib\Net45\HtmlAgilityPack.dll</HintPath>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
<Reference Include="Lucene.Net, Version=2.9.4.1, Culture=neutral, PublicKeyToken=85089178b9ac3181, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Lucene.Net.2.9.4.1\lib\net40\Lucene.Net.dll</HintPath>
</Reference>
<Reference Include="MarkdownSharp, Version=1.14.5.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Markdown.1.14.7\lib\net45\MarkdownSharp.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.AspNet.Identity.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AspNet.Identity.Owin, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.AspNet.Identity.Owin.2.2.1\lib\net45\Microsoft.AspNet.Identity.Owin.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Host.SystemWeb, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.Owin.Host.SystemWeb.3.0.1\lib\net45\Microsoft.Owin.Host.SystemWeb.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Security, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.Owin.Security.3.0.1\lib\net45\Microsoft.Owin.Security.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Security.Cookies, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.Owin.Security.Cookies.3.0.1\lib\net45\Microsoft.Owin.Security.Cookies.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Security.OAuth, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.Owin.Security.OAuth.3.0.1\lib\net45\Microsoft.Owin.Security.OAuth.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Private>True</Private>
</Reference>
<Reference Include="MiniProfiler, Version=2.1.0.0, Culture=neutral, PublicKeyToken=b44f9351044011a3, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\MiniProfiler.2.1.0\lib\net40\MiniProfiler.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Private>True</Private>
</Reference>
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
</Reference>
<Reference Include="Semver, Version=1.1.2.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\semver.1.1.2\lib\net45\Semver.dll</HintPath>
</Reference>
<Reference Include="System">
@@ -182,6 +204,7 @@
<Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Serialization" />
@@ -197,30 +220,43 @@
<Reference Include="System.Web.Extensions.Design" />
<Reference Include="System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.Http">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Http.WebHost, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll</HintPath>
</Reference>
<Reference Include="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Services">
<Name>System.Web.Services</Name>
</Reference>
<Reference Include="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.WebPages.Deployment, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Private>True</Private>
</Reference>
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml">
@@ -263,6 +299,8 @@
</ProjectReference>
<Reference Include="UrlRewritingNet.UrlRewriter, Version=2.0.7.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\UrlRewritingNet.UrlRewriter.2.0.7\lib\UrlRewritingNet.UrlRewriter.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
@@ -1958,7 +1996,6 @@
<None Include="..\Umbraco.Web.UI\Views\web.config">
<Link>Mvc\web.config</Link>
</None>
<None Include="packages.config" />
<None Include="Web References\org.umbraco.our\Reference.map">
<Generator>MSDiscoCodeGenerator</Generator>
<LastGenOutput>Reference.cs</LastGenOutput>
@@ -2053,6 +2090,9 @@
</Content>
<Content Include="umbraco.presentation\umbraco\plugins\tinymce3\tinymce3tinymceCompress.aspx" />
<None Include="app.config" />
<None Include="packages.config">
<SubType>Designer</SubType>
</None>
<None Include="Web References\org.umbraco.our\repository.wsdl" />
<None Include="Web References\org.umbraco.update\UpgradeResult.datasource">
<DependentUpon>Reference.map</DependentUpon>
@@ -44,17 +44,7 @@ namespace Umbraco.Web.WebServices
}
catch (Exception ee)
{
var errorMessage = "Error executing scheduled task";
if (HttpContext != null && HttpContext.Request != null)
{
if (HttpContext.Request.Url != null)
errorMessage = string.Format("{0} | Request to {1}", errorMessage, HttpContext.Request.Url);
if (HttpContext.Request.UserHostAddress != null)
errorMessage = string.Format("{0} | Coming from {1}", errorMessage, HttpContext.Request.UserHostAddress);
if (HttpContext.Request.UrlReferrer != null)
errorMessage = string.Format("{0} | Referrer {1}", errorMessage, HttpContext.Request.UrlReferrer);
}
LogHelper.Error<ScheduledPublishController>(errorMessage, ee);
LogHelper.Error<ScheduledPublishController>("Error executing scheduled task", ee);
Response.StatusCode = 400;
+1 -6
View File
@@ -162,12 +162,7 @@ namespace UmbracoExamine
base.Initialize(name, config);
//NOTES: useTempStorage is obsolete, tempStorageDirectory is obsolete, both have been superceded by Examine Core's IDirectoryFactory
// tempStorageDirectory never actually got finished in Umbraco Core but accidentally got shipped (it's only enabled on the searcher
// and not the indexer). So this whole block is just legacy
//detect if a dir factory has been specified, if so then useTempStorage will not be used (deprecated)
if (config["directoryFactory"] == null && config["useTempStorage"] != null)
if (config["useTempStorage"] != null)
{
var fsDir = base.GetLuceneDirectory() as FSDirectory;
if (fsDir != null)
@@ -1,6 +1,5 @@
using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.IO;
using System.Web;
using Umbraco.Core;
@@ -10,8 +9,6 @@ namespace UmbracoExamine.LocalStorage
/// <summary>
/// When running on Azure websites, we can use the local user's storage space
/// </summary>
[Obsolete("This has been superceded by IDirectoryFactory in Examine Core and should not be used")]
[EditorBrowsable(EditorBrowsableState.Never)]
public sealed class AzureLocalStorageDirectory : ILocalStorageDirectory
{
public DirectoryInfo GetLocalStorageDirectory(NameValueCollection config, string configuredPath)
@@ -1,6 +1,4 @@
using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.IO;
using System.Web;
@@ -13,8 +11,6 @@ namespace UmbracoExamine.LocalStorage
/// This is the default implementation - but it comes with it's own limitations - the CodeGen folder is cleared whenever new
/// DLLs are changed in the /bin folder (among other circumstances) which means the index would be re-synced (or rebuilt) there.
/// </remarks>
[Obsolete("This has been superceded by IDirectoryFactory in Examine Core and should not be used")]
[EditorBrowsable(EditorBrowsableState.Never)]
public sealed class CodeGenLocalStorageDirectory : ILocalStorageDirectory
{
public DirectoryInfo GetLocalStorageDirectory(NameValueCollection config, string configuredPath)
+11 -37
View File
@@ -32,7 +32,6 @@ namespace UmbracoExamine
private readonly IDataTypeService _dataTypeService;
private readonly IUserService _userService;
private readonly IContentTypeService _contentTypeService;
private readonly EntityXmlSerializer _serializer = new EntityXmlSerializer();
#region Constructors
@@ -146,7 +145,9 @@ namespace UmbracoExamine
#endregion
#region Constants & Fields
#region Constants & Fields
/// <summary>
/// Used to store the path of a content object
@@ -364,7 +365,7 @@ namespace UmbracoExamine
/// <summary>
/// This is a static query, it's parameters don't change so store statically
/// </summary>
private IQuery<IContent> _publishedQuery;
private static readonly IQuery<IContent> PublishedQuery = Query<IContent>.Builder.Where(x => x.Published == true);
protected override void PerformIndexAll(string type)
{
@@ -381,9 +382,6 @@ namespace UmbracoExamine
}
IContent[] content;
//used to track non-published entities so we can determine what items are implicitly not published
var notPublished = new HashSet<string>();
do
{
long total;
@@ -395,14 +393,8 @@ namespace UmbracoExamine
}
else
{
if (_publishedQuery == null)
{
_publishedQuery = Query<IContent>.Builder.Where(x => x.Published == true);
}
//get all paged records but order by level ascending, we need to do this because we need to track which nodes are not published so that we can determine
// which descendent nodes are implicitly not published
descendants = _contentService.GetPagedDescendants(contentParentId, pageIndex, pageSize, out total, "level", Direction.Ascending, true, (string)null);
//add the published filter
descendants = _contentService.GetPagedDescendants(contentParentId, pageIndex, pageSize, out total, "Path", Direction.Ascending, true, PublishedQuery);
}
//if specific types are declared we need to post filter them
@@ -415,12 +407,10 @@ namespace UmbracoExamine
{
content = descendants.ToArray();
}
AddNodesToIndex(GetSerializedContent(content, notPublished).WhereNotNull(), type);
AddNodesToIndex(GetSerializedContent(content), type);
pageIndex++;
} while (content.Length == pageSize);
notPublished.Clear();
break;
case IndexTypes.Media:
var mediaParentId = -1;
@@ -473,28 +463,12 @@ namespace UmbracoExamine
}
}
private IEnumerable<XElement> GetSerializedContent(IEnumerable<IContent> content, ISet<string> notPublished)
{
private IEnumerable<XElement> GetSerializedContent(IEnumerable<IContent> content)
{
var serializer = new EntityXmlSerializer();
foreach (var c in content)
{
if (SupportUnpublishedContent == false)
{
//if we don't support published content and this is not published then track it and return null
if (c.Published == false)
{
notPublished.Add(c.Path);
yield return null;
}
//if we don't support published content, check if this content item exists underneath any already tracked
//unpublished content and if so return null;
if (notPublished.Any(path => c.Path.StartsWith(string.Format("{0},", path))))
{
yield return null;
}
}
var xml = _serializer.Serialize(
var xml = serializer.Serialize(
_contentService,
_dataTypeService,
_userService,
+3
View File
@@ -84,11 +84,14 @@
<ItemGroup>
<Reference Include="Examine, Version=0.1.70.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Examine.0.1.70.0\lib\Examine.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
<Reference Include="Lucene.Net, Version=2.9.4.1, Culture=neutral, PublicKeyToken=85089178b9ac3181, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Lucene.Net.2.9.4.1\lib\net40\Lucene.Net.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
+1 -6
View File
@@ -73,12 +73,7 @@ namespace UmbracoExamine
base.Initialize(name, config);
//NOTES: useTempStorage is obsolete, tempStorageDirectory is obsolete, both have been superceded by Examine Core's IDirectoryFactory
// tempStorageDirectory never actually got finished in Umbraco Core but accidentally got shipped (it's only enabled on the searcher
// and not the indexer). So this whole block is just legacy
//detect if a dir factory has been specified, if so then useTempStorage will not be used (deprecated)
if (config != null && config["directoryFactory"] == null && config["useTempStorage"] != null)
if (config != null && config["useTempStorage"] != null)
{
//Use the temp storage directory which will store the index in the local/codegen folder, this is useful
// for websites that are running from a remove file server and file IO latency becomes an issue
@@ -47,17 +47,22 @@
<ItemGroup>
<Reference Include="Examine, Version=0.1.70.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Examine.0.1.70.0\lib\Examine.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="HtmlAgilityPack, Version=1.4.9.0, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\HtmlAgilityPack.1.4.9\lib\Net45\HtmlAgilityPack.dll</HintPath>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
<Reference Include="Lucene.Net, Version=2.9.4.1, Culture=neutral, PublicKeyToken=85089178b9ac3181, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Lucene.Net.2.9.4.1\lib\net40\Lucene.Net.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
@@ -70,33 +75,42 @@
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Web" />
<Reference Include="System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http.WebHost, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll</HintPath>
</Reference>
<Reference Include="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.WebPages.Deployment, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="Microsoft.CSharp" />
@@ -205,10 +219,10 @@
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
<Content Include="Resources\Web.config">
<SubType>Designer</SubType>
</Content>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\Strings.resx">
+1 -1
View File
@@ -5,6 +5,6 @@
<package id="Microsoft.AspNet.Razor" version="3.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="3.2.3" targetFramework="net45" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net4" />
<package id="Owin" version="1.0" targetFramework="net45" />
</packages>
@@ -108,17 +108,21 @@
<ItemGroup>
<Reference Include="AutoMapper, Version=3.3.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="AutoMapper.Net4, Version=3.3.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.Net4.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
</Reference>
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<Reference Include="Owin">
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
</Reference>
<Reference Include="System" />
@@ -138,21 +142,27 @@
</Reference>
<Reference Include="System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.WebPages.Deployment, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml">
<Name>System.XML</Name>
+4
View File
@@ -108,11 +108,14 @@
<ItemGroup>
<Reference Include="ClientDependency.Core, Version=1.9.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ClientDependency.1.9.2\lib\net45\ClientDependency.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="HtmlAgilityPack, Version=1.4.9.0, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\HtmlAgilityPack.1.4.9\lib\Net45\HtmlAgilityPack.dll</HintPath>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
@@ -165,6 +168,7 @@
</ProjectReference>
<Reference Include="System.Xml.Linq" />
<Reference Include="TidyNet, Version=1.0.0.0, Culture=neutral">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Tidy.Net.1.0.0\lib\TidyNet.dll</HintPath>
</Reference>
</ItemGroup>
@@ -70,6 +70,7 @@
<ItemGroup>
<Reference Include="ClientDependency.Core, Version=1.9.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ClientDependency.1.9.2\lib\net45\ClientDependency.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.configuration" />
+2 -2
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net-mediumtrust" version="2.0.0" targetFramework="net45" />
<package id="Microsoft.ApplicationBlocks.Data" version="1.0.1559.20655" targetFramework="net45" />
<package id="log4net-mediumtrust" version="2.0.0" targetFramework="net4" />
<package id="Microsoft.ApplicationBlocks.Data" version="1.0.1559.20655" targetFramework="net4" />
<package id="MySql.Data" version="6.9.8" targetFramework="net45" />
</packages>
@@ -69,12 +69,15 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net, Version=1.2.11.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\log4net-mediumtrust.2.0.0\lib\log4net.dll</HintPath>
</Reference>
<Reference Include="Microsoft.ApplicationBlocks.Data, Version=1.0.1559.20655, Culture=neutral">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.ApplicationBlocks.Data.1.0.1559.20655\lib\Microsoft.ApplicationBlocks.Data.dll</HintPath>
</Reference>
<Reference Include="MySql.Data, Version=6.9.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
<Reference Include="MySql.Data">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll</HintPath>
</Reference>
<Reference Include="System" />
@@ -116,6 +116,7 @@
</ProjectReference>
<Reference Include="ClientDependency.Core, Version=1.9.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ClientDependency.1.9.2\lib\net45\ClientDependency.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System">
<Name>System</Name>