Compare commits

...

465 Commits

Author SHA1 Message Date
perploug 5f1c69bc13 Stops tinymce from converting absolute urls 2013-10-11 13:12:21 +02:00
Stephan 4740e5f0c7 Merge remote-tracking branch 'origin/7.0.0' into 7.0.0 2013-10-11 12:28:56 +02:00
Stephan 4b36dcc13b Fix bug after merge 2013-10-11 12:28:31 +02:00
perploug b92f5c4719 ui.xml file changes 2013-10-11 12:19:39 +02:00
perploug 11441fb1b1 ui.xml release files 2013-10-11 12:16:24 +02:00
perploug 377879d081 Merge branch '7.0.0' of https://github.com/umbraco/Umbraco-CMS into 7.0.0 2013-10-11 12:13:29 +02:00
perploug 738cc81439 fixes membersearch returning no results 2013-10-11 12:12:29 +02:00
Sebastiaan Janssen 14ba484fc1 Don't include release configs in final package 2013-10-11 12:11:47 +02:00
Stephan 0f894da7a6 Merge remote-tracking branch 'origin/7.0.0-pubcontent' into 7.0.0 2013-10-11 12:07:26 +02:00
Stephan 52640a94ee Fix tests after merge 2013-10-11 12:05:52 +02:00
perploug 133e2fdba7 tree config updates 2013-10-11 11:48:26 +02:00
perploug e6ef1c2506 header error message 2013-10-11 11:43:57 +02:00
Stephan 7718adfca1 Merge remote-tracking branch 'origin/7.0.0' into 7.0.0-pubcontent
Conflicts:
	src/Umbraco.Core/Models/DataTypeDefinition.cs
	src/Umbraco.Core/Umbraco.Core.csproj
	src/Umbraco.Web/Security/Providers/MembersMembershipProvider.cs
	src/umbraco.providers/members/MembersMembershipProvider.cs
2013-10-11 11:11:18 +02:00
perploug afe3ace32e Merge branch '7.0.0' of https://github.com/umbraco/Umbraco-CMS into 7.0.0 2013-10-11 10:54:50 +02:00
perploug 9a0679d41c docs update 2013-10-11 10:54:39 +02:00
Sebastiaan Janssen a54b2297c7 Changed version to beta 2013-10-11 10:51:12 +02:00
Stephan 871e390c5e U4-3094 - Fix GetPropertyValue returned type in DynamicPublishedContent 2013-10-11 10:28:16 +02:00
Stephan 34875855db U4-3095 - Fix IPublishedContent navigation axes 2013-10-11 10:27:49 +02:00
Tim Geyssens 6c0fb765f0 Related links prop editor: fixes issue in view 2013-10-11 10:25:11 +02:00
Stephan 69367e0cda Merge remote-tracking branch 'origin/6.2.0-pubcontent' into 7.0.0-pubcontent
Conflicts:
	src/Umbraco.Core/Models/DataTypeDefinition.cs
	src/Umbraco.Core/Persistence/Repositories/Interfaces/IMemberRepository.cs
	src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs
	src/Umbraco.Core/Properties/AssemblyInfo.cs
	src/Umbraco.Core/Umbraco.Core.csproj
	src/Umbraco.Tests/TestHelpers/BaseWebTest.cs
	src/Umbraco.Web/Security/Providers/MembersMembershipProvider.cs
	src/umbraco.providers/members/MembersMembershipProvider.cs
2013-10-11 10:24:24 +02:00
Stephan 15bbe1b829 PublishedContentModel - keep it internal for now 2013-10-11 10:10:19 +02:00
perploug f95ec4d8f4 Merge branch '7.0.0' of https://github.com/umbraco/Umbraco-CMS into 7.0.0 2013-10-11 09:47:57 +02:00
perploug 4a6f0a791e Multinode treepicker now supports media,content,members + search 2013-10-11 09:47:36 +02:00
Tim Geyssens 3779ba38cb Related links prop editor: make sure value is saved 2013-10-11 09:47:11 +02:00
Shannon 2c6eeb7193 changes order of migrations 2013-10-11 18:40:54 +11:00
Shannon 6c5849cca9 adds new db indexes 2013-10-11 18:40:37 +11:00
Stephan 671b94dd06 PublishedContentModel - keep it internal for now 2013-10-11 09:24:26 +02:00
Stephan bc9dc911ed Merge remote-tracking branch 'origin/6.2.0' into 6.2.0-pubcontent 2013-10-11 09:24:06 +02:00
Stephan cc8298d83c U4-2606 - List registered types in a ManyObject resolver 2013-10-11 09:22:48 +02:00
Shannon 42dd48a3d1 removed editmember.aspx 2013-10-11 17:32:04 +11:00
Shannon d97a98f45d Updates the macro tag parser to not care about the class - if it ever gets stripped again it won't matter on the server side. 2013-10-11 17:28:50 +11:00
Shannon 8d892bd099 Fixes: U4-3093 RTE doesnt pre-render macros 2013-10-11 17:18:14 +11:00
Shannon 886ab32f27 Streamlines both insert macro and change password forms. 2013-10-11 16:20:10 +11:00
Shannon 937b308444 Streamlines form and form validation with new val-form-manager (replaces a couple of other directives). Fixes styling on the umb-content-name, removes the test MyPackage stuff from app-plugins. 2013-10-11 15:44:49 +11:00
Shannon ee4c0cbfc3 Streamlines how forms (editors) work with a new formHelper, this reduces much of the repetitive code and also ensures that the correct events fire, this will be the start of streamlining how all forms work - even simple ones. 2013-10-11 14:11:25 +11:00
Shannon 3ba9f87d93 Simplifies the editors and file manager service so they don't have to manually clear the files, this is now done automatically on route change. 2013-10-11 13:20:37 +11:00
Shannon 626f21aecd changes controller code to use contentId scope var 2013-10-11 13:08:12 +11:00
Shannon 2f6637dcc4 Removes the editorContextService - there is zero reason to have this and it will also mean that the content item that is being stored is never released from memory. Changes form event names to formSubmitting and formSubmitted 2013-10-11 13:05:09 +11:00
Shannon 21de6dfd00 Fixes the DataTypeDefinition - addition data ctor 2013-10-11 12:43:57 +11:00
Shannon a3b0714a9d Fixes the tab error styles - ensures all tab styles are in one place - tab errors should *not* show up until form is submitted. 2013-10-11 12:37:58 +11:00
Shannon b9975ad1f5 Gets password resetting working and displaying the generated one in the UI. 2013-10-11 12:25:10 +11:00
Shannon b63135771e Got more member reset password working based on the provider config. 2013-10-11 11:44:48 +11:00
Shannon bc828176d1 Merge remote-tracking branch 'origin/6.2.0' into 7.0.0
Conflicts:
	src/Umbraco.Core/Models/DataTypeDefinition.cs
	src/Umbraco.Core/Persistence/Repositories/Interfaces/IMemberRepository.cs
	src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs
	src/Umbraco.Core/Properties/AssemblyInfo.cs
	src/Umbraco.Core/Umbraco.Core.csproj
	src/Umbraco.Web/Security/Providers/MembersMembershipProvider.cs
	src/umbraco.providers/members/MembersMembershipProvider.cs
2013-10-11 11:02:35 +11:00
Shannon 13dcfbbd2b Fixes build - removes .net 4.5 reference of EmailAddressAttribute - we'll leave that in for v7 when targettng 4.5 2013-10-11 10:58:31 +11:00
perploug 3d8138f3ef Added configuration to the multinode picker 2013-10-10 21:15:04 +02:00
perploug e67f85695c fixes U4-3054 icon picker viewstate 2013-10-10 19:47:12 +02:00
perploug 088253ebfd minor content editor tweaks 2013-10-10 19:46:46 +02:00
perploug dc542a4ae7 Moved help section into context-sensitive modal 2013-10-10 19:46:15 +02:00
perploug 219a46f736 mocked conten path 2013-10-10 19:44:18 +02:00
perploug 7599a68c90 tree sync actually works now 2013-10-10 19:44:06 +02:00
perploug a5522188ca contentpicker dialog polish 2013-10-10 19:43:34 +02:00
perploug 36bc2473bf handles parent.right.documet js references 2013-10-10 19:43:15 +02:00
perploug abf8aa7ea3 tinymce valid elements config 2013-10-10 19:42:41 +02:00
perploug e0da6f2dec remove old membersearch 2013-10-10 19:41:41 +02:00
Stephan 8a8b09141f Merge remote-tracking branch 'origin/7.0.0' into 7.0.0-pubcontent
Conflicts:
	src/Umbraco.Tests/TestHelpers/BaseWebTest.cs
	src/Umbraco.Web.UI/Umbraco/create/PartialView.ascx
	src/Umbraco.Web.UI/Umbraco/create/PartialView.ascx.designer.cs
	src/Umbraco.Web.UI/packages.config
	src/Umbraco.Web.UI/umbraco/config/create/UI.xml
	src/Umbraco.Web/Umbraco.Web.csproj
	src/Umbraco.Web/UmbracoHelper.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/create/DLRScripting.ascx
	src/Umbraco.Web/umbraco.presentation/umbraco/create/PartialViewTasks.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/create/xslt.ascx
2013-10-10 16:15:23 +02:00
Stephan 18ea5b3768 Merge remote-tracking branch 'origin/6.2.0' into 6.2.0-pubcontent
Conflicts:
	src/Umbraco.Tests/TestHelpers/BaseWebTest.cs
2013-10-10 15:52:09 +02:00
perploug 0e392843dd Adds search field to standard content picker 2013-10-10 14:33:25 +02:00
perploug faaa408201 ultrasimple picker stub 2013-10-10 14:09:57 +02:00
perploug 9514654ca4 wrong tree root link 2013-10-10 14:09:31 +02:00
perploug e34e63db51 hides empty divs on initial load 2013-10-10 13:34:02 +02:00
perploug c6c07b3861 missing char 2013-10-10 13:33:42 +02:00
perploug 6f39f190a4 Adds guid to entitybasic 2013-10-10 13:33:25 +02:00
perploug e2c06852d5 adds "overload" to member editor so it can accept a member ID 2013-10-10 13:32:53 +02:00
perploug f45d25c09a minor member docs update 2013-10-10 13:32:31 +02:00
perploug 2ec96a9123 fixes search menu urls 2013-10-10 13:32:18 +02:00
perploug 2cea2e1b41 Merge branch '7.0.0' of https://github.com/umbraco/Umbraco-CMS into 7.0.0 2013-10-10 12:44:11 +02:00
perploug 59f711f802 memberpicker search updates 2013-10-10 12:43:59 +02:00
perploug 0d4ee6e5d1 fix missing data annotations reference 2013-10-10 12:43:48 +02:00
Shannon f9319c0db9 Lots more work done with members mostly around passwords and membership provider - can't yet update your password but it's close 2013-10-10 20:56:30 +11:00
Shannon 3ff4930e8a Properly exposes the IRememberBeingDirty.ResetDirtyProperties required method 2013-10-10 19:03:59 +11:00
Shannon ee3fb3745c Merge branch '7.0.0' of https://github.com/umbraco/Umbraco-CMS into 7.0.0 2013-10-10 18:46:55 +11:00
Shannon b512376c5c more member editor updates 2013-10-10 18:46:28 +11:00
perploug d97ae3fbd2 Merge branch '7.0.0' of https://github.com/umbraco/Umbraco-CMS into 7.0.0 2013-10-10 08:52:40 +02:00
perploug a3e4eaa2e4 membersearch support 2013-10-10 08:51:55 +02:00
perploug a2df4ea742 support for fetching a specific tree 2013-10-10 08:51:46 +02:00
perploug 79f7ea60f2 Memberpicker search field 2013-10-10 08:51:25 +02:00
Shannon 52aac5ba10 Ok, got members creating so long as the umbraco membership provider is being used - otherwise currenlty you'll get a ysod saying we don't support that. Now to get updating working. 2013-10-10 17:44:56 +11:00
Shannon 63a4e00f52 tweaks to membership providers so if we cast we can specify the member type. 2013-10-10 17:23:29 +11:00
Shannon 5df30ac0cc tweaks to membership providers so if we cast we can specify the member type. 2013-10-10 17:22:57 +11:00
Shannon cb8c1a31cb Fixes/updates more of the member repository and related items
Conflicts:
	src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs
2013-10-10 16:50:57 +11:00
Shannon 8ad4ee4e58 Fixes/updates more of the member repository and related items 2013-10-10 16:48:02 +11:00
Shannon 6c77749e32 Fixes: U4-3077 No id "xxxx" exists in dictionary 2013-10-10 15:45:52 +11:00
Shannon 4170713e29 More member service and provider updates
Conflicts:
	src/Umbraco.Core/Persistence/Repositories/Interfaces/IMemberRepository.cs
	src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs
2013-10-10 14:51:01 +11:00
Shannon 8917a5ad92 More member service and provider updates 2013-10-10 14:50:25 +11:00
Shannon 49110ffaf7 Changes the legacy membership provider to use the custom member converter which works like the legacy one used to - the new extension method isn't quite there yet. 2013-10-10 14:13:21 +11:00
Shannon a3bca42117 updates UmbracoMembershipMember 2013-10-10 14:10:28 +11:00
Shannon 7919a39bb6 updates UmbracoMembershipMember 2013-10-10 14:10:04 +11:00
Shannon 80488e012f Fixes up and implements more if the IMemberService, repository and membership providers (both legacy and what seems to be the new one). 2013-10-10 14:00:35 +11:00
Shannon 0856173c9c Merge remote-tracking branch 'origin/7.0.0' into 7.0.0 2013-10-10 13:41:11 +11:00
Shannon 98832357bf Lots of work on the member editor - creates new email address prop editor, allows text prop editor to be required based on config, fixes the section directive bug, creating change password prop ed, streamlines more of the services layer to ensure that the things that need to be public are public 2013-10-10 13:41:06 +11:00
Shannon 0843388a41 Fixes up and implements more if the IMemberService, repository and membership providers (both legacy and what seems to be the new one). 2013-10-10 13:39:17 +11:00
Shannon 71e6ea70b2 Updates member repository and tests to ensure that an existing password will not be replaced if the password specified is null or empty. 2013-10-10 12:22:38 +11:00
Shannon a87b37d6ca Cleans up more of the IContentService and ensures that we have PublishStatus returned from the publishing methods instead of hiding them internally. 2013-10-10 09:35:23 +11:00
Tim Geyssens 0594bafa5b Member picker prop editor: more WIP 2013-10-09 16:39:53 +02:00
perploug 2214916fed Merge branch '7.0.0' of https://github.com/umbraco/Umbraco-CMS into 7.0.0 2013-10-09 15:55:45 +02:00
perploug 8618947d62 fixes non-working content picker 2013-10-09 15:55:30 +02:00
perploug 912a111f14 broken da.xml file 2013-10-09 15:54:18 +02:00
Tim Geyssens 47c7f9bfda Member picker prop editor: More WIP 2013-10-09 15:29:02 +02:00
Tim Geyssens d844c33a2d Member picker prop editor: Adds stubs 2013-10-09 15:15:21 +02:00
perploug fac71dfd11 Merge killed the listview namespace 2013-10-09 15:12:43 +02:00
perploug 1e6b80e45e Merge branch '7.0.0' of https://github.com/umbraco/Umbraco-CMS into 7.0.0
Conflicts:
	src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js
2013-10-09 15:10:51 +02:00
perploug 31d3b88a5b dictionary tree icons 2013-10-09 15:07:17 +02:00
perploug de14a6dad7 labels for localization support 2013-10-09 15:07:09 +02:00
perploug e3102cf95b style updates 2013-10-09 15:06:36 +02:00
perploug ce97350d76 listview bugfixes 2013-10-09 15:06:21 +02:00
perploug a5b597e2f7 localized tree names 2013-10-09 15:05:52 +02:00
perploug 2b76d4b22d Adds publishById method to contentController 2013-10-09 15:05:27 +02:00
perploug d7b732ba4b working clientside localization 2013-10-09 15:05:05 +02:00
perploug 2d3cf3da23 section mapper 2013-10-09 15:04:30 +02:00
perploug 2ff5b63089 RTE now works without a provided configuration 2013-10-09 15:04:05 +02:00
Shannon 530f88aa11 Changes how the property and tab validation is notified about validation changes - we use a new directive on the parent form to notify child changes, this is much better for performance so we don't have multiple $watches. This also fixes the tab validation since watching $invalid on a form for some reason isn't always accurate. 2013-10-09 23:16:09 +11:00
Shannon c42e957c4c fixes unit tests 2013-10-09 20:36:12 +11:00
Shannon 659cba563a Changes property editor controller namespace to be PropertyEditors instead of just Editors 2013-10-09 20:02:39 +11:00
Shannon d255b3a6a3 Merge branch '7.0.0' of https://github.com/umbraco/Umbraco-CMS into 7.0.0 2013-10-09 19:54:08 +11:00
Shannon ba7713fb93 Auto selects all text in the header if it is still empty 2013-10-09 19:53:29 +11:00
Sebastiaan Janssen d5498cc66e Merge branch '7.0.0' of https://github.com/umbraco/Umbraco-CMS into 7.0.0 2013-10-09 10:45:43 +02:00
Sebastiaan Janssen a023ddb76b Fix json.net NuGet problem 2013-10-09 10:44:54 +02:00
Shannon f7c49758e1 Fixes more of the umbcontentname directive - but we still have no design to show a validation message 2013-10-09 19:42:41 +11:00
Shannon 95a834b8b6 Started creating the member create dialog - but really we should just do this like content/media will save this revision since it was a nice form :) 2013-10-09 19:08:03 +11:00
Shannon 5d71e08922 Fixes manifest file again - just tested that the app loads even if a manifest is invalid 2013-10-09 18:22:27 +11:00
Shannon e51b43084b Fixes: U4-2762 Handle errors in package.manifest & fixes manifest stylesheet parsing with unit test 2013-10-09 18:13:24 +11:00
Shannon f299fe76e4 fixes localization with empty recycle bin menu 2013-10-09 17:35:16 +11:00
Shannon 128cceaf91 Fixes: U4-3045 Can't empty recycle bin with unit tests 2013-10-09 17:32:13 +11:00
Shannon ccedd6757b removes cascade deletes for upgrade since we do not support these for install currently and we want to make sure they are the same... and i don' thave time to implement that. 2013-10-09 16:26:43 +11:00
Shannon a94f61702f Changes plugin folder convention to use sub folder BackOffice instead of umbraco 2013-10-09 16:08:39 +11:00
Shannon 2b2cf48fdb Implements HideLabel for property editor value editors for both c# and manifest declarations. 2013-10-09 16:06:07 +11:00
Shannon 858135175e Completes: U4-2956 Update all services with correct public methods/properties 2013-10-09 15:21:01 +11:00
Shannon de8b69a399 Creates public IApplicationTreeService and ISectionService interfaces, adds initialization methods 2013-10-09 14:31:30 +11:00
Shannon 27e6e9b91c removes duplicate declaration 2013-10-09 13:52:44 +11:00
Shannon 1c13a896eb Fixes up merge issues. 2013-10-09 13:52:24 +11:00
Shannon f8d6c85779 Merge remote-tracking branch 'origin/6.2.0' into 7.0.0
Conflicts:
	src/Umbraco.Core/ApplicationContext.cs
	src/Umbraco.Core/Models/ContentBase.cs
	src/Umbraco.Core/Models/ContentTypeBase.cs
	src/Umbraco.Core/Models/DataTypeDefinition.cs
	src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs
	src/Umbraco.Core/Persistence/RepositoryFactory.cs
	src/Umbraco.Core/Services/IMemberTypeService.cs
	src/Umbraco.Core/Services/MemberTypeService.cs
	src/Umbraco.Core/Services/ServiceContext.cs
	src/Umbraco.Tests/Routing/uQueryGetNodeIdByUrlTests.cs
2013-10-09 13:41:14 +11:00
Shannon 09b7186713 Completes: U4-2963 Updated EntityService / IUmbracoEntity to have a dictionary to fill additional data - fixes merge issues and explicitly implements interface for entities that are not UmbracoEntity and hides other implementations from intellisense. 2013-10-09 13:32:58 +11:00
Shannon c6389852ea Adds public ctors for ApplicationContext, ServiceContext, DatabaseContext, RepositoryFactory, makes IDatabaseFactory public, makes an interfaces for IEntityService, adds EnsureContext methods for ApplicationContext - to set the singleton. 2013-10-09 13:17:19 +11:00
Shannon 49f10ccd32 Fixes merge issue , fixes the ServiceContext lazy fields to be the underlying interfaces, adds public ctor 2013-10-09 12:18:42 +11:00
Shannon a8b037f2e0 Fixes member type repository when member types don't have properties declared and adds tests. Adds IMemberTypeService.
Conflicts:
	src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs
	src/Umbraco.Core/Services/ServiceContext.cs
2013-10-09 12:09:28 +11:00
Shannon 3c38b335a6 Converts DlrScripting & xslt to the correct webforms structure. 2013-10-09 12:07:50 +11:00
Shannon 3a8bbcc8fc Fixes up the PartialView, PartialViewMacro and Xslt create dialogs after merge and ensures PartialView dialog is up to v7 legacy standard 2013-10-09 11:57:14 +11:00
Shannon 1ecb864e5f Fixed umbsections directive - do not make any requests until the user is logged in - if they are already logged in, the event still executes. 2013-10-09 11:29:41 +11:00
Shannon d281f97659 Merge remote-tracking branch 'origin/6.2.0' into 7.0.0
Conflicts:
	src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
	src/Umbraco.Web.UI/Umbraco/create/PartialView.ascx
	src/Umbraco.Web.UI/Umbraco/create/PartialView.ascx.designer.cs
	src/Umbraco.Web.UI/packages.config
	src/Umbraco.Web.UI/umbraco/config/create/UI.xml
	src/Umbraco.Web.UI/umbraco/create/DLRScripting.ascx
	src/Umbraco.Web.UI/umbraco/create/xslt.ascx
	src/Umbraco.Web/Umbraco.Web.csproj
	src/Umbraco.Web/UmbracoHelper.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/create/DLRScripting.ascx
	src/Umbraco.Web/umbraco.presentation/umbraco/create/PartialViewTasks.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/create/xslt.ascx
2013-10-09 11:12:33 +11:00
Shannon 38761e1413 started on member create dialog (wip!) 2013-10-09 11:01:43 +11:00
Sebastiaan Janssen f85f418d52 We need Json.Net v5+ 2013-10-08 20:41:54 +02:00
Sebastiaan Janssen 0184b396be Whoops! Left a weird linebreak in there 2013-10-08 19:08:30 +02:00
Sebastiaan Janssen 8b2e2f8447 Create appSettings.config / connectionString.config if they don't exist yet 2013-10-08 19:00:57 +02:00
Sebastiaan Janssen 2fc8244f71 Fix NuGet package creation 2013-10-08 19:00:24 +02:00
perploug 7c5b6851a1 Added standard js libs to usercontrol proxy 2013-10-08 15:29:53 +02:00
perploug a2ebb1b06f support for loading actions directly from search results 2013-10-08 15:04:47 +02:00
perploug 196ce492be Section menu overflow detection and extra tray 2013-10-08 13:18:42 +02:00
Stephan a5848a17c5 Commit missing files after merge 2013-10-08 11:22:33 +02:00
Stephan 31535e3bd8 Merge remote-tracking branch 'origin/6.2.0-pubcontent' into 7.0.0-pubcontent
Conflicts:
	src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
	src/Umbraco.Web.UI/Umbraco/create/PartialView.ascx
	src/Umbraco.Web.UI/Umbraco/create/PartialView.ascx.designer.cs
	src/Umbraco.Web.UI/packages.config
	src/Umbraco.Web.UI/umbraco/config/create/UI.xml
	src/Umbraco.Web.UI/umbraco/create/DLRScripting.ascx
	src/Umbraco.Web.UI/umbraco/create/xslt.ascx
	src/Umbraco.Web/Umbraco.Web.csproj
	src/Umbraco.Web/UmbracoHelper.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/create/DLRScripting.ascx
	src/Umbraco.Web/umbraco.presentation/umbraco/create/PartialViewTasks.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/create/xslt.ascx
2013-10-08 11:21:38 +02:00
perploug dfc3e468c4 fixes: U4-3046 rollback dialog 2013-10-08 11:07:42 +02:00
perploug 90ec849b5f adding tree states css 2013-10-08 10:35:13 +02:00
perploug 30f147a9d3 excluding appsettings and connectionstrings config 2013-10-08 10:27:22 +02:00
Stephan e7a238b2bc Merge remote-tracking branch 'origin/7.0.0' into 7.0.0-pubcontent 2013-10-08 09:48:11 +02:00
Stephan 17c055472d Merge remote-tracking branch 'origin/6.2.0' into 6.2.0-pubcontent 2013-10-08 09:44:37 +02:00
perploug dd4827493b missing files in sln 2013-10-08 09:31:30 +02:00
Shannon 572e23d307 Adds methods to IMemberTypeService 2013-10-08 17:58:38 +11:00
Shannon febff1560e Added member type controller and resource, started getting creating members dialog working. 2013-10-08 17:49:40 +11:00
Shannon 7b14e8eacc Fixes member type repository when member types don't have properties declared and adds tests. Adds IMemberTypeService. 2013-10-08 17:47:29 +11:00
Shannon 881d922f30 Adds another overload for GetBigThumbnail, adds better thumbnail err checking to the folder browser thing and updates the file uploader to use this thumbnail proxy, now upgrades should be good. 2013-10-08 16:20:22 +11:00
Shannon 8b358da2f0 Creates big thumbnail proxy on the MediaController, now to wire it up with the folder browser and upload controls 2013-10-08 15:58:37 +11:00
Shannon 19d96ac0e2 ensures the lsit is created for styles. 2013-10-08 13:02:46 +11:00
Shannon 3a33a39411 Adds node styles and ensures they are set for the content tree nodes, now to get them to display styles 2013-10-08 12:58:11 +11:00
Shannon 883a662240 Moves tree/menu models into the Models.Trees namespace 2013-10-08 12:38:27 +11:00
Shannon e6908c7678 Adds tag support to member repository. 2013-10-08 12:29:56 +11:00
Shannon 0b8b413f2f Adds tag support for any IContentBase and to the MediaRepository, adds test to ensure tags relations are removed. 2013-10-08 12:25:03 +11:00
Shannon 38a5b49ea3 renames methods on ITagsRepository to make it clear that the tags repo/db table ONLY deals with published tags. 2013-10-08 12:07:08 +11:00
Shannon 6a43972267 Adds content service tests for tags 2013-10-08 12:05:24 +11:00
Shannon d102db795e Adds better compatibility for the legacy data layer and the ToXMl method - using our new xml converter. 2013-10-08 11:22:08 +11:00
Shannon 6f2a7180d8 Adds new ConvertDbToXml converter on the PropertyValueConverter and simplifies the ToXml method for PropertyExtensions. 2013-10-08 11:08:36 +11:00
Shannon 6cec665f7d Renames the PropertyValueEditor converter methods to be inline with the new converter method names 2013-10-08 10:58:47 +11:00
Shannon d0cd8ba346 Moves GetPath to EntityController and entityResource since all entities can have a path not just content. 2013-10-08 10:55:47 +11:00
Shannon 16bce4248d Fixes merge issues with 6.2 and copying across TempData properly. 2013-10-08 10:46:02 +11:00
Shannon a2e9ec0412 Merge remote-tracking branch 'origin/6.1.6' into 6.2.0
Conflicts:
	src/Umbraco.Web/Mvc/UmbracoPageResult.cs
