Compare commits
74 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a91669abc0 | |||
| 3b9db8a92f | |||
| 1bfc1229bd | |||
| 3d6fd2d785 | |||
| e56881abc6 | |||
| d32991c30a | |||
| 8758f9649b | |||
| 6f0f1ab2c3 | |||
| cd28240172 | |||
| 7002291c41 | |||
| 51bbf7ceb5 | |||
| 82297a6ff1 | |||
| cc5ac1a84c | |||
| 6373add383 | |||
| 180099b718 | |||
| 65f15125e1 | |||
| 856c345905 | |||
| b2cd5dfb85 | |||
| 462f7a59b5 | |||
| 22689d24ec | |||
| 4055afdf05 | |||
| a1c70a219a | |||
| 3151515855 | |||
| 25df9da715 | |||
| 9c2f438476 | |||
| 0de3be42cf | |||
| 1545e0eed7 | |||
| 42a7ed6877 | |||
| 98b8aedc4d | |||
| c7a2b54d1c | |||
| 6583ff4439 | |||
| 7b08b3e936 | |||
| bd2fc71dc5 | |||
| 0af97f63e2 | |||
| 1db635f24c | |||
| 6e27b3d6d4 | |||
| 1dea0edcf1 | |||
| 1abab41955 | |||
| d1be38be64 | |||
| 8916c68a0c | |||
| 6faa7e2fc9 | |||
| a6093f41bd | |||
| 107e66e4da | |||
| 256849f8a6 | |||
| c9c451be65 | |||
| 1fcea083e7 | |||
| 85d6ee5713 | |||
| ec81583741 | |||
| 332da9bf2d | |||
| a0036d925e | |||
| 81a99d6f7d | |||
| e912238574 | |||
| 9a830e5de6 | |||
| 7d9ba0e36e | |||
| 6c5e09fd84 | |||
| 2f8c43c689 | |||
| 7a25cb52b2 | |||
| 19bc97a7fd | |||
| 72900ef3b3 | |||
| 74ddd09c5d | |||
| e461cb92da | |||
| e91b53e66d | |||
| b5e8cb29dd | |||
| 20dc4f5bc4 | |||
| 2c399860ca | |||
| 4dc4c36581 | |||
| fe774f557c | |||
| 3ecb9d0f86 | |||
| f78a425985 | |||
| 9f365727e0 | |||
| 74d73cfe94 | |||
| 7fb9d430a9 | |||
| 7cd8ba13c0 | |||
| 1888888650 |
+2
-2
@@ -175,8 +175,8 @@
|
||||
<!-- Copy SQL CE -->
|
||||
<ItemGroup>
|
||||
<SQLCE4Files
|
||||
Include="..\src\packages\SqlServerCE.4.0.0.0\**\*.*"
|
||||
Exclude="..\src\packages\SqlServerCE.4.0.0.0\lib\**\*;..\src\packages\SqlServerCE.4.0.0.0\**\*.nu*"
|
||||
Include="..\src\packages\SqlServerCE.4.0.0.1\**\*.*"
|
||||
Exclude="..\src\packages\SqlServerCE.4.0.0.1\lib\**\*;..\src\packages\SqlServerCE.4.0.0.1\**\*.nu*"
|
||||
/>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -34,11 +34,11 @@
|
||||
<dependency id="Newtonsoft.Json" version="[6.0.8, 7.0.0)" />
|
||||
<dependency id="Examine" version="[0.1.68, 1.0.0)" />
|
||||
<dependency id="ImageProcessor" version="[2.3.2, 3.0.0)" />
|
||||
<dependency id="ImageProcessor.Web" version="[4.5.0, 5.0.0)" />
|
||||
<dependency id="ImageProcessor.Web" version="[4.5.1, 5.0.0)" />
|
||||
<dependency id="semver" version="[1.1.2, 2.0.0)" />
|
||||
<dependency id="Microsoft.AspNet.WebHelpers" version="[3.2.3, 4.0.0)" />
|
||||
<dependency id="Microsoft.AspNet.WebPages.Data" version="[3.2.3, 4.0.0)" />
|
||||
<dependency id="Umbraco.ModelsBuilder.AspNet" version="[2.2.0-beta003, 3.0.0)" />
|
||||
<dependency id="UrlRewritingNet" version="[2.0.7, 3.0.0)" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
@@ -73,7 +73,6 @@
|
||||
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Web.UI.xml" target="lib\Umbraco.Web.UI.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.dll" target="lib\UmbracoExamine.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.xml" target="lib\UmbracoExamine.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\UrlRewritingNet.UrlRewriter.dll" target="lib\UrlRewritingNet.UrlRewriter.dll" />
|
||||
<file src="tools\install.core.ps1" target="tools\install.ps1" />
|
||||
|
||||
<!-- Added to be able to produce a symbols package -->
|
||||
|
||||
@@ -17,11 +17,6 @@
|
||||
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
|
||||
xdt:Locator="Match(factoryType)"
|
||||
xdt:Transform="SetAttributes(factoryType)" />
|
||||
<pages pageBaseType="System.Web.Mvc.WebViewPage">
|
||||
<namespaces>
|
||||
<add namespace="Umbraco.Web.PublishedContentModels" xdt:Transform="InsertIfMissing" />
|
||||
</namespaces>
|
||||
</pages>
|
||||
</system.web.webPages.razor>
|
||||
|
||||
<system.web>
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
</providers>
|
||||
</siteMap>
|
||||
<httpRuntime xdt:Transform="InsertIfMissing" />
|
||||
<httpRuntime targetFramework="4.5" maxRequestLength="1048576" fcnMode="Single" xdt:Transform="SetAttributes(targetFramework,fcnMode,maxRequestLength)" />
|
||||
<httpRuntime targetFramework="4.5" maxRequestLength="51200" fcnMode="Single" xdt:Transform="SetAttributes(targetFramework,fcnMode,maxRequestLength)" />
|
||||
<membership defaultProvider="DefaultMembershipProvider" xdt:Locator="Match(defaultProvider)" xdt:Transform="Remove" />
|
||||
<roleManager defaultProvider="DefaultRoleProvider" xdt:Locator="Match(defaultProvider)" xdt:Transform="Remove"/>
|
||||
<profile defaultProvider="DefaultProfileProvider" xdt:Locator="Match(defaultProvider)" xdt:Transform="Remove"/>>
|
||||
@@ -66,7 +66,6 @@
|
||||
<add assembly="System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)"
|
||||
xdt:Transform="InsertIfMissing" />
|
||||
<add assembly="System.Web.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
|
||||
<add assembly="System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
|
||||
<add assembly="System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
|
||||
<add assembly="System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
|
||||
<add assembly="System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
|
||||
@@ -85,12 +84,10 @@
|
||||
<assemblies>
|
||||
<remove assembly="System.Web.Http" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
|
||||
<remove assembly="System.Net.Http" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
|
||||
<remove assembly="System.Runtime" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
|
||||
</assemblies>
|
||||
<assemblies>
|
||||
<remove assembly="System.Web.Http" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
|
||||
<remove assembly="System.Net.Http" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
|
||||
<remove assembly="System.Runtime" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
|
||||
</assemblies>
|
||||
</compilation>
|
||||
|
||||
@@ -146,7 +143,7 @@
|
||||
|
||||
<security xdt:Transform="InsertIfMissing">
|
||||
<requestFiltering xdt:Transform="InsertIfMissing">
|
||||
<requestLimits maxAllowedContentLength="1073741824" xdt:Transform="InsertIfMissing" />
|
||||
<requestLimits maxAllowedContentLength="52428800" xdt:Transform="InsertIfMissing" />
|
||||
</requestFiltering>
|
||||
</security>
|
||||
|
||||
|
||||
@@ -1,127 +1,36 @@
|
||||
<?xml version="1.0"?>
|
||||
<trees xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
|
||||
<!--Content-->
|
||||
<add alias="content" application="content"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="RemoveAttributes(silent)" />
|
||||
<add initialize="false" sortOrder="0" alias="contentRecycleBin" application="content" title="Recycle Bin" iconClosed="icon-folder" iconOpen="icon-folder" type="umbraco.cms.presentation.Trees.ContentRecycleBin, umbraco"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
<add initialize="true" sortOrder="0" alias="content" application="content" title="Content" iconClosed="icon-folder" iconOpen="icon-folder" type="Umbraco.Web.Trees.ContentTreeController, umbraco"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
|
||||
<!--Media-->
|
||||
<add initialize="true" sortOrder="0" alias="media" application="media" title="Media" iconClosed="icon-folder" iconOpen="icon-folder" type="Umbraco.Web.Trees.MediaTreeController, umbraco"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
<add initialize="false" sortOrder="0" alias="mediaRecycleBin" application="media" title="Recycle Bin" iconClosed="icon-folder" iconOpen="icon-folder" type="umbraco.cms.presentation.Trees.MediaRecycleBin, umbraco"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
|
||||
<!--Settings-->
|
||||
<add application="settings" alias="nodeTypes"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="Remove" />
|
||||
<add initialize="true" sortOrder="0" alias="documentTypes" application="settings" title="Document Types" iconClosed="icon-folder" iconOpen="icon-folder-open" type="Umbraco.Web.Trees.ContentTypeTreeController, umbraco"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="InsertIfMissing" />
|
||||
<add application="settings" alias="stylesheets" title="Stylesheets" type="umbraco.loadStylesheets, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="3"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
<add application="settings" alias="stylesheetProperty" title="Stylesheet Property" type="umbraco.loadStylesheetProperty, umbraco" iconClosed="" iconOpen="" initialize="false" sortOrder="0"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
<add application="settings" alias="templates" title="Templates" type="Umbraco.Web.Trees.TemplatesTreeController, umbraco" iconClosed="icon-folder" iconOpen="icon-folder-open" sortOrder="1"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
<add application="settings" alias="partialViews" title="Partial Views" silent="false" initialize="true" iconClosed="icon-folder" iconOpen="icon-folder" type="Umbraco.Web.Trees.PartialViewsTree, umbraco" sortOrder="2"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
<add application="settings" alias="scripts" title="Scripts" type="umbraco.loadScripts, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="4"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
<add application="settings" alias="dictionary" title="Dictionary" type="umbraco.loadDictionary, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="6"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
<add alias="dictionary" application="settings"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="RemoveAttributes(action)" />
|
||||
<add application="settings" alias="languages" title="Languages" type="Umbraco.Web.Trees.LanguageTreeController, umbraco" iconClosed="icon-folder" iconOpen="icon-folder-open" sortOrder="5"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
<add application="settings" initialize="true" alias="mediaTypes" title="Media Types" type="Umbraco.Web.Trees.MediaTypeTreeController, umbraco" iconClosed="icon-folder" iconOpen="icon-folder-open" sortOrder="7"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
|
||||
<!--Developer-->
|
||||
<add alias="datatype" application="developer"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="Remove" />
|
||||
<add initialize="true" sortOrder="0" alias="datatypes" application="developer" title="Data Types" iconClosed="icon-folder" iconOpen="icon-folder" type="Umbraco.Web.Trees.DataTypeTreeController, umbraco"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="InsertIfMissing" />
|
||||
<add application="developer" alias="macros" title="Macros" type="umbraco.loadMacros, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="2"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
<add application="developer" alias="packager" title="Packages" type="umbraco.loadPackager, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="3"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
<add application="developer" alias="packagerPackages" title="Packager Packages" type="umbraco.loadPackages, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" initialize="false" sortOrder="3"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
<add application="developer" alias="relationTypes" title="Relation Types" type="umbraco.loadRelationTypes, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="4"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
<add application="developer" alias="xslt" title="XSLT Files" type="umbraco.loadXslt, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="5"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
<add application="developer" alias="partialViewMacros" type="Umbraco.Web.Trees.PartialViewMacrosTree, umbraco" silent="false" initialize="true" sortOrder="6" title="Partial View Macro Files" iconClosed="icon-folder" iconOpen="icon-folder"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
<add application="developer" alias="python"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="Remove" />
|
||||
|
||||
<!--Users-->
|
||||
<add application="users" alias="users" title="Users" type="umbraco.loadUsers, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="0"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
<add application="users" alias="userTypes" title="User Types" type="umbraco.cms.presentation.Trees.UserTypes, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="1"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
<add application="users" alias="userPermissions" title="User Permissions" type="umbraco.cms.presentation.Trees.UserPermissions, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="2"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
|
||||
<!--Members-->
|
||||
<add initialize="true" sortOrder="0" alias="member" application="member" title="Members" iconClosed="icon-folder" iconOpen="icon-folder-open" type="Umbraco.Web.Trees.MemberTreeController, umbraco"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
<add application="member" alias="memberGroup"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="Remove" />
|
||||
<add application="member" sortOrder="2" alias="memberGroups" title="Member Groups" type="umbraco.loadMemberGroups, umbraco" iconClosed="icon-folder" iconOpen="icon-folder"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="InsertIfMissing" />
|
||||
<add application="member" alias="memberType"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="Remove" />
|
||||
<add application="member" sortOrder="1" alias="memberTypes" initialize="true" title="Member Types" type="Umbraco.Web.Trees.MemberTypeTreeController, umbraco" iconClosed="icon-folder" iconOpen="icon-folder-open"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="InsertIfMissing" />
|
||||
|
||||
<!--Translation-->
|
||||
<add silent="false" initialize="true" sortOrder="1" alias="openTasks" application="translation" title="Tasks assigned to you" iconClosed="icon-folder" iconOpen="icon-folder" type="umbraco.loadOpenTasks, umbraco"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
<add alias="openTasks" application="translation"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="RemoveAttributes(action)" />
|
||||
<add silent="false" initialize="true" sortOrder="2" alias="yourTasks" application="translation" title="Tasks created by you" iconClosed="icon-folder" iconOpen="icon-folder" type="umbraco.loadYourTasks, umbraco"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
<add alias="yourTasks" application="translation"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="RemoveAttributes(action)" />
|
||||
<add initialize="true" sortOrder="0" alias="content" application="content" title="Content" iconClosed="icon-folder" iconOpen="icon-folder" type="Umbraco.Web.Trees.ContentTreeController, umbraco" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add alias="content" xdt:Locator="Match(alias)" xdt:Transform="RemoveAttributes(silent)" />
|
||||
<add initialize="false" sortOrder="0" alias="contentRecycleBin" application="content" title="Recycle Bin" iconClosed="icon-folder" iconOpen="icon-folder" type="umbraco.cms.presentation.Trees.ContentRecycleBin, umbraco" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add initialize="true" sortOrder="0" alias="media" application="media" title="Media" iconClosed="icon-folder" iconOpen="icon-folder" type="Umbraco.Web.Trees.MediaTreeController, umbraco" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add initialize="false" sortOrder="0" alias="mediaRecycleBin" application="media" title="Recycle Bin" iconClosed="icon-folder" iconOpen="icon-folder" type="umbraco.cms.presentation.Trees.MediaRecycleBin, umbraco" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add application="settings" alias="stylesheets" title="Stylesheets" type="umbraco.loadStylesheets, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="0" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add application="settings" alias="stylesheetProperty" title="Stylesheet Property" type="umbraco.loadStylesheetProperty, umbraco" iconClosed="" iconOpen="" initialize="false" sortOrder="0" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add application="settings" alias="templates" title="Templates" type="Umbraco.Web.Trees.TemplatesTreeController, umbraco" iconClosed="icon-folder" iconOpen="icon-folder-open" sortOrder="1" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add application="settings" alias="partialViews" title="Partial Views" silent="false" initialize="true" iconClosed="icon-folder" iconOpen="icon-folder" type="Umbraco.Web.Trees.PartialViewsTree, umbraco" sortOrder="2" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add application="settings" alias="scripts" title="Scripts" type="umbraco.loadScripts, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="3" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add application="settings" alias="dictionary" title="Dictionary" type="umbraco.loadDictionary, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="4" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add alias="dictionary" xdt:Locator="Match(alias)" xdt:Transform="RemoveAttributes(action)" />
|
||||
<add application="settings" alias="languages" title="Languages" type="Umbraco.Web.Trees.LanguageTreeController, umbraco" iconClosed="icon-folder" iconOpen="icon-folder-open" sortOrder="5" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add application="settings" alias="mediaTypes" title="Media Types" type="umbraco.loadMediaTypes, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="6" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add application="settings" alias="nodeTypes" title="Document Types" type="umbraco.loadNodeTypes, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="7" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add initialize="true" sortOrder="0" alias="datatype" application="developer" title="Data Types" iconClosed="icon-folder" iconOpen="icon-folder" type="Umbraco.Web.Trees.DataTypeTreeController, umbraco" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add application="developer" alias="macros" title="Macros" type="umbraco.loadMacros, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="2" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add application="developer" alias="packager" title="Packages" type="umbraco.loadPackager, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="3" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add application="developer" alias="packagerPackages" title="Packager Packages" type="umbraco.loadPackages, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" initialize="false" sortOrder="3" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add application="developer" alias="relationTypes" title="Relation Types" type="umbraco.loadRelationTypes, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="4" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add application="developer" alias="xslt" title="XSLT Files" type="umbraco.loadXslt, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="5" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add application="developer" alias="partialViewMacros" type="Umbraco.Web.Trees.PartialViewMacrosTree, umbraco" silent="false" initialize="true" sortOrder="6" title="Partial View Macro Files" iconClosed="icon-folder" iconOpen="icon-folder" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add application="users" alias="users" title="Users" type="umbraco.loadUsers, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="0" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add application="users" alias="userTypes" title="User Types" type="umbraco.cms.presentation.Trees.UserTypes, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="1" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add application="users" alias="userPermissions" title="User Permissions" type="umbraco.cms.presentation.Trees.UserPermissions, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="2" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add initialize="true" sortOrder="0" alias="member" application="member" title="Members" iconClosed="icon-folder" iconOpen="icon-folder-open" type="Umbraco.Web.Trees.MemberTreeController, umbraco" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add application="member" alias="memberGroup" title="Member Groups" type="umbraco.loadMemberGroups, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="1" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add application="member" alias="memberType" title="Member Types" type="umbraco.loadMemberTypes, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="2" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add silent="false" initialize="true" sortOrder="1" alias="openTasks" application="translation" title="Tasks assigned to you" iconClosed="icon-folder" iconOpen="icon-folder" type="umbraco.loadOpenTasks, umbraco" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add alias="openTasks" xdt:Locator="Match(alias)" xdt:Transform="RemoveAttributes(action)" />
|
||||
<add silent="false" initialize="true" sortOrder="2" alias="yourTasks" application="translation" title="Tasks created by you" iconClosed="icon-folder" iconOpen="icon-folder" type="umbraco.loadYourTasks, umbraco" xdt:Locator="Match(alias)" xdt:Transform="SetAttributes()" />
|
||||
<add alias="yourTasks" xdt:Locator="Match(alias)" xdt:Transform="RemoveAttributes(action)" />
|
||||
<add application="developer" alias="python" xdt:Locator="Match(alias)" xdt:Transform="Remove" />
|
||||
</trees>
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
# Usage: on line 2 put the release version, on line 3 put the version comment (example: beta)
|
||||
7.4.0
|
||||
beta2
|
||||
7.3.8
|
||||
+6
-6
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="nuget.org" value="https://www.nuget.org/api/v2/" />
|
||||
<add key="umbracocore" value="http://www.myget.org/f/umbracocore/" />
|
||||
</packageSources>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="nuget.org" value="https://www.nuget.org/api/v2/" />
|
||||
<add key="umbracocore" value="http://www.myget.org/f/umbracocore/" />
|
||||
</packageSources>
|
||||
</configuration>
|
||||
@@ -47,13 +47,15 @@
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
|
||||
<Private>True</Private>
|
||||
<HintPath>..\packages\SqlServerCE.4.0.0.0\lib\System.Data.SqlServerCe.dll</HintPath>
|
||||
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.dll</HintPath>
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
|
||||
<Private>True</Private>
|
||||
<HintPath>..\packages\SqlServerCE.4.0.0.0\lib\System.Data.SqlServerCe.Entity.dll</HintPath>
|
||||
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.Entity.dll</HintPath>
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="SqlServerCE" version="4.0.0.0" targetFramework="net40" />
|
||||
<package id="SqlServerCE" version="4.0.0.1" targetFramework="net45" />
|
||||
</packages>
|
||||
+2
-2
@@ -11,5 +11,5 @@ using System.Resources;
|
||||
|
||||
[assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
[assembly: AssemblyFileVersion("7.4.0")]
|
||||
[assembly: AssemblyInformationalVersion("7.4.0-beta2")]
|
||||
[assembly: AssemblyFileVersion("7.3.8")]
|
||||
[assembly: AssemblyInformationalVersion("7.3.8")]
|
||||
@@ -7,14 +7,22 @@ using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface describing this cache provider as a wrapper for another
|
||||
/// </summary>
|
||||
internal interface IRuntimeCacheProviderWrapper
|
||||
{
|
||||
IRuntimeCacheProvider InnerProvider { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A wrapper for any IRuntimeCacheProvider that ensures that all inserts and returns
|
||||
/// are a deep cloned copy of the item when the item is IDeepCloneable and that tracks changes are
|
||||
/// reset if the object is TracksChangesEntityBase
|
||||
/// </summary>
|
||||
internal class DeepCloneRuntimeCacheProvider : IRuntimeCacheProvider
|
||||
internal class DeepCloneRuntimeCacheProvider : IRuntimeCacheProvider, IRuntimeCacheProviderWrapper
|
||||
{
|
||||
internal IRuntimeCacheProvider InnerProvider { get; private set; }
|
||||
public IRuntimeCacheProvider InnerProvider { get; private set; }
|
||||
|
||||
public DeepCloneRuntimeCacheProvider(IRuntimeCacheProvider innerProvider)
|
||||
{
|
||||
|
||||
@@ -11,35 +11,35 @@ namespace Umbraco.Core.Cache
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
/// <typeparam name="TId"></typeparam>
|
||||
internal class DefaultRepositoryCachePolicy<TEntity, TId> : DisposableObject, IRepositoryCachePolicy<TEntity, TId>
|
||||
/// <remarks>
|
||||
/// This cache policy uses sliding expiration and caches instances for 5 minutes. However if allow zero count is true, then we use the
|
||||
/// default policy with no expiry.
|
||||
/// </remarks>
|
||||
internal class DefaultRepositoryCachePolicy<TEntity, TId> : RepositoryCachePolicyBase<TEntity, TId>
|
||||
where TEntity : class, IAggregateRoot
|
||||
{
|
||||
private readonly RepositoryCachePolicyOptions _options;
|
||||
protected IRuntimeCacheProvider Cache { get; private set; }
|
||||
private Action _action;
|
||||
|
||||
public DefaultRepositoryCachePolicy(IRuntimeCacheProvider cache, RepositoryCachePolicyOptions options)
|
||||
{
|
||||
if (cache == null) throw new ArgumentNullException("cache");
|
||||
: base(cache)
|
||||
{
|
||||
if (options == null) throw new ArgumentNullException("options");
|
||||
|
||||
_options = options;
|
||||
Cache = cache;
|
||||
_options = options;
|
||||
}
|
||||
|
||||
public string GetCacheIdKey(object id)
|
||||
protected string GetCacheIdKey(object id)
|
||||
{
|
||||
if (id == null) throw new ArgumentNullException("id");
|
||||
|
||||
return string.Format("{0}{1}", GetCacheTypeKey(), id);
|
||||
}
|
||||
|
||||
public string GetCacheTypeKey()
|
||||
protected string GetCacheTypeKey()
|
||||
{
|
||||
return string.Format("uRepo_{0}_", typeof(TEntity).Name);
|
||||
}
|
||||
|
||||
public void CreateOrUpdate(TEntity entity, Action<TEntity> persistMethod)
|
||||
public override void CreateOrUpdate(TEntity entity, Action<TEntity> persistMethod)
|
||||
{
|
||||
if (entity == null) throw new ArgumentNullException("entity");
|
||||
if (persistMethod == null) throw new ArgumentNullException("persistMethod");
|
||||
@@ -54,7 +54,9 @@ namespace Umbraco.Core.Cache
|
||||
//just to be safe, we cannot cache an item without an identity
|
||||
if (entity.HasIdentity)
|
||||
{
|
||||
Cache.InsertCacheItem(GetCacheIdKey(entity.Id), () => entity);
|
||||
Cache.InsertCacheItem(GetCacheIdKey(entity.Id), () => entity,
|
||||
timeout: TimeSpan.FromMinutes(5),
|
||||
isSliding: true);
|
||||
}
|
||||
|
||||
//If there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
|
||||
@@ -79,24 +81,29 @@ namespace Umbraco.Core.Cache
|
||||
}
|
||||
}
|
||||
|
||||
public void Remove(TEntity entity, Action<TEntity> persistMethod)
|
||||
public override void Remove(TEntity entity, Action<TEntity> persistMethod)
|
||||
{
|
||||
if (entity == null) throw new ArgumentNullException("entity");
|
||||
if (persistMethod == null) throw new ArgumentNullException("persistMethod");
|
||||
|
||||
persistMethod(entity);
|
||||
|
||||
//set the disposal action
|
||||
var cacheKey = GetCacheIdKey(entity.Id);
|
||||
SetCacheAction(() =>
|
||||
try
|
||||
{
|
||||
Cache.ClearCacheItem(cacheKey);
|
||||
//If there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
|
||||
Cache.ClearCacheItem(GetCacheTypeKey());
|
||||
});
|
||||
persistMethod(entity);
|
||||
}
|
||||
finally
|
||||
{
|
||||
//set the disposal action
|
||||
var cacheKey = GetCacheIdKey(entity.Id);
|
||||
SetCacheAction(() =>
|
||||
{
|
||||
Cache.ClearCacheItem(cacheKey);
|
||||
//If there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
|
||||
Cache.ClearCacheItem(GetCacheTypeKey());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public TEntity Get(TId id, Func<TId, TEntity> getFromRepo)
|
||||
public override TEntity Get(TId id, Func<TId, TEntity> getFromRepo)
|
||||
{
|
||||
if (getFromRepo == null) throw new ArgumentNullException("getFromRepo");
|
||||
|
||||
@@ -113,13 +120,13 @@ namespace Umbraco.Core.Cache
|
||||
return entity;
|
||||
}
|
||||
|
||||
public TEntity Get(TId id)
|
||||
public override TEntity Get(TId id)
|
||||
{
|
||||
var cacheKey = GetCacheIdKey(id);
|
||||
return Cache.GetCacheItem<TEntity>(cacheKey);
|
||||
}
|
||||
|
||||
public bool Exists(TId id, Func<TId, bool> getFromRepo)
|
||||
public override bool Exists(TId id, Func<TId, bool> getFromRepo)
|
||||
{
|
||||
if (getFromRepo == null) throw new ArgumentNullException("getFromRepo");
|
||||
|
||||
@@ -128,7 +135,7 @@ namespace Umbraco.Core.Cache
|
||||
return fromCache != null || getFromRepo(id);
|
||||
}
|
||||
|
||||
public virtual TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> getFromRepo)
|
||||
public override TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> getFromRepo)
|
||||
{
|
||||
if (getFromRepo == null) throw new ArgumentNullException("getFromRepo");
|
||||
|
||||
@@ -158,8 +165,7 @@ namespace Umbraco.Core.Cache
|
||||
else if (_options.GetAllCacheAllowZeroCount)
|
||||
{
|
||||
//if the repository allows caching a zero count, then check the zero count cache
|
||||
var zeroCount = Cache.GetCacheItem<TEntity[]>(GetCacheTypeKey());
|
||||
if (zeroCount != null && zeroCount.Any() == false)
|
||||
if (HasZeroCountCache())
|
||||
{
|
||||
//there is a zero count cache so return an empty list
|
||||
return new TEntity[] {};
|
||||
@@ -179,28 +185,27 @@ namespace Umbraco.Core.Cache
|
||||
return entityCollection;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up the zero count cache, must return null if it doesn't exist
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected bool HasZeroCountCache()
|
||||
{
|
||||
var zeroCount = Cache.GetCacheItem<TEntity[]>(GetCacheTypeKey());
|
||||
return (zeroCount != null && zeroCount.Any() == false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs the lookup for all entities of this type from the cache
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected virtual TEntity[] GetAllFromCache()
|
||||
protected TEntity[] GetAllFromCache()
|
||||
{
|
||||
var allEntities = Cache.GetCacheItemsByKeySearch<TEntity>(GetCacheTypeKey())
|
||||
.WhereNotNull()
|
||||
.ToArray();
|
||||
return allEntities.Any() ? allEntities : new TEntity[] {};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The disposal performs the caching
|
||||
/// </summary>
|
||||
protected override void DisposeResources()
|
||||
{
|
||||
if (_action != null)
|
||||
{
|
||||
_action();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the action to execute on disposal for a single entity
|
||||
@@ -216,7 +221,9 @@ namespace Umbraco.Core.Cache
|
||||
//just to be safe, we cannot cache an item without an identity
|
||||
if (entity.HasIdentity)
|
||||
{
|
||||
Cache.InsertCacheItem(cacheKey, () => entity);
|
||||
Cache.InsertCacheItem(cacheKey, () => entity,
|
||||
timeout: TimeSpan.FromMinutes(5),
|
||||
isSliding: true);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -235,6 +242,7 @@ namespace Umbraco.Core.Cache
|
||||
{
|
||||
//there was nothing returned but we want to cache a zero count result so add an TEntity[] to the cache
|
||||
// to signify that there is a zero count cache
|
||||
//NOTE: Don't set expiry/sliding for a zero count
|
||||
Cache.InsertCacheItem(GetCacheTypeKey(), () => new TEntity[] {});
|
||||
}
|
||||
else
|
||||
@@ -247,20 +255,14 @@ namespace Umbraco.Core.Cache
|
||||
//just to be safe, we cannot cache an item without an identity
|
||||
if (localCopy.HasIdentity)
|
||||
{
|
||||
Cache.InsertCacheItem(GetCacheIdKey(entity.Id), () => localCopy);
|
||||
Cache.InsertCacheItem(GetCacheIdKey(entity.Id), () => localCopy,
|
||||
timeout: TimeSpan.FromMinutes(5),
|
||||
isSliding: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the action to execute on disposal
|
||||
/// </summary>
|
||||
/// <param name="action"></param>
|
||||
protected void SetCacheAction(Action action)
|
||||
{
|
||||
_action = action;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Collections;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
@@ -9,11 +11,157 @@ namespace Umbraco.Core.Cache
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
/// <typeparam name="TId"></typeparam>
|
||||
internal class FullDataSetRepositoryCachePolicy<TEntity, TId> : DefaultRepositoryCachePolicy<TEntity, TId>
|
||||
internal class FullDataSetRepositoryCachePolicy<TEntity, TId> : RepositoryCachePolicyBase<TEntity, TId>
|
||||
where TEntity : class, IAggregateRoot
|
||||
{
|
||||
public FullDataSetRepositoryCachePolicy(IRuntimeCacheProvider cache) : base(cache, new RepositoryCachePolicyOptions())
|
||||
private readonly Func<TEntity, TId> _getEntityId;
|
||||
private readonly Func<IEnumerable<TEntity>> _getAllFromRepo;
|
||||
private readonly bool _expires;
|
||||
|
||||
public FullDataSetRepositoryCachePolicy(IRuntimeCacheProvider cache, Func<TEntity, TId> getEntityId, Func<IEnumerable<TEntity>> getAllFromRepo, bool expires)
|
||||
: base(cache)
|
||||
{
|
||||
_getEntityId = getEntityId;
|
||||
_getAllFromRepo = getAllFromRepo;
|
||||
_expires = expires;
|
||||
}
|
||||
|
||||
private bool? _hasZeroCountCache;
|
||||
|
||||
|
||||
protected string GetCacheTypeKey()
|
||||
{
|
||||
return string.Format("uRepo_{0}_", typeof(TEntity).Name);
|
||||
}
|
||||
|
||||
public override void CreateOrUpdate(TEntity entity, Action<TEntity> persistMethod)
|
||||
{
|
||||
if (entity == null) throw new ArgumentNullException("entity");
|
||||
if (persistMethod == null) throw new ArgumentNullException("persistMethod");
|
||||
|
||||
try
|
||||
{
|
||||
persistMethod(entity);
|
||||
|
||||
//set the disposal action
|
||||
SetCacheAction(() =>
|
||||
{
|
||||
//Clear all
|
||||
Cache.ClearCacheItem(GetCacheTypeKey());
|
||||
});
|
||||
}
|
||||
catch
|
||||
{
|
||||
//set the disposal action
|
||||
SetCacheAction(() =>
|
||||
{
|
||||
//Clear all
|
||||
Cache.ClearCacheItem(GetCacheTypeKey());
|
||||
});
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Remove(TEntity entity, Action<TEntity> persistMethod)
|
||||
{
|
||||
if (entity == null) throw new ArgumentNullException("entity");
|
||||
if (persistMethod == null) throw new ArgumentNullException("persistMethod");
|
||||
|
||||
try
|
||||
{
|
||||
persistMethod(entity);
|
||||
}
|
||||
finally
|
||||
{
|
||||
//set the disposal action
|
||||
SetCacheAction(() =>
|
||||
{
|
||||
//Clear all
|
||||
Cache.ClearCacheItem(GetCacheTypeKey());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public override TEntity Get(TId id, Func<TId, TEntity> getFromRepo)
|
||||
{
|
||||
//Force get all with cache
|
||||
var found = GetAll(new TId[] { }, ids => _getAllFromRepo().WhereNotNull());
|
||||
|
||||
//we don't have anything in cache (this should never happen), just return from the repo
|
||||
if (found == null) return getFromRepo(id);
|
||||
var entity = found.FirstOrDefault(x => _getEntityId(x).Equals(id));
|
||||
if (entity == null) return null;
|
||||
|
||||
//We must ensure to deep clone each one out manually since the deep clone list only clones one way
|
||||
return (TEntity)entity.DeepClone();
|
||||
}
|
||||
|
||||
public override TEntity Get(TId id)
|
||||
{
|
||||
//Force get all with cache
|
||||
var found = GetAll(new TId[] { }, ids => _getAllFromRepo().WhereNotNull());
|
||||
|
||||
//we don't have anything in cache (this should never happen), just return null
|
||||
if (found == null) return null;
|
||||
var entity = found.FirstOrDefault(x => _getEntityId(x).Equals(id));
|
||||
if (entity == null) return null;
|
||||
|
||||
//We must ensure to deep clone each one out manually since the deep clone list only clones one way
|
||||
return (TEntity)entity.DeepClone();
|
||||
}
|
||||
|
||||
public override bool Exists(TId id, Func<TId, bool> getFromRepo)
|
||||
{
|
||||
//Force get all with cache
|
||||
var found = GetAll(new TId[] {}, ids => _getAllFromRepo().WhereNotNull());
|
||||
|
||||
//we don't have anything in cache (this should never happen), just return from the repo
|
||||
return found == null
|
||||
? getFromRepo(id)
|
||||
: found.Any(x => _getEntityId(x).Equals(id));
|
||||
}
|
||||
|
||||
public override TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> getFromRepo)
|
||||
{
|
||||
//process getting all including setting the cache callback
|
||||
var result = PerformGetAll(getFromRepo);
|
||||
|
||||
//now that the base result has been calculated, they will all be cached.
|
||||
// Now we can just filter by ids if they have been supplied
|
||||
|
||||
return (ids.Any()
|
||||
? result.Where(x => ids.Contains(_getEntityId(x))).ToArray()
|
||||
: result)
|
||||
//We must ensure to deep clone each one out manually since the deep clone list only clones one way
|
||||
.Select(x => (TEntity)x.DeepClone())
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private TEntity[] PerformGetAll(Func<TId[], IEnumerable<TEntity>> getFromRepo)
|
||||
{
|
||||
var allEntities = GetAllFromCache();
|
||||
if (allEntities.Any())
|
||||
{
|
||||
return allEntities;
|
||||
}
|
||||
|
||||
//check the zero count cache
|
||||
if (HasZeroCountCache())
|
||||
{
|
||||
//there is a zero count cache so return an empty list
|
||||
return new TEntity[] { };
|
||||
}
|
||||
|
||||
//we need to do the lookup from the repo
|
||||
var entityCollection = getFromRepo(new TId[] {})
|
||||
//ensure we don't include any null refs in the returned collection!
|
||||
.WhereNotNull()
|
||||
.ToArray();
|
||||
|
||||
//set the disposal action
|
||||
SetCacheAction(entityCollection);
|
||||
|
||||
return entityCollection;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -21,37 +169,61 @@ namespace Umbraco.Core.Cache
|
||||
/// </summary>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="entity"></param>
|
||||
protected override void SetCacheAction(string cacheKey, TEntity entity)
|
||||
protected void SetCacheAction(string cacheKey, TEntity entity)
|
||||
{
|
||||
//do nothing
|
||||
//No-op
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the action to execute on disposal for an entity collection
|
||||
/// </summary>
|
||||
/// <param name="ids"></param>
|
||||
/// <param name="entityCollection"></param>
|
||||
protected override void SetCacheAction(TId[] ids, TEntity[] entityCollection)
|
||||
protected void SetCacheAction(TEntity[] entityCollection)
|
||||
{
|
||||
//for this type of caching policy, we don't want to cache any GetAll request containing specific Ids
|
||||
if (ids.Any()) return;
|
||||
|
||||
//set the disposal action
|
||||
SetCacheAction(() =>
|
||||
{
|
||||
//We want to cache the result as a single collection
|
||||
Cache.InsertCacheItem(GetCacheTypeKey(), () => new DeepCloneableList<TEntity>(entityCollection));
|
||||
|
||||
if (_expires)
|
||||
{
|
||||
Cache.InsertCacheItem(GetCacheTypeKey(), () => new DeepCloneableList<TEntity>(entityCollection),
|
||||
timeout: TimeSpan.FromMinutes(5),
|
||||
isSliding: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Cache.InsertCacheItem(GetCacheTypeKey(), () => new DeepCloneableList<TEntity>(entityCollection));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up the zero count cache, must return null if it doesn't exist
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected bool HasZeroCountCache()
|
||||
{
|
||||
if (_hasZeroCountCache.HasValue)
|
||||
return _hasZeroCountCache.Value;
|
||||
|
||||
_hasZeroCountCache = Cache.GetCacheItem<DeepCloneableList<TEntity>>(GetCacheTypeKey()) != null;
|
||||
return _hasZeroCountCache.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This policy will cache the full data set as a single collection
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override TEntity[] GetAllFromCache()
|
||||
protected TEntity[] GetAllFromCache()
|
||||
{
|
||||
var found = Cache.GetCacheItem<DeepCloneableList<TEntity>>(GetCacheTypeKey());
|
||||
|
||||
//This method will get called before checking for zero count cache, so we'll just set the flag here
|
||||
_hasZeroCountCache = found != null;
|
||||
|
||||
return found == null ? new TEntity[] { } : found.WhereNotNull().ToArray();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
@@ -11,15 +13,21 @@ namespace Umbraco.Core.Cache
|
||||
where TEntity : class, IAggregateRoot
|
||||
{
|
||||
private readonly IRuntimeCacheProvider _runtimeCache;
|
||||
|
||||
public FullDataSetRepositoryCachePolicyFactory(IRuntimeCacheProvider runtimeCache)
|
||||
private readonly Func<TEntity, TId> _getEntityId;
|
||||
private readonly Func<IEnumerable<TEntity>> _getAllFromRepo;
|
||||
private readonly bool _expires;
|
||||
|
||||
public FullDataSetRepositoryCachePolicyFactory(IRuntimeCacheProvider runtimeCache, Func<TEntity, TId> getEntityId, Func<IEnumerable<TEntity>> getAllFromRepo, bool expires)
|
||||
{
|
||||
_runtimeCache = runtimeCache;
|
||||
_getEntityId = getEntityId;
|
||||
_getAllFromRepo = getAllFromRepo;
|
||||
_expires = expires;
|
||||
}
|
||||
|
||||
public virtual IRepositoryCachePolicy<TEntity, TId> CreatePolicy()
|
||||
{
|
||||
return new FullDataSetRepositoryCachePolicy<TEntity, TId>(_runtimeCache);
|
||||
return new FullDataSetRepositoryCachePolicy<TEntity, TId>(_runtimeCache, _getEntityId, _getAllFromRepo, _expires);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,9 +10,7 @@ namespace Umbraco.Core.Cache
|
||||
TEntity Get(TId id, Func<TId, TEntity> getFromRepo);
|
||||
TEntity Get(TId id);
|
||||
bool Exists(TId id, Func<TId, bool> getFromRepo);
|
||||
|
||||
string GetCacheIdKey(object id);
|
||||
string GetCacheTypeKey();
|
||||
|
||||
void CreateOrUpdate(TEntity entity, Action<TEntity> persistMethod);
|
||||
void Remove(TEntity entity, Action<TEntity> persistMethod);
|
||||
TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> getFromRepo);
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Umbraco.Core.Cache
|
||||
/// </remarks>
|
||||
public class IsolatedRuntimeCache
|
||||
{
|
||||
private readonly Func<Type, IRuntimeCacheProvider> _cacheFactory;
|
||||
internal Func<Type, IRuntimeCacheProvider> CacheFactory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor that allows specifying a factory for the type of runtime isolated cache to create
|
||||
@@ -20,7 +20,7 @@ namespace Umbraco.Core.Cache
|
||||
/// <param name="cacheFactory"></param>
|
||||
public IsolatedRuntimeCache(Func<Type, IRuntimeCacheProvider> cacheFactory)
|
||||
{
|
||||
_cacheFactory = cacheFactory;
|
||||
CacheFactory = cacheFactory;
|
||||
}
|
||||
|
||||
private readonly ConcurrentDictionary<Type, IRuntimeCacheProvider> _isolatedCache = new ConcurrentDictionary<Type, IRuntimeCacheProvider>();
|
||||
@@ -32,7 +32,7 @@ namespace Umbraco.Core.Cache
|
||||
/// <returns></returns>
|
||||
public IRuntimeCacheProvider GetOrCreateCache<T>()
|
||||
{
|
||||
return _isolatedCache.GetOrAdd(typeof(T), type => _cacheFactory(type));
|
||||
return _isolatedCache.GetOrAdd(typeof(T), type => CacheFactory(type));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -41,7 +41,7 @@ namespace Umbraco.Core.Cache
|
||||
/// <returns></returns>
|
||||
public IRuntimeCacheProvider GetOrCreateCache(Type type)
|
||||
{
|
||||
return _isolatedCache.GetOrAdd(type, t => _cacheFactory(t));
|
||||
return _isolatedCache.GetOrAdd(type, t => CacheFactory(t));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
internal abstract class RepositoryCachePolicyBase<TEntity, TId> : DisposableObject, IRepositoryCachePolicy<TEntity, TId>
|
||||
where TEntity : class, IAggregateRoot
|
||||
{
|
||||
private Action _action;
|
||||
|
||||
protected RepositoryCachePolicyBase(IRuntimeCacheProvider cache)
|
||||
{
|
||||
if (cache == null) throw new ArgumentNullException("cache");
|
||||
|
||||
Cache = cache;
|
||||
}
|
||||
|
||||
protected IRuntimeCacheProvider Cache { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The disposal performs the caching
|
||||
/// </summary>
|
||||
protected override void DisposeResources()
|
||||
{
|
||||
if (_action != null)
|
||||
{
|
||||
_action();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the action to execute on disposal
|
||||
/// </summary>
|
||||
/// <param name="action"></param>
|
||||
protected void SetCacheAction(Action action)
|
||||
{
|
||||
_action = action;
|
||||
}
|
||||
|
||||
public abstract TEntity Get(TId id, Func<TId, TEntity> getFromRepo);
|
||||
public abstract TEntity Get(TId id);
|
||||
public abstract bool Exists(TId id, Func<TId, bool> getFromRepo);
|
||||
public abstract void CreateOrUpdate(TEntity entity, Action<TEntity> persistMethod);
|
||||
public abstract void Remove(TEntity entity, Action<TEntity> persistMethod);
|
||||
public abstract TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> getFromRepo);
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
protected override void SetCacheAction(TId[] ids, TEntity[] entityCollection)
|
||||
{
|
||||
//do nothing
|
||||
//no-op
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,12 +18,8 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public class CacheHelper
|
||||
{
|
||||
private readonly IsolatedRuntimeCache _isolatedCacheManager;
|
||||
private readonly ICacheProvider _requestCache;
|
||||
private static readonly ICacheProvider NullRequestCache = new NullCacheProvider();
|
||||
private readonly ICacheProvider _staticCache;
|
||||
private static readonly ICacheProvider NullStaticCache = new NullCacheProvider();
|
||||
private readonly IRuntimeCacheProvider _runtimeCache;
|
||||
private static readonly IRuntimeCacheProvider NullRuntimeCache = new NullCacheProvider();
|
||||
|
||||
/// <summary>
|
||||
@@ -90,45 +86,33 @@ namespace Umbraco.Core
|
||||
if (staticCacheProvider == null) throw new ArgumentNullException("staticCacheProvider");
|
||||
if (requestCacheProvider == null) throw new ArgumentNullException("requestCacheProvider");
|
||||
if (isolatedCacheManager == null) throw new ArgumentNullException("isolatedCacheManager");
|
||||
_runtimeCache = httpCacheProvider;
|
||||
_staticCache = staticCacheProvider;
|
||||
_requestCache = requestCacheProvider;
|
||||
_isolatedCacheManager = isolatedCacheManager;
|
||||
RuntimeCache = httpCacheProvider;
|
||||
StaticCache = staticCacheProvider;
|
||||
RequestCache = requestCacheProvider;
|
||||
IsolatedRuntimeCache = isolatedCacheManager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current Request cache
|
||||
/// </summary>
|
||||
public ICacheProvider RequestCache
|
||||
{
|
||||
get { return _requestCache; }
|
||||
}
|
||||
public ICacheProvider RequestCache { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current Runtime cache
|
||||
/// </summary>
|
||||
public ICacheProvider StaticCache
|
||||
{
|
||||
get { return _staticCache; }
|
||||
}
|
||||
public ICacheProvider StaticCache { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current Runtime cache
|
||||
/// </summary>
|
||||
public IRuntimeCacheProvider RuntimeCache
|
||||
{
|
||||
get { return _runtimeCache; }
|
||||
}
|
||||
public IRuntimeCacheProvider RuntimeCache { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current Isolated Runtime cache manager
|
||||
/// </summary>
|
||||
public IsolatedRuntimeCache IsolatedRuntimeCache
|
||||
{
|
||||
get { return _isolatedCacheManager; }
|
||||
}
|
||||
|
||||
#region Legacy Runtime/Http Cache accessors
|
||||
public IsolatedRuntimeCache IsolatedRuntimeCache { get; internal set; }
|
||||
|
||||
#region Legacy Runtime/Http Cache accessors
|
||||
|
||||
/// <summary>
|
||||
/// Clears the item in umbraco's runtime cache
|
||||
@@ -137,8 +121,8 @@ namespace Umbraco.Core
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public void ClearAllCache()
|
||||
{
|
||||
_runtimeCache.ClearAllCache();
|
||||
_isolatedCacheManager.ClearAllCaches();
|
||||
RuntimeCache.ClearAllCache();
|
||||
IsolatedRuntimeCache.ClearAllCaches();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -149,7 +133,7 @@ namespace Umbraco.Core
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public void ClearCacheItem(string key)
|
||||
{
|
||||
_runtimeCache.ClearCacheItem(key);
|
||||
RuntimeCache.ClearCacheItem(key);
|
||||
}
|
||||
|
||||
|
||||
@@ -161,7 +145,7 @@ namespace Umbraco.Core
|
||||
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
|
||||
public void ClearCacheObjectTypes(string typeName)
|
||||
{
|
||||
_runtimeCache.ClearCacheObjectTypes(typeName);
|
||||
RuntimeCache.ClearCacheObjectTypes(typeName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -171,7 +155,7 @@ namespace Umbraco.Core
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public void ClearCacheObjectTypes<T>()
|
||||
{
|
||||
_runtimeCache.ClearCacheObjectTypes<T>();
|
||||
RuntimeCache.ClearCacheObjectTypes<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -182,7 +166,7 @@ namespace Umbraco.Core
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public void ClearCacheByKeySearch(string keyStartsWith)
|
||||
{
|
||||
_runtimeCache.ClearCacheByKeySearch(keyStartsWith);
|
||||
RuntimeCache.ClearCacheByKeySearch(keyStartsWith);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -193,14 +177,14 @@ namespace Umbraco.Core
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public void ClearCacheByKeyExpression(string regexString)
|
||||
{
|
||||
_runtimeCache.ClearCacheByKeyExpression(regexString);
|
||||
RuntimeCache.ClearCacheByKeyExpression(regexString);
|
||||
}
|
||||
|
||||
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public IEnumerable<T> GetCacheItemsByKeySearch<T>(string keyStartsWith)
|
||||
{
|
||||
return _runtimeCache.GetCacheItemsByKeySearch<T>(keyStartsWith);
|
||||
return RuntimeCache.GetCacheItemsByKeySearch<T>(keyStartsWith);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -213,7 +197,7 @@ namespace Umbraco.Core
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public TT GetCacheItem<TT>(string cacheKey)
|
||||
{
|
||||
return _runtimeCache.GetCacheItem<TT>(cacheKey);
|
||||
return RuntimeCache.GetCacheItem<TT>(cacheKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -227,7 +211,7 @@ namespace Umbraco.Core
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public TT GetCacheItem<TT>(string cacheKey, Func<TT> getCacheItem)
|
||||
{
|
||||
return _runtimeCache.GetCacheItem<TT>(cacheKey, getCacheItem);
|
||||
return RuntimeCache.GetCacheItem<TT>(cacheKey, getCacheItem);
|
||||
|
||||
}
|
||||
|
||||
@@ -244,7 +228,7 @@ namespace Umbraco.Core
|
||||
public TT GetCacheItem<TT>(string cacheKey,
|
||||
TimeSpan timeout, Func<TT> getCacheItem)
|
||||
{
|
||||
return _runtimeCache.GetCacheItem<TT>(cacheKey, getCacheItem, timeout);
|
||||
return RuntimeCache.GetCacheItem<TT>(cacheKey, getCacheItem, timeout);
|
||||
|
||||
}
|
||||
|
||||
@@ -263,7 +247,7 @@ namespace Umbraco.Core
|
||||
CacheItemRemovedCallback refreshAction, TimeSpan timeout,
|
||||
Func<TT> getCacheItem)
|
||||
{
|
||||
return _runtimeCache.GetCacheItem<TT>(cacheKey, getCacheItem, timeout, removedCallback: refreshAction);
|
||||
return RuntimeCache.GetCacheItem<TT>(cacheKey, getCacheItem, timeout, removedCallback: refreshAction);
|
||||
|
||||
}
|
||||
|
||||
@@ -283,7 +267,7 @@ namespace Umbraco.Core
|
||||
CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan timeout,
|
||||
Func<TT> getCacheItem)
|
||||
{
|
||||
return _runtimeCache.GetCacheItem<TT>(cacheKey, getCacheItem, timeout, false, priority, refreshAction);
|
||||
return RuntimeCache.GetCacheItem<TT>(cacheKey, getCacheItem, timeout, false, priority, refreshAction);
|
||||
|
||||
}
|
||||
|
||||
@@ -306,7 +290,7 @@ namespace Umbraco.Core
|
||||
TimeSpan timeout,
|
||||
Func<TT> getCacheItem)
|
||||
{
|
||||
var cache = _runtimeCache as HttpRuntimeCacheProvider;
|
||||
var cache = GetHttpRuntimeCacheProvider(RuntimeCache);
|
||||
if (cache != null)
|
||||
{
|
||||
var result = cache.GetCacheItem(cacheKey, () => getCacheItem(), timeout, false, priority, refreshAction, cacheDependency);
|
||||
@@ -330,7 +314,7 @@ namespace Umbraco.Core
|
||||
CacheDependency cacheDependency,
|
||||
Func<TT> getCacheItem)
|
||||
{
|
||||
var cache = _runtimeCache as HttpRuntimeCacheProvider;
|
||||
var cache = GetHttpRuntimeCacheProvider(RuntimeCache);
|
||||
if (cache != null)
|
||||
{
|
||||
var result = cache.GetCacheItem(cacheKey, () => getCacheItem(), null, false, priority, null, cacheDependency);
|
||||
@@ -352,7 +336,7 @@ namespace Umbraco.Core
|
||||
CacheItemPriority priority,
|
||||
Func<T> getCacheItem)
|
||||
{
|
||||
_runtimeCache.InsertCacheItem<T>(cacheKey, getCacheItem, priority: priority);
|
||||
RuntimeCache.InsertCacheItem<T>(cacheKey, getCacheItem, priority: priority);
|
||||
|
||||
}
|
||||
|
||||
@@ -371,7 +355,7 @@ namespace Umbraco.Core
|
||||
TimeSpan timeout,
|
||||
Func<T> getCacheItem)
|
||||
{
|
||||
_runtimeCache.InsertCacheItem<T>(cacheKey, getCacheItem, timeout, priority: priority);
|
||||
RuntimeCache.InsertCacheItem<T>(cacheKey, getCacheItem, timeout, priority: priority);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -390,7 +374,7 @@ namespace Umbraco.Core
|
||||
TimeSpan timeout,
|
||||
Func<T> getCacheItem)
|
||||
{
|
||||
var cache = _runtimeCache as HttpRuntimeCacheProvider;
|
||||
var cache = GetHttpRuntimeCacheProvider(RuntimeCache);
|
||||
if (cache != null)
|
||||
{
|
||||
cache.InsertCacheItem(cacheKey, () => getCacheItem(), timeout, false, priority, null, cacheDependency);
|
||||
@@ -416,7 +400,7 @@ namespace Umbraco.Core
|
||||
TimeSpan? timeout,
|
||||
Func<T> getCacheItem)
|
||||
{
|
||||
var cache = _runtimeCache as HttpRuntimeCacheProvider;
|
||||
var cache = GetHttpRuntimeCacheProvider(RuntimeCache);
|
||||
if (cache != null)
|
||||
{
|
||||
cache.InsertCacheItem(cacheKey, () => getCacheItem(), timeout, false, priority, refreshAction, cacheDependency);
|
||||
@@ -425,6 +409,20 @@ namespace Umbraco.Core
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
private HttpRuntimeCacheProvider GetHttpRuntimeCacheProvider(IRuntimeCacheProvider runtimeCache)
|
||||
{
|
||||
HttpRuntimeCacheProvider cache;
|
||||
var wrapper = RuntimeCache as IRuntimeCacheProviderWrapper;
|
||||
if (wrapper != null)
|
||||
{
|
||||
cache = wrapper.InnerProvider as HttpRuntimeCacheProvider;
|
||||
}
|
||||
else
|
||||
{
|
||||
cache = RuntimeCache as HttpRuntimeCacheProvider;
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,18 +14,24 @@ namespace Umbraco.Core.Collections
|
||||
/// <typeparam name="T"></typeparam>
|
||||
internal class DeepCloneableList<T> : List<T>, IDeepCloneable, IRememberBeingDirty
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:System.Collections.Generic.List`1"/> class that is empty and has the default initial capacity.
|
||||
/// </summary>
|
||||
public DeepCloneableList()
|
||||
private readonly ListCloneBehavior _listCloneBehavior;
|
||||
|
||||
public DeepCloneableList(ListCloneBehavior listCloneBehavior)
|
||||
{
|
||||
_listCloneBehavior = listCloneBehavior;
|
||||
}
|
||||
|
||||
public DeepCloneableList(IEnumerable<T> collection, ListCloneBehavior listCloneBehavior) : base(collection)
|
||||
{
|
||||
_listCloneBehavior = listCloneBehavior;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:System.Collections.Generic.List`1"/> class that contains elements copied from the specified collection and has sufficient capacity to accommodate the number of elements copied.
|
||||
/// Default behavior is CloneOnce
|
||||
/// </summary>
|
||||
/// <param name="collection">The collection whose elements are copied to the new list.</param><exception cref="T:System.ArgumentNullException"><paramref name="collection"/> is null.</exception>
|
||||
public DeepCloneableList(IEnumerable<T> collection) : base(collection)
|
||||
/// <param name="collection"></param>
|
||||
public DeepCloneableList(IEnumerable<T> collection)
|
||||
: this(collection, ListCloneBehavior.CloneOnce)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -35,20 +41,47 @@ namespace Umbraco.Core.Collections
|
||||
/// <returns></returns>
|
||||
public object DeepClone()
|
||||
{
|
||||
var newList = new DeepCloneableList<T>();
|
||||
foreach (var item in this)
|
||||
switch (_listCloneBehavior)
|
||||
{
|
||||
var dc = item as IDeepCloneable;
|
||||
if (dc != null)
|
||||
{
|
||||
newList.Add((T) dc.DeepClone());
|
||||
}
|
||||
else
|
||||
{
|
||||
newList.Add(item);
|
||||
}
|
||||
case ListCloneBehavior.CloneOnce:
|
||||
//we are cloning once, so create a new list in none mode
|
||||
// and deep clone all items into it
|
||||
var newList = new DeepCloneableList<T>(ListCloneBehavior.None);
|
||||
foreach (var item in this)
|
||||
{
|
||||
var dc = item as IDeepCloneable;
|
||||
if (dc != null)
|
||||
{
|
||||
newList.Add((T)dc.DeepClone());
|
||||
}
|
||||
else
|
||||
{
|
||||
newList.Add(item);
|
||||
}
|
||||
}
|
||||
return newList;
|
||||
case ListCloneBehavior.None:
|
||||
//we are in none mode, so just return a new list with the same items
|
||||
return new DeepCloneableList<T>(this, ListCloneBehavior.None);
|
||||
case ListCloneBehavior.Always:
|
||||
//always clone to new list
|
||||
var newList2 = new DeepCloneableList<T>(ListCloneBehavior.Always);
|
||||
foreach (var item in this)
|
||||
{
|
||||
var dc = item as IDeepCloneable;
|
||||
if (dc != null)
|
||||
{
|
||||
newList2.Add((T)dc.DeepClone());
|
||||
}
|
||||
else
|
||||
{
|
||||
newList2.Add(item);
|
||||
}
|
||||
}
|
||||
return newList2;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
return newList;
|
||||
}
|
||||
|
||||
public bool IsDirty()
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
namespace Umbraco.Core.Collections
|
||||
{
|
||||
internal enum ListCloneBehavior
|
||||
{
|
||||
/// <summary>
|
||||
/// When set, DeepClone will clone the items one time and the result list behavior will be None
|
||||
/// </summary>
|
||||
CloneOnce,
|
||||
|
||||
/// <summary>
|
||||
/// When set, DeepClone will not clone any items
|
||||
/// </summary>
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// When set, DeepClone will always clone all items
|
||||
/// </summary>
|
||||
Always
|
||||
}
|
||||
}
|
||||
@@ -280,18 +280,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
}
|
||||
}
|
||||
|
||||
[ConfigurationProperty("EnableInheritedDocumentTypes")]
|
||||
internal InnerTextConfigurationElement<bool> EnableInheritedDocumentTypes
|
||||
{
|
||||
get
|
||||
{
|
||||
return new OptionalInnerTextConfigurationElement<bool>(
|
||||
(InnerTextConfigurationElement<bool>) this["EnableInheritedDocumentTypes"],
|
||||
//set the default
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
string IContentSection.NotificationEmailAddress
|
||||
{
|
||||
get { return Notifications.NotificationEmailAddress; }
|
||||
@@ -426,10 +414,5 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
{
|
||||
get { return DefaultDocumentTypeProperty; }
|
||||
}
|
||||
|
||||
bool IContentSection.EnableInheritedDocumentTypes
|
||||
{
|
||||
get { return EnableInheritedDocumentTypes; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -59,7 +59,5 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
bool GlobalPreviewStorageEnabled { get; }
|
||||
|
||||
string DefaultDocumentTypeProperty { get; }
|
||||
|
||||
bool EnableInheritedDocumentTypes { get; }
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
public class UmbracoVersion
|
||||
{
|
||||
private static readonly Version Version = new Version("7.4.0");
|
||||
private static readonly Version Version = new Version("7.3.8");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current version of Umbraco.
|
||||
@@ -24,7 +24,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the version comment (like beta or RC).
|
||||
/// </summary>
|
||||
/// <value>The version comment.</value>
|
||||
public static string CurrentComment { get { return "beta2"; } }
|
||||
public static string CurrentComment { get { return ""; } }
|
||||
|
||||
// Get the version of the umbraco.dll by looking at a class in that dll
|
||||
// Had to do it like this due to medium trust issues, see: http://haacked.com/archive/2010/11/04/assembly-location-and-medium-trust.aspx
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
public const string Content = "content";
|
||||
|
||||
/// <summary>
|
||||
/// alias for the member tree.
|
||||
/// alias for the media tree.
|
||||
/// </summary>
|
||||
public const string Members = "member";
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
/// <summary>
|
||||
/// alias for the datatype tree.
|
||||
/// </summary>
|
||||
public const string DataTypes = "dataTypes";
|
||||
public const string DataTypes = "datatype";
|
||||
|
||||
/// <summary>
|
||||
/// alias for the dictionary tree.
|
||||
@@ -80,22 +80,6 @@
|
||||
|
||||
public const string Stylesheets = "stylesheets";
|
||||
|
||||
/// <summary>
|
||||
/// alias for the document type tree.
|
||||
/// </summary>
|
||||
public const string DocumentTypes = "documentTypes";
|
||||
|
||||
/// <summary>
|
||||
/// alias for the media type tree.
|
||||
/// </summary>
|
||||
public const string MediaTypes = "mediaTypes";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// alias for the member type tree.
|
||||
/// </summary>
|
||||
public const string MemberTypes = "memberTypes";
|
||||
|
||||
/// <summary>
|
||||
/// alias for the template tree.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static partial class Constants
|
||||
{
|
||||
public static class Icons
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// System contenttype icon
|
||||
/// </summary>
|
||||
public const string ContentType = "icon-arrangement";
|
||||
|
||||
/// <summary>
|
||||
/// System datatype icon
|
||||
/// </summary>
|
||||
public const string DataType = "icon-autofill";
|
||||
|
||||
/// <summary>
|
||||
/// System property editor icon
|
||||
/// </summary>
|
||||
public const string PropertyEditor = "icon-autofill";
|
||||
|
||||
/// <summary>
|
||||
/// System macro icon
|
||||
/// </summary>
|
||||
public const string Macro = "icon-settings-alt";
|
||||
|
||||
/// <summary>
|
||||
/// System member icon
|
||||
/// </summary>
|
||||
public const string Member = "icon-user";
|
||||
|
||||
/// <summary>
|
||||
/// System member icon
|
||||
/// </summary>
|
||||
public const string MemberType = "icon-users";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// System member icon
|
||||
/// </summary>
|
||||
public const string Template = "icon-layout";
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,36 +9,6 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public static class ObjectTypes
|
||||
{
|
||||
/// <summary>
|
||||
/// Guid for a data type container
|
||||
/// </summary>
|
||||
public const string DataTypeContainer = "521231E3-8B37-469C-9F9D-51AFC91FEB7B";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a data type container
|
||||
/// </summary>
|
||||
public static readonly Guid DataTypeContainerGuid = new Guid(DataTypeContainer);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a doc type container
|
||||
/// </summary>
|
||||
public const string DocumentTypeContainer = "2F7A2769-6B0B-4468-90DD-AF42D64F7F16";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a doc type container
|
||||
/// </summary>
|
||||
public static readonly Guid DocumentTypeContainerGuid = new Guid(DocumentTypeContainer);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a doc type container
|
||||
/// </summary>
|
||||
public const string MediaTypeContainer = "42AEF799-B288-4744-9B10-BE144B73CDC4";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a doc type container
|
||||
/// </summary>
|
||||
public static readonly Guid MediaTypeContainerGuid = new Guid(MediaTypeContainer);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Content Item object.
|
||||
/// </summary>
|
||||
@@ -59,11 +29,6 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public const string DataType = "30A2A501-1978-4DDB-A57B-F7EFED43BA3C";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a DataType object.
|
||||
/// </summary>
|
||||
public static readonly Guid DataTypeGuid = new Guid(DataType);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Document object.
|
||||
/// </summary>
|
||||
@@ -74,11 +39,6 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public const string DocumentType = "A2CB7800-F571-4787-9638-BC48539A0EFB";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Document Type object.
|
||||
/// </summary>
|
||||
public static readonly Guid DocumentTypeGuid = new Guid(DocumentType);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Media object.
|
||||
/// </summary>
|
||||
@@ -94,11 +54,6 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public const string MediaType = "4EA4382B-2F5A-4C2B-9587-AE9B3CF3602E";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Media Type object.
|
||||
/// </summary>
|
||||
public static readonly Guid MediaTypeGuid = new Guid(MediaType);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Member object.
|
||||
/// </summary>
|
||||
@@ -114,11 +69,6 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public const string MemberType = "9B5416FB-E72F-45A9-A07B-5A9A2709CE43";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Member Type object.
|
||||
/// </summary>
|
||||
public static readonly Guid MemberTypeGuid = new Guid(MemberType);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Stylesheet object.
|
||||
/// </summary>
|
||||
@@ -142,8 +92,6 @@ namespace Umbraco.Core
|
||||
/// Guid for a Lock object.
|
||||
/// </summary>
|
||||
public const string LockObject = "87A9F1FF-B1E4-4A25-BABB-465A4A47EC41";
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -158,11 +158,6 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public const string IntegerAlias = "Umbraco.Integer";
|
||||
|
||||
/// <summary>
|
||||
/// Alias for the Decimal datatype.
|
||||
/// </summary>
|
||||
public const string DecimalAlias = "Umbraco.Decimal";
|
||||
|
||||
/// <summary>
|
||||
/// Alias for the listview datatype.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static partial class Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the identifiers for property-type groups conventions that are used within the Umbraco core.
|
||||
/// </summary>
|
||||
public static class PropertyTypeGroups
|
||||
{
|
||||
/// <summary>
|
||||
/// Guid for a Image PropertyTypeGroup object.
|
||||
/// </summary>
|
||||
public const string Image = "79ED4D07-254A-42CF-8FA9-EBE1C116A596";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a File PropertyTypeGroup object.
|
||||
/// </summary>
|
||||
public const string File = "50899F9C-023A-4466-B623-ABA9049885FE";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Image PropertyTypeGroup object.
|
||||
/// </summary>
|
||||
public const string Contents = "79995FA2-63EE-453C-A29B-2E66F324CDBE";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Image PropertyTypeGroup object.
|
||||
/// </summary>
|
||||
public const string Membership = "0756729D-D665-46E3-B84A-37ACEAA614F8";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,12 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public static class Web
|
||||
{
|
||||
public const string UmbracoContextDataToken = "umbraco-context";
|
||||
public const string UmbracoDataToken = "umbraco";
|
||||
public const string PublishedDocumentRequestDataToken = "umbraco-doc-request";
|
||||
public const string CustomRouteDataToken = "umbraco-custom-route";
|
||||
public const string UmbracoRouteDefinitionDataToken = "umbraco-route-def";
|
||||
|
||||
/// <summary>
|
||||
/// The preview cookie name
|
||||
/// </summary>
|
||||
|
||||
@@ -136,7 +136,10 @@ namespace Umbraco.Core
|
||||
{
|
||||
try
|
||||
{
|
||||
x.OnApplicationInitialized(UmbracoApplication, ApplicationContext);
|
||||
using (ProfilingLogger.DebugDuration<CoreBootManager>(string.Format("Executing {0} in ApplicationInitialized", x.GetType())))
|
||||
{
|
||||
x.OnApplicationInitialized(UmbracoApplication, ApplicationContext);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -299,7 +302,10 @@ namespace Umbraco.Core
|
||||
{
|
||||
try
|
||||
{
|
||||
x.OnApplicationStarting(UmbracoApplication, ApplicationContext);
|
||||
using (ProfilingLogger.DebugDuration<CoreBootManager>(string.Format("Executing {0} in ApplicationStarting", x.GetType())))
|
||||
{
|
||||
x.OnApplicationStarting(UmbracoApplication, ApplicationContext);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -350,7 +356,10 @@ namespace Umbraco.Core
|
||||
{
|
||||
try
|
||||
{
|
||||
x.OnApplicationStarted(UmbracoApplication, ApplicationContext);
|
||||
using (ProfilingLogger.DebugDuration<CoreBootManager>(string.Format("Executing {0} in ApplicationStarted", x.GetType())))
|
||||
{
|
||||
x.OnApplicationStarted(UmbracoApplication, ApplicationContext);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -437,7 +446,6 @@ namespace Umbraco.Core
|
||||
new Lazy<Type>(() => typeof (DelimitedManifestValueValidator)),
|
||||
new Lazy<Type>(() => typeof (EmailValidator)),
|
||||
new Lazy<Type>(() => typeof (IntegerValidator)),
|
||||
new Lazy<Type>(() => typeof (DecimalValidator)),
|
||||
});
|
||||
|
||||
//by default we'll use the db server registrar unless the developer has the legacy
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Web;
|
||||
@@ -12,6 +13,12 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public class DisposableTimer : DisposableObject
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly LogType? _logType;
|
||||
private readonly IProfiler _profiler;
|
||||
private readonly Type _loggerType;
|
||||
private readonly string _endMessage;
|
||||
private readonly IDisposable _profilerStep;
|
||||
private readonly Stopwatch _stopwatch = Stopwatch.StartNew();
|
||||
private readonly Action<long> _callback;
|
||||
|
||||
@@ -25,25 +32,12 @@ namespace Umbraco.Core
|
||||
if (logger == null) throw new ArgumentNullException("logger");
|
||||
if (loggerType == null) throw new ArgumentNullException("loggerType");
|
||||
|
||||
_callback = x =>
|
||||
{
|
||||
if (profiler != null)
|
||||
{
|
||||
profiler.DisposeIfDisposable();
|
||||
}
|
||||
switch (logType)
|
||||
{
|
||||
case LogType.Debug:
|
||||
logger.Debug(loggerType, () => endMessage + " (took " + x + "ms)");
|
||||
break;
|
||||
case LogType.Info:
|
||||
logger.Info(loggerType, () => endMessage + " (took " + x + "ms)");
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("logType");
|
||||
}
|
||||
|
||||
};
|
||||
_logger = logger;
|
||||
_logType = logType;
|
||||
_profiler = profiler;
|
||||
_loggerType = loggerType;
|
||||
_endMessage = endMessage;
|
||||
|
||||
switch (logType)
|
||||
{
|
||||
case LogType.Debug:
|
||||
@@ -58,7 +52,7 @@ namespace Umbraco.Core
|
||||
|
||||
if (profiler != null)
|
||||
{
|
||||
profiler.Step(loggerType, startMessage);
|
||||
_profilerStep = profiler.Step(loggerType, startMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,7 +217,36 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
protected override void DisposeResources()
|
||||
{
|
||||
_callback.Invoke(Stopwatch.ElapsedMilliseconds);
|
||||
if (_profiler != null)
|
||||
{
|
||||
_profiler.DisposeIfDisposable();
|
||||
}
|
||||
|
||||
if (_profilerStep != null)
|
||||
{
|
||||
_profilerStep.Dispose();
|
||||
}
|
||||
|
||||
if (_logType.HasValue && _endMessage.IsNullOrWhiteSpace() == false && _loggerType != null && _logger != null)
|
||||
{
|
||||
switch (_logType)
|
||||
{
|
||||
case LogType.Debug:
|
||||
_logger.Debug(_loggerType, () => _endMessage + " (took " + Stopwatch.ElapsedMilliseconds + "ms)");
|
||||
break;
|
||||
case LogType.Info:
|
||||
_logger.Info(_loggerType, () => _endMessage + " (took " + Stopwatch.ElapsedMilliseconds + "ms)");
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("logType");
|
||||
}
|
||||
}
|
||||
|
||||
if (_callback != null)
|
||||
{
|
||||
_callback.Invoke(Stopwatch.ElapsedMilliseconds);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Exceptions
|
||||
{
|
||||
internal class DataOperationException<T> : Exception
|
||||
{
|
||||
public T Operation { get; private set; }
|
||||
|
||||
public DataOperationException(T operation, string message)
|
||||
:base(message)
|
||||
{
|
||||
Operation = operation;
|
||||
}
|
||||
|
||||
public DataOperationException(T operation)
|
||||
: base("Data operation exception: " + operation)
|
||||
{
|
||||
Operation = operation;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,41 +3,22 @@
|
||||
namespace Umbraco.Core.Exceptions
|
||||
{
|
||||
public class InvalidCompositionException : Exception
|
||||
{
|
||||
public InvalidCompositionException(string contentTypeAlias, string addedCompositionAlias, string[] propertyTypeAliass)
|
||||
{
|
||||
ContentTypeAlias = contentTypeAlias;
|
||||
AddedCompositionAlias = addedCompositionAlias;
|
||||
PropertyTypeAliases = propertyTypeAliass;
|
||||
}
|
||||
{
|
||||
public string ContentTypeAlias { get; set; }
|
||||
|
||||
public InvalidCompositionException(string contentTypeAlias, string[] propertyTypeAliass)
|
||||
{
|
||||
ContentTypeAlias = contentTypeAlias;
|
||||
PropertyTypeAliases = propertyTypeAliass;
|
||||
}
|
||||
public string AddedCompositionAlias { get; set; }
|
||||
|
||||
public string ContentTypeAlias { get; private set; }
|
||||
|
||||
public string AddedCompositionAlias { get; private set; }
|
||||
|
||||
public string[] PropertyTypeAliases { get; private set; }
|
||||
public string PropertyTypeAlias { get; set; }
|
||||
|
||||
public override string Message
|
||||
{
|
||||
get
|
||||
{
|
||||
return AddedCompositionAlias.IsNullOrWhiteSpace()
|
||||
? string.Format(
|
||||
"ContentType with alias '{0}' has an invalid composition " +
|
||||
"and there was a conflict on the following PropertyTypes: '{1}'. " +
|
||||
return string.Format(
|
||||
"InvalidCompositionException - ContentType with alias '{0}' was added as a Compsition to ContentType with alias '{1}', " +
|
||||
"but there was a conflict on the PropertyType alias '{2}'. " +
|
||||
"PropertyTypes must have a unique alias across all Compositions in order to compose a valid ContentType Composition.",
|
||||
ContentTypeAlias, string.Join(", ", PropertyTypeAliases))
|
||||
: string.Format(
|
||||
"ContentType with alias '{0}' was added as a Composition to ContentType with alias '{1}', " +
|
||||
"but there was a conflict on the following PropertyTypes: '{2}'. " +
|
||||
"PropertyTypes must have a unique alias across all Compositions in order to compose a valid ContentType Composition.",
|
||||
AddedCompositionAlias, ContentTypeAlias, string.Join(", ", PropertyTypeAliases));
|
||||
AddedCompositionAlias, ContentTypeAlias, PropertyTypeAlias);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace Umbraco.Core.IO
|
||||
return viewContent;
|
||||
}
|
||||
|
||||
internal static string GetDefaultFileContent(string layoutPageAlias = null, string modelClassName = null)
|
||||
internal static string GetDefaultFileContent(string layoutPageAlias = null)
|
||||
{
|
||||
var design = @"@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
|
||||
@{
|
||||
@@ -76,10 +76,6 @@ namespace Umbraco.Core.IO
|
||||
if (layoutPageAlias.IsNullOrWhiteSpace() == false)
|
||||
design = design.Replace("null", string.Format("\"{0}.cshtml\"", layoutPageAlias));
|
||||
|
||||
if (modelClassName.IsNullOrWhiteSpace() == false)
|
||||
design = design.Replace(".UmbracoTemplatePage", string.Format(".UmbracoTemplatePage<{0}>", modelClassName));
|
||||
|
||||
|
||||
return design;
|
||||
}
|
||||
|
||||
|
||||
@@ -340,6 +340,18 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to call when Entity is being saved
|
||||
/// </summary>
|
||||
/// <remarks>Created date is set and a Unique key is assigned</remarks>
|
||||
internal override void AddingEntity()
|
||||
{
|
||||
base.AddingEntity();
|
||||
|
||||
if(Key == Guid.Empty)
|
||||
Key = Guid.NewGuid();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to call when Entity is being updated
|
||||
/// </summary>
|
||||
|
||||
@@ -53,6 +53,9 @@ namespace Umbraco.Core.Models
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the alias of the default Template.
|
||||
/// TODO: This should be ignored from cloning!!!!!!!!!!!!!!
|
||||
/// - but to do that we have to implement callback hacks, this needs to be fixed in v8,
|
||||
/// we should not store direct entity
|
||||
/// </summary>
|
||||
[IgnoreDataMember]
|
||||
public ITemplate DefaultTemplate
|
||||
@@ -79,6 +82,9 @@ namespace Umbraco.Core.Models
|
||||
|
||||
/// <summary>
|
||||
/// Gets or Sets a list of Templates which are allowed for the ContentType
|
||||
/// TODO: This should be ignored from cloning!!!!!!!!!!!!!!
|
||||
/// - but to do that we have to implement callback hacks, this needs to be fixed in v8,
|
||||
/// we should not store direct entity
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public IEnumerable<ITemplate> AllowedTemplates
|
||||
@@ -137,6 +143,19 @@ namespace Umbraco.Core.Models
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to call when Entity is being saved
|
||||
/// </summary>
|
||||
/// <remarks>Created date is set and a Unique key is assigned</remarks>
|
||||
internal override void AddingEntity()
|
||||
{
|
||||
base.AddingEntity();
|
||||
|
||||
if (Key == Guid.Empty)
|
||||
Key = Guid.NewGuid();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates a deep clone of the current entity with its identity/alias and it's property identities reset
|
||||
/// </summary>
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Used when determining available compositions for a given content type
|
||||
/// </summary>
|
||||
internal class ContentTypeAvailableCompositionsResult
|
||||
{
|
||||
public ContentTypeAvailableCompositionsResult(IContentTypeComposition composition, bool allowed)
|
||||
{
|
||||
Composition = composition;
|
||||
Allowed = allowed;
|
||||
}
|
||||
|
||||
public IContentTypeComposition Composition { get; private set; }
|
||||
public bool Allowed { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Used when determining available compositions for a given content type
|
||||
/// </summary>
|
||||
internal class ContentTypeAvailableCompositionsResults
|
||||
{
|
||||
public ContentTypeAvailableCompositionsResults()
|
||||
{
|
||||
Ancestors = Enumerable.Empty<IContentTypeComposition>();
|
||||
Results = Enumerable.Empty<ContentTypeAvailableCompositionsResult>();
|
||||
}
|
||||
|
||||
public ContentTypeAvailableCompositionsResults(IEnumerable<IContentTypeComposition> ancestors, IEnumerable<ContentTypeAvailableCompositionsResult> results)
|
||||
{
|
||||
Ancestors = ancestors;
|
||||
Results = results;
|
||||
}
|
||||
|
||||
public IEnumerable<IContentTypeComposition> Ancestors { get; private set; }
|
||||
public IEnumerable<ContentTypeAvailableCompositionsResult> Results { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ namespace Umbraco.Core.Models
|
||||
private string _alias;
|
||||
private string _description;
|
||||
private int _sortOrder;
|
||||
private string _icon = "icon-folder";
|
||||
private string _icon = "folder.png";
|
||||
private string _thumbnail = "folder.png";
|
||||
private int _creatorId;
|
||||
private bool _allowedAsRoot;
|
||||
@@ -373,35 +373,43 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
_propertyGroups = value;
|
||||
_propertyGroups.CollectionChanged += PropertyGroupsChanged;
|
||||
PropertyGroupsChanged(_propertyGroups, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all property types, across all property groups.
|
||||
/// List of PropertyTypes available on this ContentType.
|
||||
/// This list aggregates PropertyTypes across the PropertyGroups.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
///
|
||||
/// The setter is used purely to set the property types that DO NOT belong to a group!
|
||||
///
|
||||
/// Marked as DoNotClone because the result of this property is not the natural result of the data, it is
|
||||
/// a union of data so when auto-cloning if the setter is used it will be setting the unnatural result of the
|
||||
/// data. We manually clone this instead.
|
||||
/// </remarks>
|
||||
[IgnoreDataMember]
|
||||
[DoNotClone]
|
||||
public virtual IEnumerable<PropertyType> PropertyTypes
|
||||
{
|
||||
get
|
||||
{
|
||||
return _propertyTypes.Union(PropertyGroups.SelectMany(x => x.PropertyTypes));
|
||||
var types = _propertyTypes.Union(PropertyGroups.SelectMany(x => x.PropertyTypes));
|
||||
return types;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
_propertyTypes = new PropertyTypeCollection(value);
|
||||
_propertyTypes.CollectionChanged += PropertyTypesChanged;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the property types that are not in a group.
|
||||
/// Returns the property type collection containing types that are non-groups - used for tests
|
||||
/// </summary>
|
||||
public IEnumerable<PropertyType> NoGroupPropertyTypes
|
||||
internal IEnumerable<PropertyType> NonGroupedPropertyTypes
|
||||
{
|
||||
get { return _propertyTypes; }
|
||||
set
|
||||
{
|
||||
_propertyTypes = new PropertyTypeCollection(value);
|
||||
_propertyTypes.CollectionChanged += PropertyTypesChanged;
|
||||
PropertyTypesChanged(_propertyTypes, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -452,6 +460,11 @@ namespace Umbraco.Core.Models
|
||||
/// <returns>Returns <c>True</c> if PropertyType was added, otherwise <c>False</c></returns>
|
||||
public bool AddPropertyType(PropertyType propertyType)
|
||||
{
|
||||
if (propertyType.HasIdentity == false)
|
||||
{
|
||||
propertyType.Key = Guid.NewGuid();
|
||||
}
|
||||
|
||||
if (PropertyTypeExists(propertyType.Alias) == false)
|
||||
{
|
||||
_propertyTypes.Add(propertyType);
|
||||
@@ -467,37 +480,24 @@ namespace Umbraco.Core.Models
|
||||
/// <param name="propertyTypeAlias">Alias of the PropertyType to move</param>
|
||||
/// <param name="propertyGroupName">Name of the PropertyGroup to move the PropertyType to</param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>If <paramref name="propertyGroupName"/> is null then the property is moved back to
|
||||
/// "generic properties" ie does not have a tab anymore.</remarks>
|
||||
public bool MovePropertyType(string propertyTypeAlias, string propertyGroupName)
|
||||
{
|
||||
// note: not dealing with alias casing at all here?
|
||||
if (PropertyTypes.Any(x => x.Alias == propertyTypeAlias) == false || PropertyGroups.Any(x => x.Name == propertyGroupName) == false)
|
||||
return false;
|
||||
|
||||
// get property, ensure it exists
|
||||
var propertyType = PropertyTypes.FirstOrDefault(x => x.Alias == propertyTypeAlias);
|
||||
if (propertyType == null) return false;
|
||||
|
||||
// get new group, if required, and ensure it exists
|
||||
var newPropertyGroup = propertyGroupName == null
|
||||
? null
|
||||
: PropertyGroups.FirstOrDefault(x => x.Name == propertyGroupName);
|
||||
if (propertyGroupName != null && newPropertyGroup == null) return false;
|
||||
|
||||
// get old group
|
||||
var oldPropertyGroup = PropertyGroups.FirstOrDefault(x =>
|
||||
x.PropertyTypes.Any(y => y.Alias == propertyTypeAlias));
|
||||
|
||||
// reset PropertyGroupId, which will be re-evaluated when the content type
|
||||
// is saved - what is important is group.PropertyTypes - see code in
|
||||
// ContentTypeBaseRepository.PersistUpdatedBaseContentType
|
||||
propertyType.PropertyGroupId = new Lazy<int>(() => default(int));
|
||||
propertyType.ResetDirtyProperties(); // PropertyGroupId must not be dirty
|
||||
|
||||
// remove from old group, if any - add to new group, if any
|
||||
if (oldPropertyGroup != null)
|
||||
var propertyType = PropertyTypes.First(x => x.Alias == propertyTypeAlias);
|
||||
//The PropertyType already belongs to a PropertyGroup, so we have to remove the PropertyType from that group
|
||||
if (PropertyGroups.Any(x => x.PropertyTypes.Any(y => y.Alias == propertyTypeAlias)))
|
||||
{
|
||||
var oldPropertyGroup = PropertyGroups.First(x => x.PropertyTypes.Any(y => y.Alias == propertyTypeAlias));
|
||||
oldPropertyGroup.PropertyTypes.RemoveItem(propertyTypeAlias);
|
||||
if (newPropertyGroup != null)
|
||||
newPropertyGroup.PropertyTypes.Add(propertyType);
|
||||
}
|
||||
|
||||
propertyType.PropertyGroupId = new Lazy<int>(() => default(int));
|
||||
propertyType.ResetDirtyProperties();
|
||||
|
||||
var propertyGroup = PropertyGroups.First(x => x.Name == propertyGroupName);
|
||||
propertyGroup.PropertyTypes.Add(propertyType);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@ namespace Umbraco.Core.Models
|
||||
|
||||
protected ContentTypeCompositionBase(IContentTypeComposition parent)
|
||||
: this(parent, null)
|
||||
{
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
protected ContentTypeCompositionBase(IContentTypeComposition parent, string alias)
|
||||
: base(parent, alias)
|
||||
@@ -37,21 +37,16 @@ namespace Umbraco.Core.Models
|
||||
x => x.ContentTypeComposition);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the content types that compose this content type.
|
||||
/// List of ContentTypes that make up a composition of PropertyGroups and PropertyTypes for the current ContentType
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public IEnumerable<IContentTypeComposition> ContentTypeComposition
|
||||
{
|
||||
get { return _contentTypeComposition; }
|
||||
set
|
||||
{
|
||||
_contentTypeComposition = value.ToList();
|
||||
OnPropertyChanged(ContentTypeCompositionSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the property groups for the entire composition.
|
||||
/// Returns a list of <see cref="PropertyGroup"/> objects from the composition
|
||||
/// </summary>
|
||||
[IgnoreDataMember]
|
||||
public IEnumerable<PropertyGroup> CompositionPropertyGroups
|
||||
@@ -64,7 +59,7 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the property types for the entire composition.
|
||||
/// Returns a list of <see cref="PropertyType"/> objects from the composition
|
||||
/// </summary>
|
||||
[IgnoreDataMember]
|
||||
public IEnumerable<PropertyType> CompositionPropertyTypes
|
||||
@@ -77,10 +72,10 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a content type to the composition.
|
||||
/// Adds a new ContentType to the list of composite ContentTypes
|
||||
/// </summary>
|
||||
/// <param name="contentType">The content type to add.</param>
|
||||
/// <returns>True if the content type was added, otherwise false.</returns>
|
||||
/// <param name="contentType"><see cref="ContentType"/> to add</param>
|
||||
/// <returns>True if ContentType was added, otherwise returns False</returns>
|
||||
public bool AddContentType(IContentTypeComposition contentType)
|
||||
{
|
||||
if (contentType.ContentTypeComposition.Any(x => x.CompositionAliases().Any(ContentTypeCompositionExists)))
|
||||
@@ -99,7 +94,13 @@ namespace Umbraco.Core.Models
|
||||
.Select(p => p.Alias)).ToList();
|
||||
|
||||
if (conflictingPropertyTypeAliases.Any())
|
||||
throw new InvalidCompositionException(Alias, contentType.Alias, conflictingPropertyTypeAliases.ToArray());
|
||||
throw new InvalidCompositionException
|
||||
{
|
||||
AddedCompositionAlias = contentType.Alias,
|
||||
ContentTypeAlias = Alias,
|
||||
PropertyTypeAlias =
|
||||
string.Join(", ", conflictingPropertyTypeAliases)
|
||||
};
|
||||
|
||||
_contentTypeComposition.Add(contentType);
|
||||
OnPropertyChanged(ContentTypeCompositionSelector);
|
||||
@@ -109,10 +110,10 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a content type with a specified alias from the composition.
|
||||
/// Removes a ContentType with the supplied alias from the the list of composite ContentTypes
|
||||
/// </summary>
|
||||
/// <param name="alias">The alias of the content type to remove.</param>
|
||||
/// <returns>True if the content type was removed, otherwise false.</returns>
|
||||
/// <param name="alias">Alias of a <see cref="ContentType"/></param>
|
||||
/// <returns>True if ContentType was removed, otherwise returns False</returns>
|
||||
public bool RemoveContentType(string alias)
|
||||
{
|
||||
if (ContentTypeCompositionExists(alias))
|
||||
@@ -122,10 +123,10 @@ namespace Umbraco.Core.Models
|
||||
return false;
|
||||
|
||||
RemovedContentTypeKeyTracker.Add(contentTypeComposition.Id);
|
||||
|
||||
|
||||
//If the ContentType we are removing has Compositions of its own these needs to be removed as well
|
||||
var compositionIdsToRemove = contentTypeComposition.CompositionIds().ToList();
|
||||
if (compositionIdsToRemove.Any())
|
||||
if(compositionIdsToRemove.Any())
|
||||
RemovedContentTypeKeyTracker.AddRange(compositionIdsToRemove);
|
||||
|
||||
OnPropertyChanged(ContentTypeCompositionSelector);
|
||||
@@ -162,44 +163,31 @@ namespace Umbraco.Core.Models
|
||||
|
||||
/// <summary>
|
||||
/// Adds a PropertyGroup.
|
||||
/// This method will also check if a group already exists with the same name and link it to the parent.
|
||||
/// </summary>
|
||||
/// <param name="groupName">Name of the PropertyGroup to add</param>
|
||||
/// <returns>Returns <c>True</c> if a PropertyGroup with the passed in name was added, otherwise <c>False</c></returns>
|
||||
public override bool AddPropertyGroup(string groupName)
|
||||
{
|
||||
return AddAndReturnPropertyGroup(groupName) != null;
|
||||
}
|
||||
if (PropertyGroups.Any(x => x.Name == groupName))
|
||||
return false;
|
||||
|
||||
private PropertyGroup AddAndReturnPropertyGroup(string name)
|
||||
{
|
||||
// ensure we don't have it already
|
||||
if (PropertyGroups.Any(x => x.Name == name))
|
||||
return null;
|
||||
var propertyGroup = new PropertyGroup {Name = groupName, SortOrder = 0};
|
||||
|
||||
// create the new group
|
||||
var group = new PropertyGroup { Name = name, SortOrder = 0 };
|
||||
|
||||
// check if it is inherited - there might be more than 1 but we want the 1st, to
|
||||
// reuse its sort order - if there are more than 1 and they have different sort
|
||||
// orders... there isn't much we can do anyways
|
||||
var inheritGroup = CompositionPropertyGroups.FirstOrDefault(x => x.Name == name);
|
||||
if (inheritGroup == null)
|
||||
if (CompositionPropertyGroups.Any(x => x.Name == groupName))
|
||||
{
|
||||
// no, just local, set sort order
|
||||
var lastGroup = PropertyGroups.LastOrDefault();
|
||||
if (lastGroup != null)
|
||||
group.SortOrder = lastGroup.SortOrder + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// yes, inherited, re-use sort order
|
||||
group.SortOrder = inheritGroup.SortOrder;
|
||||
var firstGroup = CompositionPropertyGroups.First(x => x.Name == groupName && x.ParentId.HasValue == false);
|
||||
propertyGroup.SetLazyParentId(new Lazy<int?>(() => firstGroup.Id));
|
||||
}
|
||||
|
||||
// add
|
||||
PropertyGroups.Add(group);
|
||||
if (PropertyGroups.Any())
|
||||
{
|
||||
var last = PropertyGroups.Last();
|
||||
propertyGroup.SortOrder = last.SortOrder + 1;
|
||||
}
|
||||
|
||||
return group;
|
||||
PropertyGroups.Add(propertyGroup);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -210,22 +198,39 @@ namespace Umbraco.Core.Models
|
||||
/// <returns>Returns <c>True</c> if PropertyType was added, otherwise <c>False</c></returns>
|
||||
public override bool AddPropertyType(PropertyType propertyType, string propertyGroupName)
|
||||
{
|
||||
// ensure no duplicate alias - over all composition properties
|
||||
if (PropertyTypeExists(propertyType.Alias))
|
||||
return false;
|
||||
if (propertyType.HasIdentity == false)
|
||||
{
|
||||
propertyType.Key = Guid.NewGuid();
|
||||
}
|
||||
|
||||
// get and ensure a group local to this content type
|
||||
var group = PropertyGroups.Contains(propertyGroupName)
|
||||
? PropertyGroups[propertyGroupName]
|
||||
: AddAndReturnPropertyGroup(propertyGroupName);
|
||||
if (group == null)
|
||||
return false;
|
||||
if (PropertyTypeExists(propertyType.Alias) == false)
|
||||
{
|
||||
if (PropertyGroups.Contains(propertyGroupName))
|
||||
{
|
||||
propertyType.PropertyGroupId = new Lazy<int>(() => PropertyGroups[propertyGroupName].Id);
|
||||
PropertyGroups[propertyGroupName].PropertyTypes.Add(propertyType);
|
||||
}
|
||||
else
|
||||
{
|
||||
//If the PropertyGroup doesn't already exist we create a new one
|
||||
var propertyTypes = new List<PropertyType> { propertyType };
|
||||
var propertyGroup = new PropertyGroup(new PropertyTypeCollection(propertyTypes)) { Name = propertyGroupName, SortOrder = 1 };
|
||||
//and check if its an inherited PropertyGroup, which exists in the composition
|
||||
if (CompositionPropertyGroups.Any(x => x.Name == propertyGroupName))
|
||||
{
|
||||
var parentPropertyGroup = CompositionPropertyGroups.First(x => x.Name == propertyGroupName && x.ParentId.HasValue == false);
|
||||
propertyGroup.SortOrder = parentPropertyGroup.SortOrder;
|
||||
//propertyGroup.ParentId = parentPropertyGroup.Id;
|
||||
propertyGroup.SetLazyParentId(new Lazy<int?>(() => parentPropertyGroup.Id));
|
||||
}
|
||||
|
||||
// add property to group
|
||||
propertyType.PropertyGroupId = new Lazy<int>(() => group.Id);
|
||||
group.PropertyTypes.Add(propertyType);
|
||||
PropertyGroups.Add(propertyGroup);
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -21,8 +21,6 @@ namespace Umbraco.Core.Models
|
||||
[EnumMember]
|
||||
Integer,
|
||||
[EnumMember]
|
||||
Date,
|
||||
[EnumMember]
|
||||
Decimal
|
||||
Date
|
||||
}
|
||||
}
|
||||
@@ -49,6 +49,8 @@ namespace Umbraco.Core.Models
|
||||
_additionalData = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
[Obsolete("Don't use this, parentId is always -1 for data types")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public DataTypeDefinition(int parentId, string propertyEditorAlias)
|
||||
{
|
||||
_parentId = parentId;
|
||||
@@ -265,5 +267,13 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get { return _additionalData; }
|
||||
}
|
||||
|
||||
internal override void AddingEntity()
|
||||
{
|
||||
base.AddingEntity();
|
||||
|
||||
if(Key == default(Guid))
|
||||
Key = Guid.NewGuid();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,10 +9,30 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
public static class DeepCloneHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Stores the metadata for the properties for a given type so we know how to create them
|
||||
/// </summary>
|
||||
private struct ClonePropertyInfo
|
||||
{
|
||||
public ClonePropertyInfo(PropertyInfo propertyInfo) : this()
|
||||
{
|
||||
if (propertyInfo == null) throw new ArgumentNullException("propertyInfo");
|
||||
PropertyInfo = propertyInfo;
|
||||
}
|
||||
|
||||
public PropertyInfo PropertyInfo { get; private set; }
|
||||
public bool IsDeepCloneable { get; set; }
|
||||
public Type GenericListType { get; set; }
|
||||
public bool IsList
|
||||
{
|
||||
get { return GenericListType != null; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to avoid constant reflection (perf)
|
||||
/// </summary>
|
||||
private static readonly ConcurrentDictionary<Type, PropertyInfo[]> PropCache = new ConcurrentDictionary<Type, PropertyInfo[]>();
|
||||
private static readonly ConcurrentDictionary<Type, ClonePropertyInfo[]> PropCache = new ConcurrentDictionary<Type, ClonePropertyInfo[]>();
|
||||
|
||||
/// <summary>
|
||||
/// Used to deep clone any reference properties on the object (should be done after a MemberwiseClone for which the outcome is 'output')
|
||||
@@ -30,81 +50,99 @@ namespace Umbraco.Core.Models
|
||||
throw new InvalidOperationException("Both the input and output types must be the same");
|
||||
}
|
||||
|
||||
//get the property metadata from cache so we only have to figure this out once per type
|
||||
var refProperties = PropCache.GetOrAdd(inputType, type =>
|
||||
inputType.GetProperties()
|
||||
.Where(x =>
|
||||
//is not attributed with the ignore clone attribute
|
||||
x.GetCustomAttribute<DoNotCloneAttribute>() == null
|
||||
.Select<PropertyInfo, ClonePropertyInfo?>(propertyInfo =>
|
||||
{
|
||||
if (
|
||||
//is not attributed with the ignore clone attribute
|
||||
propertyInfo.GetCustomAttribute<DoNotCloneAttribute>() != null
|
||||
//reference type but not string
|
||||
&& x.PropertyType.IsValueType == false && x.PropertyType != typeof (string)
|
||||
|| propertyInfo.PropertyType.IsValueType || propertyInfo.PropertyType == typeof (string)
|
||||
//settable
|
||||
&& x.CanWrite
|
||||
|| propertyInfo.CanWrite == false
|
||||
//non-indexed
|
||||
&& x.GetIndexParameters().Any() == false)
|
||||
|| propertyInfo.GetIndexParameters().Any())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
if (TypeHelper.IsTypeAssignableFrom<IDeepCloneable>(propertyInfo.PropertyType))
|
||||
{
|
||||
return new ClonePropertyInfo(propertyInfo) { IsDeepCloneable = true };
|
||||
}
|
||||
|
||||
if (TypeHelper.IsTypeAssignableFrom<IEnumerable>(propertyInfo.PropertyType)
|
||||
&& TypeHelper.IsTypeAssignableFrom<string>(propertyInfo.PropertyType) == false)
|
||||
{
|
||||
if (propertyInfo.PropertyType.IsGenericType
|
||||
&& (propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(IEnumerable<>)
|
||||
|| propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(ICollection<>)
|
||||
|| propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(IList<>)))
|
||||
{
|
||||
//if it is a IEnumerable<>, IList<T> or ICollection<> we'll use a List<>
|
||||
var genericType = typeof(List<>).MakeGenericType(propertyInfo.PropertyType.GetGenericArguments());
|
||||
return new ClonePropertyInfo(propertyInfo) { GenericListType = genericType };
|
||||
}
|
||||
if (propertyInfo.PropertyType.IsArray
|
||||
|| (propertyInfo.PropertyType.IsInterface && propertyInfo.PropertyType.IsGenericType == false))
|
||||
{
|
||||
//if its an array, we'll create a list to work with first and then convert to array later
|
||||
//otherwise if its just a regular derivitave of IEnumerable, we can use a list too
|
||||
return new ClonePropertyInfo(propertyInfo) { GenericListType = typeof(List<object>) };
|
||||
}
|
||||
//skip instead of trying to create instance of abstract or interface
|
||||
if (propertyInfo.PropertyType.IsAbstract || propertyInfo.PropertyType.IsInterface)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
//its a custom IEnumerable, we'll try to create it
|
||||
try
|
||||
{
|
||||
var custom = Activator.CreateInstance(propertyInfo.PropertyType);
|
||||
//if it's an IList we can work with it, otherwise we cannot
|
||||
var newList = custom as IList;
|
||||
if (newList == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new ClonePropertyInfo(propertyInfo) {GenericListType = propertyInfo.PropertyType};
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//could not create this type so we'll skip it
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return new ClonePropertyInfo(propertyInfo);
|
||||
})
|
||||
.Where(x => x.HasValue)
|
||||
.Select(x => x.Value)
|
||||
.ToArray());
|
||||
|
||||
foreach (var propertyInfo in refProperties)
|
||||
foreach (var clonePropertyInfo in refProperties)
|
||||
{
|
||||
if (TypeHelper.IsTypeAssignableFrom<IDeepCloneable>(propertyInfo.PropertyType))
|
||||
if (clonePropertyInfo.IsDeepCloneable)
|
||||
{
|
||||
//this ref property is also deep cloneable so clone it
|
||||
var result = (IDeepCloneable)propertyInfo.GetValue(input, null);
|
||||
var result = (IDeepCloneable)clonePropertyInfo.PropertyInfo.GetValue(input, null);
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
//set the cloned value to the property
|
||||
propertyInfo.SetValue(output, result.DeepClone(), null);
|
||||
clonePropertyInfo.PropertyInfo.SetValue(output, result.DeepClone(), null);
|
||||
}
|
||||
}
|
||||
else if (TypeHelper.IsTypeAssignableFrom<IEnumerable>(propertyInfo.PropertyType)
|
||||
&& TypeHelper.IsTypeAssignableFrom<string>(propertyInfo.PropertyType) == false)
|
||||
else if (clonePropertyInfo.IsList)
|
||||
{
|
||||
IList newList;
|
||||
if (propertyInfo.PropertyType.IsGenericType
|
||||
&& (propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(IEnumerable<>)
|
||||
|| propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(ICollection<>)
|
||||
|| propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(IList<>)))
|
||||
{
|
||||
//if it is a IEnumerable<>, IList<T> or ICollection<> we'll use a List<>
|
||||
var genericType = typeof(List<>).MakeGenericType(propertyInfo.PropertyType.GetGenericArguments());
|
||||
newList = (IList)Activator.CreateInstance(genericType);
|
||||
}
|
||||
else if (propertyInfo.PropertyType.IsArray
|
||||
|| (propertyInfo.PropertyType.IsInterface && propertyInfo.PropertyType.IsGenericType == false))
|
||||
{
|
||||
//if its an array, we'll create a list to work with first and then convert to array later
|
||||
//otherwise if its just a regular derivitave of IEnumerable, we can use a list too
|
||||
newList = new List<object>();
|
||||
}
|
||||
else
|
||||
{
|
||||
//skip instead of trying to create instance of abstract or interface
|
||||
if (propertyInfo.PropertyType.IsAbstract || propertyInfo.PropertyType.IsInterface)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//its a custom IEnumerable, we'll try to create it
|
||||
try
|
||||
{
|
||||
var custom = Activator.CreateInstance(propertyInfo.PropertyType);
|
||||
//if it's an IList we can work with it, otherwise we cannot
|
||||
newList = custom as IList;
|
||||
if (newList == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//could not create this type so we'll skip it
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
var enumerable = (IEnumerable)propertyInfo.GetValue(input, null);
|
||||
var enumerable = (IEnumerable)clonePropertyInfo.PropertyInfo.GetValue(input, null);
|
||||
if (enumerable == null) continue;
|
||||
|
||||
var newList = (IList)Activator.CreateInstance(clonePropertyInfo.GenericListType);
|
||||
|
||||
var isUsableType = true;
|
||||
|
||||
//now clone each item
|
||||
@@ -136,21 +174,21 @@ namespace Umbraco.Core.Models
|
||||
continue;
|
||||
}
|
||||
|
||||
if (propertyInfo.PropertyType.IsArray)
|
||||
if (clonePropertyInfo.PropertyInfo.PropertyType.IsArray)
|
||||
{
|
||||
//need to convert to array
|
||||
var arr = (object[])Activator.CreateInstance(propertyInfo.PropertyType, newList.Count);
|
||||
var arr = (object[])Activator.CreateInstance(clonePropertyInfo.PropertyInfo.PropertyType, newList.Count);
|
||||
for (int i = 0; i < newList.Count; i++)
|
||||
{
|
||||
arr[i] = newList[i];
|
||||
}
|
||||
//set the cloned collection
|
||||
propertyInfo.SetValue(output, arr, null);
|
||||
clonePropertyInfo.PropertyInfo.SetValue(output, arr, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
//set the cloned collection
|
||||
propertyInfo.SetValue(output, newList, null);
|
||||
clonePropertyInfo.PropertyInfo.SetValue(output, newList, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -98,5 +98,16 @@ namespace Umbraco.Core.Models
|
||||
enumerable => enumerable.GetHashCode()));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to call before inserting a new entity in the db
|
||||
/// </summary>
|
||||
internal override void AddingEntity()
|
||||
{
|
||||
base.AddingEntity();
|
||||
|
||||
Key = Guid.NewGuid();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -62,9 +62,9 @@ namespace Umbraco.Core.Models.EntityBase
|
||||
{
|
||||
get
|
||||
{
|
||||
// if an entity does NOT have a UniqueId yet, assign one now
|
||||
if (_key == Guid.Empty)
|
||||
_key = Guid.NewGuid();
|
||||
return _id.ToGuid();
|
||||
|
||||
return _key;
|
||||
}
|
||||
set
|
||||
@@ -136,7 +136,6 @@ namespace Umbraco.Core.Models.EntityBase
|
||||
{
|
||||
_hasIdentity = false;
|
||||
_id = default(int);
|
||||
_key = Guid.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -243,7 +242,6 @@ namespace Umbraco.Core.Models.EntityBase
|
||||
{
|
||||
//Memberwise clone on Entity will work since it doesn't have any deep elements
|
||||
// for any sub class this will work for standard properties as well that aren't complex object's themselves.
|
||||
var ignored = this.Key; // ensure that 'this' has a key, before cloning
|
||||
var clone = (Entity)MemberwiseClone();
|
||||
//ensure the clone has it's own dictionaries
|
||||
clone.ResetChangeTrackingCollections();
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a folder for organizing entities such as content types and data types.
|
||||
/// </summary>
|
||||
public sealed class EntityContainer : UmbracoEntity
|
||||
{
|
||||
private readonly Guid _containedObjectType;
|
||||
|
||||
private static readonly Dictionary<Guid, Guid> ObjectTypeMap = new Dictionary<Guid, Guid>
|
||||
{
|
||||
{ Constants.ObjectTypes.DataTypeGuid, Constants.ObjectTypes.DataTypeContainerGuid },
|
||||
{ Constants.ObjectTypes.DocumentTypeGuid, Constants.ObjectTypes.DocumentTypeContainerGuid },
|
||||
{ Constants.ObjectTypes.MediaTypeGuid, Constants.ObjectTypes.MediaTypeContainerGuid }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of an <see cref="EntityContainer"/> class.
|
||||
/// </summary>
|
||||
public EntityContainer(Guid containedObjectType)
|
||||
{
|
||||
if (ObjectTypeMap.ContainsKey(containedObjectType) == false)
|
||||
throw new ArgumentException("Not a contained object type.", "containedObjectType");
|
||||
_containedObjectType = containedObjectType;
|
||||
|
||||
ParentId = -1;
|
||||
Path = "-1";
|
||||
Level = 0;
|
||||
SortOrder = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of an <see cref="EntityContainer"/> class.
|
||||
/// </summary>
|
||||
internal EntityContainer(int id, Guid uniqueId, int parentId, string path, int level, int sortOrder, Guid containedObjectType, string name, int userId)
|
||||
: this(containedObjectType)
|
||||
{
|
||||
Id = id;
|
||||
Key = uniqueId;
|
||||
ParentId = parentId;
|
||||
Name = name;
|
||||
Path = path;
|
||||
Level = level;
|
||||
SortOrder = sortOrder;
|
||||
CreatorId = userId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the node object type of the contained objects.
|
||||
/// </summary>
|
||||
public Guid ContainedObjectType
|
||||
{
|
||||
get { return _containedObjectType; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the node object type of the container objects.
|
||||
/// </summary>
|
||||
public Guid ContainerObjectType
|
||||
{
|
||||
get { return ObjectTypeMap[_containedObjectType]; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the container object type corresponding to a contained object type.
|
||||
/// </summary>
|
||||
/// <param name="containedObjectType">The contained object type.</param>
|
||||
/// <returns>The object type of containers containing objects of the contained object type.</returns>
|
||||
public static Guid GetContainerObjectType(Guid containedObjectType)
|
||||
{
|
||||
if (ObjectTypeMap.ContainsKey(containedObjectType) == false)
|
||||
throw new ArgumentException("Not a contained object type.", "containedObjectType");
|
||||
return ObjectTypeMap[containedObjectType];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the contained object type corresponding to a container object type.
|
||||
/// </summary>
|
||||
/// <param name="containerObjectType">The container object type.</param>
|
||||
/// <returns>The object type of objects that containers of the container object type can contain.</returns>
|
||||
public static Guid GetContainedObjectType(Guid containerObjectType)
|
||||
{
|
||||
var contained = ObjectTypeMap.FirstOrDefault(x => x.Value == containerObjectType).Key;
|
||||
if (contained == null)
|
||||
throw new ArgumentException("Not a container object type.", "containerObjectType");
|
||||
return contained;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,15 +54,10 @@ namespace Umbraco.Core.Models
|
||||
PropertyGroupCollection PropertyGroups { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets all property types, across all property groups.
|
||||
/// Gets an enumerable list of Property Types aggregated for all groups
|
||||
/// </summary>
|
||||
IEnumerable<PropertyType> PropertyTypes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the property types that are not in a group.
|
||||
/// </summary>
|
||||
IEnumerable<PropertyType> NoGroupPropertyTypes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Removes a PropertyType from the current ContentType
|
||||
/// </summary>
|
||||
|
||||
@@ -8,17 +8,17 @@ namespace Umbraco.Core.Models
|
||||
public interface IContentTypeComposition : IContentTypeBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the content types that compose this content type.
|
||||
/// Gets a list of ContentTypes that make up a composition of PropertyGroups and PropertyTypes for the current ContentType
|
||||
/// </summary>
|
||||
IEnumerable<IContentTypeComposition> ContentTypeComposition { get; set; }
|
||||
IEnumerable<IContentTypeComposition> ContentTypeComposition { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the property groups for the entire composition.
|
||||
/// Gets a list of <see cref="PropertyGroup"/> objects from the composition
|
||||
/// </summary>
|
||||
IEnumerable<PropertyGroup> CompositionPropertyGroups { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the property types for the entire composition.
|
||||
/// Gets a list of <see cref="PropertyType"/> objects from the composition
|
||||
/// </summary>
|
||||
IEnumerable<PropertyType> CompositionPropertyTypes { get; }
|
||||
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
using AutoMapper;
|
||||
|
||||
namespace Umbraco.Core.Models.Mapping
|
||||
{
|
||||
internal static class MappingExpressionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Ignores all unmapped members by default - Use with caution!
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource"></typeparam>
|
||||
/// <typeparam name="TDest"></typeparam>
|
||||
/// <param name="expression"></param>
|
||||
/// <returns></returns>
|
||||
public static IMappingExpression<TSource, TDest> IgnoreAllUnmapped<TSource, TDest>(this IMappingExpression<TSource, TDest> expression)
|
||||
{
|
||||
expression.ForAllMembers(opt => opt.Ignore());
|
||||
return expression;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -118,5 +118,17 @@ namespace Umbraco.Core.Models
|
||||
//The Media Recycle Bin Id is -21 so we correct that here
|
||||
ParentId = parentId == -20 ? -21 : parentId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to call when Entity is being saved
|
||||
/// </summary>
|
||||
/// <remarks>Created date is set and a Unique key is assigned</remarks>
|
||||
internal override void AddingEntity()
|
||||
{
|
||||
base.AddingEntity();
|
||||
|
||||
if (Key == Guid.Empty)
|
||||
Key = Guid.NewGuid();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,5 +38,26 @@ namespace Umbraco.Core.Models
|
||||
: base(parent, alias)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to call when Entity is being saved
|
||||
/// </summary>
|
||||
/// <remarks>Created date is set and a Unique key is assigned</remarks>
|
||||
internal override void AddingEntity()
|
||||
{
|
||||
base.AddingEntity();
|
||||
|
||||
if (Key == Guid.Empty)
|
||||
Key = Guid.NewGuid();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to call when Entity is being updated
|
||||
/// </summary>
|
||||
/// <remarks>Modified Date is set and a new Version guid is set</remarks>
|
||||
internal override void UpdatingEntity()
|
||||
{
|
||||
base.UpdatingEntity();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -509,8 +509,11 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
base.AddingEntity();
|
||||
|
||||
if (ProviderUserKey == null)
|
||||
if (Key == Guid.Empty)
|
||||
{
|
||||
Key = Guid.NewGuid();
|
||||
ProviderUserKey = Key;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -60,5 +60,17 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
|
||||
public IDictionary<string, object> AdditionalData { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Method to call when Entity is being saved
|
||||
/// </summary>
|
||||
/// <remarks>Created date is set and a Unique key is assigned</remarks>
|
||||
internal override void AddingEntity()
|
||||
{
|
||||
base.AddingEntity();
|
||||
|
||||
if (Key == Guid.Empty)
|
||||
Key = Guid.NewGuid();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -131,5 +131,26 @@ namespace Umbraco.Core.Models
|
||||
MemberTypePropertyTypes.Add(propertyTypeAlias, tuple);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to call when Entity is being saved
|
||||
/// </summary>
|
||||
/// <remarks>Created date is set and a Unique key is assigned</remarks>
|
||||
internal override void AddingEntity()
|
||||
{
|
||||
base.AddingEntity();
|
||||
|
||||
if (Key == Guid.Empty)
|
||||
Key = Guid.NewGuid();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to call when Entity is being updated
|
||||
/// </summary>
|
||||
/// <remarks>Modified Date is set and a new Version guid is set</remarks>
|
||||
internal override void UpdatingEntity()
|
||||
{
|
||||
base.UpdatingEntity();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ namespace Umbraco.Core.Models
|
||||
public class PropertyGroup : Entity, IEquatable<PropertyGroup>
|
||||
{
|
||||
private string _name;
|
||||
private Lazy<int?> _parentId;
|
||||
private int _sortOrder;
|
||||
private PropertyTypeCollection _propertyTypes;
|
||||
|
||||
@@ -30,6 +31,7 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
|
||||
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<PropertyGroup, string>(x => x.Name);
|
||||
private static readonly PropertyInfo ParentIdSelector = ExpressionHelper.GetPropertyInfo<PropertyGroup, int?>(x => x.ParentId);
|
||||
private static readonly PropertyInfo SortOrderSelector = ExpressionHelper.GetPropertyInfo<PropertyGroup, int>(x => x.SortOrder);
|
||||
private readonly static PropertyInfo PropertyTypeCollectionSelector = ExpressionHelper.GetPropertyInfo<PropertyGroup, PropertyTypeCollection>(x => x.PropertyTypes);
|
||||
void PropertyTypesChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
@@ -54,6 +56,29 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Id of the Parent PropertyGroup.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A Parent PropertyGroup corresponds to an inherited PropertyGroup from a composition.
|
||||
/// If a PropertyType is inserted into an inherited group then a new group will be created with an Id reference to the parent.
|
||||
/// </remarks>
|
||||
[DataMember]
|
||||
public int? ParentId
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_parentId == null)
|
||||
return default(int?);
|
||||
return _parentId.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
_parentId = new Lazy<int?>(() => value);
|
||||
OnPropertyChanged(ParentIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Sort Order of the Group
|
||||
/// </summary>
|
||||
@@ -92,6 +117,15 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the ParentId from the lazy integer id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the Parent</param>
|
||||
internal void SetLazyParentId(Lazy<int?> id)
|
||||
{
|
||||
_parentId = id;
|
||||
}
|
||||
|
||||
public bool Equals(PropertyGroup other)
|
||||
{
|
||||
if (base.Equals(other)) return true;
|
||||
|
||||
@@ -9,7 +9,6 @@ using Umbraco.Core.Strings;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Defines the type of a <see cref="Property"/> object
|
||||
/// </summary>
|
||||
@@ -33,8 +32,6 @@ namespace Umbraco.Core.Models
|
||||
|
||||
public PropertyType(IDataTypeDefinition dataTypeDefinition)
|
||||
{
|
||||
if (dataTypeDefinition == null) throw new ArgumentNullException("dataTypeDefinition");
|
||||
|
||||
if(dataTypeDefinition.HasIdentity)
|
||||
_dataTypeDefinitionId = dataTypeDefinition.Id;
|
||||
|
||||
@@ -404,9 +401,6 @@ namespace Umbraco.Core.Models
|
||||
if (DataTypeDatabaseType == DataTypeDatabaseType.Integer && type == typeof(int))
|
||||
return true;
|
||||
|
||||
if (DataTypeDatabaseType == DataTypeDatabaseType.Decimal && type == typeof(decimal))
|
||||
return true;
|
||||
|
||||
if (DataTypeDatabaseType == DataTypeDatabaseType.Date && type == typeof(DateTime))
|
||||
return true;
|
||||
|
||||
|
||||
@@ -108,6 +108,18 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to call on entity saved when first added
|
||||
/// </summary>
|
||||
internal override void AddingEntity()
|
||||
{
|
||||
if (Key == default(Guid))
|
||||
{
|
||||
Key = Guid.NewGuid();
|
||||
}
|
||||
base.AddingEntity();
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public int LoginNodeId
|
||||
{
|
||||
|
||||
@@ -28,6 +28,18 @@ namespace Umbraco.Core.Models
|
||||
|
||||
public Guid AccessEntryId { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Method to call on entity saved when first added
|
||||
/// </summary>
|
||||
internal override void AddingEntity()
|
||||
{
|
||||
if (Key == default(Guid))
|
||||
{
|
||||
Key = Guid.NewGuid();
|
||||
}
|
||||
base.AddingEntity();
|
||||
}
|
||||
|
||||
public string RuleValue
|
||||
{
|
||||
get { return _ruleValue; }
|
||||
|
||||
@@ -230,13 +230,13 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
{
|
||||
_sourceCacheLevel = converterMeta.GetPropertyCacheLevel(this, PropertyCacheValue.Source);
|
||||
_objectCacheLevel = converterMeta.GetPropertyCacheLevel(this, PropertyCacheValue.Object);
|
||||
_objectCacheLevel = converterMeta.GetPropertyCacheLevel(this, PropertyCacheValue.XPath);
|
||||
_xpathCacheLevel = converterMeta.GetPropertyCacheLevel(this, PropertyCacheValue.XPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
_sourceCacheLevel = GetCacheLevel(_converter, PropertyCacheValue.Source);
|
||||
_objectCacheLevel = GetCacheLevel(_converter, PropertyCacheValue.Object);
|
||||
_objectCacheLevel = GetCacheLevel(_converter, PropertyCacheValue.XPath);
|
||||
_xpathCacheLevel = GetCacheLevel(_converter, PropertyCacheValue.XPath);
|
||||
}
|
||||
if (_objectCacheLevel < _sourceCacheLevel) _objectCacheLevel = _sourceCacheLevel;
|
||||
if (_xpathCacheLevel < _sourceCacheLevel) _xpathCacheLevel = _sourceCacheLevel;
|
||||
|
||||
+27
-27
@@ -1,28 +1,28 @@
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.DatabaseAnnotations;
|
||||
|
||||
namespace Umbraco.Core.Models.Rdbms
|
||||
{
|
||||
[TableName("cmsDocumentType")]
|
||||
[PrimaryKey("contentTypeNodeId", autoIncrement = false)]
|
||||
[ExplicitColumns]
|
||||
internal class ContentTypeTemplateDto
|
||||
{
|
||||
[Column("contentTypeNodeId")]
|
||||
[PrimaryKeyColumn(AutoIncrement = false, Name = "PK_cmsDocumentType", OnColumns = "contentTypeNodeId, templateNodeId")]
|
||||
[ForeignKey(typeof(ContentTypeDto), Column = "nodeId")]
|
||||
[ForeignKey(typeof(NodeDto))]
|
||||
public int ContentTypeNodeId { get; set; }
|
||||
|
||||
[Column("templateNodeId")]
|
||||
[ForeignKey(typeof(TemplateDto), Column = "nodeId")]
|
||||
public int TemplateNodeId { get; set; }
|
||||
|
||||
[Column("IsDefault")]
|
||||
[Constraint(Default = "0")]
|
||||
public bool IsDefault { get; set; }
|
||||
|
||||
[ResultColumn]
|
||||
public ContentTypeDto ContentTypeDto { get; set; }
|
||||
}
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.DatabaseAnnotations;
|
||||
|
||||
namespace Umbraco.Core.Models.Rdbms
|
||||
{
|
||||
[TableName("cmsDocumentType")]
|
||||
[PrimaryKey("contentTypeNodeId", autoIncrement = false)]
|
||||
[ExplicitColumns]
|
||||
internal class DocumentTypeDto
|
||||
{
|
||||
[Column("contentTypeNodeId")]
|
||||
[PrimaryKeyColumn(AutoIncrement = false, Name = "PK_cmsDocumentType", OnColumns = "contentTypeNodeId, templateNodeId")]
|
||||
[ForeignKey(typeof(ContentTypeDto), Column = "nodeId")]
|
||||
[ForeignKey(typeof(NodeDto))]
|
||||
public int ContentTypeNodeId { get; set; }
|
||||
|
||||
[Column("templateNodeId")]
|
||||
[ForeignKey(typeof(TemplateDto), Column = "nodeId")]
|
||||
public int TemplateNodeId { get; set; }
|
||||
|
||||
[Column("IsDefault")]
|
||||
[Constraint(Default = "0")]
|
||||
public bool IsDefault { get; set; }
|
||||
|
||||
[ResultColumn]
|
||||
public ContentTypeDto ContentTypeDto { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,12 @@ namespace Umbraco.Core.Models.Rdbms
|
||||
[ExplicitColumns]
|
||||
internal class NodeDto
|
||||
{
|
||||
public NodeDto()
|
||||
{
|
||||
//By default, always generate a new guid
|
||||
UniqueId = Guid.NewGuid();
|
||||
}
|
||||
|
||||
public const int NodeIdSeed = 1050;
|
||||
|
||||
[Column("id")]
|
||||
|
||||
@@ -33,10 +33,6 @@ namespace Umbraco.Core.Models.Rdbms
|
||||
[NullSetting(NullSetting = NullSettings.Null)]
|
||||
public int? Integer { get; set; }
|
||||
|
||||
[Column("dataDecimal")]
|
||||
[NullSetting(NullSetting = NullSettings.Null)]
|
||||
public decimal? Decimal { get; set; }
|
||||
|
||||
[Column("dataDate")]
|
||||
[NullSetting(NullSetting = NullSettings.Null)]
|
||||
public DateTime? Date { get; set; }
|
||||
@@ -59,27 +55,22 @@ namespace Umbraco.Core.Models.Rdbms
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Integer.HasValue)
|
||||
if(Integer.HasValue)
|
||||
{
|
||||
return Integer.Value;
|
||||
}
|
||||
|
||||
if (Decimal.HasValue)
|
||||
{
|
||||
return Decimal.Value;
|
||||
}
|
||||
|
||||
if (Date.HasValue)
|
||||
if(Date.HasValue)
|
||||
{
|
||||
return Date.Value;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(VarChar) == false)
|
||||
if(string.IsNullOrEmpty(VarChar) == false)
|
||||
{
|
||||
return VarChar;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(Text) == false)
|
||||
if(string.IsNullOrEmpty(Text) == false)
|
||||
{
|
||||
return Text;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,12 @@ namespace Umbraco.Core.Models.Rdbms
|
||||
[ExplicitColumns]
|
||||
internal class PropertyTypeDto
|
||||
{
|
||||
public PropertyTypeDto()
|
||||
{
|
||||
//by default always create a new guid
|
||||
UniqueId = Guid.NewGuid();
|
||||
}
|
||||
|
||||
[Column("id")]
|
||||
[PrimaryKeyColumn(IdentitySeed = 50)]
|
||||
public int Id { get; set; }
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.DatabaseAnnotations;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
|
||||
namespace Umbraco.Core.Models.Rdbms
|
||||
{
|
||||
@@ -15,6 +13,12 @@ namespace Umbraco.Core.Models.Rdbms
|
||||
[PrimaryKeyColumn(IdentitySeed = 12)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("parentGroupId")]
|
||||
[NullSetting(NullSetting = NullSettings.Null)]
|
||||
//[Constraint(Default = "NULL")]
|
||||
[ForeignKey(typeof(PropertyTypeGroupDto))]
|
||||
public int? ParentGroupId { get; set; }
|
||||
|
||||
[Column("contenttypeNodeId")]
|
||||
[ForeignKey(typeof(ContentTypeDto), Column = "nodeId")]
|
||||
public int ContentTypeNodeId { get; set; }
|
||||
@@ -27,11 +31,5 @@ namespace Umbraco.Core.Models.Rdbms
|
||||
|
||||
[ResultColumn]
|
||||
public List<PropertyTypeDto> PropertyTypeDtos { get; set; }
|
||||
|
||||
[Column("uniqueID")]
|
||||
[NullSetting(NullSetting = NullSettings.NotNull)]
|
||||
[Constraint(Default = SystemMethods.NewGuid)]
|
||||
[Index(IndexTypes.UniqueNonClustered, Name = "IX_cmsPropertyTypeGroupUniqueID")]
|
||||
public Guid UniqueId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,9 @@ namespace Umbraco.Core.Models.Rdbms
|
||||
[Column("PropertyTypeGroupId")]
|
||||
public int? Id { get; set; }
|
||||
|
||||
[Column("parentGroupId")]
|
||||
public int? ParentGroupId { get; set; }
|
||||
|
||||
[Column("PropertyGroupName")]
|
||||
public string Text { get; set; }
|
||||
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.DatabaseAnnotations;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
|
||||
namespace Umbraco.Core.Models.Rdbms
|
||||
{
|
||||
[TableName("umbracoDeployChecksum")]
|
||||
[PrimaryKey("id")]
|
||||
[ExplicitColumns]
|
||||
internal class UmbracoDeployChecksumDto
|
||||
{
|
||||
[Column("id")]
|
||||
[PrimaryKeyColumn(Name = "PK_umbracoDeployChecksum")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("entityType")]
|
||||
[Length(32)]
|
||||
[NullSetting(NullSetting = NullSettings.NotNull)]
|
||||
[Index(IndexTypes.UniqueNonClustered, Name = "IX_umbracoDeployChecksum", ForColumns = "entityType,entityGuid,entityPath")]
|
||||
public string EntityType { get; set; }
|
||||
|
||||
[Column("entityGuid")]
|
||||
[NullSetting(NullSetting = NullSettings.Null)]
|
||||
public Guid EntityGuid { get; set; }
|
||||
|
||||
[Column("entityPath")]
|
||||
[Length(256)]
|
||||
[NullSetting(NullSetting = NullSettings.Null)]
|
||||
public string EntityPath { get; set; }
|
||||
|
||||
[Column("localChecksum")]
|
||||
[NullSetting(NullSetting = NullSettings.NotNull)]
|
||||
[Length(32)]
|
||||
public string LocalChecksum { get; set; }
|
||||
|
||||
[Column("compositeChecksum")]
|
||||
[NullSetting(NullSetting = NullSettings.Null)]
|
||||
[Length(32)]
|
||||
public string CompositeChecksum { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.DatabaseAnnotations;
|
||||
|
||||
namespace Umbraco.Core.Models.Rdbms
|
||||
{
|
||||
[TableName("umbracoDeployDependency")]
|
||||
[ExplicitColumns]
|
||||
internal class UmbracoDeployDependencyDto
|
||||
{
|
||||
[Column("sourceId")]
|
||||
[PrimaryKeyColumn(AutoIncrement = false, Clustered = true, Name = "PK_umbracoDeployDependency", OnColumns = "sourceId, targetId")]
|
||||
[ForeignKey(typeof(UmbracoDeployChecksumDto), Name = "FK_umbracoDeployDependency_umbracoDeployChecksum_id1")]
|
||||
[NullSetting(NullSetting = NullSettings.NotNull)]
|
||||
public int SourceId { get; set; }
|
||||
|
||||
[Column("targetId")]
|
||||
[ForeignKey(typeof(UmbracoDeployChecksumDto), Name = "FK_umbracoDeployDependency_umbracoDeployChecksum_id2")]
|
||||
[NullSetting(NullSetting = NullSettings.NotNull)]
|
||||
public int TargetId { get; set; }
|
||||
|
||||
[Column("mode")]
|
||||
[NullSetting(NullSetting = NullSettings.NotNull)]
|
||||
public int Mode { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -118,6 +118,18 @@ namespace Umbraco.Core.Models
|
||||
return ApplicationContext.Current.Services.FileService.DetermineTemplateRenderingEngine(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to call when Entity is being saved
|
||||
/// </summary>
|
||||
/// <remarks>Created date is set and a Unique key is assigned</remarks>
|
||||
internal override void AddingEntity()
|
||||
{
|
||||
base.AddingEntity();
|
||||
|
||||
if (Key == Guid.Empty)
|
||||
Key = Guid.NewGuid();
|
||||
}
|
||||
|
||||
public void SetMasterTemplate(ITemplate masterTemplate)
|
||||
{
|
||||
if (masterTemplate == null)
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Umbraco.Core.Models
|
||||
/// <summary>
|
||||
/// Implementation of the <see cref="IUmbracoEntity"/> for internal use.
|
||||
/// </summary>
|
||||
public class UmbracoEntity : Entity, IUmbracoEntity
|
||||
internal class UmbracoEntity : Entity, IUmbracoEntity
|
||||
{
|
||||
private int _creatorId;
|
||||
private int _level;
|
||||
|
||||
@@ -11,20 +11,6 @@ namespace Umbraco.Core.Models
|
||||
internal static class UmbracoEntityExtensions
|
||||
{
|
||||
|
||||
public static bool HasChildren(this IUmbracoEntity entity)
|
||||
{
|
||||
if (entity.AdditionalData.ContainsKey("HasChildren"))
|
||||
{
|
||||
var convert = entity.AdditionalData["HasChildren"].TryConvertTo<bool>();
|
||||
if (convert)
|
||||
{
|
||||
return convert.Result;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static object GetAdditionalDataValueIgnoreCase(this IUmbracoEntity entity, string key, object defaultVal)
|
||||
{
|
||||
if (entity.AdditionalData.ContainsKeyIgnoreCase(key) == false) return defaultVal;
|
||||
|
||||
@@ -15,49 +15,49 @@ namespace Umbraco.Core.Models
|
||||
/// <summary>
|
||||
/// Content Item Type
|
||||
/// </summary>
|
||||
[UmbracoObjectType(Constants.ObjectTypes.ContentItemType)]
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.ContentItemType)]
|
||||
[FriendlyName("Content Item Type")]
|
||||
ContentItemType,
|
||||
|
||||
/// <summary>
|
||||
/// Root
|
||||
/// </summary>
|
||||
[UmbracoObjectType(Constants.ObjectTypes.SystemRoot)]
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.SystemRoot)]
|
||||
[FriendlyName("Root")]
|
||||
ROOT,
|
||||
|
||||
/// <summary>
|
||||
/// Document
|
||||
/// </summary>
|
||||
[UmbracoObjectType(Constants.ObjectTypes.Document, typeof(IContent))]
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.Document, typeof(IContent))]
|
||||
[FriendlyName("Document")]
|
||||
Document,
|
||||
|
||||
/// <summary>
|
||||
/// Media
|
||||
/// </summary>
|
||||
[UmbracoObjectType(Constants.ObjectTypes.Media, typeof(IMedia))]
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.Media, typeof(IMedia))]
|
||||
[FriendlyName("Media")]
|
||||
Media,
|
||||
|
||||
/// <summary>
|
||||
/// Member Type
|
||||
/// </summary>
|
||||
[UmbracoObjectType(Constants.ObjectTypes.MemberType, typeof(IMemberType))]
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.MemberType, typeof(IMemberType))]
|
||||
[FriendlyName("Member Type")]
|
||||
MemberType,
|
||||
|
||||
/// <summary>
|
||||
/// Template
|
||||
/// </summary>
|
||||
[UmbracoObjectType(Constants.ObjectTypes.Template, typeof(ITemplate))]
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.Template, typeof(ITemplate))]
|
||||
[FriendlyName("Template")]
|
||||
Template,
|
||||
|
||||
/// <summary>
|
||||
/// Member Group
|
||||
/// </summary>
|
||||
[UmbracoObjectType(Constants.ObjectTypes.MemberGroup)]
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.MemberGroup)]
|
||||
[FriendlyName("Member Group")]
|
||||
MemberGroup,
|
||||
|
||||
@@ -65,73 +65,50 @@ namespace Umbraco.Core.Models
|
||||
/// <summary>
|
||||
/// Content Item
|
||||
/// </summary>
|
||||
[UmbracoObjectType(Constants.ObjectTypes.ContentItem)]
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.ContentItem)]
|
||||
[FriendlyName("Content Item")]
|
||||
ContentItem,
|
||||
|
||||
/// <summary>
|
||||
/// "Media Type
|
||||
/// </summary>
|
||||
[UmbracoObjectType(Constants.ObjectTypes.MediaType, typeof(IMediaType))]
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.MediaType, typeof(IMediaType))]
|
||||
[FriendlyName("Media Type")]
|
||||
MediaType,
|
||||
|
||||
/// <summary>
|
||||
/// Document Type
|
||||
/// </summary>
|
||||
[UmbracoObjectType(Constants.ObjectTypes.DocumentType, typeof(IContentType))]
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.DocumentType, typeof(IContentType))]
|
||||
[FriendlyName("Document Type")]
|
||||
DocumentType,
|
||||
|
||||
/// <summary>
|
||||
/// Recycle Bin
|
||||
/// </summary>
|
||||
[UmbracoObjectType(Constants.ObjectTypes.ContentRecycleBin)]
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.ContentRecycleBin)]
|
||||
[FriendlyName("Recycle Bin")]
|
||||
RecycleBin,
|
||||
|
||||
/// <summary>
|
||||
/// Stylesheet
|
||||
/// </summary>
|
||||
[UmbracoObjectType(Constants.ObjectTypes.Stylesheet)]
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.Stylesheet)]
|
||||
[FriendlyName("Stylesheet")]
|
||||
Stylesheet,
|
||||
|
||||
/// <summary>
|
||||
/// Member
|
||||
/// </summary>
|
||||
[UmbracoObjectType(Constants.ObjectTypes.Member, typeof(IMember))]
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.Member, typeof(IMember))]
|
||||
[FriendlyName("Member")]
|
||||
Member,
|
||||
|
||||
/// <summary>
|
||||
/// Data Type
|
||||
/// </summary>
|
||||
[UmbracoObjectType(Constants.ObjectTypes.DataType, typeof(IDataTypeDefinition))]
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.DataType, typeof(IDataTypeDefinition))]
|
||||
[FriendlyName("Data Type")]
|
||||
DataType,
|
||||
|
||||
/// <summary>
|
||||
/// Document type container
|
||||
/// </summary>
|
||||
[UmbracoObjectType(Constants.ObjectTypes.DocumentTypeContainer)]
|
||||
[FriendlyName("Document Type Container")]
|
||||
DocumentTypeContainer,
|
||||
|
||||
/// <summary>
|
||||
/// Media type container
|
||||
/// </summary>
|
||||
[UmbracoObjectType(Constants.ObjectTypes.MediaTypeContainer)]
|
||||
[FriendlyName("Media Type Container")]
|
||||
MediaTypeContainer,
|
||||
|
||||
/// <summary>
|
||||
/// Media type container
|
||||
/// </summary>
|
||||
[UmbracoObjectType(Constants.ObjectTypes.DataTypeContainer)]
|
||||
[FriendlyName("Data Type Container")]
|
||||
DataTypeContainer
|
||||
|
||||
|
||||
DataType
|
||||
}
|
||||
}
|
||||
@@ -1,144 +1,98 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
// factory for
|
||||
// IContentType (document types)
|
||||
// IMediaType (media types)
|
||||
// IMemberType (member types)
|
||||
//
|
||||
internal class ContentTypeFactory
|
||||
{
|
||||
#region IContentType
|
||||
private readonly Guid _nodeObjectType;
|
||||
|
||||
public IContentType BuildContentTypeEntity(ContentTypeDto dto)
|
||||
public ContentTypeFactory(Guid nodeObjectType)
|
||||
{
|
||||
var contentType = new ContentType(dto.NodeDto.ParentId);
|
||||
BuildCommonEntity(contentType, dto);
|
||||
_nodeObjectType = nodeObjectType;
|
||||
}
|
||||
|
||||
#region Implementation of IEntityFactory<IContentType,DocumentTypeDto>
|
||||
|
||||
public IContentType BuildEntity(DocumentTypeDto dto)
|
||||
{
|
||||
var contentType = new ContentType(dto.ContentTypeDto.NodeDto.ParentId)
|
||||
{
|
||||
Id = dto.ContentTypeDto.NodeDto.NodeId,
|
||||
Key = dto.ContentTypeDto.NodeDto.UniqueId,
|
||||
Alias = dto.ContentTypeDto.Alias,
|
||||
Name = dto.ContentTypeDto.NodeDto.Text,
|
||||
Icon = dto.ContentTypeDto.Icon,
|
||||
Thumbnail = dto.ContentTypeDto.Thumbnail,
|
||||
SortOrder = dto.ContentTypeDto.NodeDto.SortOrder,
|
||||
Description = dto.ContentTypeDto.Description,
|
||||
CreateDate = dto.ContentTypeDto.NodeDto.CreateDate,
|
||||
Path = dto.ContentTypeDto.NodeDto.Path,
|
||||
Level = dto.ContentTypeDto.NodeDto.Level,
|
||||
CreatorId = dto.ContentTypeDto.NodeDto.UserId.Value,
|
||||
AllowedAsRoot = dto.ContentTypeDto.AllowAtRoot,
|
||||
IsContainer = dto.ContentTypeDto.IsContainer,
|
||||
Trashed = dto.ContentTypeDto.NodeDto.Trashed,
|
||||
DefaultTemplateId = dto.TemplateNodeId
|
||||
};
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
// http://issues.umbraco.org/issue/U4-1946
|
||||
contentType.ResetDirtyProperties(false);
|
||||
|
||||
return contentType;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IMediaType
|
||||
|
||||
public IMediaType BuildMediaTypeEntity(ContentTypeDto dto)
|
||||
public DocumentTypeDto BuildDto(IContentType entity)
|
||||
{
|
||||
var contentType = new MediaType(dto.NodeDto.ParentId);
|
||||
BuildCommonEntity(contentType, dto);
|
||||
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
// http://issues.umbraco.org/issue/U4-1946
|
||||
contentType.ResetDirtyProperties(false);
|
||||
|
||||
return contentType;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IMemberType
|
||||
|
||||
public IMemberType BuildMemberTypeEntity(ContentTypeDto dto)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<MemberTypeDto> BuildMemberTypeDtos(IMemberType entity)
|
||||
{
|
||||
var memberType = entity as MemberType;
|
||||
if (memberType == null || memberType.PropertyTypes.Any() == false)
|
||||
return Enumerable.Empty<MemberTypeDto>();
|
||||
|
||||
var dtos = memberType.PropertyTypes.Select(x => new MemberTypeDto
|
||||
var documentTypeDto = new DocumentTypeDto
|
||||
{ContentTypeDto = BuildContentTypeDto(entity), ContentTypeNodeId = entity.Id};
|
||||
|
||||
var contentType = entity as ContentType;
|
||||
if(contentType != null)
|
||||
{
|
||||
NodeId = entity.Id,
|
||||
PropertyTypeId = x.Id,
|
||||
CanEdit = memberType.MemberCanEditProperty(x.Alias),
|
||||
ViewOnProfile = memberType.MemberCanViewProperty(x.Alias)
|
||||
}).ToList();
|
||||
return dtos;
|
||||
documentTypeDto.TemplateNodeId = contentType.DefaultTemplateId;
|
||||
documentTypeDto.IsDefault = true;
|
||||
}
|
||||
return documentTypeDto;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Common
|
||||
|
||||
private static void BuildCommonEntity(ContentTypeBase entity, ContentTypeDto dto)
|
||||
private ContentTypeDto BuildContentTypeDto(IContentType entity)
|
||||
{
|
||||
entity.Id = dto.NodeDto.NodeId;
|
||||
entity.Key = dto.NodeDto.UniqueId;
|
||||
entity.Alias = dto.Alias;
|
||||
entity.Name = dto.NodeDto.Text;
|
||||
entity.Icon = dto.Icon;
|
||||
entity.Thumbnail = dto.Thumbnail;
|
||||
entity.SortOrder = dto.NodeDto.SortOrder;
|
||||
entity.Description = dto.Description;
|
||||
entity.CreateDate = dto.NodeDto.CreateDate;
|
||||
entity.Path = dto.NodeDto.Path;
|
||||
entity.Level = dto.NodeDto.Level;
|
||||
entity.CreatorId = dto.NodeDto.UserId.Value;
|
||||
entity.AllowedAsRoot = dto.AllowAtRoot;
|
||||
entity.IsContainer = dto.IsContainer;
|
||||
entity.Trashed = dto.NodeDto.Trashed;
|
||||
}
|
||||
|
||||
public ContentTypeDto BuildContentTypeDto(IContentTypeBase entity)
|
||||
{
|
||||
Guid nodeObjectType;
|
||||
if (entity is IContentType)
|
||||
nodeObjectType = Constants.ObjectTypes.DocumentTypeGuid;
|
||||
else if (entity is IMediaType)
|
||||
nodeObjectType = Constants.ObjectTypes.MediaTypeGuid;
|
||||
else if (entity is IMemberType)
|
||||
nodeObjectType = Constants.ObjectTypes.MemberTypeGuid;
|
||||
else
|
||||
throw new Exception("oops: invalid entity.");
|
||||
|
||||
var contentTypeDto = new ContentTypeDto
|
||||
{
|
||||
Alias = entity.Alias,
|
||||
Description = entity.Description,
|
||||
Icon = entity.Icon,
|
||||
Thumbnail = entity.Thumbnail,
|
||||
NodeId = entity.Id,
|
||||
AllowAtRoot = entity.AllowedAsRoot,
|
||||
IsContainer = entity.IsContainer,
|
||||
NodeDto = BuildNodeDto(entity, nodeObjectType)
|
||||
};
|
||||
{
|
||||
Alias = entity.Alias,
|
||||
Description = entity.Description,
|
||||
Icon = entity.Icon,
|
||||
Thumbnail = entity.Thumbnail,
|
||||
NodeId = entity.Id,
|
||||
AllowAtRoot = entity.AllowedAsRoot,
|
||||
IsContainer = entity.IsContainer,
|
||||
NodeDto = BuildNodeDto(entity)
|
||||
};
|
||||
return contentTypeDto;
|
||||
}
|
||||
|
||||
private static NodeDto BuildNodeDto(IUmbracoEntity entity, Guid nodeObjectType)
|
||||
private NodeDto BuildNodeDto(IContentType entity)
|
||||
{
|
||||
var nodeDto = new NodeDto
|
||||
{
|
||||
CreateDate = entity.CreateDate,
|
||||
NodeId = entity.Id,
|
||||
Level = short.Parse(entity.Level.ToString(CultureInfo.InvariantCulture)),
|
||||
NodeObjectType = nodeObjectType,
|
||||
ParentId = entity.ParentId,
|
||||
Path = entity.Path,
|
||||
SortOrder = entity.SortOrder,
|
||||
Text = entity.Name,
|
||||
Trashed = false,
|
||||
UniqueId = entity.Key,
|
||||
UserId = entity.CreatorId
|
||||
};
|
||||
{
|
||||
CreateDate = entity.CreateDate,
|
||||
NodeId = entity.Id,
|
||||
Level = short.Parse(entity.Level.ToString(CultureInfo.InvariantCulture)),
|
||||
NodeObjectType = _nodeObjectType,
|
||||
ParentId = entity.ParentId,
|
||||
Path = entity.Path,
|
||||
SortOrder = entity.SortOrder,
|
||||
Text = entity.Name,
|
||||
Trashed = false,
|
||||
UniqueId = entity.Key,
|
||||
UserId = entity.CreatorId
|
||||
};
|
||||
return nodeDto;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
internal class MediaTypeFactory
|
||||
{
|
||||
private readonly Guid _nodeObjectType;
|
||||
|
||||
public MediaTypeFactory(Guid nodeObjectType)
|
||||
{
|
||||
_nodeObjectType = nodeObjectType;
|
||||
}
|
||||
|
||||
#region Implementation of IEntityFactory<IMediaType,ContentTypeDto>
|
||||
|
||||
public IMediaType BuildEntity(ContentTypeDto dto)
|
||||
{
|
||||
var contentType = new MediaType(dto.NodeDto.ParentId)
|
||||
{
|
||||
Id = dto.NodeDto.NodeId,
|
||||
Key = dto.NodeDto.UniqueId,
|
||||
Alias = dto.Alias,
|
||||
Name = dto.NodeDto.Text,
|
||||
Icon = dto.Icon,
|
||||
Thumbnail = dto.Thumbnail,
|
||||
SortOrder = dto.NodeDto.SortOrder,
|
||||
Description = dto.Description,
|
||||
CreateDate = dto.NodeDto.CreateDate,
|
||||
Path = dto.NodeDto.Path,
|
||||
Level = dto.NodeDto.Level,
|
||||
CreatorId = dto.NodeDto.UserId.Value,
|
||||
AllowedAsRoot = dto.AllowAtRoot,
|
||||
IsContainer = dto.IsContainer,
|
||||
Trashed = dto.NodeDto.Trashed
|
||||
};
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
// http://issues.umbraco.org/issue/U4-1946
|
||||
contentType.ResetDirtyProperties(false);
|
||||
return contentType;
|
||||
}
|
||||
|
||||
public ContentTypeDto BuildDto(IMediaType entity)
|
||||
{
|
||||
var contentTypeDto = new ContentTypeDto
|
||||
{
|
||||
Alias = entity.Alias,
|
||||
Description = entity.Description,
|
||||
Icon = entity.Icon,
|
||||
Thumbnail = entity.Thumbnail,
|
||||
NodeId = entity.Id,
|
||||
AllowAtRoot = entity.AllowedAsRoot,
|
||||
IsContainer = entity.IsContainer,
|
||||
NodeDto = BuildNodeDto(entity)
|
||||
};
|
||||
return contentTypeDto;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private NodeDto BuildNodeDto(IMediaType entity)
|
||||
{
|
||||
var nodeDto = new NodeDto
|
||||
{
|
||||
CreateDate = entity.CreateDate,
|
||||
NodeId = entity.Id,
|
||||
Level = short.Parse(entity.Level.ToString(CultureInfo.InvariantCulture)),
|
||||
NodeObjectType = _nodeObjectType,
|
||||
ParentId = entity.ParentId,
|
||||
Path = entity.Path,
|
||||
SortOrder = entity.SortOrder,
|
||||
Text = entity.Name,
|
||||
Trashed = false,
|
||||
UniqueId = entity.Key,
|
||||
UserId = entity.CreatorId
|
||||
};
|
||||
return nodeDto;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
internal class MemberTypeFactory
|
||||
{
|
||||
private readonly Guid _nodeObjectType;
|
||||
|
||||
public MemberTypeFactory(Guid nodeObjectType)
|
||||
{
|
||||
_nodeObjectType = nodeObjectType;
|
||||
}
|
||||
|
||||
public IMemberType BuildEntity(ContentTypeDto dto)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public ContentTypeDto BuildDto(IMemberType entity)
|
||||
{
|
||||
var contentTypeDto = new ContentTypeDto
|
||||
{
|
||||
Alias = entity.Alias,
|
||||
Description = entity.Description,
|
||||
Icon = entity.Icon,
|
||||
Thumbnail = entity.Thumbnail,
|
||||
NodeId = entity.Id,
|
||||
AllowAtRoot = entity.AllowedAsRoot,
|
||||
IsContainer = entity.IsContainer,
|
||||
NodeDto = BuildNodeDto(entity)
|
||||
};
|
||||
return contentTypeDto;
|
||||
}
|
||||
|
||||
public IEnumerable<MemberTypeDto> BuildMemberTypeDtos(IMemberType entity)
|
||||
{
|
||||
var memberType = entity as MemberType;
|
||||
if (memberType == null || memberType.PropertyTypes.Any() == false)
|
||||
return Enumerable.Empty<MemberTypeDto>();
|
||||
|
||||
var memberTypes = new List<MemberTypeDto>();
|
||||
foreach (var propertyType in memberType.PropertyTypes)
|
||||
{
|
||||
memberTypes.Add(new MemberTypeDto
|
||||
{
|
||||
NodeId = entity.Id,
|
||||
PropertyTypeId = propertyType.Id,
|
||||
CanEdit = memberType.MemberCanEditProperty(propertyType.Alias),
|
||||
ViewOnProfile = memberType.MemberCanViewProperty(propertyType.Alias)
|
||||
});
|
||||
}
|
||||
|
||||
return memberTypes;
|
||||
}
|
||||
|
||||
private NodeDto BuildNodeDto(IMemberType entity)
|
||||
{
|
||||
var nodeDto = new NodeDto
|
||||
{
|
||||
CreateDate = entity.CreateDate,
|
||||
NodeId = entity.Id,
|
||||
Level = short.Parse(entity.Level.ToString(CultureInfo.InvariantCulture)),
|
||||
NodeObjectType = _nodeObjectType,
|
||||
ParentId = entity.ParentId,
|
||||
Path = entity.Path,
|
||||
SortOrder = entity.SortOrder,
|
||||
Text = entity.Name,
|
||||
Trashed = false,
|
||||
UniqueId = entity.Key,
|
||||
UserId = entity.CreatorId
|
||||
};
|
||||
return nodeDto;
|
||||
}
|
||||
|
||||
private int DeterminePropertyTypeId(int initialId, string alias, IEnumerable<PropertyType> propertyTypes)
|
||||
{
|
||||
if (initialId == 0 || initialId == default(int))
|
||||
{
|
||||
var propertyType = propertyTypes.SingleOrDefault(x => x.Alias.Equals(alias));
|
||||
if (propertyType == null)
|
||||
return default(int);
|
||||
|
||||
return propertyType.Id;
|
||||
}
|
||||
|
||||
return initialId;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,28 +51,31 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
memberType.MemberTypePropertyTypes.Add(standardPropertyType.Key,
|
||||
new MemberTypePropertyProfileAccess(false, false));
|
||||
}
|
||||
memberType.NoGroupPropertyTypes = propertyTypes;
|
||||
memberType.PropertyTypes = propertyTypes;
|
||||
|
||||
return memberType;
|
||||
}
|
||||
|
||||
private PropertyGroupCollection GetPropertyTypeGroupCollection(MemberTypeReadOnlyDto dto, MemberType memberType, Dictionary<string, PropertyType> standardProps)
|
||||
{
|
||||
// see PropertyGroupFactory, repeating code here...
|
||||
|
||||
var propertyGroups = new PropertyGroupCollection();
|
||||
var propertyGroups = new PropertyGroupCollection();
|
||||
|
||||
foreach (var groupDto in dto.PropertyTypeGroups.Where(x => x.Id.HasValue))
|
||||
{
|
||||
var group = new PropertyGroup();
|
||||
|
||||
// if the group is defined on the current member type,
|
||||
// assign its identifier, else it will be zero
|
||||
|
||||
//Only assign an Id if the PropertyGroup belongs to this ContentType
|
||||
if (groupDto.ContentTypeNodeId == memberType.Id)
|
||||
{
|
||||
// note: no idea why Id is nullable here, but better check
|
||||
if (groupDto.Id.HasValue == false)
|
||||
throw new Exception("oops: groupDto.Id has no value.");
|
||||
group.Id = groupDto.Id.Value;
|
||||
|
||||
if (groupDto.ParentGroupId.HasValue)
|
||||
group.ParentId = groupDto.ParentGroupId.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
//If the PropertyGroup is inherited, we add a reference to the group as a Parent.
|
||||
group.ParentId = groupDto.Id;
|
||||
}
|
||||
|
||||
group.Name = groupDto.Text;
|
||||
|
||||
@@ -63,9 +63,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
|
||||
//Check if property has an Id and set it, so that it can be updated if it already exists
|
||||
if (property.HasIdentity)
|
||||
{
|
||||
dto.Id = property.Id;
|
||||
}
|
||||
|
||||
if (property.DataTypeDatabaseType == DataTypeDatabaseType.Integer)
|
||||
{
|
||||
@@ -84,21 +82,11 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (property.DataTypeDatabaseType == DataTypeDatabaseType.Decimal && property.Value != null)
|
||||
{
|
||||
decimal val;
|
||||
if (decimal.TryParse(property.Value.ToString(), out val))
|
||||
{
|
||||
dto.Decimal = val;
|
||||
}
|
||||
}
|
||||
else if (property.DataTypeDatabaseType == DataTypeDatabaseType.Date && property.Value != null && string.IsNullOrWhiteSpace(property.Value.ToString()) == false)
|
||||
{
|
||||
DateTime date;
|
||||
if (DateTime.TryParse(property.Value.ToString(), out date))
|
||||
{
|
||||
if(DateTime.TryParse(property.Value.ToString(), out date))
|
||||
dto.Date = date;
|
||||
}
|
||||
}
|
||||
else if (property.DataTypeDatabaseType == DataTypeDatabaseType.Ntext && property.Value != null)
|
||||
{
|
||||
|
||||
@@ -8,21 +8,21 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
internal class PropertyGroupFactory
|
||||
{
|
||||
private readonly int _contentTypeId;
|
||||
private readonly int _id;
|
||||
private readonly DateTime _createDate;
|
||||
private readonly DateTime _updateDate;
|
||||
//a callback to create a property type which can be injected via a contructor
|
||||
private readonly Func<string, DataTypeDatabaseType, string, PropertyType> _propertyTypeCtor;
|
||||
|
||||
public PropertyGroupFactory(int contentTypeId)
|
||||
public PropertyGroupFactory(int id)
|
||||
{
|
||||
_contentTypeId = contentTypeId;
|
||||
_id = id;
|
||||
_propertyTypeCtor = (propertyEditorAlias, dbType, alias) => new PropertyType(propertyEditorAlias, dbType);
|
||||
}
|
||||
|
||||
public PropertyGroupFactory(int contentTypeId, DateTime createDate, DateTime updateDate, Func<string, DataTypeDatabaseType, string, PropertyType> propertyTypeCtor)
|
||||
public PropertyGroupFactory(int id, DateTime createDate, DateTime updateDate, Func<string, DataTypeDatabaseType, string, PropertyType> propertyTypeCtor)
|
||||
{
|
||||
_contentTypeId = contentTypeId;
|
||||
_id = id;
|
||||
_createDate = createDate;
|
||||
_updateDate = updateDate;
|
||||
_propertyTypeCtor = propertyTypeCtor;
|
||||
@@ -30,24 +30,29 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
|
||||
#region Implementation of IEntityFactory<IEnumerable<PropertyGroup>,IEnumerable<TabDto>>
|
||||
|
||||
public IEnumerable<PropertyGroup> BuildEntity(IEnumerable<PropertyTypeGroupDto> groupDtos)
|
||||
public IEnumerable<PropertyGroup> BuildEntity(IEnumerable<PropertyTypeGroupDto> dto)
|
||||
{
|
||||
// groupDtos contains all the groups, those that are defined on the current
|
||||
// content type, and those that are inherited from composition content types
|
||||
var propertyGroups = new PropertyGroupCollection();
|
||||
foreach (var groupDto in groupDtos)
|
||||
foreach (var groupDto in dto)
|
||||
{
|
||||
var group = new PropertyGroup();
|
||||
|
||||
// if the group is defined on the current content type,
|
||||
// assign its identifier, else it will be zero
|
||||
if (groupDto.ContentTypeNodeId == _contentTypeId)
|
||||
//Only assign an Id if the PropertyGroup belongs to this ContentType
|
||||
if (groupDto.ContentTypeNodeId == _id)
|
||||
{
|
||||
group.Id = groupDto.Id;
|
||||
|
||||
if (groupDto.ParentGroupId.HasValue)
|
||||
group.ParentId = groupDto.ParentGroupId.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
//If the PropertyGroup is inherited, we add a reference to the group as a Parent.
|
||||
group.ParentId = groupDto.Id;
|
||||
}
|
||||
|
||||
group.Name = groupDto.Text;
|
||||
group.SortOrder = groupDto.SortOrder;
|
||||
group.PropertyTypes = new PropertyTypeCollection();
|
||||
group.Key = groupDto.UniqueId;
|
||||
|
||||
//Because we are likely to have a group with no PropertyTypes we need to ensure that these are excluded
|
||||
var typeDtos = groupDto.PropertyTypeDtos.Where(x => x.Id > 0);
|
||||
@@ -96,12 +101,14 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
var dto = new PropertyTypeGroupDto
|
||||
{
|
||||
ContentTypeNodeId = _contentTypeId,
|
||||
ContentTypeNodeId = _id,
|
||||
SortOrder = propertyGroup.SortOrder,
|
||||
Text = propertyGroup.Name,
|
||||
UniqueId = propertyGroup.Key
|
||||
Text = propertyGroup.Name
|
||||
};
|
||||
|
||||
if (propertyGroup.ParentId.HasValue)
|
||||
dto.ParentGroupId = propertyGroup.ParentId.Value;
|
||||
|
||||
if (propertyGroup.HasIdentity)
|
||||
dto.Id = propertyGroup.Id;
|
||||
|
||||
@@ -115,14 +122,14 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
var propertyTypeDto = new PropertyTypeDto
|
||||
{
|
||||
Alias = propertyType.Alias,
|
||||
ContentTypeId = _contentTypeId,
|
||||
ContentTypeId = _id,
|
||||
DataTypeId = propertyType.DataTypeDefinitionId,
|
||||
Description = propertyType.Description,
|
||||
Mandatory = propertyType.Mandatory,
|
||||
Name = propertyType.Name,
|
||||
SortOrder = propertyType.SortOrder,
|
||||
ValidationRegExp = propertyType.ValidationRegExp,
|
||||
UniqueId = propertyType.Key
|
||||
UniqueId = propertyType.Key == Guid.Empty ? Guid.NewGuid() : propertyType.Key
|
||||
};
|
||||
|
||||
if (tabId != default(int))
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
internal override void BuildMap()
|
||||
{
|
||||
CacheMap<PropertyGroup, PropertyTypeGroupDto>(src => src.Id, dto => dto.Id);
|
||||
CacheMap<PropertyGroup, PropertyTypeGroupDto>(src => src.Key, dto => dto.UniqueId);
|
||||
CacheMap<PropertyGroup, PropertyTypeGroupDto>(src => src.ParentId, dto => dto.ParentGroupId);
|
||||
CacheMap<PropertyGroup, PropertyTypeGroupDto>(src => src.SortOrder, dto => dto.SortOrder);
|
||||
CacheMap<PropertyGroup, PropertyTypeGroupDto>(src => src.Name, dto => dto.Text);
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
{
|
||||
CacheMap<Template, TemplateDto>(src => src.Id, dto => dto.NodeId);
|
||||
CacheMap<Template, NodeDto>(src => src.MasterTemplateId, dto => dto.ParentId);
|
||||
CacheMap<Template, NodeDto>(src => src.Key, dto => dto.UniqueId);
|
||||
CacheMap<Template, TemplateDto>(src => src.Alias, dto => dto.Alias);
|
||||
CacheMap<Template, TemplateDto>(src => src.Content, dto => dto.Design);
|
||||
}
|
||||
|
||||
@@ -117,7 +117,8 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -42, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-42", SortOrder = 2, UniqueId = new Guid("0b6a45e7-44ba-430d-9da5-4e46060b9e03"), Text = "Dropdown", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
|
||||
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -41, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-41", SortOrder = 2, UniqueId = new Guid("5046194e-4237-453c-a547-15db3a07c4e1"), Text = "Date Picker", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
|
||||
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -40, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-40", SortOrder = 2, UniqueId = new Guid("bb5f57c9-ce2b-4bb9-b697-4caca783a805"), Text = "Radiobox", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
|
||||
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -39, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-39", SortOrder = 2, UniqueId = new Guid("f38f0ac7-1d27-439c-9f3f-089cd8825a53"), Text = "Dropdown multiple", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
|
||||
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -39, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-39", SortOrder = 2, UniqueId = new Guid("f38f0ac7-1d27-439c-9f3f-089cd8825a53"), Text = "Dropdown multiple", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
|
||||
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -38, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-38", SortOrder = 2, UniqueId = new Guid("fd9f1447-6c61-4a7c-9595-5aa39147d318"), Text = "Folder Browser", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
|
||||
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -37, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-37", SortOrder = 2, UniqueId = new Guid("0225af17-b302-49cb-9176-b9f35cab9c17"), Text = "Approved Color", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
|
||||
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -36, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-36", SortOrder = 2, UniqueId = new Guid("e4d66c0f-b935-4200-81f0-025f7256b89a"), Text = "Date Picker with time", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
|
||||
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = Constants.System.DefaultContentListViewDataTypeId, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-95", SortOrder = 2, UniqueId = new Guid("C0808DD3-8133-4E4B-8CE8-E2BEA84A96A4"), Text = Constants.Conventions.DataTypes.ListViewPrefix + "Content", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
|
||||
@@ -178,16 +179,16 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
|
||||
private void CreateCmsPropertyTypeGroupData()
|
||||
{
|
||||
_database.Insert("cmsPropertyTypeGroup", "id", false, new PropertyTypeGroupDto { Id = 3, ContentTypeNodeId = 1032, Text = "Image", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.Image) });
|
||||
_database.Insert("cmsPropertyTypeGroup", "id", false, new PropertyTypeGroupDto { Id = 4, ContentTypeNodeId = 1033, Text = "File", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.File) });
|
||||
_database.Insert("cmsPropertyTypeGroup", "id", false, new PropertyTypeGroupDto { Id = 5, ContentTypeNodeId = 1031, Text = "Contents", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.Contents) });
|
||||
_database.Insert("cmsPropertyTypeGroup", "id", false, new PropertyTypeGroupDto { Id = 3, ContentTypeNodeId = 1032, Text = "Image", SortOrder = 1 });
|
||||
_database.Insert("cmsPropertyTypeGroup", "id", false, new PropertyTypeGroupDto { Id = 4, ContentTypeNodeId = 1033, Text = "File", SortOrder = 1 });
|
||||
_database.Insert("cmsPropertyTypeGroup", "id", false, new PropertyTypeGroupDto { Id = 5, ContentTypeNodeId = 1031, Text = "Contents", SortOrder = 1 });
|
||||
//membership property group
|
||||
_database.Insert("cmsPropertyTypeGroup", "id", false, new PropertyTypeGroupDto { Id = 11, ContentTypeNodeId = 1044, Text = "Membership", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.Membership) });
|
||||
_database.Insert("cmsPropertyTypeGroup", "id", false, new PropertyTypeGroupDto { Id = 11, ContentTypeNodeId = 1044, Text = "Membership", SortOrder = 1 });
|
||||
}
|
||||
|
||||
private void CreateCmsPropertyTypeData()
|
||||
{
|
||||
_database.Insert("cmsPropertyType", "id", false, new PropertyTypeDto { Id = 6, UniqueId = 6.ToGuid(), DataTypeId = 1043, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.File, Name = "Upload image", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null });
|
||||
_database.Insert("cmsPropertyType", "id", false, new PropertyTypeDto { Id = 6, UniqueId = 6.ToGuid(), DataTypeId = -90, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.File, Name = "Upload image", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null });
|
||||
_database.Insert("cmsPropertyType", "id", false, new PropertyTypeDto { Id = 7, UniqueId = 7.ToGuid(), DataTypeId = -92, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Width, Name = "Width", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null });
|
||||
_database.Insert("cmsPropertyType", "id", false, new PropertyTypeDto { Id = 8, UniqueId = 8.ToGuid(), DataTypeId = -92, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Height, Name = "Height", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null });
|
||||
_database.Insert("cmsPropertyType", "id", false, new PropertyTypeDto { Id = 9, UniqueId = 9.ToGuid(), DataTypeId = -92, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null });
|
||||
@@ -195,7 +196,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
_database.Insert("cmsPropertyType", "id", false, new PropertyTypeDto { Id = 24, UniqueId = 24.ToGuid(), DataTypeId = -90, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.File, Name = "Upload file", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null });
|
||||
_database.Insert("cmsPropertyType", "id", false, new PropertyTypeDto { Id = 25, UniqueId = 25.ToGuid(), DataTypeId = -92, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null });
|
||||
_database.Insert("cmsPropertyType", "id", false, new PropertyTypeDto { Id = 26, UniqueId = 26.ToGuid(), DataTypeId = -92, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null });
|
||||
_database.Insert("cmsPropertyType", "id", false, new PropertyTypeDto { Id = 27, UniqueId = 27.ToGuid(), DataTypeId = Constants.System.DefaultMediaListViewDataTypeId, ContentTypeId = 1031, PropertyTypeGroupId = 5, Alias = "contents", Name = "Contents:", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null });
|
||||
_database.Insert("cmsPropertyType", "id", false, new PropertyTypeDto { Id = 27, UniqueId = 27.ToGuid(), DataTypeId = -38, ContentTypeId = 1031, PropertyTypeGroupId = 5, Alias = "contents", Name = "Contents:", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null });
|
||||
//membership property types
|
||||
_database.Insert("cmsPropertyType", "id", false, new PropertyTypeDto { Id = 28, UniqueId = 28.ToGuid(), DataTypeId = -89, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.Comments, Name = Constants.Conventions.Member.CommentsLabel, SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null });
|
||||
_database.Insert("cmsPropertyType", "id", false, new PropertyTypeDto { Id = 29, UniqueId = 29.ToGuid(), DataTypeId = -92, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.FailedPasswordAttempts, Name = Constants.Conventions.Member.FailedPasswordAttemptsLabel, SortOrder = 1, Mandatory = false, ValidationRegExp = null, Description = null });
|
||||
@@ -230,7 +231,8 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 6, DataTypeId = -90, PropertyEditorAlias = Constants.PropertyEditors.UploadFieldAlias, DbType = "Nvarchar" });
|
||||
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 7, DataTypeId = -92, PropertyEditorAlias = Constants.PropertyEditors.NoEditAlias, DbType = "Nvarchar" });
|
||||
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 8, DataTypeId = -36, PropertyEditorAlias = Constants.PropertyEditors.DateTimeAlias, DbType = "Date" });
|
||||
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 9, DataTypeId = -37, PropertyEditorAlias = Constants.PropertyEditors.ColorPickerAlias, DbType = "Nvarchar" });
|
||||
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 9, DataTypeId = -37, PropertyEditorAlias = Constants.PropertyEditors.ColorPickerAlias, DbType = "Nvarchar" });
|
||||
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 10, DataTypeId = -38, PropertyEditorAlias = Constants.PropertyEditors.FolderBrowserAlias, DbType = "Nvarchar" });
|
||||
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 11, DataTypeId = -39, PropertyEditorAlias = Constants.PropertyEditors.DropDownListMultipleAlias, DbType = "Nvarchar" });
|
||||
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 12, DataTypeId = -40, PropertyEditorAlias = Constants.PropertyEditors.RadioButtonListAlias, DbType = "Nvarchar" });
|
||||
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 13, DataTypeId = -41, PropertyEditorAlias = Constants.PropertyEditors.DateAlias, DbType = "Date" });
|
||||
@@ -251,6 +253,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
//_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 19, DataTypeId = 1038, PropertyEditorAlias = Constants.PropertyEditors.MarkdownEditorAlias, DbType = "Ntext" });
|
||||
//_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 20, DataTypeId = 1039, PropertyEditorAlias = Constants.PropertyEditors.UltimatePickerAlias, DbType = "Ntext" });
|
||||
//_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 23, DataTypeId = 1042, PropertyEditorAlias = Constants.PropertyEditors.MacroContainerAlias, DbType = "Ntext" });
|
||||
|
||||
}
|
||||
|
||||
private void CreateCmsDataTypePreValuesData()
|
||||
@@ -266,17 +269,6 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
_database.Insert("cmsDataTypePreValues", "id", false, new DataTypePreValueDto { Id = -2, Alias = "orderBy", SortOrder = 2, DataTypeNodeId = Constants.System.DefaultMembersListViewDataTypeId, Value = "Name" });
|
||||
_database.Insert("cmsDataTypePreValues", "id", false, new DataTypePreValueDto { Id = -3, Alias = "orderDirection", SortOrder = 3, DataTypeNodeId = Constants.System.DefaultMembersListViewDataTypeId, Value = "asc" });
|
||||
_database.Insert("cmsDataTypePreValues", "id", false, new DataTypePreValueDto { Id = -4, Alias = "includeProperties", SortOrder = 4, DataTypeNodeId = Constants.System.DefaultMembersListViewDataTypeId, Value = "[{\"alias\":\"email\",\"isSystem\":1},{\"alias\":\"username\",\"isSystem\":1},{\"alias\":\"updateDate\",\"header\":\"Last edited\",\"isSystem\":1}]" });
|
||||
|
||||
//layouts for the list view
|
||||
var cardLayout = "{\"name\": \"Grid\",\"path\": \"views/propertyeditors/listview/layouts/grid/grid.html\", \"icon\": \"icon-thumbnails-small\", \"isSystem\": 1, \"selected\": true}";
|
||||
var listLayout = "{\"name\": \"List\",\"path\": \"views/propertyeditors/listview/layouts/list/list.html\",\"icon\": \"icon-list\", \"isSystem\": 1,\"selected\": true}";
|
||||
|
||||
//defaults for the media list
|
||||
_database.Insert("cmsDataTypePreValues", "id", false, new DataTypePreValueDto { Id = -5, Alias = "pageSize", SortOrder = 1, DataTypeNodeId = Constants.System.DefaultMediaListViewDataTypeId, Value = "100" });
|
||||
_database.Insert("cmsDataTypePreValues", "id", false, new DataTypePreValueDto { Id = -6, Alias = "orderBy", SortOrder = 2, DataTypeNodeId = Constants.System.DefaultMediaListViewDataTypeId, Value = "VersionDate" });
|
||||
_database.Insert("cmsDataTypePreValues", "id", false, new DataTypePreValueDto { Id = -7, Alias = "orderDirection", SortOrder = 3, DataTypeNodeId = Constants.System.DefaultMediaListViewDataTypeId, Value = "desc" });
|
||||
_database.Insert("cmsDataTypePreValues", "id", false, new DataTypePreValueDto { Id = -8, Alias = "layouts", SortOrder = 4, DataTypeNodeId = Constants.System.DefaultMediaListViewDataTypeId, Value = "[" + cardLayout + "," + listLayout + "]" });
|
||||
_database.Insert("cmsDataTypePreValues", "id", false, new DataTypePreValueDto { Id = -9, Alias = "includeProperties", SortOrder = 5, DataTypeNodeId = Constants.System.DefaultMediaListViewDataTypeId, Value = "[{\"alias\":\"sortOrder\",\"isSystem\":1, \"header\": \"Sort order\"},{\"alias\":\"updateDate\",\"header\":\"Last edited\",\"isSystem\":1},{\"alias\":\"owner\",\"header\":\"Updated by\",\"isSystem\":1}]" });
|
||||
}
|
||||
|
||||
private void CreateUmbracoRelationTypeData()
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
{4, typeof (ContentVersionDto)},
|
||||
{5, typeof (DocumentDto)},
|
||||
|
||||
{6, typeof (ContentTypeTemplateDto)},
|
||||
{6, typeof (DocumentTypeDto)},
|
||||
{7, typeof (DataTypeDto)},
|
||||
{8, typeof (DataTypePreValueDto)},
|
||||
{9, typeof (DictionaryDto)},
|
||||
@@ -82,9 +82,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
{42, typeof (AccessRuleDto)},
|
||||
{43, typeof(CacheInstructionDto)},
|
||||
{44, typeof (ExternalLoginDto)},
|
||||
{45, typeof (MigrationDto)},
|
||||
{46, typeof (UmbracoDeployChecksumDto)},
|
||||
{47, typeof (UmbracoDeployDependencyDto)}
|
||||
{45, typeof (MigrationDto)}
|
||||
};
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -119,12 +119,6 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
return new Version(7, 2, 5);
|
||||
}
|
||||
|
||||
//if the error is for umbracoDeployChecksum it must be the previous version to 7.4 since that is when it is added
|
||||
if (Errors.Any(x => x.Item1.Equals("Table") && (x.Item2.InvariantEquals("umbracoDeployChecksum"))))
|
||||
{
|
||||
return new Version(7, 3, 4);
|
||||
}
|
||||
|
||||
return UmbracoVersion.Current;
|
||||
}
|
||||
|
||||
|
||||
@@ -289,7 +289,7 @@ namespace Umbraco.Core.Persistence.Migrations
|
||||
//NOTE: We CANNOT do this as part of the transaction!!! This is because when upgrading to 7.3, we cannot
|
||||
// create the migrations table and then add data to it in the same transaction without issuing things like GO
|
||||
// commands and since we need to support all Dbs, we need to just do this after the fact.
|
||||
var exists = _migrationEntryService.FindEntry(GlobalSettings.UmbracoMigrationName, _targetVersion);
|
||||
var exists = _migrationEntryService.FindEntry(_productName, _targetVersion);
|
||||
if (exists == null)
|
||||
{
|
||||
_migrationEntryService.CreateEntry(_productName, _targetVersion);
|
||||
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFourZero
|
||||
{
|
||||
[Migration("7.4.0", 1, GlobalSettings.UmbracoMigrationName)]
|
||||
public class AddDataDecimalColumn : MigrationBase
|
||||
{
|
||||
public AddDataDecimalColumn(ISqlSyntaxProvider sqlSyntax, ILogger logger)
|
||||
: base(sqlSyntax, logger)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
//Don't exeucte if the column is already there
|
||||
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals("cmsPropertyData") && x.ColumnName.InvariantEquals("dataDecimal")) == false)
|
||||
Create.Column("dataDecimal").OnTable("cmsPropertyData").AsDecimal().Nullable();
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
-48
@@ -1,48 +0,0 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFourZero
|
||||
{
|
||||
[Migration("7.4.0", 5, GlobalSettings.UmbracoMigrationName)]
|
||||
public class AddUmbracoDeployTables : MigrationBase
|
||||
{
|
||||
public AddUmbracoDeployTables(ISqlSyntaxProvider sqlSyntax, ILogger logger)
|
||||
: base(sqlSyntax, logger)
|
||||
{ }
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
//Don't exeucte if the table is already there
|
||||
var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
|
||||
if (tables.InvariantContains("umbracoDeployChecksum")) return;
|
||||
|
||||
Create.Table("umbracoDeployChecksum")
|
||||
.WithColumn("id").AsInt32().Identity().PrimaryKey("PK_umbracoDeployChecksum")
|
||||
.WithColumn("entityType").AsString(32).NotNullable()
|
||||
.WithColumn("entityGuid").AsGuid().Nullable()
|
||||
.WithColumn("entityPath").AsString(256).Nullable()
|
||||
.WithColumn("localChecksum").AsString(32).NotNullable()
|
||||
.WithColumn("compositeChecksum").AsString(32).Nullable();
|
||||
|
||||
Create.Table("umbracoDeployDependency")
|
||||
.WithColumn("sourceId").AsInt32().NotNullable().ForeignKey("FK_umbracoDeployDependency_umbracoDeployChecksum_id1", "umbracoDeployChecksum", "id")
|
||||
.WithColumn("targetId").AsInt32().NotNullable().ForeignKey("FK_umbracoDeployDependency_umbracoDeployChecksum_id2", "umbracoDeployChecksum", "id")
|
||||
.WithColumn("mode").AsInt32().NotNullable();
|
||||
|
||||
Create.PrimaryKey("PK_umbracoDeployDependency").OnTable("umbracoDeployDependency").Columns(new[] {"sourceId", "targetId"});
|
||||
|
||||
Create.Index("IX_umbracoDeployChecksum").OnTable("umbracoDeployChecksum")
|
||||
.OnColumn("entityType")
|
||||
.Ascending()
|
||||
.OnColumn("entityGuid")
|
||||
.Ascending()
|
||||
.OnColumn("entityPath")
|
||||
.Unique();
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{ }
|
||||
}
|
||||
}
|
||||
-80
@@ -1,80 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFourZero
|
||||
{
|
||||
[Migration("7.4.0", 2, GlobalSettings.UmbracoMigrationName)]
|
||||
public class AddUniqueIdPropertyTypeGroupColumn : MigrationBase
|
||||
{
|
||||
public AddUniqueIdPropertyTypeGroupColumn(ISqlSyntaxProvider sqlSyntax, ILogger logger)
|
||||
: base(sqlSyntax, logger)
|
||||
{ }
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
// don't execute if the column is already there
|
||||
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals("cmsPropertyTypeGroup") && x.ColumnName.InvariantEquals("uniqueID")) == false)
|
||||
{
|
||||
Create.Column("uniqueID").OnTable("cmsPropertyTypeGroup").AsGuid().NotNullable().WithDefault(SystemMethods.NewGuid);
|
||||
|
||||
// unique constraint on name + version
|
||||
Create.Index("IX_cmsPropertyTypeGroupUniqueID").OnTable("cmsPropertyTypeGroup")
|
||||
.OnColumn("uniqueID").Ascending()
|
||||
.WithOptions()
|
||||
.NonClustered()
|
||||
.WithOptions()
|
||||
.Unique();
|
||||
|
||||
// fill in the data in a way that is consistent over all environments
|
||||
// (ie cannot use random guids, http://issues.umbraco.org/issue/U4-6942)
|
||||
|
||||
foreach (var data in Context.Database.Query<dynamic>(@"
|
||||
SELECT cmsPropertyTypeGroup.id grId, cmsPropertyTypeGroup.text grName, cmsContentType.alias ctAlias, umbracoNode.nodeObjectType nObjType
|
||||
FROM cmsPropertyTypeGroup
|
||||
INNER JOIN cmsContentType
|
||||
ON cmsPropertyTypeGroup.contentTypeNodeId = cmsContentType.nodeId
|
||||
INNER JOIN umbracoNode
|
||||
ON cmsContentType.nodeId = umbracoNode.id"))
|
||||
{
|
||||
Guid guid;
|
||||
// see BaseDataCreation... built-in groups have their own guids
|
||||
if (data.grId == 3)
|
||||
{
|
||||
guid = new Guid(Constants.PropertyTypeGroups.Image);
|
||||
}
|
||||
else if (data.grId == 4)
|
||||
{
|
||||
guid = new Guid(Constants.PropertyTypeGroups.File);
|
||||
}
|
||||
else if (data.grId == 5)
|
||||
{
|
||||
guid = new Guid(Constants.PropertyTypeGroups.Contents);
|
||||
}
|
||||
else if (data.grId == 11)
|
||||
{
|
||||
guid = new Guid(Constants.PropertyTypeGroups.Membership);
|
||||
}
|
||||
else
|
||||
{
|
||||
// create a consistent guid from
|
||||
// group name + content type alias + object type
|
||||
string guidSource = data.grName + data.ctAlias + data.nObjType;
|
||||
guid = guidSource.ToGuid();
|
||||
}
|
||||
|
||||
// set the Unique Id to the one we've generated
|
||||
Update.Table("cmsPropertyTypeGroup").Set(new { uniqueID = guid }).Where(new { id = data.grId });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{ }
|
||||
}
|
||||
}
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFourZero
|
||||
{
|
||||
/// <summary>
|
||||
/// Courier on v. 7.4+ will handle ContentTypes using GUIDs instead of
|
||||
/// alias, so we need to ensure that these are initially consistent on
|
||||
/// all environments (based on the alias).
|
||||
/// </summary>
|
||||
[Migration("7.4.0", 3, GlobalSettings.UmbracoMigrationName)]
|
||||
public class EnsureContentTypeUniqueIdsAreConsistent : MigrationBase
|
||||
{
|
||||
public EnsureContentTypeUniqueIdsAreConsistent(ISqlSyntaxProvider sqlSyntax, ILogger logger)
|
||||
: base(sqlSyntax, logger)
|
||||
{ }
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
var objectTypes = new[]
|
||||
{
|
||||
Constants.ObjectTypes.DocumentTypeGuid,
|
||||
Constants.ObjectTypes.MediaTypeGuid,
|
||||
Constants.ObjectTypes.MemberTypeGuid,
|
||||
};
|
||||
|
||||
var sql = new Sql()
|
||||
.Select("umbracoNode.id,cmsContentType.alias,umbracoNode.nodeObjectType")
|
||||
.From<NodeDto>(SqlSyntax)
|
||||
.InnerJoin<ContentTypeDto>(SqlSyntax)
|
||||
.On<NodeDto, ContentTypeDto>(SqlSyntax, dto => dto.NodeId, dto => dto.NodeId)
|
||||
.WhereIn<NodeDto>(x => x.NodeObjectType, objectTypes);
|
||||
|
||||
var rows = Context.Database.Fetch<dynamic>(sql);
|
||||
|
||||
foreach (var row in rows)
|
||||
{
|
||||
// create a consistent guid from
|
||||
// alias + object type
|
||||
var guidSource = ((string) row.alias) + ((Guid) row.nodeObjectType);
|
||||
var guid = guidSource.ToGuid();
|
||||
|
||||
// set the Unique Id to the one we've generated
|
||||
Update.Table("umbracoNode").Set(new { uniqueID = guid }).Where(new { id = row.id });
|
||||
}
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{ }
|
||||
}
|
||||
}
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFourZero
|
||||
{
|
||||
[Migration("7.4.0", 4, GlobalSettings.UmbracoMigrationName)]
|
||||
public class FixListViewMediaSortOrder : MigrationBase
|
||||
{
|
||||
public FixListViewMediaSortOrder(ISqlSyntaxProvider sqlSyntax, ILogger logger)
|
||||
: base(sqlSyntax, logger)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
var mediaListviewIncludeProperties = Context.Database.Fetch<DataTypePreValueDto>(new Sql().Select("*").From<DataTypePreValueDto>(SqlSyntax).Where<DataTypePreValueDto>(x => x.Id == -9)).FirstOrDefault();
|
||||
if (mediaListviewIncludeProperties != null)
|
||||
{
|
||||
if (mediaListviewIncludeProperties.Value.Contains("\"alias\":\"sort\""))
|
||||
{
|
||||
mediaListviewIncludeProperties.Value = mediaListviewIncludeProperties.Value.Replace("\"alias\":\"sort\"", "\"alias\":\"sortOrder\"");
|
||||
Context.Database.InsertOrUpdate(mediaListviewIncludeProperties);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFourZero
|
||||
{
|
||||
[Migration("7.4.0", 4, GlobalSettings.UmbracoMigrationName)]
|
||||
public class RemoveParentIdPropertyTypeGroupColumn : MigrationBase
|
||||
{
|
||||
public RemoveParentIdPropertyTypeGroupColumn(ISqlSyntaxProvider sqlSyntax, ILogger logger)
|
||||
: base(sqlSyntax, logger)
|
||||
{ }
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
// don't execute if the column is not there anymore
|
||||
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals("cmsPropertyTypeGroup") && x.ColumnName.InvariantEquals("parentGroupId")) == false)
|
||||
return;
|
||||
|
||||
Delete.ForeignKey("FK_cmsPropertyTypeGroup_cmsPropertyTypeGroup_id").OnTable("cmsPropertyTypeGroup");
|
||||
Delete.Column("parentGroupId").FromTable("cmsPropertyTypeGroup");
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{ }
|
||||
}
|
||||
}
|
||||
+18
-12
@@ -5,13 +5,15 @@ using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZero
|
||||
{
|
||||
{
|
||||
|
||||
[Migration("7.3.0", 13, GlobalSettings.UmbracoMigrationName)]
|
||||
public class AddUniqueIdPropertyTypeColumn : MigrationBase
|
||||
{
|
||||
public AddUniqueIdPropertyTypeColumn(ISqlSyntaxProvider sqlSyntax, ILogger logger)
|
||||
: base(sqlSyntax, logger)
|
||||
{ }
|
||||
{
|
||||
}
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
@@ -22,7 +24,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe
|
||||
{
|
||||
Create.Column("uniqueID").OnTable("cmsPropertyType").AsGuid().NotNullable().WithDefault(SystemMethods.NewGuid);
|
||||
|
||||
// unique constraint on name + version
|
||||
//unique constraint on name + version
|
||||
Create.Index("IX_cmsPropertyTypeUniqueID").OnTable("cmsPropertyType")
|
||||
.OnColumn("uniqueID").Ascending()
|
||||
.WithOptions()
|
||||
@@ -30,8 +32,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe
|
||||
.WithOptions()
|
||||
.Unique();
|
||||
|
||||
// fill in the data in a way that is consistent over all environments
|
||||
// (ie cannot use random guids, http://issues.umbraco.org/issue/U4-6942)
|
||||
//now we need to fill in the data so that it is consistent, we can't have it generating random GUIDs for
|
||||
// the already existing data, see: http://issues.umbraco.org/issue/U4-6942
|
||||
|
||||
foreach (var data in Context.Database.Query<dynamic>(@"
|
||||
SELECT cmsPropertyType.id ptId, cmsPropertyType.Alias ptAlias, cmsContentType.alias ctAlias, umbracoNode.nodeObjectType nObjType
|
||||
@@ -41,18 +43,22 @@ ON cmsPropertyType.contentTypeId = cmsContentType.nodeId
|
||||
INNER JOIN umbracoNode
|
||||
ON cmsContentType.nodeId = umbracoNode.id"))
|
||||
{
|
||||
// create a consistent guid from
|
||||
// property alias + content type alias + object type
|
||||
string guidSource = data.ptAlias + data.ctAlias + data.nObjType;
|
||||
var guid = guidSource.ToGuid();
|
||||
//create a guid from the concatenation of the:
|
||||
// property type alias + the doc type alias + the content type node object type
|
||||
// - the latter is required because there can be a content type and media type with the same alias!!
|
||||
string concatAlias = data.ptAlias + data.ctAlias + data.nObjType;
|
||||
var ptGuid = concatAlias.ToGuid();
|
||||
|
||||
// set the Unique Id to the one we've generated
|
||||
Update.Table("cmsPropertyType").Set(new { uniqueID = guid }).Where(new { id = data.ptId });
|
||||
//set the Unique Id to the one we've generated
|
||||
Update.Table("cmsPropertyType").Set(new {uniqueID = ptGuid}).Where(new {id = data.ptId });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{ }
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
+40
-35
@@ -28,55 +28,60 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixZeroOne
|
||||
{
|
||||
if (database != null)
|
||||
{
|
||||
//Fetch all PropertyTypes that belongs to a PropertyTypeGroup
|
||||
//Fetch all PropertyTypes that belongs to a PropertyTypeGroup
|
||||
//NOTE: We are writing the full query because we've added a column to the PropertyTypeDto in later versions so one of the columns
|
||||
// won't exist yet
|
||||
//NOTE: We're using dynamic to avoid having this migration fail due to the UniqueId column added in 7.3 (this column is not added
|
||||
// in the table yet and will make the mapping of done by Fetch fail when the actual type is used here).
|
||||
var propertyTypes = database.Fetch<dynamic>("SELECT * FROM cmsPropertyType WHERE propertyTypeGroupId > 0");
|
||||
|
||||
var propertyGroups = database.Fetch<PropertyTypeGroupDto>("WHERE id > 0");
|
||||
|
||||
foreach (var propertyType in propertyTypes)
|
||||
{
|
||||
// get the PropertyTypeGroup of the current PropertyType, skip if not found
|
||||
var propertyTypeGroup = propertyGroups.FirstOrDefault(x => x.Id == propertyType.propertyTypeGroupId);
|
||||
if (propertyTypeGroup == null) continue;
|
||||
|
||||
// if the PropretyTypeGroup belongs to the same content type as the PropertyType, then fine
|
||||
if (propertyTypeGroup.ContentTypeNodeId == propertyType.contentTypeId) continue;
|
||||
|
||||
// else we want to assign the PropertyType to a proper PropertyTypeGroup
|
||||
// ie one that does belong to the same content - look for it
|
||||
var okPropertyTypeGroup = propertyGroups.FirstOrDefault(x =>
|
||||
x.Text == propertyTypeGroup.Text && // same name
|
||||
x.ContentTypeNodeId == propertyType.contentTypeId); // but for proper content type
|
||||
|
||||
if (okPropertyTypeGroup == null)
|
||||
//Get the PropertyTypeGroup that the current PropertyType references
|
||||
var parentPropertyTypeGroup = propertyGroups.FirstOrDefault(x => x.Id == propertyType.propertyTypeGroupId);
|
||||
if (parentPropertyTypeGroup != null)
|
||||
{
|
||||
// does not exist, create a new PropertyTypeGroup,
|
||||
var propertyGroup = new PropertyTypeGroupDto
|
||||
//If the ContentType is the same on the PropertyType and the PropertyTypeGroup the group is valid and we skip to the next
|
||||
if (parentPropertyTypeGroup.ContentTypeNodeId == propertyType.contentTypeId) continue;
|
||||
|
||||
//Check if the 'new' PropertyTypeGroup has already been created
|
||||
var existingPropertyTypeGroup =
|
||||
propertyGroups.FirstOrDefault(
|
||||
x =>
|
||||
x.ParentGroupId == parentPropertyTypeGroup.Id && x.Text == parentPropertyTypeGroup.Text &&
|
||||
x.ContentTypeNodeId == propertyType.contentTypeId);
|
||||
|
||||
//This should ensure that we don't create duplicate groups for a single ContentType
|
||||
if (existingPropertyTypeGroup == null)
|
||||
{
|
||||
ContentTypeNodeId = propertyType.contentTypeId,
|
||||
Text = propertyTypeGroup.Text,
|
||||
SortOrder = propertyTypeGroup.SortOrder
|
||||
};
|
||||
//Create a new PropertyTypeGroup that references the parent group that the PropertyType was referencing pre-6.0.1
|
||||
var propertyGroup = new PropertyTypeGroupDto
|
||||
{
|
||||
ContentTypeNodeId = propertyType.contentTypeId,
|
||||
ParentGroupId = parentPropertyTypeGroup.Id,
|
||||
Text = parentPropertyTypeGroup.Text,
|
||||
SortOrder = parentPropertyTypeGroup.SortOrder
|
||||
};
|
||||
|
||||
// save + add to list of groups
|
||||
int id = Convert.ToInt16(database.Insert(propertyGroup));
|
||||
propertyGroup.Id = id;
|
||||
propertyGroups.Add(propertyGroup);
|
||||
|
||||
// update the PropertyType to use the new PropertyTypeGroup
|
||||
propertyType.propertyTypeGroupId = id;
|
||||
//Save the PropertyTypeGroup in the database and update the list of groups with this new group
|
||||
int id = Convert.ToInt16(database.Insert(propertyGroup));
|
||||
propertyGroup.Id = id;
|
||||
propertyGroups.Add(propertyGroup);
|
||||
//Update the reference to the new PropertyTypeGroup on the current PropertyType
|
||||
propertyType.propertyTypeGroupId = id;
|
||||
database.Update("cmsPropertyType", "id", propertyType);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Update the reference to the existing PropertyTypeGroup on the current PropertyType
|
||||
propertyType.propertyTypeGroupId = existingPropertyTypeGroup.Id;
|
||||
database.Update("cmsPropertyType", "id", propertyType);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// exists, update PropertyType to use the PropertyTypeGroup
|
||||
propertyType.propertyTypeGroupId = okPropertyTypeGroup.Id;
|
||||
}
|
||||
database.Update("cmsPropertyType", "id", propertyType);
|
||||
}
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -834,7 +834,7 @@ namespace Umbraco.Core.Persistence
|
||||
var pd = PocoData.ForType(typeof(T));
|
||||
try
|
||||
{
|
||||
r = cmd.ExecuteReader();
|
||||
r = cmd.ExecuteReaderWithRetry();
|
||||
OnExecutedCommand(cmd);
|
||||
}
|
||||
catch (Exception x)
|
||||
|
||||
@@ -18,8 +18,11 @@ namespace Umbraco.Core.Persistence.Relators
|
||||
// Is this the same DictionaryItem as the current one we're processing
|
||||
if (Current != null && Current.Id == a.Id)
|
||||
{
|
||||
// Yes, just add this User2AppDto to the current item's collection
|
||||
Current.User2AppDtos.Add(p);
|
||||
if (p.AppAlias.IsNullOrWhiteSpace() == false)
|
||||
{
|
||||
// Yes, just add this User2AppDto to the current item's collection
|
||||
Current.User2AppDtos.Add(p);
|
||||
}
|
||||
|
||||
// Return null to indicate we're not done with this User yet
|
||||
return null;
|
||||
@@ -35,7 +38,7 @@ namespace Umbraco.Core.Persistence.Relators
|
||||
Current = a;
|
||||
Current.User2AppDtos = new List<User2AppDto>();
|
||||
//this can be null since we are doing a left join
|
||||
if (p.AppAlias != null)
|
||||
if (p.AppAlias.IsNullOrWhiteSpace() == false)
|
||||
{
|
||||
Current.User2AppDtos.Add(p);
|
||||
}
|
||||
|
||||
@@ -155,8 +155,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
"DELETE FROM cmsContentVersion WHERE ContentId = @Id",
|
||||
"DELETE FROM cmsContentXml WHERE nodeId = @Id",
|
||||
"DELETE FROM cmsContent WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoNode WHERE id = @Id",
|
||||
"DELETE FROM umbracoAccess WHERE nodeId = @Id"
|
||||
"DELETE FROM umbracoAccess WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoNode WHERE id = @Id"
|
||||
};
|
||||
return list;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Exceptions;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
@@ -13,7 +12,6 @@ using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Persistence.Relators;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
@@ -28,42 +26,54 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
: base(work, cache, logger, sqlSyntax)
|
||||
{
|
||||
_templateRepository = templateRepository;
|
||||
}
|
||||
}
|
||||
|
||||
private FullDataSetRepositoryCachePolicyFactory<IContentType, int> _cachePolicyFactory;
|
||||
protected override IRepositoryCachePolicyFactory<IContentType, int> CachePolicyFactory
|
||||
{
|
||||
get
|
||||
{
|
||||
//Use a FullDataSet cache policy - this will cache the entire GetAll result in a single collection
|
||||
return _cachePolicyFactory ?? (_cachePolicyFactory = new FullDataSetRepositoryCachePolicyFactory<IContentType, int>(
|
||||
RuntimeCache, GetEntityId, () => PerformGetAll(),
|
||||
//allow this cache to expire
|
||||
expires:true));
|
||||
}
|
||||
}
|
||||
|
||||
protected override IContentType PerformGet(int id)
|
||||
{
|
||||
var contentTypes = ContentTypeQueryMapper.GetContentTypes(
|
||||
new[] {id}, Database, SqlSyntax, this, _templateRepository);
|
||||
|
||||
var contentType = contentTypes.SingleOrDefault();
|
||||
return contentType;
|
||||
//use the underlying GetAll which will force cache all content types
|
||||
return GetAll().FirstOrDefault(x => x.Id == id);
|
||||
}
|
||||
|
||||
protected override IEnumerable<IContentType> PerformGetAll(params int[] ids)
|
||||
{
|
||||
if (ids.Any())
|
||||
{
|
||||
return ContentTypeQueryMapper.GetContentTypes(ids, Database, SqlSyntax, this, _templateRepository);
|
||||
}
|
||||
else
|
||||
{
|
||||
var sql = new Sql().Select("id").From<NodeDto>(SqlSyntax).Where<NodeDto>(dto => dto.NodeObjectType == NodeObjectTypeId);
|
||||
var allIds = Database.Fetch<int>(sql).ToArray();
|
||||
return ContentTypeQueryMapper.GetContentTypes(allIds, Database, SqlSyntax, this, _templateRepository);
|
||||
//NOTE: This logic should never be executed according to our cache policy
|
||||
return ContentTypeQueryMapper.GetContentTypes(Database, SqlSyntax, this, _templateRepository)
|
||||
.Where(x => ids.Contains(x.Id));
|
||||
}
|
||||
|
||||
return ContentTypeQueryMapper.GetContentTypes(Database, SqlSyntax, this, _templateRepository);
|
||||
}
|
||||
|
||||
protected override IEnumerable<IContentType> PerformGetByQuery(IQuery<IContentType> query)
|
||||
{
|
||||
var sqlClause = GetBaseQuery(false);
|
||||
var translator = new SqlTranslator<IContentType>(sqlClause, query);
|
||||
var sql = translator.Translate()
|
||||
.OrderBy<NodeDto>(x => x.Text, SqlSyntax);
|
||||
var sql = translator.Translate();
|
||||
|
||||
var dtos = Database.Fetch<ContentTypeTemplateDto, ContentTypeDto, NodeDto>(sql);
|
||||
return dtos.Any()
|
||||
? GetAll(dtos.DistinctBy(x => x.ContentTypeDto.NodeId).Select(x => x.ContentTypeDto.NodeId).ToArray())
|
||||
: Enumerable.Empty<IContentType>();
|
||||
var dtos = Database.Fetch<DocumentTypeDto, ContentTypeDto, NodeDto>(sql);
|
||||
|
||||
return
|
||||
//This returns a lookup from the GetAll cached looup
|
||||
(dtos.Any()
|
||||
? GetAll(dtos.DistinctBy(x => x.ContentTypeDto.NodeId).Select(x => x.ContentTypeDto.NodeId).ToArray())
|
||||
: Enumerable.Empty<IContentType>())
|
||||
//order the result by name
|
||||
.OrderBy(x => x.Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -87,17 +97,19 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
return Database.Fetch<string>("SELECT DISTINCT Alias FROM cmsPropertyType ORDER BY Alias");
|
||||
}
|
||||
|
||||
|
||||
#region Overrides of PetaPocoRepositoryBase<int,IContentType>
|
||||
|
||||
protected override Sql GetBaseQuery(bool isCount)
|
||||
{
|
||||
var sql = new Sql();
|
||||
|
||||
sql.Select(isCount ? "COUNT(*)" : "*")
|
||||
.From<ContentTypeDto>(SqlSyntax)
|
||||
.InnerJoin<NodeDto>(SqlSyntax)
|
||||
.On<ContentTypeDto, NodeDto>(SqlSyntax, left => left.NodeId, right => right.NodeId)
|
||||
.LeftJoin<ContentTypeTemplateDto>(SqlSyntax)
|
||||
.On<ContentTypeTemplateDto, ContentTypeDto>(SqlSyntax, left => left.ContentTypeNodeId, right => right.NodeId)
|
||||
.From<ContentTypeDto>()
|
||||
.InnerJoin<NodeDto>()
|
||||
.On<ContentTypeDto, NodeDto>(left => left.NodeId, right => right.NodeId)
|
||||
.LeftJoin<DocumentTypeDto>()
|
||||
.On<DocumentTypeDto, ContentTypeDto>(left => left.ContentTypeNodeId, right => right.NodeId)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == NodeObjectTypeId);
|
||||
|
||||
return sql;
|
||||
@@ -132,7 +144,11 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
get { return new Guid(Constants.ObjectTypes.DocumentType); }
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Unit of Work Implementation
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a content type
|
||||
/// </summary>
|
||||
@@ -171,39 +187,26 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
((ContentType)entity).AddingEntity();
|
||||
|
||||
PersistNewBaseContentType(entity);
|
||||
PersistTemplates(entity, false);
|
||||
var factory = new ContentTypeFactory(NodeObjectTypeId);
|
||||
var dto = factory.BuildDto(entity);
|
||||
|
||||
PersistNewBaseContentType(dto.ContentTypeDto, entity);
|
||||
//Inserts data into the cmsDocumentType table if a template exists
|
||||
if (dto.TemplateNodeId > 0)
|
||||
{
|
||||
dto.ContentTypeNodeId = entity.Id;
|
||||
Database.Insert(dto);
|
||||
}
|
||||
|
||||
//Insert allowed Templates not including the default one, as that has already been inserted
|
||||
foreach (var template in entity.AllowedTemplates.Where(x => x != null && x.Id != dto.TemplateNodeId))
|
||||
{
|
||||
Database.Insert(new DocumentTypeDto { ContentTypeNodeId = entity.Id, TemplateNodeId = template.Id, IsDefault = false });
|
||||
}
|
||||
|
||||
entity.ResetDirtyProperties();
|
||||
}
|
||||
|
||||
protected void PersistTemplates(IContentType entity, bool clearAll)
|
||||
{
|
||||
// remove and insert, if required
|
||||
Database.Delete<ContentTypeTemplateDto>("WHERE contentTypeNodeId = @Id", new { Id = entity.Id });
|
||||
|
||||
// we could do it all in foreach if we assume that the default template is an allowed template??
|
||||
var defaultTemplateId = ((ContentType) entity).DefaultTemplateId;
|
||||
if (defaultTemplateId > 0)
|
||||
{
|
||||
Database.Insert(new ContentTypeTemplateDto
|
||||
{
|
||||
ContentTypeNodeId = entity.Id,
|
||||
TemplateNodeId = defaultTemplateId,
|
||||
IsDefault = true
|
||||
});
|
||||
}
|
||||
foreach (var template in entity.AllowedTemplates.Where(x => x != null && x.Id != defaultTemplateId))
|
||||
{
|
||||
Database.Insert(new ContentTypeTemplateDto
|
||||
{
|
||||
ContentTypeNodeId = entity.Id,
|
||||
TemplateNodeId = template.Id,
|
||||
IsDefault = false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected override void PersistUpdatedItem(IContentType entity)
|
||||
{
|
||||
ValidateAlias(entity);
|
||||
@@ -224,33 +227,59 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
entity.SortOrder = maxSortOrder + 1;
|
||||
}
|
||||
|
||||
PersistUpdatedBaseContentType(entity);
|
||||
PersistTemplates(entity, true);
|
||||
var factory = new ContentTypeFactory(NodeObjectTypeId);
|
||||
var dto = factory.BuildDto(entity);
|
||||
|
||||
PersistUpdatedBaseContentType(dto.ContentTypeDto, entity);
|
||||
|
||||
//Look up DocumentType entries for updating - this could possibly be a "remove all, insert all"-approach
|
||||
Database.Delete<DocumentTypeDto>("WHERE contentTypeNodeId = @Id", new { Id = entity.Id });
|
||||
//Insert the updated DocumentTypeDto if a template exists
|
||||
if (dto.TemplateNodeId > 0)
|
||||
{
|
||||
Database.Insert(dto);
|
||||
}
|
||||
|
||||
//Insert allowed Templates not including the default one, as that has already been inserted
|
||||
foreach (var template in entity.AllowedTemplates.Where(x => x != null && x.Id != dto.TemplateNodeId))
|
||||
{
|
||||
Database.Insert(new DocumentTypeDto { ContentTypeNodeId = entity.Id, TemplateNodeId = template.Id, IsDefault = false });
|
||||
}
|
||||
|
||||
entity.ResetDirtyProperties();
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
protected override IContentType PerformGet(Guid id)
|
||||
{
|
||||
var contentTypes = ContentTypeQueryMapper.GetContentTypes(
|
||||
new[] { id }, Database, SqlSyntax, this, _templateRepository);
|
||||
//use the underlying GetAll which will force cache all content types
|
||||
return GetAll().FirstOrDefault(x => x.Key == id);
|
||||
}
|
||||
|
||||
var contentType = contentTypes.SingleOrDefault();
|
||||
return contentType;
|
||||
protected override IContentType PerformGet(string alias)
|
||||
{
|
||||
//use the underlying GetAll which will force cache all content types
|
||||
return GetAll().FirstOrDefault(x => x.Alias.InvariantEquals(alias));
|
||||
}
|
||||
|
||||
protected override IEnumerable<IContentType> PerformGetAll(params Guid[] ids)
|
||||
{
|
||||
//use the underlying GetAll which will force cache all content types
|
||||
|
||||
if (ids.Any())
|
||||
{
|
||||
return ContentTypeQueryMapper.GetContentTypes(ids, Database, SqlSyntax, this, _templateRepository);
|
||||
return GetAll().Where(x => ids.Contains(x.Key));
|
||||
}
|
||||
else
|
||||
{
|
||||
var sql = new Sql().Select("id").From<NodeDto>(SqlSyntax).Where<NodeDto>(dto => dto.NodeObjectType == NodeObjectTypeId);
|
||||
var allIds = Database.Fetch<int>(sql).ToArray();
|
||||
return ContentTypeQueryMapper.GetContentTypes(allIds, Database, SqlSyntax, this, _templateRepository);
|
||||
return GetAll();
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool PerformExists(Guid id)
|
||||
{
|
||||
return GetAll().FirstOrDefault(x => x.Key == id) != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,6 @@ using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Exceptions;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
@@ -116,9 +114,9 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
var sql = new Sql();
|
||||
sql.Select(isCount ? "COUNT(*)" : "*")
|
||||
.From<DataTypeDto>(SqlSyntax)
|
||||
.InnerJoin<NodeDto>(SqlSyntax)
|
||||
.On<DataTypeDto, NodeDto>(SqlSyntax, left => left.DataTypeId, right => right.NodeId)
|
||||
.From<DataTypeDto>()
|
||||
.InnerJoin<NodeDto>()
|
||||
.On<DataTypeDto, NodeDto>(left => left.DataTypeId, right => right.NodeId)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == NodeObjectTypeId);
|
||||
return sql;
|
||||
}
|
||||
@@ -146,10 +144,6 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
((DataTypeDefinition)entity).AddingEntity();
|
||||
|
||||
//ensure a datatype has a unique name before creating it
|
||||
entity.Name = EnsureUniqueNodeName(entity.Name);
|
||||
|
||||
//TODO: should the below be removed?
|
||||
//Cannot add a duplicate data type
|
||||
var exists = Database.ExecuteScalar<int>(@"SELECT COUNT(*) FROM cmsDataType
|
||||
INNER JOIN umbracoNode ON cmsDataType.nodeId = umbracoNode.id
|
||||
@@ -195,8 +189,6 @@ WHERE umbracoNode." + SqlSyntax.GetQuotedColumnName("text") + "= @name", new { n
|
||||
protected override void PersistUpdatedItem(IDataTypeDefinition entity)
|
||||
{
|
||||
|
||||
entity.Name = EnsureUniqueNodeName(entity.Name, entity.Id);
|
||||
|
||||
//Cannot change to a duplicate alias
|
||||
var exists = Database.ExecuteScalar<int>(@"SELECT COUNT(*) FROM cmsDataType
|
||||
INNER JOIN umbracoNode ON cmsDataType.nodeId = umbracoNode.id
|
||||
@@ -329,47 +321,6 @@ AND umbracoNode.id <> @id",
|
||||
AddOrUpdatePreValues(dtd, values);
|
||||
}
|
||||
|
||||
public IEnumerable<MoveEventInfo<IDataTypeDefinition>> Move(IDataTypeDefinition toMove, EntityContainer container)
|
||||
{
|
||||
var parentId = -1;
|
||||
if (container != null)
|
||||
{
|
||||
// Check on paths
|
||||
if ((string.Format(",{0},", container.Path)).IndexOf(string.Format(",{0},", toMove.Id), StringComparison.Ordinal) > -1)
|
||||
{
|
||||
throw new DataOperationException<MoveOperationStatusType>(MoveOperationStatusType.FailedNotAllowedByPath);
|
||||
}
|
||||
parentId = container.Id;
|
||||
}
|
||||
|
||||
//used to track all the moved entities to be given to the event
|
||||
var moveInfo = new List<MoveEventInfo<IDataTypeDefinition>>
|
||||
{
|
||||
new MoveEventInfo<IDataTypeDefinition>(toMove, toMove.Path, parentId)
|
||||
};
|
||||
|
||||
//do the move to a new parent
|
||||
toMove.ParentId = parentId;
|
||||
//schedule it for updating in the transaction
|
||||
AddOrUpdate(toMove);
|
||||
|
||||
//update all descendants
|
||||
var descendants = this.GetByQuery(
|
||||
new Query<IDataTypeDefinition>().Where(type => type.Path.StartsWith(toMove.Path + ",")));
|
||||
foreach (var descendant in descendants)
|
||||
{
|
||||
moveInfo.Add(new MoveEventInfo<IDataTypeDefinition>(descendant, descendant.Path, descendant.ParentId));
|
||||
|
||||
//all we're doing here is setting the parent Id to be dirty so that it resets the path/level/etc...
|
||||
descendant.ParentId = descendant.ParentId + 1;
|
||||
descendant.ParentId = descendant.ParentId - 1;
|
||||
//schedule it for updating in the transaction
|
||||
AddOrUpdate(descendant);
|
||||
}
|
||||
|
||||
return moveInfo;
|
||||
}
|
||||
|
||||
public void AddOrUpdatePreValues(IDataTypeDefinition dataType, IDictionary<string, PreValue> values)
|
||||
{
|
||||
var currentVals = new DataTypePreValueDto[] { };
|
||||
@@ -377,9 +328,9 @@ AND umbracoNode.id <> @id",
|
||||
{
|
||||
//first just get all pre-values for this data type so we can compare them to see if we need to insert or update or replace
|
||||
var sql = new Sql().Select("*")
|
||||
.From<DataTypePreValueDto>(SqlSyntax)
|
||||
.From<DataTypePreValueDto>()
|
||||
.Where<DataTypePreValueDto>(dto => dto.DataTypeNodeId == dataType.Id)
|
||||
.OrderBy<DataTypePreValueDto>(dto => dto.SortOrder, SqlSyntax);
|
||||
.OrderBy<DataTypePreValueDto>(dto => dto.SortOrder);
|
||||
currentVals = Database.Fetch<DataTypePreValueDto>(sql).ToArray();
|
||||
}
|
||||
|
||||
@@ -464,37 +415,6 @@ AND umbracoNode.id <> @id",
|
||||
return collection;
|
||||
}
|
||||
|
||||
private string EnsureUniqueNodeName(string nodeName, int id = 0)
|
||||
{
|
||||
|
||||
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
.From<NodeDto>(SqlSyntax)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == NodeObjectTypeId && x.Text.StartsWith(nodeName));
|
||||
|
||||
int uniqueNumber = 1;
|
||||
var currentName = nodeName;
|
||||
|
||||
var dtos = Database.Fetch<NodeDto>(sql);
|
||||
if (dtos.Any())
|
||||
{
|
||||
var results = dtos.OrderBy(x => x.Text, new SimilarNodeNameComparer());
|
||||
foreach (var dto in results)
|
||||
{
|
||||
if (id != 0 && id == dto.NodeId) continue;
|
||||
|
||||
if (dto.Text.ToLowerInvariant().Equals(currentName.ToLowerInvariant()))
|
||||
{
|
||||
currentName = nodeName + string.Format(" ({0})", uniqueNumber);
|
||||
uniqueNumber++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return currentName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Private class to handle pre-value crud based on units of work with transactions
|
||||
/// </summary>
|
||||
@@ -605,8 +525,6 @@ AND umbracoNode.id <> @id",
|
||||
};
|
||||
Database.Update(dto);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
internal static class PreValueConverter
|
||||
|
||||
@@ -29,7 +29,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
get
|
||||
{
|
||||
//Use a FullDataSet cache policy - this will cache the entire GetAll result in a single collection
|
||||
return _cachePolicyFactory ?? (_cachePolicyFactory = new FullDataSetRepositoryCachePolicyFactory<IDomain, int>(RuntimeCache));
|
||||
return _cachePolicyFactory ?? (_cachePolicyFactory = new FullDataSetRepositoryCachePolicyFactory<IDomain, int>(
|
||||
RuntimeCache, GetEntityId, () => PerformGetAll(), false));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,255 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.Factories;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
/// <summary>
|
||||
/// An internal repository for managing entity containers such as doc type, media type, data type containers.
|
||||
/// </summary>
|
||||
internal class EntityContainerRepository : PetaPocoRepositoryBase<int, EntityContainer>
|
||||
{
|
||||
public EntityContainerRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
|
||||
: base(work, cache, logger, sqlSyntax)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Do not cache anything
|
||||
/// </summary>
|
||||
protected override IRuntimeCacheProvider RuntimeCache
|
||||
{
|
||||
get { return new NullCacheProvider(); }
|
||||
}
|
||||
|
||||
protected override EntityContainer PerformGet(int id)
|
||||
{
|
||||
var sql = GetBaseQuery(false).Where(GetBaseWhereClause(), new { id });
|
||||
|
||||
var nodeDto = Database.Fetch<NodeDto>(sql).FirstOrDefault();
|
||||
return nodeDto == null ? null : CreateEntity(nodeDto);
|
||||
}
|
||||
|
||||
// temp - so we don't have to implement GetByQuery
|
||||
public EntityContainer Get(Guid id)
|
||||
{
|
||||
var sql = GetBaseQuery(false).Where("UniqueId=@uniqueId", new { uniqueId = id });
|
||||
|
||||
var nodeDto = Database.Fetch<NodeDto>(sql).FirstOrDefault();
|
||||
return nodeDto == null ? null : CreateEntity(nodeDto);
|
||||
}
|
||||
|
||||
public IEnumerable<EntityContainer> Get(string name, int level, Guid umbracoObjectTypeId)
|
||||
{
|
||||
var sql = GetBaseQuery(false).Where("text=@name AND level=@level AND nodeObjectType=@umbracoObjectTypeId", new { name, level, umbracoObjectTypeId });
|
||||
return Database.Fetch<NodeDto>(sql).Select(CreateEntity);
|
||||
}
|
||||
|
||||
protected override IEnumerable<EntityContainer> PerformGetAll(params int[] ids)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override IEnumerable<EntityContainer> PerformGetByQuery(IQuery<EntityContainer> query)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private static EntityContainer CreateEntity(NodeDto nodeDto)
|
||||
{
|
||||
if (nodeDto.NodeObjectType.HasValue == false)
|
||||
throw new InvalidOperationException("Node with id " + nodeDto.NodeId + " has no object type.");
|
||||
|
||||
// throws if node is not a container
|
||||
var containedObjectType = EntityContainer.GetContainedObjectType(nodeDto.NodeObjectType.Value);
|
||||
|
||||
var entity = new EntityContainer(nodeDto.NodeId, nodeDto.UniqueId,
|
||||
nodeDto.ParentId, nodeDto.Path, nodeDto.Level, nodeDto.SortOrder,
|
||||
containedObjectType,
|
||||
nodeDto.Text, nodeDto.UserId ?? 0);
|
||||
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
// http://issues.umbraco.org/issue/U4-1946
|
||||
entity.ResetDirtyProperties(false);
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
protected override Sql GetBaseQuery(bool isCount)
|
||||
{
|
||||
var sql = new Sql();
|
||||
if (isCount)
|
||||
{
|
||||
sql.Select("COUNT(*)").From<NodeDto>(SqlSyntax);
|
||||
}
|
||||
else
|
||||
{
|
||||
sql.Select("*").From<NodeDto>(SqlSyntax);
|
||||
}
|
||||
return sql;
|
||||
}
|
||||
|
||||
protected override string GetBaseWhereClause()
|
||||
{
|
||||
return "umbracoNode.id = @id"; //" and nodeObjectType = @NodeObjectType";
|
||||
}
|
||||
|
||||
protected override IEnumerable<string> GetDeleteClauses()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override Guid NodeObjectTypeId
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
protected override void PersistDeletedItem(EntityContainer entity)
|
||||
{
|
||||
var nodeDto = Database.FirstOrDefault<NodeDto>(new Sql().Select("*")
|
||||
.From<NodeDto>(SqlSyntax)
|
||||
.Where<NodeDto>(dto => dto.NodeId == entity.Id && dto.NodeObjectType == entity.ContainerObjectType));
|
||||
|
||||
if (nodeDto == null) return;
|
||||
|
||||
// move children to the parent so they are not orphans
|
||||
var childDtos = Database.Fetch<NodeDto>(new Sql().Select("*")
|
||||
.From<NodeDto>(SqlSyntax)
|
||||
.Where("parentID=@parentID AND (nodeObjectType=@containedObjectType OR nodeObjectType=@containerObjectType)",
|
||||
new
|
||||
{
|
||||
parentID = entity.Id,
|
||||
containedObjectType = entity.ContainedObjectType,
|
||||
containerObjectType = entity.ContainerObjectType
|
||||
}));
|
||||
|
||||
foreach (var childDto in childDtos)
|
||||
{
|
||||
childDto.ParentId = nodeDto.ParentId;
|
||||
Database.Update(childDto);
|
||||
}
|
||||
|
||||
// delete
|
||||
Database.Delete(nodeDto);
|
||||
}
|
||||
|
||||
protected override void PersistNewItem(EntityContainer entity)
|
||||
{
|
||||
entity.Name = entity.Name.Trim();
|
||||
Mandate.ParameterNotNullOrEmpty(entity.Name, "entity.Name");
|
||||
|
||||
// guard against duplicates
|
||||
var nodeDto = Database.FirstOrDefault<NodeDto>(new Sql().Select("*")
|
||||
.From<NodeDto>(SqlSyntax)
|
||||
.Where<NodeDto>(dto => dto.ParentId == entity.ParentId && dto.Text == entity.Name && dto.NodeObjectType == entity.ContainerObjectType));
|
||||
if (nodeDto != null)
|
||||
throw new InvalidOperationException("A container with the same name already exists.");
|
||||
|
||||
// create
|
||||
var level = 0;
|
||||
var path = "-1";
|
||||
if (entity.ParentId > -1)
|
||||
{
|
||||
var parentDto = Database.FirstOrDefault<NodeDto>(new Sql().Select("*")
|
||||
.From<NodeDto>(SqlSyntax)
|
||||
.Where<NodeDto>(dto => dto.NodeId == entity.ParentId && dto.NodeObjectType == entity.ContainerObjectType));
|
||||
|
||||
if (parentDto == null)
|
||||
throw new NullReferenceException("Could not find parent container with id " + entity.ParentId);
|
||||
|
||||
level = parentDto.Level;
|
||||
path = parentDto.Path;
|
||||
}
|
||||
|
||||
// note: sortOrder is NOT managed and always zero for containers
|
||||
|
||||
nodeDto = new NodeDto
|
||||
{
|
||||
CreateDate = DateTime.Now,
|
||||
Level = Convert.ToInt16(level + 1),
|
||||
NodeObjectType = entity.ContainerObjectType,
|
||||
ParentId = entity.ParentId,
|
||||
Path = path,
|
||||
SortOrder = 0,
|
||||
Text = entity.Name,
|
||||
UserId = entity.CreatorId,
|
||||
UniqueId = entity.Key
|
||||
};
|
||||
|
||||
// insert, get the id, update the path with the id
|
||||
var id = Convert.ToInt32(Database.Insert(nodeDto));
|
||||
nodeDto.Path = nodeDto.Path + "," + nodeDto.NodeId;
|
||||
Database.Save(nodeDto);
|
||||
|
||||
// refresh the entity
|
||||
entity.Id = id;
|
||||
entity.Path = nodeDto.Path;
|
||||
entity.Level = nodeDto.Level;
|
||||
entity.SortOrder = 0;
|
||||
entity.CreateDate = nodeDto.CreateDate;
|
||||
entity.ResetDirtyProperties();
|
||||
}
|
||||
|
||||
// beware! does NOT manage descendants in case of a new parent
|
||||
//
|
||||
protected override void PersistUpdatedItem(EntityContainer entity)
|
||||
{
|
||||
entity.Name = entity.Name.Trim();
|
||||
Mandate.ParameterNotNullOrEmpty(entity.Name, "entity.Name");
|
||||
|
||||
// find container to update
|
||||
var nodeDto = Database.FirstOrDefault<NodeDto>(new Sql().Select("*")
|
||||
.From<NodeDto>(SqlSyntax)
|
||||
.Where<NodeDto>(dto => dto.NodeId == entity.Id && dto.NodeObjectType == entity.ContainerObjectType));
|
||||
if (nodeDto == null)
|
||||
throw new InvalidOperationException("Could not find container with id " + entity.Id);
|
||||
|
||||
// guard against duplicates
|
||||
var dupNodeDto = Database.FirstOrDefault<NodeDto>(new Sql().Select("*")
|
||||
.From<NodeDto>(SqlSyntax)
|
||||
.Where<NodeDto>(dto => dto.ParentId == entity.ParentId && dto.Text == entity.Name && dto.NodeObjectType == entity.ContainerObjectType));
|
||||
if (dupNodeDto != null && dupNodeDto.NodeId != nodeDto.NodeId)
|
||||
throw new InvalidOperationException("A container with the same name already exists.");
|
||||
|
||||
// update
|
||||
nodeDto.Text = entity.Name;
|
||||
if (nodeDto.ParentId != entity.ParentId)
|
||||
{
|
||||
nodeDto.Level = 0;
|
||||
nodeDto.Path = "-1";
|
||||
if (entity.ParentId > -1)
|
||||
{
|
||||
var parent = Database.FirstOrDefault<NodeDto>(new Sql().Select("*")
|
||||
.From<NodeDto>(SqlSyntax)
|
||||
.Where<NodeDto>(dto => dto.NodeId == entity.ParentId && dto.NodeObjectType == entity.ContainerObjectType));
|
||||
|
||||
if (parent == null)
|
||||
throw new NullReferenceException("Could not find parent container with id " + entity.ParentId);
|
||||
|
||||
nodeDto.Level = Convert.ToInt16(parent.Level + 1);
|
||||
nodeDto.Path = parent.Path + "," + nodeDto.NodeId;
|
||||
}
|
||||
nodeDto.ParentId = entity.ParentId;
|
||||
}
|
||||
|
||||
// note: sortOrder is NOT managed and always zero for containers
|
||||
|
||||
// update
|
||||
Database.Update(nodeDto);
|
||||
|
||||
// refresh the entity
|
||||
entity.Path = nodeDto.Path;
|
||||
entity.Level = nodeDto.Level;
|
||||
entity.SortOrder = 0;
|
||||
entity.ResetDirtyProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user