Compare commits

...

96 Commits

Author SHA1 Message Date
Shannon 2d230a7b01 Adds a ColdBootType so we can detect and work with that if we have our own custom callbacks 2017-01-11 16:40:40 +11:00
Shannon 18c5348bdf Merge remote-tracking branch 'refs/remotes/origin/dev-v7' into temp-examine-sync 2017-01-11 16:40:10 +11:00
Shannon c50fea9794 Adds a ColdBootType so we can detect and work with that if we have our own custom callbacks 2017-01-11 16:39:13 +11:00
Mads Rasmussen 0a53f7636c remove orange color from discard changes button 2017-01-10 15:01:45 +01:00
Mads Rasmussen 6e6d552441 Merge pull request #1662 from marcemarc/patch-2
Add some green to 'stay' option - U4-9323
2017-01-10 14:59:08 +01:00
Sebastiaan Janssen 358dd7f32b Move ImageProcessor.Web.Config to not be in the .Core NuGet, it's not a dll 2017-01-10 07:30:35 +01:00
Shannon 6531d027fc fixes error with server side validation + data tyep editor 2017-01-10 11:55:36 +11:00
Shannon d11e787624 updates Nuspec with IP version 2017-01-10 11:37:31 +11:00
Shannon 055ae0d126 updates latest IP mem leak fixes 2017-01-10 11:36:35 +11:00
Sebastiaan Janssen 52b1a08912 Merge pull request #1671 from umbraco/temp-U4-9337
Perf improvements especially around URLs and node path
2017-01-09 16:12:26 +01:00
Stephan 9ba08f275e Merge branch 'temp-U4-9337' of https://github.com/umbraco/Umbraco-CMS into temp-U4-9337 2017-01-06 09:15:43 +01:00
Stephan aadd0c9129 U4-9337 - asymmetric route caching 2017-01-06 09:12:25 +01:00
Shannon b3b79a792f Merge branch 'refs/heads/dev-v7' into temp-U4-9337 2017-01-06 17:40:40 +11:00
Shannon 59cd4b5c5c Fixes more allocations at the config level 2017-01-06 17:40:03 +11:00
Shannon f5f9ff29ce Discovered we are not passing the ISqlSyntaxProvider correctly to where so it defaults to the global one which causes some issues for libraries such as UmbracoIdentity 2017-01-06 14:32:56 +11:00
Sebastiaan Janssen a10b59d03b Revert "Fixes: U4-9217 - Sanitize tags before storing them in the database"
This reverts commit 47c8e6854e.
2017-01-05 17:14:14 +01:00
Sebastiaan Janssen e6b1ecb851 Better way of cleaning the file extension to prevent XSS attacks 2017-01-05 11:52:06 +01:00
Sebastiaan Janssen 69d6609a3b Merge pull request #1675 from umbraco/temp-U4-9339
Trim the file name so that it doesn't get accepted by the server if i…
2017-01-05 11:34:23 +01:00
Claus 2196ab3713 changing this to use ToSafeFileName instead of just trimming for blank characters.
issuing a request with any character not allowed in a file path, appended to the filename - allows you to trick the validation like with the blank characters appended.
2017-01-05 11:10:21 +01:00
Stephan 89be1cf5d2 U4-9337 - with missing file... 2017-01-05 10:50:03 +01:00
Stephan 2041e85b9e U4-9337 - add doc and test 2017-01-05 10:46:40 +01:00
Claus 6c2f0e404f Merge pull request #1672 from umbraco/temp-U4-9336
U4-9336 Deleting a node with an incorrect path of -1 will unpublish every node in the entire site
2017-01-05 10:17:50 +01:00
Stephan d5e66252dc U4-9337 - minor simplification 2017-01-05 09:25:30 +01:00
Shannon c2359a96f8 missed nuspec update 2017-01-05 17:09:37 +11:00
Shannon 1df65bc3ce Updates to latest ImageProcessor.Web to fix mime types when stored outside web root 2017-01-05 16:00:45 +11:00
Shannon 530a80d7ea Adds a check to validate the NodeDto when persisting the item to validate that it's path is correct this should prevent any data corruption in the future - if the data corruption actually came from Core 2017-01-05 10:43:33 +11:00
Shannon 8be0f68390 Adds logic to validate an entity's path when it is used to GetDescendants, adds logic to fix an entity's path when it's state is going to be persisted when GetDescendants is used (i.e. MoveToRecycleBin), added this logic to Media too, adds unit tests to support 2017-01-05 10:29:03 +11:00
Sebastiaan Janssen 05cb30d79c Trim the file name so that it doesn't get accepted by the server if it's a disallowed file 2017-01-04 17:01:26 +01:00
Sebastiaan Janssen c472d4975e Add some extra logging to ScheduledPublishing to more easily see where errors are coming from 2017-01-04 16:31:55 +01:00
Stephan 0e31fcf3db U4-9337 - fix tests 2017-01-04 15:36:29 +01:00
Stephan 13ed3303f5 U4-9337 - url routing perfs 2017-01-04 13:56:41 +01:00
Claus f200ab423d updated test to fail and updated notes. 2017-01-04 11:59:07 +01:00
Shannon d889d3e385 adds test 2017-01-04 20:00:30 +11:00
Sebastiaan Janssen 0bf27fa319 Merge pull request #1669 from umbraco/temp-U4-9335
U4-9335 UmbracoExamine needs to ignore the useTempStorage option if a…
2017-01-04 09:42:01 +01:00
Shannon 466a37aab8 fix build 2017-01-04 18:42:11 +11:00
Shannon 4ab2130d7d stop allocating and re-processing config elements every time they are accessed! 2017-01-04 18:40:00 +11:00
Shannon 256ceef875 changes PublishedContentCache to explicitly cast to XmlElement (perf) 2017-01-04 18:12:28 +11:00
Shannon 2acde54880 Adds new benchmark and updates the benchmark bootstrapper to be the supported way 2017-01-04 18:11:21 +11:00
Shannon a92d255e4b adds notes, obsoletes a few classes that shouldn't have really been there 2017-01-04 17:10:48 +11:00
Sebastiaan Janssen dc62272e6e Revert "Add Microsoft.IO.RecyclableMemoryStream to the nuspec, update to the latest version (1.2.1)"
Keep the version the same as what ImageProcessor relies on to avoid confusion and conflicts

This reverts commit 56d2230251.