2013-10-08 10:37:46 +11:00
Shandem 11c9abf359 Merge pull request #145 from florisrobbemont/6.1.6
U4-3007 RouteDefinition should not store instance of controller
2013-10-07 16:31:50 -07:00
perploug 4b942dcc32 Working link picker and TinyMCE plugin 2013-10-07 15:15:02 +02:00
Sebastiaan Janssen 12b7a9d874 Argh, didn't save csproj file before committing. 2013-10-07 13:20:34 +02:00
perploug ec4eeb5de6 tree syncing 2013-10-07 10:09:03 +02:00
perploug f676ce6ac2 Remove missing file to unbreak build 2013-10-07 10:08:48 +02:00
perploug aa0bb166a8 Merge branch '7.0.0' of https://github.com/umbraco/Umbraco-CMS into 7.0.0 2013-10-07 10:08:28 +02:00
perploug 60a81ac879 Allows legacy editors to sync the tree 2013-10-07 09:48:08 +02:00
perploug a9bc67538d Fixes: U4-3000 2013-10-07 09:39:25 +02:00
perploug c0a7a9a427 adds section alias to framed urls 2013-10-07 09:33:29 +02:00
Sebastiaan Janssen df909983db Update NuGet Core dependency to AutoMapper 3+ 2013-10-07 08:37:33 +02:00
Sebastiaan Janssen 1a9e5f20a8 U4-2511 Locallink:NODEID not working 2013-10-07 08:36:26 +02:00
Sebastiaan Janssen a90f32035d U4-2733 call to umbraco.library:Request broken? 2013-10-07 08:18:44 +02:00
Sebastiaan Janssen 33b09c80aa Forgot to commit csproj file 2013-10-06 18:55:52 +02:00
Sebastiaan Janssen b2980cedc6 Also apply to media types - U4-541 Wrong dictionary key when using in backend template names 2013-10-06 18:54:46 +02:00
Sebastiaan Janssen 34b7f86b8b U4-541 Wrong dictionary key when using in backend template names 2013-10-06 18:24:46 +02:00
Sebastiaan Janssen 130f6d3a42 Additions for U4-2776 Default Content For A Razor Layout Section 2013-10-06 17:52:46 +02:00
Sebastiaan Janssen 3ff9d6adbc U4-2509 Umbraco backend search not working correctly with spaces - Also updated search.aspx dialog 2013-10-06 16:55:54 +02:00
Sebastiaan Janssen fd5de171c9 Merge branch '6.2.0' of github.com:umbraco/Umbraco-CMS into 6.2.0 2013-10-06 16:45:31 +02:00
Sebastiaan Janssen 45ad51b8df U4-2737 Snippets that are available when creating new MacroScripts should also be available for Partial Views 2013-10-06 16:45:21 +02:00
Floris Robbemont b02657f32c Cleaning up commit for issue U4-3007
Changed documentation on UmbracoMvcHandler
2013-10-05 23:31:02 +02:00
Sebastiaan Janssen 9f3784aaed U4-1242 Template editor sometimes stops editing. 2013-10-05 19:26:01 +02:00
Sebastiaan Janssen 2ab2a5a9f3 Fix bug where Right ALT+S would save in Firefox instead of inserting the correct character 2013-10-05 19:23:57 +02:00
Sebastiaan Janssen 2d83ba06a5 Fix small styling issues in installer 2013-10-05 19:18:11 +02:00
Sebastiaan Janssen 06d5c60803 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-10-05 19:09:49 +02:00
Sebastiaan Janssen fe18722e1f Merge pull request #147 from AndyButland/u4-2958
Fix for issue U4-2958 Member can edit & Show on profile do not persist on Member Type editor
2013-10-05 19:08:03 +02:00
Stephan c2e7fc2f10 PropertyValueConverter - add converters for built-in data types 2013-10-04 20:14:38 +02:00
Stephan e31dd688bf Merge remote-tracking branch 'origin/7.0.0' into 7.0.0-pubcontent
Conflicts:
	src/Umbraco.Core/Umbraco.Core.csproj
2013-10-04 14:54:18 +02:00
perploug 5060dab7a5 adds getpath to contentController 2013-10-04 14:01:07 +02:00
perploug c8fa22c767 Tree can now sync, only need to bridge it with the old legacy umbClient calls 2013-10-04 14:00:43 +02:00
perploug 418a29cbbf Odd, missing config files crashed the site 2013-10-04 11:18:57 +02:00
perploug 0b907d4ae3 more work on link picker, added dialog service and views 2013-10-04 10:53:07 +02:00
perploug 765ed9687a Merge branch '7.0.0' of https://github.com/umbraco/Umbraco-CMS into 7.0.0 2013-10-04 09:37:09 +02:00
perploug 66e7a6322a Start on link picker for RTE 2013-10-04 09:36:53 +02:00
Sebastiaan Janssen b595ec4d88 Merge pull request #149 from bjawnie/patch-1
Made two minor corrections to the text
2013-10-04 00:25:59 -07:00
Shannon 7425e070d2 Got the SetTags and RemoveTags methods in place and working. 2013-10-04 17:13:57 +10:00
Shannon 3cb70f67c9 TagsRepository is all working with unit tests, now to make the service and integrate the extension methods. 2013-10-04 16:11:51 +10:00
Shannon a029d98209 Adds db index to cmsTags over tag/group 2013-10-04 14:35:51 +10:00
Shannon db6b8930ab Removes appsettings,connectionstring configs from the repo and adds them to the ignore list. 2013-10-04 12:18:05 +10:00
Shannon 4d8a3f4453 Updated the proj file to create the appSettings, connectionString config files if they are missing, then we also ignore these files and remove them from the repo - just like the web.config 2013-10-04 12:15:35 +10:00
Shannon f1f5374b81 Fixed that damn upgrade checker to not throw exceptions 2013-10-04 11:05:19 +10:00
Shannon 961928105c Moves connectionStrings to external file, now to figure out how to deal with both of these files with multiple devs 2013-10-04 10:53:22 +10:00
Shannon c6229f131a Moves appSettings to external file and updates the code that modifies the app settings. 2013-10-04 10:34:00 +10:00
Shannon ff3aebd4b1 Completes: U4-2893 Remove the entire umbraco.macroRenderings assembly 2013-10-04 10:01:57 +10:00
Shannon ad6e4ae745 Adds ability to use the c# property name as the pre-value field key, adds examples of declaring pre-value fields. 2013-10-04 09:22:07 +10:00
Shannon b462082ed9 Fixes up some naming conventions and removes need to instantiate another umbraco helper 2013-10-04 09:00:02 +10:00
perploug 95f120e98f Unpublishing button on the content editor 2013-10-03 22:18:44 +02:00
perploug a42bd4dbf0 Merge branch '7.0.0' of https://github.com/umbraco/Umbraco-CMS into 7.0.0 2013-10-03 20:59:04 +02:00
perploug 21d6209793 Removing unussed libraries, moving legacy tinymce plugins 2013-10-03 20:58:47 +02:00
perploug 9ee1584ede Initial PublishedContent service for niceUrl access 2013-10-03 20:58:16 +02:00
perploug a3d77b7e72 Adds RTE and stylesheet services 2013-10-03 20:57:36 +02:00
perploug 14e1e741ed Added configuration fetching to tinymce service 2013-10-03 20:53:34 +02:00
perploug 94f72b3938 minor log.resource docs update 2013-10-03 20:53:16 +02:00
bjawnie 20ab14beb4 Made two minor corrections to the texts.
"Content>alias" changed to "Alternativ link" from "Alias", so it makes more sense.

"defaultdialogs>treepicker" changed to "Vælg" from "Vælg punkt", so it fits in the button.
2013-10-03 20:43:42 +02:00
Stephan e14e5bee95 Merge remote-tracking branch 'origin/7.0.0' into 7.0.0-pubcontent
Conflicts:
	src/Umbraco.Tests/CodeFirst/ContentTypeMapper.cs
	src/Umbraco.Web/Models/DynamicPublishedContent.cs
2013-10-03 18:49:58 +02:00
Stephan 9e1364db42 Merge remote-tracking branch 'origin/6.2.0' into 7.0.0 2013-10-03 18:48:42 +02:00
Stephan 1902bc4807 Merge remote-tracking branch 'origin/7.0.0' into 7.0.0-pubcontent 2013-10-03 18:17:35 +02:00
Stephan a264342bcc Merge remote-tracking branch 'origin/6.2.0' into 6.2.0-pubcontent
Conflicts:
	src/Umbraco.Tests/CodeFirst/ContentTypeMapper.cs
	src/Umbraco.Web/Models/DynamicPublishedContent.cs
2013-10-03 18:16:29 +02:00
Stephan 08660704cc Core.StringExtensions - adjust to new default IShortStringHelper (see f64b8d6) 2013-10-03 18:10:51 +02:00
Stephan 4c13dbf8b7 Core.StringExtensions - fix methods that should be extension methods 2013-10-03 18:10:50 +02:00
Stephan 9a10863760 Core.EnumerableExtensions - bugfix f9663a9 2013-10-03 18:10:48 +02:00
Tim Geyssens 74e414d858 Related links prop editor WIP 2013-10-03 16:46:32 +02:00
Tim Geyssens 6a1072e918 Related links prop editor: more WIP 2013-10-03 15:09:52 +02:00
Tim Geyssens fb1ea4b880 Related links prop editor: more work 2013-10-03 14:58:12 +02:00
Tim Geyssens cbe566302c Related links prop editor: first attempt at UI 2013-10-03 14:20:13 +02:00
Tim Geyssens 4ace6e10db Related links prop editor: adds RelatedLinksPropertyEditor.cs 2013-10-03 13:27:13 +02:00
Tim Geyssens bd32c7cc4a Related links prop editor: adds controller / view stubs 2013-10-03 13:05:13 +02:00
Shannon 25a0c595e7 Fixes up the DashboardController to use the new configuration classes, creates DashboardSecurity (which needs some unit testing) and removes all that ugly code. 2013-10-03 19:00:31 +10:00
Shannon 3d3be5ecbc Renames Control to DashboardControl so it has some meaning. 2013-10-03 17:59:23 +10:00
Shannon 1730005a58 Updates web.config template and transform for new dashboard section. 2013-10-03 17:54:10 +10:00
Shannon b9257fceeb New dashboard config classes all tested 2013-10-03 17:50:42 +10:00
Shannon e2f9b1c7d9 Got the dashboard config section classes working with tests, now to add more tests 2013-10-03 17:17:53 +10:00
Shannon 03b1c9e5ee Fixed build issue, started adding dashboard config section as real .net section. 2013-10-03 17:06:58 +10:00
Shannon 85098b84f7 started proxying events to the old tree but think it should be done opposite. 2013-10-03 15:57:32 +10:00
Shannon 936be3934b Updated MenuItemCollection with MenuItemList for full featured List access to the items. Added the MenuRendering event to TreeController, updated the tree controller events to be TypedEventHandler's though developers will need to cast the TreeController to the type they are expecting - still better than 'object'. 2013-10-03 15:05:48 +10:00
Shannon ed8f22c371 Completes: U4-2829 Allow for JSON objects to be saved/retrieved by property editors - OH YEAH!! 2013-10-03 13:52:33 +10:00
Shannon 969abb5057 Fixes merge issues 2013-10-03 12:53:26 +10:00
Shannon 21c0152131 Merge remote-tracking branch 'origin/6.2.0' into 7.0.0
Conflicts:
	src/Umbraco.Tests/BusinessLogic/BaseTest.cs
	src/Umbraco.Web.UI/install/steps/theend.ascx
	src/Umbraco.Web.UI/umbraco/Default.aspx
	src/Umbraco.Web.UI/umbraco/controls/GenericProperties/GenericProperty.ascx
	src/Umbraco.Web.UI/umbraco/developer/Xslt/editXslt.aspx
	src/Umbraco.Web.UI/umbraco/dialogs/ChangeDocType.aspx
	src/Umbraco.Web.UI/umbraco/umbraco.aspx
	src/Umbraco.Web/UmbracoContext.cs
	src/Umbraco.Web/umbraco.presentation/LegacyClasses.cs
	src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/LegacyClasses.cs
	src/Umbraco.Web/umbraco.presentation/install/steps/LegacyClasses.cs
	src/Umbraco.Web/umbraco.presentation/library.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/LiveEditing/Controls/LiveEditingToolbar.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/LiveEditing/Modules/CreateModule/CreateModule.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/LiveEditing/Modules/DeleteModule/DeleteModule.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/LiveEditing/Modules/MacroModule/MacroModule.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/LiveEditing/Modules/SkinModule/ImageUploader.aspx.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/LiveEditing/Modules/SkinModule/SkinCustomizer.ascx.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/LiveEditing/Modules/SkinModule/SkinModule.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/LiveEditing/Modules/UnpublishModule/UnpublishModule.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadTemplates.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/controls/macroParameterControl.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/create/DLRScripting.ascx.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/create/DLRScriptingTasks.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/create/MediaTypeTasks.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/create/ScriptTasks.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/create/contentTasks.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/create/mediaTasks.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/dashboard.aspx.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/developer/DataTypes/editDatatype.aspx.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/login.aspx.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/settings/editTemplate.aspx.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/umbraco.aspx.cs
	src/Umbraco.Web/umbraco.presentation/umbracobase/baseHttpModule.cs
	src/Umbraco.Web/umbraco.presentation/umbracobase/restExtension.cs
	src/umbraco.businesslogic/Utils/TypeFinder.cs
	src/umbraco.cms/businesslogic/Packager/Installer.cs
	src/umbraco.cms/businesslogic/Packager/PackageActions/addRestExtension.cs
	src/umbraco.cms/businesslogic/Packager/PackageActions/addXsltExtension.cs
	src/umbraco.cms/businesslogic/skinning/Skin.cs
	src/umbraco.cms/businesslogic/skinning/tasks/AddStyleSheetToTemplate.cs
	src/umbraco.cms/businesslogic/skinning/tasks/ModifyCss.cs
	src/umbraco.cms/businesslogic/skinning/tasks/ModifyTemplate.cs
	src/umbraco.controls/CodeArea.cs
	src/umbraco.controls/ProgressBar.cs
	src/umbraco.editorControls/macrocontainer/Editor.cs
2013-10-03 12:51:46 +10:00
Shannon 86430f1b01 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-10-03 12:46:01 +10:00
Shannon 55247fe31d Finally got around to changing all calls to umbraco.IO to Umbraco.Core.IO - that'll clear up several hundreds of warnings :) 2013-10-03 12:45:40 +10:00
Shannon 6ac724951b Explicitly adds automapper to the UI proj so we don't get that strange YSOD that says it's not there sometimes. 2013-10-03 12:18:21 +10:00
Shannon b0dfc90557 Added docs on creating trees and view path location conventions. 2013-10-03 12:11:22 +10:00
Shannon b09a743beb Gets view paths to load in dynamically based on whether a core or plugin tree is rendering, this allows us to store view files based on conventions for packages. Completes: U4-2849 Ensure editor views, etc... can exist outside of the /umbraco folder for package devs 2013-10-03 11:25:26 +10:00
Shannon 2ed4206f93 Merge remote-tracking branch 'origin/6.2.0' into 7.0.0
Conflicts:
	src/Umbraco.Web/WebBootManager.cs
2013-10-03 09:01:24 +10:00
Shandem a806f40093 Merge pull request #146 from mortenbock/6.2.0
Custom ProfilingViewEngine
2013-10-02 15:53:58 -07:00
perploug 4283734a94 Merge branch '7.0.0' of https://github.com/umbraco/Umbraco-CMS into 7.0.0 2013-10-02 19:23:57 +02:00
perploug 6c20815210 Initial commit of rte prevalue editor 2013-10-02 19:23:36 +02:00
perploug a371ebe841 Progressbart convert to css3 from gif 2013-10-02 19:23:20 +02:00
perploug 92a32a8f8d rollback dialog polish 2013-10-02 19:23:04 +02:00
perploug bb1a47aa81 Permissions dialog polish 2013-10-02 19:22:54 +02:00
perploug 6126a52156 child action icon alignment tweak 2013-10-02 19:22:34 +02:00
mortenbock 24020cfea3 Make sure the profilingengine doesn't wrap itself 2013-10-02 18:30:59 +02:00
Stephan 1b2f0246e8 Oops, fix build 2013-10-02 18:00:02 +02:00
mortenbock 9ec30860b0 Wrap all ViewEngines in a profiler
Wrap all ViewEngines in a custom profiler view engine, using the
ProfilerResolver to track performance
2013-10-02 17:48:44 +02:00
Stephan 19784e04bf Merge remote-tracking branch 'origin/6.2.0-pubcontent' into 7.0.0-pubcontent
Conflicts:
	src/Umbraco.Core/ObjectResolution/Resolution.cs
2013-10-02 17:42:59 +02:00
Stephan 3ee4399fca Merge remote-tracking branch 'origin/6.2.0' into 7.0.0
Conflicts:
	src/Umbraco.Core/ObjectResolution/Resolution.cs
2013-10-02 17:40:03 +02:00
Stephan 06206c60d9 Merge remote-tracking branch 'origin/6.2.0' into 6.2.0-pubcontent 2013-10-02 17:06:46 +02:00
Stephan 5937a7e976 CoreXml - fix tests CRLF issues for build server, take 2 2013-10-02 17:03:50 +02:00
Stephan f64b8d680d Core.StringExtensions - switch over to the new DefaultShortStringHelper 2013-10-02 16:54:56 +02:00
Stephan f9663a9e80 Core.EnumerableExtensions - refactor InGroupsOf to enumerate source only once 2013-10-02 16:54:47 +02:00
Stephan c604cc5c2f CoreXml - fix tests CRLF issues for build server 2013-10-02 16:39:54 +02:00
Shannon dc42c1ebb7 More work on streamlining package development for views and conventions. 2013-10-02 21:03:51 +10:00
Shannon 92efd6d645 Got menu items working with external packages to look for views by convention inside of their package folder. 2013-10-02 20:48:15 +10:00
Shannon 6560865f61 Fixed view path conventions for menu items 2013-10-02 20:20:02 +10:00
Shannon 8f53bea3d7 Merge branch '7.0.0' of https://github.com/umbraco/Umbraco-CMS into 7.0.0 2013-10-02 20:00:34 +10:00
Shannon 89f7a31bef Updates the Create/AddMenu overloads to ensure a name is specified, fixes all localization of all menu items for all new trees. 2013-10-02 20:00:01 +10:00
Stephan 424b8cd408 Merge remote-tracking branch 'origin/7.0.0' into 7.0.0-pubcontent 2013-10-02 11:49:23 +02:00
Stephan 65898411e7 Core.Resolution - umbraco.cms.Action should NOT reset resolution 2013-10-02 11:48:50 +02:00
Stephan 759a3619ca Core.Resolution - fix concurrency issues 2013-10-02 11:48:30 +02:00
Stephan 520ebc3394 Merge remote-tracking branch 'origin/6.2.0' into 6.2.0-pubcontent 2013-10-02 11:43:10 +02:00
Stephan e6bb999d83 Core.Resolution - umbraco.cms.Action should NOT reset resolution 2013-10-02 11:42:17 +02:00
Stephan cdd1a0a4cb Core.Resolution - fix concurrency issues
Conflicts:
	src/Umbraco.Core/ObjectResolution/Resolution.cs
2013-10-02 11:41:48 +02:00
Stephan 5e0fbe5634 Macros - bugfix parameters 2013-10-02 11:16:39 +02:00
Stephan e5b3ca1907 Merge remote-tracking branch 'origin/6.2.0' into 6.2.0-pubcontent 2013-10-02 11:14:08 +02:00
Stephan efb4a6652d Merge remote-tracking branch 'origin/7.0.0' into 7.0.0-pubcontent 2013-10-02 11:11:38 +02:00
Stephan 9b43a86b94 Core.Resolution - fix concurrency issues 2013-10-02 11:09:26 +02:00
Shannon 1090248223 Merge branch '7.0.0' of https://github.com/umbraco/Umbraco-CMS into 7.0.0 2013-10-02 18:58:21 +10:00
Shannon 880077f6e9 Created TagRepository, added foreign key to cmsTags.ParentId 2013-10-02 18:57:44 +10:00
perploug ffc1b62b8a Merge branch '7.0.0' of https://github.com/umbraco/Umbraco-CMS into 7.0.0 2013-10-02 10:56:54 +02:00
perploug 17f2602ca2 icon finder now loads .icon-* from all registered stylesheets 2013-10-02 10:56:40 +02:00
perploug a71e255468 re-adds tree cache 2013-10-02 10:55:58 +02:00
perploug f2458b833e consistent create dialogs 2013-10-02 10:55:48 +02:00
perploug 2b2d986371 Content copy with relation in js layer 2013-10-02 10:55:38 +02:00
perploug 1ed21a3ffb Better font handling with correct weights 2013-10-02 10:55:20 +02:00
perploug 1f32373bd2 sample manifest with css 2013-10-02 10:54:59 +02:00
perploug 5b1c626714 Reverts meadia sort to legacy dialog 2013-10-02 10:54:37 +02:00
perploug ce30153830 Enables the manifest to load custom stylesheets outside the js loading 2013-10-02 10:54:25 +02:00
perploug 727f3a804d Removes osx shadow files 2013-10-02 10:53:12 +02:00
Shannon be7179b962 Fixed up the TagRelationshipDto to have the correct columns, keys, etc.. as our upgrade, updated the old tags API to support the new changes. 2013-10-02 17:10:12 +10:00
Shannon 7eee954d4d OOPS! didn't mean to delete this a couple days ago :P 2013-10-02 15:56:53 +10:00
Shannon 36cb078073 Tags db upgrades done, now to look at ensuring the legacy tags stuff works. 2013-10-02 15:51:02 +10:00
Shannon 8b6171bb13 Almost got the tags tables upgraded 2013-10-02 13:50:42 +10:00
Shannon 917d5b39ec Changes auth controller post login to return an normal validation response instead of 4.3 so the err msg doesn't show up. 2013-10-02 13:42:36 +10:00
Shannon 65f809a0fb chagnes IsAuthenticated to not return a 403 so the warning msg doesn't display. 2013-10-02 09:53:58 +10:00
Shannon bad4d0c6e6 fixes merge issues 2013-10-02 09:30:53 +10:00
Shannon 2a1e3dc2f8 Merge remote-tracking branch 'origin/6.2.0' into 7.0.0
Conflicts:
	src/Umbraco.Core/Persistence/Factories/MemberTypeReadOnlyFactory.cs
	src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs
	src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs
