Compare commits

...

456 Commits

Author SHA1 Message Date
Sebastiaan Janssen e12f24af94 Merge branch '7.1.2' of https://github.com/umbraco/Umbraco-CMS into 7.1.2 2014-05-09 13:31:41 +02:00
Sebastiaan Janssen cbad216387 Update the install ps to do logging of copies and to actually copy the /umbraco folder properly 2014-05-09 13:07:41 +02:00
Sebastiaan Janssen 00880fcbfa I was confused, these files exist just fine :) 2014-05-09 13:07:03 +02:00
Stephan 080ed612e8 U4-4837 - bugfix Umbraco.Core.EnumerableExtensions.InGroupsOf 2014-05-09 10:22:23 +02:00
Stephan 5661a34e00 Bugfix media cache property alias case sensitivity 2014-05-09 10:21:31 +02:00
Sebastiaan Janssen 85012ee82a Renaming files that don't exist led to the NuGet package not being created correctly somehow 2014-05-09 09:16:51 +02:00
Shannon 53a9cdb7a0 fixes a couple tests 2014-05-09 17:10:56 +10:00
Shannon 6b6ca615ba Updates build to ignore bower and commits typeahead. 2014-05-09 17:02:14 +10:00
Shannon 2eef061c42 attempting to add the default git path to the path variable - hopefully the server has the same one 2014-05-09 15:58:09 +10:00
Shannon 70f65583d7 Fixes: U4-4546 Error: Failed to retreive data for media ids 2014-05-09 15:50:07 +10:00
Shannon 0d37a1f6e8 Fixes: U4-4849 Cannot change a users language/sections in the back office 2014-05-09 15:19:00 +10:00
Shannon 389724cba5 Re-fixes: U4-4211 User without media section permission will be logged out immediately when accessing a document type using a media picker datatype (u7.0.3) 2014-05-09 14:06:15 +10:00
Shannon 0382902984 Fixes user cloning issues with allowed sections 2014-05-09 14:01:20 +10:00
Shannon e0a0216b2d Fixes build in unit tests with ctor for service context 2014-05-09 13:28:03 +10:00
Shannon b02f7e0d3a ensure properties reset on deep clone of ContentType (this is just a fail safe check) 2014-05-09 13:26:50 +10:00
Shannon 9d96a4411f Fixes deep clone of macro object 2014-05-09 13:26:16 +10:00
Shannon 8e9a9dc996 Fixes deep clone of User object 2014-05-09 13:25:18 +10:00
Shannon b1603a21a2 Fixes up strange culture issue with thread switching with the update to the AngularJsonMediaTypeFormatter. 2014-05-09 10:46:15 +10:00
Sebastiaan Janssen 59cb1ad31e Revert "Fixes: U4-4211 User without media section permission will be logged out immediately when accessing a document type using a media picker datatype (u7.0.3) - this is done by using the entityResource in the mediaPicker but to do this we need to return a cut down version of the media properties in the additionalData which is tricky because the cropper stores json which is ntext and the existing sql didn't cater for this. This also cleans up the entity service and we no longer have this internal collection of properties, everything is just added to additionalData, then had to add mediaHelper method to deal with getting urls from a media 'entity' not just a media object."
This reverts commit c38c2ede11.
2014-05-08 16:08:16 +02:00
Sebastiaan Janssen 215ebb78ca Oops, this really needs to be Release mode 2014-05-08 13:56:19 +02:00
Sebastiaan Janssen c1796dd5ac Update ImageProcessor dependency to latest version 2014-05-08 13:28:46 +02:00
Sebastiaan Janssen 28550e3bb7 Require a recent version of NuGet in order to install Umbraco. 2014-05-08 13:28:32 +02:00
Sebastiaan Janssen bc59ff2e8c Clarified /base obsoletion to point out UmbracoApiController 2014-05-08 11:14:00 +02:00
Shannon 614327a273 Merge branch '7.1.2' of https://github.com/umbraco/Umbraco-CMS into 7.1.2 2014-05-08 19:03:58 +10:00
Shannon ed292d34db oops fixed build 2014-05-08 19:03:40 +10:00
Shandem 5ac3eb7fef Merge pull request #364 from tomfulton/patch-1
Fix U4-4779: Media Picker not working as single picker
2014-05-08 18:49:36 +10:00
Shannon 94732cff00 Renames GetCurrent to GetCurrentMember to be inline with GetCurrentMemberId 2014-05-08 18:13:59 +10:00
Shandem 7947682cf0 Merge pull request #373 from sniffdk/patch-1
Fix for issue U4-4826
2014-05-08 18:13:23 +10:00
Shannon 6506768f10 Adds GetCurrentMemberId as a method to MembershipHelper 2014-05-08 18:12:28 +10:00
Shannon 9e0d10d0a3 Adds Logout as a wrapper to formsauth in membershiphelper 2014-05-08 18:10:01 +10:00
Shannon 392b18f4dd Adds GetCurrent() to MembershipHelper 2014-05-08 18:08:06 +10:00
Shannon c3ecc9e942 Fixes: U4-4505 Add obsolete messages to /base restextentions methods ( i think i got them all ) 2014-05-08 17:25:06 +10:00
Shannon c47f9ae26d Fixes: U4-4835 If you've changed data on a content item and then attempt to logout, the 'discard changes' dialog pops up however the logout continues but the URL and view remains 2014-05-08 16:57:29 +10:00
Shannon 22b506e2fb Fixes: U4-4827 The new speechbubble container is placed over the save and publish buttons 2014-05-08 12:26:59 +10:00
Shannon 516723d31d Merge branch '7.1.2' of https://github.com/umbraco/Umbraco-CMS into 7.1.2 2014-05-08 11:38:38 +10:00
Shannon 7c30f26505 Fixes: U4-4845 Publicize INotificationService 2014-05-08 11:38:05 +10:00
Shandem 6b84a6adec Merge pull request #374 from sniffdk/patch-2
Fix for issue U4-4827
2014-05-08 11:31:22 +10:00
Shannon 6e2493854a makes Reset protected internal on ResolverBase 2014-05-08 11:22:44 +10:00
Shandem 1e13746cd0 Merge pull request #375 from rustyswayne/7.1.2
Makes HasCurrent property protected on ResolverBase.  #U4-4829
2014-05-08 11:11:12 +10:00
Shannon 8c7adf80b2 Fixes: U4-4573 7.0.4 Save and Send For Approval button not sending notification email 2014-05-08 00:45:54 +10:00
Shannon c38c2ede11 Fixes: U4-4211 User without media section permission will be logged out immediately when accessing a document type using a media picker datatype (u7.0.3) - this is done by using the entityResource in the mediaPicker but to do this we need to return a cut down version of the media properties in the additionalData which is tricky because the cropper stores json which is ntext and the existing sql didn't cater for this. This also cleans up the entity service and we no longer have this internal collection of properties, everything is just added to additionalData, then had to add mediaHelper method to deal with getting urls from a media 'entity' not just a media object. 2014-05-07 23:55:20 +10:00
Shannon a6cd2b9e18 Fixes: U4-4420 TagQuery / TagService missing method to get content with tag. 2014-05-07 14:27:10 +10:00
Rusty Swayne 5fa128697b Makes HasCurrent property protected on ResolverBase. #U4-4829 2014-05-06 10:04:14 -07:00
Mads Krohn 62c3bf6afe Fix for issue U4-4827
I simply placed the container a little higher up, just above the Save and Publish buttons.
2014-05-06 13:39:11 +02:00
Mads Krohn aec862a9de Fix for issue U4-4826
When editing an existing link in tinymce the following error is thrown:
Could not find the tree content, activeTree has not been set 

This is caused by passing a wrong value as parameter to the doLoad method in the loadActiveTree function.
2014-05-06 13:02:47 +02:00
Shannon cfd21bc924 Got this working: U4-4420 TagQuery / TagService missing method to get content with tag - just need to add some unit tests. 2014-05-06 19:04:49 +10:00
Shannon d264792e18 Fixes: U4-4819 Publicize AuthenticationExtensions 2014-05-06 18:15:38 +10:00
Shannon af732955fb Fixes up a bit more with tags look ahead, fixes up rte to show a loading... text so the UI is handled much better 2014-05-06 18:06:41 +10:00
Shannon a846ba64eb Fixes: U4-4799 Ensure image logic found in the ContentService is duplicated for the new cropper 2014-05-06 15:27:53 +10:00
Shannon d3e925add9 Fixes: U4-4803 Need to expose CurrentUser on WebSecurity as public since IUser is now public 2014-05-06 14:49:43 +10:00
Shannon 683f0c5725 Fixes: U4-4503 Tags datatype does not autocomplete 2014-05-06 14:44:24 +10:00
Shannon 6827def8ba Merge branch '7.1.2' of https://github.com/umbraco/Umbraco-CMS into 7.1.2 2014-05-06 10:41:10 +10:00
per ploug dbbe3fe5fb Removes remaining yepnop dependencies 2014-05-05 12:59:34 +02:00
Shannon d2a20b10aa nearly got tag typeahead working 2014-05-05 19:07:57 +10:00
Shannon 27e6b8c80c Adds bower to node dependencies, uses bower to get the typeahead dependency, gets bower dependencies on npm install 2014-05-05 15:55:48 +10:00
Shannon 956a92f5b4 removes unused moment.js from core/release 2014-05-05 13:35:20 +10:00
Shannon 36c7fd53cb Fixes merge issues with left over IPublishedContentProperty 2014-05-05 13:21:18 +10:00
Shannon 3df2d03fc8 Merge remote-tracking branch 'origin/6.2.0' into 7.1.2
Conflicts:
	build/Build.bat
	build/NuSpecs/UmbracoCms.Core.nuspec
	build/NuSpecs/build/UmbracoCms.targets
	src/Umbraco.Core/Models/IPublishedContentProperty.cs
	src/Umbraco.Core/Models/PublishedContent/IPublishedContentExtended.cs
	src/Umbraco.Core/Models/PublishedContent/PublishedContentExtended.cs
	src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs
	src/Umbraco.Core/Models/PublishedContent/PublishedPropertyBase.cs
	src/Umbraco.Core/Models/PublishedContent/PublishedPropertyType.cs
	src/Umbraco.Core/Models/Template.cs
	src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs
	src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs
	src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs
	src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs
	src/Umbraco.Core/Persistence/Repositories/RecycleBinRepository.cs
	src/Umbraco.Core/Services/PackagingService.cs
	src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs
	src/Umbraco.Tests/PublishedContent/PublishedContentTestElements.cs
	src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedFragment.cs
	src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs
	src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlPublishedContent.cs
	src/Umbraco.Web/PublishedContentPropertyExtension.cs
	src/Umbraco.Web/Search/ExamineEvents.cs
	src/Umbraco.Web/UmbracoHelper.cs
	src/Umbraco.Web/umbraco.presentation/CompatibilityHelper.cs
	src/Umbraco.Web/umbraco.presentation/macro.cs
	src/umbraco.cms/businesslogic/template/Template.cs
2014-05-05 12:49:06 +10:00
Sebastiaan Janssen 16c360de88 Merge pull request #363 from aweber1/patch-1
Update ImageCropMode.cs
2014-05-02 10:43:59 +02:00
Sebastiaan Janssen c661fc6537 Merge pull request #370 from BatJan/patch-5
Fix of spelling mistake in "minumum".
2014-05-01 16:44:44 +02:00
BatJan c2c5098045 Fix of spelling mistake in "minumum".
Corrected "minumum" to "minimum" according to http://issues.umbraco.org/issue/U4-4804
2014-05-01 16:35:22 +02:00
Sebastiaan Janssen 16d98488e4 Losen up the requirement for json.net dependency 2014-05-01 14:06:28 +02:00
Morten Christensen 5a862f5c64 Fixes import of nested dictionary items #U4-4663 2014-05-01 13:51:33 +02:00
Sebastiaan Janssen caf41b74b8 Add failing test - dictionary items don't get properly nested 2014-05-01 12:26:18 +02:00
Sebastiaan Janssen e858f4ff1e U4-4775 creating new member group shows error message in dialog... 2014-05-01 11:45:14 +02:00
Sebastiaan Janssen 851961ef2b U4-4775 creating new member group shows error message in dialog... 2014-05-01 10:48:27 +02:00
Sebastiaan Janssen c139c5d93e U4-3925 Cancel Document_BeforePublish event gives YSOD 2014-05-01 09:55:14 +02:00
Shannon c4603ee5cd Fixes: U4-4798 When new property types are added, the internal Examine index isn't notified and will ignore them 2014-05-01 12:43:40 +10:00
Shannon 1e9d1007b6 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2014-05-01 11:36:33 +10:00
Shannon f23af85253 Fixes: U4-4624 Media cache hits the DB on every empty property, U4-4338 Umbraco fails to enumerate TypedMedia 2014-05-01 11:36:17 +10:00
Sebastiaan Janssen b0c5d16ba7 U4-4127 Turkish culture prevents Macros embedded 2014-04-30 19:29:32 +02:00
Stephan cd5581bef6 Back to IPublishedContentProperty (for 6 only) 2014-04-30 16:53:14 +02:00
Stephan 7d8da56dcb Revert "Reintroduce IPublishedContentProperty"
This reverts commit d33cc29f98.
2014-04-30 16:39:51 +02:00
Stephan 0501b181ce Refactor template aliases to strict aliases 2014-04-30 15:46:26 +02:00
Stephan 6d076a09e4 Refactor template aliases to strict aliases (cont) 2014-04-30 15:44:29 +02:00
Stephan 3cd3230b55 Refactor template aliases to strict aliases 2014-04-30 15:38:47 +02:00
Sebastiaan Janssen 3134668cec Bump version number 2014-04-30 12:00:19 +02:00
Shannon a8cc8fa688 Fixes case sensitivity with MySQL 2014-04-30 19:58:59 +10:00
Shannon cf2217cfe1 Fixes MySQL upgrades from < 6.0 2014-04-30 19:41:40 +10:00
Shannon e88e809e29 Use new YouTube oembed https end-point (old http one redirects) and make sure videos are embedded over https to allow for https Umbraco sites. 2014-04-30 17:39:13 +10:00
Shandem b404f3b56b Merge pull request #368 from uber-rob/u4-4785
Use new YouTube oembed https end-point (old http one redirects) and make...
2014-04-30 17:31:43 +10:00
Shannon c5559d7721 Specifying assembly for membership/user provider
Addresses http://issues.umbraco.org/issue/U4-4781
2014-04-30 11:27:47 +10:00
Shandem e9da4121bd Merge pull request #365 from aaronpowell/patch-2
Specifying assembly for membership/user provider
2014-04-30 11:24:08 +10:00
Shannon 771e216813 U4-2635 Skip past replaced word when checking
Avoids infinite loop if search and replacement are equal
2014-04-30 11:21:12 +10:00
Shannon 877ae6e026 Merge remote-tracking branch 'origin/7.1.1' into 7.1.2 2014-04-30 11:16:33 +10:00
Shandem e1d99855f6 Merge pull request #367 from lctjohn/7.1.1-U4-2635
fix for: U4-2635 Replace [...] method only replaces first ocurrence of oldString
2014-04-30 11:10:28 +10:00
Rob Church 9d9db577b4 Use new YouTube oembed https end-point (old http one redirects) and make sure videos are embedded over https to allow for https Umbraco sites. 2014-04-29 19:09:45 +01:00
John b4127294e5 U4-2635 Skip past replaced word when checking
Avoids infinite loop if search and replacement are equal
2014-04-29 14:06:05 +02:00
Aaron Powell d369af5fe0 Specifying assembly for membership/user provider
Addresses http://issues.umbraco.org/issue/U4-4781
2014-04-29 21:49:56 +10:00
John 74dd1f9181 U4-2635 Skip already-checked part of source input 2014-04-29 13:33:48 +02:00
John 86f7d79e7a Fixes: U4-2635 Umbraco.Core.Strings string Rep...
...lace(this string source, string oldString, string newString,
StringComparison stringComparison) method only replaces first ocurrence
of oldString
2014-04-29 13:24:54 +02:00
John c1781c2f4b U4-2635 add failing test
Only first occurrence of oldString is replaced.
2014-04-29 12:54:51 +02:00
per ploug d0dae43dd1 Merge branch '7.1.2' of https://github.com/umbraco/Umbraco-CMS into 7.1.2 2014-04-29 11:38:29 +02:00
per ploug 90bf600378 Replaces yepnope.js with lazyload.js
Solves the caching and multi-load of the same file problems - adds a bit
of promise-based loading logic ontop of ll.js to ensure order and count
2014-04-29 11:38:13 +02:00
Stephan d33cc29f98 Reintroduce IPublishedContentProperty 2014-04-29 09:47:30 +02:00
Tom Fulton 472c9d3a88 Fix U4-4779: Media Picker not working as single picker 2014-04-29 01:00:36 -06:00
Shannon e23d7d1af3 Fixes: U4-3404 Pressing preview should save the changes and then open preview window 2014-04-29 15:09:01 +10:00
Shandem 4b97eb2a9a Merge pull request #354 from JackieNagel/link-picker-issue
fix for issue U4-4707 - When a mediaitem is selected in the linkpicker, the id is not returned
2014-04-29 14:03:48 +10:00
Shannon dadf063ad5 Fixes: U4-4777 Preview with related links property editor doesn't work - this is just a temp fix, ensures that the YSOD is not created but doesn't fix the way preview pages are created. 2014-04-29 13:46:32 +10:00
Shannon 86e18ef89d Fixes merge issues 2014-04-29 13:36:21 +10:00
Shannon e0c3eda675 Merge remote-tracking branch 'origin/6.2.0' into 7.1.2
Conflicts:
	src/Umbraco.Core/Configuration/UmbracoSettings.cs
	src/Umbraco.Core/Models/PropertyExtensions.cs
	src/Umbraco.Core/Persistence/Repositories/Interfaces/IMemberRepository.cs
	src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs
	src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs
	src/Umbraco.Core/Security/MembershipProviderBase.cs
	src/Umbraco.Core/Services/ContentService.cs
	src/Umbraco.Core/Services/MediaService.cs
	src/Umbraco.Core/Services/PackagingService.cs
	src/Umbraco.Tests/Models/DataValueSetterTests.cs
	src/Umbraco.Web.UI/web.Template.config
	src/umbraco.cms/businesslogic/media/Media.cs
	src/umbraco.cms/businesslogic/member/Member.cs
2014-04-29 13:06:10 +10:00
Shannon b98fbbc75d Fixes: U4-4770 Preview XML is not generated for many operations in the ContentService, also moves some more CRUD logic in the content service to the content repo. 2014-04-29 11:11:48 +10:00
Shannon aba1862811 Fixes: U4-4754 Member and Media repositories need to generate preview xml when EnableGlobalPreviewStorage is true 2014-04-29 09:58:38 +10:00
Adam Weber 470913f796 Update ImageCropMode.cs
Fixed spelling error in ImageCropMode.Stretch
2014-04-28 10:17:41 -05:00
Shannon 2f53698bc5 Fixes: U4-4766 UmbracoMembershipProvider.ChangePassword() is seal, what might be a breaking change? 2014-04-28 19:19:48 +10:00
Shannon e0e12d5773 Moves content xml crud logic for member service to member repo 2014-04-28 19:04:53 +10:00
Shannon 2e96de5449 Moves the CRUD logic from the media service to the media repo for dealing with content xml items and ensures it's done in the same transaction, streamlines how this process is done between the content, media, member services, adds test for it. 2014-04-28 18:53:21 +10:00
Shannon c5bce3b8cc completes: U4-4769 Remove the circular references from services for calls like ToXml which then calls into the PackagingService 2014-04-28 17:46:05 +10:00
Shannon b4286a7d4e works on U4-4769 - removing circular refs from media service 2014-04-28 17:38:24 +10:00
Shannon 31e018c045 Moves XML serialization for content/media/members to a resusable class: EntityXmlSerializer to remove the circular references we have by using the ToXml extension methods from directly in the services. This has been completed for the ContentService, next is Media and Member services. Updates the ContentService to not perform CUD operations for preview or published xml, this is now done at the repository level and now done in a single transaction for the saving and publishing events. Still need to do that for the member and media services too and the remaining methods in the content service 2014-04-28 17:28:40 +10:00
Shannon e964d52548 Merge branch 'U4-898' of https://github.com/leekelleher/Umbraco-CMS into leekelleher-U4-898 2014-04-28 12:49:28 +10:00
Shannon 50b71faff9 Adds .woff mime type 2014-04-28 12:45:12 +10:00
Shannon d7bd38386e Merge branch '7.1.2' of https://github.com/umbraco/Umbraco-CMS into 7.1.2 2014-04-28 12:40:01 +10:00
Shannon 1f581c1fcb Merge branch 'patch-1' of https://github.com/aaronpowell/Umbraco-CMS into aaronpowell-patch-1 2014-04-28 12:39:20 +10:00
Shandem 475e6970f9 Merge pull request #356 from mattbrailsford/7.1.2-rtetinymcecheck
Added check to rte controller so as not to reload tinymce script
2014-04-28 12:32:15 +10:00
Shandem 32c8a83449 Merge pull request #360 from Jwheuvel/7.1.2
Update web.config with .woff mime support
2014-04-28 12:28:31 +10:00
Shandem 33ee2a4e48 Merge pull request #362 from Jeavon/U4-4767
Fixes U4 4767 and adds 2 Tests
2014-04-28 12:26:36 +10:00
Shannon b420941ff4 Merge remote-tracking branch 'origin/6.2.0' into 7.1.2
Conflicts:
	src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs
2014-04-28 12:26:21 +10:00
Shannon 033fd1b7ff Fixes: U4-4765 backoffice user section does not save password changes in v6.2 2014-04-28 12:24:39 +10:00
Jeavon Leopold 5f0b09544a Added Test for getting a crop on a Upload property type instead of a Cropper 2014-04-27 22:17:24 +01:00
Jeavon Leopold 7aa618cbfb Fixes U4-4767 and adds a Test for it 2014-04-27 22:06:48 +01:00
Jwheuvel 44fbc29541 Update web.config with .woff mime support
Bootstrap icons aren't visible on Windows Phone because it uses the .woff variant but the mimetype isn't available. Updated the web.config and added .woff to the staticContent section of system.webServer.
2014-04-24 20:34:57 +02:00
Sebastiaan Janssen e3162d223d Tiny update 2014-04-24 17:37:15 +02:00
Sebastiaan Janssen 6e53e19e60 Adding an Allbinaries NuSpec for use on UaaS 2014-04-24 14:03:28 +02:00
Shannon d9ac529e7e Merge remote-tracking branch 'origin/6.2.0' into 7.1.2
Conflicts:
	src/Umbraco.Core/Models/PropertyType.cs
	src/Umbraco.Web.UI/umbraco_client/GenericProperty/genericProperty.js
	src/Umbraco.Web/WebServices/CoreStringsController.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentTypeControlNew.ascx.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/create/nodetypeTasks.cs
	src/umbraco.providers/members/UmbracoMembershipProvider.cs
2014-04-24 16:33:04 +10:00
Shannon 2621b25fd3 Ensures that member saving events don't get raised for normal member operations like validating and getting a user and flagging them as online. This fixes: U4-3451 Cache on Partial View refreshed, after member execute login 2014-04-24 16:28:37 +10:00
Shannon 61055380c5 Ensures that member saving events don't get raised for normal member operations like validating and getting a user and flagging them as online. This fixes: U4-3451 Cache on Partial View refreshed, after member execute login 2014-04-24 16:26:21 +10:00
Shannon adf09d925f adds a comment 2014-04-24 14:51:41 +10:00
Shannon 12170fd787 fixes ysod overlay for ajax errors 2014-04-24 14:23:17 +10:00
Shannon c32cae16db Fixes: U4-4696 Macro personalized cache with custom membership provider not working - for any membership provider regardless of provider user key type 2014-04-24 12:14:06 +10:00
Shannon 437d1b759b fix for: U4-4696. Macro personalized cache with custom membership provider not working 2014-04-24 12:13:50 +10:00
Shannon e10e04aabf Fixes: U4-4696 Macro personalized cache with custom membership provider not working - for any membership provider regardless of provider user key type 2014-04-24 12:12:06 +10:00
Shannon 2c1807bb37 Merge branch '7.1.2' of https://github.com/umbraco/Umbraco-CMS into 7.1.2 2014-04-24 11:58:31 +10:00
Shannon c6e3340be1 Updates an error msg for media resource, performs a null check 2014-04-24 11:58:18 +10:00
Shandem 3bac4877eb Merge pull request #353 from eerrecart/fix-U4-4696
fix for: U4-4696. Macro personalized cache with custom membership provider not working
2014-04-24 11:54:54 +10:00
Stephan f46811ff67 U4-3027 - fix content & property types alias casing 2014-04-24 00:18:24 +02:00
Stephan ee210ae5d8 U4-3027 - fix content & property types alias casing 2014-04-24 00:17:21 +02:00
Stephan 6d50b46bd8 U4-4747,3027... - bugfix content type editor / aliases 2014-04-23 19:28:04 +02:00
Stephan 0810e90478 U4-4747,3027... - bugfix content type editor / aliases 2014-04-23 19:26:48 +02:00
Shannon e8989de82e Merge remote-tracking branch 'origin/6.2.0' into 7.1.2 2014-04-23 22:29:54 +10:00
Shannon a51bf232ec Fixes issue with data type pre-values and using PreValueAsArray when they are dictionary formatted. 2014-04-23 22:24:16 +10:00
Shannon cefc319bfb Fixes issue with data type pre-values and using PreValueAsArray when they are dictionary formatted. 2014-04-23 22:15:33 +10:00
Shannon b60ee9944d fix merge issues 2014-04-23 20:54:31 +10:00
Shannon 0d8ffc0e67 Merge remote-tracking branch 'origin/6.2.0' into 7.1.2
Conflicts:
	src/Umbraco.Core/Persistence/Repositories/RecycleBinRepository.cs
	src/Umbraco.Core/Services/ContentService.cs
	src/Umbraco.Core/Services/ServiceContext.cs
	src/Umbraco.Tests/MockTests.cs
	src/Umbraco.Web/Cache/DistributedCacheExtensions.cs
	src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs
2014-04-23 20:45:02 +10:00
Shannon fd19411e65 Fixes: U4-4743 Add IMemberService and IUserService to ServiceContext ctor 2014-04-23 20:41:03 +10:00
Shannon 7ac7bb9714 Fixes: U4-4746 Examine does not index updated paths/levels for moved/trashed media, U4-4744 Examine events do not listen for recycle bin emptying 2014-04-23 20:28:09 +10:00
Shandem 95cd32ad8c Merge pull request #359 from Jeavon/7.1.2-ImageCropper
Adding support for Image Crop Ratio Dimension Support & UpScale to GetCropUrl & More Tests
2014-04-23 20:20:09 +10:00
Shannon 021cac9ca5 Fixes: U4-4746 Examine does not index updated paths/levels for moved/trashed media, U4-4744 Examine events do not listen for recycle bin emptying 2014-04-23 20:19:36 +10:00
Stephan aaa56002a9 Merge remote-tracking branch 'origin/7.1.2' into 7.1.2 2014-04-23 11:23:39 +02:00
Stephan c00c59af1d U4-4676 - fix property alias corruption issue 2014-04-23 11:22:47 +02:00
Sebastiaan Janssen 56d949ab9d Correcting some more paths, come on, work! 2014-04-23 11:22:45 +02:00
Sebastiaan Janssen 65ecff4248 D'oh, automated builds make obj folders, not bin folders 2014-04-23 10:57:21 +02:00
Sebastiaan Janssen 9c82e8bc8c Build needs to be in debug mode to get all the pdb files 2014-04-23 10:42:38 +02:00
Sebastiaan Janssen 421162d809 Bump version + Attempt at U4-4742 Publish debugging symbols for NuGet package 2014-04-23 10:11:36 +02:00
Shannon 360c324511 updates examine events for media to update media if it is moved to recycle bin 2014-04-23 16:11:12 +10:00
Shannon 949447c25f Fixes examine lookup for children to ignore recycled media 2014-04-23 13:40:11 +10:00
Shannon 99d7bf91b7 Fixes null check in recycle bin repo
Conflicts:
	src/Umbraco.Core/Persistence/Repositories/RecycleBinRepository.cs
2014-04-23 13:39:34 +10:00
Shannon cc3a6f8c7a Fixes examine lookup for children to ignore recycled media 2014-04-23 13:34:57 +10:00
Shannon 9bbe8e7a93 Fixes null check in recycle bin repo 2014-04-23 13:34:25 +10:00
Shannon 508a40cd50 Merge remote-tracking branch 'origin/6.2.0' into 7.1.2
Conflicts:
	src/Umbraco.Web/Controllers/UmbRegisterController.cs
	src/Umbraco.Web/Models/RegisterModel.cs
2014-04-23 12:00:32 +10:00
Shannon a92c232178 Fixes: U4-4653 MembershipHelper RegisterMember does not set password and ignores logMemberIn, adds a new flag to the model as to whether or not to have the cookie set as a persistent cookie (default is true) 2014-04-22 19:03:43 +10:00
Shannon 30901446e1 Fixes: U4-1853 Tinymce with the format dropdown added as soon as you interact with it the content tree stops working [Uncaught TypeError: Cannot set property 'href' of undefined (anonymous function) DependencyHandler.axd:57] Chrome Only.. 2014-04-22 18:17:28 +10:00
Stephan e42149e8d9 Detached PublishedProperty remains internal for now 2014-04-22 10:13:39 +02:00
Shannon a4949a1132 Merge remote-tracking branch 'origin/6.2.0' into 7.1.2 2014-04-22 17:49:01 +10:00
Shannon 0725d95941 fixes merge 2014-04-22 17:48:36 +10:00
Shannon d772336c0f Fixes: U4-4695 Copy document type to new parent seems to lose some data, U4-4535 Create Copy method on the content type Service 2014-04-22 17:48:08 +10:00
Shannon 4f8485e7d9 Merge remote-tracking branch 'origin/6.2.0' into 7.1.2 2014-04-22 14:00:28 +10:00
Shannon f673cb024a Adds unit test for ensuring reset identities on cloning a content type 2014-04-22 14:00:03 +10:00
Shannon c4046ecb32 Fixes 'Clone' methods to ensure a Deep clone is used 2014-04-22 13:48:51 +10:00
Shannon b978582675 Merge remote-tracking branch 'origin/6.2.0' into 7.1.2
Conflicts:
	src/Umbraco.Web/Mvc/RenderViewEngine.cs
2014-04-22 13:05:30 +10:00
Shannon 7823609500 Fixes: U4-4682 Get EditorTemplates and DisplayTemplates working with RenderViewEngine 2014-04-22 13:03:47 +10:00
Shannon 069ae9930a Fixes: U4-3425 App_Code XSLT Extensions aren't recognized 2014-04-22 12:20:35 +10:00
Shannon 509d3f2647 Merge remote-tracking branch 'origin/6.2.0' into 7.1.2
Conflicts:
	src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs
2014-04-22 12:01:59 +10:00
Shannon a88cb3f724 Fixes: U4-3425 App_Code XSLT Extensions aren't recognized 2014-04-22 11:59:21 +10:00
Sebastiaan Janssen 2881118a02 Fixes U4-4026 Inline styling on container affect header text - properly 2014-04-21 16:37:20 +02:00
Sebastiaan Janssen 464cfb34f2 Merge pull request #358 from nabbed/patch-1
Update README.md
2014-04-21 13:25:03 +02:00
Sebastiaan Janssen 7a04881428 Fixes U4-4728 Public Access Error Page Choose link not selectable 2014-04-21 11:42:53 +02:00
Ben Norman 8556cf5702 Update README.md 2014-04-21 19:32:36 +10:00
Sebastiaan Janssen 1c0038ead3 Fixes U4-4726 Image Cropper Listed Dimensions Inversed From Settings 2014-04-21 10:58:15 +02:00
Jeavon Leopold ef787fc769 Adding upScale parameter to GetCropUrl 2014-04-21 09:45:05 +01:00
Jeavon Leopold ec04469b16 If only one dimension specified with Ratio mode then assume a square 2014-04-21 09:27:53 +01:00
Jeavon Leopold 80db81a7c5 Adding GetCropUrl ratio mode tests 2014-04-21 08:53:40 +01:00
Jeavon Leopold 7787c51156 Creating the internal GetBaseCropUrl method and moving the logic from the Model GetCropUrl method to ImageCropperBaseExtensions so that it can be used by both the Model method and the template extensions
Also added some new tests
2014-04-21 08:38:53 +01:00
Stephan 1a02e6be97 Detached PublishedProperty 2014-04-19 18:39:11 +02:00
Stephan 536b8ee921 U4-3425 - TypeHelper referenced assemblies issue 2014-04-19 17:44:52 +02:00
Stephan 12acdd8122 U4-3425 - TypeHelper referenced assemblies issue 2014-04-19 16:48:08 +02:00
Stephan 3bf1041041 U4-3787 - Ensure we republish published descendants when republishing 2014-04-19 14:31:36 +02:00
Stephan cd459e8b7d Merge remote-tracking branch 'origin/7.1.2' into 7.1.2 2014-04-19 14:21:24 +02:00
Stephan 7ae522b511 U4-3787 - Ensure we republish published descendants when republishing 2014-04-19 14:20:26 +02:00
Jeavon Leopold 1cf20597a4 Getting Ratio mode to work with Crop dimensions and also moving cache buster to always being the last variable 2014-04-19 11:04:32 +01:00
Jeavon Leopold e8d41a1b5e Adding Ratio Mode parameter to GetCropUrl helper 2014-04-18 22:04:23 +01:00
Jeavon Leopold 9a14a29a53 Updating ImageProcessor to v1.8.8 and ImageProcessor.Web to v3.2.2 2014-04-18 20:39:38 +01:00
mattbrailsford d66998a3e3 A better test (checks to see if it's even defined) 2014-04-18 15:52:26 +01:00
mattbrailsford fe4da60b15 Added check to rte controller so as not to reload tinymce script if it's already loaded (we don't check the CSS, but I figure this is ok) [This is temp bandaid for #U4-4724] 2014-04-18 15:43:36 +01:00
Shannon 52186f5cb2 Merge remote-tracking branch 'origin/6.2.0' into 7.1.2
Conflicts:
	src/Umbraco.Core/Models/Member.cs
2014-04-17 20:08:07 +10:00
Shannon b13251778e Fixes: U4-4713 Provider Name not set when using Custom Connection String from the Installer 2014-04-17 20:05:55 +10:00
Shannon 51309e62ec Fixes: U4-4714 Sql Azure no longer a database option in 7.1 2014-04-17 19:55:17 +10:00
Shannon fee23fac0a updates deep clone to have the false flag for resetting properties (we don't want to remember them when cloning)
Conflicts:
	src/Umbraco.Core/Models/Member.cs
2014-04-17 18:54:55 +10:00
Shannon 15f4de4ed0 fixes build issues 2014-04-17 18:52:07 +10:00
Shannon 8c303893d2 updates deep clone to have the false flag for resetting properties (we don't want to remember them when cloning) 2014-04-17 18:46:37 +10:00
Shannon 7d556a0318 Merge remote-tracking branch 'origin/6.2.0' into 7.1.2
Conflicts:
	src/Umbraco.Core/Cache/CacheProviderExtensions.cs
	src/Umbraco.Core/Cache/DictionaryCacheProviderBase.cs
	src/Umbraco.Core/Cache/ICacheProvider.cs
	src/Umbraco.Core/Cache/ObjectCacheRuntimeCacheProvider.cs
	src/Umbraco.Core/Models/Member.cs
	src/Umbraco.Core/Models/PreValue.cs
	src/Umbraco.Core/Models/PropertyType.cs
	src/Umbraco.Core/Services/DataTypeService.cs
	src/Umbraco.Tests/Models/Collections/PropertyCollectionTests.cs
	src/Umbraco.Tests/Umbraco.Tests.csproj
	src/Umbraco.Web/Models/PublishedProperty.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/webservices/MediaUploader.ashx.cs
2014-04-17 18:10:42 +10:00
Shannon cf6775ec31 moves an internal class 2014-04-17 18:05:12 +10:00
Shannon 1a13366cc9 Working on U4-4701 Fixup DataTypeService and repository with cache - the deletion logic all now happens in the transaction before it was done quite poorly for updating content types :( 2014-04-17 18:03:34 +10:00
Shannon 595b039ebe Working on U4-4701 Fixup DataTypeService and repository with cache, pre-values are now persisted properly using units of work with it's own mini internal repo. 2014-04-17 17:41:08 +10:00
Shannon e6406e9757 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2014-04-17 14:23:52 +10:00
Shannon bf65bf5bab Got pre-values caching properly and data types using the runtime cache provider correctly + unit tests. 2014-04-17 14:23:37 +10:00
Stephan a39a659858 Bugfix published content extension .Next() 2014-04-16 19:10:50 +02:00
Stephan 306d83cbd6 Bugfix published content extension .Next() 2014-04-16 19:04:49 +02:00
Stephan a4eedb9f8b U4-4575 - refactor 2014-04-16 18:51:12 +02:00
Stephan 1da901be96 U4-4575 - refactor prop. conversion logic 2014-04-16 18:25:41 +02:00
Shannon d953966248 Completes: U4-4670 Add .ContainsAny string extension to Umbraco.Core.StringExtensions 2014-04-16 17:01:26 +10:00
Shannon 2f679a52f4 fix build 2014-04-16 16:52:45 +10:00
Shannon ad8ab9f46e Fixes media uploader issue to ensure non-approved file types are not saved 2014-04-16 16:48:52 +10:00
Shannon 9b344a5a69 Added tests for member groups and member cloning. Added tests to verify that all entities can be serialized without issue. 2014-04-16 16:44:08 +10:00
Shannon 0a28bdafc2 Merge remote-tracking branch 'origin/6.2.0' into 6.2-cachefixing 2014-04-16 15:54:37 +10:00
Shannon a3a0f1a0bf adds some logging 2014-04-16 15:38:16 +10:00
Shannon f69527eac1 Fixes media uploader issue to ensure non-approved file types are not saved 2014-04-16 15:38:01 +10:00
Shannon 7aa1f480c9 Fixes up some cloning with value types and collections 2014-04-16 15:33:21 +10:00
Shannon 998f031877 Merge branch '6.2.0' into 6.2-cachefixing 2014-04-16 14:01:38 +10:00
Shannon ac7cb8febe Fixes cache providers to ensure it stores and resolves clones 2014-04-16 14:01:26 +10:00
Shannon 6e166bdba7 publicizes DeepCloneHelper 2014-04-16 13:40:20 +10:00
Shannon 1f2e46a195 Simplifies much of the deep cloning with the DeepCloneHelper and adds tests 2014-04-16 13:39:42 +10:00
Shannon bb22f5a283 More code and tests written for deep cloning. 2014-04-16 11:23:00 +10:00
Jackie Nagel 4890e97168 Added removal of isMedia whenever a contentnode is selected 2014-04-15 19:59:31 +02:00
Jackie Nagel e4f63c0576 Now inserting mediaId in the link picker and setting the isMedia flag so that you can get mediaId's from the linkPicker dialogservice 2014-04-15 18:07:40 +02:00
Shannon dcac5d4709 More code and tests written for deep cloning. 2014-04-15 20:31:32 +10:00
Shannon 0e4e12d0ba More code and tests written for deep cloning. 2014-04-15 19:12:42 +10:00
Shannon 9118701669 More test written for deep cloning. 2014-04-15 14:53:19 +10:00
Shannon 58758e7a41 More work on deep cloning, have test passing for IContent 2014-04-15 13:52:49 +10:00
curiosoelbicho 1eaf02b221 fix for: U4-4696. Macro personalized cache with custom membership provider not working 2014-04-14 21:39:31 -03:00
Shannon 5697809ce9 Merge branch '7.1.2' of https://github.com/umbraco/Umbraco-CMS into 7.1.2 2014-04-14 18:33:04 +10:00
Shannon 4f5cae55c2 Fixes: U4-4654 7.1.1 InsertMacroController unescapes objects to string 2014-04-14 18:32:28 +10:00
Sebastiaan Janssen e5b4769109 Remove test code 2014-04-14 09:27:25 +02:00
Shannon 5990a95d13 Fixes: U4-4610 Unmapped members in Automapper 2014-04-14 15:20:02 +10:00
per ploug e3c4ed5bf7 Changes grunt to accept a buildversion param
use grunt build --buildversion=7.1.2 to set it in all client files
2014-04-10 14:25:26 +02:00
Sebastiaan Janssen 02a4c2f4fc Update for WebPI 2014-04-09 09:35:02 +02:00
Sebastiaan Janssen b60aa3031c Post.cshtml shouldn't be there 2014-04-08 12:03:55 +02:00
Sebastiaan Janssen 2a0e3d803f Merge branch '7.1.1' of https://github.com/umbraco/Umbraco-CMS into 7.1.1 2014-04-08 11:37:50 +02:00
Sebastiaan Janssen 670a67225a Upgrade to Json.Net 6.0.2 2014-04-08 11:37:40 +02:00
perploug 0bedf09f48 Fixes: U4-4609 v7.1 Media Picker datatype only allows selection of images not PDFs 2014-04-08 11:34:42 +02:00
perploug 41ad18deef Removes autocomplete from installer password field 2014-04-08 11:07:23 +02:00
perploug 4745be4765 Fixes missing listview icons 2014-04-08 11:07:02 +02:00
perploug 13891bb033 Merge branch '7.1.1' of https://github.com/umbraco/Umbraco-CMS into 7.1.1 2014-04-07 16:08:45 +02:00
perploug a2efd7ab53 Fixes: U4-4619 Make sure installer pings stats 2014-04-07 16:08:34 +02:00
Sebastiaan Janssen 3c204da150 Spelling error 2014-04-07 16:05:21 +02:00
Sebastiaan Janssen ab7371e146 Bump version number 2014-04-07 14:29:59 +02:00
Sebastiaan Janssen 0f5c79afbc Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 7.1.1 2014-04-07 13:02:56 +02:00
Sebastiaan Janssen 4a516f7da9 Manually applying PR #347 2014-04-07 13:01:43 +02:00
Sebastiaan Janssen fcb080658d Reverting 221bfa5f3d so that views are found in partials again
Tested creating/editing members with custom properties in combination with our snippets and
that seems to work fine now, so not sure what this was supposed to fix.
Fixes U4-4604 Surface Controller functionality changed in 7.1 breaking site
2014-04-07 12:16:45 +02:00
Aaron Powell f45edbe2fe U4-4629 - Detecting existing macros
By setting the ID of the macro the repository layer will update the existing instance rather than trying to create a new one, which would result in a duplicate alias and that violates a table index.
2014-04-07 18:10:09 +10:00
perploug 08d74e3320 Tiny tweak more 2014-04-03 14:01:25 +02:00
perploug 98fd75b55d Updating user screen on the installer 2014-04-03 13:52:18 +02:00
perploug e7da70e076 Merge branch '7.1.0' of https://github.com/umbraco/Umbraco-CMS into 7.1.0 2014-04-03 11:52:01 +02:00
perploug 200cec0e23 Hardcodes starterkit guid into the installer
This way we can change it remotely to another package instead of relying
on just getting the first guid in the collection of kits
2014-04-03 11:51:51 +02:00
perploug 807778a737 Fixes: U4-4592 U7.1 - You can trigger a lot "Unsaved changes" bars 2014-04-03 11:50:50 +02:00
Sebastiaan Janssen 66d61c9d20 One more ImageProcessor update 2014-04-03 11:29:13 +02:00
Sebastiaan Janssen ecae5a856a Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 7.1.0
Conflicts:
	src/Umbraco.Core/Services/IRelationService.cs
	src/Umbraco.Web/Models/PublishedProperty.cs
	src/Umbraco.Web/PublishedCache/MemberPublishedContent.cs
2014-04-03 11:13:13 +02:00
Sebastiaan Janssen bf8add4f8d Manually picked up PR #343 2014-04-03 11:10:43 +02:00
perploug 256fa3385a Merge branch '7.1.0' of https://github.com/umbraco/Umbraco-CMS into 7.1.0 2014-04-03 09:31:47 +02:00
perploug ebaa46b2fc Fixes: U4-4212 Insert Image in RTE not resizing image 2014-04-03 09:31:32 +02:00
Sebastiaan Janssen e207185d51 Merge branch '7.1.0' of https://github.com/umbraco/Umbraco-CMS into 7.1.0 2014-04-03 09:30:12 +02:00
Sebastiaan Janssen 5efc45a7dd Bump version number 2014-04-03 09:29:52 +02:00
Sebastiaan Janssen c3fc27565d Update version of ImageProcessor and refer to NuGet in the csproj instead of the bin (!) 2014-04-03 09:26:51 +02:00
Sebastiaan Janssen 0af3f9dce0 Fixes U4-4278 Multiple RadioButtonList on one Document
Manually applying pull request as it's a bit faster to copy&paste instead of resolve merge conflicts
2014-04-03 08:55:19 +02:00
perploug 426b02b08a Sets zoom throttle to 100 instead of 300
To limit the number of re-calculations, but still keep it somewhat
fluent
2014-04-03 00:41:27 +02:00
perploug a4e23ef82b Missing files in last commit 2014-04-03 00:40:36 +02:00
perploug d0c6c4aafa Fixes: U4-4332 MediaPicker - Typealias is hardcode several places 2014-04-03 00:37:59 +02:00
perploug 3ea7e6fb8a Partially fixes: U4-4479 Cropper preview in backoffice is a bit off from the actual crop
Makes the cropper card UI reset on save, ensuring changes populate
2014-04-02 23:04:37 +02:00
Stephan 9940b78a57 U4-4575 - fix 8371105 2014-04-02 17:00:24 +02:00
Stephan 8371105c10 U4-4575 - property converters use wrong source value 2014-04-02 16:00:46 +02:00
perploug d4b0f3c570 Resizing safeguards to ensure we only return positive 2014-04-02 14:21:40 +02:00
perploug 29416320d2 Fixes failing macrospec tests
doooh, it referenced marcoParamsDictionary - instead of
macroParamsDictionary - whats up with that Marco guy?
2014-04-02 13:43:03 +02:00
perploug d11eb485e1 Merge branch '7.1.0' of https://github.com/umbraco/Umbraco-CMS into 7.1.0 2014-04-02 13:19:41 +02:00
perploug 300bd3bed4 Fixes: U4-4558 U7 Macro Parameter Editors needs some love!
Adds some config to the media picker and fixes thumbnail issues
2014-04-02 13:19:26 +02:00
Sebastiaan Janssen 3ca5443350 Merge branch '7.1.0' of https://github.com/umbraco/Umbraco-CMS into 7.1.0 2014-04-02 12:02:29 +02:00
Sebastiaan Janssen f6d56f51d4 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 7.1.0
Conflicts:
	src/Umbraco.Core/Services/IRelationService.cs
	src/Umbraco.Web/Controllers/UmbRegisterController.cs
2014-04-02 12:01:55 +02:00
Sebastiaan Janssen 53c0bd6938 Fixes: Password is not saved when using the Register snippet 2014-04-02 11:59:16 +02:00
perploug 174aa9f4ad Fixes: U4-4581 Hotkey - Click on disabled element 2014-04-02 11:51:56 +02:00
Sebastiaan Janssen a768fe5bb3 Ports behaviour from membershiphelper from v7 to 6 to make them the same 2014-04-02 11:42:48 +02:00
Sebastiaan Janssen d9c66cd4b3 Adds AddRelation and missing events in RelationService from v7 into v6 2014-04-02 11:41:59 +02:00
Stephan 6d3e8e1f6d U4-4559 - tests 2014-04-02 11:40:05 +02:00
Stephan b6185b847f U4-4575 - property converters use wrong source value 2014-04-02 11:39:53 +02:00
perploug c8877d0a2c Fixes failing dropdown prop editor tests 2014-04-02 11:35:23 +02:00
perploug 891810b045 Adds newsletter to installer
With the good ol' V6 installer code, ahhh the smell of code patina
2014-04-02 11:20:35 +02:00
Sebastiaan Janssen 77d910b6b6 We don't really need to scream greetings to people who try to use the member picker 2014-04-01 19:14:42 +02:00
Sebastiaan Janssen 47044b3a77 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 7.1.0 2014-04-01 16:46:43 +02:00
Sebastiaan Janssen 5b693f9310 Adds ability to add/remove a single role to/from a single member, which is much nicer than having to instantiate arrays 2014-04-01 16:43:11 +02:00
Sebastiaan Janssen 40ebc1295c Fixes error thrown when saving password and actually using the Umbraco membership provider 2014-04-01 15:30:42 +02:00
Sebastiaan Janssen b769b224c2 Fixes error thrown when saving password and actually using the Umbraco membership provider 2014-04-01 15:29:16 +02:00
Sebastiaan Janssen 89efe40f41 Merge remote-tracking branch 'origin/6.2.0' into 7.1.0 2014-04-01 14:27:47 +02:00
Sebastiaan Janssen 51660d918c Assembly redirect seems to help a lot installing NuGet pkg, should finally be able to close U4-4510 nuget targets file creates an invalid path in the property group 2014-04-01 14:22:13 +02:00
Sebastiaan Janssen ea7b053106 Merge pull request #340 from leekelleher/U4-4550
Fixes: U4-4550 Media Picker preview with transparent images
2014-04-01 13:06:58 +02:00
Sebastiaan Janssen 3e17201ce7 Merge remote-tracking branch 'origin/6.2.0' into 7.1.0 2014-04-01 11:59:26 +02:00
Sebastiaan Janssen 1f03983628 Clean up belle/build folder when building with build.bat to make sure it's pristine 2014-04-01 11:54:25 +02:00
Sebastiaan Janssen 15aa6fc4b8 Fixed U4-4576 7.0.4 : InternalMemberSearcher config incorrectly uses 'enableLeadingWildcards', should be 'enableLeadingWildcard' 2014-04-01 11:53:56 +02:00
Sebastiaan Janssen 41e8a9ef2d Fixed U4-4576 7.0.4 : InternalMemberSearcher config incorrectly uses 'enableLeadingWildcards', should be 'enableLeadingWildcard' 2014-04-01 11:51:51 +02:00
perploug a492976a32 Fixes: U4-4557 Color Picker - default is black, but it can't be added without choosing another color first
Sets color to be black by default, so will be added if you click add
without setting anything, so its consistent with the default swatch
2014-04-01 10:08:50 +02:00
perploug 88e09f9077 Merge branch '7.1.0' of https://github.com/umbraco/Umbraco-CMS into 7.1.0 2014-04-01 10:02:23 +02:00
perploug 65a1709bd3 Fixes: U4-4537 Macro Textbox parameter in RTE Encoding issue 2014-04-01 10:02:10 +02:00
Sebastiaan Janssen 6478a8424a Fixes test, additional Tag mapper requires count to be updated 2014-04-01 09:11:07 +02:00
leekelleher 55ade4e491 Replaced solid/semi-transparent background, with a checkered background image. 2014-03-31 22:45:35 +01:00
Stephan a767aa9f3a Merge pull request #342 from kipusoep/7.1.0
Changed $('#form1') usage to $('form')
2014-03-31 18:19:29 +02:00
Sebastiaan Janssen 50321e5936 Merge pull request #336 from bjarnef/7.1.0_-_U4-4026
Fix for U4-4026 Inline styling affect header text
2014-03-31 17:32:50 +02:00
perploug 1321702d19 Fixes: U4-3649 Bottom button bar gradient overlaps last field
Temp fix, as we will likely refactor or editor directives before
building more core editors
2014-03-31 13:24:30 +02:00
perploug 005ff2f830 Merge branch '7.1.0' of https://github.com/umbraco/Umbraco-CMS into 7.1.0 2014-03-31 13:17:27 +02:00
perploug dff3fde840 Fixes: U4-4553 7.1 Template drop down has values but is blank
patches the it on the clientside for now, longerterm solution is to have
templates being returned as prevalues, but will leave that to shannon as
there could be other things accidentally being poked doing that.
2014-03-31 13:17:15 +02:00
Sebastiaan Janssen 44504ff6af Fixes summary for the TagMapper 2014-03-31 12:59:28 +02:00
Sebastiaan Janssen 25d3389759 Merge pull request #341 from robertjf/7.1.0
Fixes #U4-4544 Issue: TagService.GetAllTags(group) throws Exception in MappingResolver
2014-03-31 12:57:51 +02:00
Robert Foster 3f97c74712 removed commented out code 2014-03-31 22:00:54 +11:00
perploug 1152b61fb0 7.1 login greetings update 2014-03-31 12:43:05 +02:00
perploug b1842de045 Merge branch '7.1.0' of https://github.com/umbraco/Umbraco-CMS into 7.1.0 2014-03-31 12:37:26 +02:00
perploug 750a2862ee Fixes: U4-4562 Images and markdown editor 2014-03-31 12:37:08 +02:00
perploug 7632075df4 Fixes: U4-4536 Tree points to wrong views after install 2014-03-31 12:29:44 +02:00
perploug aa75cd4ea8 Fixes: U4-4549 Related Links "New Window" checkbox has css "display: none" 2014-03-31 12:28:56 +02:00
Sebastiaan Janssen 06827bd7a5 Merge pull request #338 from vnbaaij/7.1.0
Solution for  U4-4548
2014-03-31 11:57:13 +02:00
Stefan Kip 9a82ab7d4a Changed $('#form1') usage to $('form')
I'm having an issue with v6.1.6 where the form's id is 'aspnetForm' instead of 'form1', I don't know why.
Using $('form') is much safer than using $('#form1').
2014-03-31 09:56:16 +02:00
Robert Foster b1037d1936 Added a TagMapper class to resolve ITag back to TagDto. 2014-03-30 19:07:35 +11:00
leekelleher ccdc3a1eab Fixes: U4-4550 Media Picker preview with transparent images 2014-03-28 16:59:34 +00:00
leekelleher 655d629621 Rebased web.Template.config - reapplied the whitespace fixes. 2014-03-28 16:31:03 +00:00
leekelleher c8e0fedce4 Made the whitespace consistent in config files.
This may ease the frustration of web-developers doing upgrades.
2014-03-28 16:25:01 +00:00
Vincent Baaij a47387fec0 Solution for U4-4548 2014-03-28 16:03:51 +01:00
perploug c29d08c915 Fixes: U4-4489 7.1 RC, warn about changes partially overlays breadcrumb 2014-03-28 11:00:29 +01:00
perploug b8f796eb2c Fixes: U4-4532 Unable to insert Image in TinyMCE when Image property 'umbracoFile' is changed from type 'Upload' to the new 'Image Cropper' 2014-03-28 10:39:24 +01:00
Shannon b9088c9ac0 fixes build 2014-03-28 08:51:25 +11:00
Shannon 7a8f8ac0fe Merge remote-tracking branch 'origin/6.2.0' into 7.1.0 2014-03-28 08:31:52 +11:00
Shannon 49cf0f98ce U4-1752 - Add GetPreValueAsString(id) method to the @Umbraco helper 2014-03-28 08:31:21 +11:00
Shandem 22ffa86e18 Merge pull request #301 from Jeavon/U4-1752
U4-1752 - Add GetPreValueAsString(id) method to the @Umbraco helper
2014-03-28 08:21:32 +11:00
perploug c4e2d98138 U4-4532 Unable to insert Image in TinyMCE when Image property 'umbracoFile' is changed from type 'Upload' to the new 'Image Cropper'
Replaces the old media api with the resolveFile helper methods
2014-03-27 02:46:32 -07:00
Shannon c01211c62d Merge remote-tracking branch 'origin/6.2.0' into 7.1.0
Conflicts:
	src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/moveOrCopy.aspx.cs
2014-03-27 17:28:46 +11:00
Shannon d8a3e00440 Fixes: U4-2843 Copying Document Type when Selecting Master Doesn't Work (Master ignored), U4-3552 Copy nested document type is failing 2014-03-27 17:26:55 +11:00
Shannon 264c537b50 Fixes: U4-4530 Edit Profile Snippet: Check for null before loop 2014-03-27 16:52:43 +11:00
Shannon f26c61d736 renames file 2014-03-27 16:43:34 +11:00
Shannon 43f647fd94 Fixes U4-4531 dialogService.macroPicker callback wrong property name 2014-03-27 16:43:20 +11:00
Shannon cc0bcc2d59 Fixes unit tests 2014-03-27 16:27:57 +11:00
Shannon 1b23540b87 Merge remote-tracking branch 'origin/6.2.0' into 7.1.0
Conflicts:
	src/Umbraco.Web/Cache/DistributedCache.cs
2014-03-27 16:12:37 +11:00
Shannon c309e18f13 Fixes: U4-459 Public Access permissions not set on distributed servers 2014-03-27 16:11:34 +11:00
Shannon dec60885b4 Fixes more thread safety issues with Access.cs 2014-03-27 15:50:56 +11:00
Shannon eee09ec45b Completes: U4-459 Public Access permissions not set on distributed servers 2014-03-27 14:43:07 +11:00
Shannon b4daab2856 started fixing: U4-459 Public Access permissions not set on distributed servers but have commented that code out for now because it will cause problem in some LB scenarios. 2014-03-27 14:28:45 +11:00
Shannon fdfbad254d Fixes some very badly handled threading issues with the Access (public access) class 2014-03-27 14:28:12 +11:00
bjarnef 0c6e766030 Fix for U4-4026 Inline styling affect header text
Inline styling on container affect header text and dropdown with
text-align:center on language in settings section.
2014-03-27 02:42:21 +01:00
Shannon 7444363cef adds another null check to the other TranslateItem method 2014-03-27 08:13:05 +11:00
Shandem a82097b92b Merge pull request #334 from Jeavon/U4-4527
Fix for U4-4527 U7 - Creating initial Folder in media section causes exc...
2014-03-27 08:05:56 +11:00
Jeavon Leopold 07934161a4 Fix for U4-4527 U7 - Creating initial Folder in media section causes exception 2014-03-26 10:07:20 +00:00
Shandem 9194030a9a Merge pull request #333 from Nicholas-Westby/7.1.0
Replaced "retreive" with "retrieve".
2014-03-26 17:45:03 +11:00
Shannon 1cbaace777 Merge remote-tracking branch 'origin/6.2.0' into 7.1.0
Conflicts:
	build/Build.proj
	build/NuSpecs/UmbracoCms.Core.nuspec
	build/NuSpecs/build/UmbracoCms.targets
	build/NuSpecs/tools/install.ps1
	src/Umbraco.Web.UI/umbraco_client/Editors/EditScript.js
2014-03-26 15:06:03 +11:00
Nicholas-Westby ef5052324b Replaced "retreive" with "retrieve". 2014-03-25 20:49:52 -07:00
Nicholas-Westby 204a8d813c Replaced "retreive" with "retrieve". 2014-03-25 20:48:05 -07:00
Nicholas-Westby 8009cb3892 Replaced "retreive" with "retrieve". 2014-03-25 20:46:23 -07:00
Nicholas-Westby 284d168cd7 Replaced "retreive" with "retrieve". 2014-03-25 20:45:28 -07:00
Nicholas-Westby fdd025aefd Replaced "retreive" with "retrieve". 2014-03-25 20:44:47 -07:00
Nicholas-Westby e36d4768e1 Replaced "retreive" with "retrieve". 2014-03-25 20:44:08 -07:00
Nicholas-Westby df2047e8f8 Replaced "retreive" with "retrieve". 2014-03-25 20:43:32 -07:00
Nicholas-Westby d9280d5238 Replaced "retreive" with "retrieve". 2014-03-25 20:42:29 -07:00
Nicholas-Westby 388249f500 Replaced "retreive" with "retrieve". 2014-03-25 20:41:32 -07:00
Nicholas-Westby a08b75592e Replaced "retreive" with "retrieve". 2014-03-25 20:40:44 -07:00
Nicholas-Westby 38ea6dfbfe Replaced "retreive" with "retrieve". 2014-03-25 20:39:45 -07:00
Nicholas-Westby 39ccde221a Replaced "retreive" with "retrieve". 2014-03-25 20:38:58 -07:00
Nicholas-Westby 17b6366ea3 Replaced "retreive" with "retrieve". 2014-03-25 20:37:20 -07:00
Nicholas-Westby 3d6a608b12 Replaced "retreive" with "retrieve". 2014-03-25 20:36:46 -07:00
Nicholas-Westby 851f58df9c Replaced "retreive" with "retrieve". 2014-03-25 20:35:36 -07:00
Nicholas-Westby 0ff0cc6366 Replaced "retreive" with "retrieve". 2014-03-25 20:34:44 -07:00
Nicholas-Westby 08004ecc68 Replaced "retreive" with "retrieve". 2014-03-25 20:33:59 -07:00
Nicholas-Westby 4a2544d0e6 Replaced "retreive" with "retrieve". 2014-03-25 20:32:39 -07:00
Nicholas-Westby bace1cce74 Replaced "retreive" with "retrieve". 2014-03-25 20:31:31 -07:00
Nicholas-Westby acc88e25d8 Replaced "retreive" with "retrieve". 2014-03-25 20:30:17 -07:00
Nicholas-Westby 2a1a16d478 Replaced "retreive" with "retrieve". 2014-03-25 20:28:47 -07:00
Nicholas-Westby a5afb8ed19 Replaced "retreive" with "retrieve". 2014-03-25 20:27:57 -07:00
Nicholas-Westby d02678e05c Replaced "retreive" with "retrieve". 2014-03-25 20:26:58 -07:00
Nicholas-Westby 9e0bbd3c99 Replaced "retreive" with "retrieve". 2014-03-25 20:26:06 -07:00
Nicholas-Westby 539efcc669 Replaced "retreive" with "retrieve". 2014-03-25 20:25:24 -07:00
Nicholas-Westby d0d9d85151 Replaced "retreive" with "retrieve". 2014-03-25 20:24:27 -07:00
Nicholas-Westby ffa307613c Replaced "retreive" with "retrieve". 2014-03-25 20:23:36 -07:00
Nicholas-Westby 19ea6d6005 Replaced "retreive" with "retrieve". 2014-03-25 20:22:34 -07:00
Nicholas-Westby 155b1737d3 Replaced "retreive" with "retrieve". 2014-03-25 20:20:51 -07:00
Nicholas-Westby b66253f33e Replaced "retreive" with "retrieve". 2014-03-25 20:19:50 -07:00
Nicholas-Westby bcbadfe648 Replaced "retreive" with "retrieve". 2014-03-25 20:19:12 -07:00
Nicholas-Westby 3325b06873 Replaced "retreive" with "retrieve". 2014-03-25 20:18:30 -07:00
Nicholas-Westby 852914bf6b Replaced "retreive" with "retrieve". 2014-03-25 20:17:55 -07:00
Nicholas-Westby 3e14807370 Replaced "retreive" with "retrieve". 2014-03-25 20:17:18 -07:00
Nicholas-Westby e44cb6708d Replaced "retreive" with "retrieve". 2014-03-25 20:16:31 -07:00
Nicholas-Westby fd43b27d00 Replaced "retreive" with "retrieve". 2014-03-25 20:15:34 -07:00
Nicholas-Westby 524f113611 Replaced "retreive" with "retrieve". 2014-03-25 20:14:54 -07:00
Nicholas-Westby 04dcf50218 Replaced "retreive" with "retrieve". 2014-03-25 20:14:23 -07:00
Nicholas-Westby 2b497deaa3 Replaced "retreive" with "retrieve". 2014-03-25 20:13:30 -07:00
Nicholas-Westby dbe2f8ea37 Replaced "retreive" with "retrieve". 2014-03-25 20:12:50 -07:00
Nicholas-Westby 7dc0239ad1 Replaced "retreive" with "retrieve". 2014-03-25 20:11:46 -07:00
Nicholas-Westby 72fdc5f472 Replaced "retreive" with "retrieve". 2014-03-25 20:10:34 -07:00
Shannon cde3c42cec Fixes: U4-4455 Javascript error with single quotes in literals
Conflicts:
	src/Umbraco.Web.UI/umbraco_client/Editors/EditScript.js
2014-03-26 13:34:26 +11:00
Shannon 10b544abb9 Fixes: U4-4455 Javascript error with single quotes in literals 2014-03-26 13:31:15 +11:00
Shannon 88aecdf672 fixes U4-4517 Color picker not showing colors 2014-03-26 13:07:07 +11:00
Shannon ad95736eaa Fixes issues relating to adding ability to sort pre-values, had to update all property editors that use the shared sortable pre-values, ensure the list items are an array and then sorted. 2014-03-26 13:01:53 +11:00
Shannon 34a21a78a0 Merge branch '7.1.0' of https://github.com/umbraco/Umbraco-CMS into 7.1.0 2014-03-26 11:23:58 +11:00
Shannon 1e01c2669f fixes missing semi-colon 2014-03-26 11:23:48 +11:00
Shandem d3a7389b89 Fixes file name casing 2014-03-26 11:21:31 +11:00
Shandem bc8b6c4bea Fixes file name casing 2014-03-26 11:21:08 +11:00
Shandem 3953a48a3b Merge pull request #332 from arknu/7.1_U4-3744
U4-3744: Make it possible to make individual selections while still selecting the entire text on first click
2014-03-26 11:08:50 +11:00
Shannon 2f44e94bd0 Merge branch '7.1.0' of https://github.com/umbraco/Umbraco-CMS into 7.1.0 2014-03-26 11:00:46 +11:00
Shannon 5eeb8d7df6 Fixes: U4-4520 Issue: MultipleTextStringValueConverter returns an empty string array due to mismatched XML value format 2014-03-26 11:00:32 +11:00
arknu 231f23cc6e Cleaned up the code a bit 2014-03-25 22:26:05 +01:00
Sebastiaan Janssen 3235678d29 U4-4510 nuget targets file creates an invalid path in the property group
That should fix this one properly now
2014-03-25 20:40:44 +01:00
Sebastiaan Janssen f13ddddc16 U4-4510 nuget targets file creates an invalid path in the property group
That should fix this one properly now
2014-03-25 20:39:46 +01:00
arknu 490c346fcf U4-3744: Make it possible to make individual selections while still selecting the entire text on first click 2014-03-25 19:34:19 +01:00
Shannon 8f1d8419a0 Merge remote-tracking branch 'origin/6.2.0' into 7.1.0
Conflicts:
	build/NuSpecs/build/net40/UmbracoCms.targets
	build/NuSpecs/build/net45/UmbracoCms.targets
	build/NuSpecs/build/net451/UmbracoCms.targets
	src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml
2014-03-25 15:47:57 +11:00
Shannon be8320bb4b fixes some compatibility issues with PR for sortable pre-vals 2014-03-25 14:14:09 +11:00
Shannon 1d4b6178e5 Merge branch 'wip-u4-3951' of https://github.com/AndyButland/Umbraco-CMS into AndyButland-wip-u4-3951
Conflicts:
	src/Umbraco.Web.UI.Client/src/views/prevalueeditors/multivalues.html
2014-03-25 13:31:21 +11:00
Shannon 3427f596e3 fixes up a few notes. 2014-03-25 13:07:16 +11:00
Shannon c31ea7409f Merge branch 'fix-u4-3839' of https://github.com/lars-erik/Umbraco-CMS into lars-erik-fix-u4-3839 2014-03-25 12:47:26 +11:00
Shannon f88e60bcb5 Fixes: U4-3481 Adding Scripting Files and Partial View Macro File with the same name and 'create macro' selected fails. 2014-03-25 12:16:27 +11:00
Shannon c81919e269 Merge branch '7.1.0' of https://github.com/umbraco/Umbraco-CMS into 7.1.0 2014-03-25 11:45:57 +11:00
Shannon c936aaa517 Fixes: U4-3845 v7.0.0 keepUserLoggedIn issue 2014-03-25 11:45:38 +11:00
Shandem b8f88e0459 Merge pull request #330 from Jeavon/7.1.0-ImageCropper-JeavonWIP
7.1.0 image cropper - removal of lots of duplicated code, fixes for various param options and some further unit tests
2014-03-25 10:47:09 +11:00
Shannon 1628ac917c Merge branch '7.1.0' of https://github.com/umbraco/Umbraco-CMS into 7.1.0 2014-03-25 10:45:14 +11:00
Shannon ab586a49ce Fixes: U4-4508 Save causes content to vanish in IE 2014-03-25 10:44:55 +11:00
Jeavon Leopold ff2ee540e2 Fixing the CacheBusting on GetCropUrl as it was totally random which meant the server cache was creating a new cache file for every request. Now changed it to use item updateDate.ToFileTimeUtc as the cache busting value so it will change only when the item is updated in Umbraco. 2014-03-24 19:27:00 +00:00
Jeavon Leopold b450299d45 GetCropUrl - moved propertyAlias and cropAlias to after width and height so that GetCropUrl(100,100,"myProperty") is possible and renamed useFocalPoint to preferFocalPoint 2014-03-24 18:37:15 +00:00
Jeavon Leopold 0ebe535922 ImageCropDataSet - a little bit of Stylecop 2014-03-24 17:58:12 +00:00
Jeavon Leopold f5f8fe7b42 GetCropUrl - Stylecop and an additional test 2014-03-24 17:51:52 +00:00
Jeavon Leopold f51a66b728 GetCropUrl - further code duplication removal and 2 new unit tests 2014-03-24 16:32:50 +00:00
Sebastiaan Janssen f8a7b453c7 Sync the en and en_us translations 2014-03-24 17:26:04 +01:00
Sebastiaan Janssen 89235f707c Sync the en and en_us translations 2014-03-24 17:25:31 +01:00
Jeavon Leopold 550166c41b Removing HasPropertyAndValueAndCrop method as it's no longer needed 2014-03-24 15:49:04 +00:00
Jeavon Leopold 40be3957f6 GetCropUrl - ensuring that GetCropUrl(width,height) works and also adding the useFocalPoint parameter 2014-03-24 15:44:04 +00:00
Sebastiaan Janssen 6ccce4d914 U4-4515 GenericProperty.ascx.cs references non-existent lblAlias control, causing YSOD of death when editing certain document types
Whoops, missed some references
2014-03-24 16:01:47 +01:00
Sebastiaan Janssen 14ea374b24 Also removing stray semicolons here for U4-4510 nuget targets file creates an invalid path in the property group 2014-03-24 15:44:09 +01:00
Sebastiaan Janssen 4d49268c47 U4-4515 GenericProperty.ascx.cs references non-existent lblAlias control, causing YSOD of death when editing certain document types
Codebehind file somehow got out of sync
2014-03-24 15:16:57 +01:00
Sebastiaan Janssen a569796adb Removes stray semicolons from the nuget targets files 2014-03-24 14:00:12 +01:00
Jeavon Leopold 59de0613f5 GetCropUrl - Removing duplicate code 2014-03-24 11:43:55 +00:00
Sebastiaan Janssen 8391c32886 Fix whitespace 2014-03-24 09:34:48 +01:00
Sebastiaan Janssen bf2efd30e9 U4-4073 Audit Trail is missing from action menu
Removed the icons for now as they are missing and should be new style icons anyway
2014-03-24 09:34:47 +01:00
Shannon 187373132f Completes: U4-4154 convert existing property data from XML to JSON during upgrade v6 - 7 2014-03-24 18:44:18 +11:00
Shannon 79584a9cf9 Fixes thread safety issue with RichTextPreValueController 2014-03-24 16:32:42 +11:00
Shannon 96fa8c7dc9 Publicizes a few things, including the fix for U4-3981 Make Umbraco.Web.WebApi.Filters.UmbracoApplicationAuthorizeAttribute public 2014-03-24 15:41:46 +11:00
Shannon 5e43ddc13c Fixes: U4-4502 Umbraco7.0.4 media picker shows uploaded images minus 1 2014-03-24 13:43:20 +11:00
Shannon 98f76a989f Adds better error handling for the media picker - we were not detecting image types before and were getting loads of server errors. Fixes up some method return calls 2014-03-24 12:38:49 +11:00
Shannon 2e8993adb8 Merge remote-tracking branch 'origin/6.2.0' into 7.1.0
Conflicts:
	build/NuSpecs/build/net40/UmbracoCms.targets
	build/NuSpecs/build/net45/UmbracoCms.targets
	build/NuSpecs/build/net451/UmbracoCms.targets
	build/NuSpecs/tools/Readme.txt
	build/NuSpecs/tools/install.ps1
	src/Umbraco.Web/umbraco.presentation/umbraco/members/EditMember.aspx.cs
2014-03-24 11:31:52 +11:00
Shannon 81600f0f3c Merge branch 'patch-2' of https://github.com/designagencytom/Umbraco-CMS into designagencytom-patch-2
Conflicts:
	src/Umbraco.Web/umbraco.presentation/umbraco/members/EditMember.aspx.cs
2014-03-24 11:18:11 +11:00
Shannon 74ccd79408 Merge branch 'patch-1' of https://github.com/designagencytom/Umbraco-CMS into designagencytom-patch-1 2014-03-24 11:13:07 +11:00
Shandem 3e0a754dc0 Merge pull request #328 from arjanpot/7.1.0
CropUrl should be formatted with InvariantCulture.
2014-03-24 11:04:59 +11:00
Sebastiaan Janssen 006a89e136 U4-4498 Doc & Media Type, Server Error when upgrade, 7.0.4 to 7.1.0 RC via Nuget
Have to copy in the Umbraco and Umbraco_Client folder during NuGet updates as well.
2014-03-23 16:10:58 +01:00
Sebastiaan Janssen 29dbbee173 Imageprocessor config files are no longer required and shouldn't ship with Umbraco 2014-03-23 15:02:54 +01:00
arjanpot cd31637371 CropUrl should be formatted with InvariantCulture. 2014-03-22 11:22:01 +01:00
perploug ab70c98d4c Ensures the config is cleared properly every time 2014-03-20 09:41:30 -07:00
Sebastiaan Janssen 424ff02734 Forgot a few includes, fixed! 2014-03-20 17:29:16 +01:00
Sebastiaan Janssen 80bd8d962b Make sure the App_Plugins folder is there 2014-03-20 16:58:35 +01:00
Sebastiaan Janssen 956364decd v7 NuGet changes also apply to v6 2014-03-20 16:02:24 +01:00
designagencytom 6133e8f8c2 Update loadMemberGroups.cs
Sort the roles alphabetically to make it easier to manage the list when it becomes very large.
2014-03-20 13:02:25 +00:00
Jeavon Leopold b048ae4d36 U4-1752 - Add GetPreValueAsString(id) method to the @Umbraco helper 2014-02-21 10:17:29 +00:00
Shannon b7f7775b89 adds initial commit of entity cloning 2014-02-20 22:34:54 +11:00
Lars-Erik Aabech 6eeb9d6af4 Forgot document type on general properties tab 2014-01-07 18:53:47 +01:00
Lars-Erik Aabech cbefabb724 Changed TabsAndPropertyResolver's translation mechanism to use CultureDictionaryFactory. Also added translation to ContentTypeController.GetAllowedChildren. Localization "complete" and working for content editing. 2014-01-07 17:44:01 +01:00
Lars-Erik Aabech f7f6cc64ce More or less fixes content localization. Must do more tests and fix create dialog. Only tested manually on my box. 2014-01-07 16:43:03 +01:00
Lars-Erik Aabech 1408e4f64e DictionaryRepository now excludes translations with missing language. Should've committed a test to prove that TabsAndPropertiesResolver.TranslateTab uncommented fails, but can't find a nice existing fixture, so just debugging to see if it works now. 2014-01-07 16:15:59 +01:00
Lars-Erik Aabech 0a68d2f4ee Language repo now returns null for non-existing ids, making Get_WhenIdDoesntExist_ReturnsNull pass. 2014-01-07 16:03:26 +01:00
Lars-Erik Aabech 11a4a0436d Proves LanguageRepository lines 37-38 to be useless, but probably intended 2014-01-07 15:55:49 +01:00
Lars-Erik Aabech 2583800b2c Proves dictionary repository fails to get when weird 0 languageid dictionary item exists. 2014-01-07 15:53:17 +01:00
477 changed files with 12219 additions and 4680 deletions
+2 -1
View File
@@ -108,4 +108,5 @@ 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/*
build/ApiDocs/Output/*
src/Umbraco.Web.UI.Client/bower_components/*
+9 -5
View File
@@ -1,6 +1,6 @@
@ECHO OFF
SET release=7.1.0
SET comment=RC
SET release=7.1.2
SET comment=
SET version=%release%
IF [%comment%] EQU [] (SET version=%release%) ELSE (SET version=%release%-%comment%)
@@ -12,6 +12,9 @@ ECHO Installing the Microsoft.Bcl.Build package before anything else, otherwise
SET nuGetFolder=%CD%\..\src\packages\
..\src\.nuget\NuGet.exe install ..\src\Umbraco.Web.UI\packages.config -OutputDirectory %nuGetFolder%
ECHO Removing the belle build folder to make sure everything is clean as a whistle
RD ..\src\Umbraco.Web.UI.Client\build /Q /S
ECHO Performing MSBuild and producing Umbraco binaries zip files
%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe "Build.proj" /p:BUILD_RELEASE=%release% /p:BUILD_COMMENT=%comment%
@@ -30,11 +33,12 @@ echo This file is only here so that the containing folder will be included in th
ECHO Adding Web.config transform files to the NuGet package
ren .\_BuildOutput\WebApp\MacroScripts\Web.config Web.config.transform
ren .\_BuildOutput\WebApp\Views\Web.config Web.config.transform
ren .\_BuildOutput\WebApp\Xslt\Web.config Web.config.transform
ECHO Packing the NuGet release files
..\src\.nuget\NuGet.exe pack NuSpecs\UmbracoCms.Core.nuspec -Version %version%
..\src\.nuget\NuGet.exe pack NuSpecs\UmbracoCms.nuspec -Version %version%
..\src\.nuget\NuGet.exe Pack NuSpecs\UmbracoCms.Core.nuspec -Version %version%
..\src\.nuget\NuGet.exe Pack NuSpecs\UmbracoCms.nuspec -Version %version%
IF ERRORLEVEL 1 GOTO :showerror
GOTO :EOF
+11 -1
View File
@@ -310,7 +310,12 @@
</Target>
<Target Name="SetVersionNumber" Condition="'$(BUILD_RELEASE)'!=''">
<!-- Match & replace 3 and 4 digit version numbers and -beta (if it's there) -->
<PropertyGroup>
<NewVersion>$(BUILD_RELEASE)</NewVersion>
<NewVersion Condition="'$(BUILD_COMMENT)'!=''">$(BUILD_RELEASE)-$(BUILD_COMMENT)</NewVersion>
</PropertyGroup>
<!-- Match & replace 3 and 4 digit version numbers and -beta (if it's there) -->
<FileUpdate
Files="..\src\Umbraco.Core\Configuration\UmbracoVersion.cs"
Regex="(\d+)\.(\d+)\.(\d+)(.(\d+))?"
@@ -319,5 +324,10 @@
<FileUpdate Files="..\src\Umbraco.Core\Configuration\UmbracoVersion.cs"
Regex="CurrentComment { get { return &quot;([a-zA-Z]+)?&quot;"
ReplacementText="CurrentComment { get { return &quot;$(BUILD_COMMENT)&quot;"/>
<XmlPoke XmlInputPath=".\NuSpecs\build\UmbracoCms.targets"
Namespaces="&lt;Namespace Prefix='x' Uri='http://schemas.microsoft.com/developer/msbuild/2003' /&gt;"
Query="//x:UmbracoVersion"
Value="$(NewVersion)" />
</Target>
</Project>
+4 -1
View File
@@ -15,6 +15,8 @@ SET oldPath=%PATH%
path=%npmPath%;%nodePath%;%PATH%
ECHO %path%
SET buildFolder=%CD%
ECHO Change directory to %CD%\..\src\Umbraco.Web.UI.Client\
@@ -23,7 +25,8 @@ CD %CD%\..\src\Umbraco.Web.UI.Client\
ECHO Do npm install and the grunt build of Belle
call npm install
call npm install -g grunt-cli
call grunt build
call npm install -g bower
call grunt build --buildversion=7.1.2
ECHO Reset path to what it was before
path=%oldPath%
@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>UmbracoCms.Core.AllBinaries</id>
<version>6.1.2</version>
<title>Umbraco Cms Core All Binaries</title>
<authors>Morten Christensen</authors>
<owners>Umbraco HQ</owners>
<licenseUrl>http://umbraco.codeplex.com/license</licenseUrl>
<projectUrl>http://umbraco.com/</projectUrl>
<iconUrl>http://umbraco.com/media/357769/100px_transparent.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Contains the core assemblies and all of the dependant assemblies needed to run Umbraco Cms. This package only contains assemblies and can be used for package development. Use the UmbracoCms-package to setup Umbraco in Visual Studio as an ASP.NET project.</description>
<summary>Contains the core assemblies and all of the dependant assemblies needed to run Umbraco Cms</summary>
<language>en-US</language>
<tags>umbraco</tags>
</metadata>
<files>
<file src="..\_BuildOutput\bin\businesslogic.dll" target="lib\businesslogic.dll" />
<file src="..\_BuildOutput\bin\AutoMapper.dll" target="lib\AutoMapper.dll" />
<file src="..\_BuildOutput\bin\AutoMapper.Net4.dll" target="lib\AutoMapper.Net4.dll" />
<file src="..\_BuildOutput\bin\businesslogic.dll" target="lib\businesslogic.dll" />
<file src="..\_BuildOutput\bin\ClientDependency.Core.dll" target="lib\ClientDependency.Core.dll" />
<file src="..\_BuildOutput\bin\ClientDependency.Core.Mvc.dll" target="lib\ClientDependency.Core.Mvc.dll" />
<file src="..\_BuildOutput\bin\cms.dll" target="lib\cms.dll" />
<file src="..\_BuildOutput\bin\controls.dll" target="lib\controls.dll" />
<file src="..\_BuildOutput\bin\CookComputing.XmlRpcV2.dll" target="lib\CookComputing.XmlRpcV2.dll" />
<file src="..\_BuildOutput\bin\Examine.dll" target="lib\Examine.dll" />
<file src="..\_BuildOutput\bin\HtmlAgilityPack.dll" target="lib\HtmlAgilityPack.dll" />
<file src="..\_BuildOutput\bin\ICSharpCode.SharpZipLib.dll" target="lib\ICSharpCode.SharpZipLib.dll" />
<file src="..\_BuildOutput\bin\ImageProcessor.dll" target="lib\ImageProcessor.dll" />
<file src="..\_BuildOutput\bin\ImageProcessor.Web.dll" target="lib\ImageProcessor.Web.dll" />
<file src="..\_BuildOutput\bin\interfaces.dll" target="lib\interfaces.dll" />
<file src="..\_BuildOutput\bin\log4net.dll" target="lib\log4net.dll" />
<file src="..\_BuildOutput\bin\Lucene.Net.dll" target="lib\Lucene.Net.dll" />
<file src="..\_BuildOutput\bin\Microsoft.ApplicationBlocks.Data.dll" target="lib\Microsoft.ApplicationBlocks.Data.dll" />
<file src="..\_BuildOutput\bin\Microsoft.Threading.Tasks.dll" target="lib\Microsoft.Threading.Tasks.dll" />
<file src="..\_BuildOutput\bin\Microsoft.Threading.Tasks.Extensions.dll" target="lib\Microsoft.Threading.Tasks.Extensions.dll" />
<file src="..\_BuildOutput\bin\Microsoft.Web.Helpers.dll" target="lib\Microsoft.Web.Helpers.dll" />
<file src="..\_BuildOutput\bin\Microsoft.Web.Infrastructure.dll" target="lib\Microsoft.Web.Infrastructure.dll" />
<file src="..\_BuildOutput\bin\Microsoft.Web.Mvc.FixedDisplayModes.dll" target="lib\Microsoft.Web.Mvc.FixedDisplayModes.dll" />
<file src="..\_BuildOutput\bin\MiniProfiler.dll" target="lib\MiniProfiler.dll" />
<file src="..\_BuildOutput\bin\MySql.Data.dll" target="lib\MySql.Data.dll" />
<file src="..\_BuildOutput\bin\Newtonsoft.Json.dll" target="lib\Newtonsoft.Json.dll" />
<file src="..\_BuildOutput\bin\NuGet.Core.dll" target="lib\NuGet.Core.dll" />
<file src="..\_BuildOutput\bin\SQLCE4Umbraco.dll" target="lib\SQLCE4Umbraco.dll" />
<file src="..\_BuildOutput\bin\System.Data.SqlServerCe.dll" target="lib\System.Data.SqlServerCe.dll" />
<file src="..\_BuildOutput\bin\System.Data.SqlServerCe.Entity.dll" target="lib\System.Data.SqlServerCe.Entity.dll" />
<file src="..\_BuildOutput\bin\System.Net.Http.dll" target="lib\System.Net.Http.dll" />
<file src="..\_BuildOutput\bin\System.Net.Http.Extensions.dll" target="lib\System.Net.Http.Extensions.dll" />
<file src="..\_BuildOutput\bin\System.Net.Http.Formatting.dll" target="lib\System.Net.Http.Formatting.dll" />
<file src="..\_BuildOutput\bin\System.Net.Http.Primitives.dll" target="lib\System.Net.Http.Primitives.dll" />
<file src="..\_BuildOutput\bin\System.Net.Http.WebRequest.dll" target="lib\System.Net.Http.WebRequest.dll" />
<file src="..\_BuildOutput\bin\System.Web.Helpers.dll" target="lib\System.Web.Helpers.dll" />
<file src="..\_BuildOutput\bin\System.Web.Http.dll" target="lib\System.Web.Http.dll" />
<file src="..\_BuildOutput\bin\System.Web.Http.WebHost.dll" target="lib\System.Web.Http.WebHost.dll" />
<file src="..\_BuildOutput\bin\System.Web.Mvc.dll" target="lib\System.Web.Mvc.dll" />
<file src="..\_BuildOutput\bin\System.Web.Razor.dll" target="lib\System.Web.Razor.dll" />
<file src="..\_BuildOutput\bin\System.Web.WebPages.Administration.dll" target="lib\System.Web.WebPages.Administration.dll" />
<file src="..\_BuildOutput\bin\System.Web.WebPages.Deployment.dll" target="lib\System.Web.WebPages.Deployment.dll" />
<file src="..\_BuildOutput\bin\System.Web.WebPages.dll" target="lib\System.Web.WebPages.dll" />
<file src="..\_BuildOutput\bin\System.Web.WebPages.Razor.dll" target="lib\System.Web.WebPages.Razor.dll" />
<file src="..\_BuildOutput\bin\TidyNet.dll" target="lib\TidyNet.dll" />
<file src="..\_BuildOutput\bin\Umbraco.Core.dll" target="lib\Umbraco.Core.dll" />
<file src="..\_BuildOutput\bin\umbraco.DataLayer.dll" target="lib\umbraco.DataLayer.dll" />
<file src="..\_BuildOutput\bin\umbraco.dll" target="lib\umbraco.dll" />
<file src="..\_BuildOutput\bin\umbraco.editorControls.dll" target="lib\umbraco.editorControls.dll" />
<file src="..\_BuildOutput\bin\umbraco.MacroEngines.dll" target="lib\umbraco.MacroEngines.dll" />
<file src="..\_BuildOutput\bin\umbraco.providers.dll" target="lib\umbraco.providers.dll" />
<file src="..\_BuildOutput\bin\Umbraco.Web.UI.dll" target="lib\Umbraco.Web.UI.dll" />
<file src="..\_BuildOutput\bin\UmbracoExamine.dll" target="lib\UmbracoExamine.dll" />
<file src="..\_BuildOutput\bin\UrlRewritingNet.UrlRewriter.dll" target="lib\UrlRewritingNet.UrlRewriter.dll" />
</files>
</package>
@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>UmbracoCms.Core</id>
<version>7.0.0</version>
<title>Umbraco Cms Core Binaries</title>
<authors>Umbraco HQ</authors>
<owners>Umbraco HQ</owners>
<licenseUrl>http://umbraco.codeplex.com/license</licenseUrl>
<projectUrl>http://umbraco.com/</projectUrl>
<iconUrl>http://umbraco.com/media/357769/100px_transparent.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Contains the core assemblies needed to run Umbraco Cms. This package only contains assemblies and can be used for package development. Use the UmbracoCms-package to setup Umbraco in Visual Studio as an ASP.NET project.</description>
<summary>Contains the core assemblies needed to run Umbraco Cms</summary>
<language>en-US</language>
<tags>umbraco</tags>
</metadata>
<files>
<file src="..\..\src\SQLCE4Umbraco\obj\Debug\SQLCE4Umbraco.dll" target="lib" />
<file src="..\..\src\SQLCE4Umbraco\obj\Debug\SQLCE4Umbraco.pdb" target="lib" />
<file src="..\..\src\SQLCE4Umbraco\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\SQLCE4Umbraco" />
<file src="..\..\src\umbraco.businesslogic\obj\Debug\businesslogic.dll" target="lib" />
<file src="..\..\src\umbraco.businesslogic\obj\Debug\businesslogic.pdb" target="lib" />
<file src="..\..\src\umbraco.businesslogic\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.businesslogic" />
<file src="..\..\src\umbraco.cms\obj\Debug\cms.dll" target="lib" />
<file src="..\..\src\umbraco.cms\obj\Debug\cms.pdb" target="lib" />
<file src="..\..\src\umbraco.cms\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.cms" />
<file src="..\..\src\umbraco.controls\obj\Debug\controls.dll" target="lib" />
<file src="..\..\src\umbraco.controls\obj\Debug\controls.pdb" target="lib" />
<file src="..\..\src\umbraco.controls\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.controls" />
<file src="..\..\src\umbraco.interfaces\obj\Debug\interfaces.dll" target="lib" />
<file src="..\..\src\umbraco.interfaces\obj\Debug\interfaces.pdb" target="lib" />
<file src="..\..\src\umbraco.interfaces\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.interfaces" />
<file src="..\..\src\Umbraco.Core\obj\Debug\Umbraco.Core.dll" target="lib" />
<file src="..\..\src\Umbraco.Core\obj\Debug\Umbraco.Core.pdb" target="lib" />
<file src="..\..\src\Umbraco.Core\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\Umbraco.Core" />
<file src="..\..\src\umbraco.datalayer\obj\Debug\umbraco.DataLayer.dll" target="lib" />
<file src="..\..\src\umbraco.datalayer\obj\Debug\umbraco.DataLayer.pdb" target="lib" />
<file src="..\..\src\umbraco.datalayer\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.datalayer" />
<file src="..\..\src\umbraco.editorControls\obj\Debug\umbraco.editorControls.dll" target="lib" />
<file src="..\..\src\umbraco.editorControls\obj\Debug\umbraco.editorControls.pdb" target="lib" />
<file src="..\..\src\umbraco.editorControls\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.editorControls" />
<file src="..\..\src\umbraco.MacroEngines\obj\Debug\umbraco.MacroEngines.dll" target="lib" />
<file src="..\..\src\umbraco.MacroEngines\obj\Debug\umbraco.MacroEngines.pdb" target="lib" />
<file src="..\..\src\umbraco.MacroEngines\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.MacroEngines" />
<file src="..\..\src\umbraco.providers\obj\Debug\umbraco.providers.dll" target="lib" />
<file src="..\..\src\umbraco.providers\obj\Debug\umbraco.providers.pdb" target="lib" />
<file src="..\..\src\umbraco.providers\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.providers" />
<file src="..\..\src\Umbraco.Web\obj\Debug\umbraco.dll" target="lib" />
<file src="..\..\src\Umbraco.Web\obj\Debug\umbraco.pdb" target="lib" />
<file src="..\..\src\Umbraco.Web\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\Umbraco.Web" />
<file src="..\..\src\bin\Debug\Umbraco.Web.UI.dll" target="lib" />
<file src="..\..\src\bin\Debug\Umbraco.Web.UI.pdb" target="lib" />
<file src="..\..\src\Umbraco.Web.UI\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\Umbraco.Web.UI" />
<file src="..\..\src\UmbracoExamine\obj\Debug\UmbracoExamine.dll" target="lib" />
<file src="..\..\src\UmbracoExamine\obj\Debug\UmbracoExamine.pdb" target="lib" />
<file src="..\..\src\UmbracoExamine\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\UmbracoExamine" />
</files>
</package>
+5 -5
View File
@@ -26,12 +26,12 @@
<dependency id="SharpZipLib" version="[0.86.0, 1.0.0)" />
<dependency id="MySql.Data" version="[6.6.5]" />
<dependency id="xmlrpcnet" version="[2.5.0, 3.0.0)" />
<dependency id="ClientDependency" version="[1.7.0, 2.0.0)" />
<dependency id="ClientDependency-Mvc" version="[1.7.0, 2.0.0)" />
<dependency id="ClientDependency" version="[1.7.1.2, 2.0.0)" />
<dependency id="ClientDependency-Mvc" version="[1.7.0.4, 2.0.0)" />
<dependency id="AutoMapper" version="[3.0.0, 4.0.0)" />
<dependency id="Newtonsoft.Json" version="[4.5.11, 5.0.0)" />
<dependency id="ImageProcessor" version="[1.8.6.1, 2.0.0)" />
<dependency id="ImageProcessor.Web" version="[3.2.0, 4.0.0)" />
<dependency id="Newtonsoft.Json" version="[6.0.2, 7.0.0)" />
<dependency id="ImageProcessor" version="[1.9.0, 2.0.0)" />
<dependency id="ImageProcessor.Web" version="[3.2.3, 4.0.0)" />
</dependencies>
</metadata>
<files>
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<metadata minClientVersion="2.8">
<id>UmbracoCms</id>
<version>7.0.0</version>
<title>Umbraco Cms</title>
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
AddUmbracoFilesToOutput;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
AddUmbracoFilesToOutput;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
</PropertyGroup>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
AddUmbracoFilesToOutput;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
AddUmbracoFilesToOutput;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
</PropertyGroup>
</Project>
+50
View File
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<UmbracoVersion>7.1.2</UmbracoVersion>
</PropertyGroup>
<Target Name="CopyUmbracoFilesToWebRoot" BeforeTargets="AfterBuild">
<PropertyGroup>
<UmbracoFilesFolder>..\packages\UmbracoCms.$(UmbracoVersion)\UmbracoFiles\</UmbracoFilesFolder>
</PropertyGroup>
<ItemGroup>
<UmbracoFiles Include="$(UmbracoFilesFolder)**\*" />
</ItemGroup>
<Copy SourceFiles="%(UmbracoFiles.FullPath)" DestinationFiles="%(RecursiveDir)%(Filename)%(Extension)" Condition="!Exists('%(RecursiveDir)%(Filename)%(Extension)')" />
</Target>
<Target Name="AddUmbracoFilesToOutput">
<!-- With help from: http://blog.samstephens.co.nz/2010-10-18/msbuild-including-extra-files-multiple-builds/ -->
<ItemGroup>
<CustomFilesToInclude Include=".\App_Browsers\**\*">
<Dir>App_Browsers</Dir>
</CustomFilesToInclude>
<CustomFilesToInclude Include=".\App_Code\**\*">
<Dir>App_Code</Dir>
</CustomFilesToInclude>
<CustomFilesToInclude Include=".\App_Plugins\**\*">
<Dir>App_Plugins</Dir>
</CustomFilesToInclude>
<CustomFilesToInclude Include=".\bin\amd64\**\*">
<Dir>bin\amd64</Dir>
</CustomFilesToInclude>
<CustomFilesToInclude Include=".\bin\x86\**\*">
<Dir>bin\x86</Dir>
</CustomFilesToInclude>
<CustomFilesToInclude Include=".\Config\Splashes\**\*">
<Dir>Config\Splashes</Dir>
</CustomFilesToInclude>
<CustomFilesToInclude Include=".\umbraco\**\*">
<Dir>umbraco</Dir>
</CustomFilesToInclude>
<CustomFilesToInclude Include=".\umbraco_client\**\*">
<Dir>umbraco_client</Dir>
</CustomFilesToInclude>
<CustomFilesToInclude Include=".\Global.asax">
<Dir>.</Dir>
</CustomFilesToInclude>
<FilesForPackagingFromProject Include="@(CustomFilesToInclude)">
<DestinationRelativePath>%(CustomFilesToInclude.Dir)\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
</Project>
@@ -1,72 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="CopyUmbracoFilesToWebRoot" BeforeTargets="AfterBuild">
<ItemGroup>
<AppBrowsersFiles Include="..\packages\UmbracoCms.7.1.0-RC\UmbracoFiles\App_Browsers\**\*" />
<AppPluginsFiles Include="..\packages\UmbracoCms.7.1.0-RC\UmbracoFiles\App_Plugins\**\*" />
<SplashesFiles Include="..\packages\UmbracoCms.7.1.0-RC\UmbracoFiles\Config\Splashes\**\*;" />
<SqlCeBinFiles Include="..\packages\UmbracoCms.7.1.0-RC\UmbracoFiles\bin\**\*;" />
<UmbracoFiles Include="..\packages\UmbracoCms.7.1.0-RC\UmbracoFiles\umbraco\**\*;" />
<UmbracoClientFiles Include="..\packages\UmbracoCms.7.1.0-RC\UmbracoFiles\umbraco_client\**\*;" />
</ItemGroup>
<Copy SourceFiles="%(AppBrowsersFiles.FullPath)"
DestinationFiles="App_Browsers\%(RecursiveDir)%(Filename)%(Extension)"
Condition="!Exists('App_Browsers\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="%(AppPluginsFiles.FullPath)"
DestinationFiles="App_Plugins\%(RecursiveDir)%(Filename)%(Extension)"
Condition="!Exists('App_Plugins\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="%(SplashesFiles.FullPath)"
DestinationFiles="Config\Splashes\%(RecursiveDir)%(Filename)%(Extension)"
Condition="!Exists('Config\Splashes\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="%(SqlCeBinFiles.FullPath)"
DestinationFiles="bin\%(RecursiveDir)%(Filename)%(Extension)"
Condition="!Exists('bin\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="%(UmbracoFiles.FullPath)"
DestinationFiles="umbraco\%(RecursiveDir)%(Filename)%(Extension)"
Condition="!Exists('umbraco\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="%(UmbracoClientFiles.FullPath)"
DestinationFiles="umbraco_client\%(RecursiveDir)%(Filename)%(Extension)"
Condition="!Exists('umbraco_client\%(RecursiveDir)%(Filename)%(Extension)')" />
</Target>
<Target Name="AddUmbracoFilesToOutput">
<ItemGroup>
<AppBrowsersFiles Include=".\App_Browsers\**\*" />
<AppCodeFiles Include=".\App_Code\**\*" />
<AppPluginsFiles Include=".\App_Plugins\**\*" />
<GlobalAsaxFile Include=".\Global.asax;" />
<SqlCeAmd64Files Include=".\bin\amd64\**\*" />
<SqlCeX86Files Include=".\bin\x86\**\*" />
<SplashesFiles Include=".\Config\Splashes\**\*;" />
<UmbracoFiles Include=".\umbraco\**\*;" />
<UmbracoClientFiles Include=".\umbraco_client\**\*;" />
<FilesForPackagingFromProject Include="%(AppBrowsersFiles.Identity)">
<DestinationRelativePath>App_Browsers\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(AppCodeFiles.Identity)">
<DestinationRelativePath>App_Code\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(AppPluginsFiles.Identity)">
<DestinationRelativePath>App_Plugins\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(GlobalAsaxFile.Identity)">
<DestinationRelativePath>%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(SqlCeAmd64Files.Identity)">
<DestinationRelativePath>bin\amd64\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(SqlCeX86Files.Identity)">
<DestinationRelativePath>bin\x86\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(SplashesFiles.Identity)">
<DestinationRelativePath>Config\Splashes\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(UmbracoFiles.Identity)">
<DestinationRelativePath>umbraco\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(UmbracoClientFiles.Identity)">
<DestinationRelativePath>umbraco_client\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
</Project>
@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
AddUmbracoFilesToOutput;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
AddUmbracoFilesToOutput;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
</PropertyGroup>
</Project>
@@ -1,72 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="CopyUmbracoFilesToWebRoot" BeforeTargets="AfterBuild">
<ItemGroup>
<AppBrowsersFiles Include="..\packages\UmbracoCms.7.1.0-RC\UmbracoFiles\App_Browsers\**\*" />
<AppPluginsFiles Include="..\packages\UmbracoCms.7.1.0-RC\UmbracoFiles\App_Plugins\**\*" />
<SplashesFiles Include="..\packages\UmbracoCms.7.1.0-RC\UmbracoFiles\Config\Splashes\**\*;" />
<SqlCeBinFiles Include="..\packages\UmbracoCms.7.1.0-RC\UmbracoFiles\bin\**\*;" />
<UmbracoFiles Include="..\packages\UmbracoCms.7.1.0-RC\UmbracoFiles\umbraco\**\*;" />
<UmbracoClientFiles Include="..\packages\UmbracoCms.7.1.0-RC\UmbracoFiles\umbraco_client\**\*;" />
</ItemGroup>
<Copy SourceFiles="%(AppBrowsersFiles.FullPath)"
DestinationFiles="App_Browsers\%(RecursiveDir)%(Filename)%(Extension)"
Condition="!Exists('App_Browsers\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="%(AppPluginsFiles.FullPath)"
DestinationFiles="App_Plugins\%(RecursiveDir)%(Filename)%(Extension)"
Condition="!Exists('App_Plugins\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="%(SplashesFiles.FullPath)"
DestinationFiles="Config\Splashes\%(RecursiveDir)%(Filename)%(Extension)"
Condition="!Exists('Config\Splashes\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="%(SqlCeBinFiles.FullPath)"
DestinationFiles="bin\%(RecursiveDir)%(Filename)%(Extension)"
Condition="!Exists('bin\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="%(UmbracoFiles.FullPath)"
DestinationFiles="umbraco\%(RecursiveDir)%(Filename)%(Extension)"
Condition="!Exists('umbraco\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="%(UmbracoClientFiles.FullPath)"
DestinationFiles="umbraco_client\%(RecursiveDir)%(Filename)%(Extension)"
Condition="!Exists('umbraco_client\%(RecursiveDir)%(Filename)%(Extension)')" />
</Target>
<Target Name="AddUmbracoFilesToOutput">
<ItemGroup>
<AppBrowsersFiles Include=".\App_Browsers\**\*" />
<AppCodeFiles Include=".\App_Code\**\*" />
<AppPluginsFiles Include=".\App_Plugins\**\*" />
<GlobalAsaxFile Include=".\Global.asax;" />
<SqlCeAmd64Files Include=".\bin\amd64\**\*" />
<SqlCeX86Files Include=".\bin\x86\**\*" />
<SplashesFiles Include=".\Config\Splashes\**\*;" />
<UmbracoFiles Include=".\umbraco\**\*;" />
<UmbracoClientFiles Include=".\umbraco_client\**\*;" />
<FilesForPackagingFromProject Include="%(AppBrowsersFiles.Identity)">
<DestinationRelativePath>App_Browsers\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(AppCodeFiles.Identity)">
<DestinationRelativePath>App_Code\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(AppPluginsFiles.Identity)">
<DestinationRelativePath>App_Plugins\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(GlobalAsaxFile.Identity)">
<DestinationRelativePath>%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(SqlCeAmd64Files.Identity)">
<DestinationRelativePath>bin\amd64\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(SqlCeX86Files.Identity)">
<DestinationRelativePath>bin\x86\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(SplashesFiles.Identity)">
<DestinationRelativePath>Config\Splashes\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(UmbracoFiles.Identity)">
<DestinationRelativePath>umbraco\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(UmbracoClientFiles.Identity)">
<DestinationRelativePath>umbraco_client\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
</Project>
@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
AddUmbracoFilesToOutput;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
AddUmbracoFilesToOutput;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
</PropertyGroup>
</Project>
@@ -1,72 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="CopyUmbracoFilesToWebRoot" BeforeTargets="AfterBuild">
<ItemGroup>
<AppBrowsersFiles Include="..\packages\UmbracoCms.7.1.0-RC\UmbracoFiles\App_Browsers\**\*" />
<AppPluginsFiles Include="..\packages\UmbracoCms.7.1.0-RC\UmbracoFiles\App_Plugins\**\*" />
<SplashesFiles Include="..\packages\UmbracoCms.7.1.0-RC\UmbracoFiles\Config\Splashes\**\*;" />
<SqlCeBinFiles Include="..\packages\UmbracoCms.7.1.0-RC\UmbracoFiles\bin\**\*;" />
<UmbracoFiles Include="..\packages\UmbracoCms.7.1.0-RC\UmbracoFiles\umbraco\**\*;" />
<UmbracoClientFiles Include="..\packages\UmbracoCms.7.1.0-RC\UmbracoFiles\umbraco_client\**\*;" />
</ItemGroup>
<Copy SourceFiles="%(AppBrowsersFiles.FullPath)"
DestinationFiles="App_Browsers\%(RecursiveDir)%(Filename)%(Extension)"
Condition="!Exists('App_Browsers\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="%(AppPluginsFiles.FullPath)"
DestinationFiles="App_Plugins\%(RecursiveDir)%(Filename)%(Extension)"
Condition="!Exists('App_Plugins\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="%(SplashesFiles.FullPath)"
DestinationFiles="Config\Splashes\%(RecursiveDir)%(Filename)%(Extension)"
Condition="!Exists('Config\Splashes\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="%(SqlCeBinFiles.FullPath)"
DestinationFiles="bin\%(RecursiveDir)%(Filename)%(Extension)"
Condition="!Exists('bin\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="%(UmbracoFiles.FullPath)"
DestinationFiles="umbraco\%(RecursiveDir)%(Filename)%(Extension)"
Condition="!Exists('umbraco\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="%(UmbracoClientFiles.FullPath)"
DestinationFiles="umbraco_client\%(RecursiveDir)%(Filename)%(Extension)"
Condition="!Exists('umbraco_client\%(RecursiveDir)%(Filename)%(Extension)')" />
</Target>
<Target Name="AddUmbracoFilesToOutput">
<ItemGroup>
<AppBrowsersFiles Include=".\App_Browsers\**\*" />
<AppCodeFiles Include=".\App_Code\**\*" />
<AppPluginsFiles Include=".\App_Plugins\**\*" />
<GlobalAsaxFile Include=".\Global.asax;" />
<SqlCeAmd64Files Include=".\bin\amd64\**\*" />
<SqlCeX86Files Include=".\bin\x86\**\*" />
<SplashesFiles Include=".\Config\Splashes\**\*;" />
<UmbracoFiles Include=".\umbraco\**\*;" />
<UmbracoClientFiles Include=".\umbraco_client\**\*;" />
<FilesForPackagingFromProject Include="%(AppBrowsersFiles.Identity)">
<DestinationRelativePath>App_Browsers\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(AppCodeFiles.Identity)">
<DestinationRelativePath>App_Code\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(AppPluginsFiles.Identity)">
<DestinationRelativePath>App_Plugins\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(GlobalAsaxFile.Identity)">
<DestinationRelativePath>%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(SqlCeAmd64Files.Identity)">
<DestinationRelativePath>bin\amd64\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(SqlCeX86Files.Identity)">
<DestinationRelativePath>bin\x86\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(SplashesFiles.Identity)">
<DestinationRelativePath>Config\Splashes\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(UmbracoFiles.Identity)">
<DestinationRelativePath>umbraco\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(UmbracoClientFiles.Identity)">
<DestinationRelativePath>umbraco_client\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
</Project>
+7 -2
View File
@@ -2,10 +2,15 @@ A note about running Umbraco from Visual Studio.
When upgrading your website using NuGet you should answer "No" to the questions to overwrite the Web.config
file (and config files in the config folder).
We will overwrite Web.config anyway but we keep a backup in the App_Data\ConfigBackup folder. There you'll
We will overwrite Web.config anyway but we keep a backup in the App_Data\NuGetBackup folder. There you'll
find a folder with the current date and time in which the backup has been placed. Make sure to merge the
new file with the old backup files before you proceed.
Only the web.config will be overwritten by default to ensure that it has the necessary settings from the current release.
The web.config will be overwritten by default to ensure that it has the necessary settings from the current release.
We've also overwritten all the files in the Umbraco and Umbraco_Client folder, these have also been backed up in
App_Data\NuGetBackup. We didn't overwrite the UI.xml file nor did we remove any files or folders that you or a package
might have added. Only the existing files were overwritten. If you customized anything then make sure to do a compare
and merge with the NuGetBackup folder.
The config files found in the config folder will usually not be changed for patch releases, so they can usually be skipped,
but the web.config will have to have its previous "umbracoConfigurationStatus"-appsetting and "umbracoDbDSN" connection string
+32 -5
View File
@@ -1,11 +1,13 @@
param($rootPath, $toolsPath, $package, $project)
if ($project) {
$dateTime = Get-Date -Format yyyyMMdd-HHmmss
$backupPath = Join-Path (Split-Path $project.FullName -Parent) "\App_Data\ConfigBackup\$dateTime"
if ($project) {
$dateTime = Get-Date -Format yyyyMMdd-HHmmss
$backupPath = Join-Path (Split-Path $project.FullName -Parent) "\App_Data\NuGetBackup\$dateTime"
$copyLogsPath = Join-Path $backupPath "CopyLogs"
# Create backup folder if it doesn't exist yet
# Create backup folder and logs folder if it doesn't exist yet
New-Item -ItemType Directory -Force -Path $backupPath
New-Item -ItemType Directory -Force -Path $copyLogsPath
# Create a backup of original web.config
$projectDestinationPath = Split-Path $project.FullName -Parent
@@ -15,7 +17,32 @@ if ($project) {
# Copy Web.config from package to project folder
$umbracoFilesPath = Join-Path $rootPath "UmbracoFiles\Web.config"
Copy-Item $umbracoFilesPath $projectDestinationPath -Force
# Copy umbraco and umbraco_files from package to project folder
# This is only done when these folders already exist because we
# only want to do this for upgrades
$umbracoFolder = Join-Path $projectDestinationPath "Umbraco"
if(Test-Path $umbracoFolder) {
$umbracoFolderSource = Join-Path $rootPath "UmbracoFiles\Umbraco"
$umbracoBackupPath = Join-Path $backupPath "Umbraco"
New-Item -ItemType Directory -Force -Path $umbracoBackupPath
robocopy $umbracoFolder $umbracoBackupPath /e /LOG:$copyLogsPath\UmbracoBackup.log
robocopy $umbracoFolderSource $umbracoFolder /is /it /e /xf UI.xml /LOG:$copyLogsPath\UmbracoCopy.log
}
$umbracoClientFolder = Join-Path $projectDestinationPath "Umbraco_Client"
if(Test-Path $umbracoClientFolder) {
$umbracoClientFolderSource = Join-Path $rootPath "UmbracoFiles\Umbraco_Client"
$umbracoClientBackupPath = Join-Path $backupPath "Umbraco_Client"
New-Item -ItemType Directory -Force -Path $umbracoClientBackupPath
robocopy $umbracoClientFolder $umbracoClientBackupPath /e /LOG:$copyLogsPath\UmbracoClientBackup.log
robocopy $umbracoClientFolderSource $umbracoClientFolder /is /it /e /LOG:$copyLogsPath\UmbracoClientCopy.log
}
# Open readme.txt file
$DTE.ItemOperations.OpenFile($toolsPath + '\Readme.txt')
}
Binary file not shown.
+2
View File
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
namespace Umbraco.Core
+1
View File
@@ -53,5 +53,6 @@ namespace Umbraco.Core.Cache
public const string StylesheetPropertyCacheKey = "UmbracoStylesheetProperty";
public const string DataTypeCacheKey = "UmbracoDataTypeDefinition";
public const string DataTypePreValuesCacheKey = "UmbracoPreVal";
}
}
@@ -41,6 +41,12 @@ namespace Umbraco.Core.Cache
return result.Select(x => x.TryConvertTo<T>().Result);
}
public static IEnumerable<T> GetCacheItemsByKeyExpression<T>(this ICacheProvider provider, string regexString)
{
var result = provider.GetCacheItemsByKeyExpression(regexString);
return result.Select(x => x.TryConvertTo<T>().Result);
}
public static T GetCacheItem<T>(this ICacheProvider provider, string cacheKey)
{
var result = provider.GetCacheItem(cacheKey);
@@ -171,6 +171,26 @@ namespace Umbraco.Core.Cache
select c.Value).ToList();
}
public IEnumerable<object> GetCacheItemsByKeyExpression(string regexString)
{
var found = new List<object>();
foreach (var item in DictionaryCache)
{
var c = new DictionaryItemWrapper(item);
var s = c.Key as string;
if (s != null)
{
var withoutPrefix = s.TrimStart(string.Format("{0}-", CacheItemPrefix));
if (Regex.IsMatch(withoutPrefix, regexString))
{
found.Add(c.Value);
}
}
}
return found;
}
/// <summary>
/// Returns a cache item by key, does not update the cache if it isn't there.
/// </summary>
+8
View File
@@ -16,7 +16,15 @@ namespace Umbraco.Core.Cache
void ClearCacheByKeySearch(string keyStartsWith);
void ClearCacheByKeyExpression(string regexString);
IEnumerable<object> GetCacheItemsByKeySearch(string keyStartsWith);
IEnumerable<object> GetCacheItemsByKeyExpression(string regexString);
/// <summary>
/// Returns an item with a given key
/// </summary>
/// <param name="cacheKey"></param>
/// <returns></returns>
object GetCacheItem(string cacheKey);
object GetCacheItem(string cacheKey, Func<object> getCacheItem);
}
}
@@ -43,6 +43,11 @@ namespace Umbraco.Core.Cache
return Enumerable.Empty<object>();
}
public IEnumerable<object> GetCacheItemsByKeyExpression(string regexString)
{
return Enumerable.Empty<object>();
}
public virtual object GetCacheItem(string cacheKey)
{
return default(object);
@@ -114,6 +114,13 @@ namespace Umbraco.Core.Cache
select c.Value).ToList();
}
public IEnumerable<object> GetCacheItemsByKeyExpression(string regexString)
{
return (from c in MemoryCache
where Regex.IsMatch(c.Key, regexString)
select c.Value).ToList();
}
public virtual object GetCacheItem(string cacheKey)
{
var result = MemoryCache.Get(cacheKey);
@@ -59,6 +59,13 @@ namespace Umbraco.Core.Cache
select c.Value).ToList();
}
public IEnumerable<object> GetCacheItemsByKeyExpression(string regexString)
{
return (from KeyValuePair<string, object> c in StaticCache
where Regex.IsMatch(c.Key, regexString)
select c.Value).ToList();
}
public virtual object GetCacheItem(string cacheKey)
{
var result = StaticCache[cacheKey];
@@ -5,7 +5,7 @@ namespace Umbraco.Core.Configuration
{
public class UmbracoVersion
{
private static readonly Version Version = new Version("7.1.0");
private static readonly Version Version = new Version("7.1.2");
/// <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 "RC"; } }
public static string CurrentComment { get { return ""; } }
// Get the version of the umbraco.dll by looking at a class in that dll
// Had to do it like this due to medium trust issues, see: http://haacked.com/archive/2010/11/04/assembly-location-and-medium-trust.aspx
+36 -6
View File
@@ -149,7 +149,14 @@ namespace Umbraco.Core
/// <param name="connectionString"></param>
public void ConfigureDatabaseConnection(string connectionString)
{
SaveConnectionString(connectionString, string.Empty);
var provider = DbConnectionExtensions.DetectProviderFromConnectionString(connectionString);
var databaseProvider = provider.ToString();
var providerName = "System.Data.SqlClient";
if (databaseProvider.ToLower().Contains("mysql"))
{
providerName = "MySql.Data.MySqlClient";
}
SaveConnectionString(connectionString, providerName);
Initialize(string.Empty);
}
@@ -169,7 +176,7 @@ namespace Umbraco.Core
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";
@@ -465,6 +472,11 @@ namespace Umbraco.Core
string message;
var database = new UmbracoDatabase(_connectionString, ProviderName);
// If MySQL, we're going to ensure that database calls are maintaining proper casing as to remove the necessity for checks
// for case insensitive queries. In an ideal situation (which is what we're striving for), all calls would be case sensitive.
/*
var supportsCaseInsensitiveQueries = SqlSyntaxContext.SqlSyntaxProvider.SupportsCaseInsensitiveQueries(database);
if (supportsCaseInsensitiveQueries == false)
{
@@ -477,8 +489,9 @@ namespace Umbraco.Core
return new Result { Message = message, Success = false, Percentage = "15" };
}
*/
message = GetResultMessageForMySql(supportsCaseInsensitiveQueries);
message = GetResultMessageForMySql();
var schemaResult = ValidateDatabaseSchema();
var installedVersion = schemaResult.DetermineInstalledVersion();
@@ -529,9 +542,9 @@ namespace Umbraco.Core
LogHelper.Info<DatabaseContext>("Database upgrade started");
var database = new UmbracoDatabase(_connectionString, ProviderName);
var supportsCaseInsensitiveQueries = SqlSyntaxContext.SqlSyntaxProvider.SupportsCaseInsensitiveQueries(database);
//var supportsCaseInsensitiveQueries = SqlSyntaxContext.SqlSyntaxProvider.SupportsCaseInsensitiveQueries(database);
var message = GetResultMessageForMySql(supportsCaseInsensitiveQueries);
var message = GetResultMessageForMySql();
var schemaResult = ValidateDatabaseSchema();
var installedVersion = schemaResult.DetermineInstalledVersion();
@@ -558,6 +571,23 @@ namespace Umbraco.Core
}
}
private string GetResultMessageForMySql()
{
if (SqlSyntaxContext.SqlSyntaxProvider.GetType() == typeof(MySqlSyntaxProvider))
{
return "<p>&nbsp;</p><p>Congratulations, the database step ran successfully!</p>" +
"<p>Note: You're using MySQL and the database instance you're connecting to seems to support case insensitive queries.</p>" +
"<p>However, your hosting provider may not support this option. Umbraco does not currently support MySQL installs that do not support case insensitive queries</p>" +
"<p>Make sure to check with your hosting provider if they support case insensitive queries as well.</p>" +
"<p>They can check this by looking for the following setting in the my.ini file in their MySQL installation directory:</p>" +
"<pre>lower_case_table_names=1</pre><br />" +
"<p>For more technical information on case sensitivity in MySQL, have a look at " +
"<a href='http://dev.mysql.com/doc/refman/5.0/en/identifier-case-sensitivity.html'>the documentation on the subject</a></p>";
}
return string.Empty;
}
/*
private string GetResultMessageForMySql(bool? supportsCaseInsensitiveQueries)
{
if (supportsCaseInsensitiveQueries == null)
@@ -581,7 +611,7 @@ namespace Umbraco.Core
"<a href='http://dev.mysql.com/doc/refman/5.0/en/identifier-case-sensitivity.html'>the documentation on the subject</a></p>";
}
return string.Empty;
}
}*/
private Attempt<Result> CheckReadyForInstall()
{
+4 -24
View File
@@ -36,42 +36,22 @@ namespace Umbraco.Core.Dynamics
[Obsolete("This method should not be used and will be removed in the future")]
public static bool ContainsAny(this string haystack, IEnumerable<string> needles)
{
if (haystack == null) throw new ArgumentNullException("haystack");
if (!string.IsNullOrEmpty(haystack) || needles.Any())
{
return needles.Any(haystack.Contains);
}
return false;
return StringExtensions.ContainsAny(haystack, needles);
}
[Obsolete("This method should not be used and will be removed in the future")]
public static bool ContainsAny(this string haystack, params string[] needles)
{
if (haystack == null) throw new ArgumentNullException("haystack");
if (!string.IsNullOrEmpty(haystack) || needles.Length > 0)
{
return needles.Any(haystack.Contains);
}
return false;
return StringExtensions.ContainsAny(haystack, needles);
}
[Obsolete("This method should not be used and will be removed in the future")]
public static bool ContainsAny(this string haystack, StringComparison comparison, IEnumerable<string> needles)
{
if (haystack == null) throw new ArgumentNullException("haystack");
if (!string.IsNullOrEmpty(haystack) || needles.Any())
{
return needles.Any(value => haystack.IndexOf(value, comparison) >= 0);
}
return false;
return StringExtensions.ContainsAny(haystack, needles, comparison);
}
[Obsolete("This method should not be used and will be removed in the future")]
public static bool ContainsAny(this string haystack, StringComparison comparison, params string[] needles)
{
if (haystack == null) throw new ArgumentNullException("haystack");
if (!string.IsNullOrEmpty(haystack) || needles.Length > 0)
{
return needles.Any(value => haystack.IndexOf(value, comparison) >= 0);
}
return false;
return StringExtensions.ContainsAny(haystack, needles, comparison);
}
[Obsolete("This method should not be used and will be removed in the future")]
public static bool ContainsInsensitive(this string haystack, string needle)
+2 -2
View File
@@ -6,12 +6,12 @@ namespace Umbraco.Core.Dynamics
{
internal class PropertyResult : IPublishedProperty, IHtmlString
{
private readonly IPublishedProperty _source;
private readonly IPublishedProperty _source;
private readonly string _alias;
private readonly object _value;
private readonly PropertyResultType _type;
internal PropertyResult(IPublishedProperty source, PropertyResultType type)
internal PropertyResult(IPublishedProperty source, PropertyResultType type)
{
if (source == null) throw new ArgumentNullException("source");
+6 -36
View File
@@ -15,43 +15,13 @@ namespace Umbraco.Core
public static IEnumerable<IEnumerable<T>> InGroupsOf<T>(this IEnumerable<T> source, int groupSize)
{
if (source == null)
throw new NullReferenceException("source");
throw new ArgumentNullException("source");
if (groupSize <= 0)
throw new ArgumentException("Must be greater than zero.", "groupSize");
// enumerate the source only once!
return new InGroupsEnumerator<T>(source, groupSize).Groups();
}
// this class makes sure that the source is enumerated only ONCE
// which means that when it is enumerated, the actual groups content
// has to be evaluated at the same time, and stored in an array.
private class InGroupsEnumerator<T>
{
private readonly IEnumerator<T> _source;
private readonly int _count;
private bool _mightHaveNext;
public InGroupsEnumerator(IEnumerable<T> source, int count)
{
_source = source.GetEnumerator();
_count = count;
_mightHaveNext = true;
}
public IEnumerable<IEnumerable<T>> Groups()
{
while (_mightHaveNext && _source.MoveNext())
yield return Group().ToArray(); // see note above
}
private IEnumerable<T> Group()
{
var c = 0;
do
{
yield return _source.Current;
} while (++c < _count && _source.MoveNext());
_mightHaveNext = c == _count;
}
return source
.Select((x, i) => Tuple.Create(i / groupSize, x))
.GroupBy(t => t.Item1, t => t.Item2);
}
/// <summary>The distinct by.</summary>
@@ -29,7 +29,7 @@ namespace Umbraco.Core.Events
/// <remarks>
/// This is protected so that inheritors can expose it with their own name
/// </remarks>
protected T EventObject { get; private set; }
protected T EventObject { get; set; }
}
}
+92 -22
View File
@@ -1,28 +1,98 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Umbraco.Core.Events
{
public class MoveEventArgs<TEntity> : CancellableObjectEventArgs<TEntity>
{
public MoveEventArgs(TEntity eventObject, bool canCancel, int parentId) : base(eventObject, canCancel)
{
ParentId = parentId;
}
public class MoveEventInfo<TEntity>
{
public MoveEventInfo(TEntity entity, string originalPath, int newParentId)
{
Entity = entity;
OriginalPath = originalPath;
NewParentId = newParentId;
}
public MoveEventArgs(TEntity eventObject, int parentId) : base(eventObject)
{
ParentId = parentId;
}
public TEntity Entity { get; set; }
public string OriginalPath { get; set; }
public int NewParentId { get; set; }
}
/// <summary>
/// The entity being moved
/// </summary>
public TEntity Entity
{
get { return EventObject; }
}
public class MoveEventArgs<TEntity> : CancellableObjectEventArgs<TEntity>
{
/// <summary>
/// Constructor accepting a collection of MoveEventInfo objects
/// </summary>
/// <param name="canCancel"></param>
/// <param name="moveInfo">
/// A colleciton of MoveEventInfo objects that exposes all entities that have been moved during a single move operation
/// </param>
public MoveEventArgs(bool canCancel, params MoveEventInfo<TEntity>[] moveInfo)
: base(default(TEntity), canCancel)
{
if (moveInfo.FirstOrDefault() == null)
{
throw new ArgumentException("moveInfo argument must contain at least one item");
}
/// <summary>
/// Gets or Sets the Id of the objects new parent.
/// </summary>
public int ParentId { get; private set; }
}
MoveInfoCollection = moveInfo;
//assign the legacy props
EventObject = moveInfo.First().Entity;
ParentId = moveInfo.First().NewParentId;
}
/// <summary>
/// Constructor accepting a collection of MoveEventInfo objects
/// </summary>
/// <param name="moveInfo">
/// A colleciton of MoveEventInfo objects that exposes all entities that have been moved during a single move operation
/// </param>
public MoveEventArgs(params MoveEventInfo<TEntity>[] moveInfo)
: base(default(TEntity))
{
if (moveInfo.FirstOrDefault() == null)
{
throw new ArgumentException("moveInfo argument must contain at least one item");
}
MoveInfoCollection = moveInfo;
//assign the legacy props
EventObject = moveInfo.First().Entity;
ParentId = moveInfo.First().NewParentId;
}
[Obsolete("Use the overload that specifies the MoveEventInfo object")]
public MoveEventArgs(TEntity eventObject, bool canCancel, int parentId)
: base(eventObject, canCancel)
{
ParentId = parentId;
}
[Obsolete("Use the overload that specifies the MoveEventInfo object")]
public MoveEventArgs(TEntity eventObject, int parentId)
: base(eventObject)
{
ParentId = parentId;
}
/// <summary>
/// Gets all MoveEventInfo objects used to create the object
/// </summary>
public IEnumerable<MoveEventInfo<TEntity>> MoveInfoCollection { get; private set; }
/// <summary>
/// The entity being moved
/// </summary>
[Obsolete("Retrieve the entity object from the MoveInfoCollection property instead")]
public TEntity Entity
{
get { return EventObject; }
}
/// <summary>
/// Gets the Id of the object's new parent
/// </summary>
[Obsolete("Retrieve the ParentId from the MoveInfoCollection property instead")]
public int ParentId { get; private set; }
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
namespace Umbraco.Core.Media
{
//NOTE: Could definitely have done with a better name
//TODO: Could definitely have done with a better name
public class Result
{
public Status Status { get; set; }
+45 -20
View File
@@ -232,6 +232,7 @@ namespace Umbraco.Core.Models
/// <remarks>
/// This Property is kept internal until localization is introduced.
/// </remarks>
[DataMember]
internal string NodeName
{
get { return _nodeName; }
@@ -248,6 +249,7 @@ namespace Umbraco.Core.Models
/// <summary>
/// Used internally to track if permissions have been changed during the saving process for this entity
/// </summary>
[IgnoreDataMember]
internal bool PermissionsChanged
{
get { return _permissionsChanged; }
@@ -314,6 +316,7 @@ namespace Umbraco.Core.Models
PublishedState = state;
}
[DataMember]
internal PublishedState PublishedState { get; set; }
/// <summary>
@@ -333,26 +336,6 @@ namespace Umbraco.Core.Models
}
}
/// <summary>
/// Creates a clone of the current entity
/// </summary>
/// <returns></returns>
public IContent Clone()
{
var clone = (Content)this.MemberwiseClone();
clone.Key = Guid.Empty;
clone.Version = Guid.NewGuid();
clone.ResetIdentity();
foreach (var property in clone.Properties)
{
property.ResetIdentity();
property.Version = clone.Version;
}
return clone;
}
/// <summary>
/// Indicates whether a specific property on the current <see cref="IContent"/> entity is dirty.
/// </summary>
@@ -432,5 +415,47 @@ namespace Umbraco.Core.Models
base.UpdatingEntity();
Version = Guid.NewGuid();
}
/// <summary>
/// Creates a deep clone of the current entity with its identity and it's property identities reset
/// </summary>
/// <returns></returns>
[Obsolete("Use DeepCloneWithResetIdentities instead")]
public IContent Clone()
{
return DeepCloneWithResetIdentities();
}
/// <summary>
/// Creates a deep clone of the current entity with its identity and it's property identities reset
/// </summary>
/// <returns></returns>
public IContent DeepCloneWithResetIdentities()
{
var clone = (Content)DeepClone();
clone.Key = Guid.Empty;
clone.Version = Guid.NewGuid();
clone.ResetIdentity();
foreach (var property in clone.Properties)
{
property.ResetIdentity();
property.Version = clone.Version;
}
return clone;
}
public override object DeepClone()
{
var clone = (Content)base.DeepClone();
//need to manually clone this since it's not settable
clone._contentType = (IContentType)ContentType.DeepClone();
clone.ResetDirtyProperties(false);
return clone;
}
}
}
+6
View File
@@ -15,10 +15,13 @@ namespace Umbraco.Core.Models
/// <summary>
/// Represents an abstract class for base Content properties and methods
/// </summary>
[Serializable]
[DataContract(IsReference = true)]
[DebuggerDisplay("Id: {Id}, Name: {Name}, ContentType: {ContentTypeBase.Alias}")]
public abstract class ContentBase : Entity, IContentBase
{
protected IContentTypeComposition ContentTypeBase;
private Lazy<int> _parentId;
private string _name;//NOTE Once localization is introduced this will be the localized Name of the Content/Media.
private int _sortOrder;
@@ -257,6 +260,7 @@ namespace Umbraco.Core.Models
}
private readonly IDictionary<string, object> _additionalData;
/// <summary>
/// Some entities may expose additional data that other's might not, this custom data will be available in this collection
/// </summary>
@@ -445,6 +449,7 @@ namespace Umbraco.Core.Models
/// <summary>
/// Returns a collection of the result of the last validation process, this collection contains all invalid properties.
/// </summary>
[IgnoreDataMember]
internal IEnumerable<Property> LastInvalidProperties
{
get { return _lastInvalidProperties; }
@@ -466,5 +471,6 @@ namespace Umbraco.Core.Models
prop.ResetDirtyProperties(rememberPreviouslyChangedProperties);
}
}
}
}
@@ -0,0 +1,21 @@
using System;
using System.Xml.Linq;
namespace Umbraco.Core.Models
{
/// <summary>
/// Used content repository in order to add an entity to the persisted collection to be saved
/// in a single transaction during saving an entity
/// </summary>
internal class ContentPreviewEntity<TContent> : ContentXmlEntity<TContent>
where TContent : IContentBase
{
public ContentPreviewEntity(bool previewExists, TContent content, Func<TContent, XElement> xml)
: base(previewExists, content, xml)
{
Version = content.Version;
}
public Guid Version { get; private set; }
}
}
+51 -32
View File
@@ -120,38 +120,6 @@ namespace Umbraco.Core.Models
return result;
}
/// <summary>
/// Creates a clone of the current entity
/// </summary>
/// <returns></returns>
public IContentType Clone(string alias)
{
var clone = (ContentType)this.MemberwiseClone();
clone.Alias = alias;
clone.Key = Guid.Empty;
var propertyGroups = this.PropertyGroups.Select(x => x.Clone()).ToList();
clone.PropertyGroups = new PropertyGroupCollection(propertyGroups);
clone.PropertyTypes = this.PropertyTypeCollection.Select(x => x.Clone()).ToList();
clone.ResetIdentity();
clone.ResetDirtyProperties(false);
foreach (var propertyGroup in clone.PropertyGroups)
{
propertyGroup.ResetIdentity();
foreach (var propertyType in propertyGroup.PropertyTypes)
{
propertyType.ResetIdentity();
}
}
foreach (var propertyType in clone.PropertyTypes.Where(x => x.HasIdentity))
{
propertyType.ResetIdentity();
}
return clone;
}
/// <summary>
/// Method to call when Entity is being saved
@@ -173,5 +141,56 @@ namespace Umbraco.Core.Models
{
base.UpdatingEntity();
}
public override object DeepClone()
{
var clone = (ContentType)base.DeepClone();
var propertyGroups = PropertyGroups.Select(x => (PropertyGroup)x.DeepClone()).ToList();
clone.PropertyGroups = new PropertyGroupCollection(propertyGroups);
//set the property types that are not part of a group
clone.PropertyTypes = PropertyTypeCollection
.Where(x => x.PropertyGroupId == null)
.Select(x => (PropertyType)x.DeepClone()).ToList();
clone.ResetDirtyProperties(false);
return clone;
}
/// <summary>
/// Creates a deep clone of the current entity with its identity/alias and it's property identities reset
/// </summary>
/// <returns></returns>
[Obsolete("Use DeepCloneWithResetIdentities instead")]
public IContentType Clone(string alias)
{
return DeepCloneWithResetIdentities(alias);
}
/// <summary>
/// Creates a deep clone of the current entity with its identity/alias and it's property identities reset
/// </summary>
/// <returns></returns>
public IContentType DeepCloneWithResetIdentities(string alias)
{
var clone = (ContentType)DeepClone();
clone.Alias = alias;
clone.Key = Guid.Empty;
foreach (var propertyGroup in clone.PropertyGroups)
{
propertyGroup.ResetIdentity();
propertyGroup.ResetDirtyProperties(false);
}
foreach (var propertyType in clone.PropertyTypes)
{
propertyType.ResetIdentity();
propertyType.ResetDirtyProperties(false);
}
clone.ResetIdentity();
clone.ResetDirtyProperties(false);
return clone;
}
}
}
+4 -2
View File
@@ -6,6 +6,7 @@ using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Strings;
namespace Umbraco.Core.Models
{
@@ -173,7 +174,8 @@ namespace Umbraco.Core.Models
{
SetPropertyValueAndDetectChanges(o =>
{
_alias = value.ToSafeAlias();
//_alias = value.ToSafeAlias();
_alias = value.ToCleanString(CleanStringType.Alias | CleanStringType.UmbracoCase);
return _alias;
}, _alias, AliasSelector);
}
@@ -319,7 +321,7 @@ namespace Umbraco.Core.Models
}
}
private readonly IDictionary<string, object> _additionalData;
private IDictionary<string, object> _additionalData;
/// <summary>
/// Some entities may expose additional data that other's might not, this custom data will be available in this collection
/// </summary>
@@ -13,7 +13,7 @@ namespace Umbraco.Core.Models
[DataContract(IsReference = true)]
public abstract class ContentTypeCompositionBase : ContentTypeBase, IContentTypeComposition
{
private readonly List<IContentTypeComposition> _contentTypeComposition = new List<IContentTypeComposition>();
private List<IContentTypeComposition> _contentTypeComposition = new List<IContentTypeComposition>();
internal List<int> RemovedContentTypeKeyTracker = new List<int>();
protected ContentTypeCompositionBase(int parentId) : base(parentId)
@@ -217,5 +217,17 @@ namespace Umbraco.Core.Models
.Select(x => x.Id)
.Union(ContentTypeComposition.SelectMany(x => x.CompositionIds()));
}
public override object DeepClone()
{
var clone = (ContentTypeCompositionBase)base.DeepClone();
//need to manually assign since this is an internal field and will not be automatically mapped
clone.RemovedContentTypeKeyTracker = new List<int>();
clone._contentTypeComposition = ContentTypeComposition.Select(x => (IContentTypeComposition)x.DeepClone()).ToList();
clone.ResetDirtyProperties(false);
return clone;
}
}
}
+32 -1
View File
@@ -6,7 +6,7 @@ namespace Umbraco.Core.Models
/// <summary>
/// Represents a POCO for setting sort order on a ContentType reference
/// </summary>
public class ContentTypeSort : IValueObject
public class ContentTypeSort : IValueObject, IDeepCloneable
{
public ContentTypeSort()
{
@@ -33,5 +33,36 @@ namespace Umbraco.Core.Models
/// Gets or sets the Alias of the ContentType
/// </summary>
public string Alias { get; set; }
public object DeepClone()
{
var clone = (ContentTypeSort)MemberwiseClone();
var id = Id.Value;
clone.Id = new Lazy<int>(() => id);
return clone;
}
protected bool Equals(ContentTypeSort other)
{
return Id.Value.Equals(other.Id.Value) && string.Equals(Alias, other.Alias);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((ContentTypeSort) obj);
}
public override int GetHashCode()
{
unchecked
{
return (Id.GetHashCode()*397) ^ Alias.GetHashCode();
}
}
}
}
@@ -0,0 +1,60 @@
using System;
using System.Xml.Linq;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Models
{
/// <summary>
/// Used in content/media/member repositories in order to add this type of entity to the persisted collection to be saved
/// in a single transaction during saving an entity
/// </summary>
internal class ContentXmlEntity<TContent> : IAggregateRoot
where TContent : IContentBase
{
private readonly bool _entityExists;
private readonly Func<TContent, XElement> _xml;
public ContentXmlEntity(bool entityExists, TContent content, Func<TContent, XElement> xml)
{
if (content == null) throw new ArgumentNullException("content");
_entityExists = entityExists;
_xml = xml;
Content = content;
}
public ContentXmlEntity(TContent content)
{
if (content == null) throw new ArgumentNullException("content");
Content = content;
}
public XElement Xml
{
get { return _xml(Content); }
}
public TContent Content { get; private set; }
public int Id
{
get { return Content.Id; }
set { throw new NotSupportedException(); }
}
public Guid Key { get; set; }
public DateTime CreateDate { get; set; }
public DateTime UpdateDate { get; set; }
public bool HasIdentity
{
get { return _entityExists; }
}
public object DeepClone()
{
var clone = (ContentXmlEntity<TContent>)MemberwiseClone();
//Automatically deep clone ref properties that are IDeepCloneable
DeepCloneHelper.DeepCloneRefProperties(this, clone);
return clone;
}
}
}
+144
View File
@@ -0,0 +1,144 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Umbraco.Core.Models
{
public static class DeepCloneHelper
{
/// <summary>
/// Used to deep clone any reference properties on the object (should be done after a MemberwiseClone for which the outcome is 'output')
/// </summary>
/// <param name="input"></param>
/// <param name="output"></param>
/// <returns></returns>
public static void DeepCloneRefProperties(IDeepCloneable input, IDeepCloneable output)
{
var inputType = input.GetType();
var outputType = output.GetType();
if (inputType != outputType)
{
throw new InvalidOperationException("Both the input and output types must be the same");
}
var refProperties = inputType.GetProperties()
.Where(x =>
//reference type but not string
x.PropertyType.IsValueType == false && x.PropertyType != typeof (string)
//settable
&& x.CanWrite
//non-indexed
&& x.GetIndexParameters().Any() == false);
foreach (var propertyInfo in refProperties)
{
if (TypeHelper.IsTypeAssignableFrom<IDeepCloneable>(propertyInfo.PropertyType))
{
//this ref property is also deep cloneable so clone it
var result = (IDeepCloneable)propertyInfo.GetValue(input, null);
if (result != null)
{
//set the cloned value to the property
propertyInfo.SetValue(output, result.DeepClone(), null);
}
}
else if (TypeHelper.IsTypeAssignableFrom<IEnumerable>(propertyInfo.PropertyType)
&& TypeHelper.IsTypeAssignableFrom<string>(propertyInfo.PropertyType) == false)
{
IList newList;
if (propertyInfo.PropertyType.IsGenericType
&& (propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(IEnumerable<>)
|| propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(ICollection<>)
|| propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(IList<>)))
{
//if it is a IEnumerable<>, IList<T> or ICollection<> we'll use a List<>
var genericType = typeof(List<>).MakeGenericType(propertyInfo.PropertyType.GetGenericArguments());
newList = (IList)Activator.CreateInstance(genericType);
}
else if (propertyInfo.PropertyType.IsArray
|| (propertyInfo.PropertyType.IsInterface && propertyInfo.PropertyType.IsGenericType == false))
{
//if its an array, we'll create a list to work with first and then convert to array later
//otherwise if its just a regular derivitave of IEnumerable, we can use a list too
newList = new List<object>();
}
else
{
//its a custom IEnumerable, we'll try to create it
try
{
var custom = Activator.CreateInstance(propertyInfo.PropertyType);
//if it's an IList we can work with it, otherwise we cannot
newList = custom as IList;
if (newList == null)
{
continue;
}
}
catch (Exception)
{
//could not create this type so we'll skip it
continue;
}
}
var enumerable = (IEnumerable)propertyInfo.GetValue(input, null);
if (enumerable == null) continue;
var isUsableType = true;
//now clone each item
foreach (var o in enumerable)
{
//first check if the item is deep cloneable and copy that way
var dc = o as IDeepCloneable;
if (dc != null)
{
newList.Add(dc.DeepClone());
}
else if (o is string || o.GetType().IsValueType)
{
//check if the item is a value type or a string, then we can just use it
newList.Add(o);
}
else
{
//this will occur if the item is not a string or value type or IDeepCloneable, in this case we cannot
// clone each element, we'll need to skip this property, people will have to manually clone this list
isUsableType = false;
break;
}
}
//if this was not usable, skip this property
if (isUsableType == false)
{
continue;
}
if (propertyInfo.PropertyType.IsArray)
{
//need to convert to array
var arr = (object[])Activator.CreateInstance(propertyInfo.PropertyType, newList.Count);
for (int i = 0; i < newList.Count; i++)
{
arr[i] = newList[i];
}
//set the cloned collection
propertyInfo.SetValue(output, arr, null);
}
else
{
//set the cloned collection
propertyInfo.SetValue(output, newList, null);
}
}
}
}
}
}
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
@@ -96,5 +97,6 @@ namespace Umbraco.Core.Models
if(ParentId == Guid.Empty)
_parentId = new Guid("41c7638d-f529-4bff-853e-59a0c2fb1bde");
}
}
}
@@ -65,5 +65,6 @@ namespace Umbraco.Core.Models
}, _value, ValueSelector);
}
}
}
}
+62 -1
View File
@@ -1,7 +1,10 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
namespace Umbraco.Core.Models.EntityBase
{
@@ -93,7 +96,7 @@ namespace Umbraco.Core.Models.EntityBase
}
/// <summary>
/// /// Gets or sets the WasCancelled flag, which is used to track
/// Gets or sets the WasCancelled flag, which is used to track
/// whether some action against an entity was cancelled through some event.
/// This only exists so we have a way to check if an event was cancelled through
/// the new api, which also needs to take effect in the legacy api.
@@ -155,6 +158,7 @@ namespace Umbraco.Core.Models.EntityBase
/// <summary>
/// Indicates whether the current entity has an identity, eg. Id.
/// </summary>
[DataMember]
public virtual bool HasIdentity
{
get
@@ -226,5 +230,62 @@ namespace Umbraco.Core.Models.EntityBase
_hash = !HasIdentity ? new int?(base.GetHashCode()) : new int?(Id.GetHashCode() * 397 ^ GetType().GetHashCode());
return _hash.Value;
}
public virtual object DeepClone()
{
//Memberwise clone on Entity will work since it doesn't have any deep elements
// for any sub class this will work for standard properties as well that aren't complex object's themselves.
var clone = (Entity)MemberwiseClone();
//Automatically deep clone ref properties that are IDeepCloneable
DeepCloneHelper.DeepCloneRefProperties(this, clone);
clone.ResetDirtyProperties(false);
return clone;
//Using data contract serializer - has issues
//var s = Serialize(this);
//var d = Deserialize(s, this.GetType());
//return d;
//Using binary serializer - has issues
//using (var memoryStream = new MemoryStream(10))
//{
//IFormatter formatter = new BinaryFormatter();
//formatter.Serialize(memoryStream, this);
//memoryStream.Seek(0, SeekOrigin.Begin);
//return formatter.Deserialize(memoryStream);
//}
}
// serialize/deserialize with data contracts:
//public static string Serialize(object obj)
//{
// using (var memoryStream = new MemoryStream())
// using (var reader = new StreamReader(memoryStream))
// {
// var serializer = new DataContractSerializer(obj.GetType());
// serializer.WriteObject(memoryStream, obj);
// memoryStream.Position = 0;
// return reader.ReadToEnd();
// }
//}
//public static object Deserialize(string xml, Type toType)
//{
// using (Stream stream = new MemoryStream())
// {
// using (var writer = new StreamWriter(stream, Encoding.UTF8))
// {
// writer.Write(xml);
// //byte[] data = Encoding.UTF8.GetBytes(xml);
// //stream.Write(data, 0, data.Length);
// stream.Position = 0;
// var deserializer = new DataContractSerializer(toType);
// return deserializer.ReadObject(stream);
// }
// }
//}
}
}
@@ -9,7 +9,7 @@ namespace Umbraco.Core.Models.EntityBase
/// </summary>
/// <remarks>The current database schema doesn't provide a modified date
/// for all entities, so this will have to be changed at a later stage.</remarks>
public interface IEntity
public interface IEntity : IDeepCloneable
{
/// <summary>
/// The Id of the entity
@@ -3,18 +3,21 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
namespace Umbraco.Core.Models.EntityBase
{
/// <summary>
/// A base class for use to implement IRememberBeingDirty/ICanBeDirty
/// </summary>
[Serializable]
[DataContract(IsReference = true)]
public abstract class TracksChangesEntityBase : IRememberBeingDirty
{
/// <summary>
/// Tracks the properties that have changed
/// </summary>
private readonly IDictionary<string, bool> _propertyChangedInfo = new Dictionary<string, bool>();
private IDictionary<string, bool> _propertyChangedInfo = new Dictionary<string, bool>();
/// <summary>
/// Tracks the properties that we're changed before the last commit (or last call to ResetDirtyProperties)
@@ -83,7 +86,9 @@ namespace Umbraco.Core.Models.EntityBase
/// </summary>
public void ForgetPreviouslyDirtyProperties()
{
_lastPropertyChangedInfo.Clear();
//NOTE: We cannot .Clear() because when we memberwise clone this will be the SAME
// instance as the one on the clone, so we need to create a new instance.
_lastPropertyChangedInfo = new Dictionary<string, bool>();
}
/// <summary>
@@ -116,7 +121,9 @@ namespace Umbraco.Core.Models.EntityBase
_lastPropertyChangedInfo = _propertyChangedInfo.ToDictionary(v => v.Key, v => v.Value);
}
_propertyChangedInfo.Clear();
//NOTE: We cannot .Clear() because when we memberwise clone this will be the SAME
// instance as the one on the clone, so we need to create a new instance.
_propertyChangedInfo = new Dictionary<string, bool>();
}
/// <summary>
+13 -10
View File
@@ -6,16 +6,6 @@ using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Models
{
internal sealed class Folder : Entity
{
public Folder(string folderPath)
{
Path = folderPath;
}
public string Path { get; set; }
}
/// <summary>
/// Represents an abstract file which provides basic functionality for a File with an Alias and Name
/// </summary>
@@ -114,5 +104,18 @@ namespace Umbraco.Core.Models
/// </summary>
/// <returns>True if file is valid, otherwise false</returns>
public abstract bool IsValid();
public override object DeepClone()
{
var clone = (File)base.DeepClone();
//need to manually assign since they are readonly properties
clone._alias = Alias;
clone._name = Name;
clone.ResetDirtyProperties(false);
return clone;
}
}
}
+14
View File
@@ -0,0 +1,14 @@
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Models
{
internal sealed class Folder : Entity
{
public Folder(string folderPath)
{
Path = folderPath;
}
public string Path { get; set; }
}
}
+6
View File
@@ -72,5 +72,11 @@ namespace Umbraco.Core.Models
/// Changes the Published state of the content object
/// </summary>
void ChangePublishedState(PublishedState state);
/// <summary>
/// Creates a deep clone of the current entity with its identity/alias and it's property identities reset
/// </summary>
/// <returns></returns>
IContent DeepCloneWithResetIdentities();
}
}
+7
View File
@@ -29,5 +29,12 @@ namespace Umbraco.Core.Models
/// <param name="template"><see cref="ITemplate"/> to remove</param>
/// <returns>True if template was removed, otherwise False</returns>
bool RemoveTemplate(ITemplate template);
/// <summary>
/// Creates a deep clone of the current entity with its identity/alias and it's property identities reset
/// </summary>
/// <param name="newAlias"></param>
/// <returns></returns>
IContentType DeepCloneWithResetIdentities(string newAlias);
}
}
@@ -0,0 +1,9 @@
using System.Reflection;
namespace Umbraco.Core.Models
{
public interface IDeepCloneable
{
object DeepClone();
}
}
+17 -5
View File
@@ -109,9 +109,9 @@ namespace Umbraco.Core.Models
private string _scriptAssembly;
private string _scriptPath;
private string _xslt;
private readonly MacroPropertyCollection _properties;
private readonly List<string> _addedProperties;
private readonly List<string> _removedProperties;
private MacroPropertyCollection _properties;
private List<string> _addedProperties;
private List<string> _removedProperties;
private static readonly PropertyInfo AliasSelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.Alias);
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.Name);
@@ -397,7 +397,19 @@ namespace Umbraco.Core.Models
{
get { return _properties; }
}
public override object DeepClone()
{
var clone = (Macro)base.DeepClone();
clone._addedProperties = new List<string>();
clone._removedProperties = new List<string>();
clone._properties = new MacroPropertyCollection();
clone._properties.CollectionChanged += clone.PropertiesChanged;
clone.ResetDirtyProperties(false);
return clone;
}
}
}
+28 -10
View File
@@ -14,7 +14,7 @@ namespace Umbraco.Core.Models
[DataContract(IsReference = true)]
public class Member : ContentBase, IMember
{
private readonly IMemberType _contentType;
private IMemberType _contentType;
private readonly string _contentTypeAlias;
private string _username;
private string _email;
@@ -153,7 +153,7 @@ namespace Umbraco.Core.Models
/// <summary>
/// Gets or sets the raw password value
/// </summary>
[DataMember]
[IgnoreDataMember]
public string RawPasswordValue
{
get { return _rawPasswordValue; }
@@ -184,7 +184,7 @@ namespace Umbraco.Core.Models
/// Alias: umbracoMemberPasswordRetrievalQuestion
/// Part of the standard properties collection.
/// </remarks>
[IgnoreDataMember]
[DataMember]
public string PasswordQuestion
{
get
@@ -244,7 +244,7 @@ namespace Umbraco.Core.Models
/// Alias: umbracoMemberComments
/// Part of the standard properties collection.
/// </remarks>
[IgnoreDataMember]
[DataMember]
public string Comments
{
get
@@ -273,7 +273,7 @@ namespace Umbraco.Core.Models
/// Alias: umbracoMemberApproved
/// Part of the standard properties collection.
/// </remarks>
[IgnoreDataMember]
[DataMember]
public bool IsApproved
{
get
@@ -308,7 +308,7 @@ namespace Umbraco.Core.Models
/// Alias: umbracoMemberLockedOut
/// Part of the standard properties collection.
/// </remarks>
[IgnoreDataMember]
[DataMember]
public bool IsLockedOut
{
get
@@ -341,7 +341,7 @@ namespace Umbraco.Core.Models
/// Alias: umbracoMemberLastLogin
/// Part of the standard properties collection.
/// </remarks>
[IgnoreDataMember]
[DataMember]
public DateTime LastLoginDate
{
get
@@ -374,7 +374,7 @@ namespace Umbraco.Core.Models
/// Alias: umbracoMemberLastPasswordChangeDate
/// Part of the standard properties collection.
/// </remarks>
[IgnoreDataMember]
[DataMember]
public DateTime LastPasswordChangeDate
{
get
@@ -407,7 +407,7 @@ namespace Umbraco.Core.Models
/// Alias: umbracoMemberLastLockoutDate
/// Part of the standard properties collection.
/// </remarks>
[IgnoreDataMember]
[DataMember]
public DateTime LastLockoutDate
{
get
@@ -441,7 +441,7 @@ namespace Umbraco.Core.Models
/// Alias: umbracoMemberFailedPasswordAttempts
/// Part of the standard properties collection.
/// </remarks>
[IgnoreDataMember]
[DataMember]
public int FailedPasswordAttempts
{
get
@@ -563,11 +563,17 @@ namespace Umbraco.Core.Models
/* Internal experiment - only used for mapping queries.
* Adding these to have first level properties instead of the Properties collection.
*/
[IgnoreDataMember]
internal string LongStringPropertyValue { get; set; }
[IgnoreDataMember]
internal string ShortStringPropertyValue { get; set; }
[IgnoreDataMember]
internal int IntegerropertyValue { get; set; }
[IgnoreDataMember]
internal bool BoolPropertyValue { get; set; }
[IgnoreDataMember]
internal DateTime DateTimePropertyValue { get; set; }
[IgnoreDataMember]
internal string PropertyTypeAlias { get; set; }
private Attempt<T> WarnIfPropertyTypeNotFoundOnGet<T>(string propertyAlias, string propertyName, T defaultVal)
@@ -637,5 +643,17 @@ namespace Umbraco.Core.Models
return true;
}
public override object DeepClone()
{
var clone = (Member)base.DeepClone();
//need to manually clone this since it's not settable
clone._contentType = (IMemberType)ContentType.DeepClone();
clone.ResetDirtyProperties(false);
return clone;
}
}
}
+56 -69
View File
@@ -7,7 +7,7 @@ using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models.Membership
{
@@ -20,7 +20,7 @@ namespace Umbraco.Core.Models.Membership
/// </remarks>
[Serializable]
[DataContract(IsReference = true)]
public class User : TracksChangesEntityBase, IUser
public class User : Entity, IUser
{
public User(IUserType userType)
{
@@ -57,13 +57,11 @@ namespace Umbraco.Core.Models.Membership
}
private IUserType _userType;
private bool _hasIdentity;
private int _id;
private string _name;
private Type _userTypeKey;
private readonly List<string> _addedSections;
private readonly List<string> _removedSections;
private readonly ObservableCollection<string> _sectionCollection;
private List<string> _addedSections;
private List<string> _removedSections;
private ObservableCollection<string> _sectionCollection;
private int _sessionTimeout;
private int _startContentId;
private int _startMediaId;
@@ -81,7 +79,6 @@ namespace Umbraco.Core.Models.Membership
private static readonly PropertyInfo StartContentIdSelector = ExpressionHelper.GetPropertyInfo<User, int>(x => x.StartContentId);
private static readonly PropertyInfo StartMediaIdSelector = ExpressionHelper.GetPropertyInfo<User, int>(x => x.StartMediaId);
private static readonly PropertyInfo AllowedSectionsSelector = ExpressionHelper.GetPropertyInfo<User, IEnumerable<string>>(x => x.AllowedSections);
private static readonly PropertyInfo IdSelector = ExpressionHelper.GetPropertyInfo<User, object>(x => x.Id);
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<User, string>(x => x.Name);
private static readonly PropertyInfo UserTypeKeySelector = ExpressionHelper.GetPropertyInfo<User, Type>(x => x.ProviderUserKeyType);
@@ -93,52 +90,8 @@ 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 _hasIdentity;
}
protected set
{
SetPropertyValueAndDetectChanges(o =>
{
_hasIdentity = value;
return _hasIdentity;
}, _hasIdentity, HasIdentitySelector);
}
}
[DataMember]
public int Id
{
get
{
return _id;
}
set
{
SetPropertyValueAndDetectChanges(o =>
{
_id = value;
HasIdentity = true; //set the has Identity
return _id;
}, _id, IdSelector);
}
}
//this doesn't get used
[IgnoreDataMember]
public Guid Key { get; set; }
#endregion
#region Implementation of IMembershipUser
[IgnoreDataMember]
@@ -256,11 +209,7 @@ namespace Umbraco.Core.Models.Membership
[IgnoreDataMember]
public string RawPasswordAnswerValue { get; set; }
[IgnoreDataMember]
public string Comments { get; set; }
[IgnoreDataMember]
public DateTime CreateDate { get; set; }
[IgnoreDataMember]
public DateTime UpdateDate { get; set; }
public string Comments { get; set; }
[IgnoreDataMember]
public DateTime LastLoginDate { get; set; }
[IgnoreDataMember]
@@ -295,7 +244,10 @@ namespace Umbraco.Core.Models.Membership
public void RemoveAllowedSection(string sectionAlias)
{
_sectionCollection.Remove(sectionAlias);
if (_sectionCollection.Contains(sectionAlias))
{
_sectionCollection.Remove(sectionAlias);
}
}
public void AddAllowedSection(string sectionAlias)
@@ -474,24 +426,41 @@ namespace Umbraco.Core.Models.Membership
if (e.Action == NotifyCollectionChangedAction.Add)
{
//remove from the removed/added sections (since people could add/remove all they want in one request)
_removedSections.RemoveAll(s => s == e.NewItems.Cast<string>().First());
_addedSections.RemoveAll(s => s == e.NewItems.Cast<string>().First());
var item = e.NewItems.Cast<string>().First();
//add to the added sections
_addedSections.Add(e.NewItems.Cast<string>().First());
if (_addedSections.Contains(item) == false)
{
_addedSections.Add(item);
}
}
else if (e.Action == NotifyCollectionChangedAction.Remove)
{
//remove from the removed/added sections (since people could add/remove all they want in one request)
_removedSections.RemoveAll(s => s == e.OldItems.Cast<string>().First());
_addedSections.RemoveAll(s => s == e.OldItems.Cast<string>().First());
var item = e.OldItems.Cast<string>().First();
if (_removedSections.Contains(item) == false)
{
_removedSections.Add(item);
}
//add to the added sections
_removedSections.Add(e.OldItems.Cast<string>().First());
}
}
public override object DeepClone()
{
var clone = (User)base.DeepClone();
//need to create new collections otherwise they'll get copied by ref
clone._addedSections = new List<string>();
clone._removedSections = new List<string>();
clone._sectionCollection = new ObservableCollection<string>(_sectionCollection.ToList());
//re-create the event handler
clone._sectionCollection.CollectionChanged += clone.SectionCollectionChanged;
clone.ResetDirtyProperties(false);
return clone;
}
/// <summary>
/// Internal class used to wrap the user in a profile
/// </summary>
@@ -515,6 +484,24 @@ namespace Umbraco.Core.Models.Membership
get { return _user.Name; }
set { _user.Name = value; }
}
protected bool Equals(UserProfile other)
{
return _user.Equals(other._user);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((UserProfile) obj);
}
public override int GetHashCode()
{
return _user.GetHashCode();
}
}
}
}
+1 -1
View File
@@ -5,7 +5,7 @@ using System.Text;
namespace Umbraco.Core.Models
{
internal class Notification
public class Notification
{
public Notification(int entityId, int userId, string action, Guid entityType)
{
+15 -3
View File
@@ -5,10 +5,17 @@
/// </summary>
public class PreValue
{
public PreValue(int id, string value, int sortOrder)
{
Id = id;
Value = value;
SortOrder = sortOrder;
}
public PreValue(int id, string value)
{
Value = value;
Id = id;
Id = id;
Value = value;
}
public PreValue(string value)
@@ -19,11 +26,16 @@
/// <summary>
/// The value stored for the pre-value field
/// </summary>
public string Value { get; private set; }
public string Value { get; set; }
/// <summary>
/// The database id for the pre-value field value
/// </summary>
public int Id { get; private set; }
/// <summary>
/// The sort order stored for the pre-value field value
/// </summary>
public int SortOrder { get; private set; }
}
}
+12 -1
View File
@@ -13,7 +13,7 @@ namespace Umbraco.Core.Models
[DataContract(IsReference = true)]
public class Property : Entity
{
private readonly PropertyType _propertyType;
private PropertyType _propertyType;
private Guid _version;
private object _value;
private readonly PropertyTags _tagSupport = new PropertyTags();
@@ -156,5 +156,16 @@ namespace Umbraco.Core.Models
{
return _propertyType.IsPropertyValueValid(value);
}
public override object DeepClone()
{
var clone = (Property)base.DeepClone();
//need to manually assign since this is a readonly property
clone._propertyType = (PropertyType)PropertyType.DeepClone();
clone.ResetDirtyProperties(false);
return clone;
}
}
}
+16 -1
View File
@@ -5,6 +5,7 @@ using System.Collections.Specialized;
using System.Linq;
using System.Runtime.Serialization;
using System.Threading;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Models
{
@@ -13,7 +14,7 @@ namespace Umbraco.Core.Models
/// </summary>
[Serializable]
[DataContract(IsReference = true)]
public class PropertyCollection : KeyedCollection<string, Property>, INotifyCollectionChanged
public class PropertyCollection : KeyedCollection<string, Property>, INotifyCollectionChanged, IDeepCloneable
{
private readonly ReaderWriterLockSlim _addLocker = new ReaderWriterLockSlim();
internal Action OnAdd;
@@ -195,5 +196,19 @@ namespace Umbraco.Core.Models
}
}
}
/// <summary>
/// Create a deep clone of this property collection
/// </summary>
/// <returns></returns>
public object DeepClone()
{
var newList = new PropertyCollection();
foreach (var p in this)
{
newList.Add((Property)p.DeepClone());
}
return newList;
}
}
}
+3 -32
View File
@@ -17,38 +17,9 @@ namespace Umbraco.Core.Models
/// <returns>Xml of the property and its value</returns>
public static XElement ToXml(this Property property)
{
return property.ToXml(property.PropertyType, ApplicationContext.Current.Services.DataTypeService);
}
/// <summary>
/// Creates the xml representation for the <see cref="Property"/> object
/// </summary>
/// <param name="property"><see cref="Property"/> to generate xml for</param>
/// <param name="propertyType"></param>
/// <param name="dataTypeService"></param>
/// <returns>Xml of the property and its value</returns>
internal static XElement ToXml(this Property property, PropertyType propertyType, IDataTypeService dataTypeService)
{
var nodeName = UmbracoConfig.For.UmbracoSettings().Content.UseLegacyXmlSchema ? "data" : property.Alias.ToSafeAlias();
var xElement = new XElement(nodeName);
//Add the property alias to the legacy schema
if (UmbracoConfig.For.UmbracoSettings().Content.UseLegacyXmlSchema)
{
var a = new XAttribute("alias", property.Alias.ToSafeAlias());
xElement.Add(a);
}
//Get the property editor for thsi property and let it convert it to the xml structure
var propertyEditor = PropertyEditorResolver.Current.GetByAlias(property.PropertyType.PropertyEditorAlias);
if (propertyEditor != null)
{
var xmlValue = propertyEditor.ValueEditor.ConvertDbToXml(property, propertyType, dataTypeService);
xElement.Add(xmlValue);
}
return xElement;
var xmlSerializer = new EntityXmlSerializer();
return xmlSerializer.Serialize(ApplicationContext.Current.Services.DataTypeService, property);
}
}
}
+1 -17
View File
@@ -109,23 +109,6 @@ namespace Umbraco.Core.Models
}
}
internal PropertyGroup Clone()
{
var clone = (PropertyGroup) this.MemberwiseClone();
var collection = new PropertyTypeCollection();
foreach (var propertyType in this.PropertyTypes)
{
var property = propertyType.Clone();
property.ResetIdentity();
property.ResetDirtyProperties(false);
collection.Add(property);
}
clone.PropertyTypes = collection;
clone.ResetIdentity();
clone.ResetDirtyProperties(false);
return clone;
}
/// <summary>
/// Sets the ParentId from the lazy integer id
/// </summary>
@@ -159,5 +142,6 @@ namespace Umbraco.Core.Models
//Calculate the hash code for the product.
return hashName ^ hashId;
}
}
}
@@ -5,6 +5,7 @@ using System.Collections.Specialized;
using System.Linq;
using System.Runtime.Serialization;
using System.Threading;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Models
{
@@ -13,9 +14,10 @@ namespace Umbraco.Core.Models
/// </summary>
[Serializable]
[DataContract]
public class PropertyGroupCollection : KeyedCollection<string, PropertyGroup>, INotifyCollectionChanged
public class PropertyGroupCollection : KeyedCollection<string, PropertyGroup>, INotifyCollectionChanged, IDeepCloneable
{
private readonly ReaderWriterLockSlim _addLocker = new ReaderWriterLockSlim();
internal Action OnAdd;
internal PropertyGroupCollection()
@@ -131,5 +133,15 @@ namespace Umbraco.Core.Models
CollectionChanged(this, args);
}
}
public object DeepClone()
{
var newGroup = new PropertyGroupCollection();
foreach (var p in this)
{
newGroup.Add((PropertyGroup)p.DeepClone());
}
return newGroup;
}
}
}
+20 -10
View File
@@ -5,6 +5,7 @@ using System.Text.RegularExpressions;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Strings;
namespace Umbraco.Core.Models
{
@@ -96,7 +97,7 @@ namespace Umbraco.Core.Models
{
SetPropertyValueAndDetectChanges(o =>
{
_alias = value;
_alias = value.ToCleanString(CleanStringType.Alias | CleanStringType.UmbracoCase);
return _alias;
}, _alias, AliasSelector);
}
@@ -405,7 +406,9 @@ namespace Umbraco.Core.Models
}
}
//TODO: We must ensure that the property value can actually be saved based on the specified database type
//TODO Add PropertyEditor validation when its relevant to introduce
/*if (value is IEditorModel && DataTypeControlId != Guid.Empty)
{
@@ -419,14 +422,6 @@ namespace Umbraco.Core.Models
return true;
}
internal PropertyType Clone()
{
var clone = (PropertyType) MemberwiseClone();
clone.ResetIdentity();
clone.ResetDirtyProperties(false);
return clone;
}
public bool Equals(PropertyType other)
{
//Check whether the compared object is null.
@@ -450,5 +445,20 @@ namespace Umbraco.Core.Models
//Calculate the hash code for the product.
return hashName ^ hashAlias;
}
public override object DeepClone()
{
var clone = (PropertyType)base.DeepClone();
//need to manually assign the Lazy value as it will not be automatically mapped
if (PropertyGroupId != null)
{
clone._propertyGroupId = new Lazy<int>(() => PropertyGroupId.Value);
}
clone.ResetDirtyProperties(false);
return clone;
}
}
}
@@ -5,6 +5,7 @@ using System.Collections.Specialized;
using System.Linq;
using System.Runtime.Serialization;
using System.Threading;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Models
{
@@ -13,9 +14,12 @@ namespace Umbraco.Core.Models
/// </summary>
[Serializable]
[DataContract]
public class PropertyTypeCollection : KeyedCollection<string, PropertyType>, INotifyCollectionChanged
public class PropertyTypeCollection : KeyedCollection<string, PropertyType>, INotifyCollectionChanged, IDeepCloneable
{
[IgnoreDataMember]
private readonly ReaderWriterLockSlim _addLocker = new ReaderWriterLockSlim();
[IgnoreDataMember]
internal Action OnAdd;
internal PropertyTypeCollection()
@@ -131,5 +135,15 @@ namespace Umbraco.Core.Models
CollectionChanged(this, args);
}
}
public object DeepClone()
{
var newGroup = new PropertyTypeCollection();
foreach (var p in this)
{
newGroup.Add((PropertyType)p.DeepClone());
}
return newGroup;
}
}
}
@@ -4,8 +4,6 @@ using System.Globalization;
using System.Linq;
using System.Xml.Linq;
using System.Xml.XPath;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Core.Dynamics;
using Umbraco.Core.PropertyEditors;
@@ -18,6 +16,32 @@ namespace Umbraco.Core.Models.PublishedContent
/// if the property type changes, then a new class needs to be created.</remarks>
public class PublishedPropertyType
{
#region Constructors
// clone
private PublishedPropertyType(PublishedPropertyType orig)
{
ContentType = orig.ContentType;
PropertyTypeAlias = orig.PropertyTypeAlias;
DataTypeId = orig.DataTypeId;
PropertyEditorAlias = orig.PropertyEditorAlias;
_converter = orig._converter;
_sourceCacheLevel = orig._sourceCacheLevel;
_objectCacheLevel = orig._objectCacheLevel;
_xpathCacheLevel = orig._xpathCacheLevel;
_clrType = orig._clrType;
// do NOT copy the reduced cache levels
// as we should NOT clone a nested / detached type
}
/// <summary>
/// Initialize a new instance of the <see cref="PublishedPropertyType"/> class within a <see cref="PublishedContentType"/>,
/// with a <see cref="PropertyType"/>.
/// </summary>
/// <param name="contentType">The published content type.</param>
/// <param name="propertyType">The property type.</param>
/// <remarks>The new published property type belongs to the published content type and corresponds to the property type.</remarks>
public PublishedPropertyType(PublishedContentType contentType, PropertyType propertyType)
{
// PropertyEditor [1:n] DataTypeDefinition [1:n] PropertyType
@@ -31,10 +55,68 @@ namespace Umbraco.Core.Models.PublishedContent
InitializeConverters();
}
// for unit tests
/// <summary>
/// Initializes a new instance of the <see cref="PublishedPropertyType"/> class with an existing <see cref="PublishedPropertyType"/>
/// and a new property type alias.
/// </summary>
/// <param name="propertyTypeAlias">The new property type alias.</param>
/// <param name="propertyType">The existing published property type.</param>
/// <remarks>
/// <para>The new published property type does not belong to a published content type.</para>
/// <para>It is a copy of the initial published property type, with a different alias.</para>
/// </remarks>
internal PublishedPropertyType(string propertyTypeAlias, PublishedPropertyType propertyType)
: this(propertyTypeAlias, propertyType.DataTypeId, propertyType.PropertyEditorAlias)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="PublishedPropertyType"/> class with a property type alias and a property editor alias.
/// </summary>
/// <param name="propertyTypeAlias">The property type alias.</param>
/// <param name="propertyEditorAlias">The property editor alias.</param>
/// <remarks>
/// <para>The new published property type does not belong to a published content type.</para>
/// <para>It is based upon the property editor, but has no datatype definition. This will work as long
/// as the datatype definition is not required to process (eg to convert) the property values. For
/// example, this may not work if the related IPropertyValueConverter requires the datatype definition
/// to make decisions, fetch prevalues, etc.</para>
/// <para>The value of <paramref name="propertyEditorAlias"/> is assumed to be valid.</para>
/// </remarks>
internal PublishedPropertyType(string propertyTypeAlias, string propertyEditorAlias)
: this(propertyTypeAlias, 0, propertyEditorAlias)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="PublishedPropertyType"/> class with a property type alias and a datatype definition.
/// </summary>
/// <param name="propertyTypeAlias">The property type alias.</param>
/// <param name="dataTypeDefinition">The datatype definition.</param>
/// <remarks>
/// <para>The new published property type does not belong to a published content type.</para>
/// </remarks>
internal PublishedPropertyType(string propertyTypeAlias, IDataTypeDefinition dataTypeDefinition)
: this(propertyTypeAlias, dataTypeDefinition.Id, dataTypeDefinition.PropertyEditorAlias)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="PublishedPropertyType"/> class with a property type alias,
/// a datatype definition identifier, and a property editor alias.
/// </summary>
/// <param name="propertyTypeAlias">The property type alias.</param>
/// <param name="dataTypeDefinitionId">The datatype definition identifier.</param>
/// <param name="propertyEditorAlias">The property editor alias.</param>
/// <remarks>
/// <para>The new published property type does not belong to a published content type.</para>
/// <para>The values of <paramref name="dataTypeDefinitionId"/> and <paramref name="propertyEditorAlias"/> are
/// assumed to be valid and consistent.</para>
/// </remarks>
internal PublishedPropertyType(string propertyTypeAlias, int dataTypeDefinitionId, string propertyEditorAlias)
{
// ContentType to be set by PublishedContentType when creating it
// ContentType
// - in unit tests, to be set by PublishedContentType when creating it
// - in detached types, remains null
PropertyTypeAlias = propertyTypeAlias;
DataTypeId = dataTypeDefinitionId;
@@ -43,6 +125,8 @@ namespace Umbraco.Core.Models.PublishedContent
InitializeConverters();
}
#endregion
#region Property type
/// <summary>
@@ -291,5 +375,132 @@ namespace Umbraco.Core.Models.PublishedContent
}
#endregion
#region Detached
private PropertyCacheLevel _sourceCacheLevelReduced = 0;
private PropertyCacheLevel _objectCacheLevelReduced = 0;
private PropertyCacheLevel _xpathCacheLevelReduced = 0;
internal bool IsDetachedOrNested
{
// enough to test source
get { return _sourceCacheLevelReduced != 0; }
}
/// <summary>
/// Creates a detached clone of this published property type.
/// </summary>
/// <returns>A detached clone of this published property type.</returns>
/// <remarks>
/// <para>Only a published property type that has not already been detached or nested, can be detached.</para>
/// <para>Use detached published property type when creating detached properties outside of a published content.</para>
/// </remarks>
internal PublishedPropertyType Detached()
{
// verify
if (IsDetachedOrNested)
throw new Exception("PublishedPropertyType is already detached/nested.");
var detached = new PublishedPropertyType(this);
detached._sourceCacheLevel
= detached._objectCacheLevel
= detached._xpathCacheLevel
= PropertyCacheLevel.Content;
// set to none to a) indicate it's detached / nested and b) make sure any nested
// types switch all their cache to .Content
detached._sourceCacheLevelReduced
= detached._objectCacheLevelReduced
= detached._xpathCacheLevelReduced
= PropertyCacheLevel.None;
return detached;
}
/// <summary>
/// Creates a nested clone of this published property type within a specified container published property type.
/// </summary>
/// <param name="containerType">The container published property type.</param>
/// <returns>A nested clone of this published property type</returns>
/// <remarks>
/// <para>Only a published property type that has not already been detached or nested, can be nested.</para>
/// <para>Use nested published property type when creating detached properties within a published content.</para>
/// </remarks>
internal PublishedPropertyType Nested(PublishedPropertyType containerType)
{
// verify
if (IsDetachedOrNested)
throw new Exception("PublishedPropertyType is already detached/nested.");
var nested = new PublishedPropertyType(this);
// before we reduce, both xpath and object are >= source, and
// the way reduce works, the relative order of resulting xpath, object and source are preserved
// Reduce() will set _xxxCacheLevelReduced thus indicating that the type is detached / nested
Reduce(_sourceCacheLevel, _sourceCacheLevelReduced, ref nested._sourceCacheLevel, ref nested._sourceCacheLevelReduced);
Reduce(_objectCacheLevel, _objectCacheLevelReduced, ref nested._objectCacheLevel, ref nested._objectCacheLevelReduced);
Reduce(_xpathCacheLevel, _xpathCacheLevelReduced, ref nested._xpathCacheLevel, ref nested._xpathCacheLevelReduced);
return nested;
}
private static void Reduce(
PropertyCacheLevel containerCacheLevel, PropertyCacheLevel containerCacheLevelReduced,
ref PropertyCacheLevel nestedCacheLevel, ref PropertyCacheLevel nestedCacheLevelReduced)
{
// initialize if required
if (containerCacheLevelReduced == 0)
containerCacheLevelReduced = containerCacheLevel;
switch (containerCacheLevelReduced)
{
case PropertyCacheLevel.None:
// once .None, force .Content for everything
nestedCacheLevel = PropertyCacheLevel.Content;
nestedCacheLevelReduced = PropertyCacheLevel.None; // and propagate
break;
case PropertyCacheLevel.Request:
// once .Request, force .Content for everything
nestedCacheLevel = PropertyCacheLevel.Content;
nestedCacheLevelReduced = PropertyCacheLevel.Request; // and propagate
break;
case PropertyCacheLevel.Content:
// as long as .Content, accept anything
nestedCacheLevelReduced = nestedCacheLevel; // and it becomes the nested reduced
break;
case PropertyCacheLevel.ContentCache:
// once .ContentCache, accept .Request and .Content but not .ContentCache
switch (nestedCacheLevel)
{
case PropertyCacheLevel.Request:
case PropertyCacheLevel.None:
// accept
nestedCacheLevelReduced = nestedCacheLevel; // and it becomes the nested reduced
break;
case PropertyCacheLevel.Content:
// accept
nestedCacheLevelReduced = PropertyCacheLevel.ContentCache; // and propagate
break;
case PropertyCacheLevel.ContentCache:
// force .Content
nestedCacheLevel = PropertyCacheLevel.Content;
nestedCacheLevelReduced = PropertyCacheLevel.ContentCache; // and propagate
break;
default:
throw new Exception("Unsupported PropertyCacheLevel value.");
}
break;
default:
throw new Exception("Unsupported PropertyCacheLevel value.");
}
}
#endregion
}
}
+1
View File
@@ -107,5 +107,6 @@ namespace Umbraco.Core.Models
{
get { return _relationType.Id; }
}
}
}
+1
View File
@@ -127,5 +127,6 @@ namespace Umbraco.Core.Models
}, _childObjectType, ChildObjectTypeSelector);
}
}
}
}
@@ -1,4 +1,5 @@
using System;
using System.Globalization;
using System.Reflection;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.Mappers;
@@ -34,7 +35,7 @@ namespace Umbraco.Core.Models
{
UpdateDate = updateDate;
CreateDate = createDate;
Key = Id.ToString().EncodeAsGuid();
Key = Id.ToString(CultureInfo.InvariantCulture).EncodeAsGuid();
Id = id;
ServerAddress = serverAddress;
ComputerName = computerName;
@@ -51,7 +52,7 @@ namespace Umbraco.Core.Models
{
CreateDate = createDate;
UpdateDate = createDate;
Key = 0.ToString().EncodeAsGuid();
Key = 0.ToString(CultureInfo.InvariantCulture).EncodeAsGuid();
ServerAddress = serverAddress;
ComputerName = computerName;
}
+28
View File
@@ -1,10 +1,38 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Models
{
public class TaggedEntity
{
public TaggedEntity(int entityId, IEnumerable<TaggedProperty> taggedProperties)
{
EntityId = entityId;
TaggedProperties = taggedProperties;
}
public int EntityId { get; private set; }
public IEnumerable<TaggedProperty> TaggedProperties { get; private set; }
}
public class TaggedProperty
{
public TaggedProperty(int propertyTypeId, string propertyTypeAlias, IEnumerable<Tag> tags)
{
PropertyTypeId = propertyTypeId;
PropertyTypeAlias = propertyTypeAlias;
Tags = tags;
}
public int PropertyTypeId { get; private set; }
public string PropertyTypeAlias { get; private set; }
public IEnumerable<Tag> Tags { get; private set; }
}
[Serializable]
[DataContract(IsReference = true)]
public class Tag : Entity, ITag
+1
View File
@@ -132,5 +132,6 @@ namespace Umbraco.Core.Models
}, _comment, CommentSelector);
}
}
}
}
+19 -6
View File
@@ -4,6 +4,8 @@ using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Strings;
namespace Umbraco.Core.Models
{
@@ -14,20 +16,18 @@ namespace Umbraco.Core.Models
[DataContract(IsReference = true)]
public class Template : File, ITemplate
{
private readonly string _alias;
private readonly string _name;
private string _alias;
private string _name;
private int _creatorId;
private int _level;
private int _sortOrder;
private int _parentId;
private int _masterTemplateId;
private string _masterTemplateAlias;
private static readonly PropertyInfo CreatorIdSelector = ExpressionHelper.GetPropertyInfo<Template, int>(x => x.CreatorId);
private static readonly PropertyInfo LevelSelector = ExpressionHelper.GetPropertyInfo<Template, int>(x => x.Level);
private static readonly PropertyInfo SortOrderSelector = ExpressionHelper.GetPropertyInfo<Template, int>(x => x.SortOrder);
private static readonly PropertyInfo ParentIdSelector = ExpressionHelper.GetPropertyInfo<Template, int>(x => x.ParentId);
//private static readonly PropertyInfo MasterTemplateIdSelector = ExpressionHelper.GetPropertyInfo<Template, int>(x => x.MasterTemplateId);
private static readonly PropertyInfo MasterTemplateAliasSelector = ExpressionHelper.GetPropertyInfo<Template, string>(x => x.MasterTemplateAlias);
public Template(string path, string name, string alias)
@@ -35,8 +35,8 @@ namespace Umbraco.Core.Models
{
base.Path = path;
ParentId = -1;
_name = name.Replace("/", ".").Replace("\\", "");
_alias = alias.ToSafeAlias();
_name = name; //.Replace("/", ".").Replace("\\", ""); // why? that's just the name!
_alias = alias.ToCleanString(CleanStringType.UnderscoreAlias);
}
[DataMember]
@@ -189,5 +189,18 @@ namespace Umbraco.Core.Models
{
MasterTemplateId = new Lazy<int>(() => masterTemplate.Id);
}
public override object DeepClone()
{
var clone = (Template)base.DeepClone();
//need to manually assign since they are readonly properties
clone._alias = Alias;
clone._name = Name;
clone.ResetDirtyProperties(false);
return clone;
}
}
}
+52 -6
View File
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Models
@@ -283,15 +285,59 @@ namespace Umbraco.Core.Models
}
}
/// <summary>
/// Some entities may expose additional data that other's might not, this custom data will be available in this collection
/// </summary>
public IList<UmbracoProperty> UmbracoProperties { get; set; }
public override object DeepClone()
{
var clone = (UmbracoEntity) base.DeepClone();
internal class UmbracoProperty
//This ensures that any value in the dictionary that is deep cloneable is cloned too
foreach (var key in clone.AdditionalData.Keys.ToArray())
{
var deepCloneable = clone.AdditionalData[key] as IDeepCloneable;
if (deepCloneable != null)
{
clone.AdditionalData[key] = deepCloneable.DeepClone();
}
}
return clone;
}
/// <summary>
/// A struction that can be contained in the additional data of an UmbracoEntity representing
/// a user defined property
/// </summary>
public class EntityProperty : IDeepCloneable
{
public string PropertyEditorAlias { get; set; }
public string Value { get; set; }
public object Value { get; set; }
public object DeepClone()
{
//Memberwise clone on Entity will work since it doesn't have any deep elements
// for any sub class this will work for standard properties as well that aren't complex object's themselves.
var clone = MemberwiseClone();
return clone;
}
protected bool Equals(EntityProperty other)
{
return PropertyEditorAlias.Equals(other.PropertyEditorAlias) && string.Equals(Value, other.Value);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((EntityProperty) obj);
}
public override int GetHashCode()
{
unchecked
{
return (PropertyEditorAlias.GetHashCode() * 397) ^ (Value != null ? Value.GetHashCode() : 0);
}
}
}
}
}
@@ -85,10 +85,9 @@ namespace Umbraco.Core.ObjectResolution
}
/// <summary>
/// Gets a value indicating whether a the singleton nstance has been set.
/// Gets a value indicating whether a the singleton instance has been set.
/// </summary>
/// <remarks>To be used in unit tests.</remarks>
internal static bool HasCurrent
public static bool HasCurrent
{
get
{
@@ -102,9 +101,13 @@ namespace Umbraco.Core.ObjectResolution
/// <summary>
/// Resets the resolver singleton instance to null.
/// </summary>
/// <remarks>To be used in unit tests.</remarks>
/// <param name="resetResolution">By default this is true because we always need to reset resolution before we reset a resolver, however in some insanely rare cases like unit testing you might not want to do this.</param>
internal static void Reset(bool resetResolution = true)
/// <remarks>
/// To be used in unit tests. DO NOT USE THIS DURING PRODUCTION.
/// </remarks>
/// <param name="resetResolution">
/// By default this is true because we always need to reset resolution before we reset a resolver, however in some insanely rare cases like unit testing you might not want to do this.
/// </param>
protected internal static void Reset(bool resetResolution = true)
{
//In order to reset a resolver, we always must reset the resolution
@@ -37,7 +37,10 @@ namespace Umbraco.Core.Persistence.Caching
var containsKey = _cache.ContainsKey(compositeKey);
if (containsKey)
{
return _cache[compositeKey];
var result = _cache[compositeKey];
//IMPORTANT: we must clone to resolve, see: http://issues.umbraco.org/issue/U4-4259
return (IEntity)result.DeepClone();
}
return null;
@@ -56,7 +59,12 @@ namespace Umbraco.Core.Persistence.Caching
into key
let containsKey = _cache.ContainsKey(key)
where containsKey
select _cache[key]).ToList();
select _cache[key]
into result
//don't return null objects
where result != null
//IMPORTANT: we must clone to resolve, see: http://issues.umbraco.org/issue/U4-4259
select (IEntity)result.DeepClone()).ToList();
return list;
}
@@ -67,7 +75,14 @@ namespace Umbraco.Core.Persistence.Caching
/// <returns></returns>
public IEnumerable<IEntity> GetAllByType(Type type)
{
var list = _cache.Keys.Where(key => key.Contains(type.Name)).Select(key => _cache[key]).ToList();
var list = _cache.Keys
.Where(key => key.Contains(type.Name))
.Select(key => _cache[key])
//don't return null objects
.Where(result => result != null)
//IMPORTANT: we must clone to resolve, see: http://issues.umbraco.org/issue/U4-4259
.Select(result => (IEntity)result.DeepClone())
.ToList();
return list;
}
@@ -78,6 +93,9 @@ namespace Umbraco.Core.Persistence.Caching
/// <param name="entity"></param>
public void Save(Type type, IEntity entity)
{
//IMPORTANT: we must clone to store, see: http://issues.umbraco.org/issue/U4-4259
entity = (IEntity)entity.DeepClone();
_cache.AddOrUpdate(GetCompositeId(type, entity.Id), entity, (x, y) => entity);
}
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -29,6 +29,9 @@ namespace Umbraco.Core.Persistence.Caching
/// when there are async requests being made even in the context of a web request, the HttpContext.Current will be null but the HttpRuntime.Cache will
/// always be available.
///
/// TODO: Each item that get's added to this cache will be a clone of the original with it's dirty properties reset, and every item that is resolved from the cache
/// is a clone of the item that is in there, otherwise we end up with thread safety issues since multiple thread would be working on the exact same entity at the same time.
///
/// </remarks>
internal sealed class RuntimeCacheProvider : IRepositoryCacheProvider
{
@@ -64,8 +67,11 @@ namespace Umbraco.Core.Persistence.Caching
{
//ensure the key doesn't exist anymore in the tracker
_keyTracker.Remove(key);
return null;
}
return result;
//IMPORTANT: we must clone to resolve, see: http://issues.umbraco.org/issue/U4-4259
return (IEntity)result.DeepClone();
}
public IEnumerable<IEntity> GetByIds(Type type, List<Guid> ids)
@@ -85,7 +91,8 @@ namespace Umbraco.Core.Persistence.Caching
}
else
{
collection.Add(result);
//IMPORTANT: we must clone to resolve, see: http://issues.umbraco.org/issue/U4-4259
collection.Add((IEntity)result.DeepClone());
}
}
return collection;
@@ -110,7 +117,8 @@ namespace Umbraco.Core.Persistence.Caching
}
else
{
collection.Add(result);
//IMPORTANT: we must clone to resolve, see: http://issues.umbraco.org/issue/U4-4259
collection.Add((IEntity)result.DeepClone());
}
}
}
@@ -119,6 +127,9 @@ namespace Umbraco.Core.Persistence.Caching
public void Save(Type type, IEntity entity)
{
//IMPORTANT: we must clone to store, see: http://issues.umbraco.org/issue/U4-4259
entity = (IEntity)entity.DeepClone();
var key = GetCompositeId(type, entity.Id);
_keyTracker.TryAdd(key);
@@ -44,7 +44,6 @@ namespace Umbraco.Core.Persistence.Factories
ContentTypeAlias = asDictionary.ContainsKey("alias") ? (d.alias ?? string.Empty) : string.Empty,
ContentTypeIcon = asDictionary.ContainsKey("icon") ? (d.icon ?? string.Empty) : string.Empty,
ContentTypeThumbnail = asDictionary.ContainsKey("thumbnail") ? (d.thumbnail ?? string.Empty) : string.Empty,
UmbracoProperties = new List<UmbracoEntity.UmbracoProperty>()
};
var publishedVersion = default(Guid);
@@ -87,7 +86,6 @@ namespace Umbraco.Core.Persistence.Factories
ContentTypeAlias = dto.Alias ?? string.Empty,
ContentTypeIcon = dto.Icon ?? string.Empty,
ContentTypeThumbnail = dto.Thumbnail ?? string.Empty,
UmbracoProperties = new List<UmbracoEntity.UmbracoProperty>()
};
entity.IsPublished = dto.PublishedVersion != default(Guid) || (dto.NewestVersion != default(Guid) && dto.PublishedVersion == dto.NewestVersion);
@@ -98,12 +96,13 @@ namespace Umbraco.Core.Persistence.Factories
{
foreach (var propertyDto in dto.UmbracoPropertyDtos)
{
entity.UmbracoProperties.Add(new UmbracoEntity.UmbracoProperty
{
PropertyEditorAlias =
propertyDto.PropertyEditorAlias,
Value = propertyDto.UmbracoFile
});
entity.AdditionalData[propertyDto.PropertyAlias] = new UmbracoEntity.EntityProperty
{
PropertyEditorAlias = propertyDto.PropertyEditorAlias,
Value = propertyDto.NTextValue.IsNullOrWhiteSpace()
? propertyDto.NVarcharValue
: propertyDto.NTextValue.ConvertToJsonIfPossible()
};
}
}
@@ -72,7 +72,7 @@ namespace Umbraco.Core.Persistence.Factories
{
AppAlias = app
};
if (entity.Id != null)
if (entity.HasIdentity)
{
appDto.UserId = (int) entity.Id;
}
@@ -0,0 +1,43 @@
using System.Collections.Concurrent;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
namespace Umbraco.Core.Persistence.Mappers
{
/// <summary>
/// Represents a <see cref="Tag"/> to DTO mapper used to translate the properties of the public api
/// implementation to that of the database's DTO as sql: [tableName].[columnName].
/// </summary>
[MapperFor(typeof(Tag))]
[MapperFor(typeof(ITag))]
public sealed class TagMapper : 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 TagMapper()
{
BuildMap();
}
#region Overrides of BaseMapper
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache
{
get { return PropertyInfoCacheInstance; }
}
internal override void BuildMap()
{
if (PropertyInfoCache.IsEmpty)
{
CacheMap<Tag, TagDto>(src => src.Id, dto => dto.Id);
CacheMap<Tag, TagDto>(src => src.Text, dto => dto.Tag);
CacheMap<Tag, TagDto>(src => src.Group, dto => dto.Group);
}
}
#endregion
}
}
@@ -175,6 +175,8 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
.Where(x => x.IsNullOrWhiteSpace() == false).ToList();
//Add valid and invalid foreign key differences to the result object
// We'll need to do invariant contains with case insensitivity because foreign key, primary key, and even index naming w/ MySQL is not standardized
// In theory you could have: FK_ or fk_ ...or really any standard that your development department (or developer) chooses to use.
foreach (var unknown in unknownConstraintsInDatabase)
{
if (foreignKeysInSchema.InvariantContains(unknown) || primaryKeysInSchema.InvariantContains(unknown) || indexesInSchema.InvariantContains(unknown))
@@ -65,7 +65,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
return new Version(4, 7, 0);
}
return new Version(4, 9, 0);
return new Version(4, 8, 0);
}
//if the error is for umbracoServer
@@ -46,20 +46,20 @@ namespace Umbraco.Core.Persistence.Migrations
{
LogHelper.Info<MigrationRunner>("Initializing database migrations");
var foundMigrations = MigrationResolver.Current.Migrations.ToArray();
var foundMigrations = MigrationResolver.Current.Migrations.ToArray();
//filter all non-schema migrations
var migrations = isUpgrade
? OrderedUpgradeMigrations(foundMigrations).ToList()
: OrderedDowngradeMigrations(foundMigrations).ToList();
//SD: Why do we want this?
if (Migrating.IsRaisedEventCancelled(new MigrationEventArgs(migrations, _currentVersion, _targetVersion, true), this))
return false;
//Loop through migrations to generate sql
var migrationContext = InitializeMigrations(migrations, database, databaseProvider, isUpgrade);
try
{
ExecuteMigrations(migrationContext, database);
@@ -86,8 +86,8 @@ namespace Umbraco.Core.Persistence.Migrations
return true;
}
private void ExecuteMigrations(IMigrationContext context, Database database)
{
private void ExecuteMigrations(IMigrationContext context, Database database)
{
//Transactional execution of the sql that was generated from the found migrations
using (var transaction = database.GetTransaction())
{
@@ -108,13 +108,13 @@ namespace Umbraco.Core.Persistence.Migrations
transaction.Complete();
}
}
}
internal MigrationContext InitializeMigrations(List<IMigration> migrations, Database database, DatabaseProviders databaseProvider, bool isUpgrade = true)
{
{
//Loop through migrations to generate sql
var context = new MigrationContext(databaseProvider, database);
foreach (var migration in migrations)
{
var baseMigration = migration as MigrationBase;
@@ -148,7 +148,7 @@ namespace Umbraco.Core.Persistence.Migrations
}
return context;
}
}
/// <summary>
/// Filters and orders migrations based on the migrations listed and the currently configured version and the target installation version
@@ -158,17 +158,17 @@ namespace Umbraco.Core.Persistence.Migrations
internal IEnumerable<IMigration> OrderedUpgradeMigrations(IEnumerable<IMigration> foundMigrations)
{
var migrations = (from migration in foundMigrations
let migrationAttributes = migration.GetType().GetCustomAttributes<MigrationAttribute>(false)
from migrationAttribute in migrationAttributes
where migrationAttribute != null
where
let migrationAttributes = migration.GetType().GetCustomAttributes<MigrationAttribute>(false)
from migrationAttribute in migrationAttributes
where migrationAttribute != null
where
migrationAttribute.TargetVersion > _currentVersion &&
migrationAttribute.TargetVersion <= _targetVersion &&
migrationAttribute.TargetVersion <= _targetVersion &&
migrationAttribute.ProductName == _productName &&
//filter if the migration specifies a minimum current version for which to execute
(migrationAttribute.MinimumCurrentVersion == null || _currentVersion >= migrationAttribute.MinimumCurrentVersion)
orderby migrationAttribute.TargetVersion, migrationAttribute.SortOrder ascending
select migration).Distinct();
orderby migrationAttribute.TargetVersion, migrationAttribute.SortOrder ascending
select migration).Distinct();
return migrations;
}
@@ -180,17 +180,17 @@ namespace Umbraco.Core.Persistence.Migrations
public IEnumerable<IMigration> OrderedDowngradeMigrations(IEnumerable<IMigration> foundMigrations)
{
var migrations = (from migration in foundMigrations
let migrationAttributes = migration.GetType().GetCustomAttributes<MigrationAttribute>(false)
from migrationAttribute in migrationAttributes
where migrationAttribute != null
where
let migrationAttributes = migration.GetType().GetCustomAttributes<MigrationAttribute>(false)
from migrationAttribute in migrationAttributes
where migrationAttribute != null
where
migrationAttribute.TargetVersion > _currentVersion &&
migrationAttribute.TargetVersion <= _targetVersion &&
migrationAttribute.TargetVersion <= _targetVersion &&
migrationAttribute.ProductName == _productName &&
//filter if the migration specifies a minimum current version for which to execute
(migrationAttribute.MinimumCurrentVersion == null || _currentVersion >= migrationAttribute.MinimumCurrentVersion)
orderby migrationAttribute.TargetVersion, migrationAttribute.SortOrder descending
select migration).Distinct();
orderby migrationAttribute.TargetVersion, migrationAttribute.SortOrder descending
select migration).Distinct();
return migrations;
}
@@ -7,6 +7,7 @@ using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
using System.Xml;
using System.Xml.Linq;
using Newtonsoft.Json;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
@@ -32,48 +33,71 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven
var propertyData =
database.Fetch<PropertyDataDto>(
"WHERE propertyTypeId in (SELECT id from cmsPropertyType where dataTypeID IN (@dataTypeIds))", new { dataTypeIds = dataTypeIds });
if (!propertyData.Any()) return string.Empty;
var nodesIdsWithProperty = propertyData.Select(x => x.NodeId).Distinct();
var cmsContentXmlEntries = database.Fetch<ContentXmlDto>(
"WHERE nodeId in (@nodeIds)", new { nodeIds = nodesIdsWithProperty });
var propertyTypeIds = propertyData.Select(x => x.PropertyTypeId).Distinct();
var propertyTypes = database.Fetch<PropertyTypeDto>(
"WHERE id in (@propertyTypeIds)", new { propertyTypeIds = propertyTypeIds });
foreach (var data in propertyData)
{
if (!string.IsNullOrEmpty(data.Text))
if (string.IsNullOrEmpty(data.Text) == false)
{
//var cs = ApplicationContext.Current.Services.ContentService;
//fetch the current data (that's in xml format)
var xml = new XmlDocument();
xml.LoadXml(data.Text);
if (xml != null)
var links = new List<ExpandoObject>();
//loop all the stored links
foreach (XmlNode node in xml.DocumentElement.ChildNodes)
{
var links = new List<ExpandoObject>();
var title = node.Attributes["title"].Value;
var type = node.Attributes["type"].Value;
var newwindow = node.Attributes["newwindow"].Value.Equals("1") ? true : false;
var lnk = node.Attributes["link"].Value;
//loop all the stored links
foreach (XmlNode node in xml.DocumentElement.ChildNodes)
{
var title = node.Attributes["title"].Value;
var type = node.Attributes["type"].Value;
var newwindow = node.Attributes["newwindow"].Value.Equals("1") ? true : false;
var lnk = node.Attributes["link"].Value;
//create the links in the format the new prop editor expects it to be
var link = new ExpandoObject() as IDictionary<string, Object>;
link.Add("title", title);
link.Add("caption", title);
link.Add("link", lnk);
link.Add("newWindow", newwindow);
link.Add("type", type.Equals("internal") ? "internal" : "external");
link.Add("internal", type.Equals("internal") ? lnk : null);
//create the links in the format the new prop editor expects it to be
var link = new ExpandoObject() as IDictionary<string, Object>;
link.Add("title", title);
link.Add("caption", title);
link.Add("link", lnk);
link.Add("newWindow", newwindow);
link.Add("type", type.Equals("internal") ? "internal" : "external");
link.Add("internal", type.Equals("internal") ? lnk : null);
link.Add("edit", false);
link.Add("isInternal", type.Equals("internal"));
link.Add("edit", false);
link.Add("isInternal", type.Equals("internal"));
links.Add((ExpandoObject)link);
}
//store the serialized data
data.Text = JsonConvert.SerializeObject(links);
database.Update(data);
links.Add((ExpandoObject)link);
}
//store the serialized data
data.Text = JsonConvert.SerializeObject(links);
database.Update(data);
//now we need to update the cmsContentXml table
var propertyType = propertyTypes.SingleOrDefault(x => x.Id == data.PropertyTypeId);
if (propertyType != null)
{
var xmlItem = cmsContentXmlEntries.SingleOrDefault(x => x.NodeId == data.NodeId);
if (xmlItem != null)
{
var x = XElement.Parse(xmlItem.Xml);
var prop = x.Element(propertyType.Alias);
if (prop != null)
{
prop.ReplaceAll(new XCData(data.Text));
database.Update(xmlItem);
}
}
}
}
}
}
@@ -5,6 +5,7 @@ using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero
{
//see: http://issues.umbraco.org/issue/U4-4430
[Migration("7.1.0", 0, GlobalSettings.UmbracoMigrationName)]
[Migration("6.2.0", 0, GlobalSettings.UmbracoMigrationName)]
@@ -15,15 +16,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero
if (Context.CurrentDatabaseProvider == DatabaseProviders.MySql)
{
var constraints = SqlSyntaxContext.SqlSyntaxProvider.GetConstraintsPerColumn(Context.Database).Distinct().ToArray();
//This should be 2 because this table has 2 keys
if (constraints.Count(x => x.Item1.InvariantEquals("cmsContentType2ContentType") && x.Item3.InvariantEquals("PRIMARY")) == 0)
{
Create.PrimaryKey("PK_cmsContentType2ContentType")
.OnTable("cmsContentType2ContentType")
.Columns(new[] {"parentContentTypeId", "childContentTypeId"});
}
//This should be 2 because this table has 2 keys
if (constraints.Count(x => x.Item1.InvariantEquals("cmsContentTypeAllowedContentType") && x.Item3.InvariantEquals("PRIMARY")) == 0)
{
@@ -0,0 +1,34 @@
using System.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero
{
//We have to target this specifically to ensure this DOES NOT execute if upgrading from a version previous to 6.0,
// this is because when the 6.0.0 migrations are executed, this primary key get's created so if this migration is also executed
// we will get exceptions because it is trying to create the PK two times.
[Migration("6.0.0", "6.2.0", 0, GlobalSettings.UmbracoMigrationName)]
public class AssignMissingPrimaryForMySqlKeys2 : MigrationBase
{
public override void Up()
{
if (Context.CurrentDatabaseProvider == DatabaseProviders.MySql)
{
var constraints = SqlSyntaxContext.SqlSyntaxProvider.GetConstraintsPerColumn(Context.Database).Distinct().ToArray();
//This should be 2 because this table has 2 keys
if (constraints.Count(x => x.Item1.InvariantEquals("cmsContentType2ContentType") && x.Item3.InvariantEquals("PRIMARY")) == 0)
{
Create.PrimaryKey("PK_cmsContentType2ContentType")
.OnTable("cmsContentType2ContentType")
.Columns(new[] {"parentContentTypeId", "childContentTypeId"});
}
}
}
public override void Down()
{
//don't do anything, these keys should have always existed!
}
}
}
@@ -0,0 +1,109 @@
using System;
using System.Collections.Generic;
using System.Xml.Linq;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Caching;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
{
/// <summary>
/// Private class to handle preview insert/update based on standard principles and units of work with transactions
/// </summary>
internal class ContentPreviewRepository<TContent> : PetaPocoRepositoryBase<int, ContentPreviewEntity<TContent>>
where TContent : IContentBase
{
public ContentPreviewRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache)
: base(work, cache)
{
}
#region Not implemented (don't need to for the purposes of this repo)
protected override ContentPreviewEntity<TContent> PerformGet(int id)
{
throw new NotImplementedException();
}
protected override IEnumerable<ContentPreviewEntity<TContent>> PerformGetAll(params int[] ids)
{
throw new NotImplementedException();
}
protected override IEnumerable<ContentPreviewEntity<TContent>> PerformGetByQuery(IQuery<ContentPreviewEntity<TContent>> query)
{
throw new NotImplementedException();
}
protected override Sql GetBaseQuery(bool isCount)
{
throw new NotImplementedException();
}
protected override string GetBaseWhereClause()
{
throw new NotImplementedException();
}
protected override IEnumerable<string> GetDeleteClauses()
{
return new List<string>();
}
protected override Guid NodeObjectTypeId
{
get { throw new NotImplementedException(); }
}
protected override void PersistDeletedItem(ContentPreviewEntity<TContent> entity)
{
throw new NotImplementedException();
}
#endregion
protected override void PersistNewItem(ContentPreviewEntity<TContent> entity)
{
if (entity.Content.HasIdentity == false)
{
throw new InvalidOperationException("Cannot insert a preview for a content item that has no identity");
}
var previewPoco = new PreviewXmlDto
{
NodeId = entity.Id,
Timestamp = DateTime.Now,
VersionId = entity.Version,
Xml = entity.Xml.ToString(SaveOptions.None)
};
Database.Insert(previewPoco);
}
protected override void PersistUpdatedItem(ContentPreviewEntity<TContent> entity)
{
if (entity.Content.HasIdentity == false)
{
throw new InvalidOperationException("Cannot update a preview for a content item that has no identity");
}
var previewPoco = new PreviewXmlDto
{
NodeId = entity.Id,
Timestamp = DateTime.Now,
VersionId = entity.Version,
Xml = entity.Xml.ToString(SaveOptions.None)
};
Database.Update<PreviewXmlDto>(
"SET xml = @Xml, timestamp = @Timestamp WHERE nodeId = @Id AND versionId = @Version",
new
{
Xml = previewPoco.Xml,
Timestamp = previewPoco.Timestamp,
Id = previewPoco.NodeId,
Version = previewPoco.VersionId
});
}
}
}
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Linq;
using System.Xml.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
using Umbraco.Core.Models;
@@ -12,6 +14,7 @@ using Umbraco.Core.Persistence.Caching;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
@@ -25,6 +28,8 @@ namespace Umbraco.Core.Persistence.Repositories
private readonly ITemplateRepository _templateRepository;
private readonly ITagsRepository _tagRepository;
private readonly CacheHelper _cacheHelper;
private readonly ContentPreviewRepository<IContent> _contentPreviewRepository;
private readonly ContentXmlRepository<IContent> _contentXmlRepository;
public ContentRepository(IDatabaseUnitOfWork work, IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository, ITagsRepository tagRepository, CacheHelper cacheHelper)
: base(work)
@@ -36,6 +41,8 @@ namespace Umbraco.Core.Persistence.Repositories
_templateRepository = templateRepository;
_tagRepository = tagRepository;
_cacheHelper = cacheHelper;
_contentPreviewRepository = new ContentPreviewRepository<IContent>(work, NullCacheProvider.Current);
_contentXmlRepository = new ContentXmlRepository<IContent>(work, NullCacheProvider.Current);
EnsureUniqueNaming = true;
}
@@ -50,6 +57,8 @@ namespace Umbraco.Core.Persistence.Repositories
_templateRepository = templateRepository;
_tagRepository = tagRepository;
_cacheHelper = cacheHelper;
_contentPreviewRepository = new ContentPreviewRepository<IContent>(work, NullCacheProvider.Current);
_contentXmlRepository = new ContentXmlRepository<IContent>(work, NullCacheProvider.Current);
EnsureUniqueNaming = true;
}
@@ -149,12 +158,12 @@ namespace Umbraco.Core.Persistence.Repositories
"DELETE FROM umbracoRelation WHERE childId = @Id",
"DELETE FROM cmsTagRelationship WHERE nodeId = @Id",
"DELETE FROM umbracoDomains WHERE domainRootStructureID = @Id",
"DELETE FROM cmsDocument WHERE NodeId = @Id",
"DELETE FROM cmsDocument WHERE nodeId = @Id",
"DELETE FROM cmsPropertyData WHERE contentNodeId = @Id",
"DELETE FROM cmsPreviewXml WHERE nodeId = @Id",
"DELETE FROM cmsContentVersion WHERE ContentId = @Id",
"DELETE FROM cmsContentXml WHERE nodeID = @Id",
"DELETE FROM cmsContent WHERE NodeId = @Id",
"DELETE FROM cmsContentXml WHERE nodeId = @Id",
"DELETE FROM cmsContent WHERE nodeId = @Id",
"DELETE FROM umbracoNode WHERE id = @Id"
};
return list;
@@ -433,7 +442,7 @@ namespace Umbraco.Core.Persistence.Repositories
}
else
{
//In order to update the ContentVersion we need to retreive its primary key id
//In order to update the ContentVersion we need to retrieve its primary key id
var contentVerDto = Database.SingleOrDefault<ContentVersionDto>("WHERE VersionId = @Version", new { Version = entity.Version });
contentVersionDto.Id = contentVerDto.Id;
@@ -516,11 +525,16 @@ namespace Umbraco.Core.Persistence.Repositories
public IEnumerable<IContent> GetByPublishedVersion(IQuery<IContent> query)
{
// we WANT to return contents in top-down order, ie parents should come before children
// ideal would be pure xml "document order" which can be achieved with:
// ORDER BY substring(path, 1, len(path) - charindex(',', reverse(path))), sortOrder
// but that's probably an overkill - sorting by level,sortOrder should be enough
var sqlClause = GetBaseQuery(false);
var translator = new SqlTranslator<IContent>(sqlClause, query);
var sql = translator.Translate()
.Where<DocumentDto>(x => x.Published)
.OrderByDescending<ContentVersionDto>(x => x.VersionDate)
.OrderBy<NodeDto>(x => x.Level)
.OrderBy<NodeDto>(x => x.SortOrder);
//NOTE: This doesn't allow properties to be part of the query
@@ -577,6 +591,41 @@ namespace Umbraco.Core.Persistence.Repositories
return repo.GetPermissionsForEntity(entityId);
}
/// <summary>
/// Adds/updates content/published xml
/// </summary>
/// <param name="content"></param>
/// <param name="xml"></param>
public void AddOrUpdateContentXml(IContent content, Func<IContent, XElement> xml)
{
var contentExists = Database.ExecuteScalar<int>("SELECT COUNT(nodeId) FROM cmsContentXml WHERE nodeId = @Id", new { Id = content.Id }) != 0;
_contentXmlRepository.AddOrUpdate(new ContentXmlEntity<IContent>(contentExists, content, xml));
}
/// <summary>
/// Used to remove the content xml for a content item
/// </summary>
/// <param name="content"></param>
public void DeleteContentXml(IContent content)
{
_contentXmlRepository.Delete(new ContentXmlEntity<IContent>(content));
}
/// <summary>
/// Adds/updates preview xml
/// </summary>
/// <param name="content"></param>
/// <param name="xml"></param>
public void AddOrUpdatePreviewXml(IContent content, Func<IContent, XElement> xml)
{
var previewExists =
Database.ExecuteScalar<int>("SELECT COUNT(nodeId) FROM cmsPreviewXml WHERE nodeId = @Id AND versionId = @Version",
new { Id = content.Id, Version = content.Version }) != 0;
_contentPreviewRepository.AddOrUpdate(new ContentPreviewEntity<IContent>(previewExists, content, xml));
}
#endregion
/// <summary>
@@ -637,5 +686,6 @@ namespace Umbraco.Core.Persistence.Repositories
return currentName;
}
}
}
}
@@ -153,7 +153,7 @@ namespace Umbraco.Core.Persistence.Repositories
"DELETE FROM cmsPropertyType WHERE contentTypeId = @Id",
"DELETE FROM cmsPropertyTypeGroup WHERE contenttypeNodeId = @Id",
"DELETE FROM cmsDocumentType WHERE contentTypeNodeId = @Id",
"DELETE FROM cmsContentType WHERE NodeId = @Id",
"DELETE FROM cmsContentType WHERE nodeId = @Id",
"DELETE FROM umbracoNode WHERE id = @Id"
};
return list;
@@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
using System.Xml.Linq;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Caching;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
{
/// <summary>
/// Internal class to handle content/published xml insert/update based on standard principles and units of work with transactions
/// </summary>
internal class ContentXmlRepository<TContent> : PetaPocoRepositoryBase<int, ContentXmlEntity<TContent>>
where TContent : IContentBase
{
public ContentXmlRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache)
: base(work, cache)
{
}
#region Not implemented (don't need to for the purposes of this repo)
protected override ContentXmlEntity<TContent> PerformGet(int id)
{
throw new NotImplementedException();
}
protected override IEnumerable<ContentXmlEntity<TContent>> PerformGetAll(params int[] ids)
{
throw new NotImplementedException();
}
protected override IEnumerable<ContentXmlEntity<TContent>> PerformGetByQuery(IQuery<ContentXmlEntity<TContent>> query)
{
throw new NotImplementedException();
}
protected override Sql GetBaseQuery(bool isCount)
{
throw new NotImplementedException();
}
protected override string GetBaseWhereClause()
{
throw new NotImplementedException();
}
protected override IEnumerable<string> GetDeleteClauses()
{
return new List<string>();
}
protected override Guid NodeObjectTypeId
{
get { throw new NotImplementedException(); }
}
#endregion
protected override void PersistDeletedItem(ContentXmlEntity<TContent> entity)
{
//Remove 'published' xml from the cmsContentXml table for the unpublished content
Database.Delete<ContentXmlDto>("WHERE nodeId = @Id", new { Id = entity.Id });
}
protected override void PersistNewItem(ContentXmlEntity<TContent> entity)
{
if (entity.Content.HasIdentity == false)
{
throw new InvalidOperationException("Cannot insert an xml entry for a content item that has no identity");
}
var poco = new ContentXmlDto { NodeId = entity.Id, Xml = entity.Xml.ToString(SaveOptions.None) };
Database.Insert(poco);
}
protected override void PersistUpdatedItem(ContentXmlEntity<TContent> entity)
{
if (entity.Content.HasIdentity == false)
{
throw new InvalidOperationException("Cannot update an xml entry for a content item that has no identity");
}
var poco = new ContentXmlDto { NodeId = entity.Id, Xml = entity.Xml.ToString(SaveOptions.None) };
Database.Update(poco);
}
}
}
@@ -3,6 +3,8 @@ using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Linq;
using System.Threading;
using Umbraco.Core.Cache;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Rdbms;
@@ -11,6 +13,8 @@ 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 NullCacheProvider = Umbraco.Core.Persistence.Caching.NullCacheProvider;
namespace Umbraco.Core.Persistence.Repositories
{
@@ -19,16 +23,30 @@ namespace Umbraco.Core.Persistence.Repositories
/// </summary>
internal class DataTypeDefinitionRepository : PetaPocoRepositoryBase<int, IDataTypeDefinition>, IDataTypeDefinitionRepository
{
public DataTypeDefinitionRepository(IDatabaseUnitOfWork work)
private readonly CacheHelper _cacheHelper;
private readonly IContentTypeRepository _contentTypeRepository;
private readonly DataTypePreValueRepository _preValRepository;
public DataTypeDefinitionRepository(IDatabaseUnitOfWork work, CacheHelper cacheHelper,
IContentTypeRepository contentTypeRepository)
: base(work)
{
_cacheHelper = cacheHelper;
_contentTypeRepository = contentTypeRepository;
_preValRepository = new DataTypePreValueRepository(work, NullCacheProvider.Current);
}
public DataTypeDefinitionRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache)
public DataTypeDefinitionRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache, CacheHelper cacheHelper,
IContentTypeRepository contentTypeRepository)
: base(work, cache)
{
_cacheHelper = cacheHelper;
_contentTypeRepository = contentTypeRepository;
_preValRepository = new DataTypePreValueRepository(work, NullCacheProvider.Current);
}
private readonly ReaderWriterLockSlim _locker = new ReaderWriterLockSlim();
#region Overrides of RepositoryBase<int,DataTypeDefinition>
protected override IDataTypeDefinition PerformGet(int id)
@@ -83,6 +101,37 @@ namespace Umbraco.Core.Persistence.Repositories
}
}
/// <summary>
/// Override the delete method so that we can ensure that all related content type's are updated as part of the overall transaction
/// </summary>
/// <param name="entity"></param>
public override void Delete(IDataTypeDefinition entity)
{
//Find ContentTypes using this IDataTypeDefinition on a PropertyType
var query = Query<PropertyType>.Builder.Where(x => x.DataTypeDefinitionId == entity.Id);
var contentTypes = _contentTypeRepository.GetByQuery(query);
//Loop through the list of results and remove the PropertyTypes that references the DataTypeDefinition that is being deleted
foreach (var contentType in contentTypes)
{
if (contentType == null) continue;
foreach (var group in contentType.PropertyGroups)
{
var types = @group.PropertyTypes.Where(x => x.DataTypeDefinitionId == entity.Id).ToList();
foreach (var propertyType in types)
{
@group.PropertyTypes.Remove(propertyType);
}
}
_contentTypeRepository.AddOrUpdate(contentType);
}
//call the base method to queue the deletion of this data type
base.Delete(entity);
}
#endregion
#region Overrides of PetaPocoRepositoryBase<int,DataTypeDefinition>
@@ -238,5 +287,322 @@ AND umbracoNode.id <> @id",
}
#endregion
public PreValueCollection GetPreValuesCollectionByDataTypeId(int dataTypeId)
{
using (var l = new UpgradeableReadLock(_locker))
{
var cached = _cacheHelper.RuntimeCache.GetCacheItemsByKeySearch<PreValueCollection>(GetPrefixedCacheKey(dataTypeId));
if (cached != null && cached.Any())
{
//return from the cache
return cached.First();
}
l.UpgradeToWriteLock();
return GetAndCachePreValueCollection(dataTypeId);
}
}
public string GetPreValueAsString(int preValueId)
{
using (var l = new UpgradeableReadLock(_locker))
{
//We need to see if we can find the cached PreValueCollection based on the cache key above
var regex = CacheKeys.DataTypePreValuesCacheKey + @"[\d]+-[,\d]*" + preValueId + @"[,\d$]*";
var cached = _cacheHelper.RuntimeCache.GetCacheItemsByKeyExpression<PreValueCollection>(regex);
if (cached != null && cached.Any())
{
//return from the cache
var collection = cached.First();
var preVal = collection.FormatAsDictionary().Single(x => x.Value.Id == preValueId);
return preVal.Value.Value;
}
l.UpgradeToWriteLock();
//go and find the data type id for the pre val id passed in
var dto = Database.FirstOrDefault<DataTypePreValueDto>("WHERE id = @preValueId", new { preValueId = preValueId });
if (dto == null)
{
return string.Empty;
}
// go cache the collection
var preVals = GetAndCachePreValueCollection(dto.DataTypeNodeId);
//return the single value for this id
var pv = preVals.FormatAsDictionary().Single(x => x.Value.Id == preValueId);
return pv.Value.Value;
}
}
public void AddOrUpdatePreValues(int dataTypeId, IDictionary<string, PreValue> values)
{
var dtd = Get(dataTypeId);
if (dtd == null)
{
throw new InvalidOperationException("No data type found with id " + dataTypeId);
}
AddOrUpdatePreValues(dtd, values);
}
public void AddOrUpdatePreValues(IDataTypeDefinition dataType, IDictionary<string, PreValue> values)
{
var currentVals = new DataTypePreValueDto[]{};
if (dataType.HasIdentity)
{
//first just get all pre-values for this data type so we can compare them to see if we need to insert or update or replace
var sql = new Sql().Select("*")
.From<DataTypePreValueDto>()
.Where<DataTypePreValueDto>(dto => dto.DataTypeNodeId == dataType.Id)
.OrderBy<DataTypePreValueDto>(dto => dto.SortOrder);
currentVals = Database.Fetch<DataTypePreValueDto>(sql).ToArray();
}
//already existing, need to be updated
var valueIds = values.Where(x => x.Value.Id > 0).Select(x => x.Value.Id).ToArray();
var existingByIds = currentVals.Where(x => valueIds.Contains(x.Id)).ToArray();
//These ones need to be removed from the db, they no longer exist in the new values
var deleteById = currentVals.Where(x => valueIds.Contains(x.Id) == false);
foreach (var d in deleteById)
{
_preValRepository.Delete(new PreValueEntity
{
Alias = d.Alias,
Id = d.Id,
Value = d.Value,
DataType = dataType,
SortOrder = d.SortOrder
});
}
var sortOrder = 1;
foreach (var pre in values)
{
var existing = existingByIds.FirstOrDefault(valueDto => valueDto.Id == pre.Value.Id);
if (existing != null)
{
existing.Value = pre.Value.Value;
existing.SortOrder = sortOrder;
_preValRepository.AddOrUpdate(new PreValueEntity
{
//setting an id will update it
Id = existing.Id,
Alias = existing.Alias,
SortOrder = existing.SortOrder,
Value = existing.Value,
DataType = dataType,
});
}
else
{
_preValRepository.AddOrUpdate(new PreValueEntity
{
Alias = pre.Key,
SortOrder = sortOrder,
Value = pre.Value.Value,
DataType = dataType,
});
}
sortOrder++;
}
}
private string GetPrefixedCacheKey(int dataTypeId)
{
return CacheKeys.DataTypePreValuesCacheKey + dataTypeId + "-";
}
private PreValueCollection GetAndCachePreValueCollection(int dataTypeId)
{
//go get the data
var dtos = Database.Fetch<DataTypePreValueDto>("WHERE datatypeNodeId = @Id", new { Id = dataTypeId });
var list = dtos.Select(x => new Tuple<PreValue, string, int>(new PreValue(x.Id, x.Value), x.Alias, x.SortOrder)).ToList();
var collection = PreValueConverter.ConvertToPreValuesCollection(list);
//now create the cache key, this needs to include all pre-value ids so that we can use this cached item in the GetPreValuesAsString method
//the key will be: "UmbracoPreValDATATYPEID-CSVOFPREVALIDS
var key = GetPrefixedCacheKey(dataTypeId)
+ string.Join(",", collection.FormatAsDictionary().Select(x => x.Value.Id).ToArray());
//store into cache
_cacheHelper.RuntimeCache.InsertCacheItem(key, () => collection,
//30 mins
new TimeSpan(0, 0, 30),
//sliding is true
true);
return collection;
}
/// <summary>
/// Private class to handle pre-value crud based on units of work with transactions
/// </summary>
private class PreValueEntity : Entity, IAggregateRoot
{
public string Value { get; set; }
public string Alias { get; set; }
public IDataTypeDefinition DataType { get; set; }
public int SortOrder { get; set; }
}
/// <summary>
/// Private class to handle pre-value crud based on standard principles and units of work with transactions
/// </summary>
private class DataTypePreValueRepository : PetaPocoRepositoryBase<int, PreValueEntity>
{
public DataTypePreValueRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache) : base(work, cache)
{
}
#region Not implemented (don't need to for the purposes of this repo)
protected override PreValueEntity PerformGet(int id)
{
throw new NotImplementedException();
}
protected override IEnumerable<PreValueEntity> PerformGetAll(params int[] ids)
{
throw new NotImplementedException();
}
protected override IEnumerable<PreValueEntity> PerformGetByQuery(IQuery<PreValueEntity> query)
{
throw new NotImplementedException();
}
protected override Sql GetBaseQuery(bool isCount)
{
throw new NotImplementedException();
}
protected override string GetBaseWhereClause()
{
throw new NotImplementedException();
}
protected override IEnumerable<string> GetDeleteClauses()
{
return new List<string>();
}
protected override Guid NodeObjectTypeId
{
get { throw new NotImplementedException(); }
}
#endregion
protected override void PersistDeletedItem(PreValueEntity entity)
{
Database.Execute(
"DELETE FROM cmsDataTypePreValues WHERE id=@Id",
new { Id = entity.Id });
}
protected override void PersistNewItem(PreValueEntity entity)
{
if (entity.DataType.HasIdentity == false)
{
throw new InvalidOperationException("Cannot insert a pre value for a data type that has no identity");
}
//Cannot add a duplicate alias
var exists = Database.ExecuteScalar<int>(@"SELECT COUNT(*) FROM cmsDataTypePreValues
WHERE alias = @alias
AND datatypeNodeId = @dtdid",
new { alias = entity.Alias, dtdid = entity.DataType.Id });
if (exists > 0)
{
throw new DuplicateNameException("A pre value with the alias " + entity.Alias + " already exists for this data type");
}
var dto = new DataTypePreValueDto
{
DataTypeNodeId = entity.DataType.Id,
Value = entity.Value,
SortOrder = entity.SortOrder,
Alias = entity.Alias
};
Database.Insert(dto);
}
protected override void PersistUpdatedItem(PreValueEntity entity)
{
if (entity.DataType.HasIdentity == false)
{
throw new InvalidOperationException("Cannot update a pre value for a data type that has no identity");
}
//Cannot change to a duplicate alias
var exists = Database.ExecuteScalar<int>(@"SELECT COUNT(*) FROM cmsDataTypePreValues
WHERE alias = @alias
AND datatypeNodeId = @dtdid
AND id <> @id",
new { id = entity.Id, alias = entity.Alias, dtdid = entity.DataType.Id });
if (exists > 0)
{
throw new DuplicateNameException("A pre value with the alias " + entity.Alias + " already exists for this data type");
}
var dto = new DataTypePreValueDto
{
DataTypeNodeId = entity.DataType.Id,
Id = entity.Id,
Value = entity.Value,
SortOrder = entity.SortOrder,
Alias = entity.Alias
};
Database.Update(dto);
}
}
internal static class PreValueConverter
{
/// <summary>
/// Converts the tuple to a pre-value collection
/// </summary>
/// <param name="list"></param>
/// <returns></returns>
internal static PreValueCollection ConvertToPreValuesCollection(IEnumerable<Tuple<PreValue, string, int>> list)
{
//now we need to determine if they are dictionary based, otherwise they have to be array based
var dictionary = new Dictionary<string, PreValue>();
//need to check all of the keys, if there's only one and it is empty then it's an array
var keys = list.Select(x => x.Item2).Distinct().ToArray();
if (keys.Length == 1 && keys[0].IsNullOrWhiteSpace())
{
return new PreValueCollection(list.OrderBy(x => x.Item3).Select(x => x.Item1));
}
foreach (var item in list
.OrderBy(x => x.Item3) //we'll order them first so we maintain the order index in the dictionary
.GroupBy(x => x.Item2)) //group by alias
{
if (item.Count() > 1)
{
//if there's more than 1 item per key, then it cannot be a dictionary, just return the array
return new PreValueCollection(list.OrderBy(x => x.Item3).Select(x => x.Item1));
}
dictionary.Add(item.Key, item.First().Item1);
}
return new PreValueCollection(dictionary);
}
}
}
}
@@ -50,6 +50,8 @@ namespace Umbraco.Core.Persistence.Repositories
foreach (var textDto in dto.LanguageTextDtos)
{
var language = _languageRepository.Get(textDto.LanguageId);
if (language == null)
continue;
var translationFactory = new DictionaryTranslationFactory(dto.UniqueId, language);
list.Add(translationFactory.BuildEntity(textDto));
}
@@ -66,15 +66,31 @@ namespace Umbraco.Core.Persistence.Repositories
{
bool isContent = objectTypeId == new Guid(Constants.ObjectTypes.Document);
bool isMedia = objectTypeId == new Guid(Constants.ObjectTypes.Media);
var sql = GetBaseWhere(GetBase, isContent, isMedia, objectTypeId, key).Append(GetGroupBy(isContent, isMedia));
var nodeDto = _work.Database.FirstOrDefault<dynamic>(sql);
if (nodeDto == null)
return null;
var factory = new UmbracoEntityFactory();
var entity = factory.BuildEntityFromDynamic(nodeDto);
var sql = GetFullSqlForEntityType(key, isContent, isMedia, objectTypeId);
if (isMedia)
{
//for now treat media differently
//TODO: We should really use this methodology for Content/Members too!! since it includes properties and ALL of the dynamic db fields
var entities = _work.Database.Fetch<dynamic, UmbracoPropertyDto, UmbracoEntity>(
new UmbracoEntityRelator().Map, sql);
return entity;
return entities.FirstOrDefault();
}
else
{
var nodeDto = _work.Database.FirstOrDefault<dynamic>(sql);
if (nodeDto == null)
return null;
var factory = new UmbracoEntityFactory();
var entity = factory.BuildEntityFromDynamic(nodeDto);
return entity;
}
}
public virtual IUmbracoEntity Get(int id)
@@ -94,16 +110,31 @@ namespace Umbraco.Core.Persistence.Repositories
{
bool isContent = objectTypeId == new Guid(Constants.ObjectTypes.Document);
bool isMedia = objectTypeId == new Guid(Constants.ObjectTypes.Media);
var sql = GetBaseWhere(GetBase, isContent, isMedia, objectTypeId, id).Append(GetGroupBy(isContent, isMedia));
var nodeDto = _work.Database.FirstOrDefault<dynamic>(sql);
if (nodeDto == null)
return null;
var sql = GetFullSqlForEntityType(id, isContent, isMedia, objectTypeId);
if (isMedia)
{
//for now treat media differently
//TODO: We should really use this methodology for Content/Members too!! since it includes properties and ALL of the dynamic db fields
var entities = _work.Database.Fetch<dynamic, UmbracoPropertyDto, UmbracoEntity>(
new UmbracoEntityRelator().Map, sql);
var factory = new UmbracoEntityFactory();
var entity = factory.BuildEntityFromDynamic(nodeDto);
return entities.FirstOrDefault();
}
else
{
var nodeDto = _work.Database.FirstOrDefault<dynamic>(sql);
if (nodeDto == null)
return null;
return entity;
var factory = new UmbracoEntityFactory();
var entity = factory.BuildEntityFromDynamic(nodeDto);
return entity;
}
}
public virtual IEnumerable<IUmbracoEntity> GetAll(Guid objectTypeId, params int[] ids)
@@ -119,8 +150,8 @@ namespace Umbraco.Core.Persistence.Repositories
{
bool isContent = objectTypeId == new Guid(Constants.ObjectTypes.Document);
bool isMedia = objectTypeId == new Guid(Constants.ObjectTypes.Media);
var sql = GetBaseWhere(GetBase, isContent, isMedia, string.Empty, objectTypeId).Append(GetGroupBy(isContent, isMedia));
var sql = GetFullSqlForEntityType(isContent, isMedia, objectTypeId, string.Empty);
var factory = new UmbracoEntityFactory();
if (isMedia)
@@ -166,24 +197,28 @@ namespace Umbraco.Core.Persistence.Repositories
bool isMedia = objectTypeId == new Guid(Constants.ObjectTypes.Media);
var wheres = string.Concat(" AND ", string.Join(" AND ", ((Query<IUmbracoEntity>)query).WhereClauses()));
var sqlClause = GetBaseWhere(GetBase, isContent, isMedia, wheres, objectTypeId);
var translator = new SqlTranslator<IUmbracoEntity>(sqlClause, query);
var sql = translator.Translate().Append(GetGroupBy(isContent, isMedia));
var entitySql = translator.Translate();
var factory = new UmbracoEntityFactory();
if (isMedia)
{
var mediaSql = GetFullSqlForMedia(entitySql.Append(GetGroupBy(isContent, true, false)), wheres);
//treat media differently for now
//TODO: We should really use this methodology for Content/Members too!! since it includes properties and ALL of the dynamic db fields
var entities = _work.Database.Fetch<dynamic, UmbracoPropertyDto, UmbracoEntity>(
new UmbracoEntityRelator().Map, sql);
new UmbracoEntityRelator().Map, mediaSql);
return entities;
}
else
{
//use dynamic so that we can get ALL properties from the SQL so we can chuck that data into our AdditionalData
var dtos = _work.Database.Fetch<dynamic>(sql);
var dtos = _work.Database.Fetch<dynamic>(entitySql.Append(GetGroupBy(isContent, false)));
return dtos.Select(factory.BuildEntityFromDynamic).Cast<IUmbracoEntity>().ToList();
}
}
@@ -193,6 +228,62 @@ namespace Umbraco.Core.Persistence.Repositories
#region Sql Statements
protected Sql GetFullSqlForEntityType(Guid key, bool isContent, bool isMedia, Guid objectTypeId)
{
var entitySql = GetBaseWhere(GetBase, isContent, isMedia, objectTypeId, key);
if (isMedia == false) return entitySql.Append(GetGroupBy(isContent, false));
return GetFullSqlForMedia(entitySql.Append(GetGroupBy(isContent, true, false)));
}
protected Sql GetFullSqlForEntityType(int id, bool isContent, bool isMedia, Guid objectTypeId)
{
var entitySql = GetBaseWhere(GetBase, isContent, isMedia, objectTypeId, id);
if (isMedia == false) return entitySql.Append(GetGroupBy(isContent, false));
return GetFullSqlForMedia(entitySql.Append(GetGroupBy(isContent, true, false)));
}
protected Sql GetFullSqlForEntityType(bool isContent, bool isMedia, Guid objectTypeId, string additionalWhereClause)
{
var entitySql = GetBaseWhere(GetBase, isContent, isMedia, additionalWhereClause, objectTypeId);
if (isMedia == false) return entitySql.Append(GetGroupBy(isContent, false));
return GetFullSqlForMedia(entitySql.Append(GetGroupBy(isContent, true, false)));
}
private Sql GetFullSqlForMedia(Sql entitySql, string additionWhereStatement = "")
{
//this will add any dataNvarchar property to the output which can be added to the additional properties
var joinSql = new Sql()
.Select("contentNodeId, versionId, dataNvarchar, dataNtext, propertyEditorAlias, alias as propertyTypeAlias")
.From<PropertyDataDto>()
.InnerJoin<NodeDto>()
.On<PropertyDataDto, NodeDto>(dto => dto.NodeId, dto => dto.NodeId)
.InnerJoin<PropertyTypeDto>()
.On<PropertyTypeDto, PropertyDataDto>(dto => dto.Id, dto => dto.PropertyTypeId)
.InnerJoin<DataTypeDto>()
.On<PropertyTypeDto, DataTypeDto>(dto => dto.DataTypeId, dto => dto.DataTypeId)
.Where("umbracoNode.nodeObjectType = @nodeObjectType" + additionWhereStatement, new {nodeObjectType = Constants.ObjectTypes.Media});
//We're going to create a query to query against the entity SQL
// because we cannot group by nText columns and we have a COUNT in the entitySql we cannot simply left join
// the entitySql query, we have to join the wrapped query to get the ntext in the result
var wrappedSql = new Sql("SELECT * FROM (")
.Append(entitySql)
.Append(new Sql(") tmpTbl LEFT JOIN ("))
.Append(joinSql)
.Append(new Sql(") as property ON id = property.contentNodeId"))
.OrderBy("sortOrder");
return wrappedSql;
}
protected virtual Sql GetBase(bool isContent, bool isMedia, string additionWhereStatement = "")
{
var columns = new List<object>
@@ -221,13 +312,9 @@ namespace Umbraco.Core.Persistence.Repositories
columns.Add("contenttype.isContainer");
}
if (isMedia)
{
columns.Add("property.dataNvarchar as umbracoFile");
columns.Add("property.propertyEditorAlias");
}
//Creates an SQL query to return a single row for the entity
var sql = new Sql()
var entitySql = new Sql()
.Select(columns.ToArray())
.From("umbracoNode umbracoNode")
.LeftJoin("umbracoNode parent").On("parent.parentID = umbracoNode.id");
@@ -235,7 +322,7 @@ namespace Umbraco.Core.Persistence.Repositories
if (isContent || isMedia)
{
sql.InnerJoin("cmsContent content").On("content.nodeId = umbracoNode.id")
entitySql.InnerJoin("cmsContent content").On("content.nodeId = umbracoNode.id")
.LeftJoin("cmsContentType contenttype").On("contenttype.nodeId = content.contentType")
.LeftJoin(
"(SELECT nodeId, versionId FROM cmsDocument WHERE published = 1 GROUP BY nodeId, versionId) as published")
@@ -245,18 +332,7 @@ namespace Umbraco.Core.Persistence.Repositories
.On("umbracoNode.id = latest.nodeId");
}
if (isMedia)
{
sql.LeftJoin(
"(SELECT contentNodeId, versionId, dataNvarchar, propertyEditorAlias FROM cmsPropertyData " +
"INNER JOIN umbracoNode ON cmsPropertyData.contentNodeId = umbracoNode.id " +
"INNER JOIN cmsPropertyType ON cmsPropertyType.id = cmsPropertyData.propertytypeid " +
"INNER JOIN cmsDataType ON cmsPropertyType.dataTypeId = cmsDataType.nodeId "+
"WHERE umbracoNode.nodeObjectType = '" + Constants.ObjectTypes.Media + "'" + additionWhereStatement + ") as property")
.On("umbracoNode.id = property.contentNodeId");
}
return sql;
return entitySql;
}
protected virtual Sql GetBaseWhere(Func<bool, bool, string, Sql> baseQuery, bool isContent, bool isMedia, string additionWhereStatement, Guid nodeObjectType)
@@ -298,7 +374,7 @@ namespace Umbraco.Core.Persistence.Repositories
return sql;
}
protected virtual Sql GetGroupBy(bool isContent, bool isMedia)
protected virtual Sql GetGroupBy(bool isContent, bool isMedia, bool includeSort = true)
{
var columns = new List<object>
{
@@ -324,19 +400,18 @@ namespace Umbraco.Core.Persistence.Repositories
columns.Add("contenttype.thumbnail");
columns.Add("contenttype.isContainer");
}
var sql = new Sql()
.GroupBy(columns.ToArray());
if (isMedia)
if (includeSort)
{
columns.Add("property.dataNvarchar");
columns.Add("property.propertyEditorAlias");
sql = sql.OrderBy("umbracoNode.sortOrder");
}
var sql = new Sql()
.GroupBy(columns.ToArray())
.OrderBy("umbracoNode.sortOrder");
return sql;
}
#endregion
/// <summary>
@@ -377,15 +452,21 @@ namespace Umbraco.Core.Persistence.Repositories
[ResultColumn]
public List<UmbracoPropertyDto> UmbracoPropertyDtos { get; set; }
}
[ExplicitColumns]
internal class UmbracoPropertyDto
{
[Column("propertyEditorAlias")]
public string PropertyEditorAlias { get; set; }
[Column("umbracoFile")]
public string UmbracoFile { get; set; }
[Column("propertyTypeAlias")]
public string PropertyAlias { get; set; }
[Column("dataNvarchar")]
public string NVarcharValue { get; set; }
[Column("dataNtext")]
public string NTextValue { get; set; }
}
/// <summary>
@@ -412,16 +493,15 @@ namespace Umbraco.Core.Persistence.Repositories
// Is this the same UmbracoEntity as the current one we're processing
if (Current != null && Current.Key == a.uniqueID)
{
// Yes, just add this UmbracoProperty to the current UmbracoEntity's collection
if (Current.UmbracoProperties == null)
// Add this UmbracoProperty to the current additional data
Current.AdditionalData[p.PropertyAlias] = new UmbracoEntity.EntityProperty
{
Current.UmbracoProperties = new List<UmbracoEntity.UmbracoProperty>();
}
Current.UmbracoProperties.Add(new UmbracoEntity.UmbracoProperty
{
PropertyEditorAlias = p.PropertyEditorAlias,
Value = p.UmbracoFile
});
PropertyEditorAlias = p.PropertyEditorAlias,
Value = p.NTextValue.IsNullOrWhiteSpace()
? p.NVarcharValue
: p.NTextValue.ConvertToJsonIfPossible()
};
// Return null to indicate we're not done with this UmbracoEntity yet
return null;
}
@@ -437,14 +517,13 @@ namespace Umbraco.Core.Persistence.Repositories
Current = _factory.BuildEntityFromDynamic(a);
//add the property/create the prop list if null
Current.UmbracoProperties = new List<UmbracoEntity.UmbracoProperty>
{
new UmbracoEntity.UmbracoProperty
{
PropertyEditorAlias = p.PropertyEditorAlias,
Value = p.UmbracoFile
}
};
Current.AdditionalData[p.PropertyAlias] = new UmbracoEntity.EntityProperty
{
PropertyEditorAlias = p.PropertyEditorAlias,
Value = p.NTextValue.IsNullOrWhiteSpace()
? p.NVarcharValue
: p.NTextValue.ConvertToJsonIfPossible()
};
// Return the now populated previous UmbracoEntity (or null if first time through)
return prev;
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Xml.Linq;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Persistence.Querying;
@@ -37,5 +38,26 @@ namespace Umbraco.Core.Persistence.Repositories
/// <param name="entityId"></param>
/// <returns></returns>
IEnumerable<EntityPermission> GetPermissionsForEntity(int entityId);
/// <summary>
/// Used to add/update published xml for the content item
/// </summary>
/// <param name="content"></param>
/// <param name="xml"></param>
void AddOrUpdateContentXml(IContent content, Func<IContent, XElement> xml);
/// <summary>
/// Used to remove the content xml for a content item
/// </summary>
/// <param name="content"></param>
void DeleteContentXml(IContent content);
/// <summary>
/// Used to add/update preview xml for the content item
/// </summary>
/// <param name="content"></param>
/// <param name="xml"></param>
void AddOrUpdatePreviewXml(IContent content, Func<IContent, XElement> xml);
}
}
@@ -1,9 +1,15 @@
using Umbraco.Core.Models;
using System.Collections.Generic;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
{
public interface IDataTypeDefinitionRepository : IRepositoryQueryable<int, IDataTypeDefinition>
{
PreValueCollection GetPreValuesCollectionByDataTypeId(int dataTypeId);
string GetPreValueAsString(int preValueId);
void AddOrUpdatePreValues(IDataTypeDefinition dataType, IDictionary<string, PreValue> values);
void AddOrUpdatePreValues(int dataTypeId, IDictionary<string, PreValue> values);
}
}
@@ -1,8 +1,25 @@
using Umbraco.Core.Models;
using System;
using System.Xml.Linq;
using Umbraco.Core.Models;
namespace Umbraco.Core.Persistence.Repositories
{
public interface IMediaRepository : IRepositoryVersionable<int, IMedia>
{
/// <summary>
/// Used to add/update published xml for the media item
/// </summary>
/// <param name="content"></param>
/// <param name="xml"></param>
void AddOrUpdateContentXml(IMedia content, Func<IMedia, XElement> xml);
/// <summary>
/// Used to add/update preview xml for the content item
/// </summary>
/// <param name="content"></param>
/// <param name="xml"></param>
void AddOrUpdatePreviewXml(IMedia content, Func<IMedia, XElement> xml);
}
}
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Xml.Linq;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Querying;
@@ -54,5 +55,19 @@ namespace Umbraco.Core.Persistence.Repositories
Sql sql, int pageIndex, int pageSize, out int totalRecords,
Func<IEnumerable<TDto>, int[]> resolveIds);
/// <summary>
/// Used to add/update published xml for the media item
/// </summary>
/// <param name="content"></param>
/// <param name="xml"></param>
void AddOrUpdateContentXml(IMember content, Func<IMember, XElement> xml);
/// <summary>
/// Used to add/update preview xml for the content item
/// </summary>
/// <param name="content"></param>
/// <param name="xml"></param>
void AddOrUpdatePreviewXml(IMember content, Func<IMember, XElement> xml);
}
}
@@ -5,6 +5,10 @@ namespace Umbraco.Core.Persistence.Repositories
{
public interface ITagsRepository : IRepositoryQueryable<int, ITag>
{
IEnumerable<TaggedEntity> GetTaggedEntitiesByTagGroup(TaggableObjectTypes objectType, string tagGroup);
IEnumerable<TaggedEntity> GetTaggedEntitiesByTag(TaggableObjectTypes objectType, string tag, string tagGroup = null);
/// <summary>
/// Returns all tags for an entity type (content/media/member)
/// </summary>
@@ -33,7 +33,7 @@ namespace Umbraco.Core.Persistence.Repositories
var sql = GetBaseQuery(false);
sql.Where(GetBaseWhereClause(), new { Id = id });
var languageDto = Database.First<LanguageDto>(sql);
var languageDto = Database.FirstOrDefault<LanguageDto>(sql);
if (languageDto == null)
return null;
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Xml.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
using Umbraco.Core.Models;
@@ -21,6 +22,8 @@ namespace Umbraco.Core.Persistence.Repositories
{
private readonly IMediaTypeRepository _mediaTypeRepository;
private readonly ITagsRepository _tagRepository;
private readonly ContentXmlRepository<IMedia> _contentXmlRepository;
private readonly ContentPreviewRepository<IMedia> _contentPreviewRepository;
public MediaRepository(IDatabaseUnitOfWork work, IMediaTypeRepository mediaTypeRepository, ITagsRepository tagRepository)
: base(work)
@@ -29,7 +32,8 @@ namespace Umbraco.Core.Persistence.Repositories
if (tagRepository == null) throw new ArgumentNullException("tagRepository");
_mediaTypeRepository = mediaTypeRepository;
_tagRepository = tagRepository;
_contentXmlRepository = new ContentXmlRepository<IMedia>(work, NullCacheProvider.Current);
_contentPreviewRepository = new ContentPreviewRepository<IMedia>(work, NullCacheProvider.Current);
EnsureUniqueNaming = true;
}
@@ -40,7 +44,8 @@ namespace Umbraco.Core.Persistence.Repositories
if (tagRepository == null) throw new ArgumentNullException("tagRepository");
_mediaTypeRepository = mediaTypeRepository;
_tagRepository = tagRepository;
_contentXmlRepository = new ContentXmlRepository<IMedia>(work, NullCacheProvider.Current);
_contentPreviewRepository = new ContentPreviewRepository<IMedia>(work, NullCacheProvider.Current);
EnsureUniqueNaming = true;
}
@@ -137,12 +142,12 @@ namespace Umbraco.Core.Persistence.Repositories
"DELETE FROM umbracoRelation WHERE parentId = @Id",
"DELETE FROM umbracoRelation WHERE childId = @Id",
"DELETE FROM cmsTagRelationship WHERE nodeId = @Id",
"DELETE FROM cmsDocument WHERE NodeId = @Id",
"DELETE FROM cmsDocument WHERE nodeId = @Id",
"DELETE FROM cmsPropertyData WHERE contentNodeId = @Id",
"DELETE FROM cmsPreviewXml WHERE nodeId = @Id",
"DELETE FROM cmsContentVersion WHERE ContentId = @Id",
"DELETE FROM cmsContentXml WHERE nodeID = @Id",
"DELETE FROM cmsContent WHERE NodeId = @Id",
"DELETE FROM cmsContentXml WHERE nodeId = @Id",
"DELETE FROM cmsContent WHERE nodeId = @Id",
"DELETE FROM umbracoNode WHERE id = @Id"
};
return list;
@@ -181,6 +186,22 @@ namespace Umbraco.Core.Persistence.Repositories
return media;
}
public void AddOrUpdateContentXml(IMedia content, Func<IMedia, XElement> xml)
{
var contentExists = Database.ExecuteScalar<int>("SELECT COUNT(nodeId) FROM cmsContentXml WHERE nodeId = @Id", new { Id = content.Id }) != 0;
_contentXmlRepository.AddOrUpdate(new ContentXmlEntity<IMedia>(contentExists, content, xml));
}
public void AddOrUpdatePreviewXml(IMedia content, Func<IMedia, XElement> xml)
{
var previewExists =
Database.ExecuteScalar<int>("SELECT COUNT(nodeId) FROM cmsPreviewXml WHERE nodeId = @Id AND versionId = @Version",
new { Id = content.Id, Version = content.Version }) != 0;
_contentPreviewRepository.AddOrUpdate(new ContentPreviewEntity<IMedia>(previewExists, content, xml));
}
protected override void PerformDeleteVersion(int id, Guid versionId)
{
Database.Delete<PreviewXmlDto>("WHERE nodeId = @Id AND versionId = @VersionId", new { Id = id, VersionId = versionId });
@@ -299,7 +320,7 @@ namespace Umbraco.Core.Persistence.Repositories
Database.Update(newContentDto);
}
//In order to update the ContentVersion we need to retreive its primary key id
//In order to update the ContentVersion we need to retrieve its primary key id
var contentVerDto = Database.SingleOrDefault<ContentVersionDto>("WHERE VersionId = @Version", new { Version = entity.Version });
dto.Id = contentVerDto.Id;
//Updates the current version - cmsContentVersion
@@ -403,4 +424,4 @@ namespace Umbraco.Core.Persistence.Repositories
return currentName;
}
}
}
}
@@ -134,7 +134,7 @@ namespace Umbraco.Core.Persistence.Repositories
"DELETE FROM cmsContentType2ContentType WHERE childContentTypeId = @Id",
"DELETE FROM cmsPropertyType WHERE contentTypeId = @Id",
"DELETE FROM cmsPropertyTypeGroup WHERE contenttypeNodeId = @Id",
"DELETE FROM cmsContentType WHERE NodeId = @Id",
"DELETE FROM cmsContentType WHERE nodeId = @Id",
"DELETE FROM umbracoNode WHERE id = @Id"
};
return list;

Some files were not shown because too many files have changed in this diff Show More