Compare commits
435 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fce31a2e02 | |||
| b816e7f4db | |||
| 45f6d4f911 | |||
| 6a9a1d1547 | |||
| 391eb99e10 | |||
| 3b4487c836 | |||
| 46461c7c5d | |||
| 7104629ffd | |||
| b46abecde5 | |||
| e82795f798 | |||
| a6faf5b757 | |||
| 3e6e6faf03 | |||
| b3f18bc677 | |||
| a48fe40675 | |||
| 74c777b1ae | |||
| 1e955fa813 | |||
| bc371e69a3 | |||
| 9a97b636eb | |||
| 878156e21e | |||
| af376d2837 | |||
| 9dd5f250c7 | |||
| bb527996b9 | |||
| 1a171161cd | |||
| d410663a68 | |||
| 9e332ca0a4 | |||
| 02388a33ba | |||
| 3f52364308 | |||
| e157837e0e | |||
| c2318349e5 | |||
| c540c74a04 | |||
| e5b1271ce1 | |||
| dfaa15c6e7 | |||
| 4aa3e1368a | |||
| 25f10011fc | |||
| d08f08ffaf | |||
| 9a9237e78e | |||
| 1511ad58b2 | |||
| 2e9b751174 | |||
| d61ab97be3 | |||
| dd40d73b71 | |||
| 068bca84b7 | |||
| 0fda528b94 | |||
| 3552f63d87 | |||
| 01d04fde37 | |||
| 7f8c526136 | |||
| ea4be14f0c | |||
| 20df48e2f0 | |||
| 2c0f6f975c | |||
| fa7f91b39d | |||
| 72c5853fb1 | |||
| f03b1a22f9 | |||
| e7fb6e5beb | |||
| d0cc93d6a2 | |||
| 4adc2562b1 | |||
| ba6878666c | |||
| 30da7fb801 | |||
| 7086a5153a | |||
| 37937e2c8e | |||
| 7676099f2e | |||
| 0d1bb355b5 | |||
| 3276b8a4d8 | |||
| 792ab8d088 | |||
| 3d4409e52a | |||
| acd377956f | |||
| 3b6dcc3421 | |||
| cec4d41df7 | |||
| ff0bcffefa | |||
| 5dbc72897a | |||
| 83736bec01 | |||
| 2f953c3819 | |||
| 026d040a62 | |||
| 7747b8f64f | |||
| feab2de260 | |||
| 24cc417395 | |||
| 56e1fc07e4 | |||
| fbd2b3a1e1 | |||
| 8f7f761bb3 | |||
| a40ba2f27e | |||
| 893f86d34c | |||
| ddd2ab463e | |||
| cbced2caed | |||
| ce068a60d5 | |||
| 7f7f3202d2 | |||
| 0227b800a0 | |||
| 8e89aa233c | |||
| 24ceb5ce2d | |||
| 923eb300e5 | |||
| 0d93db5f1f | |||
| d2aecd12eb | |||
| 1e99c466ee | |||
| 71a9fb4f68 | |||
| 0497771750 | |||
| 000b2b639f | |||
| 885f691c0e | |||
| 92f6b5564d | |||
| ce65ae8742 | |||
| 57c9d9ca7b | |||
| feb9f40237 | |||
| 3fc96a45a6 | |||
| 3b71a6c3a5 | |||
| 9c4212703b | |||
| a20c11d438 | |||
| 89b8d056a2 | |||
| 8707348215 | |||
| 70ba0cd592 | |||
| 429b5f7c01 | |||
| db4a547801 | |||
| a9916fc415 | |||
| 64a37209b8 | |||
| f9304d7f04 | |||
| 24ae424207 | |||
| b86ef0d7ac | |||
| de97d8849a | |||
| a3576d8564 | |||
| ffdf4e7256 | |||
| f9475305bb | |||
| 0a6208f3ef | |||
| 00f2afe454 | |||
| 3800ffc11c | |||
| 2a9b1cb246 | |||
| 651182f5de | |||
| 784f873777 | |||
| a938605461 | |||
| bb9c968d3a | |||
| b8fe5df3c9 | |||
| 22b15a06f6 | |||
| cb09795280 | |||
| 81dfd0c6bc | |||
| 9f028e6d61 | |||
| ac57ec2211 | |||
| 218bb28440 | |||
| d02b230f71 | |||
| 289361c02f | |||
| fc3020ffa4 | |||
| 7c4c44cf7e | |||
| 458c51a955 | |||
| f3d64bb85d | |||
| 8261a2b69b | |||
| a5637af2d8 | |||
| ac59c5deb0 | |||
| 683ddf6d34 | |||
| eda33b1ac4 | |||
| ed0f884348 | |||
| b561351340 | |||
| 690ab29863 | |||
| a1b3345671 | |||
| e1022bd5a1 | |||
| 1f2c00e3be | |||
| bf4c58a6f4 | |||
| 9de0a62cff | |||
| 3c3f2d7c8d | |||
| 27cb1d5223 | |||
| c677f36f08 | |||
| 750f7a6b33 | |||
| dea804b402 | |||
| 3803d1d7da | |||
| 3e67b3034d | |||
| 1ada5210ad | |||
| 92e1db1667 | |||
| f0258b2bce | |||
| 9a608674eb | |||
| 0fc5af5e17 | |||
| 7dae412a29 | |||
| c3471ffbc3 | |||
| f8baf343bf | |||
| a1067e676f | |||
| ce649f54d7 | |||
| 09b9056fb0 | |||
| 8da2c22a4e | |||
| d159792256 | |||
| d08712306c | |||
| 5e30fd4ced | |||
| 314abde9ac | |||
| 606b5aa60a | |||
| 5441c30780 | |||
| 2c563168e7 | |||
| 59f8508332 | |||
| a206652a0d | |||
| 545040fdf0 | |||
| 2954b31435 | |||
| 40d1a09609 | |||
| 2e25bc8fdb | |||
| 1618ac86b8 | |||
| a4adbca12c | |||
| 8728e2f918 | |||
| d6b55c54e6 | |||
| cd53682ddb | |||
| d000b67703 | |||
| e2d5fbf545 | |||
| a6c4ce3a31 | |||
| 64246b4eef | |||
| fe8098adac | |||
| d339e7c814 | |||
| 9860ffc3bf | |||
| 7db829b2a3 | |||
| 10759773ca | |||
| 078deb704b | |||
| 6858eb3330 | |||
| 16e16f9578 | |||
| e267b7700a | |||
| f780c21ef0 | |||
| 84e7396729 | |||
| 7ed11c04c5 | |||
| 81305173ca | |||
| 6637ceaf41 | |||
| 82d5f7b72b | |||
| e69dea26a5 | |||
| 85d6f1d54a | |||
| f168093b92 | |||
| 1e45abe71e | |||
| a556b4ed21 | |||
| 953c711ca4 | |||
| f06c9e8235 | |||
| f1a439e851 | |||
| 20c2574f94 | |||
| ab4c58b3a3 | |||
| cb63642ce9 | |||
| 3fb756939e | |||
| ec14a16aec | |||
| 6944f25c9f | |||
| 45c7699a33 | |||
| 2bd2f12831 | |||
| a0e496e589 | |||
| e0dcc3afbc | |||
| a4b1b31a24 | |||
| 3634a77d61 | |||
| 13f76f7922 | |||
| d12a9e046f | |||
| 846f4b5b6c | |||
| 2869f17eff | |||
| b73c39b4e9 | |||
| feefb052fd | |||
| 87f93be6ba | |||
| 7e7c4b52b6 | |||
| 4d2d9156ba | |||
| a1603c3cbd | |||
| 82ba1a24a3 | |||
| 357db9d0b6 | |||
| 61766287bc | |||
| ffbf8b2fd6 | |||
| e8c25283b0 | |||
| f7a703195c | |||
| 848e8b5722 | |||
| 4d316c9671 | |||
| 509be9b431 | |||
| 8154382fb1 | |||
| 10ef5eb7bc | |||
| f4c1c4578f | |||
| 6f15949af7 | |||
| 2849ecadb7 | |||
| 778c698ef7 | |||
| 697f93c3ce | |||
| e6c2f0ad70 | |||
| 13976559a8 | |||
| 18121e8726 | |||
| 8b6583b554 | |||
| 234d4cf427 | |||
| 81cdc71145 | |||
| f822400036 | |||
| 2aae108cb4 | |||
| 4069fc8d1f | |||
| 643f05d949 | |||
| d36cd035e9 | |||
| c4acbf0dbc | |||
| 0a80c39962 | |||
| edee8134c2 | |||
| 2f66303b38 | |||
| 7102ed49ec | |||
| f5d94c3a05 | |||
| 92502f946b | |||
| 30a73c0886 | |||
| f5ee02a3e9 | |||
| 9827b40bea | |||
| 2de6f09634 | |||
| df16a69582 | |||
| f9323c85e4 | |||
| 2677672e50 | |||
| a38e0dcf86 | |||
| fdd7227494 | |||
| 6b74e14cdd | |||
| db528d8d7a | |||
| 9d7b3b965a | |||
| 806008a7e9 | |||
| 45fa192c95 | |||
| 92235128f1 | |||
| 06cb7a529e | |||
| fa4e9d0cd1 | |||
| 764644fc5d | |||
| 0bf27f4371 | |||
| 7622937cfd | |||
| bf41694572 | |||
| 7b897ce64c | |||
| 36a8599e62 | |||
| 1ca950f721 | |||
| ffba271fd0 | |||
| ec08d3e910 | |||
| 0bfd032fad | |||
| 2bb58b6fca | |||
| 4d2d656b3d | |||
| fa625d72f9 | |||
| 1991380e02 | |||
| 3b8d6dc2c7 | |||
| 1faeb76c27 | |||
| a064903e90 | |||
| 2850c3c3de | |||
| 1fa7cd234d | |||
| cec8001c38 | |||
| 7dbd21a854 | |||
| 3a513668fd | |||
| 9ff82f3a00 | |||
| 25999be0c9 | |||
| 853baf9462 | |||
| 6f36384a35 | |||
| d55e492d17 | |||
| fcbdf6c635 | |||
| 1fda22a4e0 | |||
| deeaf724bd | |||
| 34824ffbb0 | |||
| 6f28a0a686 | |||
| b3f6a8c71b | |||
| 98684e6292 | |||
| aad0e73fea | |||
| 9687b2abee | |||
| 4ea589e954 | |||
| 621a19d4bd | |||
| 5821444678 | |||
| 7533baf368 | |||
| d691e525b3 | |||
| 02d9d42ae2 | |||
| 17838e044c | |||
| 73173f92d6 | |||
| 7d7fcd2093 | |||
| 2ab1cf59a6 | |||
| 3ef51d7357 | |||
| 56cd1cee81 | |||
| 002988ce86 | |||
| 81c32716fe | |||
| 8b553dd067 | |||
| c52123e878 | |||
| 4e6ca57f7a | |||
| ce9cfbf071 | |||
| 8024bde429 | |||
| 9ce79e98a3 | |||
| 3e5553d9b0 | |||
| c2f34cefb5 | |||
| ccaf82d797 | |||
| 2f7727af68 | |||
| 5a9874bfad | |||
| 5047c7bbe7 | |||
| 0c45fb1b97 | |||
| 7bd745a870 | |||
| 68b4a493c6 | |||
| 6338d57959 | |||
| 7de1b2d09d | |||
| 93a4e8f426 | |||
| fcc115004e | |||
| 24062c0061 | |||
| 06cbdc37b4 | |||
| f28ae52ae3 | |||
| cfd0973f00 | |||
| 1bfdd83ba7 | |||
| 6fefcacc61 | |||
| 3b639e61b2 | |||
| 9959ff667e | |||
| de1f86c7a1 | |||
| 28d8fd0531 | |||
| e4e76eb0bf | |||
| 677cc8c8fd | |||
| 3fa5c4e0b2 | |||
| 360393c464 | |||
| d3daf88a8d | |||
| 7a99ebd6d9 | |||
| a7298e2e5a | |||
| 15d7443c61 | |||
| f2b7e27b34 | |||
| 690d08aa8c | |||
| 6719d70cc0 | |||
| 3cdcf513ec | |||
| 23d9944a61 | |||
| 31429ad9c8 | |||
| 05a8d80284 | |||
| c2d978a0db | |||
| e17b32c6e5 | |||
| de79512dd4 | |||
| 06ae6ad15e | |||
| 2a81162756 | |||
| 0a7526601c | |||
| 3e22598f4a | |||
| d842f0f5b7 | |||
| 8258619055 | |||
| 7d2f6c13c3 | |||
| b314bff127 | |||
| d66e2e52e9 | |||
| 43c426b46c | |||
| 0714aaa457 | |||
| 81dac97917 | |||
| de6e0dc8d7 | |||
| 57c68daf38 | |||
| a705561a51 | |||
| a7107f01e8 | |||
| e2ac82abca | |||
| 64d1a484bd | |||
| 585b42af48 | |||
| 7c4412fc4b | |||
| 0be8039c8f | |||
| 668265f1ac | |||
| 4735f27a66 | |||
| 6377b9aa50 | |||
| 011be60205 | |||
| a272675ed8 | |||
| 80697cf9ca | |||
| f4534aa94c | |||
| 56dec485a5 | |||
| ffde0f48cf | |||
| 5663b6890f | |||
| a2905c13f6 | |||
| e8f7a83f68 | |||
| 2956aee4e3 | |||
| 9bd8d729fa | |||
| fb9569d914 | |||
| 47974d49fe | |||
| 3f8b3031c2 | |||
| 7da41594fd | |||
| 9796b30bbb | |||
| ead837f654 | |||
| 88182edf8f | |||
| e456dd3886 | |||
| c2c4763faa | |||
| c062d3b71b | |||
| ed83fb8216 | |||
| 80601abb27 | |||
| 79384d8a0a | |||
| 793a1a9aa8 | |||
| e3da493345 | |||
| 4a8a09c78a |
@@ -107,3 +107,5 @@ src/Umbraco.Web.UI/[Cc]onfig/appSettings.config
|
||||
src/Umbraco.Web.UI/[Cc]onfig/connectionStrings.config
|
||||
src/Umbraco.Web.UI/umbraco/plugins/*
|
||||
src/Umbraco.Web.UI/umbraco/js/init.js
|
||||
build/ApiDocs/*
|
||||
build/ApiDocs/Output/*
|
||||
@@ -0,0 +1,170 @@
|
||||
/* File : TOC.css
|
||||
// Author : Eric Woodruff (Eric@EWoodruff.us)
|
||||
// Updated : 09/07/2007
|
||||
//
|
||||
// Stylesheet for the table of content
|
||||
*/
|
||||
|
||||
*
|
||||
{
|
||||
margin: 0px 0px 0px 0px;
|
||||
padding: 0px 0px 0px 0px;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
font-family: Segoe UI, Arial, Verdana, Helvetica, sans-serif;
|
||||
font-size: 0.9em;
|
||||
background-color: white;
|
||||
color: White;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
input
|
||||
{
|
||||
padding:5px;
|
||||
margin: 3px 0px 3px 0px
|
||||
}
|
||||
|
||||
img
|
||||
{
|
||||
border: 0;
|
||||
margin-left: 5px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
img.TreeNodeImg
|
||||
{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
img.TOCLink
|
||||
{
|
||||
cursor: pointer;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
a.SelectedNode, a.UnselectedNode
|
||||
{
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
padding: 1px 3px 1px 3px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
a.SelectedNode
|
||||
{
|
||||
background-color: #ffffff;
|
||||
border: solid 1px #999999;
|
||||
padding: 0px 2px 0px 2px;
|
||||
}
|
||||
|
||||
a.UnselectedNode:hover, a.SelectedNode:hover
|
||||
{
|
||||
background-color: #cccccc;
|
||||
border: solid 1px #999999;
|
||||
padding: 0px 2px 0px 2px;
|
||||
}
|
||||
|
||||
.Visible
|
||||
{
|
||||
display: block;
|
||||
margin-left: 2em;
|
||||
}
|
||||
|
||||
.Hidden
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.Tree
|
||||
{
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
width: 300px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.TreeNode, .TreeItem
|
||||
{
|
||||
white-space: nowrap;
|
||||
margin: 2px 2px 2px 2px;
|
||||
}
|
||||
|
||||
.TOCDiv
|
||||
{
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 300px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.TOCSizer
|
||||
{
|
||||
clear: none;
|
||||
float: left;
|
||||
width: 10px;
|
||||
height: 100%;
|
||||
background-image: url("Splitter.gif");
|
||||
background-position:center center;
|
||||
background-repeat:no-repeat;
|
||||
position: relative;
|
||||
cursor: w-resize;
|
||||
border-left: solid 1px #CCC;
|
||||
}
|
||||
|
||||
.TopicContent
|
||||
{
|
||||
position: relative;
|
||||
float: right;
|
||||
background-color: white;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.SearchOpts
|
||||
{
|
||||
padding: 5px 5px 10px 5px;
|
||||
color: black;
|
||||
width: 300px;
|
||||
border-bottom: solid lightgrey 1px;
|
||||
height: 110px !important;
|
||||
}
|
||||
|
||||
.NavOpts
|
||||
{
|
||||
padding: 5px 5px 6px 5px;
|
||||
color: black;
|
||||
width: 300px;
|
||||
border-bottom: solid lightgrey 1px;
|
||||
}
|
||||
|
||||
.NavOpts img {
|
||||
display:inline-block;
|
||||
margin: 0px 5px 0px 5px;
|
||||
}
|
||||
|
||||
.IndexOpts
|
||||
{
|
||||
padding: 5px 5px 6px 5px;
|
||||
color: black;
|
||||
width: 300px;
|
||||
border-bottom: solid lightgrey 1px;
|
||||
}
|
||||
|
||||
.IndexItem
|
||||
{
|
||||
white-space: nowrap;
|
||||
margin: 2px 2px 2px 2px;
|
||||
}
|
||||
|
||||
.IndexSubItem
|
||||
{
|
||||
white-space: nowrap;
|
||||
margin: 2px 2px 2px 12px;
|
||||
}
|
||||
|
||||
.PaddedText
|
||||
{
|
||||
margin: 10px 10px 10px 10px;
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
|
||||
<PropertyGroup>
|
||||
<!-- The configuration and platform will be used to determine which
|
||||
assemblies to include from solution and project documentation
|
||||
sources -->
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{cb4d85f1-7390-40ee-b41f-a724bb8fddea}</ProjectGuid>
|
||||
<SHFBSchemaVersion>1.9.5.0</SHFBSchemaVersion>
|
||||
<!-- AssemblyName, Name, and RootNamespace are not used by SHFB but Visual
|
||||
Studio adds them anyway -->
|
||||
<AssemblyName>Documentation</AssemblyName>
|
||||
<RootNamespace>Documentation</RootNamespace>
|
||||
<Name>Documentation</Name>
|
||||
<!-- SHFB properties -->
|
||||
<FrameworkVersion>.NET Framework 4.5</FrameworkVersion>
|
||||
<OutputPath>.\Output\</OutputPath>
|
||||
<HtmlHelpName>UmbracoClassLibrary</HtmlHelpName>
|
||||
<Language>en-US</Language>
|
||||
<BuildAssemblerVerbosity>OnlyErrors</BuildAssemblerVerbosity>
|
||||
<BuildLogFile>csharp-api-docs.log</BuildLogFile>
|
||||
<HelpFileFormat>Website</HelpFileFormat>
|
||||
<IndentHtml>True</IndentHtml>
|
||||
<KeepLogFile>False</KeepLogFile>
|
||||
<DisableCodeBlockComponent>False</DisableCodeBlockComponent>
|
||||
<CppCommentsFixup>False</CppCommentsFixup>
|
||||
<CleanIntermediates>True</CleanIntermediates>
|
||||
<SyntaxFilters>CSharp</SyntaxFilters>
|
||||
<SdkLinkTarget>Blank</SdkLinkTarget>
|
||||
<RootNamespaceContainer>False</RootNamespaceContainer>
|
||||
<PresentationStyle>VS2010</PresentationStyle>
|
||||
<Preliminary>False</Preliminary>
|
||||
<NamingMethod>Guid</NamingMethod>
|
||||
<HelpTitle>Umbraco .Net Class Library</HelpTitle>
|
||||
<ContentPlacement>AboveNamespaces</ContentPlacement>
|
||||
<VisibleItems>Attributes, InheritedMembers, InheritedFrameworkMembers, Protected, SealedProtected</VisibleItems>
|
||||
<ComponentConfigurations />
|
||||
<DocumentationSources>
|
||||
<DocumentationSource sourceFile="..\..\src\Umbraco.Core\Umbraco.Core.csproj" />
|
||||
<DocumentationSource sourceFile="..\..\src\Umbraco.Core\bin\Release\Umbraco.Core.xml" />
|
||||
<DocumentationSource sourceFile="..\..\src\Umbraco.Web\Umbraco.Web.csproj" />
|
||||
<DocumentationSource sourceFile="..\..\src\Umbraco.Web\bin\Release\umbraco.xml" /></DocumentationSources>
|
||||
<WebsiteSdkLinkType>None</WebsiteSdkLinkType>
|
||||
<HtmlSdkLinkType>None</HtmlSdkLinkType>
|
||||
<IncludeFavorites>False</IncludeFavorites>
|
||||
<BinaryTOC>True</BinaryTOC>
|
||||
<MissingTags>Summary, AutoDocumentCtors, AutoDocumentDispose</MissingTags>
|
||||
<TransformComponentArguments>
|
||||
<Argument Key="logoFile" Value="" />
|
||||
<Argument Key="logoHeight" Value="" />
|
||||
<Argument Key="logoWidth" Value="" />
|
||||
<Argument Key="logoAltText" Value="" />
|
||||
<Argument Key="logoPlacement" Value="left" />
|
||||
<Argument Key="logoAlignment" Value="left" />
|
||||
</TransformComponentArguments>
|
||||
<ApiFilter>
|
||||
<Filter entryType="Namespace" fullName="CookComputing.Blogger" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="CookComputing.MetaWeblog" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="dashboardUtilities" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="presentation.umbraco.webservices" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco" isExposed="False" xmlns="">
|
||||
<Filter entryType="Class" fullName="umbraco.content" filterName="content" isExposed="True" />
|
||||
<Filter entryType="Delegate" fullName="umbraco.content.ContentCacheDatabaseLoadXmlStringEventHandler" filterName="content.ContentCacheDatabaseLoadXmlStringEventHandler" isExposed="False" />
|
||||
<Filter entryType="Delegate" fullName="umbraco.content.ContentCacheLoadNodeEventHandler" filterName="content.ContentCacheLoadNodeEventHandler" isExposed="False" />
|
||||
<Filter entryType="Delegate" fullName="umbraco.content.DocumentCacheEventHandler" filterName="content.DocumentCacheEventHandler" isExposed="False" />
|
||||
<Filter entryType="Delegate" fullName="umbraco.content.RefreshContentEventHandler" filterName="content.RefreshContentEventHandler" isExposed="False" />
|
||||
<Filter entryType="Class" fullName="umbraco.ContentExtensions" filterName="ContentExtensions" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.ContentTypeExtensions" filterName="ContentTypeExtensions" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.item" filterName="item" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.library" filterName="library" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.macro" filterName="macro" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.MacroCacheContent" filterName="MacroCacheContent" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.MacroRenderingEventArgs" filterName="MacroRenderingEventArgs" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.MediaExtensions" filterName="MediaExtensions" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.MemberExtensions" filterName="MemberExtensions" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.page" filterName="page" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.PreValueExtensions" filterName="PreValueExtensions" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.RelationTypeExtensions" filterName="RelationTypeExtensions" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.template" filterName="template" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.UmbracoObjectTypeExtensions" filterName="UmbracoObjectTypeExtensions" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.uQuery" filterName="uQuery" isExposed="True" />
|
||||
<Filter entryType="Interface" fullName="umbraco.uQuery.IGetProperty" filterName="uQuery.IGetProperty" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.uQuery.Members" filterName="uQuery.Members" isExposed="True" />
|
||||
<Filter entryType="Enumeration" fullName="umbraco.uQuery.UmbracoObjectType" filterName="uQuery.UmbracoObjectType" isExposed="True" />
|
||||
</Filter>
|
||||
<Filter entryType="Namespace" fullName="umbraco.cms.presentation" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.create.controls" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.developer" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.developer.RelationTypes" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.developer.RelationTypes.TreeMenu" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.members" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.settings" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.settings.modal" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.settings.scripts" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.settings.stylesheet" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.user" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.controls" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.controls.GenericProperties" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.controls.Images" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.controls.Tree" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.developer" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.dialogs" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.js" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.layoutControls" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.NodeFactory" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.actions" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.channels" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.channels.businesslogic" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.create" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.developer.packages" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.dialogs" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.masterpages" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.members" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.nodeFactory" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.org.umbraco.update" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.plugins.tinymce3" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.preview" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.Search" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.settings" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.templateControls" isExposed="False" xmlns="">
|
||||
<Filter entryType="Class" fullName="umbraco.presentation.templateControls.Item" filterName="Item" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.presentation.templateControls.ItemRenderer" filterName="ItemRenderer" isExposed="True" />
|
||||
<Filter entryType="Class" fullName="umbraco.presentation.templateControls.Macro" filterName="Macro" isExposed="True" />
|
||||
<Filter entryType="Enumeration" fullName="umbraco.presentation.templateControls.Macro.RenderEvents" filterName="Macro.RenderEvents" isExposed="False" />
|
||||
</Filter>
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.tinymce3" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.translation" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.channels" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.controls" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.create" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.developer.Xslt" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.dialogs" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.masterpages" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.members" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.plugins.tinymce3" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.Search" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.translation" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.webservices" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco_client.tinymce3.plugins.spellchecker" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.urlRewriter" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.Web.UI" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.presentation.webservices" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.scripting" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.settings" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="Umbraco.Web.org.umbraco.our" isExposed="False" xmlns="" />
|
||||
<Filter entryType="Namespace" fullName="umbraco.webservices" isExposed="False" xmlns="" /></ApiFilter>
|
||||
</PropertyGroup>
|
||||
<!-- There are no properties for these groups. AnyCPU needs to appear in
|
||||
order for Visual Studio to perform the build. The others are optional
|
||||
common platform types that may appear. -->
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|Win32' ">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|Win32' ">
|
||||
</PropertyGroup>
|
||||
<!-- Import the SHFB build targets -->
|
||||
<Import Project="$(SHFBROOT)\SandcastleHelpFileBuilder.targets" />
|
||||
</Project>
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
@ECHO OFF
|
||||
SET release=7.0.2
|
||||
SET comment=
|
||||
SET release=7.1.0
|
||||
SET comment=beta
|
||||
SET version=%release%
|
||||
|
||||
IF [%comment%] EQU [] (SET version=%release%) ELSE (SET version=%release%-%comment%)
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
##We cannot continue if sandcastle is not installed determined by env variable: SHFBROOT
|
||||
|
||||
if (-not (Test-Path Env:\SHFBROOT))
|
||||
{
|
||||
throw "The docs cannot be build, install Sandcastle help file builder"
|
||||
}
|
||||
|
||||
$PSScriptFilePath = (Get-Item $MyInvocation.MyCommand.Path).FullName
|
||||
$BuildRoot = Split-Path -Path $PSScriptFilePath -Parent
|
||||
$OutputPath = Join-Path -Path $BuildRoot -ChildPath "ApiDocs\Output"
|
||||
$ProjFile = Join-Path -Path $BuildRoot -ChildPath "ApiDocs\csharp-api-docs.shfbproj"
|
||||
|
||||
"Building docs with project file: $ProjFile"
|
||||
|
||||
$MSBuild = "$Env:SYSTEMROOT\Microsoft.NET\Framework\v4.0.30319\msbuild.exe"
|
||||
|
||||
# build it!
|
||||
& $MSBuild "$ProjFile"
|
||||
|
||||
# remove files left over
|
||||
Remove-Item $BuildRoot\* -include csharp-api-docs.shfbproj_*
|
||||
|
||||
# copy our custom styles in
|
||||
Copy-Item $BuildRoot\ApiDocs\TOC.css $OutputPath\TOC.css
|
||||
|
||||
""
|
||||
"Done!"
|
||||
@@ -37,7 +37,6 @@
|
||||
<file src="..\_BuildOutput\WebApp\App_Data\**" target="UmbracoFiles\App_Data" />
|
||||
<file src="..\_BuildOutput\WebApp\App_Plugins\**" target="UmbracoFiles\App_Plugins" />
|
||||
<file src="..\_BuildOutput\WebApp\config\splashes\**" target="UmbracoFiles\config\splashes" />
|
||||
<file src="..\_BuildOutput\WebApp\install\**" target="UmbracoFiles\install" />
|
||||
<file src="..\_BuildOutput\WebApp\umbraco\**" target="UmbracoFiles\umbraco" />
|
||||
<file src="..\_BuildOutput\WebApp\umbraco_client\**" target="UmbracoFiles\umbraco_client" />
|
||||
<file src="..\_BuildOutput\WebApp\Global.asax" target="UmbracoFiles\Global.asax" />
|
||||
|
||||
@@ -42,6 +42,13 @@ namespace SqlCE4Umbraco
|
||||
{
|
||||
var sqlCeEngine = new SqlCeEngine(ConnectionString);
|
||||
sqlCeEngine.CreateDatabase();
|
||||
|
||||
// SD: Pretty sure this should be in a using clause but i don't want to cause unknown side-effects here
|
||||
// since it's been like this for quite some time
|
||||
//using (var sqlCeEngine = new SqlCeEngine(ConnectionString))
|
||||
//{
|
||||
// sqlCeEngine.CreateDatabase();
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -165,6 +165,9 @@ namespace Umbraco.Core
|
||||
/// </remarks>
|
||||
internal string OriginalRequestUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the version configured matches the assembly version
|
||||
/// </summary>
|
||||
private bool Configured
|
||||
{
|
||||
get
|
||||
|
||||
@@ -160,5 +160,15 @@ namespace Umbraco.Core
|
||||
{
|
||||
return new Attempt<T>(condition, result, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implicity operator to check if the attempt was successful without having to access the 'success' property
|
||||
/// </summary>
|
||||
/// <param name="a"></param>
|
||||
/// <returns></returns>
|
||||
public static implicit operator bool(Attempt<T> a)
|
||||
{
|
||||
return a.Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
|
||||
@@ -9,6 +11,7 @@ namespace Umbraco.Core.Cache
|
||||
public const string ApplicationTreeCacheKey = "ApplicationTreeCache";
|
||||
public const string ApplicationsCacheKey = "ApplicationCache";
|
||||
|
||||
[Obsolete("This is no longer used and will be removed from the codebase in the future")]
|
||||
public const string UserTypeCacheKey = "UserTypeCache";
|
||||
|
||||
public const string ContentItemCacheKey = "contentItem";
|
||||
@@ -24,13 +27,16 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
public const string MemberLibraryCacheKey = "UL_GetMember";
|
||||
public const string MemberBusinessLogicCacheKey = "MemberCacheItem_";
|
||||
|
||||
|
||||
public const string TemplateFrontEndCacheKey = "template";
|
||||
public const string TemplateBusinessLogicCacheKey = "UmbracoTemplateCache";
|
||||
|
||||
public const string UserContextCacheKey = "UmbracoUserContext";
|
||||
public const string UserContextTimeoutCacheKey = "UmbracoUserContextTimeout";
|
||||
|
||||
[Obsolete("This is no longer used and will be removed from the codebase in the future")]
|
||||
public const string UserCacheKey = "UmbracoUser";
|
||||
|
||||
public const string UserPermissionsCacheKey = "UmbracoUserPermissions";
|
||||
|
||||
public const string ContentTypeCacheKey = "UmbracoContentType";
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Umbraco.Core
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ICacheRefresher"/> implementations.
|
||||
/// </summary>
|
||||
public IEnumerable<ICacheRefresher> CacheResolvers
|
||||
public IEnumerable<ICacheRefresher> CacheRefreshers
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increases the version number in ClientDependency.config by 1
|
||||
/// Changes the version number in ClientDependency.config to a random value to avoid stale caches
|
||||
/// </summary>
|
||||
internal bool IncreaseVersionNumber()
|
||||
{
|
||||
@@ -28,9 +28,9 @@ namespace Umbraco.Core.Configuration
|
||||
|
||||
var versionAttribute = clientDependencyConfigXml.Root.Attribute("version");
|
||||
|
||||
int oldVersion;
|
||||
int.TryParse(versionAttribute.Value, out oldVersion);
|
||||
var newVersion = oldVersion + 1;
|
||||
//Set the new version to the hashcode of now
|
||||
var oldVersion = versionAttribute.Value;
|
||||
var newVersion = Math.Abs(DateTime.UtcNow.GetHashCode());
|
||||
|
||||
versionAttribute.SetValue(newVersion);
|
||||
clientDependencyConfigXml.Save(_fileName, SaveOptions.DisableFormatting);
|
||||
|
||||
@@ -6,10 +6,13 @@ using System.Web;
|
||||
using System.Web.Configuration;
|
||||
using System.Web.Hosting;
|
||||
using System.Web.Routing;
|
||||
using System.Web.Security;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using System.Xml.XPath;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Security;
|
||||
|
||||
namespace Umbraco.Core.Configuration
|
||||
{
|
||||
@@ -38,7 +41,7 @@ namespace Umbraco.Core.Configuration
|
||||
private static string _reservedUrls;
|
||||
//ensure the built on (non-changeable) reserved paths are there at all times
|
||||
private const string StaticReservedPaths = "~/app_plugins/,~/install/,";
|
||||
private const string StaticReservedUrls = "~/config/splashes/booting.aspx,~/install/default.aspx,~/config/splashes/noNodes.aspx,~/VSEnterpriseHelper.axd,";
|
||||
private const string StaticReservedUrls = "~/config/splashes/booting.aspx,~/config/splashes/noNodes.aspx,~/VSEnterpriseHelper.axd,";
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -259,7 +262,38 @@ namespace Umbraco.Core.Configuration
|
||||
SaveSetting("umbracoConfigurationStatus", value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Umbraco members membership providers' useLegacyEncoding state. This will return a boolean
|
||||
/// </summary>
|
||||
/// <value>The useLegacyEncoding status.</value>
|
||||
public static bool UmbracoMembershipProviderLegacyEncoding
|
||||
{
|
||||
get
|
||||
{
|
||||
return IsConfiguredMembershipProviderUsingLegacyEncoding(Constants.Conventions.Member.UmbracoMemberProviderName);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetMembershipProvidersLegacyEncoding(Constants.Conventions.Member.UmbracoMemberProviderName, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Umbraco users membership providers' useLegacyEncoding state. This will return a boolean
|
||||
/// </summary>
|
||||
/// <value>The useLegacyEncoding status.</value>
|
||||
public static bool UmbracoUsersMembershipProviderLegacyEncoding
|
||||
{
|
||||
get
|
||||
{
|
||||
return IsConfiguredMembershipProviderUsingLegacyEncoding(Constants.Conventions.User.UmbracoUsersProviderName);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetMembershipProvidersLegacyEncoding(Constants.Conventions.User.UmbracoUsersProviderName, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves a setting into the configuration file.
|
||||
@@ -301,7 +335,51 @@ namespace Umbraco.Core.Configuration
|
||||
setting.Remove();
|
||||
xml.Save(fileName, SaveOptions.DisableFormatting);
|
||||
ConfigurationManager.RefreshSection("appSettings");
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetMembershipProvidersLegacyEncoding(string providerName, bool useLegacyEncoding)
|
||||
{
|
||||
//check if this can even be configured.
|
||||
var membershipProvider = Membership.Providers[providerName] as MembershipProviderBase;
|
||||
if (membershipProvider == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (membershipProvider.GetType().Namespace == "umbraco.providers.members")
|
||||
{
|
||||
//its the legacy one, this cannot be changed
|
||||
return;
|
||||
}
|
||||
|
||||
var webConfigFilename = IOHelper.MapPath(string.Format("{0}/web.config", SystemDirectories.Root));
|
||||
var webConfigXml = XDocument.Load(webConfigFilename, LoadOptions.PreserveWhitespace);
|
||||
|
||||
var membershipConfigs = webConfigXml.XPathSelectElements("configuration/system.web/membership/providers/add").ToList();
|
||||
|
||||
if (membershipConfigs.Any() == false)
|
||||
return;
|
||||
|
||||
var provider = membershipConfigs.SingleOrDefault(c => c.Attribute("name") != null && c.Attribute("name").Value == providerName);
|
||||
|
||||
if (provider == null)
|
||||
return;
|
||||
|
||||
provider.SetAttributeValue("useLegacyEncoding", useLegacyEncoding);
|
||||
|
||||
webConfigXml.Save(webConfigFilename, SaveOptions.DisableFormatting);
|
||||
}
|
||||
|
||||
private static bool IsConfiguredMembershipProviderUsingLegacyEncoding(string providerName)
|
||||
{
|
||||
//check if this can even be configured.
|
||||
var membershipProvider = Membership.Providers[providerName] as MembershipProviderBase;
|
||||
if (membershipProvider == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return membershipProvider.UseLegacyEncoding;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Configuration;
|
||||
|
||||
namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
{
|
||||
internal class ContentImagingElement : ConfigurationElement
|
||||
{
|
||||
|
||||
[ConfigurationProperty("imageFileTypes")]
|
||||
internal CommaDelimitedConfigurationElement ImageFileTypes
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
return new OptionalInnerTextConfigurationElement<string>(
|
||||
(InnerTextConfigurationElement<string>)this["DefaultBackofficeProvider"],
|
||||
//set the default
|
||||
"UsersMembershipProvider");
|
||||
Constants.Conventions.User.UmbracoUsersProviderName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
public class UmbracoVersion
|
||||
{
|
||||
private static readonly Version Version = new Version("7.0.2");
|
||||
private static readonly Version Version = new Version("7.1.0");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current version of Umbraco.
|
||||
@@ -23,7 +23,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 ""; } }
|
||||
public static string CurrentComment { get { return "beta"; } }
|
||||
|
||||
// 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
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace Umbraco.Core
|
||||
|
||||
/// <summary>
|
||||
/// MediaType alias for a folder.
|
||||
/// </summary>
|
||||
/// </summary>
|
||||
public const string Folder = "Folder";
|
||||
|
||||
/// <summary>
|
||||
@@ -94,9 +94,18 @@ namespace Umbraco.Core
|
||||
public const string Image = "Image";
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constants for Umbraco user
|
||||
/// </summary>
|
||||
public static class User
|
||||
{
|
||||
public static readonly string UmbracoUsersProviderName = "UsersMembershipProvider";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constants for Umbraco Member property aliases.
|
||||
/// </summary>
|
||||
/// </summary>
|
||||
public static class Member
|
||||
{
|
||||
/// <summary>
|
||||
@@ -111,73 +120,78 @@ namespace Umbraco.Core
|
||||
/// <summary>
|
||||
/// Property alias for a Members Password Question
|
||||
/// </summary>
|
||||
public const string PasswordQuestion = "umbracoPasswordRetrievalQuestionPropertyTypeAlias";
|
||||
public const string PasswordQuestion = "umbracoMemberPasswordRetrievalQuestion";
|
||||
|
||||
public const string PasswordQuestionLabel = "Password Question";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for Members Password Answer
|
||||
/// </summary>
|
||||
public const string PasswordAnswer = "umbracoPasswordRetrievalAnswerPropertyTypeAlias";
|
||||
public const string PasswordAnswer = "umbracoMemberPasswordRetrievalAnswer";
|
||||
|
||||
public const string PasswordAnswerLabel = "Password Answer";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the Comments on a Member
|
||||
/// </summary>
|
||||
public const string Comments = "umbracoCommentPropertyTypeAlias";
|
||||
public const string Comments = "umbracoMemberComments";
|
||||
|
||||
public const string CommentsLabel = "Comments";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the Approved boolean of a Member
|
||||
/// </summary>
|
||||
public const string IsApproved = "umbracoApprovePropertyTypeAlias";
|
||||
public const string IsApproved = "umbracoMemberApproved";
|
||||
|
||||
public const string IsApprovedLabel = "Is Approved";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the Locked out boolean of a Member
|
||||
/// </summary>
|
||||
public const string IsLockedOut = "umbracoLockPropertyTypeAlias";
|
||||
public const string IsLockedOut = "umbracoMemberLockedOut";
|
||||
|
||||
public const string IsLockedOutLabel = "Is Locked Out";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the last date the Member logged in
|
||||
/// </summary>
|
||||
public const string LastLoginDate = "umbracoLastLoginPropertyTypeAlias";
|
||||
public const string LastLoginDate = "umbracoMemberLastLogin";
|
||||
|
||||
public const string LastLoginDateLabel = "Last Login Date";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the last date a Member changed its password
|
||||
/// </summary>
|
||||
public const string LastPasswordChangeDate = "umbracoMemberLastPasswordChange";
|
||||
public const string LastPasswordChangeDate = "umbracoMemberLastPasswordChangeDate";
|
||||
|
||||
public const string LastPasswordChangeDateLabel = "Last Password Change Date";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the last date a Member was locked out
|
||||
/// </summary>
|
||||
public const string LastLockoutDate = "umbracoMemberLastLockout";
|
||||
public const string LastLockoutDate = "umbracoMemberLastLockoutDate";
|
||||
|
||||
public const string LastLockoutDateLabel = "Last Lockout Date";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the number of failed login attemps
|
||||
/// </summary>
|
||||
public const string FailedPasswordAttempts = "umbracoFailedPasswordAttemptsPropertyTypeAlias";
|
||||
public const string FailedPasswordAttempts = "umbracoMemberFailedPasswordAttempts";
|
||||
|
||||
public const string FailedPasswordAttemptsLabel = "Failed Password Attempts";
|
||||
|
||||
/// <summary>
|
||||
/// Group name to put the membership properties on
|
||||
/// </summary>
|
||||
internal const string StandardPropertiesGroupName = "Membership";
|
||||
|
||||
internal static Dictionary<string, PropertyType> GetStandardPropertyTypeStubs()
|
||||
{
|
||||
return new Dictionary<string, PropertyType>
|
||||
{
|
||||
{
|
||||
Comments,
|
||||
new PropertyType(PropertyEditors.TextboxMultipleAlias, DataTypeDatabaseType.Ntext)
|
||||
new PropertyType(PropertyEditors.TextboxMultipleAlias, DataTypeDatabaseType.Ntext, true)
|
||||
{
|
||||
Alias = Comments,
|
||||
Name = CommentsLabel
|
||||
@@ -185,7 +199,7 @@ namespace Umbraco.Core
|
||||
},
|
||||
{
|
||||
FailedPasswordAttempts,
|
||||
new PropertyType(PropertyEditors.IntegerAlias, DataTypeDatabaseType.Integer)
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Integer, true)
|
||||
{
|
||||
Alias = FailedPasswordAttempts,
|
||||
Name = FailedPasswordAttemptsLabel
|
||||
@@ -193,7 +207,7 @@ namespace Umbraco.Core
|
||||
},
|
||||
{
|
||||
IsApproved,
|
||||
new PropertyType(PropertyEditors.TrueFalseAlias, DataTypeDatabaseType.Integer)
|
||||
new PropertyType(PropertyEditors.TrueFalseAlias, DataTypeDatabaseType.Integer, true)
|
||||
{
|
||||
Alias = IsApproved,
|
||||
Name = IsApprovedLabel
|
||||
@@ -201,7 +215,7 @@ namespace Umbraco.Core
|
||||
},
|
||||
{
|
||||
IsLockedOut,
|
||||
new PropertyType(PropertyEditors.TrueFalseAlias, DataTypeDatabaseType.Integer)
|
||||
new PropertyType(PropertyEditors.TrueFalseAlias, DataTypeDatabaseType.Integer, true)
|
||||
{
|
||||
Alias = IsLockedOut,
|
||||
Name = IsLockedOutLabel
|
||||
@@ -209,7 +223,7 @@ namespace Umbraco.Core
|
||||
},
|
||||
{
|
||||
LastLockoutDate,
|
||||
new PropertyType(PropertyEditors.DateAlias, DataTypeDatabaseType.Date)
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, true)
|
||||
{
|
||||
Alias = LastLockoutDate,
|
||||
Name = LastLockoutDateLabel
|
||||
@@ -217,7 +231,7 @@ namespace Umbraco.Core
|
||||
},
|
||||
{
|
||||
LastLoginDate,
|
||||
new PropertyType(PropertyEditors.DateAlias, DataTypeDatabaseType.Date)
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, true)
|
||||
{
|
||||
Alias = LastLoginDate,
|
||||
Name = LastLoginDateLabel
|
||||
@@ -225,7 +239,7 @@ namespace Umbraco.Core
|
||||
},
|
||||
{
|
||||
LastPasswordChangeDate,
|
||||
new PropertyType(PropertyEditors.DateAlias, DataTypeDatabaseType.Date)
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, true)
|
||||
{
|
||||
Alias = LastPasswordChangeDate,
|
||||
Name = LastPasswordChangeDateLabel
|
||||
@@ -233,7 +247,7 @@ namespace Umbraco.Core
|
||||
},
|
||||
{
|
||||
PasswordAnswer,
|
||||
new PropertyType(PropertyEditors.TextboxAlias, DataTypeDatabaseType.Nvarchar)
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Nvarchar, true)
|
||||
{
|
||||
Alias = PasswordAnswer,
|
||||
Name = PasswordAnswerLabel
|
||||
@@ -241,7 +255,7 @@ namespace Umbraco.Core
|
||||
},
|
||||
{
|
||||
PasswordQuestion,
|
||||
new PropertyType(PropertyEditors.TextboxAlias, DataTypeDatabaseType.Nvarchar)
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Nvarchar, true)
|
||||
{
|
||||
Alias = PasswordQuestion,
|
||||
Name = PasswordQuestionLabel
|
||||
@@ -259,7 +273,7 @@ namespace Umbraco.Core
|
||||
/// <summary>
|
||||
/// MemberType alias for default member type.
|
||||
/// </summary>
|
||||
public const string Member = "Member";
|
||||
public const string DefaultAlias = "Member";
|
||||
|
||||
public const string SystemDefaultProtectType = "_umbracoSystemDefaultProtectType";
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace Umbraco.Core
|
||||
///// <summary>
|
||||
///// Alias for the Image Cropper datatype.
|
||||
///// </summary>
|
||||
//public const string ImageCropperAlias = "Umbraco.ImageCropper";
|
||||
public const string ImageCropperAlias = "Umbraco.ImageCropper";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Integer datatype.
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web.UI;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
internal static class ControlExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Recursively finds a control with the specified identifier.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">
|
||||
/// The type of control to be found.
|
||||
/// </typeparam>
|
||||
/// <param name="parent">
|
||||
/// The parent control from which the search will start.
|
||||
/// </param>
|
||||
/// <param name="id">
|
||||
/// The identifier of the control to be found.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The control with the specified identifier, otherwise <see langword="null"/> if the control
|
||||
/// is not found.
|
||||
/// </returns>
|
||||
public static T FindControlRecursive<T>(this Control parent, string id) where T : Control
|
||||
{
|
||||
if ((parent is T) && (parent.ID == id))
|
||||
{
|
||||
return (T)parent;
|
||||
}
|
||||
|
||||
foreach (Control control in parent.Controls)
|
||||
{
|
||||
var foundControl = FindControlRecursive<T>(control, id);
|
||||
if (foundControl != null)
|
||||
{
|
||||
return foundControl;
|
||||
}
|
||||
}
|
||||
return default(T);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -287,7 +287,7 @@ namespace Umbraco.Core
|
||||
() => PluginManager.Current.ResolveAssignedMapperTypes());
|
||||
|
||||
RepositoryResolver.Current = new RepositoryResolver(
|
||||
new RepositoryFactory());
|
||||
new RepositoryFactory(ApplicationCache));
|
||||
|
||||
SqlSyntaxProvidersResolver.Current = new SqlSyntaxProvidersResolver(
|
||||
new[] { typeof(MySqlSyntaxProvider), typeof(SqlCeSyntaxProvider), typeof(SqlServerSyntaxProvider) })
|
||||
|
||||
@@ -113,8 +113,8 @@ namespace Umbraco.Core
|
||||
public void ConfigureEmbeddedDatabaseConnection()
|
||||
{
|
||||
const string providerName = "System.Data.SqlServerCe.4.0";
|
||||
const string connectionString = @"Data Source=|DataDirectory|\Umbraco.sdf;Flush Interval=1;";
|
||||
|
||||
var connectionString = GetEmbeddedDatabaseConnectionString();
|
||||
SaveConnectionString(connectionString, providerName);
|
||||
|
||||
var path = Path.Combine(GlobalSettings.FullpathToRoot, "App_Data", "Umbraco.sdf");
|
||||
@@ -122,11 +122,23 @@ namespace Umbraco.Core
|
||||
{
|
||||
var engine = new SqlCeEngine(connectionString);
|
||||
engine.CreateDatabase();
|
||||
|
||||
// SD: Pretty sure this should be in a using clause but i don't want to cause unknown side-effects here
|
||||
// since it's been like this for quite some time
|
||||
//using (var engine = new SqlCeEngine(connectionString))
|
||||
//{
|
||||
// engine.CreateDatabase();
|
||||
//}
|
||||
}
|
||||
|
||||
Initialize(providerName);
|
||||
}
|
||||
|
||||
public string GetEmbeddedDatabaseConnectionString()
|
||||
{
|
||||
return @"Data Source=|DataDirectory|\Umbraco.sdf;Flush Interval=1;";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configure a ConnectionString that has been entered manually.
|
||||
/// </summary>
|
||||
@@ -149,27 +161,29 @@ namespace Umbraco.Core
|
||||
/// <param name="password">Database Password</param>
|
||||
/// <param name="databaseProvider">Type of the provider to be used (Sql, Sql Azure, Sql Ce, MySql)</param>
|
||||
public void ConfigureDatabaseConnection(string server, string databaseName, string user, string password, string databaseProvider)
|
||||
{
|
||||
string connectionString;
|
||||
string providerName = "System.Data.SqlClient";
|
||||
if (databaseProvider.ToLower().Contains("mysql"))
|
||||
{
|
||||
providerName = "MySql.Data.MySqlClient";
|
||||
connectionString = string.Format("Server={0}; Database={1};Uid={2};Pwd={3}", server, databaseName, user, password);
|
||||
}
|
||||
else if (databaseProvider.ToLower().Contains("azure"))
|
||||
{
|
||||
connectionString = BuildAzureConnectionString(server, databaseName, user, password);
|
||||
}
|
||||
else
|
||||
{
|
||||
connectionString = string.Format("server={0};database={1};user id={2};password={3}", server, databaseName, user, password);
|
||||
}
|
||||
{
|
||||
string providerName;
|
||||
var connectionString = GetDatabaseConnectionString(server, databaseName, user, password, databaseProvider, out providerName);
|
||||
|
||||
SaveConnectionString(connectionString, providerName);
|
||||
Initialize(providerName);
|
||||
}
|
||||
|
||||
public string GetDatabaseConnectionString(string server, string databaseName, string user, string password, string databaseProvider, out string providerName)
|
||||
{
|
||||
providerName = "System.Data.SqlClient";
|
||||
if (databaseProvider.ToLower().Contains("mysql"))
|
||||
{
|
||||
providerName = "MySql.Data.MySqlClient";
|
||||
return string.Format("Server={0}; Database={1};Uid={2};Pwd={3}", server, databaseName, user, password);
|
||||
}
|
||||
if (databaseProvider.ToLower().Contains("azure"))
|
||||
{
|
||||
return BuildAzureConnectionString(server, databaseName, user, password);
|
||||
}
|
||||
return string.Format("server={0};database={1};user id={2};password={3}", server, databaseName, user, password);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures a ConnectionString for the Umbraco database that uses Microsoft SQL Server integrated security.
|
||||
/// </summary>
|
||||
@@ -178,12 +192,16 @@ namespace Umbraco.Core
|
||||
public void ConfigureIntegratedSecurityDatabaseConnection(string server, string databaseName)
|
||||
{
|
||||
const string providerName = "System.Data.SqlClient";
|
||||
string connectionString = String.Format("Server={0};Database={1};Integrated Security=true", server, databaseName);
|
||||
|
||||
var connectionString = GetIntegratedSecurityDatabaseConnectionString(server, databaseName);
|
||||
SaveConnectionString(connectionString, providerName);
|
||||
Initialize(providerName);
|
||||
}
|
||||
|
||||
public string GetIntegratedSecurityDatabaseConnectionString(string server, string databaseName)
|
||||
{
|
||||
return String.Format("Server={0};Database={1};Integrated Security=true", server, databaseName);
|
||||
}
|
||||
|
||||
internal string BuildAzureConnectionString(string server, string databaseName, string user, string password)
|
||||
{
|
||||
if (server.Contains(".") && ServerStartsWithTcp(server) == false)
|
||||
@@ -597,5 +615,34 @@ namespace Umbraco.Core
|
||||
public bool Success { get; set; }
|
||||
public string Percentage { get; set; }
|
||||
}
|
||||
|
||||
internal bool IsConnectionStringConfigured(ConnectionStringSettings databaseSettings)
|
||||
{
|
||||
var dbIsSqlCe = false;
|
||||
if (databaseSettings != null && databaseSettings.ProviderName != null)
|
||||
dbIsSqlCe = databaseSettings.ProviderName == "System.Data.SqlServerCe.4.0";
|
||||
var sqlCeDatabaseExists = false;
|
||||
if (dbIsSqlCe)
|
||||
{
|
||||
var parts = databaseSettings.ConnectionString.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var dataSourcePart = parts.FirstOrDefault(x => x.InvariantStartsWith("Data Source="));
|
||||
if (dataSourcePart != null)
|
||||
{
|
||||
var datasource = dataSourcePart.Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory").ToString());
|
||||
var filePath = datasource.Replace("Data Source=", string.Empty);
|
||||
sqlCeDatabaseExists = File.Exists(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
// Either the connection details are not fully specified or it's a SQL CE database that doesn't exist yet
|
||||
if (databaseSettings == null
|
||||
|| string.IsNullOrWhiteSpace(databaseSettings.ConnectionString) || string.IsNullOrWhiteSpace(databaseSettings.ProviderName)
|
||||
|| (dbIsSqlCe && sqlCeDatabaseExists == false))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,5 +18,30 @@ namespace Umbraco.Core
|
||||
return dt.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
|
||||
public static DateTime TruncateTo(this DateTime dt, DateTruncate truncateTo)
|
||||
{
|
||||
if (truncateTo == DateTruncate.Year)
|
||||
return new DateTime(dt.Year, 0, 0);
|
||||
if (truncateTo == DateTruncate.Month)
|
||||
return new DateTime(dt.Year, dt.Month, 0);
|
||||
if (truncateTo == DateTruncate.Day)
|
||||
return new DateTime(dt.Year, dt.Month, dt.Day);
|
||||
if (truncateTo == DateTruncate.Hour)
|
||||
return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, 0, 0);
|
||||
if (truncateTo == DateTruncate.Minute)
|
||||
return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, 0);
|
||||
return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second);
|
||||
}
|
||||
|
||||
public enum DateTruncate
|
||||
{
|
||||
Year,
|
||||
Month,
|
||||
Day,
|
||||
Hour,
|
||||
Minute,
|
||||
Second
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,25 @@ namespace Umbraco.Core
|
||||
///</summary>
|
||||
internal static class DictionaryExtensions
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Method to Get a value by the key. If the key doesn't exist it will create a new TVal object for the key and return it.
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey"></typeparam>
|
||||
/// <typeparam name="TVal"></typeparam>
|
||||
/// <param name="dict"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static TVal GetOrCreate<TKey, TVal>(this IDictionary<TKey, TVal> dict, TKey key)
|
||||
where TVal : class, new()
|
||||
{
|
||||
if (dict.ContainsKey(key) == false)
|
||||
{
|
||||
dict.Add(key, new TVal());
|
||||
}
|
||||
return dict[key];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates an item with the specified key with the specified value
|
||||
/// </summary>
|
||||
|
||||
@@ -306,10 +306,8 @@ namespace Umbraco.Core.Models
|
||||
/// <returns><see cref="Property"/> Value as a <see cref="TPassType"/></returns>
|
||||
public virtual TPassType GetValue<TPassType>(string propertyTypeAlias)
|
||||
{
|
||||
if (Properties[propertyTypeAlias].Value is TPassType)
|
||||
return (TPassType)Properties[propertyTypeAlias].Value;
|
||||
|
||||
return (TPassType)Convert.ChangeType(Properties[propertyTypeAlias].Value, typeof(TPassType));
|
||||
var convertAttempt = Properties[propertyTypeAlias].Value.TryConvertTo<TPassType>();
|
||||
return convertAttempt.Success ? convertAttempt.Result : default(TPassType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -26,6 +26,20 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
#region IContent
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this entity was just published as part of a recent save operation (i.e. it wasn't previously published)
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This is helpful for determining if the published event will execute during the saved event for a content item.
|
||||
/// </remarks>
|
||||
internal static bool JustPublished(this IContent entity)
|
||||
{
|
||||
var dirty = (IRememberBeingDirty)entity;
|
||||
return dirty.WasPropertyDirty("Published") && entity.Published;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if a new version should be created
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
public static class EntityExtensions
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this entity has just been created and persisted to the data store
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This is useful when handling events to determine if an entity is a brand new entity or was
|
||||
/// already existing.
|
||||
/// </remarks>
|
||||
public static bool IsNewEntity(this IEntity entity)
|
||||
{
|
||||
var dirty = (IRememberBeingDirty)entity;
|
||||
return dirty.WasPropertyDirty("Id");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a member type
|
||||
/// </summary>
|
||||
public interface IMemberGroup : IAggregateRoot
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the member group
|
||||
/// </summary>
|
||||
string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Profile of the user who created this Entity
|
||||
/// </summary>
|
||||
int CreatorId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Some entities may expose additional data that other's might not, this custom data will be available in this collection
|
||||
/// </summary>
|
||||
IDictionary<string, object> AdditionalData { get; }
|
||||
}
|
||||
}
|
||||
@@ -10,5 +10,11 @@
|
||||
/// </summary>
|
||||
/// <returns><see cref="RenderingEngine"/></returns>
|
||||
RenderingEngine GetTypeOfRenderingEngine();
|
||||
|
||||
/// <summary>
|
||||
/// Set the mastertemplate
|
||||
/// </summary>
|
||||
/// <param name="masterTemplate"></param>
|
||||
void SetMasterTemplate(ITemplate masterTemplate);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -29,8 +31,10 @@ namespace Umbraco.Core.Models
|
||||
: base(name, -1, contentType, new PropertyCollection())
|
||||
{
|
||||
_contentType = contentType;
|
||||
IsApproved = true;
|
||||
}
|
||||
|
||||
//TODO: Should we just get rid of this one? no reason to have a level set.
|
||||
internal Member(string name, string email, string username, string password, int parentId, IMemberType contentType)
|
||||
: base(name, parentId, contentType, new PropertyCollection())
|
||||
{
|
||||
@@ -40,6 +44,7 @@ namespace Umbraco.Core.Models
|
||||
_email = email;
|
||||
_username = username;
|
||||
_password = password;
|
||||
IsApproved = true;
|
||||
}
|
||||
|
||||
public Member(string name, string email, string username, string password, IMemberType contentType)
|
||||
@@ -51,6 +56,7 @@ namespace Umbraco.Core.Models
|
||||
_email = email;
|
||||
_username = username;
|
||||
_password = password;
|
||||
IsApproved = true;
|
||||
}
|
||||
|
||||
//public Member(string name, string email, string username, string password, IContentBase parent, IMemberType contentType)
|
||||
@@ -136,7 +142,7 @@ namespace Umbraco.Core.Models
|
||||
/// Gets or sets the Password Question
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoPasswordRetrievalQuestionPropertyTypeAlias
|
||||
/// Alias: umbracoMemberPasswordRetrievalQuestion
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
[IgnoreDataMember]
|
||||
@@ -144,12 +150,19 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.PasswordQuestion, "PasswordQuestion", default(string));
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
return Properties[Constants.Conventions.Member.PasswordQuestion].Value == null
|
||||
? string.Empty
|
||||
: Properties[Constants.Conventions.Member.PasswordQuestion].Value.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.PasswordQuestion,
|
||||
"PasswordQuestion") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.PasswordQuestion].Value = value;
|
||||
}
|
||||
}
|
||||
@@ -158,7 +171,7 @@ namespace Umbraco.Core.Models
|
||||
/// Gets or sets the Password Answer
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoPasswordRetrievalAnswerPropertyTypeAlias
|
||||
/// Alias: umbracoMemberPasswordRetrievalAnswer
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
[IgnoreDataMember]
|
||||
@@ -166,12 +179,19 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.PasswordAnswer, "PasswordAnswer", default(string));
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
return Properties[Constants.Conventions.Member.PasswordAnswer].Value == null
|
||||
? string.Empty
|
||||
: Properties[Constants.Conventions.Member.PasswordAnswer].Value.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.PasswordAnswer,
|
||||
"PasswordAnswer") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.PasswordAnswer].Value = value;
|
||||
}
|
||||
}
|
||||
@@ -180,7 +200,7 @@ namespace Umbraco.Core.Models
|
||||
/// Gets or set the comments for the member
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoCommentPropertyTypeAlias
|
||||
/// Alias: umbracoMemberComments
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
[IgnoreDataMember]
|
||||
@@ -188,12 +208,19 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.Comments, "Comments", default(string));
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
return Properties[Constants.Conventions.Member.Comments].Value == null
|
||||
? string.Empty
|
||||
: Properties[Constants.Conventions.Member.Comments].Value.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.Comments,
|
||||
"Comments") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.Comments].Value = value;
|
||||
}
|
||||
}
|
||||
@@ -202,7 +229,7 @@ namespace Umbraco.Core.Models
|
||||
/// Gets or sets a boolean indicating whether the Member is approved
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoApprovePropertyTypeAlias
|
||||
/// Alias: umbracoMemberApproved
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
[IgnoreDataMember]
|
||||
@@ -210,17 +237,25 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Properties[Constants.Conventions.Member.IsApproved].Value == null)
|
||||
return default(bool);
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.IsApproved, "IsApproved",
|
||||
//This is the default value if the prop is not found
|
||||
true);
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
if (Properties[Constants.Conventions.Member.IsApproved].Value is bool)
|
||||
return (bool)Properties[Constants.Conventions.Member.IsApproved].Value;
|
||||
|
||||
//TODO: Use TryConvertTo<T> instead
|
||||
return (bool)Convert.ChangeType(Properties[Constants.Conventions.Member.IsApproved].Value, typeof(bool));
|
||||
var tryConvert = Properties[Constants.Conventions.Member.IsApproved].Value.TryConvertTo<bool>();
|
||||
if (tryConvert.Success)
|
||||
{
|
||||
return tryConvert.Result;
|
||||
}
|
||||
//if the property exists but it cannot be converted, we will assume true
|
||||
return true;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.IsApproved,
|
||||
"IsApproved") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.IsApproved].Value = value;
|
||||
}
|
||||
}
|
||||
@@ -229,7 +264,7 @@ namespace Umbraco.Core.Models
|
||||
/// Gets or sets a boolean indicating whether the Member is locked out
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoLockPropertyTypeAlias
|
||||
/// Alias: umbracoMemberLockedOut
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
[IgnoreDataMember]
|
||||
@@ -237,17 +272,23 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Properties[Constants.Conventions.Member.IsLockedOut].Value == null)
|
||||
return default(bool);
|
||||
|
||||
if (Properties[Constants.Conventions.Member.IsLockedOut].Value is bool)
|
||||
return (bool)Properties[Constants.Conventions.Member.IsLockedOut].Value;
|
||||
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.IsLockedOut, "IsLockedOut", false);
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
var tryConvert = Properties[Constants.Conventions.Member.IsLockedOut].Value.TryConvertTo<bool>();
|
||||
if (tryConvert.Success)
|
||||
{
|
||||
return tryConvert.Result;
|
||||
}
|
||||
return false;
|
||||
//TODO: Use TryConvertTo<T> instead
|
||||
return (bool)Convert.ChangeType(Properties[Constants.Conventions.Member.IsLockedOut].Value, typeof(bool));
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.IsLockedOut,
|
||||
"IsLockedOut") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.IsLockedOut].Value = value;
|
||||
}
|
||||
}
|
||||
@@ -256,7 +297,7 @@ namespace Umbraco.Core.Models
|
||||
/// Gets or sets the date for last login
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoLastLoginPropertyTypeAlias
|
||||
/// Alias: umbracoMemberLastLogin
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
[IgnoreDataMember]
|
||||
@@ -264,17 +305,23 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Properties[Constants.Conventions.Member.LastLoginDate].Value == null)
|
||||
return default(DateTime);
|
||||
|
||||
if (Properties[Constants.Conventions.Member.LastLoginDate].Value is DateTime)
|
||||
return (DateTime)Properties[Constants.Conventions.Member.LastLoginDate].Value;
|
||||
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.LastLoginDate, "LastLoginDate", default(DateTime));
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
var tryConvert = Properties[Constants.Conventions.Member.LastLoginDate].Value.TryConvertTo<DateTime>();
|
||||
if (tryConvert.Success)
|
||||
{
|
||||
return tryConvert.Result;
|
||||
}
|
||||
return default(DateTime);
|
||||
//TODO: Use TryConvertTo<T> instead
|
||||
return (DateTime)Convert.ChangeType(Properties[Constants.Conventions.Member.LastLoginDate].Value, typeof(DateTime));
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.LastLoginDate,
|
||||
"LastLoginDate") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.LastLoginDate].Value = value;
|
||||
}
|
||||
}
|
||||
@@ -283,7 +330,7 @@ namespace Umbraco.Core.Models
|
||||
/// Gest or sets the date for last password change
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoMemberLastPasswordChange
|
||||
/// Alias: umbracoMemberLastPasswordChangeDate
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
[IgnoreDataMember]
|
||||
@@ -291,17 +338,23 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value == null)
|
||||
return default(DateTime);
|
||||
|
||||
if (Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value is DateTime)
|
||||
return (DateTime)Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value;
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.LastPasswordChangeDate, "LastPasswordChangeDate", default(DateTime));
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
var tryConvert = Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value.TryConvertTo<DateTime>();
|
||||
if (tryConvert.Success)
|
||||
{
|
||||
return tryConvert.Result;
|
||||
}
|
||||
return default(DateTime);
|
||||
//TODO: Use TryConvertTo<T> instead
|
||||
return (DateTime)Convert.ChangeType(Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value, typeof(DateTime));
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.LastPasswordChangeDate,
|
||||
"LastPasswordChangeDate") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value = value;
|
||||
}
|
||||
}
|
||||
@@ -310,7 +363,7 @@ namespace Umbraco.Core.Models
|
||||
/// Gets or sets the date for when Member was locked out
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoMemberLastLockout
|
||||
/// Alias: umbracoMemberLastLockoutDate
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
[IgnoreDataMember]
|
||||
@@ -318,17 +371,23 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Properties[Constants.Conventions.Member.LastLockoutDate].Value == null)
|
||||
return default(DateTime);
|
||||
|
||||
if (Properties[Constants.Conventions.Member.LastLockoutDate].Value is DateTime)
|
||||
return (DateTime)Properties[Constants.Conventions.Member.LastLockoutDate].Value;
|
||||
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.LastLockoutDate, "LastLockoutDate", default(DateTime));
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
var tryConvert = Properties[Constants.Conventions.Member.LastLockoutDate].Value.TryConvertTo<DateTime>();
|
||||
if (tryConvert.Success)
|
||||
{
|
||||
return tryConvert.Result;
|
||||
}
|
||||
return default(DateTime);
|
||||
//TODO: Use TryConvertTo<T> instead
|
||||
return (DateTime)Convert.ChangeType(Properties[Constants.Conventions.Member.LastLockoutDate].Value, typeof(DateTime));
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.LastLockoutDate,
|
||||
"LastLockoutDate") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.LastLockoutDate].Value = value;
|
||||
}
|
||||
}
|
||||
@@ -338,7 +397,7 @@ namespace Umbraco.Core.Models
|
||||
/// This is the number of times the password was entered incorrectly upon login.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoFailedPasswordAttemptsPropertyTypeAlias
|
||||
/// Alias: umbracoMemberFailedPasswordAttempts
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
[IgnoreDataMember]
|
||||
@@ -346,18 +405,24 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value == null)
|
||||
return default(int);
|
||||
|
||||
if (Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value is int)
|
||||
return (int)Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value;
|
||||
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.FailedPasswordAttempts, "FailedPasswordAttempts", 0);
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
var tryConvert = Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value.TryConvertTo<int>();
|
||||
if (tryConvert.Success)
|
||||
{
|
||||
return tryConvert.Result;
|
||||
}
|
||||
return default(int);
|
||||
//TODO: Use TryConvertTo<T> instead
|
||||
return (int)Convert.ChangeType(Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value, typeof(int));
|
||||
}
|
||||
set
|
||||
{
|
||||
Properties[Constants.Conventions.Member.LastLockoutDate].Value = value;
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.FailedPasswordAttempts,
|
||||
"FailedPasswordAttempts") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -471,5 +536,73 @@ namespace Umbraco.Core.Models
|
||||
internal bool BoolPropertyValue { get; set; }
|
||||
internal DateTime DateTimePropertyValue { get; set; }
|
||||
internal string PropertyTypeAlias { get; set; }
|
||||
|
||||
private Attempt<T> WarnIfPropertyTypeNotFoundOnGet<T>(string propertyAlias, string propertyName, T defaultVal)
|
||||
{
|
||||
Action doLog = () => LogHelper.Warn<Member>(
|
||||
"Trying to access the '"
|
||||
+ propertyName
|
||||
+ "' property on "
|
||||
+ typeof(Member)
|
||||
+ " but the "
|
||||
+ propertyAlias
|
||||
+ " property does not exist on the member type so a default value is returned. Ensure that you have a property type with alias: "
|
||||
+ propertyAlias
|
||||
+ " configured on your member type in order to use the '"
|
||||
+ propertyName
|
||||
+ "' property on the model correctly.");
|
||||
|
||||
//if the property doesn't exist, then do the logging and return a failure
|
||||
if (Properties.Contains(propertyAlias) == false)
|
||||
{
|
||||
//we'll put a warn in the log if this entity has been persisted
|
||||
if (HasIdentity)
|
||||
{
|
||||
doLog();
|
||||
}
|
||||
return Attempt<T>.Fail(defaultVal);
|
||||
}
|
||||
|
||||
//if the property doesn't have an identity but we do, then do logging and return failure
|
||||
var prop = Properties.Single(x => x.Alias == propertyAlias);
|
||||
if (prop.HasIdentity == false && HasIdentity)
|
||||
{
|
||||
doLog();
|
||||
return Attempt<T>.Fail(defaultVal);
|
||||
}
|
||||
|
||||
return Attempt<T>.Succeed();
|
||||
}
|
||||
|
||||
private bool WarnIfPropertyTypeNotFoundOnSet(string propertyAlias, string propertyname)
|
||||
{
|
||||
Action doLog = () => LogHelper.Warn<Member>("An attempt was made to set a value on the property '"
|
||||
+ propertyname
|
||||
+ "' on type "
|
||||
+ typeof(Member)
|
||||
+ " but the property type "
|
||||
+ propertyAlias
|
||||
+ " does not exist on the member type, ensure that this property type exists so that setting this property works correctly.");
|
||||
|
||||
//if the property doesn't exist, then do the logging and return a failure
|
||||
if (Properties.Contains(propertyAlias) == false)
|
||||
{
|
||||
if (HasIdentity)
|
||||
{
|
||||
doLog();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//if the property doesn't have an identity but we do, then do logging and return failure
|
||||
var prop = Properties.Single(x => x.Alias == propertyAlias);
|
||||
if (prop.HasIdentity == false && HasIdentity)
|
||||
{
|
||||
doLog();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a member type
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
public class MemberGroup : Entity, IMemberGroup
|
||||
{
|
||||
public MemberGroup()
|
||||
{
|
||||
AdditionalData = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
private string _name;
|
||||
private int _creatorId;
|
||||
|
||||
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<MemberGroup, string>(x => x.Name);
|
||||
private static readonly PropertyInfo CreatorIdSelector = ExpressionHelper.GetPropertyInfo<MemberGroup, int>(x => x.CreatorId);
|
||||
|
||||
[DataMember]
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
if (_name != value)
|
||||
{
|
||||
//if the name has changed, add the value to the additional data,
|
||||
//this is required purely for event handlers to know the previous name of the group
|
||||
//so we can keep the public access up to date.
|
||||
AdditionalData["previousName"] = _name;
|
||||
}
|
||||
|
||||
_name = value;
|
||||
return _name;
|
||||
}, _name, NameSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public int CreatorId
|
||||
{
|
||||
get { return _creatorId; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_creatorId = value;
|
||||
return _creatorId;
|
||||
}, _creatorId, CreatorIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,20 +14,18 @@ namespace Umbraco.Core.Models
|
||||
public class MemberType : ContentTypeCompositionBase, IMemberType
|
||||
{
|
||||
//Dictionary is divided into string: PropertyTypeAlias, Tuple: MemberCanEdit, VisibleOnProfile, PropertyTypeId
|
||||
private IDictionary<string, Tuple<bool, bool, int>> _memberTypePropertyTypes;
|
||||
private string _alias;
|
||||
|
||||
public MemberType(int parentId) : base(parentId)
|
||||
{
|
||||
_memberTypePropertyTypes = new Dictionary<string, Tuple<bool, bool, int>>();
|
||||
MemberTypePropertyTypes = new Dictionary<string, MemberTypePropertyProfileAccess>();
|
||||
}
|
||||
|
||||
public MemberType(IContentTypeComposition parent) : base(parent)
|
||||
{
|
||||
_memberTypePropertyTypes = new Dictionary<string, Tuple<bool, bool, int>>();
|
||||
MemberTypePropertyTypes = new Dictionary<string, MemberTypePropertyProfileAccess>();
|
||||
}
|
||||
|
||||
private static readonly PropertyInfo MemberTypePropertyTypesSelector = ExpressionHelper.GetPropertyInfo<MemberType, IDictionary<string, Tuple<bool, bool, int>>>(x => x.MemberTypePropertyTypes);
|
||||
private static readonly PropertyInfo AliasSelector = ExpressionHelper.GetPropertyInfo<MemberType, string>(x => x.Alias);
|
||||
|
||||
/// <summary>
|
||||
@@ -53,21 +51,10 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or Sets a Dictionary of Tuples (MemberCanEdit, VisibleOnProfile, PropertyTypeId) by the PropertyTypes' alias.
|
||||
/// Gets or Sets a Dictionary of Tuples (MemberCanEdit, VisibleOnProfile) by the PropertyTypes' alias.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
internal IDictionary<string, Tuple<bool, bool, int>> MemberTypePropertyTypes
|
||||
{
|
||||
get { return _memberTypePropertyTypes; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_memberTypePropertyTypes = value;
|
||||
return _memberTypePropertyTypes;
|
||||
}, _memberTypePropertyTypes, MemberTypePropertyTypesSelector);
|
||||
}
|
||||
}
|
||||
internal IDictionary<string, MemberTypePropertyProfileAccess> MemberTypePropertyTypes { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether a Property is editable by the Member.
|
||||
@@ -78,7 +65,7 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
if (MemberTypePropertyTypes.ContainsKey(propertyTypeAlias))
|
||||
{
|
||||
return MemberTypePropertyTypes[propertyTypeAlias].Item1;
|
||||
return MemberTypePropertyTypes[propertyTypeAlias].IsEditable;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -93,7 +80,7 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
if (MemberTypePropertyTypes.ContainsKey(propertyTypeAlias))
|
||||
{
|
||||
return MemberTypePropertyTypes[propertyTypeAlias].Item2;
|
||||
return MemberTypePropertyTypes[propertyTypeAlias].IsVisible;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -108,13 +95,11 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
if (MemberTypePropertyTypes.ContainsKey(propertyTypeAlias))
|
||||
{
|
||||
var tuple = MemberTypePropertyTypes[propertyTypeAlias];
|
||||
MemberTypePropertyTypes[propertyTypeAlias] = new Tuple<bool, bool, int>(value, tuple.Item2, tuple.Item3);
|
||||
MemberTypePropertyTypes[propertyTypeAlias].IsEditable = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
var propertyType = PropertyTypes.First(x => x.Alias.Equals(propertyTypeAlias));
|
||||
var tuple = new Tuple<bool, bool, int>(value, false, propertyType.Id);
|
||||
var tuple = new MemberTypePropertyProfileAccess(false, value);
|
||||
MemberTypePropertyTypes.Add(propertyTypeAlias, tuple);
|
||||
}
|
||||
}
|
||||
@@ -128,13 +113,11 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
if (MemberTypePropertyTypes.ContainsKey(propertyTypeAlias))
|
||||
{
|
||||
var tuple = MemberTypePropertyTypes[propertyTypeAlias];
|
||||
MemberTypePropertyTypes[propertyTypeAlias] = new Tuple<bool, bool, int>(tuple.Item1, value, tuple.Item3);
|
||||
MemberTypePropertyTypes[propertyTypeAlias].IsVisible = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
var propertyType = PropertyTypes.First(x => x.Alias.Equals(propertyTypeAlias));
|
||||
var tuple = new Tuple<bool, bool, int>(false, value, propertyType.Id);
|
||||
var tuple = new MemberTypePropertyProfileAccess(value, false);
|
||||
MemberTypePropertyTypes.Add(propertyTypeAlias, tuple);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to track the property types that are visible/editable on member profiles
|
||||
/// </summary>
|
||||
internal class MemberTypePropertyProfileAccess
|
||||
{
|
||||
public MemberTypePropertyProfileAccess(bool isVisible, bool isEditable)
|
||||
{
|
||||
IsVisible = isVisible;
|
||||
IsEditable = isEditable;
|
||||
}
|
||||
|
||||
public bool IsVisible { get; set; }
|
||||
public bool IsEditable { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -5,14 +5,14 @@
|
||||
/// </summary>
|
||||
public class EntityPermission
|
||||
{
|
||||
public EntityPermission(object userId, int entityId, string[] assignedPermissions)
|
||||
public EntityPermission(int userId, int entityId, string[] assignedPermissions)
|
||||
{
|
||||
UserId = userId;
|
||||
EntityId = entityId;
|
||||
AssignedPermissions = assignedPermissions;
|
||||
}
|
||||
|
||||
public object UserId { get; private set; }
|
||||
public int UserId { get; private set; }
|
||||
public int EntityId { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace Umbraco.Core.Models.Membership
|
||||
/// This is the number of times the password was entered incorrectly upon login.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Alias: umbracoFailedPasswordAttemptsPropertyTypeAlias
|
||||
/// Alias: umbracoMemberFailedPasswordAttempts
|
||||
/// Part of the standard properties collection.
|
||||
/// </remarks>
|
||||
int FailedPasswordAttempts { get; set; }
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
/// <summary>
|
||||
/// Defines the the Profile interface
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This interface is pretty useless but has been exposed publicly from 6.x so we're stuck with it. It would make more sense
|
||||
/// if the Id was an int but since it's not people have to cast it to int all of the time!
|
||||
/// </remarks>
|
||||
public interface IProfile
|
||||
{
|
||||
object Id { get; set; }
|
||||
|
||||
@@ -7,19 +7,18 @@ namespace Umbraco.Core.Models.Membership
|
||||
/// Defines the interface for a <see cref="User"/>
|
||||
/// </summary>
|
||||
/// <remarks>Will be left internal until a proper Membership implementation is part of the roadmap</remarks>
|
||||
internal interface IUser : IMembershipUser, IProfile
|
||||
public interface IUser : IMembershipUser
|
||||
{
|
||||
new object Id { get; set; }
|
||||
|
||||
string Name { get; set; }
|
||||
int SessionTimeout { get; set; }
|
||||
int StartContentId { get; set; }
|
||||
int StartMediaId { get; set; }
|
||||
string Language { get; set; }
|
||||
|
||||
//NOTE: I have removed this because it is obsolete in v7 and we are basically removing live editing for now
|
||||
//bool DefaultToLiveEditing { get; set; }
|
||||
|
||||
IUserType UserType { get; }
|
||||
/// <summary>
|
||||
/// Gets/sets the user type for the user
|
||||
/// </summary>
|
||||
IUserType UserType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The default permission set for the user
|
||||
@@ -32,5 +31,10 @@ namespace Umbraco.Core.Models.Membership
|
||||
IEnumerable<string> AllowedSections { get; }
|
||||
void RemoveAllowedSection(string sectionAlias);
|
||||
void AddAllowedSection(string sectionAlias);
|
||||
|
||||
/// <summary>
|
||||
/// Exposes the basic profile data
|
||||
/// </summary>
|
||||
IProfile ProfileData { get; }
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ using Umbraco.Core.Persistence.Mappers;
|
||||
namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
|
||||
internal interface IUserType : IAggregateRoot
|
||||
public interface IUserType : IAggregateRoot
|
||||
{
|
||||
/// <summary>
|
||||
/// The user type alias
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
return MembershipScenario.NativeUmbraco;
|
||||
}
|
||||
var memberType = ApplicationContext.Current.Services.MemberTypeService.GetMemberType(Constants.Conventions.MemberTypes.Member);
|
||||
var memberType = ApplicationContext.Current.Services.MemberTypeService.Get(Constants.Conventions.MemberTypes.DefaultAlias);
|
||||
return memberType != null
|
||||
? MembershipScenario.CustomProviderWithUmbracoLink
|
||||
: MembershipScenario.StandaloneCustomProvider;
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
@@ -19,7 +20,7 @@ namespace Umbraco.Core.Models.Membership
|
||||
/// </remarks>
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
internal class User : TracksChangesEntityBase, IUser
|
||||
public class User : TracksChangesEntityBase, IUser
|
||||
{
|
||||
public User(IUserType userType)
|
||||
{
|
||||
@@ -31,7 +32,12 @@ namespace Umbraco.Core.Models.Membership
|
||||
_sectionCollection = new ObservableCollection<string>();
|
||||
_addedSections = new List<string>();
|
||||
_removedSections = new List<string>();
|
||||
_language = GlobalSettings.DefaultUILanguage;
|
||||
_sectionCollection.CollectionChanged += SectionCollectionChanged;
|
||||
_isApproved = true;
|
||||
_isLockedOut = false;
|
||||
_startContentId = -1;
|
||||
_startMediaId = -1;
|
||||
}
|
||||
|
||||
public User(string name, string email, string username, string password, IUserType userType)
|
||||
@@ -41,11 +47,15 @@ namespace Umbraco.Core.Models.Membership
|
||||
_email = email;
|
||||
_username = username;
|
||||
_password = password;
|
||||
_isApproved = true;
|
||||
_isLockedOut = false;
|
||||
_startContentId = -1;
|
||||
_startMediaId = -1;
|
||||
}
|
||||
|
||||
private readonly IUserType _userType;
|
||||
private IUserType _userType;
|
||||
private bool _hasIdentity;
|
||||
private object _id;
|
||||
private int _id;
|
||||
private string _name;
|
||||
private Type _userTypeKey;
|
||||
private readonly List<string> _addedSections;
|
||||
@@ -58,7 +68,6 @@ namespace Umbraco.Core.Models.Membership
|
||||
private string _username;
|
||||
private string _email;
|
||||
private string _password;
|
||||
private Guid _key;
|
||||
private bool _isApproved;
|
||||
private bool _isLockedOut;
|
||||
private string _language;
|
||||
@@ -81,23 +90,43 @@ namespace Umbraco.Core.Models.Membership
|
||||
private static readonly PropertyInfo LanguageSelector = ExpressionHelper.GetPropertyInfo<User, string>(x => x.Language);
|
||||
private static readonly PropertyInfo DefaultPermissionsSelector = ExpressionHelper.GetPropertyInfo<User, IEnumerable<string>>(x => x.DefaultPermissions);
|
||||
private static readonly PropertyInfo DefaultToLiveEditingSelector = ExpressionHelper.GetPropertyInfo<User, bool>(x => x.DefaultToLiveEditing);
|
||||
private static readonly PropertyInfo HasIdentitySelector = ExpressionHelper.GetPropertyInfo<User, bool>(x => x.HasIdentity);
|
||||
private static readonly PropertyInfo UserTypeSelector = ExpressionHelper.GetPropertyInfo<User, IUserType>(x => x.UserType);
|
||||
|
||||
#region Implementation of IEntity
|
||||
|
||||
[IgnoreDataMember]
|
||||
public bool HasIdentity { get { return Id != null || _hasIdentity; } }
|
||||
|
||||
[IgnoreDataMember]
|
||||
int IEntity.Id
|
||||
public bool HasIdentity
|
||||
{
|
||||
get
|
||||
{
|
||||
return int.Parse(Id.ToString());
|
||||
return _hasIdentity;
|
||||
}
|
||||
protected set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_hasIdentity = value;
|
||||
return _hasIdentity;
|
||||
}, _hasIdentity, HasIdentitySelector);
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public int Id
|
||||
{
|
||||
get
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
set
|
||||
{
|
||||
Id = value;
|
||||
_hasIdentity = true;
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_id = value;
|
||||
HasIdentity = true; //set the has Identity
|
||||
return _id;
|
||||
}, _id, IdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,8 +268,8 @@ namespace Umbraco.Core.Models.Membership
|
||||
public int FailedPasswordAttempts { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IProfile
|
||||
|
||||
#region Implementation of IUser
|
||||
|
||||
[DataMember]
|
||||
public string Name
|
||||
@@ -249,17 +278,13 @@ namespace Umbraco.Core.Models.Membership
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_name = value;
|
||||
return _name;
|
||||
}, _name, NameSelector);
|
||||
{
|
||||
_name = value;
|
||||
return _name;
|
||||
}, _name, NameSelector);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IUser
|
||||
|
||||
public IEnumerable<string> AllowedSections
|
||||
{
|
||||
get { return _sectionCollection; }
|
||||
@@ -278,6 +303,11 @@ namespace Umbraco.Core.Models.Membership
|
||||
}
|
||||
}
|
||||
|
||||
public IProfile ProfileData
|
||||
{
|
||||
get { return new UserProfile(this); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used internally to check if we need to add a section in the repository to the db
|
||||
/// </summary>
|
||||
@@ -354,20 +384,6 @@ namespace Umbraco.Core.Models.Membership
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public object Id
|
||||
{
|
||||
get { return _id; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_id = value;
|
||||
return _id;
|
||||
}, _id, IdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public string Language
|
||||
{
|
||||
@@ -414,6 +430,19 @@ namespace Umbraco.Core.Models.Membership
|
||||
public IUserType UserType
|
||||
{
|
||||
get { return _userType; }
|
||||
set
|
||||
{
|
||||
if (value.HasIdentity == false)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot assign a User Type that has not been persisted");
|
||||
}
|
||||
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_userType = value;
|
||||
return _userType;
|
||||
}, _userType, UserTypeSelector);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -459,5 +488,30 @@ namespace Umbraco.Core.Models.Membership
|
||||
_removedSections.Add(e.OldItems.Cast<string>().First());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal class used to wrap the user in a profile
|
||||
/// </summary>
|
||||
private class UserProfile : IProfile
|
||||
{
|
||||
private readonly IUser _user;
|
||||
|
||||
public UserProfile(IUser user)
|
||||
{
|
||||
_user = user;
|
||||
}
|
||||
|
||||
public object Id
|
||||
{
|
||||
get { return _user.Id; }
|
||||
set { _user.Id = (int)value; }
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return _user.Name; }
|
||||
set { _user.Name = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@ namespace Umbraco.Core.Models
|
||||
|
||||
private static readonly PropertyInfo ValueSelector = ExpressionHelper.GetPropertyInfo<Property, object>(x => x.Value);
|
||||
private static readonly PropertyInfo VersionSelector = ExpressionHelper.GetPropertyInfo<Property, Guid>(x => x.Version);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the instance of the tag support, by default tags are not enabled
|
||||
/// </summary>
|
||||
@@ -68,9 +68,14 @@ namespace Umbraco.Core.Models
|
||||
/// <summary>
|
||||
/// Returns the DatabaseType that the underlaying DataType is using to store its values
|
||||
/// </summary>
|
||||
/// <remarks>Only used internally when saving the property value</remarks>
|
||||
/// <remarks>
|
||||
/// Only used internally when saving the property value.
|
||||
/// </remarks>
|
||||
[IgnoreDataMember]
|
||||
internal DataTypeDatabaseType DataTypeDatabaseType { get { return _propertyType.DataTypeDatabaseType; } }
|
||||
internal DataTypeDatabaseType DataTypeDatabaseType
|
||||
{
|
||||
get { return _propertyType.DataTypeDatabaseType; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the PropertyType, which this Property is based on
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace Umbraco.Core.Models
|
||||
[DataContract(IsReference = true)]
|
||||
public class PropertyType : Entity, IEquatable<PropertyType>
|
||||
{
|
||||
private readonly bool _isExplicitDbType;
|
||||
private string _name;
|
||||
private string _alias;
|
||||
private string _description;
|
||||
@@ -30,16 +31,29 @@ namespace Umbraco.Core.Models
|
||||
public PropertyType(IDataTypeDefinition dataTypeDefinition)
|
||||
{
|
||||
if(dataTypeDefinition.HasIdentity)
|
||||
DataTypeDefinitionId = dataTypeDefinition.Id;
|
||||
_dataTypeDefinitionId = dataTypeDefinition.Id;
|
||||
|
||||
PropertyEditorAlias = dataTypeDefinition.PropertyEditorAlias;
|
||||
DataTypeDatabaseType = dataTypeDefinition.DatabaseType;
|
||||
_propertyEditorAlias = dataTypeDefinition.PropertyEditorAlias;
|
||||
_dataTypeDatabaseType = dataTypeDefinition.DatabaseType;
|
||||
}
|
||||
|
||||
internal PropertyType(string propertyEditorAlias, DataTypeDatabaseType dataTypeDatabaseType)
|
||||
: this(propertyEditorAlias, dataTypeDatabaseType, false)
|
||||
{
|
||||
PropertyEditorAlias = propertyEditorAlias;
|
||||
DataTypeDatabaseType = dataTypeDatabaseType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used internally to assign an explicity database type for this property type regardless of what the underlying data type/property editor is.
|
||||
/// </summary>
|
||||
/// <param name="propertyEditorAlias"></param>
|
||||
/// <param name="dataTypeDatabaseType"></param>
|
||||
/// <param name="isExplicitDbType"></param>
|
||||
internal PropertyType(string propertyEditorAlias, DataTypeDatabaseType dataTypeDatabaseType, bool isExplicitDbType)
|
||||
{
|
||||
_isExplicitDbType = isExplicitDbType;
|
||||
_propertyEditorAlias = propertyEditorAlias;
|
||||
_dataTypeDatabaseType = dataTypeDatabaseType;
|
||||
}
|
||||
|
||||
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<PropertyType, string>(x => x.Name);
|
||||
@@ -165,6 +179,9 @@ namespace Umbraco.Core.Models
|
||||
get { return _dataTypeDatabaseType; }
|
||||
set
|
||||
{
|
||||
//don't allow setting this if an explicit declaration has been made in the ctor
|
||||
if (_isExplicitDbType) return;
|
||||
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_dataTypeDatabaseType = value;
|
||||
|
||||
@@ -183,5 +183,11 @@ namespace Umbraco.Core.Models
|
||||
if (Key == Guid.Empty)
|
||||
Key = Guid.NewGuid();
|
||||
}
|
||||
|
||||
|
||||
public void SetMasterTemplate(ITemplate masterTemplate)
|
||||
{
|
||||
MasterTemplateId = new Lazy<int>(() => masterTemplate.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
@@ -53,6 +54,13 @@ namespace Umbraco.Core.Models
|
||||
Trashed = trashed;
|
||||
}
|
||||
|
||||
// for MySql
|
||||
public UmbracoEntity(UInt64 trashed)
|
||||
{
|
||||
AdditionalData = new Dictionary<string, object>();
|
||||
Trashed = trashed == 1;
|
||||
}
|
||||
|
||||
public int CreatorId
|
||||
{
|
||||
get { return _creatorId; }
|
||||
|
||||
@@ -246,12 +246,14 @@ namespace Umbraco.Core
|
||||
else if (destinationType == typeof(Double))
|
||||
{
|
||||
Double value;
|
||||
return Double.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
var input2 = NormalizeNumberDecimalSeparator(input);
|
||||
return Double.TryParse(input2, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(Single))
|
||||
{
|
||||
Single value;
|
||||
return Single.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
var input2 = NormalizeNumberDecimalSeparator(input);
|
||||
return Single.TryParse(input2, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(Char))
|
||||
{
|
||||
@@ -292,7 +294,20 @@ namespace Umbraco.Core
|
||||
else if (destinationType == typeof(DateTime))
|
||||
{
|
||||
DateTime value;
|
||||
return DateTime.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
if (DateTime.TryParse(input, out value))
|
||||
{
|
||||
switch (value.Kind)
|
||||
{
|
||||
case DateTimeKind.Unspecified:
|
||||
case DateTimeKind.Utc:
|
||||
return Attempt<object>.Succeed(value);
|
||||
case DateTimeKind.Local:
|
||||
return Attempt<object>.Succeed(value.ToUniversalTime());
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
return Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(DateTimeOffset))
|
||||
{
|
||||
@@ -307,7 +322,8 @@ namespace Umbraco.Core
|
||||
else if (destinationType == typeof(Decimal))
|
||||
{
|
||||
Decimal value;
|
||||
return Decimal.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
var input2 = NormalizeNumberDecimalSeparator(input);
|
||||
return Decimal.TryParse(input2, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(Version))
|
||||
{
|
||||
@@ -319,6 +335,14 @@ namespace Umbraco.Core
|
||||
return null; // we can't decide...
|
||||
}
|
||||
|
||||
private readonly static char[] NumberDecimalSeparatorsToNormalize = new[] {'.', ','};
|
||||
|
||||
private static string NormalizeNumberDecimalSeparator(string s)
|
||||
{
|
||||
var normalized = System.Threading.Thread.CurrentThread.CurrentUICulture.NumberFormat.NumberDecimalSeparator[0];
|
||||
return s.ReplaceMany(NumberDecimalSeparatorsToNormalize, normalized);
|
||||
}
|
||||
|
||||
internal static void CheckThrowObjectDisposed(this IDisposable disposable, bool isDisposed, string objectname)
|
||||
{
|
||||
//TODO: Localise this exception
|
||||
@@ -526,7 +550,7 @@ namespace Umbraco.Core
|
||||
if (type == typeof(bool)) return XmlConvert.ToString((bool)value);
|
||||
if (type == typeof(byte)) return XmlConvert.ToString((byte)value);
|
||||
if (type == typeof(char)) return XmlConvert.ToString((char)value);
|
||||
if (type == typeof(DateTime)) return XmlConvert.ToString((DateTime)value, XmlDateTimeSerializationMode.RoundtripKind);
|
||||
if (type == typeof(DateTime)) return XmlConvert.ToString((DateTime)value, XmlDateTimeSerializationMode.Unspecified);
|
||||
if (type == typeof(DateTimeOffset)) return XmlConvert.ToString((DateTimeOffset)value);
|
||||
if (type == typeof(decimal)) return XmlConvert.ToString((decimal)value);
|
||||
if (type == typeof(double)) return XmlConvert.ToString((double)value);
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Umbraco.Core.Persistence
|
||||
{
|
||||
|
||||
//TODO: Would be good to use this exception type anytime we cannot find an entity
|
||||
|
||||
/// <summary>
|
||||
/// An exception used to indicate that an umbraco entity could not be found
|
||||
/// </summary>
|
||||
public class EntityNotFoundException : Exception
|
||||
{
|
||||
public object Id { get; private set; }
|
||||
private readonly string _msg;
|
||||
|
||||
public EntityNotFoundException(object id, string msg)
|
||||
{
|
||||
Id = id;
|
||||
_msg = msg;
|
||||
}
|
||||
|
||||
public EntityNotFoundException(string msg)
|
||||
{
|
||||
_msg = msg;
|
||||
}
|
||||
|
||||
public override string Message
|
||||
{
|
||||
get { return _msg; }
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var result = base.ToString();
|
||||
|
||||
if (Id != null)
|
||||
{
|
||||
return "Umbraco entity (id: " + Id + ") not found. " + result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
internal class MemberGroupFactory : IEntityFactory<IMemberGroup, NodeDto>
|
||||
{
|
||||
|
||||
private readonly Guid _nodeObjectTypeId;
|
||||
|
||||
public MemberGroupFactory()
|
||||
{
|
||||
_nodeObjectTypeId = new Guid(Constants.ObjectTypes.MemberGroup);
|
||||
}
|
||||
|
||||
#region Implementation of IEntityFactory<ITemplate,TemplateDto>
|
||||
|
||||
public IMemberGroup BuildEntity(NodeDto dto)
|
||||
{
|
||||
var template = new MemberGroup
|
||||
{
|
||||
CreateDate = dto.CreateDate,
|
||||
Id = dto.NodeId,
|
||||
Key = dto.UniqueId.Value,
|
||||
Name = dto.Text
|
||||
};
|
||||
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
// http://issues.umbraco.org/issue/U4-1946
|
||||
template.ResetDirtyProperties(false);
|
||||
return template;
|
||||
}
|
||||
|
||||
public NodeDto BuildDto(IMemberGroup entity)
|
||||
{
|
||||
var dto = new NodeDto
|
||||
{
|
||||
CreateDate = entity.CreateDate,
|
||||
NodeId = entity.Id,
|
||||
Level = 0,
|
||||
NodeObjectType = _nodeObjectTypeId,
|
||||
ParentId = -1,
|
||||
Path = "",
|
||||
SortOrder = 0,
|
||||
Text = entity.Name,
|
||||
Trashed = false,
|
||||
UniqueId = entity.Key,
|
||||
UserId = entity.CreatorId
|
||||
};
|
||||
|
||||
if (entity.HasIdentity)
|
||||
{
|
||||
dto.NodeId = entity.Id;
|
||||
dto.Path = "-1," + entity.Id;
|
||||
}
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
CreateDate = dto.CreateDate,
|
||||
UpdateDate = dto.UpdateDate,
|
||||
Name = dto.Text,
|
||||
ProviderUserKey = dto.UniqueId.Value,
|
||||
ProviderUserKey = dto.NodeId,
|
||||
Trashed = dto.Trashed,
|
||||
Key = dto.UniqueId.Value,
|
||||
CreatorId = dto.UserId.HasValue ? dto.UserId.Value : 0,
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.Repositories;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
@@ -10,6 +11,8 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
public IMemberType BuildEntity(MemberTypeReadOnlyDto dto)
|
||||
{
|
||||
var standardPropertyTypes = Constants.Conventions.Member.GetStandardPropertyTypeStubs();
|
||||
|
||||
var memberType = new MemberType(dto.ParentId)
|
||||
{
|
||||
Alias = dto.Alias,
|
||||
@@ -31,12 +34,12 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
AllowedContentTypes = Enumerable.Empty<ContentTypeSort>()
|
||||
};
|
||||
|
||||
var propertyTypeGroupCollection = GetPropertyTypeGroupCollection(dto, memberType);
|
||||
var propertyTypeGroupCollection = GetPropertyTypeGroupCollection(dto, memberType, standardPropertyTypes);
|
||||
memberType.PropertyGroups = propertyTypeGroupCollection;
|
||||
|
||||
var propertyTypes = GetPropertyTypes(dto, memberType);
|
||||
//By Convention we add 9 stnd PropertyTypes - This is only here to support loading of types that didn't have these conventions before.
|
||||
var standardPropertyTypes = Constants.Conventions.Member.GetStandardPropertyTypeStubs();
|
||||
var propertyTypes = GetPropertyTypes(dto, memberType, standardPropertyTypes);
|
||||
|
||||
//By Convention we add 9 stnd PropertyTypes - This is only here to support loading of types that didn't have these conventions before.
|
||||
foreach (var standardPropertyType in standardPropertyTypes)
|
||||
{
|
||||
if(dto.PropertyTypes.Any(x => x.Alias.Equals(standardPropertyType.Key))) continue;
|
||||
@@ -46,16 +49,17 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
|
||||
//Internal dictionary for adding "MemberCanEdit" and "VisibleOnProfile" properties to each PropertyType
|
||||
memberType.MemberTypePropertyTypes.Add(standardPropertyType.Key,
|
||||
new Tuple<bool, bool, int>(false, false, default(int)));
|
||||
new MemberTypePropertyProfileAccess(false, false));
|
||||
}
|
||||
memberType.PropertyTypes = propertyTypes;
|
||||
|
||||
return memberType;
|
||||
}
|
||||
|
||||
private PropertyGroupCollection GetPropertyTypeGroupCollection(MemberTypeReadOnlyDto dto, MemberType memberType)
|
||||
private PropertyGroupCollection GetPropertyTypeGroupCollection(MemberTypeReadOnlyDto dto, MemberType memberType, Dictionary<string, PropertyType> standardProps)
|
||||
{
|
||||
var propertyGroups = new PropertyGroupCollection();
|
||||
var propertyGroups = new PropertyGroupCollection();
|
||||
|
||||
foreach (var groupDto in dto.PropertyTypeGroups.Where(x => x.Id.HasValue))
|
||||
{
|
||||
var group = new PropertyGroup();
|
||||
@@ -85,11 +89,23 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
//Internal dictionary for adding "MemberCanEdit" and "VisibleOnProfile" properties to each PropertyType
|
||||
memberType.MemberTypePropertyTypes.Add(typeDto.Alias,
|
||||
new Tuple<bool, bool, int>(typeDto.CanEdit, typeDto.ViewOnProfile, typeDto.Id.Value));
|
||||
new MemberTypePropertyProfileAccess(typeDto.ViewOnProfile, typeDto.CanEdit));
|
||||
|
||||
var tempGroupDto = groupDto;
|
||||
var propertyType = new PropertyType(typeDto.PropertyEditorAlias,
|
||||
typeDto.DbType.EnumParse<DataTypeDatabaseType>(true))
|
||||
|
||||
//ensures that any built-in membership properties have their correct dbtype assigned no matter
|
||||
//what the underlying data type is
|
||||
var propDbType = MemberTypeRepository.GetDbTypeForBuiltInProperty(
|
||||
typeDto.Alias,
|
||||
typeDto.DbType.EnumParse<DataTypeDatabaseType>(true),
|
||||
standardProps);
|
||||
|
||||
var propertyType = new PropertyType(
|
||||
typeDto.PropertyEditorAlias,
|
||||
propDbType.Result,
|
||||
//This flag tells the property type that it has an explicit dbtype and that it cannot be changed
|
||||
// which is what we want for the built-in properties.
|
||||
propDbType.Success)
|
||||
{
|
||||
Alias = typeDto.Alias,
|
||||
DataTypeDefinitionId = typeDto.DataTypeId,
|
||||
@@ -118,32 +134,47 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
return propertyGroups;
|
||||
}
|
||||
|
||||
private List<PropertyType> GetPropertyTypes(MemberTypeReadOnlyDto dto, MemberType memberType)
|
||||
|
||||
|
||||
private List<PropertyType> GetPropertyTypes(MemberTypeReadOnlyDto dto, MemberType memberType, Dictionary<string, PropertyType> standardProps)
|
||||
{
|
||||
//Find PropertyTypes that does not belong to a PropertyTypeGroup
|
||||
var propertyTypes = new List<PropertyType>();
|
||||
foreach (var propertyType in dto.PropertyTypes.Where(x => (x.PropertyTypeGroupId.HasValue == false || x.PropertyTypeGroupId.Value == 0) && x.Id.HasValue))
|
||||
foreach (var typeDto in dto.PropertyTypes.Where(x => (x.PropertyTypeGroupId.HasValue == false || x.PropertyTypeGroupId.Value == 0) && x.Id.HasValue))
|
||||
{
|
||||
//Internal dictionary for adding "MemberCanEdit" and "VisibleOnProfile" properties to each PropertyType
|
||||
memberType.MemberTypePropertyTypes.Add(propertyType.Alias,
|
||||
new Tuple<bool, bool, int>(propertyType.CanEdit, propertyType.ViewOnProfile, propertyType.Id.Value));
|
||||
//PropertyType Collection
|
||||
propertyTypes.Add(new PropertyType(propertyType.PropertyEditorAlias,
|
||||
propertyType.DbType.EnumParse<DataTypeDatabaseType>(true))
|
||||
{
|
||||
Alias = propertyType.Alias,
|
||||
DataTypeDefinitionId = propertyType.DataTypeId,
|
||||
Description = propertyType.Description,
|
||||
HelpText = propertyType.HelpText,
|
||||
Id = propertyType.Id.Value,
|
||||
Mandatory = propertyType.Mandatory,
|
||||
Name = propertyType.Name,
|
||||
SortOrder = propertyType.SortOrder,
|
||||
ValidationRegExp = propertyType.ValidationRegExp,
|
||||
PropertyGroupId = new Lazy<int>(() => default(int)),
|
||||
CreateDate = dto.CreateDate,
|
||||
UpdateDate = dto.CreateDate
|
||||
});
|
||||
memberType.MemberTypePropertyTypes.Add(typeDto.Alias,
|
||||
new MemberTypePropertyProfileAccess(typeDto.ViewOnProfile, typeDto.CanEdit));
|
||||
|
||||
//ensures that any built-in membership properties have their correct dbtype assigned no matter
|
||||
//what the underlying data type is
|
||||
var propDbType = MemberTypeRepository.GetDbTypeForBuiltInProperty(
|
||||
typeDto.Alias,
|
||||
typeDto.DbType.EnumParse<DataTypeDatabaseType>(true),
|
||||
standardProps);
|
||||
|
||||
var propertyType = new PropertyType(
|
||||
typeDto.PropertyEditorAlias,
|
||||
propDbType.Result,
|
||||
//This flag tells the property type that it has an explicit dbtype and that it cannot be changed
|
||||
// which is what we want for the built-in properties.
|
||||
propDbType.Success)
|
||||
{
|
||||
Alias = typeDto.Alias,
|
||||
DataTypeDefinitionId = typeDto.DataTypeId,
|
||||
Description = typeDto.Description,
|
||||
HelpText = typeDto.HelpText,
|
||||
Id = typeDto.Id.Value,
|
||||
Mandatory = typeDto.Mandatory,
|
||||
Name = typeDto.Name,
|
||||
SortOrder = typeDto.SortOrder,
|
||||
ValidationRegExp = typeDto.ValidationRegExp,
|
||||
PropertyGroupId = new Lazy<int>(() => default(int)),
|
||||
CreateDate = dto.CreateDate,
|
||||
UpdateDate = dto.CreateDate
|
||||
};
|
||||
|
||||
propertyTypes.Add(propertyType);
|
||||
}
|
||||
return propertyTypes;
|
||||
}
|
||||
|
||||
@@ -11,17 +11,21 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
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 id)
|
||||
{
|
||||
_id = id;
|
||||
_propertyTypeCtor = (propertyEditorAlias, dbType, alias) => new PropertyType(propertyEditorAlias, dbType);
|
||||
}
|
||||
|
||||
public PropertyGroupFactory(int id, DateTime createDate, DateTime updateDate)
|
||||
public PropertyGroupFactory(int id, DateTime createDate, DateTime updateDate, Func<string, DataTypeDatabaseType, string, PropertyType> propertyTypeCtor)
|
||||
{
|
||||
_id = id;
|
||||
_createDate = createDate;
|
||||
_updateDate = updateDate;
|
||||
_propertyTypeCtor = propertyTypeCtor;
|
||||
}
|
||||
|
||||
#region Implementation of IEntityFactory<IEnumerable<PropertyGroup>,IEnumerable<TabDto>>
|
||||
@@ -55,22 +59,23 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
foreach (var typeDto in typeDtos)
|
||||
{
|
||||
var tempGroupDto = groupDto;
|
||||
var propertyType = new PropertyType(typeDto.DataTypeDto.PropertyEditorAlias,
|
||||
typeDto.DataTypeDto.DbType.EnumParse<DataTypeDatabaseType>(true))
|
||||
{
|
||||
Alias = typeDto.Alias,
|
||||
DataTypeDefinitionId = typeDto.DataTypeId,
|
||||
Description = typeDto.Description,
|
||||
Id = typeDto.Id,
|
||||
Name = typeDto.Name,
|
||||
HelpText = typeDto.HelpText,
|
||||
Mandatory = typeDto.Mandatory,
|
||||
SortOrder = typeDto.SortOrder,
|
||||
ValidationRegExp = typeDto.ValidationRegExp,
|
||||
PropertyGroupId = new Lazy<int>(() => tempGroupDto.Id),
|
||||
CreateDate = _createDate,
|
||||
UpdateDate = _updateDate
|
||||
};
|
||||
var propertyType = _propertyTypeCtor(typeDto.DataTypeDto.PropertyEditorAlias,
|
||||
typeDto.DataTypeDto.DbType.EnumParse<DataTypeDatabaseType>(true),
|
||||
typeDto.Alias);
|
||||
|
||||
propertyType.Alias = typeDto.Alias;
|
||||
propertyType.DataTypeDefinitionId = typeDto.DataTypeId;
|
||||
propertyType.Description = typeDto.Description;
|
||||
propertyType.Id = typeDto.Id;
|
||||
propertyType.Name = typeDto.Name;
|
||||
propertyType.HelpText = typeDto.HelpText;
|
||||
propertyType.Mandatory = typeDto.Mandatory;
|
||||
propertyType.SortOrder = typeDto.SortOrder;
|
||||
propertyType.ValidationRegExp = typeDto.ValidationRegExp;
|
||||
propertyType.PropertyGroupId = new Lazy<int>(() => tempGroupDto.Id);
|
||||
propertyType.CreateDate = _createDate;
|
||||
propertyType.UpdateDate = _updateDate;
|
||||
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
// http://issues.umbraco.org/issue/U4-1946
|
||||
propertyType.ResetDirtyProperties(false);
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Mappers
|
||||
{
|
||||
[MapperFor(typeof (IMemberGroup))]
|
||||
[MapperFor(typeof (MemberGroup))]
|
||||
public sealed class MemberGroupMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
|
||||
//NOTE: its an internal class but the ctor must be public since we're using Activator.CreateInstance to create it
|
||||
// otherwise that would fail because there is no public constructor.
|
||||
public MemberGroupMapper()
|
||||
{
|
||||
BuildMap();
|
||||
}
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache
|
||||
{
|
||||
get { return PropertyInfoCacheInstance; }
|
||||
}
|
||||
|
||||
internal override void BuildMap()
|
||||
{
|
||||
CacheMap<MemberGroup, NodeDto>(src => src.Id, dto => dto.NodeId);
|
||||
CacheMap<MemberGroup, NodeDto>(src => src.CreateDate, dto => dto.CreateDate);
|
||||
CacheMap<MemberGroup, NodeDto>(src => src.CreatorId, dto => dto.UserId);
|
||||
CacheMap<MemberGroup, NodeDto>(src => src.Name, dto => dto.Text);
|
||||
CacheMap<MemberGroup, NodeDto>(src => src.Key, dto => dto.UniqueId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -120,7 +120,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1036, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1036", SortOrder = 2, UniqueId = new Guid("2b24165f-9782-4aa3-b459-1de4a4d21f60"), Text = "Member Picker", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
|
||||
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1040, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1040", SortOrder = 2, UniqueId = new Guid("21e798da-e06e-4eda-a511-ed257f78d4fa"), Text = "Related Links", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
|
||||
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1041, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1041", SortOrder = 2, UniqueId = new Guid("b6b73142-b9c1-4bf8-a16d-e1c23320b549"), Text = "Tags", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
|
||||
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1044, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1044", SortOrder = 0, UniqueId = new Guid("d59be02f-1df9-4228-aa1e-01917d806cda"), Text = Constants.Conventions.MemberTypes.Member, NodeObjectType = new Guid(Constants.ObjectTypes.MemberType), CreateDate = DateTime.Now });
|
||||
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1044, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1044", SortOrder = 0, UniqueId = new Guid("d59be02f-1df9-4228-aa1e-01917d806cda"), Text = Constants.Conventions.MemberTypes.DefaultAlias, NodeObjectType = new Guid(Constants.ObjectTypes.MemberType), CreateDate = DateTime.Now });
|
||||
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1045, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1045", SortOrder = 2, UniqueId = new Guid("7E3962CC-CE20-4FFC-B661-5897A894BA7E"), Text = "Multiple Media Picker", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
|
||||
|
||||
//TODO: We're not creating these for 7.0
|
||||
@@ -135,7 +135,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
_database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 532, NodeId = 1031, Alias = Constants.Conventions.MediaTypes.Folder, Icon = "icon-folder", Thumbnail = "folder.png", IsContainer = false, AllowAtRoot = true });
|
||||
_database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 533, NodeId = 1032, Alias = Constants.Conventions.MediaTypes.Image, Icon = "icon-picture", Thumbnail = "mediaPhoto.png" });
|
||||
_database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 534, NodeId = 1033, Alias = Constants.Conventions.MediaTypes.File, Icon = "icon-document", Thumbnail = "mediaFile.png" });
|
||||
_database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 531, NodeId = 1044, Alias = Constants.Conventions.MemberTypes.Member, Icon = "icon-user", Thumbnail = "folder.png" });
|
||||
_database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 531, NodeId = 1044, Alias = Constants.Conventions.MemberTypes.DefaultAlias, Icon = "icon-user", Thumbnail = "folder.png" });
|
||||
}
|
||||
|
||||
private void CreateUmbracoUserData()
|
||||
|
||||
@@ -79,7 +79,10 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
|
||||
try
|
||||
{
|
||||
_database.DropTable(tableName);
|
||||
if (_database.TableExist(tableName))
|
||||
{
|
||||
_database.DropTable(tableName);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Deployment.Internal;
|
||||
using System.Dynamic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Script.Serialization;
|
||||
using System.Xml;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenOne
|
||||
{
|
||||
[Migration("7.1.0", 1, GlobalSettings.UmbracoMigrationName)]
|
||||
public class UpdateToNewMemberPropertyAliases : MigrationBase
|
||||
{
|
||||
public override void Up()
|
||||
{
|
||||
Execute.Code(Update);
|
||||
}
|
||||
|
||||
internal static string Update(Database database)
|
||||
{
|
||||
if (database != null)
|
||||
{
|
||||
var aliasMap = new Dictionary<string, string>
|
||||
{
|
||||
{"umbracoPasswordRetrievalQuestionPropertyTypeAlias", Constants.Conventions.Member.PasswordQuestion},
|
||||
{"umbracoPasswordRetrievalAnswerPropertyTypeAlias", Constants.Conventions.Member.PasswordAnswer},
|
||||
{"umbracoCommentPropertyTypeAlias", Constants.Conventions.Member.Comments},
|
||||
{"umbracoApprovePropertyTypeAlias", Constants.Conventions.Member.IsApproved},
|
||||
{"umbracoLockPropertyTypeAlias", Constants.Conventions.Member.IsLockedOut},
|
||||
{"umbracoLastLoginPropertyTypeAlias", Constants.Conventions.Member.LastLoginDate},
|
||||
{"umbracoMemberLastPasswordChange", Constants.Conventions.Member.LastPasswordChangeDate},
|
||||
{"umbracoMemberLastLockout", Constants.Conventions.Member.LastLockoutDate},
|
||||
{"umbracoFailedPasswordAttemptsPropertyTypeAlias", Constants.Conventions.Member.FailedPasswordAttempts}
|
||||
};
|
||||
|
||||
const string propertyTypeUpdateSql = @"UPDATE cmsPropertyType
|
||||
SET Alias = @newAlias
|
||||
WHERE Alias = @oldAlias AND contentTypeId IN (
|
||||
SELECT DISTINCT cmsContentType.nodeId FROM cmsPropertyType
|
||||
INNER JOIN cmsContentType ON cmsPropertyType.contentTypeId = cmsContentType.nodeId
|
||||
INNER JOIN umbracoNode ON cmsContentType.nodeId = umbracoNode.id
|
||||
WHERE umbracoNode.nodeObjectType = @objectType)";
|
||||
|
||||
const string xmlSelectSql = @"SELECT cmsContentXml.* FROM cmsContentXml
|
||||
INNER JOIN umbracoNode ON cmsContentXml.nodeId = umbracoNode.id
|
||||
WHERE umbracoNode.nodeObjectType = @objectType";
|
||||
|
||||
using (var trans = database.GetTransaction())
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
//Upate all of the property type aliases
|
||||
foreach (var map in aliasMap)
|
||||
{
|
||||
database.Execute(propertyTypeUpdateSql, new { newAlias = map.Value, oldAlias = map.Key, objectType = Constants.ObjectTypes.MemberType });
|
||||
}
|
||||
|
||||
//Update all of the XML
|
||||
var items = database.Fetch<ContentXmlDto>(xmlSelectSql, new {objectType = Constants.ObjectTypes.Member});
|
||||
foreach (var item in items)
|
||||
{
|
||||
foreach (var map in aliasMap)
|
||||
{
|
||||
item.Xml = item.Xml.Replace("<" + map.Key + ">", "<" + map.Value + ">");
|
||||
item.Xml = item.Xml.Replace("</" + map.Key + ">", "</" + map.Value + ">");
|
||||
}
|
||||
database.Update(item);
|
||||
}
|
||||
|
||||
trans.Complete();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.Error<UpdateToNewMemberPropertyAliases>("Exception was thrown when trying to upgrade old member aliases to the new ones", ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,11 +57,20 @@ namespace Umbraco.Core.Persistence
|
||||
|
||||
using (var tr = db.GetTransaction())
|
||||
{
|
||||
db.BulkInsertRecords(collection, tr);
|
||||
db.BulkInsertRecords(collection, tr, true);
|
||||
}
|
||||
}
|
||||
|
||||
public static void BulkInsertRecords<T>(this Database db, IEnumerable<T> collection, Transaction tr)
|
||||
/// <summary>
|
||||
/// Performs the bulk insertion in the context of a current transaction with an optional parameter to complete the transaction
|
||||
/// when finished
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="db"></param>
|
||||
/// <param name="collection"></param>
|
||||
/// <param name="tr"></param>
|
||||
/// <param name="commitTrans"></param>
|
||||
public static void BulkInsertRecords<T>(this Database db, IEnumerable<T> collection, Transaction tr, bool commitTrans = false)
|
||||
{
|
||||
//don't do anything if there are no records.
|
||||
if (collection.Any() == false)
|
||||
@@ -95,11 +104,17 @@ namespace Umbraco.Core.Persistence
|
||||
}
|
||||
}
|
||||
|
||||
tr.Complete();
|
||||
if (commitTrans)
|
||||
{
|
||||
tr.Complete();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
tr.Dispose();
|
||||
if (commitTrans)
|
||||
{
|
||||
tr.Dispose();
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Querying
|
||||
{
|
||||
@@ -25,7 +26,7 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
{
|
||||
//if (TypeSerializer.CanCreateFromString(fieldType))
|
||||
//{
|
||||
// return "'" + EscapeParam(TypeSerializer.SerializeToString(value)) + "'";
|
||||
// return "'" + escapeCallback(TypeSerializer.SerializeToString(value)) + "'";
|
||||
//}
|
||||
|
||||
throw new NotSupportedException(
|
||||
@@ -46,27 +47,24 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
|
||||
if (fieldType == typeof(DateTime))
|
||||
{
|
||||
return "'" + EscapeParam(((DateTime)value).ToIsoString()) + "'";
|
||||
return "'" + escapeCallback(((DateTime)value).ToIsoString()) + "'";
|
||||
}
|
||||
|
||||
if (fieldType == typeof(bool))
|
||||
return ((bool)value) ? Convert.ToString(1, CultureInfo.InvariantCulture) : Convert.ToString(0, CultureInfo.InvariantCulture);
|
||||
|
||||
return ShouldQuoteValue(fieldType)
|
||||
? "'" + EscapeParam(value) + "'"
|
||||
return shouldQuoteCallback(fieldType)
|
||||
? "'" + escapeCallback(value) + "'"
|
||||
: value.ToString();
|
||||
}
|
||||
|
||||
public virtual string EscapeParam(object paramValue)
|
||||
{
|
||||
return paramValue.ToString().Replace("'", "''");
|
||||
return paramValue == null
|
||||
? string.Empty
|
||||
: SqlSyntaxContext.SqlSyntaxProvider.EscapeString(paramValue.ToString());
|
||||
}
|
||||
|
||||
public virtual string EscapeAtArgument(string exp)
|
||||
{
|
||||
return PetaPocoExtensions.EscapeAtSymbols(exp);
|
||||
}
|
||||
|
||||
|
||||
public virtual bool ShouldQuoteValue(Type fieldType)
|
||||
{
|
||||
return true;
|
||||
|
||||
@@ -205,13 +205,12 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
{
|
||||
if (c.Value == null)
|
||||
return "null";
|
||||
else if (c.Value.GetType() == typeof(bool))
|
||||
if (c.Value is bool)
|
||||
{
|
||||
object o = GetQuotedValue(c.Value, c.Value.GetType());
|
||||
return string.Format("({0}={1})", GetQuotedTrueValue(), o);
|
||||
}
|
||||
else
|
||||
return GetQuotedValue(c.Value, c.Value.GetType());
|
||||
return GetQuotedValue(c.Value, c.Value.GetType());
|
||||
}
|
||||
|
||||
protected virtual string VisitUnary(UnaryExpression u)
|
||||
@@ -233,15 +232,15 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
switch (verb)
|
||||
{
|
||||
case "SqlWildcard":
|
||||
return SqlSyntaxContext.SqlSyntaxProvider.GetStringColumnWildcardComparison(col, EscapeAtArgument(RemoveQuote(val)), columnType);
|
||||
return SqlSyntaxContext.SqlSyntaxProvider.GetStringColumnWildcardComparison(col, RemoveQuote(val), columnType);
|
||||
case "Equals":
|
||||
return SqlSyntaxContext.SqlSyntaxProvider.GetStringColumnEqualComparison(col, EscapeAtArgument(RemoveQuote(val)), columnType);
|
||||
return SqlSyntaxContext.SqlSyntaxProvider.GetStringColumnEqualComparison(col, RemoveQuote(val), columnType);
|
||||
case "StartsWith":
|
||||
return SqlSyntaxContext.SqlSyntaxProvider.GetStringColumnStartsWithComparison(col, EscapeAtArgument(RemoveQuote(val)), columnType);
|
||||
return SqlSyntaxContext.SqlSyntaxProvider.GetStringColumnStartsWithComparison(col, RemoveQuote(val), columnType);
|
||||
case "EndsWith":
|
||||
return SqlSyntaxContext.SqlSyntaxProvider.GetStringColumnEndsWithComparison(col, EscapeAtArgument(RemoveQuote(val)), columnType);
|
||||
return SqlSyntaxContext.SqlSyntaxProvider.GetStringColumnEndsWithComparison(col, RemoveQuote(val), columnType);
|
||||
case "Contains":
|
||||
return SqlSyntaxContext.SqlSyntaxProvider.GetStringColumnContainsComparison(col, EscapeAtArgument(RemoveQuote(val)), columnType);
|
||||
return SqlSyntaxContext.SqlSyntaxProvider.GetStringColumnContainsComparison(col, RemoveQuote(val), columnType);
|
||||
case "InvariantEquals":
|
||||
case "SqlEquals":
|
||||
//recurse
|
||||
|
||||
@@ -243,6 +243,10 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
args.RemoveAt(0);
|
||||
}
|
||||
|
||||
//TODO: We should probably add the same logic we've done for ModelToSqlExpressionHelper with checking for:
|
||||
// InvariantStartsWith, InvariantEndsWith, SqlWildcard, etc...
|
||||
// since we should be able to easily handle that with the Poco objects too.
|
||||
|
||||
switch (m.Method.Name)
|
||||
{
|
||||
case "ToUpper":
|
||||
@@ -250,11 +254,11 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
case "ToLower":
|
||||
return string.Format("lower({0})", r);
|
||||
case "StartsWith":
|
||||
return string.Format("upper({0}) like '{1}%'", r, EscapeAtArgument(RemoveQuote(args[0].ToString().ToUpper())));
|
||||
return string.Format("upper({0}) like '{1}%'", r, RemoveQuote(args[0].ToString().ToUpper()));
|
||||
case "EndsWith":
|
||||
return string.Format("upper({0}) like '%{1}'", r, EscapeAtArgument(RemoveQuote(args[0].ToString()).ToUpper()));
|
||||
return string.Format("upper({0}) like '%{1}'", r, RemoveQuote(args[0].ToString()).ToUpper());
|
||||
case "Contains":
|
||||
return string.Format("upper({0}) like '%{1}%'", r, EscapeAtArgument(RemoveQuote(args[0].ToString()).ToUpper()));
|
||||
return string.Format("upper({0}) like '%{1}%'", r, RemoveQuote(args[0].ToString()).ToUpper());
|
||||
case "Substring":
|
||||
var startIndex = Int32.Parse(args[0].ToString()) + 1;
|
||||
if (args.Count == 2)
|
||||
|
||||
@@ -24,8 +24,9 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
private readonly IContentTypeRepository _contentTypeRepository;
|
||||
private readonly ITemplateRepository _templateRepository;
|
||||
private readonly ITagsRepository _tagRepository;
|
||||
private readonly CacheHelper _cacheHelper;
|
||||
|
||||
public ContentRepository(IDatabaseUnitOfWork work, IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository, ITagsRepository tagRepository)
|
||||
public ContentRepository(IDatabaseUnitOfWork work, IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository, ITagsRepository tagRepository, CacheHelper cacheHelper)
|
||||
: base(work)
|
||||
{
|
||||
if (contentTypeRepository == null) throw new ArgumentNullException("contentTypeRepository");
|
||||
@@ -34,11 +35,12 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
_contentTypeRepository = contentTypeRepository;
|
||||
_templateRepository = templateRepository;
|
||||
_tagRepository = tagRepository;
|
||||
_cacheHelper = cacheHelper;
|
||||
|
||||
EnsureUniqueNaming = true;
|
||||
}
|
||||
|
||||
public ContentRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache, IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository, ITagsRepository tagRepository)
|
||||
public ContentRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache, IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository, ITagsRepository tagRepository, CacheHelper cacheHelper)
|
||||
: base(work, cache)
|
||||
{
|
||||
if (contentTypeRepository == null) throw new ArgumentNullException("contentTypeRepository");
|
||||
@@ -47,6 +49,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
_contentTypeRepository = contentTypeRepository;
|
||||
_templateRepository = templateRepository;
|
||||
_tagRepository = tagRepository;
|
||||
_cacheHelper = cacheHelper;
|
||||
|
||||
EnsureUniqueNaming = true;
|
||||
}
|
||||
@@ -139,6 +142,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
var list = new List<string>
|
||||
{
|
||||
"DELETE FROM cmsTask WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoUser2NodeNotify WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoUser2NodePermission WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoRelation WHERE parentId = @Id",
|
||||
@@ -274,7 +278,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
//Assign the same permissions to it as the parent node
|
||||
// http://issues.umbraco.org/issue/U4-2161
|
||||
var permissionsRepo = new PermissionRepository<IContent>(UnitOfWork);
|
||||
var permissionsRepo = new PermissionRepository<IContent>(UnitOfWork, _cacheHelper);
|
||||
var parentPermissions = permissionsRepo.GetPermissionsForEntity(entity.ParentId).ToArray();
|
||||
//if there are parent permissions then assign them, otherwise leave null and permissions will become the
|
||||
// user's default permissions.
|
||||
@@ -283,9 +287,9 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var userPermissions = (
|
||||
from perm in parentPermissions
|
||||
from p in perm.AssignedPermissions
|
||||
select new Tuple<object, string>(perm.UserId, p)).ToList();
|
||||
select new Tuple<int, string>(perm.UserId, p)).ToList();
|
||||
|
||||
permissionsRepo.AssignEntityPermissions(entity, userPermissions);
|
||||
permissionsRepo.ReplaceEntityPermissions(entity, userPermissions);
|
||||
//flag the entity's permissions changed flag so we can track those changes.
|
||||
//Currently only used for the cache refreshers to detect if we should refresh all user permissions cache.
|
||||
((Content) entity).PermissionsChanged = true;
|
||||
@@ -555,15 +559,21 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
return GetByVersion(dto.ContentVersionDto.VersionId);
|
||||
}
|
||||
|
||||
public void AssignEntityPermissions(IContent entity, char permission, IEnumerable<object> userIds)
|
||||
/// <summary>
|
||||
/// Assigns a single permission to the current content item for the specified user ids
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="permission"></param>
|
||||
/// <param name="userIds"></param>
|
||||
public void AssignEntityPermission(IContent entity, char permission, IEnumerable<int> userIds)
|
||||
{
|
||||
var repo = new PermissionRepository<IContent>(UnitOfWork);
|
||||
repo.AssignEntityPermissions(entity, permission, userIds);
|
||||
var repo = new PermissionRepository<IContent>(UnitOfWork, _cacheHelper);
|
||||
repo.AssignEntityPermission(entity, permission, userIds);
|
||||
}
|
||||
|
||||
public IEnumerable<EntityPermission> GetPermissionsForEntity(int entityId)
|
||||
{
|
||||
var repo = new PermissionRepository<IContent>(UnitOfWork);
|
||||
var repo = new PermissionRepository<IContent>(UnitOfWork, _cacheHelper);
|
||||
return repo.GetPermissionsForEntity(entityId);
|
||||
}
|
||||
|
||||
@@ -596,33 +606,6 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
return content;
|
||||
}
|
||||
|
||||
private PropertyCollection GetPropertyCollection(int id, Guid versionId, IContentType contentType, DateTime createDate, DateTime updateDate)
|
||||
{
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
.From<PropertyDataDto>()
|
||||
.InnerJoin<PropertyTypeDto>()
|
||||
.On<PropertyDataDto, PropertyTypeDto>(left => left.PropertyTypeId, right => right.Id)
|
||||
.Where<PropertyDataDto>(x => x.NodeId == id)
|
||||
.Where<PropertyDataDto>(x => x.VersionId == versionId);
|
||||
|
||||
var propertyDataDtos = Database.Fetch<PropertyDataDto, PropertyTypeDto>(sql);
|
||||
var propertyFactory = new PropertyFactory(contentType, versionId, id, createDate, updateDate);
|
||||
var properties = propertyFactory.BuildEntity(propertyDataDtos);
|
||||
|
||||
var newProperties = properties.Where(x => x.HasIdentity == false);
|
||||
foreach (var property in newProperties)
|
||||
{
|
||||
var propertyDataDto = new PropertyDataDto{ NodeId = id, PropertyTypeId = property.PropertyTypeId, VersionId = versionId };
|
||||
int primaryKey = Convert.ToInt32(Database.Insert(propertyDataDto));
|
||||
|
||||
property.Version = versionId;
|
||||
property.Id = primaryKey;
|
||||
}
|
||||
|
||||
return new PropertyCollection(properties);
|
||||
}
|
||||
|
||||
private string EnsureUniqueNodeName(int parentId, string nodeName, int id = 0)
|
||||
{
|
||||
if (EnsureUniqueNaming == false)
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
@@ -54,19 +55,10 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
yield return dto.ContentTypeNodeId;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We need to override this method to ensure that any content cache is cleared
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <remarks>
|
||||
/// see: http://issues.umbraco.org/issue/U4-1963
|
||||
/// </remarks>
|
||||
public override void PersistUpdatedItem(IEntity entity)
|
||||
|
||||
protected virtual PropertyType CreatePropertyType(string propertyEditorAlias, DataTypeDatabaseType dbType, string propertyTypeAlias)
|
||||
{
|
||||
InMemoryCacheProvider.Current.Clear(typeof(IContent));
|
||||
RuntimeCacheProvider.Current.Clear(typeof(IContent));
|
||||
base.PersistUpdatedItem(entity);
|
||||
return new PropertyType(propertyEditorAlias, dbType);
|
||||
}
|
||||
|
||||
protected void PersistNewBaseContentType(ContentTypeDto dto, IContentTypeComposition entity)
|
||||
@@ -158,8 +150,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
//If the Id of the DataType is not set, we resolve it from the db by its PropertyEditorAlias
|
||||
if (propertyType.DataTypeDefinitionId == 0 || propertyType.DataTypeDefinitionId == default(int))
|
||||
{
|
||||
var datatype = Database.FirstOrDefault<DataTypeDto>("WHERE propertyEditorAlias = @alias", new { alias = propertyType.PropertyEditorAlias });
|
||||
propertyType.DataTypeDefinitionId = datatype.DataTypeId;
|
||||
AssignDataTypeFromPropertyEditor(propertyType);
|
||||
}
|
||||
var propertyTypeDto = propertyFactory.BuildPropertyTypeDto(tabId, propertyType);
|
||||
int typePrimaryKey = Convert.ToInt32(Database.Insert(propertyTypeDto));
|
||||
@@ -316,9 +307,12 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
//If the Id of the DataType is not set, we resolve it from the db by its PropertyEditorAlias
|
||||
if (propertyType.DataTypeDefinitionId == 0 || propertyType.DataTypeDefinitionId == default(int))
|
||||
{
|
||||
var datatype = Database.FirstOrDefault<DataTypeDto>("WHERE propertyEditorAlias = @alias", new { alias = propertyType.PropertyEditorAlias });
|
||||
propertyType.DataTypeDefinitionId = datatype.DataTypeId;
|
||||
AssignDataTypeFromPropertyEditor(propertyType);
|
||||
}
|
||||
|
||||
//validate the alias!
|
||||
ValidateAlias(propertyType);
|
||||
|
||||
var propertyTypeDto = propertyGroupFactory.BuildPropertyTypeDto(tabId, propertyType);
|
||||
int typePrimaryKey = propertyType.HasIdentity
|
||||
? Database.Update(propertyTypeDto)
|
||||
@@ -355,7 +349,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
var dtos = Database.Fetch<PropertyTypeGroupDto, PropertyTypeDto, DataTypeDto, PropertyTypeGroupDto>(new GroupPropertyTypeRelator().Map, sql);
|
||||
|
||||
var propertyGroupFactory = new PropertyGroupFactory(id, createDate, updateDate);
|
||||
var propertyGroupFactory = new PropertyGroupFactory(id, createDate, updateDate, CreatePropertyType);
|
||||
var propertyGroups = propertyGroupFactory.BuildEntity(dtos);
|
||||
return new PropertyGroupCollection(propertyGroups);
|
||||
}
|
||||
@@ -372,29 +366,88 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var dtos = Database.Fetch<PropertyTypeDto, DataTypeDto>(sql);
|
||||
|
||||
//TODO Move this to a PropertyTypeFactory
|
||||
var list = (from dto in dtos
|
||||
where (dto.PropertyTypeGroupId > 0) == false
|
||||
select
|
||||
new PropertyType(dto.DataTypeDto.PropertyEditorAlias,
|
||||
dto.DataTypeDto.DbType.EnumParse<DataTypeDatabaseType>(true))
|
||||
{
|
||||
Alias = dto.Alias,
|
||||
DataTypeDefinitionId = dto.DataTypeId,
|
||||
Description = dto.Description,
|
||||
Id = dto.Id,
|
||||
Name = dto.Name,
|
||||
HelpText = dto.HelpText,
|
||||
Mandatory = dto.Mandatory,
|
||||
SortOrder = dto.SortOrder,
|
||||
ValidationRegExp = dto.ValidationRegExp,
|
||||
CreateDate = createDate,
|
||||
UpdateDate = updateDate
|
||||
}).ToList();
|
||||
|
||||
var list = new List<PropertyType>();
|
||||
foreach (var dto in dtos.Where(x => (x.PropertyTypeGroupId > 0) == false))
|
||||
{
|
||||
var propType = CreatePropertyType(dto.DataTypeDto.PropertyEditorAlias, dto.DataTypeDto.DbType.EnumParse<DataTypeDatabaseType>(true), dto.Alias);
|
||||
propType.Alias = dto.Alias;
|
||||
propType.DataTypeDefinitionId = dto.DataTypeId;
|
||||
propType.Description = dto.Description;
|
||||
propType.Id = dto.Id;
|
||||
propType.Name = dto.Name;
|
||||
propType.HelpText = dto.HelpText;
|
||||
propType.Mandatory = dto.Mandatory;
|
||||
propType.SortOrder = dto.SortOrder;
|
||||
propType.ValidationRegExp = dto.ValidationRegExp;
|
||||
propType.CreateDate = createDate;
|
||||
propType.UpdateDate = updateDate;
|
||||
list.Add(propType);
|
||||
}
|
||||
//Reset dirty properties
|
||||
Parallel.ForEach(list, currentFile => currentFile.ResetDirtyProperties(false));
|
||||
|
||||
return new PropertyTypeCollection(list);
|
||||
}
|
||||
|
||||
protected void ValidateAlias(PropertyType pt)
|
||||
{
|
||||
Mandate.That<InvalidOperationException>(string.IsNullOrEmpty(pt.Alias) == false,
|
||||
() =>
|
||||
{
|
||||
var message =
|
||||
string.Format(
|
||||
"{0} '{1}' cannot have an empty Alias. This is most likely due to invalid characters stripped from the Alias.",
|
||||
"Property Type",
|
||||
pt.Name);
|
||||
var exception = new InvalidOperationException(message);
|
||||
|
||||
LogHelper.Error<ContentTypeBaseRepository<TId, TEntity>>(message, exception);
|
||||
throw exception;
|
||||
});
|
||||
}
|
||||
|
||||
protected void ValidateAlias(TEntity entity)
|
||||
{
|
||||
Mandate.That<InvalidOperationException>(string.IsNullOrEmpty(entity.Alias) == false,
|
||||
() =>
|
||||
{
|
||||
var message =
|
||||
string.Format(
|
||||
"{0} '{1}' cannot have an empty Alias. This is most likely due to invalid characters stripped from the Alias.",
|
||||
typeof(TEntity).Name,
|
||||
entity.Name);
|
||||
var exception = new InvalidOperationException(message);
|
||||
|
||||
LogHelper.Error<ContentTypeBaseRepository<TId, TEntity>>(message, exception);
|
||||
throw exception;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to set the data type id based on its ControlId
|
||||
/// </summary>
|
||||
/// <param name="propertyType"></param>
|
||||
private void AssignDataTypeFromPropertyEditor(PropertyType propertyType)
|
||||
{
|
||||
//we cannot try to assign a data type of it's empty
|
||||
if (propertyType.PropertyEditorAlias.IsNullOrWhiteSpace() == false)
|
||||
{
|
||||
var sql = new Sql()
|
||||
.Select("*")
|
||||
.From<DataTypeDto>()
|
||||
.Where("propertyEditorAlias = @propertyEditorAlias", new { propertyEditorAlias = propertyType.PropertyEditorAlias })
|
||||
.OrderBy<DataTypeDto>(typeDto => typeDto.DataTypeId);
|
||||
var datatype = Database.FirstOrDefault<DataTypeDto>(sql);
|
||||
//we cannot assign a data type if one was not found
|
||||
if (datatype != null)
|
||||
{
|
||||
propertyType.DataTypeDefinitionId = datatype.DataTypeId;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.Warn<ContentTypeBaseRepository<TId, TEntity>>("Could not assign a data type for the property type " + propertyType.Alias + " since no data type was found with a property editor " + propertyType.PropertyEditorAlias);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -229,18 +229,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
protected override void PersistUpdatedItem(IContentType entity)
|
||||
{
|
||||
Mandate.That<Exception>(string.IsNullOrEmpty(entity.Alias) == false,
|
||||
() =>
|
||||
{
|
||||
var message =
|
||||
string.Format(
|
||||
"ContentType '{0}' cannot have an empty Alias. This is most likely due to invalid characters stripped from the Alias.",
|
||||
entity.Name);
|
||||
var exception = new Exception(message);
|
||||
|
||||
LogHelper.Error<ContentTypeRepository>(message, exception);
|
||||
throw exception;
|
||||
});
|
||||
ValidateAlias(entity);
|
||||
|
||||
//Updates Modified date
|
||||
((ContentType)entity).UpdatingEntity();
|
||||
|
||||
@@ -23,8 +23,19 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <returns>An enumerable list of <see cref="IContent"/></returns>
|
||||
IEnumerable<IContent> GetByPublishedVersion(IQuery<IContent> query);
|
||||
|
||||
void AssignEntityPermissions(IContent entity, char permission, IEnumerable<object> userIds);
|
||||
/// <summary>
|
||||
/// Assigns a single permission to the current content item for the specified user ids
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="permission"></param>
|
||||
/// <param name="userIds"></param>
|
||||
void AssignEntityPermission(IContent entity, char permission, IEnumerable<int> userIds);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of permissions for the content item
|
||||
/// </summary>
|
||||
/// <param name="entityId"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<EntityPermission> GetPermissionsForEntity(int entityId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
public interface IMemberGroupRepository : IRepositoryQueryable<int, IMemberGroup>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a member group by it's name
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
IMemberGroup GetByName(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Creates the new member group if it doesn't already exist
|
||||
/// </summary>
|
||||
/// <param name="roleName"></param>
|
||||
IMemberGroup CreateIfNotExists(string roleName);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the member groups for a given member
|
||||
/// </summary>
|
||||
/// <param name="memberId"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<IMemberGroup> GetMemberGroupsForMember(int memberId);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the member groups for a given member
|
||||
/// </summary>
|
||||
/// <param name="username"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<IMemberGroup> GetMemberGroupsForMember(string username);
|
||||
|
||||
void AssignRoles(string[] usernames, string[] roleNames);
|
||||
|
||||
void DissociateRoles(string[] usernames, string[] roleNames);
|
||||
|
||||
void AssignRoles(int[] memberIds, string[] roleNames);
|
||||
|
||||
void DissociateRoles(int[] memberIds, string[] roleNames);
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,17 @@ using Umbraco.Core.Persistence.Querying;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
internal interface IMemberRepository : IRepositoryVersionable<int, IMember>
|
||||
public interface IMemberRepository : IRepositoryVersionable<int, IMember>
|
||||
{
|
||||
/// <summary>
|
||||
/// Finds members in a given role
|
||||
/// </summary>
|
||||
/// <param name="roleName"></param>
|
||||
/// <param name="usernameToMatch"></param>
|
||||
/// <param name="matchType"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<IMember> FindMembersInRole(string roleName, string usernameToMatch, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith);
|
||||
|
||||
/// <summary>
|
||||
/// Get all members in a specific group
|
||||
/// </summary>
|
||||
|
||||
@@ -6,7 +6,7 @@ using Umbraco.Core.Persistence.Querying;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
internal interface IUserRepository : IRepositoryQueryable<int, IUser>
|
||||
public interface IUserRepository : IRepositoryQueryable<int, IUser>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the count of items based on a complex query
|
||||
@@ -38,7 +38,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <param name="orderBy"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<IUser> GetPagedResultsByQuery(IQuery<IUser> query, int pageIndex, int pageSize, out int totalRecords, Expression<Func<IUser, string>> orderBy);
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user permissions for the specified entities
|
||||
@@ -46,7 +46,14 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="entityIds"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<EntityPermission> GetUserPermissionsForEntities(object userId, params int[] entityIds);
|
||||
IEnumerable<EntityPermission> GetUserPermissionsForEntities(int userId, params int[] entityIds);
|
||||
|
||||
/// <summary>
|
||||
/// Replaces the same permission set for a single user to any number of entities
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="permissions"></param>
|
||||
/// <param name="entityIds"></param>
|
||||
void ReplaceUserPermissions(int userId, IEnumerable<char> permissions, params int[] entityIds);
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
internal interface IUserTypeRepository : IRepositoryQueryable<int, IUserType>
|
||||
public interface IUserTypeRepository : IRepositoryQueryable<int, IUserType>
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -131,6 +131,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
var list = new List<string>
|
||||
{
|
||||
"DELETE FROM cmsTask WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoUser2NodeNotify WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoUser2NodePermission WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoRelation WHERE parentId = @Id",
|
||||
@@ -370,33 +371,6 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
#endregion
|
||||
|
||||
private PropertyCollection GetPropertyCollection(int id, Guid versionId, IMediaType contentType, DateTime createDate, DateTime updateDate)
|
||||
{
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
.From<PropertyDataDto>()
|
||||
.InnerJoin<PropertyTypeDto>()
|
||||
.On<PropertyDataDto, PropertyTypeDto>(left => left.PropertyTypeId, right => right.Id)
|
||||
.Where<PropertyDataDto>(x => x.NodeId == id)
|
||||
.Where<PropertyDataDto>(x => x.VersionId == versionId);
|
||||
|
||||
var propertyDataDtos = Database.Fetch<PropertyDataDto, PropertyTypeDto>(sql);
|
||||
var propertyFactory = new PropertyFactory(contentType, versionId, id, createDate, updateDate);
|
||||
var properties = propertyFactory.BuildEntity(propertyDataDtos);
|
||||
|
||||
var newProperties = properties.Where(x => x.HasIdentity == false);
|
||||
foreach (var property in newProperties)
|
||||
{
|
||||
var propertyDataDto = new PropertyDataDto { NodeId = id, PropertyTypeId = property.PropertyTypeId, VersionId = versionId };
|
||||
int primaryKey = Convert.ToInt32(Database.Insert(propertyDataDto));
|
||||
|
||||
property.Version = versionId;
|
||||
property.Id = primaryKey;
|
||||
}
|
||||
|
||||
return new PropertyCollection(properties);
|
||||
}
|
||||
|
||||
private string EnsureUniqueNodeName(int parentId, string nodeName, int id = 0)
|
||||
{
|
||||
if (EnsureUniqueNaming == false)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
@@ -162,6 +163,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
protected override void PersistUpdatedItem(IMediaType entity)
|
||||
{
|
||||
ValidateAlias(entity);
|
||||
|
||||
//Updates Modified date
|
||||
((MediaType)entity).UpdatingEntity();
|
||||
|
||||
|
||||
@@ -1,7 +1,383 @@
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.Caching;
|
||||
using Umbraco.Core.Persistence.Factories;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Cache;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
public class MemberGroupRepository
|
||||
|
||||
|
||||
internal class MemberGroupRepository : PetaPocoRepositoryBase<int, IMemberGroup>, IMemberGroupRepository
|
||||
{
|
||||
|
||||
private readonly CacheHelper _cacheHelper;
|
||||
|
||||
public MemberGroupRepository(IDatabaseUnitOfWork work, CacheHelper cacheHelper)
|
||||
: base(work)
|
||||
{
|
||||
if (cacheHelper == null) throw new ArgumentNullException("cacheHelper");
|
||||
_cacheHelper = cacheHelper;
|
||||
}
|
||||
|
||||
public MemberGroupRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache, CacheHelper cacheHelper)
|
||||
: base(work, cache)
|
||||
{
|
||||
if (cacheHelper == null) throw new ArgumentNullException("cacheHelper");
|
||||
_cacheHelper = cacheHelper;
|
||||
}
|
||||
|
||||
private readonly MemberGroupFactory _modelFactory = new MemberGroupFactory();
|
||||
|
||||
protected override IMemberGroup PerformGet(int id)
|
||||
{
|
||||
var sql = GetBaseQuery(false);
|
||||
sql.Where(GetBaseWhereClause(), new { Id = id });
|
||||
|
||||
var dto = Database.Fetch<NodeDto>(sql).FirstOrDefault();
|
||||
|
||||
return dto == null ? null : _modelFactory.BuildEntity(dto);
|
||||
}
|
||||
|
||||
protected override IEnumerable<IMemberGroup> PerformGetAll(params int[] ids)
|
||||
{
|
||||
if (ids.Any())
|
||||
{
|
||||
var sql = new Sql()
|
||||
.Select("*")
|
||||
.From<NodeDto>()
|
||||
.Where<NodeDto>(dto => dto.NodeObjectType == NodeObjectTypeId)
|
||||
.Where("umbracoNode.id in (@ids)", new { ids = ids });
|
||||
return Database.Fetch<NodeDto>(sql)
|
||||
.Select(x => _modelFactory.BuildEntity(x));
|
||||
}
|
||||
else
|
||||
{
|
||||
var sql = new Sql()
|
||||
.From<NodeDto>()
|
||||
.Where<NodeDto>(dto => dto.NodeObjectType == NodeObjectTypeId);
|
||||
return Database.Fetch<NodeDto>(sql)
|
||||
.Select(x => _modelFactory.BuildEntity(x));
|
||||
}
|
||||
}
|
||||
|
||||
protected override IEnumerable<IMemberGroup> PerformGetByQuery(IQuery<IMemberGroup> query)
|
||||
{
|
||||
var sqlClause = GetBaseQuery(false);
|
||||
var translator = new SqlTranslator<IMemberGroup>(sqlClause, query);
|
||||
var sql = translator.Translate();
|
||||
|
||||
return Database.Fetch<NodeDto>(sql)
|
||||
.Select(x => _modelFactory.BuildEntity(x));
|
||||
}
|
||||
|
||||
protected override Sql GetBaseQuery(bool isCount)
|
||||
{
|
||||
var sql = new Sql();
|
||||
sql.Select(isCount ? "COUNT(*)" : "*")
|
||||
.From<NodeDto>()
|
||||
.Where<NodeDto>(x => x.NodeObjectType == NodeObjectTypeId);
|
||||
return sql;
|
||||
}
|
||||
|
||||
protected override string GetBaseWhereClause()
|
||||
{
|
||||
return "umbracoNode.id = @Id";
|
||||
}
|
||||
|
||||
protected override IEnumerable<string> GetDeleteClauses()
|
||||
{
|
||||
var list = new[]
|
||||
{
|
||||
"DELETE FROM umbracoUser2NodeNotify WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoUser2NodePermission WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoRelation WHERE parentId = @Id",
|
||||
"DELETE FROM umbracoRelation WHERE childId = @Id",
|
||||
"DELETE FROM cmsTagRelationship WHERE nodeId = @Id",
|
||||
"DELETE FROM cmsMember2MemberGroup WHERE MemberGroup = @Id",
|
||||
"DELETE FROM umbracoNode WHERE id = @Id"
|
||||
};
|
||||
return list;
|
||||
}
|
||||
|
||||
protected override Guid NodeObjectTypeId
|
||||
{
|
||||
get { return new Guid(Constants.ObjectTypes.MemberGroup); }
|
||||
}
|
||||
|
||||
protected override void PersistNewItem(IMemberGroup entity)
|
||||
{
|
||||
//Save to db
|
||||
var group = (MemberGroup)entity;
|
||||
group.AddingEntity();
|
||||
var dto = _modelFactory.BuildDto(group);
|
||||
var o = Database.IsNew(dto) ? Convert.ToInt32(Database.Insert(dto)) : Database.Update(dto);
|
||||
|
||||
//Update with new correct path
|
||||
dto.Path = string.Concat("-1,", dto.NodeId);
|
||||
Database.Update(dto);
|
||||
|
||||
group.ResetDirtyProperties();
|
||||
}
|
||||
|
||||
protected override void PersistUpdatedItem(IMemberGroup entity)
|
||||
{
|
||||
var dto = _modelFactory.BuildDto(entity);
|
||||
|
||||
Database.Update(dto);
|
||||
|
||||
((ICanBeDirty)entity).ResetDirtyProperties();
|
||||
}
|
||||
|
||||
public IMemberGroup GetByName(string name)
|
||||
{
|
||||
return _cacheHelper.RuntimeCache.GetCacheItem<IMemberGroup>(
|
||||
string.Format("{0}.{1}", typeof (IMemberGroup).FullName, name),
|
||||
() =>
|
||||
{
|
||||
var qry = new Query<IMemberGroup>().Where(group => group.Name.Equals(name));
|
||||
var result = GetByQuery(qry);
|
||||
return result.FirstOrDefault();
|
||||
},
|
||||
//cache for 5 mins since that is the default in the RuntimeCacheProvider
|
||||
TimeSpan.FromMinutes(5),
|
||||
//sliding is true
|
||||
true);
|
||||
}
|
||||
|
||||
public IMemberGroup CreateIfNotExists(string roleName)
|
||||
{
|
||||
using (var transaction = Database.GetTransaction())
|
||||
{
|
||||
var qry = new Query<IMemberGroup>().Where(group => group.Name.Equals(roleName));
|
||||
var result = GetByQuery(qry);
|
||||
|
||||
if (result.Any()) return null;
|
||||
|
||||
var grp = new MemberGroup
|
||||
{
|
||||
Name = roleName
|
||||
};
|
||||
PersistNewItem(grp);
|
||||
|
||||
if (SavingMemberGroup.IsRaisedEventCancelled(new SaveEventArgs<IMemberGroup>(grp), this))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
transaction.Complete();
|
||||
|
||||
SavedMemberGroup.RaiseEvent(new SaveEventArgs<IMemberGroup>(grp), this);
|
||||
|
||||
return grp;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IMemberGroup> GetMemberGroupsForMember(int memberId)
|
||||
{
|
||||
var sql = new Sql();
|
||||
sql.Select("umbracoNode.*")
|
||||
.From<NodeDto>()
|
||||
.InnerJoin<Member2MemberGroupDto>()
|
||||
.On<NodeDto, Member2MemberGroupDto>(dto => dto.NodeId, dto => dto.MemberGroup)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == NodeObjectTypeId)
|
||||
.Where<Member2MemberGroupDto>(x => x.Member == memberId);
|
||||
|
||||
return Database.Fetch<NodeDto>(sql)
|
||||
.DistinctBy(dto => dto.NodeId)
|
||||
.Select(x => _modelFactory.BuildEntity(x));
|
||||
}
|
||||
|
||||
public IEnumerable<IMemberGroup> GetMemberGroupsForMember(string username)
|
||||
{
|
||||
//find the member by username
|
||||
var memberSql = new Sql();
|
||||
var memberObjectType = new Guid(Constants.ObjectTypes.Member);
|
||||
var escapedUsername = PetaPocoExtensions.EscapeAtSymbols(username);
|
||||
memberSql.Select("umbracoNode.id")
|
||||
.From<NodeDto>()
|
||||
.InnerJoin<MemberDto>()
|
||||
.On<NodeDto, MemberDto>(dto => dto.NodeId, dto => dto.NodeId)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == memberObjectType)
|
||||
.Where<MemberDto>(x => x.LoginName == escapedUsername);
|
||||
var memberIdUsername = Database.Fetch<int?>(memberSql).FirstOrDefault();
|
||||
if (memberIdUsername.HasValue == false)
|
||||
{
|
||||
return Enumerable.Empty<IMemberGroup>();
|
||||
}
|
||||
|
||||
var sql = new Sql();
|
||||
sql.Select("umbracoNode.*")
|
||||
.From<NodeDto>()
|
||||
.InnerJoin<Member2MemberGroupDto>()
|
||||
.On<NodeDto, Member2MemberGroupDto>(dto => dto.NodeId, dto => dto.MemberGroup)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == NodeObjectTypeId)
|
||||
.Where<Member2MemberGroupDto>(x => x.Member == memberIdUsername.Value);
|
||||
|
||||
return Database.Fetch<NodeDto>(sql)
|
||||
.DistinctBy(dto => dto.NodeId)
|
||||
.Select(x => _modelFactory.BuildEntity(x));
|
||||
}
|
||||
|
||||
public void AssignRoles(string[] usernames, string[] roleNames)
|
||||
{
|
||||
using (var transaction = Database.GetTransaction())
|
||||
{
|
||||
//first get the member ids based on the usernames
|
||||
var memberSql = new Sql();
|
||||
var memberObjectType = new Guid(Constants.ObjectTypes.Member);
|
||||
memberSql.Select("umbracoNode.id")
|
||||
.From<NodeDto>()
|
||||
.InnerJoin<MemberDto>()
|
||||
.On<NodeDto, MemberDto>(dto => dto.NodeId, dto => dto.NodeId)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == memberObjectType)
|
||||
.Where("cmsMember.LoginName in (@usernames)", new { usernames = usernames });
|
||||
var memberIds = Database.Fetch<int>(memberSql).ToArray();
|
||||
|
||||
AssignRolesInternal(memberIds, roleNames);
|
||||
transaction.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
public void DissociateRoles(string[] usernames, string[] roleNames)
|
||||
{
|
||||
using (var transaction = Database.GetTransaction())
|
||||
{
|
||||
//first get the member ids based on the usernames
|
||||
var memberSql = new Sql();
|
||||
var memberObjectType = new Guid(Constants.ObjectTypes.Member);
|
||||
memberSql.Select("umbracoNode.id")
|
||||
.From<NodeDto>()
|
||||
.InnerJoin<MemberDto>()
|
||||
.On<NodeDto, MemberDto>(dto => dto.NodeId, dto => dto.NodeId)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == memberObjectType)
|
||||
.Where("cmsMember.LoginName in (@usernames)", new { usernames = usernames });
|
||||
var memberIds = Database.Fetch<int>(memberSql).ToArray();
|
||||
|
||||
DissociateRolesInternal(memberIds, roleNames);
|
||||
transaction.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
public void AssignRoles(int[] memberIds, string[] roleNames)
|
||||
{
|
||||
using (var transaction = Database.GetTransaction())
|
||||
{
|
||||
AssignRolesInternal(memberIds, roleNames);
|
||||
transaction.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
public void AssignRolesInternal(int[] memberIds, string[] roleNames)
|
||||
{
|
||||
//create the missing roles first
|
||||
|
||||
var existingSql = new Sql()
|
||||
.Select("*")
|
||||
.From<NodeDto>()
|
||||
.Where<NodeDto>(dto => dto.NodeObjectType == NodeObjectTypeId)
|
||||
.Where("umbracoNode." + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("text") + " in (@names)", new { names = roleNames });
|
||||
var existingRoles = Database.Fetch<NodeDto>(existingSql).Select(x => x.Text);
|
||||
var missingRoles = roleNames.Except(existingRoles);
|
||||
var missingGroups = missingRoles.Select(x => new MemberGroup {Name = x}).ToArray();
|
||||
|
||||
if (SavingMemberGroup.IsRaisedEventCancelled(new SaveEventArgs<IMemberGroup>(missingGroups), this))
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (var m in missingGroups)
|
||||
{
|
||||
PersistNewItem(m);
|
||||
}
|
||||
SavedMemberGroup.RaiseEvent(new SaveEventArgs<IMemberGroup>(missingGroups), this);
|
||||
|
||||
//now go get all the dto's for roles with these role names
|
||||
var rolesForNames = Database.Fetch<NodeDto>(existingSql).ToArray();
|
||||
|
||||
//get the groups that are currently assigned to any of these members
|
||||
|
||||
var assignedSql = new Sql();
|
||||
assignedSql.Select(string.Format(
|
||||
"{0},{1},{2}",
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("text"),
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("Member"),
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("MemberGroup")))
|
||||
.From<NodeDto>()
|
||||
.InnerJoin<Member2MemberGroupDto>()
|
||||
.On<NodeDto, Member2MemberGroupDto>(dto => dto.NodeId, dto => dto.MemberGroup)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == NodeObjectTypeId)
|
||||
.Where("cmsMember2MemberGroup.Member in (@ids)", new { ids = memberIds });
|
||||
|
||||
var currentlyAssigned = Database.Fetch<AssignedRolesDto>(assignedSql).ToArray();
|
||||
|
||||
//assign the roles for each member id
|
||||
|
||||
foreach (var memberId in memberIds)
|
||||
{
|
||||
//find any roles for the current member that are currently assigned that
|
||||
//exist in the roleNames list, then determine which ones are not currently assigned.
|
||||
var mId = memberId;
|
||||
var found = currentlyAssigned.Where(x => x.MemberId == mId).ToArray();
|
||||
var assignedRoles = found.Where(x => roleNames.Contains(x.RoleName)).Select(x => x.RoleName);
|
||||
var nonAssignedRoles = roleNames.Except(assignedRoles);
|
||||
foreach (var toAssign in nonAssignedRoles)
|
||||
{
|
||||
var groupId = rolesForNames.First(x => x.Text == toAssign).NodeId;
|
||||
Database.Insert(new Member2MemberGroupDto { Member = mId, MemberGroup = groupId });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DissociateRoles(int[] memberIds, string[] roleNames)
|
||||
{
|
||||
using (var transaction = Database.GetTransaction())
|
||||
{
|
||||
DissociateRolesInternal(memberIds, roleNames);
|
||||
transaction.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
private void DissociateRolesInternal(int[] memberIds, string[] roleNames)
|
||||
{
|
||||
var existingSql = new Sql()
|
||||
.Select("*")
|
||||
.From<NodeDto>()
|
||||
.Where<NodeDto>(dto => dto.NodeObjectType == NodeObjectTypeId)
|
||||
.Where("umbracoNode." + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("text") + " in (@names)", new { names = roleNames });
|
||||
var existingRolesIds = Database.Fetch<NodeDto>(existingSql).Select(x => x.NodeId).ToArray();
|
||||
|
||||
Database.Execute("DELETE FROM cmsMember2MemberGroup WHERE Member IN (@memberIds) AND MemberGroup IN (@memberGroups)",
|
||||
new { memberIds = memberIds, memberGroups = existingRolesIds });
|
||||
}
|
||||
|
||||
private class AssignedRolesDto
|
||||
{
|
||||
[Column("text")]
|
||||
public string RoleName { get; set; }
|
||||
|
||||
[Column("Member")]
|
||||
public int MemberId { get; set; }
|
||||
|
||||
[Column("MemberGroup")]
|
||||
public int MemberGroupId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs before Save
|
||||
/// </summary>
|
||||
internal static event TypedEventHandler<IMemberGroupRepository, SaveEventArgs<IMemberGroup>> SavingMemberGroup;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs after Save
|
||||
/// </summary>
|
||||
internal static event TypedEventHandler<IMemberGroupRepository, SaveEventArgs<IMemberGroup>> SavedMemberGroup;
|
||||
}
|
||||
}
|
||||
@@ -24,23 +24,26 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
private readonly IMemberTypeRepository _memberTypeRepository;
|
||||
private readonly ITagsRepository _tagRepository;
|
||||
private readonly IMemberGroupRepository _memberGroupRepository;
|
||||
|
||||
public MemberRepository(IDatabaseUnitOfWork work, IMemberTypeRepository memberTypeRepository, ITagsRepository tagRepository)
|
||||
public MemberRepository(IDatabaseUnitOfWork work, IMemberTypeRepository memberTypeRepository, IMemberGroupRepository memberGroupRepository, ITagsRepository tagRepository)
|
||||
: base(work)
|
||||
{
|
||||
if (memberTypeRepository == null) throw new ArgumentNullException("memberTypeRepository");
|
||||
if (tagRepository == null) throw new ArgumentNullException("tagRepository");
|
||||
_memberTypeRepository = memberTypeRepository;
|
||||
_tagRepository = tagRepository;
|
||||
_memberGroupRepository = memberGroupRepository;
|
||||
}
|
||||
|
||||
public MemberRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache, IMemberTypeRepository memberTypeRepository, ITagsRepository tagRepository)
|
||||
public MemberRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache, IMemberTypeRepository memberTypeRepository, IMemberGroupRepository memberGroupRepository, ITagsRepository tagRepository)
|
||||
: base(work, cache)
|
||||
{
|
||||
if (memberTypeRepository == null) throw new ArgumentNullException("memberTypeRepository");
|
||||
if (tagRepository == null) throw new ArgumentNullException("tagRepository");
|
||||
_memberTypeRepository = memberTypeRepository;
|
||||
_tagRepository = tagRepository;
|
||||
_memberGroupRepository = memberGroupRepository;
|
||||
}
|
||||
|
||||
#region Overrides of RepositoryBase<int, IMembershipUser>
|
||||
@@ -169,6 +172,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
var list = new List<string>
|
||||
{
|
||||
"DELETE FROM cmsTask WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoUser2NodeNotify WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoUser2NodePermission WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoRelation WHERE parentId = @Id",
|
||||
@@ -242,7 +246,12 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
//Create the PropertyData for this version - cmsPropertyData
|
||||
var propertyFactory = new PropertyFactory(entity.ContentType, entity.Version, entity.Id);
|
||||
var propertyDataDtos = propertyFactory.BuildDto(((Member)entity).Properties);
|
||||
//Add Properties
|
||||
// - don't try to save the property if it doesn't exist (or doesn't have an ID) on the content type
|
||||
// - this can occur if the member type doesn't contain the built-in properties that the
|
||||
// - member object contains.
|
||||
var propsToPersist = entity.Properties.Where(x => x.PropertyType.HasIdentity).ToArray();
|
||||
var propertyDataDtos = propertyFactory.BuildDto(propsToPersist);
|
||||
var keyDictionary = new Dictionary<int, int>();
|
||||
|
||||
//Add Properties
|
||||
@@ -253,7 +262,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
}
|
||||
|
||||
//Update Properties with its newly set Id
|
||||
foreach (var property in ((Member)entity).Properties)
|
||||
foreach (var property in propsToPersist)
|
||||
{
|
||||
property.Id = keyDictionary[property.PropertyTypeId];
|
||||
}
|
||||
@@ -338,12 +347,10 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
//Add Properties
|
||||
// - don't try to save the property if it doesn't exist (or doesn't have an ID) on the content type
|
||||
// - this can occur if the member type doesn't contain the built-in properties that the
|
||||
// - member object contains.
|
||||
var existingProperties = entity.Properties
|
||||
.Where(property => entity.ContentType.PropertyTypes.Any(x => x.Alias == property.Alias && x.HasIdentity))
|
||||
.ToList();
|
||||
// - member object contains.
|
||||
var propsToPersist = entity.Properties.Where(x => x.PropertyType.HasIdentity).ToArray();
|
||||
|
||||
var propertyDataDtos = propertyFactory.BuildDto(existingProperties);
|
||||
var propertyDataDtos = propertyFactory.BuildDto(propsToPersist);
|
||||
|
||||
foreach (var propertyDataDto in propertyDataDtos)
|
||||
{
|
||||
@@ -428,6 +435,57 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
#endregion
|
||||
|
||||
public IEnumerable<IMember> FindMembersInRole(string roleName, string usernameToMatch, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith)
|
||||
{
|
||||
//get the group id
|
||||
var grpQry = new Query<IMemberGroup>().Where(group => group.Name.Equals(roleName));
|
||||
var memberGroup = _memberGroupRepository.GetByQuery(grpQry).FirstOrDefault();
|
||||
if (memberGroup == null) return Enumerable.Empty<IMember>();
|
||||
|
||||
// get the members by username
|
||||
var query = new Query<IMember>();
|
||||
switch (matchType)
|
||||
{
|
||||
case StringPropertyMatchType.Exact:
|
||||
query.Where(member => member.Username.Equals(usernameToMatch));
|
||||
break;
|
||||
case StringPropertyMatchType.Contains:
|
||||
query.Where(member => member.Username.Contains(usernameToMatch));
|
||||
break;
|
||||
case StringPropertyMatchType.StartsWith:
|
||||
query.Where(member => member.Username.StartsWith(usernameToMatch));
|
||||
break;
|
||||
case StringPropertyMatchType.EndsWith:
|
||||
query.Where(member => member.Username.EndsWith(usernameToMatch));
|
||||
break;
|
||||
case StringPropertyMatchType.Wildcard:
|
||||
query.Where(member => member.Username.SqlWildcard(usernameToMatch, TextColumnType.NVarchar));
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("matchType");
|
||||
}
|
||||
var matchedMembers = GetByQuery(query).ToArray();
|
||||
|
||||
var membersInGroup = new List<IMember>();
|
||||
//then we need to filter the matched members that are in the role
|
||||
//since the max sql params are 2100 on sql server, we'll reduce that to be safe for potentially other servers and run the queries in batches
|
||||
var inGroups = matchedMembers.InGroupsOf(1000);
|
||||
foreach (var batch in inGroups)
|
||||
{
|
||||
var memberIdBatch = batch.Select(x => x.Id);
|
||||
var sql = new Sql().Select("*").From<Member2MemberGroupDto>()
|
||||
.Where<Member2MemberGroupDto>(dto => dto.MemberGroup == memberGroup.Id)
|
||||
.Where("Member IN (@memberIds)", new { memberIds = memberIdBatch });
|
||||
var memberIdsInGroup = Database.Fetch<Member2MemberGroupDto>(sql)
|
||||
.Select(x => x.Member).ToArray();
|
||||
|
||||
membersInGroup.AddRange(matchedMembers.Where(x => memberIdsInGroup.Contains(x.Id)));
|
||||
}
|
||||
|
||||
return membersInGroup;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get all members in a specific group
|
||||
/// </summary>
|
||||
@@ -435,9 +493,13 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <returns></returns>
|
||||
public IEnumerable<IMember> GetByMemberGroup(string groupName)
|
||||
{
|
||||
var subquery = GetSubquery().Where<NodeDto>(x => x.Text == groupName);
|
||||
var grpQry = new Query<IMemberGroup>().Where(group => group.Name.Equals(groupName));
|
||||
var memberGroup = _memberGroupRepository.GetByQuery(grpQry).FirstOrDefault();
|
||||
if (memberGroup == null) return Enumerable.Empty<IMember>();
|
||||
var subQuery = new Sql().Select("Member").From<Member2MemberGroupDto>().Where<Member2MemberGroupDto>(dto => dto.MemberGroup == memberGroup.Id);
|
||||
|
||||
var sql = GetBaseQuery(false)
|
||||
.Append(new Sql("WHERE umbracoNode.id IN (" + subquery.SQL + ")", subquery.Arguments))
|
||||
.Append(new Sql("WHERE umbracoNode.id IN (" + subQuery.SQL + ")", subQuery.Arguments))
|
||||
.OrderByDescending<ContentVersionDto>(x => x.VersionDate)
|
||||
.OrderBy<NodeDto>(x => x.SortOrder);
|
||||
|
||||
@@ -548,6 +610,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var factory = new MemberReadOnlyFactory(memberTypes);
|
||||
var member = factory.BuildEntity(dto);
|
||||
|
||||
member.Properties = GetPropertyCollection(dto.NodeId, dto.VersionId, member.ContentType, dto.CreateDate, dto.UpdateDate);
|
||||
|
||||
return member;
|
||||
}
|
||||
|
||||
@@ -561,8 +625,15 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var memberTypeList = _memberTypeRepository.GetAll();
|
||||
memberTypeList.ForEach(x => memberTypes.Add(x.Alias, x));
|
||||
|
||||
var entities = new List<IMember>();
|
||||
var factory = new MemberReadOnlyFactory(memberTypes);
|
||||
return dtos.Select(factory.BuildEntity);
|
||||
foreach (var dto in dtos)
|
||||
{
|
||||
var entity = factory.BuildEntity(dto);
|
||||
entity.Properties = GetPropertyCollection(dto.NodeId, dto.VersionId, entity.ContentType, dto.CreateDate, dto.UpdateDate);
|
||||
entities.Add(entity);
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
@@ -17,17 +18,17 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// </summary>
|
||||
internal class MemberTypeRepository : ContentTypeBaseRepository<int, IMemberType>, IMemberTypeRepository
|
||||
{
|
||||
public MemberTypeRepository(IDatabaseUnitOfWork work)
|
||||
public MemberTypeRepository(IDatabaseUnitOfWork work)
|
||||
: base(work)
|
||||
{
|
||||
}
|
||||
|
||||
public MemberTypeRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache)
|
||||
public MemberTypeRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache)
|
||||
: base(work, cache)
|
||||
{
|
||||
}
|
||||
|
||||
#region Overrides of RepositoryBase<int, IMemberType>
|
||||
#region Overrides of RepositoryBase<int, IMemberType>
|
||||
|
||||
protected override IMemberType PerformGet(int id)
|
||||
{
|
||||
@@ -39,13 +40,13 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
Database.Fetch<MemberTypeReadOnlyDto, PropertyTypeReadOnlyDto, PropertyTypeGroupReadOnlyDto, MemberTypeReadOnlyDto>(
|
||||
new PropertyTypePropertyGroupRelator().Map, sql);
|
||||
|
||||
if (dtos == null || dtos.Any() == false)
|
||||
return null;
|
||||
if (dtos == null || dtos.Any() == false)
|
||||
return null;
|
||||
|
||||
var factory = new MemberTypeReadOnlyFactory();
|
||||
var member = factory.BuildEntity(dtos.First());
|
||||
var factory = new MemberTypeReadOnlyFactory();
|
||||
var member = factory.BuildEntity(dtos.First());
|
||||
|
||||
return member;
|
||||
return member;
|
||||
}
|
||||
|
||||
protected override IEnumerable<IMemberType> PerformGetAll(params int[] ids)
|
||||
@@ -98,7 +99,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
return sql;
|
||||
}
|
||||
|
||||
sql.Select("umbracoNode.*", "cmsContentType.*", "cmsPropertyType.id AS PropertyTypeId", "cmsPropertyType.Alias",
|
||||
sql.Select("umbracoNode.*", "cmsContentType.*", "cmsPropertyType.id AS PropertyTypeId", "cmsPropertyType.Alias",
|
||||
"cmsPropertyType.Name", "cmsPropertyType.Description", "cmsPropertyType.helpText", "cmsPropertyType.mandatory",
|
||||
"cmsPropertyType.validationRegExp", "cmsPropertyType.dataTypeId", "cmsPropertyType.sortOrder AS PropertyTypeSortOrder",
|
||||
"cmsPropertyType.propertyTypeGroupId AS PropertyTypesGroupId", "cmsMemberType.memberCanEdit", "cmsMemberType.viewOnProfile",
|
||||
@@ -168,15 +169,18 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
((MemberType)entity).AddingEntity();
|
||||
|
||||
//By Convention we add 9 stnd PropertyTypes to an Umbraco MemberType
|
||||
entity.AddPropertyGroup(Constants.Conventions.Member.StandardPropertiesGroupName);
|
||||
var standardPropertyTypes = Constants.Conventions.Member.GetStandardPropertyTypeStubs();
|
||||
foreach (var standardPropertyType in standardPropertyTypes)
|
||||
{
|
||||
entity.AddPropertyType(standardPropertyType.Value);
|
||||
entity.AddPropertyType(standardPropertyType.Value, Constants.Conventions.Member.StandardPropertiesGroupName);
|
||||
}
|
||||
|
||||
var factory = new MemberTypeFactory(NodeObjectTypeId);
|
||||
var dto = factory.BuildDto(entity);
|
||||
|
||||
EnsureExplicitDataTypeForBuiltInProperties(entity);
|
||||
|
||||
PersistNewBaseContentType(dto, entity);
|
||||
|
||||
//Handles the MemberTypeDto (cmsMemberType table)
|
||||
@@ -191,6 +195,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
protected override void PersistUpdatedItem(IMemberType entity)
|
||||
{
|
||||
ValidateAlias(entity);
|
||||
|
||||
//Updates Modified date
|
||||
((MemberType)entity).UpdatingEntity();
|
||||
|
||||
@@ -210,10 +216,12 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var factory = new MemberTypeFactory(NodeObjectTypeId);
|
||||
var dto = factory.BuildDto(entity);
|
||||
|
||||
EnsureExplicitDataTypeForBuiltInProperties(entity);
|
||||
|
||||
PersistUpdatedBaseContentType(dto, entity);
|
||||
|
||||
//Remove existing entries before inserting new ones
|
||||
Database.Delete<MemberTypeDto>("WHERE NodeId = @Id", new {Id = entity.Id});
|
||||
Database.Delete<MemberTypeDto>("WHERE NodeId = @Id", new { Id = entity.Id });
|
||||
|
||||
//Handles the MemberTypeDto (cmsMemberType table)
|
||||
var memberTypeDtos = factory.BuildMemberTypeDtos(entity);
|
||||
@@ -227,7 +235,50 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
#endregion
|
||||
|
||||
private IEnumerable<IMemberType> BuildFromDtos(List<MemberTypeReadOnlyDto> dtos)
|
||||
/// <summary>
|
||||
/// Override so we can specify explicit db type's on any property types that are built-in.
|
||||
/// </summary>
|
||||
/// <param name="propertyEditorAlias"></param>
|
||||
/// <param name="dbType"></param>
|
||||
/// <param name="propertyTypeAlias"></param>
|
||||
/// <returns></returns>
|
||||
protected override PropertyType CreatePropertyType(string propertyEditorAlias, DataTypeDatabaseType dbType, string propertyTypeAlias)
|
||||
{
|
||||
//custom property type constructor logic to set explicit dbtype's for built in properties
|
||||
var stdProps = Constants.Conventions.Member.GetStandardPropertyTypeStubs();
|
||||
var propDbType = GetDbTypeForBuiltInProperty(propertyTypeAlias, dbType, stdProps);
|
||||
return new PropertyType(propertyEditorAlias, propDbType.Result,
|
||||
//This flag tells the property type that it has an explicit dbtype and that it cannot be changed
|
||||
// which is what we want for the built-in properties.
|
||||
propDbType.Success);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensure that all the built-in membership provider properties have their correct data type
|
||||
/// and property editors assigned. This occurs prior to saving so that the correct values are persisted.
|
||||
/// </summary>
|
||||
/// <param name="memberType"></param>
|
||||
private static void EnsureExplicitDataTypeForBuiltInProperties(IContentTypeBase memberType)
|
||||
{
|
||||
var stdProps = Constants.Conventions.Member.GetStandardPropertyTypeStubs();
|
||||
foreach (var propertyType in memberType.PropertyTypes)
|
||||
{
|
||||
var dbTypeAttempt = GetDbTypeForBuiltInProperty(propertyType.Alias, propertyType.DataTypeDatabaseType, stdProps);
|
||||
if (dbTypeAttempt)
|
||||
{
|
||||
//this reset's it's current data type reference which will be re-assigned based on the property editor assigned on the next line
|
||||
propertyType.DataTypeDefinitionId = 0;
|
||||
propertyType.DataTypeId = GetPropertyEditorForBuiltInProperty(propertyType.Alias, propertyType.DataTypeId, stdProps).Result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds a collection of entities from a collection of Dtos
|
||||
/// </summary>
|
||||
/// <param name="dtos"></param>
|
||||
/// <returns></returns>
|
||||
private static IEnumerable<IMemberType> BuildFromDtos(List<MemberTypeReadOnlyDto> dtos)
|
||||
{
|
||||
if (dtos == null || dtos.Any() == false)
|
||||
return Enumerable.Empty<IMemberType>();
|
||||
@@ -235,5 +286,58 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var factory = new MemberTypeReadOnlyFactory();
|
||||
return dtos.Select(factory.BuildEntity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this is one of our internal properties - we will manually assign the data type since they must
|
||||
/// always correspond to the correct db type no matter what the backing data type is assigned.
|
||||
/// </summary>
|
||||
/// <param name="propAlias"></param>
|
||||
/// <param name="dbType"></param>
|
||||
/// <param name="standardProps"></param>
|
||||
/// <returns>
|
||||
/// Successful attempt if it was a built in property
|
||||
/// </returns>
|
||||
internal static Attempt<DataTypeDatabaseType> GetDbTypeForBuiltInProperty(
|
||||
string propAlias,
|
||||
DataTypeDatabaseType dbType,
|
||||
Dictionary<string, PropertyType> standardProps)
|
||||
{
|
||||
var aliases = standardProps.Select(x => x.Key).ToArray();
|
||||
|
||||
//check if it is built in
|
||||
if (aliases.Contains(propAlias))
|
||||
{
|
||||
//return the pre-determined db type for this property
|
||||
return Attempt<DataTypeDatabaseType>.Succeed(standardProps.Single(x => x.Key == propAlias).Value.DataTypeDatabaseType);
|
||||
}
|
||||
|
||||
return Attempt<DataTypeDatabaseType>.Fail(dbType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="propAlias"></param>
|
||||
/// <param name="propertyEditor"></param>
|
||||
/// <param name="standardProps"></param>
|
||||
/// <returns>
|
||||
/// Successful attempt if it was a built in property
|
||||
/// </returns>
|
||||
internal static Attempt<Guid> GetPropertyEditorForBuiltInProperty(
|
||||
string propAlias,
|
||||
Guid propertyEditor,
|
||||
Dictionary<string, PropertyType> standardProps)
|
||||
{
|
||||
var aliases = standardProps.Select(x => x.Key).ToArray();
|
||||
|
||||
//check if it is built in
|
||||
if (aliases.Contains(propAlias))
|
||||
{
|
||||
//return the pre-determined db type for this property
|
||||
return Attempt<Guid>.Succeed(standardProps.Single(x => x.Key == propAlias).Value.DataTypeId);
|
||||
}
|
||||
|
||||
return Attempt<Guid>.Fail(propertyEditor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,20 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Dynamic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web.Caching;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using Umbraco.Core.Services;
|
||||
using CacheKeys = Umbraco.Core.Cache.CacheKeys;
|
||||
using Umbraco.Core.Cache;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
@@ -20,10 +26,12 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
where TEntity : class, IAggregateRoot
|
||||
{
|
||||
private readonly IDatabaseUnitOfWork _unitOfWork;
|
||||
private readonly CacheHelper _cache;
|
||||
|
||||
internal PermissionRepository(IDatabaseUnitOfWork unitOfWork)
|
||||
internal PermissionRepository(IDatabaseUnitOfWork unitOfWork, CacheHelper cache)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
_cache = cache;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -32,39 +40,57 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="entityIds"></param>
|
||||
/// <returns></returns>
|
||||
internal IEnumerable<EntityPermission> GetUserPermissionsForEntities(object userId, params int[] entityIds)
|
||||
public IEnumerable<EntityPermission> GetUserPermissionsForEntities(int userId, params int[] entityIds)
|
||||
{
|
||||
var entityIdKey = string.Join(",", entityIds.Select(x => x.ToString(CultureInfo.InvariantCulture)));
|
||||
return _cache.RuntimeCache.GetCacheItem<IEnumerable<EntityPermission>>(
|
||||
string.Format("{0}{1}{2}", CacheKeys.UserPermissionsCacheKey, userId, entityIdKey),
|
||||
() =>
|
||||
{
|
||||
var whereBuilder = new StringBuilder();
|
||||
|
||||
var whereBuilder = new StringBuilder();
|
||||
|
||||
//where userId = @userId AND
|
||||
whereBuilder.Append(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("userId"));
|
||||
whereBuilder.Append("=");
|
||||
whereBuilder.Append(userId);
|
||||
whereBuilder.Append(" AND ");
|
||||
//where userId = @userId AND
|
||||
whereBuilder.Append(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("userId"));
|
||||
whereBuilder.Append("=");
|
||||
whereBuilder.Append(userId);
|
||||
|
||||
//where nodeId = @nodeId1 OR nodeId = @nodeId2, etc...
|
||||
whereBuilder.Append("(");
|
||||
for (var index = 0; index < entityIds.Length; index++)
|
||||
{
|
||||
var entityId = entityIds[index];
|
||||
whereBuilder.Append(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("nodeId"));
|
||||
whereBuilder.Append("=");
|
||||
whereBuilder.Append(entityId);
|
||||
if (index < entityIds.Length - 1)
|
||||
{
|
||||
whereBuilder.Append(" OR ");
|
||||
}
|
||||
}
|
||||
whereBuilder.Append(")");
|
||||
if (entityIds.Any())
|
||||
{
|
||||
whereBuilder.Append(" AND ");
|
||||
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
.From<User2NodePermissionDto>()
|
||||
.Where(whereBuilder.ToString());
|
||||
//where nodeId = @nodeId1 OR nodeId = @nodeId2, etc...
|
||||
whereBuilder.Append("(");
|
||||
for (var index = 0; index < entityIds.Length; index++)
|
||||
{
|
||||
var entityId = entityIds[index];
|
||||
whereBuilder.Append(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("nodeId"));
|
||||
whereBuilder.Append("=");
|
||||
whereBuilder.Append(entityId);
|
||||
if (index < entityIds.Length - 1)
|
||||
{
|
||||
whereBuilder.Append(" OR ");
|
||||
}
|
||||
}
|
||||
whereBuilder.Append(")");
|
||||
}
|
||||
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
.From<User2NodePermissionDto>()
|
||||
.Where(whereBuilder.ToString());
|
||||
|
||||
//ToArray() to ensure it's all fetched from the db once.
|
||||
var result = _unitOfWork.Database.Fetch<User2NodePermissionDto>(sql).ToArray();
|
||||
return ConvertToPermissionList(result);
|
||||
|
||||
},
|
||||
//Since this cache can be quite large (http://issues.umbraco.org/issue/U4-2161) we will only have this exist in cache for 20 minutes,
|
||||
// then it will refresh from the database.
|
||||
new TimeSpan(0, 20, 0),
|
||||
//Since this cache can be quite large (http://issues.umbraco.org/issue/U4-2161) we will make this priority below average
|
||||
priority: CacheItemPriority.BelowNormal);
|
||||
|
||||
//ToArray() to ensure it's all fetched from the db once.
|
||||
var result = _unitOfWork.Database.Fetch<User2NodePermissionDto>(sql).ToArray();
|
||||
return ConvertToPermissionList(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -72,7 +98,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// </summary>
|
||||
/// <param name="entityId"></param>
|
||||
/// <returns></returns>
|
||||
internal IEnumerable<EntityPermission> GetPermissionsForEntity(int entityId)
|
||||
public IEnumerable<EntityPermission> GetPermissionsForEntity(int entityId)
|
||||
{
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
@@ -85,7 +111,118 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
return ConvertToPermissionList(result);
|
||||
}
|
||||
|
||||
private IEnumerable<EntityPermission> ConvertToPermissionList(IEnumerable<User2NodePermissionDto> result)
|
||||
/// <summary>
|
||||
/// Assigns the same permission set for a single user to any number of entities
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="permissions"></param>
|
||||
/// <param name="entityIds"></param>
|
||||
/// <remarks>
|
||||
/// This will first clear the permissions for this user and entities and recreate them
|
||||
/// </remarks>
|
||||
public void ReplaceUserPermissions(int userId, IEnumerable<char> permissions, params int[] entityIds)
|
||||
{
|
||||
var db = _unitOfWork.Database;
|
||||
using (var trans = db.GetTransaction())
|
||||
{
|
||||
db.Execute("DELETE FROM umbracoUser2NodePermission WHERE userId=@userId AND nodeId in (@nodeIds)",
|
||||
new {userId = userId, nodeIds = entityIds});
|
||||
|
||||
var toInsert = new List<User2NodePermissionDto>();
|
||||
foreach (var p in permissions)
|
||||
{
|
||||
foreach (var e in entityIds)
|
||||
{
|
||||
toInsert.Add(new User2NodePermissionDto
|
||||
{
|
||||
NodeId = e,
|
||||
Permission = p.ToString(CultureInfo.InvariantCulture),
|
||||
UserId = userId
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_unitOfWork.Database.BulkInsertRecords(toInsert, trans);
|
||||
|
||||
trans.Complete();
|
||||
|
||||
//Raise the event
|
||||
AssignedPermissions.RaiseEvent(
|
||||
new SaveEventArgs<EntityPermission>(ConvertToPermissionList(toInsert), false), this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns one permission to an entity for multiple users
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="permission"></param>
|
||||
/// <param name="userIds"></param>
|
||||
public void AssignEntityPermission(TEntity entity, char permission, IEnumerable<int> userIds)
|
||||
{
|
||||
var db = _unitOfWork.Database;
|
||||
using (var trans = db.GetTransaction())
|
||||
{
|
||||
db.Execute("DELETE FROM umbracoUser2NodePermission WHERE nodeId=@nodeId AND permission=@permission AND userId in (@userIds)",
|
||||
new
|
||||
{
|
||||
nodeId = entity.Id,
|
||||
permission = permission.ToString(CultureInfo.InvariantCulture),
|
||||
userIds = userIds
|
||||
});
|
||||
|
||||
var actions = userIds.Select(id => new User2NodePermissionDto
|
||||
{
|
||||
NodeId = entity.Id,
|
||||
Permission = permission.ToString(CultureInfo.InvariantCulture),
|
||||
UserId = id
|
||||
}).ToArray();
|
||||
|
||||
_unitOfWork.Database.BulkInsertRecords(actions, trans);
|
||||
|
||||
trans.Complete();
|
||||
|
||||
//Raise the event
|
||||
AssignedPermissions.RaiseEvent(
|
||||
new SaveEventArgs<EntityPermission>(ConvertToPermissionList(actions), false), this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns permissions to an entity for multiple users/permission entries
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="userPermissions">
|
||||
/// A key/value pair list containing a userId and a permission to assign
|
||||
/// </param>
|
||||
/// <remarks>
|
||||
/// This will first clear the permissions for this entity then re-create them
|
||||
/// </remarks>
|
||||
public void ReplaceEntityPermissions(TEntity entity, IEnumerable<Tuple<int, string>> userPermissions)
|
||||
{
|
||||
var db = _unitOfWork.Database;
|
||||
using (var trans = db.GetTransaction())
|
||||
{
|
||||
db.Execute("DELETE FROM umbracoUser2NodePermission WHERE nodeId=@nodeId", new { nodeId = entity.Id });
|
||||
|
||||
var actions = userPermissions.Select(p => new User2NodePermissionDto
|
||||
{
|
||||
NodeId = entity.Id,
|
||||
Permission = p.Item2,
|
||||
UserId = p.Item1
|
||||
}).ToArray();
|
||||
|
||||
_unitOfWork.Database.BulkInsertRecords(actions, trans);
|
||||
|
||||
trans.Complete();
|
||||
|
||||
//Raise the event
|
||||
AssignedPermissions.RaiseEvent(
|
||||
new SaveEventArgs<EntityPermission>(ConvertToPermissionList(actions), false), this);
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<EntityPermission> ConvertToPermissionList(IEnumerable<User2NodePermissionDto> result)
|
||||
{
|
||||
var permissions = new List<EntityPermission>();
|
||||
var nodePermissions = result.GroupBy(x => x.NodeId);
|
||||
@@ -99,118 +236,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
}
|
||||
}
|
||||
return permissions;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns one permission to an entity for multiple users
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="permission"></param>
|
||||
/// <param name="userIds"></param>
|
||||
internal void AssignEntityPermissions(TEntity entity, char permission, IEnumerable<object> userIds)
|
||||
{
|
||||
var actions = userIds.Select(id => new User2NodePermissionDto
|
||||
{
|
||||
NodeId = entity.Id,
|
||||
Permission = permission.ToString(CultureInfo.InvariantCulture),
|
||||
UserId = (int)id
|
||||
});
|
||||
|
||||
_unitOfWork.Database.BulkInsertRecords(actions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns permissions to an entity for multiple users/permission entries
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="userPermissions">
|
||||
/// A key/value pair list containing a userId and a permission to assign
|
||||
/// </param>
|
||||
internal void AssignEntityPermissions(TEntity entity, IEnumerable<Tuple<object, string>> userPermissions)
|
||||
{
|
||||
var actions = userPermissions.Select(p => new User2NodePermissionDto
|
||||
{
|
||||
NodeId = entity.Id,
|
||||
Permission = p.Item2,
|
||||
UserId = (int)p.Item1
|
||||
});
|
||||
|
||||
_unitOfWork.Database.BulkInsertRecords(actions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replace permissions for an entity for multiple users
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="permissions"></param>
|
||||
/// <param name="userIds"></param>
|
||||
internal void ReplaceEntityPermissions(TEntity entity, string permissions, IEnumerable<object> userIds)
|
||||
{
|
||||
_unitOfWork.Database.Update<User2NodePermissionDto>(
|
||||
GenerateReplaceEntityPermissionsSql(entity.Id, permissions, userIds.ToArray()));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An overload to replace entity permissions and all replace all descendant permissions
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="permissions"></param>
|
||||
/// <param name="getDescendantIds">
|
||||
/// A callback to get the descendant Ids of the current entity
|
||||
/// </param>
|
||||
/// <param name="userIds"></param>
|
||||
internal void ReplaceEntityPermissions(TEntity entity, string permissions, Func<IEntity, IEnumerable<int>> getDescendantIds, IEnumerable<object> userIds)
|
||||
{
|
||||
_unitOfWork.Database.Update<User2NodePermissionDto>(
|
||||
GenerateReplaceEntityPermissionsSql(
|
||||
new[] { entity.Id }.Concat(getDescendantIds(entity)).ToArray(),
|
||||
permissions,
|
||||
userIds.ToArray()));
|
||||
}
|
||||
|
||||
internal static string GenerateReplaceEntityPermissionsSql(int entityId, string permissions, object[] userIds)
|
||||
{
|
||||
return GenerateReplaceEntityPermissionsSql(new[] { entityId }, permissions, userIds);
|
||||
}
|
||||
|
||||
internal static string GenerateReplaceEntityPermissionsSql(int[] entityIds, string permissions, object[] userIds)
|
||||
{
|
||||
//create the "SET" clause of the update statement
|
||||
var sqlSet = string.Format("SET {0}={1}",
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("permission"),
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedValue(permissions));
|
||||
|
||||
//build the nodeIds part of the where clause
|
||||
var sqlNodeWhere = BuildOrClause(entityIds, "nodeId");
|
||||
|
||||
//build up the userIds part of the where clause
|
||||
var userWhereBuilder = BuildOrClause(userIds, "userId");
|
||||
|
||||
var sqlWhere = new Sql();
|
||||
sqlWhere.Where(string.Format("{0} AND {1}", sqlNodeWhere, userWhereBuilder));
|
||||
|
||||
return string.Format("{0} {1}", sqlSet, sqlWhere.SQL);
|
||||
}
|
||||
|
||||
private static string BuildOrClause<T>(IEnumerable<T> ids, string colName)
|
||||
{
|
||||
var asArray = ids.ToArray();
|
||||
var userWhereBuilder = new StringBuilder();
|
||||
userWhereBuilder.Append("(");
|
||||
for (var index = 0; index < asArray.Length; index++)
|
||||
{
|
||||
var userId = asArray[index];
|
||||
userWhereBuilder.Append(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(colName));
|
||||
userWhereBuilder.Append("=");
|
||||
userWhereBuilder.Append(userId);
|
||||
if (index < asArray.Length - 1)
|
||||
{
|
||||
userWhereBuilder.Append(" OR ");
|
||||
}
|
||||
}
|
||||
userWhereBuilder.Append(")");
|
||||
return userWhereBuilder.ToString();
|
||||
}
|
||||
|
||||
public static event TypedEventHandler<PermissionRepository<TEntity>, SaveEventArgs<EntityPermission>> AssignedPermissions;
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <param name="entity"></param>
|
||||
public void AddOrUpdate(TEntity entity)
|
||||
{
|
||||
if (!entity.HasIdentity)
|
||||
if (entity.HasIdentity == false)
|
||||
{
|
||||
_work.RegisterAdded(entity, this);
|
||||
}
|
||||
@@ -104,7 +104,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
// http://issues.umbraco.org/issue/U4-1946
|
||||
TracksChangesEntityBase asEntity = entity as TracksChangesEntityBase;
|
||||
var asEntity = entity as TracksChangesEntityBase;
|
||||
if (asEntity != null)
|
||||
{
|
||||
asEntity.ResetDirtyProperties(false);
|
||||
@@ -135,13 +135,16 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
if (ids.Any())
|
||||
{
|
||||
var entities = _cache.GetByIds(typeof(TEntity), ids.Select(id => id is int ? ConvertIdToGuid(id) : ConvertStringIdToGuid(id.ToString())).ToList());
|
||||
var entities = _cache.GetByIds(
|
||||
typeof (TEntity), ids.Select(id => id is int ? ConvertIdToGuid(id) : ConvertStringIdToGuid(id.ToString())).ToList())
|
||||
.ToArray();
|
||||
|
||||
if (ids.Count().Equals(entities.Count()) && entities.Any(x => x == null) == false)
|
||||
return entities.Select(x => (TEntity)x);
|
||||
}
|
||||
else
|
||||
{
|
||||
var allEntities = _cache.GetAllByType(typeof(TEntity));
|
||||
var allEntities = _cache.GetAllByType(typeof (TEntity)).ToArray();
|
||||
|
||||
if (allEntities.Any())
|
||||
{
|
||||
@@ -154,7 +157,10 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
}
|
||||
}
|
||||
|
||||
var entityCollection = PerformGetAll(ids);
|
||||
var entityCollection = PerformGetAll(ids)
|
||||
//ensure we don't include any null refs in the returned collection!
|
||||
.WhereNotNull()
|
||||
.ToArray();
|
||||
|
||||
foreach (var entity in entityCollection)
|
||||
{
|
||||
@@ -175,7 +181,9 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <returns></returns>
|
||||
public IEnumerable<TEntity> GetByQuery(IQuery<TEntity> query)
|
||||
{
|
||||
return PerformGetByQuery(query);
|
||||
return PerformGetByQuery(query)
|
||||
//ensure we don't include any null refs in the returned collection!
|
||||
.WhereNotNull();
|
||||
}
|
||||
|
||||
protected abstract bool PerformExists(TId id);
|
||||
|
||||
@@ -22,17 +22,20 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
internal class UserRepository : PetaPocoRepositoryBase<int, IUser>, IUserRepository
|
||||
{
|
||||
private readonly IUserTypeRepository _userTypeRepository;
|
||||
private readonly CacheHelper _cacheHelper;
|
||||
|
||||
public UserRepository(IDatabaseUnitOfWork work, IUserTypeRepository userTypeRepository)
|
||||
public UserRepository(IDatabaseUnitOfWork work, IUserTypeRepository userTypeRepository, CacheHelper cacheHelper)
|
||||
: base(work)
|
||||
{
|
||||
_userTypeRepository = userTypeRepository;
|
||||
_cacheHelper = cacheHelper;
|
||||
}
|
||||
|
||||
public UserRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache, IUserTypeRepository userTypeRepository)
|
||||
public UserRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache, IUserTypeRepository userTypeRepository, CacheHelper cacheHelper)
|
||||
: base(work, cache)
|
||||
{
|
||||
_userTypeRepository = userTypeRepository;
|
||||
_cacheHelper = cacheHelper;
|
||||
}
|
||||
|
||||
#region Overrides of RepositoryBase<int,IUser>
|
||||
@@ -128,6 +131,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
var list = new List<string>
|
||||
{
|
||||
"DELETE FROM cmsTask WHERE userId = @Id",
|
||||
"DELETE FROM cmsTask WHERE parentUserId = @Id",
|
||||
"DELETE FROM umbracoUser2NodePermission WHERE userId = @Id",
|
||||
"DELETE FROM umbracoUser2NodeNotify WHERE userId = @Id",
|
||||
"DELETE FROM umbracoUserLogins WHERE userId = @Id",
|
||||
@@ -315,12 +320,24 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="entityIds"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<EntityPermission> GetUserPermissionsForEntities(object userId, params int[] entityIds)
|
||||
public IEnumerable<EntityPermission> GetUserPermissionsForEntities(int userId, params int[] entityIds)
|
||||
{
|
||||
var repo = new PermissionRepository<IContent>(UnitOfWork);
|
||||
var repo = new PermissionRepository<IContent>(UnitOfWork, _cacheHelper);
|
||||
return repo.GetUserPermissionsForEntities(userId, entityIds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces the same permission set for a single user to any number of entities
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="permissions"></param>
|
||||
/// <param name="entityIds"></param>
|
||||
public void ReplaceUserPermissions(int userId, IEnumerable<char> permissions, params int[] entityIds)
|
||||
{
|
||||
var repo = new PermissionRepository<IContent>(UnitOfWork, _cacheHelper);
|
||||
repo.ReplaceUserPermissions(userId, permissions, entityIds);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private IEnumerable<IUser> ConvertFromDtos(IEnumerable<UserDto> dtos)
|
||||
|
||||
@@ -5,6 +5,7 @@ using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.Caching;
|
||||
using Umbraco.Core.Persistence.Factories;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
@@ -120,5 +121,42 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is a fix for U4-1407 - when property types are added to a content type - the property of the entity are not actually created
|
||||
/// and we get YSODs
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="versionId"></param>
|
||||
/// <param name="contentType"></param>
|
||||
/// <param name="createDate"></param>
|
||||
/// <param name="updateDate"></param>
|
||||
/// <returns></returns>
|
||||
protected PropertyCollection GetPropertyCollection(int id, Guid versionId, IContentTypeComposition contentType, DateTime createDate, DateTime updateDate)
|
||||
{
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
.From<PropertyDataDto>()
|
||||
.InnerJoin<PropertyTypeDto>()
|
||||
.On<PropertyDataDto, PropertyTypeDto>(left => left.PropertyTypeId, right => right.Id)
|
||||
.Where<PropertyDataDto>(x => x.NodeId == id)
|
||||
.Where<PropertyDataDto>(x => x.VersionId == versionId);
|
||||
|
||||
var propertyDataDtos = Database.Fetch<PropertyDataDto, PropertyTypeDto>(sql);
|
||||
var propertyFactory = new PropertyFactory(contentType, versionId, id, createDate, updateDate);
|
||||
var properties = propertyFactory.BuildEntity(propertyDataDtos).ToArray();
|
||||
|
||||
var newProperties = properties.Where(x => x.HasIdentity == false && x.PropertyType.HasIdentity);
|
||||
foreach (var property in newProperties)
|
||||
{
|
||||
var propertyDataDto = new PropertyDataDto { NodeId = id, PropertyTypeId = property.PropertyTypeId, VersionId = versionId };
|
||||
int primaryKey = Convert.ToInt32(Database.Insert(propertyDataDto));
|
||||
|
||||
property.Version = versionId;
|
||||
property.Id = primaryKey;
|
||||
}
|
||||
|
||||
return new PropertyCollection(properties);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using Umbraco.Core.Configuration;
|
||||
using System;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Persistence.Caching;
|
||||
using Umbraco.Core.Persistence.Repositories;
|
||||
@@ -12,12 +13,28 @@ namespace Umbraco.Core.Persistence
|
||||
public class RepositoryFactory
|
||||
{
|
||||
private readonly bool _disableAllCache;
|
||||
private readonly CacheHelper _cacheHelper;
|
||||
private readonly IUmbracoSettingsSection _settings;
|
||||
|
||||
#region Ctors
|
||||
public RepositoryFactory()
|
||||
: this(false, UmbracoConfig.For.UmbracoSettings())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public RepositoryFactory(CacheHelper cacheHelper)
|
||||
: this(false, UmbracoConfig.For.UmbracoSettings())
|
||||
{
|
||||
if (cacheHelper == null) throw new ArgumentNullException("cacheHelper");
|
||||
_disableAllCache = false;
|
||||
_cacheHelper = cacheHelper;
|
||||
}
|
||||
|
||||
public RepositoryFactory(bool disableAllCache, CacheHelper cacheHelper)
|
||||
: this(disableAllCache, UmbracoConfig.For.UmbracoSettings())
|
||||
{
|
||||
if (cacheHelper == null) throw new ArgumentNullException("cacheHelper");
|
||||
_cacheHelper = cacheHelper;
|
||||
}
|
||||
|
||||
public RepositoryFactory(bool disableAllCache)
|
||||
@@ -30,9 +47,17 @@ namespace Umbraco.Core.Persistence
|
||||
{
|
||||
_disableAllCache = disableAllCache;
|
||||
_settings = settings;
|
||||
|
||||
_cacheHelper = _disableAllCache ? CacheHelper.CreateDisabledCacheHelper() : ApplicationContext.Current.ApplicationCache;
|
||||
}
|
||||
|
||||
internal RepositoryFactory(bool disableAllCache, IUmbracoSettingsSection settings, CacheHelper cacheHelper)
|
||||
{
|
||||
_disableAllCache = disableAllCache;
|
||||
_settings = settings;
|
||||
_cacheHelper = cacheHelper;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public virtual ITagsRepository CreateTagsRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new TagsRepository(
|
||||
@@ -43,18 +68,19 @@ namespace Umbraco.Core.Persistence
|
||||
public virtual IContentRepository CreateContentRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new ContentRepository(
|
||||
uow,
|
||||
uow,
|
||||
_disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : RuntimeCacheProvider.Current,
|
||||
CreateContentTypeRepository(uow),
|
||||
CreateTemplateRepository(uow),
|
||||
CreateTagsRepository(uow)) { EnsureUniqueNaming = _settings.Content.EnsureUniqueNaming };
|
||||
CreateTagsRepository(uow),
|
||||
_cacheHelper) { EnsureUniqueNaming = _settings.Content.EnsureUniqueNaming };
|
||||
}
|
||||
|
||||
public virtual IContentTypeRepository CreateContentTypeRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new ContentTypeRepository(
|
||||
uow,
|
||||
_disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : InMemoryCacheProvider.Current,
|
||||
_disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : RuntimeCacheProvider.Current,
|
||||
new TemplateRepository(uow, NullCacheProvider.Current));
|
||||
}
|
||||
|
||||
@@ -69,7 +95,7 @@ namespace Umbraco.Core.Persistence
|
||||
{
|
||||
return new DictionaryRepository(
|
||||
uow,
|
||||
_disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : InMemoryCacheProvider.Current,
|
||||
_disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : RuntimeCacheProvider.Current,
|
||||
CreateLanguageRepository(uow));
|
||||
}
|
||||
|
||||
@@ -77,7 +103,7 @@ namespace Umbraco.Core.Persistence
|
||||
{
|
||||
return new LanguageRepository(
|
||||
uow,
|
||||
_disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : InMemoryCacheProvider.Current);
|
||||
_disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : RuntimeCacheProvider.Current);
|
||||
}
|
||||
|
||||
public virtual IMediaRepository CreateMediaRepository(IDatabaseUnitOfWork uow)
|
||||
@@ -93,7 +119,7 @@ namespace Umbraco.Core.Persistence
|
||||
{
|
||||
return new MediaTypeRepository(
|
||||
uow,
|
||||
_disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : InMemoryCacheProvider.Current);
|
||||
_disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : RuntimeCacheProvider.Current);
|
||||
}
|
||||
|
||||
public virtual IRelationRepository CreateRelationRepository(IDatabaseUnitOfWork uow)
|
||||
@@ -133,20 +159,22 @@ namespace Umbraco.Core.Persistence
|
||||
NullCacheProvider.Current);
|
||||
}
|
||||
|
||||
internal virtual IUserTypeRepository CreateUserTypeRepository(IDatabaseUnitOfWork uow)
|
||||
public virtual IUserTypeRepository CreateUserTypeRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new UserTypeRepository(
|
||||
uow,
|
||||
//There's not many user types but we query on users all the time so the result needs to be cached
|
||||
RuntimeCacheProvider.Current);
|
||||
_disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : RuntimeCacheProvider.Current);
|
||||
}
|
||||
|
||||
internal virtual IUserRepository CreateUserRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
public virtual IUserRepository CreateUserRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new UserRepository(
|
||||
uow,
|
||||
NullCacheProvider.Current,
|
||||
CreateUserTypeRepository(uow));
|
||||
//Need to cache users - we look up user information more than anything in the back office!
|
||||
_disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : RuntimeCacheProvider.Current,
|
||||
CreateUserTypeRepository(uow),
|
||||
_cacheHelper);
|
||||
}
|
||||
|
||||
internal virtual IMacroRepository CreateMacroRepository(IDatabaseUnitOfWork uow)
|
||||
@@ -154,20 +182,27 @@ namespace Umbraco.Core.Persistence
|
||||
return new MacroRepository(uow, _disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : RuntimeCacheProvider.Current);
|
||||
}
|
||||
|
||||
internal virtual IMemberRepository CreateMemberRepository(IDatabaseUnitOfWork uow)
|
||||
public virtual IMemberRepository CreateMemberRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new MemberRepository(uow,
|
||||
_disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : RuntimeCacheProvider.Current,
|
||||
return new MemberRepository(
|
||||
uow,
|
||||
_disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : RuntimeCacheProvider.Current,
|
||||
CreateMemberTypeRepository(uow),
|
||||
CreateMemberGroupRepository(uow),
|
||||
CreateTagsRepository(uow));
|
||||
}
|
||||
|
||||
internal virtual IMemberTypeRepository CreateMemberTypeRepository(IDatabaseUnitOfWork uow)
|
||||
public virtual IMemberTypeRepository CreateMemberTypeRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new MemberTypeRepository(uow, _disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : InMemoryCacheProvider.Current);
|
||||
return new MemberTypeRepository(uow, _disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : RuntimeCacheProvider.Current);
|
||||
}
|
||||
|
||||
internal virtual IEntityRepository CreateEntityRepository(IDatabaseUnitOfWork uow)
|
||||
public virtual IMemberGroupRepository CreateMemberGroupRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new MemberGroupRepository(uow, _disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : RuntimeCacheProvider.Current, _cacheHelper);
|
||||
}
|
||||
|
||||
public virtual IEntityRepository CreateEntityRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new EntityRepository(uow);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Umbraco.Core.Persistence
|
||||
{
|
||||
//TODO: check if any of this works and for what databse types it works for:
|
||||
// ref: http://stackoverflow.com/questions/16171144/how-to-check-for-database-availability
|
||||
|
||||
internal static class SqlExtensions
|
||||
{
|
||||
public static bool IsConnectionAvailable(string connString)
|
||||
{
|
||||
using (var connection = new SqlConnection(connString))
|
||||
{
|
||||
return connection.IsAvailable();
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsAvailable(this SqlConnection connection)
|
||||
{
|
||||
try
|
||||
{
|
||||
connection.Open();
|
||||
connection.Close();
|
||||
}
|
||||
catch (SqlException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,8 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
/// </summary>
|
||||
public interface ISqlSyntaxProvider
|
||||
{
|
||||
string EscapeString(string val);
|
||||
|
||||
string GetStringColumnEqualComparison(string column, string value, TextColumnType columnType);
|
||||
string GetStringColumnStartsWithComparison(string column, string value, TextColumnType columnType);
|
||||
string GetStringColumnEndsWithComparison(string column, string value, TextColumnType columnType);
|
||||
|
||||
@@ -327,5 +327,10 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
// add message to check with their hosting provider
|
||||
return supportsCaseInsensitiveQueries;
|
||||
}
|
||||
|
||||
public override string EscapeString(string val)
|
||||
{
|
||||
return PetaPocoExtensions.EscapeAtSymbols(MySql.Data.MySqlClient.MySqlHelper.EscapeString(val));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,6 +103,11 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
DbTypeMap.Set<byte[]>(DbType.Binary, BlobColumnDefinition);
|
||||
}
|
||||
|
||||
public virtual string EscapeString(string val)
|
||||
{
|
||||
return PetaPocoExtensions.EscapeAtSymbols(val.Replace("'", "''"));
|
||||
}
|
||||
|
||||
public virtual string GetStringColumnEqualComparison(string column, string value, TextColumnType columnType)
|
||||
{
|
||||
//use the 'upper' method to always ensure strings are matched without case sensitivity no matter what the db setting.
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace Umbraco.Core
|
||||
/// it will use the cached resolved plugins that it has already found which means that no assembly scanning is necessary. This leads
|
||||
/// to much faster startup times.
|
||||
/// </remarks>
|
||||
internal class PluginManager
|
||||
public class PluginManager
|
||||
{
|
||||
private readonly ApplicationContext _appContext;
|
||||
private const string CacheKey = "umbraco-plugins.list";
|
||||
@@ -107,7 +107,7 @@ namespace Umbraco.Core
|
||||
/// <remarks>
|
||||
/// The setter is generally only used for unit tests
|
||||
/// </remarks>
|
||||
internal static PluginManager Current
|
||||
public static PluginManager Current
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -783,12 +783,13 @@ namespace Umbraco.Core
|
||||
UpdateCachedPluginsFile<T>(typeList.GetTypes(), resolutionKind);
|
||||
}
|
||||
|
||||
#region Public Methods
|
||||
/// <summary>
|
||||
/// Generic method to find the specified type and cache the result
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
internal IEnumerable<Type> ResolveTypes<T>(bool cacheResult = true, IEnumerable<Assembly> specificAssemblies = null)
|
||||
public IEnumerable<Type> ResolveTypes<T>(bool cacheResult = true, IEnumerable<Assembly> specificAssemblies = null)
|
||||
{
|
||||
return ResolveTypes<T>(
|
||||
() => TypeFinder.FindClassesOfType<T>(specificAssemblies ?? AssembliesToScan),
|
||||
@@ -802,11 +803,11 @@ namespace Umbraco.Core
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TAttribute"></typeparam>
|
||||
/// <returns></returns>
|
||||
internal IEnumerable<Type> ResolveTypesWithAttribute<T, TAttribute>(bool cacheResult = true)
|
||||
public IEnumerable<Type> ResolveTypesWithAttribute<T, TAttribute>(bool cacheResult = true, IEnumerable<Assembly> specificAssemblies = null)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return ResolveTypes<T>(
|
||||
() => TypeFinder.FindClassesOfTypeWithAttribute<T, TAttribute>(AssembliesToScan),
|
||||
() => TypeFinder.FindClassesOfTypeWithAttribute<T, TAttribute>(specificAssemblies ?? AssembliesToScan),
|
||||
TypeResolutionKind.FindTypesWithAttribute,
|
||||
cacheResult);
|
||||
}
|
||||
@@ -816,14 +817,15 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
/// <typeparam name="TAttribute"></typeparam>
|
||||
/// <returns></returns>
|
||||
internal IEnumerable<Type> ResolveAttributedTypes<TAttribute>(bool cacheResult = true)
|
||||
public IEnumerable<Type> ResolveAttributedTypes<TAttribute>(bool cacheResult = true, IEnumerable<Assembly> specificAssemblies = null)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return ResolveTypes<TAttribute>(
|
||||
() => TypeFinder.FindClassesWithAttribute<TAttribute>(AssembliesToScan),
|
||||
() => TypeFinder.FindClassesWithAttribute<TAttribute>(specificAssemblies ?? AssembliesToScan),
|
||||
TypeResolutionKind.FindAttributedTypes,
|
||||
cacheResult);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Used for unit tests
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Newtonsoft.Json;
|
||||
@@ -127,7 +128,7 @@ namespace Umbraco.Core.PropertyEditors
|
||||
/// <returns></returns>
|
||||
public DataTypeDatabaseType GetDatabaseType()
|
||||
{
|
||||
switch (ValueType.ToUpper())
|
||||
switch (ValueType.ToUpper(CultureInfo.InvariantCulture))
|
||||
{
|
||||
case "INT":
|
||||
case "INTEGER":
|
||||
|
||||
@@ -26,13 +26,14 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
if (source == null) return DateTime.MinValue;
|
||||
|
||||
// in XML a DateTime is: string - format "yyyy-MM-ddTHH:mm:ss"
|
||||
// Actually, not always sometimes it is formatted in UTC style with 'Z' suffixed on the end but that is due to this bug:
|
||||
// http://issues.umbraco.org/issue/U4-4145, http://issues.umbraco.org/issue/U4-3894
|
||||
// We should just be using TryConvertTo instead.
|
||||
var sourceString = source as string;
|
||||
if (sourceString != null)
|
||||
{
|
||||
DateTime value;
|
||||
return DateTime.TryParseExact(sourceString, "yyyy-MM-ddTHH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out value)
|
||||
? value
|
||||
: DateTime.MinValue;
|
||||
var attempt = sourceString.TryConvertTo<DateTime>();
|
||||
return attempt.Success == false ? DateTime.MinValue : attempt.Result;
|
||||
}
|
||||
|
||||
// in the database a DateTime is: DateTime
|
||||
@@ -47,7 +48,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
public override object ConvertSourceToXPath(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
// source should come from ConvertSource and be a DateTime already
|
||||
return XmlConvert.ToString((DateTime) source, "yyyy-MM-ddTHH:mm:ss");
|
||||
return XmlConvert.ToString((DateTime)source, XmlDateTimeSerializationMode.Unspecified);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
{
|
||||
/// <summary>
|
||||
/// Ensures that no matter what is selected in (editor), the value results in a string.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>For more details see issues http://issues.umbraco.org/issue/U4-3776 (MNTP)
|
||||
/// and http://issues.umbraco.org/issue/U4-4160 (media picker).</para>
|
||||
/// <para>The cache level is set to .Content because the string is supposed to depend
|
||||
/// on the source value only, and not on any other content. It is NOT appropriate
|
||||
/// to use that converter for values whose .ToString() would depend on other content.</para>
|
||||
/// </remarks>
|
||||
[DefaultPropertyValueConverter]
|
||||
[PropertyValueType(typeof(string))]
|
||||
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
|
||||
public class MustBeStringValueConverter : PropertyValueConverterBase
|
||||
{
|
||||
private static readonly string[] Aliases =
|
||||
{
|
||||
Constants.PropertyEditors.MultiNodeTreePickerAlias,
|
||||
Constants.PropertyEditors.MultipleMediaPickerAlias
|
||||
};
|
||||
|
||||
public override bool IsConverter(PublishedPropertyType propertyType)
|
||||
{
|
||||
return Aliases.Contains(propertyType.PropertyEditorAlias);
|
||||
}
|
||||
|
||||
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
if (source == null) return null;
|
||||
return source.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace Umbraco.Core.Security
|
||||
{
|
||||
/// <summary>
|
||||
/// A marker interface used internally to identify Umbraco built-in Users membership providers
|
||||
/// </summary>
|
||||
internal interface IUsersMembershipProvider
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,16 @@ namespace Umbraco.Core.Security
|
||||
{
|
||||
internal static class MembershipProviderExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns true if the provider specified is a built-in Umbraco users provider
|
||||
/// </summary>
|
||||
/// <param name="membershipProvider"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsUmbracoUsersProvider(this MembershipProvider membershipProvider)
|
||||
{
|
||||
return (membershipProvider is IUsersMembershipProvider);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the provider specified is a built-in Umbraco membership provider
|
||||
/// </summary>
|
||||
@@ -20,6 +30,8 @@ namespace Umbraco.Core.Security
|
||||
return (membershipProvider is UmbracoMembershipProviderBase);
|
||||
}
|
||||
|
||||
//TODO: Add role provider checks too
|
||||
|
||||
public static UmbracoMembershipProviderBase AsUmbracoMembershipProvider(this MembershipProvider membershipProvider)
|
||||
{
|
||||
return (UmbracoMembershipProviderBase)membershipProvider;
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
using System.Collections.Specialized;
|
||||
|
||||
namespace Umbraco.Core.Security
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface for exposing the content type properties for storing membership data in when
|
||||
/// a membership provider's data is backed by an Umbraco content type.
|
||||
/// </summary>
|
||||
public interface IUmbracoMemberTypeMembershipProvider
|
||||
{
|
||||
|
||||
string LockPropertyTypeAlias { get; }
|
||||
string LastLockedOutPropertyTypeAlias { get; }
|
||||
string FailedPasswordAttemptsPropertyTypeAlias { get; }
|
||||
string ApprovedPropertyTypeAlias { get; }
|
||||
string CommentPropertyTypeAlias { get; }
|
||||
string LastLoginPropertyTypeAlias { get; }
|
||||
string LastPasswordChangedPropertyTypeAlias { get; }
|
||||
string PasswordRetrievalQuestionPropertyTypeAlias { get; }
|
||||
string PasswordRetrievalAnswerPropertyTypeAlias { get; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ using System.Web.Security;
|
||||
|
||||
namespace Umbraco.Core.Security
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// A base membership provider class for umbraco providers
|
||||
/// </summary>
|
||||
|
||||
@@ -59,14 +59,32 @@ namespace Umbraco.Core.Services
|
||||
_repositoryFactory = repositoryFactory;
|
||||
}
|
||||
|
||||
//TODO: There are various ways to expose permission setting on this service, we just need to list out the different ways we'll need to
|
||||
// be able to acheive this for the core, for now this is here so I can run a unit test.
|
||||
internal void AssignContentPermissions(IContent entity, char permission, IEnumerable<object> userIds)
|
||||
/// <summary>
|
||||
/// Assigns a single permission to the current content item for the specified user ids
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="permission"></param>
|
||||
/// <param name="userIds"></param>
|
||||
public void AssignContentPermission(IContent entity, char permission, IEnumerable<int> userIds)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
repository.AssignEntityPermissions(entity, permission, userIds);
|
||||
repository.AssignEntityPermission(entity, permission, userIds);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of permissions for the content item
|
||||
/// </summary>
|
||||
/// <param name="content"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<EntityPermission> GetPermissionsForEntity(IContent content)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
return repository.GetPermissionsForEntity(content.Id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,12 +176,20 @@ namespace Umbraco.Core.Services
|
||||
var contentType = FindContentTypeByAlias(contentTypeAlias);
|
||||
var content = new Content(name, parentId, contentType);
|
||||
|
||||
//NOTE: I really hate the notion of these Creating/Created events - they are so inconsistent, I've only just found
|
||||
// out that in these 'WithIdentity' methods, the Saving/Saved events were not fired, wtf. Anyways, they're added now.
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IContent>(content, contentTypeAlias, parentId), this))
|
||||
{
|
||||
content.WasCancelled = true;
|
||||
return content;
|
||||
}
|
||||
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IContent>(content), this))
|
||||
{
|
||||
content.WasCancelled = true;
|
||||
return content;
|
||||
}
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
@@ -173,6 +199,8 @@ namespace Umbraco.Core.Services
|
||||
uow.Commit();
|
||||
}
|
||||
|
||||
Saved.RaiseEvent(new SaveEventArgs<IContent>(content, false), this);
|
||||
|
||||
Created.RaiseEvent(new NewEventArgs<IContent>(content, false, contentTypeAlias, parentId), this);
|
||||
|
||||
Audit.Add(AuditTypes.New, string.Format("Content '{0}' was created with Id {1}", name, content.Id), content.CreatorId, content.Id);
|
||||
@@ -198,12 +226,20 @@ namespace Umbraco.Core.Services
|
||||
var contentType = FindContentTypeByAlias(contentTypeAlias);
|
||||
var content = new Content(name, parent, contentType);
|
||||
|
||||
//NOTE: I really hate the notion of these Creating/Created events - they are so inconsistent, I've only just found
|
||||
// out that in these 'WithIdentity' methods, the Saving/Saved events were not fired, wtf. Anyways, they're added now.
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IContent>(content, contentTypeAlias, parent), this))
|
||||
{
|
||||
content.WasCancelled = true;
|
||||
return content;
|
||||
}
|
||||
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IContent>(content), this))
|
||||
{
|
||||
content.WasCancelled = true;
|
||||
return content;
|
||||
}
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
@@ -213,6 +249,8 @@ namespace Umbraco.Core.Services
|
||||
uow.Commit();
|
||||
}
|
||||
|
||||
Saved.RaiseEvent(new SaveEventArgs<IContent>(content, false), this);
|
||||
|
||||
Created.RaiseEvent(new NewEventArgs<IContent>(content, false, contentTypeAlias, parent), this);
|
||||
|
||||
Audit.Add(AuditTypes.New, string.Format("Content '{0}' was created with Id {1}", name, content.Id), content.CreatorId, content.Id);
|
||||
@@ -628,10 +666,10 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="content">The <see cref="IContent"/> to publish</param>
|
||||
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
||||
/// <returns>True if publishing succeeded, otherwise False</returns>
|
||||
[Obsolete("Use PublishWithStatus instead, that method will provide more detailed information on the outcome")]
|
||||
public bool Publish(IContent content, int userId = 0)
|
||||
{
|
||||
var result = SaveAndPublishDo(content, userId);
|
||||
LogHelper.Info<ContentService>("Call was made to ContentService.Publish, use PublishWithStatus instead since that method will provide more detailed information on the outcome");
|
||||
return result.Success;
|
||||
}
|
||||
|
||||
@@ -1220,6 +1258,7 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sends an <see cref="IContent"/> to Publication, which executes handlers and events for the 'Send to Publication' action.
|
||||
/// </summary>
|
||||
@@ -1458,6 +1497,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
//bulk insert it into the database
|
||||
uow.Database.BulkInsertRecords(xmlItems, tr);
|
||||
|
||||
tr.Complete();
|
||||
}
|
||||
|
||||
Audit.Add(AuditTypes.Publish, "RebuildXmlStructures completed, the xml has been regenerated in the database", 0, -1);
|
||||
@@ -1929,7 +1970,7 @@ namespace Umbraco.Core.Services
|
||||
/// <summary>
|
||||
/// Occurs before Create
|
||||
/// </summary>
|
||||
[Obsolete("This event should not be used, it was originally created for backwards compatibility for the legacy API. To modify a new document before it is saved use the Saving event")]
|
||||
[Obsolete("Use the Created event instead, the Creating and Created events both offer the same functionality, Creating event has been deprecated.")]
|
||||
public static event TypedEventHandler<IContentService, NewEventArgs<IContent>> Creating;
|
||||
|
||||
/// <summary>
|
||||
@@ -1939,7 +1980,6 @@ namespace Umbraco.Core.Services
|
||||
/// Please note that the Content object has been created, but might not have been saved
|
||||
/// so it does not have an identity yet (meaning no Id has been set).
|
||||
/// </remarks>
|
||||
[Obsolete("This event should not be used, it was originally created for backwards compatibility for the legacy API. To modify a new document before it is saved use the Saving event")]
|
||||
public static event TypedEventHandler<IContentService, NewEventArgs<IContent>> Created;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -226,17 +226,17 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = _uowProvider.GetUnitOfWork())
|
||||
{
|
||||
var sortOrderObj =
|
||||
uow.Database.ExecuteScalar<object>(
|
||||
"SELECT max(sortorder) FROM cmsDataTypePreValues WHERE datatypeNodeId = @DataTypeId", new { DataTypeId = id });
|
||||
int sortOrder;
|
||||
if (sortOrderObj == null || int.TryParse(sortOrderObj.ToString(), out sortOrder) == false)
|
||||
{
|
||||
sortOrder = 1;
|
||||
}
|
||||
|
||||
using (var transaction = uow.Database.GetTransaction())
|
||||
{
|
||||
var sortOrderObj =
|
||||
uow.Database.ExecuteScalar<object>(
|
||||
"SELECT max(sortorder) FROM cmsDataTypePreValues WHERE datatypeNodeId = @DataTypeId", new { DataTypeId = id });
|
||||
int sortOrder;
|
||||
if (sortOrderObj == null || int.TryParse(sortOrderObj.ToString(), out sortOrder) == false)
|
||||
{
|
||||
sortOrder = 1;
|
||||
}
|
||||
|
||||
foreach (var value in values)
|
||||
{
|
||||
var dto = new DataTypePreValueDto { DataTypeNodeId = id, Value = value, SortOrder = sortOrder };
|
||||
|
||||
@@ -11,6 +11,20 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
public interface IContentService : IService
|
||||
{
|
||||
/// <summary>
|
||||
/// Assigns a single permission to the current content item for the specified user ids
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="permission"></param>
|
||||
/// <param name="userIds"></param>
|
||||
void AssignContentPermission(IContent entity, char permission, IEnumerable<int> userIds);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of permissions for the content item
|
||||
/// </summary>
|
||||
/// <param name="content"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<EntityPermission> GetPermissionsForEntity(IContent content);
|
||||
|
||||
bool SendToPublication(IContent content, int userId = 0);
|
||||
|
||||
@@ -249,7 +263,6 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="content">The <see cref="IContent"/> to publish</param>
|
||||
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
||||
/// <returns>True if publishing succeeded, otherwise False</returns>
|
||||
[Obsolete("Use PublishWithStatus instead, that method will provide more detailed information on the outcome")]
|
||||
bool Publish(IContent content, int userId = 0);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
public interface IMemberGroupService : IService
|
||||
{
|
||||
IEnumerable<IMemberGroup> GetAll();
|
||||
IMemberGroup GetById(int id);
|
||||
IMemberGroup GetByName(string name);
|
||||
void Save(IMemberGroup memberGroup, bool raiseEvents = true);
|
||||
void Delete(IMemberGroup memberGroup);
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ namespace Umbraco.Core.Services
|
||||
/// <summary>
|
||||
/// Defines the MemberService, which is an easy access to operations involving (umbraco) members.
|
||||
/// </summary>
|
||||
internal interface IMemberService : IMembershipMemberService
|
||||
public interface IMemberService : IMembershipMemberService
|
||||
{
|
||||
/// <summary>
|
||||
/// Checks if a member with the id exists
|
||||
@@ -16,14 +16,7 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
bool Exists(int id);
|
||||
|
||||
/// <summary>
|
||||
/// Get a member by its id
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
IMember GetById(int id);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get a member by the unique key
|
||||
/// </summary>
|
||||
@@ -31,6 +24,13 @@ namespace Umbraco.Core.Services
|
||||
/// <returns></returns>
|
||||
IMember GetByKey(Guid id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a member by it's id
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
IMember GetById(int id);
|
||||
|
||||
/// <summary>
|
||||
/// Get all members for the member type alias
|
||||
/// </summary>
|
||||
@@ -65,6 +65,17 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="memberTypeId"></param>
|
||||
void DeleteMembersOfType(int memberTypeId);
|
||||
|
||||
/// <summary>
|
||||
/// Find members based on their display name
|
||||
/// </summary>
|
||||
/// <param name="displayNameToMatch"></param>
|
||||
/// <param name="pageIndex"></param>
|
||||
/// <param name="pageSize"></param>
|
||||
/// <param name="totalRecords"></param>
|
||||
/// <param name="matchType"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<IMember> FindMembersByDisplayName(string displayNameToMatch, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith);
|
||||
|
||||
/// <summary>
|
||||
/// Get members based on a property search
|
||||
/// </summary>
|
||||
|
||||
@@ -3,28 +3,28 @@ using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
internal interface IMemberTypeService : IService
|
||||
{
|
||||
public interface IMemberTypeService : IService
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a list of all available <see cref="IContentType"/> objects
|
||||
/// </summary>
|
||||
/// <param name="ids">Optional list of ids</param>
|
||||
/// <returns>An Enumerable list of <see cref="IContentType"/> objects</returns>
|
||||
IEnumerable<IMemberType> GetAllMemberTypes(params int[] ids);
|
||||
IEnumerable<IMemberType> GetAll(params int[] ids);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="IMemberType"/> object by its Id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the <see cref="IMediaType"/> to retrieve</param>
|
||||
/// <returns><see cref="IMediaType"/></returns>
|
||||
IMemberType GetMemberType(int id);
|
||||
IMemberType Get(int id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="IMemberType"/> object by its Alias
|
||||
/// </summary>
|
||||
/// <param name="alias">Alias of the <see cref="IMediaType"/> to retrieve</param>
|
||||
/// <returns><see cref="IMediaType"/></returns>
|
||||
IMemberType GetMemberType(string alias);
|
||||
IMemberType Get(string alias);
|
||||
|
||||
/// <summary>
|
||||
/// Saves a single <see cref="IMemberType"/> object
|
||||
|
||||
@@ -6,16 +6,16 @@ using Umbraco.Core.Persistence.Querying;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Defines part of the MemberService, which is specific to methods used by the membership provider.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Idea is to have this is an isolated interface so that it can be easily 'replaced' in the membership provider impl.
|
||||
/// </remarks>
|
||||
internal interface IMembershipMemberService : IMembershipMemberService<IMember>
|
||||
public interface IMembershipMemberService : IMembershipMemberService<IMember>, IMembershipRoleService<IMember>
|
||||
{
|
||||
IMember CreateMember(string email, string username, string password, IMemberType memberType);
|
||||
IMember CreateMember(string username, string email, string password, string memberType);
|
||||
IMember CreateMemberWithIdentity(string username, string email, string password, IMemberType memberType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -24,7 +24,7 @@ namespace Umbraco.Core.Services
|
||||
/// <remarks>
|
||||
/// Idea is to have this is an isolated interface so that it can be easily 'replaced' in the membership provider impl.
|
||||
/// </remarks>
|
||||
internal interface IMembershipMemberService<T> : IService
|
||||
public interface IMembershipMemberService<T> : IService
|
||||
where T : class, IMembershipUser
|
||||
{
|
||||
/// <summary>
|
||||
@@ -48,9 +48,14 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="password"></param>
|
||||
/// <param name="memberTypeAlias"></param>
|
||||
/// <returns></returns>
|
||||
T CreateMember(string username, string email, string password, string memberTypeAlias);
|
||||
T CreateWithIdentity(string username, string email, string password, string memberTypeAlias);
|
||||
|
||||
T GetById(object id);
|
||||
/// <summary>
|
||||
/// Gets the member by the provider key
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
T GetByProviderKey(object id);
|
||||
|
||||
/// <summary>
|
||||
/// Get a member by email
|
||||
@@ -62,20 +67,20 @@ namespace Umbraco.Core.Services
|
||||
T GetByUsername(string login);
|
||||
|
||||
void Delete(T membershipUser);
|
||||
|
||||
void Save(T entity, bool raiseEvents = true);
|
||||
|
||||
void Save(T membershipUser, bool raiseEvents = true);
|
||||
void Save(IEnumerable<T> entities, bool raiseEvents = true);
|
||||
|
||||
void Save(IEnumerable<T> members, bool raiseEvents = true);
|
||||
IEnumerable<T> FindByEmail(string emailStringToMatch, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith);
|
||||
|
||||
IEnumerable<T> FindMembersByEmail(string emailStringToMatch, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith);
|
||||
|
||||
IEnumerable<T> FindMembersByUsername(string login, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith);
|
||||
IEnumerable<T> FindByUsername(string login, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the total number of members based on the count type
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
int GetMemberCount(MemberCountType countType);
|
||||
int GetCount(MemberCountType countType);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of paged member data
|
||||
@@ -84,6 +89,6 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="pageSize"></param>
|
||||
/// <param name="totalRecords"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<T> GetAllMembers(int pageIndex, int pageSize, out int totalRecords);
|
||||
IEnumerable<T> GetAll(int pageIndex, int pageSize, out int totalRecords);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
public interface IMembershipRoleService<out T>
|
||||
where T : class, IMembershipUser
|
||||
{
|
||||
void AddRole(string roleName);
|
||||
IEnumerable<string> GetAllRoles();
|
||||
IEnumerable<string> GetAllRoles(int memberId);
|
||||
IEnumerable<string> GetAllRoles(string username);
|
||||
IEnumerable<T> GetMembersInRole(string roleName);
|
||||
IEnumerable<T> FindMembersInRole(string roleName, string usernameToMatch, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith);
|
||||
bool DeleteRole(string roleName, bool throwIfBeingUsed);
|
||||
void AssignRoles(string[] usernames, string[] roleNames);
|
||||
void DissociateRoles(string[] usernames, string[] roleNames);
|
||||
void AssignRoles(int[] memberIds, string[] roleNames);
|
||||
void DissociateRoles(int[] memberIds, string[] roleNames);
|
||||
}
|
||||
}
|
||||
@@ -8,10 +8,10 @@ namespace Umbraco.Core.Services
|
||||
/// <remarks>
|
||||
/// Idea is to have this is an isolated interface so that it can be easily 'replaced' in the membership provider impl.
|
||||
/// </remarks>
|
||||
internal interface IMembershipUserService : IMembershipMemberService<IUser>
|
||||
public interface IMembershipUserService : IMembershipMemberService<IUser>
|
||||
{
|
||||
|
||||
IUser CreateMember(string username, string email, string password, IUserType userType);
|
||||
IUser CreateUserWithIdentity(string username, string email, string password, IUserType userType);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -7,18 +7,64 @@ namespace Umbraco.Core.Services
|
||||
/// <summary>
|
||||
/// Defines the UserService, which is an easy access to operations involving <see cref="IProfile"/> and eventually Users.
|
||||
/// </summary>
|
||||
internal interface IUserService : IMembershipUserService
|
||||
public interface IUserService : IMembershipUserService
|
||||
{
|
||||
/// <summary>
|
||||
/// To permanently delete the user pass in true, otherwise they will just be disabled
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="deletePermanently"></param>
|
||||
void Delete(IUser user, bool deletePermanently);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an IProfile by User Id.
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the User to retrieve</param>
|
||||
/// <returns><see cref="IProfile"/></returns>
|
||||
IProfile GetProfileById(int id);
|
||||
|
||||
/// <summary>
|
||||
/// Get profile by username
|
||||
/// </summary>
|
||||
/// <param name="username"></param>
|
||||
/// <returns></returns>
|
||||
IProfile GetProfileByUserName(string username);
|
||||
|
||||
/// <summary>
|
||||
/// Get user by Id
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
IUser GetUserById(int id);
|
||||
|
||||
/// <summary>
|
||||
/// This is useful when an entire section is removed from config
|
||||
/// </summary>
|
||||
/// <param name="sectionAlias"></param>
|
||||
void DeleteSectionFromAllUsers(string sectionAlias);
|
||||
|
||||
/// <summary>
|
||||
/// Get permissions set for user and specified node ids
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="nodeIds">
|
||||
/// Specifiying nothing will return all user permissions for all nodes
|
||||
/// </param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<EntityPermission> GetPermissions(IUser user, params int[] nodeIds);
|
||||
|
||||
/// <summary>
|
||||
/// Replaces the same permission set for a single user to any number of entities
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="permissions"></param>
|
||||
/// <param name="entityIds"></param>
|
||||
void ReplaceUserPermissions(int userId, IEnumerable<char> permissions, params int[] entityIds);
|
||||
|
||||
#region User types
|
||||
|
||||
IEnumerable<IUserType> GetAllUserTypes(params int[] ids);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an IUserType by its Alias
|
||||
/// </summary>
|
||||
@@ -26,6 +72,13 @@ namespace Umbraco.Core.Services
|
||||
/// <returns><see cref="IUserType"/></returns>
|
||||
IUserType GetUserTypeByAlias(string alias);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an IUserType by its Id
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
IUserType GetUserTypeById(int id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an IUserType by its Name
|
||||
/// </summary>
|
||||
@@ -45,19 +98,7 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
/// <param name="userType"></param>
|
||||
void DeleteUserType(IUserType userType);
|
||||
|
||||
/// <summary>
|
||||
/// This is useful when an entire section is removed from config
|
||||
/// </summary>
|
||||
/// <param name="sectionAlias"></param>
|
||||
void DeleteSectionFromAllUsers(string sectionAlias);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of the sections that the user is allowed access to
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IEnumerable<string> GetUserSections(IUser user);
|
||||
|
||||
IEnumerable<EntityPermission> GetPermissions(IUser user, params int[] nodeIds);
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -122,12 +122,23 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
var mediaType = FindMediaTypeByAlias(mediaTypeAlias);
|
||||
var media = new Models.Media(name, parentId, mediaType);
|
||||
|
||||
//NOTE: I really hate the notion of these Creating/Created events - they are so inconsistent, I've only just found
|
||||
// out that in these 'WithIdentity' methods, the Saving/Saved events were not fired, wtf. Anyways, they're added now.
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IMedia>(media, mediaTypeAlias, parentId), this))
|
||||
{
|
||||
media.WasCancelled = true;
|
||||
return media;
|
||||
}
|
||||
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMedia>(media), this))
|
||||
{
|
||||
media.WasCancelled = true;
|
||||
return media;
|
||||
}
|
||||
|
||||
//TODO: Once we fix up the transaction logic, these write locks should be replaced with
|
||||
// an outter transaction instead.
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
@@ -142,6 +153,8 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMedia>(media, false), this);
|
||||
|
||||
Created.RaiseEvent(new NewEventArgs<IMedia>(media, false, mediaTypeAlias, parentId), this);
|
||||
|
||||
Audit.Add(AuditTypes.New, string.Format("Media '{0}' was created with Id {1}", name, media.Id), media.CreatorId, media.Id);
|
||||
@@ -166,12 +179,21 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
var mediaType = FindMediaTypeByAlias(mediaTypeAlias);
|
||||
var media = new Models.Media(name, parent, mediaType);
|
||||
|
||||
//NOTE: I really hate the notion of these Creating/Created events - they are so inconsistent, I've only just found
|
||||
// out that in these 'WithIdentity' methods, the Saving/Saved events were not fired, wtf. Anyways, they're added now.
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IMedia>(media, mediaTypeAlias, parent), this))
|
||||
{
|
||||
media.WasCancelled = true;
|
||||
return media;
|
||||
}
|
||||
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMedia>(media), this))
|
||||
{
|
||||
media.WasCancelled = true;
|
||||
return media;
|
||||
}
|
||||
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
@@ -186,6 +208,8 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMedia>(media, false), this);
|
||||
|
||||
Created.RaiseEvent(new NewEventArgs<IMedia>(media, false, mediaTypeAlias, parent), this);
|
||||
|
||||
Audit.Add(AuditTypes.New, string.Format("Media '{0}' was created with Id {1}", name, media.Id), media.CreatorId, media.Id);
|
||||
@@ -938,6 +962,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
//bulk insert it into the database
|
||||
uow.Database.BulkInsertRecords(xmlItems, tr);
|
||||
|
||||
tr.Complete();
|
||||
}
|
||||
|
||||
Audit.Add(AuditTypes.Publish, "RebuildXmlStructures completed, the xml has been regenerated in the database", 0, -1);
|
||||
@@ -1040,7 +1066,7 @@ namespace Umbraco.Core.Services
|
||||
/// <summary>
|
||||
/// Occurs before Create
|
||||
/// </summary>
|
||||
[Obsolete("This event should not be used, it was originally created for backwards compatibility for the legacy API. To modify a new document before it is saved use the Saving event")]
|
||||
[Obsolete("Use the Created event instead, the Creating and Created events both offer the same functionality, Creating event has been deprecated.")]
|
||||
public static event TypedEventHandler<IMediaService, NewEventArgs<IMedia>> Creating;
|
||||
|
||||
/// <summary>
|
||||
@@ -1050,7 +1076,6 @@ namespace Umbraco.Core.Services
|
||||
/// Please note that the Media object has been created, but not saved
|
||||
/// so it does not have an identity yet (meaning no Id has been set).
|
||||
/// </remarks>
|
||||
[Obsolete("This event should not be used, it was originally created for backwards compatibility for the legacy API. To modify a new document before it is saved use the Saving event")]
|
||||
public static event TypedEventHandler<IMediaService, NewEventArgs<IMedia>> Created;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Persistence.Repositories;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
public class MemberGroupService : IMemberGroupService
|
||||
{
|
||||
private readonly RepositoryFactory _repositoryFactory;
|
||||
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
|
||||
|
||||
public MemberGroupService(RepositoryFactory repositoryFactory)
|
||||
: this(new PetaPocoUnitOfWorkProvider(), repositoryFactory)
|
||||
{
|
||||
}
|
||||
|
||||
public MemberGroupService(IDatabaseUnitOfWorkProvider provider)
|
||||
: this(provider, new RepositoryFactory())
|
||||
{
|
||||
}
|
||||
|
||||
public MemberGroupService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory)
|
||||
{
|
||||
_repositoryFactory = repositoryFactory;
|
||||
_uowProvider = provider;
|
||||
|
||||
//Proxy events!
|
||||
MemberGroupRepository.SavedMemberGroup += MemberGroupRepository_SavedMemberGroup;
|
||||
MemberGroupRepository.SavingMemberGroup += MemberGroupRepository_SavingMemberGroup;
|
||||
}
|
||||
|
||||
#region Proxied event handlers
|
||||
void MemberGroupRepository_SavingMemberGroup(IMemberGroupRepository sender, SaveEventArgs<IMemberGroup> e)
|
||||
{
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMemberGroup>(e.SavedEntities), this))
|
||||
{
|
||||
e.Cancel = true;
|
||||
}
|
||||
}
|
||||
|
||||
void MemberGroupRepository_SavedMemberGroup(IMemberGroupRepository sender, SaveEventArgs<IMemberGroup> e)
|
||||
{
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMemberGroup>(e.SavedEntities, false), this);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public IEnumerable<IMemberGroup> GetAll()
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
return repository.GetAll();
|
||||
}
|
||||
}
|
||||
|
||||
public IMemberGroup GetById(int id)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
return repository.Get(id);
|
||||
}
|
||||
}
|
||||
|
||||
public IMemberGroup GetByName(string name)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
return repository.GetByName(name);
|
||||
}
|
||||
}
|
||||
|
||||
public void Save(IMemberGroup memberGroup, bool raiseEvents = true)
|
||||
{
|
||||
if (raiseEvents)
|
||||
{
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMemberGroup>(memberGroup), this))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(uow))
|
||||
{
|
||||
repository.AddOrUpdate(memberGroup);
|
||||
uow.Commit();
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMemberGroup>(memberGroup, false), this);
|
||||
}
|
||||
|
||||
public void Delete(IMemberGroup memberGroup)
|
||||
{
|
||||
if (Deleting.IsRaisedEventCancelled(new DeleteEventArgs<IMemberGroup>(memberGroup), this))
|
||||
return;
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(uow))
|
||||
{
|
||||
repository.Delete(memberGroup);
|
||||
uow.Commit();
|
||||
}
|
||||
|
||||
Deleted.RaiseEvent(new DeleteEventArgs<IMemberGroup>(memberGroup, false), this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs before Delete of a member group
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IMemberGroupService, DeleteEventArgs<IMemberGroup>> Deleting;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs after Delete of a member group
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IMemberGroupService, DeleteEventArgs<IMemberGroup>> Deleted;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs before Save of a member group
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// We need to proxy these events because the events need to take place at the repo level
|
||||
/// </remarks>
|
||||
public static event TypedEventHandler<IMemberGroupService, SaveEventArgs<IMemberGroup>> Saving;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs after Save of a member group
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// We need to proxy these events because the events need to take place at the repo level
|
||||
/// </remarks>
|
||||
public static event TypedEventHandler<IMemberGroupService, SaveEventArgs<IMemberGroup>> Saved;
|
||||
}
|
||||
}
|
||||
@@ -5,12 +5,14 @@ using System.Threading;
|
||||
using System.Web.Security;
|
||||
using System.Xml.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Umbraco.Core.Auditing;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Persistence.Repositories;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using System.Linq;
|
||||
@@ -20,26 +22,31 @@ namespace Umbraco.Core.Services
|
||||
/// <summary>
|
||||
/// Represents the MemberService.
|
||||
/// </summary>
|
||||
internal class MemberService : IMemberService
|
||||
public class MemberService : IMemberService
|
||||
{
|
||||
private readonly RepositoryFactory _repositoryFactory;
|
||||
private readonly IMemberGroupService _memberGroupService;
|
||||
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
|
||||
|
||||
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim();
|
||||
|
||||
internal MemberService(RepositoryFactory repositoryFactory)
|
||||
: this(new PetaPocoUnitOfWorkProvider(), repositoryFactory)
|
||||
public MemberService(RepositoryFactory repositoryFactory, IMemberGroupService memberGroupService)
|
||||
: this(new PetaPocoUnitOfWorkProvider(), repositoryFactory, memberGroupService)
|
||||
{
|
||||
}
|
||||
|
||||
internal MemberService(IDatabaseUnitOfWorkProvider provider)
|
||||
: this(provider, new RepositoryFactory())
|
||||
public MemberService(IDatabaseUnitOfWorkProvider provider, IMemberGroupService memberGroupService)
|
||||
: this(provider, new RepositoryFactory(), memberGroupService)
|
||||
{
|
||||
}
|
||||
|
||||
internal MemberService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory)
|
||||
public MemberService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, IMemberGroupService memberGroupService)
|
||||
{
|
||||
if (provider == null) throw new ArgumentNullException("provider");
|
||||
if (repositoryFactory == null) throw new ArgumentNullException("repositoryFactory");
|
||||
if (memberGroupService == null) throw new ArgumentNullException("memberGroupService");
|
||||
_repositoryFactory = repositoryFactory;
|
||||
_memberGroupService = memberGroupService;
|
||||
_uowProvider = provider;
|
||||
}
|
||||
|
||||
@@ -207,6 +214,38 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IMember> FindMembersByDisplayName(string displayNameToMatch, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberRepository(uow))
|
||||
{
|
||||
var query = new Query<IMember>();
|
||||
|
||||
switch (matchType)
|
||||
{
|
||||
case StringPropertyMatchType.Exact:
|
||||
query.Where(member => member.Name.Equals(displayNameToMatch));
|
||||
break;
|
||||
case StringPropertyMatchType.Contains:
|
||||
query.Where(member => member.Name.Contains(displayNameToMatch));
|
||||
break;
|
||||
case StringPropertyMatchType.StartsWith:
|
||||
query.Where(member => member.Name.StartsWith(displayNameToMatch));
|
||||
break;
|
||||
case StringPropertyMatchType.EndsWith:
|
||||
query.Where(member => member.Name.EndsWith(displayNameToMatch));
|
||||
break;
|
||||
case StringPropertyMatchType.Wildcard:
|
||||
query.Where(member => member.Name.SqlWildcard(displayNameToMatch, TextColumnType.NVarchar));
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("matchType");
|
||||
}
|
||||
|
||||
return repository.GetPagedResultsByQuery(query, pageIndex, pageSize, out totalRecords, dto => dto.Name);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does a search for members that contain the specified string in their email address
|
||||
/// </summary>
|
||||
@@ -216,7 +255,7 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="pageIndex"></param>
|
||||
/// <param name="pageSize"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<IMember> FindMembersByEmail(string emailStringToMatch, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith)
|
||||
public IEnumerable<IMember> FindByEmail(string emailStringToMatch, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberRepository(uow))
|
||||
@@ -248,7 +287,7 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IMember> FindMembersByUsername(string login, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith)
|
||||
public IEnumerable<IMember> FindByUsername(string login, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberRepository(uow))
|
||||
@@ -489,7 +528,7 @@ namespace Umbraco.Core.Services
|
||||
/// that have their last active date within the Membership.UserIsOnlineTimeWindow (which is in minutes). It isn't exact science
|
||||
/// but that is how MS have made theirs so we'll follow that principal.
|
||||
/// </remarks>
|
||||
public int GetMemberCount(MemberCountType countType)
|
||||
public int GetCount(MemberCountType countType)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateMemberRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
@@ -529,7 +568,7 @@ namespace Umbraco.Core.Services
|
||||
|
||||
}
|
||||
|
||||
public IEnumerable<IMember> GetAllMembers(int pageIndex, int pageSize, out int totalRecords)
|
||||
public IEnumerable<IMember> GetAll(int pageIndex, int pageSize, out int totalRecords)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberRepository(uow))
|
||||
@@ -538,11 +577,29 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
public IMember CreateMember(string email, string username, string password, IMemberType memberType)
|
||||
public IMember CreateMember(string username, string email, string password, string memberTypeAlias)
|
||||
{
|
||||
var memberTypeService = ApplicationContext.Current.Services.MemberTypeService;
|
||||
var memberType = memberTypeService.Get(memberTypeAlias);
|
||||
|
||||
var member = new Member(username, email.ToLower().Trim(), username, password, -1, memberType);
|
||||
|
||||
Created.RaiseEvent(new NewEventArgs<IMember>(member, false, memberTypeAlias, -1), this);
|
||||
|
||||
return member;
|
||||
}
|
||||
|
||||
public IMember CreateMemberWithIdentity(string username, string email, string password, IMemberType memberType)
|
||||
{
|
||||
if (memberType == null) throw new ArgumentNullException("memberType");
|
||||
|
||||
var member = new Member(email, email, username, password, -1, memberType);
|
||||
var member = new Member(username, email.ToLower().Trim(), username, password, -1, memberType);
|
||||
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMember>(member), this))
|
||||
{
|
||||
member.WasCancelled = true;
|
||||
return member;
|
||||
}
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberRepository(uow))
|
||||
@@ -555,9 +612,12 @@ namespace Umbraco.Core.Services
|
||||
CreateAndSaveMemberXml(xml, member.Id, uow.Database);
|
||||
}
|
||||
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMember>(member, false), this);
|
||||
Created.RaiseEvent(new NewEventArgs<IMember>(member, false, memberType.Alias, -1), this);
|
||||
|
||||
return member;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates and persists a new Member
|
||||
/// </summary>
|
||||
@@ -566,7 +626,7 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="password"></param>
|
||||
/// <param name="memberTypeAlias"></param>
|
||||
/// <returns></returns>
|
||||
public IMember CreateMember(string email, string username, string password, string memberTypeAlias)
|
||||
IMember IMembershipMemberService<IMember>.CreateWithIdentity(string username, string email, string password, string memberTypeAlias)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
IMemberType memberType;
|
||||
@@ -582,7 +642,7 @@ namespace Umbraco.Core.Services
|
||||
throw new ArgumentException(string.Format("No MemberType matching the passed in Alias: '{0}' was found", memberTypeAlias));
|
||||
}
|
||||
|
||||
return CreateMember(email, username, password, memberTypeAlias);
|
||||
return CreateMemberWithIdentity(username, email, password, memberType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -593,17 +653,18 @@ namespace Umbraco.Core.Services
|
||||
/// </remarks>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public IMember GetById(object id)
|
||||
public IMember GetByProviderKey(object id)
|
||||
{
|
||||
if (id is int)
|
||||
{
|
||||
return GetById((int)id);
|
||||
}
|
||||
|
||||
if (id is Guid)
|
||||
var asGuid = id.TryConvertTo<Guid>();
|
||||
if (asGuid.Success)
|
||||
{
|
||||
return GetByKey((Guid)id);
|
||||
}
|
||||
var asInt = id.TryConvertTo<int>();
|
||||
if (asInt.Success)
|
||||
{
|
||||
return GetById((int)id);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -660,39 +721,42 @@ namespace Umbraco.Core.Services
|
||||
|
||||
Deleted.RaiseEvent(new DeleteEventArgs<IMember>(member, false), this);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Saves an updated Member
|
||||
/// </summary>
|
||||
/// <param name="member"></param>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="raiseEvents"></param>
|
||||
public void Save(IMember member, bool raiseEvents = true)
|
||||
public void Save(IMember entity, bool raiseEvents = true)
|
||||
{
|
||||
if (raiseEvents)
|
||||
{
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMember>(member), this))
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMember>(entity), this))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberRepository(uow))
|
||||
{
|
||||
repository.AddOrUpdate(member);
|
||||
repository.AddOrUpdate(entity);
|
||||
uow.Commit();
|
||||
|
||||
var xml = member.ToXml();
|
||||
CreateAndSaveMemberXml(xml, member.Id, uow.Database);
|
||||
var xml = entity.ToXml();
|
||||
CreateAndSaveMemberXml(xml, entity.Id, uow.Database);
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMember>(member, false), this);
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMember>(entity, false), this);
|
||||
}
|
||||
|
||||
public void Save(IEnumerable<IMember> members, bool raiseEvents = true)
|
||||
public void Save(IEnumerable<IMember> entities, bool raiseEvents = true)
|
||||
{
|
||||
if (raiseEvents)
|
||||
{
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMember>(members), this))
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMember>(entities), this))
|
||||
return;
|
||||
}
|
||||
using (new WriteLock(Locker))
|
||||
@@ -700,7 +764,7 @@ namespace Umbraco.Core.Services
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberRepository(uow))
|
||||
{
|
||||
foreach (var member in members)
|
||||
foreach (var member in entities)
|
||||
{
|
||||
repository.AddOrUpdate(member);
|
||||
}
|
||||
@@ -708,19 +772,143 @@ namespace Umbraco.Core.Services
|
||||
//commit the whole lot in one go
|
||||
uow.Commit();
|
||||
|
||||
foreach (var member in members)
|
||||
foreach (var member in entities)
|
||||
{
|
||||
CreateAndSaveMemberXml(member.ToXml(), member.Id, uow.Database);
|
||||
}
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMember>(members, false), this);
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMember>(entities, false), this);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IMembershipRoleService Implementation
|
||||
|
||||
public void AddRole(string roleName)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(uow))
|
||||
{
|
||||
repository.CreateIfNotExists(roleName);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetAllRoles()
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(uow))
|
||||
{
|
||||
var result = repository.GetAll();
|
||||
return result.Select(x => x.Name).Distinct();
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetAllRoles(int memberId)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(uow))
|
||||
{
|
||||
var result = repository.GetMemberGroupsForMember(memberId);
|
||||
return result.Select(x => x.Name).Distinct();
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetAllRoles(string username)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(uow))
|
||||
{
|
||||
var result = repository.GetMemberGroupsForMember(username);
|
||||
return result.Select(x => x.Name).Distinct();
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IMember> GetMembersInRole(string roleName)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberRepository(uow))
|
||||
{
|
||||
return repository.GetByMemberGroup(roleName);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IMember> FindMembersInRole(string roleName, string usernameToMatch, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberRepository(uow))
|
||||
{
|
||||
return repository.FindMembersInRole(roleName, usernameToMatch, matchType);
|
||||
}
|
||||
}
|
||||
|
||||
public bool DeleteRole(string roleName, bool throwIfBeingUsed)
|
||||
{
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
if (throwIfBeingUsed)
|
||||
{
|
||||
var inRole = GetMembersInRole(roleName);
|
||||
if (inRole.Any())
|
||||
{
|
||||
throw new InvalidOperationException("The role " + roleName + " is currently assigned to members");
|
||||
}
|
||||
}
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(uow))
|
||||
{
|
||||
var qry = new Query<IMemberGroup>().Where(g => g.Name == roleName);
|
||||
var found = repository.GetByQuery(qry).ToArray();
|
||||
|
||||
foreach (var memberGroup in found)
|
||||
{
|
||||
_memberGroupService.Delete(memberGroup);
|
||||
}
|
||||
return found.Any();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AssignRoles(string[] usernames, string[] roleNames)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(uow))
|
||||
{
|
||||
repository.AssignRoles(usernames, roleNames);
|
||||
}
|
||||
}
|
||||
|
||||
public void DissociateRoles(string[] usernames, string[] roleNames)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(uow))
|
||||
{
|
||||
repository.DissociateRoles(usernames, roleNames);
|
||||
}
|
||||
}
|
||||
|
||||
public void AssignRoles(int[] memberIds, string[] roleNames)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(uow))
|
||||
{
|
||||
repository.AssignRoles(memberIds, roleNames);
|
||||
}
|
||||
}
|
||||
|
||||
public void DissociateRoles(int[] memberIds, string[] roleNames)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(uow))
|
||||
{
|
||||
repository.DissociateRoles(memberIds, roleNames);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Rebuilds all xml content in the cmsContentXml table for all media
|
||||
/// </summary>
|
||||
@@ -797,6 +985,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
//bulk insert it into the database
|
||||
uow.Database.BulkInsertRecords(xmlItems, tr);
|
||||
|
||||
tr.Complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -810,7 +1000,6 @@ namespace Umbraco.Core.Services
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Occurs before Delete
|
||||
/// </summary>
|
||||
@@ -825,12 +1014,21 @@ namespace Umbraco.Core.Services
|
||||
/// Occurs before Save
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IMemberService, SaveEventArgs<IMember>> Saving;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs after Create
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Please note that the Member object has been created, but might not have been saved
|
||||
/// so it does not have an identity yet (meaning no Id has been set).
|
||||
/// </remarks>
|
||||
public static event TypedEventHandler<IMemberService, NewEventArgs<IMember>> Created;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs after Save
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IMemberService, SaveEventArgs<IMember>> Saved;
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
@@ -895,5 +1093,6 @@ namespace Umbraco.Core.Services
|
||||
return new Member(name, email, username, password, -1, memType);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user