2013-10-02 09:22:33 +10:00
perploug 5199a5dc99 Move, Copy, protect, notifications dialogs polish 2013-10-02 00:11:10 +02:00
perploug 2e8a8e3623 Working move dialog, needs feedback and validation 2013-10-01 16:14:54 +02:00
perploug 1ec74a5ae8 Fixes: U4-3005 userdialog refuses to close 2013-10-01 15:51:39 +02:00
perploug 6c02eadd88 Merge branch '7.0.0' of https://github.com/umbraco/Umbraco-CMS into 7.0.0 2013-10-01 15:37:19 +02:00
perploug 60c4307f2e Fixes: u4-3009 missing context menu in search results 2013-10-01 15:37:05 +02:00
perploug e1c0e70d07 Fixes: U4-3001 missing root node in tree selectors 2013-10-01 15:36:42 +02:00
Floris Robbemont 9ddee615cc U4-3007 RouteDefinition should not store instance of controller 2013-10-01 14:09:38 +02:00
Shannon 2c88c7c971 Fixed up content tree to check for IsContainer with the new entity AdditionalData, fixes up the AddContainerView to be part of the ContentModelMapper. 2013-10-01 21:12:32 +10:00
Shannon 9e361b7669 Merge branch '7.0.0' of https://github.com/umbraco/Umbraco-CMS into 7.0.0 2013-10-01 21:02:47 +10:00
perploug e64eb05dcd adds alt+click to context menu to skip default action 2013-10-01 12:32:43 +02:00
perploug 0898638e33 Fixes: U4-2982 missing translation on contextmenu 2013-10-01 12:32:27 +02:00
perploug 5dd9510d69 Fixes: U4-2973 - View editor save button broken 2013-10-01 11:51:19 +02:00
perploug 229b770447 fixes: U4-2854 Re-adds actions on root tree nodes 2013-10-01 11:40:56 +02:00
Shannon 434e194ba7 Merge branch '7.0.0' of https://github.com/umbraco/Umbraco-CMS into 7.0.0 2013-10-01 19:38:18 +10:00
Shannon 9c96b247be Completes: U4-2963 Updated EntityService / IUmbracoEntity to have a dictionary to fill additional data 2013-10-01 19:37:51 +10:00
Morten Christensen 74f6a34651 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-10-01 10:20:29 +02:00
Morten Christensen 7dee2802fe Fixing Member and MemberType, so the ids are properly assigned through the repositories.
Adding test to assert that no Properties, PropertyTypes or PropertyGroups exists without an id when loaded from the db.
NOTE Changes signature of Member class as Email, Username and Password is required.
2013-10-01 10:20:16 +02:00
perploug 15d25ebb3d Merge branch '7.0.0' of https://github.com/umbraco/Umbraco-CMS into 7.0.0 2013-10-01 10:11:08 +02:00
perploug fbe388a616 Cleans up rte embed dialog 2013-10-01 10:10:55 +02:00
perploug 891955f164 Fixes: U4-2953 - could not load google fonts file 2013-10-01 10:10:41 +02:00
Shannon f7103c97cf Completes: U4-2768 Remove legacy/unused webforms files/classes in folder: /umbraco 2013-10-01 17:03:03 +10:00
Shannon a90e96d066 Completes: U4-2926 Remove unused/obsoleted 'tasks' for media & content 2013-10-01 16:42:32 +10:00
Shannon 4e56d88eb5 Fixes: U4-2672 Fix how trees are rendered when a start node is applied, the Content/Media titles must always be visible 2013-10-01 16:38:10 +10:00
Shannon 770514919d Gets member deleting working and adds refresh to each letter node. 2013-10-01 15:54:44 +10:00
Shannon 31a5951626 Updated member tree/editor to use the GUID 2013-10-01 15:36:08 +10:00
Shannon 76b7b131a9 Gets members saving (initially) still needs lots more work though, waiting on some feedback from morten in the meantime. 2013-10-01 15:25:04 +10:00
Shannon 4602a6b989 Fixes an issue with the MemberTypeReadOnlyFactory 2013-10-01 14:46:16 +10:00
Shannon e27a0e2bd2 updates boolean and check box list to use onValueChanged to detect any server value changes. 2013-10-01 14:16:57 +10:00
Shannon e5c7a35e8f updates g-maps editor to use onValueChanged to detect if a server val has changed. 2013-10-01 14:12:15 +10:00
Shannon 6277bc379e updates mediapicker to use onValueChanged in case the server value changes. 2013-10-01 14:10:11 +10:00
Shannon 2bb279d8f7 Ensures rte controller will re-load itself if server data has changed. 2013-10-01 14:08:14 +10:00
Shannon a8f87d6dc1 Updates mediapicker to not use jquery each methods since they are not DOM items, use underscore instead. 2013-10-01 14:07:56 +10:00
Shannon bb350035ef Fixed merge issues 2013-10-01 13:43:55 +10:00
Shannon 6f6c33a721 Merge remote-tracking branch 'origin/6.2.0' into 7.0.0
Conflicts:
	build/NuSpecs/UmbracoCms.Core.nuspec
	build/NuSpecs/UmbracoCms.nuspec
	src/Umbraco.Core/Persistence/Factories/MemberTypeReadOnlyFactory.cs
	src/Umbraco.Core/Persistence/Relators/PropertyDataRelator.cs
	src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs
	src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs
	src/Umbraco.Tests/BusinessLogic/BaseTest.cs
	src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs
	src/Umbraco.Tests/TestHelpers/TestHelper.cs
	src/Umbraco.Tests/Umbraco.Tests.csproj
2013-10-01 13:38:17 +10:00
Shannon 7451e83c73 Integrates authentication within the routes and prevents controllers from being loaded when the user isn't authorized. Ensures we also have a /login route and allows routes to redirect when auth fails. 2013-10-01 13:23:13 +10:00
Shannon 79e35d5c06 Ensures that if a user session times out and another user logs in that we redirect to root 2013-10-01 10:08:55 +10:00
Shannon 59196020bb Fixes up content controller move/copy actions 2013-10-01 10:04:07 +10:00
perploug fc1e4f959e adds container doctype lookup
TODO: find a better/faster way to do this
2013-10-01 00:54:46 +02:00
perploug 146aca31a0 Updating legacy domain, publsh and sort dialogs 2013-10-01 00:47:18 +02:00
perploug c928769911 adds container UI to doctype editor 2013-09-30 23:34:43 +02:00
perploug cdbc02354d umbracoField dialog tweaks 2013-09-30 23:34:20 +02:00
perploug bd3cdd83f6 WIP: adds move and copy methos to content contoller 2013-09-30 23:34:07 +02:00
perploug 5a757f129c Implements doctype container 2013-09-30 23:33:27 +02:00
perploug 987c4401a3 U4-2852: Fixes error messages 2013-09-30 23:32:35 +02:00
perploug dee067d071 cleans up umbfield legacy dialog 2013-09-30 21:37:35 +02:00
perploug d901f4d4f1 umb-dialog visual tweaks 2013-09-30 21:36:49 +02:00
perploug 081457ddc8 enables classes on inline modals 2013-09-30 21:36:22 +02:00
perploug 4f98a1b0c8 adds move to content.resource 2013-09-30 21:36:08 +02:00
perploug 7668c3bafa adds initial loading back to umb-tree 2013-09-30 21:35:54 +02:00
Sebastiaan Janssen 5238293c09 Merge branch '6.1.6' into 6.2.0
Conflicts:
	build/Build.bat
	src/Umbraco.Core/Configuration/UmbracoVersion.cs
	src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
	src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs
2013-09-30 16:09:25 +02:00
Sebastiaan Janssen 226e35d65a NuSpec update: we can only accept a specific version of MySQL 2013-09-30 14:32:06 +02:00
Stephan 05f7ede26a Merge branch '6.2.0-pubcontent' into 7.0.0-pubcontent
Conflicts:
	src/Umbraco.Web/umbraco.presentation/macro.cs
2013-09-30 14:12:36 +02:00
Stephan ea638c37b7 Merge remote-tracking branch 'origin/7.0.0' into 7.0.0-pubcontent
Conflicts:
	src/Umbraco.Web/UmbracoContext.cs
2013-09-30 14:05:12 +02:00
Stephan bfa7ab788b Merge remote-tracking branch 'origin/6.2.0' into 6.2.0-pubcontent 2013-09-30 14:00:01 +02:00
Stephan 5a15c93195 PublishedContent - ensure exceptions don't corrupt InPreviewMode 2013-09-30 13:58:02 +02:00
Stephan 77777c8007 Bugfix e775421 2013-09-30 13:57:58 +02:00
perploug 85e2c3e5b1 Merge branch '7.0.0' of https://github.com/umbraco/Umbraco-CMS into 7.0.0 2013-09-30 13:19:10 +02:00
perploug 47d124a41b wraps datepicker valye set in apply 2013-09-30 13:18:56 +02:00
perploug ca56539c65 Fixes U4-2980 - tabs not in the right order 2013-09-30 13:18:34 +02:00
perploug 8b25210895 adds localdata to timepicer hide event 2013-09-30 13:10:58 +02:00
perploug 9c4dc838a5 Adds number prevalue editor 2013-09-30 13:10:34 +02:00
perploug 57511b9c5a Fixes: U4-2977 legacy tabs reset to one one submit 2013-09-30 13:10:15 +02:00
Sebastiaan Janssen cdda69c4cd U4-2788 Error installing Umbraco 6.1.5 with SQL CE 4 option 2013-09-30 12:39:28 +02:00
Shannon 472ef6e48c Starts fixing: U4-2947 Fix complex property editors with $watch expressions 2013-09-30 20:33:19 +10:00
Shannon 9ff74b39f8 fixed web.config xform for debugging 2013-09-30 20:24:11 +10:00
Morten Christensen 5aa01e78ab Updating conn.string in test 2013-09-30 12:13:49 +02:00
Morten Christensen a21bee6683 Fixing MemberType- and MemberRepository so properties, property types and property groups are properly initialized. 2013-09-30 12:12:58 +02:00
Shannon 0cff484113 fixes unit test 2013-09-30 12:12:17 +02:00
Shannon 3e9afcfc41 Finishes: U4-2678 Fix logging out and then logging in as another user, the sections, etc... do not get updated. 2013-09-30 20:08:15 +10:00
Shannon 830fde372e Fixes EditUser.aspx 2013-09-30 11:49:31 +02:00
Shannon ac2a4a1e0a Fixing: U4-2678 Fix logging out and then logging in as another user, the sections, etc... do not get updated. - all event broadcasting is now centralized. 2013-09-30 19:14:30 +10:00
Shannon 5ffca11c5b Fixing: U4-2678 Fix logging out and then logging in as another user, the sections, etc... do not get updated. 2013-09-30 18:58:24 +10:00
Shannon 35f65a2c64 re-enables LoadMinimalDocument and adds this to the optimized check, even in optimized model the OnRenderNode can still execute with a minimal doc. 2013-09-30 10:55:38 +02:00
Shannon e5320f0abd Obsoletes the LoadMinimalDocument flag since it no longer serves a purpose. 2013-09-30 10:55:26 +02:00
Sebastiaan Janssen 965a7fc500 Fixes: U4-2925 Tree performance is very poor in 6.1.x when having event subscriptions 2013-09-30 10:55:13 +02:00
Sebastiaan Janssen abbf8aeb42 U4-2709 Error after upgrading from 6.1.3 to 6.1.4 2013-09-30 10:49:33 +02:00
Sebastiaan Janssen 328ada2f38 Bump version number 2013-09-30 10:46:08 +02:00
Sebastiaan Janssen 767252cdf1 Creates IDisposeOnRequestEnd and ensures UmbracoContext and UmbracoDatabase implement it, then we only dispose of these types of objects at the end of the request if they are part of the httpcontext items (U4-2738). Fixes: U4-2988 UmbracoObjectTypesExtensions is not thread safe 2013-09-30 10:31:45 +02:00
Sebastiaan Janssen 010d47c68b Fixes U4-2822 Datepicker throws "Specified cast is not valid" when saving through API 2013-09-30 10:23:43 +02:00
Shannon 56f1062db8 Fixes up EditUser - non-admins who have access to the Users app can edit other non-admins and cannot change anyone to be admin, but only admins can edit other admins that are not the root admin. Only the root admin can edit the root admin. 2013-09-30 17:28:44 +10:00
Shannon a11e947f96 Fixes: U4-2780 UserPermissions editor just YSODs 2013-09-30 17:12:31 +10:00
Shannon 0be07f467f Fixes: U4-2989 Username & password must be changed if login credentials are invalid in order to submit again. 2013-09-30 17:03:26 +10:00
Shannon 1a9ced80f9 Fixes: U4-2974 Authentication fail displays username and password 2013-09-30 16:31:52 +10:00
Shannon 33599a15a2 Fixes: U4-2952 Preview mode causes ysod - null reference 2013-09-30 16:06:56 +10:00
Shannon 42f9427e24 ignores the built in member properties for now, adds more logging to Resolution to try to figure out the underlying problem. 2013-09-30 15:42:29 +10:00
Shannon e0878fdd9f fixes unit test 2013-09-30 14:48:05 +10:00
Shannon fb3bad90d6 had to change port 9999 to 9990 because the new sony vaio admin uses 9999 2013-09-30 14:24:39 +10:00
Shannon 590838302b Merge remote-tracking branch 'origin/6.2.0' into 7.0.0-member-editor-wip
Conflicts:
	src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs
2013-09-30 14:19:12 +10:00
Shannon c9aac96c1a Fixes EditUser.aspx 2013-09-30 14:15:39 +10:00
Shannon bbdce28951 Merge remote-tracking branch 'origin/6.2.0' into 7.0.0-member-editor-wip
Conflicts:
	src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadContent.cs
2013-09-30 13:52:01 +10:00
Shannon cf6ecf5bc9 Merge remote-tracking branch 'origin/7.0.0' into 7.0.0-member-editor-wip
Conflicts:
	src/Umbraco.Web.UI/config/trees.config
2013-09-30 13:51:18 +10:00
Shannon 4df79ce55b re-enables LoadMinimalDocument and adds this to the optimized check, even in optimized model the OnRenderNode can still execute with a minimal doc. 2013-09-30 13:47:19 +10:00
Shannon 15d2021786 Obsoletes the LoadMinimalDocument flag since it no longer serves a purpose. 2013-09-30 13:36:49 +10:00
Shannon a8f6b9eeb9 Fixes: U4-2925 Tree performance is very poor in 6.1.x when having event subscriptions 2013-09-30 13:31:48 +10:00
Shannon 3d4b403c0e Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-09-30 12:02:51 +10:00
Shannon 957760d29a Creates IDisposeOnRequestEnd and ensures UmbracoContext and UmbracoDatabase implement it, then we only dispose of these types of objects at the end of the request if they are part of the httpcontext items (U4-2738). Fixes: U4-2988 UmbracoObjectTypesExtensions is not thread safe 2013-09-30 12:02:35 +10:00
Stephan 928f7a1ed0 Merge branch '6.2.0-pubcontent' into 7.0.0-pubcontent
Conflicts:
	src/Umbraco.Web/Umbraco.Web.csproj
	src/Umbraco.Web/umbraco.presentation/macro.cs
2013-09-29 16:05:52 +02:00
Stephan a7603747a6 XmlPublishedCache - 'version' is not a property 2013-09-29 15:22:39 +02:00
Stephan e7754213f1 INode to IPublishedContent transition for Razor macros 2013-09-29 15:22:35 +02:00
Stephan ea82e9c67e Web.Routing - fix PublishedContentRequest exception message 2013-09-29 15:22:31 +02:00
Stephan 182cc1ace7 Web.UmbracoHelper - add Url overload w/mode 2013-09-29 15:22:27 +02:00
Stephan 205b9889f2 Macros - PartialViewMacro use IPublishedContent, not INode 2013-09-29 15:22:23 +02:00
Stephan 4a58fbfa1d PublishedContent - add OfType<> extension to IPublishedContent 2013-09-29 15:22:19 +02:00
Stephan af534e87f3 PublishedContent - bugfix IsDraft on previewed document 2013-09-29 15:22:15 +02:00
Stephan 53c753b8d9 Fix build after merge 2013-09-28 17:11:05 +02:00
Stephan a8a2c706ba Merge branch '7.0.0' into 7.0.0-pubcontent
Conflicts:
	src/Umbraco.Core/PublishedContentHelper.cs
