Compare commits
145 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4935525591 | |||
| 693778fe74 | |||
| 8eee7cae2f | |||
| 226e35d65a | |||
| cdda69c4cd | |||
| 0cff484113 | |||
| 830fde372e | |||
| 35f65a2c64 | |||
| e5320f0abd | |||
| 965a7fc500 | |||
| abbf8aeb42 | |||
| 328ada2f38 | |||
| 767252cdf1 | |||
| 010d47c68b | |||
| a353f6fb74 | |||
| a64efb93b3 | |||
| cf9f11ff45 | |||
| d7481b5ca4 | |||
| 2fb55cb831 | |||
| 0e6a926a3f | |||
| 173ac65eb5 | |||
| 7c28e1aeba | |||
| 5989d19f7f | |||
| da1c33a034 | |||
| 2111a5e31e | |||
| 5478de911b | |||
| 7765acb130 | |||
| 5640daff32 | |||
| a1cae3f286 | |||
| d22dbb4654 | |||
| 4d5a8298b0 | |||
| 9e2733ce69 | |||
| fbfdd8d398 | |||
| 2552dffdad | |||
| 52540165f1 | |||
| 2b408df24c | |||
| d559411187 | |||
| 3a4a6579d3 | |||
| 1e76cf67d3 | |||
| 61149f8112 | |||
| adb059e0da | |||
| 4337976887 | |||
| efe5de87a6 | |||
| 389642946e | |||
| 53d30aa3cb | |||
| e233cffb9d | |||
| 9e58ebed24 | |||
| f51c4e332e | |||
| 03a0a0a0e9 | |||
| dcb381770f | |||
| 65db0e69a9 | |||
| 23c6a91e9c | |||
| a03c6dcf13 | |||
| 3029d97f33 | |||
| f41d967864 | |||
| 4a481b05d4 | |||
| 66c6b5b524 | |||
| e3b0f71549 | |||
| 973b466798 | |||
| fa0eef4333 | |||
| a343a76a26 | |||
| d0a9e3236e | |||
| b899805ec9 | |||
| 766497e355 | |||
| 67a2a9cfe4 | |||
| 766ba0c8f5 | |||
| ca71c59880 | |||
| 6c87cf729a | |||
| 5c63afa31a | |||
| fa88768c91 | |||
| bfabfd9fa5 | |||
| aa1c411c8c | |||
| c52c452b36 | |||
| 86811fe507 | |||
| 363de53b82 | |||
| 958fb66f2c | |||
| 30e12c1367 | |||
| 89ff7d85e2 | |||
| 61fbf2cfc6 | |||
| ce847e97a8 | |||
| 1e61563f79 | |||
| b4f9985695 | |||
| 82f19ede8c | |||
| 0fbc32a87f | |||
| dc2de4b5e7 | |||
| 5fce741940 | |||
| 14e4a8061c | |||
| 1b9f071581 | |||
| 79141ef86d | |||
| 08609a887c | |||
| b11932240c | |||
| d47b4517c1 | |||
| 226a13c6e1 | |||
| d78a03a610 | |||
| b7a1123319 | |||
| 7e9cad34db | |||
| c4b44ea0e3 | |||
| 3435a75e9e | |||
| bdb6c5768a | |||
| 87a3c53e22 | |||
| 898d25f3cb | |||
| 9bc3fdd555 | |||
| cbda86fe92 | |||
| b48f0f52e0 | |||
| e2eeafcbfc | |||
| ad697db42b | |||
| 9bb31e9456 | |||
| a195d33332 | |||
| 82a87cbd92 | |||
| 5b26436862 | |||
| eed61f9053 | |||
| 55c68485e9 | |||
| b9ba350a2f | |||
| 696306e7c9 | |||
| 9bf86aff09 | |||
| f50de5b049 | |||
| d734ba6136 | |||
| c49becea53 | |||
| 614aea203d | |||
| ed88bbf75f | |||
| e41d3c7e84 | |||
| b5494546c7 | |||
| 7bac1ef1cd | |||
| da15d40b04 | |||
| 67bd303173 | |||
| 20e6843bf0 | |||
| 85c80b07f9 | |||
| 557dccd88b | |||
| 334f0bfd2b | |||
| 986d37afd6 | |||
| 63ea79a4d6 | |||
| e4df176a37 | |||
| d926180e3a | |||
| 72bb1b3583 | |||
| 240e58e061 | |||
| e980296d6d | |||
| d23482b7a6 | |||
| 212800f706 | |||
| d47ff4005c | |||
| dfeb1c7a0b | |||
| 9a3c2bbc5c | |||
| 0b0fb92cf1 | |||
| 6f09da0927 | |||
| febe6ec241 | |||
| 6f85eefd85 |
@@ -79,3 +79,8 @@ src/Umbraco.Web.UI.Client/[Bb]uild/[Bb]elle/
|
||||
src/Umbraco.Web.UI/[Uu]ser[Cc]ontrols/
|
||||
build/_BuildOutput/
|
||||
tools/NDepend/
|
||||
src/*.vspx
|
||||
src/*.psess
|
||||
NDependOut/*
|
||||
QueryResult.htm
|
||||
*.ndproj
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
@ECHO OFF
|
||||
SET release=6.1.3
|
||||
SET release=6.1.6
|
||||
SET comment=
|
||||
SET version=%release%
|
||||
|
||||
|
||||
+12
-1
@@ -228,7 +228,7 @@
|
||||
</Target>
|
||||
|
||||
<!-- Copy the xml documentation to the bin folder -->
|
||||
<Target Name="CopyXmlDocumentation" DependsOnTargets="CompileProjects">
|
||||
<Target Name="CopyXmlDocumentation" DependsOnTargets="CleanupPresentation">
|
||||
<ItemGroup>
|
||||
<XmlDocumentationFiles Include="$(SolutionBinFolder)*.xml" />
|
||||
</ItemGroup>
|
||||
@@ -240,6 +240,17 @@
|
||||
<Message Text="CopyXmlDocumentation" />
|
||||
</Target>
|
||||
|
||||
<!-- Unlike 2010, the VS2012 build targets file doesn't clean up the umbraco.presentation dir, do it manually -->
|
||||
<!-- Also, it places umbraco.XmlSerializers.dll in the root, even though it's also in the bin folder. Kill! -->
|
||||
<Target Name="CleanupPresentation" DependsOnTargets="CompileProjects">
|
||||
<ItemGroup>
|
||||
<PresentationFolderToDelete Include="$(WebAppFolder)umbraco.presentation" />
|
||||
<XmlSerializersDll Include="$(WebAppFolder)umbraco.XmlSerializers.dll" />
|
||||
</ItemGroup>
|
||||
<RemoveDir Directories="@(PresentationFolderToDelete)" />
|
||||
<Delete Files="@(XmlSerializersDll)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CompileProjects" DependsOnTargets="CompileExternalExamineProjects">
|
||||
|
||||
<Message Text="Compiling web project to build\$(BuildFolder)" Importance="high" />
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-16"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>UmbracoCms.Core</id>
|
||||
<version>6.1.2</version>
|
||||
<version>6.2.0</version>
|
||||
<title>Umbraco Cms Core Binaries</title>
|
||||
<authors>Morten Christensen</authors>
|
||||
<owners>Umbraco HQ</owners>
|
||||
@@ -14,57 +14,57 @@
|
||||
<summary>Contains the core assemblies needed to run Umbraco Cms</summary>
|
||||
<language>en-US</language>
|
||||
<tags>umbraco</tags>
|
||||
<dependencies>
|
||||
<dependencies>
|
||||
<dependency id="Microsoft.AspNet.Mvc" version="4.0" />
|
||||
<dependency id="Microsoft.AspNet.WebApi" version="4.0" />
|
||||
<dependency id="Microsoft.AspNet.Mvc.FixedDisplayModes" version="1.0.0" />
|
||||
<dependency id="MiniProfiler" version="2.1.0" />
|
||||
<dependency id="HtmlAgilityPack" version="1.4.6" />
|
||||
<dependency id="Lucene.Net" version="[2.9.4.1]" />
|
||||
<dependency id="SharpZipLib" version="0.86.0" />
|
||||
<dependency id="MySql.Data" version="[6.6.5]" />
|
||||
<dependency id="xmlrpcnet" version="2.5.0" />
|
||||
<dependency id="ClientDependency" version="[1.7.0,1.7.1)" />
|
||||
<dependency id="ClientDependency-Mvc" version="[1.7.0,1.7.1)" />
|
||||
<dependency id="Microsoft.AspNet.WebApi" version="4.0" />
|
||||
<dependency id="Microsoft.AspNet.Mvc.FixedDisplayModes" version="1.0.0" />
|
||||
<dependency id="MiniProfiler" version="[2.1.0, 3.0.0)" />
|
||||
<dependency id="HtmlAgilityPack" version="[1.4.6, 2.0.0)" />
|
||||
<dependency id="Lucene.Net" version="[2.9.4.1, 3.0.0.0)" />
|
||||
<dependency id="SharpZipLib" version="[0.86.0, 1.0.0)" />
|
||||
<dependency id="MySql.Data" version="[6.6.5]" />
|
||||
<dependency id="xmlrpcnet" version="[2.5.0, 3.0.0)" />
|
||||
<dependency id="ClientDependency" version="[1.7.0, 2.0.0)" />
|
||||
<dependency id="ClientDependency-Mvc" version="[1.7.0, 2.0.0)" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="..\_BuildOutput\WebApp\bin\businesslogic.dll" target="lib\businesslogic.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\businesslogic.xml" target="lib\businesslogic.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\cms.dll" target="lib\cms.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\cms.xml" target="lib\cms.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\controls.dll" target="lib\controls.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\controls.xml" target="lib\controls.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Examine.dll" target="lib\Examine.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\interfaces.dll" target="lib\interfaces.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\interfaces.xml" target="lib\interfaces.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\log4net.dll" target="lib\log4net.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Microsoft.ApplicationBlocks.Data.dll" target="lib\Microsoft.ApplicationBlocks.Data.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Microsoft.Web.Helpers.dll" target="lib\Microsoft.Web.Helpers.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Our.Umbraco.uGoLive.47x.dll" target="lib\Our.Umbraco.uGoLive.47x.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Our.Umbraco.uGoLive.Checks.dll" target="lib\Our.Umbraco.uGoLive.Checks.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Our.Umbraco.uGoLive.dll" target="lib\Our.Umbraco.uGoLive.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\SQLCE4Umbraco.dll" target="lib\SQLCE4Umbraco.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\System.Data.SqlServerCe.dll" target="lib\System.Data.SqlServerCe.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\System.Data.SqlServerCe.Entity.dll" target="lib\System.Data.SqlServerCe.Entity.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\TidyNet.dll" target="lib\TidyNet.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Core.dll" target="lib\Umbraco.Core.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Core.xml" target="lib\Umbraco.Core.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.DataLayer.dll" target="lib\umbraco.DataLayer.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.DataLayer.xml" target="lib\umbraco.DataLayer.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.dll" target="lib\umbraco.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.xml" target="lib\umbraco.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.editorControls.dll" target="lib\umbraco.editorControls.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.editorControls.xml" target="lib\umbraco.editorControls.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.MacroEngines.dll" target="lib\umbraco.MacroEngines.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.MacroEngines.xml" target="lib\umbraco.MacroEngines.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.macroRenderings.dll" target="lib\umbraco.macroRenderings.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.macroRenderings.xml" target="lib\umbraco.macroRenderings.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.dll" target="lib\umbraco.providers.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.xml" target="lib\umbraco.providers.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Web.UI.dll" target="lib\Umbraco.Web.UI.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.XmlSerializers.dll" target="lib\umbraco.XmlSerializers.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.dll" target="lib\UmbracoExamine.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\UrlRewritingNet.UrlRewriter.dll" target="lib\UrlRewritingNet.UrlRewriter.dll" />
|
||||
</files>
|
||||
<files>
|
||||
<file src="..\_BuildOutput\WebApp\bin\businesslogic.dll" target="lib\businesslogic.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\businesslogic.xml" target="lib\businesslogic.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\cms.dll" target="lib\cms.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\cms.xml" target="lib\cms.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\controls.dll" target="lib\controls.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\controls.xml" target="lib\controls.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Examine.dll" target="lib\Examine.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\interfaces.dll" target="lib\interfaces.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\interfaces.xml" target="lib\interfaces.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\log4net.dll" target="lib\log4net.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Microsoft.ApplicationBlocks.Data.dll" target="lib\Microsoft.ApplicationBlocks.Data.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Microsoft.Web.Helpers.dll" target="lib\Microsoft.Web.Helpers.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Our.Umbraco.uGoLive.47x.dll" target="lib\Our.Umbraco.uGoLive.47x.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Our.Umbraco.uGoLive.Checks.dll" target="lib\Our.Umbraco.uGoLive.Checks.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Our.Umbraco.uGoLive.dll" target="lib\Our.Umbraco.uGoLive.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\SQLCE4Umbraco.dll" target="lib\SQLCE4Umbraco.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\System.Data.SqlServerCe.dll" target="lib\System.Data.SqlServerCe.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\System.Data.SqlServerCe.Entity.dll" target="lib\System.Data.SqlServerCe.Entity.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\TidyNet.dll" target="lib\TidyNet.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Core.dll" target="lib\Umbraco.Core.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Core.xml" target="lib\Umbraco.Core.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.DataLayer.dll" target="lib\umbraco.DataLayer.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.DataLayer.xml" target="lib\umbraco.DataLayer.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.dll" target="lib\umbraco.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.xml" target="lib\umbraco.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.editorControls.dll" target="lib\umbraco.editorControls.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.editorControls.xml" target="lib\umbraco.editorControls.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.MacroEngines.dll" target="lib\umbraco.MacroEngines.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.MacroEngines.xml" target="lib\umbraco.MacroEngines.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.macroRenderings.dll" target="lib\umbraco.macroRenderings.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.macroRenderings.xml" target="lib\umbraco.macroRenderings.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.dll" target="lib\umbraco.providers.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.xml" target="lib\umbraco.providers.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Web.UI.dll" target="lib\Umbraco.Web.UI.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.XmlSerializers.dll" target="lib\umbraco.XmlSerializers.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.dll" target="lib\UmbracoExamine.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\UrlRewritingNet.UrlRewriter.dll" target="lib\UrlRewritingNet.UrlRewriter.dll" />
|
||||
</files>
|
||||
</package>
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-16"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>UmbracoCms</id>
|
||||
|
||||
@@ -7,10 +7,11 @@ The config files found in the config folder will usually not be changed for patc
|
||||
but the web.config will have to have its previous "umbracoConfigurationStatus"-appsetting and "umbracoDbDSN" connection string
|
||||
copied over (as a minimum).
|
||||
|
||||
It's not possible to create a deploy package from Visual Studio, which contains everything out of the box. This is
|
||||
due to a number of files and folders that are not added to the Visual Studio project. These folders include:
|
||||
install, umbraco and umbraco_client.
|
||||
A custom deploy script will be added in a later release.
|
||||
This nuget package includes build targets that extends the creation of a deploy package, which is generated by
|
||||
Publishing from Visual Studio. The targets will only work once Publishing is configured, so if you don't use
|
||||
Publish this won't affect you.
|
||||
These folders will now be automatically included when creating a deploy package or publishing to the file system:
|
||||
umbraco and umbraco_client.
|
||||
|
||||
Please read the release notes on our.umbraco.org:
|
||||
http://our.umbraco.org/contribute/releases
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Web;
|
||||
using System.Web.Caching;
|
||||
using System.Web.Security;
|
||||
using System.Xml;
|
||||
using System.Configuration;
|
||||
|
||||
@@ -299,6 +300,32 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
}
|
||||
|
||||
internal static string AuthCookieName
|
||||
{
|
||||
get
|
||||
{
|
||||
var value = GetKey("/settings/security/authCookieName");
|
||||
if (string.IsNullOrEmpty(value) == false)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
return "UMB_UCONTEXT";
|
||||
}
|
||||
}
|
||||
|
||||
internal static string AuthCookieDomain
|
||||
{
|
||||
get
|
||||
{
|
||||
var value = GetKey("/settings/security/authCookieDomain");
|
||||
if (string.IsNullOrEmpty(value) == false)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
return FormsAuthentication.CookieDomain;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables the experimental canvas (live) editing on the frontend of the website
|
||||
/// </summary>
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
public class UmbracoVersion
|
||||
{
|
||||
private static readonly Version Version = new Version("6.1.3");
|
||||
private static readonly Version Version = new Version("6.1.6");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current version of Umbraco.
|
||||
|
||||
@@ -112,7 +112,7 @@ namespace Umbraco.Core
|
||||
public void ConfigureEmbeddedDatabaseConnection()
|
||||
{
|
||||
const string providerName = "System.Data.SqlServerCe.4.0";
|
||||
const string connectionString = @"Data Source=|DataDirectory|\Umbraco.sdf";
|
||||
const string connectionString = @"Data Source=|DataDirectory|\Umbraco.sdf;Flush Interval=1;";
|
||||
|
||||
SaveConnectionString(connectionString, providerName);
|
||||
|
||||
@@ -296,16 +296,15 @@ namespace Umbraco.Core
|
||||
if (databaseSettings != null && string.IsNullOrWhiteSpace(databaseSettings.ConnectionString) == false && string.IsNullOrWhiteSpace(databaseSettings.ProviderName) == false)
|
||||
{
|
||||
var providerName = "System.Data.SqlClient";
|
||||
string connString = null;
|
||||
if (!string.IsNullOrEmpty(ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName].ProviderName))
|
||||
{
|
||||
providerName = ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName].ProviderName;
|
||||
|
||||
_connectionString =
|
||||
ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName].ConnectionString;
|
||||
|
||||
connString = ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName].ConnectionString;
|
||||
}
|
||||
Initialize(providerName, connString);
|
||||
|
||||
Initialize(providerName);
|
||||
DetermineSqlServerVersion();
|
||||
}
|
||||
else if (ConfigurationManager.AppSettings.ContainsKey(GlobalSettings.UmbracoConnectionName) && string.IsNullOrEmpty(ConfigurationManager.AppSettings[GlobalSettings.UmbracoConnectionName]) == false)
|
||||
{
|
||||
@@ -342,6 +341,8 @@ namespace Umbraco.Core
|
||||
|
||||
//Remove the legacy connection string, so we don't end up in a loop if something goes wrong.
|
||||
GlobalSettings.RemoveSetting(GlobalSettings.UmbracoConnectionName);
|
||||
|
||||
DetermineSqlServerVersion();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -369,6 +370,55 @@ namespace Umbraco.Core
|
||||
}
|
||||
}
|
||||
|
||||
internal void Initialize(string providerName, string connectionString)
|
||||
{
|
||||
_connectionString = connectionString;
|
||||
Initialize(providerName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the lazy resolution of determining the SQL server version if that is the db type we're using
|
||||
/// </summary>
|
||||
private void DetermineSqlServerVersion()
|
||||
{
|
||||
|
||||
var sqlServerSyntax = SqlSyntaxContext.SqlSyntaxProvider as SqlServerSyntaxProvider;
|
||||
if (sqlServerSyntax != null)
|
||||
{
|
||||
//this will not execute now, it is lazy so will only execute when we need to actually know
|
||||
// the sql server version.
|
||||
sqlServerSyntax.VersionName = new Lazy<SqlServerVersionName>(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var database = this._factory.CreateDatabase();
|
||||
|
||||
var version = database.ExecuteScalar<string>("SELECT SERVERPROPERTY('productversion')");
|
||||
var firstPart = version.Split('.')[0];
|
||||
switch (firstPart)
|
||||
{
|
||||
case "11":
|
||||
return SqlServerVersionName.V2012;
|
||||
case "10":
|
||||
return SqlServerVersionName.V2008;
|
||||
case "9":
|
||||
return SqlServerVersionName.V2005;
|
||||
case "8":
|
||||
return SqlServerVersionName.V2000;
|
||||
case "7":
|
||||
return SqlServerVersionName.V7;
|
||||
default:
|
||||
return SqlServerVersionName.Other;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return SqlServerVersionName.Invalid;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
internal DatabaseSchemaResult ValidateDatabaseSchema()
|
||||
{
|
||||
if (_configured == false || (string.IsNullOrEmpty(_connectionString) || string.IsNullOrEmpty(ProviderName)))
|
||||
@@ -460,6 +510,8 @@ namespace Umbraco.Core
|
||||
message = message + "<p>Upgrade completed!</p>";
|
||||
}
|
||||
|
||||
//now that everything is done, we need to determine the version of SQL server that is executing
|
||||
|
||||
LogHelper.Info<DatabaseContext>("Database configuration status: " + message);
|
||||
|
||||
return new Result { Message = message, Success = true, Percentage = "100" };
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Events
|
||||
{
|
||||
public class RecycleBinEventArgs : CancellableEventArgs
|
||||
{
|
||||
public RecycleBinEventArgs(Guid nodeObjectType, IEnumerable<int> ids, List<string> files, bool emptiedSuccessfully)
|
||||
: base(false)
|
||||
{
|
||||
NodeObjectType = nodeObjectType;
|
||||
Ids = ids;
|
||||
Files = files;
|
||||
RecycleBinEmptiedSuccessfully = emptiedSuccessfully;
|
||||
}
|
||||
|
||||
public RecycleBinEventArgs(Guid nodeObjectType, IEnumerable<int> ids, List<string> files)
|
||||
: base(true)
|
||||
{
|
||||
NodeObjectType = nodeObjectType;
|
||||
Ids = ids;
|
||||
Files = files;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Id of the node object type of the items
|
||||
/// being deleted from the Recycle Bin.
|
||||
/// </summary>
|
||||
public Guid NodeObjectType { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of Ids for each of the items being deleted from the Recycle Bin.
|
||||
/// </summary>
|
||||
public IEnumerable<int> Ids { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of Files that should be deleted as part
|
||||
/// of emptying the Recycle Bin.
|
||||
/// </summary>
|
||||
public List<string> Files { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Boolean indicating whether the Recycle Bin was emptied successfully
|
||||
/// </summary>
|
||||
public bool RecycleBinEmptiedSuccessfully { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Boolean indicating whether this event was fired for the Content's Recycle Bin.
|
||||
/// </summary>
|
||||
public bool IsContentRecycleBin
|
||||
{
|
||||
get { return NodeObjectType == new Guid(Constants.ObjectTypes.Document); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Boolean indicating whether this event was fired for the Media's Recycle Bin.
|
||||
/// </summary>
|
||||
public bool IsMediaRecycleBin
|
||||
{
|
||||
get { return NodeObjectType == new Guid(Constants.ObjectTypes.Media); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Any class implementing this interface that is added to the httpcontext.items keys or values will be disposed of at the end of the request.
|
||||
/// </summary>
|
||||
public interface IDisposeOnRequestEnd : IDisposable
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -139,7 +139,10 @@ namespace Umbraco.Core.Models
|
||||
/// <summary>
|
||||
/// Boolean indicating whether this Content is Published or not
|
||||
/// </summary>
|
||||
/// <remarks>Setting Published to true/false should be private or internal</remarks>
|
||||
/// <remarks>
|
||||
/// Setting Published to true/false should be private or internal and should ONLY be used for wiring up the value
|
||||
/// from the db or modifying it based on changing the published state.
|
||||
/// </remarks>
|
||||
[DataMember]
|
||||
public bool Published
|
||||
{
|
||||
@@ -372,11 +375,25 @@ namespace Umbraco.Core.Models
|
||||
/// <returns>True if entity is dirty, otherwise False</returns>
|
||||
public override bool IsDirty()
|
||||
{
|
||||
bool dirtyEntity = base.IsDirty();
|
||||
return IsEntityDirty() || IsAnyUserPropertyDirty();
|
||||
}
|
||||
|
||||
bool dirtyProperties = Properties.Any(x => x.IsDirty());
|
||||
/// <summary>
|
||||
/// Returns true if only the entity properties are direty
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal bool IsEntityDirty()
|
||||
{
|
||||
return base.IsDirty();
|
||||
}
|
||||
|
||||
return dirtyEntity || dirtyProperties;
|
||||
/// <summary>
|
||||
/// Returns true if any of the properties are dirty
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal bool IsAnyUserPropertyDirty()
|
||||
{
|
||||
return Properties.Any(x => x.IsDirty());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -293,7 +293,10 @@ namespace Umbraco.Core.Models
|
||||
/// <returns><see cref="Property"/> Value as a <see cref="TPassType"/></returns>
|
||||
public virtual TPassType GetValue<TPassType>(string propertyTypeAlias)
|
||||
{
|
||||
return (TPassType)Properties[propertyTypeAlias].Value;
|
||||
if (Properties[propertyTypeAlias].Value is TPassType)
|
||||
return (TPassType)Properties[propertyTypeAlias].Value;
|
||||
|
||||
return (TPassType)Convert.ChangeType(Properties[propertyTypeAlias].Value, typeof(TPassType));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -436,5 +439,20 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
|
||||
public abstract void ChangeTrashedState(bool isTrashed, int parentId = -20);
|
||||
|
||||
/// <summary>
|
||||
/// We will override this method to ensure that when we reset the dirty properties that we
|
||||
/// also reset the dirty changes made to the content's Properties (user defined)
|
||||
/// </summary>
|
||||
/// <param name="rememberPreviouslyChangedProperties"></param>
|
||||
internal override void ResetDirtyProperties(bool rememberPreviouslyChangedProperties)
|
||||
{
|
||||
base.ResetDirtyProperties(rememberPreviouslyChangedProperties);
|
||||
|
||||
foreach (var prop in Properties)
|
||||
{
|
||||
prop.ResetDirtyProperties(rememberPreviouslyChangedProperties);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ using System.Xml.Linq;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Media;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Core.Persistence;
|
||||
@@ -23,6 +24,107 @@ namespace Umbraco.Core.Models
|
||||
public static class ContentExtensions
|
||||
{
|
||||
#region IContent
|
||||
|
||||
/// <summary>
|
||||
/// Determines if a new version should be created
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// A new version needs to be created when:
|
||||
/// * The publish status is changed
|
||||
/// * The language is changed
|
||||
/// * The item is already published and is being published again and any property value is changed (to enable a rollback)
|
||||
/// </remarks>
|
||||
internal static bool ShouldCreateNewVersion(this IContent entity)
|
||||
{
|
||||
var publishedState = ((Content)entity).PublishedState;
|
||||
return ShouldCreateNewVersion(entity, publishedState);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if a new version should be created
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="publishedState"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// A new version needs to be created when:
|
||||
/// * The publish status is changed
|
||||
/// * The language is changed
|
||||
/// * The item is already published and is being published again and any property value is changed (to enable a rollback)
|
||||
/// </remarks>
|
||||
internal static bool ShouldCreateNewVersion(this IContent entity, PublishedState publishedState)
|
||||
{
|
||||
var dirtyEntity = (ICanBeDirty)entity;
|
||||
|
||||
//check if the published state has changed or the language
|
||||
var contentChanged =
|
||||
(dirtyEntity.IsPropertyDirty("Published") && publishedState != PublishedState.Unpublished)
|
||||
|| dirtyEntity.IsPropertyDirty("Language");
|
||||
|
||||
//return true if published or language has changed
|
||||
if (contentChanged)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//check if any user prop has changed
|
||||
var propertyValueChanged = ((Content) entity).IsAnyUserPropertyDirty();
|
||||
//check if any content prop has changed
|
||||
var contentDataChanged = ((Content) entity).IsEntityDirty();
|
||||
|
||||
//return true if the item is published and a property has changed or if any content property has changed
|
||||
return (propertyValueChanged && publishedState == PublishedState.Published) || contentDataChanged;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the published db flag should be set to true for the current entity version and all other db
|
||||
/// versions should have their flag set to false.
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This is determined by:
|
||||
/// * If a new version is being created and the entity is published
|
||||
/// * If the published state has changed and the entity is published OR the entity has been un-published.
|
||||
/// </remarks>
|
||||
internal static bool ShouldClearPublishedFlagForPreviousVersions(this IContent entity)
|
||||
{
|
||||
var publishedState = ((Content)entity).PublishedState;
|
||||
return entity.ShouldClearPublishedFlagForPreviousVersions(publishedState, entity.ShouldCreateNewVersion(publishedState));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the published db flag should be set to true for the current entity version and all other db
|
||||
/// versions should have their flag set to false.
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="publishedState"></param>
|
||||
/// <param name="isCreatingNewVersion"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This is determined by:
|
||||
/// * If a new version is being created and the entity is published
|
||||
/// * If the published state has changed and the entity is published OR the entity has been un-published.
|
||||
/// </remarks>
|
||||
internal static bool ShouldClearPublishedFlagForPreviousVersions(this IContent entity, PublishedState publishedState, bool isCreatingNewVersion)
|
||||
{
|
||||
if (isCreatingNewVersion && entity.Published)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//If Published state has changed then previous versions should have their publish state reset.
|
||||
//If state has been changed to unpublished the previous versions publish state should also be reset.
|
||||
if (((ICanBeDirty)entity).IsPropertyDirty("Published") && (entity.Published || publishedState == PublishedState.Unpublished))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of the current contents ancestors, not including the content itself.
|
||||
/// </summary>
|
||||
|
||||
@@ -181,6 +181,38 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a clone of the current entity
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IContentType Clone(string alias)
|
||||
{
|
||||
var clone = (ContentType)this.MemberwiseClone();
|
||||
clone.Alias = alias;
|
||||
clone.Key = Guid.Empty;
|
||||
var propertyGroups = this.PropertyGroups.Select(x => x.Clone()).ToList();
|
||||
clone.PropertyGroups = new PropertyGroupCollection(propertyGroups);
|
||||
clone.PropertyTypes = this.PropertyTypeCollection.Select(x => x.Clone()).ToList();
|
||||
clone.ResetIdentity();
|
||||
clone.ResetDirtyProperties(false);
|
||||
|
||||
foreach (var propertyGroup in clone.PropertyGroups)
|
||||
{
|
||||
propertyGroup.ResetIdentity();
|
||||
foreach (var propertyType in propertyGroup.PropertyTypes)
|
||||
{
|
||||
propertyType.ResetIdentity();
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var propertyType in clone.PropertyTypes.Where(x => x.HasIdentity))
|
||||
{
|
||||
propertyType.ResetIdentity();
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to call when Entity is being saved
|
||||
/// </summary>
|
||||
|
||||
@@ -494,5 +494,14 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
_parentId = id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PropertyTypes that are not part of a PropertyGroup
|
||||
/// </summary>
|
||||
[IgnoreDataMember]
|
||||
internal PropertyTypeCollection PropertyTypeCollection
|
||||
{
|
||||
get { return _propertyTypes; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,10 +22,15 @@ namespace Umbraco.Core.Models
|
||||
/// <returns>Xml of the property and its value</returns>
|
||||
public static XElement ToXml(this Property property)
|
||||
{
|
||||
string nodeName = UmbracoSettings.UseLegacyXmlSchema ? "data" : property.Alias.ToSafeAlias();
|
||||
return property.ToXml(ApplicationContext.Current.Services.DataTypeService);
|
||||
}
|
||||
|
||||
internal static XElement ToXml(this Property property, IDataTypeService dataTypeService)
|
||||
{
|
||||
var nodeName = UmbracoSettings.UseLegacyXmlSchema ? "data" : property.Alias.ToSafeAlias();
|
||||
|
||||
var xd = new XmlDocument();
|
||||
XmlNode xmlNode = xd.CreateNode(XmlNodeType.Element, nodeName, "");
|
||||
var xmlNode = xd.CreateNode(XmlNodeType.Element, nodeName, "");
|
||||
|
||||
//Add the property alias to the legacy schema
|
||||
if (UmbracoSettings.UseLegacyXmlSchema)
|
||||
@@ -37,9 +42,17 @@ namespace Umbraco.Core.Models
|
||||
|
||||
//This seems to fail during testing
|
||||
//SD: With the new null checks below, this shouldn't fail anymore.
|
||||
var dt = property.PropertyType.DataType(property.Id);
|
||||
var dt = property.PropertyType.DataType(property.Id, dataTypeService);
|
||||
if (dt != null && dt.Data != null)
|
||||
{
|
||||
{
|
||||
//We've already got the value for the property so we're going to give it to the
|
||||
// data type's data property so it doesn't go re-look up the value from the db again.
|
||||
var defaultData = dt.Data as IDataValueSetter;
|
||||
if (defaultData != null)
|
||||
{
|
||||
defaultData.SetValue(property.Value, property.PropertyType.DataTypeDatabaseType.ToString());
|
||||
}
|
||||
|
||||
xmlNode.AppendChild(dt.Data.ToXMl(xd));
|
||||
}
|
||||
|
||||
|
||||
@@ -108,6 +108,23 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
}
|
||||
|
||||
internal PropertyGroup Clone()
|
||||
{
|
||||
var clone = (PropertyGroup) this.MemberwiseClone();
|
||||
var collection = new PropertyTypeCollection();
|
||||
foreach (var propertyType in this.PropertyTypes)
|
||||
{
|
||||
var property = propertyType.Clone();
|
||||
property.ResetIdentity();
|
||||
property.ResetDirtyProperties(false);
|
||||
collection.Add(property);
|
||||
}
|
||||
clone.PropertyTypes = collection;
|
||||
clone.ResetIdentity();
|
||||
clone.ResetDirtyProperties(false);
|
||||
return clone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the ParentId from the lazy integer id
|
||||
/// </summary>
|
||||
|
||||
@@ -378,6 +378,14 @@ namespace Umbraco.Core.Models
|
||||
return true;
|
||||
}
|
||||
|
||||
internal PropertyType Clone()
|
||||
{
|
||||
var clone = (PropertyType) this.MemberwiseClone();
|
||||
clone.ResetIdentity();
|
||||
clone.ResetDirtyProperties(false);
|
||||
return clone;
|
||||
}
|
||||
|
||||
public bool Equals(PropertyType other)
|
||||
{
|
||||
//Check whether the compared object is null.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using umbraco.interfaces;
|
||||
using Umbraco.Core.Services;
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -9,6 +10,7 @@ namespace Umbraco.Core.Models
|
||||
/// </summary>
|
||||
/// <param name="propertyType">PropertyType that references a DataType</param>
|
||||
/// <param name="propertyId">Id of the Property which references this DataType through its PropertyType</param>
|
||||
/// <param name="dataTypeService"></param>
|
||||
/// <returns><see cref="IDataType"/></returns>
|
||||
/// <remarks>
|
||||
/// This extension method is left internal because we don't want to take
|
||||
@@ -16,10 +18,10 @@ namespace Umbraco.Core.Models
|
||||
/// be replaced by PropertyEditors. It is however needed to generate xml
|
||||
/// for a property/propertytype when publishing.
|
||||
/// </remarks>
|
||||
internal static IDataType DataType(this PropertyType propertyType, int propertyId)
|
||||
internal static IDataType DataType(this PropertyType propertyType, int propertyId, IDataTypeService dataTypeService)
|
||||
{
|
||||
Mandate.ParameterNotNull(propertyType, "propertyType");
|
||||
var dataType = ApplicationContext.Current.Services.DataTypeService.GetDataTypeById(propertyType.DataTypeId);
|
||||
var dataType = dataTypeService.GetDataTypeById(propertyType.DataTypeId);
|
||||
if (dataType == null)
|
||||
{
|
||||
return null;
|
||||
|
||||
@@ -65,12 +65,12 @@ namespace Umbraco.Core.Models.Rdbms
|
||||
return Date.Value;
|
||||
}
|
||||
|
||||
if(!string.IsNullOrEmpty(VarChar))
|
||||
if(string.IsNullOrEmpty(VarChar) == false)
|
||||
{
|
||||
return VarChar;
|
||||
}
|
||||
|
||||
if(!string.IsNullOrEmpty(Text))
|
||||
if(string.IsNullOrEmpty(Text) == false)
|
||||
{
|
||||
return Text;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
@@ -9,7 +10,8 @@ namespace Umbraco.Core.Models
|
||||
/// </summary>
|
||||
public static class UmbracoObjectTypesExtensions
|
||||
{
|
||||
private static readonly Dictionary<UmbracoObjectTypes, Guid> UmbracoObjectTypeCache = new Dictionary<UmbracoObjectTypes,Guid>();
|
||||
//MUST be concurrent to avoid thread collisions!
|
||||
private static readonly ConcurrentDictionary<UmbracoObjectTypes, Guid> UmbracoObjectTypeCache = new ConcurrentDictionary<UmbracoObjectTypes, Guid>();
|
||||
|
||||
/// <summary>
|
||||
/// Get an UmbracoObjectTypes value from it's name
|
||||
@@ -48,24 +50,22 @@ namespace Umbraco.Core.Models
|
||||
/// <returns>a GUID value of the UmbracoObjectTypes</returns>
|
||||
public static Guid GetGuid(this UmbracoObjectTypes umbracoObjectType)
|
||||
{
|
||||
if (UmbracoObjectTypeCache.ContainsKey(umbracoObjectType))
|
||||
return UmbracoObjectTypeCache[umbracoObjectType];
|
||||
return UmbracoObjectTypeCache.GetOrAdd(umbracoObjectType, types =>
|
||||
{
|
||||
var type = typeof(UmbracoObjectTypes);
|
||||
var memInfo = type.GetMember(umbracoObjectType.ToString());
|
||||
var attributes = memInfo[0].GetCustomAttributes(typeof(UmbracoObjectTypeAttribute),
|
||||
false);
|
||||
|
||||
var type = typeof(UmbracoObjectTypes);
|
||||
var memInfo = type.GetMember(umbracoObjectType.ToString());
|
||||
var attributes = memInfo[0].GetCustomAttributes(typeof(UmbracoObjectTypeAttribute),
|
||||
false);
|
||||
if (attributes.Length == 0)
|
||||
return Guid.Empty;
|
||||
|
||||
if (attributes.Length == 0)
|
||||
return Guid.Empty;
|
||||
var attribute = ((UmbracoObjectTypeAttribute)attributes[0]);
|
||||
if (attribute == null)
|
||||
return Guid.Empty;
|
||||
|
||||
var attribute = ((UmbracoObjectTypeAttribute)attributes[0]);
|
||||
if (attribute == null)
|
||||
return Guid.Empty;
|
||||
|
||||
UmbracoObjectTypeCache.Add(umbracoObjectType, attribute.ObjectId);
|
||||
|
||||
return attribute.ObjectId;
|
||||
return attribute.ObjectId;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Currently just used to get the machine name in med trust and to format a machine name for use with file names
|
||||
/// </summary>
|
||||
internal class NetworkHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the machine name that is safe to use in file paths.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// see: https://github.com/Shandem/ClientDependency/issues/4
|
||||
/// </remarks>
|
||||
public static string FileSafeMachineName
|
||||
{
|
||||
get { return MachineName.ReplaceNonAlphanumericChars('-'); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current machine name
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Tries to resolve the machine name, if it cannot it uses the config section.
|
||||
/// </remarks>
|
||||
public static string MachineName
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return Environment.MachineName;
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
return System.Net.Dns.GetHostName();
|
||||
}
|
||||
catch
|
||||
{
|
||||
//if we get here it means we cannot access the machine name
|
||||
throw new ApplicationException("Cannot resolve the current machine name eithe by Environment.MachineName or by Dns.GetHostname()");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using System.Data;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Umbraco.Core.Persistence.DatabaseAnnotations;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.DatabaseModelDefinitions
|
||||
{
|
||||
@@ -107,6 +108,12 @@ namespace Umbraco.Core.Persistence.DatabaseModelDefinitions
|
||||
var constraintAttribute = propertyInfo.FirstAttribute<ConstraintAttribute>();
|
||||
if (constraintAttribute != null)
|
||||
{
|
||||
//Special case for MySQL as it can't have multiple default DateTime values, which
|
||||
//is what the umbracoServer table definition is trying to create
|
||||
if (SqlSyntaxContext.SqlSyntaxProvider is MySqlSyntaxProvider && definition.TableName == "umbracoServer" &&
|
||||
definition.TableName.ToLowerInvariant() == "lastNotifiedDate".ToLowerInvariant())
|
||||
return definition;
|
||||
|
||||
definition.ConstraintName = constraintAttribute.Name ?? string.Empty;
|
||||
definition.DefaultValue = constraintAttribute.Default ?? string.Empty;
|
||||
}
|
||||
|
||||
@@ -14,9 +14,9 @@ namespace Umbraco.Core.Persistence
|
||||
/// </remarks>
|
||||
internal class DefaultDatabaseFactory : DisposableObject, IDatabaseFactory
|
||||
{
|
||||
private readonly string _connectionStringName;
|
||||
private readonly string _connectionString;
|
||||
private readonly string _providerName;
|
||||
private readonly string _connectionStringName;
|
||||
public string ConnectionString { get; private set; }
|
||||
public string ProviderName { get; private set; }
|
||||
|
||||
//very important to have ThreadStatic:
|
||||
// see: http://issues.umbraco.org/issue/U4-2172
|
||||
@@ -52,8 +52,8 @@ namespace Umbraco.Core.Persistence
|
||||
{
|
||||
Mandate.ParameterNotNullOrEmpty(connectionString, "connectionString");
|
||||
Mandate.ParameterNotNullOrEmpty(providerName, "providerName");
|
||||
_connectionString = connectionString;
|
||||
_providerName = providerName;
|
||||
ConnectionString = connectionString;
|
||||
ProviderName = providerName;
|
||||
}
|
||||
|
||||
public UmbracoDatabase CreateDatabase()
|
||||
@@ -68,8 +68,8 @@ namespace Umbraco.Core.Persistence
|
||||
//double check
|
||||
if (_nonHttpInstance == null)
|
||||
{
|
||||
_nonHttpInstance = string.IsNullOrEmpty(_connectionString) == false && string.IsNullOrEmpty(_providerName) == false
|
||||
? new UmbracoDatabase(_connectionString, _providerName)
|
||||
_nonHttpInstance = string.IsNullOrEmpty(ConnectionString) == false && string.IsNullOrEmpty(ProviderName) == false
|
||||
? new UmbracoDatabase(ConnectionString, ProviderName)
|
||||
: new UmbracoDatabase(_connectionStringName);
|
||||
}
|
||||
}
|
||||
@@ -81,8 +81,8 @@ namespace Umbraco.Core.Persistence
|
||||
if (HttpContext.Current.Items.Contains(typeof(DefaultDatabaseFactory)) == false)
|
||||
{
|
||||
HttpContext.Current.Items.Add(typeof (DefaultDatabaseFactory),
|
||||
string.IsNullOrEmpty(_connectionString) == false && string.IsNullOrEmpty(_providerName) == false
|
||||
? new UmbracoDatabase(_connectionString, _providerName)
|
||||
string.IsNullOrEmpty(ConnectionString) == false && string.IsNullOrEmpty(ProviderName) == false
|
||||
? new UmbracoDatabase(ConnectionString, ProviderName)
|
||||
: new UmbracoDatabase(_connectionStringName));
|
||||
}
|
||||
return (UmbracoDatabase)HttpContext.Current.Items[typeof(DefaultDatabaseFactory)];
|
||||
|
||||
@@ -223,8 +223,6 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 4, DataTypeId = -88, ControlId = new Guid(Constants.PropertyEditors.Textbox), DbType = "Nvarchar" });
|
||||
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 5, DataTypeId = -89, ControlId = new Guid(Constants.PropertyEditors.TextboxMultiple), DbType = "Ntext" });
|
||||
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 6, DataTypeId = -90, ControlId = new Guid(Constants.PropertyEditors.UploadField), DbType = "Nvarchar" });
|
||||
//Dropdown list
|
||||
//_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 12, DataTypeId = -91, ControlId = new Guid("a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6"), DbType = "Nvarchar" });
|
||||
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 7, DataTypeId = -92, ControlId = new Guid(Constants.PropertyEditors.NoEdit), DbType = "Nvarchar" });
|
||||
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 8, DataTypeId = -36, ControlId = new Guid(Constants.PropertyEditors.DateTime), DbType = "Date" });
|
||||
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 9, DataTypeId = -37, ControlId = new Guid(Constants.PropertyEditors.ColorPicker), DbType = "Nvarchar" });
|
||||
@@ -234,24 +232,6 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 13, DataTypeId = -41, ControlId = new Guid(Constants.PropertyEditors.Date), DbType = "Date" });
|
||||
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 14, DataTypeId = -42, ControlId = new Guid(Constants.PropertyEditors.DropDownList), DbType = "Integer" });
|
||||
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 15, DataTypeId = -43, ControlId = new Guid(Constants.PropertyEditors.CheckBoxList), DbType = "Nvarchar" });
|
||||
// Fix for rich text editor backwards compatibility -> 83722133-f80c-4273-bdb6-1befaa04a612 TinyMCE DataType
|
||||
//_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 22, DataTypeId = -44, ControlId = new Guid("a3776494-0574-4d93-b7de-efdfdec6f2d1"), DbType = "Ntext" });
|
||||
//Radiobutton list
|
||||
//_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 23, DataTypeId = -128, ControlId = new Guid("a52c7c1c-c330-476e-8605-d63d3b84b6a6"), DbType = "Nvarchar" });
|
||||
//Dropdown list multiple
|
||||
//_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 24, DataTypeId = -129, ControlId = new Guid("928639ed-9c73-4028-920c-1e55dbb68783"), DbType = "Nvarchar" });
|
||||
//Dropdown list
|
||||
//_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 25, DataTypeId = -130, ControlId = new Guid("a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6"), DbType = "Nvarchar" });
|
||||
//Dropdown list
|
||||
//_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 26, DataTypeId = -131, ControlId = new Guid("a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6"), DbType = "Nvarchar" });
|
||||
//Dropdown list
|
||||
//_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 27, DataTypeId = -132, ControlId = new Guid("a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6"), DbType = "Nvarchar" });
|
||||
//No edit
|
||||
//_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 28, DataTypeId = -133, ControlId = new Guid("6c738306-4c17-4d88-b9bd-6546f3771597"), DbType = "Ntext" });
|
||||
//Dropdown list multiple
|
||||
//_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 29, DataTypeId = -134, ControlId = new Guid("928639ed-9c73-4028-920c-1e55dbb68783"), DbType = "Nvarchar" });
|
||||
//Not found - maybe a legacy thing?
|
||||
//_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 30, DataTypeId = -50, ControlId = new Guid("aaf99bb2-dbbe-444d-a296-185076bf0484"), DbType = "Date" });
|
||||
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 16, DataTypeId = 1034, ControlId = new Guid(Constants.PropertyEditors.ContentPicker), DbType = "Integer" });
|
||||
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 17, DataTypeId = 1035, ControlId = new Guid(Constants.PropertyEditors.MediaPicker), DbType = "Integer" });
|
||||
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 18, DataTypeId = 1036, ControlId = new Guid(Constants.PropertyEditors.MemberPicker), DbType = "Integer" });
|
||||
|
||||
@@ -6,6 +6,7 @@ using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Umbraco.Core.Persistence.Migrations.Initial;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence
|
||||
@@ -32,76 +33,145 @@ namespace Umbraco.Core.Persistence
|
||||
|
||||
public static void BulkInsertRecords<T>(this Database db, IEnumerable<T> collection)
|
||||
{
|
||||
//don't do anything if there are no records.
|
||||
if (collection.Any() == false)
|
||||
return;
|
||||
|
||||
using (var tr = db.GetTransaction())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (SqlSyntaxContext.SqlSyntaxProvider is SqlCeSyntaxProvider)
|
||||
{
|
||||
//SqlCe doesn't support bulk insert statements!
|
||||
|
||||
foreach (var poco in collection)
|
||||
{
|
||||
db.Insert(poco);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
string sql;
|
||||
using (var cmd = db.GenerateBulkInsertCommand(collection, db.Connection, out sql))
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
tr.Complete();
|
||||
}
|
||||
catch
|
||||
{
|
||||
tr.Dispose();
|
||||
throw;
|
||||
}
|
||||
db.BulkInsertRecords(collection, tr);
|
||||
}
|
||||
}
|
||||
|
||||
internal static IDbCommand GenerateBulkInsertCommand<T>(this Database db, IEnumerable<T> collection, IDbConnection connection, out string sql)
|
||||
public static void BulkInsertRecords<T>(this Database db, IEnumerable<T> collection, Transaction tr)
|
||||
{
|
||||
//don't do anything if there are no records.
|
||||
if (collection.Any() == false)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
//if it is sql ce or it is a sql server version less than 2008, we need to do individual inserts.
|
||||
var sqlServerSyntax = SqlSyntaxContext.SqlSyntaxProvider as SqlServerSyntaxProvider;
|
||||
if ((sqlServerSyntax != null && (int)sqlServerSyntax.VersionName.Value < (int)SqlServerVersionName.V2008)
|
||||
|| SqlSyntaxContext.SqlSyntaxProvider is SqlCeSyntaxProvider)
|
||||
{
|
||||
//SqlCe doesn't support bulk insert statements!
|
||||
|
||||
foreach (var poco in collection)
|
||||
{
|
||||
db.Insert(poco);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] sqlStatements;
|
||||
var cmds = db.GenerateBulkInsertCommand(collection, db.Connection, out sqlStatements);
|
||||
for (var i = 0; i < sqlStatements.Length; i++)
|
||||
{
|
||||
using (var cmd = cmds[i])
|
||||
{
|
||||
cmd.CommandText = sqlStatements[i];
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tr.Complete();
|
||||
}
|
||||
catch
|
||||
{
|
||||
tr.Dispose();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a bulk insert command
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="db"></param>
|
||||
/// <param name="collection"></param>
|
||||
/// <param name="connection"></param>
|
||||
/// <param name="sql"></param>
|
||||
/// <returns>Sql commands with populated command parameters required to execute the sql statement</returns>
|
||||
/// <remarks>
|
||||
/// The limits for number of parameters are 2100 (in sql server, I think there's many more allowed in mysql). So
|
||||
/// we need to detect that many params and split somehow.
|
||||
/// For some reason the 2100 limit is not actually allowed even though the exception from sql server mentions 2100 as a max, perhaps it is 2099
|
||||
/// that is max. I've reduced it to 2000 anyways.
|
||||
/// </remarks>
|
||||
internal static IDbCommand[] GenerateBulkInsertCommand<T>(
|
||||
this Database db,
|
||||
IEnumerable<T> collection,
|
||||
IDbConnection connection,
|
||||
out string[] sql)
|
||||
{
|
||||
//A filter used below a few times to get all columns except result cols and not the primary key if it is auto-incremental
|
||||
Func<Database.PocoData, KeyValuePair<string, Database.PocoColumn>, bool> includeColumn = (data, column) =>
|
||||
{
|
||||
if (column.Value.ResultColumn) return false;
|
||||
if (data.TableInfo.AutoIncrement && column.Key == data.TableInfo.PrimaryKey) return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
var pd = Database.PocoData.ForType(typeof(T));
|
||||
var tableName = db.EscapeTableName(pd.TableInfo.TableName);
|
||||
|
||||
//get all columns but not the primary key if it is auto-incremental
|
||||
var cols = string.Join(", ", (
|
||||
from c in pd.Columns
|
||||
where
|
||||
//don't return ResultColumns
|
||||
!c.Value.ResultColumn
|
||||
//if the table is auto-incremental, don't return the primary key
|
||||
&& (pd.TableInfo.AutoIncrement && c.Key != pd.TableInfo.PrimaryKey)
|
||||
select tableName + "." + db.EscapeSqlIdentifier(c.Key))
|
||||
.ToArray());
|
||||
//get all columns to include and format for sql
|
||||
var cols = string.Join(", ",
|
||||
pd.Columns
|
||||
.Where(c => includeColumn(pd, c))
|
||||
.Select(c => tableName + "." + db.EscapeSqlIdentifier(c.Key)).ToArray());
|
||||
|
||||
var cmd = db.CreateCommand(connection, "");
|
||||
var itemArray = collection.ToArray();
|
||||
|
||||
var pocoValues = new List<string>();
|
||||
var index = 0;
|
||||
foreach (var poco in collection)
|
||||
//calculate number of parameters per item
|
||||
var paramsPerItem = pd.Columns.Count(i => includeColumn(pd, i));
|
||||
|
||||
//Example calc:
|
||||
// Given: we have 4168 items in the itemArray, each item contains 8 command parameters (values to be inserterted)
|
||||
// 2100 / 8 = 262.5
|
||||
// Math.Floor(2100 / 8) = 262 items per trans
|
||||
// 4168 / 262 = 15.908... = there will be 16 trans in total
|
||||
|
||||
//all items will be included if we have disabled db parameters
|
||||
var itemsPerTrans = Math.Floor(2000.00 / paramsPerItem);
|
||||
//there will only be one transaction if we have disabled db parameters
|
||||
var numTrans = Math.Ceiling(itemArray.Length / itemsPerTrans);
|
||||
|
||||
var sqlQueries = new List<string>();
|
||||
var commands = new List<IDbCommand>();
|
||||
|
||||
for (var tIndex = 0; tIndex < numTrans; tIndex++)
|
||||
{
|
||||
var values = new List<string>();
|
||||
foreach (var i in pd.Columns)
|
||||
var itemsForTrans = itemArray
|
||||
.Skip(tIndex * (int)itemsPerTrans)
|
||||
.Take((int)itemsPerTrans);
|
||||
|
||||
var cmd = db.CreateCommand(connection, "");
|
||||
var pocoValues = new List<string>();
|
||||
var index = 0;
|
||||
foreach (var poco in itemsForTrans)
|
||||
{
|
||||
if (pd.TableInfo.AutoIncrement && i.Key == pd.TableInfo.PrimaryKey)
|
||||
var values = new List<string>();
|
||||
//get all columns except result cols and not the primary key if it is auto-incremental
|
||||
foreach (var i in pd.Columns.Where(x => includeColumn(pd, x)))
|
||||
{
|
||||
continue;
|
||||
db.AddParam(cmd, i.Value.GetValue(poco), "@");
|
||||
values.Add(string.Format("{0}{1}", "@", index++));
|
||||
}
|
||||
values.Add(string.Format("{0}{1}", "@", index++));
|
||||
db.AddParam(cmd, i.Value.GetValue(poco), "@");
|
||||
pocoValues.Add("(" + string.Join(",", values.ToArray()) + ")");
|
||||
}
|
||||
pocoValues.Add("(" + string.Join(",", values.ToArray()) + ")");
|
||||
|
||||
var sqlResult = string.Format("INSERT INTO {0} ({1}) VALUES {2}", tableName, cols, string.Join(", ", pocoValues));
|
||||
sqlQueries.Add(sqlResult);
|
||||
commands.Add(cmd);
|
||||
}
|
||||
sql = string.Format("INSERT INTO {0} ({1}) VALUES {2}", tableName, cols, string.Join(", ", pocoValues));
|
||||
return cmd;
|
||||
|
||||
sql = sqlQueries.ToArray();
|
||||
|
||||
return commands.ToArray();
|
||||
}
|
||||
|
||||
public static void CreateTable(this Database db, bool overwrite, Type modelType)
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Querying
|
||||
{
|
||||
/// <summary>
|
||||
/// Logic that is shared with the expression helpers
|
||||
/// </summary>
|
||||
internal class BaseExpressionHelper
|
||||
{
|
||||
public virtual string GetQuotedValue(object value, Type fieldType, Func<object, string> escapeCallback = null, Func<Type, bool> shouldQuoteCallback = null)
|
||||
{
|
||||
if (value == null) return "NULL";
|
||||
|
||||
if (escapeCallback == null)
|
||||
{
|
||||
escapeCallback = EscapeParam;
|
||||
}
|
||||
if (shouldQuoteCallback == null)
|
||||
{
|
||||
shouldQuoteCallback = ShouldQuoteValue;
|
||||
}
|
||||
|
||||
if (!fieldType.UnderlyingSystemType.IsValueType && fieldType != typeof(string))
|
||||
{
|
||||
//if (TypeSerializer.CanCreateFromString(fieldType))
|
||||
//{
|
||||
// return "'" + EscapeParam(TypeSerializer.SerializeToString(value)) + "'";
|
||||
//}
|
||||
|
||||
throw new NotSupportedException(
|
||||
string.Format("Property of type: {0} is not supported", fieldType.FullName));
|
||||
}
|
||||
|
||||
if (fieldType == typeof(int))
|
||||
return ((int)value).ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
if (fieldType == typeof(float))
|
||||
return ((float)value).ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
if (fieldType == typeof(double))
|
||||
return ((double)value).ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
if (fieldType == typeof(decimal))
|
||||
return ((decimal)value).ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
if (fieldType == typeof(DateTime))
|
||||
{
|
||||
return "'" + EscapeParam(((DateTime)value).ToIsoString()) + "'";
|
||||
}
|
||||
|
||||
if (fieldType == typeof(bool))
|
||||
return ((bool)value) ? Convert.ToString(1, CultureInfo.InvariantCulture) : Convert.ToString(0, CultureInfo.InvariantCulture);
|
||||
|
||||
return ShouldQuoteValue(fieldType)
|
||||
? "'" + EscapeParam(value) + "'"
|
||||
: value.ToString();
|
||||
}
|
||||
|
||||
public virtual string EscapeParam(object paramValue)
|
||||
{
|
||||
return paramValue.ToString().Replace("'", "''");
|
||||
}
|
||||
|
||||
public virtual string EscapeAtArgument(string exp)
|
||||
{
|
||||
if (exp.StartsWith("@"))
|
||||
return string.Concat("@", exp);
|
||||
|
||||
return exp;
|
||||
}
|
||||
|
||||
public virtual bool ShouldQuoteValue(Type fieldType)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected virtual string RemoveQuote(string exp)
|
||||
{
|
||||
if (exp.StartsWith("'") && exp.EndsWith("'"))
|
||||
{
|
||||
exp = exp.Remove(0, 1);
|
||||
exp = exp.Remove(exp.Length - 1, 1);
|
||||
}
|
||||
return exp;
|
||||
}
|
||||
|
||||
protected virtual string RemoveQuoteFromAlias(string exp)
|
||||
{
|
||||
|
||||
if ((exp.StartsWith("\"") || exp.StartsWith("`") || exp.StartsWith("'"))
|
||||
&&
|
||||
(exp.EndsWith("\"") || exp.EndsWith("`") || exp.EndsWith("'")))
|
||||
{
|
||||
exp = exp.Remove(0, 1);
|
||||
exp = exp.Remove(exp.Length - 1, 1);
|
||||
}
|
||||
return exp;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Querying
|
||||
{
|
||||
internal class ModelToSqlExpressionHelper<T>
|
||||
internal class ModelToSqlExpressionHelper<T> : BaseExpressionHelper
|
||||
{
|
||||
private string sep = " ";
|
||||
private BaseMapper _mapper;
|
||||
@@ -246,7 +246,7 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
case "ToLower":
|
||||
return string.Format("lower({0})", r);
|
||||
case "StartsWith":
|
||||
return string.Format("upper({0}) like '{1}%'", r, RemoveQuote(args[0].ToString().ToUpper()));
|
||||
return string.Format("upper({0}) like '{1}%'", r, EscapeAtArgument(RemoveQuote(args[0].ToString().ToUpper())));
|
||||
case "EndsWith":
|
||||
return string.Format("upper({0}) like '%{1}'", r, RemoveQuote(args[0].ToString()).ToUpper());
|
||||
case "Contains":
|
||||
@@ -435,72 +435,7 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
|
||||
public virtual string GetQuotedValue(object value, Type fieldType)
|
||||
{
|
||||
if (value == null) return "NULL";
|
||||
|
||||
if (!fieldType.UnderlyingSystemType.IsValueType && fieldType != typeof(string))
|
||||
{
|
||||
throw new NotSupportedException(
|
||||
string.Format("Property of type: {0} is not supported", fieldType.FullName));
|
||||
}
|
||||
|
||||
if (fieldType == typeof(int))
|
||||
return ((int)value).ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
if (fieldType == typeof(float))
|
||||
return ((float)value).ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
if (fieldType == typeof(double))
|
||||
return ((double)value).ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
if (fieldType == typeof(decimal))
|
||||
return ((decimal)value).ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
if (fieldType == typeof (DateTime))
|
||||
{
|
||||
return "'" + EscapeParam(((DateTime)value).ToIsoString()) + "'";
|
||||
}
|
||||
|
||||
|
||||
if (fieldType == typeof(bool))
|
||||
return ((bool)value) ? Convert.ToString(1, CultureInfo.InvariantCulture) : Convert.ToString(0, CultureInfo.InvariantCulture);
|
||||
|
||||
return ShouldQuoteValue(fieldType)
|
||||
? "'" + EscapeParam(value) + "'"
|
||||
: value.ToString();
|
||||
}
|
||||
|
||||
public virtual string EscapeParam(object paramValue)
|
||||
{
|
||||
return paramValue.ToString().Replace("'", "''");
|
||||
}
|
||||
|
||||
public virtual bool ShouldQuoteValue(Type fieldType)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected string RemoveQuote(string exp)
|
||||
{
|
||||
|
||||
if (exp.StartsWith("'") && exp.EndsWith("'"))
|
||||
{
|
||||
exp = exp.Remove(0, 1);
|
||||
exp = exp.Remove(exp.Length - 1, 1);
|
||||
}
|
||||
return exp;
|
||||
}
|
||||
|
||||
protected string RemoveQuoteFromAlias(string exp)
|
||||
{
|
||||
|
||||
if ((exp.StartsWith("\"") || exp.StartsWith("`") || exp.StartsWith("'"))
|
||||
&&
|
||||
(exp.EndsWith("\"") || exp.EndsWith("`") || exp.EndsWith("'")))
|
||||
{
|
||||
exp = exp.Remove(0, 1);
|
||||
exp = exp.Remove(exp.Length - 1, 1);
|
||||
}
|
||||
return exp;
|
||||
return GetQuotedValue(value, fieldType, EscapeParam, ShouldQuoteValue);
|
||||
}
|
||||
|
||||
private string GetTrueExpression()
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
@@ -9,7 +8,7 @@ using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Querying
|
||||
{
|
||||
internal class PocoToSqlExpressionHelper<T>
|
||||
internal class PocoToSqlExpressionHelper<T> : BaseExpressionHelper
|
||||
{
|
||||
private string sep = " ";
|
||||
private Database.PocoData pd;
|
||||
@@ -251,7 +250,7 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
case "ToLower":
|
||||
return string.Format("lower({0})", r);
|
||||
case "StartsWith":
|
||||
return string.Format("upper({0}) like '{1}%'", r, RemoveQuote(args[0].ToString().ToUpper()));
|
||||
return string.Format("upper({0}) like '{1}%'", r, EscapeAtArgument(RemoveQuote(args[0].ToString().ToUpper())));
|
||||
case "EndsWith":
|
||||
return string.Format("upper({0}) like '%{1}'", r, RemoveQuote(args[0].ToString()).ToUpper());
|
||||
case "Contains":
|
||||
@@ -440,53 +439,7 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
|
||||
public virtual string GetQuotedValue(object value, Type fieldType)
|
||||
{
|
||||
if (value == null) return "NULL";
|
||||
|
||||
if (!fieldType.UnderlyingSystemType.IsValueType && fieldType != typeof(string))
|
||||
{
|
||||
//if (TypeSerializer.CanCreateFromString(fieldType))
|
||||
//{
|
||||
// return "'" + EscapeParam(TypeSerializer.SerializeToString(value)) + "'";
|
||||
//}
|
||||
|
||||
throw new NotSupportedException(
|
||||
string.Format("Property of type: {0} is not supported", fieldType.FullName));
|
||||
}
|
||||
|
||||
if (fieldType == typeof(int))
|
||||
return ((int)value).ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
if (fieldType == typeof(float))
|
||||
return ((float)value).ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
if (fieldType == typeof(double))
|
||||
return ((double)value).ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
if (fieldType == typeof(decimal))
|
||||
return ((decimal)value).ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
if (fieldType == typeof (DateTime))
|
||||
{
|
||||
return "'" + EscapeParam(((DateTime)value).ToIsoString()) + "'";
|
||||
}
|
||||
|
||||
|
||||
if (fieldType == typeof(bool))
|
||||
return ((bool)value) ? Convert.ToString(1, CultureInfo.InvariantCulture) : Convert.ToString(0, CultureInfo.InvariantCulture);
|
||||
|
||||
return ShouldQuoteValue(fieldType)
|
||||
? "'" + EscapeParam(value) + "'"
|
||||
: value.ToString();
|
||||
}
|
||||
|
||||
public virtual string EscapeParam(object paramValue)
|
||||
{
|
||||
return paramValue.ToString().Replace("'", "''");
|
||||
}
|
||||
|
||||
public virtual bool ShouldQuoteValue(Type fieldType)
|
||||
{
|
||||
return true;
|
||||
return GetQuotedValue(value, fieldType, EscapeParam, ShouldQuoteValue);
|
||||
}
|
||||
|
||||
protected virtual string GetFieldName(Database.PocoData pocoData, string name)
|
||||
@@ -497,30 +450,6 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(column.Value.ColumnName));
|
||||
}
|
||||
|
||||
protected string RemoveQuote(string exp)
|
||||
{
|
||||
|
||||
if (exp.StartsWith("'") && exp.EndsWith("'"))
|
||||
{
|
||||
exp = exp.Remove(0, 1);
|
||||
exp = exp.Remove(exp.Length - 1, 1);
|
||||
}
|
||||
return exp;
|
||||
}
|
||||
|
||||
protected string RemoveQuoteFromAlias(string exp)
|
||||
{
|
||||
|
||||
if ((exp.StartsWith("\"") || exp.StartsWith("`") || exp.StartsWith("'"))
|
||||
&&
|
||||
(exp.EndsWith("\"") || exp.EndsWith("`") || exp.EndsWith("'")))
|
||||
{
|
||||
exp = exp.Remove(0, 1);
|
||||
exp = exp.Remove(exp.Length - 1, 1);
|
||||
}
|
||||
return exp;
|
||||
}
|
||||
|
||||
private string GetTrueExpression()
|
||||
{
|
||||
object o = GetQuotedTrueValue();
|
||||
|
||||
@@ -170,11 +170,31 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
return content;
|
||||
}
|
||||
|
||||
public override void DeleteVersion(Guid versionId)
|
||||
{
|
||||
var sql = new Sql()
|
||||
.Select("*")
|
||||
.From<DocumentDto>()
|
||||
.InnerJoin<ContentVersionDto>().On<ContentVersionDto, DocumentDto>(left => left.VersionId, right => right.VersionId)
|
||||
.Where<ContentVersionDto>(x => x.VersionId == versionId)
|
||||
.Where<DocumentDto>(x => x.Newest == true);
|
||||
var dto = Database.Fetch<DocumentDto, ContentVersionDto>(sql).FirstOrDefault();
|
||||
|
||||
if(dto == null) return;
|
||||
|
||||
using (var transaction = Database.GetTransaction())
|
||||
{
|
||||
PerformDeleteVersion(dto.NodeId, versionId);
|
||||
|
||||
transaction.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void PerformDeleteVersion(int id, Guid versionId)
|
||||
{
|
||||
Database.Delete<PreviewXmlDto>("WHERE nodeId = @Id AND versionId = @VersionId", new { Id = id, VersionId = versionId });
|
||||
Database.Delete<PropertyDataDto>("WHERE nodeId = @Id AND versionId = @VersionId", new { Id = id, VersionId = versionId });
|
||||
Database.Delete<ContentVersionDto>("WHERE nodeId = @Id AND VersionId = @VersionId", new { Id = id, VersionId = versionId });
|
||||
Database.Delete<PropertyDataDto>("WHERE contentNodeId = @Id AND versionId = @VersionId", new { Id = id, VersionId = versionId });
|
||||
Database.Delete<ContentVersionDto>("WHERE ContentId = @Id AND VersionId = @VersionId", new { Id = id, VersionId = versionId });
|
||||
Database.Delete<DocumentDto>("WHERE nodeId = @Id AND versionId = @VersionId", new { Id = id, VersionId = versionId });
|
||||
}
|
||||
|
||||
@@ -275,8 +295,9 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
protected override void PersistUpdatedItem(IContent entity)
|
||||
{
|
||||
var publishedState = ((Content) entity).PublishedState;
|
||||
//A new version should only be created if published state (or language) has changed
|
||||
bool shouldCreateNewVersion = (((ICanBeDirty)entity).IsPropertyDirty("Published") && publishedState != PublishedState.Unpublished) || ((ICanBeDirty)entity).IsPropertyDirty("Language");
|
||||
|
||||
//check if we need to create a new version
|
||||
bool shouldCreateNewVersion = entity.ShouldCreateNewVersion(publishedState);
|
||||
if (shouldCreateNewVersion)
|
||||
{
|
||||
//Updates Modified date and Version Guid
|
||||
@@ -327,7 +348,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
//If Published state has changed then previous versions should have their publish state reset.
|
||||
//If state has been changed to unpublished the previous versions publish state should also be reset.
|
||||
if (((ICanBeDirty)entity).IsPropertyDirty("Published") && (entity.Published || publishedState == PublishedState.Unpublished))
|
||||
//if (((ICanBeDirty)entity).IsPropertyDirty("Published") && (entity.Published || publishedState == PublishedState.Unpublished))
|
||||
if (entity.ShouldClearPublishedFlagForPreviousVersions(publishedState, shouldCreateNewVersion))
|
||||
{
|
||||
var publishedDocs = Database.Fetch<DocumentDto>("WHERE nodeId = @Id AND published = @IsPublished", new { Id = entity.Id, IsPublished = true });
|
||||
foreach (var doc in publishedDocs)
|
||||
@@ -338,19 +360,18 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
}
|
||||
}
|
||||
|
||||
//Look up (newest) entries by id in cmsDocument table to set newest = false
|
||||
var documentDtos = Database.Fetch<DocumentDto>("WHERE nodeId = @Id AND newest = @IsNewest", new { Id = entity.Id, IsNewest = true });
|
||||
foreach (var documentDto in documentDtos)
|
||||
{
|
||||
var docDto = documentDto;
|
||||
docDto.Newest = false;
|
||||
Database.Update(docDto);
|
||||
}
|
||||
|
||||
var contentVersionDto = dto.ContentVersionDto;
|
||||
if (shouldCreateNewVersion)
|
||||
{
|
||||
//Look up (newest) entries by id in cmsDocument table to set newest = false
|
||||
//NOTE: This is only relevant when a new version is created, which is why its done inside this if-statement.
|
||||
var documentDtos = Database.Fetch<DocumentDto>("WHERE nodeId = @Id AND newest = @IsNewest", new { Id = entity.Id, IsNewest = true });
|
||||
foreach (var documentDto in documentDtos)
|
||||
{
|
||||
var docDto = documentDto;
|
||||
docDto.Newest = false;
|
||||
Database.Update(docDto);
|
||||
}
|
||||
|
||||
//Create a new version - cmsContentVersion
|
||||
//Assumes a new Version guid and Version date (modified date) has been set
|
||||
Database.Insert(contentVersionDto);
|
||||
@@ -449,7 +470,19 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
foreach (var dto in dtos)
|
||||
{
|
||||
yield return CreateContentFromDto(dto, dto.VersionId);
|
||||
//Check in the cache first. If it exists there AND it is published
|
||||
// then we can use that entity. Otherwise if it is not published (which can be the case
|
||||
// because we only store the 'latest' entries in the cache which might not be the published
|
||||
// version)
|
||||
var fromCache = TryGetFromCache(dto.NodeId);
|
||||
if (fromCache.Success && fromCache.Result.Published)
|
||||
{
|
||||
yield return fromCache.Result;
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return CreateContentFromDto(dto, dto.VersionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -469,7 +502,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Private method to create a content object from a DocumentDto, which is used by Get and GetByVersion.
|
||||
/// </summary>
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
bool isContent = objectTypeId == new Guid(Constants.ObjectTypes.Document);
|
||||
bool isMedia = objectTypeId == new Guid(Constants.ObjectTypes.Media);
|
||||
var sql = GetBaseWhere(GetBase, isContent, isMedia, objectTypeId).Append(GetGroupBy(isContent, isMedia));
|
||||
var sql = GetBaseWhere(GetBase, isContent, isMedia, string.Empty, objectTypeId).Append(GetGroupBy(isContent, isMedia));
|
||||
var dtos = isMedia
|
||||
? _work.Database.Fetch<UmbracoEntityDto, UmbracoPropertyDto, UmbracoEntityDto>(
|
||||
new UmbracoEntityRelator().Map, sql)
|
||||
@@ -101,7 +101,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
public virtual IEnumerable<IUmbracoEntity> GetByQuery(IQuery<IUmbracoEntity> query)
|
||||
{
|
||||
var sqlClause = GetBase(false, false);
|
||||
var wheres = string.Concat(" AND ", string.Join(" AND ", ((Query<IUmbracoEntity>) query).WhereClauses()));
|
||||
var sqlClause = GetBase(false, false, wheres);
|
||||
var translator = new SqlTranslator<IUmbracoEntity>(sqlClause, query);
|
||||
var sql = translator.Translate().Append(GetGroupBy(false, false));
|
||||
|
||||
@@ -117,7 +118,9 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
bool isContent = objectTypeId == new Guid(Constants.ObjectTypes.Document);
|
||||
bool isMedia = objectTypeId == new Guid(Constants.ObjectTypes.Media);
|
||||
var sqlClause = GetBaseWhere(GetBase, isContent, isMedia, objectTypeId);
|
||||
|
||||
var wheres = string.Concat(" AND ", string.Join(" AND ", ((Query<IUmbracoEntity>)query).WhereClauses()));
|
||||
var sqlClause = GetBaseWhere(GetBase, isContent, isMedia, wheres, objectTypeId);
|
||||
var translator = new SqlTranslator<IUmbracoEntity>(sqlClause, query);
|
||||
var sql = translator.Translate().Append(GetGroupBy(isContent, isMedia));
|
||||
|
||||
@@ -136,7 +139,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
#region Sql Statements
|
||||
|
||||
protected virtual Sql GetBase(bool isContent, bool isMedia)
|
||||
protected virtual Sql GetBase(bool isContent, bool isMedia, string additionWhereStatement = "")
|
||||
{
|
||||
var columns = new List<object>
|
||||
{
|
||||
@@ -187,42 +190,38 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
.On("umbracoNode.id = latest.nodeId");
|
||||
}
|
||||
|
||||
/*if (isContent)
|
||||
{
|
||||
sql.LeftJoin(
|
||||
"(SELECT contentNodeId, versionId, dataNvarchar, controlId FROM cmsPropertyData INNER JOIN cmsPropertyType ON cmsPropertyType.id = cmsPropertyData.propertytypeid" +
|
||||
" INNER JOIN cmsDataType ON cmsPropertyType.dataTypeId = cmsDataType.nodeId) as property")
|
||||
.On("umbracoNode.id = property.contentNodeId AND latest.versionId = property.versionId");
|
||||
}*/
|
||||
if (isMedia)
|
||||
{
|
||||
sql.LeftJoin(
|
||||
"(SELECT contentNodeId, versionId, dataNvarchar, controlId FROM cmsPropertyData INNER JOIN cmsPropertyType ON cmsPropertyType.id = cmsPropertyData.propertytypeid" +
|
||||
" INNER JOIN cmsDataType ON cmsPropertyType.dataTypeId = cmsDataType.nodeId) as property")
|
||||
"(SELECT contentNodeId, versionId, dataNvarchar, controlId FROM cmsPropertyData " +
|
||||
"INNER JOIN umbracoNode ON cmsPropertyData.contentNodeId = umbracoNode.id " +
|
||||
"INNER JOIN cmsPropertyType ON cmsPropertyType.id = cmsPropertyData.propertytypeid " +
|
||||
"INNER JOIN cmsDataType ON cmsPropertyType.dataTypeId = cmsDataType.nodeId "+
|
||||
"WHERE umbracoNode.nodeObjectType = '" + Constants.ObjectTypes.Media + "'" + additionWhereStatement + ") as property")
|
||||
.On("umbracoNode.id = property.contentNodeId");
|
||||
}
|
||||
|
||||
return sql;
|
||||
}
|
||||
|
||||
protected virtual Sql GetBaseWhere(Func<bool, bool, Sql> baseQuery, bool isContent, bool isMedia, Guid id)
|
||||
protected virtual Sql GetBaseWhere(Func<bool, bool, string, Sql> baseQuery, bool isContent, bool isMedia, string additionWhereStatement, Guid id)
|
||||
{
|
||||
var sql = baseQuery(isContent, isMedia)
|
||||
var sql = baseQuery(isContent, isMedia, additionWhereStatement)
|
||||
.Where("umbracoNode.nodeObjectType = @NodeObjectType", new { NodeObjectType = id });
|
||||
return sql;
|
||||
}
|
||||
|
||||
protected virtual Sql GetBaseWhere(Func<bool, bool, Sql> baseQuery, bool isContent, bool isMedia, int id)
|
||||
protected virtual Sql GetBaseWhere(Func<bool, bool, string, Sql> baseQuery, bool isContent, bool isMedia, int id)
|
||||
{
|
||||
var sql = baseQuery(isContent, isMedia)
|
||||
var sql = baseQuery(isContent, isMedia, " AND umbracoNode.id = '"+ id +"'")
|
||||
.Where("umbracoNode.id = @Id", new { Id = id })
|
||||
.Append(GetGroupBy(isContent, isMedia));
|
||||
return sql;
|
||||
}
|
||||
|
||||
protected virtual Sql GetBaseWhere(Func<bool, bool, Sql> baseQuery, bool isContent, bool isMedia, Guid objectId, int id)
|
||||
protected virtual Sql GetBaseWhere(Func<bool, bool, string, Sql> baseQuery, bool isContent, bool isMedia, Guid objectId, int id)
|
||||
{
|
||||
var sql = baseQuery(isContent, isMedia)
|
||||
var sql = baseQuery(isContent, isMedia, " AND umbracoNode.id = '"+ id +"'")
|
||||
.Where("umbracoNode.id = @Id AND umbracoNode.nodeObjectType = @NodeObjectType",
|
||||
new {Id = id, NodeObjectType = objectId});
|
||||
return sql;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
|
||||
@@ -15,7 +16,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
IContent GetByLanguage(int id, string language);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all published Content byh the specified query
|
||||
/// Gets all published Content by the specified query
|
||||
/// </summary>
|
||||
/// <param name="query">Query to execute against published versions</param>
|
||||
/// <returns>An enumerable list of <see cref="IContent"/></returns>
|
||||
|
||||
@@ -4,6 +4,5 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
public interface IMediaRepository : IRepositoryVersionable<int, IMedia>
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -176,8 +176,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
protected override void PerformDeleteVersion(int id, Guid versionId)
|
||||
{
|
||||
Database.Delete<PreviewXmlDto>("WHERE nodeId = @Id AND versionId = @VersionId", new { Id = id, VersionId = versionId });
|
||||
Database.Delete<PropertyDataDto>("WHERE nodeId = @Id AND versionId = @VersionId", new { Id = id, VersionId = versionId });
|
||||
Database.Delete<ContentVersionDto>("WHERE nodeId = @Id AND VersionId = @VersionId", new { Id = id, VersionId = versionId });
|
||||
Database.Delete<PropertyDataDto>("WHERE contentNodeId = @Id AND versionId = @VersionId", new { Id = id, VersionId = versionId });
|
||||
Database.Delete<ContentVersionDto>("WHERE ContentId = @Id AND VersionId = @VersionId", new { Id = id, VersionId = versionId });
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a repository specific to the Recycle Bins
|
||||
/// available for Content and Media.
|
||||
/// </summary>
|
||||
internal class RecycleBinRepository : DisposableObject
|
||||
{
|
||||
private readonly IDatabaseUnitOfWork _unitOfWork;
|
||||
|
||||
public RecycleBinRepository(IDatabaseUnitOfWork unitOfWork)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of files, which are referenced on items in the Recycle Bin.
|
||||
/// The list is generated by the convention that a file is referenced by
|
||||
/// the Upload data type or a property type with the alias 'umbracoFile'.
|
||||
/// </summary>
|
||||
/// <param name="nodeObjectType"></param>
|
||||
/// <returns></returns>
|
||||
public List<string> GetFilesInRecycleBin(Guid nodeObjectType)
|
||||
{
|
||||
var db = _unitOfWork.Database;
|
||||
|
||||
//Issue query to get all trashed content or media that has the Upload field as a property
|
||||
//The value for each field is stored in a list: FilesToDelete<string>()
|
||||
//Alias: Constants.Conventions.Media.File and ControlId: Constants.PropertyEditors.UploadField
|
||||
var sql = new Sql();
|
||||
sql.Select("DISTINCT(dataNvarchar)")
|
||||
.From<PropertyDataDto>()
|
||||
.InnerJoin<NodeDto>().On<PropertyDataDto, NodeDto>(left => left.NodeId, right => right.NodeId)
|
||||
.InnerJoin<PropertyTypeDto>().On<PropertyDataDto, PropertyTypeDto>(left => left.PropertyTypeId, right => right.Id)
|
||||
.InnerJoin<DataTypeDto>().On<PropertyTypeDto, DataTypeDto>(left => left.DataTypeId, right => right.DataTypeId)
|
||||
.Where("umbracoNode.trashed = '1' AND umbracoNode.nodeObjectType = @NodeObjectType AND dataNvarchar IS NOT NULL AND (cmsPropertyType.Alias = @FileAlias OR cmsDataType.controlId = @ControlId)",
|
||||
new { FileAlias = Constants.Conventions.Media.File, NodeObjectType = nodeObjectType, ControlId = Constants.PropertyEditors.UploadField });
|
||||
|
||||
var files = db.Fetch<string>(sql);
|
||||
return files;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of Ids for each of the items in the Recycle Bin.
|
||||
/// </summary>
|
||||
/// <param name="nodeObjectType"></param>
|
||||
/// <returns></returns>
|
||||
public List<int> GetIdsOfItemsInRecycleBin(Guid nodeObjectType)
|
||||
{
|
||||
var db = _unitOfWork.Database;
|
||||
|
||||
var idsSql = new Sql();
|
||||
idsSql.Select("DISTINCT(id)")
|
||||
.From<NodeDto>()
|
||||
.Where<NodeDto>(x => x.Trashed && x.NodeObjectType == nodeObjectType);
|
||||
|
||||
var ids = db.Fetch<int>(idsSql);
|
||||
return ids;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Empties the Recycle Bin by running single bulk-Delete queries
|
||||
/// against the Content- or Media's Recycle Bin.
|
||||
/// </summary>
|
||||
/// <param name="nodeObjectType"></param>
|
||||
/// <returns></returns>
|
||||
public bool EmptyRecycleBin(Guid nodeObjectType)
|
||||
{
|
||||
var db = _unitOfWork.Database;
|
||||
|
||||
//Construct and execute delete statements for all trashed items by 'nodeObjectType'
|
||||
var deletes = new List<string>
|
||||
{
|
||||
FormatDeleteStatement("umbracoUser2NodeNotify", "nodeId"),
|
||||
FormatDeleteStatement("umbracoUser2NodePermission", "nodeId"),
|
||||
FormatDeleteStatement("umbracoRelation", "parentId"),
|
||||
FormatDeleteStatement("umbracoRelation", "childId"),
|
||||
FormatDeleteStatement("cmsTagRelationship", "nodeId"),
|
||||
FormatDeleteStatement("umbracoDomains", "domainRootStructureID"),
|
||||
FormatDeleteStatement("cmsDocument", "NodeId"),
|
||||
FormatDeleteStatement("cmsPropertyData", "contentNodeId"),
|
||||
FormatDeleteStatement("cmsPreviewXml", "nodeId"),
|
||||
FormatDeleteStatement("cmsContentVersion", "ContentId"),
|
||||
FormatDeleteStatement("cmsContentXml", "nodeID"),
|
||||
FormatDeleteStatement("cmsContent", "NodeId"),
|
||||
"UPDATE umbracoNode SET parentID = '-20' WHERE trashed = '1' AND nodeObjectType = @NodeObjectType",
|
||||
"DELETE FROM umbracoNode WHERE trashed = '1' AND nodeObjectType = @NodeObjectType"
|
||||
};
|
||||
|
||||
//Wraps in transaction - this improves performance and also ensures
|
||||
// that if any of the deletions fails that the whole thing is rolled back.
|
||||
using (var trans = db.GetTransaction())
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var delete in deletes)
|
||||
{
|
||||
db.Execute(delete, new { NodeObjectType = nodeObjectType });
|
||||
}
|
||||
|
||||
trans.Complete();
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
trans.Dispose();
|
||||
LogHelper.Error<RecycleBinRepository>("An error occurred while emptying the Recycle Bin: " + ex.Message, ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes all files passed in.
|
||||
/// </summary>
|
||||
/// <param name="files"></param>
|
||||
/// <returns></returns>
|
||||
public bool DeleteFiles(IEnumerable<string> files)
|
||||
{
|
||||
try
|
||||
{
|
||||
var fs = FileSystemProviderManager.Current.GetFileSystemProvider<MediaFileSystem>();
|
||||
Parallel.ForEach(files, file =>
|
||||
{
|
||||
if (UmbracoSettings.UploadAllowDirectories)
|
||||
{
|
||||
var relativeFilePath = fs.GetRelativePath(file);
|
||||
var parentDirectory = System.IO.Path.GetDirectoryName(relativeFilePath);
|
||||
fs.DeleteDirectory(parentDirectory, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
fs.DeleteFile(file, true);
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.Error<RecycleBinRepository>("An error occurred while deleting files attached to deleted nodes: " + ex.Message, ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private string FormatDeleteStatement(string tableName, string keyName)
|
||||
{
|
||||
//This query works with sql ce and sql server:
|
||||
//DELETE FROM umbracoUser2NodeNotify WHERE umbracoUser2NodeNotify.nodeId IN
|
||||
//(SELECT nodeId FROM umbracoUser2NodeNotify as TB1 INNER JOIN umbracoNode as TB2 ON TB1.nodeId = TB2.id WHERE TB2.trashed = '1' AND TB2.nodeObjectType = 'C66BA18E-EAF3-4CFF-8A22-41B16D66A972')
|
||||
return
|
||||
string.Format(
|
||||
"DELETE FROM {0} WHERE {0}.{1} IN (SELECT TB1.{1} FROM {0} as TB1 INNER JOIN umbracoNode as TB2 ON TB1.{1} = TB2.id WHERE TB2.trashed = '1' AND TB2.nodeObjectType = @NodeObjectType)",
|
||||
tableName, keyName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose disposable properties
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Ensure the unit of work is disposed
|
||||
/// </remarks>
|
||||
protected override void DisposeResources()
|
||||
{
|
||||
_unitOfWork.DisposeIfDisposable();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -85,11 +85,10 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <returns></returns>
|
||||
public TEntity Get(TId id)
|
||||
{
|
||||
Guid key = id is int ? ConvertIdToGuid(id) : ConvertStringIdToGuid(id.ToString());
|
||||
var rEntity = _cache.GetById(typeof(TEntity), key);
|
||||
if (rEntity != null)
|
||||
var fromCache = TryGetFromCache(id);
|
||||
if (fromCache.Success)
|
||||
{
|
||||
return (TEntity)rEntity;
|
||||
return fromCache.Result;
|
||||
}
|
||||
|
||||
var entity = PerformGet(id);
|
||||
@@ -112,6 +111,17 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
return entity;
|
||||
}
|
||||
|
||||
protected Attempt<TEntity> TryGetFromCache(TId id)
|
||||
{
|
||||
Guid key = id is int ? ConvertIdToGuid(id) : ConvertStringIdToGuid(id.ToString());
|
||||
var rEntity = _cache.GetById(typeof(TEntity), key);
|
||||
if (rEntity != null)
|
||||
{
|
||||
return new Attempt<TEntity>(true, (TEntity) rEntity);
|
||||
}
|
||||
return Attempt<TEntity>.False;
|
||||
}
|
||||
|
||||
protected abstract IEnumerable<TEntity> PerformGetAll(params TId[] ids);
|
||||
/// <summary>
|
||||
/// Gets all entities of type TEntity or a list according to the passed in Ids
|
||||
@@ -173,14 +183,12 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <returns></returns>
|
||||
public bool Exists(TId id)
|
||||
{
|
||||
Guid key = id is int ? ConvertIdToGuid(id) : ConvertStringIdToGuid(id.ToString());
|
||||
var rEntity = _cache.GetById(typeof(TEntity), key);
|
||||
if (rEntity != null)
|
||||
var fromCache = TryGetFromCache(id);
|
||||
if (fromCache.Success)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return PerformExists(id);
|
||||
return PerformExists(id);
|
||||
}
|
||||
|
||||
protected abstract int PerformCount(IQuery<TEntity> query);
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
public int Compare(string x, string y)
|
||||
{
|
||||
if (x.LastIndexOf(')') == x.Length - 1 && y.LastIndexOf(')') == y.Length - 1)
|
||||
if (x.LastIndexOf('(') != -1 && x.LastIndexOf(')') == x.Length - 1 && y.LastIndexOf(')') == y.Length - 1)
|
||||
{
|
||||
if (x.ToLower().Substring(0, x.LastIndexOf('(')) == y.ToLower().Substring(0, y.LastIndexOf('(')))
|
||||
{
|
||||
|
||||
@@ -43,8 +43,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
public virtual void DeleteVersion(Guid versionId)
|
||||
{
|
||||
var dto = Database.FirstOrDefault<ContentVersionDto>("WHERE versionId = @VersionId AND newest = @Newest", new { VersionId = versionId, Newest = false });
|
||||
Mandate.That<Exception>(dto != null);
|
||||
var dto = Database.FirstOrDefault<ContentVersionDto>("WHERE versionId = @VersionId", new { VersionId = versionId });
|
||||
if(dto == null) return;
|
||||
|
||||
using (var transaction = Database.GetTransaction())
|
||||
{
|
||||
@@ -56,8 +56,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
public virtual void DeleteVersions(int id, DateTime versionDate)
|
||||
{
|
||||
var list = Database.Fetch<ContentVersionDto>("WHERE nodeId = @Id AND VersionDate < @VersionDate", new { Id = id, VersionDate = versionDate });
|
||||
Mandate.That<Exception>(list.Any());
|
||||
var list = Database.Fetch<ContentVersionDto>("WHERE ContentId = @Id AND VersionDate < @VersionDate", new { Id = id, VersionDate = versionDate });
|
||||
if (list.Any() == false) return;
|
||||
|
||||
using (var transaction = Database.GetTransaction())
|
||||
{
|
||||
|
||||
@@ -9,34 +9,6 @@ namespace Umbraco.Core.Persistence
|
||||
/// </summary>
|
||||
public class RepositoryFactory
|
||||
{
|
||||
|
||||
internal virtual ServerRegistrationRepository CreateServerRegistrationRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new ServerRegistrationRepository(
|
||||
uow,
|
||||
NullCacheProvider.Current);
|
||||
}
|
||||
|
||||
internal virtual IUserTypeRepository CreateUserTypeRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new UserTypeRepository(
|
||||
uow,
|
||||
NullCacheProvider.Current);
|
||||
}
|
||||
|
||||
internal virtual IUserRepository CreateUserRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new UserRepository(
|
||||
uow,
|
||||
NullCacheProvider.Current,
|
||||
CreateUserTypeRepository(uow));
|
||||
}
|
||||
|
||||
internal virtual IEntityRepository CreateEntityRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new EntityRepository(uow);
|
||||
}
|
||||
|
||||
public virtual IContentRepository CreateContentRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new ContentRepository(
|
||||
@@ -120,5 +92,37 @@ namespace Umbraco.Core.Persistence
|
||||
{
|
||||
return new TemplateRepository(uow, RuntimeCacheProvider.Current);
|
||||
}
|
||||
|
||||
internal virtual ServerRegistrationRepository CreateServerRegistrationRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new ServerRegistrationRepository(
|
||||
uow,
|
||||
NullCacheProvider.Current);
|
||||
}
|
||||
|
||||
internal virtual IUserTypeRepository CreateUserTypeRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new UserTypeRepository(
|
||||
uow,
|
||||
NullCacheProvider.Current);
|
||||
}
|
||||
|
||||
internal virtual IUserRepository CreateUserRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new UserRepository(
|
||||
uow,
|
||||
NullCacheProvider.Current,
|
||||
CreateUserTypeRepository(uow));
|
||||
}
|
||||
|
||||
internal virtual IEntityRepository CreateEntityRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new EntityRepository(uow);
|
||||
}
|
||||
|
||||
internal virtual RecycleBinRepository CreateRecycleBinRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new RecycleBinRepository(uow);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,20 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
public static ISqlSyntaxProvider Provider { get { return new SqlServerSyntaxProvider(); } }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the version name of SQL server (i.e. the year 2008, 2005, etc...)
|
||||
/// </summary>
|
||||
internal enum SqlServerVersionName
|
||||
{
|
||||
Invalid = -1,
|
||||
V7 = 0,
|
||||
V2000 = 1,
|
||||
V2005 = 2,
|
||||
V2008 = 3,
|
||||
V2012 = 4,
|
||||
Other = 5
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents an SqlSyntaxProvider for Sql Server
|
||||
/// </summary>
|
||||
@@ -36,6 +50,11 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
InitColumnTypeMap();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets the version of the current SQL server instance
|
||||
/// </summary>
|
||||
internal Lazy<SqlServerVersionName> VersionName { get; set; }
|
||||
|
||||
public override string GetQuotedTableName(string tableName)
|
||||
{
|
||||
return string.Format("[{0}]", tableName);
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Umbraco.Core.Persistence
|
||||
/// can then override any additional execution (such as additional loggging, functionality, etc...) that we need to without breaking compatibility since we'll always be exposing
|
||||
/// this object instead of the base PetaPoco database object.
|
||||
/// </remarks>
|
||||
public class UmbracoDatabase : Database
|
||||
public class UmbracoDatabase : Database, IDisposeOnRequestEnd
|
||||
{
|
||||
private readonly Guid _instanceId = Guid.NewGuid();
|
||||
/// <summary>
|
||||
|
||||
@@ -20,7 +20,6 @@ using File = System.IO.File;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Used to resolve all plugin types and cache them and is also used to instantiate plugin types
|
||||
/// </summary>
|
||||
@@ -37,6 +36,7 @@ namespace Umbraco.Core
|
||||
internal class PluginManager
|
||||
{
|
||||
private readonly ApplicationContext _appContext;
|
||||
private const string CacheKey = "umbraco-plugins.list";
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new PluginManager with an ApplicationContext instance which ensures that the plugin xml
|
||||
@@ -251,7 +251,7 @@ namespace Umbraco.Core
|
||||
XDocument xml;
|
||||
if (_appContext != null)
|
||||
{
|
||||
xml = _appContext.ApplicationCache.GetCacheItem("umbraco-plugins.list",
|
||||
xml = _appContext.ApplicationCache.GetCacheItem(CacheKey,
|
||||
new TimeSpan(0, 0, 5, 0),
|
||||
() => XDocument.Load(filePath));
|
||||
}
|
||||
@@ -304,18 +304,18 @@ namespace Umbraco.Core
|
||||
|
||||
if (_appContext != null)
|
||||
{
|
||||
_appContext.ApplicationCache.ClearCacheItem("umbraco-plugins.list");
|
||||
_appContext.ApplicationCache.ClearCacheItem(CacheKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private string GetPluginListFilePath()
|
||||
{
|
||||
return Path.Combine(_tempFolder, "umbraco-plugins.list");
|
||||
return Path.Combine(_tempFolder, string.Format("umbraco-plugins.{0}.list", NetworkHelper.FileSafeMachineName));
|
||||
}
|
||||
|
||||
private string GetPluginHashFilePath()
|
||||
{
|
||||
return Path.Combine(_tempFolder, "umbraco-plugins.hash");
|
||||
return Path.Combine(_tempFolder, string.Format("umbraco-plugins.{0}.hash", NetworkHelper.FileSafeMachineName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -8,15 +8,14 @@ namespace Umbraco.Core.Publishing
|
||||
/// </summary>
|
||||
internal class PublishStatus
|
||||
{
|
||||
public IContent ContentItem { get; private set; }
|
||||
public PublishStatusType StatusType { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets sets the invalid properties if the status failed due to validation.
|
||||
/// </summary>
|
||||
public IEnumerable<Property> InvalidProperties { get; set; }
|
||||
public PublishStatus()
|
||||
{
|
||||
//initialize
|
||||
InvalidProperties = new List<Property>();
|
||||
}
|
||||
|
||||
public PublishStatus(IContent content, PublishStatusType statusType)
|
||||
: this()
|
||||
{
|
||||
ContentItem = content;
|
||||
StatusType = statusType;
|
||||
@@ -29,6 +28,13 @@ namespace Umbraco.Core.Publishing
|
||||
: this(content, PublishStatusType.Success)
|
||||
{
|
||||
}
|
||||
|
||||
public IContent ContentItem { get; private set; }
|
||||
public PublishStatusType StatusType { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets sets the invalid properties if the status failed due to validation.
|
||||
/// </summary>
|
||||
public IEnumerable<Property> InvalidProperties { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
using System;
|
||||
using System.Web;
|
||||
using System.Web.Security;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core.Security
|
||||
{
|
||||
internal static class FormsAuthenticationTicketExtensions
|
||||
{
|
||||
public static UmbracoBackOfficeIdentity CreateUmbracoIdentity(this FormsAuthenticationTicket ticket)
|
||||
{
|
||||
try
|
||||
{
|
||||
//create the Umbraco user identity
|
||||
return new UmbracoBackOfficeIdentity(ticket);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//This might occur if we cannot decrypt the value in which case we'll just ignore it, it will
|
||||
// be handled by the base pages
|
||||
LogHelper.Error(typeof(FormsAuthenticationTicketExtensions), "An error occurred decrypting the user's ticket", ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extensions to create and renew and remove authentication tickets for the Umbraco back office
|
||||
/// </summary>
|
||||
internal static class AuthenticationExtensions
|
||||
{
|
||||
//public static UmbracoBackOfficeIdentity GetCurrentIdentity(this HttpContextBase http)
|
||||
//{
|
||||
// return http.User.Identity as UmbracoBackOfficeIdentity;
|
||||
//}
|
||||
|
||||
//internal static UmbracoBackOfficeIdentity GetCurrentIdentity(this HttpContext http)
|
||||
//{
|
||||
// return new HttpContextWrapper(http).GetCurrentIdentity();
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// This clears the authentication cookie
|
||||
/// </summary>
|
||||
public static void UmbracoLogout(this HttpContextBase http)
|
||||
{
|
||||
Logout(http, UmbracoSettings.AuthCookieName);
|
||||
}
|
||||
|
||||
internal static void UmbracoLogout(this HttpContext http)
|
||||
{
|
||||
new HttpContextWrapper(http).UmbracoLogout();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the umbraco authentication ticket
|
||||
/// </summary>
|
||||
/// <param name="http"></param>
|
||||
/// <param name="userdata"></param>
|
||||
public static void CreateUmbracoAuthTicket(this HttpContextBase http, UserData userdata)
|
||||
{
|
||||
CreateAuthTicket(
|
||||
http,
|
||||
userdata,
|
||||
//This is one full day... this is how Umbraco has always created this cookie, it is setup to always
|
||||
//expire one day from issue and it never gets updated.
|
||||
1440,
|
||||
"/",
|
||||
UmbracoSettings.AuthCookieName,
|
||||
UmbracoSettings.AuthCookieDomain);
|
||||
}
|
||||
|
||||
internal static void CreateUmbracoAuthTicket(this HttpContext http, UserData userdata)
|
||||
{
|
||||
new HttpContextWrapper(http).CreateUmbracoAuthTicket(userdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the umbraco auth ticket
|
||||
/// </summary>
|
||||
/// <param name="http"></param>
|
||||
/// <returns></returns>
|
||||
public static FormsAuthenticationTicket GetUmbracoAuthTicket(this HttpContextBase http)
|
||||
{
|
||||
return GetAuthTicket(http, UmbracoSettings.AuthCookieName);
|
||||
}
|
||||
|
||||
internal static FormsAuthenticationTicket GetUmbracoAuthTicket(this HttpContext http)
|
||||
{
|
||||
return new HttpContextWrapper(http).GetUmbracoAuthTicket();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This clears the authentication cookie
|
||||
/// </summary>
|
||||
/// <param name="http"></param>
|
||||
/// <param name="cookieName"></param>
|
||||
private static void Logout(this HttpContextBase http, string cookieName)
|
||||
{
|
||||
//remove from the request
|
||||
http.Request.Cookies.Remove(cookieName);
|
||||
|
||||
//expire from the response
|
||||
var formsCookie = http.Response.Cookies[cookieName];
|
||||
if (formsCookie != null)
|
||||
{
|
||||
//this will expire immediately and be removed from the browser
|
||||
formsCookie.Expires = DateTime.Now.AddYears(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
//ensure there's def an expired cookie
|
||||
http.Response.Cookies.Add(new HttpCookie(cookieName) { Expires = DateTime.Now.AddYears(-1) });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// In v6 this is a custom cookie, in v7 this is a real formsauth cookie.
|
||||
/// </summary>
|
||||
/// <param name="http"></param>
|
||||
/// <param name="cookieName"></param>
|
||||
/// <returns></returns>
|
||||
private static FormsAuthenticationTicket GetAuthTicket(this HttpContextBase http, string cookieName)
|
||||
{
|
||||
var formsCookie = http.Request.Cookies[cookieName];
|
||||
if (formsCookie == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
//get the cookie value
|
||||
var cookieVal = formsCookie.Value.DecryptWithMachineKey();
|
||||
|
||||
//here we need to see if the cookie val can be serialized into UserData, if not it means it's probably an old cookie
|
||||
var deserialized = JsonConvert.DeserializeObject<UserData>(cookieVal);
|
||||
|
||||
//in v6, we're not using real FormsAuth but our own custom cookie and then we just return a custom FormsAuth ticket
|
||||
// for this request.
|
||||
return new FormsAuthenticationTicket(
|
||||
4,
|
||||
deserialized.RealName,
|
||||
DateTime.Now,
|
||||
DateTime.Now.AddMinutes(GlobalSettings.TimeOutInMinutes),
|
||||
false,
|
||||
cookieVal,
|
||||
"/");
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//occurs when decryption fails
|
||||
http.Logout(cookieName);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a custom umbraco auth cookie with the data specified
|
||||
/// </summary>
|
||||
/// <param name="http">The HTTP.</param>
|
||||
/// <param name="userData">The user data.</param>
|
||||
/// <param name="minutesPersisted">The minutes persisted.</param>
|
||||
/// <param name="cookiePath">The cookie path.</param>
|
||||
/// <param name="cookieName">Name of the cookie.</param>
|
||||
/// <param name="cookieDomain">The cookie domain.</param>
|
||||
private static void CreateAuthTicket(this HttpContextBase http,
|
||||
UserData userData,
|
||||
int minutesPersisted,
|
||||
string cookiePath,
|
||||
string cookieName,
|
||||
string cookieDomain)
|
||||
{
|
||||
var cookie = new HttpCookie(cookieName);
|
||||
|
||||
if (GlobalSettings.UseSSL)
|
||||
cookie.Secure = true;
|
||||
|
||||
//ensure http only, this should only be able to be accessed via the server
|
||||
cookie.HttpOnly = true;
|
||||
cookie.Path = cookiePath;
|
||||
cookie.Domain = cookieDomain;
|
||||
cookie.Expires = DateTime.Now.AddMinutes(minutesPersisted);
|
||||
|
||||
//serialize the user data
|
||||
var json = JsonConvert.SerializeObject(userData);
|
||||
//encrypt it
|
||||
var encTicket = json.EncryptWithMachineKey();
|
||||
|
||||
//set the cookie value
|
||||
cookie.Value = encTicket;
|
||||
|
||||
http.Response.Cookies.Set(cookie);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
using System;
|
||||
using System.Web;
|
||||
using System.Web.Security;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Umbraco.Core.Security
|
||||
{
|
||||
/// <summary>
|
||||
/// A custom user identity for the Umbraco backoffice
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// All values are lazy loaded for performance reasons as the constructor is called for every single request
|
||||
/// </remarks>
|
||||
internal class UmbracoBackOfficeIdentity : FormsIdentity
|
||||
{
|
||||
public UmbracoBackOfficeIdentity(FormsAuthenticationTicket ticket)
|
||||
: base(ticket)
|
||||
{
|
||||
UserData = ticket.UserData;
|
||||
EnsureDeserialized();
|
||||
}
|
||||
|
||||
protected readonly string UserData;
|
||||
internal UserData DeserializedData;
|
||||
|
||||
public string UserContextId
|
||||
{
|
||||
get { return DeserializedData.UserContextId; }
|
||||
}
|
||||
|
||||
public int StartContentNode
|
||||
{
|
||||
get { return DeserializedData.StartContentNode; }
|
||||
}
|
||||
|
||||
public int StartMediaNode
|
||||
{
|
||||
get { return DeserializedData.StartMediaNode; }
|
||||
}
|
||||
|
||||
public string[] AllowedApplications
|
||||
{
|
||||
get { return DeserializedData.AllowedApplications; }
|
||||
}
|
||||
|
||||
public object Id
|
||||
{
|
||||
get { return DeserializedData.Id; }
|
||||
}
|
||||
|
||||
public string RealName
|
||||
{
|
||||
get { return DeserializedData.RealName; }
|
||||
}
|
||||
|
||||
public string Culture
|
||||
{
|
||||
get { return DeserializedData.Culture; }
|
||||
}
|
||||
|
||||
//public int SessionTimeout
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// EnsureDeserialized();
|
||||
// return DeserializedData.SessionTimeout;
|
||||
// }
|
||||
//}
|
||||
|
||||
public string[] Roles
|
||||
{
|
||||
get { return DeserializedData.Roles; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This will ensure we only deserialize once
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For performance reasons, we'll also check if there's an http context available,
|
||||
/// if so, we'll chuck our instance in there so that we only deserialize once per request.
|
||||
/// </remarks>
|
||||
protected void EnsureDeserialized()
|
||||
{
|
||||
if (DeserializedData != null)
|
||||
return;
|
||||
|
||||
if (HttpContext.Current != null)
|
||||
{
|
||||
//check if we've already done this in this request
|
||||
var data = HttpContext.Current.Items[typeof(UmbracoBackOfficeIdentity)] as UserData;
|
||||
if (data != null)
|
||||
{
|
||||
DeserializedData = data;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(UserData))
|
||||
{
|
||||
throw new NullReferenceException("The " + typeof(UserData) + " found in the ticket cannot be empty");
|
||||
}
|
||||
DeserializedData = JsonConvert.DeserializeObject<UserData>(UserData);
|
||||
|
||||
if (HttpContext.Current != null)
|
||||
{
|
||||
HttpContext.Current.Items[typeof (UmbracoBackOfficeIdentity)] = DeserializedData;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Umbraco.Core.Security
|
||||
{
|
||||
/// <summary>
|
||||
/// Data structure used to store information in the authentication cookie
|
||||
/// </summary>
|
||||
[DataContract(Name = "userData", Namespace = "")]
|
||||
internal class UserData
|
||||
{
|
||||
public UserData()
|
||||
{
|
||||
AllowedApplications = new string[] {};
|
||||
Roles = new string[] {};
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// When their session is going to expire (in ticks)
|
||||
///// </summary>
|
||||
//[DataMember(Name = "timeout")]
|
||||
//public long Timeout { get; set; }
|
||||
|
||||
[DataMember(Name = "userContextId")]
|
||||
public string UserContextId { get; set; }
|
||||
|
||||
[DataMember(Name = "id")]
|
||||
public object Id { get; set; }
|
||||
|
||||
[DataMember(Name = "roles")]
|
||||
public string[] Roles { get; set; }
|
||||
|
||||
[DataMember(Name = "username")]
|
||||
public string Username { get; set; }
|
||||
|
||||
[DataMember(Name = "name")]
|
||||
public string RealName { get; set; }
|
||||
|
||||
[DataMember(Name = "startContent")]
|
||||
public int StartContentNode { get; set; }
|
||||
|
||||
[DataMember(Name = "startMedia")]
|
||||
public int StartMediaNode { get; set; }
|
||||
|
||||
[DataMember(Name = "allowedApps")]
|
||||
public string[] AllowedApplications { get; set; }
|
||||
|
||||
[DataMember(Name = "culture")]
|
||||
public string Culture { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Caching;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Persistence.Repositories;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using Umbraco.Core.Publishing;
|
||||
|
||||
@@ -250,6 +251,17 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
internal IEnumerable<IContent> GetPublishedContentOfContentType(int id)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
var query = Query<IContent>.Builder.Where(x => x.ContentTypeId == id);
|
||||
var contents = repository.GetByPublishedVersion(query);
|
||||
|
||||
return contents;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IContent"/> objects by Level
|
||||
/// </summary>
|
||||
@@ -431,6 +443,19 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all published content items
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal IEnumerable<IContent> GetAllPublished()
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
var query = Query<IContent>.Builder.Where(x => x.Trashed == false);
|
||||
return repository.GetByPublishedVersion(query);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IContent"/> objects, which has an expiration date less than or equal to today.
|
||||
/// </summary>
|
||||
@@ -986,27 +1011,29 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
public void EmptyRecycleBin()
|
||||
{
|
||||
//TODO: Why don't we have a base class to share between MediaService/ContentService as some of this is exacty the same?
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var query = Query<IContent>.Builder.Where(x => x.Trashed == true);
|
||||
var contents = repository.GetByQuery(query).OrderByDescending(x => x.Level);
|
||||
List<int> ids;
|
||||
List<string> files;
|
||||
bool success;
|
||||
var nodeObjectType = new Guid(Constants.ObjectTypes.Document);
|
||||
|
||||
foreach (var content in contents)
|
||||
using (var repository = _repositoryFactory.CreateRecycleBinRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
if (Deleting.IsRaisedEventCancelled(new DeleteEventArgs<IContent>(content), this))
|
||||
continue;
|
||||
ids = repository.GetIdsOfItemsInRecycleBin(nodeObjectType);
|
||||
files = repository.GetFilesInRecycleBin(nodeObjectType);
|
||||
|
||||
repository.Delete(content);
|
||||
if (EmptyingRecycleBin.IsRaisedEventCancelled(new RecycleBinEventArgs(nodeObjectType, ids, files), this))
|
||||
return;
|
||||
|
||||
Deleted.RaiseEvent(new DeleteEventArgs<IContent>(content, false), this);
|
||||
success = repository.EmptyRecycleBin(nodeObjectType);
|
||||
if (success)
|
||||
repository.DeleteFiles(files);
|
||||
}
|
||||
uow.Commit();
|
||||
}
|
||||
|
||||
Audit.Add(AuditTypes.Delete, "Empty Recycle Bin performed by user", 0, -20);
|
||||
EmptiedRecycleBin.RaiseEvent(new RecycleBinEventArgs(nodeObjectType, ids, files, success), this);
|
||||
}
|
||||
Audit.Add(AuditTypes.Delete, "Empty Content Recycle Bin performed by user", 0, -20);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1353,46 +1380,45 @@ namespace Umbraco.Core.Services
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
if (contentTypeIds.Any() == false)
|
||||
{
|
||||
//Remove all Document records from the cmsContentXml table (DO NOT REMOVE Media/Members!)
|
||||
uow.Database.Execute(@"DELETE FROM cmsContentXml WHERE nodeId IN
|
||||
(SELECT DISTINCT cmsContentXml.nodeId FROM cmsContentXml
|
||||
INNER JOIN cmsDocument ON cmsContentXml.nodeId = cmsDocument.nodeId)");
|
||||
|
||||
//get all content items that are published
|
||||
// Consider creating a Path query instead of recursive method:
|
||||
// var query = Query<IContent>.Builder.Where(x => x.Path.StartsWith("-1"));
|
||||
var rootContent = GetRootContent();
|
||||
foreach (var content in rootContent.Where(content => content.Published))
|
||||
{
|
||||
list.Add(content);
|
||||
list.AddRange(GetPublishedDescendants(content));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var id in contentTypeIds)
|
||||
{
|
||||
//first we'll clear out the data from the cmsContentXml table for this type
|
||||
uow.Database.Execute(@"delete from cmsContentXml where nodeId in
|
||||
(select cmsDocument.nodeId from cmsDocument
|
||||
inner join cmsContent on cmsDocument.nodeId = cmsContent.nodeId
|
||||
where published = 1 and contentType = @contentTypeId)", new {contentTypeId = id});
|
||||
//First we're going to get the data that needs to be inserted before clearing anything, this
|
||||
//ensures that we don't accidentally leave the content xml table empty if something happens
|
||||
//during the lookup process.
|
||||
|
||||
//now get all published content objects of this type and add to the list
|
||||
list.AddRange(GetContentOfContentType(id).Where(content => content.Published));
|
||||
}
|
||||
}
|
||||
list.AddRange(contentTypeIds.Any() == false
|
||||
? GetAllPublished()
|
||||
: contentTypeIds.SelectMany(GetPublishedContentOfContentType));
|
||||
|
||||
var xmlItems = new List<ContentXmlDto>();
|
||||
foreach (var c in list)
|
||||
{
|
||||
//generate the xml
|
||||
var xml = c.ToXml();
|
||||
//create the dto to insert
|
||||
var poco = new ContentXmlDto { NodeId = c.Id, Xml = xml.ToString(SaveOptions.None) };
|
||||
//insert it into the database
|
||||
uow.Database.Insert(poco);
|
||||
xmlItems.Add(new ContentXmlDto {NodeId = c.Id, Xml = xml.ToString(SaveOptions.None)});
|
||||
}
|
||||
|
||||
//Ok, now we need to remove the data and re-insert it, we'll do this all in one transaction too.
|
||||
using (var tr = uow.Database.GetTransaction())
|
||||
{
|
||||
if (contentTypeIds.Any() == false)
|
||||
{
|
||||
//Remove all Document records from the cmsContentXml table (DO NOT REMOVE Media/Members!)
|
||||
uow.Database.Execute(@"DELETE FROM cmsContentXml WHERE nodeId IN
|
||||
(SELECT DISTINCT cmsContentXml.nodeId FROM cmsContentXml
|
||||
INNER JOIN cmsDocument ON cmsContentXml.nodeId = cmsDocument.nodeId)");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var id in contentTypeIds)
|
||||
{
|
||||
//first we'll clear out the data from the cmsContentXml table for this type
|
||||
uow.Database.Execute(@"delete from cmsContentXml where nodeId in
|
||||
(select cmsDocument.nodeId from cmsDocument
|
||||
inner join cmsContent on cmsDocument.nodeId = cmsContent.nodeId
|
||||
where published = 1 and contentType = @contentTypeId)", new { contentTypeId = id });
|
||||
}
|
||||
}
|
||||
|
||||
//bulk insert it into the database
|
||||
uow.Database.BulkInsertRecords(xmlItems, tr);
|
||||
}
|
||||
}
|
||||
Audit.Add(AuditTypes.Publish, "RebuildXmlStructures completed, the xml has been regenerated in the database", 0, -1);
|
||||
@@ -1436,7 +1462,12 @@ namespace Umbraco.Core.Services
|
||||
LogHelper.Info<ContentService>(
|
||||
string.Format("Content '{0}' with Id '{1}' could not be published because of invalid properties.",
|
||||
content.Name, content.Id));
|
||||
result.Add(new Attempt<PublishStatus>(false, new PublishStatus(content, PublishStatusType.FailedContentInvalid)));
|
||||
result.Add(
|
||||
new Attempt<PublishStatus>(false,
|
||||
new PublishStatus(content, PublishStatusType.FailedContentInvalid)
|
||||
{
|
||||
InvalidProperties = ((ContentBase) content).LastInvalidProperties
|
||||
}));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1854,7 +1885,7 @@ namespace Umbraco.Core.Services
|
||||
/// Occurs after Create
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Please note that the Content object has been created, but not saved
|
||||
/// Please note that the Content object has been created, but might not have been saved
|
||||
/// so it does not have an identity yet (meaning no Id has been set).
|
||||
/// </remarks>
|
||||
public static event TypedEventHandler<IContentService, NewEventArgs<IContent>> Created;
|
||||
@@ -1908,6 +1939,16 @@ namespace Umbraco.Core.Services
|
||||
/// Occurs after Send to Publish
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IContentService, SendToPublishEventArgs<IContent>> SentToPublish;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs before the Recycle Bin is emptied
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IContentService, RecycleBinEventArgs> EmptyingRecycleBin;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs after the Recycle Bin has been Emptied
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IContentService, RecycleBinEventArgs> EmptiedRecycleBin;
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -11,10 +11,11 @@ using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using Umbraco.Core.Publishing;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Represents the Media Service, which is an easy access to operations involving <see cref="IMedia"/>
|
||||
/// </summary>
|
||||
public class MediaService : IMediaService
|
||||
@@ -536,27 +537,29 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
public void EmptyRecycleBin()
|
||||
{
|
||||
//TODO: Why don't we have a base class to share between MediaService/ContentService as some of this is exacty the same?
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
List<int> ids;
|
||||
List<string> files;
|
||||
bool success;
|
||||
var nodeObjectType = new Guid(Constants.ObjectTypes.Media);
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
|
||||
{
|
||||
var query = Query<IMedia>.Builder.Where(x => x.Trashed == true);
|
||||
var contents = repository.GetByQuery(query).OrderByDescending(x => x.Level);
|
||||
using (var repository = _repositoryFactory.CreateRecycleBinRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
ids = repository.GetIdsOfItemsInRecycleBin(nodeObjectType);
|
||||
files = repository.GetFilesInRecycleBin(nodeObjectType);
|
||||
|
||||
foreach (var content in contents)
|
||||
{
|
||||
if (Deleting.IsRaisedEventCancelled(new DeleteEventArgs<IMedia>(content), this))
|
||||
continue;
|
||||
if (EmptyingRecycleBin.IsRaisedEventCancelled(new RecycleBinEventArgs(nodeObjectType, ids, files), this))
|
||||
return;
|
||||
|
||||
repository.Delete(content);
|
||||
success = repository.EmptyRecycleBin(nodeObjectType);
|
||||
if (success)
|
||||
repository.DeleteFiles(files);
|
||||
}
|
||||
|
||||
Deleted.RaiseEvent(new DeleteEventArgs<IMedia>(content, false), this);
|
||||
}
|
||||
uow.Commit();
|
||||
}
|
||||
|
||||
Audit.Add(AuditTypes.Delete, "Empty Recycle Bin performed by user", 0, -20);
|
||||
EmptiedRecycleBin.RaiseEvent(new RecycleBinEventArgs(nodeObjectType, ids, files, success), this);
|
||||
}
|
||||
Audit.Add(AuditTypes.Delete, "Empty Media Recycle Bin performed by user", 0, -21);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -875,15 +878,16 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
var xmlItems = new List<ContentXmlDto>();
|
||||
foreach (var c in list)
|
||||
{
|
||||
//generate the xml
|
||||
var xml = c.ToXml();
|
||||
//create the dto to insert
|
||||
var poco = new ContentXmlDto { NodeId = c.Id, Xml = xml.ToString(SaveOptions.None) };
|
||||
//insert it into the database
|
||||
uow.Database.Insert(poco);
|
||||
xmlItems.Add(new ContentXmlDto { NodeId = c.Id, Xml = xml.ToString(SaveOptions.None) });
|
||||
}
|
||||
//bulk insert it into the database
|
||||
uow.Database.BulkInsertRecords(xmlItems);
|
||||
}
|
||||
Audit.Add(AuditTypes.Publish, "RebuildXmlStructures completed, the xml has been regenerated in the database", 0, -1);
|
||||
}
|
||||
@@ -1009,6 +1013,16 @@ namespace Umbraco.Core.Services
|
||||
/// Occurs after Move
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IMediaService, MoveEventArgs<IMedia>> Moved;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs before the Recycle Bin is emptied
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IMediaService, RecycleBinEventArgs> EmptyingRecycleBin;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs after the Recycle Bin has been Emptied
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IMediaService, RecycleBinEventArgs> EmptiedRecycleBin;
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -43,13 +43,13 @@ namespace Umbraco.Core.Services
|
||||
public IProfile GetProfileById(int id)
|
||||
{
|
||||
var user = GetUserById(id);
|
||||
return new Profile(user.Id, user.Username);
|
||||
return new Profile(user.Id, user.Name);
|
||||
}
|
||||
|
||||
public IProfile GetProfileByUserName(string username)
|
||||
{
|
||||
var user = GetUserByUserName(username);
|
||||
return new Profile(user.Id, user.Username);
|
||||
return new Profile(user.Id, user.Name);
|
||||
}
|
||||
|
||||
public IUser GetUserByUserName(string username)
|
||||
|
||||
@@ -28,6 +28,27 @@ namespace Umbraco.Core
|
||||
[UmbracoWillObsolete("Do not use this constants. See IShortStringHelper.CleanStringForSafeAliasJavaScriptCode.")]
|
||||
public const string UmbracoInvalidFirstCharacters = "01234567890";
|
||||
|
||||
internal static string ReplaceNonAlphanumericChars(this string input, char replacement)
|
||||
{
|
||||
//any character that is not alphanumeric, convert to a hyphen
|
||||
var mName = input;
|
||||
foreach (var c in mName.ToCharArray().Where(c => !char.IsLetterOrDigit(c)))
|
||||
{
|
||||
mName = mName.Replace(c, replacement);
|
||||
}
|
||||
return mName;
|
||||
}
|
||||
|
||||
public static string ExceptChars(this string str, HashSet<char> toExclude)
|
||||
{
|
||||
var sb = new StringBuilder(str.Length);
|
||||
foreach (var c in str.Where(c => toExclude.Contains(c) == false))
|
||||
{
|
||||
sb.Append(c);
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encrypt the string using the MachineKey in medium trust
|
||||
/// </summary>
|
||||
|
||||
+367
-342
@@ -19,54 +19,56 @@ using Umbraco.Core.IO;
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// A utility class to find all classes of a certain type by reflection in the current bin folder
|
||||
/// of the web application.
|
||||
/// </summary>
|
||||
public static class TypeFinder
|
||||
{
|
||||
|
||||
private static readonly ConcurrentBag<Assembly> LocalFilteredAssemblyCache = new ConcurrentBag<Assembly>();
|
||||
private static readonly ReaderWriterLockSlim LocalFilteredAssemblyCacheLocker = new ReaderWriterLockSlim();
|
||||
private static ReadOnlyCollection<Assembly> _allAssemblies = null;
|
||||
private static ReadOnlyCollection<Assembly> _binFolderAssemblies = null;
|
||||
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim();
|
||||
/// <summary>
|
||||
/// A utility class to find all classes of a certain type by reflection in the current bin folder
|
||||
/// of the web application.
|
||||
/// </summary>
|
||||
public static class TypeFinder
|
||||
{
|
||||
private static readonly HashSet<Assembly> LocalFilteredAssemblyCache = new HashSet<Assembly>();
|
||||
private static readonly ReaderWriterLockSlim LocalFilteredAssemblyCacheLocker = new ReaderWriterLockSlim();
|
||||
private static HashSet<Assembly> _allAssemblies = null;
|
||||
private static HashSet<Assembly> _binFolderAssemblies = null;
|
||||
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim();
|
||||
|
||||
/// <summary>
|
||||
/// lazily load a reference to all assemblies and only local assemblies.
|
||||
/// This is a modified version of: http://www.dominicpettifer.co.uk/Blog/44/how-to-get-a-reference-to-all-assemblies-in-the--bin-folder
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// We do this because we cannot use AppDomain.Current.GetAssemblies() as this will return only assemblies that have been
|
||||
/// loaded in the CLR, not all assemblies.
|
||||
/// See these threads:
|
||||
/// http://issues.umbraco.org/issue/U5-198
|
||||
/// http://stackoverflow.com/questions/3552223/asp-net-appdomain-currentdomain-getassemblies-assemblies-missing-after-app
|
||||
/// http://stackoverflow.com/questions/2477787/difference-between-appdomain-getassemblies-and-buildmanager-getreferencedassembl
|
||||
/// </remarks>
|
||||
internal static IEnumerable<Assembly> GetAllAssemblies()
|
||||
{
|
||||
if (_allAssemblies == null)
|
||||
{
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
List<Assembly> assemblies = null;
|
||||
try
|
||||
{
|
||||
var isHosted = HttpContext.Current != null;
|
||||
/// <summary>
|
||||
/// lazily load a reference to all assemblies and only local assemblies.
|
||||
/// This is a modified version of: http://www.dominicpettifer.co.uk/Blog/44/how-to-get-a-reference-to-all-assemblies-in-the--bin-folder
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// We do this because we cannot use AppDomain.Current.GetAssemblies() as this will return only assemblies that have been
|
||||
/// loaded in the CLR, not all assemblies.
|
||||
/// See these threads:
|
||||
/// http://issues.umbraco.org/issue/U5-198
|
||||
/// http://stackoverflow.com/questions/3552223/asp-net-appdomain-currentdomain-getassemblies-assemblies-missing-after-app
|
||||
/// http://stackoverflow.com/questions/2477787/difference-between-appdomain-getassemblies-and-buildmanager-getreferencedassembl
|
||||
/// </remarks>
|
||||
internal static HashSet<Assembly> GetAllAssemblies()
|
||||
{
|
||||
using (var lck = new UpgradeableReadLock(Locker))
|
||||
{
|
||||
if (_allAssemblies == null)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
if (isHosted)
|
||||
{
|
||||
assemblies = new List<Assembly>(BuildManager.GetReferencedAssemblies().Cast<Assembly>());
|
||||
}
|
||||
}
|
||||
catch (InvalidOperationException e)
|
||||
{
|
||||
if (!(e.InnerException is SecurityException))
|
||||
throw;
|
||||
}
|
||||
lck.UpgradeToWriteLock();
|
||||
|
||||
HashSet<Assembly> assemblies = null;
|
||||
try
|
||||
{
|
||||
var isHosted = HttpContext.Current != null;
|
||||
|
||||
try
|
||||
{
|
||||
if (isHosted)
|
||||
{
|
||||
assemblies = new HashSet<Assembly>(BuildManager.GetReferencedAssemblies().Cast<Assembly>());
|
||||
}
|
||||
}
|
||||
catch (InvalidOperationException e)
|
||||
{
|
||||
if (!(e.InnerException is SecurityException))
|
||||
throw;
|
||||
}
|
||||
|
||||
|
||||
if (assemblies == null)
|
||||
@@ -77,7 +79,7 @@ namespace Umbraco.Core
|
||||
var binAssemblyFiles = Directory.GetFiles(binFolder, "*.dll", SearchOption.TopDirectoryOnly).ToList();
|
||||
//var binFolder = Assembly.GetExecutingAssembly().GetAssemblyFile().Directory;
|
||||
//var binAssemblyFiles = Directory.GetFiles(binFolder.FullName, "*.dll", SearchOption.TopDirectoryOnly).ToList();
|
||||
assemblies = new List<Assembly>();
|
||||
assemblies = new HashSet<Assembly>();
|
||||
foreach (var a in binAssemblyFiles)
|
||||
{
|
||||
try
|
||||
@@ -99,151 +101,161 @@ namespace Umbraco.Core
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//if for some reason they are still no assemblies, then use the AppDomain to load in already loaded assemblies.
|
||||
if (!assemblies.Any())
|
||||
{
|
||||
assemblies.AddRange(AppDomain.CurrentDomain.GetAssemblies().ToList());
|
||||
}
|
||||
if (!assemblies.Any())
|
||||
{
|
||||
foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
assemblies.Add(a);
|
||||
}
|
||||
}
|
||||
|
||||
//here we are trying to get the App_Code assembly
|
||||
var fileExtensions = new[] {".cs", ".vb"}; //only vb and cs files are supported
|
||||
var appCodeFolder = new DirectoryInfo(IOHelper.MapPath(IOHelper.ResolveUrl("~/App_code")));
|
||||
//check if the folder exists and if there are any files in it with the supported file extensions
|
||||
if (appCodeFolder.Exists && (fileExtensions.Any(x => appCodeFolder.GetFiles("*" + x).Any())))
|
||||
{
|
||||
var appCodeAssembly = Assembly.Load("App_Code");
|
||||
if (!assemblies.Contains(appCodeAssembly)) // BuildManager will find App_Code already
|
||||
assemblies.Add(appCodeAssembly);
|
||||
}
|
||||
//here we are trying to get the App_Code assembly
|
||||
var fileExtensions = new[] { ".cs", ".vb" }; //only vb and cs files are supported
|
||||
var appCodeFolder = new DirectoryInfo(IOHelper.MapPath(IOHelper.ResolveUrl("~/App_code")));
|
||||
//check if the folder exists and if there are any files in it with the supported file extensions
|
||||
if (appCodeFolder.Exists && (fileExtensions.Any(x => appCodeFolder.GetFiles("*" + x).Any())))
|
||||
{
|
||||
var appCodeAssembly = Assembly.Load("App_Code");
|
||||
if (!assemblies.Contains(appCodeAssembly)) // BuildManager will find App_Code already
|
||||
assemblies.Add(appCodeAssembly);
|
||||
}
|
||||
|
||||
//now set the _allAssemblies
|
||||
_allAssemblies = new ReadOnlyCollection<Assembly>(assemblies);
|
||||
//now set the _allAssemblies
|
||||
_allAssemblies = new HashSet<Assembly>(assemblies);
|
||||
|
||||
}
|
||||
catch (InvalidOperationException e)
|
||||
{
|
||||
if (!(e.InnerException is SecurityException))
|
||||
throw;
|
||||
}
|
||||
catch (InvalidOperationException e)
|
||||
{
|
||||
if (!(e.InnerException is SecurityException))
|
||||
throw;
|
||||
|
||||
_binFolderAssemblies = _allAssemblies;
|
||||
}
|
||||
}
|
||||
}
|
||||
_binFolderAssemblies = _allAssemblies;
|
||||
}
|
||||
}
|
||||
|
||||
return _allAssemblies;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns only assemblies found in the bin folder that have been loaded into the app domain.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This will be used if we implement App_Plugins from Umbraco v5 but currently it is not used.
|
||||
/// </remarks>
|
||||
internal static IEnumerable<Assembly> GetBinAssemblies()
|
||||
{
|
||||
return _allAssemblies;
|
||||
}
|
||||
}
|
||||
|
||||
if (_binFolderAssemblies == null)
|
||||
{
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var assemblies = GetAssembliesWithKnownExclusions().ToArray();
|
||||
var binFolder = Assembly.GetExecutingAssembly().GetAssemblyFile().Directory;
|
||||
var binAssemblyFiles = Directory.GetFiles(binFolder.FullName, "*.dll", SearchOption.TopDirectoryOnly).ToList();
|
||||
var domainAssemblyNames = binAssemblyFiles.Select(AssemblyName.GetAssemblyName);
|
||||
var safeDomainAssemblies = new List<Assembly>();
|
||||
var binFolderAssemblies = new List<Assembly>();
|
||||
/// <summary>
|
||||
/// Returns only assemblies found in the bin folder that have been loaded into the app domain.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This will be used if we implement App_Plugins from Umbraco v5 but currently it is not used.
|
||||
/// </remarks>
|
||||
internal static HashSet<Assembly> GetBinAssemblies()
|
||||
{
|
||||
|
||||
foreach (var a in assemblies)
|
||||
{
|
||||
try
|
||||
{
|
||||
//do a test to see if its queryable in med trust
|
||||
var assemblyFile = a.GetAssemblyFile();
|
||||
safeDomainAssemblies.Add(a);
|
||||
}
|
||||
catch (SecurityException)
|
||||
{
|
||||
//we will just ignore this because this will fail
|
||||
//in medium trust for system assemblies, we get an exception but we just want to continue until we get to
|
||||
//an assembly that is ok.
|
||||
}
|
||||
}
|
||||
if (_binFolderAssemblies == null)
|
||||
{
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var assemblies = GetAssembliesWithKnownExclusions().ToArray();
|
||||
var binFolder = Assembly.GetExecutingAssembly().GetAssemblyFile().Directory;
|
||||
var binAssemblyFiles = Directory.GetFiles(binFolder.FullName, "*.dll", SearchOption.TopDirectoryOnly).ToList();
|
||||
var domainAssemblyNames = binAssemblyFiles.Select(AssemblyName.GetAssemblyName);
|
||||
var safeDomainAssemblies = new HashSet<Assembly>();
|
||||
var binFolderAssemblies = new HashSet<Assembly>();
|
||||
|
||||
foreach (var assemblyName in domainAssemblyNames)
|
||||
{
|
||||
try
|
||||
{
|
||||
var foundAssembly =
|
||||
safeDomainAssemblies.FirstOrDefault(a => a.GetAssemblyFile() == assemblyName.GetAssemblyFile());
|
||||
if (foundAssembly != null)
|
||||
{
|
||||
binFolderAssemblies.Add(foundAssembly);
|
||||
}
|
||||
}
|
||||
catch (SecurityException)
|
||||
{
|
||||
//we will just ignore this because if we are trying to do a call to:
|
||||
// AssemblyName.ReferenceMatchesDefinition(a.GetName(), assemblyName)))
|
||||
//in medium trust for system assemblies, we get an exception but we just want to continue until we get to
|
||||
//an assembly that is ok.
|
||||
}
|
||||
}
|
||||
foreach (var a in assemblies)
|
||||
{
|
||||
try
|
||||
{
|
||||
//do a test to see if its queryable in med trust
|
||||
var assemblyFile = a.GetAssemblyFile();
|
||||
safeDomainAssemblies.Add(a);
|
||||
}
|
||||
catch (SecurityException)
|
||||
{
|
||||
//we will just ignore this because this will fail
|
||||
//in medium trust for system assemblies, we get an exception but we just want to continue until we get to
|
||||
//an assembly that is ok.
|
||||
}
|
||||
}
|
||||
|
||||
_binFolderAssemblies = new ReadOnlyCollection<Assembly>(binFolderAssemblies);
|
||||
}
|
||||
}
|
||||
return _binFolderAssemblies;
|
||||
}
|
||||
foreach (var assemblyName in domainAssemblyNames)
|
||||
{
|
||||
try
|
||||
{
|
||||
var foundAssembly =
|
||||
safeDomainAssemblies.FirstOrDefault(a => a.GetAssemblyFile() == assemblyName.GetAssemblyFile());
|
||||
if (foundAssembly != null)
|
||||
{
|
||||
binFolderAssemblies.Add(foundAssembly);
|
||||
}
|
||||
}
|
||||
catch (SecurityException)
|
||||
{
|
||||
//we will just ignore this because if we are trying to do a call to:
|
||||
// AssemblyName.ReferenceMatchesDefinition(a.GetName(), assemblyName)))
|
||||
//in medium trust for system assemblies, we get an exception but we just want to continue until we get to
|
||||
//an assembly that is ok.
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return a list of found local Assemblies excluding the known assemblies we don't want to scan
|
||||
/// and exluding the ones passed in and excluding the exclusion list filter, the results of this are
|
||||
/// cached for perforance reasons.
|
||||
/// </summary>
|
||||
/// <param name="excludeFromResults"></param>
|
||||
/// <returns></returns>
|
||||
internal static IEnumerable<Assembly> GetAssembliesWithKnownExclusions(
|
||||
IEnumerable<Assembly> excludeFromResults = null)
|
||||
{
|
||||
if (LocalFilteredAssemblyCache.Any()) return LocalFilteredAssemblyCache;
|
||||
using (new WriteLock(LocalFilteredAssemblyCacheLocker))
|
||||
{
|
||||
var assemblies = GetFilteredAssemblies(excludeFromResults, KnownAssemblyExclusionFilter);
|
||||
assemblies.ForEach(LocalFilteredAssemblyCache.Add);
|
||||
}
|
||||
return LocalFilteredAssemblyCache;
|
||||
}
|
||||
_binFolderAssemblies = new HashSet<Assembly>(binFolderAssemblies);
|
||||
}
|
||||
}
|
||||
return _binFolderAssemblies;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return a list of found local Assemblies and exluding the ones passed in and excluding the exclusion list filter
|
||||
/// </summary>
|
||||
/// <param name="excludeFromResults"></param>
|
||||
/// <param name="exclusionFilter"></param>
|
||||
/// <returns></returns>
|
||||
private static IEnumerable<Assembly> GetFilteredAssemblies(
|
||||
IEnumerable<Assembly> excludeFromResults = null,
|
||||
string[] exclusionFilter = null)
|
||||
{
|
||||
if (excludeFromResults == null)
|
||||
excludeFromResults = new List<Assembly>();
|
||||
if (exclusionFilter == null)
|
||||
exclusionFilter = new string[] { };
|
||||
/// <summary>
|
||||
/// Return a list of found local Assemblies excluding the known assemblies we don't want to scan
|
||||
/// and exluding the ones passed in and excluding the exclusion list filter, the results of this are
|
||||
/// cached for perforance reasons.
|
||||
/// </summary>
|
||||
/// <param name="excludeFromResults"></param>
|
||||
/// <returns></returns>
|
||||
internal static HashSet<Assembly> GetAssembliesWithKnownExclusions(
|
||||
IEnumerable<Assembly> excludeFromResults = null)
|
||||
{
|
||||
using (var lck = new UpgradeableReadLock(LocalFilteredAssemblyCacheLocker))
|
||||
{
|
||||
if (LocalFilteredAssemblyCache.Any()) return LocalFilteredAssemblyCache;
|
||||
|
||||
return GetAllAssemblies()
|
||||
.Where(x => !excludeFromResults.Contains(x)
|
||||
&& !x.GlobalAssemblyCache
|
||||
&& !exclusionFilter.Any(f => x.FullName.StartsWith(f)));
|
||||
}
|
||||
lck.UpgradeToWriteLock();
|
||||
|
||||
/// <summary>
|
||||
/// this is our assembly filter to filter out known types that def dont contain types we'd like to find or plugins
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// NOTE the comma vs period... comma delimits the name in an Assembly FullName property so if it ends with comma then its an exact name match
|
||||
/// </remarks>
|
||||
internal static readonly string[] KnownAssemblyExclusionFilter = new[]
|
||||
var assemblies = GetFilteredAssemblies(excludeFromResults, KnownAssemblyExclusionFilter);
|
||||
foreach (var a in assemblies)
|
||||
{
|
||||
LocalFilteredAssemblyCache.Add(a);
|
||||
}
|
||||
|
||||
return LocalFilteredAssemblyCache;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return a distinct list of found local Assemblies and exluding the ones passed in and excluding the exclusion list filter
|
||||
/// </summary>
|
||||
/// <param name="excludeFromResults"></param>
|
||||
/// <param name="exclusionFilter"></param>
|
||||
/// <returns></returns>
|
||||
private static IEnumerable<Assembly> GetFilteredAssemblies(
|
||||
IEnumerable<Assembly> excludeFromResults = null,
|
||||
string[] exclusionFilter = null)
|
||||
{
|
||||
if (excludeFromResults == null)
|
||||
excludeFromResults = new HashSet<Assembly>();
|
||||
if (exclusionFilter == null)
|
||||
exclusionFilter = new string[] { };
|
||||
|
||||
return GetAllAssemblies()
|
||||
.Where(x => !excludeFromResults.Contains(x)
|
||||
&& !x.GlobalAssemblyCache
|
||||
&& !exclusionFilter.Any(f => x.FullName.StartsWith(f)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// this is our assembly filter to filter out known types that def dont contain types we'd like to find or plugins
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// NOTE the comma vs period... comma delimits the name in an Assembly FullName property so if it ends with comma then its an exact name match
|
||||
/// </remarks>
|
||||
internal static readonly string[] KnownAssemblyExclusionFilter = new[]
|
||||
{
|
||||
"mscorlib,",
|
||||
"System.",
|
||||
@@ -287,11 +299,11 @@ namespace Umbraco.Core
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TAttribute"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>()
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return FindClassesOfTypeWithAttribute<T, TAttribute>(GetAssembliesWithKnownExclusions(), true);
|
||||
}
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>()
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return FindClassesOfTypeWithAttribute<T, TAttribute>(GetAssembliesWithKnownExclusions(), true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds any classes derived from the type T that contain the attribute TAttribute
|
||||
@@ -300,11 +312,11 @@ namespace Umbraco.Core
|
||||
/// <typeparam name="TAttribute"></typeparam>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>(IEnumerable<Assembly> assemblies)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return FindClassesOfTypeWithAttribute<T, TAttribute>(assemblies, true);
|
||||
}
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>(IEnumerable<Assembly> assemblies)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return FindClassesOfTypeWithAttribute<T, TAttribute>(assemblies, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds any classes derived from the type T that contain the attribute TAttribute
|
||||
@@ -314,13 +326,13 @@ namespace Umbraco.Core
|
||||
/// <param name="assemblies"></param>
|
||||
/// <param name="onlyConcreteClasses"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>(
|
||||
IEnumerable<Assembly> assemblies,
|
||||
bool onlyConcreteClasses)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return FindClassesOfTypeWithAttribute<TAttribute>(typeof (T), assemblies, onlyConcreteClasses);
|
||||
}
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>(
|
||||
IEnumerable<Assembly> assemblies,
|
||||
bool onlyConcreteClasses)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return FindClassesOfTypeWithAttribute<TAttribute>(typeof(T), assemblies, onlyConcreteClasses);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds any classes derived from the assignTypeFrom Type that contain the attribute TAttribute
|
||||
@@ -330,85 +342,85 @@ namespace Umbraco.Core
|
||||
/// <param name="assemblies"></param>
|
||||
/// <param name="onlyConcreteClasses"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<TAttribute>(
|
||||
Type assignTypeFrom,
|
||||
IEnumerable<Assembly> assemblies,
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<TAttribute>(
|
||||
Type assignTypeFrom,
|
||||
IEnumerable<Assembly> assemblies,
|
||||
bool onlyConcreteClasses)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
if (assemblies == null) throw new ArgumentNullException("assemblies");
|
||||
|
||||
return GetClasses(assignTypeFrom, assemblies, onlyConcreteClasses,
|
||||
{
|
||||
if (assemblies == null) throw new ArgumentNullException("assemblies");
|
||||
|
||||
return GetClasses(assignTypeFrom, assemblies, onlyConcreteClasses,
|
||||
//the additional filter will ensure that any found types also have the attribute applied.
|
||||
t => t.GetCustomAttributes<TAttribute>(false).Any());
|
||||
}
|
||||
t => t.GetCustomAttributes<TAttribute>(false).Any());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches all filtered local assemblies specified for classes of the type passed in.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesOfType<T>()
|
||||
{
|
||||
return FindClassesOfType<T>(GetAssembliesWithKnownExclusions(), true);
|
||||
}
|
||||
/// <summary>
|
||||
/// Searches all filtered local assemblies specified for classes of the type passed in.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesOfType<T>()
|
||||
{
|
||||
return FindClassesOfType<T>(GetAssembliesWithKnownExclusions(), true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all types found of in the assemblies specified of type T
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <param name="onlyConcreteClasses"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesOfType<T>(IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
|
||||
{
|
||||
if (assemblies == null) throw new ArgumentNullException("assemblies");
|
||||
/// <summary>
|
||||
/// Returns all types found of in the assemblies specified of type T
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <param name="onlyConcreteClasses"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesOfType<T>(IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
|
||||
{
|
||||
if (assemblies == null) throw new ArgumentNullException("assemblies");
|
||||
|
||||
return GetClasses(typeof(T), assemblies, onlyConcreteClasses);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all types found of in the assemblies specified of type T
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesOfType<T>(IEnumerable<Assembly> assemblies)
|
||||
{
|
||||
return FindClassesOfType<T>(assemblies, true);
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns all types found of in the assemblies specified of type T
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesOfType<T>(IEnumerable<Assembly> assemblies)
|
||||
{
|
||||
return FindClassesOfType<T>(assemblies, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the classes with attribute.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="assemblies">The assemblies.</param>
|
||||
/// <param name="onlyConcreteClasses">if set to <c>true</c> only concrete classes.</param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesWithAttribute<T>(IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
|
||||
where T : Attribute
|
||||
{
|
||||
return FindClassesWithAttribute(typeof(T), assemblies, onlyConcreteClasses);
|
||||
}
|
||||
/// <summary>
|
||||
/// Finds the classes with attribute.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="assemblies">The assemblies.</param>
|
||||
/// <param name="onlyConcreteClasses">if set to <c>true</c> only concrete classes.</param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesWithAttribute<T>(IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
|
||||
where T : Attribute
|
||||
{
|
||||
return FindClassesWithAttribute(typeof(T), assemblies, onlyConcreteClasses);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds any classes with the attribute.
|
||||
/// </summary>
|
||||
/// <param name="attributeType">The attribute type </param>
|
||||
/// <param name="assemblies">The assemblies.</param>
|
||||
/// <param name="onlyConcreteClasses">if set to <c>true</c> only concrete classes.</param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesWithAttribute(
|
||||
Type attributeType,
|
||||
IEnumerable<Assembly> assemblies,
|
||||
bool onlyConcreteClasses)
|
||||
{
|
||||
if (assemblies == null) throw new ArgumentNullException("assemblies");
|
||||
/// <summary>
|
||||
/// Finds any classes with the attribute.
|
||||
/// </summary>
|
||||
/// <param name="attributeType">The attribute type </param>
|
||||
/// <param name="assemblies">The assemblies.</param>
|
||||
/// <param name="onlyConcreteClasses">if set to <c>true</c> only concrete classes.</param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesWithAttribute(
|
||||
Type attributeType,
|
||||
IEnumerable<Assembly> assemblies,
|
||||
bool onlyConcreteClasses)
|
||||
{
|
||||
if (assemblies == null) throw new ArgumentNullException("assemblies");
|
||||
|
||||
if (TypeHelper.IsTypeAssignableFrom<Attribute>(attributeType) == false)
|
||||
throw new ArgumentException("The type specified: " + attributeType + " is not an Attribute type");
|
||||
if (TypeHelper.IsTypeAssignableFrom<Attribute>(attributeType) == false)
|
||||
throw new ArgumentException("The type specified: " + attributeType + " is not an Attribute type");
|
||||
|
||||
var foundAssignableTypes = new List<Type>();
|
||||
var foundAssignableTypes = new HashSet<Type>();
|
||||
|
||||
var assemblyList = assemblies.ToArray();
|
||||
|
||||
@@ -418,71 +430,74 @@ namespace Umbraco.Core
|
||||
var referencedAssemblies = TypeHelper.GetReferencedAssemblies(attributeType, assemblyList);
|
||||
|
||||
foreach (var a in referencedAssemblies)
|
||||
{
|
||||
{
|
||||
//get all types in the assembly that are sub types of the current type
|
||||
var allTypes = GetTypesWithFormattedException(a).ToArray();
|
||||
|
||||
var types = allTypes.Where(t => TypeHelper.IsNonStaticClass(t)
|
||||
&& (onlyConcreteClasses == false || t.IsAbstract == false)
|
||||
//the type must have this attribute
|
||||
|
||||
var types = allTypes.Where(t => TypeHelper.IsNonStaticClass(t)
|
||||
&& (onlyConcreteClasses == false || t.IsAbstract == false)
|
||||
//the type must have this attribute
|
||||
&& t.GetCustomAttributes(attributeType, false).Any());
|
||||
|
||||
foundAssignableTypes.AddRange(types);
|
||||
}
|
||||
foreach (var t in types)
|
||||
{
|
||||
foundAssignableTypes.Add(t);
|
||||
}
|
||||
}
|
||||
|
||||
return foundAssignableTypes;
|
||||
}
|
||||
return foundAssignableTypes;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Finds the classes with attribute.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="assemblies">The assemblies.</param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesWithAttribute<T>(IEnumerable<Assembly> assemblies)
|
||||
where T : Attribute
|
||||
{
|
||||
return FindClassesWithAttribute<T>(assemblies, true);
|
||||
}
|
||||
/// <summary>
|
||||
/// Finds the classes with attribute.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="assemblies">The assemblies.</param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesWithAttribute<T>(IEnumerable<Assembly> assemblies)
|
||||
where T : Attribute
|
||||
{
|
||||
return FindClassesWithAttribute<T>(assemblies, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the classes with attribute in filtered local assemblies
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesWithAttribute<T>()
|
||||
where T : Attribute
|
||||
{
|
||||
return FindClassesWithAttribute<T>(GetAssembliesWithKnownExclusions());
|
||||
}
|
||||
/// <summary>
|
||||
/// Finds the classes with attribute in filtered local assemblies
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesWithAttribute<T>()
|
||||
where T : Attribute
|
||||
{
|
||||
return FindClassesWithAttribute<T>(GetAssembliesWithKnownExclusions());
|
||||
}
|
||||
|
||||
|
||||
#region Private methods
|
||||
|
||||
/// <summary>
|
||||
/// Finds types that are assignable from the assignTypeFrom parameter and will scan for these types in the assembly
|
||||
/// list passed in, however we will only scan assemblies that have a reference to the assignTypeFrom Type or any type
|
||||
/// deriving from the base type.
|
||||
/// </summary>
|
||||
/// <param name="assignTypeFrom"></param>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <param name="onlyConcreteClasses"></param>
|
||||
/// <param name="additionalFilter">An additional filter to apply for what types will actually be included in the return value</param>
|
||||
/// <returns></returns>
|
||||
private static IEnumerable<Type> GetClasses(
|
||||
Type assignTypeFrom,
|
||||
IEnumerable<Assembly> assemblies,
|
||||
#region Private methods
|
||||
|
||||
/// <summary>
|
||||
/// Finds types that are assignable from the assignTypeFrom parameter and will scan for these types in the assembly
|
||||
/// list passed in, however we will only scan assemblies that have a reference to the assignTypeFrom Type or any type
|
||||
/// deriving from the base type.
|
||||
/// </summary>
|
||||
/// <param name="assignTypeFrom"></param>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <param name="onlyConcreteClasses"></param>
|
||||
/// <param name="additionalFilter">An additional filter to apply for what types will actually be included in the return value</param>
|
||||
/// <returns></returns>
|
||||
private static IEnumerable<Type> GetClasses(
|
||||
Type assignTypeFrom,
|
||||
IEnumerable<Assembly> assemblies,
|
||||
bool onlyConcreteClasses,
|
||||
Func<Type, bool> additionalFilter = null)
|
||||
{
|
||||
{
|
||||
//the default filter will always return true.
|
||||
if (additionalFilter == null)
|
||||
{
|
||||
additionalFilter = type => true;
|
||||
}
|
||||
|
||||
var foundAssignableTypes = new List<Type>();
|
||||
var foundAssignableTypes = new HashSet<Type>();
|
||||
|
||||
var assemblyList = assemblies.ToArray();
|
||||
|
||||
@@ -510,8 +525,11 @@ namespace Umbraco.Core
|
||||
.ToArray();
|
||||
|
||||
//add the types to our list to return
|
||||
foundAssignableTypes.AddRange(filteredTypes);
|
||||
|
||||
foreach (var t in filteredTypes)
|
||||
{
|
||||
foundAssignableTypes.Add(t);
|
||||
}
|
||||
|
||||
//now we need to include types that may be inheriting from sub classes of the type being searched for
|
||||
//so we will search in assemblies that reference those types too.
|
||||
foreach (var subTypesInAssembly in allSubTypes.GroupBy(x => x.Assembly))
|
||||
@@ -529,54 +547,61 @@ namespace Umbraco.Core
|
||||
|
||||
//if there's a base class amongst the types then we'll only search for that type.
|
||||
//otherwise we'll have to search for all of them.
|
||||
var subTypesToSearch = new List<Type>();
|
||||
var subTypesToSearch = new HashSet<Type>();
|
||||
if (baseClassAttempt.Success)
|
||||
{
|
||||
subTypesToSearch.Add(baseClassAttempt.Result);
|
||||
}
|
||||
else
|
||||
{
|
||||
subTypesToSearch.AddRange(subTypeList);
|
||||
foreach (var t in subTypeList)
|
||||
{
|
||||
subTypesToSearch.Add(t);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
foreach (var typeToSearch in subTypesToSearch)
|
||||
{
|
||||
//recursively find the types inheriting from this sub type in the other non-scanned assemblies.
|
||||
var foundTypes = GetClasses(typeToSearch, otherAssemblies, onlyConcreteClasses, additionalFilter);
|
||||
foundAssignableTypes.AddRange(foundTypes);
|
||||
|
||||
foreach (var f in foundTypes)
|
||||
{
|
||||
foundAssignableTypes.Add(f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return foundAssignableTypes;
|
||||
}
|
||||
}
|
||||
return foundAssignableTypes;
|
||||
}
|
||||
|
||||
private static IEnumerable<Type> GetTypesWithFormattedException(Assembly a)
|
||||
{
|
||||
//if the assembly is dynamic, do not try to scan it
|
||||
if (a.IsDynamic)
|
||||
return Enumerable.Empty<Type>();
|
||||
private static IEnumerable<Type> GetTypesWithFormattedException(Assembly a)
|
||||
{
|
||||
//if the assembly is dynamic, do not try to scan it
|
||||
if (a.IsDynamic)
|
||||
return Enumerable.Empty<Type>();
|
||||
|
||||
try
|
||||
{
|
||||
return a.GetExportedTypes();
|
||||
}
|
||||
catch (ReflectionTypeLoadException ex)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("Could not load types from assembly " + a.FullName + ", errors:");
|
||||
foreach (var loaderException in ex.LoaderExceptions.WhereNotNull())
|
||||
{
|
||||
sb.AppendLine("Exception: " + loaderException);
|
||||
}
|
||||
throw new ReflectionTypeLoadException(ex.Types, ex.LoaderExceptions, sb.ToString());
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
return a.GetExportedTypes();
|
||||
}
|
||||
catch (ReflectionTypeLoadException ex)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("Could not load types from assembly " + a.FullName + ", errors:");
|
||||
foreach (var loaderException in ex.LoaderExceptions.WhereNotNull())
|
||||
{
|
||||
sb.AppendLine("Exception: " + loaderException);
|
||||
}
|
||||
throw new ReflectionTypeLoadException(ex.Types, ex.LoaderExceptions, sb.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,16 @@ namespace Umbraco.Core
|
||||
private static readonly ConcurrentDictionary<Type, FieldInfo[]> GetFieldsCache = new ConcurrentDictionary<Type, FieldInfo[]>();
|
||||
private static readonly ConcurrentDictionary<Tuple<Type, bool, bool, bool>, PropertyInfo[]> GetPropertiesCache = new ConcurrentDictionary<Tuple<Type, bool, bool, bool>, PropertyInfo[]>();
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the method is actually overriding a base method
|
||||
/// </summary>
|
||||
/// <param name="m"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsOverride(MethodInfo m)
|
||||
{
|
||||
return m.GetBaseDefinition().DeclaringType != m.DeclaringType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find all assembly references that are referencing the assignTypeFrom Type's assembly found in the assemblyList
|
||||
/// </summary>
|
||||
|
||||
@@ -156,6 +156,7 @@
|
||||
<Compile Include="Events\EventExtensions.cs" />
|
||||
<Compile Include="Events\MigrationEventArgs.cs" />
|
||||
<Compile Include="Events\PublishEventArgs.cs" />
|
||||
<Compile Include="Events\RecycleBinEventArgs.cs" />
|
||||
<Compile Include="Events\TypedEventHandler.cs" />
|
||||
<Compile Include="Events\MoveEventArgs.cs" />
|
||||
<Compile Include="Events\NewEventArgs.cs" />
|
||||
@@ -164,6 +165,7 @@
|
||||
<Compile Include="Events\SaveEventArgs.cs" />
|
||||
<Compile Include="Events\SendToPublishEventArgs.cs" />
|
||||
<Compile Include="IApplicationEventHandler.cs" />
|
||||
<Compile Include="IDisposeOnRequestEnd.cs" />
|
||||
<Compile Include="IO\ResizedImage.cs" />
|
||||
<Compile Include="IO\UmbracoMediaFile.cs" />
|
||||
<Compile Include="Media\MediaSubfolderCounter.cs" />
|
||||
@@ -237,6 +239,7 @@
|
||||
<Compile Include="Models\UmbracoEntity.cs" />
|
||||
<Compile Include="Models\UmbracoObjectTypes.cs" />
|
||||
<Compile Include="Models\UmbracoObjectTypesExtensions.cs" />
|
||||
<Compile Include="NetworkHelper.cs" />
|
||||
<Compile Include="ObjectResolution\ApplicationEventsResolver.cs" />
|
||||
<Compile Include="ObjectResolution\ResolverCollection.cs" />
|
||||
<Compile Include="Persistence\Caching\InMemoryCacheProvider.cs" />
|
||||
@@ -458,6 +461,7 @@
|
||||
<Compile Include="Persistence\PetaPocoConnectionExtensions.cs" />
|
||||
<Compile Include="Persistence\PetaPocoExtensions.cs" />
|
||||
<Compile Include="Persistence\PetaPocoSqlExtensions.cs" />
|
||||
<Compile Include="Persistence\Querying\BaseExpressionHelper.cs" />
|
||||
<Compile Include="Persistence\Querying\PocoToSqlExpressionHelper.cs" />
|
||||
<Compile Include="Persistence\Querying\IQuery.cs" />
|
||||
<Compile Include="Persistence\Querying\ModelToSqlExpressionHelper.cs" />
|
||||
@@ -496,6 +500,7 @@
|
||||
<Compile Include="Persistence\Repositories\MediaTypeRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\PermissionRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\PetaPocoRepositoryBase.cs" />
|
||||
<Compile Include="Persistence\Repositories\RecycleBinRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\RelationRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\RelationTypeRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\RepositoryBase.cs" />
|
||||
@@ -665,6 +670,9 @@
|
||||
<Compile Include="Publishing\PublishStatus.cs" />
|
||||
<Compile Include="Publishing\PublishStatusType.cs" />
|
||||
<Compile Include="RenderingEngine.cs" />
|
||||
<Compile Include="Security\AuthenticationExtensions.cs" />
|
||||
<Compile Include="Security\UmbracoBackOfficeIdentity.cs" />
|
||||
<Compile Include="Security\UserData.cs" />
|
||||
<Compile Include="Serialization\AbstractSerializationService.cs" />
|
||||
<Compile Include="Serialization\Formatter.cs" />
|
||||
<Compile Include="Serialization\IFormatter.cs" />
|
||||
|
||||
@@ -2,6 +2,8 @@ using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.IO;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
@@ -10,6 +12,42 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public static class UriExtensions
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the current uri is a back office request
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <returns></returns>
|
||||
internal static bool IsBackOfficeRequest(this Uri url)
|
||||
{
|
||||
|
||||
var authority = url.GetLeftPart(UriPartial.Authority);
|
||||
var afterAuthority = url.GetLeftPart(UriPartial.Query)
|
||||
.TrimStart(authority)
|
||||
.TrimStart("/");
|
||||
|
||||
|
||||
|
||||
//check if this is in the umbraco back office
|
||||
return afterAuthority.InvariantStartsWith(GlobalSettings.Path.TrimStart("/"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the current uri is an install request
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <returns></returns>
|
||||
internal static bool IsInstallerRequest(this Uri url)
|
||||
{
|
||||
var authority = url.GetLeftPart(UriPartial.Authority);
|
||||
var afterAuthority = url.GetLeftPart(UriPartial.Query)
|
||||
.TrimStart(authority)
|
||||
.TrimStart("/");
|
||||
|
||||
//check if this is in the umbraco back office
|
||||
return afterAuthority.InvariantStartsWith(IOHelper.ResolveUrl("~/install").TrimStart("/"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is a performance tweak to check if this is a .css, .js or .ico, .jpg, .jpeg, .png, .gif file request since
|
||||
/// .Net will pass these requests through to the module when in integrated mode.
|
||||
@@ -19,7 +57,7 @@ namespace Umbraco.Core
|
||||
/// <returns></returns>
|
||||
internal static bool IsClientSideRequest(this Uri url)
|
||||
{
|
||||
var toIgnore = new[] { ".js", ".css", ".ico", ".png", ".jpg", ".jpeg", ".gif" };
|
||||
var toIgnore = new[] { ".js", ".css", ".ico", ".png", ".jpg", ".jpeg", ".gif", ".html", ".svg" };
|
||||
return toIgnore.Any(x => Path.GetExtension(url.LocalPath).InvariantEquals(x));
|
||||
}
|
||||
|
||||
@@ -31,14 +69,14 @@ namespace Umbraco.Core
|
||||
/// <returns>The rewritten uri.</returns>
|
||||
/// <remarks>Everything else remains unchanged, except for the fragment which is removed.</remarks>
|
||||
public static Uri Rewrite(this Uri uri, string path)
|
||||
{
|
||||
{
|
||||
if (!path.StartsWith("/"))
|
||||
throw new ArgumentException("Path must start with a slash.", "path");
|
||||
|
||||
return uri.IsAbsoluteUri
|
||||
? new Uri(uri.GetLeftPart(UriPartial.Authority) + path + uri.Query)
|
||||
return uri.IsAbsoluteUri
|
||||
? new Uri(uri.GetLeftPart(UriPartial.Authority) + path + uri.Query)
|
||||
: new Uri(path + uri.GetSafeQuery(), UriKind.Relative);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rewrites the path and query of a uri.
|
||||
@@ -49,18 +87,18 @@ namespace Umbraco.Core
|
||||
/// <returns>The rewritten uri.</returns>
|
||||
/// <remarks>Everything else remains unchanged, except for the fragment which is removed.</remarks>
|
||||
public static Uri Rewrite(this Uri uri, string path, string query)
|
||||
{
|
||||
{
|
||||
if (!path.StartsWith("/"))
|
||||
throw new ArgumentException("Path must start with a slash.", "path");
|
||||
if (query.Length > 0 && !query.StartsWith("?"))
|
||||
throw new ArgumentException("Query must start with a question mark.", "query");
|
||||
if (query == "?")
|
||||
query = "";
|
||||
|
||||
return uri.IsAbsoluteUri
|
||||
? new Uri(uri.GetLeftPart(UriPartial.Authority) + path + query)
|
||||
|
||||
return uri.IsAbsoluteUri
|
||||
? new Uri(uri.GetLeftPart(UriPartial.Authority) + path + query)
|
||||
: new Uri(path + query, UriKind.Relative);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the absolute path of the uri, even if the uri is relative.
|
||||
@@ -68,10 +106,10 @@ namespace Umbraco.Core
|
||||
/// <param name="uri">The uri.</param>
|
||||
/// <returns>The absolute path of the uri.</returns>
|
||||
/// <remarks>Default uri.AbsolutePath does not support relative uris.</remarks>
|
||||
public static string GetSafeAbsolutePath(this Uri uri)
|
||||
{
|
||||
if (uri.IsAbsoluteUri)
|
||||
return uri.AbsolutePath;
|
||||
public static string GetSafeAbsolutePath(this Uri uri)
|
||||
{
|
||||
if (uri.IsAbsoluteUri)
|
||||
return uri.AbsolutePath;
|
||||
|
||||
// cannot get .AbsolutePath on relative uri (InvalidOperation)
|
||||
var s = uri.OriginalString;
|
||||
@@ -80,7 +118,7 @@ namespace Umbraco.Core
|
||||
var pos = posq > 0 ? posq : (posf > 0 ? posf : 0);
|
||||
var path = pos > 0 ? s.Substring(0, pos) : s;
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the decoded, absolute path of the uri.
|
||||
@@ -89,9 +127,9 @@ namespace Umbraco.Core
|
||||
/// <returns>The absolute path of the uri.</returns>
|
||||
/// <remarks>Only for absolute uris.</remarks>
|
||||
public static string GetAbsolutePathDecoded(this Uri uri)
|
||||
{
|
||||
return System.Web.HttpUtility.UrlDecode(uri.AbsolutePath);
|
||||
}
|
||||
{
|
||||
return System.Web.HttpUtility.UrlDecode(uri.AbsolutePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the decoded, absolute path of the uri, even if the uri is relative.
|
||||
@@ -100,32 +138,32 @@ namespace Umbraco.Core
|
||||
/// <returns>The absolute path of the uri.</returns>
|
||||
/// <remarks>Default uri.AbsolutePath does not support relative uris.</remarks>
|
||||
public static string GetSafeAbsolutePathDecoded(this Uri uri)
|
||||
{
|
||||
return System.Web.HttpUtility.UrlDecode(uri.GetSafeAbsolutePath());
|
||||
}
|
||||
{
|
||||
return System.Web.HttpUtility.UrlDecode(uri.GetSafeAbsolutePath());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rewrites the path of the uri so it ends with a slash.
|
||||
/// </summary>
|
||||
/// <param name="uri">The uri.</param>
|
||||
/// <returns>The rewritten uri.</returns>
|
||||
/// <remarks>Everything else remains unchanged.</remarks>
|
||||
/// <summary>
|
||||
/// Rewrites the path of the uri so it ends with a slash.
|
||||
/// </summary>
|
||||
/// <param name="uri">The uri.</param>
|
||||
/// <returns>The rewritten uri.</returns>
|
||||
/// <remarks>Everything else remains unchanged.</remarks>
|
||||
public static Uri EndPathWithSlash(this Uri uri)
|
||||
{
|
||||
var path = uri.GetSafeAbsolutePath();
|
||||
if (uri.IsAbsoluteUri)
|
||||
{
|
||||
if (path != "/" && !path.EndsWith("/"))
|
||||
uri = new Uri(uri.GetLeftPart(UriPartial.Authority) + path + "/" + uri.Query);
|
||||
return uri;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (path != "/" && !path.EndsWith("/"))
|
||||
uri = new Uri(path + "/" + uri.Query, UriKind.Relative);
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
{
|
||||
var path = uri.GetSafeAbsolutePath();
|
||||
if (uri.IsAbsoluteUri)
|
||||
{
|
||||
if (path != "/" && !path.EndsWith("/"))
|
||||
uri = new Uri(uri.GetLeftPart(UriPartial.Authority) + path + "/" + uri.Query);
|
||||
return uri;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (path != "/" && !path.EndsWith("/"))
|
||||
uri = new Uri(path + "/" + uri.Query, UriKind.Relative);
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rewrites the path of the uri so it does not end with a slash.
|
||||
@@ -134,20 +172,20 @@ namespace Umbraco.Core
|
||||
/// <returns>The rewritten uri.</returns>
|
||||
/// <remarks>Everything else remains unchanged.</remarks>
|
||||
public static Uri TrimPathEndSlash(this Uri uri)
|
||||
{
|
||||
var path = uri.GetSafeAbsolutePath();
|
||||
if (uri.IsAbsoluteUri)
|
||||
{
|
||||
if (path != "/")
|
||||
uri = new Uri(uri.GetLeftPart(UriPartial.Authority) + path.TrimEnd('/') + uri.Query);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (path != "/")
|
||||
uri = new Uri(path.TrimEnd('/') + uri.Query, UriKind.Relative);
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
{
|
||||
var path = uri.GetSafeAbsolutePath();
|
||||
if (uri.IsAbsoluteUri)
|
||||
{
|
||||
if (path != "/")
|
||||
uri = new Uri(uri.GetLeftPart(UriPartial.Authority) + path.TrimEnd('/') + uri.Query);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (path != "/")
|
||||
uri = new Uri(path.TrimEnd('/') + uri.Query, UriKind.Relative);
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms a relative uri into an absolute uri.
|
||||
@@ -155,13 +193,13 @@ namespace Umbraco.Core
|
||||
/// <param name="uri">The relative uri.</param>
|
||||
/// <param name="baseUri">The base absolute uri.</param>
|
||||
/// <returns>The absolute uri.</returns>
|
||||
public static Uri MakeAbsolute(this Uri uri, Uri baseUri)
|
||||
{
|
||||
if (uri.IsAbsoluteUri)
|
||||
throw new ArgumentException("Uri is already absolute.", "uri");
|
||||
public static Uri MakeAbsolute(this Uri uri, Uri baseUri)
|
||||
{
|
||||
if (uri.IsAbsoluteUri)
|
||||
throw new ArgumentException("Uri is already absolute.", "uri");
|
||||
|
||||
return new Uri(baseUri.GetLeftPart(UriPartial.Authority) + uri.GetSafeAbsolutePath() + uri.GetSafeQuery());
|
||||
}
|
||||
return new Uri(baseUri.GetLeftPart(UriPartial.Authority) + uri.GetSafeAbsolutePath() + uri.GetSafeQuery());
|
||||
}
|
||||
|
||||
static string GetSafeQuery(this Uri uri)
|
||||
{
|
||||
@@ -176,5 +214,5 @@ namespace Umbraco.Core
|
||||
|
||||
return query;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@
|
||||
</appSettings>
|
||||
|
||||
<connectionStrings>
|
||||
<add name="umbracoDbDSN" connectionString="Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf" providerName="System.Data.SqlServerCe.4.0"/>
|
||||
<add name="umbracoDbDSN" connectionString="Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;" providerName="System.Data.SqlServerCe.4.0"/>
|
||||
</connectionStrings>
|
||||
|
||||
<FileSystemProviders>
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace Umbraco.Tests.BusinessLogic
|
||||
|
||||
private void InitializeDatabase()
|
||||
{
|
||||
ConfigurationManager.AppSettings.Set(Core.Configuration.GlobalSettings.UmbracoConnectionName, @"datalayer=SQLCE4Umbraco.SqlCEHelper,SQLCE4Umbraco;data source=|DataDirectory|\UmbracoPetaPocoTests.sdf");
|
||||
ConfigurationManager.AppSettings.Set(Core.Configuration.GlobalSettings.UmbracoConnectionName, @"datalayer=SQLCE4Umbraco.SqlCEHelper,SQLCE4Umbraco;data source=|DataDirectory|\UmbracoPetaPocoTests.sdf;Flush Interval=1;");
|
||||
|
||||
ClearDatabase();
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace Umbraco.Tests.Migrations.Upgrades
|
||||
|
||||
public override UmbracoDatabase GetConfiguredDatabase()
|
||||
{
|
||||
return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf", "System.Data.SqlServerCe.4.0");
|
||||
return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;", "System.Data.SqlServerCe.4.0");
|
||||
}
|
||||
|
||||
public override DatabaseProviders GetDatabaseProvider()
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace Umbraco.Tests.Migrations.Upgrades
|
||||
|
||||
public override UmbracoDatabase GetConfiguredDatabase()
|
||||
{
|
||||
return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf", "System.Data.SqlServerCe.4.0");
|
||||
return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;", "System.Data.SqlServerCe.4.0");
|
||||
}
|
||||
|
||||
public override DatabaseProviders GetDatabaseProvider()
|
||||
|
||||
@@ -100,7 +100,7 @@ namespace Umbraco.Tests.Migrations.Upgrades
|
||||
|
||||
public UmbracoDatabase GetConfiguredDatabase()
|
||||
{
|
||||
return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf", "System.Data.SqlServerCe.4.0");
|
||||
return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;", "System.Data.SqlServerCe.4.0");
|
||||
}
|
||||
|
||||
public string GetDatabaseSpecificSqlScript()
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Tests.TestHelpers.Entities;
|
||||
|
||||
namespace Umbraco.Tests.Models
|
||||
{
|
||||
[TestFixture]
|
||||
public class ContentExtensionsTests
|
||||
{
|
||||
[Test]
|
||||
public void Should_Create_New_Version_When_Publishing()
|
||||
{
|
||||
var contentType = MockedContentTypes.CreateTextpageContentType();
|
||||
var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1);
|
||||
|
||||
content.ResetDirtyProperties(false);
|
||||
|
||||
content.ChangePublishedState(PublishedState.Published);
|
||||
Assert.IsTrue(content.ShouldCreateNewVersion());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Should_Create_New_Version_When_Saving_After_Publishing()
|
||||
{
|
||||
var contentType = MockedContentTypes.CreateTextpageContentType();
|
||||
var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1);
|
||||
|
||||
content.ResetDirtyProperties(false);
|
||||
content.ChangePublishedState(PublishedState.Published);
|
||||
content.ResetDirtyProperties(false);
|
||||
|
||||
content.ChangePublishedState(PublishedState.Saved);
|
||||
Assert.IsTrue(content.ShouldCreateNewVersion());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Should_Create_New_Version_When_Language_Changed()
|
||||
{
|
||||
var contentType = MockedContentTypes.CreateTextpageContentType();
|
||||
var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1);
|
||||
|
||||
content.ResetDirtyProperties(false);
|
||||
|
||||
content.Language = "en-AU";
|
||||
Assert.IsTrue(content.ShouldCreateNewVersion(PublishedState.Unpublished));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Should_Create_New_Version_When_Any_Property_Value_Changed_And_Its_Already_Published()
|
||||
{
|
||||
var contentType = MockedContentTypes.CreateTextpageContentType();
|
||||
var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1);
|
||||
|
||||
content.ResetDirtyProperties(false);
|
||||
|
||||
content.Properties.First().Value = "hello world";
|
||||
Assert.IsTrue(content.ShouldCreateNewVersion(PublishedState.Published));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Should_Not_Create_New_Version_When_Published_Status_Not_Changed()
|
||||
{
|
||||
var contentType = MockedContentTypes.CreateTextpageContentType();
|
||||
var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1);
|
||||
|
||||
content.ResetDirtyProperties(false);
|
||||
|
||||
Assert.IsFalse(content.ShouldCreateNewVersion(PublishedState.Unpublished));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Should_Not_Create_New_Version_When_Not_Published_And_Property_Changed()
|
||||
{
|
||||
var contentType = MockedContentTypes.CreateTextpageContentType();
|
||||
var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1);
|
||||
|
||||
content.ResetDirtyProperties(false);
|
||||
|
||||
content.Properties.First().Value = "hello world";
|
||||
Assert.IsFalse(content.ShouldCreateNewVersion(PublishedState.Unpublished));
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void Should_Clear_Published_Flag_When_Newly_Published_Version()
|
||||
{
|
||||
var contentType = MockedContentTypes.CreateTextpageContentType();
|
||||
var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1);
|
||||
|
||||
content.ResetDirtyProperties(false);
|
||||
|
||||
content.ChangePublishedState(PublishedState.Published);
|
||||
Assert.IsTrue(content.ShouldClearPublishedFlagForPreviousVersions());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Should_Not_Clear_Published_Flag_When_Saving_Version()
|
||||
{
|
||||
var contentType = MockedContentTypes.CreateTextpageContentType();
|
||||
var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1);
|
||||
|
||||
content.ResetDirtyProperties(false);
|
||||
content.ChangePublishedState(PublishedState.Published);
|
||||
content.ResetDirtyProperties(false);
|
||||
|
||||
content.ChangePublishedState(PublishedState.Saved);
|
||||
Assert.IsFalse(content.ShouldClearPublishedFlagForPreviousVersions());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Should_Clear_Published_Flag_When_Unpublishing_From_Published()
|
||||
{
|
||||
var contentType = MockedContentTypes.CreateTextpageContentType();
|
||||
var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1);
|
||||
|
||||
content.ResetDirtyProperties(false);
|
||||
content.ChangePublishedState(PublishedState.Published);
|
||||
content.ResetDirtyProperties(false);
|
||||
|
||||
content.ChangePublishedState(PublishedState.Unpublished);
|
||||
Assert.IsTrue(content.ShouldClearPublishedFlagForPreviousVersions());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Should_Not_Clear_Published_Flag_When_Unpublishing_From_Saved()
|
||||
{
|
||||
var contentType = MockedContentTypes.CreateTextpageContentType();
|
||||
var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1);
|
||||
|
||||
content.ResetDirtyProperties(false);
|
||||
content.ChangePublishedState(PublishedState.Saved);
|
||||
content.ResetDirtyProperties(false);
|
||||
|
||||
content.ChangePublishedState(PublishedState.Unpublished);
|
||||
Assert.IsFalse(content.ShouldClearPublishedFlagForPreviousVersions());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,21 @@ namespace Umbraco.Tests.Models
|
||||
[TestFixture]
|
||||
public class ContentTests
|
||||
{
|
||||
[Test]
|
||||
public void All_Dirty_Properties_Get_Reset()
|
||||
{
|
||||
var contentType = MockedContentTypes.CreateTextpageContentType();
|
||||
var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1);
|
||||
|
||||
content.ResetDirtyProperties(false);
|
||||
|
||||
Assert.IsFalse(content.IsDirty());
|
||||
foreach (var prop in content.Properties)
|
||||
{
|
||||
Assert.IsFalse(prop.IsDirty());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Verify_Mocked_Content()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Xml;
|
||||
using NUnit.Framework;
|
||||
using Rhino.Mocks;
|
||||
using Rhino.Mocks.Interfaces;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using umbraco.cms.businesslogic.datatype;
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Tests.Models
|
||||
{
|
||||
[TestFixture]
|
||||
public class DataValueSetterTests : BaseUmbracoApplicationTest
|
||||
{
|
||||
protected override void FreezeResolution()
|
||||
{
|
||||
ShortStringHelperResolver.Current = new ShortStringHelperResolver(new DefaultShortStringHelper());
|
||||
base.FreezeResolution();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LoadValueFromDatabase_Is_Not_Called_When_SetValue_Is_Used()
|
||||
{
|
||||
// Arrange
|
||||
var baseDataType = MockRepository.GenerateStub<BaseDataType>();
|
||||
var dataTypeData = MockRepository.GenerateMock<DefaultData>(baseDataType);
|
||||
dataTypeData.Stub(x => x.Value).CallOriginalMethod(OriginalCallOptions.NoExpectation);
|
||||
|
||||
// Act
|
||||
|
||||
((IDataValueSetter)dataTypeData).SetValue("Hello world", DataTypeDatabaseType.Nvarchar.ToString());
|
||||
var val = dataTypeData.Value;
|
||||
|
||||
// Assert
|
||||
|
||||
dataTypeData.AssertWasNotCalled(data => data.LoadValueFromDatabase());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LoadValueFromDatabase_Is_Called_When_SetValue_Is_Not_Used()
|
||||
{
|
||||
// Arrange
|
||||
var baseDataType = MockRepository.GenerateStub<BaseDataType>();
|
||||
var dataTypeData = MockRepository.GenerateMock<DefaultData>(baseDataType);
|
||||
dataTypeData
|
||||
.Stub(data => data.LoadValueFromDatabase()).WhenCalled(invocation => Debug.WriteLine("asdf"));
|
||||
dataTypeData.Stub(x => x.Value).CallOriginalMethod(OriginalCallOptions.NoExpectation);
|
||||
|
||||
// Act
|
||||
|
||||
var val = dataTypeData.Value;
|
||||
|
||||
// Assert
|
||||
|
||||
dataTypeData.AssertWasCalled(data => data.LoadValueFromDatabase());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetValue_Is_Called_When_Executing_ToXml_On_A_Property_With_DataType_That_Implements_IDataValueSetter()
|
||||
{
|
||||
// Arrange
|
||||
var dataTypeId = Guid.NewGuid();
|
||||
|
||||
var dataTypeData = MockRepository.GenerateMock<IData, IDataValueSetter>();
|
||||
|
||||
dataTypeData
|
||||
.Stub(data => data.ToXMl(Arg<XmlDocument>.Is.Anything))
|
||||
.Return(null) // you have to call Return() even though we're about to override it
|
||||
.WhenCalled(invocation =>
|
||||
{
|
||||
var xmlDoc = (XmlDocument) invocation.Arguments[0];
|
||||
invocation.ReturnValue = xmlDoc.CreateElement("test");
|
||||
});
|
||||
|
||||
var dataType = MockRepository.GenerateStub<IDataType>();
|
||||
dataType.Stub(type => type.Data).Return(dataTypeData);
|
||||
|
||||
var dataTypeSvc = MockRepository.GenerateStub<IDataTypeService>();
|
||||
dataTypeSvc.Stub(service => service.GetDataTypeById(dataTypeId)).Return(dataType);
|
||||
|
||||
var property = new Property(
|
||||
1234,
|
||||
Guid.NewGuid(),
|
||||
new PropertyType(dataTypeId, DataTypeDatabaseType.Nvarchar)
|
||||
{
|
||||
Alias = "test"
|
||||
}, "Hello world");
|
||||
|
||||
// Act
|
||||
|
||||
var xml = property.ToXml(dataTypeSvc);
|
||||
|
||||
// Assert
|
||||
|
||||
((IDataValueSetter)dataTypeData).AssertWasCalled(setter => setter.SetValue("Hello world", DataTypeDatabaseType.Nvarchar.ToString()));
|
||||
}
|
||||
|
||||
[TestCase(DataTypeDatabaseType.Nvarchar)]
|
||||
[TestCase(DataTypeDatabaseType.Date)]
|
||||
[TestCase(DataTypeDatabaseType.Integer)]
|
||||
[TestCase(DataTypeDatabaseType.Ntext)]
|
||||
public void DefaultData_SetValue_Ensures_Empty_String_When_Null_Value_Any_Data_Type(DataTypeDatabaseType type)
|
||||
{
|
||||
var defaultData = new DefaultData(MockRepository.GenerateMock<BaseDataType>());
|
||||
|
||||
((IDataValueSetter)defaultData).SetValue(null, type.ToString());
|
||||
|
||||
Assert.AreEqual(string.Empty, defaultData.Value);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -69,7 +69,7 @@ namespace Umbraco.Tests.Persistence
|
||||
//Get the connectionstring settings from config
|
||||
var settings = ConfigurationManager.ConnectionStrings[Core.Configuration.GlobalSettings.UmbracoConnectionName];
|
||||
|
||||
//by default the conn string is: Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf
|
||||
//by default the conn string is: Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;
|
||||
//we'll just replace the sdf file with our custom one:
|
||||
//Create the Sql CE database
|
||||
var engine = new SqlCeEngine(settings.ConnectionString.Replace("UmbracoPetaPocoTests", "DatabaseContextTests"));
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
@@ -73,13 +74,47 @@ namespace Umbraco.Tests.Persistence
|
||||
db.OpenSharedConnection();
|
||||
|
||||
// Act
|
||||
string sql;
|
||||
string[] sql;
|
||||
db.GenerateBulkInsertCommand(servers, db.Connection, out sql);
|
||||
db.CloseSharedConnection();
|
||||
|
||||
// Assert
|
||||
Assert.That(sql,
|
||||
Assert.That(sql[0],
|
||||
Is.EqualTo("INSERT INTO [umbracoServer] ([umbracoServer].[address], [umbracoServer].[computerName], [umbracoServer].[registeredDate], [umbracoServer].[lastNotifiedDate], [umbracoServer].[isActive]) VALUES (@0,@1,@2,@3,@4), (@5,@6,@7,@8,@9)"));
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void Generate_Bulk_Import_Sql_Exceeding_Max_Params()
|
||||
{
|
||||
// Arrange
|
||||
var db = DatabaseContext.Database;
|
||||
|
||||
var servers = new List<ServerRegistrationDto>();
|
||||
for (var i = 0; i < 1500; i++)
|
||||
{
|
||||
servers.Add(new ServerRegistrationDto
|
||||
{
|
||||
Address = "address" + i,
|
||||
ComputerName = "computer" + i,
|
||||
DateRegistered = DateTime.Now,
|
||||
IsActive = true,
|
||||
LastNotified = DateTime.Now
|
||||
});
|
||||
}
|
||||
db.OpenSharedConnection();
|
||||
|
||||
// Act
|
||||
string[] sql;
|
||||
db.GenerateBulkInsertCommand(servers, db.Connection, out sql);
|
||||
db.CloseSharedConnection();
|
||||
|
||||
// Assert
|
||||
Assert.That(sql.Length, Is.EqualTo(4));
|
||||
foreach (var s in sql)
|
||||
{
|
||||
Assert.LessOrEqual(Regex.Matches(s, "@\\d+").Count, 2000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,12 +35,12 @@ namespace Umbraco.Tests.Persistence
|
||||
}
|
||||
|
||||
//Create the Sql CE database
|
||||
var engine = new SqlCeEngine("Datasource=|DataDirectory|test.sdf");
|
||||
var engine = new SqlCeEngine("Datasource=|DataDirectory|test.sdf;Flush Interval=1;");
|
||||
engine.CreateDatabase();
|
||||
|
||||
SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider;
|
||||
|
||||
_database = new Database("Datasource=|DataDirectory|test.sdf",
|
||||
_database = new Database("Datasource=|DataDirectory|test.sdf;Flush Interval=1;",
|
||||
"System.Data.SqlServerCe.4.0");
|
||||
}
|
||||
|
||||
|
||||
@@ -160,14 +160,15 @@ namespace Umbraco.Tests
|
||||
{
|
||||
var tempFolder = IOHelper.MapPath("~/App_Data/TEMP/PluginCache");
|
||||
var manager = new PluginManager(false);
|
||||
var filePath = Path.Combine(tempFolder, "umbraco-plugins.list");
|
||||
var filePath= Path.Combine(tempFolder, string.Format("umbraco-plugins.{0}.list", NetworkHelper.FileSafeMachineName));
|
||||
|
||||
File.WriteAllText(filePath, @"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||
<plugins>
|
||||
<baseType type=""umbraco.interfaces.ICacheRefresher"">
|
||||
<add type=""umbraco.macroCacheRefresh, umbraco, Version=6.0.0.0, Culture=neutral, PublicKeyToken=null"" />
|
||||
</baseType>
|
||||
</plugins>");
|
||||
|
||||
|
||||
Assert.IsTrue(manager.DetectLegacyPluginListFile());
|
||||
|
||||
File.Delete(filePath);
|
||||
@@ -295,7 +296,7 @@ namespace Umbraco.Tests
|
||||
public void Resolves_Trees()
|
||||
{
|
||||
var trees = PluginManager.Current.ResolveTrees();
|
||||
Assert.AreEqual(36, trees.Count());
|
||||
Assert.AreEqual(40, trees.Count());
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace Umbraco.Tests.PublishedCache
|
||||
Assert.AreEqual(mRoot.Id, publishedMedia.Id);
|
||||
Assert.AreEqual(mRoot.CreateDateTime.ToString("dd/MM/yyyy HH:mm:ss"), publishedMedia.CreateDate.ToString("dd/MM/yyyy HH:mm:ss"));
|
||||
Assert.AreEqual(mRoot.User.Id, publishedMedia.CreatorId);
|
||||
Assert.AreEqual(mRoot.User.LoginName, publishedMedia.CreatorName);
|
||||
Assert.AreEqual(mRoot.User.Name, publishedMedia.CreatorName);
|
||||
Assert.AreEqual(mRoot.ContentType.Alias, publishedMedia.DocumentTypeAlias);
|
||||
Assert.AreEqual(mRoot.ContentType.Id, publishedMedia.DocumentTypeId);
|
||||
Assert.AreEqual(mRoot.Level, publishedMedia.Level);
|
||||
|
||||
@@ -306,12 +306,13 @@ namespace Umbraco.Tests.Services
|
||||
public void Can_RePublish_All_Content()
|
||||
{
|
||||
// Arrange
|
||||
var contentService = ServiceContext.ContentService;
|
||||
var contentService = (ContentService)ServiceContext.ContentService;
|
||||
var rootContent = contentService.GetRootContent();
|
||||
foreach (var c in rootContent)
|
||||
{
|
||||
contentService.PublishWithChildren(c);
|
||||
}
|
||||
var allContent = rootContent.Concat(rootContent.SelectMany(x => x.Descendants()));
|
||||
//for testing we need to clear out the contentXml table so we can see if it worked
|
||||
var provider = new PetaPocoUnitOfWorkProvider();
|
||||
var uow = provider.GetUnitOfWork();
|
||||
@@ -319,13 +320,49 @@ namespace Umbraco.Tests.Services
|
||||
{
|
||||
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);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(published);
|
||||
uow = provider.GetUnitOfWork();
|
||||
using (var repo = RepositoryResolver.Current.ResolveByType<IContentRepository>(uow))
|
||||
{
|
||||
Assert.AreEqual(allContent.Count(), uow.Database.ExecuteScalar<int>("select count(*) from cmsContentXml"));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_RePublish_All_Content_Of_Type()
|
||||
{
|
||||
// Arrange
|
||||
var contentService = (ContentService)ServiceContext.ContentService;
|
||||
var rootContent = contentService.GetRootContent();
|
||||
foreach (var c in rootContent)
|
||||
{
|
||||
contentService.PublishWithChildren(c);
|
||||
}
|
||||
var allContent = rootContent.Concat(rootContent.SelectMany(x => x.Descendants()));
|
||||
//for testing we need to clear out the contentXml table so we can see if it worked
|
||||
var provider = new PetaPocoUnitOfWorkProvider();
|
||||
var uow = provider.GetUnitOfWork();
|
||||
using (RepositoryResolver.Current.ResolveByType<IContentRepository>(uow))
|
||||
{
|
||||
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
|
||||
contentService.RePublishAll(new int[]{allContent.Last().ContentTypeId});
|
||||
|
||||
// Assert
|
||||
uow = provider.GetUnitOfWork();
|
||||
using (var repo = RepositoryResolver.Current.ResolveByType<IContentRepository>(uow))
|
||||
{
|
||||
@@ -688,15 +725,21 @@ namespace Umbraco.Tests.Services
|
||||
{
|
||||
// Arrange
|
||||
var contentService = ServiceContext.ContentService;
|
||||
var content = contentService.GetById(1048);
|
||||
var temp = contentService.GetById(1048);
|
||||
|
||||
// Act
|
||||
var copy = contentService.Copy(content, content.ParentId, false, 0);
|
||||
var copy = contentService.Copy(temp, temp.ParentId, false, 0);
|
||||
var content = contentService.GetById(1048);
|
||||
|
||||
// Assert
|
||||
Assert.That(copy, Is.Not.Null);
|
||||
Assert.That(copy.Id, Is.Not.EqualTo(content.Id));
|
||||
Assert.AreNotSame(content, copy);
|
||||
foreach (var property in copy.Properties)
|
||||
{
|
||||
Assert.AreNotEqual(property.Id, content.Properties[property.Alias].Id);
|
||||
Assert.AreEqual(property.Value, content.Properties[property.Alias].Value);
|
||||
}
|
||||
//Assert.AreNotEqual(content.Name, copy.Name);
|
||||
}
|
||||
|
||||
@@ -776,6 +819,64 @@ namespace Umbraco.Tests.Services
|
||||
Assert.That(hasPublishedVersion, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Verify_Property_Types_On_Content()
|
||||
{
|
||||
// Arrange
|
||||
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);
|
||||
contentService.Save(content);
|
||||
var id = content.Id;
|
||||
|
||||
// Act
|
||||
var sut = contentService.GetById(id);
|
||||
|
||||
// Arrange
|
||||
Assert.That(sut.GetValue<bool>("isTrue"), Is.True);
|
||||
Assert.That(sut.GetValue<int>("number"), Is.EqualTo(42));
|
||||
Assert.That(sut.GetValue<string>("bodyText"), Is.EqualTo("Lorem Ipsum Body Text Test"));
|
||||
Assert.That(sut.GetValue<string>("singleLineText"), Is.EqualTo("Single Line Text Test"));
|
||||
Assert.That(sut.GetValue<string>("multilineText"), Is.EqualTo("Multiple lines \n in one box"));
|
||||
Assert.That(sut.GetValue<string>("upload"), Is.EqualTo("/media/1234/koala.jpg"));
|
||||
Assert.That(sut.GetValue<string>("label"), Is.EqualTo("Non-editable label"));
|
||||
Assert.That(sut.GetValue<DateTime>("dateTime"), Is.EqualTo(content.GetValue<DateTime>("dateTime")));
|
||||
Assert.That(sut.GetValue<string>("colorPicker"), Is.EqualTo("black"));
|
||||
Assert.That(sut.GetValue<string>("folderBrowser"), Is.Empty);
|
||||
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"), Is.EqualTo(content.GetValue<DateTime>("date")));
|
||||
Assert.That(sut.GetValue<string>("ddl"), Is.EqualTo("1234"));
|
||||
Assert.That(sut.GetValue<string>("chklist"), Is.EqualTo("randomc"));
|
||||
Assert.That(sut.GetValue<int>("contentPicker"), Is.EqualTo(1090));
|
||||
Assert.That(sut.GetValue<int>("mediaPicker"), Is.EqualTo(1091));
|
||||
Assert.That(sut.GetValue<int>("memberPicker"), Is.EqualTo(1092));
|
||||
Assert.That(sut.GetValue<string>("simpleEditor"), Is.EqualTo("This is simply edited"));
|
||||
Assert.That(sut.GetValue<string>("ultimatePicker"), Is.EqualTo("1234,1235"));
|
||||
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"));
|
||||
Assert.That(sut.GetValue<string>("macroContainer"), Is.Empty);
|
||||
Assert.That(sut.GetValue<string>("imgCropper"), Is.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Delete_Previous_Versions_Not_Latest()
|
||||
{
|
||||
// Arrange
|
||||
var contentService = ServiceContext.ContentService;
|
||||
var content = contentService.GetById(1049);
|
||||
var version = content.Version;
|
||||
|
||||
// Act
|
||||
contentService.DeleteVersion(1049, version, true, 0);
|
||||
var sut = contentService.GetById(1049);
|
||||
|
||||
// Assert
|
||||
Assert.That(sut.Version, Is.EqualTo(version));
|
||||
}
|
||||
|
||||
private IEnumerable<IContent> CreateContentHierarchy()
|
||||
{
|
||||
var contentType = ServiceContext.ContentTypeService.GetContentType("umbTextpage");
|
||||
|
||||
@@ -263,6 +263,41 @@ namespace Umbraco.Tests.Services
|
||||
Assert.That(homepage.CompositionPropertyTypes.Count(), Is.EqualTo(4));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Copy_ContentType_By_Performing_Clone()
|
||||
{
|
||||
// Arrange
|
||||
var service = ServiceContext.ContentTypeService;
|
||||
var metaContentType = MockedContentTypes.CreateMetaContentType();
|
||||
service.Save(metaContentType);
|
||||
|
||||
var simpleContentType = MockedContentTypes.CreateSimpleContentType("category", "Category", metaContentType);
|
||||
service.Save(simpleContentType);
|
||||
var categoryId = simpleContentType.Id;
|
||||
|
||||
// Act
|
||||
var sut = simpleContentType.Clone("newcategory");
|
||||
service.Save(sut);
|
||||
|
||||
// Assert
|
||||
Assert.That(sut.HasIdentity, Is.True);
|
||||
|
||||
var contentType = service.GetContentType(sut.Id);
|
||||
var category = service.GetContentType(categoryId);
|
||||
|
||||
Assert.That(contentType.CompositionAliases().Any(x => x.Equals("meta")), Is.True);
|
||||
Assert.AreEqual(contentType.ParentId, category.ParentId);
|
||||
Assert.AreEqual(contentType.Level, category.Level);
|
||||
Assert.AreEqual(contentType.PropertyTypes.Count(), category.PropertyTypes.Count());
|
||||
Assert.AreNotEqual(contentType.Id, category.Id);
|
||||
Assert.AreNotEqual(contentType.Key, category.Key);
|
||||
Assert.AreNotEqual(contentType.Path, category.Path);
|
||||
Assert.AreNotEqual(contentType.SortOrder, category.SortOrder);
|
||||
Assert.AreNotEqual(contentType.PropertyTypes.First(x => x.Alias.Equals("title")).Id, category.PropertyTypes.First(x => x.Alias.Equals("title")).Id);
|
||||
Assert.AreNotEqual(contentType.PropertyGroups.First(x => x.Name.Equals("Content")).Id, category.PropertyGroups.First(x => x.Name.Equals("Content")).Id);
|
||||
|
||||
}
|
||||
|
||||
private ContentType CreateComponent()
|
||||
{
|
||||
var component = new ContentType(-1)
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Tests.TestHelpers.Entities;
|
||||
|
||||
namespace Umbraco.Tests.Services
|
||||
{
|
||||
//[TestFixture]
|
||||
//public class PackagingServiceTests : BaseServiceTest
|
||||
//{
|
||||
// [Test]
|
||||
// public void Export_Content()
|
||||
// {
|
||||
// var yesNo = DataTypesResolver.Current.GetById(new Guid(Constants.PropertyEditors.TrueFalse));
|
||||
// var txtField = DataTypesResolver.Current.GetById(new Guid(Constants.PropertyEditors.Textbox));
|
||||
|
||||
// var contentWithDataType = MockedContentTypes.CreateSimpleContentType(
|
||||
// "test",
|
||||
// "Test",
|
||||
// new PropertyTypeCollection(
|
||||
// new PropertyType[]
|
||||
// {
|
||||
// new PropertyType(new DataTypeDefinition(-1, txtField.Id)
|
||||
// {
|
||||
// Name = "Testing Textfield", DatabaseType = DataTypeDatabaseType.Ntext
|
||||
// }),
|
||||
// new PropertyType(new DataTypeDefinition(-1, yesNo.Id)
|
||||
// {
|
||||
// Name = "Testing intfield", DatabaseType = DataTypeDatabaseType.Integer
|
||||
// })
|
||||
// }));
|
||||
|
||||
// var content = MockedContent.CreateSimpleContent(contentWithDataType);
|
||||
// content.Name = "Test";
|
||||
|
||||
// var exported = ServiceContext.PackagingService.Export(content);
|
||||
|
||||
// }
|
||||
//}
|
||||
}
|
||||
@@ -0,0 +1,362 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Data.SqlServerCe;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Xml.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Caching;
|
||||
using Umbraco.Core.Persistence.Repositories;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Tests.TestHelpers.Entities;
|
||||
|
||||
namespace Umbraco.Tests.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Tests covering all methods in the ContentService class.
|
||||
/// This is more of an integration test as it involves multiple layers
|
||||
/// as well as configuration.
|
||||
/// </summary>
|
||||
[TestFixture, RequiresSTA]
|
||||
[NUnit.Framework.Ignore("These should not be run by the server, only directly as they are only benchmark tests")]
|
||||
public class PerformanceTests : BaseDatabaseFactoryTest
|
||||
{
|
||||
[SetUp]
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
}
|
||||
|
||||
protected override string GetDbConnectionString()
|
||||
{
|
||||
return @"server=.\SQLEXPRESS;database=UmbTest;user id=sa;password=test";
|
||||
}
|
||||
|
||||
protected override string GetDbProviderName()
|
||||
{
|
||||
return "System.Data.SqlClient";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// new schema per test
|
||||
/// </summary>
|
||||
protected override DatabaseBehavior DatabaseTestBehavior
|
||||
{
|
||||
get { return DatabaseBehavior.NewSchemaPerTest; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// don't create anything, we're testing against our own server
|
||||
/// </summary>
|
||||
protected override void CreateSqlCeDatabase()
|
||||
{
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public override void TearDown()
|
||||
{
|
||||
base.TearDown();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Get_All_Published_Content()
|
||||
{
|
||||
var result = PrimeDbWithLotsOfContent();
|
||||
var contentSvc = (ContentService) ServiceContext.ContentService;
|
||||
|
||||
var countOfPublished = result.Count(x => x.Published);
|
||||
var contentTypeId = result.First().ContentTypeId;
|
||||
|
||||
using (DisposableTimer.DebugDuration<PerformanceTests>("Getting published content normally"))
|
||||
{
|
||||
//do this 10x!
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
//clear the cache to make this test valid
|
||||
RuntimeCacheProvider.Current.Clear();
|
||||
|
||||
var published = new List<IContent>();
|
||||
//get all content items that are published
|
||||
var rootContent = contentSvc.GetRootContent();
|
||||
foreach (var content in rootContent.Where(content => content.Published))
|
||||
{
|
||||
published.Add(content);
|
||||
published.AddRange(contentSvc.GetPublishedDescendants(content));
|
||||
}
|
||||
Assert.AreEqual(countOfPublished, published.Count(x => x.ContentTypeId == contentTypeId));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
using (DisposableTimer.DebugDuration<PerformanceTests>("Getting published content optimized"))
|
||||
{
|
||||
|
||||
//do this 10x!
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
//clear the cache to make this test valid
|
||||
RuntimeCacheProvider.Current.Clear();
|
||||
|
||||
//get all content items that are published
|
||||
var published = contentSvc.GetAllPublished();
|
||||
|
||||
Assert.AreEqual(countOfPublished, published.Count(x => x.ContentTypeId == contentTypeId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Get_All_Published_Content_Of_Type()
|
||||
{
|
||||
var result = PrimeDbWithLotsOfContent();
|
||||
var contentSvc = (ContentService)ServiceContext.ContentService;
|
||||
|
||||
var countOfPublished = result.Count(x => x.Published);
|
||||
var contentTypeId = result.First().ContentTypeId;
|
||||
|
||||
using (DisposableTimer.DebugDuration<PerformanceTests>("Getting published content of type normally"))
|
||||
{
|
||||
//do this 10x!
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
//clear the cache to make this test valid
|
||||
RuntimeCacheProvider.Current.Clear();
|
||||
//get all content items that are published of this type
|
||||
var published = contentSvc.GetContentOfContentType(contentTypeId).Where(content => content.Published);
|
||||
Assert.AreEqual(countOfPublished, published.Count(x => x.ContentTypeId == contentTypeId));
|
||||
}
|
||||
}
|
||||
|
||||
using (DisposableTimer.DebugDuration<PerformanceTests>("Getting published content of type optimized"))
|
||||
{
|
||||
|
||||
//do this 10x!
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
//clear the cache to make this test valid
|
||||
RuntimeCacheProvider.Current.Clear();
|
||||
//get all content items that are published of this type
|
||||
var published = contentSvc.GetPublishedContentOfContentType(contentTypeId);
|
||||
Assert.AreEqual(countOfPublished, published.Count(x => x.ContentTypeId == contentTypeId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Truncate_Insert_Vs_Update_Insert()
|
||||
{
|
||||
var customObjectType = Guid.NewGuid();
|
||||
//chuck lots of data in the db
|
||||
var nodes = PrimeDbWithLotsOfContentXmlRecords(customObjectType);
|
||||
|
||||
//now we need to test the difference between truncating all records and re-inserting them as we do now,
|
||||
//vs updating them (which might result in checking if they exist for or listening on an exception).
|
||||
using (DisposableTimer.DebugDuration<PerformanceTests>("Starting truncate + normal insert test"))
|
||||
{
|
||||
//do this 10x!
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
//clear all the xml entries
|
||||
DatabaseContext.Database.Execute(@"DELETE FROM cmsContentXml WHERE nodeId IN
|
||||
(SELECT DISTINCT cmsContentXml.nodeId FROM cmsContentXml
|
||||
INNER JOIN cmsContent ON cmsContentXml.nodeId = cmsContent.nodeId)");
|
||||
|
||||
//now we insert each record for the ones we've deleted like we do in the content service.
|
||||
var xmlItems = nodes.Select(node => new ContentXmlDto { NodeId = node.NodeId, Xml = UpdatedXmlStructure }).ToList();
|
||||
foreach (var xml in xmlItems)
|
||||
{
|
||||
var result = DatabaseContext.Database.Insert(xml);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//now, isntead of truncating, we'll attempt to update and if it doesn't work then we insert
|
||||
using (DisposableTimer.DebugDuration<PerformanceTests>("Starting update test"))
|
||||
{
|
||||
//do this 10x!
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
//now we insert each record for the ones we've deleted like we do in the content service.
|
||||
var xmlItems = nodes.Select(node => new ContentXmlDto { NodeId = node.NodeId, Xml = UpdatedXmlStructure }).ToList();
|
||||
foreach (var xml in xmlItems)
|
||||
{
|
||||
var result = DatabaseContext.Database.Update(xml);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//now, test truncating but then do bulk insertion of records
|
||||
using (DisposableTimer.DebugDuration<PerformanceTests>("Starting truncate + bulk insert test"))
|
||||
{
|
||||
//do this 10x!
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
//clear all the xml entries
|
||||
DatabaseContext.Database.Execute(@"DELETE FROM cmsContentXml WHERE nodeId IN
|
||||
(SELECT DISTINCT cmsContentXml.nodeId FROM cmsContentXml
|
||||
INNER JOIN cmsContent ON cmsContentXml.nodeId = cmsContent.nodeId)");
|
||||
|
||||
//now we insert each record for the ones we've deleted like we do in the content service.
|
||||
var xmlItems = nodes.Select(node => new ContentXmlDto { NodeId = node.NodeId, Xml = UpdatedXmlStructure }).ToList();
|
||||
DatabaseContext.Database.BulkInsertRecords(xmlItems);
|
||||
}
|
||||
}
|
||||
|
||||
//now, test truncating but then do bulk insertion of records
|
||||
using (DisposableTimer.DebugDuration<PerformanceTests>("Starting truncate + bulk insert test in one transaction"))
|
||||
{
|
||||
//do this 10x!
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
//now we insert each record for the ones we've deleted like we do in the content service.
|
||||
var xmlItems = nodes.Select(node => new ContentXmlDto { NodeId = node.NodeId, Xml = UpdatedXmlStructure }).ToList();
|
||||
|
||||
using (var tr = DatabaseContext.Database.GetTransaction())
|
||||
{
|
||||
//clear all the xml entries
|
||||
DatabaseContext.Database.Execute(@"DELETE FROM cmsContentXml WHERE nodeId IN
|
||||
(SELECT DISTINCT cmsContentXml.nodeId FROM cmsContentXml
|
||||
INNER JOIN cmsContent ON cmsContentXml.nodeId = cmsContent.nodeId)");
|
||||
|
||||
|
||||
DatabaseContext.Database.BulkInsertRecords(xmlItems, tr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private IEnumerable<IContent> PrimeDbWithLotsOfContent()
|
||||
{
|
||||
var contentType1 = MockedContentTypes.CreateSimpleContentType();
|
||||
contentType1.AllowedAsRoot = true;
|
||||
ServiceContext.ContentTypeService.Save(contentType1);
|
||||
contentType1.AllowedContentTypes = new List<ContentTypeSort>
|
||||
{
|
||||
new ContentTypeSort
|
||||
{
|
||||
Alias = contentType1.Alias,
|
||||
Id = new Lazy<int>(() => contentType1.Id),
|
||||
SortOrder = 0
|
||||
}
|
||||
};
|
||||
var result = new List<IContent>();
|
||||
ServiceContext.ContentTypeService.Save(contentType1);
|
||||
IContent lastParent = MockedContent.CreateSimpleContent(contentType1);
|
||||
ServiceContext.ContentService.SaveAndPublish(lastParent);
|
||||
result.Add(lastParent);
|
||||
//create 20 deep
|
||||
for (var i = 0; i < 20; i++)
|
||||
{
|
||||
//for each level, create 20
|
||||
IContent content = null;
|
||||
for (var j = 1; j <= 10; j++)
|
||||
{
|
||||
content = MockedContent.CreateSimpleContent(contentType1, "Name" + j, lastParent);
|
||||
//only publish evens
|
||||
if (j % 2 == 0)
|
||||
{
|
||||
ServiceContext.ContentService.SaveAndPublish(content);
|
||||
}
|
||||
else
|
||||
{
|
||||
ServiceContext.ContentService.Save(content);
|
||||
}
|
||||
result.Add(content);
|
||||
}
|
||||
|
||||
//assign the last one as the next parent
|
||||
lastParent = content;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private IEnumerable<NodeDto> PrimeDbWithLotsOfContentXmlRecords(Guid customObjectType)
|
||||
{
|
||||
var nodes = new List<NodeDto>();
|
||||
for (var i = 1; i < 10000; i++)
|
||||
{
|
||||
nodes.Add(new NodeDto
|
||||
{
|
||||
Level = 1,
|
||||
ParentId = -1,
|
||||
NodeObjectType = customObjectType,
|
||||
Text = i.ToString(CultureInfo.InvariantCulture),
|
||||
UserId = 0,
|
||||
CreateDate = DateTime.Now,
|
||||
Trashed = false,
|
||||
SortOrder = 0,
|
||||
Path = ""
|
||||
});
|
||||
}
|
||||
DatabaseContext.Database.BulkInsertRecords(nodes);
|
||||
|
||||
//re-get the nodes with ids
|
||||
var sql = new Sql();
|
||||
sql.Select("*").From<NodeDto>().Where<NodeDto>(x => x.NodeObjectType == customObjectType);
|
||||
nodes = DatabaseContext.Database.Fetch<NodeDto>(sql);
|
||||
|
||||
//create the cmsContent data, each with a new content type id (so we can query on it later if needed)
|
||||
var contentTypeId = 0;
|
||||
var cmsContentItems = nodes.Select(node => new ContentDto { NodeId = node.NodeId, ContentTypeId = contentTypeId++ }).ToList();
|
||||
DatabaseContext.Database.BulkInsertRecords(cmsContentItems);
|
||||
|
||||
//create the xml data
|
||||
var xmlItems = nodes.Select(node => new ContentXmlDto { NodeId = node.NodeId, Xml = TestXmlStructure }).ToList();
|
||||
DatabaseContext.Database.BulkInsertRecords(xmlItems);
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
private const string TestXmlStructure = @"<Homepage id='1231' parentID='-1' level='1' creatorID='0' sortOrder='0' createDate='2013-07-05T12:05:28' updateDate='2013-07-26T11:58:52' nodeName='Home (1)' urlName='home-(1)' path='-1,1231' isDoc='' nodeType='1221' creatorName='admin' writerName='admin' writerID='0' template='2629' nodeTypeAlias='Homepage'>
|
||||
<umbracoNaviHide>0</umbracoNaviHide>
|
||||
<title>Standard Site for Umbraco by Koiak</title>
|
||||
<description><![CDATA[]]></description>
|
||||
<keywords><![CDATA[]]></keywords>
|
||||
<slideshow><![CDATA[1250,1251,1252]]></slideshow>
|
||||
<panelContent1><![CDATA[<h2>Built by Creative Founds</h2>
|
||||
<p><img src='/images/web_applications.jpg' alt='Web Applications' class='fr'/><strong>Creative Founds</strong> design and build first class software solutions that deliver big results. We provide ASP.NET web and mobile applications, Umbraco development service & technical consultancy.</p>
|
||||
<p><a href='http://www.creativefounds.co.uk' target='_blank'>www.creativefounds.co.uk</a></p>]]></panelContent1>
|
||||
<panelContent2><![CDATA[<h2>Umbraco Development</h2>
|
||||
<p><img src='/images/umbraco_square.jpg' alt='Umbraco' class='fr'/>Umbraco the the leading ASP.NET open source CMS, under pinning over 150,000 websites. Our Certified Developers are experts in developing high performance and feature rich websites.</p>]]></panelContent2>
|
||||
<panelContent3><![CDATA[<h2>Contact Us</h2>
|
||||
<p><a href='http://www.twitter.com/chriskoiak' target='_blank'><img src='/images/twitter_square.png' alt='Contact Us on Twitter' class='fr'/></a>We'd love to hear how this package has helped you and how it can be improved. Get in touch on the <a href='http://our.umbraco.org/projects/starter-kits/standard-website-mvc' target='_blank'>project website</a> or via <a href='http://www.twitter.com/chriskoiak' target='_blank'>twitter</a></p>]]></panelContent3>
|
||||
<primaryNavigation><![CDATA[1231,1232,1236,1238,1239]]></primaryNavigation>
|
||||
<address>Standard Website MVC, Company Address, Glasgow, Postcode</address>
|
||||
<copyright>Copyright &copy; 2012 Your Company</copyright>
|
||||
<affiliationLink1>http://www.umbraco.org</affiliationLink1>
|
||||
<affiliationImage1>/media/1477/umbraco_logo.png</affiliationImage1>
|
||||
<affiliationLink2></affiliationLink2>
|
||||
<affiliationImage2></affiliationImage2>
|
||||
<affiliationLink3></affiliationLink3>
|
||||
<affiliationImage3></affiliationImage3>
|
||||
<headerNavigation><![CDATA[1242,1243]]></headerNavigation>
|
||||
<myList><![CDATA[]]></myList>
|
||||
<myDate>2013-07-01T00:00:00</myDate>
|
||||
</Homepage>";
|
||||
|
||||
private const string UpdatedXmlStructure = @"<Standard id='1238' parentID='1231' level='2' creatorID='0' sortOrder='2' createDate='2013-07-05T12:05:29' updateDate='2013-07-05T12:05:34' nodeName='Clients' urlName='clients' path='-1,1231,1238' isDoc='' nodeType='1217' creatorName='admin' writerName='admin' writerID='0' template='1213' nodeTypeAlias='Standard'>
|
||||
<umbracoNaviHide>0</umbracoNaviHide>
|
||||
<title></title>
|
||||
<description><![CDATA[]]></description>
|
||||
<keywords><![CDATA[]]></keywords>
|
||||
<bodyText><![CDATA[<h2>Clients</h2>
|
||||
<p><strong>This is a standard content page.</strong></p>
|
||||
<p><span>Vestibulum malesuada aliquet ante, vitae ullamcorper felis faucibus vel. Vestibulum condimentum faucibus tellus porta ultrices. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. </span></p>
|
||||
<p><span>Cras at auctor orci. Praesent facilisis erat nec odio consequat at posuere ligula pretium. Nulla eget felis id nisl volutpat pellentesque. Ut id augue id ligula placerat rutrum a nec purus. Maecenas sed lectus ac mi pellentesque luctus quis sit amet turpis. Vestibulum adipiscing convallis vestibulum. </span></p>
|
||||
<p><span>Duis condimentum lectus at orci placerat vitae imperdiet lorem cursus. Duis hendrerit porta lorem, non suscipit quam consectetur vitae. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean elit augue, tincidunt nec tincidunt id, elementum vel est.</span></p>]]></bodyText>
|
||||
<contentPanels><![CDATA[]]></contentPanels>
|
||||
</Standard>";
|
||||
|
||||
}
|
||||
}
|
||||
@@ -46,37 +46,47 @@ namespace Umbraco.Tests.TestHelpers
|
||||
//Used to flag if its the first test in the current fixture
|
||||
private bool _isFirstTestInFixture = false;
|
||||
|
||||
private ApplicationContext _appContext;
|
||||
|
||||
[SetUp]
|
||||
public override void Initialize()
|
||||
{
|
||||
InitializeFirstRunFlags();
|
||||
|
||||
base.Initialize();
|
||||
|
||||
|
||||
var path = TestHelper.CurrentAssemblyDirectory;
|
||||
AppDomain.CurrentDomain.SetData("DataDirectory", path);
|
||||
|
||||
ApplicationContext.Current = new ApplicationContext(
|
||||
var dbFactory = new DefaultDatabaseFactory(
|
||||
GetDbConnectionString(),
|
||||
GetDbProviderName());
|
||||
_appContext = new ApplicationContext(
|
||||
//assign the db context
|
||||
new DatabaseContext(new DefaultDatabaseFactory()),
|
||||
new DatabaseContext(dbFactory),
|
||||
//assign the service context
|
||||
new ServiceContext(new PetaPocoUnitOfWorkProvider(), new FileUnitOfWorkProvider(), new PublishingStrategy()),
|
||||
new ServiceContext(new PetaPocoUnitOfWorkProvider(dbFactory), new FileUnitOfWorkProvider(), new PublishingStrategy()),
|
||||
//disable cache
|
||||
false)
|
||||
{
|
||||
IsReady = true
|
||||
};
|
||||
|
||||
DatabaseContext.Initialize();
|
||||
base.Initialize();
|
||||
|
||||
CreateDatabase();
|
||||
DatabaseContext.Initialize(dbFactory.ProviderName, dbFactory.ConnectionString);
|
||||
|
||||
CreateSqlCeDatabase();
|
||||
|
||||
InitializeDatabase();
|
||||
|
||||
//ensure the configuration matches the current version for tests
|
||||
SettingsForTests.ConfigurationStatus = UmbracoVersion.Current.ToString(3);
|
||||
}
|
||||
|
||||
|
||||
protected override void SetupApplicationContext()
|
||||
{
|
||||
ApplicationContext.Current = _appContext;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The database behavior to use for the test/fixture
|
||||
/// </summary>
|
||||
@@ -85,10 +95,23 @@ namespace Umbraco.Tests.TestHelpers
|
||||
get { return DatabaseBehavior.NewSchemaPerTest; }
|
||||
}
|
||||
|
||||
protected virtual string GetDbProviderName()
|
||||
{
|
||||
return "System.Data.SqlServerCe.4.0";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the db conn string
|
||||
/// </summary>
|
||||
protected virtual string GetDbConnectionString()
|
||||
{
|
||||
return @"Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the SqlCe database if required
|
||||
/// </summary>
|
||||
protected virtual void CreateDatabase()
|
||||
protected virtual void CreateSqlCeDatabase()
|
||||
{
|
||||
if (DatabaseTestBehavior == DatabaseBehavior.NoDatabasePerFixture)
|
||||
return;
|
||||
@@ -97,7 +120,9 @@ namespace Umbraco.Tests.TestHelpers
|
||||
|
||||
//Get the connectionstring settings from config
|
||||
var settings = ConfigurationManager.ConnectionStrings[Core.Configuration.GlobalSettings.UmbracoConnectionName];
|
||||
ConfigurationManager.AppSettings.Set(Core.Configuration.GlobalSettings.UmbracoConnectionName, @"datalayer=SQLCE4Umbraco.SqlCEHelper,SQLCE4Umbraco;data source=|DataDirectory|\UmbracoPetaPocoTests.sdf");
|
||||
ConfigurationManager.AppSettings.Set(
|
||||
Core.Configuration.GlobalSettings.UmbracoConnectionName,
|
||||
GetDbConnectionString());
|
||||
|
||||
string dbFilePath = string.Concat(path, "\\UmbracoPetaPocoTests.sdf");
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@ namespace Umbraco.Tests.TestHelpers
|
||||
|
||||
SetupPluginManager();
|
||||
|
||||
SetupApplicationContext();
|
||||
|
||||
FreezeResolution();
|
||||
}
|
||||
|
||||
@@ -40,7 +42,7 @@ namespace Umbraco.Tests.TestHelpers
|
||||
ApplicationContext.Current = null;
|
||||
ResetPluginManager();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// By default this returns false which means the plugin manager will not be reset so it doesn't need to re-scan
|
||||
/// all of the assemblies. Inheritors can override this if plugin manager resetting is required, generally needs
|
||||
|
||||
@@ -79,6 +79,38 @@ namespace Umbraco.Tests.TestHelpers.Entities
|
||||
return content;
|
||||
}
|
||||
|
||||
public static Content CreateAllTypesContent(IContentType contentType, string name, int parentId)
|
||||
{
|
||||
var content = new Content("Random Content Name", parentId, contentType) { Language = "en-US", Level = 1, SortOrder = 1, CreatorId = 0, WriterId = 0 };
|
||||
|
||||
content.SetValue("isTrue", true);
|
||||
content.SetValue("number", 42);
|
||||
content.SetValue("bodyText", "Lorem Ipsum Body Text Test");
|
||||
content.SetValue("singleLineText", "Single Line Text Test");
|
||||
content.SetValue("multilineText", "Multiple lines \n in one box");
|
||||
content.SetValue("upload", "/media/1234/koala.jpg");
|
||||
content.SetValue("label", "Non-editable label");
|
||||
content.SetValue("dateTime", DateTime.Now.AddDays(-20));
|
||||
content.SetValue("colorPicker", "black");
|
||||
content.SetValue("folderBrowser", "");
|
||||
content.SetValue("ddlMultiple", "1234,1235");
|
||||
content.SetValue("rbList", "random");
|
||||
content.SetValue("date", DateTime.Now.AddDays(-10));
|
||||
content.SetValue("ddl", "1234");
|
||||
content.SetValue("chklist", "randomc");
|
||||
content.SetValue("contentPicker", 1090);
|
||||
content.SetValue("mediaPicker", 1091);
|
||||
content.SetValue("memberPicker", 1092);
|
||||
content.SetValue("simpleEditor", "This is simply edited");
|
||||
content.SetValue("ultimatePicker", "1234,1235");
|
||||
content.SetValue("relatedLinks", "<links><link title=\"google\" link=\"http://google.com\" type=\"external\" newwindow=\"0\" /></links>");
|
||||
content.SetValue("tags", "this,is,tags");
|
||||
content.SetValue("macroContainer", "");
|
||||
content.SetValue("imgCropper", "");
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
public static IEnumerable<Content> CreateTextpageContent(IContentType contentType, int parentId, int amount)
|
||||
{
|
||||
var list = new List<Content>();
|
||||
|
||||
@@ -166,6 +166,51 @@ namespace Umbraco.Tests.TestHelpers.Entities
|
||||
return contentType;
|
||||
}
|
||||
|
||||
public static ContentType CreateAllTypesContentType(string alias, string name)
|
||||
{
|
||||
var contentType = new ContentType(-1)
|
||||
{
|
||||
Alias = alias,
|
||||
Name = name,
|
||||
Description = "ContentType containing all standard DataTypes",
|
||||
Icon = ".sprTreeDoc3",
|
||||
Thumbnail = "doc.png",
|
||||
SortOrder = 1,
|
||||
CreatorId = 0,
|
||||
Trashed = false
|
||||
};
|
||||
|
||||
var contentCollection = new PropertyTypeCollection();
|
||||
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.TrueFalse), DataTypeDatabaseType.Integer) { Alias = "isTrue", Name = "Is True or False", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -49 });
|
||||
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.Integer), DataTypeDatabaseType.Integer) { Alias = "number", Name = "Number", Mandatory = false, SortOrder = 2, DataTypeDefinitionId = -51 });
|
||||
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.TinyMCEv3), DataTypeDatabaseType.Ntext) { Alias = "bodyText", Name = "Body Text", Mandatory = false, SortOrder = 3, DataTypeDefinitionId = -87 });
|
||||
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.Textbox), DataTypeDatabaseType.Nvarchar) { Alias = "singleLineText", Name = "Text String", Mandatory = false, SortOrder = 4, DataTypeDefinitionId = -88 });
|
||||
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.TextboxMultiple), DataTypeDatabaseType.Ntext) { Alias = "multilineText", Name = "Multiple Text Strings", Mandatory = false, SortOrder = 5, DataTypeDefinitionId = -89 });
|
||||
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.UploadField), DataTypeDatabaseType.Nvarchar) { Alias = "upload", Name = "Upload Field", Mandatory = false, SortOrder = 6, DataTypeDefinitionId = -90 });
|
||||
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.NoEdit), DataTypeDatabaseType.Nvarchar) { Alias = "label", Name = "Label", Mandatory = false, SortOrder = 7, DataTypeDefinitionId = -92 });
|
||||
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.DateTime), DataTypeDatabaseType.Date) { Alias = "dateTime", Name = "Date Time", Mandatory = false, SortOrder = 8, DataTypeDefinitionId = -36 });
|
||||
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.ColorPicker), DataTypeDatabaseType.Nvarchar) { Alias = "colorPicker", Name = "Color Picker", Mandatory = false, SortOrder = 9, DataTypeDefinitionId = -37 });
|
||||
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.FolderBrowser), DataTypeDatabaseType.Nvarchar) { Alias = "folderBrowser", Name = "Folder Browser", Mandatory = false, SortOrder = 10, DataTypeDefinitionId = -38 });
|
||||
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.DropDownListMultiple), DataTypeDatabaseType.Nvarchar) { Alias = "ddlMultiple", Name = "Dropdown List Multiple", Mandatory = false, SortOrder = 11, DataTypeDefinitionId = -39 });
|
||||
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.RadioButtonList), DataTypeDatabaseType.Nvarchar) { Alias = "rbList", Name = "Radio Button List", Mandatory = false, SortOrder = 12, DataTypeDefinitionId = -40 });
|
||||
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.Date), DataTypeDatabaseType.Date) { Alias = "date", Name = "Date", Mandatory = false, SortOrder = 13, DataTypeDefinitionId = -41 });
|
||||
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.DropDownList), DataTypeDatabaseType.Integer) { Alias = "ddl", Name = "Dropdown List", Mandatory = false, SortOrder = 14, DataTypeDefinitionId = -42 });
|
||||
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.CheckBoxList), DataTypeDatabaseType.Nvarchar) { Alias = "chklist", Name = "Checkbox List", Mandatory = false, SortOrder = 15, DataTypeDefinitionId = -43 });
|
||||
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.ContentPicker), DataTypeDatabaseType.Integer) { Alias = "contentPicker", Name = "Content Picker", Mandatory = false, SortOrder = 16, DataTypeDefinitionId = 1034 });
|
||||
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.MediaPicker), DataTypeDatabaseType.Integer) { Alias = "mediaPicker", Name = "Media Picker", Mandatory = false, SortOrder = 17, DataTypeDefinitionId = 1035 });
|
||||
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.MemberPicker), DataTypeDatabaseType.Integer) { Alias = "memberPicker", Name = "Member Picker", Mandatory = false, SortOrder = 18, DataTypeDefinitionId = 1036 });
|
||||
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.UltraSimpleEditor), DataTypeDatabaseType.Ntext) { Alias = "simpleEditor", Name = "Ultra Simple Editor", Mandatory = false, SortOrder = 19, DataTypeDefinitionId = 1038 });
|
||||
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.UltimatePicker), DataTypeDatabaseType.Ntext) { Alias = "ultimatePicker", Name = "Ultimate Picker", Mandatory = false, SortOrder = 20, DataTypeDefinitionId = 1039 });
|
||||
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.RelatedLinks), DataTypeDatabaseType.Ntext) { Alias = "relatedLinks", Name = "Related Links", Mandatory = false, SortOrder = 21, DataTypeDefinitionId = 1040 });
|
||||
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.Tags), DataTypeDatabaseType.Ntext) { Alias = "tags", Name = "Tags", Mandatory = false, SortOrder = 22, DataTypeDefinitionId = 1041 });
|
||||
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.MacroContainer), DataTypeDatabaseType.Ntext) { Alias = "macroContainer", Name = "Macro Container", Mandatory = false, SortOrder = 23, DataTypeDefinitionId = 1042 });
|
||||
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.ImageCropper), DataTypeDatabaseType.Ntext) { Alias = "imgCropper", Name = "Image Cropper", Mandatory = false, SortOrder = 24, DataTypeDefinitionId = 1043 });
|
||||
|
||||
contentType.PropertyGroups.Add(new PropertyGroup(contentCollection) { Name = "Content", SortOrder = 1 });
|
||||
|
||||
return contentType;
|
||||
}
|
||||
|
||||
public static MediaType CreateVideoMediaType()
|
||||
{
|
||||
var mediaType = new MediaType(-1)
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace Umbraco.Tests.TestHelpers
|
||||
/// </summary>
|
||||
public static void InitializeDatabase()
|
||||
{
|
||||
ConfigurationManager.AppSettings.Set(Core.Configuration.GlobalSettings.UmbracoConnectionName, @"datalayer=SQLCE4Umbraco.SqlCEHelper,SQLCE4Umbraco;data source=|DataDirectory|\UmbracoPetaPocoTests.sdf");
|
||||
ConfigurationManager.AppSettings.Set(Core.Configuration.GlobalSettings.UmbracoConnectionName, @"datalayer=SQLCE4Umbraco.SqlCEHelper,SQLCE4Umbraco;data source=|DataDirectory|\UmbracoPetaPocoTests.sdf;Flush Interval=1;");
|
||||
|
||||
ClearDatabase();
|
||||
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
using umbraco.cms.presentation.Trees;
|
||||
|
||||
namespace Umbraco.Tests.Trees
|
||||
{
|
||||
[TestFixture]
|
||||
public class BaseContentTreeTests
|
||||
{
|
||||
|
||||
[TearDown]
|
||||
public void TestTearDown()
|
||||
{
|
||||
BaseTree.AfterTreeRender -= EventHandler;
|
||||
BaseTree.BeforeTreeRender -= EventHandler;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Run_Optimized()
|
||||
{
|
||||
var tree1 = new MyOptimizedContentTree1("content");
|
||||
var tree2 = new MyOptimizedContentTree2("content");
|
||||
|
||||
Assert.IsTrue(tree1.UseOptimizedRendering);
|
||||
Assert.IsTrue(tree2.UseOptimizedRendering);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Not_Optimized_Events_AfterRender()
|
||||
{
|
||||
var tree = new MyOptimizedContentTree1("content");
|
||||
|
||||
BaseTree.AfterTreeRender += EventHandler;
|
||||
|
||||
Assert.IsFalse(tree.UseOptimizedRendering);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Not_Optimized_Events_BeforeRender()
|
||||
{
|
||||
var tree = new MyOptimizedContentTree1("content");
|
||||
|
||||
BaseTree.BeforeTreeRender += EventHandler;
|
||||
|
||||
Assert.IsFalse(tree.UseOptimizedRendering);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Not_Optimized_Overriden_Method()
|
||||
{
|
||||
var tree = new MyNotOptimizedContentTree("content");
|
||||
|
||||
Assert.IsFalse(tree.UseOptimizedRendering);
|
||||
}
|
||||
|
||||
private void EventHandler(object sender, TreeEventArgs treeEventArgs)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//optimized because we are not overriding OnRenderNode
|
||||
public class MyOptimizedContentTree1 : BaseContentTree
|
||||
{
|
||||
public MyOptimizedContentTree1(string application)
|
||||
: base(application)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void CreateRootNode(ref XmlTreeNode rootNode)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class MyOptimizedContentTree2 : BaseContentTree
|
||||
{
|
||||
public MyOptimizedContentTree2(string application)
|
||||
: base(application)
|
||||
{
|
||||
}
|
||||
|
||||
protected override bool LoadMinimalDocument
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
protected override void CreateRootNode(ref XmlTreeNode rootNode)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//even if we override it will still be optimized because of the LoadMinimalDocument flag
|
||||
protected override void OnRenderNode(ref XmlTreeNode xNode, umbraco.cms.businesslogic.web.Document doc)
|
||||
{
|
||||
base.OnRenderNode(ref xNode, doc);
|
||||
}
|
||||
}
|
||||
|
||||
public class MyNotOptimizedContentTree : BaseContentTree
|
||||
{
|
||||
public MyNotOptimizedContentTree(string application)
|
||||
: base(application)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void CreateRootNode(ref XmlTreeNode rootNode)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override bool LoadMinimalDocument
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
protected override void OnRenderNode(ref XmlTreeNode xNode, umbraco.cms.businesslogic.web.Document doc)
|
||||
{
|
||||
base.OnRenderNode(ref xNode, doc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using NUnit.Framework;
|
||||
using umbraco.cms.presentation.Trees;
|
||||
|
||||
namespace Umbraco.Tests.Trees
|
||||
{
|
||||
[TestFixture]
|
||||
public class BaseMediaTreeTests
|
||||
{
|
||||
|
||||
[TearDown]
|
||||
public void TestTearDown()
|
||||
{
|
||||
BaseTree.AfterTreeRender -= EventHandler;
|
||||
BaseTree.BeforeTreeRender -= EventHandler;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Run_Optimized()
|
||||
{
|
||||
var tree = new MyOptimizedMediaTree("media");
|
||||
|
||||
Assert.IsTrue(tree.UseOptimizedRendering);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Not_Optimized_Events_AfterRender()
|
||||
{
|
||||
var tree = new MyOptimizedMediaTree("media");
|
||||
|
||||
BaseTree.AfterTreeRender += EventHandler;
|
||||
|
||||
Assert.IsFalse(tree.UseOptimizedRendering);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Not_Optimized_Events_BeforeRender()
|
||||
{
|
||||
var tree = new MyOptimizedMediaTree("media");
|
||||
|
||||
BaseTree.BeforeTreeRender += EventHandler;
|
||||
|
||||
Assert.IsFalse(tree.UseOptimizedRendering);
|
||||
}
|
||||
|
||||
private void EventHandler(object sender, TreeEventArgs treeEventArgs)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class MyOptimizedMediaTree : BaseMediaTree
|
||||
{
|
||||
public MyOptimizedMediaTree(string application)
|
||||
: base(application)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void CreateRootNode(ref XmlTreeNode rootNode)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -48,9 +48,9 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Examine, Version=0.1.51.2941, Culture=neutral, processorArchitecture=MSIL">
|
||||
<Reference Include="Examine, Version=0.1.52.2941, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Examine.0.1.51.2941\lib\Examine.dll</HintPath>
|
||||
<HintPath>..\packages\Examine.0.1.52.2941\lib\Examine.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
@@ -185,9 +185,13 @@
|
||||
<Compile Include="Configurations\FileSystemProviderTests.cs" />
|
||||
<Compile Include="CoreXml\FrameworkXmlTests.cs" />
|
||||
<Compile Include="Integration\CreateContent.cs" />
|
||||
<Compile Include="Models\ContentExtensionsTests.cs" />
|
||||
<Compile Include="Models\DataValueSetterTests.cs" />
|
||||
<Compile Include="Persistence\PetaPocoExtensionsTest.cs" />
|
||||
<Compile Include="Persistence\Repositories\UserRepositoryTest.cs" />
|
||||
<Compile Include="Persistence\Repositories\UserTypeRepositoryTest.cs" />
|
||||
<Compile Include="Services\PackagingServiceTests.cs" />
|
||||
<Compile Include="Services\PerformanceTests.cs" />
|
||||
<Compile Include="Services\UserServiceTests.cs" />
|
||||
<Compile Include="TestHelpers\BaseSeleniumTest.cs" />
|
||||
<Compile Include="Integration\InstallPackage.cs" />
|
||||
@@ -346,6 +350,8 @@
|
||||
<Compile Include="TestHelpers\Entities\MockedContentTypes.cs" />
|
||||
<Compile Include="TestHelpers\Entities\MockedEntity.cs" />
|
||||
<Compile Include="TestHelpers\Entities\MockedMedia.cs" />
|
||||
<Compile Include="Trees\BaseContentTreeTests.cs" />
|
||||
<Compile Include="Trees\BaseMediaTreeTests.cs" />
|
||||
<Compile Include="UmbracoExamine\ContentServiceTest.cs" />
|
||||
<Compile Include="UmbracoExamine\EventsTest.cs" />
|
||||
<Compile Include="TypeHelperTests.cs" />
|
||||
|
||||
@@ -10,6 +10,38 @@ namespace Umbraco.Tests
|
||||
[TestFixture]
|
||||
public class UriExtensionsTests
|
||||
{
|
||||
[TestCase("http://www.domain.com/umbraco", true)]
|
||||
[TestCase("http://www.domain.com/Umbraco/", true)]
|
||||
[TestCase("http://www.domain.com/umbraco/default.aspx", true)]
|
||||
[TestCase("http://www.domain.com/umbraco/test/test", true)]
|
||||
[TestCase("http://www.domain.com/Umbraco/test/test.aspx", true)]
|
||||
[TestCase("http://www.domain.com/umbraco/test/test.js", true)]
|
||||
[TestCase("http://www.domain.com/umbrac", false)]
|
||||
[TestCase("http://www.domain.com/test", false)]
|
||||
[TestCase("http://www.domain.com/test/umbraco", false)]
|
||||
[TestCase("http://www.domain.com/test/umbraco.aspx", false)]
|
||||
public void Is_Back_Office_Request(string input, bool expected)
|
||||
{
|
||||
var source = new Uri(input);
|
||||
Assert.AreEqual(expected, source.IsBackOfficeRequest());
|
||||
}
|
||||
|
||||
[TestCase("http://www.domain.com/install", true)]
|
||||
[TestCase("http://www.domain.com/Install/", true)]
|
||||
[TestCase("http://www.domain.com/install/default.aspx", true)]
|
||||
[TestCase("http://www.domain.com/install/test/test", true)]
|
||||
[TestCase("http://www.domain.com/Install/test/test.aspx", true)]
|
||||
[TestCase("http://www.domain.com/install/test/test.js", true)]
|
||||
[TestCase("http://www.domain.com/instal", false)]
|
||||
[TestCase("http://www.domain.com/umbraco", false)]
|
||||
[TestCase("http://www.domain.com/umbraco/umbraco", false)]
|
||||
[TestCase("http://www.domain.com/test/umbraco.aspx", false)]
|
||||
public void Is_Installer_Request(string input, bool expected)
|
||||
{
|
||||
var source = new Uri(input);
|
||||
Assert.AreEqual(expected, source.IsInstallerRequest());
|
||||
}
|
||||
|
||||
[TestCase("http://www.domain.com/foo/bar", "/", "http://www.domain.com/")]
|
||||
[TestCase("http://www.domain.com/foo/bar#hop", "/", "http://www.domain.com/")]
|
||||
[TestCase("http://www.domain.com/foo/bar?q=2#hop", "/", "http://www.domain.com/?q=2")]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Examine" version="0.1.51.2941" targetFramework="net40" />
|
||||
<package id="Examine" version="0.1.52.2941" targetFramework="net40" />
|
||||
<package id="log4net-mediumtrust" version="2.0.0" targetFramework="net40" />
|
||||
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net40" />
|
||||
<package id="Microsoft.AspNet.Mvc" version="4.0.30506.0" targetFramework="net40" />
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
<appender-ref ref="ConsoleAppender" />
|
||||
</root>
|
||||
|
||||
<logger name="Umbraco.Core.Publishing.PublishingStrategy">
|
||||
<level value="WARN" />
|
||||
</logger>
|
||||
|
||||
<logger name="Umbraco.Core.PluginManager">
|
||||
<level value="WARN" />
|
||||
</logger>
|
||||
@@ -13,6 +17,10 @@
|
||||
<level value="WARN" />
|
||||
</logger>
|
||||
|
||||
<logger name="Umbraco.Core.Persistence.Migrations.Initial.DatabaseSchemaCreation">
|
||||
<level value="WARN" />
|
||||
</logger>
|
||||
|
||||
<logger name="Umbraco.Core.Persistence.Migrations.Initial.BaseDataCreation">
|
||||
<level value="WARN" />
|
||||
</logger>
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
<IISExpressUseClassicPipelineMode />
|
||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
|
||||
<RestorePackages>true</RestorePackages>
|
||||
<MvcProjectUpgradeChecked>true</MvcProjectUpgradeChecked>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<OutputPath>bin\</OutputPath>
|
||||
@@ -108,9 +109,9 @@
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\ClientDependency-Mvc.1.7.0.4\lib\ClientDependency.Core.Mvc.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Examine, Version=0.1.51.2941, Culture=neutral, processorArchitecture=MSIL">
|
||||
<Reference Include="Examine, Version=0.1.52.2941, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Examine.0.1.51.2941\lib\Examine.dll</HintPath>
|
||||
<HintPath>..\packages\Examine.0.1.52.2941\lib\Examine.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="log4net, Version=1.2.11.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
@@ -916,6 +917,7 @@
|
||||
<Content Include="Umbraco_Client\Tinymce3\Langs\no.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Langs\pl.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Langs\pt.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Langs\ru.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Langs\sv.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Langs\zh.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\license.txt" />
|
||||
@@ -936,6 +938,7 @@
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Advhr\Langs\no_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Advhr\Langs\pl_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Advhr\Langs\pt_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Advhr\Langs\ru_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Advhr\Langs\sv_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Advhr\Langs\zh_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Advhr\rule.htm" />
|
||||
@@ -958,6 +961,7 @@
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Advimage\Langs\no_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Advimage\Langs\pl_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Advimage\Langs\pt_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Advimage\Langs\ru_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Advimage\Langs\sv_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Advimage\Langs\zh_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Advlink\Css\advlink.css" />
|
||||
@@ -977,6 +981,7 @@
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Advlink\Langs\no_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Advlink\Langs\pl_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Advlink\Langs\pt_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Advlink\Langs\ru_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Advlink\Langs\sv_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Advlink\Langs\zh_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Advlink\link.htm" />
|
||||
@@ -1029,6 +1034,7 @@
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Emotions\Langs\no_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Emotions\Langs\pl_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Emotions\Langs\pt_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Emotions\Langs\ru_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Emotions\Langs\sv_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Emotions\Langs\zh_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Example\dialog.htm" />
|
||||
@@ -1058,6 +1064,7 @@
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Fullpage\Langs\no_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Fullpage\Langs\pl_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Fullpage\Langs\pt_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Fullpage\Langs\ru_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Fullpage\Langs\sv_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Fullpage\Langs\zh_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Fullscreen\editor_plugin.js" />
|
||||
@@ -1091,6 +1098,7 @@
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Layer\editor_plugin_src.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Legacyoutput\editor_plugin.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Legacyoutput\editor_plugin_src.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Media\Langs\ru_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Lists\editor_plugin.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Lists\editor_plugin_src.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Media\Css\media.css" />
|
||||
@@ -1140,6 +1148,7 @@
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Paste\Langs\no_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Paste\Langs\pl_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Paste\Langs\pt_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Paste\Langs\ru_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Paste\Langs\sv_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Paste\Langs\zh_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Paste\pastetext.htm" />
|
||||
@@ -1170,6 +1179,7 @@
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Searchreplace\Langs\no_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Searchreplace\Langs\pl_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Searchreplace\Langs\pt_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Searchreplace\Langs\ru_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Searchreplace\Langs\sv_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Searchreplace\Langs\zh_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Searchreplace\searchreplace.htm" />
|
||||
@@ -1194,6 +1204,7 @@
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Style\Langs\no_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Style\Langs\pl_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Style\Langs\pt_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Style\Langs\ru_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Style\Langs\sv_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Style\Langs\zh_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Style\props.htm" />
|
||||
@@ -1223,6 +1234,7 @@
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Table\Langs\no_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Table\Langs\pl_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Table\Langs\pt_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Table\Langs\ru_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Table\Langs\sv_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Table\Langs\zh_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Table\merge_cells.htm" />
|
||||
@@ -1246,6 +1258,7 @@
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Template\Langs\no_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Template\Langs\pl_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Template\Langs\pt_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Template\Langs\ru_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Template\Langs\sv_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Template\Langs\zh_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Template\template.htm" />
|
||||
@@ -1260,8 +1273,12 @@
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracocss\Langs\en_us_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracocss\Langs\it.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracocss\Langs\it_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracocss\Langs\ja.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracocss\Langs\ja_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracocss\Langs\ru.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracocss\Langs\ru_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracocss\Langs\sv.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracocss\Langs\sv_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracocss\Langs\zh.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracocss\Langs\zh_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoembed\dialog.htm" />
|
||||
@@ -1270,6 +1287,8 @@
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoembed\Img\ajax-loader.gif" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoembed\Img\embed.gif" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoembed\Js\dialog.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoembed\Langs\da.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoembed\Langs\da_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoembed\Langs\de.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoembed\Langs\de_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoembed\Langs\en.js" />
|
||||
@@ -1278,8 +1297,12 @@
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoembed\Langs\en_us_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoembed\Langs\it.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoembed\Langs\it_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoembed\Langs\ja.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoembed\Langs\ja_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoembed\Langs\ru.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoembed\Langs\ru_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoembed\Langs\sv.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoembed\Langs\sv_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoembed\Langs\zh.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoembed\Langs\zh_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoimg\editor_plugin_src.js" />
|
||||
@@ -1287,8 +1310,10 @@
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoimg\Langs\en_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoimg\Langs\en_us_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoimg\Langs\he_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoimg\Langs\it_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoimg\Langs\ja_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoimg\Langs\ru_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoimg\Langs\sv_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracoimg\Langs\zh_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracolink\editor_plugin_src.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracolink\Js\umbracolink.js" />
|
||||
@@ -1297,6 +1322,7 @@
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracolink\Langs\he_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracolink\Langs\ja_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracolink\Langs\ru_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracolink\Langs\sv_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracolink\Langs\zh_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracomacro\dialog.htm" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracomacro\editor_plugin_src.js" />
|
||||
@@ -1312,6 +1338,8 @@
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracomacro\Langs\ja_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracomacro\Langs\ru.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracomacro\Langs\ru_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracomacro\Langs\sv.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracomacro\Langs\sv_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracomacro\Langs\zh.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracomacro\Langs\zh_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Umbracopaste\editor_plugin_src.js" />
|
||||
@@ -1353,6 +1381,7 @@
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Xhtmlxtras\Langs\no_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Xhtmlxtras\Langs\pl_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Xhtmlxtras\Langs\pt_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Xhtmlxtras\Langs\ru_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Xhtmlxtras\Langs\sv_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Plugins\Xhtmlxtras\Langs\zh_dlg.js" />
|
||||
<Content Include="Umbraco_Client\Tinymce3\Themes\Advanced\about.htm" />
|
||||
@@ -2574,9 +2603,9 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.0\x86\*.* "$(TargetDir)x86\"
|
||||
<WebProjectProperties>
|
||||
<UseIIS>True</UseIIS>
|
||||
<AutoAssignPort>True</AutoAssignPort>
|
||||
<DevelopmentServerPort>6130</DevelopmentServerPort>
|
||||
<DevelopmentServerPort>6160</DevelopmentServerPort>
|
||||
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||
<IISUrl>http://localhost:6130</IISUrl>
|
||||
<IISUrl>http://localhost:6160</IISUrl>
|
||||
<NTLMAuthentication>False</NTLMAuthentication>
|
||||
<UseCustomServer>False</UseCustomServer>
|
||||
<CustomServerUrl>
|
||||
|
||||
@@ -21,7 +21,7 @@ More information and documentation can be found on CodePlex: http://umbracoexami
|
||||
|
||||
<!-- default external indexer, which excludes protected and published pages-->
|
||||
<add name="ExternalIndexer" type="UmbracoExamine.UmbracoContentIndexer, UmbracoExamine"/>
|
||||
|
||||
|
||||
</providers>
|
||||
</ExamineIndexProviders>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<user>0</user>
|
||||
<startNode>1080</startNode>
|
||||
<fullTree>False</fullTree>
|
||||
<documentTypeAlias>Home</documentTypeAlias>
|
||||
<documentTypeAlias>Base</documentTypeAlias>
|
||||
<fields>
|
||||
<categories>
|
||||
</categories>
|
||||
@@ -14,6 +14,6 @@
|
||||
<excerpt>
|
||||
</excerpt>
|
||||
</fields>
|
||||
<mediaObjectSupport enabled="True" folderId="-1" mediaTypeAlias="image" mediaTypeFileProperty="umbracoFile" />
|
||||
<mediaObjectSupport enabled="True" folderId="-1" mediaTypeAlias="Image" mediaTypeFileProperty="umbracoFile" />
|
||||
</channel>
|
||||
</metablogapi>
|
||||
+1
-1
@@ -101,7 +101,7 @@ namespace Umbraco.Web.UI.Install.Steps {
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::System.Web.UI.WebControls.TextBox DatabaseName;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// DatabaseIntegratedSecurity control.
|
||||
/// </summary>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<packages>
|
||||
<package id="ClientDependency" version="1.7.0.4" targetFramework="net40" />
|
||||
<package id="ClientDependency-Mvc" version="1.7.0.4" targetFramework="net40" />
|
||||
<package id="Examine" version="0.1.51.2941" targetFramework="net40" />
|
||||
<package id="Examine" version="0.1.52.2941" targetFramework="net40" />
|
||||
<package id="log4net-mediumtrust" version="2.0.0" targetFramework="net40" />
|
||||
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net40" />
|
||||
<package id="Microsoft.AspNet.Mvc" version="4.0.30506.0" targetFramework="net40" />
|
||||
|
||||
@@ -406,7 +406,7 @@
|
||||
<key alias="renewSession">Förnya nu för att spara ditt arbete</key>
|
||||
</area>
|
||||
<area alias="login">
|
||||
<key alias="bottomText"><![CDATA[<p style="text-align:right;">© 2001 - {0} <br /><a href="http://umbraco.org" style="text-decoration: none" target="_blank">umbraco.org</a></p> ]]></key>
|
||||
<key alias="bottomText"><![CDATA[<p style="text-align:right;">© 2001 - %0% <br /><a href="http://umbraco.org" style="text-decoration: none" target="_blank">umbraco.org</a></p> ]]></key>
|
||||
<key alias="topText">Välkommen till umbraco, skriv ditt användarnamn och lösenord i textfälten nedan:</key>
|
||||
</area>
|
||||
<area alias="main">
|
||||
@@ -757,4 +757,4 @@
|
||||
<key alias="userTypes">Användartyper</key>
|
||||
<key alias="writer">Skribent</key>
|
||||
</area>
|
||||
</language>
|
||||
</language>
|
||||
|
||||
@@ -1,16 +1,34 @@
|
||||
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="passwordChanger.ascx.cs" Inherits="umbraco.controls.passwordChanger" %>
|
||||
|
||||
<a href="#" onclick="if (document.getElementById('umbPasswordChanger').style.display == '' || document.getElementById('umbPasswordChanger').style.display == 'none') {document.getElementById('umbPasswordChanger').style.display = 'block'; this.style.display = 'none';}">Change password</a><br />
|
||||
<script type="text/javascript">
|
||||
(function ($) {
|
||||
Umbraco.Sys.registerNamespace("Umbraco.Controls");
|
||||
Umbraco.Controls.PasswordChanger = {
|
||||
toggle: function (e) {
|
||||
if (!$("#umbPasswordChanger").is(":visible")) {
|
||||
ValidatorEnable(document.getElementById('<%=CompareValidator1.ClientID %>'), true);
|
||||
$(e).closest(".propertyItem").replaceWith($("#umbPasswordChanger"));
|
||||
$("#umbPasswordChanger").show();
|
||||
$(e).hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
})(jQuery);
|
||||
</script>
|
||||
|
||||
<div id="umbPasswordChanger" style="display: none;">
|
||||
<table>
|
||||
<tr><th style="width: 270px;"><%=umbraco.ui.GetText("user", "newPassword")%>:</th><td style="width: 359px">
|
||||
<asp:TextBox ID="umbPasswordChanger_passwordNew" autocomplete="off" AutoCompleteType="None" TextMode="password" runat="server"></asp:TextBox>
|
||||
</td></tr>
|
||||
<tr><th><%=umbraco.ui.GetText("user", "confirmNewPassword")%>:</th><td style="width: 359px">
|
||||
<asp:TextBox ID="umbPasswordChanger_passwordNewConfirm" autocomplete="off" AutoCompleteType="None" TextMode="password" runat="server"></asp:TextBox>
|
||||
<asp:CompareValidator ID="CompareValidator1" runat="server" ErrorMessage="Passwords must match" ControlToValidate="umbPasswordChanger_passwordNew"
|
||||
ControlToCompare="umbPasswordChanger_passwordNewConfirm" Operator="Equal"></asp:CompareValidator>
|
||||
</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<a href="#" onclick="Umbraco.Controls.PasswordChanger.toggle(this);">Change password</a><br />
|
||||
|
||||
<div class="propertyItem" id="umbPasswordChanger" style="display: none;">
|
||||
|
||||
<div class="propertyItemheader"><%=umbraco.ui.GetText("user", "newPassword")%></div>
|
||||
<div class="propertyItemContent">
|
||||
<asp:TextBox ID="umbPasswordChanger_passwordNew" autocomplete="off" AutoCompleteType="None" TextMode="password" runat="server"></asp:TextBox>
|
||||
</div>
|
||||
|
||||
<div class="propertyItemheader"><%=umbraco.ui.GetText("user", "confirmNewPassword")%></div>
|
||||
<div class="propertyItemContent">
|
||||
<asp:TextBox ID="umbPasswordChanger_passwordNewConfirm" autocomplete="off" AutoCompleteType="None" TextMode="password" runat="server"></asp:TextBox>
|
||||
<asp:CompareValidator ID="CompareValidator1" runat="server" Enabled="False" ErrorMessage="Passwords must match" ControlToValidate="umbPasswordChanger_passwordNew"
|
||||
ControlToCompare="umbPasswordChanger_passwordNewConfirm" Operator="Equal"></asp:CompareValidator>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<%@ Page Language="c#" CodeBehind="EditNodeTypeNew.aspx.cs" AutoEventWireup="True"
|
||||
<%@ Page Language="c#" CodeBehind="EditNodeTypeNew.aspx.cs" AutoEventWireup="True" ValidateRequest="false"
|
||||
Async="true" AsyncTimeOut="300" Trace="false" Inherits="Umbraco.Web.UI.Umbraco.Settings.EditNodeTypeNew" MasterPageFile="../masterpages/umbracoPage.Master" %>
|
||||
|
||||
<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<%@ Page MasterPageFile="../masterpages/umbracoPage.Master" Language="c#" CodeBehind="EditTemplate.aspx.cs"
|
||||
ValidateRequest="false" AutoEventWireup="True" Inherits="Umbraco.Web.UI.Umbraco.Settings.EditTemplate" %>
|
||||
<%@ Import Namespace="Umbraco.Core" %>
|
||||
<%@ Import Namespace="Umbraco.Core.IO" %>
|
||||
<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %>
|
||||
<%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %>
|
||||
@@ -19,6 +20,7 @@
|
||||
jQuery(document).ready(function() {
|
||||
//create the editor
|
||||
editor = new Umbraco.Editors.EditTemplate({
|
||||
restServiceLocation: "<%= Url.GetSaveFileServicePath() %>",
|
||||
umbracoPath: '<%= IOHelper.ResolveUrl(SystemDirectories.Umbraco) %>',
|
||||
editorClientId: '<%= editorSource.ClientID %>',
|
||||
useMasterPages: <%=umbraco.UmbracoSettings.UseAspNetMasterPages.ToString().ToLower()%>,
|
||||
|
||||
@@ -114,11 +114,18 @@ namespace Umbraco.Web.UI.Umbraco.Settings.Views
|
||||
NameTxt.Text = OriginalFileName;
|
||||
var file = IOHelper.MapPath(SystemDirectories.MvcViews.EnsureEndsWith('/') + OriginalFileName);
|
||||
|
||||
// validate file path
|
||||
if (file.StartsWith(IOHelper.MapPath(SystemDirectories.MvcViews.EnsureEndsWith('/')))) {
|
||||
|
||||
using (var sr = File.OpenText(file))
|
||||
{
|
||||
var s = sr.ReadToEnd();
|
||||
editorSource.Text = s;
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
throw new ArgumentException("Couldn't open file - illegal path");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,9 +62,19 @@ $.datepicker._connectDatepicker = function(target, inst) {
|
||||
*/
|
||||
$.datepicker._showDatepickerOverride = $.datepicker._showDatepicker;
|
||||
$.datepicker._showDatepicker = function (input) {
|
||||
// keep the current value
|
||||
var originalval = input.value;
|
||||
|
||||
// Keep the first 10 chars for now yyyy-mm-dd - this removes the time part which was breaking the standardDatePicker parsing code
|
||||
input.value = originalval.length>10 ? originalval.substring(0, 10) : originalval;
|
||||
|
||||
|
||||
// Call the original method which will show the datepicker
|
||||
$.datepicker._showDatepickerOverride(input);
|
||||
|
||||
// Put it back
|
||||
input.value = originalval;
|
||||
|
||||
input = input.target || input;
|
||||
|
||||
// find from button/image trigger
|
||||
|
||||
@@ -101,27 +101,57 @@
|
||||
save: function(templateName, templateAlias, codeVal) {
|
||||
var self = this;
|
||||
|
||||
umbraco.presentation.webservices.codeEditorSave.SaveTemplate(
|
||||
templateName, templateAlias, codeVal, self._opts.templateId, this._opts.masterPageDropDown.val(),
|
||||
function(t) { self.submitSucces(t); },
|
||||
function(t) { self.submitFailure(t); });
|
||||
|
||||
$.post(self._opts.restServiceLocation + "SaveTemplate",
|
||||
JSON.stringify({
|
||||
templateName: templateName,
|
||||
templateAlias: templateAlias,
|
||||
templateContents: codeVal,
|
||||
templateId: self._opts.templateId,
|
||||
masterTemplateId: this._opts.masterPageDropDown.val()
|
||||
}),
|
||||
function (e) {
|
||||
if (e.success) {
|
||||
self.submitSuccess(e);
|
||||
} else {
|
||||
self.submitFailure(e.message, e.header);
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
submitSucces: function(t) {
|
||||
if (t != 'true') {
|
||||
top.UmbSpeechBubble.ShowMessage('error', this._opts.text.templateErrorHeader, this._opts.text.templateErrorText);
|
||||
submitSuccess: function (args) {
|
||||
var msg = args.message;
|
||||
var header = args.header;
|
||||
var path = this._opts.treeSyncPath;
|
||||
var pathChanged = false;
|
||||
if (args.path) {
|
||||
if (path != args.path) {
|
||||
pathChanged = true;
|
||||
}
|
||||
path = args.path;
|
||||
}
|
||||
|
||||
top.UmbSpeechBubble.ShowMessage('save', header, msg);
|
||||
UmbClientMgr.mainTree().setActiveTreeType('templates');
|
||||
if (pathChanged) {
|
||||
UmbClientMgr.mainTree().moveNode(this._opts.templateId, path);
|
||||
}
|
||||
else {
|
||||
top.UmbSpeechBubble.ShowMessage('save', this._opts.text.templateSavedHeader, this._opts.text.templateSavedText);
|
||||
UmbClientMgr.mainTree().syncTree(path, true);
|
||||
}
|
||||
|
||||
UmbClientMgr.mainTree().setActiveTreeType('templates');
|
||||
UmbClientMgr.mainTree().syncTree(this._opts.treeSyncPath, true);
|
||||
},
|
||||
|
||||
submitFailure: function(t) {
|
||||
top.UmbSpeechBubble.ShowMessage('error', this._opts.text.templateErrorHeader, this._opts.text.templateErrorText);
|
||||
submitFailure: function (err, header) {
|
||||
top.UmbSpeechBubble.ShowMessage('error', header, err);
|
||||
}
|
||||
});
|
||||
|
||||
//Set defaults for jQuery ajax calls.
|
||||
$.ajaxSetup({
|
||||
dataType: 'json',
|
||||
cache: false,
|
||||
contentType: 'application/json; charset=utf-8'
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
@@ -80,7 +80,7 @@
|
||||
}),
|
||||
function(e) {
|
||||
if (e.success) {
|
||||
self.submitSuccess(e.message, e.header);
|
||||
self.submitSuccess(e);
|
||||
} else {
|
||||
self.submitFailure(e.message, e.header);
|
||||
}
|
||||
@@ -97,7 +97,7 @@
|
||||
}),
|
||||
function(e) {
|
||||
if (e.success) {
|
||||
self.submitSuccess(e.message, e.header);
|
||||
self.submitSuccess(e);
|
||||
} else {
|
||||
self.submitFailure(e.message, e.header);
|
||||
}
|
||||
@@ -105,8 +105,20 @@
|
||||
}
|
||||
},
|
||||
|
||||
submitSuccess: function (err, header) {
|
||||
top.UmbSpeechBubble.ShowMessage('save', header, err);
|
||||
submitSuccess: function (args) {
|
||||
|
||||
var msg = args.message;
|
||||
var header = args.header;
|
||||
var path = this._opts.treeSyncPath;
|
||||
var pathChanged = false;
|
||||
if (args.path) {
|
||||
if (path != args.path) {
|
||||
pathChanged = true;
|
||||
}
|
||||
path = args.path;
|
||||
}
|
||||
|
||||
top.UmbSpeechBubble.ShowMessage('save', header, msg);
|
||||
|
||||
UmbClientMgr.mainTree().setActiveTreeType(this._opts.currentTreeType);
|
||||
|
||||
@@ -114,11 +126,19 @@
|
||||
|
||||
if (this._opts.editorType == "Template") {
|
||||
//templates are different because they are ID based, whereas view files are file based without a static id
|
||||
UmbClientMgr.mainTree().syncTree(this._opts.treeSyncPath, true);
|
||||
|
||||
if (pathChanged) {
|
||||
UmbClientMgr.mainTree().moveNode(this._opts.templateId, path);
|
||||
}
|
||||
else {
|
||||
UmbClientMgr.mainTree().syncTree(path, true);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
//we need to pass in the newId parameter so it knows which node to resync after retreival from the server
|
||||
UmbClientMgr.mainTree().syncTree(this._opts.treeSyncPath, true, null, newFilePath.split("/")[1]);
|
||||
UmbClientMgr.mainTree().syncTree(path, true, null, newFilePath.split("/")[1]);
|
||||
}
|
||||
|
||||
//then we need to update our current tree sync path to represent the new one
|
||||
|
||||
@@ -64,7 +64,16 @@
|
||||
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
|
||||
</dependentAssembly>
|
||||
|
||||
|
||||
<dependentAssembly xdt:Transform="Remove"
|
||||
xdt:Locator="Condition(_defaultNamespace:assemblyIdentity[@name='HtmlAgilityPack']])"/>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="HtmlAgilityPack" publicKeyToken="bd319b19eaf3b43a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="1.4.5.0-1.4.6.0" newVersion="1.4.6.0" />
|
||||
</dependentAssembly>
|
||||
|
||||
</assemblyBinding>
|
||||
|
||||
</runtime>
|
||||
|
||||
</configuration>
|
||||
@@ -269,6 +269,12 @@
|
||||
<assemblyIdentity name="System.Web.WebPages.Razor" publicKeyToken="31bf3856ad364e35"/>
|
||||
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0"/>
|
||||
</dependentAssembly>
|
||||
|
||||
<!-- Ensure correct version of HtmlAgilityPack -->
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="HtmlAgilityPack" publicKeyToken="bd319b19eaf3b43a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="1.4.5.0-1.4.6.0" newVersion="1.4.6.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
||||
|
||||
@@ -466,7 +466,7 @@ namespace Umbraco.Web
|
||||
Mandate.ParameterNotNullOrEmpty(action, "action");
|
||||
Mandate.ParameterNotNullOrEmpty(controllerName, "controllerName");
|
||||
|
||||
var formAction = UmbracoContext.Current.OriginalRequestUrl.ToString();
|
||||
var formAction = UmbracoContext.Current.OriginalRequestUrl.PathAndQuery;
|
||||
return html.RenderForm(formAction, FormMethod.Post, htmlAttributes, controllerName, action, area, additionalRouteVals);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,9 +13,23 @@ namespace Umbraco.Web.Install
|
||||
/// </summary>
|
||||
internal class UmbracoInstallAuthorizeAttribute : AuthorizeAttribute
|
||||
{
|
||||
private readonly ApplicationContext _applicationContext;
|
||||
private readonly ApplicationContext _applicationContext;
|
||||
private readonly UmbracoContext _umbracoContext;
|
||||
|
||||
private ApplicationContext GetApplicationContext()
|
||||
{
|
||||
return _applicationContext ?? ApplicationContext.Current;
|
||||
}
|
||||
|
||||
private UmbracoContext GetUmbracoContext()
|
||||
{
|
||||
return _umbracoContext ?? UmbracoContext.Current;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// THIS SHOULD BE ONLY USED FOR UNIT TESTS
|
||||
/// </summary>
|
||||
/// <param name="umbracoContext"></param>
|
||||
public UmbracoInstallAuthorizeAttribute(UmbracoContext umbracoContext)
|
||||
{
|
||||
if (umbracoContext == null) throw new ArgumentNullException("umbracoContext");
|
||||
@@ -23,11 +37,9 @@ namespace Umbraco.Web.Install
|
||||
_applicationContext = _umbracoContext.Application;
|
||||
}
|
||||
|
||||
public UmbracoInstallAuthorizeAttribute()
|
||||
: this(UmbracoContext.Current)
|
||||
{
|
||||
|
||||
}
|
||||
public UmbracoInstallAuthorizeAttribute()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that the user must be logged in or that the application is not configured just yet.
|
||||
@@ -41,13 +53,13 @@ namespace Umbraco.Web.Install
|
||||
try
|
||||
{
|
||||
//if its not configured then we can continue
|
||||
if (!_applicationContext.IsConfigured)
|
||||
if (!GetApplicationContext().IsConfigured)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var umbCtx = GetUmbracoContext();
|
||||
//otherwise we need to ensure that a user is logged in
|
||||
var isLoggedIn = _umbracoContext.Security.ValidateUserContextId(_umbracoContext.Security.UmbracoUserContextId);
|
||||
var isLoggedIn = umbCtx.Security.ValidateUserContextId(umbCtx.Security.UmbracoUserContextId);
|
||||
if (isLoggedIn)
|
||||
{
|
||||
return true;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user