Compare commits

...

1243 Commits

Author SHA1 Message Date
Sebastiaan Janssen 026805e4c1 Bumps version 2016-03-03 11:25:51 +01:00
Sebastiaan Janssen a7dad09f44 Ignores unit test that refuses to work on AppVeyor 2016-03-03 11:22:11 +01:00
Sebastiaan Janssen e4aa7c068b Get this branch to build on AppVeyor 2016-03-03 11:22:01 +01:00
Sebastiaan Janssen cc211ab3bd Removes unused class 2016-03-03 11:21:36 +01:00
Sebastiaan Janssen cb72e6344a Merge pull request #1155 from darrenferguson/6.2.5-dictionary-thread-safety-fix
Apply 8905878a87 to 6.2.5 for performan…
2016-03-03 11:17:07 +01:00
Shannon bf3ddd9384 Apply 8905878a87 to 6.2.5 for performance fix. 2016-03-01 15:33:22 +00:00
Shannon 8a6ece4a6d Ensures all mvc refs are original 4.0.0.0 so there's no more probs during build/run 2015-05-11 11:49:30 +10:00
Shannon d2662c17f7 Fix dictionary key access
Looks like someone does not know how to use a dictionary
2015-02-20 10:06:13 +01:00
Sebastiaan Janssen 18c2652f67 Copy webapi dlls locally so that they get included in the final zip build 2015-02-19 16:24:32 +01:00
Sebastiaan Janssen da0d97c108 Bump version 2015-02-19 15:57:10 +01:00
Sebastiaan Janssen f672a323b0 Bump version 2015-02-19 15:11:08 +01:00
Shannon a59dd32dd1 Updates cdf refs 2015-02-18 09:15:07 +01:00
Sebastiaan Janssen d4d5a355e3 Update CDF dependency 2015-02-10 15:08:27 +01:00
Shannon f4a0bcfc96 updates nuspec 2015-02-03 13:15:15 +11:00
Shannon aadae6334b Fixes: U4-2038 Violation of PRIMARY KEY constraint 'PK_cmsContentPreviewXml' YSOD occurs when publishing content
Conflicts:
	src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs
	src/Umbraco.Core/Umbraco.Core.csproj
2015-01-30 10:13:04 +11:00
Shannon 7590bd86dd Merge branch 'dev-v6' of https://github.com/umbraco/Umbraco-CMS into dev-v6 2015-01-07 15:44:05 +11:00
Shannon 6b25e5299f fixes unit test 2015-01-07 15:43:47 +11:00
Stephan b30555f5a4 Merge pull request #599 from solutionmania/dev-v6
Merge into dev v6
2014-12-23 17:44:25 +01:00
Chris Roberts d4d77611eb Fixed: U4-5193 HasAccess override method name error 2014-12-23 16:27:51 +00:00
Chris Roberts 662ed03f0a Fixed: U4-6051 HasAccces method tests the roles of the wrong user 2014-12-23 16:23:47 +00:00
Shannon 3c01dcb30c Fixes: U4-6030 2014-12-18 15:16:29 +11:00
Shannon aa439cacda working on U4-6030 2014-12-18 14:58:49 +11:00
Shannon e643f2a0ba working on U4-6030 2014-12-18 14:20:41 +11:00
Shannon a32d38f7ea Fixes: U4-5992 Caching of XPathNodeIterator in umbraco.library is not thread safe and will cause media errors like valueDictionary exception 2014-12-16 14:26:53 +11:00
Shannon 864994a56e updates error msgs when sending requests to the same server pointing to docs on baseUrl 2014-12-08 17:04:22 +11:00
Shannon 3405c5001b working on U4-5964, U4-5907, U4-5965 2014-12-08 15:18:32 +11:00
Shannon 4d8732d925 The only way i could get this project to build and run was to change the transform to explicitly target 4.0.0.1 for mvc and webapi, otherwise nothing works and horribly cryptic build errors. Added the tests for the BackgroundTaskRunner 2014-12-08 14:59:32 +11:00
Sebastiaan Janssen 4eb9a54fa5 Ports v7 changes for U4-5728 - OriginalRequestUrl not initialized, KeepAlive or ScheduledPublishing run too soon
#U4-5728
2014-12-07 16:16:29 +01:00
Shannon 71ca90d74b Merge remote-tracking branch 'origin/6.2.2' into 6.2.4 2014-11-21 09:14:22 +11:00
Shannon Deminick fb42472f31 Merge pull request #554 from cloud46limited/umbUKFest-3556
Fixed type in Step 4 install wizard - U4-3556.
2014-11-21 09:13:10 +11:00
Gareth Evans - Cloud46 Limited b6695b6953 Fixed type in Step 4 install wizard - U4-3556. 2014-11-20 14:48:26 +00:00
Shannon 1eab26c0f6 reverts IQuery 2014-10-08 17:26:55 +11:00
Shannon 0543c620eb bumps version 2014-10-08 17:25:06 +11:00
Shannon 646e5f173d Fixes descendant queries to ensure that the comma is suffixed to the path, otherwise strange things could happen when there are longer ids! 2014-10-08 17:23:14 +11:00
Shannon b5594517bd Fixes: U4-5583 Can no longer link to Media Items from RTE in 6.2.3 - Due to a cherry pick/merge issue since the newer 7.x EntityRepository deals with NVarchar and NText values whereas the 6.x one did not. Have backported the mapping poco classes to now also support NVarchar and NText for the EntityRepository. Have also fixed the basic query to ensure that there are no left joins before inner joins which can also cause problems. Fixed up the duplicate where clause. Adds more tests to entity service. 2014-10-08 17:13:28 +11:00
Sebastiaan Janssen 246dfba8ac Bump version 2014-10-02 18:06:15 +02:00
Shannon 7d189a6fb8 Backports the @ symbol escaping fixes 2014-10-03 00:28:49 +10:00
Shannon 71242430da Fixes a query that would cause the new petapoco changes to have issues since it was asking for the wrong type 2014-10-01 16:37:42 +10:00
Shannon 4ee4f296fc updates version 2014-09-29 17:31:24 +10:00
Shannon b9e4950e36 fixes up entity repo merges to support old db schema 2014-09-29 17:30:09 +10:00
Shannon ba52f9235e Backports fixes to SQL parameterization and PetaPoco mem updates 2014-09-29 17:11:58 +10:00
Sebastiaan Janssen 33ccf490ab Update nuspec to ask for a valid nuget pkg 2014-08-25 15:53:45 +02:00
Sebastiaan Janssen 03ba8c9e14 Update to 6.2.2, removes airinstallbadge 2014-08-25 13:46:21 +02:00
Shannon 13b57c7638 adds some logging 2014-08-25 16:40:45 +10:00
Shannon a8b297903d Ensures we don't get any ysods when changing doc type properties and the content re-creation since it's running on an async thread (U4-5388 , U4-5387 ) 2014-08-25 16:16:42 +10:00
Shannon 89b5774106 Fixes: U4-5380 Booting.aspx security issue 2014-08-21 14:39:06 -06:00
Shannon 774f201514 Adds a simple cache mechanism to hold reflected property info when cloning - reduces perf to 10% of what it used to be 2014-08-20 20:09:05 -06:00
Sebastiaan Janssen 12e2aa679b Merge pull request #455 from leekelleher/U4-4249
U4-4249 - PetaPocoExtensions CreateTable doesn't recreate the table
2014-08-20 10:45:56 +02:00
leekelleher 1978930fa2 Amends CreateTable, so if 'overwrite' is enabled, the table is dropped, then recreated. 2014-08-19 18:56:15 +01:00
Stephan c4e4f9579b U4-4931 - fix tests 2014-08-15 09:54:04 +02:00
Stephan 9782f66507 U4-5084 - fix commit 2014-08-14 22:24:12 +02:00
Stephan e9938afc83 Merge pull request #418 from zpqrtbnk/6.2-4931
U4-4931 - lock contention & potential application lockdown
2014-08-14 20:52:13 +02:00
Stephan fcda9821d0 Merge branch '6.2.2' into 6.2-4931 2014-08-14 20:50:37 +02:00
Stephan bdc234b18a U4-5084 - DynamicPublishedContentList ext methods confusion 2014-08-14 20:49:49 +02:00
Sebastiaan Janssen 908afbd264 #U4-2238 Fixed
Issue when saving/publishing special characters - '' hexadecimal value 0x03, is an invalid character
2014-08-14 10:26:38 +02:00
Sebastiaan Janssen c548ad6a98 Update failing unit test now that MaxInvalidPasswordAttempts is 20 by default 2014-08-14 10:16:02 +02:00
Sebastiaan Janssen 99b2a2da38 #U4-5337 fixed Due in version: 7.1.5,6.2.2
Too easy to lock yourself out of the backoffice
2014-08-12 11:06:24 +02:00
Sebastiaan Janssen 15ed458ad3 #U4-5258 Fixed
RelationService AreRelated should accepts two entity IDs and a relationTypeAlias
2014-08-12 10:25:33 +02:00
Shannon 6ce303a918 Completes: U4-5264 Add Count methods to IContentService, IMediaService, etc... 2014-08-05 12:37:20 -06:00
Shannon 62d3dc78fa Ensures all caching is disabled for editing templates (master pages and views) 2014-08-05 10:59:54 -06:00
Shannon 3374f9e023 Ensures that the batched distributed calls doesn't cache refresh the server executing the distributed calls since tht will already be done locally. 2014-08-05 10:32:07 -06:00
Stephan 2675992d82 Merge branch '6.2.2' into 6.2-4931 2014-08-05 18:20:04 +02:00
Stephan ce29f54663 U4-4837 - bugfix Umbraco.Core.EnumerableExtensions.InGroupsOf 2014-08-05 17:52:43 +02:00
Shannon 7261162d8a Fixes some of U4-2633 Bundle all cache refresher transmissions into a single call per request for much better performance. See last note on issue. 2014-08-04 17:50:19 -06:00
Shannon b5f900e789 added a couple of tests for member names 2014-07-28 19:37:44 -07:00
Shannon fdab6d5de5 Merge branch '6.2.2' of https://github.com/umbraco/Umbraco-CMS into 6.2.2 2014-07-24 09:39:12 -07:00
Shannon ff94eba3a7 Fixes: U4-5273 6.2: Umbraco.Field no longer rendering macro container 2014-07-24 09:39:05 -07:00
Sebastiaan Janssen e200e2fc48 Removes obsolete cachebrowser 2014-07-24 16:17:40 +02:00
Shannon 22dde5a421 U4-4738 Backoffice search should support node ID search 2014-07-23 14:07:21 -07:00
Shannon 7f510c107a updates proj's with correct specific version attributes 2014-07-23 12:31:38 -07:00
Shannon 2ebfd8f3d4 updates nuspec to have latest versions for all dependencies 2014-07-23 12:31:16 -07:00
Shannon fd7930256b Uninstalls package CodeSharp.Package.AspNetWebPage and removes refs to Nuget.Core and Webpages.Administration - neither of which are used anywhere... but we've been shipping Umbraco with them for some reason. 2014-07-23 10:53:30 -07:00
Shannon c24775adb0 re-installs mvc, webapi and ensures running the latest 2.0.x versions of webpages and razor, now all proj's are consistent with correct versions referenced and copy local set correctly. 2014-07-23 10:03:26 -07:00
Shannon 217f591db0 updates proj references to have SpecificVersion set to false for libs 2014-07-22 16:13:26 -07:00
Shannon d453aedd0d Microsoft.Net.Http required a reinstall command for the UI project as noted by it's persisted 'requiresReinstall' attribute in the packages.config - also ensures that ALL of the WebApi DLLs are copied local 2014-07-22 15:51:13 -07:00
Shannon 4693fb23c8 removes unneeded lock on master controller factory - must have been left over from some v5 stuff for some reason :( this will speed things up a bit! 2014-07-18 16:28:54 +10:00
Shannon 7848a3095d Fixes: U4-5207 User Type with a space in the name breaks User Content 2014-07-16 14:12:04 +10:00
Shannon 388eea95e5 fixes a single vs first check with render route handler when there might be duplicate routes assigned to a controller, fixes short/int parse 2014-07-16 13:46:15 +10:00
Shannon 6167d1584a Fixes an xss vulnerability 2014-07-15 11:37:31 +10:00
Stephan bfd0c5e309 U4-4931 - also for ObjectCacheRuntime provider 2014-07-10 10:25:51 +02:00
Stephan 43669e62b4 Merge branch '6.2.2' into 6.2-4931 2014-07-10 10:25:12 +02:00
Shannon 6b128ea7d4 Fixes: U4-5208 RenderActionInvoker needs to be able to run async so needs to inherit from AsyncControllerActionInvoker 2014-07-10 17:29:34 +10:00
Shannon d5993a4783 Backports fix from 7 for GetDimensions call to ensure the file exists 2014-07-10 12:09:26 +10:00
Shannon 86c2a6e8a9 updates physical file system, now that files are being disposed of properly we don't need to delete first 2014-07-10 11:51:48 +10:00
Shannon 874f464a2b Fixes: U4-5190 Overwrite Media File in 6.2.1 - process cannot access along with a bunch of other undisposed disposables :/ 2014-07-10 11:45:57 +10:00
Shannon b3c41e051f Fixes: U4-5199 Appending certain query strings to URLs cause InvalidOperationException (The UmbracoContext.Current is null) 2014-07-10 11:10:49 +10:00
Shannon a88637910f updates content xml bits so if it's called outside a web req it still executes.
Conflicts:
	src/Umbraco.Web/umbraco.presentation/content.cs
2014-07-10 10:45:26 +10:00
Shannon 431e93000e Fixes: U4-5157 Membership.GetUser() causes 13 SQL queries, including duplicates 2014-07-08 19:04:38 +10:00
Shannon 1a821b4073 super quick performance win in the case where people don't pass in distinct values 2014-07-01 17:41:22 +10:00
Shannon a89b9e9da6 ignores log4net tests 2014-07-01 11:16:57 +10:00
Shannon 8917701fa3 ignores failing test - need stephane to look 2014-07-01 11:03:47 +10:00
Shannon 68b17bff08 Ensures no membership user writing when checking public access 2014-07-01 10:52:29 +10:00
Shannon 7a12060c37 Potentially fixes U4-5069 Deadlock occurring in MemberService.GetByUsername
Conflicts:
	src/Umbraco.Web/Security/MembershipHelper.cs
2014-07-01 10:46:52 +10:00
Shannon 525280d466 fixed some tests 2014-06-30 14:09:36 +10:00
Shannon 496beca8f2 This Can_Find_Targetted_Migrations test needed a valid database to pass. This update ensures that the database is created with the old version 4.8 db schema. 2014-06-30 14:02:43 +10:00
Stephan 637a22293d U4-4931 - fixing & refactoring 2014-06-28 18:33:31 +02:00
Stephan 3c8517edcb Merge branch '6.2.2' into 6.2-4931 2014-06-28 16:26:44 +02:00
Stephan 45e6127d00 U4-4866 - fix the build 2014-06-28 16:26:27 +02:00
Stephan 6eb5d3f7ef Merge branch '6.2.2' into 6.2-4931 2014-06-28 16:06:30 +02:00
Stephan e6986432df U4-4931 - fixing & refactoring 2014-06-28 12:24:02 +02:00
Shannon 80103e6155 Fixes: U4-4866 Select content root when creating a package 2014-06-26 16:55:44 +10:00
Shannon 392634eb76 bumps nuspec versions 2014-06-26 11:44:28 +10:00
Shannon 259bc863f0 Removes Examine.dll deploy from nuspec 2014-06-26 11:32:43 +10:00
Shannon 582bafdefd Updates version 2014-06-26 10:02:09 +10:00
Shannon 9924ef2381 Merge branch '6.2.1' into 6.2.2 2014-06-26 09:57:16 +10:00
Shannon 859fbaaa05 Fixes: U4-5121 umbraco.content launches threadpool threads to reload the xml cache which causes lots of other issues
Conflicts:
	src/Umbraco.Web/umbraco.presentation/content.cs
2014-06-25 19:02:49 +10:00
Shannon 72991334c4 little bit of code cleanup 2014-06-25 15:55:52 +10:00
Shannon c659d5b85e fixes dll ref 2014-06-25 14:35:14 +10:00
Shannon a4bf4b0977 Fixes: U4-5118 Examine not storing XML fragments - updates to latest examine 2014-06-25 14:19:31 +10:00
Shannon bef6ce66f1 Updated core nuspec to include Examine 2014-06-25 14:19:06 +10:00
Shannon a18a2198a8 removes comment 2014-06-25 12:25:27 +10:00
Shannon 7cf7ac687c last issue with state/keep alive timer 2014-06-25 12:03:31 +10:00
Shannon 7ce0272169 updates state param with timers to use singleton 2014-06-25 11:56:36 +10:00
Shannon acb934e3f1 ensures timer's are not GCd 2014-06-25 11:52:48 +10:00
Shannon 3aa486a463 another log 2014-06-25 11:36:58 +10:00
Shannon 5aa0621c90 adds some notes 2014-06-25 11:36:14 +10:00
Shannon 625b8f7e65 Ensures the 'Index' portion of the path is used for scheduled publishing 2014-06-25 11:26:08 +10:00
Shannon e27163f3a7 adds logging to scheduled bits 2014-06-25 11:00:11 +10:00
Shannon 65ea6f94d3 adds authorization to the scheduled publishing , this new attribute can be used to secure scheduled tasks as well. 2014-06-23 15:02:23 +10:00
Shannon 9158ea1ace fixes url returned in GetCurrentServerUmbracoBaseUrl 2014-06-20 14:45:45 +10:00
Shannon e8f7f77bb6 Fixes: U4-581 Automatic publishing not working in load balanced setup - added some more convention and configuration to distributed calls so that servers are aware of the master and how to call into themselves for scheduled tasks, ping and scheduled publishing. Will need to update the docs on LB regarding this too. Cleaned up the code that does the scheduling and separates it into proper segments. Obsoletes the old presentation classes that were doing it. 2014-06-20 14:34:21 +10:00
Stephan 75e003185a U4-4931 - do not cache exceptions 2014-06-17 19:34:24 +02:00
Stephan 9d12e1c7df Merge branch '6.2.2' into 6.2-4931 2014-06-17 19:19:17 +02:00
Shannon b8575ef158 Started writing test implementation to mimic what developers might test in their controllers to expose the pitfalls of umbraco testing so we can make this simpler - identifying what needs to be public and how to re-strcuture some objects constructors, etc... to simplify and make this possible. 2014-06-17 18:53:23 +10:00
Shannon d3bb750f98 Updated to latest Examine with lock fixes 2014-06-17 16:07:08 +10:00
Morten Christensen 02eff33d29 Fixes U4-2640 LocalizationService throws exception when getting dictionary items and adds tests for the LocalizationService 2014-06-08 13:16:32 +02:00
Shannon b43f39a0cb disables dist call 2014-06-08 12:50:45 +02:00
Shannon d0cb27d1c1 Completes: U4-2633 Bundle all cache refresher transmissions into a single call per request for much better performance 2014-06-08 12:49:20 +02:00
Stephan 16a1720bf7 Merge remote-tracking branch 'origin/6.2.1' into 6.2.1 2014-05-28 17:11:56 +02:00
Sebastiaan Janssen ea32776174 Bump version 2014-05-28 17:07:51 +02:00
Stephan 320b53ae3c U4-4773 - bring back IPublishedContentProperty Alias and Version (compat) 2014-05-28 11:36:31 +02:00
Shannon d987dfb5a2 Fixes: U4-4141 7.0.2 "Save and send for approval" fails for a writer user on a newly created unsaved content page 2014-05-28 12:40:43 +10:00
Stephan 74806984b3 U4-4931 - fixing & refactoring 2014-05-27 12:17:48 +02:00
Stephan c8c278c7bc Merge remote-tracking branch 'origin/6.2.1' into 6.2.1 2014-05-27 12:17:43 +02:00
Sebastiaan Janssen 13e8e972eb U4-4956 UserService.SavePassword method always throws a not supported exception 2014-05-27 11:43:50 +02:00
Stephan a8e4c3eb9a Merge remote-tracking branch 'origin/6.2.1' into 6.2.1 2014-05-26 18:07:45 +02:00
Stephan d631039c0d U4-4928 - issue with missing media content properties 2014-05-26 18:07:20 +02:00
Stephan 113b866485 U4-4931 - fixing & refactoring 2014-05-26 15:56:29 +02:00
Stephan 6c6ef8d144 Merge remote-tracking branch 'origin/6.2.1' into 6.2.1 2014-05-26 15:03:38 +02:00
Stephan 95b9a46b88 U4-4928 - issue with missing media content properties 2014-05-26 15:02:05 +02:00
Stephan 99250cefbb U4-4931 - fixing & refactoring 2014-05-23 10:46:41 +02:00
Stephan dc651a1c42 Merge remote-tracking branch 'origin/6.2.1' into 6.2.1 2014-05-23 10:46:13 +02:00
Sebastiaan Janssen 8fb446960c U4-4927 Image Cropper Crop URL is wrong in 6.2.0
Reverts part of 067268a96e which was refactored wrong
2014-05-22 19:39:25 +02:00
Stephan 4e9fd5a223 U4-4931 - fixing & refactoring 2014-05-22 13:43:55 +02:00
Stephan e2c36d7212 Merge remote-tracking branch 'origin/6.2.1' into HEAD 2014-05-22 13:40:58 +02:00
Shannon 62887607ff fixes csrf with mediauploader.ashx 2014-05-22 12:44:04 +10:00
Stephan 695cc07912 Merge remote-tracking branch 'origin/6.2.1' into 6.2.1 2014-05-20 09:32:54 +02:00
Stephan f325794523 U4-4949 - fix issue with domains 2014-05-20 09:32:26 +02:00
Sebastiaan Janssen 3ec6d2b82f U4-4861 6.2.0 Nuget package copies wrong files 2014-05-19 10:08:26 +02:00
Stephan 46f57a3115 U4-4931 - lock contention & potential application lockdown 2014-05-18 19:13:22 +02:00
Sebastiaan Janssen d697c590e7 U4-4930 NuGet update fails to copy new Umbraco binaries 2014-05-16 18:54:49 +02:00
Sebastiaan Janssen a55cd67fd6 U4-4650 Pluralization of document type aliases doesn't always work 2014-05-16 14:33:25 +02:00
Sebastiaan Janssen afa81be102 Fixes U4-4650 Pluralization of document type aliases doesn't always work 2014-05-16 14:23:40 +02:00
Stephan ddd0e8abb5 Bugfix media cache property alias case sensitivity 2014-05-16 10:10:55 +02:00
Stephan e07f573683 Fix the build 2014-05-16 09:57:21 +02:00
Shannon 1f88960b3f Fixes: U4-4926 Pre-values need to be cloned in/out of the cache
Conflicts:
	src/Umbraco.Core/Models/PreValue.cs
	src/Umbraco.Core/Models/PreValueCollection.cs
2014-05-16 12:09:47 +10:00
Shannon d8edf67b82 Fixes: U4-4842 Unable to edit "name" and "alias" to MediaType property 2014-05-16 12:09:08 +10:00
Shannon 365a8e85e9 Fixes: U4-2356 2014-05-15 16:13:54 +10:00
Shannon 5f9dddafd8 fixed an upgrade script when upgrading from old 4.x versions 2014-05-15 14:11:43 +10:00
Shannon 836297df58 Fixes error message on publishing when it fails due to any of these statuses: FailedHasExpired, FailedAwaitingRelease, FailedIsTrashed 2014-05-15 13:35:52 +10:00
Shannon 78613823ae Fixes: U4-4853 Richtext Editor doesn't render macros after upgrade to Umbraco 6.2.0 2014-05-13 15:22:16 +10:00
Shannon 937e840104 Fixes: U4-4873 RuntimeCacheRefresher does not remove items when media or content requires cache refreshing & U4-4871 Synced media indexes between load balanced servers do not sync all properties 2014-05-13 10:40:56 +10:00
Shannon 313d77eb91 Fixes: U4-4789 PluginCache doesn't update with code defined PropertyEditors in package and publicizes a couple things 2014-05-12 17:19:17 +10:00
Stephan 4e5019d5af U4-4851 - Umbraco.Field legacy names 2014-05-11 21:33:56 +02:00
Shannon da0b935604 Fixes merge 2014-05-09 16:08:05 +10:00
Shannon b91a06ab98 Fixes: U4-4849 Cannot change a users language/sections in the back office 2014-05-09 16:00:30 +10:00
Shannon d61fb5d94d Fixes user cloning issues with allowed sections 2014-05-09 15:59:30 +10:00
Shannon 3b424274ee ensure properties reset on deep clone of ContentType (this is just a fail safe check) 2014-05-09 15:57:17 +10:00
Shannon b763c2ab2f Fixes deep clone of User object 2014-05-09 15:56:45 +10:00
Sebastiaan Janssen 16d98488e4 Losen up the requirement for json.net dependency 2014-05-01 14:06:28 +02:00
Morten Christensen 5a862f5c64 Fixes import of nested dictionary items #U4-4663 2014-05-01 13:51:33 +02:00
Sebastiaan Janssen caf41b74b8 Add failing test - dictionary items don't get properly nested 2014-05-01 12:26:18 +02:00
Sebastiaan Janssen e858f4ff1e U4-4775 creating new member group shows error message in dialog... 2014-05-01 11:45:14 +02:00
Sebastiaan Janssen 851961ef2b U4-4775 creating new member group shows error message in dialog... 2014-05-01 10:48:27 +02:00
Sebastiaan Janssen c139c5d93e U4-3925 Cancel Document_BeforePublish event gives YSOD 2014-05-01 09:55:14 +02:00
Shannon c4603ee5cd Fixes: U4-4798 When new property types are added, the internal Examine index isn't notified and will ignore them 2014-05-01 12:43:40 +10:00
Shannon 1e9d1007b6 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2014-05-01 11:36:33 +10:00
Shannon f23af85253 Fixes: U4-4624 Media cache hits the DB on every empty property, U4-4338 Umbraco fails to enumerate TypedMedia 2014-05-01 11:36:17 +10:00
Sebastiaan Janssen b0c5d16ba7 U4-4127 Turkish culture prevents Macros embedded 2014-04-30 19:29:32 +02:00
Stephan cd5581bef6 Back to IPublishedContentProperty (for 6 only) 2014-04-30 16:53:14 +02:00
Stephan 7d8da56dcb Revert "Reintroduce IPublishedContentProperty"
This reverts commit d33cc29f98.
2014-04-30 16:39:51 +02:00
Stephan 0501b181ce Refactor template aliases to strict aliases 2014-04-30 15:46:26 +02:00
Sebastiaan Janssen 3134668cec Bump version number 2014-04-30 12:00:19 +02:00
Shannon a8cc8fa688 Fixes case sensitivity with MySQL 2014-04-30 19:58:59 +10:00
Shannon cf2217cfe1 Fixes MySQL upgrades from < 6.0 2014-04-30 19:41:40 +10:00
Shannon e88e809e29 Use new YouTube oembed https end-point (old http one redirects) and make sure videos are embedded over https to allow for https Umbraco sites. 2014-04-30 17:39:13 +10:00
Shannon c5559d7721 Specifying assembly for membership/user provider
Addresses http://issues.umbraco.org/issue/U4-4781
2014-04-30 11:27:47 +10:00
Shannon 771e216813 U4-2635 Skip past replaced word when checking
Avoids infinite loop if search and replacement are equal
2014-04-30 11:21:12 +10:00
Stephan d33cc29f98 Reintroduce IPublishedContentProperty 2014-04-29 09:47:30 +02:00
Shannon b98fbbc75d Fixes: U4-4770 Preview XML is not generated for many operations in the ContentService, also moves some more CRUD logic in the content service to the content repo. 2014-04-29 11:11:48 +10:00
Shannon aba1862811 Fixes: U4-4754 Member and Media repositories need to generate preview xml when EnableGlobalPreviewStorage is true 2014-04-29 09:58:38 +10:00
Shannon 2f53698bc5 Fixes: U4-4766 UmbracoMembershipProvider.ChangePassword() is seal, what might be a breaking change? 2014-04-28 19:19:48 +10:00
Shannon e0e12d5773 Moves content xml crud logic for member service to member repo 2014-04-28 19:04:53 +10:00
Shannon 2e96de5449 Moves the CRUD logic from the media service to the media repo for dealing with content xml items and ensures it's done in the same transaction, streamlines how this process is done between the content, media, member services, adds test for it. 2014-04-28 18:53:21 +10:00
Shannon c5bce3b8cc completes: U4-4769 Remove the circular references from services for calls like ToXml which then calls into the PackagingService 2014-04-28 17:46:05 +10:00
Shannon b4286a7d4e works on U4-4769 - removing circular refs from media service 2014-04-28 17:38:24 +10:00
Shannon 31e018c045 Moves XML serialization for content/media/members to a resusable class: EntityXmlSerializer to remove the circular references we have by using the ToXml extension methods from directly in the services. This has been completed for the ContentService, next is Media and Member services. Updates the ContentService to not perform CUD operations for preview or published xml, this is now done at the repository level and now done in a single transaction for the saving and publishing events. Still need to do that for the member and media services too and the remaining methods in the content service 2014-04-28 17:28:40 +10:00
Shannon 50b71faff9 Adds .woff mime type 2014-04-28 12:45:12 +10:00
Shannon 033fd1b7ff Fixes: U4-4765 backoffice user section does not save password changes in v6.2 2014-04-28 12:24:39 +10:00
Shannon 2621b25fd3 Ensures that member saving events don't get raised for normal member operations like validating and getting a user and flagging them as online. This fixes: U4-3451 Cache on Partial View refreshed, after member execute login 2014-04-24 16:28:37 +10:00
Shannon 61055380c5 Ensures that member saving events don't get raised for normal member operations like validating and getting a user and flagging them as online. This fixes: U4-3451 Cache on Partial View refreshed, after member execute login 2014-04-24 16:26:21 +10:00
Shannon adf09d925f adds a comment 2014-04-24 14:51:41 +10:00
Shannon 12170fd787 fixes ysod overlay for ajax errors 2014-04-24 14:23:17 +10:00
Shannon c32cae16db Fixes: U4-4696 Macro personalized cache with custom membership provider not working - for any membership provider regardless of provider user key type 2014-04-24 12:14:06 +10:00
Shannon 437d1b759b fix for: U4-4696. Macro personalized cache with custom membership provider not working 2014-04-24 12:13:50 +10:00
Stephan f46811ff67 U4-3027 - fix content & property types alias casing 2014-04-24 00:18:24 +02:00
Stephan 6d50b46bd8 U4-4747,3027... - bugfix content type editor / aliases 2014-04-23 19:28:04 +02:00
Shannon a51bf232ec Fixes issue with data type pre-values and using PreValueAsArray when they are dictionary formatted. 2014-04-23 22:24:16 +10:00
Shannon fd19411e65 Fixes: U4-4743 Add IMemberService and IUserService to ServiceContext ctor 2014-04-23 20:41:03 +10:00
Shannon 7ac7bb9714 Fixes: U4-4746 Examine does not index updated paths/levels for moved/trashed media, U4-4744 Examine events do not listen for recycle bin emptying 2014-04-23 20:28:09 +10:00
Shannon 021cac9ca5 Fixes: U4-4746 Examine does not index updated paths/levels for moved/trashed media, U4-4744 Examine events do not listen for recycle bin emptying 2014-04-23 20:19:36 +10:00
Shannon 949447c25f Fixes examine lookup for children to ignore recycled media 2014-04-23 13:40:11 +10:00
Shannon 99d7bf91b7 Fixes null check in recycle bin repo
Conflicts:
	src/Umbraco.Core/Persistence/Repositories/RecycleBinRepository.cs
2014-04-23 13:39:34 +10:00
Shannon a92c232178 Fixes: U4-4653 MembershipHelper RegisterMember does not set password and ignores logMemberIn, adds a new flag to the model as to whether or not to have the cookie set as a persistent cookie (default is true) 2014-04-22 19:03:43 +10:00
Shannon 30901446e1 Fixes: U4-1853 Tinymce with the format dropdown added as soon as you interact with it the content tree stops working [Uncaught TypeError: Cannot set property 'href' of undefined (anonymous function) DependencyHandler.axd:57] Chrome Only.. 2014-04-22 18:17:28 +10:00
Shannon d772336c0f Fixes: U4-4695 Copy document type to new parent seems to lose some data, U4-4535 Create Copy method on the content type Service 2014-04-22 17:48:08 +10:00
Shannon f673cb024a Adds unit test for ensuring reset identities on cloning a content type 2014-04-22 14:00:03 +10:00
Shannon c4046ecb32 Fixes 'Clone' methods to ensure a Deep clone is used 2014-04-22 13:48:51 +10:00
Shannon 7823609500 Fixes: U4-4682 Get EditorTemplates and DisplayTemplates working with RenderViewEngine 2014-04-22 13:03:47 +10:00
Shannon a88cb3f724 Fixes: U4-3425 App_Code XSLT Extensions aren't recognized 2014-04-22 11:59:21 +10:00
Stephan 536b8ee921 U4-3425 - TypeHelper referenced assemblies issue 2014-04-19 17:44:52 +02:00
Stephan 3bf1041041 U4-3787 - Ensure we republish published descendants when republishing 2014-04-19 14:31:36 +02:00
Shannon fee23fac0a updates deep clone to have the false flag for resetting properties (we don't want to remember them when cloning)
Conflicts:
	src/Umbraco.Core/Models/Member.cs
2014-04-17 18:54:55 +10:00
Shannon cf6775ec31 moves an internal class 2014-04-17 18:05:12 +10:00
Shannon 1a13366cc9 Working on U4-4701 Fixup DataTypeService and repository with cache - the deletion logic all now happens in the transaction before it was done quite poorly for updating content types :( 2014-04-17 18:03:34 +10:00
Shannon 595b039ebe Working on U4-4701 Fixup DataTypeService and repository with cache, pre-values are now persisted properly using units of work with it's own mini internal repo. 2014-04-17 17:41:08 +10:00
Shannon e6406e9757 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2014-04-17 14:23:52 +10:00
Shannon bf65bf5bab Got pre-values caching properly and data types using the runtime cache provider correctly + unit tests. 2014-04-17 14:23:37 +10:00
Stephan 306d83cbd6 Bugfix published content extension .Next() 2014-04-16 19:04:49 +02:00
Stephan 1da901be96 U4-4575 - refactor prop. conversion logic 2014-04-16 18:25:41 +02:00
Shannon d953966248 Completes: U4-4670 Add .ContainsAny string extension to Umbraco.Core.StringExtensions 2014-04-16 17:01:26 +10:00
Shannon 2f679a52f4 fix build 2014-04-16 16:52:45 +10:00
Shannon ad8ab9f46e Fixes media uploader issue to ensure non-approved file types are not saved 2014-04-16 16:48:52 +10:00
Shannon 9b344a5a69 Added tests for member groups and member cloning. Added tests to verify that all entities can be serialized without issue. 2014-04-16 16:44:08 +10:00
Shannon 0a28bdafc2 Merge remote-tracking branch 'origin/6.2.0' into 6.2-cachefixing 2014-04-16 15:54:37 +10:00
Shannon 7aa1f480c9 Fixes up some cloning with value types and collections 2014-04-16 15:33:21 +10:00
Shannon 998f031877 Merge branch '6.2.0' into 6.2-cachefixing 2014-04-16 14:01:38 +10:00
Shannon ac7cb8febe Fixes cache providers to ensure it stores and resolves clones 2014-04-16 14:01:26 +10:00
Shannon 6e166bdba7 publicizes DeepCloneHelper 2014-04-16 13:40:20 +10:00
Shannon 1f2e46a195 Simplifies much of the deep cloning with the DeepCloneHelper and adds tests 2014-04-16 13:39:42 +10:00
Shannon bb22f5a283 More code and tests written for deep cloning. 2014-04-16 11:23:00 +10:00
Shannon dcac5d4709 More code and tests written for deep cloning. 2014-04-15 20:31:32 +10:00
Shannon 0e4e12d0ba More code and tests written for deep cloning. 2014-04-15 19:12:42 +10:00
Shannon 9118701669 More test written for deep cloning. 2014-04-15 14:53:19 +10:00
Shannon 58758e7a41 More work on deep cloning, have test passing for IContent 2014-04-15 13:52:49 +10:00
Sebastiaan Janssen 4a516f7da9 Manually applying PR #347 2014-04-07 13:01:43 +02:00
Sebastiaan Janssen bf8add4f8d Manually picked up PR #343 2014-04-03 11:10:43 +02:00
Stephan 9940b78a57 U4-4575 - fix 8371105 2014-04-02 17:00:24 +02:00
Stephan 8371105c10 U4-4575 - property converters use wrong source value 2014-04-02 16:00:46 +02:00
Sebastiaan Janssen 53c0bd6938 Fixes: Password is not saved when using the Register snippet 2014-04-02 11:59:16 +02:00
Sebastiaan Janssen a768fe5bb3 Ports behaviour from membershiphelper from v7 to 6 to make them the same 2014-04-02 11:42:48 +02:00
Sebastiaan Janssen d9c66cd4b3 Adds AddRelation and missing events in RelationService from v7 into v6 2014-04-02 11:41:59 +02:00
Sebastiaan Janssen 5b693f9310 Adds ability to add/remove a single role to/from a single member, which is much nicer than having to instantiate arrays 2014-04-01 16:43:11 +02:00
Sebastiaan Janssen 40ebc1295c Fixes error thrown when saving password and actually using the Umbraco membership provider 2014-04-01 15:30:42 +02:00
Sebastiaan Janssen 51660d918c Assembly redirect seems to help a lot installing NuGet pkg, should finally be able to close U4-4510 nuget targets file creates an invalid path in the property group 2014-04-01 14:22:13 +02:00
Sebastiaan Janssen 15aa6fc4b8 Fixed U4-4576 7.0.4 : InternalMemberSearcher config incorrectly uses 'enableLeadingWildcards', should be 'enableLeadingWildcard' 2014-04-01 11:53:56 +02:00
Shannon b9088c9ac0 fixes build 2014-03-28 08:51:25 +11:00
Shannon 49cf0f98ce U4-1752 - Add GetPreValueAsString(id) method to the @Umbraco helper 2014-03-28 08:31:21 +11:00
Shannon d8a3e00440 Fixes: U4-2843 Copying Document Type when Selecting Master Doesn't Work (Master ignored), U4-3552 Copy nested document type is failing 2014-03-27 17:26:55 +11:00
Shannon c309e18f13 Fixes: U4-459 Public Access permissions not set on distributed servers 2014-03-27 16:11:34 +11:00
Shannon cde3c42cec Fixes: U4-4455 Javascript error with single quotes in literals
Conflicts:
	src/Umbraco.Web.UI/umbraco_client/Editors/EditScript.js
2014-03-26 13:34:26 +11:00
Sebastiaan Janssen f13ddddc16 U4-4510 nuget targets file creates an invalid path in the property group
That should fix this one properly now
2014-03-25 20:39:46 +01:00
Sebastiaan Janssen 89235f707c Sync the en and en_us translations 2014-03-24 17:25:31 +01:00
Sebastiaan Janssen a569796adb Removes stray semicolons from the nuget targets files 2014-03-24 14:00:12 +01:00
Shannon 81600f0f3c Merge branch 'patch-2' of https://github.com/designagencytom/Umbraco-CMS into designagencytom-patch-2
Conflicts:
	src/Umbraco.Web/umbraco.presentation/umbraco/members/EditMember.aspx.cs
2014-03-24 11:18:11 +11:00
Shannon 74ccd79408 Merge branch 'patch-1' of https://github.com/designagencytom/Umbraco-CMS into designagencytom-patch-1 2014-03-24 11:13:07 +11:00
Sebastiaan Janssen 424ff02734 Forgot a few includes, fixed! 2014-03-20 17:29:16 +01:00
Sebastiaan Janssen 80bd8d962b Make sure the App_Plugins folder is there 2014-03-20 16:58:35 +01:00
Sebastiaan Janssen 956364decd v7 NuGet changes also apply to v6 2014-03-20 16:02:24 +01:00
designagencytom 6133e8f8c2 Update loadMemberGroups.cs
Sort the roles alphabetically to make it easier to manage the list when it becomes very large.
2014-03-20 13:02:25 +00:00
Shannon bcb7561e74 fixes unit test 2014-03-20 17:44:13 +11:00
Shannon 83f4c0262e Fixes: U4-4475 Creating new member doesn't put it in examine. Fixes up some cache refreshers to ensure they are calling the base method so that events fire consistently.
Conflicts:
	src/Umbraco.Web/Cache/UserPermissionsCacheRefresher.cs
2014-03-20 12:38:19 +11:00
Shannon 15222e176e Fixes: U4-4474 YSOD when expanding Members tree 2014-03-20 10:37:54 +11:00
Shannon 84dd7dc61a Fixes: U4-4466 6.2-beta - Creating Member Type without Alias results in no viewable Member Types in back office 2014-03-20 09:52:31 +11:00
Shannon ff5dadde53 Fixes unit test and another potential migration problem using an old alias for foreign key 2014-03-19 18:43:10 +11:00
Shannon ded82611a7 Finalizes: U4-4472 Image cropper should use IFileSystem - currently uses standard IO 2014-03-19 15:09:50 +11:00
Shandem 6a8cb5e123 Merge pull request #270 from stefana99/6.2.0-imagecropper
Changes to imageCropper, supports new mediafilesystem
2014-03-19 14:48:38 +11:00
Shandem 09428d703c Merge pull request #298 from KevinJump/6.2.0--PackageServiceFixes
6.2.0  package service fixes
2014-03-19 14:43:19 +11:00
Shannon a0541b000e Fixes: U4-4463 Upgrade 6.2.0 > 7.1.0 fails - due to incorrect formatting of foreign keys for sql servers
Conflicts:
	src/Umbraco.Tests/Migrations/AlterMigrationTests.cs
	src/Umbraco.Tests/Migrations/Stubs/AlterUserTableMigrationStub.cs
2014-03-19 10:33:37 +11:00
Shannon 668935548d Fixes: U4-4394 7.0.4: Inconsistency in member tree listings
Conflicts:
	src/Umbraco.Core/Persistence/Querying/BaseExpressionHelper.cs
	src/Umbraco.Core/Persistence/Repositories/Interfaces/IMemberRepository.cs
	src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs
	src/Umbraco.Web/Trees/MemberTreeController.cs
2014-03-19 09:28:13 +11:00
Shannon 14141fcaa5 Fixes the dictionary query syntax properly for all db's 2014-03-19 09:24:57 +11:00
Sebastiaan Janssen 7c5942b05f Updating minimum required versions of dependencies to be the same as v7. 2014-03-18 18:40:20 +01:00
Sebastiaan Janssen 8b4d4e3189 Update readme and remove non-functioning backups from install.ps1 2014-03-18 18:38:16 +01:00
Sebastiaan Janssen 4f008f5848 Bump version to RC 2014-03-18 18:37:42 +01:00
Sebastiaan Janssen 1a40ccc838 Updating nuget targets files, like on v7. Also updates nuget author name. 2014-03-18 17:51:33 +01:00
Stephan e80963093d Fix MySql dictionary issue
Conflicts:
	src/umbraco.cms/businesslogic/language/Item.cs
2014-03-18 12:44:32 +01:00
Shannon 0749124f45 fixes bug with col name 2014-03-18 20:11:22 +11:00
Shannon bef970437a doh, fix for new ctor 2014-03-18 19:39:17 +11:00
Shannon dda36f0147 added additional ctor for member to create an empty one 2014-03-18 19:30:54 +11:00
Shannon caad775399 Removes the User membership provider name constant - it is not a constant, this value is configurable! 2014-03-18 18:52:17 +11:00
Shannon 7a7720c460 Gets #U4-4454 Can't log in a new member created through memberservice completed 2014-03-18 18:41:18 +11:00
Shannon b2aeb835d5 Implements the SavePassword method of the MemberService 2014-03-18 17:45:11 +11:00
Shannon 8dd950bd52 Ensures all access to the users membership provider is done with our extension method 2014-03-18 17:22:25 +11:00
Shannon e2881e07d1 Ensures that all calls to the members membership provider are done so explicitly with the membership provider alias - this decouples the need to have the umbraco membership provider declared as the default, we were doing both before. 2014-03-18 17:08:21 +11:00
Shannon 71de4dc7de Fixes: U4-3675 [NonAction] attribute should be ignored by Umbraco RenderActionInvoker 2014-03-18 14:28:05 +11:00
Shannon e22476f54a fixes some test logic 2014-03-18 14:19:26 +11:00
Shannon 20ae16b2d7 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2014-03-18 14:18:50 +11:00
Shannon 9e466971af fixes some test logic 2014-03-18 14:18:34 +11:00
Stephan 3c6029c969 Merge remote-tracking branch 'origin/6.2.0' into 6.2.0 2014-03-17 15:27:25 +01:00
Stephan a4a0de3503 U4-4373, U4-4374 - finalize fixes 2014-03-17 15:25:25 +01:00
Shannon 217267bf94 Supercharges integration tests - now running at a great speed. 2014-03-17 22:22:44 +11:00
Shannon 4748366766 Fixes up some more test attributes 2014-03-17 20:59:31 +11:00
Shannon ab00782d84 Fixes potential issue with why test were failing 2014-03-17 20:33:30 +11:00
Shannon d19d1b3a18 Changes database behavior in integration tests to be opt-in, removes the db behavior to have a new schema per fixture, now we only deal in new files + schema per fixture/tests as it was taking longer to uninstall the db tables than just delete the file. 2014-03-17 19:38:29 +11:00
Shannon 30cfa4c0ae moves MemberCountType to correct namespace 2014-03-17 14:18:38 +11:00
Shannon d028ee2c3e Completes: U4-4457 Upgrade to latest CDF 2014-03-17 14:08:07 +11:00
Shannon a60e2318ad Fix Null Prevalue Values on Export of DataTypes
Exporting a DataType that has a Numeric pre-value that has no value
causes an Exception - added null checking to pre value.value
2014-03-17 13:23:26 +11:00
Shannon f642a7fd63 Fixes: U4-4368 Cannot insert the value NULL into column 'name' when creating new relation type from API 2014-03-17 13:21:17 +11:00
Shannon d1d54d8e84 Fixes: U4-4427 Exception with selecting content start node in Multi-node tree picker 6.2.0 2014-03-17 13:12:08 +11:00
Shannon bbeedb6c1b Fixes: U4-4373 @Library.NodeById(-1).Id returns "0" instead of "-1"(6.2.0 beta) & U4-4374 @Model.NodeById(-1).DescendantsOrSelf().First().Id results in Excecption (6.2.0 beta) 2014-03-17 12:27:37 +11:00
Shannon 4745995f92 Fixes: U4-4373 @Library.NodeById(-1).Id returns "0" instead of "-1"(6.2.0 beta) 2014-03-17 11:45:42 +11:00
Shannon c66aca2d41 Adds migration to rename the index umbracoUserLogins_Index to IX_umbracoUserLogins_Index so that it follows standards, fixes unit test 2014-03-17 11:24:01 +11:00
Shannon af148a4544 reverts the notion of shema migration - we will run migrations normally as we've been doing, this fixes a couple of unit tests too. 2014-03-17 10:48:56 +11:00
Shannon d7ea8e02d6 fixes unit test 2014-03-17 09:40:28 +11:00
Shannon 58814d4ac2 updates the migration order 2014-03-15 20:11:42 +11:00
Shannon bd1dc4f88d Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2014-03-15 18:53:25 +11:00
Shannon 67c1cc44c5 oops, fixes some logic with a closing bracket in the wrong place 2014-03-15 18:53:03 +11:00
Morten Christensen b680f87c12 Adding a note about the usage of the PackageInstallation class in the PackagingService 2014-03-14 12:14:43 +01:00
Morten Christensen 8db6633c91 Initial implementation of a new package installation approach based on PR-297. Everything is left internal as we don't know when something like this can be introduced.
Idea is to be able to install a complete package using the PackagingService, so that we eventually can obsolete the old Packager/Installer-code.
2014-03-14 12:11:38 +01:00
Shannon 3e5128147c fixes typo 2014-03-14 19:34:09 +11:00
Shannon b5329ace3b Backports fixes for legacy encoding checks and to not do any db lookups for the new membership providers and also ensures the legacy membership provider doesn't do any db lookups on init. 2014-03-14 18:38:57 +11:00
Shannon e1a134f587 Fixes: U4-4430 MySql primary key issues 2014-03-14 17:11:21 +11:00
Shannon bbe6194b06 Exception is thrown if trying to run mysql in med trust. Migrations arranged to execute schema migrations first and then data migrations. If a schema migration fails it will attempt to run the downgrade scripts of the migrations if running mysql since schema changes aren't supported in transactions. Updated all sql syntax providers to try to return only the column indexes, not key indexes. Updates the db version checker to include errors for all missing columns, indexes and constraints in the db and vice versa in the schema. 2014-03-14 13:04:20 +11:00
Shannon d76fd7d25e updates schema result to have case ignored. 2014-03-13 20:45:07 +11:00
Shannon e020989577 Give some love to mysql with regards to schema validation and the syntax provider - need ignore case comparisons. 2014-03-13 20:42:57 +11:00
Shannon 7258964bb7 Ensures version specific db providers are not referenced in the web.config 2014-03-13 20:14:11 +11:00
Shannon bcc2424577 fixes issue with getting 'other' 'members 2014-03-13 18:43:16 +11:00
Shannon 221bfa5f3d Fixes up issues with editing the member profile and registering a member with our snippets including specifying a custom member type. 2014-03-13 14:10:05 +11:00
Shannon 85a74e4fa7 Fixes: U4-4419 TempData is not being cleared on RedirectToCurrentUmbracoPage - it actually shouldn't be cleared but we need to handle how we add it properly as tempdata only clears when it is read 2014-03-13 12:21:31 +11:00
Shannon a8858ecfdd fixes unit tests 2014-03-13 11:10:29 +11:00
Shannon 0dc00a62e2 Adds ability to have proxy migrations so there is no duplication of declaring migrations and no duplication of executing already executed migrations. Would have been a bit nicer to have 2014-03-12 20:36:40 +11:00
Shannon 3b26834484 updates migration to make it a little faster 2014-03-12 18:40:39 +11:00
Shannon aee10348e5 Ensures not to add new indexes if they already exist 2014-03-12 18:37:22 +11:00
Shannon d0fc3ddba5 ensures applicationeventsresolver is disposed of in the correct place. 2014-03-12 18:11:05 +11:00
Shannon 3aadca167f oops, updated the reset to resetcollections for clearing collections for resolvers. 2014-03-12 18:00:00 +11:00
Shannon 3a92c26a7f Adds ability to extract index details from databases using sql syntax provider. 2014-03-12 17:17:52 +11:00
Shannon ff21379547 Makes ApplicationEventsResolver IDisposable so we can clear resources after startup. 2014-03-12 14:16:52 +11:00
Shannon aed4c1faed minor code cleanup and a null check. 2014-03-11 17:26:14 +11:00
Shannon 48bbf1ecb2 Fixes unit tests 2014-03-11 15:02:23 +11:00
Shannon c500d29029 adds some exceptions 2014-03-11 14:44:18 +11:00
Shannon 2c8fe5a130 fixes a few issues 2014-03-11 14:35:49 +11:00
Shannon d737afa327 Working on 2014-03-11 14:23:51 +11:00
Shannon ec6cb4520c Fixes: U4-3835 U7(nightly214) - Umbraco.Field not working 2014-03-10 17:44:40 +11:00
Shannon 3626d5b79d fixes unit tests 2014-03-10 17:27:22 +11:00
Shannon 980e8e84a6 Fixes: U4-4353 You are able to create duplicate content/media/member type's with the same alias 2014-03-10 17:26:04 +11:00
Shannon fb764641c5 Fixes: U4-4335 It's Possible to Create Duplicate Data Types 2014-03-10 15:16:17 +11:00
Shannon b94cee68e7 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2014-03-10 11:23:06 +11:00
Shannon b67fbbcbd8 Fixes: U4-4015 Usercontrol Browse Properties error 2014-03-10 11:22:49 +11:00
Sebastiaan Janssen 4d3eef1124 Update version 2014-03-07 15:25:10 +01:00
Shannon 3e6e6faf03 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2014-03-07 20:08:22 +11:00
Shannon b3f18bc677 fixed an issue with setting password with legacy api 2014-03-07 20:08:10 +11:00
Sebastiaan Janssen a48fe40675 Also clean up v6 snippets 2014-03-07 09:46:45 +01:00
Shannon 1511ad58b2 oops, put back the defaults for umbracoSettings 2014-03-06 20:16:55 +11:00
Shannon 2e9b751174 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2014-03-06 20:12:21 +11:00
Shannon d61ab97be3 Fixes: U4-4217 Ensure that the cmsTask data is cleared for any entity that uses umbracoNode table 2014-03-06 20:12:05 +11:00
Stephan dd40d73b71 Merge remote-tracking branch 'origin/6.2.0' into 6.2.0 2014-03-06 10:06:50 +01:00
Shannon 068bca84b7 Fixes: U4-156 Drag / drop support 2014-03-06 20:05:13 +11:00
Shannon 0fda528b94 Fixes: U4-1550 Publish notifications on a load balanced environment 2014-03-06 19:47:23 +11:00
Shannon 3552f63d87 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2014-03-06 19:29:35 +11:00
Shannon 01d04fde37 Fixes: U4-4060 Rollback feature does not show differences 2014-03-06 19:29:09 +11:00
Stephan 7f8c526136 Fix TryConvertTo handling of number decimal separator 2014-03-06 09:14:05 +01:00
Stephan ea4be14f0c Fix 026d040 - keep Standalone stuff internal 2014-03-06 09:10:14 +01:00
Stephan 20df48e2f0 Merge remote-tracking branch 'origin/6.2.0' into 6.2.0 2014-03-06 08:49:38 +01:00
Stephan 2c0f6f975c Bugfix UmbracoEntity ctor test 2014-03-06 08:42:41 +01:00
Shannon fa7f91b39d Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2014-03-06 18:26:10 +11:00
Shannon 72c5853fb1 Completes: U4-3937 Ensure media is indexed across all servers in LB environment with Distributed Cache calls
for members
2014-03-06 18:25:38 +11:00
Stephan f03b1a22f9 Merge remote-tracking branch 'origin/6.2.0' into 6.2.0 2014-03-06 08:12:51 +01:00
Shannon e7fb6e5beb Streamlines member and user services CreateMemberWithIdentity to be similar to media/content and not have a raise events flag. Also implements the CreateWithIdentity explicitly 2014-03-06 18:07:02 +11:00
Shannon d0cc93d6a2 Fixes: U4-3937 Ensure media is indexed across all servers in LB environment with Distributed Cache calls
This fix is for media indexes to be distributed properly and for unpublished content to be distributed properly, now to get members to do the same.
2014-03-06 17:50:08 +11:00
Shannon 4adc2562b1 Fixes issue with ugolive dashboard trying to load in knockout from a bundle which causes the examine mgr to fail 2014-03-06 17:49:09 +11:00
Shannon ba6878666c Fixes pretty ugly issue of the Saving/Saved events not being raised when using CreateWithIdentity 2014-03-06 17:35:47 +11:00
Stephan 792ab8d088 Introduce support for content fragments 2014-03-05 15:46:37 +01:00
Stephan 3d4409e52a Refactor CacheRefreshersResolver.CacheResolvers into .CacheRefreshers 2014-03-05 15:46:35 +01:00
Stephan acd377956f Improve how DomainHelper determines domain 2014-03-05 15:46:34 +01:00
Stephan 3b6dcc3421 Factor Dictionary.ReplaceKey method 2014-03-05 15:46:33 +01:00
Stephan cec4d41df7 Add comments to UmbracoViewPageOfTModel 2014-03-05 15:46:32 +01:00
Stephan ff0bcffefa Implement DefaultShortStringHelper.PostFilter to cut url segments at 240 chars 2014-03-05 15:46:31 +01:00
Stephan 5dbc72897a Add method to reset PublishedContentRequest template 2014-03-05 15:46:30 +01:00
Stephan 83736bec01 U4-4190 - enable retrieval of wildcard domains 2014-03-05 15:46:29 +01:00
Stephan 2f953c3819 Fix a38e0dc - use UInt64 instead of int 2014-03-05 15:46:28 +01:00
Stephan 026d040a62 Enable StandaloneApplication to work with Powershell 2014-03-05 15:39:16 +01:00
Stephan 7747b8f64f U4-3579 - support chars such as <, > or & in prevalues 2014-03-05 15:33:15 +01:00
Shannon feb9f40237 updates some ctors on umbraco context and routing context to have lazy overloads which allows us to more easily create/mock the umbraco context. 2014-03-03 04:16:09 +01:00
Shannon 651182f5de Fixes sql statement - to be like we have in v7 that supports all sql servers 2014-02-25 02:37:48 +11:00
Shannon 22b15a06f6 Fixes how member is approved is set by defaut and adds unit test for it. Also ensures that it returns true if the property value is invalid for whatever odd reason. 2014-02-25 02:10:25 +11:00
Shannon cb09795280 Removes new member service Creating event, as only Created makes sense. Deprecates the other 'Creating' events with a note to just use the Created event. 2014-02-25 01:45:41 +11:00
Sebastiaan Janssen a5637af2d8 Adding missing CreateMember method that also as a convenience allows you to pass in the member type alias instead of a whole membertype 2014-02-22 18:32:26 +01:00
Sebastiaan Janssen ac59c5deb0 Fixing some potential upgrade issues and two issues found with the legacy member API
- For legacy API we never had and "approved" checkbox, so the assumption is that members are always approved
- The RequiresUniqueEmail check was wrong, previously the assumption was: if there's no e-mail then don't check for uniqueness
2014-02-22 16:44:02 +01:00
Sebastiaan Janssen 683ddf6d34 Apparently we rely on <error404>1</error404> to be in umbracoSettings.config 2014-02-22 16:03:59 +01:00
Sebastiaan Janssen eda33b1ac4 Update incorrect summary 2014-02-22 14:47:59 +01:00
Sebastiaan Janssen ed0f884348 Been a while: properly syncing /config/*.config with /config/*.Release.config 2014-02-21 17:50:58 +01:00
Sebastiaan Janssen b561351340 Update UI.Release.xml with the correct Partial View references 2014-02-21 17:33:19 +01:00
Sebastiaan Janssen 690ab29863 Use the database "agnostic" query for this (see U4-3876) 2014-02-21 17:01:59 +01:00
Shannon 27cb1d5223 completes: U4-4275 Hide built-in member type properties from the insert umbraco field list 2014-02-21 16:20:07 +11:00
Shannon c677f36f08 Changes some of the naming conventions for the underlying membership provider services bits. 2014-02-21 16:03:32 +11:00
Shannon 750f7a6b33 Updates some method names to be less confusing regarding permissions 2014-02-21 15:55:56 +11:00
Shannon dea804b402 fixes some permission logic and a unit test 2014-02-21 15:46:39 +11:00
Shannon 3803d1d7da fixes reflected property on dynamicnode and unit test 2014-02-21 15:22:02 +11:00
Shannon 3e67b3034d Added the ability to specify explicit db type's for a property type using an overloaded ctor argument. This allows us to specify explicit db types for properties without having them get overwritten during the repository saving logic which will always reset it to be the db type of the underlying property editor. In the case of our built-in membership properties we do not want this to happen. Fixes some unit tests. Removes built-in props from being included in the property types on the profile model on the front-end. 2014-02-21 12:56:00 +11:00
Shannon 1ada5210ad updated to latest examine 2014-02-21 09:54:53 +11:00
Shannon 9a608674eb fixes another test 2014-02-20 23:11:27 +11:00
Shannon 7dae412a29 fixes most of the newly failing unit tests and adds better null checking 2014-02-20 23:00:04 +11:00
Shannon b7f7775b89 adds initial commit of entity cloning 2014-02-20 22:34:54 +11:00
Shannon a1067e676f publicizes some repository factory methods and interfaces 2014-02-20 21:56:58 +11:00
Shannon ce649f54d7 Upgraded to latest examine, completes: U4-4240 Update with new examine version 0.1.53 2014-02-20 15:01:47 +11:00
Shannon d159792256 Updates last step of installer logic, we don't care about other providers as that would never have worked anyways 2014-02-20 14:38:00 +11:00
Shannon 606b5aa60a fixes logic in membershiphelper updatemember 2014-02-20 13:55:56 +11:00
Shannon a206652a0d updates login redirect logic to be more inline with v7, less greedy which is better. 2014-02-20 13:37:12 +11:00
Shannon 545040fdf0 Fixes installer upgrade 2014-02-20 13:09:54 +11:00
Shannon 40d1a09609 Updates the membership helper in how it updates the membership provider data, updates the editMember page to update the membership provider properties all via the membership provider 2014-02-19 23:49:53 +11:00
Shannon 2e25bc8fdb Moves all FindCOntrolRecursive calls to an extension method 2014-02-19 23:49:08 +11:00
Shannon 1618ac86b8 Adds implicit bool operator for Attempt, makes things nicer to check for success :) 2014-02-19 22:45:22 +11:00
Shannon a4adbca12c Removes the ability to edit the data type for a built-in membership property. Ensures that even if a data type is attempted to be changed with the API that the built-in properties are always persisted with the data type that we have defined by convention. 2014-02-19 21:56:33 +11:00
Shannon 8728e2f918 Fixes: U4-4260 When changing sort order on member type and saving, this doesn't get reflected on the member 2014-02-19 20:17:21 +11:00
Shannon cd53682ddb removes ability to configure custom fields for the new membership provider 2014-02-19 17:52:45 +11:00
Shannon e2d5fbf545 Fixes issue with ensuring properties on entities when a new property type has been created - but if the property type doesn't have an id, we should ignore it. 2014-02-19 17:27:08 +11:00
Shannon d339e7c814 updates the property type editability for built in member types 2014-02-19 16:57:33 +11:00
Shannon 078deb704b Completes: U4-4255 Add readonly membership provider properties to the profile model 2014-02-19 16:27:14 +11:00
Shannon 6858eb3330 Fixes: U4-4257 Fix member type editor to not have to re-call 'Save' so many times,
streamlines how the show property and editable property on member type's are dealt with (removes tuples)
2014-02-19 16:14:34 +11:00
Shannon e267b7700a Ensures that member properties are created when member type property type's are added (same as U4-1407), streamlines how this occurs on the base class. Streamlines how empty aliases are validated at the repo level for members, media, content. Makes built-in member property type's non-editable 2014-02-19 14:23:48 +11:00
Kevin Jump 366697f4eb PackageService: Fixes Single import for DataTypes
Importing a file with a single data type failed, because the DataType
element is at the root when exported.
2014-02-18 15:10:11 +00:00
Kevin Jump 987644379e Fix U4-4119 - Export Fails for Generic Properties
Adds null checking for PropertyGroupID on export so that properties with
no group (tab) don't throw an exception.
2014-02-18 15:07:47 +00:00
Shannon 1e45abe71e oops, changes the failedpassattempts back to noedit 2014-02-18 17:58:57 +11:00
Shannon a556b4ed21 Logs warnings if accessing built-in properties on the member model but the underlying property type is missing. 2014-02-18 17:53:02 +11:00
Shannon 953c711ca4 Updates the default member type property types to use "Labels", then needed to update the member type repo and membertypereadonlyfactory to ensure that even though the underlying data type for the property exposes a different Db Type that we 'reset' that Db Type to what it always should be. This means that no matter what underlying data type a developer changes a property to, if it is a built-in membership property, the Db Type will always stay consistent and save in the correct column. Of course if someone enters some invalid data, then the data will not be saved. 2014-02-18 17:19:38 +11:00
Shannon f06c9e8235 Ensures the default member type properties are put on a custom tab 2014-02-18 15:39:00 +11:00
Shannon f1a439e851 removes version specific references to mysql in the proj files and web.config
ensures that escaping in the sql expression classes is done correctly without any double escaping. Also ensures that escaping is happening using the equals operator, not just the Equals() method and adds unit tests for them.
Fixes: U4-4232 Umbraco.Core.Persistence.Querying issue with backslashes
2014-02-18 14:57:03 +11:00
Shannon a0e496e589 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2014-02-17 21:38:38 +11:00
Shannon e0dcc3afbc Streamlines how strings are escaped with the sql expression helpers and syntax providers. Fixes: U4-4232 Umbraco.Core.Persistence.Querying issue with backslashes 2014-02-17 21:38:13 +11:00
Stephan 3634a77d61 U4-4241 - UrlAbsolute() returns relative urls 2014-02-17 10:47:51 +01:00
Shannon 846f4b5b6c Removes the various old hacks for the legacy user's membership provider, now that we have the AllowManuallyChangingPassword flag, these hacks are not required. 2014-02-17 19:32:04 +11:00
Shannon 2869f17eff ensures the default property aliases are set during ctor 2014-02-17 18:02:29 +11:00
Shannon feefb052fd Updates the BulkInsertRecords method to optionally close the trans - shouldn't by default. Updates how permissions are handled in the new services and exposes another method, ensures it's all wrapped in trans and ensures that cache is cleared properly. Fixes: U4-4213 "Replace child node permissions" does not work if all permissions cleared 2014-02-17 17:45:59 +11:00
Shannon 4d2d9156ba updates more plugin manager defs 2014-02-17 15:58:57 +11:00
Shannon 82ba1a24a3 Ensures we perform null checks in both GetAll and GetByQuery as we never want to include a null item in the resultant collection - which could happen depending on what the sub class repository is doing.
Fixes: U4-3145 Cache file periodically becomes corrupted: "Oops: this document is published but is not in the cache (internal error)"
2014-02-17 15:45:36 +11:00
Shannon 357db9d0b6 completes: U4-3282 Expose permission assignment methods at the service layer 2014-02-17 15:33:17 +11:00
Shannon 61766287bc Cleans up some more of the old 'object' User Id references. 2014-02-17 15:26:38 +11:00
Shannon ffbf8b2fd6 completes: U4-4103 Publicize PluginManager for devs to use to create their own plugins 2014-02-17 15:08:27 +11:00
Shannon f7a703195c Fixes: U4-4215 Tree.config registeres tree inconsistently 2014-02-17 14:56:12 +11:00
Shannon 509be9b431 Updates the underlying UmbracoServiceMembershipProvider to deal with 'object' for provider key, this then lets us deal with either guid or int for the new membership provider, just like the old one does. 2014-02-17 14:14:17 +11:00
Shannon 10ef5eb7bc adds new interface for members' membership providers to implement so we know what aliases to store data against. 2014-02-17 13:16:28 +11:00
Shannon 2849ecadb7 fix legacy member wrapping new api and mixing email/login name 2014-02-17 12:24:11 +11:00
Shannon 697f93c3ce removes null check for LoginName, since it gets set to the name passed in if it is empty 2014-02-17 12:09:27 +11:00
Shannon 18121e8726 Enxures user start node's are -1 by default when creating the model. 2014-02-17 11:48:32 +11:00
Shannon 81cdc71145 Ensures new user objects are approved by default. 2014-02-17 11:17:15 +11:00
Shannon 4069fc8d1f fixes issue with legacy user.Password property and fixes comparison of sections 2014-02-13 17:19:28 +11:00
Shannon 0a80c39962 Fixes merge 2014-02-13 15:25:57 +11:00
Florian Verdonck edee8134c2 Updated request after feedback 2014-02-13 15:21:40 +11:00
Shannon 30a73c0886 updated web.config template to use new role provider. 2014-02-13 14:45:24 +11:00
Shannon f5ee02a3e9 Updates the membership partial view templates to redirect to current page by default but allows this to be overridden. Creates a new RedirectToCurrentUmbracoUrl method which is slightly diff from RedirectToCurrentUmbracoPage since it doesn't care about the actual page item rendering, just the currently rendered URL which is useful if coming from a rewritten URL (which is what happens with public access rewrites) 2014-02-13 13:30:32 +11:00
Shannon 9827b40bea Fixes: U4-4223 MVC based forms with SurfaceControllers don't work when rendered in Webforms mode.
This slightly changes how the routing works in the module, now we always send the request to the RenderRouteHandler, this will first process the logic for route hijacking, then it will determine if the request was found to be a WebForms template, if so then we'll return the webforms handler. This also now allows us to have POSTed values to SurfaceController's from forms that have been rendered in Webforms whilst maintaining all viewdata, tempdata and model state on postback even when rendering in webforms!
2014-02-13 13:19:51 +11:00
Stephan f9323c85e4 Fix issue with 9d7b3b96 in .designer.cs file 2014-02-12 13:22:35 +01:00
Stephan 2677672e50 Merge remote-tracking branch 'origin/6.2.0' into 6.2.0 2014-02-12 13:22:30 +01:00
Morten Christensen a38e0dcf86 Adding integer overload for UmbracoEntity so it can be used with a dynamic object containing either a boolean or integer retrieved from the database to initialize the UmbracoEntity object. 2014-02-12 12:47:47 +01:00
Stephan fdd7227494 Fix DynamicPublishedContent to use CleanStringType.ConvertCase 2014-02-12 10:46:57 +01:00
Stephan 6b74e14cdd Backport DefaultShortStringHelper from 7.1 2014-02-12 10:40:00 +01:00
Shannon 9d7b3b965a fixes some issues with new bundles. 2014-02-12 18:19:20 +11:00
Shannon 806008a7e9 Fixes issue with @ symbols in login name and a member group query 2014-02-12 18:02:00 +11:00
Shannon 45fa192c95 Fixes some unit tests 2014-02-12 17:25:45 +11:00
Shannon 92235128f1 Got new MemberGroupService done, completed the MemberService for role based stuff, created a member group cache refresher since we are caching member groups by name (probably should cache others too). Public access stuff changes if a name of a member group is changed which is now done with an event instead of coded into the biz logic. 2014-02-12 17:14:16 +11:00
Shannon 7622937cfd implemented remaining methods for member groups/roles + unit tests 2014-02-11 20:38:48 +11:00
Shannon bf41694572 Fixed up some more of the member group + member stuff with more unit tests 2014-02-11 19:21:36 +11:00
Shannon 7b897ce64c Member group repo updated along with the member service to support roles, etc... got first of many unit tests passing. 2014-02-11 12:43:55 +11:00
Shannon 1ca950f721 Starts creating the IMemberGroupService and supporting classes. 2014-02-10 19:48:16 +11:00
Shannon ffba271fd0 Creates the MemberGroupRepository and supporting models. 2014-02-10 19:35:32 +11:00
Shannon ec08d3e910 Updates MembershipHelper to not change the email/name if the value has not changed. Updates the templates to show only validation summaries for their own values/prefixes. Fixes some underlying MVC methods that merge view state to ensure the prefixes work with validation summaries properly when not showing property level errors. Updates the Umb controllers to add model level validation msgs when failed. 2014-02-10 18:34:12 +11:00
Shannon 0bfd032fad Obsoletes the RedirectOnSucces on the RegisterModel as it is not needed. Adds RedirectUrl to the ProfileModel and updates the controller to redirect properly (ensures it doesn't just redirect to home!) 2014-02-10 16:46:45 +11:00
Shannon 2bb58b6fca Updates MembershipHelper to ensure that the membership provider is used when updating a profile, specifically to deal with unique emails. Updates the profile edit template to have correct validation procedures. 2014-02-10 16:22:15 +11:00
Shannon 4d2d656b3d Moved ChangePassword method to MembershipHelper and makes it public, adds an overload. 2014-02-10 14:29:29 +11:00
Shannon fa625d72f9 updates some comments 2014-02-10 14:12:44 +11:00
Shannon 1991380e02 Changes CDF version to be the hash code of UTC now 2014-02-10 13:53:12 +11:00
Shannon 3b8d6dc2c7 Merge remote-tracking branch 'origin/6.2.0' into 6.2.0 2014-02-10 13:50:43 +11:00
Shannon 1faeb76c27 Removes the need for duplicate templates for partial views. Of course we can have partial view only templates if necessary but currently we just borrow them from the partial view macros and update the header 2014-02-10 13:50:31 +11:00
Sebastiaan Janssen 3a513668fd U4-4185 Log fails to show unicode (cyrillic) characters 2014-02-05 15:52:20 +01:00
Stephan 3ef51d7357 U4-2317 - issue with domains & languages management 2014-01-30 16:18:06 +01:00
Stephan 8b553dd067 U4-4144 - work around media cache exceptions on invalid properties 2014-01-29 19:30:17 +01:00
Shannon ccaf82d797 Fixes object extensions for dates with a 'kind' specified. 2014-01-29 11:21:35 +11:00
Shannon f28ae52ae3 moved logic to update a profile to MembershipHelper. 2014-01-28 21:57:00 +11:00
Shannon cfd0973f00 Moves the registration logic to the MembershipHelper, fixes up the views to keep the indexes so props save. 2014-01-28 21:42:30 +11:00
Shannon 1bfdd83ba7 Cleans up more of the membership controllers and snippets to be using the membership helper and fixes up a few issues 2014-01-28 19:41:21 +11:00
Shannon 6fefcacc61 Adds more methods to the MembershipHelper, updates the RegisterModel and obsoletes the standard ctor so biz logic is not happening in the model, updates the snippets to use the correct way. Fixes an issue in the membership repo for persisting new members when the member type doesn't contain all the built-in props. 2014-01-28 18:59:27 +11:00
Shannon 3b639e61b2 Exposes MembershipHelper onthe UmbracoViewPage so people can use it directly in views. 2014-01-28 17:02:20 +11:00
Shannon 9959ff667e publicizes MembershipHelper and exposes it on the various base classes: SurfaceController, UmbracoApiController and UmbracoUserControl as the property "Members", will add more helper methods. 2014-01-28 16:58:55 +11:00
Shannon de1f86c7a1 adds logic to the membership helper to create a new LoginStatusModel with the values filled in, obsoletes the empty ctor on LoginStatusModel since that does some biz logic lookups, instead replaces it with a static method to create an empty one. 2014-01-28 16:30:58 +11:00
Shannon 28d8fd0531 Changes LoginStatusModel to use the correct api and updates the new membership provider stuff to ensure that the provideruserkey is the int id of the model for backwards compatibility. 2014-01-28 16:13:05 +11:00
Shannon e4e76eb0bf Backports commit: Prefixed built in controllers to better avoid conflicts with people's custom code
Conflicts:
	src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/EditProfile.cshtml
	src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/Login.cshtml
	src/Umbraco.Web/Controllers/UmbLoginController.cs
	src/Umbraco.Web/Controllers/UmbLoginStatusController.cs
	src/Umbraco.Web/Controllers/UmbProfileController.cs
	src/Umbraco.Web/Controllers/UmbRegisterController.cs
	src/Umbraco.Web/Umbraco.Web.csproj
2014-01-28 13:47:16 +11:00
Shannon 677cc8c8fd Fixes ProfileController to use normal .Net APIs and the new members service - also removes the Response.Redirect that was in there, why was it like that? 2014-01-28 13:35:43 +11:00
Shannon 3fa5c4e0b2 Updates RegisterController with the standard ASP.Net APIs to create and login a member. 2014-01-28 13:21:30 +11:00
Shannon 360393c464 Fixes LoginStatusController to use the standard ASP.Net APIs 2014-01-28 13:07:25 +11:00
Shannon d3daf88a8d Fixes the LoginController to use the correct APIs 2014-01-28 12:58:22 +11:00
Shannon 7a99ebd6d9 Starts the implementation of the new role provider. 2014-01-28 12:48:41 +11:00
Shannon a7298e2e5a Completes: U4-4148 Anytime RuntimeCacheProvider or InMemoryCacheProvider is used, a cache refresher will need to handle it's distribution! 2014-01-28 12:20:10 +11:00
Shannon 15d7443c61 Streamlines the content type cache refreshing, leaving some of the legacy cache clearing but that shouldn't really have an effect, with these new changes it should be guaranteed that the distributed cache is executed always for Doc, media and member types. 2014-01-28 12:13:27 +11:00
Shannon f2b7e27b34 Fixes: U4-2721 RuntimeCacheProvider is not cleared when data type changes and updates the repo factory to not use the InMemory cache provider since we should only ever use that for very very specific reasons since the memory can never auto-clear with that provider. 2014-01-28 11:30:02 +11:00
Shannon 690d08aa8c Completes wrapping the new IUserService from the legacy User object. Ensures User cache is handled correctly and distributed cache is updated for Users. 2014-01-28 10:46:59 +11:00
Shannon 6719d70cc0 Updates UserTypeCacheRefresher to clear the runtime cache accordingly. 2014-01-28 09:22:01 +11:00
Shannon 3cdcf513ec removes ancient test project 2014-01-28 09:00:17 +11:00
Shannon 43c426b46c Update booting.aspx
Throw the exception immediately if the parameter is not there or empty.

If the parameter is not there it's defaulted to the current url, and this will redirect to itself and create an endless loop here.
2014-01-24 12:36:02 +11:00
Shannon e2ac82abca Gets most of the User and UserType legacy objects wrapping the new services, yay! Now just need to sort out all the caching stuff which I have tasks for. 2014-01-23 18:44:41 +11:00
Shannon 64d1a484bd Fixes User Id issues with HasIdentity, wraps legacy UserType to the new service, fixes the uninstalling db schema to not throw exceptions and clog up the unit test log. 2014-01-23 17:11:58 +11:00
Shannon 585b42af48 More Save()'s missing and removes the extra calls to XmlGenerate - should save some processing time. 2014-01-23 16:13:29 +11:00
Shannon 7c4412fc4b Ensures that Save() is called wherever member data is saved 2014-01-23 16:09:59 +11:00
Shannon 0be8039c8f Changes how IProfile works which is now just exposed by the IUser instead of implemented, this cleans up the Id situation. 2014-01-23 15:31:49 +11:00
Shannon 668265f1ac Allows forcing pass change with new provider, updates conventions to not allow editing of question/answer - unfortunately cannot make the other ones readonly because noEdit data type is the wrong clr type. 2014-01-23 15:11:54 +11:00
Shannon 4735f27a66 Fixes more naming conventions with CreateMemberWithIdentity, fixes memberTasks to ensure the name is set, fixes new membership providers which had the name/email call reversed. Updates the cache refresher event handler to listen to MemberService events instead of the old legacy API events. 2014-01-23 14:55:41 +11:00
Shannon 6377b9aa50 Fixes some underlying type conversions, fixes more of the member type wrapping, updates contenttypecontrolnew to work with member types properly, ensures the property type cache is cleared when member types change. 2014-01-23 13:33:58 +11:00
Shannon 011be60205 Finishes wrapping the member service and fixes a few bugs - ensures the RepositoryBase doesn't keep enumerating when getting all 2014-01-23 12:30:28 +11:00
Shannon a272675ed8 Wraps the MemberService from the legacy Member object 2014-01-23 11:41:01 +11:00
Shannon 80697cf9ca MemberType fully wraps new MemberTypeService 2014-01-23 10:57:24 +11:00
Shannon f4534aa94c adds unit tests for member type can view/can edit properties 2014-01-23 10:55:22 +11:00
Shannon 56dec485a5 Starts wrapping MemberTypeService from the legacy MemberType object. Changes the User.Id to an int - no more casting. Changes CreateMember to CreateMemberWithIdentity for consistency. Adds raiseEvent params to the create/save methods. Updates the MemberTypeService to have consistent naming conventions. Starts wrapping more of the MemberService from the legacy Member object. 2014-01-23 10:41:57 +11:00
Shannon ffde0f48cf Starts wrapping MemberTypeService from the legacy MemberType object. Changes the User.Id to an int - no more casting. Changes CreateMember to CreateMemberWithIdentity for consistency. Adds raiseEvent params to the create/save methods. Updates the MemberTypeService to have consistent naming conventions. Starts wrapping more of the MemberService from the legacy Member object. 2014-01-23 10:35:30 +11:00
Shannon 2956aee4e3 Fixes: U4-4108 The backoffice should not be accessible when the app is not configured, it should redirect to the installer and U4-4106 Set the new membership providers to be shipped as default. 2014-01-22 15:26:45 +11:00
Shannon 9bd8d729fa publicizes user stuff, changes the IUser.Id to an int - no need for it to be an object and casted everywhere. Updates the login logic to perform the mapping logic for custom membership providers with an extension method. 2014-01-22 14:07:18 +11:00
Shannon fb9569d914 Fixes user membership providers to throw exceptions on duplicate emails when the provider is configured to not allow duplicates. 2014-01-22 13:20:00 +11:00
Shannon 47974d49fe obsoletes old providers, creates new membership role provider stub 2014-01-22 12:16:47 +11:00
Shannon 3f8b3031c2 completes: U4-3996 Fix EditUser to use the membership provider properly, U4-3997 Fix EditMember to use the membership provider properly 2014-01-22 11:57:33 +11:00
Shannon 7da41594fd re-publicizes member services, fixes: U4-4102 Un-obsolete ContentService.Publish 2014-01-22 11:27:44 +11:00
Shannon 9796b30bbb Fixes: U4-4104 Using strongly typed Html.Action<T> with a PluginController causes exception 2014-01-22 11:02:24 +11:00
Shannon c2c4763faa Ensures username is escaped in user service 2014-01-20 16:11:38 +11:00
Shannon c062d3b71b Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2014-01-20 16:01:53 +11:00
Shannon ed83fb8216 updates user task creation for release 2014-01-20 16:00:19 +11:00
Stephan 326309e61e U4-4056 - better unicode/ascii support for urls 2014-01-16 17:09:21 +01:00
Shannon c38030def2 Fixes: U4-3855 Preview cookie should be a session cookie not persisted 2014-01-16 20:47:13 +11:00
Shannon 949861a890 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2014-01-16 20:03:52 +11:00
Shannon 122069752a fixes legacy validate member logic 2014-01-16 20:03:29 +11:00
Sebastiaan Janssen ae83b0fbaf Hardcoded empty snippets need to be updated as well.. 2014-01-15 21:07:24 +01:00
Sebastiaan Janssen 99e91a1053 U4-2737 Snippets that are available when creating new MacroScripts should also be available for Partial Views 2014-01-15 20:55:17 +01:00
Sebastiaan Janssen bad118ac6b U4-4046 Rename "empty template" to "empty" 2014-01-15 10:17:46 +01:00
Shannon 5c614a88a2 ensures webapi plugincontrollers are routed to /backoffice if [IsBackOffice] is specified 2014-01-15 13:29:17 +11:00
Shannon 3ef9635406 Fixes: U4-4010 Member and user session gets mixed - fixes how we detect a back office request + unit tests and added new IsBackOffice attribute 2014-01-15 13:17:38 +11:00
Shannon 75a42fd0d6 fixes the protect page logic 2014-01-15 10:42:01 +11:00
Shannon 84da5f43a2 U4-4045 The "Empty" partial view snippet should have @inherits 2014-01-15 10:41:37 +11:00
Shannon 000c2637d6 fixes view state and err msg 2014-01-14 16:54:32 +11:00
Shannon 563867cd8b Temp fix for: U4-3968 Umbraco 7.01 - Membership - Public Access - Add Single User protection - crash, fixes protectPage so that it uses the membership provider to make changes, updates the UI logic so that if you choose an existing user it will you about it, fixes it so you cannot arbitrarily change a member's password. 2014-01-14 16:21:00 +11:00
Shannon 86c66511dd changes all calls from Member.InUmbracoMemberMode() to Membership.Provider.IsUmbracoMembershipProvider() and obsoletes the InUmbracoMemberMode 2014-01-14 14:17:28 +11:00
Shannon 7d57521ad8 Fixes some thread safety issues with old membership API 2014-01-14 11:53:41 +11:00
Shannon e74e8f9d73 Fixes: U4-4005 Member custom properties not saving from code, only from backend, wraps more of the getter functions in legacy member class with new member service methods, fixes paged result method when there are no results. 2014-01-13 18:36:08 +11:00
Shannon 23b0c89848 ensures the mail usage is disposed. 2014-01-13 17:28:49 +11:00
Shannon aebc30c7a3 Removes the version specific info from the CDF and Examine references in all proj files. 2014-01-13 14:02:50 +11:00
Shannon 44bc365fdd Moves all notification sending logic to the notification service, improves performance during any action when notifications are to be sent, ensures emails are sent out async to not block up the current request. 2014-01-13 13:50:30 +11:00
Shannon 06defee410 Completed new NotificationService, moved Diff to Core 2014-01-13 13:05:25 +11:00
Morten Christensen 955573256d Updating the legacy Installer class to use the new methods in the PackagingService 2014-01-10 15:11:07 +01:00
Morten Christensen d963f5cd7d Updating a few methods that are made public in 7.0.2 2014-01-10 14:57:27 +01:00
Morten Christensen 2467b5ee3b Removing some internal experimental stuff that isnt used 2014-01-10 14:53:27 +01:00
Morten Christensen f86eb4b741 Adds import and export of languages along with tests 2014-01-10 14:48:55 +01:00
Morten Christensen 33b99073f0 Moving events out of the repository scope.
Adding Get Language by Iso Code method
2014-01-10 14:48:31 +01:00
Morten Christensen 880636c5a6 Adding languages xml to existing xml file for testing purposes 2014-01-10 14:47:31 +01:00
Morten Christensen 6e344f335e Adding Export of DictionaryItems including test 2014-01-10 13:08:33 +01:00
Morten Christensen 6b205bd725 Updates from PR#127 from Lars-Erik. Had to manually copy in the changes because the PR was closed.
Adds Import of Dictionary Items to the PackagingService along with tests and a fix for the DictionaryRepository.
2014-01-10 11:45:41 +01:00
Shannon 531306a091 Created notifications repository and service with unit tests, then need to start integrating that so notifications are properly sent. 2014-01-10 17:03:00 +11:00
Shannon 4346f73159 Fixes naming conventions from old Notification class 2014-01-10 15:13:25 +11:00
Shannon 4db6ce4b22 Fixes various issues relating to File Repositories and Services: U4-4014 FileRepositories offer no way to create folders, U4-4013 The models that the FileService produces causes security exceptions, U4-3993 Replace system.io calls in umbraco.scriptTasks legacy task
updates to latest CDF
2014-01-09 18:08:13 +11:00
Shannon 7c720460f5 Fixes: U4-3876 MySQL cmsContentXml Migration Error on 7.0.1 Upgrade 2014-01-09 10:33:35 +11:00
Shannon 961755336a adds another test for #U4-3876 2014-01-08 20:34:20 +11:00
Shannon e0aff8a1e4 adds a unit test 2014-01-08 20:25:35 +11:00
Shannon 6fa0c627a5 working on #U4-3876 2014-01-08 20:19:08 +11:00
Shannon 66a63b3cbb ignores these tests for now, they are successful when running isolated but as a whole they don't pass because of something with the legacy data layer. 2014-01-08 18:39:37 +11:00
Shannon 21c5b6fe02 fixes user lookup on legacy provider 2014-01-08 18:20:18 +11:00
Shannon ffed85640d fixes provider user key issue 2014-01-08 18:12:07 +11:00
Shannon cdbf89ee57 Fixes up the unit tests 2014-01-08 17:08:13 +11:00
Shannon 056b13eb98 fixes up the double member creation in the createuser method 2014-01-08 16:29:09 +11:00
Shannon 9467a67661 Backports the permissions repo updates, permissions on user/content repo updates and default permissions for users 2014-01-08 15:42:49 +11:00
Shannon 0f9f11bbcf re-internalizes some classes for now 2014-01-08 14:03:10 +11:00
Shannon 5b6cc51516 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2014-01-08 13:04:01 +11:00
Shannon 80b83ab64b Fixes up password changer on postback, fixes up more of the edit user and edit member pages. 2014-01-08 13:03:33 +11:00
Morten Christensen c6751f0374 Correcting the legacy template MakeNew private method so the OnNew event is fired after the design is added and file is created. 2014-01-07 13:24:05 +01:00
Morten Christensen d71c686aea Typo or missing update in legacy User class 2014-01-07 13:23:03 +01:00
Morten Christensen 4c5dfb42d5 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2014-01-07 13:13:38 +01:00
Shannon 0245efe3cb Fixes the change password dashboard to work properly. Fixes the EditUser to property save the member and the user. Adds new (probably temporary) MembershipHelper which is used to update a MembershipUser. Updates the User model to ignore the membership properties that we currently cannot persist. Ensures the legacy User membership provider still looks for a typed membership user (which should never have happened). Fixes small issue with underlying membership provider trying to encrypt an empty string. 2014-01-07 17:01:22 +11:00
Shannon 0b4ddf82aa Adds more user service tests 2014-01-06 17:43:29 +11:00
Shannon 3ff173732b implements the remaining incomplete parts of the UserService, adds more unit tests 2014-01-06 17:30:08 +11:00
Shannon f3f7aa70d1 Ensures a default member/user type is assigned on membership provider initialize, adds more unit tests 2014-01-06 16:18:25 +11:00
Shannon cd82bc6d21 streamlined the new membership provider classes so now they all share the same logic and use IMembershipMemberService<T> which is used by both IMember and IUser services 2014-01-06 15:38:34 +11:00
Shannon c3a6c7c473 fixes up more of the legacy user membership provider 2014-01-06 14:02:09 +11:00
Shannon 5538a2e793 fixed up the failing unit tests for member service counts, added more unit tests for UserService and implemented more of the required methods. 2014-01-06 12:25:14 +11:00
Shannon 1b7dc76df2 Updated much more of the UserService + some unit tests 2014-01-06 11:56:53 +11:00
Shannon 85c85cd1eb Simplifies and streamlines the models used between IMember and IUser along with the services used for both of these entities.
Updates the model used to store and retreive permissions, instead of a single string it is an Enumerable<string> which gives us some flexibility in the future and since this was not public (yet) it's the perfect time to do this.
Removes the base Profile classes from User since these are not required, since we cannot share base classes between Member and User, these weren't necessary.
2014-01-06 11:04:26 +11:00
Shannon ba5f2bc69d Ensure the old membership provider's count online members is implemented 2014-01-02 15:57:27 +11:00
Shannon 17883358b6 Fixes some issues with the User membership provider, updates user create dialog to also have an email address (which is required by membership), adds validation to the member and user create dialogs to ensure that the email address is validated to be a correcty formatted address. 2014-01-02 14:13:43 +11:00
Shannon fc0c6a1cd8 fixes stored password check with legacy encoding. 2013-12-31 13:27:47 +11:00
Sebastiaan Janssen 934d4020b2 Merge pull request #224 from Attackmonkey/Hackathon-2760
Fixes issue U4-2760, sorting installed packages
2013-12-29 06:30:09 -08:00
Sebastiaan Janssen 8b03ba4f42 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-12-29 15:26:44 +01:00
Sebastiaan Janssen 3caf84c63c Merge branch 'Hackathon-U4-3063' of https://github.com/Attackmonkey/Umbraco-CMS into Attackmonkey-Hackathon-U4-3063 2013-12-29 15:24:47 +01:00
Sebastiaan Janssen aae16f227e Merge pull request #227 from mattbrailsford/6.2.0-3454
Maintains tab sort order for doc type imports/exports.
2013-12-29 06:20:09 -08:00
Sebastiaan Janssen 443002cdde Merge pull request #273 from esunxray/patch-2
Update zh.xml
2013-12-29 06:19:30 -08:00
Sebastiaan Janssen 75150f0bfa Merge pull request #223 from Attackmonkey/Hackathon-2757
Fixes issue U4-2757 where generic properties are not ordered correctly.
2013-12-29 06:18:19 -08:00
Sebastiaan Janssen af73fd8b68 Merge pull request #218 from dipunm/U4-2551
Missing languages in RTE insert link dialog.
2013-12-29 06:11:53 -08:00
Sebastiaan Janssen 139df63ddf Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-12-29 15:08:10 +01:00
Sebastiaan Janssen a49058fe00 Fixes U4-510 Copy node makes multiple copies 2013-12-29 15:07:28 +01:00
Sebastiaan Janssen dcde00cec1 Merge pull request #213 from leekelleher/U4-3452
Fixes: U4-3452 Update the MIT License URL (Packager)
2013-12-29 05:58:02 -08:00
Sebastiaan Janssen bcc70f7a1e Merge pull request #197 from mkariti/u4-415
U4-415
2013-12-29 05:39:30 -08:00
Sebastiaan Janssen 32bc2f1d69 merge ismailmayat-UK-Festival 2013-12-29 14:34:54 +01:00
Sebastiaan Janssen 4d3f67885a Fixes U4-1076 Apostrophes in document type description are shown preceded/escaped by a slash in the Create Node dialog 2013-12-29 14:12:23 +01:00
Sebastiaan Janssen a269e9d426 Merge branch 'BatJan-master' into 6.2.0 2013-12-29 13:51:54 +01:00
Sebastiaan Janssen af5a382f93 Merge branch 'master' of https://github.com/BatJan/Umbraco-CMS into BatJan-master 2013-12-29 13:51:18 +01:00
Sebastiaan Janssen dad910b8ab Merge pull request #212 from mattbrailsford/6.2.0-1004
Added ValidateRequest="false" on package installer page to allow user co...
2013-12-28 03:50:10 -08:00
Shannon 8a70c440f2 Added many more unit tests for the membership provider base class and fixed some logic inconsistencies. 2013-12-28 18:55:43 +11:00
Shannon fbdb1d5d6c Fixes: U4-3942 Cannot configure the request if there is not content assigned - exception
Conflicts:
	src/Umbraco.Tests/Umbraco.Tests.csproj
2013-12-28 14:01:08 +11:00
Shannon edaa5ebd43 Lots more unit tests for the membership providers and some other fixups - have a new failing test as i need to sort out salting issue with encrypted passwords. 2013-12-24 14:03:18 +11:00
Shandem c12b270511 Merge pull request #268 from james-melville/6.2.0
Fixes: U4-3814 - 6.1.6 XSS vulnerability in backoffice
2013-12-23 16:14:52 -08:00
Shannon c8fa2b3880 Merge branch 'abjerner-patch-1' into 6.2.0
Conflicts:
	src/Umbraco.Web/PublishedContentExtensions.cs
2013-12-24 11:08:48 +11:00
Shannon 1c139b685a updates legacy membership provider to use efficient paging. 2013-12-20 18:12:54 +11:00
Shannon 7a8b3dc9bc Updated the member service/repo to have paged queries and results which use db paging for maximum efficiency (of course only works for things like email, username but those are 2 specific things that are needed by the membership provider) 2013-12-20 18:11:12 +11:00
Shannon a4dde1948f Implements the member count methods on the member service and adds unit tests. 2013-12-20 16:20:32 +11:00
Shannon 0f68818a19 Updated member service with the newer property value queries and added unit tests for all of them 2013-12-20 15:44:53 +11:00
Shannon 414b65b269 More WIP on the membership providers - both new and old. They are now both working with the same up-to-date logic and base classes. Updated the interface definitions on the member services to support the membership provider queries - now to implement the logic. 2013-12-20 14:01:10 +11:00
Shannon 2dd04799b2 WIP membership provider updates 2013-12-19 18:33:25 +11:00
esunxray 1c901e00cc Update zh.xml
add line <key alias="resetPassword">重设密码</key>
2013-12-19 14:53:50 +08:00
Shandem c589c741e8 Merge pull request #220 from leekelleher/U4-2006
Fixes: U4-2006 Domain.GetDomain(string DomainName) is case-sensitive
2013-12-18 20:56:03 -08:00
Shandem c8923cbc27 Merge pull request #221 from AnthonyCogworks/U4-2272
Replaced HttpContext.Current.Cache with HttpRuntime.Cache
2013-12-18 20:54:57 -08:00
Shandem 063f405a06 Merge pull request #230 from Yawka/U4-2772
U4 2772
2013-12-18 20:51:17 -08:00
Shandem addfbcf2a7 Merge pull request #232 from Yawka/U4-2034
U4 2034
2013-12-18 20:48:52 -08:00
Shandem 8ee133bb75 Merge pull request #239 from OptimisticCoder/U4-451
U4-451 Inconsistent line endings in template files created by Umbraco
2013-12-18 20:46:46 -08:00
Shandem fa1185cbd8 Merge pull request #241 from OptimisticCoder/U4-3039
U4-3039 Import Document Type leaves files in App_Data
2013-12-18 20:43:15 -08:00
Shandem 68e0a414a0 Merge pull request #245 from esn303/patch-1
Fixed minor typos
2013-12-18 20:39:43 -08:00
Shandem 89860bd786 Merge pull request #261 from esunxray/patch-1
Update zh.xml
2013-12-18 20:26:48 -08:00
Shandem b5cfefa052 Merge pull request #265 from Jeavon/U4-3247
Fixes U4-3247 - TinyMce v3 doesn't work with IE11
2013-12-18 20:22:19 -08:00
Shannon b2c0f3c35a some file formatting 2013-12-19 15:21:02 +11:00
Shannon a43f4b7b7f Completes: U4-1521 Updated back office to use ClientDependency bundles for common files 2013-12-19 15:05:05 +11:00
Shandem 7ce3949852 Merge pull request #209 from ProNotion/U4-1521
U4 1521
2013-12-18 18:37:02 -08:00
Shandem 4862419744 Merge pull request #198 from craigacronin/U4-1891
Fixed as per issue comments, but also implemented for another 3 overload...
2013-12-18 18:33:57 -08:00
Shannon 6b810c89f6 un-ignores PublishedContentExtensionTests 2013-12-19 13:28:17 +11:00
Shandem 89b0a2fd89 Merge pull request #170 from lars-erik/6.2.0_fix_publishedcontentextensiontests_sidebysidefriendly
Should make the PublishedContentExtensionTests green when ran together w...
2013-12-18 18:25:38 -08:00
Shannon 8aceae9880 re-formats some code, simplifies calls using InvariantEquals extension method 2013-12-19 13:22:33 +11:00
Shandem 384d4d60f1 Merge pull request #168 from stevetemple/6.1.6-multiple-action-route-issue
Fix error when multiple routes have the same controller
2013-12-18 18:18:44 -08:00
Shannon 67caf81a74 adds a couple of null checks. 2013-12-19 13:14:38 +11:00
Shannon 763ab26446 Updates packaging service to not export empty properties. 2013-12-19 13:13:13 +11:00
Shannon 67a8fa5f07 Merge branch 'wtct-U4-3091' into 6.2.0 2013-12-19 13:05:27 +11:00
Shannon 5c59317bf8 changes casing of col names 2013-12-19 12:52:37 +11:00
Shannon a2ec53dd4f Merge branch 'wtct-U4-3071' into 6.2.0 2013-12-19 12:50:42 +11:00
Shannon db78c78df2 fixes some merge issues with view engine wrapping PR. 2013-12-19 12:45:46 +11:00
Shannon 4558549d5a Fixes appendformat issue 2013-12-19 12:40:41 +11:00
Shannon d98801d5d1 Merge branch '6.2.0' of https://github.com/mortenbock/Umbraco-CMS into mortenbock-6.2.0
Conflicts:
	src/Umbraco.Web/WebBootManager.cs
2013-12-19 12:35:33 +11:00
Shandem de9ecf6afc Merge pull request #143 from IDisposable/patch-1
Added contextualKeyBuilder optional argument to allow the key used for cachin...
2013-12-18 17:32:26 -08:00
Shandem 702790bf77 Merge pull request #144 from IDisposable/patch-2
Make CacheHelperExtensions public so we can call CachedPartialView and C...
2013-12-18 17:30:01 -08:00
Shannon c912e80134 modified media service tests to not have to create data in teh base tests 2013-12-19 12:27:21 +11:00
Shannon 098c856138 Merge branch '6.2.0' of https://github.com/sniffdk/Umbraco-CMS into sniffdk-6.2.0
Conflicts:
	src/Umbraco.Tests/Umbraco.Tests.csproj
2013-12-19 12:11:33 +11:00
Shannon b45306e1ff Merge branch '6.2.0' of https://github.com/dprothero/Umbraco-CMS into dprothero-6.2.0
Conflicts:
	src/Umbraco.Web/umbraco.presentation/umbraco/members/EditMember.aspx.cs
2013-12-19 11:59:22 +11:00
Shannon 3499f39970 Merge branch 'kipusoep-patch-1' into 6.2.0 2013-12-19 11:49:30 +11:00
Shannon 9115aa1a6d merge issue with proj file 2013-12-19 11:46:31 +11:00
Shannon 904cbbb906 missing proj file update 2013-12-19 11:41:26 +11:00
Shannon 8656d3e4b9 adds some null checks, removes old unused webforms files for tree control 2013-12-19 11:35:53 +11:00
Shannon 40988b4655 Merge branch 'select-parent-on-movecopy' of https://github.com/pynej/Umbraco-CMS into pynej-select-parent-on-movecopy
Completes: U4-3920 Move/Copy/Content-Picker time saver - pre-selects current node
2013-12-19 11:25:54 +11:00
Shannon 06dbea84d8 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-12-19 11:06:11 +11:00
Shannon f54cf32057 Converted spell checker deserialization to json.net and changed the deserialized object to internal with correct naming conventions. 2013-12-19 11:06:00 +11:00
Shannon 64dbf0207b Merge branch 'DougMac-6.1.4' into 6.2.0 2013-12-19 10:38:56 +11:00
Stephan 206c88105e Left some Console.WriteLine statements uncommented 2013-12-18 17:50:47 +01:00
Morten Christensen 3177b979d3 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-12-18 10:00:47 +01:00
Shannon 4ab32dd270 moves classes into sep files 2013-12-18 18:09:54 +11:00
Shannon fec55e9d1c Updates IMemberService with methods to search on string properties with an option to define how to match the string property, adds all supporting unit tests. 2013-12-18 17:37:46 +11:00
Shannon a21aa079ff Adds ability to use the query builder with string matches based on an NText column 2013-12-18 17:22:00 +11:00
Shannon ef4246478d Fixes: U4-2294 6.1.0: umbracoServer table can't be created on MySQL <5.6.5 2013-12-18 15:30:40 +11:00
Shannon 137d859532 backports missing logic and tests from 7 that I overlooked. 2013-12-17 16:13:38 +11:00
Shannon 82b2821e27 Gets the members services ensuring members xml is being handled correctly, fixes issue with the static variable holding the default member type properties (this was then persisted in mem and then reused across all member types). Added more unit tests to verify all. 2013-12-17 15:40:47 +11:00
Shannon b270cefacc Upgrading member repositories and services with tests 2013-12-17 14:53:21 +11:00
Shannon b4e984fe6a adds/updates unit tests for member and member type repository 2013-12-17 12:38:11 +11:00
Shannon f62e4fa973 adds/updates member type repo tests 2013-12-17 11:42:03 +11:00
Shannon ee8050f38f Fixes ContentTypeBase event assignment issue - an event handler was added for every property type added - that was not correct. 2013-12-17 11:35:56 +11:00
Stephan b506b5c8e9 U4-3710 - bugfix 2013-12-16 17:01:35 +01:00
stefana99 067268a96e Changes to imageCropper, supports new mediafilesystem 2013-12-16 13:35:18 +00:00
Morten Christensen d9e843f0ba Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-12-16 09:48:18 +01:00
Shannon 66dd0d073c backports the member type service updates 2013-12-16 19:05:03 +11:00
Shannon 29c22cc4b5 exposes repository service 2013-12-16 19:02:53 +11:00
Shannon e29031a2c4 Back ported relationship repo/service updates 2013-12-16 18:44:11 +11:00
Shannon 3ff0cca033 back ports entity service updates 2013-12-16 18:23:40 +11:00
Shannon fe16cc91fa back ports packaging service updates 2013-12-16 18:17:30 +11:00
Shannon 7e6fdcb05e back ported template repo and file service updates 2013-12-16 18:10:44 +11:00
Shannon d1e071b9cb adds additional unit tests for the data type service to include pre-value handling. 2013-12-16 17:47:40 +11:00
Shannon 2ce952bdbb backports data type service updates and fixes unit tests with correct seeding value. 2013-12-16 17:17:23 +11:00
Shannon 6a9b8d5540 Fixes a unit test issue with the mntp editor initialization. 2013-12-16 16:27:59 +11:00
Shannon af86a5d7b1 backporting imediaservice changes 2013-12-16 16:04:37 +11:00
Shannon 0f25029ff6 Fixed typo 2013-12-16 16:02:34 +11:00
Shannon 060e584503 backported IContentService updates 2013-12-16 15:57:59 +11:00
Shannon 743c0bb31c Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-12-16 14:19:10 +11:00
Shannon 4bac3e19fe Fixes up webbootmanager with new cachehelper updates. 2013-12-16 14:18:58 +11:00
Shannon b86cddda94 fixes up unit tests 2013-12-16 13:55:46 +11:00
Shannon 11103c0bc5 proj file 2013-12-16 13:23:07 +11:00
Shannon 8210702474 removes the xquery tests - we don't need these and r# keeps wanting to run them 2013-12-16 13:22:52 +11:00
Shannon a42b660648 Backporting the cachehelper and associated cache classes. 2013-12-16 13:19:10 +11:00
Shannon f11d4fbedd Worked on the application cache, added request cache, changed some stuff over to be interfaces, added unit tests suite (need mroe) to test all caching providers.
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
2013-12-16 12:51:02 +11:00
Shannon 9105c08a4c getting membership provider to the same state as v7 2013-12-16 12:20:38 +11:00
Stephan 5aec753859 U4-3710, -3732 - Fix default ShortStringHelper 2013-12-13 12:20:57 +01:00
james-melville eeaa9166ac Fixes: U4-3814 - 6.1.6 XSS vulnerability in backoffice 2013-12-13 10:25:32 +00:00
Shannon 751ace1168 Merge branch '6.2.0-membershipprovider' into 6.2.0
Conflicts:
	src/Umbraco.Web/Umbraco.Web.csproj
	src/Umbraco.Web/umbraco.presentation/umbraco/members/EditMember.aspx.cs
2013-12-13 17:17:24 +11:00
Shannon 51da5343ea Fixes installation issue with rebuilding media cache
Conflicts:
	src/Umbraco.Core/Umbraco.Core.csproj
	src/Umbraco.Web.UI/config/trees.config
	src/Umbraco.Web/Umbraco.Web.csproj
2013-12-13 17:07:29 +11:00
Shannon 34df5009e0 Upgraded installer to do a two part install - first install then if an upgrade is required do the upgrade in a second call - this way we can have the progress bar update since the media xml installer can take some time. 2013-12-13 16:58:21 +11:00
Anders Bjerner e17b5e6a7b Update PublishedContentExtensions.cs
Added overloaded extension methods for Next() and Previous() to take a delegate (eg. lambda expression) as a second parameter. The methods are based on this thread by Jeavon Leopold: http://our.umbraco.org/forum/developers/razor/46832-Filtered-Next()-and-Previous()-v7-UmbracoHelperMVC

The code is tested in 7.0.0, but since it only relies on the existing Next() and Previous() methods, it should work in 6.1.x and 7.1.1 as well.
2013-12-12 15:32:52 +01:00
Shannon a1c65f0518 Gets that naggy unit test passing 2013-12-12 17:52:03 +11:00
Shannon c5047148b3 Fixes legacy media business logic to return null when calling ToXml if the media item is trashed - this makes it consistent with how content works and also prevents being able to show the media on the front-end when it is trashed. Fixes up how the MediaService rebuilds the XML to make sure it's transactional based. Fixes: U4-3820 cached media xml is not cleared from the cmsContentXml table when recycled
Conflicts:
	src/Umbraco.Web/umbraco.presentation/library.cs
2013-12-10 12:56:31 +11:00
Shannon ed2126eef9 ensures media xml cache is rebuilt on upgrade 2013-12-10 11:54:18 +11:00
Shannon ce4b56895e fixes installer login check 2013-12-10 11:51:41 +11:00
Shannon 94db371234 Ensures macro and urls are not parsed in the ItemRenderer when a content item is assigned since that parsing will occur with the value converters 2013-12-10 09:59:13 +11:00
Sebastiaan Janssen 103e226b51 Merge pull request #215 from dipeshhirani/U4-752
U4-752 Add culture invariant languages to create language dialog
2013-12-09 13:40:21 -08:00
Shannon 57f2250f13 Fixes: U4-3820 cached media xml is not cleared from the cmsContentXml table when recycled 2013-12-09 16:56:02 +11:00
dipeshhirani bb1edd2051 remove commented line 2013-12-08 16:23:03 +00:00
Sebastiaan Janssen 14790559cb Merge pull request #140 from pynej/search-node-type
Add node type to search results
2013-12-08 07:56:50 -08:00
Sebastiaan Janssen 97457087c7 Merge pull request #266 from greystate/patch-1
Fix a typo/grammar error in da.xml
2013-12-08 06:21:31 -08:00
Shannon 37eb66510f Fixes: U4-3505 Sometimes macro parameter types are not resolved during startup 2013-12-06 14:07:29 +11:00
Shannon 4cb4ff0617 Fix MySQL migrations.
Conflicts:
	src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AlterTagRelationsTable.cs
2013-12-06 10:26:32 +11:00
Chriztian Steinmeier dc60eb8383 Fix a typo/grammar error in da.xml 2013-12-05 13:06:24 +01:00
Jeavon Leopold 3f1b057f45 Fixes U4-3247 - v6.1.6 RTE view/edit HTML doesn't work with IE 11 by upgrading TinyMce to v3.5.10 2013-12-05 09:06:01 +00:00
Shannon f6179ff813 Strange, somehow these updates got overwritten 2013-12-05 16:11:15 +11:00
Shannon 1735c5adca adds Exists(string username) to member service and wraps IsMember with that call. 2013-12-05 16:04:53 +11:00
Shannon 31e715e146 Updates legacy Member class to setupNode based on the new IMember object (just like we do with media/content) - this will speed up data retrieval and is the start of wrapping the new API from the old one. 2013-12-05 15:51:38 +11:00
Shannon 5f50bae65c Cleaning up a bit of the legacy member class
Conflicts:
	src/umbraco.cms/businesslogic/member/Member.cs
2013-12-05 14:48:30 +11:00
Shannon e6d8a83519 Ensures that the ContentBase item is set on Document/Media and that the property value is set based on the already loaded value in the model if IData implements IDataValueSetter (which DefaultData does). This streamlines how properties get their data and will save on a ton of queries when using the legacy API. 2013-12-05 14:26:18 +11:00
Shannon 38df2017de Fixes issue with deleting content types that have content 2013-12-04 15:01:27 +11:00
Shannon 33aa4e2062 Fixes potential xss 2013-12-04 13:33:24 +11:00
Shannon 1efa75c891 Fixes potential xss 2013-12-04 12:42:40 +11:00
Shannon d4514844f8 Fixes a few other potential xss entry points 2013-12-03 17:58:42 +11:00
Shannon 6b7a495d19 Fixes a few other potential xss entry points and cleans up some legacy webforms files 2013-12-03 16:38:58 +11:00
Shannon 601eb0bf38 Fixes a few other potential xss entry points and cleans up some legacy webforms files 2013-12-03 16:28:51 +11:00
Shannon 037e7e0797 Fixes remaining xslt injection U4-3175 2013-12-03 15:56:50 +11:00
Shannon a7e32e97e3 Fixes xss issue 2013-12-03 15:40:12 +11:00
esunxray cacf87be2d Update zh.xml
update Chinese file for 6.2, this can be merged into V7.
2013-11-29 21:26:16 +08:00
Shannon e981776e6d Created new EnsurePublishedContentRequestAttribute for custom routing to still be able to render macros. 2013-11-29 17:41:38 +11:00
Shannon 250276bbd4 Merge branch '6.1.6-U4-3619' into 6.2.0 2013-11-29 11:26:01 +11:00
Shannon af29f61478 Fixes csrf issue 2013-11-29 11:10:25 +11:00
Shannon 58fc51ae93 Fixes: U4-3736 Unit test Can_Get_File_Dates() now testing correctly, disregarding local (nont-UTC) time. 2013-11-28 09:30:50 +11:00
Shannon 20813ef207 Fixes: U4-3673 Creating content with Services API always sets created by to admin
Conflicts:
	src/Umbraco.Tests/Services/ContentServiceTests.cs
2013-11-25 13:25:01 +11:00
Shannon d04f2a98b9 Fixes tests 2013-11-21 17:47:57 +11:00
Shannon f41f82adc5 Changes locker to be static 2013-11-21 14:46:18 +11:00
Shannon e6ae88c016 Fixes hash generation and checking with the trees.config file - since this is changed during startup our plugin cache was never active :( 2013-11-21 14:45:52 +11:00
Shannon 474dcd0754 Fixes: U4-3587 Can't delete a member when there is a group assigned
Conflicts:
	src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs
2013-11-20 18:24:44 +11:00
Shannon 369f6ac935 fixes merge issue 2013-11-20 18:15:11 +11:00
Shannon 5a928aa459 FIxes installer when duplicate conflicts: U4-3612 Cannot install Txt starter kit in the back office
Conflicts:
	src/umbraco.cms/businesslogic/Packager/Installer.cs
2013-11-20 17:28:33 +11:00
Shannon 416a9ed064 Comments out backported code - need to wait till we merge in the custom membership branch. 2013-11-20 17:10:15 +11:00
Shannon b13c3aa3b9 Fixes: U4-3610 When adding another tab to a member type no members will load and result in a YSOD
Conflicts:
	src/Umbraco.Core/Persistence/Relators/PropertyTypePropertyGroupRelator.cs
2013-11-20 16:59:41 +11:00
Shannon 99ae94a82f Ensures that members are auto-approved if creating a member via the legacy members API. 2013-11-20 16:40:30 +11:00
Shandem 96440c9ee5 Merge pull request #248 from lars-erik/6.2.0-fix-sqlsyntaxprovider-indexclustring
6.2.0 fix sqlsyntaxprovider indexclustring
2013-11-14 22:00:31 -08:00
Shannon b4c005c140 Fixes up the EntityRepository to use dynamics for media as well so that *all* fields in the main table are returned so we can store this information in AdditionalData, now that this is working nicely we should make the entity repo lookup the properties for content too just like we're doing for media since these get put into AdditionalData as well and there's really not much overhead to do that.
Conflicts:
	src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs
2013-11-15 14:53:26 +11:00
Shannon eca823ea90 Fix for U4-3529 Ysod editing Partial View 2013-11-15 13:49:20 +11:00
Marc Stöcker 376fe0bf55 changed wording to correct one in context of content
wording was wrong until today, needed a completely different meaning in the context of the content section; ironically it's just "Alias" now ;)
2013-11-14 22:22:25 +01:00
Lars-Erik Aabech e3cd85a6a2 Made CreateIndexBuilder set IndexType in Clustered(), NonClustered() and Unique(). 2013-11-14 10:55:35 +01:00
Lars-Erik Aabech 69f805ecca Proof that CreateIndexBuilder.NonClustered() does not affect index creation statement on SQL Server.
CreateIndexBuilder_SqlServer_NonClustered_CreatesNonClusteredIndex() fails expecting NONCLUSTERED but getting CLUSTERED.
CreateIndexBuilder_SqlServer_Unique_CreatesUniqueNonClusteredIndex() fails expecting UNIQUE NONCLUSTERED but getting CLUSTERED.
2013-11-14 10:53:58 +01:00
Shandem c037e2e09f Merge pull request #246 from lars-erik/6.2.0-fix-U4-3508
Fixes Template.ToXml() (U4-3508) and refactored Template.Import to use P...
2013-11-13 15:51:29 -08:00
lars-erik d8debf6789 Fixes Template.ToXml() (U4-3508) and refactored Template.Import to use PackagingService.ImportTemplates.
Fixed nullreference bug in ImportTemplates when used with XElement("Template"). (Added test for case with one template only)
2013-11-13 14:27:05 +01:00
Marc Stöcker 282da69d61 Fixed minor typos 2013-11-13 13:27:56 +01:00
Shandem e9ed1bf17a Merge pull request #244 from leekelleher/U4-3051
Fixes: U4-3051 GetAncestorOrSelfDocuments gets stuck in infinite loop
2013-11-12 14:11:05 -08:00
leekelleher cfcfb75dcc Fixes: U4-3051 GetAncestorOrSelfDocuments gets stuck in infinite loop 2013-11-12 21:26:21 +00:00
Morten Christensen 181593f5ea Merge pull request #234 from saciervo/fix/petapoco-fetch
SqlHelper Refactoring
2013-11-11 02:59:49 -08:00
Shannon a311a54d3d Hugely simplifies setting properties from macro parameters on user control macros with tests. 2013-11-11 12:22:29 +11:00
OptimisticCoder c83844468d U4-3039 Import Document Type leaves files in App_Data
Added File.Delete to clean up temp files.
Added try/catch round it and logging if it fails for any reason.
2013-11-09 15:18:43 +00:00
OptimisticCoder 80b5cfbb07 U4-451 Inconsistent line endings in template files created by Umbraco
Changed all "\n"'s to Environment.NewLine
Changed a string that was being appended in that method to a StringBuilder to be more efficient.
Cleaned up old commented out code from the method.
2013-11-09 14:37:22 +00:00
Sandro Ciervo 9911f03745 Fixed potential DbReaderException
- Use Fetch<T> instead of Query<T> because we create another DbReader inside the loop with DoesMacroHaveParameters().
2013-11-07 20:09:06 +01:00
yawka aacb86bf92 Add trim to all urls 2013-11-07 19:09:50 +02:00
yawka 59391f58ec Remove previous fix, and move it to IsReservedPathOrUrl 2013-11-07 19:06:25 +02:00
yawka 0debf9c34f Add check is path is whitespace 2013-11-07 19:05:50 +02:00
Morten Christensen 9fa17ef6cb Initial datalayer refactoring work on the legacy User class 2013-11-07 17:56:38 +01:00
Morten Christensen d227aa19b8 Leaving the original internal method intact 2013-11-07 17:56:12 +01:00
Sebastiaan Janssen d76336cd39 Merge pull request #194 from Attackmonkey/Hackathon-U4-3228
Fixes issue U4-3228, where dictionary item names are not trimmed.
2013-11-07 08:45:21 -08:00
yawka e0a10080b1 Add UI validation for regular expression property 2013-11-07 18:39:27 +02:00
yawka 807df434f6 Add validation for regular expression property 2013-11-07 18:39:02 +02:00
Sebastiaan Janssen 0dc3920309 Merge pull request #191 from dipeshhirani/U4-2756
Fixed the issue below: U4-2756
2013-11-07 08:38:44 -08:00
Sebastiaan Janssen 98d1aafb75 Merge pull request #187 from wpyz/6.2.0
Fixes issue with opening VS solution when only Visual Studio 2013 is installed (fixes U4-3445)
2013-11-07 08:36:40 -08:00
mattbrailsford d963917556 Added SortOrder to XML for document types (used by export)
Added ability for doctype importer to set the sort order if a sort order element is available
2013-11-07 16:30:23 +00:00
Tim Payne 347d41c841 Fixes issue U4-2760, and makes the installed packages list by name in alphabetical order to make it easier to see what's installed. 2013-11-07 16:06:16 +00:00
Tim Payne f16aa38fff Fixes issue U4-2757 where generic properties are not ordered correctly. 2013-11-07 15:51:58 +00:00
Sebastiaan Janssen 6a0d7ec8d6 Merge pull request #183 from mkariti/U4-1477
fix U4-1477
2013-11-07 07:49:27 -08:00
adang@thecogworks.co.uk 62a7e0acd0 Replaced HttpContext.Current.Cache with HttpRuntime.Cache 2013-11-07 15:44:55 +00:00
leekelleher 8e89d13142 Fixes: U4-2006 Domain.GetDomain(string DomainName) is case-sensitive 2013-11-07 15:41:34 +00:00
dipunm a5782a40af Missing languages in RTE insert link dialog.
Also included files in csproj file to ensure proper build.
2013-11-07 14:59:00 +00:00
dipeshhirani c6af319805 commented out the line that checked if the language is neutral. 2013-11-07 14:56:00 +00:00
leekelleher 516beedbbb Fixes: U4-3452 Update the MIT License URL (Packager) 2013-11-07 14:48:20 +00:00
mattbrailsford 7cd01fc50b Added ValidateRequest="false" on package installer page to allow user controls which postback html / code. 2013-11-07 14:35:44 +00:00
Simon Dingley e9d12ae0d8 Revert "Group jQueryTree script files"
This reverts commit baed01518c.
2013-11-07 14:23:53 +00:00
Tim Payne 02e167c1f6 Fixes issue U4-3063 where copying a document type uses the rename for the node alias, but not the title, resulting in two Doctypes with the same name, but different aliases, rather than different names AND aliases. 2013-11-07 14:20:47 +00:00
Simon Dingley baed01518c Group jQueryTree script files 2013-11-07 13:21:01 +00:00
Morten Christensen f9a86385b5 Rearranging the create schema extensions methods to provide a bit more flexibility for external usage. 2013-11-07 14:03:34 +01:00
Craig Cronin a0106ff811 Fixed as per issue comments, but also implemented for another 3 overloads 2013-11-07 12:50:26 +00:00
Simon Dingley e0da5a9cb2 Groups jQuery dependencies using the ClientDependency Group property 2013-11-07 12:45:35 +00:00
mkariti 451d5eb484 U4-415 2013-11-07 14:40:26 +02:00
Morten Christensen b8f7df1a96 Fixing the broken stylesheetrepository test and ignoring the StylesheetRepository in the RepositoryResolverTest for the time being as it takes two different UOWs as opposed to other repositories. 2013-11-07 13:33:49 +01:00
Tim Payne 425fd80e65 Fixes issue U4-3228, where dictionary item names are not trimmed. 2013-11-07 12:28:43 +00:00
Morten Christensen 04bb778dc1 Fix StylesheetRepositoryTest which broke as a result of PR #176 2013-11-07 12:52:25 +01:00
dipeshhirani 3f2be3342a Fixed the issue below:
The "Unpublish" button (under Properties tab) is bad translated to Italian.
The used word is "Non pubblicato". This phrase is mean "It is not published".
A best translation is "Non pubblicare" (unpublish).

Did not do any of the others as they are either already done or the requesters change seems incorrect/irrelevent
2013-11-07 11:42:08 +00:00
Morten Christensen 3ba50e7bae Merge pull request #176 from pynej/add-stylesheet-ids
Fix for missing Id's on FileService.GetStylesheets() call.  This is need...
2013-11-07 03:41:33 -08:00
Morten Christensen 7306ddef14 Merge pull request #182 from stocksr/6.2.0-petapoco-refactor
6.2.0 petapoco refactor - umbraco.cms.businesslogic.language.Item
2013-11-07 03:37:37 -08:00
Morten Christensen 17bb29eb66 Merge pull request #185 from saciervo/6.2.0
Use PetaPoco instead of SqlHelper
2013-11-07 03:35:49 -08:00
Morten Christensen 8bf3de738f Merge pull request #188 from stocksr/6.2.0-petapoco-refactor-umbraco.cms.businesslogic.language.Language
Refactoring umbraco.cms.businesslogic.language.Language class
2013-11-07 03:34:08 -08:00
Robert Stocks 2d37502a44 Refactoring umbraco.cms.businesslogic.language.Language class 2013-11-07 11:28:00 +00:00
Ryan Lewis d5c485205a Whitespace 2013-11-07 11:24:40 +00:00
Ryan Lewis 9533198365 Can open VS solution with only Visual Studio 2013 installed (fixes U4-3445) 2013-11-07 11:23:41 +00:00
Morten Christensen 66f20e3800 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-11-07 12:19:27 +01:00
Sandro Ciervo 9269a98806 Refactored Umbraco.Web.UI.Controls.InsertMacroSplitButton
- CreateChildControls()
- DoesMacroHaveParameters (Int32)
2013-11-07 12:15:03 +01:00
mkariti 7c97fddec5 fix U4-1477 2013-11-07 13:08:56 +02:00
Morten Christensen a567cf2a87 Minor update to the DefaultData so the used PetaPoco db object is consistent 2013-11-07 12:00:45 +01:00
Morten Christensen 1e319d667b Updating the remaining methods in the Notification class so it no longer uses the legacy SqlHelper. 2013-11-07 11:59:59 +01:00
Sebastiaan Janssen cc039e365d Merge pull request #181 from Attackmonkey/Tim-Payne-Hackathon-U4-2708
Fixes issue U4-2708
2013-11-07 02:55:03 -08:00
Morten Christensen f91ff5dc31 Special commit for a special Lars-Erik 2013-11-07 11:48:25 +01:00
Robert Stocks 9347a2edbb Refactoring umbraco.cms.businesslogic.language.Item class - Fix Update and Delete calls 2013-11-07 10:40:23 +00:00
yawka 1923b68594 Fix 2034, add check for whitespaces 2013-11-07 12:36:35 +02:00
Robert Stocks 64a73ef528 Refactoring umbraco.cms.businesslogic.language.Item class 2013-11-07 10:20:55 +00:00
Tim Payne 4ea04f5ffe Fixes issue U4-2708 2013-11-07 10:08:11 +00:00
Morten Christensen 6b006e6fd7 Refactoring GetUserNotifications method in the Notification class 2013-11-07 11:00:19 +01:00
Shannon fc0654a80f Fixes: U4-2241 Native Multi-node tree picker in Member Types: Saving clears selected items 2013-11-07 12:02:41 +11:00
Sebastiaan Janssen 4717faaf1b Merge pull request #180 from Jeavon/U4-3432
Fix for U4-3432Rollback Dialog - CreateDate/Creator formatting tweaks
2013-11-06 09:48:08 -08:00
Jeavon Leopold e7d587f776 Fix for U4-3432Rollback Dialog - CreateDate/Creator formatting tweaks required 2013-11-06 17:19:18 +00:00
Stephan dca0c85db5 Merge remote-tracking branch 'origin/6.2.0' into 6.2.0 2013-11-04 12:54:07 +01:00
Shannon 5006115b2d Fixes object extensions and tests
Conflicts:
	src/Umbraco.Core/ObjectExtensions.cs
	src/Umbraco.Tests/ObjectExtensionsTests.cs
2013-11-02 15:20:04 +11:00
Stephan 058cec7551 Cache AspNet hosting permission level 2013-11-01 16:57:31 +01:00
Stephan 2671709991 U4-2518 - issue with virtual dir named Umbraco 2013-11-01 09:53:50 +01:00
Shannon ac2d8633af Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-11-01 18:07:18 +11:00
Shannon 76bc312842 Fixes an issue with empty string conversions to date time - should fail 2013-11-01 18:06:58 +11:00
Stephan 767719357e U4-3279 - better exception message when failing to find a content type 2013-10-31 18:28:49 +01:00
Stephan 7b29bd67f3 Merge remote-tracking branch 'origin/6.2.0' into 6.2.0 2013-10-31 15:29:16 +01:00
Shannon dc4a0fec80 Merge branch '6.2.0' into 6.2.0-membershipprovider
Conflicts:
	src/Umbraco.Web/Umbraco.Web.csproj
2013-10-31 11:36:04 +11:00
Shannon 4c3d700c54 Changes the UserMembershipProvider to validate an already hashed/encrypted password and then validate a non hashed/encrypted attempt, this is to maintain compatibility with how v6 works, it's not ideal but needs to be there. Creates a settable property on the password changer to be able to dynamically hide the old password field if you are going to manually set the old password. Updates the EditUser to hide the old password field and pass in the alraedy encrypted pword to validate against like it used to be. 2013-10-31 11:35:12 +11:00
Jeremy Pyne 6451f6ad68 Fix sql errors in prev change. 2013-10-29 10:00:25 -04:00
Jeremy Pyne 7cd6882f28 Removed dependence in Stylesheet repository on Entity Service. 2013-10-29 09:24:05 -04:00
Jeremy Pyne dc336728b5 Fix for missing Id's on FileService.GetStylesheets() call. This is needed as sytlesheets can only be loaded in the editor via their Id so listing stylesheets needs to list there Id as well for custom plugins to render the build in editor. 2013-10-28 14:32:18 -04:00
Shannon 49d5791825 Adds DescendantsOrSelf extensions on ienumerable to published content extensions 2013-10-28 12:35:50 +11:00
Shannon 6cfb864055 Fixes DataTypeDefinitionRepository to properly delete a data type including it's pre-values 2013-10-28 11:23:09 +11:00
Stephan 89c5d5d613 PublishedContent - get published properties to report the CLR type of the value 2013-10-28 01:09:34 +01:00
Stephan 73b7729b82 Standalone - fix so it works again 2013-10-28 01:07:29 +01:00
Stephan c66d49dbfe PublishedContent - remove useles code in model factory 2013-10-28 01:07:17 +01:00
Shannon 9a3b70149c Fixes packaging service to export data type's property with the ID as the property editor ID 2013-10-28 11:00:14 +11:00
Shandem 98cc1c63ce Merge pull request #173 from pynej/trees-config-action
Trees config action
2013-10-27 16:00:00 -07:00
Stephan 128a08f169 Web.Mvc - Refactor UmbracoViewPage, UmbracoTemplatePage, support strongly-typed content
Conflicts:
	src/Umbraco.Web/Umbraco.Web.csproj
2013-10-25 13:21:29 +02:00
Stephan 4487e686d7 Core.TypeExtensions - add methods 2013-10-25 13:19:20 +02:00
Shannon ae32968efd Updates the legacy membership providers and WebSecurity/Password changer to stay backwards compatible with their previous settings whilst still keeping all of the provider fixes. 2013-10-23 10:19:43 +11:00
Shannon c1778918b5 Fixes more membership provider woes. 2013-10-22 17:37:03 +11:00
Shannon 680a4b9570 Fixes a lot -
U4-3208 Ensure all membership provider properties exist on the default Member type shipped with Umbraco
U4-3158 user back office password policies doesn't adhere to membership provider rules
and even more fixes to the membership provider like actually integrating the last locked out date and last pword change date. Fixes member creation to actually use the membership provider - this means that the password is created properly based on the provider config. Fixes the provider to have default fields specified so people don't actually have to specify in config.
2013-10-22 13:41:04 +11:00
Jeremy Pyne ba6ba15732 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.1.3-clean 2013-10-18 11:37:28 -04:00
Jeremy Pyne 291f526368 Fix to properly read actions from trees.config. 2013-10-18 11:37:06 -04:00
Shannon ff61812e65 Merge remote-tracking branch 'origin/6.2.0' into 6.2.0-membershipprovider 2013-10-18 16:14:24 +11:00
Shannon d20ea58467 Fixes: U4-3193 Partial view cache needs to invalidate based on cache refreshers 2013-10-18 16:13:41 +11:00
Shandem c4f3dae317 Merge pull request #172 from IDisposable/6.2.0
Reduce Exceptions thrown during type conversions.
2013-10-17 18:07:52 -07:00
Marc Brooks 4d5b330567 Reduce Exceptions thrown during type conversions.
There are tons of places where null, blank or empty strings are being
converted to primative types (like int,, long, etc) or other ValueTypes
(like Guid, DateTime, etc.). When this is attempted, Exceptions are
thrown (and caught/swallowed) to allow for value defaulting. Since this
happens all the time in normal operation, tons of Exceptions are being
thrown. By switching to the TryParse methods available on all primative
types and the interesting ValueTypes, we can greatly speed the
processing of content data.
2013-10-17 19:12:08 -05:00
Shannon a87e699f8d Updates the web.config template to allow password reset 2013-10-18 09:54:34 +11:00
Shannon 40287fd427 adds some tests for membership provider base 2013-10-18 09:33:10 +11:00
Shannon 5d5f7a4516 Updated edit member with correct usage of password changer. 2013-10-18 08:52:46 +11:00
Shannon 61ef83c748 Gets the password changer working - on the edit user page. reset/change password wth validation 2013-10-18 00:37:51 +11:00
Shannon f82329b371 More updates the password changer and edit user 2013-10-17 22:52:37 +11:00
Shannon 0fee434ac2 Working on the password changer control to present the correct inputs based on the membership provider given.... nearly there. 2013-10-17 22:40:38 +11:00
Shannon 3aab41b1e4 Fixes lots of membership provider stuff
U4-3057 MembershipPasswordFormat problem at EncodePassword method in UmbracoMembershipProvider class
U4-3176 UsersMembershipProvider.CreateUser does not encrypt/hash the password
U4-3173 UserMembershipProvider.ChangePassword does not work

- Now we need to update the UI for the member

Signed-off-by: Shannon <sdeminick@gmail.com>
2013-10-17 20:20:43 +11:00
Jan Skovgaard 3abd4df8bd Enabled lists plugin in tinymce by default
Fixes http://issues.umbraco.org/issue/U4-3023
2013-10-16 16:01:17 +02:00
Jan Skovgaard ea239e6122 Missing languages in RTE insert link dialogue
Fixes this issue: http://issues.umbraco.org/issue/U4-2551
2013-10-16 15:53:56 +02:00
Lars-Erik Aabech 3fe99a402e Should make the PublishedContentExtensionTests green when ran together with everything else in TeamCity 2013-10-16 15:45:39 +02:00
Sebastiaan Janssen f9ad06be29 Something odd going on with the new tests being affected by tests that ran before them, no time to fix. Runs fine independently. 2013-10-16 14:19:24 +02:00
Steve Temple e738738e54 Only check actions if more than 1 route matches & ignore case when comparing controller names 2013-10-16 12:02:20 +01:00
Sebastiaan Janssen 699c651daa Merge pull request #169 from stocksr/U4-3033-take2
Really Fix U4-3033 - inserting extra blank line at end of CSS
2013-10-16 04:00:26 -07:00
Robert Stocks 79299175c1 Really Fix U4-3033 - inserting extra blank line at end of CSS 2013-10-16 11:49:02 +01:00
Sebastiaan Janssen 14e3976e88 Merge pull request #142 from lars-erik/6.2.0-recursive_isofdocumenttype
Recursive PublishedContentExtensions IsDocumentType
2013-10-16 02:55:09 -07:00
Sebastiaan Janssen 76c86daf24 Update da.xml 2013-10-16 11:50:12 +02:00
Lars-Erik Aabech a1ef40e4be Split the recursive IsDocumentType into an overload for "real" backwards compatibility.
Changed string comparison to use InvariantEquals. (guessing it doesn't _really_ break backw. compat?)
Added XML docs.
2013-10-16 11:38:58 +02:00
Sebastiaan Janssen e4a0904de6 Merge pull request #167 from lars-erik/change-doctype-defaultnone
Change doctype - default suggestion none when no matching alias.
2013-10-16 01:09:02 -07:00
Steve Temple f502912225 Updated to use invariant culture 2013-10-15 23:51:39 +01:00
Steve Temple c8a26bf6a3 Merge branch '6.1.6-multiple-action-route-issue' of github.com:stevetemple/Umbraco-CMS into 6.1.6-multiple-action-route-issue 2013-10-15 17:18:46 +01:00
Steve Temple e06e50c4fc Tidied up tabs to match Umbraco standard and nicer string comparison 2013-10-15 17:18:12 +01:00
Steve Temple 4236473b14 Tidied up tabs to match Umbraco standard 2013-10-15 17:15:53 +01:00
Steve Temple 3285e161c0 Fix issue with error http://our.umbraco.org/forum/developers/api-questions/41483-Umbraco-6-MVC-RenderRouteHandlerHandlePostedValues-Sequence-contains-more-than-one-matching-element when multiple routes share the same controller 2013-10-15 17:09:51 +01:00
Lars-Erik Aabech 607a52883a Change doctype - default suggestion none when no matching alias. 2013-10-15 13:21:30 +02:00
Sebastiaan Janssen 4651dfc763 Merge pull request #166 from stocksr/U4-3033
Fix U4-3033 - inserting extra blank line at end of CSS
2013-10-15 01:13:37 -07:00
Robert Stocks da74c0a163 Fix U4-3033 - inserting extra blank line at end of CSS 2013-10-15 09:09:03 +01:00
Shannon fbb7f18f23 fixes publish status when publishing child that doesn't have a parent published. 2013-10-15 14:12:10 +11:00
Shannon af43b35d17 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-10-14 10:46:06 +11:00
Shannon 72ea43758d Fixes - U4-3119 Non-Admin Users Cannot Create or Edit Users regardless of permission settings - 6.1.6 2013-10-14 10:45:51 +11:00
Stephan ee5af4998f Fix bug after merge 2013-10-11 12:30:17 +02:00
Stephan 565a020acf Merge remote-tracking branch 'origin/6.2.0' into 6.2.0-pubcontent 2013-10-11 11:14:36 +02:00
Stephan 15bbe1b829 PublishedContentModel - keep it internal for now 2013-10-11 10:10:19 +02:00
Shannon c459a893a5 adds new db indexes 2013-10-11 18:45: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
wtct b5c3fb1728 FFROM to FROM 2013-10-11 09:16:18 +02: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
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
wtct e1caf3a470 U4-3091 2013-10-10 14:45:18 +02: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 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 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 a3bca42117 updates UmbracoMembershipMember 2013-10-10 14:10:28 +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
wtct b6cf182341 Affect the order of domains 2013-10-09 17:52:05 +02:00
Shannon 27e6e9b91c removes duplicate declaration 2013-10-09 13:52:44 +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
Stephan 17c055472d Merge remote-tracking branch 'origin/6.2.0' into 6.2.0-pubcontent 2013-10-08 09:44:37 +02: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
Sebastiaan Janssen 12b7a9d874 Argh, didn't save csproj file before committing. 2013-10-07 13:20:34 +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
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
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 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
mortenbock c74cdb28d6 Testing the wrapping of view engines 2013-10-03 11:01:37 +02: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
Shandem a806f40093 Merge pull request #146 from mortenbock/6.2.0
Custom ProfilingViewEngine
2013-10-02 15:53:58 -07:00
mortenbock 24020cfea3 Make sure the profilingengine doesn't wrap itself 2013-10-02 18:30:59 +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 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
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
Floris Robbemont 9ddee615cc U4-3007 RouteDefinition should not store instance of controller 2013-10-01 14:09:38 +02: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
Marc Brooks b200cb463e Make CacheHelperExtensions public so we can call CachedPartialView and ClearPartialViewCache
In order to allow extensions to the logic and usage of the CachedPartial HtmlHelper, expose CachedPartialView and ClearPartialViewCache by making the wrapping static class public.
2013-09-30 18:28:45 -05:00
Marc Brooks cdf5ddf539 Added cacheKeyBuilder optional argument to allow the key used for caching to be contextual.
when building cached partials that work with many different instances of the same  partial view (e.g. using the same partial more than once on a page with different ViewDataDictionary or different model), it is necessary to either name each instance differently (ugh), or not cache.

By adding an optional argument to the CachedPartial Html helper method, we can vary the cache-key depending on the context of insertion. For maximum flexibility, pass the model and the viewData to the function so it can use that data to format a cacheKey suffix.

A typical use would be something like:

@Html.CachedPartial(
"EventListings"
, FeedRepository.getFeed(new CalendarEventsModel
  {
     StartingDate = DateTime.UtcNow.Date
     , Count = 10
  })
, 0
, contextualKeyBuilder: (model, viewData) =>
  {
     return (model as CalendarEventsModel).StartingDate.ToString();
  }
)
2013-09-30 18:23:56 -05: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
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
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 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 e0878fdd9f fixes unit test 2013-09-30 14:48:05 +10:00
Shannon c9aac96c1a Fixes EditUser.aspx 2013-09-30 14:15:39 +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 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
Lars-Erik Aabech b6777e4635 Recursive PublishedContentExtensions IsDocumentType
Optional recursive parameter defaulted to false for backwards compatibility and no performance hit.
Settings recursive = true fetches content type for content and checks ancestor content types for the same alias.
2013-09-27 13:12:16 +02: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
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 725b938de1 PublishedContent - revert to using property.Value vs .ObjectValue 2013-09-25 13:17:21 +02:00
Stephan 2ef4b77bd9 Fix broken tests 2013-09-24 11:28:54 +02:00
Stephan fae9fc6e2d Merge branch '6.2.0' into 6.2.0-pubcontent 2013-09-24 10:51:44 +02:00
Shannon 099c1ff2ea Fixes: U4-2914 Examine doesn't index newly created items 2013-09-24 10:39:47 +10:00
Jeremy Pyne 5716edcf80 Added node type to quick search(as a toooltip).
Added node type to search results.
2013-09-23 16:19:05 -04: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
Morten Christensen ebf60071ab Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-09-18 11:51:13 +02:00
Morten Christensen f4b8d9bd6e Fixing broken Publishing test after the service and repository tests are probably setup. 2013-09-18 11:50:52 +02:00
Morten Christensen 5cf07ba6be Refactoring how DeleteVersion and DeleteVersions is used in the Content- and MediaRepository, so we ensure that the latest version is never deleted. Worse case would have been an incomplete content node, which we want to avoid. So better to have a fail safe way of deleting versions, and use the regular Delete method for deleting the latest version. 2013-09-18 11:49:36 +02:00
Stephan cb4eef54a4 Core.Cache - fix issue introduced in 761354d 2013-09-18 11:47:37 +02:00
Stephan 7a541ba489 Merge branch '6.2.0' into 6.2.0-pubcontent 2013-09-18 11:34:00 +02:00
Stephan d2647ea607 Core.Cache - fix issue introduced in 761354d 2013-09-18 11:33:42 +02:00
Stephan a785cd1569 Merge branch '6.2.0' into 6.2.0-pubcontent 2013-09-18 10:56:07 +02:00
Stephan d1f36346de Core.Cache - fix bug in StaticCacheProvider 2013-09-18 10:55:20 +02:00
Stephan 761354dbf5 Core.Cache - add new method to remove items from cache 2013-09-18 10:55:10 +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
Morten Christensen dc1a67bfa2 Fixes U4-2822 Datepicker throws "Specified cast is not valid" when saving through API 2013-09-18 10:06:08 +02:00
Shannon 95df28bf64 Fixes issue with runtime cache provider when retrieving all items of a certain type, we were sending back an array of nulls if the cache was expired. 2013-09-18 17:44:25 +10:00
Shannon a027c3cb22 Found out if we don't do ToArray here and if we were caching we'd end up with null values in the cache, do to yield return i think. 2013-09-18 16:08:15 +10:00
Shannon f1c0aa2439 adds a comment 2013-09-18 15:21:35 +10:00
Shannon c8fa881bc5 Ensures all service tests do not use any caching in their underlying repos. This change has been made to the base database test classes so any repo/service access done for inheritors also ensure that no cache is used for tests. 2013-09-18 12:54:06 +10:00
Shannon b17db9f143 Fixed last failing unit test with repo's 2013-09-18 12:42:18 +10:00
Shannon 23b7e94ce3 Fixes pretty big issue with MediaType's not implementing the same IsDirty property check rules as ContentType when they should have shared the same rules. After removing caching on the unit tests, this bug became known. 2013-09-18 12:36:38 +10:00
Shannon 8fe7c0da9e Changed all repository tests to ensure they are not testing with cache enabled... now to fix the problems :( 2013-09-18 11:40:40 +10: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
Shannon 5b943ca866 fixed couple tests 2013-09-17 11:53:57 +10:00
Shannon abe3efa9a1 Replaces Rhino mocks with Moq... so much nicer/easier. 2013-09-17 11:35:08 +10: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
Sebastiaan Janssen 9d243c6c46 Merge pull request #139 from greystate/pedantic-casing
Minor corrections to language files
2013-09-15 04:24:44 -07:00
Sebastiaan Janssen 8f8da5a7ec Merge pull request #138 from kalletoxic/6.2.0
Swedish languagefile
2013-09-13 03:27:14 -07:00
Kalle Ekstrand 7e1d8a6108 Swedish languagefile
This is a fully translated languagefile fpr the swedish language.
2013-09-13 12:10:16 +02:00
Mads Krohn 0fe33c120b Removing unwanted ToList() 2013-09-13 10:42:08 +02:00
Mads Krohn 10ea234dbf Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-09-13 10:29:12 +02:00
Mads Krohn 31f146fc6f Updates to the media trashed state handling
Tweaked the logic for determining when a media item is trashed or not.
Added unit tests. Removed unnecessary comments.
2013-09-13 10:29:03 +02:00
Stephan 67a632aa43 Merge branch '6.2.0' into zb-cleanup 2013-09-12 11:13:07 +02:00
Shannon dcd5decd3a Fixes up the events in the new MacroRendering event stuff 2013-09-12 14:55:29 +10:00
Shandem b6d4415f5c Merge pull request #131 from neehouse/6.2.0
Removing file location restriction from PartialViewMacro
2013-09-11 21:47:51 -07:00
Shannon 24471c32f9 Improved search with "and", partial match U4-2509
- added partial matching on each word.
- fixed bug so 'all' words match rather than 'any' words.
2013-09-12 14:12:33 +10:00
Mads Krohn 0af73b0290 Fixed U4-2842 Umb 6.1.5 - moving a media item from recycle bin / trash 2013-09-12 00:14:44 +02:00
Chriztian Steinmeier b22fd4c5b1 Minor typos 2013-09-11 21:36:45 +02:00
Chriztian Steinmeier e977a8c656 Fix spelling of "publisere" => "publicere" 2013-09-11 21:36:03 +02:00
Chriztian Steinmeier af6eb2724d Casing XSLT (zh) 2013-09-11 21:22:00 +02:00
Chriztian Steinmeier 237ee71177 Casing XSLT (ru) 2013-09-11 21:21:44 +02:00
Chriztian Steinmeier d5604ea427 Casing XSLT (pt) 2013-09-11 21:21:38 +02:00
Chriztian Steinmeier 16f8c61f28 Casing XSLT (pl) 2013-09-11 21:21:31 +02:00
Chriztian Steinmeier f066473f14 Casing XSLT (nl) 2013-09-11 21:21:24 +02:00
Chriztian Steinmeier 1a1641d300 Casing XSLT (ko) 2013-09-11 21:21:15 +02:00
Chriztian Steinmeier 3d46cd1186 Casing XSLT (it) 2013-09-11 21:21:08 +02:00
Chriztian Steinmeier 1d200b6f2f Casing XSLT (fr) 2013-09-11 21:21:03 +02:00
Chriztian Steinmeier 86f0c7c7c9 Casing XSLT (he) 2013-09-11 21:20:55 +02:00
Chriztian Steinmeier 72e1b5a0c6 Casing XSLT (es) 2013-09-11 21:20:36 +02:00
Chriztian Steinmeier 94a78aec4b Correct XSLT casing for da, en & en-us 2013-09-11 21:19:40 +02:00
Stephan f53a23553b Core.Attempt - replace calls to obsolete ctor 2013-09-11 11:06:14 +02:00
Stephan 42c432caa0 Merge branch '6.2.0' into zb-cleanup 2013-09-11 10:39:40 +02:00
Morten Christensen e69b043cfa Oops, double column is no good syntax... 2013-09-11 10:24:05 +02:00
Morten Christensen 812d5c1391 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-09-11 10:17:08 +02:00
Morten Christensen 8d510fd512 Committing some POC code in the test project for strongly typed models/queries 2013-09-11 10:16:49 +02:00
Morten Christensen c5c44cec37 Correcting syntax output for AlterColumnExpression, so Shannon's migrations will work 2013-09-11 10:15:31 +02:00
Stephan 82f81d1f4f Core.Attempt - backport and refactor Attempt.Outcome from v7 2013-09-11 10:03:17 +02:00
Stephan 32e3048717 Core.Attempt - refactor Succ() into Succeed() 2013-09-11 09:30:00 +02:00
Shannon 90abe8c25f Fixes: U4-2823 RenderRouteHandler.GetUmbracoRouteDefinition() fails to store the route definition when an incidental alias-controller match is made 2013-09-11 12:15:29 +10:00
Shannon 9f1d212375 Implements: U4-2824 Type Converter for string type with unit test 2013-09-11 11:57:15 +10:00
Stephan 9ca048f0ad Core.Attempt - maintain backward compatibility 2013-09-10 17:56:49 +02:00
Stephan 85ab96f71a Core.Attempt - refactor and cleanup 2013-09-10 17:56:47 +02:00
Stephan 1ba8ad5fbb Comments - UmbracoModule 2013-09-10 17:56:46 +02:00
Stephan 433e141761 Comments - misc 2013-09-10 17:56:44 +02:00
Stephan 9fa5821f07 Comments - Web.Standalone 2013-09-10 17:56:43 +02:00
Stephan 447b3227a9 Web.Routing - remove duplicate code 2013-09-10 17:56:41 +02:00
Stephan ddfd9eeb18 Core.UriExtensions - refactor + issue with IsClientSideRequest 2013-09-10 17:56:39 +02:00
Stephan 6e0fa9f945 Core.Configuration - support missing notDynamicXmlDocumentElements 2013-09-10 17:56:38 +02:00
Stephan 4d726167f6 Core.XmlHelper - refactor 2013-09-10 17:56:36 +02:00
neehouse 1781528390 Removing Whitespace 2013-09-10 09:36:09 -04:00
neehouse c0214ac4ec Modified the MacroRendering event as requested. Removed the unnecessary check for the file path from the Partial View Macro as it would not be hit anyhow since the macro engine is determined using the same rule. U4-2644 & U4-2643 2013-09-10 09:34:19 -04:00
Shannon b2deb3def3 Fixes: U4-2815 The code to determine the macro type is currently case sensitive 2013-09-10 11:15:25 +10:00
neehouse 998e222881 Adding event to RenderMacro methods to allow for manipulation of the MacroModel. 2013-09-09 14:00:08 -04:00
Sebastiaan Janssen 58ba7d2d6d Fixes U4-502 TextString/TextBox multiple don't accept polish Ś character 2013-09-08 21:29:20 +02:00
Sebastiaan Janssen edd9aa80ae Fixes U4-489 Installer, link to folder permission video broken 2013-09-08 21:18:00 +02:00
Sebastiaan Janssen 7ddb77db66 Fixed U4-576 Umb 4.7.x - Dashboards 2013-09-08 21:06:22 +02:00
Sebastiaan Janssen b25e015890 Merge branch '6.2.0' of github.com:umbraco/Umbraco-CMS into 6.2.0 2013-09-08 19:42:51 +02:00
Sebastiaan Janssen 686250c586 Fixed U4-608 Empty tinymce config throws null ref exception 2013-09-08 19:42:34 +02:00
Stephan c5197dbe17 U4-2807 - better exception message on bogus domain 2013-09-07 10:25:39 +02:00
neehouse d821401ea2 Removing file location restriction from PartialViewMacro to allow custom paths. 2013-09-06 15:34:19 -04:00
Stephan 39316a345f Tests - stop deleting dummy.txt files 2013-09-06 20:24:22 +02:00
Sebastiaan Janssen 349dc9a228 Merge branch '6.2.0' of github.com:umbraco/Umbraco-CMS into 6.2.0 2013-09-06 16:20:16 +02:00
Sebastiaan Janssen 303c1e16b8 Change document type did unnecessary checks on root node which resulted in YSOD 2013-09-06 16:17:08 +02:00
Shannon c2b1ed205b Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-09-06 11:40:56 +10:00
Shannon fee02af4eb Completes: U4-1639 Add support to generate GET urls to SurfaceController actions 2013-09-06 11:40:37 +10:00
dprothero 6675bac1dc Fix #U4-2796 - fixed copy/paste error (does not affect functionality) 2013-09-05 15:23:25 -07:00
dprothero 0d49a59cfe Fix #U4-2796 Possible to have duplicate Login Name (Member.LoginName) for Umbraco Members 2013-09-05 15:15:40 -07:00
leekelleher 4770e903fb Minor corrected to uQuery doco/comments. 2013-09-05 18:22:48 +01:00
Stefan Kip baa22301e9 Added Exception which tells you which datatype is unable to load 2013-09-05 11:31:06 +02:00
Morten Christensen e080965468 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-09-05 11:28:45 +02:00
Morten Christensen 0c05836537 Fixes U4-2791 Error creating node containing @ v6.1.4.
Adding unit test which covers both U4-2791 and U4-2607
2013-09-05 10:44:28 +02:00
Shannon c269f55074 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-09-05 14:01:48 +10:00
Shannon 177486418d Implements: U4-1639 Add support to generate GET urls to SurfaceController actions 2013-09-05 14:01:28 +10:00
Morten Christensen 3393b6b0da Adding comments to the MemberService methods 2013-09-04 16:35:54 +02:00
Morten Christensen 33bba57047 Implementing addtional methods in the MemberService 2013-09-04 16:30:51 +02:00
Morten Christensen 269f573b82 Refactoring the GetById method in the MemberService. 2013-09-04 16:00:38 +02:00
Morten Christensen 2ec367fd59 Removing the SecurityHelper and moving the 3 methods into the Provider as private classes, as they aren't used anywhere else.
The SecUtility will be removed along with the legacy MembershipProvider when cleanup is possible.
2013-09-04 15:44:29 +02:00
Morten Christensen 72dcb32ac2 Refactoring the TypedModelBase and UmbracoTempaltePage for the TypedModel POC 2013-09-04 15:42:25 +02:00
Morten Christensen 1f68cad45b Refactoring MemberService and MembersMembershipProvider from Darrens pull request to fit the changes made the past week.
SecurityHelper is moved to the Umbraco.Web.Security namespace.
MembershipExtensions are changed to the new models
2013-09-04 15:42:01 +02:00
Morten Christensen 8ffbad4b49 Merge pull request #118 from darrenferguson/6.2.0
Adding new Memership provider implementation
2013-09-04 06:14:40 -07:00
Morten Christensen 24091991fa Updating MemberRepository test fixture. All tests ignored while using local db for testing. 2013-09-04 14:47:42 +02:00
Morten Christensen d65e94f519 Adding LocalizationService test fixture class 2013-09-04 14:43:48 +02:00
Morten Christensen 966416c0a5 Updating classes for small TypedModel POC 2013-09-04 11:30:21 +02:00
Morten Christensen 09de4a3666 Adding LocalizationService to ctor 2013-09-04 11:30:00 +02:00
Morten Christensen f2f1d265ec Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-09-03 17:15:03 +02:00
Morten Christensen 642c6c1afe Implementing a POC and tests for a simple TypedModel base class 2013-09-03 17:03:35 +02:00
Morten Christensen c5945789f0 Refactoring the MemberRepository to use the new Member class 2013-09-03 17:02:15 +02:00
Morten Christensen 6742bf4708 Removing the old Member, MemberType and MemberGroup classes from the Model.Membership namespace 2013-09-03 17:01:34 +02:00
Sebastiaan Janssen 5e83023ce5 Merge pull request #126 from Jeavon/6.2.0
U4-2783 url attribute in installedPackages.config is not populated when ...
2013-09-03 05:55:51 -07:00
Jeavon Leopold 05039fdd7c U4-2783 url attribute in installedPackages.config is not populated when a package is installed 2013-09-03 13:32:10 +01:00
Sebastiaan Janssen 21954f7bc6 Merge branch '6.2.0' of github.com:umbraco/Umbraco-CMS into 6.2.0 2013-09-03 10:31:17 +02:00
Sebastiaan Janssen 25d2b56ed7 U4-2776 Default Content For A Razor Layout Section 2013-09-03 10:31:00 +02:00
Shannon eeeb99b3b5 Fixes U4-2738 Collection Disposal issue when deploying 6.1.4 on Windows Server 2008 (Random, environment specific) 2013-09-03 17:19:31 +10:00
Morten Christensen 008d413302 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0
Conflicts:
	src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs
	src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs
	src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs
	src/Umbraco.Tests/Services/ContentServiceTests.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/moveOrCopy.aspx.cs
2013-09-02 15:55:05 +02:00
Morten Christensen 186d5157ec Implementing the read only side of the MemberType/MemberTypeRepository.
PropertyTypes and PropertyGroups are loaded as part of the MemberType in one go.
MemberTypeRepository uses the same approach as the ContentTypeRepository and MediaTypeRepository for saving/updating.
Refactoring how the 9-PropertyType convention is handled.
2013-09-02 15:53:09 +02:00
Sebastiaan Janssen 35c7b224bd Fix merge issue 2013-09-02 12:49:01 +02:00
Sebastiaan Janssen 437408464f Merge branch '6.1.5' into 6.2.0
Conflicts:
	.gitignore
	build/Build.bat
	src/Umbraco.Core/Configuration/UmbracoVersion.cs
	src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
	src/Umbraco.Web/Umbraco.Web.csproj
	src/Umbraco.Web/umbraco.presentation/umbraco/create/PartialViewTasks.cs
2013-09-02 12:29:47 +02:00
Morten Christensen 969dece8fc Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-09-02 09:53:42 +02:00
Sebastiaan Janssen a535a4c96f Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-09-01 17:21:32 +02:00
Sebastiaan Janssen c3ef39661b Fix MySQL install failing on UmbracoServer table 2013-09-01 17:21:19 +02:00
Sebastiaan Janssen e9b9fb15c1 Can't install starterkits message was always showing, even if install folder was present 2013-09-01 16:47:28 +02:00
Sebastiaan Janssen 3d4b54064f I love managing files in csproj files.. NOT. 2013-09-01 15:32:55 +02:00
Sebastiaan Janssen 14303fab0c File move didn't make it into the csproj file previously, leading to build errors. Fixed!
Also changed default PartialView template and added another Empty one
2013-09-01 15:05:17 +02:00
Sebastiaan Janssen 262ef8d305 Merge pull request #115 from stocksr/6.2.0
U4-516 - Fix DatePicker with time default value
2013-09-01 05:34:18 -07:00
Sebastiaan Janssen 6e6ac8a4d5 Merge pull request #124 from AndyButland/wip-u4-2759
U4-2759 - member authorise attribute was not restricting for group
2013-09-01 05:22:51 -07:00
AndyButland a262f0b342 Fixed bug where member authorise attribute was not restricting for groups 2013-08-31 22:52:54 +01:00
Morten Christensen 20b4975cfb Creating a new Member/IMember and MemberType/IMemberType class under the Umbraco.Core.Model namespace in order to move away from the weird structure that we initially ported over.
Refactoring the MemberTypeRepository to use the new MemberType class.
Starting the implementation of ReadOnly DTOs for MemberType.
Starting the implementation of the factory for the MemberTypeReadOnlyDto.
2013-08-31 19:13:36 +02:00
Morten Christensen 757283a3ff Making explicit references to the legacy member class to avoid ambiguous references to the new member classes 2013-08-31 19:09:29 +02:00
Morten Christensen ea76c42c7b Updating Resolves_Assigned_Mappers test to reflect current number of mappers 2013-08-31 18:02:10 +02:00
Morten Christensen 0196afa12a Correcting the update of the cmsContentVersion table so the UpdateDate is updated properly 2013-08-30 17:24:42 +02:00
Morten Christensen 5d5c25f0e4 Implemented new IMemberType, MemberTypeFactory, MemberFactory and MemberTypeMapper.
Started implementation of MemberTypeRepository.
2013-08-30 17:24:06 +02:00
Morten Christensen 09c9fb4e8f Fixes U4-2731 Document.BeforeMove + Document.AfterMove Doesn't get fired.
Using the legacy Document and Media classes for the .Move and .Copy calls as they already use the new services under the hood, so shouldn't make any noticeable difference except that the legacy events will also work.
2013-08-30 10:52:58 +02:00
Morten Christensen d44318f589 Fixes U4-2752 ContentService.DeleteVersion and DeleteVersions fail 2013-08-30 10:50:43 +02:00
Morten Christensen 9112e2e626 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-08-30 09:43:11 +02:00
Shannon 9b56c7eab6 Fixes U4-2300 6.1.0: Changing a template's parent causes tree to collapse 2013-08-30 14:15:51 +10:00
Shannon f332e6530a Ensures the whole ancestry of view data is merged in with unit tests. 2013-08-30 12:50:39 +10:00
Shannon c228c24ba5 Creted MergeParentContextViewData filter, this is by default applied to SurfaceController's and the PartialViewMacroController. Now if you are rendering a partial view macro or a child action from a SurfaceController and are putting data into ViewData on a POST, you don't have to access the ViewData from the ParentViewContext. 2013-08-30 12:03:16 +10:00
Shannon 697aa03758 Fixes U4-1339 SurfaceController returning PartialView - cannot use ModelState - TempData merge correctly. 2013-08-30 11:34:02 +10:00
Stephan c62689450b Merge remote-tracking branch 'origin/6.2.0' into 6.2.0 2013-08-29 17:28:46 +02:00
Jeremy Pyne e65a71a05a Added code to pre-select the current node in content tree pickers based on the location of the document in the tree.
This is a HUGE time saver with an even moderately complex site hierarchy.
2013-08-29 11:14:51 -04:00
Jeremy Pyne 7a2a444579 Fix for select parent o move or copy in 6.1.3. 2013-08-29 11:14:35 -04:00
Jeremy Pyne e16ebecda4 Merge branch '6.1.3-clean' into select-parent-on-movecopy 2013-08-29 11:09:20 -04:00
Stephan 0ed4c1868b U4-2549 - fix it differently 2013-08-29 17:08:16 +02:00
Sebastiaan Janssen 2bdbd6c7d9 Updated controller, more flexible, moved UmbracoProperty to Umbraco.Web.Helpers 2013-08-29 16:12:50 +02:00
Sebastiaan Janssen 23517d0c36 Argh, starter kit is hardcoding a content type, so I have to register the new member type with a different Id 2013-08-29 16:10:23 +02:00
Sebastiaan Janssen 2238f81d83 Oops, accidentally killed creating a partial view from the backoffice as it's also using PartialViewTasks.cs (like when you create a partial view macro) 2013-08-29 16:09:23 +02:00
Morten Christensen 37ce5c7a22 Implementing subquery addon for PerformGetByQuery, which allows for better querying first level properties as well as the property collection on a member 2013-08-29 15:42:13 +02:00
Sebastiaan Janssen 4ef10c8afe Install a default member type during initial setup 2013-08-29 13:54:30 +02:00
Morten Christensen e5145f3eb0 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-08-29 12:51:43 +02:00
Shannon 244dcff8da Fixes: U4-1339 SurfaceController returning PartialView - cannot use ModelState ? 2013-08-29 14:51:30 +10:00
Shannon 2e747caa10 Fixes: U4-2727 PluginManager's TypeList can contain duplicates - updates the locks to be upgradeable read locks, changes over all lists/collecitons to be HashSet<T> this ensures no duplicates and also improves performance. 2013-08-29 13:33:01 +10:00
Shannon 93691f13df Fixes U4-2734 Don't set the cache references to null when disposing the UmbracoContext 2013-08-29 12:38:14 +10:00
Shannon 258d526435 Merge branch 'U4-2711-Fix-imagecropper-ToXMl' of https://github.com/stocksr/Umbraco-CMS into stocksr-U4-2711-Fix-imagecropper-ToXMl
Conflicts:
	src/umbraco.editorControls/imagecropper/DataTypeData.cs
2013-08-29 12:31:08 +10:00
Shannon 357dc6ec8e Fixes: U4-2711 DAMP throws unknown exception on image upload with image cropper 2013-08-29 12:27:49 +10:00
Shannon 232c81543a Fixes the rest of U4-2713 Property Editor Value Converters don't get applied to Umbraco.TypedMedia 2013-08-29 12:11:48 +10:00
Shannon 581f3a1893 Fixes build errors 2013-08-29 12:01:30 +10:00
Shannon 9fc3efd73a Fixes U4-2713 Property Editor Value Converters don't get applied to Umbraco.TypedMedia 2013-08-29 11:59:07 +10:00
Shannon 9445f008bc Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-08-29 10:09:09 +10:00
Shannon 36c281a19a updated ignore 2013-08-29 10:08:54 +10:00
Stephan 3fc4f36859 U4-2549 - fix issue with last chance content finder
Conflicts:
	src/Umbraco.Web/Umbraco.Web.csproj
2013-08-28 18:16:20 +02:00
Sebastiaan Janssen 02566589fe Added admin permission for change doctype action to the OOB installer 2013-08-28 17:52:44 +02:00
Sebastiaan Janssen 49637e62fe Updated, more robust versions of the Member template/snippets 2013-08-28 17:52:06 +02:00
Morten Christensen 136673fd23 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-08-28 17:27:43 +02:00
Morten Christensen c7351dfad7 Adding additional methods to the MemberRepository to support various types of lookups/queries, and experimenting with adding dummy properties to the model so a strongly typed query can be translated using mappers.
GetByQuery needs to be refactored so the selection is done in a subquery, so we don't loose properties in the result set
2013-08-28 17:27:29 +02:00
Morten Christensen 575abc6abf Implementing the mapper for Member. Refactoring the MemberProfile, IMember and IMembershipUser interfaces 2013-08-28 15:24:22 +02:00
Morten Christensen 6f63369e11 Updating the Member and MemberProfile class to include the standard UmbracoEntity properties.
Refactoring the sql query and the dtos to use the PropertyType as Primary and Property as secondary as a Property might be empty for a defined type.
Adding labels to the conventional Member PropertyType aliases.
2013-08-28 14:17:16 +02:00
Darren Ferguson 1995b25092 Adding new Memership provider implementation
Obsolete SecUtility class
Add Security Helper class
2013-08-28 12:48:04 +01:00
Sebastiaan Janssen f26d759c84 Moved controllers and models as per Shannon's suggestion
Added LoginStatus and updated Register
Updated to use CDF instead of <script> tags
2013-08-28 13:36:04 +02:00
Morten Christensen 3f0dc7f652 Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-08-28 09:38:40 +02:00
Sebastiaan Janssen 8274883fa5 Bump version number to 6.2.0 2013-08-28 09:09:21 +02:00
Sebastiaan Janssen 12b3d50717 Merge branch '6.2.0' of github.com:umbraco/Umbraco-CMS into 6.2.0 2013-08-27 19:29:43 +02:00
Sebastiaan Janssen 86276206d5 Add register member partial view macro template 2013-08-27 19:29:15 +02:00
Stephan da719377df U4-2691 - fix issue with alt template and internal redirects 2013-08-27 18:06:53 +02:00
Robert Stocks 614dc8f4d1 Fix U4-2711 add Null Check to ToXMl method
Fixes Object reference not set to an instance of an object. at
umbraco.editorControls.imagecropper.DataTypeData.ToXMl(XmlDocument data)
2013-08-27 16:10:04 +01:00
Morten Christensen a3f41af3ba Updating the sql query in the MemberRepository 2013-08-27 15:50:17 +02:00
Morten Christensen 342232f21e Updating the Member class and adding an UmbracoMember wrapper as a bridge between MembershipUser and Member 2013-08-27 15:49:46 +02:00
Morten Christensen c3c9c10060 Implementing a factory for readonly Member objects 2013-08-27 15:48:58 +02:00
Morten Christensen 89fbad447b Adding propertytype alias conventions for Member 2013-08-27 15:48:18 +02:00
Morten Christensen 0aa38728fc Updating the readonly dtos 2013-08-27 15:48:00 +02:00
Robert Stocks 23e4003af0 U4-516 - Fix DatePicker with time default value
Enables the standard jQuery date picker to parse the current value of
the field correctly, this prevents it from defaulting to Today and
overwriting the currently stored value.
2013-08-27 12:04:20 +01:00
Sebastiaan Janssen 53b6fb7b56 Add login template to partial view macros 2013-08-27 11:37:20 +02:00
Sebastiaan Janssen 6bbc2de43e Update failing unit test due to added action for changing the document type on a node 2013-08-27 09:37:00 +02:00
DougMac 0218e39664 Fixes: U4-2060 Spell Checker Broke After Google Update 2013-08-26 22:50:53 +01:00
Sebastiaan Janssen 91590c824f Merge branch '6.2.0' of github.com:umbraco/Umbraco-CMS into 6.2.0 2013-08-26 17:28:31 +02:00
Sebastiaan Janssen d17b2cf884 Added ability to have predefined templates for Partial View Macros 2013-08-26 17:28:15 +02:00
Morten Christensen aed017641d Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0 2013-08-26 17:01:05 +02:00
Morten Christensen 2b82e74b90 Adding test fixture for the MemberRepository 2013-08-26 17:00:12 +02:00
Morten Christensen 37d190c97d Implementing read-only DTOs for improved reading of Members from db.
Started implementation of Member, MemberType and MemberGroup repositories.
2013-08-26 16:59:41 +02:00
Morten Christensen f1818aae1b Updating the Profile and Member classes 2013-08-26 16:58:08 +02:00
Sebastiaan Janssen ee4312b7f2 U4-2464 Single user protection, password not changeable! 2013-08-26 13:56:22 +02:00
Sebastiaan Janssen 2345a5e133 U4-2477 Member editing - Indicate which box is active and which is inactive 2013-08-26 13:45:09 +02:00
Sebastiaan Janssen cbe8f15007 U4-2636 Allow at root property are outside of view in backoffice 2013-08-26 12:11:07 +02:00
Sebastiaan Janssen dd59038369 Fixes U4-2686 Error when trying to delete member group with ampersand in name. 2013-08-26 10:29:30 +02:00
Sebastiaan Janssen c9942d7ca5 Merge pull request #106 from pynej/code-mirror-search
Added plugin to all code area editors to suppressed normal browser Find ...
2013-08-25 08:37:08 -07:00
Sebastiaan Janssen ab8e6b8f33 Merge branch 'wip-dragdrop2' of https://github.com/AndyButland/Umbraco-CMS into AndyButland-wip-dragdrop2 2013-08-25 17:26:08 +02:00
Sebastiaan Janssen d21f10ec1e Db migration to allow admins to change the document type 2013-08-25 17:14:01 +02:00
Sebastiaan Janssen 76d0ffb797 Merge branch 'wip-changedoctypeui' of https://github.com/AndyButland/Umbraco-CMS into AndyButland-wip-changedoctypeui
Conflicts:
	.gitignore
	src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
	src/Umbraco.Web.UI/config/ClientDependency.config
	src/Umbraco.Web/Umbraco.Web.csproj
2013-08-25 15:50:07 +02:00
Sebastiaan Janssen 6437179a83 Merge pull request #112 from dampee/6.1.3
U4-2638 Developer/Packages/Install Starterkit give 500 server error
2013-08-25 05:36:49 -07:00
Sebastiaan Janssen cc45bbeca6 Fix unit tests that failed because UmbracoSettings.config was being cleaned up 2013-08-23 16:22:26 +02:00
Sebastiaan Janssen 8cd9266ea6 Updated obsolete msg after feedback here: https://github.com/umbraco/Umbraco-CMS/commit/2b532f72c34a33e2966b1fb5c7f068564e518c91#commitcomment-3899011 2013-08-23 14:17:40 +02:00
Sebastiaan Janssen ad44feb6dd Don't throw exception when node has no template and asking for GetTemplateAlias (return string.Empty instead) 2013-08-23 14:08:13 +02:00
Sebastiaan Janssen 16ed85ecc9 Merge branch '4.11.10' into 6.2.0
Conflicts:
	.gitignore
	build/Build.bat
	src/Umbraco.Core/Configuration/GlobalSettings.cs
2013-08-23 13:48:38 +02:00
Sebastiaan Janssen 9d45b10ee5 Merge pull request #104 from umbraco/6.0.7
6.0.7
2013-08-23 04:46:41 -07:00
Sebastiaan Janssen e9f8cf25b9 Merge branch '6.0.0-PetaPocoExtension' into 6.2.0
Conflicts:
	.hgignore
2013-08-23 13:42:26 +02:00
Sebastiaan Janssen 19a3b8809e Merge branch '4.11.9' into 6.2.0
Conflicts:
	.hgtags
2013-08-23 12:18:25 +02:00
Sebastiaan Janssen 96e40b8b4f Merge pull request #101 from umbraco/4.11.8
Closing branch 4.11.9 as that version number was used for the emergency ...
2013-08-23 03:17:46 -07:00
Sebastiaan Janssen 53aeb59eb4 Merge pull request #100 from umbraco/6.0.5
Closing branch 6.0.5 as that version number was used for the emergency s...
2013-08-23 03:17:29 -07:00
Sebastiaan Janssen befb42cd68 Merge pull request #99 from umbraco/4.11.7---cmsContentXml-fixes
Close 4.11.7 - cmsContentXml fixes branch
2013-08-23 03:17:06 -07:00
Sebastiaan Janssen 15bab05e18 Merge branch '6.2.0' of github.com:umbraco/Umbraco-CMS into 6.2.0 2013-08-23 12:15:37 +02:00
Sebastiaan Janssen 7d2e408363 Merge branch '4.11.5' into 6.2.0
Conflicts:
	.hgtags
2013-08-23 12:15:28 +02:00
Sebastiaan Janssen c1cc62543d Merge pull request #97 from umbraco/6.1.0-public
Close 6.1.0-public branch, merged.
2013-08-23 03:13:19 -07:00
Sebastiaan Janssen 6d61c93f62 Merge pull request #96 from umbraco/6.0.0-LegacyApi-Refactor
Close 6.0.0-LegacyApi-Refactor branch
2013-08-23 03:12:29 -07:00
Sebastiaan Janssen 38c8860e92 Merge pull request #95 from umbraco/6.0.0-Repository-Resolvers-refactor
Closing branch after having merged the changes to events to the main 6.0...
2013-08-23 03:12:08 -07:00
Sebastiaan Janssen 4719bfb4ad Merge pull request #94 from umbraco/4.10.1
Close 4.10.1 branch
2013-08-23 03:11:49 -07:00
Sebastiaan Janssen b5719ab103 Merge pull request #93 from umbraco/4.6.1
Closing branch
2013-08-23 03:10:24 -07:00
Sebastiaan Janssen c82573a697 Merge pull request #92 from umbraco/4.7.1
Closing branch
2013-08-23 03:10:03 -07:00
Sebastiaan Janssen 6448554343 Merge pull request #91 from umbraco/4.7.2
Closing branch
2013-08-23 03:09:40 -07:00
Sebastiaan Janssen c0b9e803d9 Merge pull request #90 from umbraco/4.8-apptreexml-wip
Closing branch
2013-08-23 03:08:55 -07:00
Sebastiaan Janssen ab06a22272 Merge pull request #89 from umbraco/4.8-tinymce-wip
Closing old branch
2013-08-23 03:08:31 -07:00
Sebastiaan Janssen eac56eba47 Merge pull request #88 from umbraco/4.8-solutioncleanup-wip
Close 4.8-solutioncleanup-wip branch
2013-08-23 03:07:25 -07:00
Sebastiaan Janssen 0e822bdc81 Merge pull request #87 from umbraco/4.6.0
Closing branch
2013-08-23 02:52:25 -07:00
Shannon ec4f6de631 Fixes: U4-2701 The media creation process needs to be optimized, there's far too much IO occuring 2013-08-23 13:41:16 +10:00
Shannon 3bb61294e9 Ensures all IDisposables are in a using clause for all processes involved with the media uploader, there were also a few streams not being closed or disposed either!
U4-2699 The media upload process doesn't dispose all resources
2013-08-23 11:46:55 +10:00
Shannon c477da95fd Ensures all IDisposables are in a using clause for all processes involved with the media uploader, there were also a few streams not being closed or disposed either! 2013-08-23 11:20:00 +10:00
dampee fb03de37ce U4-2638 Developer/Packages/Install Starterkit give 500 server error 2013-08-19 12:51:13 +02:00
DougMac 7e645f9a6a Fixes: U4-2060 Spell Checker Broke After Google Update
The Google spell check at https://www.google.com/tbproxy/spell no longer
works. This updates to a newer Google Api (again undocumented)
2013-08-17 10:50:26 +01:00
Jeremy Pyne f3e8359e36 Added plugin to all code area editors to suppressed normal browser Find function with internal code mirror functions. This is needed for search to work on long documents and also adds more advanced regex search and replace options including:
Ctrl-F / Cmd-F
Start searching
Ctrl-G / Cmd-G
Find next
Shift-Ctrl-G / Shift-Cmd-G
Find previous
Shift-Ctrl-F / Cmd-Option-F
Replace
Shift-Ctrl-R / Shift-Cmd-Option-F
Replace all

Demo: http://codemirror.net/demo/search.html
2013-08-07 16:08:40 -04:00
Sebastiaan Janssen 89622998e0 Merge pull request #34 from luckyrat/6.0.7
Fixes U4-2187 - Enable support for MySQL on Linux
2013-07-23 06:24:42 -07:00
AndyButland 2fd9efffa1 Styling of drop zone for draggable document type properties 2013-06-29 23:37:02 +02:00
AndyButland 91465c6aa2 Fixed issue with re-ordering on a single tab 2013-06-29 23:15:41 +02:00
AndyButland f4eb8c7517 Localised no properties message 2013-06-29 22:57:53 +02:00
AndyButland bd3616239f Fixed issue where dropped properties not saving when dropped on a tab inherited from a parent document type 2013-06-29 22:42:41 +02:00
AndyButland ef0744a849 Drag/drop UI for document type properties and tabs 2013-06-29 22:42:15 +02:00
AndyButland adeb859195 Reload content page when document type changed if content already loaded; improved display of confirmation screen 2013-06-29 22:30:12 +02:00
AndyButland aaec90e47a Used override on change document type to clear properties; display of summary on completion 2013-06-29 21:54:48 +02:00
Sebastiaan Janssen d4d21c18b2 Correct little mistake in nuspec file 2013-06-28 14:21:00 +02:00
AndyButland 9d0f544840 Handled inherited properties on source and destination side 2013-06-27 22:24:10 +02:00
AndyButland 3ecd564c57 Sync tree once document type changed 2013-06-27 21:49:06 +02:00
AndyButland 9c23bbd87a Minor styling improvements 2013-06-27 21:44:53 +02:00
AndyButland d3562b797e Back-office UI for change of document type for content item 2013-06-27 21:29:27 +02:00
Chris Tomlinson ea1aefa09e Fixes U4-2187 - Enable support for MySQL on Linux 2013-06-26 15:46:50 +01:00
Jeremy Pyne fe23502e67 Added code to actually pre-select the parent node instead of just locating it in the tree. This seams keeps the Ui in a sane state.
Updated control code in Umbraco.Web.Ui from Umbraco.Web.
2013-06-25 15:48:16 -04:00
Jeremy Pyne ad2764e3ac Added code to select the parent node when doing Move/Copy operations. This will save lots of time for users.
This code can also be added to other places that use the TreeControl to pre-select the currently selected item(media pickers for example) so that changing content will be quicker.
2013-06-24 14:51:52 -04:00
Sebastiaan Janssen 1628dfaa2f Update version to 4.11.10 2013-06-20 17:20:17 +02:00
Shannon 3ff888f77a Fixes: #U4-2403 2013-06-20 14:47:59 +02:00
Murray@tbpc10.terabyte.co.nz 9af3a10da8 #U4-2326 Added Try Catch for PlatformNotSupportedException
Signed-off-by: Sebastiaan Janssen <sebastiaan@umbraco.com>
2013-06-20 14:46:21 +02:00
Sebastiaan Janssen 0470a0ca51 Add gitignore 2013-06-20 14:46:13 +02:00
Sebastiaan Janssen 7b6cda6b44 Closing branch 4.11.9 2013-05-30 09:46:32 -02:00
Sebastiaan Janssen 332d91b6dc Added tag release-4.11.9 for changeset fb8fd83e8e70 2013-05-30 09:46:21 -02:00
Sebastiaan Janssen 85421cf714 Closing branch 4.11.9 as that version number was used for the emergency security fixes 2013-05-01 13:08:21 -02:00
Sebastiaan Janssen 97dd5433e0 Closing branch 6.0.5 as that version number was used for the emergency security fixes 2013-05-01 13:06:59 -02:00
Shannon Deminick 0ae9a75b32 Close 4.11.7 - cmsContentXml fixes branch 2013-04-25 12:20:27 -10:00
Stephan 4c3b9c6f35 Close 6.1.0-public branch, merged. 2013-04-10 14:05:11 -02:00
Sebastiaan Janssen a7bd0d97a7 Closing branch 4.11.5 2013-03-01 06:51:01 -01:00
Sebastiaan Janssen 5943c87fc6 Added tag Release-4.11.5 for changeset 74cfea3262f4 2013-03-01 06:50:28 -01:00
Sebastiaan Janssen ac9d6431f4 Close 6.0.0-LegacyApi-Refactor branch 2012-12-28 08:56:41 -01:00
Morten Christensen a6b16b4878 Closing branch after having merged the changes to events to the main 6.0.0 branch. 2012-12-21 08:29:45 -01:00
Shannon Deminick 6abca67fc4 Close 4.10.1 branch 2012-11-14 21:19:00 +05:00
sitereactor 2738f45d14 Closing feature branch 2012-10-18 12:25:46 -02:00
sebastiaan 34bbf95146 Closing branch 2012-09-10 07:53:20 -02:00
sebastiaan ecd6c42924 Closing branch 2012-09-10 07:53:03 -02:00
sebastiaan 03e34cde87 Closing branch 2012-09-10 07:52:35 -02:00
sebastiaan 7d69e859f9 Closing branch 2012-09-10 07:52:15 -02:00
sebastiaan 661e92218a Closing branch 2012-09-10 07:51:28 -02:00
sebastiaan 3a2ac6c4d3 Closing old branch 2012-09-10 07:19:22 -02:00
shannon@ShandemVaio.home f62b8a604e Close 4.8-solutioncleanup-wip branch 2012-06-27 23:33:10 +04:00
1370 changed files with 72190 additions and 39206 deletions
+2
View File
@@ -82,5 +82,7 @@ tools/NDepend/
src/*.vspx
src/*.psess
NDependOut/*
*.ndproj
QueryResult.htm
*.ndproj
src/Umbraco.Tests/Views/web.config
+1 -1
View File
@@ -1,5 +1,5 @@
@ECHO OFF
SET release=6.1.6
SET release=6.2.6
SET comment=
SET version=%release%
+8
View File
@@ -299,6 +299,10 @@
</Target>
<Target Name="SetVersionNumber" Condition="'$(BUILD_RELEASE)'!=''">
<PropertyGroup>
<NewVersion>$(BUILD_RELEASE)</NewVersion>
<NewVersion Condition="'$(BUILD_COMMENT)'!=''">$(BUILD_RELEASE)-$(BUILD_COMMENT)</NewVersion>
</PropertyGroup>
<!-- Match & replace 3 and 4 digit version numbers and -beta (if it's there) -->
<FileUpdate
Files="..\src\Umbraco.Core\Configuration\UmbracoVersion.cs"
@@ -308,5 +312,9 @@
<FileUpdate Files="..\src\Umbraco.Core\Configuration\UmbracoVersion.cs"
Regex="CurrentComment { get { return &quot;([a-zA-Z]+)?&quot;"
ReplacementText="CurrentComment { get { return &quot;$(BUILD_COMMENT)&quot;"/>
<XmlPoke XmlInputPath=".\NuSpecs\build\UmbracoCms.targets"
Namespaces="&lt;Namespace Prefix='x' Uri='http://schemas.microsoft.com/developer/msbuild/2003' /&gt;"
Query="//x:UmbracoVersion"
Value="$(NewVersion)" />
</Target>
</Project>
+14 -8
View File
@@ -2,9 +2,9 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>UmbracoCms.Core</id>
<version>6.2.0</version>
<version>6.2.3</version>
<title>Umbraco Cms Core Binaries</title>
<authors>Morten Christensen</authors>
<authors>Umbraco HQ</authors>
<owners>Umbraco HQ</owners>
<licenseUrl>http://umbraco.codeplex.com/license</licenseUrl>
<projectUrl>http://umbraco.com/</projectUrl>
@@ -15,17 +15,23 @@
<language>en-US</language>
<tags>umbraco</tags>
<dependencies>
<dependency id="Microsoft.AspNet.Mvc" version="4.0" />
<dependency id="Microsoft.AspNet.WebApi" version="4.0" />
<dependency id="Microsoft.AspNet.Mvc.FixedDisplayModes" version="1.0.0" />
<dependency id="Microsoft.AspNet.Mvc" version="[4.0.30506.0,5.0.0)" />
<dependency id="Microsoft.AspNet.WebApi" version="[4.0.30506,5.0.0)" />
<dependency id="Microsoft.AspNet.WebApi.WebHost" version="[4.0.30506, 5.0.0)" />
<dependency id="Microsoft.AspNet.WebApi.Core" version="[4.0.30506, 5.0.0)" />
<dependency id="Microsoft.AspNet.WebApi.Client" version="[4.0.30506, 5.0.0)" />
<dependency id="Microsoft.AspNet.Mvc.FixedDisplayModes" version="1.0.1" />
<dependency id="Microsoft.Net.Http" version="[2.0.20710.0, 3.0.0)" />
<dependency id="MiniProfiler" version="[2.1.0, 3.0.0)" />
<dependency id="HtmlAgilityPack" version="[1.4.6, 2.0.0)" />
<dependency id="Lucene.Net" version="[2.9.4.1, 3.0.0.0)" />
<dependency id="SharpZipLib" version="[0.86.0, 1.0.0)" />
<dependency id="MySql.Data" version="[6.6.5]" />
<dependency id="xmlrpcnet" version="[2.5.0, 3.0.0)" />
<dependency id="ClientDependency" version="[1.7.0, 2.0.0)" />
<dependency id="ClientDependency-Mvc" version="[1.7.0, 2.0.0)" />
<dependency id="ClientDependency" version="[1.8.2.1, 2.0.0)" />
<dependency id="ClientDependency-Mvc" version="[1.7.0.4, 2.0.0)" />
<dependency id="Newtonsoft.Json" version="[4.5.11, 6.0.0)" />
<dependency id="Examine" version="[0.1.57, 1.0.0)" />
</dependencies>
</metadata>
<files>
@@ -35,7 +41,6 @@
<file src="..\_BuildOutput\WebApp\bin\cms.xml" target="lib\cms.xml" />
<file src="..\_BuildOutput\WebApp\bin\controls.dll" target="lib\controls.dll" />
<file src="..\_BuildOutput\WebApp\bin\controls.xml" target="lib\controls.xml" />
<file src="..\_BuildOutput\WebApp\bin\Examine.dll" target="lib\Examine.dll" />
<file src="..\_BuildOutput\WebApp\bin\interfaces.dll" target="lib\interfaces.dll" />
<file src="..\_BuildOutput\WebApp\bin\interfaces.xml" target="lib\interfaces.xml" />
<file src="..\_BuildOutput\WebApp\bin\log4net.dll" target="lib\log4net.dll" />
@@ -66,5 +71,6 @@
<file src="..\_BuildOutput\WebApp\bin\umbraco.XmlSerializers.dll" target="lib\umbraco.XmlSerializers.dll" />
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.dll" target="lib\UmbracoExamine.dll" />
<file src="..\_BuildOutput\WebApp\bin\UrlRewritingNet.UrlRewriter.dll" target="lib\UrlRewritingNet.UrlRewriter.dll" />
<file src="tools\install.core.ps1" target="tools\install.ps1" />
</files>
</package>
+7 -9
View File
@@ -2,9 +2,9 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>UmbracoCms</id>
<version>6.1.2</version>
<version>6.2.3</version>
<title>Umbraco Cms</title>
<authors>Morten Christensen</authors>
<authors>Umbraco HQ</authors>
<owners>Umbraco HQ</owners>
<licenseUrl>http://umbraco.codeplex.com/license</licenseUrl>
<projectUrl>http://umbraco.com/</projectUrl>
@@ -19,11 +19,9 @@
</dependencies>
</metadata>
<files>
<file src="..\_BuildOutput\WebApp\bin\amd64\**" target="Content\bin\amd64" />
<file src="..\_BuildOutput\WebApp\bin\x86\**" target="Content\bin\x86" />
<file src="..\_BuildOutput\Configs\**" target="Content\config" exclude="..\_BuildOutput\Configs\Web.config.transform" />
<file src="..\_BuildOutput\WebApp\css\**" target="Content\css" />
<file src="..\_BuildOutput\WebApp\macroScripts\**" target="Content\macroScripts" />
<file src="..\_BuildOutput\WebApp\macroScripts\**" target="Content\macroScripts" exclude="..\_BuildOutput\WebApp\macroScripts\Web.config" />
<file src="..\_BuildOutput\WebApp\masterpages\**" target="Content\masterpages" />
<file src="..\_BuildOutput\WebApp\media\**" target="Content\media" />
<file src="..\_BuildOutput\WebApp\scripts\**" target="Content\scripts" />
@@ -32,15 +30,15 @@
<file src="..\_BuildOutput\WebApp\xslt\**" target="Content\xslt" />
<file src="..\_BuildOutput\WebApp\default.aspx" target="Content\default.aspx" />
<file src="..\_BuildOutput\WebApp\Web.config" target="Content\Web.config" />
<file src="..\_BuildOutput\WebApp\Global.asax" target="Content\Global.asax" />
<file src="..\_BuildOutput\WebApp\App_Browsers\**" target="UmbracoFiles\App_Browsers" />
<file src="..\_BuildOutput\WebApp\App_Code\**" target="UmbracoFiles\App_Code" />
<file src="..\_BuildOutput\WebApp\App_Data\**" target="UmbracoFiles\App_Data" />
<file src="..\_BuildOutput\WebApp\App_Plugins\**" target="UmbracoFiles\App_Plugins" />
<file src="..\_BuildOutput\WebApp\App_Plugins\**" target="UmbracoFiles\App_Plugins" />
<file src="..\_BuildOutput\WebApp\bin\amd64\**" target="UmbracoFiles\bin\amd64" />
<file src="..\_BuildOutput\WebApp\bin\x86\**" target="UmbracoFiles\bin\x86" />
<file src="..\_BuildOutput\WebApp\config\splashes\**" target="UmbracoFiles\config\splashes" />
<file src="..\_BuildOutput\WebApp\install\**" target="UmbracoFiles\install" />
<file src="..\_BuildOutput\WebApp\umbraco\**" target="UmbracoFiles\umbraco" />
<file src="..\_BuildOutput\WebApp\umbraco_client\**" target="UmbracoFiles\umbraco_client" />
<file src="..\_BuildOutput\WebApp\Global.asax" target="UmbracoFiles\Global.asax" />
<file src="..\_BuildOutput\WebApp\Web.config" target="UmbracoFiles\Web.config" />
<file src="tools\install.ps1" target="tools\install.ps1" />
<file src="tools\Readme.txt" target="tools\Readme.txt" />
+50
View File
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<UmbracoVersion>6.2.6</UmbracoVersion>
</PropertyGroup>
<Target Name="CopyUmbracoFilesToWebRoot" BeforeTargets="AfterBuild">
<PropertyGroup>
<UmbracoFilesFolder>..\packages\UmbracoCms.$(UmbracoVersion)\UmbracoFiles\</UmbracoFilesFolder>
</PropertyGroup>
<ItemGroup>
<UmbracoFiles Include="$(UmbracoFilesFolder)**\*" />
</ItemGroup>
<Copy SourceFiles="%(UmbracoFiles.FullPath)" DestinationFiles="%(RecursiveDir)%(Filename)%(Extension)" Condition="!Exists('%(RecursiveDir)%(Filename)%(Extension)')" />
</Target>
<Target Name="AddUmbracoFilesToOutput">
<!-- With help from: http://blog.samstephens.co.nz/2010-10-18/msbuild-including-extra-files-multiple-builds/ -->
<ItemGroup>
<CustomFilesToInclude Include=".\App_Browsers\**\*">
<Dir>App_Browsers</Dir>
</CustomFilesToInclude>
<CustomFilesToInclude Include=".\App_Code\**\*">
<Dir>App_Code</Dir>
</CustomFilesToInclude>
<CustomFilesToInclude Include=".\App_Plugins\**\*">
<Dir>App_Plugins</Dir>
</CustomFilesToInclude>
<CustomFilesToInclude Include=".\bin\amd64\**\*">
<Dir>bin\amd64</Dir>
</CustomFilesToInclude>
<CustomFilesToInclude Include=".\bin\x86\**\*">
<Dir>bin\x86</Dir>
</CustomFilesToInclude>
<CustomFilesToInclude Include=".\Config\Splashes\**\*">
<Dir>Config\Splashes</Dir>
</CustomFilesToInclude>
<CustomFilesToInclude Include=".\umbraco\**\*">
<Dir>umbraco</Dir>
</CustomFilesToInclude>
<CustomFilesToInclude Include=".\umbraco_client\**\*">
<Dir>umbraco_client</Dir>
</CustomFilesToInclude>
<CustomFilesToInclude Include=".\Global.asax">
<Dir>.</Dir>
</CustomFilesToInclude>
<FilesForPackagingFromProject Include="@(CustomFilesToInclude)">
<DestinationRelativePath>%(CustomFilesToInclude.Dir)\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
</Project>
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="AddUmbracoFilesToOutput">
<ItemGroup>
<UmbracoFiles Include=".\umbraco\**\*;" />
<UmbracoClientFiles Include=".\umbraco_client\**\*;" />
<AppBrowsersFiles Include=".\App_Browsers\**\*" />
<FilesForPackagingFromProject Include="%(UmbracoFiles.Identity)">
<DestinationRelativePath>umbraco\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(UmbracoClientFiles.Identity)">
<DestinationRelativePath>umbraco_client\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(AppBrowsersFiles.Identity)">
<DestinationRelativePath>App_Browsers\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
</Project>
@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
AddUmbracoFilesToOutput;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
AddUmbracoFilesToOutput;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
</PropertyGroup>
</Project>
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="AddUmbracoFilesToOutput">
<ItemGroup>
<UmbracoFiles Include=".\umbraco\**\*;" />
<UmbracoClientFiles Include=".\umbraco_client\**\*;" />
<AppBrowsersFiles Include=".\App_Browsers\**\*" />
<FilesForPackagingFromProject Include="%(UmbracoFiles.Identity)">
<DestinationRelativePath>umbraco\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(UmbracoClientFiles.Identity)">
<DestinationRelativePath>umbraco_client\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(AppBrowsersFiles.Identity)">
<DestinationRelativePath>App_Browsers\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
</Project>
@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
AddUmbracoFilesToOutput;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
AddUmbracoFilesToOutput;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
</PropertyGroup>
</Project>
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="AddUmbracoFilesToOutput">
<ItemGroup>
<UmbracoFiles Include=".\umbraco\**\*;" />
<UmbracoClientFiles Include=".\umbraco_client\**\*;" />
<AppBrowsersFiles Include=".\App_Browsers\**\*" />
<FilesForPackagingFromProject Include="%(UmbracoFiles.Identity)">
<DestinationRelativePath>umbraco\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(UmbracoClientFiles.Identity)">
<DestinationRelativePath>umbraco_client\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(AppBrowsersFiles.Identity)">
<DestinationRelativePath>App_Browsers\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
</Project>
+14 -5
View File
@@ -1,8 +1,17 @@
A note about running Umbraco from Visual Studio.
When upgrading your website using nuget a backup of config files and web.config will be created. Only the web.config will
be overwritten by default to ensure that it has the necessary settings from the current release. This means that you'll
have to merge the files if you made any changes to the previous config files.
When upgrading your website using NuGet you should answer "No" to the questions to overwrite the Web.config
file (and config files in the config folder).
We will overwrite Web.config anyway but we keep a backup in the App_Data\NuGetBackup folder. There you'll
find a folder with the current date and time in which the backup has been placed. Make sure to merge the
new file with the old backup files before you proceed.
The web.config will be overwritten by default to ensure that it has the necessary settings from the current release.
We've also overwritten all the files in the Umbraco and Umbraco_Client folder, these have also been backed up in
App_Data\NuGetBackup. We didn't overwrite the UI.xml file nor did we remove any files or folders that you or a package
might have added. Only the existing files were overwritten. If you customized anything then make sure to do a compare
and merge with the NuGetBackup folder.
The config files found in the config folder will usually not be changed for patch releases, so they can usually be skipped,
but the web.config will have to have its previous "umbracoConfigurationStatus"-appsetting and "umbracoDbDSN" connection string
copied over (as a minimum).
@@ -10,8 +19,8 @@ copied over (as a minimum).
This nuget package includes build targets that extends the creation of a deploy package, which is generated by
Publishing from Visual Studio. The targets will only work once Publishing is configured, so if you don't use
Publish this won't affect you.
These folders will now be automatically included when creating a deploy package or publishing to the file system:
umbraco and umbraco_client.
These things will now be automatically included when creating a deploy package or publishing to the file system:
umbraco, umbraco_client, config\splashes and global.asax.
Please read the release notes on our.umbraco.org:
http://our.umbraco.org/contribute/releases
+24
View File
@@ -0,0 +1,24 @@
param($rootPath, $toolsPath, $package, $project)
if ($project) {
$dateTime = Get-Date -Format yyyyMMdd-HHmmss
$backupPath = Join-Path (Split-Path $project.FullName -Parent) "\App_Data\NuGetBackup\$dateTime"
$copyLogsPath = Join-Path $backupPath "CopyLogs"
$projectDestinationPath = Split-Path $project.FullName -Parent
# Create backup folder and logs folder if it doesn't exist yet
New-Item -ItemType Directory -Force -Path $backupPath
New-Item -ItemType Directory -Force -Path $copyLogsPath
# After backing up, remove all dlls from bin folder in case dll files are included in the VS project
# See: http://issues.umbraco.org/issue/U4-4930
$umbracoBinFolder = Join-Path $projectDestinationPath "bin"
if(Test-Path $umbracoBinFolder) {
$umbracoBinBackupPath = Join-Path $backupPath "bin"
New-Item -ItemType Directory -Force -Path $umbracoBinBackupPath
robocopy $umbracoBinFolder $umbracoBinBackupPath /e /LOG:$copyLogsPath\UmbracoBinBackup.log
Remove-Item $umbracoBinFolder\*.dll -Force -Confirm:$false
}
}
+38 -18
View File
@@ -1,27 +1,47 @@
param($rootPath, $toolsPath, $package, $project)
if ($project) {
# Create a backup of extisting umbraco config files
$configPath = Join-Path (Split-Path $project.FullName -Parent) "\config"
$backupPath = Join-Path $configPath "\backup"
Get-ChildItem -path $configPath |
Where -filterscript {($_.Name.EndsWith("config"))} | Foreach-Object {
$newFileName = Join-Path $backupPath $_.Name.replace(".config",".config.backup")
New-Item -ItemType File -Path $newFileName -Force
Copy-Item $_.FullName $newFileName -Force
}
$dateTime = Get-Date -Format yyyyMMdd-HHmmss
$backupPath = Join-Path (Split-Path $project.FullName -Parent) "\App_Data\NuGetBackup\$dateTime"
$copyLogsPath = Join-Path $backupPath "CopyLogs"
# Create backup folder and logs folder if it doesn't exist yet
New-Item -ItemType Directory -Force -Path $backupPath
New-Item -ItemType Directory -Force -Path $copyLogsPath
# Create a backup of original web.config
$projectDestinationPath = Split-Path $project.FullName -Parent
$webConfigSource = Join-Path $projectDestinationPath "web.config"
$webConfigDestination = Join-Path $projectDestinationPath "web.config.backup"
Copy-Item $webConfigSource $webConfigDestination
# Copy umbraco files from package to project folder
$projectDestinationPath = Split-Path $project.FullName -Parent
$umbracoFilesPath = Join-Path $rootPath "UmbracoFiles\*"
Copy-Item $umbracoFilesPath $projectDestinationPath -recurse -force
$webConfigSource = Join-Path $projectDestinationPath "Web.config"
Copy-Item $webConfigSource $backupPath -Force
# Copy Web.config from package to project folder
$umbracoFilesPath = Join-Path $rootPath "UmbracoFiles\Web.config"
Copy-Item $umbracoFilesPath $projectDestinationPath -Force
# Copy umbraco and umbraco_files from package to project folder
# This is only done when these folders already exist because we
# only want to do this for upgrades
$umbracoFolder = Join-Path $projectDestinationPath "Umbraco"
if(Test-Path $umbracoFolder) {
$umbracoFolderSource = Join-Path $rootPath "UmbracoFiles\Umbraco"
$umbracoBackupPath = Join-Path $backupPath "Umbraco"
New-Item -ItemType Directory -Force -Path $umbracoBackupPath
robocopy $umbracoFolder $umbracoBackupPath /e /LOG:$copyLogsPath\UmbracoBackup.log
robocopy $umbracoFolderSource $umbracoFolder /is /it /e /xf UI.xml /LOG:$copyLogsPath\UmbracoCopy.log
}
$umbracoClientFolder = Join-Path $projectDestinationPath "Umbraco_Client"
if(Test-Path $umbracoClientFolder) {
$umbracoClientFolderSource = Join-Path $rootPath "UmbracoFiles\Umbraco_Client"
$umbracoClientBackupPath = Join-Path $backupPath "Umbraco_Client"
New-Item -ItemType Directory -Force -Path $umbracoClientBackupPath
robocopy $umbracoClientFolder $umbracoClientBackupPath /e /LOG:$copyLogsPath\UmbracoClientBackup.log
robocopy $umbracoClientFolderSource $umbracoClientFolder /is /it /e /LOG:$copyLogsPath\UmbracoClientCopy.log
}
# Open readme.txt file
$DTE.ItemOperations.OpenFile($toolsPath + '\Readme.txt')
}
+1
View File
@@ -80,6 +80,7 @@
</ItemGroup>
<ItemGroup>
<Content Include="Sql\Total.sql" />
<None Include="app.config" />
<None Include="packages.config" />
<None Include="Sql\Version4_1_Upgrade.sql" />
</ItemGroup>
+15
View File
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
+155 -126
View File
@@ -12,7 +12,7 @@ using Umbraco.Core.Services;
namespace Umbraco.Core
{
/// <summary>
/// <summary>
/// the Umbraco Application context
/// </summary>
/// <remarks>
@@ -20,73 +20,102 @@ namespace Umbraco.Core
/// </remarks>
public class ApplicationContext : IDisposable
{
/// <summary>
/// Constructor
/// </summary>
internal ApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext)
: this(dbContext, serviceContext, true)
{
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="dbContext"></param>
/// <param name="serviceContext"></param>
/// <param name="enableCache"></param>
internal ApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext, bool enableCache)
: this(enableCache)
/// <param name="cache"></param>
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;
_services = serviceContext;
ApplicationCache = cache;
}
/// <summary>
/// Empty constructor normally reserved for unit tests when a DatabaseContext or a ServiceContext is not
/// necessarily required or needs to be set after construction.
/// </summary>
internal ApplicationContext() : this(true)
{
}
/// <summary>
/// Constructor used to specify if we will enable application cache or not
/// Creates a basic app context
/// </summary>
/// <param name="enableCache"></param>
internal ApplicationContext(bool enableCache)
/// <param name="cache"></param>
public ApplicationContext(CacheHelper cache)
{
//create a new application cache from the HttpRuntime.Cache
ApplicationCache = HttpRuntime.Cache == null
? new CacheHelper(new System.Web.Caching.Cache(), enableCache)
: new CacheHelper(HttpRuntime.Cache, enableCache);
ApplicationCache = cache;
}
/// <summary>
/// Singleton accessor
/// </summary>
public static ApplicationContext Current { get; internal set; }
/// <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>
/// Returns the application wide cache accessor
/// </summary>
/// <remarks>
/// Any caching that is done in the application (app wide) should be done through this property
/// </remarks>
public CacheHelper ApplicationCache { get; private set; }
/// <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;
}
// IsReady is set to true by the boot manager once it has successfully booted
/// <summary>
/// Singleton accessor
/// </summary>
public static ApplicationContext Current { get; internal set; }
/// <summary>
/// Returns the application wide cache accessor
/// </summary>
/// <remarks>
/// Any caching that is done in the application (app wide) should be done through this property
/// </remarks>
public CacheHelper ApplicationCache { get; private set; }
// IsReady is set to true by the boot manager once it has successfully booted
// note - the original umbraco module checks on content.Instance in umbraco.dll
// now, the boot task that setup the content store ensures that it is ready
bool _isReady = false;
readonly System.Threading.ManualResetEventSlim _isReadyEvent = new System.Threading.ManualResetEventSlim(false);
private DatabaseContext _databaseContext;
private ServiceContext _services;
readonly ManualResetEventSlim _isReadyEvent = new ManualResetEventSlim(false);
private DatabaseContext _databaseContext;
private ServiceContext _services;
public bool IsReady
public bool IsReady
{
get
{
@@ -96,14 +125,14 @@ namespace Umbraco.Core
{
AssertIsNotReady();
_isReady = value;
_isReadyEvent.Set();
_isReadyEvent.Set();
}
}
public bool WaitForReady(int timeout)
{
return _isReadyEvent.WaitHandle.WaitOne(timeout);
}
public bool WaitForReady(int timeout)
{
return _isReadyEvent.WaitHandle.WaitOne(timeout);
}
// notes
@@ -112,14 +141,14 @@ namespace Umbraco.Core
// the system is configured if they match
// if they don't, install runs, updates web.config (presumably) and updates GlobalSettings.ConfiguredStatus
//
// then there is Application["umbracoNeedConfiguration"] which makes no sense... getting rid of it...
// then there is Application["umbracoNeedConfiguration"] which makes no sense... getting rid of it... SD: I have actually remove that now!
//
public bool IsConfigured
{
// fixme - let's do this for the time being
// todo - we should not do this - ok for now
get
{
return Configured;
return Configured;
}
}
@@ -135,45 +164,45 @@ namespace Umbraco.Core
/// </remarks>
internal string OriginalRequestUrl { get; set; }
private bool Configured
{
get
{
try
{
string configStatus = ConfigurationStatus;
string currentVersion = UmbracoVersion.Current.ToString(3);
private bool Configured
{
get
{
try
{
string configStatus = ConfigurationStatus;
string currentVersion = UmbracoVersion.Current.ToString(3);
if (currentVersion != configStatus)
{
LogHelper.Info<ApplicationContext>("CurrentVersion different from configStatus: '" + currentVersion + "','" + configStatus + "'");
}
if (currentVersion != configStatus)
{
LogHelper.Info<ApplicationContext>("CurrentVersion different from configStatus: '" + currentVersion + "','" + configStatus + "'");
}
return (configStatus == currentVersion);
}
catch
{
return false;
}
}
}
private string ConfigurationStatus
{
get
{
try
{
return ConfigurationManager.AppSettings["umbracoConfigurationStatus"];
}
catch
{
return String.Empty;
}
}
}
return (configStatus == currentVersion);
}
catch
{
return false;
}
}
}
private string ConfigurationStatus
{
get
{
try
{
return ConfigurationManager.AppSettings["umbracoConfigurationStatus"];
}
catch
{
return String.Empty;
}
}
}
private void AssertIsReady()
{
@@ -187,39 +216,39 @@ namespace Umbraco.Core
throw new Exception("ApplicationContext has already been initialized.");
}
/// <summary>
/// Gets the current DatabaseContext
/// </summary>
/// <remarks>
/// Internal set is generally only used for unit tests
/// </remarks>
public DatabaseContext DatabaseContext
{
get
{
if (_databaseContext == null)
throw new InvalidOperationException("The DatabaseContext has not been set on the ApplicationContext");
return _databaseContext;
}
internal set { _databaseContext = value; }
}
/// <summary>
/// Gets the current ServiceContext
/// </summary>
/// <remarks>
/// Internal set is generally only used for unit tests
/// </remarks>
public ServiceContext Services
{
get
{
if (_services == null)
throw new InvalidOperationException("The ServiceContext has not been set on the ApplicationContext");
return _services;
}
internal set { _services = value; }
}
/// <summary>
/// Gets the current DatabaseContext
/// </summary>
/// <remarks>
/// Internal set is generally only used for unit tests
/// </remarks>
public DatabaseContext DatabaseContext
{
get
{
if (_databaseContext == null)
throw new InvalidOperationException("The DatabaseContext has not been set on the ApplicationContext");
return _databaseContext;
}
internal set { _databaseContext = value; }
}
/// <summary>
/// Gets the current ServiceContext
/// </summary>
/// <remarks>
/// Internal set is generally only used for unit tests
/// </remarks>
public ServiceContext Services
{
get
{
if (_services == null)
throw new InvalidOperationException("The ServiceContext has not been set on the ApplicationContext");
return _services;
}
internal set { _services = value; }
}
private volatile bool _disposed;
@@ -245,26 +274,26 @@ namespace Umbraco.Core
//clear the cache
if (ApplicationCache != null)
{
ApplicationCache.ClearAllCache();
ApplicationCache.ClearAllCache();
}
//reset all resolvers
ResolverCollection.ResetAll();
//reset resolution itself (though this should be taken care of by resetting any of the resolvers above)
Resolution.Reset();
//reset the instance objects
this.ApplicationCache = null;
if (_databaseContext != null) //need to check the internal field here
{
if (DatabaseContext.IsDatabaseConfigured)
{
DatabaseContext.Database.Dispose();
}
DatabaseContext.Database.Dispose();
}
}
this.DatabaseContext = null;
this.Services = null;
this._isReady = false; //set the internal field
// Indicate that the instance has been disposed.
_disposed = true;
}
+2
View File
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
namespace Umbraco.Core
+155 -55
View File
@@ -2,65 +2,165 @@ using System;
namespace Umbraco.Core
{
/// <summary>
/// Represents the result of an operation attempt
/// </summary>
/// <typeparam name="T"></typeparam>
/// <remarks></remarks>
[Serializable]
public struct Attempt<T>
{
private readonly bool _success;
private readonly T _result;
private readonly Exception _error;
/// <summary>
/// Provides ways to create attempts.
/// </summary>
public static class Attempt
{
/// <summary>
/// Creates a successful attempt with a result.
/// </summary>
/// <typeparam name="T">The type of the attempted operation result.</typeparam>
/// <param name="result">The result of the attempt.</param>
/// <returns>The successful attempt.</returns>
public static Attempt<T> Succeed<T>(T result)
{
return Attempt<T>.Succeed(result);
}
/// <summary>
/// Gets a value indicating whether this <see cref="Attempt{T}"/> represents a successful operation.
/// </summary>
/// <remarks></remarks>
public bool Success
{
get { return _success; }
}
/// <summary>
/// Creates a failed attempt with a result.
/// </summary>
/// <typeparam name="T">The type of the attempted operation result.</typeparam>
/// <param name="result">The result of the attempt.</param>
/// <returns>The failed attempt.</returns>
public static Attempt<T> Fail<T>(T result)
{
return Attempt<T>.Fail(result);
}
/// <summary>
/// Gets the error associated with an unsuccessful attempt.
/// </summary>
/// <value>The error.</value>
public Exception Error { get { return _error; } }
/// <summary>
/// Creates a failed attempt with a result and an exception.
/// </summary>
/// <typeparam name="T">The type of the attempted operation result.</typeparam>
/// <param name="result">The result of the attempt.</param>
/// <param name="exception">The exception causing the failure of the attempt.</param>
/// <returns>The failed attempt.</returns>
public static Attempt<T> Fail<T>(T result, Exception exception)
{
return Attempt<T>.Fail(result, exception);
}
/// <summary>
/// Gets the parse result.
/// </summary>
/// <remarks></remarks>
public T Result
{
get { return _result; }
}
/// <summary>
/// Creates a successful or a failed attempt, with a result.
/// </summary>
/// <typeparam name="T">The type of the attempted operation result.</typeparam>
/// <param name="success">A value indicating whether the attempt is successful.</param>
/// <param name="result">The result of the attempt.</param>
/// <returns>The attempt.</returns>
public static Attempt<T> If<T>(bool success, T result)
{
return Attempt<T>.SucceedIf(success, result);
}
/// <summary>
/// Represents an unsuccessful parse operation
/// </summary>
public static readonly Attempt<T> False = new Attempt<T>(false, default(T));
/// <summary>
/// Initializes a new instance of the <see cref="Attempt{T}"/> struct.
/// </summary>
/// <param name="success">If set to <c>true</c> this tuple represents a successful parse result.</param>
/// <param name="result">The parse result.</param>
/// <remarks></remarks>
public Attempt(bool success, T result)
{
_success = success;
_result = result;
_error = null;
}
/// <summary>
/// Executes an attempt function, with callbacks.
/// </summary>
/// <typeparam name="T">The type of the attempted operation result.</typeparam>
/// <param name="attempt">The attempt returned by the attempt function.</param>
/// <param name="onSuccess">An action to execute in case the attempt succeeds.</param>
/// <param name="onFail">An action to execute in case the attempt fails.</param>
/// <returns>The outcome of the attempt.</returns>
/// <remarks>Runs <paramref name="onSuccess"/> or <paramref name="onFail"/> depending on the
/// whether the attempt function reports a success or a failure.</remarks>
public static Outcome Try<T>(Attempt<T> attempt, Action<T> onSuccess, Action<Exception> onFail = null)
{
if (attempt.Success)
{
onSuccess(attempt.Result);
return Outcome.Success;
}
public Attempt(Exception error)
{
_success = false;
_result = default(T);
_error = error;
}
}
if (onFail != null)
{
onFail(attempt.Exception);
}
return Outcome.Failure;
}
/// <summary>
/// Represents the outcome of an attempt.
/// </summary>
/// <remarks>Can be a success or a failure, and allows for attempts chaining.</remarks>
public struct Outcome
{
private readonly bool _success;
/// <summary>
/// Gets an outcome representing a success.
/// </summary>
public static readonly Outcome Success = new Outcome(true);
/// <summary>
/// Gets an outcome representing a failure.
/// </summary>
public static readonly Outcome Failure = new Outcome(false);
private Outcome(bool success)
{
_success = success;
}
/// <summary>
/// Executes another attempt function, if the previous one failed, with callbacks.
/// </summary>
/// <typeparam name="T">The type of the attempted operation result.</typeparam>
/// <param name="nextFunction">The attempt function to execute, returning an attempt.</param>
/// <param name="onSuccess">An action to execute in case the attempt succeeds.</param>
/// <param name="onFail">An action to execute in case the attempt fails.</param>
/// <returns>If it executes, returns the outcome of the attempt, else returns a success outcome.</returns>
/// <remarks>
/// <para>Executes only if the previous attempt failed, else does not execute and return a success outcome.</para>
/// <para>If it executes, then runs <paramref name="onSuccess"/> or <paramref name="onFail"/> depending on the
/// whether the attempt function reports a success or a failure.</para>
/// </remarks>
public Outcome OnFailure<T>(Func<Attempt<T>> nextFunction, Action<T> onSuccess, Action<Exception> onFail = null)
{
return _success
? Success
: ExecuteNextFunction(nextFunction, onSuccess, onFail);
}
/// <summary>
/// Executes another attempt function, if the previous one succeeded, with callbacks.
/// </summary>
/// <typeparam name="T">The type of the attempted operation result.</typeparam>
/// <param name="nextFunction">The attempt function to execute, returning an attempt.</param>
/// <param name="onSuccess">An action to execute in case the attempt succeeds.</param>
/// <param name="onFail">An action to execute in case the attempt fails.</param>
/// <returns>If it executes, returns the outcome of the attempt, else returns a failed outcome.</returns>
/// <remarks>
/// <para>Executes only if the previous attempt succeeded, else does not execute and return a success outcome.</para>
/// <para>If it executes, then runs <paramref name="onSuccess"/> or <paramref name="onFail"/> depending on the
/// whether the attempt function reports a success or a failure.</para>
/// </remarks>
public Outcome OnSuccess<T>(Func<Attempt<T>> nextFunction, Action<T> onSuccess, Action<Exception> onFail = null)
{
return _success
? ExecuteNextFunction(nextFunction, onSuccess, onFail)
: Failure;
}
private static Outcome ExecuteNextFunction<T>(Func<Attempt<T>> nextFunction, Action<T> onSuccess, Action<Exception> onFail = null)
{
var attempt = nextFunction();
if (attempt.Success)
{
onSuccess(attempt.Result);
return Success;
}
if (onFail != null)
{
onFail(attempt.Exception);
}
return Failure;
}
}
}
}
+174
View File
@@ -0,0 +1,174 @@
using System;
using Umbraco.Core.Dynamics;
namespace Umbraco.Core
{
/// <summary>
/// Represents the result of an operation attempt.
/// </summary>
/// <typeparam name="T">The type of the attempted operation result.</typeparam>
[Serializable]
public struct Attempt<T>
{
private readonly bool _success;
private readonly T _result;
private readonly Exception _exception;
/// <summary>
/// Gets a value indicating whether this <see cref="Attempt{T}"/> was successful.
/// </summary>
public bool Success
{
get { return _success; }
}
/// <summary>
/// Gets the exception associated with an unsuccessful attempt.
/// </summary>
public Exception Exception { get { return _exception; } }
/// <summary>
/// Gets the exception associated with an unsuccessful attempt.
/// </summary>
/// <remarks>Keep it for backward compatibility sake.</remarks>
[Obsolete(".Error is obsolete, you should use .Exception instead.", false)]
public Exception Error { get { return _exception; } }
/// <summary>
/// Gets the attempt result.
/// </summary>
public T Result
{
get { return _result; }
}
// optimize, use a singleton failed attempt
private static readonly Attempt<T> Failed = new Attempt<T>(false, default(T), null);
/// <summary>
/// Represents an unsuccessful attempt.
/// </summary>
/// <remarks>Keep it for backward compatibility sake.</remarks>
[Obsolete(".Failed is obsolete, you should use Attempt<T>.Fail() instead.", false)]
public static readonly Attempt<T> False = Failed;
// private - use Succeed() or Fail() methods to create attempts
private Attempt(bool success, T result, Exception exception)
{
_success = success;
_result = result;
_exception = exception;
}
/// <summary>
/// Initialize a new instance of the <see cref="Attempt{T}"/> struct with a result.
/// </summary>
/// <param name="success">A value indicating whether the attempt is successful.</param>
/// <param name="result">The result of the attempt.</param>
/// <remarks>Keep it for backward compatibility sake.</remarks>
[Obsolete("Attempt ctors are obsolete, you should use Attempt<T>.Succeed(), Attempt<T>.Fail() or Attempt<T>.If() instead.", false)]
public Attempt(bool success, T result)
: this(success, result, null)
{ }
/// <summary>
/// Initialize a new instance of the <see cref="Attempt{T}"/> struct representing a failed attempt, with an exception.
/// </summary>
/// <param name="exception">The exception causing the failure of the attempt.</param>
/// <remarks>Keep it for backward compatibility sake.</remarks>
[Obsolete("Attempt ctors are obsolete, you should use Attempt<T>.Succeed(), Attempt<T>.Fail() or Attempt<T>.If() instead.", false)]
public Attempt(Exception exception)
: this(false, default(T), exception)
{ }
/// <summary>
/// Creates a successful attempt.
/// </summary>
/// <returns>The successful attempt.</returns>
public static Attempt<T> Succeed()
{
return new Attempt<T>(true, default(T), null);
}
/// <summary>
/// Creates a successful attempt with a result.
/// </summary>
/// <param name="result">The result of the attempt.</param>
/// <returns>The successful attempt.</returns>
public static Attempt<T> Succeed(T result)
{
return new Attempt<T>(true, result, null);
}
/// <summary>
/// Creates a failed attempt.
/// </summary>
/// <returns>The failed attempt.</returns>
public static Attempt<T> Fail()
{
return Failed;
}
/// <summary>
/// Creates a failed attempt with an exception.
/// </summary>
/// <param name="exception">The exception causing the failure of the attempt.</param>
/// <returns>The failed attempt.</returns>
public static Attempt<T> Fail(Exception exception)
{
return new Attempt<T>(false, default(T), exception);
}
/// <summary>
/// Creates a failed attempt with a result.
/// </summary>
/// <param name="result">The result of the attempt.</param>
/// <returns>The failed attempt.</returns>
public static Attempt<T> Fail(T result)
{
return new Attempt<T>(false, result, null);
}
/// <summary>
/// Creates a failed attempt with a result and an exception.
/// </summary>
/// <param name="result">The result of the attempt.</param>
/// <param name="exception">The exception causing the failure of the attempt.</param>
/// <returns>The failed attempt.</returns>
public static Attempt<T> Fail(T result, Exception exception)
{
return new Attempt<T>(false, result, exception);
}
/// <summary>
/// Creates a successful or a failed attempt.
/// </summary>
/// <param name="condition">A value indicating whether the attempt is successful.</param>
/// <returns>The attempt.</returns>
public static Attempt<T> SucceedIf(bool condition)
{
return condition ? new Attempt<T>(true, default(T), null) : Failed;
}
/// <summary>
/// Creates a successful or a failed attempt, with a result.
/// </summary>
/// <param name="condition">A value indicating whether the attempt is successful.</param>
/// <param name="result">The result of the attempt.</param>
/// <returns>The attempt.</returns>
public static Attempt<T> SucceedIf(bool condition, T result)
{
return new Attempt<T>(condition, result, null);
}
/// <summary>
/// Implicity operator to check if the attempt was successful without having to access the 'success' property
/// </summary>
/// <param name="a"></param>
/// <returns></returns>
public static implicit operator bool(Attempt<T> a)
{
return a.Success;
}
}
}
+8 -2
View File
@@ -1,3 +1,5 @@
using System;
namespace Umbraco.Core.Cache
{
@@ -9,6 +11,7 @@ namespace Umbraco.Core.Cache
public const string ApplicationTreeCacheKey = "ApplicationTreeCache";
public const string ApplicationsCacheKey = "ApplicationCache";
[Obsolete("This is no longer used and will be removed from the codebase in the future")]
public const string UserTypeCacheKey = "UserTypeCache";
public const string ContentItemCacheKey = "contentItem";
@@ -24,13 +27,16 @@ namespace Umbraco.Core.Cache
public const string MemberLibraryCacheKey = "UL_GetMember";
public const string MemberBusinessLogicCacheKey = "MemberCacheItem_";
public const string TemplateFrontEndCacheKey = "template";
public const string TemplateBusinessLogicCacheKey = "UmbracoTemplateCache";
public const string UserContextCacheKey = "UmbracoUserContext";
public const string UserContextTimeoutCacheKey = "UmbracoUserContextTimeout";
[Obsolete("This is no longer used and will be removed from the codebase in the future")]
public const string UserCacheKey = "UmbracoUser";
public const string UserPermissionsCacheKey = "UmbracoUserPermissions";
public const string ContentTypeCacheKey = "UmbracoContentType";
@@ -47,6 +53,6 @@ namespace Umbraco.Core.Cache
public const string StylesheetPropertyCacheKey = "UmbracoStylesheetProperty";
public const string DataTypeCacheKey = "UmbracoDataTypeDefinition";
public const string DataTypePreValuesCacheKey = "UmbracoPreVal";
}
}
@@ -1,24 +0,0 @@
using System;
using System.Collections.Generic;
namespace Umbraco.Core.Cache
{
/// <summary>
/// An abstract class for implementing a basic cache provider
/// </summary>
/// <remarks>
/// THIS MUST REMAIN INTERNAL UNTIL WE STREAMLINE HOW ALL CACHE IS HANDLED, WE NEED TO SUPPORT HTTP RUNTIME CACHE, IN MEMORY CACHE, ETC...
/// </remarks>
internal abstract class CacheProviderBase
{
public abstract void ClearAllCache();
public abstract void ClearCacheItem(string key);
public abstract void ClearCacheObjectTypes(string typeName);
public abstract void ClearCacheObjectTypes<T>();
public abstract void ClearCacheByKeySearch(string keyStartsWith);
public abstract void ClearCacheByKeyExpression(string regexString);
public abstract IEnumerable<T> GetCacheItemsByKeySearch<T>(string keyStartsWith);
public abstract T GetCacheItem<T>(string cacheKey);
public abstract T GetCacheItem<T>(string cacheKey, Func<T> getCacheItem);
}
}
@@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Caching;
namespace Umbraco.Core.Cache
{
/// <summary>
/// Extensions for strongly typed access
/// </summary>
internal static class CacheProviderExtensions
{
public static T GetCacheItem<T>(this IRuntimeCacheProvider provider,
string cacheKey,
Func<T> getCacheItem,
TimeSpan? timeout,
bool isSliding = false,
CacheItemPriority priority = CacheItemPriority.Normal,
CacheItemRemovedCallback removedCallback = null,
string[] dependentFiles = null)
{
var result = provider.GetCacheItem(cacheKey, () => getCacheItem(), timeout, isSliding, priority, removedCallback, dependentFiles);
return result == null ? default(T) : result.TryConvertTo<T>().Result;
}
public static void InsertCacheItem<T>(this IRuntimeCacheProvider provider,
string cacheKey,
Func<T> getCacheItem,
TimeSpan? timeout = null,
bool isSliding = false,
CacheItemPriority priority = CacheItemPriority.Normal,
CacheItemRemovedCallback removedCallback = null,
string[] dependentFiles = null)
{
provider.InsertCacheItem(cacheKey, () => getCacheItem(), timeout, isSliding, priority, removedCallback, dependentFiles);
}
public static IEnumerable<T> GetCacheItemsByKeySearch<T>(this ICacheProvider provider, string keyStartsWith)
{
var result = provider.GetCacheItemsByKeySearch(keyStartsWith);
return result.Select(x => x.TryConvertTo<T>().Result);
}
public static IEnumerable<T> GetCacheItemsByKeyExpression<T>(this ICacheProvider provider, string regexString)
{
var result = provider.GetCacheItemsByKeyExpression(regexString);
return result.Select(x => x.TryConvertTo<T>().Result);
}
public static T GetCacheItem<T>(this ICacheProvider provider, string cacheKey)
{
var result = provider.GetCacheItem(cacheKey);
if (result == null)
{
return default(T);
}
return result.TryConvertTo<T>().Result;
}
public static T GetCacheItem<T>(this ICacheProvider provider, string cacheKey, Func<T> getCacheItem)
{
var result = provider.GetCacheItem(cacheKey, () => getCacheItem());
if (result == null)
{
return default(T);
}
return result.TryConvertTo<T>().Result;
}
}
}
@@ -0,0 +1,204 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Umbraco.Core.Cache
{
internal abstract class DictionaryCacheProviderBase : ICacheProvider
{
// prefix cache keys so we know which one are ours
protected const string CacheItemPrefix = "umbrtmche";
// an object that represent a value that has not been created yet
protected readonly object ValueNotCreated = new object();
// manupulate the underlying cache entries
// these *must* be called from within the appropriate locks
// and use the full prefixed cache keys
protected abstract IEnumerable<DictionaryEntry> GetDictionaryEntries();
protected abstract void RemoveEntry(string key);
protected abstract object GetEntry(string key);
// read-write lock the underlying cache
protected abstract IDisposable ReadLock { get; }
protected abstract IDisposable WriteLock { get; }
protected string GetCacheKey(string key)
{
return string.Format("{0}-{1}", CacheItemPrefix, key);
}
protected object GetSafeLazyValue(Lazy<object> lazy, bool onlyIfValueIsCreated = false)
{
try
{
// if onlyIfValueIsCreated, do not trigger value creation
// must return something, though, to differenciate from null values
if (onlyIfValueIsCreated && lazy.IsValueCreated == false) return ValueNotCreated;
return lazy.Value;
}
catch
{
return null;
}
}
#region Clear
public virtual void ClearAllCache()
{
using (WriteLock)
{
foreach (var entry in GetDictionaryEntries()
.ToArray())
RemoveEntry((string) entry.Key);
}
}
public virtual void ClearCacheItem(string key)
{
var cacheKey = GetCacheKey(key);
using (WriteLock)
{
RemoveEntry(cacheKey);
}
}
public virtual void ClearCacheObjectTypes(string typeName)
{
using (WriteLock)
{
foreach (var entry in GetDictionaryEntries()
.Where(x =>
{
// entry.Value is Lazy<object> and not null, its value may be null
// remove null values as well, does not hurt
// get non-created as NonCreatedValue & exceptions as null
var value = GetSafeLazyValue((Lazy<object>)x.Value, true);
return value == null || value.GetType().ToString().InvariantEquals(typeName);
})
.ToArray())
RemoveEntry((string) entry.Key);
}
}
public virtual void ClearCacheObjectTypes<T>()
{
var typeOfT = typeof(T);
using (WriteLock)
{
foreach (var entry in GetDictionaryEntries()
.Where(x =>
{
// entry.Value is Lazy<object> and not null, its value may be null
// remove null values as well, does not hurt
// compare on exact type, don't use "is"
// get non-created as NonCreatedValue & exceptions as null
var value = GetSafeLazyValue((Lazy<object>)x.Value, true);
return value == null || value.GetType() == typeOfT;
})
.ToArray())
RemoveEntry((string) entry.Key);
}
}
public virtual void ClearCacheObjectTypes<T>(Func<string, T, bool> predicate)
{
var typeOfT = typeof(T);
var plen = CacheItemPrefix.Length + 1;
using (WriteLock)
{
foreach (var entry in GetDictionaryEntries()
.Where(x =>
{
// entry.Value is Lazy<object> and not null, its value may be null
// remove null values as well, does not hurt
// compare on exact type, don't use "is"
// get non-created as NonCreatedValue & exceptions as null
var value = GetSafeLazyValue((Lazy<object>)x.Value, true);
if (value == null) return true;
return value.GetType() == typeOfT
// run predicate on the 'public key' part only, ie without prefix
&& predicate(((string)x.Key).Substring(plen), (T)value);
}))
RemoveEntry((string) entry.Key);
}
}
public virtual void ClearCacheByKeySearch(string keyStartsWith)
{
var plen = CacheItemPrefix.Length + 1;
using (WriteLock)
{
foreach (var entry in GetDictionaryEntries()
.Where(x => ((string)x.Key).Substring(plen).InvariantStartsWith(keyStartsWith))
.ToArray())
RemoveEntry((string) entry.Key);
}
}
public virtual void ClearCacheByKeyExpression(string regexString)
{
var plen = CacheItemPrefix.Length + 1;
using (WriteLock)
{
foreach (var entry in GetDictionaryEntries()
.Where(x => Regex.IsMatch(((string)x.Key).Substring(plen), regexString))
.ToArray())
RemoveEntry((string) entry.Key);
}
}
#endregion
#region Get
public virtual IEnumerable<object> GetCacheItemsByKeySearch(string keyStartsWith)
{
var plen = CacheItemPrefix.Length + 1;
IEnumerable<DictionaryEntry> entries;
using (ReadLock)
{
entries = GetDictionaryEntries()
.Where(x => ((string)x.Key).Substring(plen).InvariantStartsWith(keyStartsWith))
.ToArray(); // evaluate while locked
}
return entries
.Select(x => GetSafeLazyValue((Lazy<object>)x.Value)) // return exceptions as null
.Where(x => x != null); // backward compat, don't store null values in the cache
}
public virtual IEnumerable<object> GetCacheItemsByKeyExpression(string regexString)
{
const string prefix = CacheItemPrefix + "-";
var plen = prefix.Length;
IEnumerable<DictionaryEntry> entries;
using (ReadLock)
{
entries = GetDictionaryEntries()
.Where(x => Regex.IsMatch(((string)x.Key).Substring(plen), regexString))
.ToArray(); // evaluate while locked
}
return entries
.Select(x => GetSafeLazyValue((Lazy<object>)x.Value)) // return exceptions as null
.Where(x => x != null); // backward compat, don't store null values in the cache
}
public virtual object GetCacheItem(string cacheKey)
{
cacheKey = GetCacheKey(cacheKey);
Lazy<object> result;
using (ReadLock)
{
result = GetEntry(cacheKey) as Lazy<object>; // null if key not found
}
return result == null ? null : GetSafeLazyValue(result); // return exceptions as null
}
public abstract object GetCacheItem(string cacheKey, Func<object> getCacheItem);
#endregion
}
}
@@ -0,0 +1,125 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Umbraco.Core.Cache
{
/// <summary>
/// A cache provider that caches items in the HttpContext.Items
/// </summary>
internal class HttpRequestCacheProvider : DictionaryCacheProviderBase
{
// context provider
// the idea is that there is only one, application-wide HttpRequestCacheProvider instance,
// that is initialized with a method that returns the "current" context.
// NOTE
// but then it is initialized with () => new HttpContextWrapper(HttpContent.Current)
// which is higly inefficient because it creates a new wrapper each time we refer to _context()
// so replace it with _context1 and _context2 below + a way to get context.Items.
//private readonly Func<HttpContextBase> _context;
// NOTE
// and then in almost 100% cases _context2 will be () => HttpContext.Current
// so why not bring that logic in here and fallback on to HttpContext.Current when
// _context1 is null?
//private readonly HttpContextBase _context1;
//private readonly Func<HttpContext> _context2;
private readonly HttpContextBase _context;
private IDictionary ContextItems
{
//get { return _context1 != null ? _context1.Items : _context2().Items; }
get { return _context != null ? _context.Items : HttpContext.Current.Items; }
}
// for unit tests
public HttpRequestCacheProvider(HttpContextBase context)
{
_context = context;
}
// main constructor
// will use HttpContext.Current
public HttpRequestCacheProvider(/*Func<HttpContext> context*/)
{
//_context2 = context;
}
protected override IEnumerable<DictionaryEntry> GetDictionaryEntries()
{
const string prefix = CacheItemPrefix + "-";
return ContextItems.Cast<DictionaryEntry>()
.Where(x => x.Key is string && ((string)x.Key).StartsWith(prefix));
}
protected override void RemoveEntry(string key)
{
ContextItems.Remove(key);
}
protected override object GetEntry(string key)
{
return ContextItems[key];
}
#region Lock
protected override IDisposable ReadLock
{
// there's no difference between ReadLock and WriteLock here
get { return WriteLock; }
}
protected override IDisposable WriteLock
{
// NOTE
// could think about just overriding base.Locker to return a different
// object but then we'd create a ReaderWriterLockSlim per request,
// which is less efficient than just using a basic monitor lock.
get
{
return new MonitorLock(ContextItems.SyncRoot);
}
}
#endregion
#region Get
public override object GetCacheItem(string cacheKey, Func<object> getCacheItem)
{
cacheKey = GetCacheKey(cacheKey);
Lazy<object> result;
using (WriteLock)
{
result = ContextItems[cacheKey] as Lazy<object>; // null if key not found
// cannot create value within the lock, so if result.IsValueCreated is false, just
// do nothing here - means that if creation throws, a race condition could cause
// more than one thread to reach the return statement below and throw - accepted.
if (result == null || GetSafeLazyValue(result, true) == null) // get non-created as NonCreatedValue & exceptions as null
{
result = new Lazy<object>(getCacheItem);
ContextItems[cacheKey] = result;
}
}
// this may throw if getCacheItem throws, but this is the only place where
// it would throw as everywhere else we use GetLazySaveValue() to hide exceptions
// and pretend exceptions were never inserted into cache to begin with.
return result.Value;
}
#endregion
#region Insert
#endregion
}
}
+136 -289
View File
@@ -2,355 +2,202 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Web.Caching;
using Umbraco.Core.Logging;
using CacheItemPriority = System.Web.Caching.CacheItemPriority;
namespace Umbraco.Core.Cache
{
/// <summary>
/// A CacheProvider that wraps the logic of the HttpRuntime.Cache
/// </summary>
internal class HttpRuntimeCacheProvider : RuntimeCacheProviderBase
internal class HttpRuntimeCacheProvider : DictionaryCacheProviderBase, IRuntimeCacheProvider
{
// locker object that supports upgradeable read locking
// does not need to support recursion if we implement the cache correctly and ensure
// that methods cannot be reentrant, ie we do NOT create values while holding a lock.
private readonly ReaderWriterLockSlim _locker = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);
private readonly System.Web.Caching.Cache _cache;
private static readonly object Locker = new object();
public HttpRuntimeCacheProvider(System.Web.Caching.Cache cache)
{
_cache = cache;
}
/// <summary>
/// Clears everything in umbraco's runtime cache, which means that not only
/// umbraco content is removed, but also other cache items from pages running in
/// the same application / website. Use with care :-)
/// </summary>
public override void ClearAllCache()
protected override IEnumerable<DictionaryEntry> GetDictionaryEntries()
{
var cacheEnumerator = _cache.GetEnumerator();
while (cacheEnumerator.MoveNext())
{
_cache.Remove(cacheEnumerator.Key.ToString());
}
const string prefix = CacheItemPrefix + "-";
return _cache.Cast<DictionaryEntry>()
.Where(x => x.Key is string && ((string) x.Key).StartsWith(prefix));
}
/// <summary>
/// Clears the item in umbraco's runtime cache with the given key
/// </summary>
/// <param name="key">Key</param>
public override void ClearCacheItem(string key)
protected override void RemoveEntry(string key)
{
// NH 10 jan 2012
// Patch by the always wonderful Stéphane Gay to avoid cache null refs
lock (Locker)
{
if (_cache[key] == null) return;
_cache.Remove(key); ;
}
_cache.Remove(key);
}
/// <summary>
/// Clears all objects in the System.Web.Cache with the System.Type name as the
/// input parameter. (using [object].GetType())
/// </summary>
/// <param name="typeName">The name of the System.Type which should be cleared from cache ex "System.Xml.XmlDocument"</param>
public override void ClearCacheObjectTypes(string typeName)
protected override object GetEntry(string key)
{
try
{
lock (Locker)
{
foreach (DictionaryEntry c in _cache)
{
if (_cache[c.Key.ToString()] != null
&& _cache[c.Key.ToString()].GetType().ToString().InvariantEquals(typeName))
{
_cache.Remove(c.Key.ToString());
}
}
}
}
catch (Exception e)
{
LogHelper.Error<CacheHelper>("Cache clearing error", e);
}
return _cache.Get(key);
}
/// <summary>
/// Clears all objects in the System.Web.Cache with the System.Type specified
/// </summary>
public override void ClearCacheObjectTypes<T>()
#region Lock
protected override IDisposable ReadLock
{
try
{
lock (Locker)
{
foreach (DictionaryEntry c in _cache)
{
if (_cache[c.Key.ToString()] != null
&& _cache[c.Key.ToString()].GetType() == typeof(T))
{
_cache.Remove(c.Key.ToString());
}
}
}
}
catch (Exception e)
{
LogHelper.Error<CacheHelper>("Cache clearing error", e);
}
get { return new ReadLock(_locker); }
}
/// <summary>
/// Clears all cache items that starts with the key passed.
/// </summary>
/// <param name="keyStartsWith">The start of the key</param>
public override void ClearCacheByKeySearch(string keyStartsWith)
protected override IDisposable WriteLock
{
foreach (DictionaryEntry c in _cache)
{
if (c.Key is string && ((string)c.Key).InvariantStartsWith(keyStartsWith))
{
ClearCacheItem((string)c.Key);
}
}
get { return new WriteLock(_locker); }
}
/// <summary>
/// Clears all cache items that have a key that matches the regular expression
/// </summary>
/// <param name="regexString"></param>
public override void ClearCacheByKeyExpression(string regexString)
{
foreach (DictionaryEntry c in _cache)
{
if (c.Key is string && Regex.IsMatch(((string)c.Key), regexString))
{
ClearCacheItem((string)c.Key);
}
}
}
#endregion
public override IEnumerable<T> GetCacheItemsByKeySearch<T>(string keyStartsWith)
{
return (from DictionaryEntry c in _cache
where c.Key is string && ((string)c.Key).InvariantStartsWith(keyStartsWith)
select c.Value.TryConvertTo<T>()
into attempt
where attempt.Success
select attempt.Result).ToList();
}
/// <summary>
/// Returns a cache item by key, does not update the cache if it isn't there.
/// </summary>
/// <typeparam name="TT"></typeparam>
/// <param name="cacheKey"></param>
/// <returns></returns>
public override TT GetCacheItem<TT>(string cacheKey)
{
var result = _cache.Get(cacheKey);
if (result == null)
{
return default(TT);
}
return result.TryConvertTo<TT>().Result;
}
#region Get
/// <summary>
/// Gets (and adds if necessary) an item from the cache with all of the default parameters
/// </summary>
/// <typeparam name="TT"></typeparam>
/// <param name="cacheKey"></param>
/// <param name="getCacheItem"></param>
/// <returns></returns>
public override TT GetCacheItem<TT>(string cacheKey, Func<TT> getCacheItem)
public override object GetCacheItem(string cacheKey, Func<object> getCacheItem)
{
return GetCacheItem(cacheKey, CacheItemPriority.Normal, null, null, null, getCacheItem, Locker);
return GetCacheItem(cacheKey, getCacheItem, null, dependentFiles: null);
}
/// <summary>
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
/// This overload is here for legacy purposes
/// </summary>
/// <typeparam name="TT"></typeparam>
/// <param name="cacheKey"></param>
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
/// <param name="getCacheItem"></param>
/// <returns></returns>
public override TT GetCacheItem<TT>(string cacheKey,
TimeSpan? timeout, Func<TT> getCacheItem)
{
return GetCacheItem(cacheKey, null, timeout, getCacheItem);
}
/// <summary>
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
/// </summary>
/// <typeparam name="TT"></typeparam>
/// <param name="cacheKey"></param>
/// <param name="refreshAction"></param>
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
/// <param name="getCacheItem"></param>
/// <returns></returns>
public override TT GetCacheItem<TT>(string cacheKey,
CacheItemRemovedCallback refreshAction, TimeSpan? timeout,
Func<TT> getCacheItem)
{
return GetCacheItem(cacheKey, CacheItemPriority.Normal, refreshAction, timeout, getCacheItem);
}
/// <summary>
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
/// </summary>
/// <typeparam name="TT"></typeparam>
/// <param name="cacheKey"></param>
/// <param name="timeout"></param>
/// <param name="isSliding"></param>
/// <param name="priority"></param>
/// <param name="refreshAction"></param>
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
/// <param name="getCacheItem"></param>
/// <param name="removedCallback"></param>
/// <param name="dependency"></param>
/// <returns></returns>
public override TT GetCacheItem<TT>(string cacheKey,
CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan? timeout,
Func<TT> getCacheItem)
internal object GetCacheItem(string cacheKey, Func<object> getCacheItem, TimeSpan? timeout, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, CacheDependency dependency = null)
{
return GetCacheItem(cacheKey, priority, refreshAction, null, timeout, getCacheItem);
}
cacheKey = GetCacheKey(cacheKey);
/// <summary>
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
/// </summary>
/// <typeparam name="TT"></typeparam>
/// <param name="cacheKey"></param>
/// <param name="priority"></param>
/// <param name="refreshAction"></param>
/// <param name="cacheDependency"></param>
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
/// <param name="getCacheItem"></param>
/// <returns></returns>
public override TT GetCacheItem<TT>(string cacheKey,
CacheItemPriority priority,
CacheItemRemovedCallback refreshAction,
CacheDependency cacheDependency,
TimeSpan? timeout,
Func<TT> getCacheItem)
{
return GetCacheItem(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem, Locker);
}
// NOTE - because we don't know what getCacheItem does, how long it will take and whether it will hang,
// getCacheItem should run OUTSIDE of the global application lock else we run into lock contention and
// nasty performance issues.
/// <summary>
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
/// </summary>
/// <typeparam name="TT"></typeparam>
/// <param name="cacheKey"></param>
/// <param name="priority"></param>
/// <param name="refreshAction"></param>
/// <param name="cacheDependency"></param>
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
/// <param name="getCacheItem"></param>
/// <param name="syncLock"></param>
/// <returns></returns>
private TT GetCacheItem<TT>(string cacheKey,
CacheItemPriority priority, CacheItemRemovedCallback refreshAction,
CacheDependency cacheDependency, TimeSpan? timeout, Func<TT> getCacheItem, object syncLock)
{
var result = _cache.Get(cacheKey);
if (result == null)
// So.... we insert a Lazy<object> in the cache while holding the global application lock, and then rely
// on the Lazy lock to ensure that getCacheItem runs once and everybody waits on it, while the global
// application lock has been released.
// NOTE
// The Lazy value creation may produce a null value.
// Must make sure (for backward compatibility) that we pretend they are not in the cache.
// So if we find an entry in the cache that already has its value created and is null,
// pretend it was not there. If value is not already created, wait... and return null, that's
// what prior code did.
// NOTE
// The Lazy value creation may throw.
// So... the null value _will_ be in the cache but never returned
Lazy<object> result;
// Fast!
// Only one thread can enter an UpgradeableReadLock at a time, but it does not prevent other
// threads to enter a ReadLock in the meantime -- only upgrading to WriteLock will prevent all
// reads. We first try with a normal ReadLock for maximum concurrency and take the penalty of
// having to re-lock in case there's no value. Would need to benchmark to figure out whether
// it's worth it, though...
using (new ReadLock(_locker))
{
lock (syncLock)
result = _cache.Get(cacheKey) as Lazy<object>; // null if key not found
}
var value = result == null ? null : GetSafeLazyValue(result);
if (value != null) return value;
using (var lck = new UpgradeableReadLock(_locker))
{
result = _cache.Get(cacheKey) as Lazy<object>; // null if key not found
// cannot create value within the lock, so if result.IsValueCreated is false, just
// do nothing here - means that if creation throws, a race condition could cause
// more than one thread to reach the return statement below and throw - accepted.
if (result == null || GetSafeLazyValue(result, true) == null) // get non-created as NonCreatedValue & exceptions as null
{
result = _cache.Get(cacheKey);
if (result == null)
{
result = getCacheItem();
if (result != null)
{
//we use Insert instead of add if for some crazy reason there is now a cache with the cache key in there, it will just overwrite it.
_cache.Insert(cacheKey, result, cacheDependency,
timeout == null ? System.Web.Caching.Cache.NoAbsoluteExpiration : DateTime.Now.Add(timeout.Value),
TimeSpan.Zero, priority, refreshAction);
}
}
result = new Lazy<object>(getCacheItem);
var absolute = isSliding ? System.Web.Caching.Cache.NoAbsoluteExpiration : (timeout == null ? System.Web.Caching.Cache.NoAbsoluteExpiration : DateTime.Now.Add(timeout.Value));
var sliding = isSliding == false ? System.Web.Caching.Cache.NoSlidingExpiration : (timeout ?? System.Web.Caching.Cache.NoSlidingExpiration);
lck.UpgradeToWriteLock();
_cache.Insert(cacheKey, result, dependency, absolute, sliding, priority, removedCallback);
}
}
return result.TryConvertTo<TT>().Result;
// this may throw if getCacheItem throws, but this is the only place where
// it would throw as everywhere else we use GetLazySaveValue() to hide exceptions
// and pretend exceptions were never inserted into cache to begin with.
return result.Value;
}
/// <summary>
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="cacheKey"></param>
/// <param name="priority"></param>
/// <param name="getCacheItem"></param>
public override void InsertCacheItem<T>(string cacheKey,
CacheItemPriority priority,
Func<T> getCacheItem)
public object GetCacheItem(string cacheKey, Func<object> getCacheItem, TimeSpan? timeout, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
{
InsertCacheItem(cacheKey, priority, null, null, null, getCacheItem);
}
/// <summary>
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="cacheKey"></param>
/// <param name="priority"></param>
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
/// <param name="getCacheItem"></param>
public override void InsertCacheItem<T>(string cacheKey,
CacheItemPriority priority,
TimeSpan? timeout,
Func<T> getCacheItem)
{
InsertCacheItem(cacheKey, priority, null, null, timeout, getCacheItem);
}
/// <summary>
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="cacheKey"></param>
/// <param name="priority"></param>
/// <param name="cacheDependency"></param>
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
/// <param name="getCacheItem"></param>
public override void InsertCacheItem<T>(string cacheKey,
CacheItemPriority priority,
CacheDependency cacheDependency,
TimeSpan? timeout,
Func<T> getCacheItem)
{
InsertCacheItem(cacheKey, priority, null, cacheDependency, timeout, getCacheItem);
}
/// <summary>
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="cacheKey"></param>
/// <param name="priority"></param>
/// <param name="refreshAction"></param>
/// <param name="cacheDependency"></param>
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
/// <param name="getCacheItem"></param>
public override void InsertCacheItem<T>(string cacheKey,
CacheItemPriority priority,
CacheItemRemovedCallback refreshAction,
CacheDependency cacheDependency,
TimeSpan? timeout,
Func<T> getCacheItem)
{
object result = getCacheItem();
if (result != null)
CacheDependency dependency = null;
if (dependentFiles != null && dependentFiles.Any())
{
//we use Insert instead of add if for some crazy reason there is now a cache with the cache key in there, it will just overwrite it.
_cache.Insert(cacheKey, result, cacheDependency,
timeout == null ? System.Web.Caching.Cache.NoAbsoluteExpiration : DateTime.Now.Add(timeout.Value),
TimeSpan.Zero, priority, refreshAction);
dependency = new CacheDependency(dependentFiles);
}
return GetCacheItem(cacheKey, getCacheItem, timeout, isSliding, priority, removedCallback, dependency);
}
#endregion
#region Insert
/// <summary>
/// This overload is here for legacy purposes
/// </summary>
/// <param name="cacheKey"></param>
/// <param name="getCacheItem"></param>
/// <param name="timeout"></param>
/// <param name="isSliding"></param>
/// <param name="priority"></param>
/// <param name="removedCallback"></param>
/// <param name="dependency"></param>
internal void InsertCacheItem(string cacheKey, Func<object> getCacheItem, TimeSpan? timeout = null, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, CacheDependency dependency = null)
{
// NOTE - here also we must insert a Lazy<object> but we can evaluate it right now
// and make sure we don't store a null value.
var result = new Lazy<object>(getCacheItem);
var value = result.Value; // force evaluation now - this may throw if cacheItem throws, and then nothing goes into cache
if (value == null) return; // do not store null values (backward compat)
cacheKey = GetCacheKey(cacheKey);
var absolute = isSliding ? System.Web.Caching.Cache.NoAbsoluteExpiration : (timeout == null ? System.Web.Caching.Cache.NoAbsoluteExpiration : DateTime.Now.Add(timeout.Value));
var sliding = isSliding == false ? System.Web.Caching.Cache.NoSlidingExpiration : (timeout ?? System.Web.Caching.Cache.NoSlidingExpiration);
using (new WriteLock(_locker))
{
_cache.Insert(cacheKey, result, dependency, absolute, sliding, priority, removedCallback);
}
}
public void InsertCacheItem(string cacheKey, Func<object> getCacheItem, TimeSpan? timeout = null, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
{
CacheDependency dependency = null;
if (dependentFiles != null && dependentFiles.Any())
{
dependency = new CacheDependency(dependentFiles);
}
InsertCacheItem(cacheKey, getCacheItem, timeout, isSliding, priority, removedCallback, dependency);
}
#endregion
}
}
+30
View File
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
namespace Umbraco.Core.Cache
{
/// <summary>
/// An abstract class for implementing a basic cache provider
/// </summary>
public interface ICacheProvider
{
void ClearAllCache();
void ClearCacheItem(string key);
void ClearCacheObjectTypes(string typeName);
void ClearCacheObjectTypes<T>();
void ClearCacheObjectTypes<T>(Func<string, T, bool> predicate);
void ClearCacheByKeySearch(string keyStartsWith);
void ClearCacheByKeyExpression(string regexString);
IEnumerable<object> GetCacheItemsByKeySearch(string keyStartsWith);
IEnumerable<object> GetCacheItemsByKeyExpression(string regexString);
/// <summary>
/// Returns an item with a given key
/// </summary>
/// <param name="cacheKey"></param>
/// <returns></returns>
object GetCacheItem(string cacheKey);
object GetCacheItem(string cacheKey, Func<object> getCacheItem);
}
}
@@ -0,0 +1,35 @@
using System;
using System.Runtime.Caching;
using System.Text;
using System.Web.Caching;
using CacheItemPriority = System.Web.Caching.CacheItemPriority;
namespace Umbraco.Core.Cache
{
/// <summary>
/// An abstract class for implementing a runtime cache provider
/// </summary>
/// <remarks>
/// </remarks>
public interface IRuntimeCacheProvider : ICacheProvider
{
object GetCacheItem(
string cacheKey,
Func<object> getCacheItem,
TimeSpan? timeout,
bool isSliding = false,
CacheItemPriority priority = CacheItemPriority.Normal,
CacheItemRemovedCallback removedCallback = null,
string[] dependentFiles = null);
void InsertCacheItem(
string cacheKey,
Func<object> getCacheItem,
TimeSpan? timeout = null,
bool isSliding = false,
CacheItemPriority priority = CacheItemPriority.Normal,
CacheItemRemovedCallback removedCallback = null,
string[] dependentFiles = null);
}
}
+27 -41
View File
@@ -5,81 +5,67 @@ using System.Web.Caching;
namespace Umbraco.Core.Cache
{
internal class NullCacheProvider : RuntimeCacheProviderBase
internal class NullCacheProvider : IRuntimeCacheProvider
{
public override void ClearAllCache()
public virtual void ClearAllCache()
{
}
public override void ClearCacheItem(string key)
public virtual void ClearCacheItem(string key)
{
}
public override void ClearCacheObjectTypes(string typeName)
public virtual void ClearCacheObjectTypes(string typeName)
{
}
public override void ClearCacheObjectTypes<T>()
public virtual void ClearCacheObjectTypes<T>()
{
}
public override void ClearCacheByKeySearch(string keyStartsWith)
public virtual void ClearCacheObjectTypes<T>(Func<string, T, bool> predicate)
{
}
public override void ClearCacheByKeyExpression(string regexString)
public virtual void ClearCacheByKeySearch(string keyStartsWith)
{
}
public override IEnumerable<T> GetCacheItemsByKeySearch<T>(string keyStartsWith)
public virtual void ClearCacheByKeyExpression(string regexString)
{
return Enumerable.Empty<T>();
}
public override T GetCacheItem<T>(string cacheKey)
public virtual IEnumerable<object> GetCacheItemsByKeySearch(string keyStartsWith)
{
return default(T);
return Enumerable.Empty<object>();
}
public override T GetCacheItem<T>(string cacheKey, Func<T> getCacheItem)
public IEnumerable<object> GetCacheItemsByKeyExpression(string regexString)
{
return Enumerable.Empty<object>();
}
public virtual object GetCacheItem(string cacheKey)
{
return default(object);
}
public virtual object GetCacheItem(string cacheKey, Func<object> getCacheItem)
{
return getCacheItem();
}
public override T GetCacheItem<T>(string cacheKey, TimeSpan? timeout, Func<T> getCacheItem)
public object GetCacheItem(string cacheKey, Func<object> getCacheItem, TimeSpan? timeout, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
{
return getCacheItem();
}
public override T GetCacheItem<T>(string cacheKey, CacheItemRemovedCallback refreshAction, TimeSpan? timeout, Func<T> getCacheItem)
{
return getCacheItem();
}
public override T GetCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan? timeout, Func<T> getCacheItem)
{
return getCacheItem();
}
public override T GetCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, CacheDependency cacheDependency, TimeSpan? timeout, Func<T> getCacheItem)
{
return getCacheItem();
}
public override void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, Func<T> getCacheItem)
{
}
public override void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, TimeSpan? timeout, Func<T> getCacheItem)
{
}
public override void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheDependency cacheDependency, TimeSpan? timeout, Func<T> getCacheItem)
{
}
public override void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, CacheDependency cacheDependency, TimeSpan? timeout, Func<T> getCacheItem)
public void InsertCacheItem(string cacheKey, Func<object> getCacheItem, TimeSpan? timeout = null, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
{
}
}
}
@@ -0,0 +1,288 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.Caching;
using System.Text.RegularExpressions;
using System.Threading;
using System.Web.Caching;
using Umbraco.Core.Logging;
using CacheItemPriority = System.Web.Caching.CacheItemPriority;
namespace Umbraco.Core.Cache
{
/// <summary>
/// A cache provider that wraps the logic of a System.Runtime.Caching.ObjectCache
/// </summary>
internal class ObjectCacheRuntimeCacheProvider : IRuntimeCacheProvider
{
private readonly ReaderWriterLockSlim _locker = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
internal ObjectCache MemoryCache;
// an object that represent a value that has not been created yet
protected readonly object ValueNotCreated = new object();
public ObjectCacheRuntimeCacheProvider()
{
MemoryCache = new MemoryCache("in-memory");
}
protected object GetSafeLazyValue(Lazy<object> lazy, bool onlyIfValueIsCreated = false)
{
try
{
// if onlyIfValueIsCreated, do not trigger value creation
// must return something, though, to differenciate from null values
if (onlyIfValueIsCreated && lazy.IsValueCreated == false) return ValueNotCreated;
return lazy.Value;
}
catch
{
return null;
}
}
#region Clear
public virtual void ClearAllCache()
{
using (new WriteLock(_locker))
{
MemoryCache.DisposeIfDisposable();
MemoryCache = new MemoryCache("in-memory");
}
}
public virtual void ClearCacheItem(string key)
{
using (new WriteLock(_locker))
{
if (MemoryCache[key] == null) return;
MemoryCache.Remove(key);
}
}
public virtual void ClearCacheObjectTypes(string typeName)
{
using (new WriteLock(_locker))
{
foreach (var key in MemoryCache
.Where(x =>
{
// x.Value is Lazy<object> and not null, its value may be null
// remove null values as well, does not hurt
// get non-created as NonCreatedValue & exceptions as null
var value = GetSafeLazyValue((Lazy<object>)x.Value, true);
return value == null || value.GetType().ToString().InvariantEquals(typeName);
})
.Select(x => x.Key)
.ToArray()) // ToArray required to remove
MemoryCache.Remove(key);
}
}
public virtual void ClearCacheObjectTypes<T>()
{
using (new WriteLock(_locker))
{
var typeOfT = typeof (T);
foreach (var key in MemoryCache
.Where(x =>
{
// x.Value is Lazy<object> and not null, its value may be null
// remove null values as well, does not hurt
// get non-created as NonCreatedValue & exceptions as null
var value = GetSafeLazyValue((Lazy<object>)x.Value, true);
return value == null || value.GetType() == typeOfT;
})
.Select(x => x.Key)
.ToArray()) // ToArray required to remove
MemoryCache.Remove(key);
}
}
public virtual void ClearCacheObjectTypes<T>(Func<string, T, bool> predicate)
{
using (new WriteLock(_locker))
{
var typeOfT = typeof(T);
foreach (var key in MemoryCache
.Where(x =>
{
// x.Value is Lazy<object> and not null, its value may be null
// remove null values as well, does not hurt
// get non-created as NonCreatedValue & exceptions as null
var value = GetSafeLazyValue((Lazy<object>)x.Value, true);
if (value == null) return true;
return value.GetType() == typeOfT
&& predicate(x.Key, (T) value);
})
.Select(x => x.Key)
.ToArray()) // ToArray required to remove
MemoryCache.Remove(key);
}
}
public virtual void ClearCacheByKeySearch(string keyStartsWith)
{
using (new WriteLock(_locker))
{
foreach (var key in MemoryCache
.Where(x => x.Key.InvariantStartsWith(keyStartsWith))
.Select(x => x.Key)
.ToArray()) // ToArray required to remove
MemoryCache.Remove(key);
}
}
public virtual void ClearCacheByKeyExpression(string regexString)
{
using (new WriteLock(_locker))
{
foreach (var key in MemoryCache
.Where(x => Regex.IsMatch(x.Key, regexString))
.Select(x => x.Key)
.ToArray()) // ToArray required to remove
MemoryCache.Remove(key);
}
}
#endregion
#region Get
public IEnumerable<object> GetCacheItemsByKeySearch(string keyStartsWith)
{
KeyValuePair<string, object>[] entries;
using (new ReadLock(_locker))
{
entries = MemoryCache
.Where(x => x.Key.InvariantStartsWith(keyStartsWith))
.ToArray(); // evaluate while locked
}
return entries
.Select(x => GetSafeLazyValue((Lazy<object>)x.Value)) // return exceptions as null
.Where(x => x != null) // backward compat, don't store null values in the cache
.ToList();
}
public IEnumerable<object> GetCacheItemsByKeyExpression(string regexString)
{
KeyValuePair<string, object>[] entries;
using (new ReadLock(_locker))
{
entries = MemoryCache
.Where(x => Regex.IsMatch(x.Key, regexString))
.ToArray(); // evaluate while locked
}
return entries
.Select(x => GetSafeLazyValue((Lazy<object>)x.Value)) // return exceptions as null
.Where(x => x != null) // backward compat, don't store null values in the cache
.ToList();
}
public object GetCacheItem(string cacheKey)
{
Lazy<object> result;
using (new ReadLock(_locker))
{
result = MemoryCache.Get(cacheKey) as Lazy<object>; // null if key not found
}
return result == null ? null : GetSafeLazyValue(result); // return exceptions as null
}
public object GetCacheItem(string cacheKey, Func<object> getCacheItem)
{
return GetCacheItem(cacheKey, getCacheItem, null);
}
public object GetCacheItem(string cacheKey, Func<object> getCacheItem, TimeSpan? timeout, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal,CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
{
// see notes in HttpRuntimeCacheProvider
Lazy<object> result;
using (var lck = new UpgradeableReadLock(_locker))
{
result = MemoryCache.Get(cacheKey) as Lazy<object>;
if (result == null || GetSafeLazyValue(result, true) == null) // get non-created as NonCreatedValue & exceptions as null
{
result = new Lazy<object>(getCacheItem);
var policy = GetPolicy(timeout, isSliding, removedCallback, dependentFiles);
lck.UpgradeToWriteLock();
MemoryCache.Set(cacheKey, result, policy);
}
}
return result.Value;
}
#endregion
#region Insert
public void InsertCacheItem(string cacheKey, Func<object> getCacheItem, TimeSpan? timeout = null, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
{
// NOTE - here also we must insert a Lazy<object> but we can evaluate it right now
// and make sure we don't store a null value.
var result = new Lazy<object>(getCacheItem);
var value = result.Value; // force evaluation now
if (value == null) return; // do not store null values (backward compat)
var policy = GetPolicy(timeout, isSliding, removedCallback, dependentFiles);
MemoryCache.Set(cacheKey, result, policy);
}
#endregion
private static CacheItemPolicy GetPolicy(TimeSpan? timeout = null, bool isSliding = false, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
{
var absolute = isSliding ? ObjectCache.InfiniteAbsoluteExpiration : (timeout == null ? ObjectCache.InfiniteAbsoluteExpiration : DateTime.Now.Add(timeout.Value));
var sliding = isSliding == false ? ObjectCache.NoSlidingExpiration : (timeout ?? ObjectCache.NoSlidingExpiration);
var policy = new CacheItemPolicy
{
AbsoluteExpiration = absolute,
SlidingExpiration = sliding
};
if (dependentFiles != null && dependentFiles.Any())
{
policy.ChangeMonitors.Add(new HostFileChangeMonitor(dependentFiles.ToList()));
}
if (removedCallback != null)
{
policy.RemovedCallback = arguments =>
{
//convert the reason
var reason = CacheItemRemovedReason.Removed;
switch (arguments.RemovedReason)
{
case CacheEntryRemovedReason.Removed:
reason = CacheItemRemovedReason.Removed;
break;
case CacheEntryRemovedReason.Expired:
reason = CacheItemRemovedReason.Expired;
break;
case CacheEntryRemovedReason.Evicted:
reason = CacheItemRemovedReason.Underused;
break;
case CacheEntryRemovedReason.ChangeMonitorChanged:
reason = CacheItemRemovedReason.Expired;
break;
case CacheEntryRemovedReason.CacheSpecificEviction:
reason = CacheItemRemovedReason.Underused;
break;
}
//call the callback
removedCallback(arguments.CacheItem.Key, arguments.CacheItem.Value, reason);
};
}
return policy;
}
}
}
@@ -1,24 +0,0 @@
using System;
using System.Text;
using System.Web.Caching;
namespace Umbraco.Core.Cache
{
/// <summary>
/// An abstract class for implementing a runtime cache provider
/// </summary>
/// <remarks>
/// THIS MUST REMAIN INTERNAL UNTIL WE STREAMLINE HOW ALL CACHE IS HANDLED, WE NEED TO SUPPORT HTTP RUNTIME CACHE, IN MEMORY CACHE, REQUEST CACHE, ETC...
/// </remarks>
internal abstract class RuntimeCacheProviderBase : CacheProviderBase
{
public abstract T GetCacheItem<T>(string cacheKey, TimeSpan? timeout, Func<T> getCacheItem);
public abstract T GetCacheItem<T>(string cacheKey, CacheItemRemovedCallback refreshAction, TimeSpan? timeout, Func<T> getCacheItem);
public abstract T GetCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan? timeout, Func<T> getCacheItem);
public abstract T GetCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, CacheDependency cacheDependency, TimeSpan? timeout, Func<T> getCacheItem);
public abstract void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, Func<T> getCacheItem);
public abstract void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, TimeSpan? timeout, Func<T> getCacheItem);
public abstract void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheDependency cacheDependency, TimeSpan? timeout, Func<T> getCacheItem);
public abstract void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, CacheDependency cacheDependency, TimeSpan? timeout, Func<T> getCacheItem);
}
}
+36 -57
View File
@@ -10,92 +10,71 @@ namespace Umbraco.Core.Cache
/// <summary>
/// A cache provider that statically caches everything in an in memory dictionary
/// </summary>
internal class StaticCacheProvider : CacheProviderBase
internal class StaticCacheProvider : ICacheProvider
{
private readonly ConcurrentDictionary<string, object> _staticCache = new ConcurrentDictionary<string, object>();
internal readonly ConcurrentDictionary<string, object> StaticCache = new ConcurrentDictionary<string, object>();
public override void ClearAllCache()
public virtual void ClearAllCache()
{
_staticCache.Clear();
StaticCache.Clear();
}
public override void ClearCacheItem(string key)
public virtual void ClearCacheItem(string key)
{
object val;
_staticCache.TryRemove(key, out val);
StaticCache.TryRemove(key, out val);
}
public override void ClearCacheObjectTypes(string typeName)
public virtual void ClearCacheObjectTypes(string typeName)
{
foreach (var key in _staticCache.Keys)
{
if (_staticCache[key] != null
&& _staticCache[key].GetType().ToString().InvariantEquals(typeName))
{
object val;
_staticCache.TryRemove(key, out val);
}
}
StaticCache.RemoveAll(kvp => kvp.Value != null && kvp.Value.GetType().ToString().InvariantEquals(typeName));
}
public override void ClearCacheObjectTypes<T>()
public virtual void ClearCacheObjectTypes<T>()
{
foreach (var key in _staticCache.Keys)
{
if (_staticCache[key] != null
&& _staticCache[key].GetType() == typeof(T))
{
object val;
_staticCache.TryRemove(key, out val);
}
}
var typeOfT = typeof(T);
StaticCache.RemoveAll(kvp => kvp.Value != null && kvp.Value.GetType() == typeOfT);
}
public override void ClearCacheByKeySearch(string keyStartsWith)
public virtual void ClearCacheObjectTypes<T>(Func<string, T, bool> predicate)
{
foreach (var key in _staticCache.Keys)
{
if (key.InvariantStartsWith(keyStartsWith))
{
ClearCacheItem(key);
}
}
var typeOfT = typeof(T);
StaticCache.RemoveAll(kvp => kvp.Value != null && kvp.Value.GetType() == typeOfT && predicate(kvp.Key, (T)kvp.Value));
}
public override void ClearCacheByKeyExpression(string regexString)
public virtual void ClearCacheByKeySearch(string keyStartsWith)
{
foreach (var key in _staticCache.Keys)
{
if (Regex.IsMatch(key, regexString))
{
ClearCacheItem(key);
}
}
StaticCache.RemoveAll(kvp => kvp.Key.InvariantStartsWith(keyStartsWith));
}
public override IEnumerable<T> GetCacheItemsByKeySearch<T>(string keyStartsWith)
public virtual void ClearCacheByKeyExpression(string regexString)
{
return (from KeyValuePair<string, object> c in _staticCache
StaticCache.RemoveAll(kvp => Regex.IsMatch(kvp.Key, regexString));
}
public virtual IEnumerable<object> GetCacheItemsByKeySearch(string keyStartsWith)
{
return (from KeyValuePair<string, object> c in StaticCache
where c.Key.InvariantStartsWith(keyStartsWith)
select c.Value.TryConvertTo<T>()
into attempt
where attempt.Success
select attempt.Result).ToList();
select c.Value).ToList();
}
public override T GetCacheItem<T>(string cacheKey)
public IEnumerable<object> GetCacheItemsByKeyExpression(string regexString)
{
var result = _staticCache[cacheKey];
if (result == null)
{
return default(T);
}
return result.TryConvertTo<T>().Result;
return (from KeyValuePair<string, object> c in StaticCache
where Regex.IsMatch(c.Key, regexString)
select c.Value).ToList();
}
public override T GetCacheItem<T>(string cacheKey, Func<T> getCacheItem)
public virtual object GetCacheItem(string cacheKey)
{
return (T)_staticCache.GetOrAdd(cacheKey, getCacheItem);
var result = StaticCache[cacheKey];
return result;
}
public virtual object GetCacheItem(string cacheKey, Func<object> getCacheItem)
{
return StaticCache.GetOrAdd(cacheKey, key => getCacheItem());
}
}
+165 -193
View File
@@ -12,195 +12,130 @@ using Umbraco.Core.Logging;
namespace Umbraco.Core
{
/// <summary>
/// Class that is exposed by the ApplicationContext for application wide caching purposes
/// </summary>
/// <summary>
/// Class that is exposed by the ApplicationContext for application wide caching purposes
/// </summary>
public class CacheHelper
{
private readonly bool _enableCache;
private readonly CacheProviderBase _staticCache;
private readonly CacheProviderBase _nullStaticCache = new NullCacheProvider();
private readonly RuntimeCacheProviderBase _httpCache;
private readonly RuntimeCacheProviderBase _nullHttpCache = new NullCacheProvider();
{
private readonly bool _enableCache;
private readonly ICacheProvider _requestCache;
private readonly ICacheProvider _nullRequestCache = new NullCacheProvider();
private readonly ICacheProvider _staticCache;
private readonly ICacheProvider _nullStaticCache = new NullCacheProvider();
private readonly IRuntimeCacheProvider _httpCache;
private readonly IRuntimeCacheProvider _nullHttpCache = new NullCacheProvider();
public CacheHelper(System.Web.Caching.Cache cache)
: this(cache, true)
{
}
/// <summary>
/// Creates a cache helper with disabled caches
/// </summary>
/// <returns></returns>
/// <remarks>
/// Good for unit testing
/// </remarks>
public static CacheHelper CreateDisabledCacheHelper()
{
return new CacheHelper(null, null, null, false);
}
internal CacheHelper(System.Web.Caching.Cache cache, bool enableCache)
: this(new HttpRuntimeCacheProvider(cache), enableCache)
{
}
internal CacheHelper(RuntimeCacheProviderBase httpCacheProvider, bool enableCache)
: this(httpCacheProvider, new StaticCacheProvider(), enableCache)
/// <summary>
/// Initializes a new instance for use in the web
/// </summary>
public CacheHelper()
: this(
new HttpRuntimeCacheProvider(HttpRuntime.Cache),
new StaticCacheProvider(),
new HttpRequestCacheProvider())
{
}
internal CacheHelper(RuntimeCacheProviderBase httpCacheProvider, CacheProviderBase staticCacheProvider, bool enableCache)
/// <summary>
/// Initializes a new instance for use in the web
/// </summary>
/// <param name="cache"></param>
public CacheHelper(System.Web.Caching.Cache cache)
: this(
new HttpRuntimeCacheProvider(cache),
new StaticCacheProvider(),
new HttpRequestCacheProvider())
{
_httpCache = httpCacheProvider;
_staticCache = staticCacheProvider;
}
/// <summary>
/// Initializes a new instance based on the provided providers
/// </summary>
/// <param name="httpCacheProvider"></param>
/// <param name="staticCacheProvider"></param>
/// <param name="requestCacheProvider"></param>
public CacheHelper(
IRuntimeCacheProvider httpCacheProvider,
ICacheProvider staticCacheProvider,
ICacheProvider requestCacheProvider)
: this(httpCacheProvider, staticCacheProvider, requestCacheProvider, true)
{
}
/// <summary>
/// Private ctor used for creating a disabled cache helper
/// </summary>
/// <param name="httpCacheProvider"></param>
/// <param name="staticCacheProvider"></param>
/// <param name="requestCacheProvider"></param>
/// <param name="enableCache"></param>
private CacheHelper(
IRuntimeCacheProvider httpCacheProvider,
ICacheProvider staticCacheProvider,
ICacheProvider requestCacheProvider,
bool enableCache)
{
if (enableCache)
{
_httpCache = httpCacheProvider;
_staticCache = staticCacheProvider;
_requestCache = requestCacheProvider;
}
else
{
_httpCache = null;
_staticCache = null;
_requestCache = null;
}
_enableCache = enableCache;
}
#region Static cache
/// <summary>
/// Clears the item in umbraco's static cache
/// Returns the current Request cache
/// </summary>
internal void ClearAllStaticCache()
public ICacheProvider RequestCache
{
if (!_enableCache)
{
_nullStaticCache.ClearAllCache();
}
else
{
_staticCache.ClearAllCache();
}
get { return _enableCache ? _requestCache : _nullRequestCache; }
}
/// <summary>
/// Clears the item in umbraco's static cache with the given key
/// Returns the current Runtime cache
/// </summary>
/// <param name="key">Key</param>
internal void ClearStaticCacheItem(string key)
public ICacheProvider StaticCache
{
if (!_enableCache)
{
_nullStaticCache.ClearCacheItem(key);
}
else
{
_staticCache.ClearCacheItem(key);
}
get { return _enableCache ? _staticCache : _nullStaticCache; }
}
/// <summary>
/// Clears all objects in the static cache with the System.Type name as the
/// input parameter. (using [object].GetType())
/// Returns the current Runtime cache
/// </summary>
/// <param name="typeName">The name of the System.Type which should be cleared from cache ex "System.Xml.XmlDocument"</param>
internal void ClearStaticCacheObjectTypes(string typeName)
public IRuntimeCacheProvider RuntimeCache
{
if (!_enableCache)
{
_nullStaticCache.ClearCacheObjectTypes(typeName);
}
else
{
_staticCache.ClearCacheObjectTypes(typeName);
}
get { return _enableCache ? _httpCache : _nullHttpCache; }
}
/// <summary>
/// Clears all objects in the static cache with the System.Type specified
/// </summary>
internal void ClearStaticCacheObjectTypes<T>()
{
if (!_enableCache)
{
_nullStaticCache.ClearCacheObjectTypes<T>();
}
else
{
_staticCache.ClearCacheObjectTypes<T>();
}
}
#region Legacy Runtime/Http Cache accessors
/// <summary>
/// Clears all static cache items that starts with the key passed.
/// </summary>
/// <param name="keyStartsWith">The start of the key</param>
internal void ClearStaticCacheByKeySearch(string keyStartsWith)
{
if (!_enableCache)
{
_nullStaticCache.ClearCacheByKeySearch(keyStartsWith);
}
else
{
_staticCache.ClearCacheByKeySearch(keyStartsWith);
}
}
/// <summary>
/// Clears all cache items that have a key that matches the regular expression
/// </summary>
/// <param name="regexString"></param>
internal void ClearStaticCacheByKeyExpression(string regexString)
{
if (!_enableCache)
{
_nullStaticCache.ClearCacheByKeyExpression(regexString);
}
else
{
_staticCache.ClearCacheByKeyExpression(regexString);
}
}
internal IEnumerable<T> GetStaticCacheItemsByKeySearch<T>(string keyStartsWith)
{
if (!_enableCache)
{
return _nullStaticCache.GetCacheItemsByKeySearch<T>(keyStartsWith);
}
else
{
return _staticCache.GetCacheItemsByKeySearch<T>(keyStartsWith);
}
}
/// <summary>
/// Returns a static cache item by key, does not update the cache if it isn't there.
/// </summary>
/// <typeparam name="TT"></typeparam>
/// <param name="cacheKey"></param>
/// <returns></returns>
internal TT GetStaticCacheItem<TT>(string cacheKey)
{
if (!_enableCache)
{
return _nullStaticCache.GetCacheItem<TT>(cacheKey);
}
else
{
return _staticCache.GetCacheItem<TT>(cacheKey);
}
}
/// <summary>
/// Gets (and adds if necessary) an item from the static cache with all of the default parameters
/// </summary>
/// <typeparam name="TT"></typeparam>
/// <param name="cacheKey"></param>
/// <param name="getCacheItem"></param>
/// <returns></returns>
internal TT GetStaticCacheItem<TT>(string cacheKey, Func<TT> getCacheItem)
{
if (!_enableCache)
{
return _nullStaticCache.GetCacheItem<TT>(cacheKey, getCacheItem);
}
else
{
return _staticCache.GetCacheItem<TT>(cacheKey, getCacheItem);
}
}
#endregion
#region Runtime/Http Cache
/// <summary>
/// Clears the item in umbraco's runtime cache
/// </summary>
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
public void ClearAllCache()
{
if (!_enableCache)
if (_enableCache == false)
{
_nullHttpCache.ClearAllCache();
}
@@ -214,9 +149,10 @@ namespace Umbraco.Core
/// Clears the item in umbraco's runtime cache with the given key
/// </summary>
/// <param name="key">Key</param>
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
public void ClearCacheItem(string key)
{
if (!_enableCache)
if (_enableCache == false)
{
_nullHttpCache.ClearCacheItem(key);
}
@@ -232,9 +168,10 @@ namespace Umbraco.Core
/// input parameter. (using [object].GetType())
/// </summary>
/// <param name="typeName">The name of the System.Type which should be cleared from cache ex "System.Xml.XmlDocument"</param>
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
public void ClearCacheObjectTypes(string typeName)
{
if (!_enableCache)
if (_enableCache == false)
{
_nullHttpCache.ClearCacheObjectTypes(typeName);
}
@@ -247,9 +184,10 @@ namespace Umbraco.Core
/// <summary>
/// Clears all objects in the System.Web.Cache with the System.Type specified
/// </summary>
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
public void ClearCacheObjectTypes<T>()
{
if (!_enableCache)
if (_enableCache == false)
{
_nullHttpCache.ClearCacheObjectTypes<T>();
}
@@ -263,9 +201,10 @@ namespace Umbraco.Core
/// Clears all cache items that starts with the key passed.
/// </summary>
/// <param name="keyStartsWith">The start of the key</param>
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
public void ClearCacheByKeySearch(string keyStartsWith)
{
if (!_enableCache)
if (_enableCache == false)
{
_nullHttpCache.ClearCacheByKeySearch(keyStartsWith);
}
@@ -279,9 +218,10 @@ namespace Umbraco.Core
/// Clears all cache items that have a key that matches the regular expression
/// </summary>
/// <param name="regexString"></param>
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
public void ClearCacheByKeyExpression(string regexString)
{
if (!_enableCache)
if (_enableCache == false)
{
_nullHttpCache.ClearCacheByKeyExpression(regexString);
}
@@ -291,9 +231,10 @@ namespace Umbraco.Core
}
}
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
public IEnumerable<T> GetCacheItemsByKeySearch<T>(string keyStartsWith)
{
if (!_enableCache)
if (_enableCache == false)
{
return _nullHttpCache.GetCacheItemsByKeySearch<T>(keyStartsWith);
}
@@ -309,9 +250,10 @@ namespace Umbraco.Core
/// <typeparam name="TT"></typeparam>
/// <param name="cacheKey"></param>
/// <returns></returns>
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
public TT GetCacheItem<TT>(string cacheKey)
{
if (!_enableCache)
if (_enableCache == false)
{
return _nullHttpCache.GetCacheItem<TT>(cacheKey);
}
@@ -328,9 +270,10 @@ namespace Umbraco.Core
/// <param name="cacheKey"></param>
/// <param name="getCacheItem"></param>
/// <returns></returns>
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
public TT GetCacheItem<TT>(string cacheKey, Func<TT> getCacheItem)
{
if (!_enableCache)
if (_enableCache == false)
{
return _nullHttpCache.GetCacheItem<TT>(cacheKey, getCacheItem);
}
@@ -348,16 +291,17 @@ namespace Umbraco.Core
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
/// <param name="getCacheItem"></param>
/// <returns></returns>
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
public TT GetCacheItem<TT>(string cacheKey,
TimeSpan timeout, Func<TT> getCacheItem)
{
if (!_enableCache)
if (_enableCache == false)
{
return _nullHttpCache.GetCacheItem<TT>(cacheKey, timeout, getCacheItem);
return _nullHttpCache.GetCacheItem<TT>(cacheKey, getCacheItem, timeout);
}
else
{
return _httpCache.GetCacheItem<TT>(cacheKey, timeout, getCacheItem);
return _httpCache.GetCacheItem<TT>(cacheKey, getCacheItem, timeout);
}
}
@@ -370,17 +314,18 @@ namespace Umbraco.Core
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
/// <param name="getCacheItem"></param>
/// <returns></returns>
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
public TT GetCacheItem<TT>(string cacheKey,
CacheItemRemovedCallback refreshAction, TimeSpan timeout,
Func<TT> getCacheItem)
{
if (!_enableCache)
{
return _nullHttpCache.GetCacheItem<TT>(cacheKey, refreshAction, timeout, getCacheItem);
return _nullHttpCache.GetCacheItem<TT>(cacheKey, getCacheItem, timeout, removedCallback: refreshAction);
}
else
{
return _httpCache.GetCacheItem<TT>(cacheKey, refreshAction, timeout, getCacheItem);
return _httpCache.GetCacheItem<TT>(cacheKey, getCacheItem, timeout, removedCallback: refreshAction);
}
}
@@ -394,17 +339,18 @@ namespace Umbraco.Core
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
/// <param name="getCacheItem"></param>
/// <returns></returns>
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
public TT GetCacheItem<TT>(string cacheKey,
CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan timeout,
Func<TT> getCacheItem)
{
if (!_enableCache)
if (_enableCache == false)
{
return _nullHttpCache.GetCacheItem<TT>(cacheKey, priority, refreshAction, timeout, getCacheItem);
return _nullHttpCache.GetCacheItem<TT>(cacheKey, getCacheItem, timeout, false, priority, refreshAction);
}
else
{
return _httpCache.GetCacheItem<TT>(cacheKey, priority, refreshAction, timeout, getCacheItem);
return _httpCache.GetCacheItem<TT>(cacheKey, getCacheItem, timeout, false, priority, refreshAction);
}
}
@@ -419,6 +365,7 @@ namespace Umbraco.Core
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
/// <param name="getCacheItem"></param>
/// <returns></returns>
[Obsolete("Do not use this method, we no longer support the caching overloads with references to CacheDependency, use the overloads specifying a file collection instead")]
public TT GetCacheItem<TT>(string cacheKey,
CacheItemPriority priority,
CacheItemRemovedCallback refreshAction,
@@ -426,13 +373,19 @@ namespace Umbraco.Core
TimeSpan timeout,
Func<TT> getCacheItem)
{
if (!_enableCache)
if (_enableCache == false)
{
return _nullHttpCache.GetCacheItem<TT>(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem);
return _nullHttpCache.GetCacheItem<TT>(cacheKey, getCacheItem, timeout, false, priority, refreshAction, null);
}
else
{
return _httpCache.GetCacheItem<TT>(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem);
var cache = _httpCache as HttpRuntimeCacheProvider;
if (cache != null)
{
var result = cache.GetCacheItem(cacheKey, () => getCacheItem(), timeout, false, priority, refreshAction, cacheDependency);
return result == null ? default(TT) : result.TryConvertTo<TT>().Result;
}
throw new InvalidOperationException("Cannot use this obsoleted overload when the current provider is not of type " + typeof(HttpRuntimeCacheProvider));
}
}
@@ -445,6 +398,7 @@ namespace Umbraco.Core
/// <param name="cacheDependency"></param>
/// <param name="getCacheItem"></param>
/// <returns></returns>
[Obsolete("Do not use this method, we no longer support the caching overloads with references to CacheDependency, use the overloads specifying a file collection instead")]
public TT GetCacheItem<TT>(string cacheKey,
CacheItemPriority priority,
CacheDependency cacheDependency,
@@ -452,11 +406,17 @@ namespace Umbraco.Core
{
if (!_enableCache)
{
return _nullHttpCache.GetCacheItem<TT>(cacheKey, priority, null, cacheDependency, null, getCacheItem);
return _nullHttpCache.GetCacheItem<TT>(cacheKey, getCacheItem, null, false, priority, null, null);
}
else
{
return _httpCache.GetCacheItem<TT>(cacheKey, priority, null, cacheDependency, null, getCacheItem);
var cache = _httpCache as HttpRuntimeCacheProvider;
if (cache != null)
{
var result = cache.GetCacheItem(cacheKey, () => getCacheItem(), null, false, priority, null, cacheDependency);
return result == null ? default(TT) : result.TryConvertTo<TT>().Result;
}
throw new InvalidOperationException("Cannot use this obsoleted overload when the current provider is not of type " + typeof(HttpRuntimeCacheProvider));
}
}
@@ -471,13 +431,13 @@ namespace Umbraco.Core
CacheItemPriority priority,
Func<T> getCacheItem)
{
if (!_enableCache)
if (_enableCache == false)
{
_nullHttpCache.InsertCacheItem<T>(cacheKey, priority, getCacheItem);
_nullHttpCache.InsertCacheItem<T>(cacheKey, getCacheItem, priority: priority);
}
else
{
_httpCache.InsertCacheItem<T>(cacheKey, priority, getCacheItem);
_httpCache.InsertCacheItem<T>(cacheKey, getCacheItem, priority: priority);
}
}
@@ -494,13 +454,13 @@ namespace Umbraco.Core
TimeSpan timeout,
Func<T> getCacheItem)
{
if (!_enableCache)
if (_enableCache == false)
{
_nullHttpCache.InsertCacheItem<T>(cacheKey, priority, timeout, getCacheItem);
_nullHttpCache.InsertCacheItem<T>(cacheKey, getCacheItem, timeout, priority: priority);
}
else
{
_httpCache.InsertCacheItem<T>(cacheKey, priority, timeout, getCacheItem);
_httpCache.InsertCacheItem<T>(cacheKey, getCacheItem, timeout, priority: priority);
}
}
@@ -513,19 +473,25 @@ namespace Umbraco.Core
/// <param name="cacheDependency"></param>
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
/// <param name="getCacheItem"></param>
[Obsolete("Do not use this method, we no longer support the caching overloads with references to CacheDependency, use the overloads specifying a file collection instead")]
public void InsertCacheItem<T>(string cacheKey,
CacheItemPriority priority,
CacheDependency cacheDependency,
TimeSpan timeout,
Func<T> getCacheItem)
{
if (!_enableCache)
if (_enableCache == false)
{
_nullHttpCache.InsertCacheItem<T>(cacheKey, priority, cacheDependency, timeout, getCacheItem);
_nullHttpCache.InsertCacheItem<T>(cacheKey, getCacheItem, timeout, priority: priority, dependentFiles: null);
}
else
{
_httpCache.InsertCacheItem<T>(cacheKey, priority, cacheDependency, timeout, getCacheItem);
var cache = _httpCache as HttpRuntimeCacheProvider;
if (cache != null)
{
cache.InsertCacheItem(cacheKey, () => getCacheItem(), timeout, false, priority, null, cacheDependency);
}
throw new InvalidOperationException("Cannot use this obsoleted overload when the current provider is not of type " + typeof(HttpRuntimeCacheProvider));
}
}
@@ -539,6 +505,7 @@ namespace Umbraco.Core
/// <param name="cacheDependency"></param>
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
/// <param name="getCacheItem"></param>
[Obsolete("Do not use this method, we no longer support the caching overloads with references to CacheDependency, use the overloads specifying a file collection instead")]
public void InsertCacheItem<T>(string cacheKey,
CacheItemPriority priority,
CacheItemRemovedCallback refreshAction,
@@ -546,17 +513,22 @@ namespace Umbraco.Core
TimeSpan? timeout,
Func<T> getCacheItem)
{
if (!_enableCache)
if (_enableCache == false)
{
_nullHttpCache.InsertCacheItem<T>(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem);
_nullHttpCache.InsertCacheItem<T>(cacheKey, getCacheItem, timeout, false, priority, refreshAction, null);
}
else
{
_httpCache.InsertCacheItem<T>(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem);
var cache = _httpCache as HttpRuntimeCacheProvider;
if (cache != null)
{
cache.InsertCacheItem(cacheKey, () => getCacheItem(), timeout, false, priority, refreshAction, cacheDependency);
}
throw new InvalidOperationException("Cannot use this obsoleted overload when the current provider is not of type " + typeof(HttpRuntimeCacheProvider));
}
}
}
#endregion
}
}
}
+1 -1
View File
@@ -27,7 +27,7 @@ namespace Umbraco.Core
/// <summary>
/// Gets the <see cref="ICacheRefresher"/> implementations.
/// </summary>
public IEnumerable<ICacheRefresher> CacheResolvers
public IEnumerable<ICacheRefresher> CacheRefreshers
{
get
{
@@ -16,7 +16,7 @@ namespace Umbraco.Core.Configuration
}
/// <summary>
/// Increases the version number in ClientDependency.config by 1
/// Changes the version number in ClientDependency.config to a random value to avoid stale caches
/// </summary>
internal bool IncreaseVersionNumber()
{
@@ -28,9 +28,9 @@ namespace Umbraco.Core.Configuration
var versionAttribute = clientDependencyConfigXml.Root.Attribute("version");
int oldVersion;
int.TryParse(versionAttribute.Value, out oldVersion);
var newVersion = oldVersion + 1;
//Set the new version to the hashcode of now
var oldVersion = versionAttribute.Value;
var newVersion = Math.Abs(DateTime.UtcNow.GetHashCode());
versionAttribute.SetValue(newVersion);
clientDependencyConfigXml.Save(_fileName, SaveOptions.DisableFormatting);
@@ -5,10 +5,13 @@ using System.Linq;
using System.Web;
using System.Web.Configuration;
using System.Web.Routing;
using System.Web.Security;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Security;
namespace Umbraco.Core.Configuration
{
@@ -175,7 +178,10 @@ namespace Umbraco.Core.Configuration
{
throw new InvalidOperationException("Cannot create an MVC Area path without the umbracoPath specified");
}
return Path.TrimStart(SystemDirectories.Root).TrimStart('~').TrimStart('/').Replace('/', '-').Trim().ToLower();
var path = Path;
if (path.StartsWith(SystemDirectories.Root)) // beware of TrimStart, see U4-2518
path = path.Substring(SystemDirectories.Root.Length);
return path.TrimStart('~').TrimStart('/').Replace('/', '-').Trim().ToLower();
}
}
@@ -197,7 +203,7 @@ namespace Umbraco.Core.Configuration
/// Gets the database connection string
/// </summary>
/// <value>The database connection string.</value>
[Obsolete("Use System.ConfigurationManager.ConnectionStrings to get the connection with the key Umbraco.Core.Configuration.GlobalSettings.UmbracoConnectionName instead")]
[Obsolete("Use System.Configuration.ConfigurationManager.ConnectionStrings[\"umbracoDbDSN\"] instead")]
public static string DbDsn
{
get
@@ -209,7 +215,7 @@ namespace Umbraco.Core.Configuration
{
connectionString = settings.ConnectionString;
// The SqlCe connectionString is formatted slightly differently, so we need to updat it
// The SqlCe connectionString is formatted slightly differently, so we need to update it
if (settings.ProviderName.Contains("SqlServerCe"))
connectionString = string.Format("datalayer=SQLCE4Umbraco.SqlCEHelper,SQLCE4Umbraco;{0}", connectionString);
}
@@ -252,7 +258,38 @@ namespace Umbraco.Core.Configuration
SaveSetting("umbracoConfigurationStatus", value);
}
}
/// <summary>
/// Gets or sets the Umbraco members membership providers' useLegacyEncoding state. This will return a boolean
/// </summary>
/// <value>The useLegacyEncoding status.</value>
public static bool UmbracoMembershipProviderLegacyEncoding
{
get
{
return IsConfiguredMembershipProviderUsingLegacyEncoding(Constants.Conventions.Member.UmbracoMemberProviderName);
}
set
{
SetMembershipProvidersLegacyEncoding(Constants.Conventions.Member.UmbracoMemberProviderName, value);
}
}
/// <summary>
/// Gets or sets the Umbraco users membership providers' useLegacyEncoding state. This will return a boolean
/// </summary>
/// <value>The useLegacyEncoding status.</value>
public static bool UmbracoUsersMembershipProviderLegacyEncoding
{
get
{
return IsConfiguredMembershipProviderUsingLegacyEncoding(UmbracoSettings.DefaultBackofficeProvider);
}
set
{
SetMembershipProvidersLegacyEncoding(UmbracoSettings.DefaultBackofficeProvider, value);
}
}
/// <summary>
/// Saves a setting into the configuration file.
@@ -312,6 +349,38 @@ namespace Umbraco.Core.Configuration
return fileName;
}
private static void SetMembershipProvidersLegacyEncoding(string providerName, bool useLegacyEncoding)
{
var webConfigFilename = GetFullWebConfigFileName();
var webConfigXml = XDocument.Load(webConfigFilename, LoadOptions.PreserveWhitespace);
var membershipConfigs = webConfigXml.XPathSelectElements("configuration/system.web/membership/providers/add").ToList();
if (membershipConfigs.Any() == false)
return;
var provider = membershipConfigs.SingleOrDefault(c => c.Attribute("name") != null && c.Attribute("name").Value == providerName);
if (provider == null)
return;
provider.SetAttributeValue("useLegacyEncoding", useLegacyEncoding);
webConfigXml.Save(webConfigFilename, SaveOptions.DisableFormatting);
}
private static bool IsConfiguredMembershipProviderUsingLegacyEncoding(string providerName)
{
//check if this can even be configured.
var membershipProvider = Membership.Providers[providerName] as MembershipProviderBase;
if (membershipProvider == null)
{
return false;
}
return membershipProvider.UseLegacyEncoding;
}
/// <summary>
/// Gets the full path to root.
/// </summary>
@@ -701,8 +770,12 @@ namespace Umbraco.Core.Configuration
StartsWithContainer _newReservedList = new StartsWithContainer();
foreach (string reservedUrl in _reservedUrlsCache.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries))
{
if (string.IsNullOrWhiteSpace(reservedUrl))
continue;
//resolves the url to support tilde chars
string reservedUrlTrimmed = IOHelper.ResolveUrl(reservedUrl).Trim().ToLower();
string reservedUrlTrimmed = IOHelper.ResolveUrl(reservedUrl.Trim()).Trim().ToLower();
if (reservedUrlTrimmed.Length > 0)
_newReservedList.Add(reservedUrlTrimmed);
}
@@ -710,8 +783,11 @@ namespace Umbraco.Core.Configuration
foreach (string reservedPath in _reservedPathsCache.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries))
{
bool trimEnd = !reservedPath.EndsWith("/");
if (string.IsNullOrWhiteSpace(reservedPath))
continue;
//resolves the url to support tilde chars
string reservedPathTrimmed = IOHelper.ResolveUrl(reservedPath).Trim().ToLower();
string reservedPathTrimmed = IOHelper.ResolveUrl(reservedPath.Trim()).Trim().ToLower();
if (reservedPathTrimmed.Length > 0)
_newReservedList.Add(reservedPathTrimmed + (reservedPathTrimmed.EndsWith("/") ? "" : "/"));
@@ -309,7 +309,7 @@ namespace Umbraco.Core.Configuration
{
return value;
}
return "UMB_UCONTEXT";
return Constants.Web.AuthCookieName;
}
}
@@ -502,8 +502,12 @@ namespace Umbraco.Core.Configuration
}
}
//TODO: I"m not sure why we need this, need to ask Gareth what the deal is, pretty sure we can remove it or change it, seems like
// massive overkill.
// we have that one because we auto-discover when a property is "xml" and should be returned by Razor as
// dynamic xml. But, stuff such as "<p>hello</p>" can be parsed into xml and would be returned as xml,
// unless <p> has been defined in the exclusion list... this is dirty and not-efficient, we should at least
// cache the list somewhere!
//
// TODO get rid of that whole dynamic xml mess
/// <summary>
/// razor DynamicNode typecasting detects XML and returns DynamicXml - Root elements that won't convert to DynamicXml
@@ -514,12 +518,10 @@ namespace Umbraco.Core.Configuration
{
try
{
List<string> items = new List<string>();
XmlNode root = GetKeyAsNode("/settings/scripting/razor/notDynamicXmlDocumentElements");
foreach (XmlNode element in root.SelectNodes(".//element"))
{
items.Add(element.InnerText);
}
var items = new List<string>();
var root = GetKeyAsNode("/settings/scripting/razor/notDynamicXmlDocumentElements");
if (root != null)
items.AddRange(root.SelectNodes(".//element").Cast<XmlNode>().Select(n => n.InnerText));
return items;
}
catch
@@ -656,7 +658,7 @@ namespace Umbraco.Core.Configuration
{
string defaultProvider = GetKey("/settings/providers/users/DefaultBackofficeProvider");
if (String.IsNullOrEmpty(defaultProvider))
defaultProvider = "UsersMembershipProvider";
defaultProvider = "UsersMembershipProvider";
return defaultProvider;
}
@@ -841,6 +843,11 @@ namespace Umbraco.Core.Configuration
get { return GetKeyAsNode("/settings/scheduledTasks"); }
}
internal static string ScheduledTasksBaseUrl
{
get { return GetKey("/settings/scheduledTasks/@baseUrl"); }
}
/// <summary>
/// Gets a list of characters that will be replaced when generating urls
/// </summary>
@@ -853,6 +860,8 @@ namespace Umbraco.Core.Configuration
/// <summary>
/// Whether to replace double dashes from url (ie my--story----from--dash.aspx caused by multiple url replacement chars
/// </summary>
// was used by the legacy short string helper, is not used anymore by the new default short string helper
// should update documentation
internal static bool RemoveDoubleDashesFromUrlReplacing
{
get
@@ -1079,7 +1088,7 @@ namespace Umbraco.Core.Configuration
bool globalPreviewEnabled = false;
string value = GetKey("/settings/content/GlobalPreviewStorageEnabled");
if (bool.TryParse(value, out globalPreviewEnabled))
return !globalPreviewEnabled;
return globalPreviewEnabled;
// Return default
return false;
}
@@ -5,7 +5,7 @@ namespace Umbraco.Core.Configuration
{
public class UmbracoVersion
{
private static readonly Version Version = new Version("6.1.6");
private static readonly Version Version = new Version("6.2.6");
/// <summary>
/// Gets the current version of Umbraco.
+176 -2
View File
@@ -1,4 +1,8 @@
namespace Umbraco.Core
using System;
using System.Collections.Generic;
using Umbraco.Core.Models;
namespace Umbraco.Core
{
public static partial class Constants
{
@@ -81,7 +85,7 @@
/// <summary>
/// MediaType alias for a folder.
/// </summary>
/// </summary>
public const string Folder = "Folder";
/// <summary>
@@ -89,6 +93,176 @@
/// </summary>
public const string Image = "Image";
}
/// <summary>
/// Constants for Umbraco Member property aliases.
/// </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>
public const string PasswordQuestion = "umbracoMemberPasswordRetrievalQuestion";
public const string PasswordQuestionLabel = "Password Question";
/// <summary>
/// Property alias for Members Password Answer
/// </summary>
public const string PasswordAnswer = "umbracoMemberPasswordRetrievalAnswer";
public const string PasswordAnswerLabel = "Password Answer";
/// <summary>
/// Property alias for the Comments on a Member
/// </summary>
public const string Comments = "umbracoMemberComments";
public const string CommentsLabel = "Comments";
/// <summary>
/// Property alias for the Approved boolean of a Member
/// </summary>
public const string IsApproved = "umbracoMemberApproved";
public const string IsApprovedLabel = "Is Approved";
/// <summary>
/// Property alias for the Locked out boolean of a Member
/// </summary>
public const string IsLockedOut = "umbracoMemberLockedOut";
public const string IsLockedOutLabel = "Is Locked Out";
/// <summary>
/// Property alias for the last date the Member logged in
/// </summary>
public const string LastLoginDate = "umbracoMemberLastLogin";
public const string LastLoginDateLabel = "Last Login Date";
/// <summary>
/// Property alias for the last date a Member changed its password
/// </summary>
public const string LastPasswordChangeDate = "umbracoMemberLastPasswordChangeDate";
public const string LastPasswordChangeDateLabel = "Last Password Change Date";
/// <summary>
/// Property alias for the last date a Member was locked out
/// </summary>
public const string LastLockoutDate = "umbracoMemberLastLockoutDate";
public const string LastLockoutDateLabel = "Last Lockout Date";
/// <summary>
/// Property alias for the number of failed login attemps
/// </summary>
public const string FailedPasswordAttempts = "umbracoMemberFailedPasswordAttempts";
public const string FailedPasswordAttemptsLabel = "Failed Password Attempts";
/// <summary>
/// Group name to put the membership properties on
/// </summary>
internal const string StandardPropertiesGroupName = "Membership";
internal static Dictionary<string, PropertyType> GetStandardPropertyTypeStubs()
{
return new Dictionary<string, PropertyType>
{
{
Comments,
new PropertyType(new Guid(PropertyEditors.TextboxMultiple), DataTypeDatabaseType.Ntext, true)
{
Alias = Comments,
Name = CommentsLabel
}
},
{
FailedPasswordAttempts,
new PropertyType(new Guid(PropertyEditors.NoEdit), DataTypeDatabaseType.Integer, true)
{
Alias = FailedPasswordAttempts,
Name = FailedPasswordAttemptsLabel
}
},
{
IsApproved,
new PropertyType(new Guid(PropertyEditors.TrueFalse), DataTypeDatabaseType.Integer, true)
{
Alias = IsApproved,
Name = IsApprovedLabel
}
},
{
IsLockedOut,
new PropertyType(new Guid(PropertyEditors.TrueFalse), DataTypeDatabaseType.Integer, true)
{
Alias = IsLockedOut,
Name = IsLockedOutLabel
}
},
{
LastLockoutDate,
new PropertyType(new Guid(PropertyEditors.NoEdit), DataTypeDatabaseType.Date, true)
{
Alias = LastLockoutDate,
Name = LastLockoutDateLabel
}
},
{
LastLoginDate,
new PropertyType(new Guid(PropertyEditors.NoEdit), DataTypeDatabaseType.Date, true)
{
Alias = LastLoginDate,
Name = LastLoginDateLabel
}
},
{
LastPasswordChangeDate,
new PropertyType(new Guid(PropertyEditors.NoEdit), DataTypeDatabaseType.Date, true)
{
Alias = LastPasswordChangeDate,
Name = LastPasswordChangeDateLabel
}
},
{
PasswordAnswer,
new PropertyType(new Guid(PropertyEditors.NoEdit), DataTypeDatabaseType.Nvarchar, true)
{
Alias = PasswordAnswer,
Name = PasswordAnswerLabel
}
},
{
PasswordQuestion,
new PropertyType(new Guid(PropertyEditors.NoEdit), DataTypeDatabaseType.Nvarchar, true)
{
Alias = PasswordQuestion,
Name = PasswordQuestionLabel
}
}
};
}
}
/// <summary>
/// Defines the alias identifiers for Umbraco member types.
/// </summary>
public static class MemberTypes
{
/// <summary>
/// MemberType alias for default member type.
/// </summary>
public const string Member = "Member";
public const string SystemDefaultProtectType = "_umbracoSystemDefaultProtectType";
}
/// <summary>
/// Constants for Umbraco URLs/Querystrings.
+51
View File
@@ -0,0 +1,51 @@
namespace Umbraco.Core
{
public static partial class Constants
{
/// <summary>
/// Defines the constants used for Umbraco packages in the package.config xml
/// </summary>
public static class Packaging
{
public const string UmbPackageNodeName = "umbPackage";
public const string DataTypesNodeName = "DataTypes";
public const string PackageXmlFileName = "package.xml";
public const string UmbracoPackageExtention = ".umb";
public const string DataTypeNodeName = "DataType";
public const string LanguagesNodeName = "Languages";
public const string FilesNodeName = "Files";
public const string StylesheetsNodeName = "Stylesheets";
public const string TemplatesNodeName = "Templates";
public const string OrgnameNodeName = "orgName";
public const string NameNodeName = "Name";
public const string TemplateNodeName = "Template";
public const string AliasNodeName = "Alias";
public const string DictionaryitemsNodeName = "DictionaryItems";
public const string MacrosNodeName = "macros";
public const string DocumentSetNodeName = "DocumentSet";
public const string DocumentTypesNodeName = "DocumentTypes";
public const string DocumentTypeNodeName = "DocumentType";
public const string FileNodeName = "file";
public const string OrgPathNodeName = "orgPath";
public const string GuidNodeName = "guid";
public const string StylesheetNodeName = "styleSheet";
public const string MacroNodeName = "macro";
public const string InfoNodeName = "info";
public const string PackageRequirementsMajorXpath = "/package/requirements/major";
public const string PackageRequirementsMinorXpath = "/package/requirements/minor";
public const string PackageRequirementsPatchXpath = "/package/requirements/patch";
public const string PackageNameXpath = "/package/name";
public const string PackageVersionXpath = "/package/version";
public const string PackageUrlXpath = "/package/url";
public const string PackageLicenseXpath = "/package/license";
public const string AuthorNameXpath = "/author/name";
public const string AuthorWebsiteXpath = "/author/website";
public const string ReadmeXpath = "/readme";
public const string ControlNodeName = "control";
public const string ActionNodeName = "Action";
public const string ActionsNodeName = "Actions";
public const string UndoNodeAttribute = "undo";
public const string RunatNodeAttribute = "runat";
}
}
}
+22
View File
@@ -0,0 +1,22 @@
namespace Umbraco.Core
{
public static partial class Constants
{
/// <summary>
/// Defines the identifiers for Umbraco system nodes.
/// </summary>
public static class Web
{
/// <summary>
/// The preview cookie name
/// </summary>
public const string PreviewCookieName = "UMB_PREVIEW";
/// <summary>
/// The auth cookie name
/// </summary>
public const string AuthCookieName = "UMB_UCONTEXT";
}
}
}
+46
View File
@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
namespace Umbraco.Core
{
internal static class ControlExtensions
{
/// <summary>
/// Recursively finds a control with the specified identifier.
/// </summary>
/// <typeparam name="T">
/// The type of control to be found.
/// </typeparam>
/// <param name="parent">
/// The parent control from which the search will start.
/// </param>
/// <param name="id">
/// The identifier of the control to be found.
/// </param>
/// <returns>
/// The control with the specified identifier, otherwise <see langword="null"/> if the control
/// is not found.
/// </returns>
public static T FindControlRecursive<T>(this Control parent, string id) where T : Control
{
if ((parent is T) && (parent.ID == id))
{
return (T)parent;
}
foreach (Control control in parent.Controls)
{
var foundControl = FindControlRecursive<T>(control, id);
if (foundControl != null)
{
return foundControl;
}
}
return default(T);
}
}
}
+43 -22
View File
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.ObjectResolution;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Mappers;
@@ -12,6 +14,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;
@@ -36,6 +39,7 @@ namespace Umbraco.Core
private bool _isComplete = false;
private readonly UmbracoApplicationBase _umbracoApplication;
protected ApplicationContext ApplicationContext { get; private set; }
protected CacheHelper ApplicationCache { get; set; }
protected UmbracoApplicationBase UmbracoApplication
{
@@ -55,16 +59,19 @@ namespace Umbraco.Core
InitializeProfilerResolver();
CreateApplicationCache();
_timer = DisposableTimer.DebugDuration<CoreBootManager>("Umbraco application starting", "Umbraco application startup complete");
//create database and service contexts for the app context
var dbFactory = new DefaultDatabaseFactory(GlobalSettings.UmbracoConnectionName);
Database.Mapper = new PetaPocoMapper();
var dbContext = new DatabaseContext(dbFactory);
var serviceContext = new ServiceContext(
new PetaPocoUnitOfWorkProvider(dbFactory),
new FileUnitOfWorkProvider(),
new PublishingStrategy());
var serviceContext = new ServiceContext(
new PetaPocoUnitOfWorkProvider(dbFactory),
new FileUnitOfWorkProvider(),
new PublishingStrategy(),
ApplicationCache);
CreateApplicationContext(dbContext, serviceContext);
@@ -92,7 +99,21 @@ namespace Umbraco.Core
protected virtual void CreateApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext)
{
//create the ApplicationContext
ApplicationContext = ApplicationContext.Current = new ApplicationContext(dbContext, serviceContext);
ApplicationContext = ApplicationContext.Current = new ApplicationContext(dbContext, serviceContext, ApplicationCache);
}
/// <summary>
/// Creates and assigns the ApplicationCache based on a new instance of System.Web.Caching.Cache
/// </summary>
protected virtual void CreateApplicationCache()
{
var cacheHelper = new CacheHelper(
new ObjectCacheRuntimeCacheProvider(),
new StaticCacheProvider(),
//we have no request based cache when not running in web-based context
new NullCacheProvider());
ApplicationCache = cacheHelper;
}
/// <summary>
@@ -125,8 +146,9 @@ namespace Umbraco.Core
{
CanResolveBeforeFrozen = true
};
//add custom types here that are internal
ApplicationEventsResolver.Current.AddType<PublishedContentHelper>();
// add custom types here that are internal, if needed
//ApplicationEventsResolver.Current.AddType<>();
}
/// <summary>
@@ -228,7 +250,7 @@ namespace Umbraco.Core
() => PluginManager.Current.ResolveAssignedMapperTypes());
RepositoryResolver.Current = new RepositoryResolver(
new RepositoryFactory());
new RepositoryFactory(ApplicationCache));
SqlSyntaxProvidersResolver.Current = new SqlSyntaxProvidersResolver(
new[] { typeof(MySqlSyntaxProvider), typeof(SqlCeSyntaxProvider), typeof(SqlServerSyntaxProvider) })
@@ -253,28 +275,27 @@ namespace Umbraco.Core
//the database migration objects
MigrationResolver.Current = new MigrationResolver(
() => PluginManager.Current.ResolveMigrationTypes());
() => PluginManager.Current.ResolveTypes<IMigration>());
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
PropertyEditorValueConvertersResolver.Current.AddType<DatePickerPropertyEditorValueConverter>();
PropertyEditorValueConvertersResolver.Current.AddType<TinyMcePropertyEditorValueConverter>();
PropertyEditorValueConvertersResolver.Current.AddType<YesNoPropertyEditorValueConverter>();
// this is how we'd switch over to DefaultShortStringHelper _and_ still use
// UmbracoSettings UrlReplaceCharacters...
//ShortStringHelperResolver.Current = new ShortStringHelperResolver(
// new DefaultShortStringHelper().WithConfig(DefaultShortStringHelper.ApplyUrlReplaceCharacters));
// initialize the new property value converters by discovering IPropertyValueConverter
PropertyValueConvertersResolver.Current = new PropertyValueConvertersResolver(
PluginManager.Current.ResolveTypes<IPropertyValueConverter>());
// use the Legacy one for now
// use the new DefaultShortStringHelper
ShortStringHelperResolver.Current = new ShortStringHelperResolver(
new LegacyShortStringHelper());
//new LegacyShortStringHelper());
new DefaultShortStringHelper().WithDefaultConfig());
UrlSegmentProviderResolver.Current = new UrlSegmentProviderResolver(
typeof (DefaultUrlSegmentProvider));
// keep it internal for now
PublishedContentModelFactoryResolver.Current = new PublishedContentModelFactoryResolver();
// new PublishedContentModelFactoryImpl());
}
}
}
@@ -22,8 +22,8 @@ namespace Umbraco.Core
if (value is string)
{
var str = (string)value;
if (str == null || str.Length == 0 || str == "0") return false;
if (str == "1") return true;
if (str == "0" || str == "") return false;
}
return base.ConvertFrom(context, culture, value);
+163 -61
View File
@@ -3,6 +3,7 @@ using System.Configuration;
using System.Data.SqlServerCe;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Configuration;
using System.Xml.Linq;
using Umbraco.Core.Configuration;
@@ -28,7 +29,7 @@ namespace Umbraco.Core
private string _providerName;
private DatabaseSchemaResult _result;
internal DatabaseContext(IDatabaseFactory factory)
public DatabaseContext(IDatabaseFactory factory)
{
_factory = factory;
}
@@ -426,6 +427,13 @@ namespace Umbraco.Core
if (_result == null)
{
if (SystemUtilities.GetCurrentTrustLevel() != AspNetHostingPermissionLevel.Unrestricted
&& ProviderName == "MySql.Data.MySqlClient")
{
throw new InvalidOperationException("Cannot use MySql in Medium Trust configuration");
}
var database = new UmbracoDatabase(_connectionString, ProviderName);
var dbSchema = new DatabaseSchemaCreation(database);
_result = dbSchema.ValidateSchema();
@@ -433,26 +441,26 @@ namespace Umbraco.Core
return _result;
}
internal Result CreateDatabaseSchemaAndDataOrUpgrade()
{
if (_configured == false || (string.IsNullOrEmpty(_connectionString) || string.IsNullOrEmpty(ProviderName)))
{
return new Result
{
Message =
"Database configuration is invalid. Please check that the entered database exists and that the provided username and password has write access to the database.",
Success = false,
Percentage = "10"
};
}
internal Result CreateDatabaseSchemaAndData()
{
try
{
var readyForInstall = CheckReadyForInstall();
if (readyForInstall.Success == false)
{
return readyForInstall.Result;
}
LogHelper.Info<DatabaseContext>("Database configuration status: Started");
var message = string.Empty;
string message;
var database = new UmbracoDatabase(_connectionString, ProviderName);
// If MySQL, we're going to ensure that database calls are maintaining proper casing as to remove the necessity for checks
// for case insensitive queries. In an ideal situation (which is what we're striving for), all calls would be case sensitive.
/*
var supportsCaseInsensitiveQueries = SqlSyntaxContext.SqlSyntaxProvider.SupportsCaseInsensitiveQueries(database);
if (supportsCaseInsensitiveQueries == false)
{
@@ -465,50 +473,75 @@ namespace Umbraco.Core
return new Result { Message = message, Success = false, Percentage = "15" };
}
else if (supportsCaseInsensitiveQueries == null)
{
message = "<p>&nbsp;</p><p>Warning! Could not check if your database type supports case insensitive queries. <br />We currently do not support these databases that do not support case insensitive queries.</p>" +
"<p>You can check this by looking for the following setting in your my.ini file in your MySQL installation directory:</p>" +
"<pre>lower_case_table_names=1</pre><br />" +
"<p>Note: Make sure to check with your hosting provider if they support case insensitive queries as well.</p>" +
"<p>For more technical information on case sensitivity in MySQL, have a look at " +
"<a href='http://dev.mysql.com/doc/refman/5.0/en/identifier-case-sensitivity.html'>the documentation on the subject</a></p>";
}
else
{
if (SqlSyntaxContext.SqlSyntaxProvider.GetType() == typeof(MySqlSyntaxProvider))
{
message = "<p>&nbsp;</p><p>Congratulations, the database step ran successfully!</p>" +
"<p>Note: You're using MySQL and the database instance you're connecting to seems to support case insensitive queries.</p>" +
"<p>However, your hosting provider may not support this option. Umbraco does not currently support MySQL installs that do not support case insensitive queries</p>" +
"<p>Make sure to check with your hosting provider if they support case insensitive queries as well.</p>" +
"<p>They can check this by looking for the following setting in the my.ini file in their MySQL installation directory:</p>" +
"<pre>lower_case_table_names=1</pre><br />" +
"<p>For more technical information on case sensitivity in MySQL, have a look at " +
"<a href='http://dev.mysql.com/doc/refman/5.0/en/identifier-case-sensitivity.html'>the documentation on the subject</a></p>";
}
}
*/
message = GetResultMessageForMySql();
var schemaResult = ValidateDatabaseSchema();
var installedVersion = schemaResult.DetermineInstalledVersion();
//If Configuration Status is empty and the determined version is "empty" its a new install - otherwise upgrade the existing
if (string.IsNullOrEmpty(GlobalSettings.ConfigurationStatus) && installedVersion.Equals(new Version(0, 0, 0)))
{
database.CreateDatabaseSchema();
message = message + "<p>Installation completed!</p>";
//now that everything is done, we need to determine the version of SQL server that is executing
LogHelper.Info<DatabaseContext>("Database configuration status: " + message);
return new Result { Message = message, Success = true, Percentage = "100" };
}
else
//we need to do an upgrade so return a new status message and it will need to be done during the next step
LogHelper.Info<DatabaseContext>("Database requires upgrade");
message = "<p>Upgrading database, this may take some time...</p>";
return new Result
{
RequiresUpgrade = true,
Message = message,
Success = true,
Percentage = "30"
};
}
catch (Exception ex)
{
return HandleInstallException(ex);
}
}
/// <summary>
/// This assumes all of the previous checks are done!
/// </summary>
/// <returns></returns>
internal Result UpgradeSchemaAndData()
{
try
{
var readyForInstall = CheckReadyForInstall();
if (readyForInstall.Success == false)
{
var configuredVersion = string.IsNullOrEmpty(GlobalSettings.ConfigurationStatus)
return readyForInstall.Result;
}
LogHelper.Info<DatabaseContext>("Database upgrade started");
var database = new UmbracoDatabase(_connectionString, ProviderName);
//var supportsCaseInsensitiveQueries = SqlSyntaxContext.SqlSyntaxProvider.SupportsCaseInsensitiveQueries(database);
var message = GetResultMessageForMySql();
var schemaResult = ValidateDatabaseSchema();
var installedVersion = schemaResult.DetermineInstalledVersion();
//DO the upgrade!
var configuredVersion = string.IsNullOrEmpty(GlobalSettings.ConfigurationStatus)
? installedVersion
: new Version(GlobalSettings.ConfigurationStatus);
var targetVersion = UmbracoVersion.Current;
var runner = new MigrationRunner(configuredVersion, targetVersion, GlobalSettings.UmbracoMigrationName);
var upgraded = runner.Execute(database, true);
message = message + "<p>Upgrade completed!</p>";
}
var targetVersion = UmbracoVersion.Current;
var runner = new MigrationRunner(configuredVersion, targetVersion, GlobalSettings.UmbracoMigrationName);
var upgraded = runner.Execute(database, true);
message = message + "<p>Upgrade completed!</p>";
//now that everything is done, we need to determine the version of SQL server that is executing
@@ -518,26 +551,95 @@ namespace Umbraco.Core
}
catch (Exception ex)
{
LogHelper.Info<DatabaseContext>("Database configuration failed with the following error and stack trace: " + ex.Message + "\n" + ex.StackTrace);
if (_result != null)
{
LogHelper.Info<DatabaseContext>("The database schema validation produced the following summary: \n" + _result.GetSummary());
}
return new Result
{
Message =
"The database configuration failed with the following message: " + ex.Message +
"\n Please check log file for additional information (can be found in '/App_Data/Logs/UmbracoTraceLog.txt')",
Success = false,
Percentage = "90"
};
return HandleInstallException(ex);
}
}
private string GetResultMessageForMySql()
{
if (SqlSyntaxContext.SqlSyntaxProvider.GetType() == typeof(MySqlSyntaxProvider))
{
return "<p>&nbsp;</p><p>Congratulations, the database step ran successfully!</p>" +
"<p>Note: You're using MySQL and the database instance you're connecting to seems to support case insensitive queries.</p>" +
"<p>However, your hosting provider may not support this option. Umbraco does not currently support MySQL installs that do not support case insensitive queries</p>" +
"<p>Make sure to check with your hosting provider if they support case insensitive queries as well.</p>" +
"<p>They can check this by looking for the following setting in the my.ini file in their MySQL installation directory:</p>" +
"<pre>lower_case_table_names=1</pre><br />" +
"<p>For more technical information on case sensitivity in MySQL, have a look at " +
"<a href='http://dev.mysql.com/doc/refman/5.0/en/identifier-case-sensitivity.html'>the documentation on the subject</a></p>";
}
return string.Empty;
}
/*
private string GetResultMessageForMySql(bool? supportsCaseInsensitiveQueries)
{
if (supportsCaseInsensitiveQueries == null)
{
return "<p>&nbsp;</p><p>Warning! Could not check if your database type supports case insensitive queries. <br />We currently do not support these databases that do not support case insensitive queries.</p>" +
"<p>You can check this by looking for the following setting in your my.ini file in your MySQL installation directory:</p>" +
"<pre>lower_case_table_names=1</pre><br />" +
"<p>Note: Make sure to check with your hosting provider if they support case insensitive queries as well.</p>" +
"<p>For more technical information on case sensitivity in MySQL, have a look at " +
"<a href='http://dev.mysql.com/doc/refman/5.0/en/identifier-case-sensitivity.html'>the documentation on the subject</a></p>";
}
if (SqlSyntaxContext.SqlSyntaxProvider.GetType() == typeof(MySqlSyntaxProvider))
{
return "<p>&nbsp;</p><p>Congratulations, the database step ran successfully!</p>" +
"<p>Note: You're using MySQL and the database instance you're connecting to seems to support case insensitive queries.</p>" +
"<p>However, your hosting provider may not support this option. Umbraco does not currently support MySQL installs that do not support case insensitive queries</p>" +
"<p>Make sure to check with your hosting provider if they support case insensitive queries as well.</p>" +
"<p>They can check this by looking for the following setting in the my.ini file in their MySQL installation directory:</p>" +
"<pre>lower_case_table_names=1</pre><br />" +
"<p>For more technical information on case sensitivity in MySQL, have a look at " +
"<a href='http://dev.mysql.com/doc/refman/5.0/en/identifier-case-sensitivity.html'>the documentation on the subject</a></p>";
}
return string.Empty;
}*/
private Attempt<Result> CheckReadyForInstall()
{
if (SystemUtilities.GetCurrentTrustLevel() != AspNetHostingPermissionLevel.Unrestricted
&& ProviderName == "MySql.Data.MySqlClient")
{
throw new InvalidOperationException("Cannot use MySql in Medium Trust configuration");
}
if (_configured == false || (string.IsNullOrEmpty(_connectionString) || string.IsNullOrEmpty(ProviderName)))
{
return Attempt.Fail(new Result
{
Message =
"Database configuration is invalid. Please check that the entered database exists and that the provided username and password has write access to the database.",
Success = false,
Percentage = "10"
});
}
return Attempt<Result>.Succeed();
}
private Result HandleInstallException(Exception ex)
{
LogHelper.Info<DatabaseContext>("Database configuration failed with the following error and stack trace: " + ex.Message + "\n" + ex.StackTrace);
if (_result != null)
{
LogHelper.Info<DatabaseContext>("The database schema validation produced the following summary: \n" + _result.GetSummary());
}
return new Result
{
Message =
"The database configuration failed with the following message: " + ex.Message +
"\n Please check log file for additional information (can be found in '/App_Data/Logs/UmbracoTraceLog.txt')",
Success = false,
Percentage = "90"
};
}
internal class Result
{
public bool RequiresUpgrade { get; set; }
public string Message { get; set; }
public bool Success { get; set; }
public string Percentage { get; set; }
+25
View File
@@ -18,5 +18,30 @@ namespace Umbraco.Core
return dt.ToString("yyyy-MM-dd HH:mm:ss");
}
public static DateTime TruncateTo(this DateTime dt, DateTruncate truncateTo)
{
if (truncateTo == DateTruncate.Year)
return new DateTime(dt.Year, 0, 0);
if (truncateTo == DateTruncate.Month)
return new DateTime(dt.Year, dt.Month, 0);
if (truncateTo == DateTruncate.Day)
return new DateTime(dt.Year, dt.Month, dt.Day);
if (truncateTo == DateTruncate.Hour)
return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, 0, 0);
if (truncateTo == DateTruncate.Minute)
return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, 0);
return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second);
}
public enum DateTruncate
{
Year,
Month,
Day,
Hour,
Minute,
Second
}
}
}
+60 -23
View File
@@ -131,30 +131,48 @@ namespace Umbraco.Core
return n;
}
/// <summary>
/// Returns a new dictionary of this ... others merged leftward.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TK"></typeparam>
/// <typeparam name="TV"></typeparam>
/// <param name="me"></param>
/// <param name="others"></param>
/// <returns></returns>
/// <remarks>
/// Reference: http://stackoverflow.com/questions/294138/merging-dictionaries-in-c
/// </remarks>
public static T MergeLeft<T, TK, TV>(this T me, params IDictionary<TK, TV>[] others)
where T : IDictionary<TK, TV>, new()
{
var newMap = new T();
foreach (var p in (new List<IDictionary<TK, TV>> { me }).Concat(others).SelectMany(src => src))
{
newMap[p.Key] = p.Value;
}
return newMap;
}
/// <summary>
/// Merges all key/values from the sources dictionaries into the destination dictionary
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TK"></typeparam>
/// <typeparam name="TV"></typeparam>
/// <param name="destination">The source dictionary to merge other dictionaries into</param>
/// <param name="overwrite">
/// By default all values will be retained in the destination if the same keys exist in the sources but
/// this can changed if overwrite = true, then any key/value found in any of the sources will overwritten in the destination. Note that
/// it will just use the last found key/value if this is true.
/// </param>
/// <param name="sources">The other dictionaries to merge values from</param>
public static void MergeLeft<T, TK, TV>(this T destination, IEnumerable<IDictionary<TK, TV>> sources, bool overwrite = false)
where T : IDictionary<TK, TV>
{
foreach (var p in sources.SelectMany(src => src).Where(p => overwrite || destination.ContainsKey(p.Key) == false))
{
destination[p.Key] = p.Value;
}
}
/// <summary>
/// <summary>
/// Merges all key/values from the sources dictionaries into the destination dictionary
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TK"></typeparam>
/// <typeparam name="TV"></typeparam>
/// <param name="destination">The source dictionary to merge other dictionaries into</param>
/// <param name="overwrite">
/// By default all values will be retained in the destination if the same keys exist in the sources but
/// this can changed if overwrite = true, then any key/value found in any of the sources will overwritten in the destination. Note that
/// it will just use the last found key/value if this is true.
/// </param>
/// <param name="source">The other dictionary to merge values from</param>
public static void MergeLeft<T, TK, TV>(this T destination, IDictionary<TK, TV> source, bool overwrite = false)
where T : IDictionary<TK, TV>
{
destination.MergeLeft(new[] {source}, overwrite);
}
/// <summary>
/// Returns the value of the key value based on the key, if the key is not found, a null value is returned
/// </summary>
/// <typeparam name="TKey">The type of the key.</typeparam>
@@ -187,6 +205,25 @@ namespace Umbraco.Core
return String.Empty;
}
/// <summary>
/// Returns the value of the key value based on the key as it's string value, if the key is not found or is an empty string, then the provided default value is returned
/// </summary>
/// <param name="d"></param>
/// <param name="key"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static string GetValueAsString<TKey, TVal>(this IDictionary<TKey, TVal> d, TKey key, string defaultValue)
{
if (d.ContainsKey(key))
{
var value = d[key].ToString();
if (value != string.Empty)
return value;
}
return defaultValue;
}
/// <summary>contains key ignore case.</summary>
/// <param name="dictionary">The dictionary.</param>
/// <param name="key">The key.</param>
@@ -82,7 +82,7 @@ namespace Umbraco.Core.Dynamics
null,
thisObject,
args);
return new Attempt<TryInvokeMemberResult>(true, new TryInvokeMemberResult(result, TryInvokeMemberSuccessReason.FoundProperty));
return Attempt.Succeed(new TryInvokeMemberResult(result, TryInvokeMemberSuccessReason.FoundProperty));
}
catch (MissingMethodException)
{
@@ -97,7 +97,7 @@ namespace Umbraco.Core.Dynamics
null,
thisObject,
args);
return new Attempt<TryInvokeMemberResult>(true, new TryInvokeMemberResult(result, TryInvokeMemberSuccessReason.FoundMethod));
return Attempt.Succeed(new TryInvokeMemberResult(result, TryInvokeMemberSuccessReason.FoundMethod));
}
catch (MissingMethodException)
{
@@ -106,13 +106,14 @@ namespace Umbraco.Core.Dynamics
try
{
result = FindAndExecuteExtensionMethod(thisObject, args, binder.Name, findExtensionMethodsOnTypes);
return new Attempt<TryInvokeMemberResult>(true, new TryInvokeMemberResult(result, TryInvokeMemberSuccessReason.FoundExtensionMethod));
return Attempt.Succeed(new TryInvokeMemberResult(result, TryInvokeMemberSuccessReason.FoundExtensionMethod));
}
catch (TargetInvocationException ext)
{
//don't log here, we return this exception because the caller may need to do something specific when
//this exception occurs.
return new Attempt<TryInvokeMemberResult>(ext);
var mresult = new TryInvokeMemberResult(null, TryInvokeMemberSuccessReason.FoundExtensionMethod);
return Attempt<TryInvokeMemberResult>.Fail(mresult, ext);
}
catch (Exception ex)
{
@@ -124,16 +125,17 @@ namespace Umbraco.Core.Dynamics
sb.Append(t + ",");
}
LogHelper.Error<DynamicInstanceHelper>(sb.ToString(), ex);
return new Attempt<TryInvokeMemberResult>(ex);
var mresult = new TryInvokeMemberResult(null, TryInvokeMemberSuccessReason.FoundExtensionMethod);
return Attempt<TryInvokeMemberResult>.Fail(mresult, ex);
}
}
return Attempt<TryInvokeMemberResult>.False;
return Attempt<TryInvokeMemberResult>.Fail();
}
}
catch (Exception ex)
{
LogHelper.Error<DynamicInstanceHelper>("An unhandled exception occurred in method TryInvokeMember", ex);
return new Attempt<TryInvokeMemberResult>(ex);
return Attempt<TryInvokeMemberResult>.Fail(ex);
}
}
+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;
}
}
}
+8 -8
View File
@@ -201,9 +201,9 @@ namespace Umbraco.Core.Dynamics
//this is the result of an extension method execution gone wrong so we return dynamic null
if (attempt.Result.Reason == DynamicInstanceHelper.TryInvokeMemberSuccessReason.FoundExtensionMethod
&& attempt.Error != null && attempt.Error is TargetInvocationException)
&& attempt.Exception != null && attempt.Exception is TargetInvocationException)
{
result = new DynamicNull();
result = DynamicNull.Null;
return true;
}
@@ -261,7 +261,7 @@ namespace Umbraco.Core.Dynamics
var attributes = xmlElement.Attributes(name).Select(attr => attr.Value).ToArray();
if (attributes.Any())
{
return new Attempt<IEnumerable<string>>(true, attributes);
return Attempt<IEnumerable<string>>.Succeed(attributes);
}
if (!attributes.Any() && xmlElement.Name == "root" && xmlElement.Elements().Count() == 1)
@@ -271,12 +271,12 @@ namespace Umbraco.Core.Dynamics
if (childElements.Any())
{
//we've found a match by the first child of an element called 'root' (strange, but sure)
return new Attempt<IEnumerable<string>>(true, childElements);
return Attempt<IEnumerable<string>>.Succeed(childElements);
}
}
//no deal
return Attempt<IEnumerable<string>>.False;
return Attempt<IEnumerable<string>>.Fail();
}
/// <summary>
@@ -293,7 +293,7 @@ namespace Umbraco.Core.Dynamics
//Check if we've got any matches, if so then return true
if (elements.Any())
{
return new Attempt<IEnumerable<XElement>>(true, elements);
return Attempt<IEnumerable<XElement>>.Succeed(elements);
}
if (!elements.Any() && xmlElement.Name == "root" && xmlElement.Elements().Count() == 1)
@@ -303,12 +303,12 @@ namespace Umbraco.Core.Dynamics
if (childElements.Any())
{
//we've found a match by the first child of an element called 'root' (strange, but sure)
return new Attempt<IEnumerable<XElement>>(true, childElements);
return Attempt<IEnumerable<XElement>>.Succeed(childElements);
}
}
//no deal
return Attempt<IEnumerable<XElement>>.False;
return Attempt<IEnumerable<XElement>>.Fail();
}
private bool HandleIEnumerableXElement(IEnumerable<XElement> elements, out object result)
@@ -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);
+4 -24
View File
@@ -36,42 +36,22 @@ namespace Umbraco.Core.Dynamics
[Obsolete("This method should not be used and will be removed in the future")]
public static bool ContainsAny(this string haystack, IEnumerable<string> needles)
{
if (haystack == null) throw new ArgumentNullException("haystack");
if (!string.IsNullOrEmpty(haystack) || needles.Any())
{
return needles.Any(haystack.Contains);
}
return false;
return StringExtensions.ContainsAny(haystack, needles);
}
[Obsolete("This method should not be used and will be removed in the future")]
public static bool ContainsAny(this string haystack, params string[] needles)
{
if (haystack == null) throw new ArgumentNullException("haystack");
if (!string.IsNullOrEmpty(haystack) || needles.Length > 0)
{
return needles.Any(haystack.Contains);
}
return false;
return StringExtensions.ContainsAny(haystack, needles);
}
[Obsolete("This method should not be used and will be removed in the future")]
public static bool ContainsAny(this string haystack, StringComparison comparison, IEnumerable<string> needles)
{
if (haystack == null) throw new ArgumentNullException("haystack");
if (!string.IsNullOrEmpty(haystack) || needles.Any())
{
return needles.Any(value => haystack.IndexOf(value, comparison) >= 0);
}
return false;
return StringExtensions.ContainsAny(haystack, needles, comparison);
}
[Obsolete("This method should not be used and will be removed in the future")]
public static bool ContainsAny(this string haystack, StringComparison comparison, params string[] needles)
{
if (haystack == null) throw new ArgumentNullException("haystack");
if (!string.IsNullOrEmpty(haystack) || needles.Length > 0)
{
return needles.Any(value => haystack.IndexOf(value, comparison) >= 0);
}
return false;
return StringExtensions.ContainsAny(haystack, needles, comparison);
}
[Obsolete("This method should not be used and will be removed in the future")]
public static bool ContainsInsensitive(this string haystack, string needle)
+25 -40
View File
@@ -1,65 +1,50 @@
using System;
using Umbraco.Core.Models;
using umbraco.interfaces;
using System.Web;
namespace Umbraco.Core.Dynamics
{
internal class PropertyResult : IPublishedContentProperty, IHtmlString
{
{
private readonly IPublishedContentProperty _source;
private readonly string _alias;
private readonly object _value;
private readonly PropertyResultType _type;
internal PropertyResult(IPublishedContentProperty source, PropertyResultType type)
{
if (source == null) throw new ArgumentNullException("source");
Alias = source.Alias;
Value = source.Value;
Version = source.Version;
PropertyType = type;
_type = type;
_source = source;
}
internal PropertyResult(string alias, object value, Guid version, PropertyResultType type)
internal PropertyResult(string alias, object value, Guid version, PropertyResultType type)
{
if (alias == null) throw new ArgumentNullException("alias");
if (value == null) throw new ArgumentNullException("value");
Alias = alias;
Value = value;
Version = version;
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);
}
}
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 Guid Version { get; private set; }
/// <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 Alias { get { return PropertyTypeAlias; }}
public Guid Version { get { return Guid.Empty; }}
// implements IHtmlString.ToHtmlString
public string ToHtmlString()
{
return ValueAsString;
var value = Value;
return value == null ? string.Empty : value.ToString();
}
}
}
+42 -30
View File
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using Umbraco.Core.Logging;
namespace Umbraco.Core
{
@@ -13,17 +14,16 @@ 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 ArgumentNullException("source");
if (groupSize <= 0)
throw new ArgumentException("Must be greater than zero.", "groupSize");
while ((i * groupSize) < length)
{
yield return source.Skip(i * groupSize).Take(groupSize);
i++;
}
return source
.Select((x, i) => Tuple.Create(i / groupSize, x))
.GroupBy(t => t.Item1, t => t.Item2);
}
/// <summary>The distinct by.</summary>
/// <param name="source">The source.</param>
/// <param name="keySelector">The key selector.</param>
@@ -96,23 +96,13 @@ namespace Umbraco.Core
}
/// <summary>The flatten list.</summary>
/// <param name="items">The items.</param>
/// <param name="selectChild">The select child.</param>
/// <typeparam name="TItem">Item type</typeparam>
/// <param name="e">The items.</param>
/// <param name="f">The select child.</param>
/// <typeparam name="T">Item type</typeparam>
/// <returns>list of TItem</returns>
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "By design")]
public static IEnumerable<TItem> FlattenList<TItem>(this IEnumerable<TItem> items, Func<TItem, IEnumerable<TItem>> selectChild)
public static IEnumerable<T> FlattenList<T>(this IEnumerable<T> e, Func<T, IEnumerable<T>> f)
{
IEnumerable<TItem> children = items != null && items.Any()
? items.SelectMany(selectChild).FlattenList(selectChild)
: Enumerable.Empty<TItem>();
if (items != null)
{
return items.Concat(children);
}
return null;
return e.SelectMany(c => f(c).FlattenList(f)).Concat(e);
}
/// <summary>
@@ -243,23 +233,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>
@@ -29,7 +29,7 @@ namespace Umbraco.Core.Events
/// <remarks>
/// This is protected so that inheritors can expose it with their own name
/// </remarks>
protected T EventObject { get; private set; }
protected T EventObject { get; set; }
}
}
+92 -22
View File
@@ -1,28 +1,98 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Umbraco.Core.Events
{
public class MoveEventArgs<TEntity> : CancellableObjectEventArgs<TEntity>
{
public MoveEventArgs(TEntity eventObject, bool canCancel, int parentId) : base(eventObject, canCancel)
{
ParentId = parentId;
}
public class MoveEventInfo<TEntity>
{
public MoveEventInfo(TEntity entity, string originalPath, int newParentId)
{
Entity = entity;
OriginalPath = originalPath;
NewParentId = newParentId;
}
public MoveEventArgs(TEntity eventObject, int parentId) : base(eventObject)
{
ParentId = parentId;
}
public TEntity Entity { get; set; }
public string OriginalPath { get; set; }
public int NewParentId { get; set; }
}
/// <summary>
/// The entity being moved
/// </summary>
public TEntity Entity
{
get { return EventObject; }
}
public class MoveEventArgs<TEntity> : CancellableObjectEventArgs<TEntity>
{
/// <summary>
/// Constructor accepting a collection of MoveEventInfo objects
/// </summary>
/// <param name="canCancel"></param>
/// <param name="moveInfo">
/// A colleciton of MoveEventInfo objects that exposes all entities that have been moved during a single move operation
/// </param>
public MoveEventArgs(bool canCancel, params MoveEventInfo<TEntity>[] moveInfo)
: base(default(TEntity), canCancel)
{
if (moveInfo.FirstOrDefault() == null)
{
throw new ArgumentException("moveInfo argument must contain at least one item");
}
/// <summary>
/// Gets or Sets the Id of the objects new parent.
/// </summary>
public int ParentId { get; private set; }
}
MoveInfoCollection = moveInfo;
//assign the legacy props
EventObject = moveInfo.First().Entity;
ParentId = moveInfo.First().NewParentId;
}
/// <summary>
/// Constructor accepting a collection of MoveEventInfo objects
/// </summary>
/// <param name="moveInfo">
/// A colleciton of MoveEventInfo objects that exposes all entities that have been moved during a single move operation
/// </param>
public MoveEventArgs(params MoveEventInfo<TEntity>[] moveInfo)
: base(default(TEntity))
{
if (moveInfo.FirstOrDefault() == null)
{
throw new ArgumentException("moveInfo argument must contain at least one item");
}
MoveInfoCollection = moveInfo;
//assign the legacy props
EventObject = moveInfo.First().Entity;
ParentId = moveInfo.First().NewParentId;
}
[Obsolete("Use the overload that specifies the MoveEventInfo object")]
public MoveEventArgs(TEntity eventObject, bool canCancel, int parentId)
: base(eventObject, canCancel)
{
ParentId = parentId;
}
[Obsolete("Use the overload that specifies the MoveEventInfo object")]
public MoveEventArgs(TEntity eventObject, int parentId)
: base(eventObject)
{
ParentId = parentId;
}
/// <summary>
/// Gets all MoveEventInfo objects used to create the object
/// </summary>
public IEnumerable<MoveEventInfo<TEntity>> MoveInfoCollection { get; private set; }
/// <summary>
/// The entity being moved
/// </summary>
[Obsolete("Retrieve the entity object from the MoveInfoCollection property instead")]
public TEntity Entity
{
get { return EventObject; }
}
/// <summary>
/// Gets the Id of the object's new parent
/// </summary>
[Obsolete("Retrieve the ParentId from the MoveInfoCollection property instead")]
public int ParentId { get; private set; }
}
}
+6
View File
@@ -34,6 +34,12 @@ namespace Umbraco.Core
AddInt(d.GetHashCode());
}
internal void AddString(string s)
{
if (s != null)
AddInt((StringComparer.InvariantCulture).GetHashCode(s));
}
internal void AddCaseInsensitiveString(string s)
{
if (s != null)
+29 -16
View File
@@ -1,37 +1,50 @@
using System.IO;
using System;
using System.IO;
using Umbraco.Core.CodeAnnotations;
namespace Umbraco.Core.IO
{
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
{
public static class FileSystemExtensions
{
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
internal static long GetSize(this IFileSystem fs, string path)
public static long GetSize(this IFileSystem fs, string path)
{
var s = fs.OpenFile(path);
var size = s.Length;
s.Close();
using (var s = fs.OpenFile(path))
{
var size = s.Length;
s.Close();
return size;
return size;
}
}
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
internal static void CopyFile(this IFileSystem fs, string path, string newPath)
public static void CopyFile(this IFileSystem fs, string path, string newPath)
{
fs.AddFile(newPath, fs.OpenFile(path));
using (var stream = fs.OpenFile(path))
{
fs.AddFile(newPath, stream);
}
}
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
internal static string GetExtension(this IFileSystem fs, string path)
public static string GetExtension(this IFileSystem fs, string path)
{
return Path.GetExtension(fs.GetFullPath(path));
}
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
internal static string GetFileName(this IFileSystem fs, string path)
public static string GetFileName(this IFileSystem fs, string path)
{
return Path.GetFileName(fs.GetFullPath(path));
}
//TODO: Currently this is the only way to do this
internal static void CreateFolder(this IFileSystem fs, string folderPath)
{
var path = fs.GetRelativePath(folderPath);
var tempFile = Path.Combine(path, Guid.NewGuid().ToString("N") + ".tmp");
using (var s = new MemoryStream())
{
fs.AddFile(tempFile, s);
}
fs.DeleteFile(tempFile);
}
}
}
+2
View File
@@ -5,6 +5,8 @@ using Umbraco.Core.CodeAnnotations;
namespace Umbraco.Core.IO
{
//TODO: There is no way to create a directory here without creating a file in a directory and then deleting it
public interface IFileSystem
{
IEnumerable<string> GetDirectories(string path);
+1 -1
View File
@@ -43,7 +43,7 @@ namespace Umbraco.Core.IO
//Replaces tildes with the root dir
public static string ResolveUrl(string virtualPath)
{
if (virtualPath.StartsWith("~"))
if (virtualPath.StartsWith("~"))
return virtualPath.Replace("~", SystemDirectories.Root).Replace("//", "/");
else if (Uri.IsWellFormedUriString(virtualPath, UriKind.Absolute))
return virtualPath;
+3 -2
View File
@@ -93,8 +93,9 @@ namespace Umbraco.Core.IO
public void AddFile(string path, Stream stream, bool overrideIfExists)
{
if (FileExists(path) && !overrideIfExists) throw new InvalidOperationException(string.Format("A file at path '{0}' already exists", path));
var exists = FileExists(path);
if (exists && overrideIfExists == false) throw new InvalidOperationException(string.Format("A file at path '{0}' already exists", path));
EnsureDirectory(Path.GetDirectoryName(path));
if (stream.CanSeek)
+15 -8
View File
@@ -133,16 +133,23 @@ namespace Umbraco.Core.IO
{
if (_size == null)
{
EnsureFileSupportsResizing();
if (_fs.FileExists(Path))
{
EnsureFileSupportsResizing();
var fs = _fs.OpenFile(Path);
var image = Image.FromStream(fs);
var fileWidth = image.Width;
var fileHeight = image.Height;
fs.Close();
image.Dispose();
using (var fs = _fs.OpenFile(Path))
using (var image = Image.FromStream(fs))
{
_size = new Size(fileWidth, fileHeight);
var fileWidth = image.Width;
var fileHeight = image.Height;
_size = new Size(fileWidth, fileHeight);
}
}
else
{
_size = new Size(-1, -1);
}
}
return _size.Value;
}
+49 -22
View File
@@ -1,9 +1,7 @@
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models
{
@@ -234,6 +232,7 @@ namespace Umbraco.Core.Models
/// <remarks>
/// This Property is kept internal until localization is introduced.
/// </remarks>
[DataMember]
internal string NodeName
{
get { return _nodeName; }
@@ -250,6 +249,7 @@ namespace Umbraco.Core.Models
/// <summary>
/// Used internally to track if permissions have been changed during the saving process for this entity
/// </summary>
[IgnoreDataMember]
internal bool PermissionsChanged
{
get { return _permissionsChanged; }
@@ -316,6 +316,7 @@ namespace Umbraco.Core.Models
PublishedState = state;
}
[DataMember]
internal PublishedState PublishedState { get; set; }
/// <summary>
@@ -335,26 +336,6 @@ namespace Umbraco.Core.Models
}
}
/// <summary>
/// Creates a clone of the current entity
/// </summary>
/// <returns></returns>
public IContent Clone()
{
var clone = (Content)this.MemberwiseClone();
clone.Key = Guid.Empty;
clone.Version = Guid.NewGuid();
clone.ResetIdentity();
foreach (var property in clone.Properties)
{
property.ResetIdentity();
property.Version = clone.Version;
}
return clone;
}
/// <summary>
/// Indicates whether a specific property on the current <see cref="IContent"/> entity is dirty.
/// </summary>
@@ -434,5 +415,51 @@ namespace Umbraco.Core.Models
base.UpdatingEntity();
Version = Guid.NewGuid();
}
/// <summary>
/// Creates a deep clone of the current entity with its identity and it's property identities reset
/// </summary>
/// <returns></returns>
[Obsolete("Use DeepCloneWithResetIdentities instead")]
public IContent Clone()
{
return DeepCloneWithResetIdentities();
}
/// <summary>
/// Creates a deep clone of the current entity with its identity and it's property identities reset
/// </summary>
/// <returns></returns>
public IContent DeepCloneWithResetIdentities()
{
var clone = (Content)DeepClone();
clone.Key = Guid.Empty;
clone.Version = Guid.NewGuid();
clone.ResetIdentity();
foreach (var property in clone.Properties)
{
property.ResetIdentity();
property.Version = clone.Version;
}
return clone;
}
public override object DeepClone()
{
var clone = (Content)base.DeepClone();
//turn off change tracking
clone.DisableChangeTracking();
//need to manually clone this since it's not settable
clone._contentType = (IContentType)ContentType.DeepClone();
//this shouldn't really be needed since we're not tracking
clone.ResetDirtyProperties(false);
//re-enable tracking
clone.EnableChangeTracking();
return clone;
}
}
}
+21 -4
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;
@@ -14,10 +15,13 @@ namespace Umbraco.Core.Models
/// <summary>
/// Represents an abstract class for base Content properties and methods
/// </summary>
[Serializable]
[DataContract(IsReference = true)]
[DebuggerDisplay("Id: {Id}, Name: {Name}, ContentType: {ContentTypeBase.Alias}")]
public abstract class ContentBase : Entity, IContentBase
{
protected IContentTypeComposition ContentTypeBase;
private Lazy<int> _parentId;
private string _name;//NOTE Once localization is introduced this will be the localized Name of the Content/Media.
private int _sortOrder;
@@ -50,6 +54,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 +78,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 +259,17 @@ 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>
/// List of PropertyGroups available on this Content object
/// </summary>
@@ -293,10 +310,8 @@ namespace Umbraco.Core.Models
/// <returns><see cref="Property"/> Value as a <see cref="TPassType"/></returns>
public virtual TPassType GetValue<TPassType>(string propertyTypeAlias)
{
if (Properties[propertyTypeAlias].Value is TPassType)
return (TPassType)Properties[propertyTypeAlias].Value;
return (TPassType)Convert.ChangeType(Properties[propertyTypeAlias].Value, typeof(TPassType));
var convertAttempt = Properties[propertyTypeAlias].Value.TryConvertTo<TPassType>();
return convertAttempt.Success ? convertAttempt.Result : default(TPassType);
}
/// <summary>
@@ -433,6 +448,7 @@ namespace Umbraco.Core.Models
/// <summary>
/// Returns a collection of the result of the last validation process, this collection contains all invalid properties.
/// </summary>
[IgnoreDataMember]
internal IEnumerable<Property> LastInvalidProperties
{
get { return _lastInvalidProperties; }
@@ -454,5 +470,6 @@ namespace Umbraco.Core.Models
prop.ResetDirtyProperties(rememberPreviouslyChangedProperties);
}
}
}
}
+153 -126
View File
@@ -25,6 +25,20 @@ namespace Umbraco.Core.Models
{
#region IContent
/// <summary>
/// Returns true if this entity was just published as part of a recent save operation (i.e. it wasn't previously published)
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
/// <remarks>
/// This is helpful for determining if the published event will execute during the saved event for a content item.
/// </remarks>
internal static bool JustPublished(this IContent entity)
{
var dirty = (IRememberBeingDirty)entity;
return dirty.WasPropertyDirty("Published") && entity.Published;
}
/// <summary>
/// Determines if a new version should be created
/// </summary>
@@ -208,6 +222,28 @@ namespace Umbraco.Core.Models
}
#endregion
/// <summary>
/// Removes characters that are not valide XML characters from all entity properties
/// of type string. See: http://stackoverflow.com/a/961504/5018
/// </summary>
/// <returns></returns>
/// <remarks>
/// If this is not done then the xml cache can get corrupt and it will throw YSODs upon reading it.
/// </remarks>
/// <param name="entity"></param>
public static void SanitizeEntityPropertiesForXmlStorage(this IContentBase entity)
{
entity.Name = entity.Name.ToValidXmlString();
foreach (var property in entity.Properties)
{
if (property.Value is string)
{
var value = (string)property.Value;
property.Value = value.ToValidXmlString();
}
}
}
/// <summary>
/// Checks if the IContentBase has children
/// </summary>
@@ -363,8 +399,7 @@ namespace Umbraco.Core.Models
/// <param name="propertyTypeAlias">Alias of the property to save the value on</param>
/// <param name="fileName">Name of the file</param>
/// <param name="fileStream"><see cref="Stream"/> to save to disk</param>
public static void SetValue(this IContentBase content, string propertyTypeAlias, string fileName,
Stream fileStream)
public static void SetValue(this IContentBase content, string propertyTypeAlias, string fileName, Stream fileStream)
{
var name = IOHelper.SafeFileName(fileName);
@@ -378,75 +413,82 @@ namespace Umbraco.Core.Models
if (property == null)
return;
bool supportsResizing = false;
var numberedFolder = MediaSubfolderCounter.Current.Increment();
string fileName = UmbracoSettings.UploadAllowDirectories
var fileName = UmbracoSettings.UploadAllowDirectories
? Path.Combine(numberedFolder.ToString(CultureInfo.InvariantCulture), name)
: numberedFolder + "-" + name;
string extension = Path.GetExtension(name).Substring(1).ToLowerInvariant();
var extension = Path.GetExtension(name).Substring(1).ToLowerInvariant();
//the file size is the length of the stream in bytes
var fileSize = fileStream.Length;
var fs = FileSystemProviderManager.Current.GetFileSystemProvider<MediaFileSystem>();
fs.AddFile(fileName, fileStream);
//Check if file supports resizing and create thumbnails
if (("," + UmbracoSettings.ImageFileTypes + ",").Contains(string.Format(",{0},", extension)))
{
supportsResizing = true;
var supportsResizing = ("," + UmbracoSettings.ImageFileTypes + ",").Contains(string.Format(",{0},", extension));
// Make default thumbnail
var thumbUrl = Resize(fs, fileName, extension, 100, "thumb");
//Look up Prevalues for this upload datatype - if it is an upload datatype
var uploadFieldId = new Guid(Constants.PropertyEditors.UploadField);
if (property.PropertyType.DataTypeId == uploadFieldId)
{
//Get Prevalues by the DataType's Id: property.PropertyType.DataTypeId
var values = ApplicationContext.Current.Services.DataTypeService.GetPreValuesByDataTypeId(property.PropertyType.DataTypeDefinitionId);
var thumbnailSizes = values.FirstOrDefault();
//Additional thumbnails configured as prevalues on the DataType
if (thumbnailSizes != null)
{
char sep = (!thumbnailSizes.Contains("") && thumbnailSizes.Contains(",")) ? ',' : ';';
foreach (string thumb in thumbnailSizes.Split(sep))
{
int thumbSize;
if (thumb != "" && int.TryParse(thumb, out thumbSize))
{
Resize(fs, fileName, extension, thumbSize, string.Format("thumb_{0}", thumbSize));
}
}
}
}
}
//the config section used to auto-fill properties
XmlNode uploadFieldConfigNode = null;
//Check for auto fill of additional properties
if (UmbracoSettings.ImageAutoFillImageProperties != null)
{
XmlNode uploadFieldConfigNode =
uploadFieldConfigNode =
UmbracoSettings.ImageAutoFillImageProperties.SelectSingleNode(
string.Format("uploadField [@alias = \"{0}\"]", propertyTypeAlias));
}
if (uploadFieldConfigNode != null)
{
//Only add dimensions to web images
if (supportsResizing)
if (supportsResizing)
{
//get the original image from the original stream
if (fileStream.CanSeek) fileStream.Seek(0, 0);
using (var originalImage = Image.FromStream(fileStream))
{
// Make default thumbnail
Resize(fs, fileName, extension, 100, "thumb", originalImage);
//Look up Prevalues for this upload datatype - if it is an upload datatype
var uploadFieldId = new Guid(Constants.PropertyEditors.UploadField);
if (property.PropertyType.DataTypeId == uploadFieldId)
{
SetPropertyValue(content, uploadFieldConfigNode, "widthFieldAlias", GetDimensions(fs, fileName).Item1.ToString(CultureInfo.InvariantCulture));
SetPropertyValue(content, uploadFieldConfigNode, "heightFieldAlias", GetDimensions(fs, fileName).Item2.ToString(CultureInfo.InvariantCulture));
}
else
{
SetPropertyValue(content, uploadFieldConfigNode, "widthFieldAlias", string.Empty);
SetPropertyValue(content, uploadFieldConfigNode, "heightFieldAlias", string.Empty);
//Get Prevalues by the DataType's Id: property.PropertyType.DataTypeId
var values = ApplicationContext.Current.Services.DataTypeService.GetPreValuesByDataTypeId(property.PropertyType.DataTypeDefinitionId);
var thumbnailSizes = values.FirstOrDefault();
//Additional thumbnails configured as prevalues on the DataType
if (thumbnailSizes != null)
{
char sep = (!thumbnailSizes.Contains("") && thumbnailSizes.Contains(",")) ? ',' : ';';
foreach (var thumb in thumbnailSizes.Split(sep))
{
int thumbSize;
if (thumb != "" && int.TryParse(thumb, out thumbSize))
{
Resize(fs, fileName, extension, thumbSize, string.Format("thumb_{0}", thumbSize), originalImage);
}
}
}
}
SetPropertyValue(content, uploadFieldConfigNode, "lengthFieldAlias", fs.GetSize(fileName).ToString(CultureInfo.InvariantCulture));
SetPropertyValue(content, uploadFieldConfigNode, "extensionFieldAlias", extension);
//while the image is still open, we'll check if we need to auto-populate the image properties
if (uploadFieldConfigNode != null)
{
SetPropertyValue(content, uploadFieldConfigNode, "widthFieldAlias", originalImage.Width.ToString(CultureInfo.InvariantCulture));
SetPropertyValue(content, uploadFieldConfigNode, "heightFieldAlias", originalImage.Height.ToString(CultureInfo.InvariantCulture));
}
}
}
//if auto-fill is true, then fill the remaining, non-image properties
if (uploadFieldConfigNode != null)
{
SetPropertyValue(content, uploadFieldConfigNode, "lengthFieldAlias", fileSize.ToString(CultureInfo.InvariantCulture));
SetPropertyValue(content, uploadFieldConfigNode, "extensionFieldAlias", extension);
}
//Set the value of the property to that of the uploaded file's url
property.Value = fs.GetUrl(fileName);
}
@@ -460,68 +502,37 @@ namespace Umbraco.Core.Models
}
}
private static string Resize(MediaFileSystem fileSystem, string path, string extension, int maxWidthHeight, string fileNameAddition)
private static ResizedImage Resize(MediaFileSystem fileSystem, string path, string extension, int maxWidthHeight, string fileNameAddition, Image originalImage)
{
var fileNameThumb = DoResize(fileSystem, path, extension, GetDimensions(fileSystem, path).Item1, GetDimensions(fileSystem, path).Item2, maxWidthHeight, fileNameAddition);
return fileSystem.GetUrl(fileNameThumb);
}
private static Tuple<int, int> GetDimensions(MediaFileSystem fileSystem, string path)
{
var fs = fileSystem.OpenFile(path);
var image = Image.FromStream(fs);
var fileWidth = image.Width;
var fileHeight = image.Height;
fs.Close();
image.Dispose();
return new Tuple<int, int>(fileWidth, fileHeight);
}
private static string DoResize(MediaFileSystem fileSystem, string path, string extension, int width, int height, int maxWidthHeight, string fileNameAddition)
{
var fs = fileSystem.OpenFile(path);
var image = Image.FromStream(fs);
fs.Close();
string fileNameThumb = String.IsNullOrEmpty(fileNameAddition) ?
string.Format("{0}_UMBRACOSYSTHUMBNAIL.jpg", path.Substring(0, path.LastIndexOf("."))) :
string.Format("{0}_{1}.jpg", path.Substring(0, path.LastIndexOf(".")), fileNameAddition);
var fileNameThumb = String.IsNullOrEmpty(fileNameAddition)
? string.Format("{0}_UMBRACOSYSTHUMBNAIL.jpg", path.Substring(0, path.LastIndexOf(".")))
: string.Format("{0}_{1}.jpg", path.Substring(0, path.LastIndexOf(".")), fileNameAddition);
var thumb = GenerateThumbnail(fileSystem,
image,
originalImage,
maxWidthHeight,
width,
height,
path,
extension,
fileNameThumb,
maxWidthHeight == 0);
fileNameThumb = thumb.Item3;
image.Dispose();
return fileNameThumb;
return thumb;
}
private static Tuple<int, int, string> GenerateThumbnail(MediaFileSystem fileSystem, Image image, int maxWidthHeight, int fileWidth,
int fileHeight, string fullFilePath, string extension,
string thumbnailFileName, bool useFixedDimensions)
private static ResizedImage GenerateThumbnail(MediaFileSystem fileSystem, Image image, int maxWidthHeight, string extension, string thumbnailFileName, bool useFixedDimensions)
{
// Generate thumbnail
float f = 1;
if (!useFixedDimensions)
{
var fx = (float)image.Size.Width / (float)maxWidthHeight;
var fy = (float)image.Size.Height / (float)maxWidthHeight;
var fx = image.Width / (float)maxWidthHeight;
var fy = image.Height / (float)maxWidthHeight;
// must fit in thumbnail size
f = Math.Max(fx, fy); //if (f < 1) f = 1;
}
var widthTh = (int)Math.Round((float)fileWidth / f); int heightTh = (int)Math.Round((float)fileHeight / f);
var widthTh = (int)Math.Round(image.Width / f);
var heightTh = (int)Math.Round(image.Height / f);
// fixes for empty width or height
if (widthTh == 0)
@@ -530,44 +541,45 @@ namespace Umbraco.Core.Models
heightTh = 1;
// Create new image with best quality settings
var bp = new Bitmap(widthTh, heightTh);
var g = Graphics.FromImage(bp);
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
using (var bp = new Bitmap(widthTh, heightTh))
{
using (var g = Graphics.FromImage(bp))
{
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
// Copy the old image to the new and resized
var rect = new Rectangle(0, 0, widthTh, heightTh);
g.DrawImage(image, rect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel);
// Copy the old image to the new and resized
var rect = new Rectangle(0, 0, widthTh, heightTh);
g.DrawImage(image, rect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel);
// Copy metadata
var imageEncoders = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo codec = null;
if (extension.ToLower() == "png" || extension.ToLower() == "gif")
codec = imageEncoders.Single(t => t.MimeType.Equals("image/png"));
else
codec = imageEncoders.Single(t => t.MimeType.Equals("image/jpeg"));
// Copy metadata
var imageEncoders = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo codec;
if (extension.ToLower() == "png" || extension.ToLower() == "gif")
codec = imageEncoders.Single(t => t.MimeType.Equals("image/png"));
else
codec = imageEncoders.Single(t => t.MimeType.Equals("image/jpeg"));
// Set compresion ratio to 90%
var ep = new EncoderParameters();
ep.Param[0] = new EncoderParameter(Encoder.Quality, 90L);
// Save the new image using the dimensions of the image
var newFileName = thumbnailFileName.Replace("UMBRACOSYSTHUMBNAIL",
string.Format("{0}x{1}", widthTh, heightTh));
using (var ms = new MemoryStream())
{
bp.Save(ms, codec, ep);
ms.Seek(0, 0);
// Set compresion ratio to 90%
var ep = new EncoderParameters();
ep.Param[0] = new EncoderParameter(Encoder.Quality, 90L);
fileSystem.AddFile(newFileName, ms);
}
// Save the new image using the dimensions of the image
string newFileName = thumbnailFileName.Replace("UMBRACOSYSTHUMBNAIL",
string.Format("{0}x{1}", widthTh, heightTh));
var ms = new MemoryStream();
bp.Save(ms, codec, ep);
ms.Seek(0, 0);
fileSystem.AddFile(newFileName, ms);
ms.Close();
bp.Dispose();
g.Dispose();
return new Tuple<int, int, string>(widthTh, heightTh, newFileName);
return new ResizedImage(widthTh, heightTh, newFileName);
}
}
}
/// <summary>
@@ -637,11 +649,16 @@ namespace Umbraco.Core.Models
return ApplicationContext.Current.Services.PackagingService.Export(media);
}
/// <summary>
/// Creates the full xml representation for the <see cref="IMedia"/> object and all of it's descendants
/// </summary>
/// <param name="media"><see cref="IMedia"/> to generate xml for</param>
/// <returns>Xml representation of the passed in <see cref="IMedia"/></returns>
internal static XElement ToDeepXml(this IMedia media)
{
return ApplicationContext.Current.Services.PackagingService.Export(media, true);
}
/// <summary>
/// Creates the xml representation for the <see cref="IContent"/> object
/// </summary>
@@ -654,5 +671,15 @@ namespace Umbraco.Core.Models
//If current IContent is published we should get latest unpublished version
return content.ToXml();
}
/// <summary>
/// Creates the xml representation for the <see cref="IMember"/> object
/// </summary>
/// <param name="member"><see cref="IMember"/> to generate xml for</param>
/// <returns>Xml representation of the passed in <see cref="IContent"/></returns>
public static XElement ToXml(this IMember member)
{
return ApplicationContext.Current.Services.PackagingService.Export(member);
}
}
}
@@ -0,0 +1,23 @@
using System;
using System.Xml.Linq;
namespace Umbraco.Core.Models
{
/// <summary>
/// Used content repository in order to add an entity to the persisted collection to be saved
/// in a single transaction during saving an entity
/// </summary>
internal class ContentPreviewEntity<TContent> : ContentXmlEntity<TContent>
where TContent : IContentBase
{
public ContentPreviewEntity(TContent content, Func<TContent, XElement> xml)
: base(content, xml)
{
}
public Guid Version
{
get { return Content.Version; }
}
}
}
+33 -97
View File
@@ -121,98 +121,6 @@ namespace Umbraco.Core.Models
return result;
}
/// <summary>
/// Indicates whether a specific property on the current <see cref="IContent"/> entity is dirty.
/// </summary>
/// <param name="propertyName">Name of the property to check</param>
/// <returns>True if Property is dirty, otherwise False</returns>
public override bool IsPropertyDirty(string propertyName)
{
bool existsInEntity = base.IsPropertyDirty(propertyName);
bool anyDirtyGroups = PropertyGroups.Any(x => x.IsPropertyDirty(propertyName));
bool anyDirtyTypes = PropertyTypes.Any(x => x.IsPropertyDirty(propertyName));
return existsInEntity || anyDirtyGroups || anyDirtyTypes;
}
/// <summary>
/// Indicates whether the current entity is dirty.
/// </summary>
/// <returns>True if entity is dirty, otherwise False</returns>
public override bool IsDirty()
{
bool dirtyEntity = base.IsDirty();
bool dirtyGroups = PropertyGroups.Any(x => x.IsDirty());
bool dirtyTypes = PropertyTypes.Any(x => x.IsDirty());
return dirtyEntity || dirtyGroups || dirtyTypes;
}
/// <summary>
/// Resets dirty properties by clearing the dictionary used to track changes.
/// </summary>
/// <remarks>
/// Please note that resetting the dirty properties could potentially
/// obstruct the saving of a new or updated entity.
/// </remarks>
public override void ResetDirtyProperties()
{
base.ResetDirtyProperties();
//loop through each property group to reset the property types
var propertiesReset = new List<int>();
foreach (var propertyGroup in PropertyGroups)
{
propertyGroup.ResetDirtyProperties();
foreach (var propertyType in propertyGroup.PropertyTypes)
{
propertyType.ResetDirtyProperties();
propertiesReset.Add(propertyType.Id);
}
}
//then loop through our property type collection since some might not exist on a property group
//but don't re-reset ones we've already done.
foreach (var propertyType in PropertyTypes.Where(x => propertiesReset.Contains(x.Id) == false))
{
propertyType.ResetDirtyProperties();
}
}
/// <summary>
/// Creates a clone of the current entity
/// </summary>
/// <returns></returns>
public IContentType Clone(string alias)
{
var clone = (ContentType)this.MemberwiseClone();
clone.Alias = alias;
clone.Key = Guid.Empty;
var propertyGroups = this.PropertyGroups.Select(x => x.Clone()).ToList();
clone.PropertyGroups = new PropertyGroupCollection(propertyGroups);
clone.PropertyTypes = this.PropertyTypeCollection.Select(x => x.Clone()).ToList();
clone.ResetIdentity();
clone.ResetDirtyProperties(false);
foreach (var propertyGroup in clone.PropertyGroups)
{
propertyGroup.ResetIdentity();
foreach (var propertyType in propertyGroup.PropertyTypes)
{
propertyType.ResetIdentity();
}
}
foreach (var propertyType in clone.PropertyTypes.Where(x => x.HasIdentity))
{
propertyType.ResetIdentity();
}
return clone;
}
/// <summary>
/// Method to call when Entity is being saved
/// </summary>
@@ -225,13 +133,41 @@ namespace Umbraco.Core.Models
Key = Guid.NewGuid();
}
/// <summary>
/// Method to call when Entity is being updated
/// Creates a deep clone of the current entity with its identity/alias and it's property identities reset
/// </summary>
/// <remarks>Modified Date is set and a new Version guid is set</remarks>
internal override void UpdatingEntity()
{
base.UpdatingEntity();
/// <returns></returns>
[Obsolete("Use DeepCloneWithResetIdentities instead")]
public IContentType Clone(string alias)
{
return DeepCloneWithResetIdentities(alias);
}
/// <summary>
/// Creates a deep clone of the current entity with its identity/alias and it's property identities reset
/// </summary>
/// <returns></returns>
public IContentType DeepCloneWithResetIdentities(string alias)
{
var clone = (ContentType)DeepClone();
clone.Alias = alias;
clone.Key = Guid.Empty;
foreach (var propertyGroup in clone.PropertyGroups)
{
propertyGroup.ResetIdentity();
propertyGroup.ResetDirtyProperties(false);
}
foreach (var propertyType in clone.PropertyTypes)
{
propertyType.ResetIdentity();
propertyType.ResetDirtyProperties(false);
}
clone.ResetIdentity();
clone.ResetDirtyProperties(false);
return clone;
}
}
}
+115 -4
View File
@@ -1,10 +1,12 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Strings;
namespace Umbraco.Core.Models
{
@@ -42,6 +44,8 @@ namespace Umbraco.Core.Models
_allowedContentTypes = new List<ContentTypeSort>();
_propertyGroups = new PropertyGroupCollection();
_propertyTypes = new PropertyTypeCollection();
_propertyTypes.CollectionChanged += PropertyTypesChanged;
_additionalData = new Dictionary<string, object>();
}
protected ContentTypeBase(IContentTypeBase parent)
@@ -52,6 +56,8 @@ namespace Umbraco.Core.Models
_allowedContentTypes = new List<ContentTypeSort>();
_propertyGroups = new PropertyGroupCollection();
_propertyTypes = new PropertyTypeCollection();
_propertyTypes.CollectionChanged += PropertyTypesChanged;
_additionalData = new Dictionary<string, object>();
}
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, string>(x => x.Name);
@@ -168,7 +174,8 @@ namespace Umbraco.Core.Models
{
SetPropertyValueAndDetectChanges(o =>
{
_alias = value.ToSafeAlias();
//_alias = value.ToSafeAlias();
_alias = value.ToCleanString(CleanStringType.Alias | CleanStringType.UmbracoCase);
return _alias;
}, _alias, AliasSelector);
}
@@ -314,6 +321,16 @@ namespace Umbraco.Core.Models
}
}
private IDictionary<string, object> _additionalData;
/// <summary>
/// Some entities may expose additional data that other's might not, this custom data will be available in this collection
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
IDictionary<string, object> IUmbracoEntity.AdditionalData
{
get { return _additionalData; }
}
/// <summary>
/// Gets or sets a list of integer Ids for allowed ContentTypes
/// </summary>
@@ -334,7 +351,9 @@ namespace Umbraco.Core.Models
/// <summary>
/// List of PropertyGroups available on this ContentType
/// </summary>
/// <remarks>A PropertyGroup corresponds to a Tab in the UI</remarks>
/// <remarks>
/// A PropertyGroup corresponds to a Tab in the UI
/// </remarks>
[DataMember]
public virtual PropertyGroupCollection PropertyGroups
{
@@ -350,7 +369,13 @@ namespace Umbraco.Core.Models
/// List of PropertyTypes available on this ContentType.
/// This list aggregates PropertyTypes across the PropertyGroups.
/// </summary>
/// <remarks>
/// Marked as DoNotClone because the result of this property is not the natural result of the data, it is
/// a union of data so when auto-cloning if the setter is used it will be setting the unnatural result of the
/// data. We manually clone this instead.
/// </remarks>
[IgnoreDataMember]
[DoNotClone]
public virtual IEnumerable<PropertyType> PropertyTypes
{
get
@@ -366,6 +391,14 @@ namespace Umbraco.Core.Models
}
/// <summary>
/// Returns the property type collection containing types that are non-groups - used for tests
/// </summary>
internal IEnumerable<PropertyType> NonGroupedPropertyTypes
{
get { return _propertyTypes; }
}
/// <summary>
/// A boolean flag indicating if a property type has been removed from this instance.
/// </summary>
/// <remarks>
@@ -415,8 +448,7 @@ namespace Umbraco.Core.Models
{
if (PropertyTypeExists(propertyType.Alias) == false)
{
_propertyTypes.Add(propertyType);
_propertyTypes.CollectionChanged += PropertyTypesChanged;
_propertyTypes.Add(propertyType);
return true;
}
@@ -503,5 +535,84 @@ namespace Umbraco.Core.Models
{
get { return _propertyTypes; }
}
/// <summary>
/// Indicates whether a specific property on the current <see cref="IContent"/> entity is dirty.
/// </summary>
/// <param name="propertyName">Name of the property to check</param>
/// <returns>True if Property is dirty, otherwise False</returns>
public override bool IsPropertyDirty(string propertyName)
{
bool existsInEntity = base.IsPropertyDirty(propertyName);
bool anyDirtyGroups = PropertyGroups.Any(x => x.IsPropertyDirty(propertyName));
bool anyDirtyTypes = PropertyTypes.Any(x => x.IsPropertyDirty(propertyName));
return existsInEntity || anyDirtyGroups || anyDirtyTypes;
}
/// <summary>
/// Indicates whether the current entity is dirty.
/// </summary>
/// <returns>True if entity is dirty, otherwise False</returns>
public override bool IsDirty()
{
bool dirtyEntity = base.IsDirty();
bool dirtyGroups = PropertyGroups.Any(x => x.IsDirty());
bool dirtyTypes = PropertyTypes.Any(x => x.IsDirty());
return dirtyEntity || dirtyGroups || dirtyTypes;
}
/// <summary>
/// Resets dirty properties by clearing the dictionary used to track changes.
/// </summary>
/// <remarks>
/// Please note that resetting the dirty properties could potentially
/// obstruct the saving of a new or updated entity.
/// </remarks>
public override void ResetDirtyProperties()
{
base.ResetDirtyProperties();
//loop through each property group to reset the property types
var propertiesReset = new List<int>();
foreach (var propertyGroup in PropertyGroups)
{
propertyGroup.ResetDirtyProperties();
foreach (var propertyType in propertyGroup.PropertyTypes)
{
propertyType.ResetDirtyProperties();
propertiesReset.Add(propertyType.Id);
}
}
//then loop through our property type collection since some might not exist on a property group
//but don't re-reset ones we've already done.
foreach (var propertyType in PropertyTypes.Where(x => propertiesReset.Contains(x.Id) == false))
{
propertyType.ResetDirtyProperties();
}
}
public override object DeepClone()
{
var clone = (ContentTypeBase)base.DeepClone();
//turn off change tracking
clone.DisableChangeTracking();
//need to manually wire up the event handlers for the property type collections - we've ensured
// its ignored from the auto-clone process because its return values are unions, not raw and
// we end up with duplicates, see: http://issues.umbraco.org/issue/U4-4842
clone._propertyTypes = (PropertyTypeCollection)_propertyTypes.DeepClone();
clone._propertyTypes.CollectionChanged += clone.PropertyTypesChanged;
//this shouldn't really be needed since we're not tracking
clone.ResetDirtyProperties(false);
//re-enable tracking
clone.EnableChangeTracking();
return clone;
}
}
}
@@ -13,7 +13,7 @@ namespace Umbraco.Core.Models
[DataContract(IsReference = true)]
public abstract class ContentTypeCompositionBase : ContentTypeBase, IContentTypeComposition
{
private readonly List<IContentTypeComposition> _contentTypeComposition = new List<IContentTypeComposition>();
private List<IContentTypeComposition> _contentTypeComposition = new List<IContentTypeComposition>();
internal List<int> RemovedContentTypeKeyTracker = new List<int>();
protected ContentTypeCompositionBase(int parentId) : base(parentId)
@@ -217,5 +217,21 @@ namespace Umbraco.Core.Models
.Select(x => x.Id)
.Union(ContentTypeComposition.SelectMany(x => x.CompositionIds()));
}
public override object DeepClone()
{
var clone = (ContentTypeCompositionBase)base.DeepClone();
//turn off change tracking
clone.DisableChangeTracking();
//need to manually assign since this is an internal field and will not be automatically mapped
clone.RemovedContentTypeKeyTracker = new List<int>();
clone._contentTypeComposition = ContentTypeComposition.Select(x => (IContentTypeComposition)x.DeepClone()).ToList();
//this shouldn't really be needed since we're not tracking
clone.ResetDirtyProperties(false);
//re-enable tracking
clone.EnableChangeTracking();
return clone;
}
}
}
+32 -1
View File
@@ -6,7 +6,7 @@ namespace Umbraco.Core.Models
/// <summary>
/// Represents a POCO for setting sort order on a ContentType reference
/// </summary>
public class ContentTypeSort : IValueObject
public class ContentTypeSort : IValueObject, IDeepCloneable
{
public ContentTypeSort()
{
@@ -33,5 +33,36 @@ namespace Umbraco.Core.Models
/// Gets or sets the Alias of the ContentType
/// </summary>
public string Alias { get; set; }
public object DeepClone()
{
var clone = (ContentTypeSort)MemberwiseClone();
var id = Id.Value;
clone.Id = new Lazy<int>(() => id);
return clone;
}
protected bool Equals(ContentTypeSort other)
{
return Id.Value.Equals(other.Id.Value) && string.Equals(Alias, other.Alias);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((ContentTypeSort) obj);
}
public override int GetHashCode()
{
unchecked
{
return (Id.GetHashCode()*397) ^ Alias.GetHashCode();
}
}
}
}
@@ -0,0 +1,64 @@
using System;
using System.Xml.Linq;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Models
{
/// <summary>
/// Used in content/media/member repositories in order to add this type of entity to the persisted collection to be saved
/// in a single transaction during saving an entity
/// </summary>
internal class ContentXmlEntity<TContent> : IAggregateRoot
where TContent : IContentBase
{
private readonly Func<TContent, XElement> _xml;
public ContentXmlEntity(TContent content, Func<TContent, XElement> xml)
{
if (content == null) throw new ArgumentNullException("content");
_xml = xml;
Content = content;
}
public ContentXmlEntity(TContent content)
{
if (content == null) throw new ArgumentNullException("content");
Content = content;
}
public XElement Xml
{
get { return _xml(Content); }
}
public TContent Content { get; private set; }
public int Id
{
get { return Content.Id; }
set { throw new NotSupportedException(); }
}
public Guid Key { get; set; }
public DateTime CreateDate { get; set; }
public DateTime UpdateDate { get; set; }
/// <summary>
/// Special case, always return false, this will cause the repositories managing
/// this object to always do an 'insert' but these are special repositories that
/// do an InsertOrUpdate on insert since the data for this needs to be managed this way
/// </summary>
public bool HasIdentity
{
get { return false; }
}
public object DeepClone()
{
var clone = (ContentXmlEntity<TContent>)MemberwiseClone();
//Automatically deep clone ref properties that are IDeepCloneable
DeepCloneHelper.DeepCloneRefProperties(this, clone);
return clone;
}
}
}
+21 -1
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;
@@ -31,6 +33,7 @@ namespace Umbraco.Core.Models
{
_parentId = parentId;
_controlId = controlId;
_additionalData = new Dictionary<string, object>();
}
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<DataTypeDefinition, string>(x => x.Name);
@@ -160,9 +163,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;
}
}
/// <summary>
/// Id of the DataType control
/// </summary>
@@ -177,6 +182,8 @@ namespace Umbraco.Core.Models
_controlId = value;
return _controlId;
}, _controlId, ControlIdSelector);
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
_additionalData["ControlId"] = value;
}
}
@@ -194,9 +201,22 @@ 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; }
}
internal override void AddingEntity()
{
base.AddingEntity();
+174
View File
@@ -0,0 +1,174 @@
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Umbraco.Core.Models
{
/// <summary>
/// Used to attribute properties that have a setter and are a reference type
/// that should be ignored for cloning when using the DeepCloneHelper
/// </summary>
/// <remarks>
///
/// This attribute must be used:
/// * when the property is backed by a field but the result of the property is the un-natural data stored in the field
///
/// This attribute should not be used:
/// * when the property is virtual
/// * when the setter performs additional required logic other than just setting the underlying field
///
/// </remarks>
internal class DoNotCloneAttribute : Attribute
{
}
public static class DeepCloneHelper
{
/// <summary>
/// Used to avoid constant reflection (perf)
/// </summary>
private static readonly ConcurrentDictionary<Type, PropertyInfo[]> PropCache = new ConcurrentDictionary<Type, PropertyInfo[]>();
/// <summary>
/// Used to deep clone any reference properties on the object (should be done after a MemberwiseClone for which the outcome is 'output')
/// </summary>
/// <param name="input"></param>
/// <param name="output"></param>
/// <returns></returns>
public static void DeepCloneRefProperties(IDeepCloneable input, IDeepCloneable output)
{
var inputType = input.GetType();
var outputType = output.GetType();
if (inputType != outputType)
{
throw new InvalidOperationException("Both the input and output types must be the same");
}
var refProperties = PropCache.GetOrAdd(inputType, type =>
inputType.GetProperties()
.Where(x =>
//is not attributed with the ignore clone attribute
Attribute.GetCustomAttribute(x, typeof(DoNotCloneAttribute)) == null
//reference type but not string
&& x.PropertyType.IsValueType == false && x.PropertyType != typeof (string)
//settable
&& x.CanWrite
//non-indexed
&& x.GetIndexParameters().Any() == false)
.ToArray());
foreach (var propertyInfo in refProperties)
{
if (TypeHelper.IsTypeAssignableFrom<IDeepCloneable>(propertyInfo.PropertyType))
{
//this ref property is also deep cloneable so clone it
var result = (IDeepCloneable)propertyInfo.GetValue(input, null);
if (result != null)
{
//set the cloned value to the property
propertyInfo.SetValue(output, result.DeepClone(), null);
}
}
else if (TypeHelper.IsTypeAssignableFrom<IEnumerable>(propertyInfo.PropertyType)
&& TypeHelper.IsTypeAssignableFrom<string>(propertyInfo.PropertyType) == false)
{
IList newList;
if (propertyInfo.PropertyType.IsGenericType
&& (propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(IEnumerable<>)
|| propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(ICollection<>)
|| propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(IList<>)))
{
//if it is a IEnumerable<>, IList<T> or ICollection<> we'll use a List<>
var genericType = typeof(List<>).MakeGenericType(propertyInfo.PropertyType.GetGenericArguments());
newList = (IList)Activator.CreateInstance(genericType);
}
else if (propertyInfo.PropertyType.IsArray
|| (propertyInfo.PropertyType.IsInterface && propertyInfo.PropertyType.IsGenericType == false))
{
//if its an array, we'll create a list to work with first and then convert to array later
//otherwise if its just a regular derivitave of IEnumerable, we can use a list too
newList = new List<object>();
}
else
{
//its a custom IEnumerable, we'll try to create it
try
{
var custom = Activator.CreateInstance(propertyInfo.PropertyType);
//if it's an IList we can work with it, otherwise we cannot
newList = custom as IList;
if (newList == null)
{
continue;
}
}
catch (Exception)
{
//could not create this type so we'll skip it
continue;
}
}
var enumerable = (IEnumerable)propertyInfo.GetValue(input, null);
if (enumerable == null) continue;
var isUsableType = true;
//now clone each item
foreach (var o in enumerable)
{
//first check if the item is deep cloneable and copy that way
var dc = o as IDeepCloneable;
if (dc != null)
{
newList.Add(dc.DeepClone());
}
else if (o is string || o.GetType().IsValueType)
{
//check if the item is a value type or a string, then we can just use it
newList.Add(o);
}
else
{
//this will occur if the item is not a string or value type or IDeepCloneable, in this case we cannot
// clone each element, we'll need to skip this property, people will have to manually clone this list
isUsableType = false;
break;
}
}
//if this was not usable, skip this property
if (isUsableType == false)
{
continue;
}
if (propertyInfo.PropertyType.IsArray)
{
//need to convert to array
var arr = (object[])Activator.CreateInstance(propertyInfo.PropertyType, newList.Count);
for (int i = 0; i < newList.Count; i++)
{
arr[i] = newList[i];
}
//set the cloned collection
propertyInfo.SetValue(output, arr, null);
}
else
{
//set the cloned collection
propertyInfo.SetValue(output, newList, null);
}
}
}
}
}
}
+2 -1
View File
@@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models
{
@@ -97,5 +97,6 @@ namespace Umbraco.Core.Models
if(ParentId == Guid.Empty)
_parentId = new Guid("41c7638d-f529-4bff-853e-59a0c2fb1bde");
}
}
}
@@ -65,5 +65,6 @@ namespace Umbraco.Core.Models
}, _value, ValueSelector);
}
}
}
}
+70 -1
View File
@@ -1,7 +1,10 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
namespace Umbraco.Core.Models.EntityBase
{
@@ -93,7 +96,7 @@ namespace Umbraco.Core.Models.EntityBase
}
/// <summary>
/// /// Gets or sets the WasCancelled flag, which is used to track
/// Gets or sets the WasCancelled flag, which is used to track
/// whether some action against an entity was cancelled through some event.
/// This only exists so we have a way to check if an event was cancelled through
/// the new api, which also needs to take effect in the legacy api.
@@ -155,6 +158,7 @@ namespace Umbraco.Core.Models.EntityBase
/// <summary>
/// Indicates whether the current entity has an identity, eg. Id.
/// </summary>
[DataMember]
public virtual bool HasIdentity
{
get
@@ -226,5 +230,70 @@ namespace Umbraco.Core.Models.EntityBase
_hash = !HasIdentity ? new int?(base.GetHashCode()) : new int?(Id.GetHashCode() * 397 ^ GetType().GetHashCode());
return _hash.Value;
}
public virtual object DeepClone()
{
//Memberwise clone on Entity will work since it doesn't have any deep elements
// for any sub class this will work for standard properties as well that aren't complex object's themselves.
var clone = (Entity)MemberwiseClone();
//ensure the clone has it's own dictionaries
clone.ResetChangeTrackingCollections();
//turn off change tracking
clone.DisableChangeTracking();
//Automatically deep clone ref properties that are IDeepCloneable
DeepCloneHelper.DeepCloneRefProperties(this, clone);
//this shouldn't really be needed since we're not tracking
clone.ResetDirtyProperties(false);
//re-enable tracking
clone.EnableChangeTracking();
return clone;
//Using data contract serializer - has issues
//var s = Serialize(this);
//var d = Deserialize(s, this.GetType());
//return d;
//Using binary serializer - has issues
//using (var memoryStream = new MemoryStream(10))
//{
//IFormatter formatter = new BinaryFormatter();
//formatter.Serialize(memoryStream, this);
//memoryStream.Seek(0, SeekOrigin.Begin);
//return formatter.Deserialize(memoryStream);
//}
}
// serialize/deserialize with data contracts:
//public static string Serialize(object obj)
//{
// using (var memoryStream = new MemoryStream())
// using (var reader = new StreamReader(memoryStream))
// {
// var serializer = new DataContractSerializer(obj.GetType());
// serializer.WriteObject(memoryStream, obj);
// memoryStream.Position = 0;
// return reader.ReadToEnd();
// }
//}
//public static object Deserialize(string xml, Type toType)
//{
// using (Stream stream = new MemoryStream())
// {
// using (var writer = new StreamWriter(stream, Encoding.UTF8))
// {
// writer.Write(xml);
// //byte[] data = Encoding.UTF8.GetBytes(xml);
// //stream.Write(data, 0, data.Length);
// stream.Position = 0;
// var deserializer = new DataContractSerializer(toType);
// return deserializer.ReadObject(stream);
// }
// }
//}
}
}
@@ -9,7 +9,7 @@ namespace Umbraco.Core.Models.EntityBase
/// </summary>
/// <remarks>The current database schema doesn't provide a modified date
/// for all entities, so this will have to be changed at a later stage.</remarks>
public interface IEntity
public interface IEntity : IDeepCloneable
{
/// <summary>
/// The Id of the entity
@@ -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; }
}
}
@@ -3,18 +3,31 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
namespace Umbraco.Core.Models.EntityBase
{
/// <summary>
/// A base class for use to implement IRememberBeingDirty/ICanBeDirty
/// </summary>
[Serializable]
[DataContract(IsReference = true)]
public abstract class TracksChangesEntityBase : IRememberBeingDirty
{
//TODO: This needs to go on to ICanBeDirty http://issues.umbraco.org/issue/U4-5662
public virtual IEnumerable<string> GetDirtyProperties()
{
return _propertyChangedInfo.Where(x => x.Value).Select(x => x.Key);
}
private bool _changeTrackingEnabled = true;
/// <summary>
/// Tracks the properties that have changed
/// </summary>
private readonly IDictionary<string, bool> _propertyChangedInfo = new Dictionary<string, bool>();
private IDictionary<string, bool> _propertyChangedInfo = new Dictionary<string, bool>();
/// <summary>
/// Tracks the properties that we're changed before the last commit (or last call to ResetDirtyProperties)
@@ -32,6 +45,9 @@ namespace Umbraco.Core.Models.EntityBase
/// <param name="propertyInfo">The property info.</param>
protected virtual void OnPropertyChanged(PropertyInfo propertyInfo)
{
//return if we're not tracking changes
if (_changeTrackingEnabled == false) return;
_propertyChangedInfo[propertyInfo.Name] = true;
if (PropertyChanged != null)
@@ -83,7 +99,9 @@ namespace Umbraco.Core.Models.EntityBase
/// </summary>
public void ForgetPreviouslyDirtyProperties()
{
_lastPropertyChangedInfo.Clear();
//NOTE: We cannot .Clear() because when we memberwise clone this will be the SAME
// instance as the one on the clone, so we need to create a new instance.
_lastPropertyChangedInfo = new Dictionary<string, bool>();
}
/// <summary>
@@ -116,7 +134,25 @@ namespace Umbraco.Core.Models.EntityBase
_lastPropertyChangedInfo = _propertyChangedInfo.ToDictionary(v => v.Key, v => v.Value);
}
_propertyChangedInfo.Clear();
//NOTE: We cannot .Clear() because when we memberwise clone this will be the SAME
// instance as the one on the clone, so we need to create a new instance.
_propertyChangedInfo = new Dictionary<string, bool>();
}
protected void ResetChangeTrackingCollections()
{
_propertyChangedInfo = new Dictionary<string, bool>();
_lastPropertyChangedInfo = new Dictionary<string, bool>();
}
protected void DisableChangeTracking()
{
_changeTrackingEnabled = false;
}
protected void EnableChangeTracking()
{
_changeTrackingEnabled = true;
}
/// <summary>
@@ -136,12 +172,20 @@ namespace Umbraco.Core.Models.EntityBase
{
var initVal = value;
var newVal = setValue(value);
if (!Equals(initVal, newVal))
//don't track changes, just set the value (above)
if (_changeTrackingEnabled == false) return false;
if (Equals(initVal, newVal) == false)
{
OnPropertyChanged(propertySelector);
return true;
}
return false;
}
}
}
@@ -0,0 +1,24 @@
using System.Linq;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Models
{
public static class EntityExtensions
{
/// <summary>
/// Returns true if this entity has just been created and persisted to the data store
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
/// <remarks>
/// This is useful when handling events to determine if an entity is a brand new entity or was
/// already existing.
/// </remarks>
public static bool IsNewEntity(this IEntity entity)
{
var dirty = (IRememberBeingDirty)entity;
return dirty.WasPropertyDirty("Id");
}
}
}
+35 -5
View File
@@ -23,6 +23,8 @@ namespace Umbraco.Core.Models
private static readonly PropertyInfo ContentSelector = ExpressionHelper.GetPropertyInfo<File, string>(x => x.Content);
private static readonly PropertyInfo PathSelector = ExpressionHelper.GetPropertyInfo<File, string>(x => x.Path);
private string _alias;
private string _name;
/// <summary>
/// Gets or sets the Name of the File including extension
@@ -32,7 +34,11 @@ namespace Umbraco.Core.Models
{
get
{
return new FileInfo(Path).Name;
if (_name == null)
{
_name = System.IO.Path.GetFileName(Path);
}
return _name;
}
}
@@ -44,10 +50,14 @@ namespace Umbraco.Core.Models
{
get
{
var fileInfo = new FileInfo(Path);
var name = fileInfo.Name;
int lastIndexOf = name.LastIndexOf(".", StringComparison.InvariantCultureIgnoreCase);
return name.Substring(0, lastIndexOf);
if (_alias == null)
{
var name = System.IO.Path.GetFileName(Path);
if (name == null) return string.Empty;
var lastIndexOf = name.LastIndexOf(".", StringComparison.InvariantCultureIgnoreCase);
_alias = name.Substring(0, lastIndexOf);
}
return _alias;
}
}
@@ -60,6 +70,10 @@ namespace Umbraco.Core.Models
get { return _path; }
set
{
//reset
_alias = null;
_name = null;
SetPropertyValueAndDetectChanges(o =>
{
_path = value;
@@ -90,5 +104,21 @@ namespace Umbraco.Core.Models
/// </summary>
/// <returns>True if file is valid, otherwise false</returns>
public abstract bool IsValid();
public override object DeepClone()
{
var clone = (File)base.DeepClone();
//turn off change tracking
clone.DisableChangeTracking();
//need to manually assign since they are readonly properties
clone._alias = Alias;
clone._name = Name;
//this shouldn't really be needed since we're not tracking
clone.ResetDirtyProperties(false);
//re-enable tracking
clone.EnableChangeTracking();
return clone;
}
}
}
+14
View File
@@ -0,0 +1,14 @@
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Models
{
internal sealed class Folder : Entity
{
public Folder(string folderPath)
{
Path = folderPath;
}
public string Path { get; set; }
}
}
+6
View File
@@ -72,5 +72,11 @@ namespace Umbraco.Core.Models
/// Changes the Published state of the content object
/// </summary>
void ChangePublishedState(PublishedState state);
/// <summary>
/// Creates a deep clone of the current entity with its identity/alias and it's property identities reset
/// </summary>
/// <returns></returns>
IContent DeepCloneWithResetIdentities();
}
}
+7 -1
View File
@@ -1,5 +1,4 @@
using System.Collections.Generic;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models
{
@@ -30,5 +29,12 @@ namespace Umbraco.Core.Models
/// <param name="template"><see cref="ITemplate"/> to remove</param>
/// <returns>True if template was removed, otherwise False</returns>
bool RemoveTemplate(ITemplate template);
/// <summary>
/// Creates a deep clone of the current entity with its identity/alias and it's property identities reset
/// </summary>
/// <param name="newAlias"></param>
/// <returns></returns>
IContentType DeepCloneWithResetIdentities(string newAlias);
}
}
@@ -0,0 +1,9 @@
using System.Reflection;
namespace Umbraco.Core.Models
{
public interface IDeepCloneable
{
object DeepClone();
}
}
+18
View File
@@ -0,0 +1,18 @@
using System;
using Umbraco.Core.Models.Membership;
namespace Umbraco.Core.Models
{
public interface IMember : IContentBase, IMembershipUser
{
/// <summary>
/// String alias of the default ContentType
/// </summary>
string ContentTypeAlias { get; }
/// <summary>
/// Gets the ContentType used by this content object
/// </summary>
IMemberType ContentType { get; }
}
}
+26
View File
@@ -0,0 +1,26 @@
using System.Collections.Generic;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Models
{
/// <summary>
/// Represents a member type
/// </summary>
public interface IMemberGroup : IAggregateRoot
{
/// <summary>
/// The name of the member group
/// </summary>
string Name { get; set; }
/// <summary>
/// Profile of the user who created this Entity
/// </summary>
int CreatorId { get; set; }
/// <summary>
/// Some entities may expose additional data that other's might not, this custom data will be available in this collection
/// </summary>
IDictionary<string, object> AdditionalData { get; }
}
}
+36
View File
@@ -0,0 +1,36 @@
namespace Umbraco.Core.Models
{
/// <summary>
/// Defines a MemberType, which Member is based on
/// </summary>
public interface IMemberType : IContentTypeComposition
{
/// <summary>
/// Gets a boolean indicating whether a Property is editable by the Member.
/// </summary>
/// <param name="propertyTypeAlias">PropertyType Alias of the Property to check</param>
/// <returns></returns>
bool MemberCanEditProperty(string propertyTypeAlias);
/// <summary>
/// Gets a boolean indicating whether a Property is visible on the Members profile.
/// </summary>
/// <param name="propertyTypeAlias">PropertyType Alias of the Property to check</param>
/// <returns></returns>
bool MemberCanViewProperty(string propertyTypeAlias);
/// <summary>
/// Sets a boolean indicating whether a Property is editable by the Member.
/// </summary>
/// <param name="propertyTypeAlias">PropertyType Alias of the Property to set</param>
/// <param name="value">Boolean value, true or false</param>
void SetMemberCanEditProperty(string propertyTypeAlias, bool value);
/// <summary>
/// Sets a boolean indicating whether a Property is visible on the Members profile.
/// </summary>
/// <param name="propertyTypeAlias">PropertyType Alias of the Property to set</param>
/// <param name="value">Boolean value, true or false</param>
void SetMemberCanViewProperty(string propertyTypeAlias, bool value);
}
}
+121 -28
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; }
#endregion
#region Properties
/// <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<IPublishedContentProperty> Properties { get; }
/// <summary>
/// Returns the property value for the property alias specified
/// </summary>
/// <param name="propertyAlias"></param>
/// <returns></returns>
object this[string propertyAlias] { 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>
IPublishedContentProperty GetProperty(string alias);
/// <summary>
/// Returns a property on the object based on an 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>
IPublishedContentProperty 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,11 +1,65 @@
using System;
namespace Umbraco.Core.Models
{
public interface IPublishedContentProperty
{
string Alias { get; }
object Value { get; }
Guid Version { get; }
}
using System;
namespace Umbraco.Core.Models
{
/// <summary>
/// Represents a property of an <c>IPublishedContent</c>.
/// </summary>
public interface IPublishedContentProperty
{
/// <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; }
string Alias { get; }
Guid Version { get; }
}
}
+38
View File
@@ -0,0 +1,38 @@
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Models
{
public interface IRelation : IAggregateRoot
{
/// <summary>
/// Gets or sets the Parent Id of the Relation (Source)
/// </summary>
[DataMember]
int ParentId { get; set; }
/// <summary>
/// Gets or sets the Child Id of the Relation (Destination)
/// </summary>
[DataMember]
int ChildId { get; set; }
/// <summary>
/// Gets or sets the <see cref="RelationType"/> for the Relation
/// </summary>
[DataMember]
IRelationType RelationType { get; set; }
/// <summary>
/// Gets or sets a comment for the Relation
/// </summary>
[DataMember]
string Comment { get; set; }
/// <summary>
/// Gets the Id of the <see cref="RelationType"/> that this Relation is based on.
/// </summary>
[IgnoreDataMember]
int RelationTypeId { get; }
}
}
+41
View File
@@ -0,0 +1,41 @@
using System;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Models
{
public interface IRelationType : IAggregateRoot
{
/// <summary>
/// Gets or sets the Name of the RelationType
/// </summary>
[DataMember]
string Name { get; set; }
/// <summary>
/// Gets or sets the Alias of the RelationType
/// </summary>
[DataMember]
string Alias { get; set; }
/// <summary>
/// Gets or sets a boolean indicating whether the RelationType is Bidirectional (true) or Parent to Child (false)
/// </summary>
[DataMember]
bool IsBidirectional { get; set; }
/// <summary>
/// Gets or sets the Parents object type id
/// </summary>
/// <remarks>Corresponds to the NodeObjectType in the umbracoNode table</remarks>
[DataMember]
Guid ParentObjectType { get; set; }
/// <summary>
/// Gets or sets the Childs object type id
/// </summary>
/// <remarks>Corresponds to the NodeObjectType in the umbracoNode table</remarks>
[DataMember]
Guid ChildObjectType { get; set; }
}
}
+6
View File
@@ -10,5 +10,11 @@
/// </summary>
/// <returns><see cref="RenderingEngine"/></returns>
RenderingEngine GetTypeOfRenderingEngine();
/// <summary>
/// Set the mastertemplate
/// </summary>
/// <param name="masterTemplate"></param>
void SetMasterTemplate(ITemplate masterTemplate);
}
}
-1
View File
@@ -3,7 +3,6 @@ using System.Globalization;
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models
{
+654
View File
@@ -0,0 +1,654 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Logging;
namespace Umbraco.Core.Models
{
/// <summary>
/// Represents a Member object
/// </summary>
[Serializable]
[DataContract(IsReference = true)]
public class Member : ContentBase, IMember
{
private IMemberType _contentType;
private readonly string _contentTypeAlias;
private string _username;
private string _email;
private string _rawPasswordValue;
private object _providerUserKey;
private Type _userTypeKey;
/// <summary>
/// Constructor for creating an empty Member object
/// </summary>
/// <param name="contentType">ContentType for the current Content object</param>
public Member(IMemberType contentType)
: base("", -1, contentType, new PropertyCollection())
{
Mandate.ParameterNotNull(contentType, "contentType");
_contentTypeAlias = contentType.Alias;
_contentType = contentType;
IsApproved = true;
//this cannot be null but can be empty
_rawPasswordValue = "";
_email = "";
_username = "";
}
/// <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)
: this(contentType)
{
Mandate.ParameterNotNull(contentType, "contentType");
Mandate.ParameterNotNullOrEmpty(name, "name");
_contentTypeAlias = contentType.Alias;
_contentType = contentType;
IsApproved = true;
//this cannot be null but can be empty
_rawPasswordValue = "";
_email = "";
_username = "";
}
/// <summary>
/// Constructor for creating a Member object
/// </summary>
/// <param name="name"></param>
/// <param name="email"></param>
/// <param name="username"></param>
/// <param name="contentType"></param>
public Member(string name, string email, string username, IMemberType contentType)
: base(name, -1, contentType, new PropertyCollection())
{
Mandate.ParameterNotNull(contentType, "contentType");
Mandate.ParameterNotNullOrEmpty(name, "name");
Mandate.ParameterNotNullOrEmpty(email, "email");
Mandate.ParameterNotNullOrEmpty(username, "username");
_contentTypeAlias = contentType.Alias;
_contentType = contentType;
_email = email;
_username = username;
IsApproved = true;
//this cannot be null but can be empty
_rawPasswordValue = "";
}
/// <summary>
/// Constructor for creating a Member object
/// </summary>
/// <param name="name"></param>
/// <param name="email"></param>
/// <param name="username"></param>
/// <param name="rawPasswordValue">
/// The password value passed in to this parameter should be the encoded/encrypted/hashed format of the member's password
/// </param>
/// <param name="contentType"></param>
public Member(string name, string email, string username, string rawPasswordValue, IMemberType contentType)
: base(name, -1, contentType, new PropertyCollection())
{
Mandate.ParameterNotNull(contentType, "contentType");
_contentTypeAlias = contentType.Alias;
_contentType = contentType;
_email = email;
_username = username;
_rawPasswordValue = rawPasswordValue;
IsApproved = true;
}
private static readonly PropertyInfo UsernameSelector = ExpressionHelper.GetPropertyInfo<Member, string>(x => x.Username);
private static readonly PropertyInfo EmailSelector = ExpressionHelper.GetPropertyInfo<Member, string>(x => x.Email);
private static readonly PropertyInfo PasswordSelector = ExpressionHelper.GetPropertyInfo<Member, string>(x => x.RawPasswordValue);
private static readonly PropertyInfo ProviderUserKeySelector = ExpressionHelper.GetPropertyInfo<Member, object>(x => x.ProviderUserKey);
private static readonly PropertyInfo UserTypeKeySelector = ExpressionHelper.GetPropertyInfo<Member, Type>(x => x.ProviderUserKeyType);
/// <summary>
/// Gets or sets the Username
/// </summary>
[DataMember]
public string Username
{
get { return _username; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_username = value;
return _username;
}, _username, UsernameSelector);
}
}
/// <summary>
/// Gets or sets the Email
/// </summary>
[DataMember]
public string Email
{
get { return _email; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_email = value;
return _email;
}, _email, EmailSelector);
}
}
/// <summary>
/// Gets or sets the raw password value
/// </summary>
[IgnoreDataMember]
public string RawPasswordValue
{
get { return _rawPasswordValue; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_rawPasswordValue = value;
return _rawPasswordValue;
}, _rawPasswordValue, PasswordSelector);
}
}
/// <summary>
/// Gets or sets the Groups that Member is part of
/// </summary>
[DataMember]
public IEnumerable<string> Groups { get; set; }
/// <summary>
/// Gets or sets the Password Question
/// </summary>
/// <remarks>
/// Alias: umbracoPasswordRetrievalQuestionPropertyTypeAlias
/// Part of the standard properties collection.
/// </remarks>
[DataMember]
public string PasswordQuestion
{
get
{
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.PasswordQuestion, "PasswordQuestion", default(string));
if (a.Success == false) return a.Result;
return Properties[Constants.Conventions.Member.PasswordQuestion].Value == null
? string.Empty
: Properties[Constants.Conventions.Member.PasswordQuestion].Value.ToString();
}
set
{
if (WarnIfPropertyTypeNotFoundOnSet(
Constants.Conventions.Member.PasswordQuestion,
"PasswordQuestion") == false) return;
Properties[Constants.Conventions.Member.PasswordQuestion].Value = value;
}
}
/// <summary>
/// Gets or sets the raw password answer value
/// </summary>
/// <remarks>
/// For security reasons this value should be encrypted, the encryption process is handled by the memberhip provider
///
/// Alias: umbracoPasswordRetrievalAnswerPropertyTypeAlias
/// Part of the standard properties collection.
/// </remarks>
[IgnoreDataMember]
public string RawPasswordAnswerValue
{
get
{
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.PasswordAnswer, "PasswordAnswer", default(string));
if (a.Success == false) return a.Result;
return Properties[Constants.Conventions.Member.PasswordAnswer].Value == null
? string.Empty
: Properties[Constants.Conventions.Member.PasswordAnswer].Value.ToString();
}
set
{
if (WarnIfPropertyTypeNotFoundOnSet(
Constants.Conventions.Member.PasswordAnswer,
"PasswordAnswer") == false) return;
Properties[Constants.Conventions.Member.PasswordAnswer].Value = value;
}
}
/// <summary>
/// Gets or set the comments for the member
/// </summary>
/// <remarks>
/// Alias: umbracoCommentPropertyTypeAlias
/// Part of the standard properties collection.
/// </remarks>
[DataMember]
public string Comments
{
get
{
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.Comments, "Comments", default(string));
if (a.Success == false) return a.Result;
return Properties[Constants.Conventions.Member.Comments].Value == null
? string.Empty
: Properties[Constants.Conventions.Member.Comments].Value.ToString();
}
set
{
if (WarnIfPropertyTypeNotFoundOnSet(
Constants.Conventions.Member.Comments,
"Comments") == false) return;
Properties[Constants.Conventions.Member.Comments].Value = value;
}
}
/// <summary>
/// Gets or sets a boolean indicating whether the Member is approved
/// </summary>
/// <remarks>
/// Alias: umbracoApprovePropertyTypeAlias
/// Part of the standard properties collection.
/// </remarks>
[DataMember]
public bool IsApproved
{
get
{
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.IsApproved, "IsApproved",
//This is the default value if the prop is not found
true);
if (a.Success == false) return a.Result;
var tryConvert = Properties[Constants.Conventions.Member.IsApproved].Value.TryConvertTo<bool>();
if (tryConvert.Success)
{
return tryConvert.Result;
}
//if the property exists but it cannot be converted, we will assume true
return true;
}
set
{
if (WarnIfPropertyTypeNotFoundOnSet(
Constants.Conventions.Member.IsApproved,
"IsApproved") == false) return;
Properties[Constants.Conventions.Member.IsApproved].Value = value;
}
}
/// <summary>
/// Gets or sets a boolean indicating whether the Member is locked out
/// </summary>
/// <remarks>
/// Alias: umbracoLockPropertyTypeAlias
/// Part of the standard properties collection.
/// </remarks>
[DataMember]
public bool IsLockedOut
{
get
{
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.IsLockedOut, "IsLockedOut", false);
if (a.Success == false) return a.Result;
var tryConvert = Properties[Constants.Conventions.Member.IsLockedOut].Value.TryConvertTo<bool>();
if (tryConvert.Success)
{
return tryConvert.Result;
}
return false;
}
set
{
if (WarnIfPropertyTypeNotFoundOnSet(
Constants.Conventions.Member.IsLockedOut,
"IsLockedOut") == false) return;
Properties[Constants.Conventions.Member.IsLockedOut].Value = value;
}
}
/// <summary>
/// Gets or sets the date for last login
/// </summary>
/// <remarks>
/// Alias: umbracoLastLoginPropertyTypeAlias
/// Part of the standard properties collection.
/// </remarks>
[DataMember]
public DateTime LastLoginDate
{
get
{
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.LastLoginDate, "LastLoginDate", default(DateTime));
if (a.Success == false) return a.Result;
var tryConvert = Properties[Constants.Conventions.Member.LastLoginDate].Value.TryConvertTo<DateTime>();
if (tryConvert.Success)
{
return tryConvert.Result;
}
return default(DateTime);
}
set
{
if (WarnIfPropertyTypeNotFoundOnSet(
Constants.Conventions.Member.LastLoginDate,
"LastLoginDate") == false) return;
Properties[Constants.Conventions.Member.LastLoginDate].Value = value;
}
}
/// <summary>
/// Gest or sets the date for last password change
/// </summary>
/// <remarks>
/// Alias: umbracoMemberLastPasswordChange
/// Part of the standard properties collection.
/// </remarks>
[DataMember]
public DateTime LastPasswordChangeDate
{
get
{
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.LastPasswordChangeDate, "LastPasswordChangeDate", default(DateTime));
if (a.Success == false) return a.Result;
var tryConvert = Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value.TryConvertTo<DateTime>();
if (tryConvert.Success)
{
return tryConvert.Result;
}
return default(DateTime);
}
set
{
if (WarnIfPropertyTypeNotFoundOnSet(
Constants.Conventions.Member.LastPasswordChangeDate,
"LastPasswordChangeDate") == false) return;
Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value = value;
}
}
/// <summary>
/// Gets or sets the date for when Member was locked out
/// </summary>
/// <remarks>
/// Alias: umbracoMemberLastLockout
/// Part of the standard properties collection.
/// </remarks>
[DataMember]
public DateTime LastLockoutDate
{
get
{
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.LastLockoutDate, "LastLockoutDate", default(DateTime));
if (a.Success == false) return a.Result;
var tryConvert = Properties[Constants.Conventions.Member.LastLockoutDate].Value.TryConvertTo<DateTime>();
if (tryConvert.Success)
{
return tryConvert.Result;
}
return default(DateTime);
}
set
{
if (WarnIfPropertyTypeNotFoundOnSet(
Constants.Conventions.Member.LastLockoutDate,
"LastLockoutDate") == false) return;
Properties[Constants.Conventions.Member.LastLockoutDate].Value = value;
}
}
/// <summary>
/// Gets or sets the number of failed password attempts.
/// This is the number of times the password was entered incorrectly upon login.
/// </summary>
/// <remarks>
/// Alias: umbracoFailedPasswordAttemptsPropertyTypeAlias
/// Part of the standard properties collection.
/// </remarks>
[DataMember]
public int FailedPasswordAttempts
{
get
{
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.FailedPasswordAttempts, "FailedPasswordAttempts", 0);
if (a.Success == false) return a.Result;
var tryConvert = Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value.TryConvertTo<int>();
if (tryConvert.Success)
{
return tryConvert.Result;
}
return default(int);
}
set
{
if (WarnIfPropertyTypeNotFoundOnSet(
Constants.Conventions.Member.FailedPasswordAttempts,
"FailedPasswordAttempts") == false) return;
Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value = value;
}
}
/// <summary>
/// String alias of the default ContentType
/// </summary>
[DataMember]
public virtual string ContentTypeAlias
{
get { return _contentTypeAlias; }
}
/// <summary>
/// User key from the Provider.
/// </summary>
/// <remarks>
/// When using standard umbraco provider this key will
/// correspond to the guid UniqueId/Key.
/// Otherwise it will the one available from the asp.net
/// membership provider.
/// </remarks>
[DataMember]
public virtual object ProviderUserKey
{
get
{
return _providerUserKey;
}
set
{
SetPropertyValueAndDetectChanges(o =>
{
_providerUserKey = value;
return _providerUserKey;
}, _providerUserKey, ProviderUserKeySelector);
}
}
/// <summary>
/// Gets or sets the type of the provider user key.
/// </summary>
/// <value>
/// The type of the provider user key.
/// </value>
[IgnoreDataMember]
internal Type ProviderUserKeyType
{
get
{
return _userTypeKey;
}
private set
{
SetPropertyValueAndDetectChanges(o =>
{
_userTypeKey = value;
return _userTypeKey;
}, _userTypeKey, UserTypeKeySelector);
}
}
/// <summary>
/// Sets the type of the provider user key.
/// </summary>
/// <param name="type">The type.</param>
internal void SetProviderUserKeyType(Type type)
{
ProviderUserKeyType = type;
}
/// <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>
/// Gets the ContentType used by this content object
/// </summary>
[IgnoreDataMember]
public IMemberType ContentType
{
get { return _contentType; }
}
public override void ChangeTrashedState(bool isTrashed, int parentId = -20)
{
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.
* Adding these to have first level properties instead of the Properties collection.
*/
[IgnoreDataMember]
internal string LongStringPropertyValue { get; set; }
[IgnoreDataMember]
internal string ShortStringPropertyValue { get; set; }
[IgnoreDataMember]
internal int IntegerropertyValue { get; set; }
[IgnoreDataMember]
internal bool BoolPropertyValue { get; set; }
[IgnoreDataMember]
internal DateTime DateTimePropertyValue { get; set; }
[IgnoreDataMember]
internal string PropertyTypeAlias { get; set; }
private Attempt<T> WarnIfPropertyTypeNotFoundOnGet<T>(string propertyAlias, string propertyName, T defaultVal)
{
Action doLog = () => LogHelper.Warn<Member>(
"Trying to access the '"
+ propertyName
+ "' property on "
+ typeof(Member)
+ " but the "
+ propertyAlias
+ " property does not exist on the member type so a default value is returned. Ensure that you have a property type with alias: "
+ propertyAlias
+ " configured on your member type in order to use the '"
+ propertyName
+ "' property on the model correctly.");
//if the property doesn't exist, then do the logging and return a failure
if (Properties.Contains(propertyAlias) == false)
{
//we'll put a warn in the log if this entity has been persisted
if (HasIdentity)
{
doLog();
}
return Attempt<T>.Fail(defaultVal);
}
//if the property doesn't have an identity but we do, then do logging and return failure
var prop = Properties.Single(x => x.Alias == propertyAlias);
if (prop.HasIdentity == false && HasIdentity)
{
doLog();
return Attempt<T>.Fail(defaultVal);
}
return Attempt<T>.Succeed();
}
private bool WarnIfPropertyTypeNotFoundOnSet(string propertyAlias, string propertyname)
{
Action doLog = () => LogHelper.Warn<Member>("An attempt was made to set a value on the property '"
+ propertyname
+ "' on type "
+ typeof(Member)
+ " but the property type "
+ propertyAlias
+ " does not exist on the member type, ensure that this property type exists so that setting this property works correctly.");
//if the property doesn't exist, then do the logging and return a failure
if (Properties.Contains(propertyAlias) == false)
{
if (HasIdentity)
{
doLog();
}
return false;
}
//if the property doesn't have an identity but we do, then do logging and return failure
var prop = Properties.Single(x => x.Alias == propertyAlias);
if (prop.HasIdentity == false && HasIdentity)
{
doLog();
return false;
}
return true;
}
public override object DeepClone()
{
var clone = (Member)base.DeepClone();
//turn off change tracking
clone.DisableChangeTracking();
//need to manually clone this since it's not settable
clone._contentType = (IMemberType)ContentType.DeepClone();
//this shouldn't really be needed since we're not tracking
clone.ResetDirtyProperties(false);
//re-enable tracking
clone.EnableChangeTracking();
return clone;
}
}
}
+76
View File
@@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Models
{
/// <summary>
/// Represents a member type
/// </summary>
[Serializable]
[DataContract(IsReference = true)]
public class MemberGroup : Entity, IMemberGroup
{
public MemberGroup()
{
AdditionalData = new Dictionary<string, object>();
}
private string _name;
private int _creatorId;
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<MemberGroup, string>(x => x.Name);
private static readonly PropertyInfo CreatorIdSelector = ExpressionHelper.GetPropertyInfo<MemberGroup, int>(x => x.CreatorId);
[DataMember]
public string Name
{
get { return _name; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
if (_name != value)
{
//if the name has changed, add the value to the additional data,
//this is required purely for event handlers to know the previous name of the group
//so we can keep the public access up to date.
AdditionalData["previousName"] = _name;
}
_name = value;
return _name;
}, _name, NameSelector);
}
}
public int CreatorId
{
get { return _creatorId; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_creatorId = value;
return _creatorId;
}, _creatorId, CreatorIdSelector);
}
}
public IDictionary<string, object> AdditionalData { get; private set; }
/// <summary>
/// Method to call when Entity is being saved
/// </summary>
/// <remarks>Created date is set and a Unique key is assigned</remarks>
internal override void AddingEntity()
{
base.AddingEntity();
if (Key == Guid.Empty)
Key = Guid.NewGuid();
}
}
}
+148
View File
@@ -0,0 +1,148 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
namespace Umbraco.Core.Models
{
/// <summary>
/// Represents the content type that a <see cref="Member"/> object is based on
/// </summary>
[Serializable]
[DataContract(IsReference = true)]
public class MemberType : ContentTypeCompositionBase, IMemberType
{
//Dictionary is divided into string: PropertyTypeAlias, Tuple: MemberCanEdit, VisibleOnProfile, PropertyTypeId
private string _alias;
public MemberType(int parentId) : base(parentId)
{
MemberTypePropertyTypes = new Dictionary<string, MemberTypePropertyProfileAccess>();
}
public MemberType(IContentTypeComposition parent) : base(parent)
{
MemberTypePropertyTypes = new Dictionary<string, MemberTypePropertyProfileAccess>();
}
private static readonly PropertyInfo AliasSelector = ExpressionHelper.GetPropertyInfo<MemberType, string>(x => x.Alias);
/// <summary>
/// The Alias of the ContentType
/// </summary>
[DataMember]
public override string Alias
{
get { return _alias; }
set
{
//NOTE: WE are overriding this because we don't want to do a ToSafeAlias when the alias is the special case of
// "_umbracoSystemDefaultProtectType" which is used internally, currently there is an issue with the safe alias as it strips
// leading underscores which we don't want in this case.
// see : http://issues.umbraco.org/issue/U4-3968
SetPropertyValueAndDetectChanges(o =>
{
_alias = value == "_umbracoSystemDefaultProtectType"
? value
: (value == null ? string.Empty : value.ToSafeAlias() );
return _alias;
}, _alias, AliasSelector);
}
}
/// <summary>
/// Gets or Sets a Dictionary of Tuples (MemberCanEdit, VisibleOnProfile) by the PropertyTypes' alias.
/// </summary>
[DataMember]
internal IDictionary<string, MemberTypePropertyProfileAccess> MemberTypePropertyTypes { get; private set; }
/// <summary>
/// Gets a boolean indicating whether a Property is editable by the Member.
/// </summary>
/// <param name="propertyTypeAlias">PropertyType Alias of the Property to check</param>
/// <returns></returns>
public bool MemberCanEditProperty(string propertyTypeAlias)
{
if (MemberTypePropertyTypes.ContainsKey(propertyTypeAlias))
{
return MemberTypePropertyTypes[propertyTypeAlias].IsEditable;
}
return false;
}
/// <summary>
/// Gets a boolean indicating whether a Property is visible on the Members profile.
/// </summary>
/// <param name="propertyTypeAlias">PropertyType Alias of the Property to check</param>
/// <returns></returns>
public bool MemberCanViewProperty(string propertyTypeAlias)
{
if (MemberTypePropertyTypes.ContainsKey(propertyTypeAlias))
{
return MemberTypePropertyTypes[propertyTypeAlias].IsVisible;
}
return false;
}
/// <summary>
/// Sets a boolean indicating whether a Property is editable by the Member.
/// </summary>
/// <param name="propertyTypeAlias">PropertyType Alias of the Property to set</param>
/// <param name="value">Boolean value, true or false</param>
public void SetMemberCanEditProperty(string propertyTypeAlias, bool value)
{
if (MemberTypePropertyTypes.ContainsKey(propertyTypeAlias))
{
MemberTypePropertyTypes[propertyTypeAlias].IsEditable = value;
}
else
{
var tuple = new MemberTypePropertyProfileAccess(false, value);
MemberTypePropertyTypes.Add(propertyTypeAlias, tuple);
}
}
/// <summary>
/// Sets a boolean indicating whether a Property is visible on the Members profile.
/// </summary>
/// <param name="propertyTypeAlias">PropertyType Alias of the Property to set</param>
/// <param name="value">Boolean value, true or false</param>
public void SetMemberCanViewProperty(string propertyTypeAlias, bool value)
{
if (MemberTypePropertyTypes.ContainsKey(propertyTypeAlias))
{
MemberTypePropertyTypes[propertyTypeAlias].IsVisible = value;
}
else
{
var tuple = new MemberTypePropertyProfileAccess(value, false);
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();
}
}
}
@@ -0,0 +1,17 @@
namespace Umbraco.Core.Models
{
/// <summary>
/// Used to track the property types that are visible/editable on member profiles
/// </summary>
internal class MemberTypePropertyProfileAccess
{
public MemberTypePropertyProfileAccess(bool isVisible, bool isEditable)
{
IsVisible = isVisible;
IsEditable = isEditable;
}
public bool IsVisible { get; set; }
public bool IsEditable { get; set; }
}
}
@@ -0,0 +1,24 @@
namespace Umbraco.Core.Models.Membership
{
/// <summary>
/// Represents a user -> entity permission
/// </summary>
public class EntityPermission
{
public EntityPermission(int userId, int entityId, string[] assignedPermissions)
{
UserId = userId;
EntityId = entityId;
AssignedPermissions = assignedPermissions;
}
public int UserId { get; private set; }
public int EntityId { get; private set; }
/// <summary>
/// The assigned permissions for the user/entity combo
/// </summary>
public string[] AssignedPermissions { get; private set; }
}
}

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