2013-09-27 15:59:42 +02:00
Shannon a3d674f574 Updated the saving model and validator inheritance chain to better support members, have the members editor display data and posting/validating data - now need to get the correct fields being displayed and the correct tab/layout but coming along very nicely! 2013-09-27 16:59:38 +10:00
Stephan 9a66948857 Merge pull request #141 from IDisposable/patch-1
Fix order of null-check versus dotting through to .UmbracoContext.
2013-09-26 23:29:59 -07:00
Shannon 82c784d560 Most of the member tree working, have the member editor rendering data 2013-09-27 15:19:39 +10:00
Shannon 30095000e6 Updates to latest version of JSON.Net 2013-09-27 13:25:28 +10:00
Shannon 5d224cca9b Updates to latest version of Microsoft.Net.Http 2013-09-27 13:22:27 +10:00
Shannon c5c1a7ddfc Upgrades to latest AutoMapper lib 2013-09-27 13:16:25 +10:00
Marc Brooks b5022bb183 Fix order of null-check versus dotting through to .UmbracoContext.
The order of operations in the constructor dots through to the _routingContext.UmbracoContext before checking if the value was null and throwing the argument exception (which really isn't an ArgumentException...)
2013-09-26 13:41:51 -05:00
Sebastiaan Janssen 2e9bc3bb2b Oops updated wrong branch 2013-09-26 15:43:08 +02:00
Sebastiaan Janssen 98e487753f Pointing to the Belle docs for building from source 2013-09-26 14:52:48 +02:00
Stephan ce15d46a5e Merge remote-tracking branch 'fork1/6.2.0-pubcontent' into 7.0.0-pubcontent 2013-09-26 09:12:02 +02:00
Stephan 02ffebde49 Merge branch '7.0.0' into 7.0.0-pubcontent 2013-09-26 09:06:01 +02:00
Stephan 2e06c61a4f Fix issues after merge 2013-09-26 09:04:23 +02:00
Stephan 36d6e4b4da Merge branch '7.0.0' into 7.0.0-pubcontent
Conflicts:
	src/Umbraco.Core/Cache/HttpRuntimeCacheProvider.cs
	src/Umbraco.Core/PublishedContentHelper.cs
	src/Umbraco.Tests/Umbraco.Tests.csproj
	src/Umbraco.Web/Models/XmlPublishedContent.cs
	src/Umbraco.Web/Models/XmlPublishedContentProperty.cs
	src/Umbraco.Web/Templates/TemplateUtilities.cs
2013-09-26 08:57:01 +02:00
Stephan 725b938de1 PublishedContent - revert to using property.Value vs .ObjectValue 2013-09-25 13:17:21 +02:00
Stephan 042973ce19 PublishedContent - revert to using property.Value vs .ObjectValue 2013-09-25 12:54:24 +02:00
Stephan f9022d8189 Cleanup project after merge 2013-09-24 16:31:26 +02:00
Stephan 7f4a98883b Merge branch '7.0.0' into 7.0.0-pubcontent 2013-09-24 16:24:20 +02:00
Stephan 8ff0307a95 Fix bugs & tests after merge 2013-09-24 16:23:03 +02:00
Stephan 917c514fab PublishedContent - use generic published content in MacroController 2013-09-24 15:05:53 +02:00
Stephan 2ef4b77bd9 Fix broken tests 2013-09-24 11:28:54 +02:00
Stephan c7ac4eea2f Merge branch '7.0.0' into 7.0.0-pubcontent 2013-09-24 10:53:26 +02:00
Stephan fae9fc6e2d Merge branch '6.2.0' into 6.2.0-pubcontent 2013-09-24 10:51:44 +02:00
Stephan 000e278e48 Fix bugs & tests after merge 2013-09-24 10:49:30 +02:00
Stephan bcfb562dde Fix build after merge 2013-09-24 09:12:58 +02:00
Stephan 3ca8b356ee Merge branch '6.2.0-pubcontent' into 7.0.0-pubcontent
Conflicts:
	src/Umbraco.Core/Cache/CacheProviderBase.cs
	src/Umbraco.Core/Cache/HttpRuntimeCacheProvider.cs
	src/Umbraco.Core/Cache/NullCacheProvider.cs
	src/Umbraco.Core/Cache/StaticCacheProvider.cs
	src/Umbraco.Core/Configuration/UmbracoSettings.cs
	src/Umbraco.Core/CoreBootManager.cs
	src/Umbraco.Core/Dynamics/PropertyResult.cs
	src/Umbraco.Core/Models/IPublishedContentProperty.cs
	src/Umbraco.Core/Models/PublishedItemType.cs
	src/Umbraco.Core/PropertyEditors/IPropertyEditorValueConverter.cs
	src/Umbraco.Core/PropertyEditors/PropertyEditorValueConvertersResolver.cs
	src/Umbraco.Core/PropertyEditors/PropertyValueConvertersResolver.cs
	src/Umbraco.Core/PublishedContentExtensions.cs
	src/Umbraco.Core/PublishedContentHelper.cs
	src/Umbraco.Core/Umbraco.Core.csproj
	src/Umbraco.Tests/CodeFirst/StronglyTypedMapperTest.cs
	src/Umbraco.Tests/LibraryTests.cs
	src/Umbraco.Tests/PropertyEditors/PropertyEditorValueConverterTests.cs
	src/Umbraco.Tests/PublishedCache/PublishedContentCacheTests.cs
	src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs
	src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs
	src/Umbraco.Web/ExamineExtensions.cs
	src/Umbraco.Web/Models/DynamicPublishedContent.cs
	src/Umbraco.Web/Models/XmlPublishedContent.cs
	src/Umbraco.Web/Models/XmlPublishedContentProperty.cs
	src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs
	src/Umbraco.Web/PublishedContentExtensions.cs
	src/Umbraco.Web/Templates/TemplateUtilities.cs
	src/Umbraco.Web/Umbraco.Web.csproj
	src/Umbraco.Web/WebBootManager.cs
	src/Umbraco.Web/umbraco.presentation/macro.cs
	src/umbraco.MacroEngines/RazorDynamicNode/PropertyResult.cs
	src/umbraco.MacroEngines/RazorDynamicNode/PublishedContentExtensions.cs
2013-09-23 21:57:22 +02:00
Stephan 6c32cf9529 Fix broken build 2013-09-23 17:30:09 +02:00
Stephan d925f856ae Take care of FIXMEs 2013-09-23 16:55:59 +02:00
Stephan 3de2196e01 PublishedContent - reorg. existing IPropertyValueConverter impl. 2013-09-23 16:42:35 +02:00
Stephan ac2d010df3 PublishedContent - refactor PublishedContentType cache 2013-09-23 16:18:39 +02:00
Stephan eb4317a9c1 Take care of FIXMEs 2013-09-23 13:08:45 +02:00
Stephan c3caf7ff04 PublishedContent - align with v7, refactor IPublishedProperty & names 2013-09-19 13:12:18 +02:00
Stephan f9cae9c4d8 PublishedContent - align with v7, refactor IPropertyValueConverter 2013-09-19 12:07:43 +02:00
Stephan dd16af0989 PublishedContent - align with v7, refactor PublishedPropertyType 2013-09-19 12:07:30 +02:00
Stephan c118990a4c Merge branch '6.2.0' into 6.2.0-pubcontent 2013-09-18 12:51:07 +02:00
Stephan 7a541ba489 Merge branch '6.2.0' into 6.2.0-pubcontent 2013-09-18 11:34:00 +02:00
Stephan a785cd1569 Merge branch '6.2.0' into 6.2.0-pubcontent 2013-09-18 10:56:07 +02:00
Stephan 1e786ac311 PublishedContent - proper PublishedContentType cache management 2013-09-18 10:09:11 +02:00
Stephan 0c28e01347 Core.Cache - add new method to remove items from cache 2013-09-18 10:09:08 +02:00
Stephan 08566f32de Take care of more FIXMEs 2013-09-18 10:09:05 +02:00
Stephan 16ec58f338 Merge branch '6.2.0' into 6.2.0-pubcontent 2013-09-17 10:49:46 +02:00
Stephan e8fd6a6ece Take care of FIXMEs 2013-09-17 10:18:26 +02:00
Stephan ee4f4440d5 PublishedContent - implement strongly typed methods for other axes 2013-09-16 17:17:51 +02:00
Stephan f4d060f3eb PublishedContent - implement strongly typed methods for parent, children, ancestors & descendants axes 2013-09-16 17:17:49 +02:00
Stephan 85cb7fadfc PublishedContent - implement a model factory 2013-09-16 17:17:48 +02:00
Stephan ac19ac7a6b PublishedContent - use PublishedContentModelFactory in XmlPublishedCache 2013-09-16 17:17:46 +02:00
Stephan 0415a31d0e PublishedContent - the big refactoring 2013-09-16 17:17:45 +02:00
Stephan 912716f889 Content - add @isDraft to preview Xml for draft content 2013-09-16 17:17:42 +02:00
Stephan 5dc9bb752e Macros - cache xslt settings 2013-09-16 17:17:41 +02:00
Stephan cf435011df Macros - support navigable caches 2013-09-16 17:17:39 +02:00
Stephan f63514e8ea Web.PublishedCache - add XPathNavigatorIsNavigable to caches 2013-09-16 17:17:38 +02:00
Stephan 1ddf2fa365 Core.Xml - import NavigableNavigator initial version 2013-09-16 17:17:36 +02:00
1482 changed files with 33975 additions and 102304 deletions
+2
View File
@@ -103,3 +103,5 @@ src/Umbraco.Web.UI/[Uu]mbraco/[Ll]ib/*
src/Umbraco.Web.UI/[Uu]mbraco/[Vv]iews/**/*.html
src/Umbraco.Web.UI/[Uu]mbraco/[Vv]iews/**/*.js
src/Umbraco.Web.UI/[Cc]onfig/appSettings.config
src/Umbraco.Web.UI/[Cc]onfig/connectionStrings.config
+1 -1
View File
@@ -1,6 +1,6 @@
@ECHO OFF
SET release=7.0.0
SET comment=alpha
SET comment=beta
SET version=%release%
IF [%comment%] EQU [] (SET version=%release%) ELSE (SET version=%release%-%comment%)
+6 -7
View File
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>UmbracoCms.Core</id>
@@ -20,13 +20,14 @@
<dependency id="Microsoft.AspNet.Mvc.FixedDisplayModes" version="1.0.0" />
<dependency id="MiniProfiler" version="[2.1.0, 3.0.0)" />
<dependency id="HtmlAgilityPack" version="[1.4.6, 2.0.0)" />
<dependency id="Lucene.Net" version="[2.9.4.1]" />
<dependency id="Lucene.Net" version="[2.9.4.1, 3.0.0.0)" />
<dependency id="SharpZipLib" version="[0.86.0, 1.0.0)" />
<dependency id="MySql.Data" version="[6.6.5]" />
<dependency id="xmlrpcnet" version="[2.5.0, 3.0.0)" />
<dependency id="ClientDependency" version="[1.7.0, 1.7.1)" />
<dependency id="ClientDependency-Mvc" version="[1.7.0, 1.7.1)" />
<dependency id="AutoMapper" version="[2.2.1, 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="AutoMapper" version="[3.0.0, 4.0.0)" />
<dependency id="Newtonsoft.Json" version="[5.0.0, 6.0.0)" />
</dependencies>
</metadata>
<files>
@@ -59,8 +60,6 @@
<file src="..\_BuildOutput\WebApp\bin\umbraco.editorControls.xml" target="lib\umbraco.editorControls.xml" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.MacroEngines.dll" target="lib\umbraco.MacroEngines.dll" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.MacroEngines.xml" target="lib\umbraco.MacroEngines.xml" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.macroRenderings.dll" target="lib\umbraco.macroRenderings.dll" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.macroRenderings.xml" target="lib\umbraco.macroRenderings.xml" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.dll" target="lib\umbraco.providers.dll" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.xml" target="lib\umbraco.providers.xml" />
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Web.UI.dll" target="lib\Umbraco.Web.UI.dll" />
+1 -1
View File
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>UmbracoCms</id>
+6
View File
@@ -22,6 +22,12 @@ if ($project) {
$umbracoFilesPath = Join-Path $rootPath "UmbracoFiles\*"
Copy-Item $umbracoFilesPath $projectDestinationPath -recurse -force
# Remove Newtonsoft.Json if present in the bin folder
# If we don't do this, the correct version never gets copied in
$projectDestinationPath = Split-Path $project.FullName -Parent
$jsonDllFile = Join-Path $projectDestinationPath "bin\Newtonsoft.Json.dll"
Remove-Item $jsonDllFile -Confirm:$false
# Open readme.txt file
$DTE.ItemOperations.OpenFile($toolsPath + '\Readme.txt')
}
+52 -5
View File
@@ -28,12 +28,11 @@ namespace Umbraco.Core
/// <param name="dbContext"></param>
/// <param name="serviceContext"></param>
/// <param name="cache"></param>
internal ApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext, CacheHelper cache)
public ApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext, CacheHelper cache)
{
if (dbContext == null) throw new ArgumentNullException("dbContext");
if (serviceContext == null) throw new ArgumentNullException("serviceContext");
if (cache == null) throw new ArgumentNullException("cache");
_databaseContext = dbContext;
_services = serviceContext;
ApplicationCache = cache;
@@ -43,12 +42,60 @@ namespace Umbraco.Core
/// Creates a basic app context
/// </summary>
/// <param name="cache"></param>
internal ApplicationContext(CacheHelper cache)
public ApplicationContext(CacheHelper cache)
{
ApplicationCache = cache;
}
/// <summary>
/// <summary>
/// A method used to set and/or ensure that a global ApplicationContext singleton is created.
/// </summary>
/// <param name="appContext">
/// The instance to set on the global application singleton
/// </param>
/// <param name="replaceContext">If set to true and the singleton is already set, it will be replaced</param>
/// <returns></returns>
/// <remarks>
/// This is NOT thread safe
/// </remarks>
public static ApplicationContext EnsureContext(ApplicationContext appContext, bool replaceContext)
{
if (ApplicationContext.Current != null)
{
if (!replaceContext)
return ApplicationContext.Current;
}
ApplicationContext.Current = appContext;
return ApplicationContext.Current;
}
/// <summary>
/// A method used to create and ensure that a global ApplicationContext singleton is created.
/// </summary>
/// <param name="cache"></param>
/// <param name="replaceContext">
/// If set to true will replace the current singleton instance - This should only be used for unit tests or on app
/// startup if for some reason the boot manager is not the umbraco boot manager.
/// </param>
/// <param name="dbContext"></param>
/// <param name="serviceContext"></param>
/// <returns></returns>
/// <remarks>
/// This is NOT thread safe
/// </remarks>
public static ApplicationContext EnsureContext(DatabaseContext dbContext, ServiceContext serviceContext, CacheHelper cache, bool replaceContext)
{
if (ApplicationContext.Current != null)
{
if (!replaceContext)
return ApplicationContext.Current;
}
var ctx = new ApplicationContext(dbContext, serviceContext, cache);
ApplicationContext.Current = ctx;
return ApplicationContext.Current;
}
/// <summary>
/// Singleton accessor
/// </summary>
public static ApplicationContext Current { get; internal set; }
@@ -99,7 +146,7 @@ namespace Umbraco.Core
//
public bool IsConfigured
{
// fixme - we should not do this - ok for now
// todo - we should not do this - ok for now
get
{
return Configured;
-1
View File
@@ -47,6 +47,5 @@ namespace Umbraco.Core.Cache
public const string StylesheetPropertyCacheKey = "UmbracoStylesheetProperty";
public const string DataTypeCacheKey = "UmbracoDataTypeDefinition";
}
}
@@ -55,7 +55,7 @@ namespace Umbraco.Core.Cache
}
}
/// <summary>
/// <summary>
/// Gets (and adds if necessary) an item from the cache with all of the default parameters
/// </summary>
/// <param name="cacheKey"></param>
+1 -9
View File
@@ -32,7 +32,7 @@ namespace Umbraco.Core
/// <remarks>
/// Good for unit testing
/// </remarks>
internal static CacheHelper CreateDisabledCacheHelper()
public static CacheHelper CreateDisabledCacheHelper()
{
return new CacheHelper(null, null, null, false);
}
@@ -74,14 +74,6 @@ namespace Umbraco.Core
{
}
internal void ClearStaticCacheObjectTypes<T>(Func<string, T, bool> predicate)
{
if (_enableCache)
_staticCache.ClearCacheObjectTypes(predicate);
else
_nullStaticCache.ClearCacheObjectTypes(predicate);
}
/// <summary>
/// Private ctor used for creating a disabled cache helper
/// </summary>
@@ -3,7 +3,7 @@ using System.Configuration;
namespace Umbraco.Core.Configuration.BaseRest
{
[ConfigurationKey("BaseRestExtensions")]
internal class BaseRestSection : UmbracoConfigurationSection, IBaseRestSection
{
private const string KeyEnabled = "enabled";
@@ -1,28 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Umbraco.Core.Configuration
{
/// <summary>
/// Indicates the configuration key for a section or a group.
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public sealed class ConfigurationKeyAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="ConfigurationKeyAttribute"/> class with a configuration key.
/// </summary>
/// <param name="configurationKey">The configurationkey.</param>
public ConfigurationKeyAttribute(string configurationKey)
{
ConfigurationKey = configurationKey;
}
/// <summary>
/// Gets or sets the configuration key.
/// </summary>
public string ConfigurationKey { get; private set; }
}
}
@@ -0,0 +1,34 @@
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace Umbraco.Core.Configuration.Dashboard
{
internal class AccessElement : RawXmlConfigurationElement, IAccess
{
public AccessElement()
{
}
public AccessElement(XElement rawXml)
:base(rawXml)
{
}
public IEnumerable<IAccessItem> Rules
{
get
{
var result = new List<AccessItem>();
if (RawXml != null)
{
result.AddRange(RawXml.Elements("deny").Select(x => new AccessItem {Action = AccessType.Deny, Value = x.Value }));
result.AddRange(RawXml.Elements("grant").Select(x => new AccessItem { Action = AccessType.Grant, Value = x.Value }));
result.AddRange(RawXml.Elements("grantBySection").Select(x => new AccessItem { Action = AccessType.GrantBySection, Value = x.Value }));
}
return result;
}
}
}
}
@@ -0,0 +1,15 @@
namespace Umbraco.Core.Configuration.Dashboard
{
internal class AccessItem : IAccessItem
{
/// <summary>
/// This can be grant, deny or grantBySection
/// </summary>
public AccessType Action { get; set; }
/// <summary>
/// The value of the action
/// </summary>
public string Value { get; set; }
}
}
@@ -0,0 +1,9 @@
namespace Umbraco.Core.Configuration.Dashboard
{
public enum AccessType
{
Grant,
Deny,
GrantBySection
}
}
@@ -0,0 +1,18 @@
using System.Configuration;
namespace Umbraco.Core.Configuration.Dashboard
{
internal class AreasElement : ConfigurationElement, IArea
{
[ConfigurationProperty("area", IsRequired = true)]
public InnerTextConfigurationElement<string> AreaName
{
get { return (InnerTextConfigurationElement<string>)this["area"]; }
}
string IArea.AreaName
{
get { return AreaName; }
}
}
}
@@ -0,0 +1,37 @@
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
namespace Umbraco.Core.Configuration.Dashboard
{
internal class ControlCollection : ConfigurationElementCollection, IEnumerable<IDashboardControl>
{
internal void Add(ControlElement c)
{
BaseAdd(c);
}
protected override ConfigurationElement CreateNewElement()
{
return new ControlElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((ControlElement)element).ControlPath;
}
IEnumerator<IDashboardControl> IEnumerable<IDashboardControl>.GetEnumerator()
{
for (var i = 0; i < Count; i++)
{
yield return BaseGet(i) as IDashboardControl;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
@@ -0,0 +1,74 @@
using System;
using System.Configuration;
using System.Linq;
using System.Xml.Linq;
namespace Umbraco.Core.Configuration.Dashboard
{
internal class ControlElement : RawXmlConfigurationElement, IDashboardControl
{
public bool ShowOnce
{
get
{
return RawXml.Attribute("showOnce") == null
? false
: bool.Parse(RawXml.Attribute("showOnce").Value);
}
}
public bool AddPanel
{
get
{
return RawXml.Attribute("addPanel") == null
? true
: bool.Parse(RawXml.Attribute("addPanel").Value);
}
}
public string PanelCaption
{
get
{
return RawXml.Attribute("panelCaption") == null
? ""
: RawXml.Attribute("panelCaption").Value;
}
}
public AccessElement Access
{
get
{
var access = RawXml.Element("access");
if (access == null)
{
return new AccessElement();
}
return new AccessElement(access);
}
}
public string ControlPath
{
get
{
//we need to return the first (and only) text element of the children (wtf... who designed this configuration ! :P )
var txt = RawXml.Nodes().OfType<XText>().FirstOrDefault();
if (txt == null)
{
throw new ConfigurationErrorsException("The control element must contain a text node indicating the control path");
}
return txt.Value.Trim();
}
}
IAccess IDashboardControl.AccessRights
{
get { return Access; }
}
}
}
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Text;
using System.Threading.Tasks;
namespace Umbraco.Core.Configuration.Dashboard
{
internal class DashboardSection : ConfigurationSection, IDashboardSection
{
[ConfigurationCollection(typeof(SectionCollection), AddItemName = "section")]
[ConfigurationProperty("", IsDefaultCollection = true)]
public SectionCollection SectionCollection
{
get { return (SectionCollection)base[""]; }
set { base[""] = value; }
}
IEnumerable<ISection> IDashboardSection.Sections
{
get { return SectionCollection; }
}
}
}
@@ -0,0 +1,9 @@
using System.Collections.Generic;
namespace Umbraco.Core.Configuration.Dashboard
{
public interface IAccess
{
IEnumerable<IAccessItem> Rules { get; }
}
}
@@ -0,0 +1,15 @@
namespace Umbraco.Core.Configuration.Dashboard
{
public interface IAccessItem
{
/// <summary>
/// This can be grant, deny or grantBySection
/// </summary>
AccessType Action { get; set; }
/// <summary>
/// The value of the action
/// </summary>
string Value { get; set; }
}
}
@@ -0,0 +1,7 @@
namespace Umbraco.Core.Configuration.Dashboard
{
public interface IArea
{
string AreaName { get; }
}
}
@@ -0,0 +1,15 @@
namespace Umbraco.Core.Configuration.Dashboard
{
public interface IDashboardControl
{
bool ShowOnce { get; }
bool AddPanel { get; }
string PanelCaption { get; }
string ControlPath { get; }
IAccess AccessRights { get; }
}
}
@@ -0,0 +1,9 @@
using System.Collections.Generic;
namespace Umbraco.Core.Configuration.Dashboard
{
public interface IDashboardSection
{
IEnumerable<ISection> Sections { get; }
}
}
@@ -0,0 +1,13 @@
using System.Collections.Generic;
namespace Umbraco.Core.Configuration.Dashboard
{
public interface IDashboardTab
{
string Caption { get; }
IEnumerable<IDashboardControl> Controls { get; }
IAccess AccessRights { get; }
}
}
@@ -0,0 +1,15 @@
using System.Collections.Generic;
namespace Umbraco.Core.Configuration.Dashboard
{
public interface ISection
{
string Alias { get; }
string Area { get; }
IEnumerable<IDashboardTab> Tabs { get; }
IAccess AccessRights { get; }
}
}
@@ -0,0 +1,37 @@
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
namespace Umbraco.Core.Configuration.Dashboard
{
internal class SectionCollection : ConfigurationElementCollection, IEnumerable<ISection>
{
internal void Add(SectionElement c)
{
BaseAdd(c);
}
protected override ConfigurationElement CreateNewElement()
{
return new SectionElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((SectionElement)element).Alias;
}
IEnumerator<ISection> IEnumerable<ISection>.GetEnumerator()
{
for (var i = 0; i < Count; i++)
{
yield return BaseGet(i) as ISection;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
@@ -0,0 +1,49 @@
using System.Collections.Generic;
using System.Configuration;
namespace Umbraco.Core.Configuration.Dashboard
{
internal class SectionElement : ConfigurationElement, ISection
{
[ConfigurationProperty("alias", IsRequired = true)]
public string Alias
{
get { return (string) this["alias"]; }
}
[ConfigurationProperty("areas", IsRequired = true)]
public AreasElement Area
{
get { return (AreasElement)this["areas"]; }
}
[ConfigurationProperty("access")]
public AccessElement Access
{
get { return (AccessElement)this["access"]; }
}
[ConfigurationCollection(typeof(SectionCollection), AddItemName = "tab")]
[ConfigurationProperty("", IsDefaultCollection = true)]
public TabCollection TabCollection
{
get { return (TabCollection)base[""]; }
set { base[""] = value; }
}
IEnumerable<IDashboardTab> ISection.Tabs
{
get { return TabCollection; }
}
string ISection.Area
{
get { return Area.AreaName; }
}
IAccess ISection.AccessRights
{
get { return Access; }
}
}
}
@@ -0,0 +1,37 @@
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
namespace Umbraco.Core.Configuration.Dashboard
{
internal class TabCollection : ConfigurationElementCollection, IEnumerable<IDashboardTab>
{
internal void Add(TabElement c)
{
BaseAdd(c);
}
protected override ConfigurationElement CreateNewElement()
{
return new TabElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((TabElement)element).Caption;
}
IEnumerator<IDashboardTab> IEnumerable<IDashboardTab>.GetEnumerator()
{
for (var i = 0; i < Count; i++)
{
yield return BaseGet(i) as IDashboardTab;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
@@ -0,0 +1,38 @@
using System.Collections.Generic;
using System.Configuration;
namespace Umbraco.Core.Configuration.Dashboard
{
internal class TabElement : ConfigurationElement, IDashboardTab
{
[ConfigurationProperty("caption", IsRequired = true)]
public string Caption
{
get { return (string)this["caption"]; }
}
[ConfigurationProperty("access")]
public AccessElement Access
{
get { return (AccessElement)this["access"]; }
}
[ConfigurationCollection(typeof(ControlCollection), AddItemName = "control")]
[ConfigurationProperty("", IsDefaultCollection = true)]
public ControlCollection ControlCollection
{
get { return (ControlCollection)base[""]; }
set { base[""] = value; }
}
IEnumerable<IDashboardControl> IDashboardTab.Controls
{
get { return ControlCollection; }
}
IAccess IDashboardTab.AccessRights
{
get { return Access; }
}
}
}
@@ -265,10 +265,10 @@ namespace Umbraco.Core.Configuration
/// <param name="value">Value of the setting to be saved.</param>
internal static void SaveSetting(string key, string value)
{
var fileName = GetFullWebConfigFileName();
var fileName = IOHelper.MapPath(string.Format("{0}/appSettings.config", SystemDirectories.Config));
var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace);
var appSettings = xml.Root.Descendants("appSettings").Single();
var appSettings = xml.Root.DescendantsAndSelf("appSettings").Single();
// Update appSetting if it exists, or else create a new appSetting for the given key and value
var setting = appSettings.Descendants("add").FirstOrDefault(s => s.Attribute("key").Value == key);
@@ -287,10 +287,10 @@ namespace Umbraco.Core.Configuration
/// <param name="key">Key of the setting to be removed.</param>
internal static void RemoveSetting(string key)
{
var fileName = GetFullWebConfigFileName();
var fileName = IOHelper.MapPath(string.Format("{0}/appSettings.config", SystemDirectories.Config));
var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace);
var appSettings = xml.Root.Descendants("appSettings").Single();
var appSettings = xml.Root.DescendantsAndSelf("appSettings").Single();
var setting = appSettings.Descendants("add").FirstOrDefault(s => s.Attribute("key").Value == key);
if (setting != null)
@@ -301,21 +301,6 @@ namespace Umbraco.Core.Configuration
}
}
private static string GetFullWebConfigFileName()
{
var webConfig = new WebConfigurationFileMap();
var vDir = FullpathToRoot;
foreach (VirtualDirectoryMapping v in webConfig.VirtualDirectories)
{
if (v.IsAppRoot)
vDir = v.PhysicalDirectory;
}
var fileName = System.IO.Path.Combine(vDir, "web.config");
return fileName;
}
/// <summary>
/// Gets the full path to root.
/// </summary>
@@ -25,8 +25,8 @@ namespace Umbraco.Core.Configuration
//now validate and set the raw value
if (RawXml.HasElements)
throw new InvalidOperationException("An InnerTextConfigurationElement cannot contain any child elements, only attributes and a value");
RawValue = RawXml.Value;
RawValue = RawXml.Value.Trim();
//RawValue = reader.ReadElementContentAsString();
}
@@ -5,6 +5,7 @@ using System.Configuration;
using System.Linq;
using System.Threading;
using Umbraco.Core.Configuration.BaseRest;
using Umbraco.Core.Configuration.Dashboard;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
@@ -31,7 +32,7 @@ namespace Umbraco.Core.Configuration
/// </summary>
private UmbracoConfig()
{
if (UmbracoSettings() == null)
if (_umbracoSettings == null)
{
var umbracoSettings = ConfigurationManager.GetSection("umbracoConfiguration/settings") as IUmbracoSettingsSection;
if (umbracoSettings == null)
@@ -41,7 +42,7 @@ namespace Umbraco.Core.Configuration
SetUmbracoSettings(umbracoSettings);
}
if (BaseRestExtensions() == null)
if (_baseRestExtensions == null)
{
var baseRestExtensions = ConfigurationManager.GetSection("umbracoConfiguration/BaseRestExtensions") as IBaseRestSection;
if (baseRestExtensions == null)
@@ -50,6 +51,16 @@ namespace Umbraco.Core.Configuration
}
SetBaseRestExtensions(baseRestExtensions);
}
if (_dashboardSection == null)
{
var dashboardConfig = ConfigurationManager.GetSection("umbracoConfiguration/dashBoard") as IDashboardSection;
if (dashboardConfig == null)
{
LogHelper.Warn<UmbracoConfig>("Could not load the " + typeof(IDashboardSection) + " from config file!");
}
SetDashboardSettings(dashboardConfig);
}
}
/// <summary>
@@ -57,13 +68,31 @@ namespace Umbraco.Core.Configuration
/// </summary>
/// <param name="umbracoSettings"></param>
/// <param name="baseRestSettings"></param>
public UmbracoConfig(IUmbracoSettingsSection umbracoSettings, IBaseRestSection baseRestSettings)
/// <param name="dashboardSettings"></param>
public UmbracoConfig(IUmbracoSettingsSection umbracoSettings, IBaseRestSection baseRestSettings, IDashboardSection dashboardSettings)
{
SetUmbracoSettings(umbracoSettings);
SetBaseRestExtensions(baseRestSettings);
SetDashboardSettings(dashboardSettings);
}
private IDashboardSection _dashboardSection;
private IUmbracoSettingsSection _umbracoSettings;
private IBaseRestSection _baseRestExtensions;
/// <summary>
/// Gets the IDashboardSection
/// </summary>
public IDashboardSection DashboardSettings()
{
return _dashboardSection;
}
//ONLY for unit testing
internal void SetDashboardSettings(IDashboardSection value)
{
_dashboardSection = value;
}
//ONLY for unit testing
internal void SetUmbracoSettings(IUmbracoSettingsSection value)
@@ -78,9 +107,7 @@ namespace Umbraco.Core.Configuration
{
return _umbracoSettings;
}
private IBaseRestSection _baseRestExtensions;
//ONLY for unit testing
public void SetBaseRestExtensions(IBaseRestSection value)
{
@@ -3,7 +3,7 @@ using System.Configuration;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
[ConfigurationKey("umbracoConfiguration/settings/content")]
internal class ContentElement : ConfigurationElement, IContentSection
{
[ConfigurationProperty("imaging")]
@@ -4,7 +4,7 @@ using System.Linq;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
[ConfigurationKey("umbracoConfiguration/settings")]
public class UmbracoSettingsSection : ConfigurationSection, IUmbracoSettingsSection
{
[ConfigurationProperty("content")]
@@ -1,4 +1,4 @@
using System;
using System;
using System.Reflection;
namespace Umbraco.Core.Configuration
@@ -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 "alpha"; } }
public static string CurrentComment { get { return "beta"; } }
// Get the version of the umbraco.dll by looking at a class in that dll
// Had to do it like this due to medium trust issues, see: http://haacked.com/archive/2010/11/04/assembly-location-and-medium-trust.aspx
@@ -53,6 +53,11 @@
/// </summary>
public const string Content = "content";
/// <summary>
/// alias for the media tree.
/// </summary>
public const string Members = "member";
/// <summary>
/// alias for the media tree.
/// </summary>
@@ -99,6 +99,10 @@ namespace Umbraco.Core
/// </summary>
public static class Member
{
public static readonly string UmbracoMemberProviderName = "UmbracoMembershipProvider";
public static readonly string UmbracoRoleProviderName = "UmbracoRoleProvider";
/// <summary>
/// Property alias for a Members Password Question
/// </summary>
@@ -411,6 +411,11 @@ namespace Umbraco.Core
/// Alias for the XPath DropDownList datatype.
/// </summary>
public const string XPathDropDownListAlias = "Umbraco.XPathDropDownList";
/// <summary>
/// Alias for the email address property editor
/// </summary>
public const string EmailAddressAlias = "Umbraco.EmailAddress";
}
}
}
+22 -10
View File
@@ -7,6 +7,7 @@ using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.Mapping;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.ObjectResolution;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Mappers;
@@ -17,6 +18,7 @@ using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
using Umbraco.Core.Profiling;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.PropertyEditors.ValueConverters;
using Umbraco.Core.Publishing;
using Umbraco.Core.Macros;
using Umbraco.Core.Services;
@@ -308,25 +310,35 @@ namespace Umbraco.Core
//the database migration objects
MigrationResolver.Current = new MigrationResolver(
() => PluginManager.Current.ResolveMigrationTypes());
//NOTE: These are legacy in v7+ and will eventually need to be removed.
PropertyEditorValueConvertersResolver.Current = new PropertyEditorValueConvertersResolver(
// todo: remove once we drop IPropertyEditorValueConverter support.
PropertyEditorValueConvertersResolver.Current = new PropertyEditorValueConvertersResolver(
PluginManager.Current.ResolvePropertyEditorValueConverters());
//add the internal ones, these are not public currently so need to add them manually
PropertyValueConvertersResolver.Current = new PropertyValueConvertersResolver(
PluginManager.Current.ResolvePropertyValueConverters());
// fixme - why not use the following syntax?
//PluginManager.Current.ResolveTypes<IPropertyValueConverter>());
// this is how we'd switch over to DefaultShortStringHelper _and_ still use
// UmbracoSettings UrlReplaceCharacters...
//ShortStringHelperResolver.Current = new ShortStringHelperResolver(
// new DefaultShortStringHelper().WithConfig(DefaultShortStringHelper.ApplyUrlReplaceCharacters));
// use the Legacy one for now
// use the new DefaultShortStringHelper but sort-of remain compatible
// - use UmbracoSettings UrlReplaceCharacters
// - allow underscores in terms, allow leading digits
ShortStringHelperResolver.Current = new ShortStringHelperResolver(
new LegacyShortStringHelper());
new DefaultShortStringHelper()
.WithConfig(CleanStringType.Url, DefaultShortStringHelper.ApplyUrlReplaceCharacters,
allowUnderscoreInTerm: true, allowLeadingDigits: true));
// that was the old one
//ShortStringHelperResolver.Current = new ShortStringHelperResolver(
// new LegacyShortStringHelper());
UrlSegmentProviderResolver.Current = new UrlSegmentProviderResolver(
typeof (DefaultUrlSegmentProvider));
// keep it internal for now
PublishedContentModelFactoryResolver.Current = new PublishedContentModelFactoryResolver();
// new PublishedContentModelFactoryImpl());
}
}
}
+6 -15
View File
@@ -6,6 +6,7 @@ using System.Linq;
using System.Web.Configuration;
using System.Xml.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Migrations;
@@ -28,7 +29,7 @@ namespace Umbraco.Core
private string _providerName;
private DatabaseSchemaResult _result;
internal DatabaseContext(IDatabaseFactory factory)
public DatabaseContext(IDatabaseFactory factory)
{
_factory = factory;
}
@@ -112,7 +113,7 @@ namespace Umbraco.Core
public void ConfigureEmbeddedDatabaseConnection()
{
const string providerName = "System.Data.SqlServerCe.4.0";
const string connectionString = @"Data Source=|DataDirectory|\Umbraco.sdf;Flush Interval=1;File Access Retry Timeout=10";
const string connectionString = @"Data Source=|DataDirectory|\Umbraco.sdf;Flush Interval=1;";
SaveConnectionString(connectionString, providerName);
@@ -248,20 +249,10 @@ namespace Umbraco.Core
_connectionString = connectionString;
_providerName = providerName;
var webConfig = new WebConfigurationFileMap();
var vDir = GlobalSettings.FullpathToRoot;
foreach (VirtualDirectoryMapping v in webConfig.VirtualDirectories)
{
if (v.IsAppRoot)
{
vDir = v.PhysicalDirectory;
}
}
var fileName = Path.Combine(vDir, "web.config");
var fileName = IOHelper.MapPath(string.Format("{0}/connectionStrings.config", SystemDirectories.Config));
var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace);
var connectionstrings = xml.Root.Descendants("connectionStrings").Single();
var connectionstrings = xml.Root.DescendantsAndSelf("connectionStrings").Single();
// Update connectionString if it exists, or else create a new appSetting for the given key and value
var setting = connectionstrings.Descendants("add").FirstOrDefault(s => s.Attribute("name").Value == GlobalSettings.UmbracoConnectionName);
@@ -112,7 +112,8 @@ namespace Umbraco.Core.Dynamics
{
//don't log here, we return this exception because the caller may need to do something specific when
//this exception occurs.
return Attempt<TryInvokeMemberResult>.Fail(ext);
var mresult = new TryInvokeMemberResult(null, TryInvokeMemberSuccessReason.FoundExtensionMethod);
return Attempt<TryInvokeMemberResult>.Fail(mresult, ext);
}
catch (Exception ex)
{
@@ -124,7 +125,8 @@ namespace Umbraco.Core.Dynamics
sb.Append(t + ",");
}
LogHelper.Error<DynamicInstanceHelper>(sb.ToString(), ex);
return Attempt<TryInvokeMemberResult>.Fail(ex);
var mresult = new TryInvokeMemberResult(null, TryInvokeMemberSuccessReason.FoundExtensionMethod);
return Attempt<TryInvokeMemberResult>.Fail(mresult, ex);
}
}
return Attempt<TryInvokeMemberResult>.Fail();
+31 -9
View File
@@ -11,78 +11,101 @@ namespace Umbraco.Core.Dynamics
//Because it's IEnumerable, if the user is actually trying @Model.TextPages or similar
//it will still return an enumerable object (assuming the call actually failed because there were no children of that type)
//but in .Where, if they use a property that doesn't exist, the lambda will bypass this and return false
// returned when TryGetMember fails on a DynamicPublishedContent
//
// so if user does @CurrentPage.TextPages it will get something that is enumerable (but empty)
// note - not sure I understand the stuff about .Where, though
public class DynamicNull : DynamicObject, IEnumerable, IHtmlString
{
public static readonly DynamicNull Null = new DynamicNull();
private DynamicNull() {}
public IEnumerator GetEnumerator()
{
return (new List<DynamicNull>()).GetEnumerator();
}
public DynamicNull Where(string predicate, params object[] values)
{
return this;
}
public DynamicNull OrderBy(string orderBy)
{
return this;
}
public DynamicNull ToContentSet()
{
return this;
}
public int Count()
{
return 0;
}
public override string ToString()
{
return string.Empty;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = this;
return true;
}
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
{
result = this;
return true;
}
public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
{
result = this;
return true;
}
public bool IsNull()
{
return true;
}
public bool HasValue()
{
return false;
}
public string Name
{
get
{
return string.Empty;
}
get { return string.Empty; }
}
public int Id
{
get
{
return 0;
}
get { return 0; }
}
public static implicit operator bool(DynamicNull n)
{
return false;
}
public static implicit operator DateTime(DynamicNull n)
{
return DateTime.MinValue;
}
public static implicit operator int(DynamicNull n)
{
return 0;
}
public static implicit operator string(DynamicNull n)
{
return string.Empty;
@@ -92,6 +115,5 @@ namespace Umbraco.Core.Dynamics
{
return string.Empty;
}
}
}
+1 -1
View File
@@ -203,7 +203,7 @@ namespace Umbraco.Core.Dynamics
if (attempt.Result.Reason == DynamicInstanceHelper.TryInvokeMemberSuccessReason.FoundExtensionMethod
&& attempt.Exception != null && attempt.Exception is TargetInvocationException)
{
result = new DynamicNull();
result = DynamicNull.Null;
return true;
}
@@ -13,7 +13,96 @@ namespace Umbraco.Core.Dynamics
/// Utility class for finding extension methods on a type to execute
/// </summary>
internal static class ExtensionMethodFinder
{
{
private static readonly MethodInfo[] AllExtensionMethods;
static ExtensionMethodFinder()
{
AllExtensionMethods = TypeFinder.GetAssembliesWithKnownExclusions()
// assemblies that contain extension methods
.Where(a => a.IsDefined(typeof(ExtensionAttribute), false))
// types that contain extension methods
.SelectMany(a => a.GetTypes()
.Where(t => t.IsDefined(typeof(ExtensionAttribute), false) && t.IsSealed && t.IsGenericType == false && t.IsNested == false))
// actual extension methods
.SelectMany(t => t.GetMethods(BindingFlags.Static | BindingFlags.Public)
.Where(m => m.IsDefined(typeof(ExtensionAttribute), false)))
// and also IEnumerable<T> extension methods - because the assembly is excluded
.Concat(typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public))
.ToArray();
}
// ORIGINAL CODE IS NOT COMPLETE, DOES NOT HANDLE GENERICS, ETC...
// so this is an attempt at fixing things, but it's not done yet
// and do we really want to do this? extension methods are not supported on dynamics, period
// we should use strongly typed content instead of dynamics.
/*
// get all extension methods for type thisType, with name name,
// accepting argsCount arguments (not counting the instance of thisType).
private static IEnumerable<MethodInfo> GetExtensionMethods(Type thisType, string name, int argsCount)
{
var key = string.Format("{0}.{1}::{2}", thisType.FullName, name, argsCount);
var types = thisType.GetBaseTypes(true); // either do this OR have MatchFirstParameter handle the stuff... F*XME
var methods = AllExtensionMethods
.Where(m => m.Name == name)
.Where(m => m.GetParameters().Length == argsCount)
.Where(m => MatchFirstParameter(thisType, m.GetParameters()[0].ParameterType));
// f*xme - is this what we should cache?
return methods;
}
// find out whether the first parameter is a match for thisType
private static bool MatchFirstParameter(Type thisType, Type firstParameterType)
{
return MethodArgZeroHasCorrectTargetType(null, firstParameterType, thisType);
}
// get the single extension method for type thisType, with name name,
// that accepts the arguments in args (which does not contain the instance of thisType).
public static MethodInfo GetExtensionMethod(Type thisType, string name, object[] args)
{
MethodInfo result = null;
foreach (var method in GetExtensionMethods(thisType, name, args.Length).Where(m => MatchParameters(m, args)))
{
if (result == null)
result = method;
else
throw new AmbiguousMatchException("More than one matching extension method was found.");
}
return result;
}
// find out whether the method can accept the arguments
private static bool MatchParameters(MethodInfo method, IList<object> args)
{
var parameters = method.GetParameters();
var i = 0;
for (; i < parameters.Length; ++i)
{
if (MatchParameter(parameters[i].ParameterType, args[i].GetType()) == false)
break;
}
return (i == parameters.Length);
}
internal static bool MatchParameter(Type parameterType, Type argumentType)
{
// public static int DoSomething<T>(Foo foo, T t1, T t2)
// DoSomething(foo, t1, t2) => how can we match?!
return parameterType == argumentType; // f*xme of course!
}
*
*/
// BELOW IS THE ORIGINAL CODE...
/// <summary>
/// Returns all extension methods found matching the definition
/// </summary>
@@ -27,6 +116,10 @@ namespace Umbraco.Core.Dynamics
/// </remarks>
private static IEnumerable<MethodInfo> GetAllExtensionMethods(Type thisType, string name, int argumentCount, bool argsContainsThis)
{
// at *least* we can cache the extension methods discovery
var candidates = AllExtensionMethods;
/*
//only scan assemblies we know to contain extension methods (user assemblies)
var assembliesToScan = TypeFinder.GetAssembliesWithKnownExclusions();
@@ -45,6 +138,7 @@ namespace Umbraco.Core.Dynamics
//add the extension methods defined in IEnumerable
candidates = candidates.Concat(typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public));
*/
//filter by name
var methodsByName = candidates.Where(m => m.Name == name);
+23 -37
View File
@@ -1,60 +1,46 @@
using System;
using Umbraco.Core.Models;
using umbraco.interfaces;
using System.Web;
namespace Umbraco.Core.Dynamics
{
internal class PropertyResult : IPublishedContentProperty, IHtmlString
{
internal PropertyResult(IPublishedContentProperty source, PropertyResultType type)
internal class PropertyResult : IPublishedProperty, IHtmlString
{
private readonly IPublishedProperty _source;
private readonly string _alias;
private readonly object _value;
private readonly PropertyResultType _type;
internal PropertyResult(IPublishedProperty source, PropertyResultType type)
{
if (source == null) throw new ArgumentNullException("source");
Alias = source.Alias;
Value = source.Value;
PropertyType = type;
_type = type;
_source = source;
}
internal PropertyResult(string alias, object value, PropertyResultType type)
{
if (alias == null) throw new ArgumentNullException("alias");
if (value == null) throw new ArgumentNullException("value");
Alias = alias;
Value = value;
PropertyType = type;
_type = type;
_alias = alias;
_value = value;
}
internal PropertyResultType PropertyType { get; private set; }
public string Alias { get; private set; }
internal PropertyResultType PropertyType { get { return _type; } }
public object Value { get; private set; }
/// <summary>
/// Returns the value as a string output, this is used in the final rendering process of a property
/// </summary>
internal string ValueAsString
{
get
{
return Value == null ? "" : Convert.ToString(Value);
}
}
/// <summary>
/// The Id of the document for which this property belongs to
/// </summary>
public int DocumentId { get; set; }
/// <summary>
/// The alias of the document type alias for which this property belongs to
/// </summary>
public string DocumentTypeAlias { get; set; }
public string PropertyTypeAlias { get { return _source == null ? _alias : _source.PropertyTypeAlias; } }
public object DataValue { get { return _source == null ? _value : _source.DataValue; } }
public bool HasValue { get { return _source == null || _source.HasValue; } }
public object Value { get { return _source == null ? _value : _source.Value; } }
public object XPathValue { get { return Value == null ? null : Value.ToString(); } }
public string ToHtmlString()
{
return ValueAsString;
var value = Value;
return value == null ? string.Empty : value.ToString();
}
}
}
+65 -14
View File
@@ -13,16 +13,45 @@ namespace Umbraco.Core
{
public static IEnumerable<IEnumerable<T>> InGroupsOf<T>(this IEnumerable<T> source, int groupSize)
{
var i = 0;
var length = source.Count();
if (source == null)
throw new NullReferenceException("source");
while ((i * groupSize) < length)
{
yield return source.Skip(i * groupSize).Take(groupSize);
i++;
}
// 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;
}
}
/// <summary>The distinct by.</summary>
/// <param name="source">The source.</param>
@@ -243,23 +272,45 @@ namespace Umbraco.Core
});
}
///<summary>Finds the index of the first item matching an expression in an enumerable.</summary>
///<param name="items">The enumerable to search.</param>
///<param name="predicate">The expression to test the items against.</param>
///<returns>The index of the first matching item, or -1 if no items match.</returns>
/// <summary>
/// Finds the index of the first item matching an expression in an enumerable.
/// </summary>
/// <typeparam name="T">The type of the enumerated objects.</typeparam>
/// <param name="items">The enumerable to search.</param>
/// <param name="predicate">The expression to test the items against.</param>
/// <returns>The index of the first matching item, or -1.</returns>
public static int FindIndex<T>(this IEnumerable<T> items, Func<T, bool> predicate)
{
return FindIndex(items, 0, predicate);
}
/// <summary>
/// Finds the index of the first item matching an expression in an enumerable.
/// </summary>
/// <typeparam name="T">The type of the enumerated objects.</typeparam>
/// <param name="items">The enumerable to search.</param>
/// <param name="startIndex">The index to start at.</param>
/// <param name="predicate">The expression to test the items against.</param>
/// <returns>The index of the first matching item, or -1.</returns>
public static int FindIndex<T>(this IEnumerable<T> items, int startIndex, Func<T, bool> predicate)
{
if (items == null) throw new ArgumentNullException("items");
if (predicate == null) throw new ArgumentNullException("predicate");
if (startIndex < 0) throw new ArgumentOutOfRangeException("startIndex");
var index = startIndex;
if (index > 0)
items = items.Skip(index);
var retVal = 0;
foreach (var item in items)
{
if (predicate(item)) return retVal;
retVal++;
if (predicate(item)) return index;
index++;
}
return -1;
}
///<summary>Finds the index of the first occurence of an item in an enumerable.</summary>
///<param name="items">The enumerable to search.</param>
///<param name="item">The item to find.</param>
+14
View File
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Umbraco.Core
{
/// <summary>
/// Any class implementing this interface that is added to the httpcontext.items keys or values will be disposed of at the end of the request.
/// </summary>
public interface IDisposeOnRequestEnd : IDisposable
{
}
}
+1 -1
View File
@@ -10,7 +10,7 @@ namespace Umbraco.Core.Macros
/// </summary>
internal class MacroTagParser
{
private static readonly Regex MacroRteContent = new Regex(@"(<div class=[""']umb-macro-holder.+?[""'].*?>.*?<!--\s*?)(<\?UMBRACO_MACRO.*?/>)(.*?</div>)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
private static readonly Regex MacroRteContent = new Regex(@"(<div.*?>.*?<!--\s*?)(<\?UMBRACO_MACRO.*?/>)(.*?</div>)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
private static readonly Regex MacroPersistedFormat = new Regex(@"(<\?UMBRACO_MACRO macroAlias=[""'](\w+?)[""'].+?)(?:/>|>.*?</\?UMBRACO_MACRO>)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
/// <summary>
+28 -6
View File
@@ -6,6 +6,7 @@ using System.Text.RegularExpressions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Core.Manifest
@@ -18,7 +19,8 @@ namespace Umbraco.Core.Manifest
private readonly DirectoryInfo _pluginsDir;
//used to strip comments
private static readonly Regex Comments = new Regex("(/\\*.*\\*/)", RegexOptions.Compiled);
private static readonly Regex CommentsSurround = new Regex(@"/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/", RegexOptions.Compiled);
private static readonly Regex CommentsLine = new Regex(@"//.*?$", RegexOptions.Compiled | RegexOptions.Multiline);
public ManifestParser(DirectoryInfo pluginsDir)
{
@@ -116,11 +118,20 @@ namespace Umbraco.Core.Manifest
{
if (m.IsNullOrWhiteSpace()) continue;
//remove any comments first, NOTE: I think JSON.Net will do this for us! but we'll leave it here for now
Comments.Replace(m, match => "");
//remove any comments first
var replaced = CommentsSurround.Replace(m, match => " ");
replaced = CommentsLine.Replace(replaced, match => "");
var deserialized = JsonConvert.DeserializeObject<JObject>(m);
JObject deserialized;
try
{
deserialized = JsonConvert.DeserializeObject<JObject>(replaced);
}
catch (Exception ex)
{
LogHelper.Error<ManifestParser>("An error occurred parsing manifest with contents: " + m, ex);
continue;
}
//validate the javascript
var init = deserialized.Properties().Where(x => x.Name == "javascript").ToArray();
@@ -128,7 +139,14 @@ namespace Umbraco.Core.Manifest
{
throw new FormatException("The manifest is not formatted correctly contains more than one 'javascript' element");
}
//validate the css
var cssinit = deserialized.Properties().Where(x => x.Name == "css").ToArray();
if (cssinit.Length > 1)
{
throw new FormatException("The manifest is not formatted correctly contains more than one 'css' element");
}
//validate the property editors section
var propEditors = deserialized.Properties().Where(x => x.Name == "propertyEditors").ToArray();
if (propEditors.Length > 1)
@@ -139,6 +157,9 @@ namespace Umbraco.Core.Manifest
var jConfig = init.Any() ? (JArray)deserialized["javascript"] : new JArray();
ReplaceVirtualPaths(jConfig);
var cssConfig = cssinit.Any() ? (JArray)deserialized["css"] : new JArray();
ReplaceVirtualPaths(cssConfig);
//replace virtual paths for each property editor
if (deserialized["propertyEditors"] != null)
{
@@ -158,6 +179,7 @@ namespace Umbraco.Core.Manifest
var manifest = new PackageManifest()
{
JavaScriptInitialize = jConfig,
StylesheetInitialize = cssConfig,
PropertyEditors = propEditors.Any() ? (JArray)deserialized["propertyEditors"] : new JArray(),
ParameterEditors = propEditors.Any() ? (JArray)deserialized["parameterEditors"] : new JArray()
};
@@ -12,6 +12,11 @@ namespace Umbraco.Core.Manifest
/// </summary>
public JArray JavaScriptInitialize { get; set; }
/// <summary>
/// The json array used to initialize the application with the CSS dependencies required
/// </summary>
public JArray StylesheetInitialize { get; set; }
/// <summary>
/// The json array of property editors
/// </summary>
+8 -1
View File
@@ -16,8 +16,15 @@ namespace Umbraco.Core.Media
/// <summary>
/// A helper class used for imaging
/// </summary>
internal class ImageHelper
internal static class ImageHelper
{
public static string GetMimeType(this Image image)
{
var format = image.RawFormat;
var codec = ImageCodecInfo.GetImageDecoders().First(c => c.FormatID == format.Guid);
return codec.MimeType;
}
internal static IEnumerable<ResizedImage> GenerateMediaThumbnails(
IFileSystem fs,
string fileName,
+3 -3
View File
@@ -4,7 +4,7 @@ using System.Diagnostics;
namespace Umbraco.Core.Models
{
[DebuggerDisplay("Tree - {Title} ({ApplicationAlias})")]
internal class ApplicationTree
public class ApplicationTree
{
/// <summary>
/// Initializes a new instance of the <see cref="ApplicationTree"/> class.
@@ -23,7 +23,7 @@ namespace Umbraco.Core.Models
/// <param name="iconClosed">The icon closed.</param>
/// <param name="iconOpened">The icon opened.</param>
/// <param name="type">The tree type.</param>
public ApplicationTree(bool initialize, byte sortOrder, string applicationAlias, string alias, string title, string iconClosed, string iconOpened, string type)
public ApplicationTree(bool initialize, int sortOrder, string applicationAlias, string alias, string title, string iconClosed, string iconOpened, string type)
{
this.Initialize = initialize;
this.SortOrder = sortOrder;
@@ -45,7 +45,7 @@ namespace Umbraco.Core.Models
/// Gets or sets the sort order.
/// </summary>
/// <value>The sort order.</value>
public byte SortOrder { get; set; }
public int SortOrder { get; set; }
/// <summary>
/// Gets the application alias.
+19 -1
View File
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
@@ -50,6 +51,7 @@ namespace Umbraco.Core.Models
_contentTypeId = int.Parse(contentType.Id.ToString(CultureInfo.InvariantCulture));
_properties = properties;
_properties.EnsurePropertyTypes(PropertyTypes);
_additionalData = new Dictionary<string, object>();
}
/// <summary>
@@ -73,6 +75,7 @@ namespace Umbraco.Core.Models
_contentTypeId = int.Parse(contentType.Id.ToString(CultureInfo.InvariantCulture));
_properties = properties;
_properties.EnsurePropertyTypes(PropertyTypes);
_additionalData = new Dictionary<string, object>();
}
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<ContentBase, string>(x => x.Name);
@@ -253,6 +256,21 @@ 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>
[EditorBrowsable(EditorBrowsableState.Never)]
IDictionary<string, object> IUmbracoEntity.AdditionalData
{
get { return _additionalData; }
}
/// <summary>
/// Some entities may expose additional data that other's might not, this custom data will be available in this collection
/// </summary>
public IDictionary<string, object> AdditionalData { get; private set; }
/// <summary>
/// List of PropertyGroups available on this Content object
/// </summary>
@@ -446,7 +464,7 @@ namespace Umbraco.Core.Models
/// also reset the dirty changes made to the content's Properties (user defined)
/// </summary>
/// <param name="rememberPreviouslyChangedProperties"></param>
internal override void ResetDirtyProperties(bool rememberPreviouslyChangedProperties)
public override void ResetDirtyProperties(bool rememberPreviouslyChangedProperties)
{
base.ResetDirtyProperties(rememberPreviouslyChangedProperties);
+95 -14
View File
@@ -58,7 +58,7 @@ namespace Umbraco.Core.Models
internal static bool ShouldCreateNewVersion(this IContent entity, PublishedState publishedState)
{
var dirtyEntity = (ICanBeDirty)entity;
//check if the published state has changed or the language
var contentChanged =
(dirtyEntity.IsPropertyDirty("Published") && publishedState != PublishedState.Unpublished)
@@ -71,9 +71,9 @@ namespace Umbraco.Core.Models
}
//check if any user prop has changed
var propertyValueChanged = ((Content) entity).IsAnyUserPropertyDirty();
var propertyValueChanged = ((Content)entity).IsAnyUserPropertyDirty();
//check if any content prop has changed
var contentDataChanged = ((Content) entity).IsEntityDirty();
var contentDataChanged = ((Content)entity).IsEntityDirty();
//return true if the item is published and a property has changed or if any content property has changed
return (propertyValueChanged && publishedState == PublishedState.Published) || contentDataChanged;
@@ -296,7 +296,7 @@ namespace Umbraco.Core.Models
.Select(propertyType => propertyType.Id)
.Contains(property.PropertyTypeId))
.OrderBy(x => x.PropertyType.SortOrder);
}
}
/// <summary>
/// Set property values by alias with an annonymous object
@@ -334,6 +334,8 @@ namespace Umbraco.Core.Models
}
}
#region SetValue for setting file contents
/// <summary>
/// Sets and uploads the file from a HttpPostedFileBase object as the property value
/// </summary>
@@ -380,7 +382,7 @@ namespace Umbraco.Core.Models
{
SetValue(content, propertyTypeAlias, (HttpPostedFileBase)value);
}
/// <summary>
/// Sets and uploads the file from a <see cref="Stream"/> as the property value
/// </summary>
@@ -416,7 +418,7 @@ namespace Umbraco.Core.Models
var fs = FileSystemProviderManager.Current.GetFileSystemProvider<MediaFileSystem>();
fs.AddFile(fileName, fileStream);
//Check if file supports resizing and create thumbnails
var supportsResizing = UmbracoConfig.For.UmbracoSettings().Content.ImageFileTypes.InvariantContains(extension);
@@ -461,14 +463,14 @@ namespace Umbraco.Core.Models
}
ImageHelper.GenerateMediaThumbnails(fs, fileName, extension, originalImage, additionalSizes);
//while the image is still open, we'll check if we need to auto-populate the image properties
if (uploadFieldConfigNode != null)
{
content.SetValue(uploadFieldConfigNode.WidthFieldAlias, originalImage.Width.ToString(CultureInfo.InvariantCulture));
content.SetValue(uploadFieldConfigNode.HeightFieldAlias, originalImage.Height.ToString(CultureInfo.InvariantCulture));
}
}
}
@@ -482,12 +484,15 @@ namespace Umbraco.Core.Models
//Set the value of the property to that of the uploaded file's url
property.Value = fs.GetUrl(fileName);
}
/// <summary>
/// Gets the <see cref="IProfile"/> for the Creator of this media item.
/// </summary>
public static IProfile GetCreatorProfile(this IMedia media)
{
#endregion
#region User/Profile methods
/// <summary>
/// Gets the <see cref="IProfile"/> for the Creator of this media item.
/// </summary>
public static IProfile GetCreatorProfile(this IMedia media)
{
return ApplicationContext.Current.Services.UserService.GetProfileById(media.CreatorId);
}
@@ -506,6 +511,7 @@ namespace Umbraco.Core.Models
{
return ApplicationContext.Current.Services.UserService.GetProfileById(content.WriterId);
}
#endregion
/// <summary>
/// Checks whether an <see cref="IContent"/> item has any published versions
@@ -519,7 +525,77 @@ namespace Umbraco.Core.Models
return ApplicationContext.Current.Services.ContentService.HasPublishedVersion(content.Id);
}
#region Tag methods
/// <summary>
/// Sets tags for the property - will add tags to the tags table and set the property value to be the comma delimited value of the tags.
/// </summary>
/// <param name="content">The content item to assign the tags to</param>
/// <param name="propertyTypeAlias">The property alias to assign the tags to</param>
/// <param name="tags">The tags to assign</param>
/// <param name="replaceTags">True to replace the tags on the current property with the tags specified or false to merge them with the currently assigned ones</param>
/// <param name="tagGroup">The group/category to assign the tags, the default value is "default"</param>
/// <returns></returns>
public static void SetTags(this IContentBase content, string propertyTypeAlias, IEnumerable<string> tags, bool replaceTags, string tagGroup = "default")
{
var property = content.Properties[propertyTypeAlias];
if (property == null)
{
throw new IndexOutOfRangeException("No property exists with name " + propertyTypeAlias);
}
var trimmedTags = tags.Select(x => x.Trim()).ToArray();
property.TagSupport.Enable = true;
property.TagSupport.Tags = trimmedTags.Select(x => new Tuple<string, string>(x, tagGroup));
property.TagSupport.Behavior = replaceTags ? PropertyTagBehavior.Replace : PropertyTagBehavior.Merge;
//ensure the property value is set to the same thing
if (replaceTags)
{
property.Value = string.Join(",", trimmedTags);
}
else
{
var currTags = property.Value.ToString().Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries)
.Select(x => x.Trim());
property.Value = string.Join(",", trimmedTags.Union(currTags));
}
}
/// <summary>
/// Remove any of the tags specified in the collection from the property if they are currently assigned.
/// </summary>
/// <param name="content"></param>
/// <param name="propertyTypeAlias"></param>
/// <param name="tags"></param>
/// <param name="tagGroup">The group/category that the tags are currently assigned to, the default value is "default"</param>
public static void RemoveTags(this IContentBase content, string propertyTypeAlias, IEnumerable<string> tags, string tagGroup = "default")
{
var property = content.Properties[propertyTypeAlias];
if (property == null)
{
throw new IndexOutOfRangeException("No property exists with name " + propertyTypeAlias);
}
var trimmedTags = tags.Select(x => x.Trim()).ToArray();
property.TagSupport.Behavior = PropertyTagBehavior.Remove;
property.TagSupport.Enable = true;
property.TagSupport.Tags = trimmedTags.Select(x => new Tuple<string, string>(x, tagGroup));
//set the property value
var currTags = property.Value.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(x => x.Trim());
property.Value = string.Join(",", currTags.Except(trimmedTags));
}
#endregion
#region XML methods
/// <summary>
/// Creates the full xml representation for the <see cref="IContent"/> object and all of it's descendants
/// </summary>
@@ -567,5 +643,10 @@ namespace Umbraco.Core.Models
//If current IContent is published we should get latest unpublished version
return content.ToXml();
}
#endregion
}
}
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
@@ -42,6 +43,7 @@ namespace Umbraco.Core.Models
_allowedContentTypes = new List<ContentTypeSort>();
_propertyGroups = new PropertyGroupCollection();
_propertyTypes = new PropertyTypeCollection();
_additionalData = new Dictionary<string, object>();
}
protected ContentTypeBase(IContentTypeBase parent)
@@ -52,6 +54,7 @@ namespace Umbraco.Core.Models
_allowedContentTypes = new List<ContentTypeSort>();
_propertyGroups = new PropertyGroupCollection();
_propertyTypes = new PropertyTypeCollection();
_additionalData = new Dictionary<string, object>();
}
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, string>(x => x.Name);
@@ -314,6 +317,21 @@ 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>
[EditorBrowsable(EditorBrowsableState.Never)]
IDictionary<string, object> IUmbracoEntity.AdditionalData
{
get { return _additionalData; }
}
/// <summary>
/// Some entities may expose additional data that other's might not, this custom data will be available in this collection
/// </summary>
public IDictionary<string, object> AdditionalData { get; private set; }
/// <summary>
/// Gets or sets a list of integer Ids for allowed ContentTypes
/// </summary>
+32 -3
View File
@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
@@ -33,12 +35,15 @@ namespace Umbraco.Core.Models
{
_parentId = parentId;
_propertyEditorAlias = LegacyPropertyEditorIdToAliasConverter.GetAliasFromLegacyId(controlId, true);
_additionalData = new Dictionary<string, object>();
}
public DataTypeDefinition(int parentId, string propertyEditorAlias)
{
_parentId = parentId;
_propertyEditorAlias = propertyEditorAlias;
_additionalData = new Dictionary<string, object>();
}
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<DataTypeDefinition, string>(x => x.Name);
@@ -170,9 +175,11 @@ namespace Umbraco.Core.Models
_trashed = value;
return _trashed;
}, _trashed, TrashedSelector);
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
_additionalData["Trashed"] = value;
}
}
[DataMember]
public string PropertyEditorAlias
{
@@ -184,6 +191,8 @@ namespace Umbraco.Core.Models
_propertyEditorAlias = value;
return _propertyEditorAlias;
}, _propertyEditorAlias, PropertyEditorAliasSelector);
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
_additionalData["DatabaseType"] = value;
}
}
@@ -203,6 +212,8 @@ namespace Umbraco.Core.Models
{
var alias = LegacyPropertyEditorIdToAliasConverter.GetAliasFromLegacyId(value, true);
PropertyEditorAlias = alias;
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
_additionalData["ControlId"] = value;
}
}
@@ -220,9 +231,27 @@ namespace Umbraco.Core.Models
_databaseType = value;
return _databaseType;
}, _databaseType, DatabaseTypeSelector);
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
_additionalData["DatabaseType"] = value;
}
}
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>
[EditorBrowsable(EditorBrowsableState.Never)]
IDictionary<string, object> IUmbracoEntity.AdditionalData
{
get { return _additionalData; }
}
/// <summary>
/// Some entities may expose additional data that other's might not, this custom data will be available in this collection
/// </summary>
public IDictionary<string, object> AdditionalData { get; private set; }
internal override void AddingEntity()
{
base.AddingEntity();
@@ -231,4 +260,4 @@ namespace Umbraco.Core.Models
Key = Guid.NewGuid();
}
}
}
}
@@ -9,5 +9,6 @@
bool WasDirty();
bool WasPropertyDirty(string propertyName);
void ForgetPreviouslyDirtyProperties();
void ResetDirtyProperties(bool rememberPreviouslyChangedProperties);
}
}
@@ -1,4 +1,6 @@
namespace Umbraco.Core.Models.EntityBase
using System.Collections.Generic;
namespace Umbraco.Core.Models.EntityBase
{
public interface IUmbracoEntity : IAggregateRoot
{
@@ -41,5 +43,10 @@
/// Not all entities support being trashed, they'll always return false.
/// </remarks>
bool Trashed { get; }
/// <summary>
/// Some entities may expose additional data that other's might not, this custom data will be available in this collection
/// </summary>
IDictionary<string, object> AdditionalData { get; }
}
}
@@ -108,7 +108,7 @@ namespace Umbraco.Core.Models.EntityBase
/// Please note that resetting the dirty properties could potentially
/// obstruct the saving of a new or updated entity.
/// </remarks>
internal virtual void ResetDirtyProperties(bool rememberPreviouslyChangedProperties)
public virtual void ResetDirtyProperties(bool rememberPreviouslyChangedProperties)
{
if (rememberPreviouslyChangedProperties)
{
+122 -29
View File
@@ -1,20 +1,48 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.Models
{
/// <summary>
/// Defines a published item in Umbraco
/// Represents a cached content.
/// </summary>
/// <remarks>
/// A replacement for INode which needs to occur since INode doesn't contain the document type alias
/// and INode is poorly formatted with mutable properties (i.e. Lists instead of IEnumerable)
/// <para>SD: A replacement for INode which needs to occur since INode doesn't contain the document type alias
/// and INode is poorly formatted with mutable properties (i.e. Lists instead of IEnumerable).</para>
/// <para>Stephan: initially, that was for cached published content only. Now, we're using it also for
/// cached preview (so, maybe unpublished) content. A better name would therefore be ICachedContent, as
/// has been suggested. However, can't change now. Maybe in v7?</para>
/// </remarks>
public interface IPublishedContent
{
int Id { get; }
public interface IPublishedContent
{
#region ContentSet
// Because of http://issues.umbraco.org/issue/U4-1797 and in order to implement
// Index() and methods that derive from it such as IsFirst(), IsLast(), etc... all
// content items must know about their containing content set.
/// <summary>
/// Gets the content set to which the content belongs.
/// </summary>
/// <remarks>The default set consists in the siblings of the content (including the content
/// itself) ordered by <c>sortOrder</c>.</remarks>
IEnumerable<IPublishedContent> ContentSet { get; }
#endregion
#region ContentType
/// <summary>
/// Gets the content type.
/// </summary>
PublishedContentType ContentType { get; }
#endregion
#region Content
int Id { get; }
int TemplateId { get; }
int SortOrder { get; }
string Name { get; }
@@ -31,32 +59,97 @@ namespace Umbraco.Core.Models
Guid Version { get; }
int Level { get; }
string Url { get; }
/// <summary>
/// Gets a value indicating whether the content is a content (aka a document) or a media.
/// </summary>
PublishedItemType ItemType { get; }
/// <summary>
/// Gets a value indicating whether the content is draft.
/// </summary>
/// <remarks>A content is draft when it is the unpublished version of a content, which may
/// have a published version, or not.</remarks>
bool IsDraft { get; }
/// <summary>
/// Gets the index of the published content within its current owning content set.
/// </summary>
/// <returns>The index of the published content within its current owning content set.</returns>
int GetIndex();
#endregion
#region Tree
/// <summary>
/// Gets the parent of the content.
/// </summary>
/// <remarks>The parent of root content is <c>null</c>.</remarks>
IPublishedContent Parent { get; }
/// <summary>
/// Gets the children of the content.
/// </summary>
/// <remarks>Children are sorted by their sortOrder.</remarks>
IEnumerable<IPublishedContent> Children { get; }
ICollection<IPublishedContentProperty> Properties { get; }
#endregion
/// <summary>
/// Returns the property value for the property alias specified
/// </summary>
/// <param name="propertyAlias"></param>
/// <returns></returns>
object this[string propertyAlias] { get; }
#region Properties
/// <summary>
/// Returns a property on the object based on an alias
/// <summary>
/// Gets the properties of the content.
/// </summary>
/// <remarks>
/// <para>Contains one <c>IPublishedProperty</c> for each property defined for the content type, including
/// inherited properties. Some properties may have no value.</para>
/// <para>The properties collection of an IPublishedContent instance should be read-only ie it is illegal
/// to add properties to the collection.</para>
/// </remarks>
ICollection<IPublishedProperty> Properties { get; }
/// <summary>
/// Gets a property identified by its alias.
/// </summary>
/// <param name="alias">The property alias.</param>
/// <returns>The property identified by the alias.</returns>
/// <remarks>
/// <para>If the content type has no property with that alias, including inherited properties, returns <c>null</c>,</para>
/// <para>otherwise return a property -- that may have no value (ie <c>HasValue</c> is <c>false</c>).</para>
/// <para>The alias is case-insensitive.</para>
/// </remarks>
IPublishedProperty GetProperty(string alias);
/// <summary>
/// Gets a property identified by its alias.
/// </summary>
/// <param name="alias">The property alias.</param>
/// <param name="recurse">A value indicating whether to navigate the tree upwards until a property with a value is found.</param>
/// <returns>The property identified by the alias.</returns>
/// <remarks>
/// <para>Navigate the tree upwards and look for a property with that alias and with a value (ie <c>HasValue</c> is <c>true</c>).
/// If found, return the property. If no property with that alias is found, having a value or not, return <c>null</c>. Otherwise
/// return the first property that was found with the alias but had no value (ie <c>HasValue</c> is <c>false</c>).</para>
/// <para>The alias is case-insensitive.</para>
/// </remarks>
IPublishedProperty GetProperty(string alias, bool recurse);
/// <summary>
/// Gets the value of a property identified by its alias.
/// </summary>
/// <param name="alias"></param>
/// <returns></returns>
/// <remarks>
/// Although we do have a a property to return Properties of the object, in some cases a custom implementation may not know
/// about all properties until specifically asked for one by alias.
///
/// This method is mostly used in places such as DynamicPublishedContent when trying to resolve a property based on an alias.
/// In some cases Pulish Stores, a property value may exist in multiple places and we need to fallback to different cached locations
/// therefore sometimes the 'Properties' collection may not be sufficient.
/// </remarks>
IPublishedContentProperty GetProperty(string alias);
}
/// <param name="alias">The property alias.</param>
/// <returns>The value of the property identified by the alias.</returns>
/// <remarks>
/// <para>If <c>GetProperty(alias)</c> is <c>null</c> then returns <c>null</c> else return <c>GetProperty(alias).Value</c>.</para>
/// <para>So if the property has no value, returns the default value for that property type.</para>
/// <para>This one is defined here really because we cannot define index extension methods, but all it should do is:
/// <code>var p = GetProperty(alias); return p == null ? null : p.Value;</code> and nothing else.</para>
/// <para>The recursive syntax (eg "_title") is _not_ supported here.</para>
/// <para>The alias is case-insensitive.</para>
/// </remarks>
object this[string alias] { get; } // todo - should obsolete this[alias] (when?)
#endregion
}
}
@@ -1,10 +0,0 @@
using System;
namespace Umbraco.Core.Models
{
public interface IPublishedContentProperty
{
string Alias { get; }
object Value { get; }
}
}
@@ -0,0 +1,60 @@
namespace Umbraco.Core.Models
{
/// <summary>
/// Represents a property of an <c>IPublishedContent</c>.
/// </summary>
public interface IPublishedProperty
{
/// <summary>
/// Gets the alias of the property.
/// </summary>
string PropertyTypeAlias { get; }
/// <summary>
/// Gets a value indicating whether the property has a value.
/// </summary>
/// <remarks>
/// <para>This is somewhat implementation-dependent -- depending on whatever IPublishedCache considers
/// a missing value.</para>
/// <para>The XmlPublishedCache raw values are strings, and it will consider missing, null or empty (and
/// that includes whitespace-only) strings as "no value".</para>
/// <para>Other caches that get their raw value from the database would consider that a property has "no
/// value" if it is missing, null, or an empty string (including whitespace-only).</para>
/// </remarks>
bool HasValue { get; }
/// <summary>
/// Gets the data value of the property.
/// </summary>
/// <remarks>
/// <para>The data value is whatever was passed to the property when it was instanciated, and it is
/// somewhat implementation-dependent -- depending on how the IPublishedCache is implemented.</para>
/// <para>The XmlPublishedCache raw values are strings exclusively since they come from the Xml cache.</para>
/// <para>For other caches that get their raw value from the database, it would be either a string,
/// an integer (Int32), or a date and time (DateTime).</para>
/// <para>If you're using that value, you're probably wrong, unless you're doing some internal
/// Umbraco stuff.</para>
/// </remarks>
object DataValue { get; }
/// <summary>
/// Gets the object value of the property.
/// </summary>
/// <remarks>
/// <para>The value is what you want to use when rendering content in an MVC view ie in C#.</para>
/// <para>It can be null, or any type of CLR object.</para>
/// <para>It has been fully prepared and processed by the appropriate converter.</para>
/// </remarks>
object Value { get; }
/// <summary>
/// Gets the XPath value of the property.
/// </summary>
/// <remarks>
/// <para>The XPath value is what you want to use when navigating content via XPath eg in the XSLT engine.</para>
/// <para>It must be either null, or a string, or an XPathNavigator.</para>
/// <para>It has been fully prepared and processed by the appropriate converter.</para>
/// </remarks>
object XPathValue { get; }
}
}
+17
View File
@@ -0,0 +1,17 @@
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Models
{
public interface ITag : IAggregateRoot
{
[DataMember]
string Text { get; set; }
[DataMember]
string Group { get; set; }
//TODO: enable this at some stage
//int ParentId { get; set; }
}
}
+1 -1
View File
@@ -172,7 +172,7 @@ namespace Umbraco.Core.Models
OnPropertyChanged(PropertiesSelector);
}
internal override void ResetDirtyProperties(bool rememberPreviouslyChangedProperties)
public override void ResetDirtyProperties(bool rememberPreviouslyChangedProperties)
{
_addedProperties.Clear();
_removedProperties.Clear();
+24 -6
View File
@@ -20,19 +20,37 @@ namespace Umbraco.Core.Models
private object _providerUserKey;
private Type _userTypeKey;
public Member(string name, int parentId, IMemberType contentType, PropertyCollection properties) : base(name, parentId, contentType, properties)
/// <summary>
/// Constructor for creating a Member object
/// </summary>
/// <param name="name">Name of the content</param>
/// <param name="contentType">ContentType for the current Content object</param>
public Member(string name, IMemberType contentType)
: base(name, -1, contentType, new PropertyCollection())
{
Mandate.ParameterNotNull(contentType, "contentType");
_contentType = contentType;
}
public Member(string name, IContentBase parent, IMemberType contentType, PropertyCollection properties)
: base(name, parent, contentType, properties)
public Member(string name, string email, string username, string password, int parentId, IMemberType contentType)
: base(name, parentId, contentType, new PropertyCollection())
{
Mandate.ParameterNotNull(contentType, "contentType");
_contentType = contentType;
_email = email;
_username = username;
_password = password;
}
public Member(string name, string email, string username, string password, IContentBase parent, IMemberType contentType)
: base(name, parent, contentType, new PropertyCollection())
{
Mandate.ParameterNotNull(contentType, "contentType");
_contentType = contentType;
_email = email;
_username = username;
_password = password;
}
private static readonly PropertyInfo DefaultContentTypeAliasSelector = ExpressionHelper.GetPropertyInfo<Member, string>(x => x.ContentTypeAlias);
@@ -420,7 +438,7 @@ namespace Umbraco.Core.Models
public override void ChangeTrashedState(bool isTrashed, int parentId = -20)
{
throw new NotImplementedException("Members can't be trashed as no Recycle Bin exists, so use of this method is invalid");
throw new NotSupportedException("Members can't be trashed as no Recycle Bin exists, so use of this method is invalid");
}
/* Internal experiment - only used for mapping queries.
+21
View File
@@ -114,5 +114,26 @@ namespace Umbraco.Core.Models
MemberTypePropertyTypes.Add(propertyTypeAlias, tuple);
}
}
/// <summary>
/// Method to call when Entity is being saved
/// </summary>
/// <remarks>Created date is set and a Unique key is assigned</remarks>
internal override void AddingEntity()
{
base.AddingEntity();
if (Key == Guid.Empty)
Key = Guid.NewGuid();
}
/// <summary>
/// Method to call when Entity is being updated
/// </summary>
/// <remarks>Modified Date is set and a new Version guid is set</remarks>
internal override void UpdatingEntity()
{
base.UpdatingEntity();
}
}
}
@@ -2,6 +2,8 @@
namespace Umbraco.Core.Models.Membership
{
//TODO: THere's still a bunch of properties that don't exist in this use that need to be mapped somehow.
internal class UmbracoMembershipMember : MembershipUser
{
private readonly IMember _member;
@@ -21,5 +23,44 @@ namespace Umbraco.Core.Models.Membership
get { return _member.Email; }
set { _member.Email = value; }
}
public override object ProviderUserKey
{
get { return _member.Key; }
}
public override System.DateTime CreationDate
{
get { return _member.CreateDate; }
}
public override string UserName
{
get { return _member.Username; }
}
public override string Comment
{
get { return _member.Comments; }
set { _member.Comments = value; }
}
public override bool IsApproved
{
get { return _member.IsApproved; }
set { _member.IsApproved = value; }
}
public override bool IsLockedOut
{
get { return _member.IsLockedOut; }
}
public override System.DateTime LastLoginDate
{
get { return _member.LastLoginDate; }
set { _member.LastLoginDate = value; }
}
}
}
@@ -133,7 +133,7 @@ namespace Umbraco.Core.Models.Membership
/// be flagged as dirty.
/// </summary>
/// <param name="rememberPreviouslyChangedProperties"></param>
internal override void ResetDirtyProperties(bool rememberPreviouslyChangedProperties)
public override void ResetDirtyProperties(bool rememberPreviouslyChangedProperties)
{
_addedSections.Clear();
_removedSections.Clear();
@@ -1,63 +1,63 @@
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Umbraco.Web.Models
{
/// <summary>
/// Represents a paged result for a model collection
/// </summary>
/// <typeparam name="T"></typeparam>
[DataContract(Name = "pagedCollection", Namespace = "")]
public class PagedResult<T>
{
public PagedResult(long totalItems, long pageNumber, long pageSize)
{
TotalItems = totalItems;
PageNumber = pageNumber;
PageSize = pageSize;
if (pageSize > 0)
{
TotalPages = (long) Math.Ceiling(totalItems/(Decimal) pageSize);
}
else
{
TotalPages = 1;
}
}
[DataMember(Name = "pageNumber")]
public long PageNumber { get; private set; }
[DataMember(Name = "pageSize")]
public long PageSize { get; private set; }
[DataMember(Name = "totalPages")]
public long TotalPages { get; private set; }
[DataMember(Name = "totalItems")]
public long TotalItems { get; private set; }
[DataMember(Name = "items")]
public IEnumerable<T> Items { get; set; }
/// <summary>
/// Calculates the skip size based on the paged parameters specified
/// </summary>
/// <remarks>
/// Returns 0 if the page number or page size is zero
/// </remarks>
internal int SkipSize
{
get
{
if (PageNumber > 0 && PageSize > 0)
{
return Convert.ToInt32((PageNumber - 1)*PageSize);
}
return 0;
}
}
}
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Umbraco.Core.Models
{
/// <summary>
/// Represents a paged result for a model collection
/// </summary>
/// <typeparam name="T"></typeparam>
[DataContract(Name = "pagedCollection", Namespace = "")]
public class PagedResult<T>
{
public PagedResult(long totalItems, long pageNumber, long pageSize)
{
TotalItems = totalItems;
PageNumber = pageNumber;
PageSize = pageSize;
if (pageSize > 0)
{
TotalPages = (long) Math.Ceiling(totalItems/(Decimal) pageSize);
}
else
{
TotalPages = 1;
}
}
[DataMember(Name = "pageNumber")]
public long PageNumber { get; private set; }
[DataMember(Name = "pageSize")]
public long PageSize { get; private set; }
[DataMember(Name = "totalPages")]
public long TotalPages { get; private set; }
[DataMember(Name = "totalItems")]
public long TotalItems { get; private set; }
[DataMember(Name = "items")]
public IEnumerable<T> Items { get; set; }
/// <summary>
/// Calculates the skip size based on the paged parameters specified
/// </summary>
/// <remarks>
/// Returns 0 if the page number or page size is zero
/// </remarks>
internal int SkipSize
{
get
{
if (PageNumber > 0 && PageSize > 0)
{
return Convert.ToInt32((PageNumber - 1)*PageSize);
}
return 0;
}
}
}
}
+9
View File
@@ -16,6 +16,7 @@ namespace Umbraco.Core.Models
private readonly PropertyType _propertyType;
private Guid _version;
private object _value;
private readonly PropertyTags _tagSupport = new PropertyTags();
protected Property()
{
@@ -44,6 +45,14 @@ namespace Umbraco.Core.Models
private static readonly PropertyInfo ValueSelector = ExpressionHelper.GetPropertyInfo<Property, object>(x => x.Value);
private static readonly PropertyInfo VersionSelector = ExpressionHelper.GetPropertyInfo<Property, Guid>(x => x.Version);
/// <summary>
/// Returns the instance of the tag support, by default tags are not enabled
/// </summary>
internal PropertyTags TagSupport
{
get { return _tagSupport; }
}
/// <summary>
/// Returns the Alias of the PropertyType, which this Property is based on
/// </summary>
+14 -28
View File
@@ -20,48 +20,34 @@ namespace Umbraco.Core.Models
return property.ToXml(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="dataTypeService"></param>
/// <returns>Xml of the property and its value</returns>
internal static XElement ToXml(this Property property, IDataTypeService dataTypeService)
{
var nodeName = UmbracoConfig.For.UmbracoSettings().Content.UseLegacyXmlSchema ? "data" : property.Alias.ToSafeAlias();
var xd = new XmlDocument();
var xmlNode = xd.CreateNode(XmlNodeType.Element, nodeName, "");
var xElement = new XElement(nodeName);
//Add the property alias to the legacy schema
if (UmbracoConfig.For.UmbracoSettings().Content.UseLegacyXmlSchema)
{
var alias = xd.CreateAttribute("alias");
alias.Value = property.Alias.ToSafeAlias();
xmlNode.Attributes.Append(alias);
var a = new XAttribute("alias", property.Alias.ToSafeAlias());
xElement.Add(a);
}
// * Get the XML result from the property editor if there is one, otherwise just construct a simple
// XML construct from the value returned from the Property Editor.
// More details discussed here: https://groups.google.com/forum/?fromgroups=#!topic/umbraco-dev/fieWZzHj7oY
//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 cacheValue = propertyEditor.ValueEditor.FormatValueForCache(property);
switch (property.PropertyType.DataTypeDatabaseType)
{
case DataTypeDatabaseType.Date:
case DataTypeDatabaseType.Integer:
xmlNode.AppendChild(xd.CreateTextNode(cacheValue.ToString()));
break;
case DataTypeDatabaseType.Nvarchar:
case DataTypeDatabaseType.Ntext:
//put text in cdata
xmlNode.AppendChild(xd.CreateCDataSection(cacheValue.ToString()));
break;
default:
throw new ArgumentOutOfRangeException();
}
var xmlValue = propertyEditor.ValueEditor.ConvertDbToXml(property);
xElement.Add(xmlValue);
}
var element = xmlNode.GetXElement();
return element;
return xElement;
}
}
}
+43
View File
@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
namespace Umbraco.Core.Models
{
/// <summary>
/// A property extension class that allows us to enable tags for any given property
/// </summary>
internal class PropertyTags
{
public PropertyTags()
{
Enable = false;
Behavior = PropertyTagBehavior.Merge;
}
/// <summary>
/// The behavior of how to save the tags assigned -
/// Merge (keep existing and append new),
/// Remove (remove any of the tags in the Tags property that are currently assigned,
/// Replace (replace the currently assigned tags with the ones specified)
/// </summary>
public PropertyTagBehavior Behavior { get; set; }
/// <summary>
/// Flags the property to have tagging enabled
/// </summary>
public bool Enable { get; set; }
/// <summary>
/// The actual tags to associate - tag/group
/// </summary>
public IEnumerable<Tuple<string, string>> Tags { get; set; }
}
internal enum PropertyTagBehavior
{
Replace,
Remove,
Merge
}
}
@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// Provides methods to handle extended content.
/// </summary>
internal interface IPublishedContentExtended : IPublishedContent
{
/// <summary>
/// Adds a property to the extended content.
/// </summary>
/// <param name="property">The property to add.</param>
void AddProperty(IPublishedProperty property);
/// <summary>
/// Gets a value indicating whether properties were added to the extended content.
/// </summary>
bool HasAddedProperties { get; }
/// <summary>
/// Sets the content set of the extended content.
/// </summary>
/// <param name="contentSet"></param>
void SetContentSet(IEnumerable<IPublishedContent> contentSet);
/// <summary>
/// Resets the content set of the extended content.
/// </summary>
void ClearContentSet();
/// <summary>
/// Sets the index of the extended content.
/// </summary>
/// <param name="value">The index value.</param>
void SetIndex(int value);
/// <summary>
/// Resets the index of the extended content.
/// </summary>
void ClearIndex();
}
}
@@ -0,0 +1,16 @@
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// Provides the model creation service.
/// </summary>
internal interface IPublishedContentModelFactory
{
/// <summary>
/// Creates a strongly-typed model representing a published content.
/// </summary>
/// <param name="content">The original published content.</param>
/// <returns>The strongly-typed model representing the published content, or the published content
/// itself it the factory has no model for that content type.</returns>
IPublishedContent CreateModel(IPublishedContent content);
}
}
@@ -0,0 +1,151 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
namespace Umbraco.Core.Models.PublishedContent
{
public class PublishedContentExtended : PublishedContentWrapped, IPublishedContentExtended
{
#region Constructor
// protected for models, private for our static Extend method
protected PublishedContentExtended(IPublishedContent content)
: base(content)
{ }
#endregion
#region Index
private int? _index;
public override int GetIndex()
{
// fast
if (_index.HasValue) return _index.Value;
// slow -- and don't cache, not in a set
if (_contentSet == null) return Content.GetIndex();
// slow -- but cache for next time
var index = _contentSet.FindIndex(x => x.Id == Id);
if (index < 0)
throw new IndexOutOfRangeException("Could not find content in the content set.");
_index = index;
return index;
}
#endregion
#region Extend
internal static IPublishedContentExtended Extend(IPublishedContent content, IEnumerable<IPublishedContent> contentSet)
{
var wrapped = content as PublishedContentExtended;
while (wrapped != null && ((IPublishedContentExtended)wrapped).HasAddedProperties == false)
wrapped = (content = wrapped.Unwrap()) as PublishedContentExtended;
// if the factory returns something else than content it means it has created
// a model, and then that model has to inherit from PublishedContentExtended,
// => implements the internal IPublishedContentExtended.
var model = PublishedContentModelFactory.CreateModel(content);
var extended = model == content // == means the factory did not create a model
? new PublishedContentExtended(content) // so we have to extend
: model; // else we can use what the factory returned
var extended2 = extended as IPublishedContentExtended;
if (extended2 != null) // always true, but keeps Resharper happy
extended2.SetContentSet(contentSet);
return extended2;
}
#endregion
#region IPublishedContentExtended
void IPublishedContentExtended.AddProperty(IPublishedProperty property)
{
if (_properties == null)
_properties = new Collection<IPublishedProperty>();
_properties.Add(property);
}
bool IPublishedContentExtended.HasAddedProperties
{
get { return _properties != null; }
}
void IPublishedContentExtended.SetContentSet(IEnumerable<IPublishedContent> contentSet)
{
_contentSet = contentSet;
}
void IPublishedContentExtended.ClearContentSet()
{
_contentSet = null;
}
void IPublishedContentExtended.SetIndex(int value)
{
_index = value;
}
void IPublishedContentExtended.ClearIndex()
{
_index = null;
}
#endregion
#region Content set
private IEnumerable<IPublishedContent> _contentSet;
public override IEnumerable<IPublishedContent> ContentSet
{
get { return _contentSet ?? Content.ContentSet; }
}
#endregion
#region Properties
private ICollection<IPublishedProperty> _properties;
public override ICollection<IPublishedProperty> Properties
{
get
{
return _properties == null
? Content.Properties
: Content.Properties.Union(_properties).ToList();
}
}
public override object this[string alias]
{
get
{
if (_properties != null)
{
var property = _properties.FirstOrDefault(prop => prop.PropertyTypeAlias.InvariantEquals(alias));
if (property != null) return property.HasValue ? property.Value : null;
}
return Content[alias];
}
}
public override IPublishedProperty GetProperty(string alias)
{
return _properties == null
? Content.GetProperty(alias)
: _properties.FirstOrDefault(prop => prop.PropertyTypeAlias.InvariantEquals(alias)) ?? Content.GetProperty(alias);
}
#endregion
}
}
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// Represents a strongly-typed published content.
/// </summary>
/// <remarks>Every strongly-typed published content class should inherit from <c>PublishedContentModel</c>
/// (or inherit from a class that inherits from... etc.) so they are picked by the factory.</remarks>
internal abstract class PublishedContentModel : PublishedContentExtended
{
/// <summary>
/// Initializes a new instance of the <see cref="PublishedContentModel"/> class with
/// an original <see cref="IPublishedContent"/> instance.
/// </summary>
/// <param name="content">The original content.</param>
protected PublishedContentModel(IPublishedContent content)
: base(content)
{ }
}
}
@@ -0,0 +1,29 @@
using System;
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// Indicates that the class is a published content model for a specified content type.
/// </summary>
/// <remarks>By default, the name of the class is assumed to be the content type alias. The
/// <c>PublishedContentModelAttribute</c> can be used to indicate a different alias.</remarks>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
internal sealed class PublishedContentModelAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="PublishedContentModelAttribute"/> class with a content type alias.
/// </summary>
/// <param name="contentTypeAlias">The content type alias.</param>
public PublishedContentModelAttribute(string contentTypeAlias)
{
if (string.IsNullOrWhiteSpace(contentTypeAlias))
throw new ArgumentException("Argument cannot be null nor empty.", "contentTypeAlias");
ContentTypeAlias = contentTypeAlias;
}
/// <summary>
/// Gets or sets the content type alias.
/// </summary>
public string ContentTypeAlias { get; private set; }
}
}
@@ -0,0 +1,20 @@
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// Provides strongly typed published content models services.
/// </summary>
internal static class PublishedContentModelFactory
{
/// <summary>
/// Creates a strongly typed published content model for an internal published content.
/// </summary>
/// <param name="content">The internal published content.</param>
/// <returns>The strongly typed published content model.</returns>
public static IPublishedContent CreateModel(IPublishedContent content)
{
return PublishedContentModelFactoryResolver.Current.HasValue
? PublishedContentModelFactoryResolver.Current.Factory.CreateModel(content)
: content;
}
}
}
@@ -0,0 +1,69 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// Implements a strongly typed content model factory
/// </summary>
internal class PublishedContentModelFactoryImpl : IPublishedContentModelFactory
{
//private readonly Dictionary<string, ConstructorInfo> _constructors
// = new Dictionary<string, ConstructorInfo>();
private readonly Dictionary<string, Func<IPublishedContent, IPublishedContent>> _constructors
= new Dictionary<string, Func<IPublishedContent, IPublishedContent>>();
public PublishedContentModelFactoryImpl()
{
var types = PluginManager.Current.ResolveTypes<PublishedContentModel>();
var ctorArgTypes = new[] { typeof(IPublishedContent) };
foreach (var type in types)
{
if (type.Inherits<PublishedContentModel>() == false)
throw new InvalidOperationException(string.Format("Type {0} is marked with PublishedContentModel attribute but does not inherit from PublishedContentExtended.", type.FullName));
var constructor = type.GetConstructor(ctorArgTypes);
if (constructor == null)
throw new InvalidOperationException(string.Format("Type {0} is missing a public constructor with one argument of type IPublishedContent.", type.FullName));
var attribute = type.GetCustomAttribute<PublishedContentModelAttribute>(false);
var typeName = attribute == null ? type.Name : attribute.ContentTypeAlias;
typeName = typeName.ToLowerInvariant();
if (_constructors.ContainsKey(typeName))
throw new InvalidOperationException(string.Format("More that one type want to be a model for content type {0}.", typeName));
// should work everywhere, but slow
//_constructors[typeName] = constructor;
// much faster with a dynamic method but potential MediumTrust issues
// here http://stackoverflow.com/questions/16363838/how-do-you-call-a-constructor-via-an-expression-tree-on-an-existing-object
// fast enough and works in MediumTrust
// read http://boxbinary.com/2011/10/how-to-run-a-unit-test-in-medium-trust-with-nunitpart-three-umbraco-framework-testing/
var exprArg = Expression.Parameter(typeof(IPublishedContent), "content");
var exprNew = Expression.New(constructor, exprArg);
var expr = Expression.Lambda<Func<IPublishedContent, IPublishedContent>>(exprNew, exprArg);
var func = expr.Compile();
_constructors[typeName] = func;
}
}
public IPublishedContent CreateModel(IPublishedContent content)
{
// be case-insensitive
var contentTypeAlias = content.DocumentTypeAlias.ToLowerInvariant();
//ConstructorInfo constructor;
//return _constructors.TryGetValue(contentTypeAlias, out constructor)
// ? (IPublishedContent) constructor.Invoke(new object[] { content })
// : content;
Func<IPublishedContent, IPublishedContent> constructor;
return _constructors.TryGetValue(contentTypeAlias, out constructor)
? constructor(content)
: content;
}
}
}
@@ -0,0 +1,45 @@
using Umbraco.Core.ObjectResolution;
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// Resolves the IPublishedContentModelFactory object.
/// </summary>
internal class PublishedContentModelFactoryResolver : SingleObjectResolverBase<PublishedContentModelFactoryResolver, IPublishedContentModelFactory>
{
/// <summary>
/// Initializes a new instance of the <see cref="PublishedContentModelFactoryResolver"/>.
/// </summary>
/// <remarks>The resolver is created by the <c>WebBootManager</c> and thus the constructor remains internal.</remarks>
internal PublishedContentModelFactoryResolver()
: base()
{ }
/// <summary>
/// Initializes a new instance of the <see cref="PublishedContentModelFactoryResolver"/> with a factory.
/// </summary>
/// <param name="factory">The factory.</param>
/// <remarks>The resolver is created by the <c>WebBootManager</c> and thus the constructor remains internal.</remarks>
internal PublishedContentModelFactoryResolver(IPublishedContentModelFactory factory)
: base(factory)
{ }
/// <summary>
/// Sets the factory.
/// </summary>
/// <param name="factory">The factory.</param>
/// <remarks>For developers, at application startup.</remarks>
public void SetFactory(IPublishedContentModelFactory factory)
{
Value = factory;
}
/// <summary>
/// Gets the factory.
/// </summary>
public IPublishedContentModelFactory Factory
{
get { return Value; }
}
}
}
@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// Represents an ordered set of <see cref="IPublishedContent"/>.
/// </summary>
/// <typeparam name="T">The type of content.</typeparam>
public class PublishedContentOrderedSet<T> : PublishedContentSet<T>, IOrderedEnumerable<T>
where T : class, IPublishedContent
{
// ReSharper disable ParameterTypeCanBeEnumerable.Local
internal PublishedContentOrderedSet(IOrderedEnumerable<T> content)
// ReSharper restore ParameterTypeCanBeEnumerable.Local
: base(content)
{ }
// note: because we implement IOrderedEnumerable, we don't need to implement the ThenBy nor
// ThenByDescending methods here, only CreateOrderedEnumerable and that does it.
#region IOrderedEnumerable<T>
public IOrderedEnumerable<T> CreateOrderedEnumerable<TKey>(Func<T, TKey> keySelector, IComparer<TKey> comparer, bool descending)
{
return new PublishedContentOrderedSet<T>(((IOrderedEnumerable<T>)Source).CreateOrderedEnumerable(keySelector, comparer, descending));
}
#endregion
}
}
@@ -0,0 +1,234 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// Represents a set of <see cref="IPublishedContent"/>.
/// </summary>
/// <typeparam name="T">The type of content.</typeparam>
/// <remarks>
/// <para>A <c>ContentSet{T}</c> is created from an <c>IEnumerable{T}</c> using the <c>ToContentSet</c>
/// extension method.</para>
/// <para>The content set source is enumerated only once. Same as what you get
/// when you call ToList on an IEnumerable. Only, ToList enumerates its source when
/// created, whereas a content set enumerates its source only when the content set itself
/// is enumerated.</para>
/// </remarks>
public class PublishedContentSet<T> : IEnumerable<T>
where T : class, IPublishedContent
{
// used by <c>ToContentSet</c> extension method to initialize a new set from an IEnumerable.
internal PublishedContentSet(IEnumerable<T> source)
{
if (source == null)
throw new ArgumentNullException("source");
Source = source;
}
#region Source
protected readonly IEnumerable<T> Source;
#endregion
#region Enumerated
// cache the enumeration so we don't enumerate more than once. Same as what you get
// when you call ToList on an IEnumerable. Only, ToList enumerates its source when
// created, whereas a content set enumerates its source only when the content set itself
// is enumerated.
// cache the wrapped items so if we reset the enumeration, we do not re-wrap everything (only new items).
private T[] _enumerated;
private readonly Dictionary<T, IPublishedContentExtended> _xContent = new Dictionary<T, IPublishedContentExtended>();
// wrap an item, ie create the actual clone for this set
private T MapContentAsT(T t)
{
return MapContent(t) as T;
}
internal IPublishedContentExtended MapContent(T t)
{
IPublishedContentExtended extend;
if (_xContent.TryGetValue(t, out extend)) return extend;
extend = PublishedContentExtended.Extend(t, this);
var asT = extend as T;
if (asT == null)
throw new InvalidOperationException(string.Format("Failed extend a published content of type {0}."
+ "Got {1} when expecting {2}.", t.GetType().FullName, extend.GetType().FullName, typeof(T).FullName));
_xContent[t] = extend;
return extend;
}
private T[] Enumerated
{
get
{
// enumerate the source and cache the result
// tell clones about their index within the set (for perfs purposes)
var index = 0;
return _enumerated ?? (_enumerated = Source.Select(t =>
{
var extend = MapContent(t);
extend.SetIndex(index++);
return extend as T;
}).ToArray());
}
}
// indicates that the source has changed
// so the set can clear its inner caches
// should only be used by DynamicPublishedContentList
internal void SourceChanged()
{
// reset the cached enumeration so it's enumerated again
if (_enumerated == null) return;
_enumerated = null;
foreach (var item in _xContent.Values)
item.ClearIndex();
var removed = _xContent.Keys.Except(Source);
foreach (var content in removed)
{
_xContent[content].ClearContentSet();
_xContent.Remove(content);
}
}
/// <summary>
/// Gets the number of items in the set.
/// </summary>
/// <returns>The number of items in the set.</returns>
/// <remarks>Will cause the set to be enumerated if it hasn't been already.</remarks>
public virtual int Count
{
get { return Enumerated.Length; }
}
#endregion
#region IEnumerable<T>
public IEnumerator<T> GetEnumerator()
{
return ((IEnumerable<T>)Enumerated).GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
#region Wrap methods returning T
public T ElementAt(int index)
{
return MapContentAsT(Source.ElementAt(index));
}
public T ElementAtOrDefault(int index)
{
var element = Source.ElementAtOrDefault(index);
return element == null ? null : MapContentAsT(element);
}
public T First()
{
return MapContentAsT(Source.First());
}
public T First(Func<T, bool> predicate)
{
return MapContentAsT(Source.First(predicate));
}
public T FirstOrDefault()
{
var first = Source.FirstOrDefault();
return first == null ? null : MapContentAsT(first);
}
public T FirstOrDefault(Func<T, bool> predicate)
{
var first = Source.FirstOrDefault(predicate);
return first == null ? null : MapContentAsT(first);
}
public T Last()
{
return MapContentAsT(Source.Last());
}
public T Last(Func<T, bool> predicate)
{
return MapContentAsT(Source.Last(predicate));
}
public T LastOrDefault()
{
var last = Source.LastOrDefault();
return last == null ? null : MapContentAsT(last);
}
public T LastOrDefault(Func<T, bool> predicate)
{
var last = Source.LastOrDefault(predicate);
return last == null ? null : MapContentAsT(last);
}
public T Single()
{
return MapContentAsT(Source.Single());
}
public T Single(Func<T, bool> predicate)
{
return MapContentAsT(Source.Single(predicate));
}
public T SingleOrDefault()
{
var single = Source.SingleOrDefault();
return single == null ? null : MapContentAsT(single);
}
public T SingleOrDefault(Func<T, bool> predicate)
{
var single = Source.SingleOrDefault(predicate);
return single == null ? null : MapContentAsT(single);
}
#endregion
#region Wrap methods returning IOrderedEnumerable<T>
public PublishedContentOrderedSet<T> OrderBy<TKey>(Func<T, TKey> keySelector)
{
return new PublishedContentOrderedSet<T>(Source.OrderBy(keySelector));
}
public PublishedContentOrderedSet<T> OrderBy<TKey>(Func<T, TKey> keySelector, IComparer<TKey> comparer)
{
return new PublishedContentOrderedSet<T>(Source.OrderBy(keySelector, comparer));
}
public PublishedContentOrderedSet<T> OrderByDescending<TKey>(Func<T, TKey> keySelector)
{
return new PublishedContentOrderedSet<T>(Source.OrderByDescending(keySelector));
}
public PublishedContentOrderedSet<T> OrderByDescending<TKey>(Func<T, TKey> keySelector, IComparer<TKey> comparer)
{
return new PublishedContentOrderedSet<T>(Source.OrderByDescending(keySelector, comparer));
}
#endregion
}
}
@@ -0,0 +1,168 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Web.Caching;
using System.Web.UI;
using Umbraco.Core.Cache;
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// Represents an <see cref="IPublishedContent"/> type.
/// </summary>
/// <remarks>Instances of the <see cref="PublishedContentType"/> class are immutable, ie
/// if the content type changes, then a new class needs to be created.</remarks>
public class PublishedContentType
{
private readonly PublishedPropertyType[] _propertyTypes;
// fast alias-to-index xref containing both the raw alias and its lowercase version
private readonly Dictionary<string, int> _indexes = new Dictionary<string, int>();
// internal so it can be used by PublishedNoCache which does _not_ want to cache anything and so will never
// use the static cache getter PublishedContentType.GetPublishedContentType(alias) below - anything else
// should use it.
internal PublishedContentType(IContentTypeComposition contentType)
{
Id = contentType.Id;
Alias = contentType.Alias;
_propertyTypes = contentType.CompositionPropertyTypes
.Select(x => new PublishedPropertyType(this, x))
.ToArray();
InitializeIndexes();
}
// internal so it can be used for unit tests
internal PublishedContentType(int id, string alias, IEnumerable<PublishedPropertyType> propertyTypes)
{
Id = id;
Alias = alias;
_propertyTypes = propertyTypes.ToArray();
foreach (var propertyType in _propertyTypes)
propertyType.ContentType = this;
InitializeIndexes();
}
private void InitializeIndexes()
{
for (var i = 0; i < _propertyTypes.Length; i++)
{
var propertyType = _propertyTypes[i];
_indexes[propertyType.PropertyTypeAlias] = i;
_indexes[propertyType.PropertyTypeAlias.ToLowerInvariant()] = i;
}
}
#region Content type
public int Id { get; private set; }
public string Alias { get; private set; }
#endregion
#region Properties
public IEnumerable<PublishedPropertyType> PropertyTypes
{
get { return _propertyTypes; }
}
// alias is case-insensitive
// this is the ONLY place where we compare ALIASES!
public int GetPropertyIndex(string alias)
{
int index;
if (_indexes.TryGetValue(alias, out index)) return index; // fastest
if (_indexes.TryGetValue(alias.ToLowerInvariant(), out index)) return index; // slower
return -1;
}
// virtual for unit tests
public virtual PublishedPropertyType GetPropertyType(string alias)
{
var index = GetPropertyIndex(alias);
return GetPropertyType(index);
}
// virtual for unit tests
public virtual PublishedPropertyType GetPropertyType(int index)
{
return index >= 0 && index < _propertyTypes.Length ? _propertyTypes[index] : null;
}
#endregion
#region Cache
// these methods are called by ContentTypeCacheRefresher and DataTypeCacheRefresher
internal static void ClearAll()
{
Logging.LogHelper.Debug<PublishedContentType>("Clear all.");
// ok and faster to do it by types, assuming noone else caches PublishedContentType instances
//ApplicationContext.Current.ApplicationCache.ClearStaticCacheByKeySearch("PublishedContentType_");
ApplicationContext.Current.ApplicationCache.StaticCache.ClearCacheObjectTypes<PublishedContentType>();
}
internal static void ClearContentType(int id)
{
Logging.LogHelper.Debug<PublishedContentType>("Clear content type w/id {0}.", () => id);
// requires a predicate because the key does not contain the ID
// faster than key strings comparisons anyway
ApplicationContext.Current.ApplicationCache.StaticCache.ClearCacheObjectTypes<PublishedContentType>(
(key, value) => value.Id == id);
}
internal static void ClearDataType(int id)
{
Logging.LogHelper.Debug<PublishedContentType>("Clear data type w/id {0}.", () => id);
// there is no recursion to handle here because a PublishedContentType contains *all* its
// properties ie both its own properties and those that were inherited (it's based upon an
// IContentTypeComposition) and so every PublishedContentType having a property based upon
// the cleared data type, be it local or inherited, will be cleared.
ApplicationContext.Current.ApplicationCache.StaticCache.ClearCacheObjectTypes<PublishedContentType>(
(key, value) => value.PropertyTypes.Any(x => x.DataTypeId == id));
}
public static PublishedContentType Get(PublishedItemType itemType, string alias)
{
var key = string.Format("PublishedContentType_{0}_{1}",
itemType == PublishedItemType.Content ? "content" : "media", alias.ToLowerInvariant());
var type = ApplicationContext.Current.ApplicationCache.StaticCache.GetCacheItem<PublishedContentType>(key,
() => CreatePublishedContentType(itemType, alias));
return type;
}
private static PublishedContentType CreatePublishedContentType(PublishedItemType itemType, string alias)
{
if (GetPublishedContentTypeCallback != null)
return GetPublishedContentTypeCallback(alias);
var contentType = itemType == PublishedItemType.Content
? (IContentTypeComposition) ApplicationContext.Current.Services.ContentTypeService.GetContentType(alias)
: (IContentTypeComposition) ApplicationContext.Current.Services.ContentTypeService.GetMediaType(alias);
return new PublishedContentType(contentType);
}
// for unit tests - changing the callback must reset the cache obviously
private static Func<string, PublishedContentType> _getPublishedContentTypeCallBack;
internal static Func<string, PublishedContentType> GetPublishedContentTypeCallback
{
get { return _getPublishedContentTypeCallBack; }
set
{
// see note above
//ClearAll();
ApplicationContext.Current.ApplicationCache.StaticCache.ClearCacheByKeySearch("PublishedContentType_");
_getPublishedContentTypeCallBack = value;
}
}
#endregion
}
}
@@ -0,0 +1,208 @@
using System;
using System.Collections.Generic;
namespace Umbraco.Core.Models.PublishedContent
{
//
// This class has two purposes.
//
// - First, we cannot implement strongly-typed content by inheriting from some sort
// of "master content" because that master content depends on the actual content cache
// that is being used. It can be an XmlPublishedContent with the XmlPublishedCache,
// or just anything else.
//
// So we implement strongly-typed content by encapsulating whatever content is
// returned by the content cache, and providing extra properties (mostly) or
// methods or whatever. This class provides the base for such encapsulation.
//
// - Second, any time a content is used in a content set obtained from
// IEnumerable<IPublishedContent>.ToContentSet(), it needs to be cloned and extended
// in order to know about its position in the set. This class provides the base
// for implementing such extension.
//
/// <summary>
/// Provides an abstract base class for <c>IPublishedContent</c> implementations that
/// wrap and extend another <c>IPublishedContent</c>.
/// </summary>
public abstract class PublishedContentWrapped : IPublishedContent
{
protected readonly IPublishedContent Content;
/// <summary>
/// Initialize a new instance of the <see cref="PublishedContentWrapped"/> class
/// with an <c>IPublishedContent</c> instance to wrap and extend.
/// </summary>
/// <param name="content">The content to wrap and extend.</param>
protected PublishedContentWrapped(IPublishedContent content)
{
Content = content;
}
/// <summary>
/// Gets the wrapped content.
/// </summary>
/// <returns>The wrapped content, that was passed as an argument to the constructor.</returns>
public IPublishedContent Unwrap()
{
return Content;
}
#region ContentSet
public virtual IEnumerable<IPublishedContent> ContentSet
{
get { return Content.ContentSet; }
}
#endregion
#region ContentType
public virtual PublishedContentType ContentType { get { return Content.ContentType; } }
#endregion
#region Content
public virtual int Id
{
get { return Content.Id; }
}
public virtual int TemplateId
{
get { return Content.TemplateId; }
}
public virtual int SortOrder
{
get { return Content.SortOrder; }
}
public virtual string Name
{
get { return Content.Name; }
}
public virtual string UrlName
{
get { return Content.UrlName; }
}
public virtual string DocumentTypeAlias
{
get { return Content.DocumentTypeAlias; }
}
public virtual int DocumentTypeId
{
get { return Content.DocumentTypeId; }
}
public virtual string WriterName
{
get { return Content.WriterName; }
}
public virtual string CreatorName
{
get { return Content.CreatorName; }
}
public virtual int WriterId
{
get { return Content.WriterId; }
}
public virtual int CreatorId
{
get { return Content.CreatorId; }
}
public virtual string Path
{
get { return Content.Path; }
}
public virtual DateTime CreateDate
{
get { return Content.CreateDate; }
}
public virtual DateTime UpdateDate
{
get { return Content.UpdateDate; }
}
public virtual Guid Version
{
get { return Content.Version; }
}
public virtual int Level
{
get { return Content.Level; }
}
public virtual string Url
{
get { return Content.Url; }
}
public virtual PublishedItemType ItemType
{
get { return Content.ItemType; }
}
public virtual bool IsDraft
{
get { return Content.IsDraft; }
}
public virtual int GetIndex()
{
return Content.GetIndex();
}
#endregion
#region Tree
public virtual IPublishedContent Parent
{
get { return Content.Parent; }
}
public virtual IEnumerable<IPublishedContent> Children
{
get { return Content.Children; }
}
#endregion
#region Properties
public virtual ICollection<IPublishedProperty> Properties
{
get { return Content.Properties; }
}
public virtual object this[string alias]
{
get { return Content[alias]; }
}
public virtual IPublishedProperty GetProperty(string alias)
{
return Content.GetProperty(alias);
}
public virtual IPublishedProperty GetProperty(string alias, bool recurse)
{
return Content.GetProperty(alias, recurse);
}
#endregion
}
}
@@ -0,0 +1,31 @@
using System;
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// Provides a base class for <c>IPublishedProperty</c> implementations which converts and caches
/// the value source to the actual value to use when rendering content.
/// </summary>
internal abstract class PublishedPropertyBase : IPublishedProperty
{
public readonly PublishedPropertyType PropertyType;
protected PublishedPropertyBase(PublishedPropertyType propertyType)
{
if (propertyType == null)
throw new ArgumentNullException("propertyType");
PropertyType = propertyType;
}
public string PropertyTypeAlias
{
get { return PropertyType.PropertyTypeAlias; }
}
// these have to be provided by the actual implementation
public abstract bool HasValue { get; }
public abstract object DataValue { get; }
public abstract object Value { get; }
public abstract object XPathValue { get; }
}
}
@@ -0,0 +1,237 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Xml.Linq;
using System.Xml.XPath;
using Umbraco.Core.Dynamics;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// Represents an <see cref="IPublishedProperty"/> type.
/// </summary>
/// <remarks>Instances of the <see cref="PublishedPropertyType"/> class are immutable, ie
/// if the property type changes, then a new class needs to be created.</remarks>
public class PublishedPropertyType
{
public PublishedPropertyType(PublishedContentType contentType, PropertyType propertyType)
{
// PropertyEditor [1:n] DataTypeDefinition [1:n] PropertyType
ContentType = contentType;
PropertyTypeAlias = propertyType.Alias;
DataTypeId = propertyType.DataTypeDefinitionId;
PropertyEditorAlias = propertyType.PropertyEditorAlias;
InitializeConverters();
}
// for unit tests
internal PublishedPropertyType(string propertyTypeAlias, int dataTypeDefinitionId, string propertyEditorAlias)
{
// ContentType to be set by PublishedContentType when creating it
PropertyTypeAlias = propertyTypeAlias;
DataTypeId = dataTypeDefinitionId;
PropertyEditorAlias = propertyEditorAlias;
InitializeConverters();
}
#region Property type
/// <summary>
/// Gets or sets the published content type containing the property type.
/// </summary>
// internally set by PublishedContentType constructor
public PublishedContentType ContentType { get; internal set; }
/// <summary>
/// Gets or sets the alias uniquely identifying the property type.
/// </summary>
public string PropertyTypeAlias { get; private set; }
/// <summary>
/// Gets or sets the identifier uniquely identifying the data type supporting the property type.
/// </summary>
public int DataTypeId { get; private set; }
/// <summary>
/// Gets or sets the alias uniquely identifying the property editor for the property type.
/// </summary>
public string PropertyEditorAlias { get; private set; }
#endregion
#region Converters
private IPropertyValueConverter _converter;
private PropertyCacheLevel _sourceCacheLevel;
private PropertyCacheLevel _objectCacheLevel;
private PropertyCacheLevel _xpathCacheLevel;
private void InitializeConverters()
{
var converters = PropertyValueConvertersResolver.Current.Converters.ToArray();
// todo: remove Union() once we drop IPropertyEditorValueConverter support.
_converter = null;
foreach (var converter in converters.Union(GetCompatConverters()).Where(x => x.IsConverter(this)))
{
if (_converter == null)
{
_converter = converter;
}
else
{
throw new InvalidOperationException(string.Format("More than one converter for property type {0}.{1}",
ContentType.Alias, PropertyTypeAlias));
}
}
// get the cache levels, quietely fixing the inconsistencies (no need to throw, really)
_sourceCacheLevel = GetCacheLevel(_converter, PropertyCacheValue.Source);
_objectCacheLevel = GetCacheLevel(_converter, PropertyCacheValue.Object);
_objectCacheLevel = GetCacheLevel(_converter, PropertyCacheValue.XPath);
if (_objectCacheLevel < _sourceCacheLevel) _objectCacheLevel = _sourceCacheLevel;
if (_xpathCacheLevel < _sourceCacheLevel) _xpathCacheLevel = _sourceCacheLevel;
}
static PropertyCacheLevel GetCacheLevel(IPropertyValueConverter converter, PropertyCacheValue value)
{
if (converter == null)
return PropertyCacheLevel.Request;
var attr = converter.GetType().GetCustomAttributes<PropertyValueCacheAttribute>(false)
.FirstOrDefault(x => x.Value == value || x.Value == PropertyCacheValue.All);
return attr == null ? PropertyCacheLevel.Request : attr.Level;
}
// converts the raw value into the source value
// uses converters, else falls back to dark (& performance-wise expensive) magic
// source: the property raw value
// preview: whether we are previewing or not
public object ConvertDataToSource(object source, bool preview)
{
// use the converter else use dark (& performance-wise expensive) magic
return _converter != null
? _converter.ConvertDataToSource(this, source, preview)
: ConvertUsingDarkMagic(source);
}
// gets the source cache level
public PropertyCacheLevel SourceCacheLevel { get { return _sourceCacheLevel; } }
// converts the source value into the clr value
// uses converters, else returns the source value
// source: the property source value
// preview: whether we are previewing or not
public object ConvertSourceToObject(object source, bool preview)
{
// use the converter if any
// else just return the source value
return _converter != null
? _converter.ConvertSourceToObject(this, source, preview)
: source;
}
// gets the value cache level
public PropertyCacheLevel ObjectCacheLevel { get { return _objectCacheLevel; } }
// converts the source value into the xpath value
// uses the converter else returns the source value as a string
// if successful, returns either a string or an XPathNavigator
// source: the property source value
// preview: whether we are previewing or not
public object ConvertSourceToXPath(object source, bool preview)
{
// use the converter if any
if (_converter != null)
return _converter.ConvertSourceToXPath(this, source, preview);
// else just return the source value as a string or an XPathNavigator
if (source == null) return null;
var xElement = source as XElement;
if (xElement != null)
return xElement.CreateNavigator();
return source.ToString().Trim();
}
// gets the xpath cache level
public PropertyCacheLevel XPathCacheLevel { get { return _xpathCacheLevel; } }
internal static object ConvertUsingDarkMagic(object source)
{
// convert to string
var stringSource = source as string;
if (stringSource == null) return source; // not a string => return the object
stringSource = stringSource.Trim();
if (stringSource.Length == 0) return null; // empty string => return null
// try numbers and booleans
// make sure we use the invariant culture ie a dot decimal point, comma is for csv
// NOTE far from perfect: "01a" is returned as a string but "012" is returned as an integer...
int i;
if (int.TryParse(stringSource, NumberStyles.Integer, CultureInfo.InvariantCulture, out i))
return i;
float f;
if (float.TryParse(stringSource, NumberStyles.Float, CultureInfo.InvariantCulture, out f))
return f;
bool b;
if (bool.TryParse(stringSource, out b))
return b;
// try xml - that is expensive, performance-wise
XElement elt;
if (XmlHelper.TryCreateXElementFromPropertyValue(stringSource, out elt))
return new DynamicXml(elt); // xml => return DynamicXml for compatiblity's sake
return source;
}
#endregion
#region Compat
// backward-compatibility: support IPropertyEditorValueConverter while we have to
// todo: remove once we drop IPropertyEditorValueConverter support.
IEnumerable<IPropertyValueConverter> GetCompatConverters()
{
var propertyEditorGuid = LegacyPropertyEditorIdToAliasConverter.GetLegacyIdFromAlias(PropertyEditorAlias, LegacyPropertyEditorIdToAliasConverter.NotFoundLegacyIdResponseBehavior.ReturnNull);
return PropertyEditorValueConvertersResolver.HasCurrent && propertyEditorGuid.HasValue
? PropertyEditorValueConvertersResolver.Current.Converters
.Where(x => x.IsConverterFor(propertyEditorGuid.Value, ContentType.Alias, PropertyTypeAlias))
.Select(x => new CompatConverter(x))
: Enumerable.Empty<IPropertyValueConverter>();
}
class CompatConverter : PropertyValueConverterBase
{
private readonly IPropertyEditorValueConverter _converter;
public CompatConverter(IPropertyEditorValueConverter converter)
{
_converter = converter;
}
public override bool IsConverter(PublishedPropertyType propertyType)
{
return true;
}
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
// NOTE: ignore preview, because IPropertyEditorValueConverter does not support it
return _converter.ConvertPropertyValue(source).Result;
}
}
#endregion
}
}
+8 -1
View File
@@ -1,11 +1,18 @@
namespace Umbraco.Core.Models
{
/// <summary>
/// The type of published item
/// The type of published content, ie whether it is a content or a media.
/// </summary>
public enum PublishedItemType
{
/// <summary>
/// A content, ie what was formerly known as a document.
/// </summary>
Content,
/// <summary>
/// A media.
/// </summary>
Media
}
}
@@ -1,23 +0,0 @@
namespace Umbraco.Core.Models
{
/// <summary>
/// The definition of a published property
/// </summary>
public class PublishedPropertyDefinition
{
public PublishedPropertyDefinition(string propertyTypeAlias, string documentTypeAlias, string propertyEditorAlias)
{
//PropertyId = propertyId;
DocumentTypeAlias = documentTypeAlias;
PropertyTypeAlias = propertyTypeAlias;
PropertyEditorAlias = propertyEditorAlias;
//ItemType = itemType;
}
//public int PropertyId { get; private set; }
public string DocumentTypeAlias { get; private set; }
public string PropertyTypeAlias { get; private set; }
public string PropertyEditorAlias { get; private set; }
//public PublishedItemType ItemType { get; private set; }
}
}
@@ -15,6 +15,7 @@ namespace Umbraco.Core.Models.Rdbms
[Column("ContentId")]
[ForeignKey(typeof(ContentDto), Column = "nodeId")]
[Index(IndexTypes.NonClustered, Name = "IX_cmsContentVersion_ContentId")]
public int NodeId { get; set; }
[Column("VersionId")]
@@ -16,6 +16,7 @@ namespace Umbraco.Core.Models.Rdbms
public int NodeId { get; set; }
[Column("published")]
[Index(IndexTypes.NonClustered, Name = "IX_cmsDocument_published")]
public bool Published { get; set; }
[Column("documentUser")]
@@ -51,6 +52,7 @@ namespace Umbraco.Core.Models.Rdbms
[Column("newest")]
[Constraint(Default = "0")]
[Index(IndexTypes.NonClustered, Name = "IX_cmsDocument_newest")]
public bool Newest { get; set; }
[ResultColumn]
+3 -2
View File
@@ -15,11 +15,12 @@ namespace Umbraco.Core.Models.Rdbms
[Column("trashed")]
[Constraint(Default = "0")]
[Index(IndexTypes.NonClustered, Name = "IX_umbracoNodeTrashed")]
public bool Trashed { get; set; }
[Column("parentID")]
[ForeignKey(typeof(NodeDto))]
[IndexAttribute(IndexTypes.NonClustered, Name = "IX_umbracoNodeParentId")]
[Index(IndexTypes.NonClustered, Name = "IX_umbracoNodeParentId")]
public int ParentId { get; set; }
[Column("nodeUser")]
@@ -46,7 +47,7 @@ namespace Umbraco.Core.Models.Rdbms
[Column("nodeObjectType")]
[NullSetting(NullSetting = NullSettings.Null)]
[IndexAttribute(IndexTypes.NonClustered, Name = "IX_umbracoNodeObjectType")]
[Index(IndexTypes.NonClustered, Name = "IX_umbracoNodeObjectType")]
public Guid? NodeObjectType { get; set; }
[Column("createDate")]
@@ -18,5 +18,8 @@ namespace Umbraco.Core.Models.Rdbms
[Column("PropertyGroupSortOrder")]
public int SortOrder { get; set; }
[Column("contenttypeNodeId")]
public int ContentTypeNodeId { get; set; }
}
}
@@ -17,7 +17,7 @@ namespace Umbraco.Core.Models.Rdbms
[Column("contentTypeId")]
public int ContentTypeId { get; set; }
[Column("propertyTypeGroupId")]
[Column("PropertyTypesGroupId")]
public int? PropertyTypeGroupId { get; set; }
[Column("Alias")]
+2
View File
@@ -15,10 +15,12 @@ namespace Umbraco.Core.Models.Rdbms
[Column("tag")]
[NullSetting(NullSetting = NullSettings.Null)]
[Length(200)]
[Index(IndexTypes.NonClustered, ForColumns = "tag,group", Name = "IX_cmsTags")]
public string Tag { get; set; }//NOTE Is set to [varchar] (200) in Sql Server script
[Column("ParentId")]
[NullSetting(NullSetting = NullSettings.Null)]
[ForeignKey(typeof(TagDto), Name = "FK_cmsTags_cmsTags")]
public int? ParentId { get; set; }
[Column("group")]
@@ -9,12 +9,16 @@ namespace Umbraco.Core.Models.Rdbms
internal class TagRelationshipDto
{
[Column("nodeId")]
[PrimaryKeyColumn(AutoIncrement = false, Name = "PK_cmsTagRelationship", OnColumns = "nodeId, tagId")]
[ForeignKey(typeof(NodeDto))]
[PrimaryKeyColumn(AutoIncrement = false, Name = "PK_cmsTagRelationship", OnColumns = "nodeId, propertyTypeId, tagId")]
[ForeignKey(typeof(ContentDto), Name = "FK_cmsTagRelationship_cmsContent", Column = "nodeId")]
public int NodeId { get; set; }
[Column("tagId")]
[ForeignKey(typeof(TagDto))]
public int TagId { get; set; }
[Column("propertyTypeId")]
[ForeignKey(typeof(PropertyTypeDto), Name = "FK_cmsTagRelationship_cmsPropertyType")]
public int PropertyTypeId { get; set; }
}
}
+57
View File
@@ -0,0 +1,57 @@
using System;
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Models
{
[Serializable]
[DataContract(IsReference = true)]
public class Tag : Entity, ITag
{
public Tag()
{
}
public Tag(int id, string text, string @group)
{
Text = text;
Group = @group;
Id = id;
}
private static readonly PropertyInfo TextSelector = ExpressionHelper.GetPropertyInfo<Tag, string>(x => x.Text);
private static readonly PropertyInfo GroupSelector = ExpressionHelper.GetPropertyInfo<Tag, string>(x => x.Group);
private string _text;
private string _group;
public string Text
{
get { return _text; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_text = value;
return _text;
}, _text, TextSelector);
}
}
public string Group
{
get { return _group; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_group = value;
return _group;
}, _group, GroupSelector);
}
}
//TODO: enable this at some stage
//public int ParentId { get; set; }
}
}
+34 -2
View File
@@ -44,10 +44,12 @@ namespace Umbraco.Core.Models
public UmbracoEntity()
{
AdditionalData = new Dictionary<string, object>();
}
public UmbracoEntity(bool trashed)
{
AdditionalData = new Dictionary<string, object>();
Trashed = trashed;
}
@@ -142,6 +144,9 @@ namespace Umbraco.Core.Models
}
}
public IDictionary<string, object> AdditionalData { get; private set; }
public bool HasChildren
{
get { return _hasChildren; }
@@ -152,6 +157,9 @@ namespace Umbraco.Core.Models
_hasChildren = value;
return _hasChildren;
}, _hasChildren, HasChildrenSelector);
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
AdditionalData["HasChildren"] = value;
}
}
@@ -164,7 +172,10 @@ namespace Umbraco.Core.Models
{
_isPublished = value;
return _isPublished;
}, _isPublished, IsPublishedSelector);
}, _isPublished, IsPublishedSelector);
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
AdditionalData["IsPublished"] = value;
}
}
@@ -178,6 +189,9 @@ namespace Umbraco.Core.Models
_isDraft = value;
return _isDraft;
}, _isDraft, IsDraftSelector);
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
AdditionalData["IsDraft"] = value;
}
}
@@ -191,6 +205,9 @@ namespace Umbraco.Core.Models
_hasPendingChanges = value;
return _hasPendingChanges;
}, _hasPendingChanges, HasPendingChangesSelector);
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
AdditionalData["HasPendingChanges"] = value;
}
}
@@ -204,6 +221,9 @@ namespace Umbraco.Core.Models
_contentTypeAlias = value;
return _contentTypeAlias;
}, _contentTypeAlias, ContentTypeAliasSelector);
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
AdditionalData["ContentTypeAlias"] = value;
}
}
@@ -217,6 +237,9 @@ namespace Umbraco.Core.Models
_contentTypeIcon = value;
return _contentTypeIcon;
}, _contentTypeIcon, ContentTypeIconSelector);
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
AdditionalData["ContentTypeIcon"] = value;
}
}
@@ -230,6 +253,9 @@ namespace Umbraco.Core.Models
_contentTypeThumbnail = value;
return _contentTypeThumbnail;
}, _contentTypeThumbnail, ContentTypeThumbnailSelector);
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
AdditionalData["ContentTypeThumbnail"] = value;
}
}
@@ -242,10 +268,16 @@ namespace Umbraco.Core.Models
{
_nodeObjectTypeId = value;
return _nodeObjectTypeId;
}, _nodeObjectTypeId, NodeObjectTypeIdSelector);
}, _nodeObjectTypeId, NodeObjectTypeIdSelector);
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
AdditionalData["NodeObjectTypeId"] = value;
}
}
/// <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; }
internal class UmbracoProperty
@@ -1,4 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using Umbraco.Core.CodeAnnotations;
@@ -9,7 +10,8 @@ namespace Umbraco.Core.Models
/// </summary>
public static class UmbracoObjectTypesExtensions
{
private static readonly Dictionary<UmbracoObjectTypes, Guid> UmbracoObjectTypeCache = new Dictionary<UmbracoObjectTypes,Guid>();
//MUST be concurrent to avoid thread collisions!
private static readonly ConcurrentDictionary<UmbracoObjectTypes, Guid> UmbracoObjectTypeCache = new ConcurrentDictionary<UmbracoObjectTypes, Guid>();
/// <summary>
/// Get an UmbracoObjectTypes value from it's name
@@ -48,24 +50,22 @@ namespace Umbraco.Core.Models
/// <returns>a GUID value of the UmbracoObjectTypes</returns>
public static Guid GetGuid(this UmbracoObjectTypes umbracoObjectType)
{
if (UmbracoObjectTypeCache.ContainsKey(umbracoObjectType))
return UmbracoObjectTypeCache[umbracoObjectType];
return UmbracoObjectTypeCache.GetOrAdd(umbracoObjectType, types =>
{
var type = typeof(UmbracoObjectTypes);
var memInfo = type.GetMember(umbracoObjectType.ToString());
var attributes = memInfo[0].GetCustomAttributes(typeof(UmbracoObjectTypeAttribute),
false);
var type = typeof(UmbracoObjectTypes);
var memInfo = type.GetMember(umbracoObjectType.ToString());
var attributes = memInfo[0].GetCustomAttributes(typeof(UmbracoObjectTypeAttribute),
false);
if (attributes.Length == 0)
return Guid.Empty;
if (attributes.Length == 0)
return Guid.Empty;
var attribute = ((UmbracoObjectTypeAttribute)attributes[0]);
if (attribute == null)
return Guid.Empty;
var attribute = ((UmbracoObjectTypeAttribute)attributes[0]);
if (attribute == null)
return Guid.Empty;
UmbracoObjectTypeCache.Add(umbracoObjectType, attribute.ObjectId);
return attribute.ObjectId;
return attribute.ObjectId;
});
}
/// <summary>
@@ -169,47 +169,46 @@ namespace Umbraco.Core.ObjectResolution
{
get
{
// ensure we can
if (CanResolveBeforeFrozen == false)
Resolution.EnsureIsFrozen();
using (Resolution.Reader(CanResolveBeforeFrozen))
{
// note: we apply .ToArray() to the output of CreateInstance() because that is an IEnumerable that
// comes from the PluginManager we want to be _sure_ that it's not a Linq of some sort, but the
// instances have actually been instanciated when we return.
// note: we apply .ToArray() to the output of CreateInstance() because that is an IEnumerable that
// comes from the PluginManager we want to be _sure_ that it's not a Linq of some sort, but the
// instances have actually been instanciated when we return.
switch (LifetimeScope)
{
case ObjectLifetimeScope.HttpRequest:
// create new instances per HttpContext
using (var l = new UpgradeableReadLock(_lock))
{
// create if not already there
if (CurrentHttpContext.Items[_httpContextKey] == null)
{
l.UpgradeToWriteLock();
CurrentHttpContext.Items[_httpContextKey] = CreateInstances().ToArray();
}
return (TResolved[])CurrentHttpContext.Items[_httpContextKey];
}
switch (LifetimeScope)
{
case ObjectLifetimeScope.HttpRequest:
// create new instances per HttpContext
using (var l = new UpgradeableReadLock(_lock))
{
// create if not already there
if (CurrentHttpContext.Items[_httpContextKey] == null)
{
l.UpgradeToWriteLock();
CurrentHttpContext.Items[_httpContextKey] = CreateInstances().ToArray();
}
return (TResolved[])CurrentHttpContext.Items[_httpContextKey];
}
case ObjectLifetimeScope.Application:
// create new instances per application
using (var l = new UpgradeableReadLock(_lock))
{
// create if not already there
if (_applicationInstances == null)
{
l.UpgradeToWriteLock();
_applicationInstances = CreateInstances().ToArray();
}
return _applicationInstances;
}
case ObjectLifetimeScope.Application:
// create new instances per application
using(var l = new UpgradeableReadLock(_lock))
{
// create if not already there
if (_applicationInstances == null)
{
l.UpgradeToWriteLock();
_applicationInstances = CreateInstances().ToArray();
}
return _applicationInstances;
}
case ObjectLifetimeScope.Transient:
default:
// create new instances each time
return CreateInstances().ToArray();
}
case ObjectLifetimeScope.Transient:
default:
// create new instances each time
return CreateInstances().ToArray();
}
}
}
}
@@ -459,6 +458,21 @@ namespace Umbraco.Core.ObjectResolution
}
}
/// <summary>
/// Gets the types in the collection of types.
/// </summary>
/// <returns>The types in the collection of types.</returns>
/// <remarks>Returns an enumeration, the list cannot be modified.</remarks>
public virtual IEnumerable<Type> GetTypes()
{
Type[] types;
using (new ReadLock(_lock))
{
types = _instanceTypes.ToArray();
}
return types;
}
/// <summary>
/// Returns a value indicating whether the specified type is already in the collection of types.
/// </summary>
+56 -26
View File
@@ -1,5 +1,7 @@
using System;
using System.Linq;
using System.Threading;
using Umbraco.Core.Logging;
namespace Umbraco.Core.ObjectResolution
{
@@ -12,8 +14,8 @@ namespace Umbraco.Core.ObjectResolution
/// </remarks>
internal static class Resolution
{
private static readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
private volatile static bool _isFrozen;
private static readonly ReaderWriterLockSlim ConfigurationLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
private volatile static bool _isFrozen;
/// <summary>
/// Occurs when resolution is frozen.
@@ -24,18 +26,26 @@ namespace Umbraco.Core.ObjectResolution
/// <summary>
/// Gets or sets a value indicating whether resolution of objects is frozen.
/// </summary>
public static bool IsFrozen
// internal for unit tests, use ReadFrozen if you want to be sure
internal static bool IsFrozen
{
get { return _isFrozen; }
private set { _isFrozen = value; }
get
{
using (new ReadLock(ConfigurationLock))
{
return _isFrozen;
}
}
}
public static void EnsureIsFrozen()
{
if (!_isFrozen)
throw new InvalidOperationException("Resolution is not frozen, it is not yet possible to get values from it.");
public static IDisposable Reader(bool canReadUnfrozen = false)
{
IDisposable l = new ReadLock(ConfigurationLock);
if (canReadUnfrozen || _isFrozen) return l;
}
l.Dispose();
throw new InvalidOperationException("Resolution is not frozen, it is not yet possible to get values from it.");
}
/// <summary>
/// Returns a disposable object that represents safe access to unfrozen resolution configuration.
@@ -45,13 +55,11 @@ namespace Umbraco.Core.ObjectResolution
{
get
{
IDisposable l = new WriteLock(_lock);
if (_isFrozen)
{
l.Dispose();
throw new InvalidOperationException("Resolution is frozen, it is not possible to configure it anymore.");
}
return l;
IDisposable l = new WriteLock(ConfigurationLock);
if (_isFrozen == false) return l;
l.Dispose();
throw new InvalidOperationException("Resolution is frozen, it is not possible to configure it anymore.");
}
}
@@ -71,20 +79,23 @@ namespace Umbraco.Core.ObjectResolution
// keep the class here because it needs write-access to Resolution.IsFrozen
private class DirtyBackdoor : IDisposable
{
private static readonly System.Threading.ReaderWriterLockSlim _dirtyLock = new ReaderWriterLockSlim();
private IDisposable _lock;
private bool _frozen;
private readonly IDisposable _lock;
private readonly bool _frozen;
public DirtyBackdoor()
{
_lock = new WriteLock(_dirtyLock);
LogHelper.Debug(typeof(DirtyBackdoor), "Creating back door for resolution");
_lock = new WriteLock(ConfigurationLock);
_frozen = _isFrozen;
_isFrozen = false;
}
public void Dispose()
{
LogHelper.Debug(typeof(DirtyBackdoor), "Disposing back door for resolution");
_isFrozen = _frozen;
_lock.Dispose();
}
@@ -96,11 +107,17 @@ namespace Umbraco.Core.ObjectResolution
/// <exception cref="InvalidOperationException">resolution is already frozen.</exception>
public static void Freeze()
{
if (_isFrozen)
throw new InvalidOperationException("Resolution is frozen. It is not possible to freeze it again.");
LogHelper.Debug(typeof(Resolution), "Freezing resolution");
_isFrozen = true;
if (Frozen != null)
using (new WriteLock(ConfigurationLock))
{
if (_isFrozen)
throw new InvalidOperationException("Resolution is frozen. It is not possible to freeze it again.");
_isFrozen = true;
}
if (Frozen != null)
Frozen(null, null);
}
@@ -110,7 +127,20 @@ namespace Umbraco.Core.ObjectResolution
/// <remarks>To be used in unit tests.</remarks>
internal static void Reset()
{
_isFrozen = false;
LogHelper.Debug(typeof(Resolution), "Resetting resolution");
/*
var trace = new System.Diagnostics.StackTrace();
var testing = trace.GetFrames().Any(frame =>
frame.GetMethod().DeclaringType.FullName.StartsWith("Umbraco.Tests"));
if (testing == false)
throw new InvalidOperationException("Only unit tests can reset configuration.");
*/
using (new WriteLock(ConfigurationLock))
{
_isFrozen = false;
}
Frozen = null;
}
}

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