# Conflicts:
#	build/NuSpecs/UmbracoCms.Core.nuspec
2017-01-03 17:04:38 +01:00
Niels Hartvig 60f6a60ca9 Update install post url to https 2017-01-03 16:11:32 +01:00
Sebastiaan Janssen eef8d21112 Merge pull request #1667 from umbraco/U-9333
Makes EXIF data in resized images default
2017-01-03 15:59:43 +01:00
Sebastiaan Janssen 6a374cbfa6 Make the NuGet install and upgrade work 2017-01-03 15:57:21 +01:00
Sebastiaan Janssen ccb8ac4cfc Merge branch 'dev-v7' into U-9333
# Conflicts:
#	src/Umbraco.Web.UI/packages.config
2017-01-03 14:19:43 +01:00
hartvig 5de21734c0 Merge pull request #1650 from Bitmapped/U4-9298
Fix U4-9298
2017-01-03 12:56:46 +01:00
Sebastiaan Janssen 18deb8ad99 Merge pull request #1666 from defsteph/patch-1
Fixes issue U4-9332
2017-01-03 12:54:09 +01:00
Claus 3426ae3722 Merge pull request #1668 from umbraco/temp-U4-9318
U4-9318 Examine indexes inherited unpublished nodes on index rebuild
2017-01-03 11:44:33 +01:00
Sebastiaan Janssen d04510f5f2 Merge pull request #1661 from umbraco/temp-U4-9319
U4-9319 Update to latest ImageProcessor v2.5.0 and ImageProcessor.Web…
2017-01-03 10:21:26 +01:00
Sebastiaan Janssen 84c0682f16 Not necessary to install Microsoft.IO.RecyclableMemoryStream, the ImageProcessor dependency will do that for us 2017-01-03 10:20:22 +01:00
Shannon 53bbc5f922 U4-9335 UmbracoExamine needs to ignore the useTempStorage option if an IDirectoryFactory config option is supplied by the indexer 2017-01-03 19:39:34 +11:00
Sebastiaan Janssen 56d2230251 Add Microsoft.IO.RecyclableMemoryStream to the nuspec, update to the latest version (1.2.1) 2017-01-03 09:25:10 +01:00
Sebastiaan Janssen 62f21d3cee Update nuspec to install latest version of ImageProcessor 2017-01-03 09:17:05 +01:00
Shannon b9c90af8be U4-9329 ExamineIndex.config should not ship with the {machinename} token for Examine
Removes Sync from being the default for developers locally (that shouldnt have been committed), actually removes the machinename token from release
2017-01-03 17:37:15 +11:00
Shannon 7a661c1b48 clears the tracked paths collection just to possible make GC a bit happier 2017-01-03 17:16:07 +11:00
Shannon c871a711dd U4-9318 Examine indexes inherited unpublished nodes on index RebuildIndex
This reduces allocations since we don't need to create a new serializer for every doc
2017-01-03 16:43:54 +11:00
Shannon d671caf3ab moves static query to lazily initialize 2017-01-03 14:36:06 +11:00
Shannon d412d90b17 fixing more IP assembly/nuget refs 2017-01-03 11:14:34 +11:00
Shannon 2f74181262 fixing more IP assembly/nuget refs 2017-01-03 11:06:15 +11:00
Shannon 45fd23ff02 Merge branch 'refs/heads/dev-v7' into temp-U4-9319 2017-01-03 10:36:45 +11:00
Shannon 4e2fb8e5dc Fixes IP nuget references and fixes up several other Nuget assembly references. 2017-01-03 10:36:26 +11:00
Niels Hartvig afbceca184 Makes EXIF data in resized images default 2017-01-02 17:29:37 +01:00
Stephan Lonntorp 1b8c68af02 Fixes issue U4-9332
U4-9332 Language of DefaultCultureDictionary is cached without the current Culture identifier
2017-01-02 14:53:57 +01:00
Shannon 98430fd573 U4-9326 Removing a master template from a Template does not update the Template's path correctly 2016-12-30 11:42:02 +11:00
Marc Goodson 4a547ba1c9 Add some green to 'stay' option - U4-9323
Closes U4-9323 http://issues.umbraco.org/issue/U4-9323
2016-12-28 15:11:10 +00:00
Shannon 59f39fd535 Ensures we remove the new DLL with the install script like other files 2016-12-28 19:48:35 +11:00
Shannon b4ca04596c U4-9319 Update to latest ImageProcessor v2.5.0 and ImageProcessor.Web v4.7.0 2016-12-28 19:21:00 +11:00
Mikkel Holck Madsen 2d94ac7a19 Merge pull request #1658 from umbraco/temp-U4-9199
Fixes: U4-9199 Grid RTE (rich text editor/ tinyMCE) does not have a m…
2016-12-27 14:45:42 +01:00
Mads Rasmussen 4c97c689e9 Fixes: U4-9199 Grid RTE (rich text editor/ tinyMCE) does not have a max height, causing the user to have to scroll up to see RTE menu buttons 2016-12-22 14:06:23 +01:00
Sebastiaan Janssen f2f4c23c80 Merge pull request #1652 from umbraco/U4-9301
Updates login controller to not accept non local urls
2016-12-20 13:55:31 +01:00
Claus 67ea15706e Merge pull request #1651 from umbraco/temp-U4-9282
U4-9282 Rollback not working
2016-12-20 11:24:05 +01:00
Claus 5cc75b8cc3 Merge pull request #1654 from umbraco/temp-U4-9302
U4-9302 Add logging of non security related connection string details…
2016-12-20 11:01:50 +01:00
Claus 653ac66ff3 Merge pull request #1653 from umbraco/temp-U4-9262
U4-9262 CleanForXss breaks rgba() values set as grid background color…
2016-12-20 10:32:36 +01:00
Shannon 3f7e593bc2 U4-9302 Add logging of non security related connection string details when the connection fails 2016-12-20 14:10:06 +11:00
Shannon 39505cd868 U4-9262 CleanForXss breaks rgba() values set as grid background color style 2016-12-20 13:27:53 +11:00
Shannon 0daaa3e785 Revert "Merge pull request #1618 from AliSheikhTaheri/U4-9180"
This reverts commit 4050a375bc, reversing
changes made to a058f26462.
2016-12-20 12:28:45 +11:00
Shannon Deminick 4050a375bc Merge pull request #1618 from AliSheikhTaheri/U4-9180
U4-9180 Optimise Log4net
2016-12-20 11:08:11 +11:00
Niels Hartvig da27108d0d Updates login controller to not accept non local urls 2016-12-19 10:44:22 +01:00
hartvig a058f26462 Update README.md 2016-12-19 09:20:21 +01:00
Shannon c8f0f05570 U4-9246 Should ship with numRecompilesBeforeAppRestart="50" to avoid max recompilations reached errors 2016-12-19 17:10:29 +11:00
Shannon 347ed2896a U4-9282 Rollback not working 2016-12-19 16:58:24 +11:00
Shannon 5c40a1f9e9 bumps version 2016-12-19 16:42:05 +11:00
Brian Powell afa39866ad Fix U4-9298 2016-12-17 21:12:45 -05:00
Shannon 7254db40eb publicizes ExamineExtensions.ConvertSearchResultToPublishedContent 2016-12-15 17:44:32 +11:00
Shannon 04481c33e7 Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2016-12-15 10:45:57 +11:00
Shannon 4c107470c3 updates some angular docs 2016-12-15 10:43:53 +11:00
Warren Buckley 4b39f490f3 Merge pull request #1602 from cheeseytoastie/U4-9148_-_Splash_screen_apostophe_typo
U4-9148 noNodes Splash screen apostrophe char typo fixed (in "Be a pa…
2016-12-09 13:32:53 +00:00
Sebastiaan Janssen c607ceda48 Merge pull request #1557 from tompipe/U4-9127-SortMemberProperties
Fixed issue with member properties sort order
2016-12-09 08:59:52 +01:00
Claus d4acd4629a Merge pull request #1646 from umbraco/temp-U4-9259
Lazily creates the static queries instead of eagerly, this fixes an i…
2016-12-08 10:09:32 +01:00
Shannon b413b7b5af Lazily creates the static queries instead of eagerly, this fixes an issue of if these services are accessed before Umbraco has booted 2016-12-08 12:48:44 +11:00
Stephan 0415e910dc Merge pull request #1645 from umbraco/temp-U4-9255
U4-9255 Not having access to settings section causes backoffice user …
2016-12-07 13:06:24 +01:00
Claus 960040e51e U4-9255 Not having access to settings section causes backoffice user to be logged out when browsing media list views 2016-12-07 12:57:29 +01:00
Ali Sheikh Taheri 19b24b5109 Added maximum number of backups to keep. 2016-11-14 11:56:21 +00:00
Ali Sheikh Taheri 3aaa33ebe9 added .log file extension for backup logs. 2016-11-14 11:55:09 +00:00
Ali Sheikh Taheri 4ae7a32e29 Fix for maximum file size. 2016-11-14 11:54:42 +00:00
Steve Morgan dfbadb1550 U4-9148 noNodes Splash screen apostrophe char typo fixed (in "Be a part of the community" - we're) 2016-11-03 17:03:33 +00:00
Tom Pipe 0a49d54a85 Fixed issue with member properties sort order 2016-10-29 18:23:25 +01:00
100 changed files with 1679 additions and 976 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 350,000 websites worldwide: [https://umbraco.com](https://umbraco.com)
The friendliest, most flexible and fastest growing ASP.NET CMS used by more than 390,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.4.5, 3.0.0)" />
<dependency id="ImageProcessor.Web" version="[4.6.6, 5.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="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,6 +18,7 @@
<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>
@@ -43,6 +44,7 @@
<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,6 +71,7 @@ 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 }
@@ -0,0 +1 @@
<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.5
7.5.7
-4
View File
@@ -49,13 +49,9 @@
<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 2016")]
[assembly: AssemblyCopyright("Copyright © Umbraco 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -11,5 +11,5 @@ using System.Resources;
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("7.5.5")]
[assembly: AssemblyInformationalVersion("7.5.5")]
[assembly: AssemblyFileVersion("7.5.7")]
[assembly: AssemblyInformationalVersion("7.5.7")]
@@ -4,8 +4,7 @@ using System.Configuration;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class ContentElement : ConfigurationElement, IContentSection
internal class ContentElement : UmbracoConfigurationElement, IContentSection
{
[ConfigurationProperty("imaging")]
internal ContentImagingElement Imaging
@@ -22,25 +21,13 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
[ConfigurationProperty("ResolveUrlsFromTextString")]
internal InnerTextConfigurationElement<bool> ResolveUrlsFromTextString
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["ResolveUrlsFromTextString"],
//set the default
false);
}
get { return GetOptionalTextElement<bool>("ResolveUrlsFromTextString", false); }
}
[ConfigurationProperty("UploadAllowDirectories")]
internal InnerTextConfigurationElement<bool> UploadAllowDirectories
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["UploadAllowDirectories"],
//set the default
true);
}
get { return GetOptionalTextElement("UploadAllowDirectories", true); }
}
public IEnumerable<IContentErrorPage> Error404Collection
@@ -63,121 +50,61 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
[ConfigurationProperty("ensureUniqueNaming")]
internal InnerTextConfigurationElement<bool> EnsureUniqueNaming
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["ensureUniqueNaming"],
//set the default
true);
}
get { return GetOptionalTextElement("ensureUniqueNaming", true); }
}
[ConfigurationProperty("TidyEditorContent")]
internal InnerTextConfigurationElement<bool> TidyEditorContent
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["TidyEditorContent"],
//set the default
false);
}
get { return GetOptionalTextElement("TidyEditorContent", false); }
}
[ConfigurationProperty("TidyCharEncoding")]
internal InnerTextConfigurationElement<string> TidyCharEncoding
{
get
{
return new OptionalInnerTextConfigurationElement<string>(
(InnerTextConfigurationElement<string>)this["TidyCharEncoding"],
//set the default
"UTF8");
}
get { return GetOptionalTextElement("TidyCharEncoding", "UTF8"); }
}
[ConfigurationProperty("XmlCacheEnabled")]
internal InnerTextConfigurationElement<bool> XmlCacheEnabled
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["XmlCacheEnabled"],
//set the default
true);
}
get { return GetOptionalTextElement("XmlCacheEnabled", true); }
}
[ConfigurationProperty("ContinouslyUpdateXmlDiskCache")]
internal InnerTextConfigurationElement<bool> ContinouslyUpdateXmlDiskCache
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["ContinouslyUpdateXmlDiskCache"],
//set the default
true);
}
get { return GetOptionalTextElement("ContinouslyUpdateXmlDiskCache", true); }
}
[ConfigurationProperty("XmlContentCheckForDiskChanges")]
internal InnerTextConfigurationElement<bool> XmlContentCheckForDiskChanges
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["XmlContentCheckForDiskChanges"],
//set the default
false);
}
get { return GetOptionalTextElement("XmlContentCheckForDiskChanges", false); }
}
[ConfigurationProperty("EnableSplashWhileLoading")]
internal InnerTextConfigurationElement<bool> EnableSplashWhileLoading
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["EnableSplashWhileLoading"],
//set the default
false);
}
get { return GetOptionalTextElement("EnableSplashWhileLoading", false); }
}
[ConfigurationProperty("PropertyContextHelpOption")]
internal InnerTextConfigurationElement<string> PropertyContextHelpOption
{
get
{
return new OptionalInnerTextConfigurationElement<string>(
(InnerTextConfigurationElement<string>)this["PropertyContextHelpOption"],
//set the default
"text");
}
get { return GetOptionalTextElement("PropertyContextHelpOption", "text"); }
}
[ConfigurationProperty("UseLegacyXmlSchema")]
internal InnerTextConfigurationElement<bool> UseLegacyXmlSchema
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["UseLegacyXmlSchema"],
//set the default
false);
}
get { return GetOptionalTextElement("UseLegacyXmlSchema", false); }
}
[ConfigurationProperty("ForceSafeAliases")]
internal InnerTextConfigurationElement<bool> ForceSafeAliases
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["ForceSafeAliases"],
//set the default
true);
}
get { return GetOptionalTextElement("ForceSafeAliases", true); }
}
[ConfigurationProperty("PreviewBadge")]
@@ -185,123 +112,63 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
{
get
{
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>");
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>");
}
}
[ConfigurationProperty("UmbracoLibraryCacheDuration")]
internal InnerTextConfigurationElement<int> UmbracoLibraryCacheDuration
{
get
{
return new OptionalInnerTextConfigurationElement<int>(
(InnerTextConfigurationElement<int>)this["UmbracoLibraryCacheDuration"],
//set the default
1800);
}
get { return GetOptionalTextElement("UmbracoLibraryCacheDuration", 1800); }
}
[ConfigurationProperty("MacroErrors")]
internal InnerTextConfigurationElement<MacroErrorBehaviour> MacroErrors
{
get
{
return new OptionalInnerTextConfigurationElement<MacroErrorBehaviour>(
(InnerTextConfigurationElement<MacroErrorBehaviour>)this["MacroErrors"],
//set the default
MacroErrorBehaviour.Inline);
}
get { return GetOptionalTextElement("MacroErrors", 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 new OptionalInnerTextConfigurationElement<IconPickerBehaviour>(
(InnerTextConfigurationElement<IconPickerBehaviour>)this["DocumentTypeIconList"],
//set the default
IconPickerBehaviour.HideFileDuplicates);
}
get { return GetOptionalTextElement("DocumentTypeIconList", IconPickerBehaviour.HideFileDuplicates); }
}
[ConfigurationProperty("disallowedUploadFiles")]
internal CommaDelimitedConfigurationElement DisallowedUploadFiles
{
get
{
return new OptionalCommaDelimitedConfigurationElement(
(CommaDelimitedConfigurationElement)this["disallowedUploadFiles"],
//set the default
new[] { "ashx", "aspx", "ascx", "config", "cshtml", "vbhtml", "asmx", "air", "axd" });
}
get { return GetOptionalDelimitedElement("disallowedUploadFiles", new[] {"ashx", "aspx", "ascx", "config", "cshtml", "vbhtml", "asmx", "air", "axd"}); }
}
[ConfigurationProperty("cloneXmlContent")]
internal InnerTextConfigurationElement<bool> CloneXmlContent
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["cloneXmlContent"],
//set the default
true);
}
get { return GetOptionalTextElement("cloneXmlContent", true); }
}
[ConfigurationProperty("GlobalPreviewStorageEnabled")]
internal InnerTextConfigurationElement<bool> GlobalPreviewStorageEnabled
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["GlobalPreviewStorageEnabled"],
//set the default
false);
}
get { return GetOptionalTextElement("GlobalPreviewStorageEnabled", false); }
}
[ConfigurationProperty("defaultDocumentTypeProperty")]
internal InnerTextConfigurationElement<string> DefaultDocumentTypeProperty
{
get
{
return new OptionalInnerTextConfigurationElement<string>(
(InnerTextConfigurationElement<string>)this["defaultDocumentTypeProperty"],
//set the default
"Textstring");
}
get { return GetOptionalTextElement("defaultDocumentTypeProperty", "Textstring"); }
}
[ConfigurationProperty("EnableInheritedDocumentTypes")]
internal InnerTextConfigurationElement<bool> EnableInheritedDocumentTypes
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>) this["EnableInheritedDocumentTypes"],
//set the default
true);
}
get { return GetOptionalTextElement("EnableInheritedDocumentTypes", true); }
}
[ConfigurationProperty("EnableInheritedMediaTypes")]
internal InnerTextConfigurationElement<bool> EnableInheritedMediaTypes
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["EnableInheritedMediaTypes"],
//set the default
true);
}
get { return GetOptionalTextElement("EnableInheritedMediaTypes", true); }
}
string IContentSection.NotificationEmailAddress
@@ -3,42 +3,24 @@ using System.Configuration;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class ContentScriptEditorElement : ConfigurationElement
internal class ContentScriptEditorElement : UmbracoConfigurationElement
{
[ConfigurationProperty("scriptFolderPath")]
internal InnerTextConfigurationElement<string> ScriptFolderPath
{
get
{
return new OptionalInnerTextConfigurationElement<string>(
(InnerTextConfigurationElement<string>)this["scriptFolderPath"],
//set the default
"/scripts");
}
get { return GetOptionalTextElement("scriptFolderPath", "/scripts"); }
}
[ConfigurationProperty("scriptFileTypes")]
internal OptionalCommaDelimitedConfigurationElement ScriptFileTypes
{
get
{
return new OptionalCommaDelimitedConfigurationElement(
(OptionalCommaDelimitedConfigurationElement)this["scriptFileTypes"],
//set the default
new[] { "js", "xml" });
}
get { return GetOptionalDelimitedElement("scriptFileTypes", new[] {"js", "xml"}); }
}
[ConfigurationProperty("scriptDisableEditor")]
internal InnerTextConfigurationElement<bool> ScriptEditorDisable
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>) this["scriptDisableEditor"],
//set the default
false);
}
get { return GetOptionalTextElement("scriptDisableEditor", false); }
}
}
@@ -2,7 +2,7 @@
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class ImagingAutoFillUploadFieldElement : ConfigurationElement, IImagingAutoFillUploadField
internal class ImagingAutoFillUploadFieldElement : UmbracoConfigurationElement, IImagingAutoFillUploadField
{
/// <summary>
/// Allow setting internally so we can create a default
@@ -17,49 +17,25 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
[ConfigurationProperty("widthFieldAlias")]
internal InnerTextConfigurationElement<string> WidthFieldAlias
{
get
{
return new OptionalInnerTextConfigurationElement<string>(
(InnerTextConfigurationElement<string>)this["widthFieldAlias"],
//set the default
"umbracoWidth");
}
get { return GetOptionalTextElement("widthFieldAlias", "umbracoWidth"); }
}
[ConfigurationProperty("heightFieldAlias")]
internal InnerTextConfigurationElement<string> HeightFieldAlias
{
get
{
return new OptionalInnerTextConfigurationElement<string>(
(InnerTextConfigurationElement<string>)this["heightFieldAlias"],
//set the default
"umbracoHeight");
}
get { return GetOptionalTextElement("heightFieldAlias", "umbracoHeight"); }
}
[ConfigurationProperty("lengthFieldAlias")]
internal InnerTextConfigurationElement<string> LengthFieldAlias
{
get
{
return new OptionalInnerTextConfigurationElement<string>(
(InnerTextConfigurationElement<string>)this["lengthFieldAlias"],
//set the default
"umbracoBytes");
}
get { return GetOptionalTextElement("lengthFieldAlias", "umbracoBytes"); }
}
[ConfigurationProperty("extensionFieldAlias")]
internal InnerTextConfigurationElement<string> ExtensionFieldAlias
{
get
{
return new OptionalInnerTextConfigurationElement<string>(
(InnerTextConfigurationElement<string>)this["extensionFieldAlias"],
//set the default
"umbracoExtension");
}
get { return GetOptionalTextElement("extensionFieldAlias", "umbracoExtension"); }
}
string IImagingAutoFillUploadField.Alias
@@ -3,67 +3,37 @@ using System.Configuration;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class LoggingElement : ConfigurationElement, ILoggingSection
internal class LoggingElement : UmbracoConfigurationElement, ILoggingSection
{
[ConfigurationProperty("autoCleanLogs")]
internal InnerTextConfigurationElement<bool> AutoCleanLogs
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["autoCleanLogs"],
//set the default
false);
}
get { return GetOptionalTextElement("autoCleanLogs", false); }
}
[ConfigurationProperty("enableLogging")]
internal InnerTextConfigurationElement<bool> EnableLogging
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["enableLogging"],
//set the default
true);
}
get { return GetOptionalTextElement("enableLogging", true); }
}
[ConfigurationProperty("enableAsyncLogging")]
internal InnerTextConfigurationElement<bool> EnableAsyncLogging
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["enableAsyncLogging"],
//set the default
true);
}
get { return GetOptionalTextElement("enableAsyncLogging", true); }
}
[ConfigurationProperty("cleaningMiliseconds")]
internal InnerTextConfigurationElement<int> CleaningMiliseconds
{
get
{
return new OptionalInnerTextConfigurationElement<int>(
(InnerTextConfigurationElement<int>)this["cleaningMiliseconds"],
//set the default
-1);
}
get { return GetOptionalTextElement("cleaningMiliseconds", -1); }
}
[ConfigurationProperty("maxLogAge")]
internal InnerTextConfigurationElement<int> MaxLogAge
{
get
{
return new OptionalInnerTextConfigurationElement<int>(
(InnerTextConfigurationElement<int>)this["maxLogAge"],
//set the default
-1);
}
get { return GetOptionalTextElement("maxLogAge", -1); }
}
[ConfigurationCollection(typeof(DisabledLogTypesCollection), AddItemName = "logTypeAlias")]
@@ -2,7 +2,7 @@
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class NotificationsElement : ConfigurationElement
internal class NotificationsElement : UmbracoConfigurationElement
{
[ConfigurationProperty("email")]
internal InnerTextConfigurationElement<string> NotificationEmailAddress
@@ -13,13 +13,7 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
[ConfigurationProperty("disableHtmlEmail")]
internal InnerTextConfigurationElement<bool> DisableHtmlEmail
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>) this["disableHtmlEmail"],
//set the default
false);
}
get { return GetOptionalTextElement("disableHtmlEmail", false); }
}
}
@@ -5,30 +5,18 @@ using System.Collections.Generic;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class RequestHandlerElement : ConfigurationElement, IRequestHandlerSection
internal class RequestHandlerElement : UmbracoConfigurationElement, IRequestHandlerSection
{
[ConfigurationProperty("useDomainPrefixes")]
public InnerTextConfigurationElement<bool> UseDomainPrefixes
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["useDomainPrefixes"],
//set the default
false);
}
get { return GetOptionalTextElement("useDomainPrefixes", false); }
}
[ConfigurationProperty("addTrailingSlash")]
public InnerTextConfigurationElement<bool> AddTrailingSlash
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["addTrailingSlash"],
//set the default
true);
}
get { return GetOptionalTextElement("addTrailingSlash", true); }
}
private UrlReplacingElement _defaultUrlReplacing;
@@ -2,66 +2,36 @@
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class SecurityElement : ConfigurationElement, ISecuritySection
internal class SecurityElement : UmbracoConfigurationElement, ISecuritySection
{
[ConfigurationProperty("keepUserLoggedIn")]
internal InnerTextConfigurationElement<bool> KeepUserLoggedIn
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["keepUserLoggedIn"],
//set the default
true);
}
get { return GetOptionalTextElement("keepUserLoggedIn", true); }
}
[ConfigurationProperty("hideDisabledUsersInBackoffice")]
internal InnerTextConfigurationElement<bool> HideDisabledUsersInBackoffice
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["hideDisabledUsersInBackoffice"],
//set the default
false);
}
get { return GetOptionalTextElement("hideDisabledUsersInBackoffice", false); }
}
[ConfigurationProperty("allowPasswordReset")]
internal InnerTextConfigurationElement<bool> AllowPasswordReset
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["allowPasswordReset"],
//set the default
true);
}
get { return GetOptionalTextElement("allowPasswordReset", true); }
}
[ConfigurationProperty("authCookieName")]
internal InnerTextConfigurationElement<string> AuthCookieName
{
get
{
return new OptionalInnerTextConfigurationElement<string>(
(InnerTextConfigurationElement<string>)this["authCookieName"],
//set the default
Constants.Web.AuthCookieName);
}
get { return GetOptionalTextElement("authCookieName", Constants.Web.AuthCookieName); }
}
[ConfigurationProperty("authCookieDomain")]
internal InnerTextConfigurationElement<string> AuthCookieDomain
{
get
{
return new OptionalInnerTextConfigurationElement<string>(
(InnerTextConfigurationElement<string>)this["authCookieDomain"],
//set the default
null);
}
get { return GetOptionalTextElement<string>("authCookieDomain", null); }
}
bool ISecuritySection.KeepUserLoggedIn
@@ -3,55 +3,31 @@ using System.Configuration;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class TemplatesElement : ConfigurationElement, ITemplatesSection
internal class TemplatesElement : UmbracoConfigurationElement, ITemplatesSection
{
[ConfigurationProperty("useAspNetMasterPages")]
internal InnerTextConfigurationElement<bool> UseAspNetMasterPages
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["useAspNetMasterPages"],
//set the default
true);
}
get { return GetOptionalTextElement("useAspNetMasterPages", true); }
}
[ConfigurationProperty("enableSkinSupport")]
internal InnerTextConfigurationElement<bool> EnableSkinSupport
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["enableSkinSupport"],
//set the default
true);
}
get { return GetOptionalTextElement("enableSkinSupport", true); }
}
[ConfigurationProperty("defaultRenderingEngine", IsRequired = true)]
internal InnerTextConfigurationElement<RenderingEngine> DefaultRenderingEngine
{
get
{
return new OptionalInnerTextConfigurationElement<RenderingEngine>(
(InnerTextConfigurationElement<RenderingEngine>)this["defaultRenderingEngine"],
//set the default
RenderingEngine.Mvc);
}
get { return GetOptionalTextElement("defaultRenderingEngine", RenderingEngine.Mvc); }
}
[Obsolete("This has no affect and will be removed in future versions")]
[ConfigurationProperty("enableTemplateFolders")]
internal InnerTextConfigurationElement<bool> EnableTemplateFolders
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["enableTemplateFolders"],
//set the default
false);
}
get { return GetOptionalTextElement("enableTemplateFolders", false); }
}
bool ITemplatesSection.UseAspNetMasterPages
@@ -0,0 +1,36 @@
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.5");
private static readonly Version Version = new Version("7.5.7");
/// <summary>
/// Gets the current version of Umbraco.
+25 -4
View File
@@ -34,6 +34,12 @@ 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)
@@ -110,13 +116,28 @@ namespace Umbraco.Core
{
get
{
if (IsDatabaseConfigured == false) return false;
var canConnect = DbConnectionExtensions.IsConnectionAvailable(ConnectionString, DatabaseProvider);
LogHelper.Info<DatabaseContext>("CanConnect = " + canConnect);
return canConnect;
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;
}
}
/// <summary>
/// Gets the configured umbraco db connection string.
/// </summary>
@@ -1,9 +1,9 @@
namespace Umbraco.Core.Logging
{
using System;
using System.Runtime.CompilerServices;
using System;
using System.Runtime.CompilerServices;
using ImageProcessor.Common.Exceptions;
using ImageProcessor.Common.Exceptions;
namespace Umbraco.Core.Logging
{
/// <summary>
/// A logger for explicitly logging ImageProcessor exceptions.
+1 -2
View File
@@ -404,8 +404,7 @@ namespace Umbraco.Core.Models
return content.Properties
.Where(property => propertyGroup.PropertyTypes
.Select(propertyType => propertyType.Id)
.Contains(property.PropertyTypeId))
.OrderBy(x => x.PropertyType.SortOrder);
.Contains(property.PropertyTypeId));
}
/// <summary>
@@ -1,15 +1,117 @@
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,9 +4,11 @@ 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
@@ -69,6 +71,38 @@ 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
@@ -79,7 +113,8 @@ 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<IDbConnection>("Configured database is reporting as not being available!", exc);
LogHelper.WarnWithException(typeof(DbConnectionExtensions),
"Configured database is reporting as not being available! {0}", exc, connection.GetConnStringExSecurityInfo);
return false;
}
@@ -27,6 +27,7 @@ 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>();
@@ -34,6 +35,13 @@ 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,6 +14,14 @@ 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,13 +94,7 @@ namespace Umbraco.Core.Persistence.Repositories
return ProcessQuery(sql);
}
#endregion
#region Static Queries
private readonly IQuery<IContent> _publishedQuery = Query<IContent>.Builder.Where(x => x.Published == true);
#endregion
#endregion
#region Overrides of PetaPocoRepositoryBase<IContent>
@@ -348,6 +342,7 @@ 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
@@ -485,6 +480,7 @@ 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
@@ -857,7 +853,8 @@ order by umbracoNode.level, umbracoNode.parentID, umbracoNode.sortOrder";
if (withCache)
{
var cached = RuntimeCache.GetCacheItem<IContent>(GetCacheIdKey<IContent>(dto.NodeId));
if (cached != null && cached.Published)
//only use this cached version if the dto returned is also the publish version, they must match
if (cached != null && cached.Published && dto.Published)
{
content[i] = cached;
continue;
@@ -324,6 +324,7 @@ 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
@@ -397,6 +398,7 @@ 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,7 +241,12 @@ 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
+43 -5
View File
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;
using System.Xml;
@@ -11,6 +12,7 @@ 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;
@@ -58,7 +60,7 @@ namespace Umbraco.Core.Services
#region Static Queries
private readonly IQuery<IContent> _notTrashedQuery = Query<IContent>.Builder.Where(x => x.Trashed == false);
private IQuery<IContent> _notTrashedQuery;
#endregion
@@ -714,7 +716,12 @@ namespace Umbraco.Core.Services
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
public IEnumerable<IContent> GetDescendants(IContent content)
{
using (var repository = RepositoryFactory.CreateContentRepository(UowProvider.GetUnitOfWork()))
//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))
{
var pathMatch = content.Path + ",";
var query = Query<IContent>.Builder.Where(x => x.Path.StartsWith(pathMatch) && x.Id != content.Id);
@@ -793,6 +800,12 @@ 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);
@@ -990,6 +1003,10 @@ 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(
@@ -1677,16 +1694,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>(items), this))
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IContent>(asArray), 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();
@@ -1806,6 +1823,23 @@ 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();
@@ -1913,6 +1947,10 @@ 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
+7 -1
View File
@@ -64,7 +64,7 @@ namespace Umbraco.Core.Services
#region Static Queries
private readonly IQuery<IUmbracoEntity> _rootEntityQuery = Query<IUmbracoEntity>.Builder.Where(x => x.ParentId == -1);
private IQuery<IUmbracoEntity> _rootEntityQuery;
#endregion
@@ -392,6 +392,12 @@ 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()))
{
+71 -45
View File
@@ -2,6 +2,7 @@ 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;
@@ -527,6 +528,10 @@ 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))
{
@@ -619,7 +624,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);
@@ -998,56 +1003,63 @@ namespace Umbraco.Core.Services
{
if (media == null) throw new ArgumentNullException("media");
var originalPath = media.Path;
var evtMsgs = EventMessagesFactory.Get();
if (Trashing.IsRaisedEventCancelled(
new MoveEventArgs<IMedia>(new MoveEventInfo<IMedia>(media, originalPath, Constants.System.RecycleBinMedia)), this))
using (new WriteLock(Locker))
{
return OperationStatus.Cancelled(evtMsgs);
}
//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 moveInfo = new List<MoveEventInfo<IMedia>>
{
new MoveEventInfo<IMedia>(media, originalPath, Constants.System.RecycleBinMedia)
};
var originalPath = media.Path;
//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)
if (Trashing.IsRaisedEventCancelled(
new MoveEventArgs<IMedia>(new MoveEventInfo<IMedia>(media, originalPath, Constants.System.RecycleBinMedia)), this))
{
//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));
return OperationStatus.Cancelled(evtMsgs);
}
uow.Commit();
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);
}
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>
@@ -1064,8 +1076,6 @@ 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.
@@ -1154,7 +1164,6 @@ 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))
@@ -1316,6 +1325,23 @@ 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
@@ -0,0 +1,24 @@
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,6 +43,11 @@ 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)
{
@@ -146,11 +151,12 @@ 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
@@ -159,7 +165,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.");
coldboot = true;
ColdBootType = ColdBootType.NeverSynced;
}
else
{
@@ -175,11 +181,11 @@ namespace Umbraco.Core.Sync
+ " to the latest found in the database and maintain cache updates based on that Id.",
() => count, () => Options.MaxProcessingInstructionCount);
coldboot = true;
ColdBootType = ColdBootType.ExceedsMaxProcessingInstructionCount;
}
}
if (coldboot)
if (ColdBootType != ColdBootType.NoColdBoot)
{
// go get the last id in the db and store it
// note: do it BEFORE initializing otherwise some instructions might get lost
+11 -26
View File
@@ -21,7 +21,7 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DefineConstants>TRACE;DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
@@ -39,67 +39,54 @@
<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">
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
<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 Include="ImageProcessor, Version=2.5.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ImageProcessor.2.5.1\lib\net45\ImageProcessor.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="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">
<Reference Include="Microsoft.Owin.Security, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<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">
<SpecificVersion>False</SpecificVersion>
<Reference Include="MySql.Data, Version=6.9.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
<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">
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
</Reference>
<Reference Include="Semver">
<Reference Include="Semver, Version=1.1.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\semver.1.1.2\lib\net45\Semver.dll</HintPath>
</Reference>
<Reference Include="System" />
@@ -107,11 +94,9 @@
<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" />
@@ -296,6 +281,7 @@
<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" />
@@ -1325,6 +1311,7 @@
<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" />
@@ -1440,9 +1427,7 @@
<ItemGroup>
<None Include="app.config" />
<None Include="FileResources\BlockingWeb.config" />
<None Include="packages.config">
<SubType>Designer</SubType>
</None>
<None Include="packages.config" />
</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.4.5.0" targetFramework="net45" />
<package id="log4net-mediumtrust" version="2.0.0" targetFramework="net4" />
<package id="ImageProcessor" version="2.5.1" targetFramework="net45" />
<package id="log4net-mediumtrust" version="2.0.0" targetFramework="net45" />
<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="net4" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net45" />
<package id="SqlServerCE" version="4.0.0.1" targetFramework="net45" />
</packages>
@@ -0,0 +1,58 @@
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;
}
}
}
}
+7 -16
View File
@@ -8,23 +8,14 @@ namespace Umbraco.Tests.Benchmarks
{
public static void Main(string[] args)
{
if (args.Length == 1)
var switcher = new BenchmarkSwitcher(new[]
{
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("?");
}
typeof(BulkInsertBenchmarks),
typeof(ModelToSqlExpressionHelperBenchmarks),
typeof(XmlBenchmarks),
typeof(LinqCastBenchmarks)
});
switcher.Run(args);
}
}
}
@@ -39,31 +39,24 @@
<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">
@@ -73,20 +66,16 @@
<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" />
@@ -96,6 +85,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="LinqCastBenchmarks.cs" />
<Compile Include="ModelToSqlExpressionHelperBenchmarks.cs" />
<Compile Include="BulkInsertBenchmarks.cs" />
<Compile Include="Program.cs" />
@@ -106,10 +96,6 @@
<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>
@@ -120,7 +106,22 @@
<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>
@@ -128,14 +129,6 @@
</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,7 +1,10 @@
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
@@ -9,6 +12,132 @@ 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,6 +707,35 @@ 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,25 +71,19 @@ 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(8, cachedIds.Count);
foreach (var sample in samples)
{
var key = sample.Value;
Assert.IsTrue(cachedIds.ContainsKey(key));
Assert.AreEqual(sample.Key, cachedIds[key]);
}
}
var cachedIds = cache.RoutesCache.GetCachedIds();
Assert.AreEqual(0, cachedIds.Count);
}
// test hideTopLevelNodeFromPath false
[TestCase(1046, "/home/")]
@@ -147,10 +141,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));
@@ -173,14 +167,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));
}
}
@@ -0,0 +1,325 @@
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,11 +302,12 @@ 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(7, cachedIds.Count);
Assert.AreEqual(0, cachedIds.Count);
CheckRoute(cachedRoutes, cachedIds, 1001, "1001/");
CheckRoute(cachedRoutes, cachedIds, 10011, "10011/");
@@ -328,12 +329,11 @@ namespace Umbraco.Tests.Routing
Assert.AreEqual("http://domain1.com/fr/1001-2-1/", routingContext.UrlProvider.GetUrl(100121, new Uri("http://domain2.com"), false));
}
void CheckRoute(IDictionary<int, string> routes, IDictionary<string, int> ids, int id, string route)
private static 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.IsTrue(ids.ContainsKey(route));
Assert.AreEqual(id, ids[route]);
Assert.IsFalse(ids.ContainsKey(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>
]>
+126 -80
View File
@@ -35,18 +35,64 @@ namespace Umbraco.Tests.Services
[SetUp]
public override void Initialize()
{
base.Initialize();
base.Initialize();
}
[TearDown]
public override void TearDown()
{
base.TearDown();
}
[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()
{
@@ -104,7 +150,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);
@@ -121,7 +167,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
@@ -230,7 +276,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
@@ -265,7 +311,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());
@@ -395,7 +441,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) };
@@ -410,7 +456,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);
@@ -461,34 +507,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()
@@ -506,7 +552,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);
@@ -548,9 +594,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;
@@ -560,9 +606,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
@@ -575,7 +621,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()
{
@@ -595,12 +641,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"));
@@ -857,14 +903,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);
@@ -872,7 +918,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"));
}
}
@@ -889,7 +935,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");
@@ -899,7 +945,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())
@@ -1085,7 +1131,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
@@ -1116,7 +1162,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);
@@ -1146,7 +1192,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
@@ -1166,7 +1212,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);
@@ -1186,9 +1232,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));
}
@@ -1375,7 +1421,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
@@ -1418,14 +1464,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))
@@ -1443,9 +1489,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]
@@ -1468,20 +1514,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);
@@ -1496,7 +1542,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")));
@@ -1507,23 +1553,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()
@@ -1542,7 +1588,7 @@ namespace Umbraco.Tests.Services
}
contentService.Publish(content);
using (var uow = provider.GetUnitOfWork())
{
Assert.IsTrue(uow.Database.Exists<ContentXmlDto>(content.Id));
@@ -1559,10 +1605,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);
}
}
@@ -1665,11 +1711,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));
@@ -1680,12 +1726,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);
+6 -26
View File
@@ -53,41 +53,32 @@
<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">
<Reference Include="Moq, Version=4.1.1309.919, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
<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">
@@ -95,14 +86,12 @@
<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">
<Reference Include="Semver, Version=1.1.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\semver.1.1.2\lib\net45\Semver.dll</HintPath>
</Reference>
<Reference Include="System" />
@@ -111,17 +100,14 @@
<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" />
@@ -131,46 +117,39 @@
<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">
<Reference Include="WebDriver, Version=2.32.0.0, Culture=neutral, PublicKeyToken=1c2bd1631853048f, processorArchitecture=MSIL">
<HintPath>..\packages\Selenium.WebDriver.2.32.0\lib\net40\WebDriver.dll</HintPath>
</Reference>
</ItemGroup>
@@ -181,6 +160,7 @@
<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" />
@@ -612,9 +592,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,22 +69,6 @@
};
}
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,6 +172,55 @@ 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();
@@ -185,6 +234,9 @@ angular.module("umbraco.directives")
scope.onBlur();
}
unpinToolbar();
$('.umb-panel-body').off('scroll', pinToolbar);
});
});
@@ -196,6 +248,9 @@ angular.module("umbraco.directives")
scope.onFocus();
}
pinToolbar();
$('.umb-panel-body').on('scroll', pinToolbar);
});
});
@@ -207,6 +262,9 @@ 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
* Http errors. See /docs/source/using-promises-resources.md
* 500 Http server errors.
*
* @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 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>
<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>
@@ -178,8 +178,6 @@ 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, $sanitize) {
function ($rootScope, $scope, $log, assetsService, umbRequestHelper, angularHelper, $timeout, $element) {
var $typeahead;
@@ -41,7 +41,6 @@ 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);
+18 -12
View File
@@ -41,9 +41,9 @@
<TargetFrameworkProfile />
<UseIISExpress>true</UseIISExpress>
<IISExpressSSLPort>44319</IISExpressSSLPort>
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
<IISExpressAnonymousAuthentication>enabled</IISExpressAnonymousAuthentication>
<IISExpressWindowsAuthentication>disabled</IISExpressWindowsAuthentication>
<IISExpressUseClassicPipelineMode>false</IISExpressUseClassicPipelineMode>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
<MvcProjectUpgradeChecked>true</MvcProjectUpgradeChecked>
@@ -56,7 +56,7 @@
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
<ConfigurationOverrideFile>
</ConfigurationOverrideFile>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DefineConstants>TRACE;DEBUG</DefineConstants>
<DocumentationFile>
</DocumentationFile>
<DebugSymbols>true</DebugSymbols>
@@ -135,13 +135,11 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
<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 Include="ImageProcessor, Version=2.5.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ImageProcessor.2.5.1\lib\net45\ImageProcessor.dll</HintPath>
</Reference>
<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 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>
<Reference Include="log4net, Version=1.2.11.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@@ -168,6 +166,9 @@
<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>
@@ -651,6 +652,11 @@
<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>
@@ -2415,9 +2421,9 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\"
<WebProjectProperties>
<UseIIS>True</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>7550</DevelopmentServerPort>
<DevelopmentServerPort>7570</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:7550</IISUrl>
<IISUrl>http://localhost:7570</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
@@ -66,7 +66,7 @@
if(cfg != null)
foreach (JProperty property in cfg.Properties())
{
var propertyValue = TemplateUtilities.CleanForXss(property.Value.ToString());
var propertyValue = HttpUtility.HtmlAttributeEncode(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 = TemplateUtilities.CleanForXss(property.Value.ToString());
var propertyValue = property.Value.ToString();
if (string.IsNullOrWhiteSpace(propertyValue) == false)
{
cssVals.Add(property.Name + ":" + propertyValue + ";");
@@ -84,7 +84,7 @@
}
if (cssVals.Any())
attrs.Add("style='" + string.Join(" ", cssVals) + "'");
attrs.Add("style='" + HttpUtility.HtmlAttributeEncode(string.Join(" ", cssVals)) + "'");
}
return new MvcHtmlString(string.Join(" ", attrs));
@@ -66,7 +66,7 @@
if(cfg != null)
foreach (JProperty property in cfg.Properties())
{
var propertyValue = TemplateUtilities.CleanForXss(property.Value.ToString());
var propertyValue = HttpUtility.HtmlAttributeEncode(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 = TemplateUtilities.CleanForXss(property.Value.ToString());
var propertyValue = property.Value.ToString();
if (string.IsNullOrWhiteSpace(propertyValue) == false)
{
cssVals.Add(property.Name + ":" + propertyValue + ";");
@@ -84,7 +84,7 @@
}
if (cssVals.Any())
attrs.Add("style=\"" + string.Join(" ", cssVals) + "\"");
attrs.Add("style=\"" + HttpUtility.HtmlAttributeEncode(string.Join(" ", cssVals)) + "\"");
}
return new MvcHtmlString(string.Join(" ", attrs));
@@ -62,7 +62,7 @@
if(cfg != null)
foreach (JProperty property in cfg.Properties())
{
var propertyValue = TemplateUtilities.CleanForXss(property.Value.ToString());
var propertyValue = HttpUtility.HtmlAttributeEncode(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 = TemplateUtilities.CleanForXss(property.Value.ToString());
var propertyValue = property.Value.ToString();
if (string.IsNullOrWhiteSpace(propertyValue) == false)
{
cssVals.Add(property.Name + ":" + propertyValue + ";");
@@ -80,7 +80,7 @@
}
if (cssVals.Any())
attrs.Add("style='" + string.Join(" ", cssVals) + "'");
attrs.Add("style='" + HttpUtility.HtmlAttributeEncode(string.Join(" ", cssVals)) + "'");
}
return new MvcHtmlString(string.Join(" ", attrs));
@@ -66,17 +66,17 @@
if(cfg != null)
foreach (JProperty property in cfg.Properties())
{
var propertyValue = TemplateUtilities.CleanForXss(property.Value.ToString());
var propertyValue = HttpUtility.HtmlAttributeEncode(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 = TemplateUtilities.CleanForXss(property.Value.ToString());
var propertyValue = property.Value.ToString();
if (string.IsNullOrWhiteSpace(propertyValue) == false)
{
cssVals.Add(property.Name + ":" + propertyValue + ";");
@@ -84,7 +84,7 @@
}
if (cssVals.Any())
attrs.Add("style=\"" + string.Join(" ", cssVals) + "\"");
attrs.Add("style=\"" + HttpUtility.HtmlAttributeEncode(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(TemplateUtilities.CleanForXss(Model.value.ToString())));
markup = markup.Replace("#value#", umbracoHelper.ReplaceLineBreaksForHtml(HttpUtility.HtmlEncode(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/{machinename}/Internal/"/>
<IndexSet SetName="InternalIndexSet" IndexPath="~/App_Data/TEMP/ExamineIndexes/Internal/"/>
<!-- The internal index set used by Umbraco back-office for indexing members - DO NOT REMOVE -->
<IndexSet SetName="InternalMemberIndexSet" IndexPath="~/App_Data/TEMP/ExamineIndexes/{machinename}/InternalMember/">
<IndexSet SetName="InternalMemberIndexSet" IndexPath="~/App_Data/TEMP/ExamineIndexes/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/{machinename}/External/" />
<IndexSet SetName="ExternalIndexSet" IndexPath="~/App_Data/TEMP/ExamineIndexes/External/" />
</ExamineLuceneIndexSets>
@@ -12,18 +12,15 @@ 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"
useTempStorage="Sync"/>
analyzer="Lucene.Net.Analysis.WhitespaceAnalyzer, Lucene.Net"/>
<add name="InternalMemberIndexer" type="UmbracoExamine.UmbracoMemberIndexer, UmbracoExamine"
supportUnpublished="true"
supportProtected="true"
analyzer="Lucene.Net.Analysis.Standard.StandardAnalyzer, Lucene.Net"
useTempStorage="Sync"/>
analyzer="Lucene.Net.Analysis.Standard.StandardAnalyzer, Lucene.Net"/>
<!-- default external indexer, which excludes protected and unpublished pages-->
<add name="ExternalIndexer" type="UmbracoExamine.UmbracoContentIndexer, UmbracoExamine"
useTempStorage="Sync"/>
<add name="ExternalIndexer" type="UmbracoExamine.UmbracoContentIndexer, UmbracoExamine"/>
</providers>
</ExamineIndexProviders>
@@ -31,16 +28,13 @@ 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"
useTempStorage="Sync"/>
analyzer="Lucene.Net.Analysis.WhitespaceAnalyzer, Lucene.Net"/>
<add name="ExternalSearcher" type="UmbracoExamine.UmbracoExamineSearcher, UmbracoExamine"
useTempStorage="Sync"/>
<add name="ExternalSearcher" type="UmbracoExamine.UmbracoExamineSearcher, UmbracoExamine"/>
<add name="InternalMemberSearcher" type="UmbracoExamine.UmbracoExamineSearcher, UmbracoExamine"
analyzer="Lucene.Net.Analysis.Standard.StandardAnalyzer, Lucene.Net"
enableLeadingWildcard="true"
useTempStorage="Sync"/>
enableLeadingWildcard="true"/>
</providers>
</ExamineSearchProviders>
@@ -0,0 +1,10 @@
<?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>
@@ -0,0 +1,61 @@
<?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>
@@ -0,0 +1,24 @@
<?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, were 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, we're 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>
+4 -2
View File
@@ -5,8 +5,9 @@
<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.4.5.0" targetFramework="net45" />
<package id="ImageProcessor.Web" version="4.6.6.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="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" />
@@ -21,6 +22,7 @@
<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" />
+13 -2
View File
@@ -14,7 +14,13 @@
<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>
</configSections>
<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>
<umbracoConfiguration>
<settings configSource="config\umbracoSettings.config" />
@@ -119,7 +125,7 @@
<add verb="*" path="DependencyHandler.axd" type="ClientDependency.Core.CompositeFiles.CompositeDependencyHandler, ClientDependency.Core " />
</httpHandlers>
<compilation defaultLanguage="c#" debug="false" batch="false" targetFramework="4.5">
<compilation defaultLanguage="c#" debug="false" batch="false" targetFramework="4.5" numRecompilesBeforeAppRestart="50">
<assemblies>
<remove assembly="System.Web.Http" />
<remove assembly="System.Net.Http" />
@@ -434,4 +440,9 @@
</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,11 +30,20 @@ namespace Umbraco.Web.Controllers
//if there is a specified path to redirect to then use it
if (model.RedirectUrl.IsNullOrWhiteSpace() == false)
{
return Redirect(model.RedirectUrl);
// 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);
}
}
//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",
return _requestCacheProvider.GetCacheItem<ILanguage>(typeof (DefaultCultureDictionary).Name + "Culture" + Culture.Name,
() => _localizationService.GetLanguageByIsoCode(Culture.Name));
}
}
@@ -88,35 +88,37 @@ namespace Umbraco.Web.Editors
where TPersisted : IContentBase
{
//Map the property values
foreach (var p in contentItem.ContentDto.Properties)
foreach (var property in contentItem.ContentDto.Properties)
{
//get the dbo property
var dboProperty = contentItem.PersistedContent.Properties[p.Alias];
var dboProperty = contentItem.PersistedContent.Properties[property.Alias];
//create the property data to send to the property editor
var d = new Dictionary<string, object>();
var dictionary = new Dictionary<string, object>();
//add the files if any
var files = contentItem.UploadedFiles.Where(x => x.PropertyAlias == p.Alias).ToArray();
if (files.Length > 0)
{
d.Add("files", files);
}
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 data = new ContentPropertyData(p.Value, p.PreValues, d);
var data = new ContentPropertyData(property.Value, property.PreValues, dictionary);
//get the deserialized value from the property editor
if (p.PropertyEditor == null)
if (property.PropertyEditor == null)
{
LogHelper.Warn<ContentController>("No property editor found for property " + p.Alias);
LogHelper.Warn<ContentController>("No property editor found for property " + property.Alias);
}
else
{
var valueEditor = p.PropertyEditor.ValueEditor;
var valueEditor = property.PropertyEditor.ValueEditor;
//don't persist any bound value if the editor is readonly
if (valueEditor.IsReadOnly == false)
{
var propVal = p.PropertyEditor.ValueEditor.ConvertEditorToDb(data, dboProperty.Value);
var supportTagsAttribute = TagExtractor.GetAttribute(p.PropertyEditor);
var propVal = property.PropertyEditor.ValueEditor.ConvertEditorToDb(data, dboProperty.Value);
var supportTagsAttribute = TagExtractor.GetAttribute(property.PropertyEditor);
if (supportTagsAttribute != null)
{
TagExtractor.SetPropertyTags(dboProperty, data, propVal, supportTagsAttribute);
+2 -1
View File
@@ -525,7 +525,8 @@ namespace Umbraco.Web.Editors
foreach (var file in result.FileData)
{
var fileName = file.Headers.ContentDisposition.FileName.Trim(new[] { '\"' }).TrimEnd();
var ext = fileName.Substring(fileName.LastIndexOf('.') + 1).ToLower();
var safeFileName = fileName.ToSafeFileName();
var ext = safeFileName.Substring(safeFileName.LastIndexOf('.') + 1).ToLower();
if (UmbracoConfig.For.UmbracoSettings().Content.DisallowedUploadFiles.Contains(ext) == false)
{
@@ -49,6 +49,7 @@ namespace Umbraco.Web.Editors
return Services.ContentTypeService.CountContentTypes();
}
[UmbracoTreeAuthorize(Constants.Trees.MediaTypes, Constants.Trees.Media)]
public MediaTypeDisplay GetById(int id)
{
var ct = Services.ContentTypeService.GetMediaType(id);
+5 -5
View File
@@ -9,12 +9,12 @@ using Umbraco.Web.PublishedCache;
namespace Umbraco.Web
{
/// <summary>
/// Extension methods for Examine
/// </summary>
internal static class ExamineExtensions
/// <summary>
/// Extension methods for Examine
/// </summary>
public static class ExamineExtensions
{
internal static PublishedContentSet<IPublishedContent> ConvertSearchResultToPublishedContent(this IEnumerable<SearchResult> results,
public 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("http://umbraco.org/base/Ecom/SubmitEmail/installer.aspx", values);
client.UploadValues("https://umbraco.com/base/Ecom/SubmitEmail/installer.aspx", values);
}
catch { /* fail in silence */ }
}
@@ -1,8 +1,10 @@
using System.Text;
using System;
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;
@@ -27,10 +29,13 @@ 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=" + url);
fullUrl.Append("?url=" + HttpUtility.UrlEncode(url));
foreach (var p in RequestParams)
fullUrl.Append(string.Format("&{0}={1}", p.Key, p.Value));
+2 -4
View File
@@ -46,9 +46,7 @@ namespace Umbraco.Web.Models
{
var route = umbracoContext == null
? null // for tests only
: umbracoContext.ContentCache.GetRouteById(contentId); // cached
if (route != null && route.StartsWith("err/")) route = null;
: umbracoContext.ContentCache.GetRouteById(contentId); // may be cached
var domainHelper = new DomainHelper(domainService);
IDomain domain;
@@ -73,7 +71,7 @@ namespace Umbraco.Web.Models
}
else
{
// if content is published then we have a (cached) route
// if content is published then we have a 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<ContentPropertyDisplay>();
var properties = new List<Property>();
// merge properties for groups with the same name
foreach (var group in groupsByName)
@@ -237,13 +237,16 @@ namespace Umbraco.Web.Models.Mapping
var groupProperties = content.GetPropertiesForGroup(group)
.Where(x => IgnoreProperties.Contains(x.Alias) == false); // skip ignored
properties.AddRange(Mapper.Map<IEnumerable<Property>, IEnumerable<ContentPropertyDisplay>>(groupProperties));
properties.AddRange(groupProperties);
}
if (properties.Count == 0)
continue;
TranslateProperties(properties);
// 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);
// add the tab
// we need to pick an identifier... there is no "right" way...
@@ -256,7 +259,7 @@ namespace Umbraco.Web.Models.Mapping
Id = groupId,
Alias = groupName,
Label = _localizedTextService.UmbracoDictionaryTranslate(groupName),
Properties = properties,
Properties = mappedProperties,
IsActive = false
});
}
@@ -1,7 +1,6 @@
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;
@@ -61,14 +60,7 @@ 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>()).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);
return json == null ? null : json.Select(x => x.Value<string>());
}
/// <summary>
@@ -2,11 +2,9 @@ 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;
@@ -18,7 +16,6 @@ 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
{
@@ -83,7 +80,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);
_routesCache.Store(content.Id, route, true); // trusted route
}
public virtual string GetRouteById(UmbracoContext umbracoContext, bool preview, int contentId)
@@ -102,38 +99,13 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
if (route == null)
return null;
// 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?
// 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);
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);
return route;
}
IPublishedContent DetermineIdByRoute(UmbracoContext umbracoContext, bool preview, string route, bool hideTopLevelNode)
@@ -149,18 +121,25 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
//check if we can find the node in our xml cache
var id = NavigateRoute(umbracoContext, preview, startNodeId, path, hideTopLevelNode);
if (id > 0) return GetById(umbracoContext, preview, id);
return id > 0 ? GetById(umbracoContext, preview, id) : null;
}
// 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)
private static XmlElement GetXmlElementChildWithLowestSortOrder(XmlNode element)
{
XmlElement elt = null;
var min = int.MaxValue;
foreach (var n in element.ChildNodes)
{
var id2 = NavigateRoute(umbracoContext, preview, startNodeId, path, false);
if (id2 > 0) return GetById(umbracoContext, preview, id2);
}
var e = n as XmlElement;
if (e == null) continue;
return null;
var sortOrder = int.Parse(e.GetAttribute("sortOrder"));
if (sortOrder >= min) continue;
min = sortOrder;
elt = e;
}
return elt;
}
private int NavigateRoute(UmbracoContext umbracoContext, bool preview, int startNodeId, string path, bool hideTopLevelNode)
@@ -177,17 +156,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
return elt == null ? -1 : startNodeId;
}
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;
}
}
elt = GetXmlElementChildWithLowestSortOrder(xml.DocumentElement);
return elt == null ? -1 : int.Parse(elt.GetAttribute("id"));
}
@@ -201,12 +170,19 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
if (hideTopLevelNode && startNodeId <= 0)
{
foreach (var e in elt.ChildNodes.OfType<XmlElement>())
//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)
{
var e = n as XmlElement;
if (e == null) continue;
var id = NavigateElementRoute(e, urlParts);
if (id > 0) return id;
}
return -1;
if (urlParts.Length > 1)
return -1;
}
return NavigateElementRoute(elt, urlParts);
@@ -224,8 +200,14 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
while (found && i < urlParts.Length)
{
found = false;
foreach (var child in elt.ChildNodes.OfType<XmlElement>())
//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)
{
var child = o as XmlElement;
if (child == null) continue;
var noNode = UseLegacySchema
? child.Name != "node"
: child.GetAttributeNode("isDoc") == null;
@@ -233,8 +215,12 @@ 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++;
}
@@ -243,7 +229,8 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
string DetermineRouteById(UmbracoContext umbracoContext, bool preview, int contentId)
{
var elt = GetXml(umbracoContext, preview).GetElementById(contentId.ToString(CultureInfo.InvariantCulture));
var xml = GetXml(umbracoContext, preview);
var elt = xml.GetElementById(contentId.ToString(CultureInfo.InvariantCulture));
if (elt == null) return null;
var domainHelper = GetDomainHelper(umbracoContext.Application.Services.DomainService);
@@ -270,7 +257,18 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
// no domain, respect HideTopLevelNodeFromPath for legacy purposes
if (hasDomains == false && GlobalSettings.HideTopLevelNodeFromPath)
ApplyHideTopLevelNodeFromPath(umbracoContext, eltId, eltParentId, pathParts);
{
if (eltParentId == -1)
{
var rootNode = GetXmlElementChildWithLowestSortOrder(xml.DocumentElement);
if (rootNode != null && rootNode == elt)
pathParts.RemoveAt(pathParts.Count - 1);
}
else
{
pathParts.RemoveAt(pathParts.Count - 1);
}
}
// assemble the route
pathParts.Reverse();
@@ -280,30 +278,6 @@ 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,10 +83,12 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
/// </summary>
/// <param name="nodeId">The node identified.</param>
/// <param name="route">The route.</param>
public void Store(int nodeId, string route)
/// <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)
{
_routes.AddOrUpdate(nodeId, i => route, (i, s) => route);
_nodeIds.AddOrUpdate(route, i => nodeId, (i, s) => nodeId);
if (trust)
_nodeIds.AddOrUpdate(route, i => nodeId, (i, s) => nodeId);
}
/// <summary>
@@ -119,15 +121,12 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
/// <param name="nodeId">The node identifier.</param>
public void ClearNode(int nodeId)
{
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);
string route;
if (_routes.TryRemove(nodeId, out route))
{
int id;
_nodeIds.TryRemove(route, out id);
}
}
/// <summary>
@@ -65,14 +65,6 @@ 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
@@ -115,9 +107,6 @@ 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,6 +67,32 @@ 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,8 +295,7 @@ namespace Umbraco.Web.Routing
private static bool IsNotRoute(string route)
{
// null if content not found
// err/- if collision or anomaly or ...
return route == null || route.StartsWith("err/");
return route == null;
}
// gets a value indicating whether server is 'slave'
@@ -1,7 +1,10 @@
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
@@ -62,34 +65,45 @@ namespace Umbraco.Web.Routing
{
urls.Add(ui.Text("content", "getUrlException", umbracoContext.Security.CurrentUser));
}
else if (url.StartsWith("#err-"))
else
{
// route error, report
var id = int.Parse(url.Substring(5));
var o = umbracoContext.ContentCache.GetById(id);
string s;
if (o == null)
// 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)
{
s = "(unknown)";
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));
}
else
{
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(url);
urls.AddRange(urlProvider.GetOtherUrls(content.Id));
}
urls.Add(ui.Text("content", "routeError", s, umbracoContext.Security.CurrentUser));
}
else
{
urls.Add(url);
urls.AddRange(urlProvider.GetOtherUrls(content.Id));
}
return urls;
}
+2 -1
View File
@@ -428,7 +428,8 @@ 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)))
.Where(x => builtIns.Contains(x.Alias) == false && memberType.MemberCanEditProperty(x.Alias))
.OrderBy(p => p.SortOrder))
{
var value = string.Empty;
if (member != null)
+3 -43
View File
@@ -99,92 +99,70 @@
</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">
<Reference Include="dotless.Core, Version=1.4.1.0, Culture=neutral, PublicKeyToken=96b446c9e63eae34, processorArchitecture=MSIL">
<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">
@@ -204,7 +182,6 @@
<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" />
@@ -220,43 +197,30 @@
<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">
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<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">
@@ -299,8 +263,6 @@
</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>
@@ -1996,6 +1958,7 @@
<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>
@@ -2090,9 +2053,6 @@
</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,7 +44,17 @@ namespace Umbraco.Web.WebServices
}
catch (Exception ee)
{
LogHelper.Error<ScheduledPublishController>("Error executing scheduled task", 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);
Response.StatusCode = 400;
+6 -1
View File
@@ -162,7 +162,12 @@ namespace UmbracoExamine
base.Initialize(name, config);
if (config["useTempStorage"] != null)
//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)
{
var fsDir = base.GetLuceneDirectory() as FSDirectory;
if (fsDir != null)
@@ -1,5 +1,6 @@
using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.IO;
using System.Web;
using Umbraco.Core;
@@ -9,6 +10,8 @@ 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,4 +1,6 @@
using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.IO;
using System.Web;
@@ -11,6 +13,8 @@ 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)
+37 -11
View File
@@ -32,6 +32,7 @@ namespace UmbracoExamine
private readonly IDataTypeService _dataTypeService;
private readonly IUserService _userService;
private readonly IContentTypeService _contentTypeService;
private readonly EntityXmlSerializer _serializer = new EntityXmlSerializer();
#region Constructors
@@ -145,9 +146,7 @@ namespace UmbracoExamine
#endregion
#region Constants & Fields
#region Constants & Fields
/// <summary>
/// Used to store the path of a content object
@@ -365,7 +364,7 @@ namespace UmbracoExamine
/// <summary>
/// This is a static query, it's parameters don't change so store statically
/// </summary>
private static readonly IQuery<IContent> PublishedQuery = Query<IContent>.Builder.Where(x => x.Published == true);
private IQuery<IContent> _publishedQuery;
protected override void PerformIndexAll(string type)
{
@@ -382,6 +381,9 @@ 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;
@@ -393,8 +395,14 @@ namespace UmbracoExamine
}
else
{
//add the published filter
descendants = _contentService.GetPagedDescendants(contentParentId, pageIndex, pageSize, out total, "Path", Direction.Ascending, true, PublishedQuery);
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);
}
//if specific types are declared we need to post filter them
@@ -407,10 +415,12 @@ namespace UmbracoExamine
{
content = descendants.ToArray();
}
AddNodesToIndex(GetSerializedContent(content), type);
AddNodesToIndex(GetSerializedContent(content, notPublished).WhereNotNull(), type);
pageIndex++;
} while (content.Length == pageSize);
notPublished.Clear();
break;
case IndexTypes.Media:
var mediaParentId = -1;
@@ -463,12 +473,28 @@ namespace UmbracoExamine
}
}
private IEnumerable<XElement> GetSerializedContent(IEnumerable<IContent> content)
{
var serializer = new EntityXmlSerializer();
private IEnumerable<XElement> GetSerializedContent(IEnumerable<IContent> content, ISet<string> notPublished)
{
foreach (var c in content)
{
var xml = serializer.Serialize(
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(
_contentService,
_dataTypeService,
_userService,
-3
View File
@@ -84,14 +84,11 @@
<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" />
+6 -1
View File
@@ -73,7 +73,12 @@ namespace UmbracoExamine
base.Initialize(name, config);
if (config != null && config["useTempStorage"] != null)
//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)
{
//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,22 +47,17 @@
<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">
@@ -75,42 +70,33 @@
<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" />
@@ -219,10 +205,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="net4" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
</packages>
@@ -108,21 +108,17 @@
<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">
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
</Reference>
<Reference Include="System" />
@@ -142,27 +138,21 @@
</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,14 +108,11 @@
<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" />
@@ -168,7 +165,6 @@
</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,7 +70,6 @@
<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="net4" />
<package id="Microsoft.ApplicationBlocks.Data" version="1.0.1559.20655" targetFramework="net4" />
<package id="log4net-mediumtrust" version="2.0.0" targetFramework="net45" />
<package id="Microsoft.ApplicationBlocks.Data" version="1.0.1559.20655" targetFramework="net45" />
<package id="MySql.Data" version="6.9.8" targetFramework="net45" />
</packages>
@@ -69,15 +69,12 @@
</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">
<SpecificVersion>False</SpecificVersion>
<Reference Include="MySql.Data, Version=6.9.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
<HintPath>..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll</HintPath>
</Reference>
<Reference Include="System" />
@@ -116,7 +116,6 @@
</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>