Compare commits

...

1110 Commits

Author SHA1 Message Date
Shannon Deminick 635ebcb9be removed error check as this was causing errors 2013-04-05 00:40:03 +06:00
Shannon Deminick 33f7a8477d updated to latest version of Umbraco.Azure via nuget 2013-04-05 00:09:14 +06:00
Shannon Deminick 646194e013 Merge with 6.0.4 2013-04-04 23:36:57 +06:00
Shannon Deminick 425fcf36eb un-reverted changes to UserType cache refresher 2013-04-04 23:36:31 +06:00
Shannon Deminick 31fd05ebca Merge 2013-04-04 23:30:36 +06:00
Shannon Deminick 495b4ed9e0 Refactors the WebSecurity class to not be static and be part of the UmbracoContext. Makes a few methods internal on it so that
it's not relying on the legacy User class. Cleans up the new BasePage and EnsuredUmbracoPage
2013-04-04 23:30:17 +06:00
Shannon Deminick 87c904cc96 Fixes: #U4-2044, #U4-2048 2013-04-04 21:57:41 +06:00
Morten Christensen 792599a42f Minor correct to the doc.SaveAndPublish method. 2013-04-04 12:20:50 -02:00
Morten Christensen 03c65c8eec Updating build version to 6.1.0 beta
Updating nuspec with new references.
2013-04-04 12:13:59 -02:00
Morten Christensen 14aeb55c14 Removing unused ServiceStack.Text reference/nuget package.
Ignore Macro tests for the model and repo as its not used and still internal. Might be an idea to remove it altogether.
2013-04-04 12:02:27 -02:00
Sebastiaan Janssen 7ddbc83731 Merge gone wrong, my bad! 2013-04-04 10:20:13 -02:00
Sebastiaan Janssen 17533c57d3 Merge with 6.0.4 2013-04-04 10:04:29 -02:00
Sebastiaan Janssen 433668e202 Merge 2013-04-04 09:46:34 -02:00
Sebastiaan Janssen 9edcc0c903 Revert UserType caching changes until Shannon can commit UserTypeCacheRefresher 2013-04-04 09:46:20 -02:00
Morten Christensen 7610ee5f8b Adding event proxies to the ContentService for publishing events for easier discoverability.
Fixes U4-2046
2013-04-04 07:16:33 -02:00
Morten Christensen eab9be4ef7 Fixing issue with reimporting document types and the structure of allowed doc types.
Removing old code from Installer.
2013-04-04 06:02:08 -02:00
Shannon Deminick f747f69c62 Merge with 6.0.4 2013-04-04 05:46:25 +06:00
Shannon Deminick e48a030aab Merge 2013-04-04 05:46:01 +06:00
Shannon Deminick e07985439a Fixed up some unit tests 2013-04-04 05:05:52 +06:00
Shannon Deminick 620f21d7d7 Converted over Application.cs to use ApplicationContext.Current 2013-04-04 04:42:36 +06:00
Shannon Deminick 4a13047d5d Converted ApplicationTree to use ApplicationContext.Current.ApplicationCache 2013-04-04 04:34:40 +06:00
Shannon Deminick 446a480f21 converted ui to use ApplicationContext.Current.ApplicationCache 2013-04-04 04:19:05 +06:00
Shannon Deminick b56f8c8fb3 Fixes: #U4-2043 - User Type cache is not invalidated in LB scenarios 2013-04-04 03:43:05 +06:00
Morten Christensen e207b1f1e1 Adds new test case for single doc type imports.
Corrects issue with installing/importing single or multiple doc types, which is not part of the usual complete package xml.
2013-04-03 18:26:54 -02:00
Shannon Deminick 296c24f829 Fixes: #U4-2042 - ensures users cannot continue to user the back office after they've been disabled and
ensures that the user context cache is cleared when users are saved which will work in LB environments.
Changes more HttpRuntime.Cache dependencies to ApplicationContext.Current.ApplicationCache.
2013-04-04 02:11:31 +06:00
Shannon Deminick c5e88ef69f Fixes: #U4-2041, #U4-2040 - user cache is not invalidated when permissions change across LB environments, also streamlined how caching is handled in
these classes which now use the standardized events way to do things. Fixes a performance issue and ensures that the cache is not invalidated for 'micro'
operations during permission changes.
2013-04-04 00:30:28 +06:00
Shannon Deminick 2a7e493c74 Changes all instances of the legacy Cache class to be using ApplicationContext.Current.ApplicationCache.
Fixes: #U4-2039 - ensures macro xslt cache is invalidated in LB scenarios.
2013-04-03 23:39:51 +06:00
Shannon Deminick e14d3fd379 changes all instances accessing cache by key "contentItem" to use CacheKeys.ContentItemCache and replaces
all of it's cache usages with the ApplicationContext.Current.ApplicationCache. Obsoletes a couple of methods
that are not used.
2013-04-03 22:34:40 +06:00
Shannon Deminick fd3540f92d Removes unused private method 2013-04-03 20:40:06 +06:00
Sebastiaan Janssen fa43cfd58f Silly designer file, of course you need to change to. kthxbi 2013-04-03 11:43:28 -02:00
Sebastiaan Janssen 711afe8bb7 Breaking changes reverted 2013-04-03 11:41:53 -02:00
Stephan 23525300bb Web.PublishedCache - add XPathNavigator support 2013-04-03 11:19:10 -02:00
Shannon Deminick b9d7f0c5a5 Fixes merge issues, merge ensures that js error is fixed and that thread-safe caching is in place
in the ContentType.cs class.
2013-04-02 22:06:15 +06:00
Shannon Deminick 3d76614a78 Merge with 4.11.7 2013-04-02 21:31:21 +06:00
Sebastiaan Janssen de0e6f3179 Merge 2013-04-02 08:08:31 -02:00
Sebastiaan Janssen 39edb9b7e2 Fixes U4-2032 Preview for an RTE field shows published content instead of actual
preview
2013-04-02 08:07:18 -02:00
Shannon Deminick a638488eb7 Fixes unit tests which require the ApplicationContext.Current singleton to be setup 2013-04-01 23:30:19 +06:00
Shannon Deminick a2a539f7db Merge 2013-04-01 23:12:47 +06:00
Shannon Deminick 6768bb4793 Fixes: #U4-1874 - merges in thread-safe fixes for static object caching from 6.1 and cleans up
a bunch of the code in ContentType.cs. Back ports fixes for Languages.cs from 6.1 and cleans up code.
2013-04-01 23:12:17 +06:00
Sebastiaan Janssen 19c2841576 Fixes U4-535 Stylesheet content gets deleted if you change case 2013-04-01 14:27:20 -02:00
Sebastiaan Janssen 71aa248a4e Fixes U4-535 Stylesheet content gets deleted if you change case 2013-04-01 14:27:20 -02:00
Sebastiaan Janssen eeaef5ac5c Merge 2013-04-01 11:51:48 -02:00
Sebastiaan Janssen bea50f4562 Fixes: U4-662 Most icon for document type can't be shown in 4.8.1. 2013-04-01 11:50:27 -02:00
Sebastiaan Janssen ff337457f8 Fixes: U4-662 Most icon for document type can't be shown in 4.8.1. 2013-04-01 11:31:03 -02:00
Stephan 8d33488923 Web.PublishedCache - make parts of XmlPublishedCache virtual 2013-03-31 18:40:55 -02:00
Stephan 32a6a49077 Macros - bugfix & cleanup macros 2013-03-31 18:47:37 -02:00
Stephan b93ea7c69b U4-2033 - fix the tests, now we're returning lower case 2013-04-03 08:40:09 -02:00
Morten Christensen 640be73a66 A few refactoring bits for the FolderBrowserService. 2013-04-03 07:03:57 -02:00
Morten Christensen 32ae88fc81 Merge 2013-04-03 05:25:42 -02:00
Morten Christensen a4c9c3bfd9 Updating EntityService and repository to add content and media specific properties to the UmbracoEntity for performance enhancements.
Adding sample implementation in the BaseMediaTree but keeping it commented out as it won't work with the legacy events.
And a bit of code cleanup
2013-04-03 05:25:26 -02:00
Shannon Deminick 182107286c Fixes merge issues 2013-04-02 23:08:43 +06:00
Shannon Deminick a7e939e71f Merge with 6.0.4 2013-04-02 22:39:39 +06:00
Stephan 83d05bd01c U4-2033 - url segment is not lower case 2013-04-02 11:34:40 -02:00
Stephan 9fb10ea004 presentation.UmbracoContext - get property values from appropriate sources 2013-04-02 09:23:53 -02:00
Stephan c916df0d13 Core.Strings - apply 2551076f571a to 6.1.0 2013-04-02 09:19:49 -02:00
Stephan 99a63a3cdb fix build 2013-04-01 16:35:03 -02:00
Stephan ad52c0f033 Web.Cache - add notes to cache refreshers re. dependencies 2013-03-31 18:40:55 -02:00
Stephan 6d18d32356 Web.Routing - bugfix PublishedContentRequestEngine
no macro would run when rendering a 404 document
2013-03-31 18:40:54 -02:00
Stephan 75f0f1f4ee Web.UmbracoContext - allow for InPreviewMode override in tests 2013-03-31 18:40:54 -02:00
Stephan 425a9f6a34 Core.Xml - import framework xml tests 2013-03-31 18:40:54 -02:00
Stephan 1d5f7ae822 Core.Strings - handle config. errors in DefaultShortStringHelper 2013-03-31 18:40:54 -02:00
Morten Christensen 49b5ddf850 Refactor of fix for U4-2014 2013-03-31 18:17:01 -02:00
Morten Christensen 3f7a93e0c9 Adding test fixture for the EntityService.
Refactoring sql query used in the EntityRepository.
Correcting a few issues with the UmbracoObjectTypes extensions.
2013-03-30 09:52:37 -01:00
Shannon Deminick b449b8762b Merge 2013-03-29 23:53:08 +06:00
Shannon Deminick 13e555f50b Fixed merge issue based on overlap with class + namespace name. 2013-03-29 23:52:40 +06:00
Shannon Deminick 48c809a797 Merge with 4.11.7 2013-03-29 23:22:18 +06:00
Shannon Deminick 55c7f72d8e Converts create.aspx to have the correct webforms file/class structure, fixed logging for userTask,
fixed issue with last regex fix for xss
2013-03-29 23:14:42 +06:00
Sebastiaan Janssen 8612113fc0 Merge 2013-03-29 15:02:43 -01:00
Sebastiaan Janssen 69b0c7cf09 Fixes: U4-2024 Umbraco 6.0.3 : Error while importing Document Type 2013-03-29 15:01:04 -01:00
Shannon Deminick 72ad9f51c1 Merge with 6.0.4 2013-03-29 21:41:08 +06:00
Shannon Deminick 37a97a2e7c Merge with 4.11.7 2013-03-29 21:34:56 +06:00
Shannon Deminick 5f4eaef4a2 Fixes: #U4-2022 2013-03-29 21:31:27 +06:00
Sebastiaan Janssen 44f5c3a34f Fixes U4-2019 Create new Document Type dialog displays poorly in Chrome 2013-03-29 09:13:44 -01:00
Sebastiaan Janssen a33ae696a2 Fixes U4-2014 Can't install XSLTSearch 3.0.4 with Umbraco 6.0.3
Updated the topological sorter to only add items that exist in the indexes
2013-03-29 08:46:09 -01:00
Sebastiaan Janssen 2705efb809 Updated file for WebPI builds 2013-03-29 08:34:34 -01:00
Shannon Deminick 20fb27f7e1 Fixed server registration ctor and factory to ensure IsActive is correct. 2013-03-28 11:27:13 +06:00
Shannon Deminick c8e20cf64b Fixes: #U4-2012, #U4-2005 2013-03-28 09:07:36 +06:00
Sebastiaan Janssen 648d631151 Opening new branch 2013-03-27 14:48:13 -01:00
Sebastiaan Janssen 27c0c4d64e Opening new branch 2013-03-27 14:47:35 -01:00
Sebastiaan Janssen 52cf559536 Closing 4.11.6 branch 2013-03-27 12:00:18 -01:00
Sebastiaan Janssen c9b0362c62 Closed 6.0.3 branch 2013-03-27 11:54:12 -01:00
Sebastiaan Janssen 11e5bdf556 Added tag release-6.0.3 for changeset aed55cba2900 2013-03-27 11:14:18 -01:00
Sebastiaan Janssen 3d0be3836c Added tag release-4.11.6 for changeset 14338b0ab173 2013-03-27 11:13:56 -01:00
Sebastiaan Janssen 2bc33e0115 Merge 2013-03-27 08:58:34 -01:00
Sebastiaan Janssen 8576d9c67e Bump version to 4.11.6 2013-03-27 08:56:30 -01:00
Shannon Deminick 3accecd504 Merge with 6.0.3 2013-03-27 03:09:57 +06:00
Shannon Deminick a0651f4383 Merge with 4.11.6 2013-03-27 03:09:36 +06:00
Shannon Deminick 9452d5fd09 adds patch for #U4-1754 and updates 2013-03-27 03:08:37 +06:00
Shannon Deminick 1f40d726de adds patch for #U4-1754 2013-03-27 02:59:42 +06:00
Shannon Deminick 2699611ba3 adds patch for #U4-1754 2013-03-27 02:58:59 +06:00
Shannon Deminick d9121b4684 fixes merge 2013-03-26 22:12:35 +06:00
Shannon Deminick 132ec1702c Merge with 6.0.3 2013-03-26 22:09:50 +06:00
Shannon Deminick 43795f0007 Merge with 4.11.6 2013-03-26 22:03:23 +06:00
Shannon Deminick b1fa06bfe8 Removes unused code. 2013-03-26 22:02:49 +06:00
Shannon Deminick 4dc22b6ce4 Applies patch for #U4-497 for getting exceptions for xslt 2013-03-26 22:02:08 +06:00
Shannon Deminick a4e3127704 Ensures that xslt can throw exceptions too with the new settings - #U4-497 2013-03-26 21:40:50 +06:00
Sebastiaan Janssen d4ab60f8af Merge with 4.11.6 2013-03-26 13:29:45 -01:00
Sebastiaan Janssen 883277125a Can't use parameters here as the query gets butchered. 2013-03-26 13:27:46 -01:00
Sebastiaan Janssen 2678e23c7d Update Resolves_Assigned_Mappers to make sure the unit tests run 2013-03-26 12:26:08 -01:00
Sebastiaan Janssen 8edfc0ffdd Merge with 4.11.6 2013-03-26 09:53:59 -01:00
Sebastiaan Janssen ff961abaab Actual fix for U4-1987 Error when attempting to save document type 2013-03-26 09:50:48 -01:00
Sebastiaan Janssen b2414c1ab8 Fixes U4-1987 Error when attempting to save document type 2013-03-26 09:33:08 -01:00
Sebastiaan Janssen 9dde86d591 Fixes U4-1999 When copying content with subcontent, the new subcontent data is a
direct reference to the old.
2013-03-26 08:39:50 -01:00
Sebastiaan Janssen b4ce4fbdef Logging warning when package installer can't create a property due to a missing
datatype for that property
2013-03-26 07:55:43 -01:00
Sebastiaan Janssen 4285484c1b Update code comment 2013-03-26 07:19:39 -01:00
Sebastiaan Janssen 2fd299ebfc Change TinyMCE to use the mediaservice to get the original image + some updates
to the new mediaservice method.
2013-03-26 07:15:22 -01:00
Morten Christensen f545f293b1 Adding GetMediaByUrl method to MediaService cause Sebastiaan needs it for less hacky code. 2013-03-26 05:46:20 -01:00
Morten Christensen 4dc94d1e0b Merge 2013-03-26 05:00:04 -01:00
Morten Christensen b058b1e345 Removing LEFT JOIN from query as its already part of the builder 2013-03-26 04:59:56 -01:00
Morten Christensen dfa1e73ddf Continueing implementation of the EntityRepository and Service. 2013-03-25 18:54:12 -01:00
Sebastiaan Janssen b745c0ae90 If the image is not resized, there's probably not going to be an underscore,
just query for the whole image source then.
2013-03-25 18:18:14 -01:00
Sebastiaan Janssen f2efff5411 Temporary fix until we can fix this properly for U4-1812 - Changing Width or
Height in Insert Picture popup results in NaN in other dimension
2013-03-25 18:09:31 -01:00
Shannon Deminick 390f56a64d Merge with 6.0.3 2013-03-25 20:54:49 +06:00
Shannon Deminick 04c623f19c Merge 2013-03-25 20:54:31 +06:00
Shannon Deminick 633d88c8c4 Changed DefaultServerMessenger to have an overridable method to send the request, added some internals visible to. 2013-03-25 20:54:21 +06:00
Sebastiaan Janssen 9ef5890636 Changing sortorder on tabs now also re-orders the tabs in the contenttype editor 2013-03-25 13:33:32 -01:00
Sebastiaan Janssen bc9fd04a36 Related to U4-1847 - Tabs weren't imported with the correct sort order and when
a datatype can't be found we should silently fail and not create the property
that wants that datatype (that's how v4 did it).
2013-03-25 12:49:43 -01:00
Sebastiaan Janssen 185c5d78f1 Query changed due to fix fe02cef72d87 that uses 1/0 instead of True/False 2013-03-25 11:27:54 -01:00
Brian Powell 3ea9963166 Fixes U4-1904 / U4-1905 2013-03-25 10:39:35 -01:00
Sebastiaan Janssen ab40822a98 Fix merge issue by re-applying Stephen Roberts' patch 2013-03-25 10:30:55 -01:00
Sebastiaan Janssen dffce76e29 Merge with 4.11.6 2013-03-25 10:24:36 -01:00
Sebastiaan Janssen d1e02f506c PropertyGroupId can be null 2013-03-25 07:51:44 -01:00
Morten Christensen 40a9da5ee0 Merge with 6.0.3 2013-03-23 07:24:27 -01:00
Morten Christensen 5e18d13178 Fixing parsing issue with saving boolean values in the Integer column for Members.
Related to issue U4-1989
2013-03-23 07:22:43 -01:00
Shannon Deminick 3b982b80f5 Fixes test issues, needed to disable application cache for these tests since the cache invalidation happens at the CacheRefresher level but for these
tests (any many other ones) we are not 'booting' umbraco with the Boot managers so the CacheRefreshers are not wired up to listen to events to clear
the cache. This puts us another step closer to having a proper global cache solution that will work for everything. At least now, all of the legacy
code is using the ApplicationCache which we can now control from a central location. Changed NiceUrlsProviderWithDomainsTests to only require a new db
schema per fixture.
2013-03-23 04:01:52 +06:00
Shannon Deminick 1cada5aeb5 Merge with 6.0.3 2013-03-23 02:35:21 +06:00
Shannon Deminick 1dfca6836d Merge with 4.11.6 2013-03-23 02:34:59 +06:00
Shannon Deminick dbbdd16bb9 Fixes: #U4-497 2013-03-23 02:34:34 +06:00
Shannon Deminick 64719586dc Merge 2013-03-23 02:32:07 +06:00
Shannon Deminick 63d010f78f Fixes: #U4-497 2013-03-23 02:31:24 +06:00
Shannon Deminick e97a01c75c Fixes: #U4-1992 - Creates DictionaryCacheRefresher to ensure that all cache associated with the dictionary is updated amongst all
servers when it is changed/removed. Removes RemoveByJson as we only actually require RefreshByJson since we can put any sort of parameters
in a custom json string including whether it is a remove operation (if required)
2013-03-23 01:59:25 +06:00
Stephan 65ae43918d merge 2013-03-22 17:45:10 -01:00
Stephan 21c635f61a Core.Strings - Add support for UrlReplaceCharacters to DefaultShortStringHelper 2013-03-22 17:39:35 -01:00
Stephan 6cc747bf76 Core.Strings - fix bug in helper freeze 2013-03-22 17:38:28 -01:00
Shannon Deminick af2693af76 Fixes how language and dictionary items are cached (ConcurrentDictionary), also fixes up how the Language object
is created and how it raises it's new event and fixes thread safety with it. Also fixes how Language was not checking
for invalid culture codes.
2013-03-23 00:24:37 +06:00
Shannon Deminick d95fc0210e Merge with 6.0.3 2013-03-22 22:11:56 +06:00
Shannon Deminick 74362fba23 Merge 2013-03-22 22:11:26 +06:00
Shannon Deminick 00de509478 Merge 2013-03-22 22:11:08 +06:00
Shannon Deminick 1b5139889c Changed event handler to AfterDelete for DataTypeDefinition, fixes merge issue with Entity and changes WasCancelled to be tracked. 2013-03-22 22:10:24 +06:00
Morten Christensen 112502cf18 Fixes U4-547 2013-03-22 15:09:36 -01:00
Shannon Deminick d976fbe4de Merge with 6.0.3 2013-03-22 22:03:50 +06:00
Stephan 47474d31d6 Web.PublishedCache - rename LegacyXmlCache into XmlPublishedCache 2013-03-22 15:02:26 -01:00
Shannon Deminick 1db7f808c9 Merge with 4.11.6 2013-03-22 21:59:52 +06:00
Shannon Deminick 762cca145f Fixes: #U4-1931 - allow empty string in dictionary item. 2013-03-22 21:59:21 +06:00
Shannon Deminick 840a95ba62 Merge 2013-03-22 21:56:43 +06:00
Shannon Deminick e18d8da872 Fixes: #U4-1931 - allow setting an empty string to a dictionary item. 2013-03-22 21:56:25 +06:00
Morten Christensen 65dc5eaeee Corrects incorrect sql query in the ContentTypeBaseRepository and looping through property types in the DataTypeService.
Adds initial test fixture for the DataTypeService.
Fixes U4-1939
2013-03-22 14:54:44 -01:00
Morten Christensen 4f81e06d3d Fixes U4-1894 by ensuring that all overloads of SetValue uses the IOHelper.SafeFileName 2013-03-22 14:18:45 -01:00
Morten Christensen 6b74b75b6f Adding a few checks to ensure that we don't try to bulk save an empty list 2013-03-22 14:08:20 -01:00
Morten Christensen 98e53b3d74 Correcting a few checks for multiple or single item imports in the PackagingService 2013-03-22 13:58:21 -01:00
Morten Christensen a1f01f9d5c re-inverting the check for existing datatypedefinitions in the packaging service 2013-03-22 13:48:51 -01:00
Sebastiaan Janssen f5d8cb0275 Merge 2013-03-22 13:36:26 -01:00
Sebastiaan Janssen 0d8b65caea Merge 2013-03-22 13:36:04 -01:00
Sebastiaan Janssen 70285991bb I think this was an oversight, if a definition is NOT null, then fill it 2013-03-22 13:35:47 -01:00
Sebastiaan Janssen a336eaa4a1 Check all of the elements for null, apparently any kind of installable thing can
be missing from the install xml file
2013-03-22 13:35:19 -01:00
Morten Christensen fdefe993b7 Fixes U4-1990 2013-03-22 12:54:46 -01:00
Morten Christensen ba0e72a1c1 Fixes U4-1937 by calling save when media is updated with new properties. Also uses the incremented folder count instead of the property id. 2013-03-22 12:30:20 -01:00
Morten Christensen c5710277a5 Redoing the fix for U4-1875 2013-03-22 12:13:06 -01:00
leekelleher b6ec364156 Updated references to the new constants for Application and MediaType aliases. 2013-03-22 13:13:05 +00:00
leekelleher 6b07ee83eb Added constants for Application (section aliases), System (node IDs) and MediaType aliases. 2013-03-22 13:11:27 +00:00
Morten Christensen 5cd2d568e3 Fixes U4-1938 by actually calling and checking the Before/AfterDelete events for DataTypeDefinitions.
Backported from 32fb51f603a3
2013-03-22 11:12:32 -01:00
Morten Christensen 9c89a56d8d Fixes U4-1938 by actually calling and checking the Before/AfterDelete events for DataTypeDefinitions. 2013-03-22 10:53:07 -01:00
Morten Christensen 9ba7664f78 Updating repositories to handle sort order upon updating in a consistent manner.
Related to U4-1828
2013-03-22 10:34:05 -01:00
Morten Christensen 4b87a5c2d3 Adding safe alias cast to Templates.
Updating doc type create dialog to verify alias before saving.
Updating ContentTypeRepository to Mandate that the alias is not empty.
Fixes the cause for U4-1976
2013-03-22 09:56:21 -01:00
Shannon Deminick 7e0c1fac36 Fixes: #U4-1717 - UmbracoContext.EnsuresContext is public. 2013-03-22 05:23:11 +06:00
Shannon Deminick 8cdfba42d5 Moves clearing of the routes cache for when domains are changed to the DomainCacheRefresher. 2013-03-22 05:15:58 +06:00
Shannon Deminick e8dd56786b Fixes: #U4-1986 - data type cache is not refreshed in load balanced environments. 2013-03-22 05:04:32 +06:00
Shannon Deminick 2a9309ea38 un-obsoletes a bunch of the Member api since it shouldn't be obsoleted. Ensures that members cache is cleared when a member is updated or deleted using
the API and that this cache is also refreshed on other servers.
2013-03-22 04:34:57 +06:00
Shannon Deminick c732ee6eb2 Fixes: #U4-1982 - removes the RelationType cache 2013-03-22 02:54:59 +06:00
Shannon Deminick ee2f2dfda0 Fixes: #U4-1981 - ensures template cache is properly refreshed amonsgst all servers 2013-03-22 02:08:55 +06:00
Shannon Deminick 9d6b38a1c1 Fixes: #U4-1980 - stylesheet and stylesheet property cache is not refreshed in load balanced environments. 2013-03-22 01:49:34 +06:00
Morten Christensen f0699afb6e Fixes U4-1974 2013-03-21 18:45:06 -01:00
Shannon Deminick f6490a897a Fixes: #U4-1978 - Creates DomainCacheRefresher - domain cache is now refreshed across all servers 2013-03-22 00:49:07 +06:00
Shannon Deminick ce8f5c167c Fixes: #U4-1933 - Adds LanguageCacheRefresher, removes the invalidate cache calls from within the legacy language object. 2013-03-22 00:35:15 +06:00
Morten Christensen b4d5658d45 Fixes U4-1828 by correctly incrementing the sortorder ... doh! 2013-03-21 17:34:08 -01:00
Morten Christensen d485c3da97 Fixes U4-1875 by correcting the Creating events in the ContentService and MediaService, so null is returned if the creation of an object is cancelled.
In the legacy Document and Media classes we check if the created object is null to determine if the event has been cancelled through the new api.
2013-03-21 16:09:45 -01:00
Shannon Deminick 5f242aa3f6 Converts the media cache refresher to be a json cache refresher since it was impossible before to have media cache
cleared when media was deleted. Created base classes for cache refreshers, we now have a new event - CacheUpdated
which can now be used by code to execute on each individual server when any cache refresher is updated. Listening to events
normally only fire on the individual server so if people are wanting to refresh their own cache there was previously no way
to do that.
2013-03-21 22:53:58 +06:00
Morten Christensen 1214082997 Fixes U4-1883 by setting the Document/Media UpdateDate property in the Save/SaveAndPublish methods 2013-03-21 14:56:50 -01:00
Morten Christensen 1a56e6693a Removing dictionary from DataTypeDefinition as it wasn't used.
Updating package xml to include DatabaseType for testing.
2013-03-21 14:50:39 -01:00
Morten Christensen c6b7f20dab Fixes U4-1849 by introducing a new attribute for packaged DataTypes, so it stores information about the database type.
Will still default to Ntext, but seeing as the database type has never been used before it always defaulted to Ntext.
2013-03-21 14:40:17 -01:00
Morten Christensen 5cc55ad6e2 Fixing U4-1948 by setting the Published property when using document.Publish so updating the cache won't be skipped. 2013-03-21 13:51:45 -01:00
Morten Christensen a55fedab0a Adding a few checks to ensure package installation doesn't fail when properties are not present in the xml. 2013-03-21 13:40:54 -01:00
Shannon Deminick ab8b0f4ebb Merge with 6.0.3 2013-03-21 20:39:33 +06:00
Shannon Deminick a57d3f7eba Merge 2013-03-21 20:31:23 +06:00
Shannon Deminick f5a1e41569 missing checkin file 2013-03-21 20:30:32 +06:00
Morten Christensen 0e12f14a4a Making the export method internal until its been properly implemented 2013-03-21 13:10:31 -01:00
Morten Christensen 3e25b71d9e Updating test for adding PropertyType outside a group to use the proper method for doing so. 2013-03-21 12:58:55 -01:00
Morten Christensen 63de9e6691 Refactoring package installer to use the new PackagingService.
Refactoring ImportDocumentType dialog to import through the PackagingService.
Making a few corrections to the ProppertyGroup and PropertyType classes to support bulk saving.
2013-03-21 12:34:10 -01:00
Stephan 8c79977a23 Web - move GetByAlias out of PublishedCache 2013-03-21 08:54:25 -01:00
Shannon Deminick 52f05612ad Adds another method of distributed cache syncing using a custom json payload. this is necessary for things like ContentType cache
updates especially when deleting one since we require all sorts of Ids from the object but the object will be deleted by the time
the request reaches other servers so instead we create a json payload to send to other servers which contains all information necessary
to refresh/clear the cache on the other servers. This will probably be the preferred way going forward to handle cache refreshing.
With this in place, when removing a conent type cache is removed based on events.
This also adds a 'class' generic argument constraint to the repository base classes to guarantee we can do null checks and then we also
fix a null check on RepositoryBase. Updates the Entity class to properly support tracking properties - this now allows us to determine if
an entity was new, which is now used to ensure we don't re-update all of the content cache when a new content type is created.
Have also changed the deletion and creation of document types to use the new API, this allows for a lot less processing and streamlining how
all cache is invalidated. Fixes the construction of a new Template and Content Type in the v6 api and ensures that default values are set - #U4-1972, #U4-1971
2013-03-21 08:38:18 +06:00
Morten Christensen b9ea85d29d Updating Template to have a lazy master template id.
Adding a few new methods to the DataTypeService, which were needed for the import of DataTypes.
Adding bulk saving of templates.
Adding TopologicalSorter for sorting dependencies.
Implementing import of DataTypes and Templates.
Renaming the import test fixture for consistency after having creating the PackagingService.
2013-03-20 20:31:44 -01:00
Shannon Deminick c5a0da6aa5 Updated ContentTypeCacheRefresher to ensure that content xml cache is only refreshed for doc types not
media types, also ensures that the route cache is cleared (#U4-1969). Changes the deletion of media and
doc types to use the new Api - this ensures that cache is refreshed properly.
2013-03-21 01:04:27 +06:00
Shannon Deminick 266aa3423b Merge 2013-03-21 00:06:50 +06:00
Shannon Deminick 7ea87638f7 Updates all Entity models to use SetPropertyValueAndDetectChanges for setting all simple properties so that
tracking changes works the way it is supposed to. Creates a TracksChangesEntityBase class for any other entity
that wants to implement IRememberBeingDirty (now Entity inherits from this). Upgraded a bunch of other entities that
were not tracking changes properly.
2013-03-21 00:05:56 +06:00
Shannon Deminick b96b372400 Ensure ResetDirtyProperties(false); is set where appropriate (any PerformGet and the base Get)
relates to : #U4-1946
2013-03-20 23:13:55 +06:00
Stephan fcb8f0d417 Web.Routing - RoutesCache goes with PublishedCache 2013-03-20 16:01:49 -01:00
Stephan 6e3c4854b9 Web - add extension methods to ContextualContentCache 2013-03-20 16:01:48 -01:00
Stephan ba24deffc9 Core.Configuration - fix version 2013-03-20 16:01:48 -01:00
Shannon Deminick aa7fd7bb2b Removed cache refreshing code from inside of the ascx control as it is now all handled via business logic. 2013-03-20 22:03:35 +06:00
Shannon Deminick e7a6a29e59 Merge 2013-03-20 21:18:24 +06:00
Shannon Deminick c43efbbfc4 Changed the remaining/relavent properties on ContentTypeBase to use the SetPropertyValueAndDetectChanges
to set property values.
2013-03-20 21:03:48 +06:00
Shannon Deminick adedc9b64b Ensures mocked test entities don't have dirty properties on initialization. Ensures content xml structure
is rebuilt when a content type's alias is changed or a property type is removed from it. Adds ability  to rebuild
content xml structures for specified content types, not for all content. Adds ContentTypeExtensions and
more unit tests for ContentTypeTests. Changes RuntimeCacheProvider to use new ConcurrentHashSet instead of a dictionary
with the same key/value. Adds overload to IRepositoryCacheProvider to clear cache by type. Clears the IContent cache when
a Content type is saved.
All relates to fixing #U4-1943
2013-03-20 20:53:12 +06:00
Morten Christensen d0787e92fe Implementing PackagingService and moving Import Export methods to this service to have it specialized and centralized around packaging operations. 2013-03-20 13:51:46 -01:00
Morten Christensen ffe9953c43 Merge 2013-03-19 20:08:40 -01:00
Morten Christensen 99a9f1ab87 Adding note to mediaService regarding issue U4-1937 2013-03-19 20:06:33 -01:00
Morten Christensen 7def26a489 Implementing import methods in the Content- and ContentType services.
Adding tests to verify import is correct.
2013-03-19 20:05:55 -01:00
Stephan 73d77083ae Web.PublishedCache - bugfix & fix tests 2013-03-19 17:54:41 -01:00
Stephan b2a1f67fb4 Web.PublishedCache - move XML away from UmbracoContext 2013-03-19 17:54:41 -01:00
Stephan 3a0d617b14 Web - cleanup UmbracoHelper XPath methods 2013-03-19 17:54:37 -01:00
Stephan ce0c72d9f8 Web.PublishedCache - introduce contextual caches 2013-03-19 17:51:55 -01:00
Stephan cb966ac70b Web.Routing - use UmbracoContext.ContentCache 2013-03-19 17:50:38 -01:00
Shannon Deminick 6c40f32c2a Fixes merge issues. 2013-03-20 00:50:37 +06:00
Stephan cce32f406f Web.PublishedCache - move caches to UmbracoContext 2013-03-19 17:50:36 -01:00
Shannon Deminick 610ff91a9d Merge with 6.0.3 2013-03-20 00:23:24 +06:00
Shannon Deminick a76ffe8daf Backported changes from 6.1 to fix how RePublishAll behaves in the content service to ensure its the same as what was done with
Document.RePublishAll
2013-03-20 00:19:36 +06:00
Shannon Deminick 45f39158ba Merge 2013-03-19 23:55:29 +06:00
Shannon Deminick d7b5d73e62 updated merge 2013-03-19 23:54:56 +06:00
Shannon Deminick 780a9632f0 Merge 2013-03-19 23:49:51 +06:00
Shannon Deminick 603b6c73f7 Adds some notes. 2013-03-19 23:49:20 +06:00
Shannon Deminick 1b66c42c9b Fixes RePublishAll method to ensure it performs the same function as the legacy Document.RePublishAll - it just
re-generates the XML in the cmsContentXml table. Updates the Sql providers to support truncate table. Updates the RepublishAll
unit test. Adds a TruncateTable extension to PetaPoco. Adds locking to certain service methods that perform more than once function.
2013-03-19 23:46:13 +06:00
Morten Christensen 5175fb5188 Updating the EntityService implementation 2013-03-19 09:34:36 -01:00
Shannon Deminick b260769799 Fixes: #U4-1946 - when entities are constructed via the factories (i.e. from the database), ensure that
properties are not tracked as dirty already.
2013-03-19 07:37:33 +06:00
Shannon Deminick 4495fd05c4 Creates IRememberBeingDirty interface to track the properties that we're changed before the last commit for a given entity.
Adds internal property and tracks it's dirty changes to the ContentTypeBase - HasPropertyBeenRemoved.
Fixes: #U4-1942 - ensures content xml cache is refreshed even across servers when a property is removed or when the alias is changed.
2013-03-19 06:38:15 +06:00
Morten Christensen 923653f2b5 Merge 2013-03-18 20:19:09 -01:00
Morten Christensen 083320002b Continueing with the implementation of the EntityRepository 2013-03-18 20:18:12 -01:00
Shannon Deminick 3052c7311f Converts dictionary cache in ContentType to use concurrent dictionary. Changes ContentTypeControlNew to
not call the propertytype.delete() method if it is a DocumentType or MediaType (should only be called for
legacy code like members). Updates ContentTypeCacheRefresher to ensure that all of the content type cache is
cleared properly in the ICacheRefresher.
2013-03-19 02:02:11 +06:00
leekelleher 3af7958940 Updated references for alias conventions constants across the solution. 2013-03-18 17:55:02 +00:00
leekelleher c7498cec03 Added constants for regular conventions within the Umbraco core.
e.g. popular property-type aliases.
2013-03-18 17:51:57 +00:00
Stephan abe4ec6524 Core.Configuration - simplify 2013-03-18 15:49:43 -01:00
Shannon Deminick e3a8b4ac78 Moves some legacy classes into LegacyClasses.cs and un-seals some refreshers with comments to support legacy classes. 2013-03-18 21:18:22 +06:00
Morten Christensen 365dffe2db Merge 2013-03-18 14:15:30 -01:00
Sebastiaan Janssen 259fbcb8f0 Fixed U4-1934 Error in comments of config files 2013-03-18 08:50:24 -01:00
Morten Christensen 381157ac5d Initial implementation of the EntityRepository and Service, which will be used to retrieve a basic object with a minimum set of propreties for the models that have their base in the umbracoNode table.
The intention is to use this for loading trees in the backoffice for faster loading.
2013-03-17 16:25:21 -01:00
Shannon Deminick f993e96547 Seals a bunch of classes that need to be 2013-03-16 09:03:26 +06:00
Shannon Deminick 734f75b3ad Removes completely unnused macro cache key 2013-03-16 08:53:27 +06:00
Shannon Deminick 7ef066f396 Removed erroneous cache flushing for tabs since there is no cache for tabs 2013-03-16 08:51:25 +06:00
Shannon Deminick 23bb0e3ac3 Fixes: #U4-1930, #U4-1928, #U4-1929 - addes ContentTypeCacheRefresher to ensure that content type cache is cleared
in load balanced scenarios. Cleans up a bit of code too.
2013-03-16 08:47:55 +06:00
Shannon Deminick 2dea4a1d70 updates more cache handling, fixes syntax error in examineindex.release.config, fixes the DefaultServerMessenger ctor
to be lazy since the db context isn't initialized yet (will speed up start a bit too), ensures that the macro/xslt caching
clearing is only done on the single server instead or re-posing another distributed call.
2013-03-16 01:37:05 +06:00
Shannon Deminick 07bdd138cc Merge with 6.0.3 2013-03-15 11:31:54 +06:00
Shannon Deminick ee9f91b5cf Merge with 4.11.6 2013-03-15 11:31:34 +06:00
Shannon Deminick db3f21429e Fixes infinite loop bug with string trimming. 2013-03-15 11:31:11 +06:00
Shannon Deminick 2b750843c5 Fixed up base web test, removes RequiresDbSetup in place of new database behavior - NoDatabasePerFixture.
Fixed issue with another test... no idea how it didn't show up failing before.
Fixes issue with string extensions and an infinite loop when the string to strip is empty/null.
2013-03-15 11:28:05 +06:00
Shannon Deminick bd81507ecb Merge with 6.0.3 2013-03-15 08:29:22 +04:00
Shannon Deminick 033692d7ee had some strange issues with unit tests, added error checks. 2013-03-15 08:26:49 +04:00
Shannon Deminick 23146cb12a Merge with 4.11.6 2013-03-15 08:06:26 +04:00
Shannon Deminick 04b9607741 Fixes: #U4-1916 and another issue for vdirs, added unit tests, changed UI web project to always
launch in a VDIR.
2013-03-15 08:03:19 +04:00
Shannon Deminick ea7fb32fb9 Merge with 6.0.3 2013-03-15 06:23:54 +04:00
leekelleher 2cd64dd540 Missed a few TinyMCE GUID references, (due to their string format). 2013-03-14 22:15:39 +00:00
leekelleher 2a058cdbcc Fixed a conflict-references between Constants (in Umbraco.Web.Mvc and Umbraco.Core) 2013-03-14 22:01:09 +00:00
leekelleher 37860b4015 Replaced all hard-coded GUID references to use the new Constants. 2013-03-14 22:00:37 +00:00
leekelleher 0f056b1702 Updated GUID references in editorControls and uQuery to use the new Constants. 2013-03-14 21:58:31 +00:00
leekelleher aa5588bbd3 Added Constants (static class).
Included all GUIDs for PropertyEditors and ObjectTypes.
2013-03-14 21:55:46 +00:00
Stephen Roberts 0e392b398c Fixed Property order for document types with Master document types. 2013-03-14 11:08:02 +00:00
Sebastiaan Janssen 5914690ad8 Allow leading sign in number field so that negative numbers are supported 2013-03-25 10:09:02 -01:00
Shannon Deminick 33c5c41a31 Added better support for clearing the db schema for test. Added more support for different db behaviors for tests, now to update
the behaviors where necessary as this will speed things up quite a lot.
2013-03-14 02:43:17 +04:00
Morten Christensen c4aa9095f2 Fixes U4-1858 by ensuring that the text field is reset before setting or removing a value 2013-03-13 20:24:21 -01:00
Shannon Deminick 8d3c798c6c Changed tests to clear out the current database instead of trying to delete/re-create it. Fixes up
other test inconsistencies and more error checking on the ApplicationContext.Dispose.
2013-03-14 01:07:54 +04:00
Morten Christensen 79ce586c8b Fixes U4-1808 by removing the database lookup from an id that was resolved from the media url 2013-03-13 19:26:22 -01:00
Morten Christensen 8fba03c05d Fixes U4-1863 and U4-1908 by ensuring that content and media are loaded in the same manner through the new api 2013-03-13 18:55:25 -01:00
Shannon Deminick 245591c31f Fixed up another test inconsistency 2013-03-13 18:52:15 +04:00
Shannon Deminick 8fb8fc00b4 Fixes up inheritance structure of BaseTableByTableTests 2013-03-13 18:41:24 +04:00
Shannon Deminick 50b05d25f5 Added BaseUmbracoApplicationTests and fixed up dispose on the ApplicationContext to ensure the db object is disposed and doesn't
reset the PluginManager (as this shouldn't really need to be done). Cleaned up all unit tests so they follow the same structure and
uses this base class where necessary and eliminates a lot of duplicate code.
2013-03-13 18:31:07 +04:00
Shannon Deminick c04ee7bdc7 Removes type check caching from TypeHelper... is actually much slower. 2013-03-13 01:40:34 +04:00
Shannon Deminick 75d218d2e3 Updated how mappers for persistence work with the MapperFor attribute and have made BaseMapper public but have
kept all properties, etc.. internal just so that they can be found so we don't have to register them.
Updates unit test to ensure the plugin manager is init'd properly with the 'false' override. Ensures that the base
db test also initializes the plugin manager properly.
2013-03-13 01:09:29 +04:00
Shannon Deminick 4efa2c9f57 teeny bit of code cleanup 2013-03-12 23:51:53 +04:00
Shannon Deminick 630a44358f ensures cache clearing by search is done with case insensitivity 2013-03-12 23:30:43 +04:00
Shannon Deminick f7015d521b Merge 2013-03-12 22:58:53 +04:00
Shannon Deminick 860c8c1002 Fixes: #U4-482, #U4-549. Macro cache streamlining - ensures it is cleared based on event handling instead of inline everywhere
in code. Unit tests for CacheHelper, unit tests for umbraco.macro, updates to
ObjectExtensions.TryConvertTo + unit tests, enhanced disposable method of ApplicationContext.
2013-03-12 22:58:21 +04:00
Stephan a2120d1c6b Web.Routing - improve domains management 2013-03-12 16:12:38 -01:00
Stephan fc3f9dfeae Web.Routing - hide new wildcard domains from public APIs
only way to get them is through internal methods
+ improve / fix domains handling
+ fix failing tests
2013-03-12 15:16:12 -01:00
Shannon Deminick cf64c0243c MacroCacheRefresher also implements ICacheRefresher<macro> 2013-03-12 17:08:31 +04:00
Stephan ca9f53738b Web.UI - AssignDomain2 dialog (U4-19) 2013-03-12 12:00:34 -01:00
Shannon Deminick 8d2e466e34 Changes MediaCacheRefresher to be ICacheRefresher<T> and updates MacroCacheRefresher to use correct
macro object.
2013-03-12 03:11:35 +04:00
Shannon Deminick ec46d65bb4 Streamlines how macro cache is handled 2013-03-12 03:00:42 +04:00
Shannon Deminick 164f22aa50 Makes ApplicationContext disposable so that 3rd party devs are able to reset their applications (or unit tests), updated
resolution and created a ResolverCollection to track all resolvers created so it's super easy to reset all of them at once
(which is what happens on ApplicationContext.Dispose. ApplicationContext.Dispose is also implicitly implemented as to not
show in intellisense that the Dispose method exists... must be cast to IDisposable to work.
2013-03-12 01:50:56 +04:00
Shannon Deminick cc50003e3e Fixup merge issues 2013-03-12 00:40:37 +04:00
Shannon Deminick 8698deb469 Merge with 6.0.3 2013-03-12 00:21:10 +04:00
Shannon Deminick 738e4f5c46 Merge 2013-03-12 00:20:12 +04:00
Shannon Deminick 2fdcb9164a Fix merge issues 2013-03-12 00:19:06 +04:00
Shannon Deminick 7404a1f93d Merge with 4.11.6 2013-03-12 00:14:50 +04:00
Shannon Deminick c8b8b28e9b applies patch for #U4-1890 2013-03-12 00:10:59 +04:00
Shannon Deminick 5bd2571395 Merge 2013-03-12 00:01:14 +04:00
Shannon Deminick c0cd157e60 applies patch for #U4-1890 2013-03-12 00:00:55 +04:00
Sebastiaan Janssen ac2f9b172c .transformed files are auto-generated and shouldn't be under source control 2013-03-11 17:15:30 -01:00
Sebastiaan Janssen c854ea8a35 .transformed files are auto-generated and shouldn't be under source control 2013-03-11 17:11:59 -01:00
Shannon Deminick 9bd865d259 Fixes: #U4-1890 - allows access to the UmbracoContext during application startup. 2013-03-11 23:46:47 +06:00
Sebastiaan Janssen b8e4a73c3b Revert Casey's mistakenly added files 2013-03-11 15:55:35 -01:00
Shannon Deminick 2d55dda662 Merge with 6.0.3 2013-03-11 22:04:29 +06:00
Shannon Deminick 63192f3a65 Merge 2013-03-11 22:04:06 +06:00
Shannon Deminick 29b2458ef3 Merge 2013-03-11 22:01:54 +06:00
Shannon Deminick 1e6de161e6 Merge with 6.0.3 2013-03-11 22:01:40 +06:00
Shannon Deminick 508886b1ad transormed file changed.... 2013-03-11 22:00:59 +06:00
Stephan 3ab0879a99 Core.Strings - refactor ToSafeFileName 2013-03-11 14:58:07 -01:00
Shannon Deminick 4baecfe833 Merge with 6.0.3 2013-03-11 21:56:47 +06:00
Shannon Deminick 727f62d418 Merge with 4.11.6 2013-03-11 21:49:27 +06:00
Shannon Deminick 68c4255a51 updates proper error handling for razor script macros 2013-03-11 21:49:04 +06:00
Shannon Deminick 187af3e361 Fixed merge issue 2013-03-11 21:23:35 +06:00
Shannon Deminick c6f29a50d6 Merge with 4.11.6 2013-03-11 21:17:57 +06:00
Shannon Deminick d07212c89b Fixed changes with new MacroErrors config and how macros are rendered so it supports all macro types and also fixes up a bit of code
in the umbraco.macro class.
2013-03-11 21:06:02 +06:00
Shannon Deminick 28c55320a1 Updates the pull request for handling macro errors.
Backports fixes for partial view macros from 6.x - U4-1488, U4-1844, U4-1730, U4-1843
2013-03-11 20:11:11 +06:00
Morten Christensen cb0dd70434 Minor change to the SqlSyntaxProvidersResolver in the CoreBootManager as per Shannons review. 2013-03-11 12:44:12 -01:00
Shannon Deminick fd58017e97 imported patches for pull request spudstuff/u4497 2013-03-11 18:49:45 +06:00
Morten Christensen 928d92fce4 Making the Sql Syntax Providers public and changing a few names and bits for consistency.
Adding resolver for the syntax providers and wiring it up in the boot manager.
2013-03-09 10:43:34 -01:00
Casey Neehouse 09408b898e Merge 2013-03-08 19:38:33 +05:00
Morten Christensen d1b05332c5 Manually adds fix for U4-1869 from 6.0.3 branch 2013-03-07 20:28:13 -01:00
Morten Christensen 3612f18f3f Merge with 6.0.3 2013-03-07 20:22:37 -01:00
Morten Christensen 836b0f39c2 Additional correction of the implementation for U4-1869 2013-03-07 20:19:39 -01:00
Morten Christensen 1b01386673 Changing the initial fix of U4-1869 to use UrlReplacingCharacters 2013-03-07 19:56:59 -01:00
Morten Christensen 2a09f02afb Fixing incorrect sql syntax when the query contains two expressions. 2013-03-07 19:56:10 -01:00
Morten Christensen ee95434cea Implements U4-1869 by adding the 3 characters to the list of reserved characters. 2013-03-07 19:04:25 -01:00
Shannon Deminick 86852f9815 updated server registrar 2013-03-07 23:23:20 +06:00
Shannon Deminick 9aa44c40ce re-instated the upgrade script and put the server rego back on the service context. 2013-03-07 22:57:42 +06:00
Shannon Deminick da331b7408 Changed how model mappers work for persistence objects so we don't have to statically associate the mapper. 2013-03-07 22:27:47 +06:00
Casey Neehouse caad0afed8 Corrects u4-1870 - Refactor Load Content SQL to check if ID is in published list
versus using a join that can cause duplicate entries.
2013-03-07 21:00:31 +05:00
Shannon Deminick 0230bedeb6 Reinstated server registration repositories and db table 2013-03-07 21:40:00 +06:00
Shannon Deminick bd6aa51397 Merge with 6.0.3 2013-03-07 21:27:54 +06:00
Shannon Deminick 9b85bc0e64 Added installer step to choose rendering engine but have left it disabled, might make a dashboard instead for that. 2013-03-07 21:25:11 +06:00
Morten Christensen fe08e7fc2f Fixes U4-1865 by excluding trashed items from GetByLevel method for both Content and Media 2013-03-07 13:42:14 -01:00
Morten Christensen 4ad96b49e7 Fixes U4-1862 2013-03-07 13:35:17 -01:00
Morten Christensen 9a1bb4a2dd Adding unit test to assert issue with issue with creation of property types outside a property type group.
Fixes U4-1861.
2013-03-07 13:33:22 -01:00
Shannon Deminick 2044d1b5db manually merged in installer changes from 6.0.3 2013-03-07 04:06:30 +06:00
Shannon Deminick 2c05eda899 Merge with 6.0.3 2013-03-07 04:01:04 +06:00
Sebastiaan Janssen c39f902ed5 And one more fix for U4-1845 to make upgrades succeed as well 2013-03-06 14:30:09 -01:00
Sebastiaan Janssen b7dc052cb2 Additional fixes for U4-1845 to maintain compatibility for people using the
wrong connection string
2013-03-06 14:09:01 -01:00
Morten Christensen 0c77114cd5 Fixes U4-1845 by correcting the sql ce connectionstring 2013-03-06 13:36:03 -01:00
Morten Christensen 222a5237b0 Version updated to 6.0.3 2013-03-06 12:03:01 -01:00
Morten Christensen de55cb8392 Correcting fix for U4-1835 2013-03-06 08:32:05 -01:00
Morten Christensen df164ee618 Fixes U4-1835 by checking if the value is null before running the regex validation against the value. 2013-03-06 08:02:09 -01:00
Morten Christensen 21b0687a57 Fixes U4-1837 by syncing tree after saveing DataTypeDefinition 2013-03-06 07:57:00 -01:00
Morten Christensen 9310efa280 Fixes U4-1831 by catching exception if there is no current logged in user. 2013-03-06 07:54:09 -01:00
Morten Christensen a41b55a9e6 Fixes U4-1846 2013-03-06 07:50:20 -01:00
Morten Christensen af2d8a4755 Fix related to U4-1407 but for Media. We already committed this fix for Content. 2013-03-06 07:49:29 -01:00
Shannon Deminick 0852200861 Merge with 6.0.3 2013-03-06 04:12:58 +06:00
Shannon Deminick d48e339b81 Fixes: #U4-1844, #U4-1730, #U4-1843 2013-03-06 04:12:28 +06:00
Shannon Deminick f955955ad8 Merge with 6.0.3 2013-03-06 03:18:11 +06:00
Shannon Deminick 9b6d498cf7 Merge with 4.11.6 2013-03-06 03:17:47 +06:00
Shannon Deminick 62d365573f Back ports fixes for: #U4-1614, #U4-793 - preview working properly in mvc 2013-03-06 03:17:18 +06:00
Shannon Deminick 9042a23de7 Fixes: #U4-1614, #U4-793 - preview working properly in mvc 2013-03-06 03:12:04 +06:00
Shannon Deminick b9eaaa0f29 Merge with 6.0.3 2013-03-05 23:55:41 +06:00
Shannon Deminick 04bf011fcd Merge with 4.11.6 2013-03-05 23:55:09 +06:00
Shannon Deminick f3b7a8a581 Fixes: #U4-1471 - issue with having NewRelic installed and some sort of conflict with shutting down
our logger.
2013-03-05 23:49:45 +06:00
Shannon Deminick 5d62902684 Fixes up the double event for MakeNew on document (#U4-1737) 2013-03-05 22:34:31 +06:00
Shannon Deminick f79d046a87 Merge with 6.0.3 2013-03-05 22:19:31 +06:00
Shannon Deminick 82d645a0f7 Merge with 4.11.6 2013-03-05 22:18:53 +06:00
Shannon Deminick a8936de638 Fixes: #U4-1834 2013-03-05 21:52:22 +06:00
Shannon Deminick a765f36d24 Adds unit tests for DynamicNode and DynamicPublishedContent, fixes both when querying for recursive properties.
Fixes: #U4-1839
2013-03-05 21:00:16 +06:00
Shannon Deminick 737d7d6712 merge issue 2013-03-05 09:13:24 +06:00
Shannon Deminick 4d8ed22206 Merge with 6.0.3 2013-03-05 08:42:43 +06:00
Shannon Deminick 6b691eb461 Merge with 4.11.6 2013-03-05 08:34:14 +06:00
Shannon Deminick 046da1a8ce Fixes: #U4-1824 - issue with razor dynamic node property access performance enhancements. 2013-03-05 07:06:41 +06:00
Shannon Deminick ca7abd6c78 Merge 2013-03-05 06:08:59 +06:00
Shannon Deminick 06dc76496d Merge with 6.0.3 2013-03-05 06:08:02 +06:00
Shannon Deminick 452688b2bb Merge with 4.11.6 2013-03-05 05:57:35 +06:00
Shannon Deminick 7cc0f2a514 Fixes: #U4-1819 2013-03-05 05:56:53 +06:00
Sebastiaan Janssen a2251fe062 Created branch 6.0.3 2013-03-04 10:19:22 -01:00
Sebastiaan Janssen 3d0684eac0 Closing branch 6.0.2 2013-03-04 10:18:18 -01:00
Sebastiaan Janssen a8fafaa194 Added tag Release-6.0.2 for changeset b247b35d8211 2013-03-04 10:18:08 -01:00
Morten Christensen 2b8a6e532e Fixing U4-1820 2013-03-03 11:25:48 -01:00
Morten Christensen d497659f1f Fixes U4-1814 for Document and Media by adding both legacy Before/After Move events 2013-03-03 11:19:15 -01:00
Morten Christensen 0cafeac6eb Fixes U4-1818 2013-03-03 11:11:51 -01:00
Morten Christensen 4516305f3c Fixes U4-1816 2013-03-03 10:34:39 -01:00
Morten Christensen 04c8390a4f Fixes sorting of ContentTypes and Content related to U4-1816.
Updating upgrade code for PropertyTypes / PropertyTypeGroups.
2013-03-02 08:11:47 -01:00
Shannon Deminick 2877b7bda4 Fixes: #U4-1819 2013-03-02 05:46:00 +06:00
Hendy fc94d92b37 Merge 2013-03-01 23:26:00 +00:00
Hendy 84171c6b98 Added Media and Member support to XPath CheckBoxList 2013-03-01 22:53:14 +00:00
Shannon Deminick c137854e01 Merge with 6.0.2 2013-03-02 03:45:06 +06:00
Shannon Deminick 3ff88bc4fa Fixing strange merge issues. 2013-03-02 03:44:43 +06:00
Shannon Deminick fe9f5b224a Fixing really strange merge issues! 2013-03-02 03:34:37 +06:00
Shannon Deminick 45f2cc9a20 Merge with 6.0.2 2013-03-02 02:52:25 +06:00
Shannon Deminick 4b54edf660 Merge 2013-03-02 02:51:05 +06:00
Shannon Deminick f1c680c7e2 Merge with 6.0.2 2013-03-02 02:50:17 +06:00
Shannon Deminick 36108df4d0 Merge with 6.0.2 2013-03-02 02:49:24 +06:00
Shannon Deminick 1bc9d1d9c3 Merge with 4.11.6 2013-03-02 02:45:19 +06:00
Shannon Deminick b5cbe63a4e Back merged from 6.1 the changes required for #U4-1822 and #U4-1797 2013-03-02 02:43:22 +06:00
Shannon Deminick 4882df43bd Back merged from 6.1 the changes required for #U4-1822 and #U4-1797 2013-03-02 01:50:53 +06:00
Shannon Deminick 51ad21302a Merge 2013-03-02 01:03:07 +06:00
Shannon Deminick 010893a73a Fixes: #U4-1822, #U4-1797 - Is helpers and indexes on result collections using IPublishedContent or DynamicPublishedContent were incorrect,
added unit tests to support issues and fixes.
2013-03-02 01:02:38 +06:00
Morten Christensen cb03178d99 Updating version 2013-03-01 15:39:24 -01:00
Morten Christensen 361fa8836b Merge 2013-03-01 15:37:06 -01:00
Morten Christensen 194ebb57b9 Updating migration 2013-03-01 15:36:53 -01:00
Hendy 5effe5015e Added Media and Member support to XPath DropDownList 2013-03-01 15:28:03 +00:00
Stephan 32e6604cf7 Web.Routing - add InternalRedirectPreservesTemplate setting (U4-1222...) 2013-03-01 13:56:12 -01:00
Stephan b2cedf6380 Web.BaseRest - use new settings & config interface 2013-03-01 13:56:12 -01:00
Stephan 9fc5ee897f Web.Routing - implement UrlProviderMode 2013-03-01 13:56:11 -01:00
Stephan e8e8053063 Web.Configuration - migrate TryIisCustomErrors 2013-03-01 13:56:11 -01:00
Stephan c635ec67d0 Web.Configuration - import WebRouting infrastructure 2013-03-01 13:56:11 -01:00
Stephan 750370d148 Core.Configuration, Tests - refactor settings management 2013-03-12 12:02:04 -01:00
Stephan 2c6daa2918 Core.Configuration - cleanup 2013-03-01 13:56:11 -01:00
Stephan e33c877605 Core.Strings - fix tests 2013-03-01 11:47:02 -01:00
Sebastiaan Janssen ee2943b9fb Created branch 4.11.6 2013-03-01 06:56:34 -01:00
Sebastiaan Janssen a3b03988b3 Created branch 6.0.2 2013-03-01 06:55:54 -01:00
Stephan 85e73df3c8 Web.Routing - refactor & resharp 2013-02-28 20:20:40 -01:00
Shannon Deminick a17a11d50b Fixed: #U4-1810, pretty much finished the examine management dashboard. 2013-03-01 03:04:29 +06:00
Sebastiaan Janssen 6d5f7c4293 Checking the filepath correctly this time 2013-02-28 16:23:43 -01:00
Morten Christensen cc32e73235 Merge 2013-02-28 16:00:49 -01:00
Morten Christensen 92ef4d8055 Adds migration execute method for code, so it'll run in the process method of the migration runner. 2013-02-28 16:00:35 -01:00
Sebastiaan Janssen e57e2f5b5f Migrations should be sorted by version number as well 2013-02-28 15:38:07 -01:00
Sebastiaan Janssen 0b4efe4eeb Merge with 4.11.5 2013-02-28 15:10:31 -01:00
Sebastiaan Janssen c250fa560e Restrict the NuGet .Core dependency to the same version. 2013-02-28 15:08:30 -01:00
Morten Christensen 6eeae52333 Adding the actually migration class 2013-02-28 15:01:50 -01:00
Morten Christensen c38c18fed8 Adding migration for updating PropertyGroups and PropertyTypes 2013-02-28 14:54:42 -01:00
Sebastiaan Janssen 0af47963c6 Merge 2013-02-28 09:56:19 -01:00
Sebastiaan Janssen b017e8690a Fix errors in log caused by no prevalues beind selected. 2013-02-28 09:53:57 -01:00
Sebastiaan Janssen 916e442ee4 Fix errors in log caused by no prevalues beind selected. 2013-02-28 09:53:57 -01:00
Morten Christensen ecae9c47b7 Fixes U4-1798 by adding the current user's id when saving Media, MediaTypes and DocumentTypes. 2013-02-28 09:37:33 -01:00
Morten Christensen 836a99128f Fixes moving PropertyTypes between Tabs/PropertyGroups from inherited doc types.
Adds method to move a PropertyType to another PropertyGroup.
2013-02-28 09:07:15 -01:00
Shannon Deminick 6ead98a51d updated latest examine patch dll. added indexing actions to the dashboard. have optimize working great all
with the new umbraco api framework.
2013-02-28 05:05:06 +06:00
Morten Christensen abefbc7581 Merge 2013-02-27 17:02:10 -01:00
Morten Christensen 365addedf4 Fixes deleting tabs and having the property types move to Generic Properties 2013-02-27 17:01:53 -01:00
Shannon Deminick 7cc12211e1 Fixed unit tests 2013-02-27 23:34:55 +06:00
Shannon Deminick f9b7e1b7fa Merge with 6.0.1 2013-02-27 23:20:34 +06:00
Shannon Deminick 44f5439a2c Merge with 4.11.5 2013-02-27 23:14:50 +06:00
Shannon Deminick 8a9680e75c updated unit test logic 2013-02-27 23:13:48 +06:00
Shannon Deminick ae0991bc67 Fixed unit tests now that we have default values stored in GlobalSettings. 2013-02-27 23:02:12 +06:00
Shannon Deminick 0caaaa500c Merge with 4.11.5 2013-02-27 22:38:46 +06:00
Shannon Deminick 36c66e676a Fixed unit tests 2013-02-27 22:35:27 +06:00
Shannon Deminick 33c5f3fcc7 updating examine dash 2013-02-27 22:21:58 +06:00
Shannon Deminick 47f6924ac3 Fixes: #U4-1790 for 6.1 (slightly different fix than 6.0.1) 2013-02-27 21:59:21 +06:00
Sebastiaan Janssen a14baeb111 Merge 2013-02-27 14:58:47 -01:00
Sebastiaan Janssen 5b4d8ed6f3 U4-1793 YSOD when moving a node back to root 2013-02-27 14:57:42 -01:00
Morten Christensen 25ea4003f9 Merge 2013-02-27 14:42:43 -01:00
Morten Christensen 30cef671dc Removing unused code 2013-02-27 14:42:17 -01:00
Morten Christensen 250e627b1d Fixes saving of RegEx in DocTypes.
Fixes loading and saving of properties on inherited tabs.
Adjusts logic around the creation of tabs/property groups
2013-02-27 14:39:11 -01:00
Shannon Deminick 45b8daa18c Merge with 6.0.1 2013-02-27 21:38:45 +06:00
Sebastiaan Janssen 5b00501d21 trySkipIisCustomErrors was defined twice in the Release config 2013-02-27 14:38:15 -01:00
Shannon Deminick 06e5350c43 Fixes: #U4-1790 - Examine indexing non-published items for indexers that are not supporting non-published items. 2013-02-27 21:35:36 +06:00
Sebastiaan Janssen ba530061a0 Merge 2013-02-27 13:53:14 -01:00
Sebastiaan Janssen 89ae3bc143 Add RevertToCleanInstall.bat to 4.11.5 too, it's handy. 2013-02-27 13:51:58 -01:00
Shannon Deminick 484afccf89 Merge with 4.11.5 2013-02-27 20:46:29 +06:00
Shannon Deminick 3951f59d09 Merge 2013-02-27 20:46:06 +06:00
Shannon Deminick 2589ec8367 Merge 2013-02-27 20:45:25 +06:00
Shannon Deminick a6aeada197 Merge with 4.11.5 2013-02-27 20:44:56 +06:00
Shannon Deminick cd8c998ebf Fixes: U4-1788 - ensures internal reserved paths and urls (that cannot be modified) are stored staticly in code,
Also fixes that the _reservedPathsCache and _reservedUrlsCache actually works, before we were doing an
object.ReferenceEquals comparison which would never have worked and it was also not thread safe.
2013-02-27 20:42:11 +06:00
Shannon Deminick 2a9e32e8fd Fixes: U4-1788 - ensures internal reserved paths and urls (that cannot be modified) are stored staticly in code 2013-02-27 20:13:15 +06:00
Sebastiaan Janssen 603724ddd6 Merge 2013-02-27 12:47:21 -01:00
Sebastiaan Janssen 902cfc5a22 Merge with 4.11.5 2013-02-27 12:43:52 -01:00
Sebastiaan Janssen 2cb544591b Pull in new translations 2013-02-27 12:43:21 -01:00
Morten Christensen db7aa99b85 Fixes PerformGetByQuery related to U4-1783. The query does not need to be version specific. 2013-02-27 11:19:53 -01:00
Morten Christensen 031ceccf5d Removing need to load a Property from within FileHandlerData.
This means that newly created properties based on the upload field can be properly saved.
2013-02-27 11:02:27 -01:00
Morten Christensen 7127706c43 Merge 2013-02-27 10:29:26 -01:00
Morten Christensen d078ef8f5e Minor adjustment to property tracking 2013-02-27 10:28:40 -01:00
Morten Christensen 289b9743c5 Fixes regression issue with installing document types using legacy api. 2013-02-27 10:23:48 -01:00
Sebastiaan Janssen eda9ba07f4 Wrongly doing an append where I meant to just replace the html 2013-02-27 09:53:45 -01:00
Shannon Deminick 1157c11d89 added searcher properties 2013-02-27 06:53:18 +06:00
Shannon Deminick 6815092b62 Changed default api routes to support multiple actions, not strict REST only methods. updated more examine mgmt. 2013-02-27 06:50:26 +06:00
Shannon Deminick 876753cb54 Merge 2013-02-27 05:25:21 +06:00
Shannon Deminick b374dcf2c2 fixed issue with test project's invalid references (for web api). Added UmbracoAuthorizedApiController, change the
examine mgmt tools to use web api, got the dashboard displaying all relavent properties for indexers.
2013-02-27 05:24:45 +06:00
Shannon Deminick f7cfa507d7 fixed bug with attributes 2013-02-27 00:41:24 +06:00
Shannon Deminick 5df0013406 Merge with 6.0.1 2013-02-27 00:37:24 +06:00
Shannon Deminick 30d08bfae1 missing proj file update 2013-02-27 00:34:08 +06:00
Shannon Deminick b0ae03b220 publicly exposes the UmbracoAuthorizeAttribute for MVC and creates one for web api too. 2013-02-27 00:33:59 +06:00
Shannon Deminick ffb9849745 Merge 2013-02-27 00:20:50 +06:00
Shannon Deminick cc55107da3 Added method to WebSecurity to validate members, updated routes for umbraco api controllers 2013-02-27 00:19:48 +06:00
Stephan 6c4ee40b96 Core.Configuration - import infrastructure 2013-02-26 16:52:44 -01:00
Stephan c637c517b8 Web.Routing - better PublishedContentRequest support for redirect & status 2013-02-26 16:52:42 -01:00
Stephan cdf6249a41 Core - add some TypeExtensions 2013-02-28 20:10:47 -01:00
Stephan d9540bcfc5 Core - cleanup UriExtensions, create unit tests, make it public 2013-02-26 16:52:27 -01:00
Stephan 1b1b5c047c U4-1779 - Web.BaseRest supports rest extensions over multiple classes 2013-02-26 16:52:06 -01:00
Sebastiaan Janssen fa5b9e5689 Typo: U4-512 "Memebertype saved" 2013-02-26 17:29:53 -01:00
Stephan 6948d70b75 U4-1779 - Web.BaseRest supports rest extensions over multiple classes 2013-02-26 16:52:06 -01:00
Sebastiaan Janssen 3f9b022ae4 Merge with 4.11.5 2013-02-26 17:30:50 -01:00
Stephan aeb417d3d8 U4-1779 - Web.BaseRest supports rest extensions over multiple classes 2013-02-26 16:52:06 -01:00
Shannon Deminick bcfc7b2507 Adds UrlHelper extensions to get the url of any umbraco web api controller. Updates proj dependencies. 2013-02-26 23:13:32 +06:00
Sebastiaan Janssen 990ab7f87f Merge 2013-02-26 15:52:48 -01:00
Sebastiaan Janssen 861198eec9 Merge with 4.11.5 2013-02-26 15:50:11 -01:00
Sebastiaan Janssen c26df8da6f U4-591 Access bug in dashboard 2013-02-26 15:48:22 -01:00
Shannon Deminick 7c32365bd3 moved web api controllers to namespace Umbraco.Web.WebApi and created web api member authorize attribute 2013-02-26 22:14:32 +06:00
Morten Christensen b5aefdce04 Merge 2013-02-26 14:53:41 -01:00
Morten Christensen adfb7cfaa4 Fixes U4-1756 by ordering the DocumentTypes prior to deleting them 2013-02-26 14:52:55 -01:00
Morten Christensen 0a88ba05c8 Corrected an issue related to the upload field when a Document without any files uploaded was deleted 2013-02-26 14:52:33 -01:00
Shannon Deminick bf6ba727a4 Merge with 6.0.1 2013-02-26 21:42:55 +06:00
Shannon Deminick 9ee295d49e Merge with 4.11.5 2013-02-26 21:35:55 +06:00
Shannon Deminick 1e02d85fca Fixes: #U4-1773 (backport fix from 6.0.1) 2013-02-26 21:35:09 +06:00
Shannon Deminick 7173b44b4f Merge with 4.11.5 2013-02-26 21:18:17 +06:00
Shannon Deminick 69f6edadb3 Merge 2013-02-26 21:17:57 +06:00
Shannon Deminick d1dc2331f8 Merge 2013-02-26 21:15:31 +06:00
Morten Christensen bb2f3a1732 Fixes U4-1784 2013-02-26 14:11:24 -01:00
Shannon Deminick 4b29d7ba2e Merge with 4.11.5 2013-02-26 21:11:20 +06:00
Shannon Deminick d503deb8c5 reverted member index config, for pre 6.1 we will still need to manually set the member fields. 2013-02-26 21:07:59 +06:00
Morten Christensen 0859b92aaf Fixes U4-1781 so Saved is called when saving a DataTypeDefinition in the backoffice 2013-02-26 13:59:08 -01:00
Morten Christensen b409740da5 Merge 2013-02-26 13:35:52 -01:00
Morten Christensen a888e0564c Calling save when creating a DataTypeDefinition related to U4-1781 2013-02-26 13:32:02 -01:00
Morten Christensen fef96e8b43 Fixes issue related to moving PropertyTypes between tabs.
Ensures that the right tabs with the right ids are loaded in the dropdown.
2013-02-26 13:31:29 -01:00
Sebastiaan Janssen 429522a0bc U4-1775 Copying nodes results in same name under sort and in MNTP 2013-02-26 13:08:31 -01:00
Morten Christensen e9b2261aab Fixes the moving of a PropertyType from a named tab to generic properties 2013-02-26 11:30:19 -01:00
Morten Christensen 02adb6e112 Removing the creation of Properties that doesn't exist from within the Content class, as it could cause other issues.
Refactoring how Properties are loaded to ensure that new properties are created for newly added PropertyTypes.
Corrected the saving of PropertyTypes not within a PropertyGroup.
Changed the loading of Content/Document to use the new API to ensure that properties are properly loaded.
2013-02-26 10:57:40 -01:00
Sebastiaan Janssen 695d26434c U4-600 Wrong membersearch.png path in MemberSearch.ascx 2013-02-26 09:48:14 -01:00
Morten Christensen 00d408e6bc Merge 2013-02-26 09:13:34 -01:00
Morten Christensen 0498161367 Fixes U4-1630 by ensuring that PropertyTypes with a changed name or alias aren't deleted from the db upon comparison.
Ensures cache is cleared for updated PropertyTypes.
2013-02-26 09:13:05 -01:00
Shannon Deminick 63159702e3 Implemented UmbracoApiController as a plugin and is auto routed 2013-02-26 03:45:39 +06:00
Shannon Deminick 545a873af2 added code comments 2013-02-26 02:28:22 +06:00
Shannon Deminick db268c6805 renamed to MemberAuthorizeAttribute and changed it to inherit from a AuthorizeAttribute as this happens much further up the chain than
the filter attribute and also contains the correct logic to ensure authorization always happens regardless of if the page is cached. Cleaned
up our other authorize attibutes.
2013-02-26 02:21:51 +06:00
Shannon Deminick 2967075c1f Merge 2013-02-26 01:27:48 +06:00
Shannon Deminick 4761e4bd43 Installs web api (nuget) 2013-02-26 01:23:58 +06:00
Shannon Deminick a27dccd0d9 Fix merge issue 2013-02-26 01:17:57 +06:00
Shannon Deminick 6b8bfc2e2d Manually applies fix for U4-1776 SafeAlias culture problem since the files/class structure has changed in 6.1 2013-02-26 01:13:31 +06:00
Shannon Deminick 5b15218174 Merge with 6.0.1 2013-02-26 01:05:36 +06:00
Shannon Deminick 0d3d4693b4 Merge with 4.11.5 2013-02-26 01:00:44 +06:00
Shannon Deminick a19de645e4 Merge 2013-02-26 00:59:06 +06:00
Shannon Deminick f0a53ea9c0 Merge 2013-02-26 00:58:24 +06:00
Shannon Deminick fbcabc94f2 Merge with 4.11.5 2013-02-26 00:50:58 +06:00
Shannon Deminick de9a27db10 Updates to latest Examine lib (another bug fixed) 2013-02-26 00:45:42 +06:00
Morten Christensen d494b061f3 Merge 2013-02-25 15:00:55 -01:00
Morten Christensen ebc8443e70 Removing unnecessary save from MediaType 2013-02-25 14:58:04 -01:00
Morten Christensen 48ee59b94e Adding check related to U4-1757 2013-02-25 14:57:43 -01:00
Sebastiaan Janssen 560dcad90a Updates for MySQL: Check for case-sensitivity 2013-02-25 14:42:07 -01:00
Morten Christensen 7498b2f994 Merge 2013-02-25 14:37:14 -01:00
Morten Christensen df4f92197a Fixes U4-1764 by reducing the number of times a DocumentType is saved from 3 to 1.
Instead of having the Allowed Templates saved in the EditNodeTypeNew control its now done via a callback.
2013-02-25 14:34:29 -01:00
Sebastiaan Janssen 13b1191aad Additional fixes for U4-1776 SafeAlias culture problem 2013-02-25 13:44:31 -01:00
Sebastiaan Janssen adaec42982 Merge with 4.11.5 2013-02-25 13:35:39 -01:00
Sebastiaan Janssen b6d5b7d603 Fixes U4-1776 SafeAlias culture problem 2013-02-25 13:33:51 -01:00
Sebastiaan Janssen 93d7cf4dc3 Fixes U4-1776 SafeAlias culture problem 2013-02-25 13:28:54 -01:00
Shannon Deminick e9f2546c2a Merge 2013-02-25 20:17:18 +06:00
Shannon Deminick 007c4d5862 Fixes: #U4-1773 2013-02-25 20:17:04 +06:00
Sebastiaan Janssen f3621aa743 MySQL: Check for case-sensitivity 2013-02-25 13:14:26 -01:00
Morten Christensen 46cf4398a0 Fixes issue with the Member editor throwing a YSOD because new API was used in the ContentControl.
The new API is now only used if available, which is the case for Content and Media, but currently not for Members.
2013-02-25 13:13:10 -01:00
Morten Christensen 1599f493fa Fixes U4-1696 2013-02-25 13:11:58 -01:00
Shannon Deminick 894cfb2e85 update to examine details 2013-02-25 20:00:11 +06:00
Morten Christensen b5d79ebb74 Fixes U4-1690 with a proper implementation for removing ContentTypes from a composition. 2013-02-25 11:15:56 -01:00
Morten Christensen 1cc8367fa9 Merge 2013-02-25 10:32:01 -01:00
Morten Christensen 7e5087ae7d Fixing issues related to DocTypes 2013-02-25 10:31:38 -01:00
Sebastiaan Janssen d6f9909bec Merge with 4.11.5 2013-02-25 08:46:22 -01:00
Tom Fulton 0c42596dc8 Fixed: U4-1678 Saving a Media should show a SpeechBubble 2013-02-25 08:39:18 -01:00
Shannon Deminick 7deae8ea37 Update to latest examine (bug fixed), started Examine Management dashboard FF project. 2013-02-23 23:00:31 +06:00
Shannon Deminick 03aa7fd06b Fixes umbraco content service 2013-02-23 22:11:38 +06:00
Shannon Deminick 54ba547c8c Converted ~/Umbraco/MasterPages/Default.Master to use correct web forms code behind structure. 2013-02-23 03:20:05 +06:00
Shannon Deminick c1172b6823 Fixes issue with UmbracoContentService when getting all user property names 2013-02-23 01:59:21 +06:00
Shannon Deminick a91d531db2 Fixes very strange issue of FirstOrDefault not actually returning 'null' when it is actually null, never seen anything like it and
PropertyType is not a value type so should be null. real strange.
2013-02-23 01:50:04 +06:00
Shannon Deminick dd0d4e872f Merge with 6.0.1 2013-02-23 00:24:38 +06:00
Shannon Deminick 9b4da4c8f8 Merge with 4.11.5 2013-02-23 00:21:52 +06:00
Shannon Deminick cfc81d0e84 Merge 2013-02-23 00:21:44 +06:00
Shannon Deminick 265fd6b91c Merge with 6.0.1 2013-02-23 00:19:05 +06:00
Morten Christensen 00e10deecb Merge 2013-02-22 16:42:17 -01:00
Morten Christensen 46e67e4a92 Skipping PropertyTypes that doesn't belong to the current ContentType 2013-02-22 16:42:06 -01:00
Morten Christensen 520a7f238d Refactoring ContentTypeControlNew and ContentControl 2013-02-22 16:25:45 -01:00
Shannon Deminick 3c41871e59 Fixes: #U4-1748 2013-02-22 21:42:38 +06:00
Shannon Deminick 038b4300ba Ensures plugin cache is cleared on install 2013-02-22 21:29:48 +06:00
Sebastiaan Janssen 8cf9c1ba97 Fixes: U4-1769 Dictionary Item with "Illigal" character can not be deleted 2013-02-22 14:15:22 -01:00
Shannon Deminick 958d7940f2 Manually applies changes from 6.0.1 to installer files from revisions 8033aae62d4a, fdeca60cb2c1 2013-02-22 21:02:24 +06:00
Shannon Deminick a3f7ef7002 Merge with 6.0.1 2013-02-22 20:04:57 +06:00
Shannon Deminick e2d806f5d9 Merge with 4.11.5 2013-02-22 20:00:10 +06:00
Shannon Deminick 7a47d63b48 Fixed remaining tests 2013-02-22 19:55:22 +06:00
Sebastiaan Janssen 596c4ac329 Fixes: U4-1721 V6: Publish of a page ends in YSOD when using legacy schema 2013-02-22 12:36:24 -01:00
Sebastiaan Janssen 8ad8a3239a Make sure that the installer doesn't crash if dbSettings are null 2013-02-22 12:01:47 -01:00
Morten Christensen c0fa011cc3 Merge 2013-02-22 11:50:00 -01:00
Sebastiaan Janssen 4648a8c103 Fixes U4-1746 Duplicate image source (src) when inserting resized image in tiny
mce (richtext editor)
2013-02-22 11:41:01 -01:00
Sebastiaan Janssen 2df05da7fc Fixes U4-1746 Duplicate image source (src) when inserting resized image in tiny
mce (richtext editor)
2013-02-22 11:41:01 -01:00
Sebastiaan Janssen 87947871d1 Have to add new Examine version to Web.UI as well, else the build output from
build.bat file will not be able to find it.
2013-02-22 09:57:58 -01:00
Sebastiaan Janssen 87fee572ff Enable nuget package restore for teamcity, upgrade examine dll 2013-02-22 09:47:23 -01:00
Shannon Deminick 36eb340c11 Merge 2013-02-22 10:49:15 +06:00
Shannon Deminick aa929e8091 Merge with 6.0.1 2013-02-22 10:45:04 +06:00
Shannon Deminick e00c0fc447 Another update to examine to fix another issue: 10362 2013-02-22 10:41:42 +06:00
Shannon Deminick 2ebfbd5d08 Fixed one test with merging 2013-02-22 10:34:43 +06:00
Shannon Deminick 567be2aecf Fixed up merge issues 2013-02-22 07:08:45 +06:00
Shannon Deminick 6a6ac99c34 Merge with 6.0.1 2013-02-22 06:58:44 +06:00
Shannon Deminick 7137c57ac9 merge issue with mediaxml file 2013-02-22 06:49:02 +06:00
Shannon Deminick d68b4d97f6 Fixing merge issues 2013-02-22 06:43:52 +06:00
Shannon Deminick 89f7a3ec63 Clearly these files shouldn't be deleted :P 2013-02-22 06:23:03 +06:00
Shannon Deminick 96a62b57fb Merge with 4.11.5 2013-02-22 06:21:12 +06:00
Shannon Deminick 7092a9ccbb Reverted the macro engines and web proj's, it would seem as though 4.x on the build server hasn't
been configured for nuget package restor (or something like that)
2013-02-22 06:05:10 +06:00
Shannon Deminick e9ea9b5e1b Updates DynamicNode with some performance enhancements especially around things like HasProperty and GetProperty.
Also when it returned children, it was actually re-iterating over all children (going to the repo to find them even though
they were already resolved).
2013-02-22 05:44:17 +06:00
Shannon Deminick fd1efb29ec Fixes issue when saving settings to web.config, not sure how this error never came up before. Was missing a "\" between the path and "web.config".
Using Path.Combine is much safer than just string.Concat!
2013-02-22 04:45:20 +06:00
Shannon Deminick cf4781153e Fixes: #U4-873, #U4-888 - fixes media sorting in razor + MVC. Updates Nunit libs and Examine lib. Adds unit tests to
support new sorting fixes. Fixes up a few other issues with the legacy ExamineBackedMedia class, it will now handle all data
stored in Examine. Simplifies the Examine internal index sets to include all data.
2013-02-22 04:12:24 +06:00
Stephan 03fc0c868c Core.Strings - fix more unit tests (resolvers init issues) 2013-02-21 16:53:25 -01:00
Morten Christensen 46687429fb Merge 2013-02-21 16:52:13 -01:00
Morten Christensen ce7aa43aa7 Refactoring ContentTypeControlNew to better work with the new api.
Adding a few helper methods to ContentTypeBase, which should make it easier to work with PropertyTypes and Groups.
2013-02-21 16:48:19 -01:00
Shannon Deminick ebed142cd5 Another fix for file sys test 2013-02-21 23:47:16 +06:00
Shannon Deminick dced287c1c Merge with 6.0.1 2013-02-21 23:08:14 +06:00
Shannon Deminick 76e5304233 Merge with 4.11.5 2013-02-21 23:07:59 +06:00
Shannon Deminick d162aba14a Fix for file system test 2013-02-21 23:07:37 +06:00
Shannon Deminick bcd426092c Merge with 6.0.1 2013-02-21 22:52:49 +06:00
Shannon Deminick 387398b044 Merge 2013-02-21 22:52:29 +06:00
Shannon Deminick 62ed7e0a53 Merge with 6.0.1 2013-02-21 22:48:45 +06:00
Shannon Deminick 635b8bd82e Removes all need of UmbracoSettings.UseLegacyXmlSchema = false; in unit tests since the default is false. 2013-02-21 22:46:50 +06:00
Shannon Deminick f2071379fc Merge with 4.11.5 2013-02-21 22:40:24 +06:00
Shannon Deminick ec075f5807 Merge 2013-02-21 22:38:38 +06:00
Shannon Deminick 566986201f Changes ContentFinderByNiceUrlTests to not require a database by having an overloaded ctor param on
ContentFinderByNiceUrl to not require a domain lookup (up-ported from 6.0.x and 4.x logic). Changes
ContentFinderByAliasTests to not require a database by splitting the two tests, now there is also a
ContentFinderByAliasWithDomainsTests.
2013-02-21 22:32:44 +06:00
Shannon Deminick a9947cda48 Merge with 6.0.1 2013-02-21 22:22:23 +06:00
Shannon Deminick eb8875066c Reverts LookupByNiceUrlTests to not require a database setup 2013-02-21 22:12:30 +06:00
Sebastiaan Janssen dca90e6316 Merge 2013-02-21 15:09:20 -01:00
Sebastiaan Janssen 2a47b384d2 Merge 2013-02-21 15:08:43 -01:00
Sebastiaan Janssen 29e5872a0f Merge with 4.11.5 2013-02-21 15:07:17 -01:00
Sebastiaan Janssen df31fafec5 Update en_us umbracoembed file, had the wrong content 2013-02-21 15:06:37 -01:00
Shannon Deminick 5f28f279e0 Merge with 4.11.5 2013-02-21 22:03:42 +06:00
Shannon Deminick 828dc64035 Backports fix for FullpathToRoot in GlobalSettings... not sure how some unit tests have been working this whole time.
Changes UseLegacySchema default value to false... was set to true!?
un-ignores LookupByNiceUrl tests and still ensures it doesn't require a database to test by passing in an optional parameter
to LookupByNiceUrl to specify if we want to include domain lookups or not (default is true)
2013-02-21 22:02:56 +06:00
Shannon Deminick 1d9e445a42 Merge 2013-02-21 21:34:30 +06:00
Shannon Deminick 271b0691e2 Fixed up merge 2013-02-21 21:33:21 +06:00
Shannon Deminick cf46df441a Merge with 6.0.1 2013-02-21 21:17:47 +06:00
Shannon Deminick 1aa137e9da merge fix 2013-02-21 21:13:21 +06:00
Shannon Deminick 042eb47c17 Merge with 4.11.5 2013-02-21 21:02:11 +06:00
Sebastiaan Janssen a6556d0195 Merge 2013-02-21 14:01:28 -01:00
Shannon Deminick 0b74164a8e New base test class for anything relating to published content/media, un-ignores strongly typed tests. 2013-02-21 21:01:00 +06:00
Sebastiaan Janssen 807b32fb0d Fixed: U4-1676 Renamed node has old name on sort 2013-02-21 14:00:10 -01:00
Shannon Deminick 62be1b1267 un-ignores Can_Get_File_Dates in AbstractFileSystemTests... not sure why it was ignored seems to work properly. 2013-02-21 20:42:49 +06:00
Shannon Deminick aec017e933 Merge with 6.0.1 2013-02-21 20:07:18 +06:00
Shannon Deminick bda3fbc698 Merge with 4.11.5 2013-02-21 20:07:05 +06:00
Sebastiaan Janssen 85ae7e764f Merge 2013-02-21 08:52:48 -01:00
Sebastiaan Janssen c744e47665 Fixes U4-1668 4.11.4 NiceUrl property on dynamicnode does not work until a
property has been requested from the dynamic node
2013-02-21 08:52:23 -01:00
Sebastiaan Janssen 3daa624627 Fixes U4-1668 4.11.4 NiceUrl property on dynamicnode does not work until a
property has been requested from the dynamic node
2013-02-21 08:52:23 -01:00
Shannon Deminick 3727ef54aa Commented out migration tests for 6.1 since we don't have any now that the servers stuff is commented out. 2013-02-21 08:19:07 +06:00
Shannon Deminick 5615f9590b Merge with 6.0.1 2013-02-21 06:18:45 +06:00
Shannon Deminick 9a7894df76 Merge with 4.11.5 2013-02-21 06:18:30 +06:00
Shannon Deminick e084ddeb41 Fixed up some merge issues. 2013-02-21 06:14:01 +06:00
Shannon Deminick f8760b34b8 Merge with 6.0.1 2013-02-21 06:10:25 +06:00
Shannon Deminick 6734420c6f merge issue, had 2 declarations in the proj for SettingsForTests 2013-02-21 06:03:56 +06:00
Shannon Deminick fd795e14c6 Merge with 4.11.5 2013-02-21 05:52:42 +06:00
Shannon Deminick f2d105d8b9 Fixed #U4-814 and got all possible unit tests that were not working for DynamicNode but were working for
DynamicPublishedContent working. And fixed up the DynamicPublishedContent unit tests as these weren't working at all...
but seemed to say they did on the build server. strange.
2013-02-21 05:44:44 +06:00
Shannon Deminick 9d95c04ab6 Fixed #U4-814 and got all possible unit tests that were not working for DynamicNode but were working for
DynamicPublishedContent working.
2013-02-21 05:13:08 +06:00
Shannon Deminick d622f76393 Fixed #U4-814 and got all possible unit tests that were not working for DynamicNode but were working for
DynamicPublishedContent working.
2013-02-21 05:02:06 +06:00
Shannon Deminick d8af1aaf7b Changed logging in unit tests to filter out things we don't need to see 2013-02-21 03:13:16 +06:00
Shannon Deminick c93193c5c8 Changed logging in unit tests to filter out things we don't need to see 2013-02-21 03:13:16 +06:00
Shannon Deminick 62c4713593 Changed logging in unit tests to filter out things we don't need to see 2013-02-21 03:13:16 +06:00
Sebastiaan Janssen d4fc82dae1 Calculate the hash of the WebPI package so it's not such a manual process. 2013-02-20 18:28:07 -01:00
Sebastiaan Janssen d4058bd81f Merge 2013-02-20 15:57:16 -01:00
Sebastiaan Janssen bc824ba66a Updates for WebPI testers: Check if SQL CE file exists when connectionstring is
filled in, make sure the connection string exists in web.config and if it has
empty values, run the installer instead of trying to start the site.
Also never claim the database is configure when the providername is empty.
2013-02-20 15:55:39 -01:00
Shannon Deminick e3ef3dfb32 Fixes events test 2013-02-20 22:27:58 +06:00
Sebastiaan Janssen 4201286038 Don't check for database.windows.net to determine SQL Azure as WebPI sets a
custom server name
2013-02-20 15:03:43 -01:00
Shannon Deminick 7509724e35 Comments out Server registration and db classes for now, we'll revisit this again soon for automatic
distributed cache without the need for xml. This code is nearly there to work in most classic implementations
of a load balanced site where each node has an internal DNS/Hostname entry. Needs some fine tuning but we'll release
this in a later version.
2013-02-20 21:55:02 +06:00
Stephan e333ad2b23 Tests.Routing - fix tests 2013-02-20 14:38:28 -01:00
Sebastiaan Janssen a8eeabb73d Merge 2013-02-20 14:34:49 -01:00
Sebastiaan Janssen b06620f56e Make the SQL Azure connection string support custom domains and all kinds of
ways of entering it.
2013-02-20 14:34:18 -01:00
Shannon Deminick a41e32c068 un-commented out the sort order test for examine 2013-02-20 21:32:57 +06:00
Shannon Deminick 3baf326498 Merge 2013-02-20 21:31:33 +06:00
Shannon Deminick 8ea9627d51 Updated to Examine 1.45, Updated FixedDisplayModes to 1.0.1 2013-02-20 21:29:56 +06:00
Stephan 957feefb2e Tests.Routing - fix tests 2013-02-20 14:23:29 -01:00
Morten Christensen e8524963dd Fixes U4-1716 2013-02-20 11:20:06 -01:00
Stephan 5b0a8c0668 Tests - fix build broken by back-porting 6.x code 2013-02-20 10:12:41 -01:00
Sebastiaan Janssen 5d931d1146 Merge 2013-02-20 08:52:06 -01:00
Stephan 40b7659078 Tests.Routing, Web.Routing - more tests + fix wildcard domains 2013-02-20 08:51:41 -01:00
Stephan 0427ecc7f4 Tests.Routing - add tests for wildcard domains 2013-02-20 08:12:48 -01:00
Stephan 11560a5451 Test.Routing - more umbracoUrlAlias test 2013-02-20 06:47:07 -01:00
Shannon Deminick 879c77c68d Applies same try/catch logic for setup/teardown because I'm still experiencing issues with the SQLCE
db file being locked which mucks up the rest of the setup/teardowns and tests fail.
2013-02-20 07:07:57 +06:00
Shannon Deminick e71dd3008d Merge 2013-02-20 06:39:09 +06:00
Shannon Deminick 597c888d36 Merge 2013-02-20 06:36:21 +06:00
Shannon Deminick 5bef77c0fb Merge 2013-02-20 06:30:39 +06:00
Shannon Deminick 89b85bcf4b Fixed Render route handler tests. 2013-02-20 06:30:06 +06:00
Shannon Deminick 694d252ce5 Fixed base test classes to ensure that if/when an issue goes wrong removing the database file that the class can
continue to TearDown (or force a teardown if it is starting up)
2013-02-20 05:54:41 +06:00
Shannon Deminick 7efc06429c Fixes up index set extensions and now have the Sorting test working. PDF indexer tests working. 2013-02-20 05:01:40 +06:00
Sebastiaan Janssen ef4c02f759 Merge 2013-02-19 20:58:00 -01:00
Sebastiaan Janssen 452a0a43b0 Fixes U4-1561 V6.0 RC - Member Profile property saving doesn't work 2013-02-19 20:57:20 -01:00
Shannon Deminick ad188fab70 More tests fixed. 2013-02-20 03:02:44 +06:00
Shannon Deminick b47f9e87f1 Fixed up merging and unit test structures so taht BaseWebTest uses BaseDatabaseFactoryTests.
Fixed up Examine unit test issues
2013-02-20 02:50:08 +06:00
Stephan c3ccf3a609 Tests - cleanup settings handling for more reliable tests 2013-02-19 18:01:52 -01:00
Stephan 60bbede408 U4-1441 - fix, fix and fix! 2013-02-19 17:49:49 -01:00
Shannon Deminick dddc308167 Merge with 6.0.1 2013-02-20 00:44:04 +06:00
Shannon Deminick 0751aff31f Fixes more of #U4-1706 and adds another unit test. Ensures we never return items from the recycle bin even if the indexes exist. Updated logic to ensure
items don't get indexed even if they are saved and currently exist in the recycle bin and ensures that indexes are removed on both trashed
and deleted.
2013-02-20 00:13:35 +06:00
Shannon Deminick a2ea20de70 un-ignores PublishedMedia tests. Streamlines BaseWebTest so now we only have one place for database init logic (will
enhance this more today). Changed ExamineEvents to not delete indexes on trashed and changed PublishedMediaStore to ignore
nodes in the recycle bin path... and now to write unit tests for that.
2013-02-19 22:46:44 +06:00
Shannon Deminick 5919dca5d5 Merge with 6.0.1 2013-02-19 22:15:16 +06:00
Shannon Deminick 3bfa1be60c Patch applied for #U4-1636 2013-02-19 22:14:08 +06:00
Shannon Deminick 8d38cf3c44 Applying patch for #U4-1636 2013-02-19 22:11:55 +06:00
Shannon Deminick a3a9ab069a Applying patch for #U4-1636 2013-02-19 22:09:55 +06:00
Morten Christensen da908501e5 Merge 2013-02-19 14:58:12 -01:00
Morten Christensen 995ed22401 Comments related to U4-1714 2013-02-19 14:58:02 -01:00
Sebastiaan Janssen c9cd4c721c Merge 2013-02-19 14:52:34 -01:00
Sebastiaan Janssen c059c14d7a Fixes U4-1706 DynamicMedia pulls content from Recyling Bin 2013-02-19 14:51:51 -01:00
Stephan 7493426e25 Core.Strings - fix unit tests 2013-02-19 14:00:17 -01:00
Stephan 04c9771978 U4-1611 - bugfix 2013-02-19 13:58:16 -01:00
Stephan 9c8b5cd97e U4-1441 - fix, fix and fix! 2013-02-19 17:49:49 -01:00
Stephan 8bb447065c Tests - cleanup settings handling for more reliable tests 2013-02-19 17:45:22 -01:00
Stephan 1d0299af89 U4-1611 - bugfix 2013-02-19 13:58:16 -01:00
Morten Christensen 5b8beceea8 Merge 2013-02-19 13:46:45 -01:00
Morten Christensen e4568520a9 Improves performance when working with DocumentTypes in the backoffice - related to U4-1714 2013-02-19 13:45:57 -01:00
Shannon Deminick 1733e876c4 Merge with 6.0.1 2013-02-19 20:19:43 +06:00
Shannon Deminick cbba628eaf Merge with 4.11.5 2013-02-19 20:18:15 +06:00
Shannon Deminick c958422317 Merge 2013-02-19 20:17:48 +06:00
Shannon Deminick c2d0e255df Fixes: #U4-1537 2013-02-19 20:17:17 +06:00
Shannon Deminick e096890400 Fixes: #U4-1537 2013-02-19 20:12:13 +06:00
Shannon Deminick 6a9277a712 Fixes: #U4-1537 2013-02-19 20:04:50 +06:00
Morten Christensen ec4b1c8f70 Fixes U4-1689 and U4-1719.
Refactoring UmbracoImageMediaFactory so it uses the extension method for uploading/setting images, so its a bit more DRY.
2013-02-19 11:06:00 -01:00
Stephan 2d336fde73 Tests - cleanup settings handling for more reliable tests 2013-02-19 10:07:22 -01:00
Morten Christensen 1af904435a Merge 2013-02-19 08:47:04 -01:00
Stephan ac3bec5d9e Web.Routing - refactor domains management 2013-02-19 06:37:25 -01:00
Stephan 7da60e9937 Web.Routing - sanitize DomainAndUri 2013-02-26 16:52:43 -01:00
Stephan eba5fc84c0 Web.Routing - refactor wildcard domains 2013-02-26 16:52:43 -01:00
Stephan 71d8736e7e Web.Routing - refactor & resharp 2013-02-19 06:37:25 -01:00
Stephan ae1ff4c39a Web.Routing - cleanup resolvers 2013-02-19 06:37:24 -01:00
Stephan f9f998e823 Core.Strings - refactor cms.helper.Casing 2013-02-26 18:12:22 -01:00
Stephan e10fc26729 Core.Strings - add arguments checks 2013-02-19 06:34:06 -01:00
Stephan 0d6999292c Core.Strings, Web.UI - refactor UI aliases management (3) 2013-02-19 06:30:19 -01:00
Stephan 3e7681d4d2 Core.Strings, Web.UI - refactor UI aliases management (2) 2013-02-19 06:29:59 -01:00
Stephan c838b8a381 Core.Strings - resharp 2013-02-19 06:27:13 -01:00
Stephan 96a279499b Core.Strings - supports allowUnderscoreInTerm in new DefaultShortStringHelper 2013-02-19 06:27:13 -01:00
Stephan a3f0b7a37f Core.Strings, Web.UI - refactor UI aliases management (1) 2013-02-19 06:26:58 -01:00
Shannon Deminick ec87b951d5 Fixes up merge issue. 2013-02-19 07:45:01 +06:00
Shannon Deminick 2e033b3bb6 Merge 2013-02-19 07:32:57 +06:00
Shannon Deminick d8721197b7 Fixes up pull request so that there is no breaking changes. We now type check for a new base class called
UmbracoControllerFactory to get the controller type. Adds SurfaceRouteHandler to ensure that UmbracoMvcHandler is used for all SurfaceControllers, and updates
all routes accordingly. Streamlines the RenderRouteHandler to then just look up surface routes in the route table
for posted values. This now ensures that UmbracoMvcHandler is used even with plugin surface controllers.
2013-02-19 07:30:46 +06:00
Shannon Deminick 4a05b0ea31 Merge with 6.0.1 2013-02-19 06:20:48 +06:00
Shannon Deminick 7b2f03ba50 Merge with 4.11.5 2013-02-19 06:20:12 +06:00
Shannon Deminick 005d3e7d64 Removes area routing for local surface controllers and BeginUmbracoForm, adds strongly typed Html.Action<T>
method for rendering SurfaceController child actions regardless of area (so you don't have to specify).
All relates to #U4-1727
2013-02-19 06:19:26 +06:00
Shannon Deminick 12f8638223 Fixes: #U4-1727 2013-02-19 06:18:51 +06:00
Shannon Deminick 137b0754d6 Removes area routing for local surface controllers and BeginUmbracoForm, adds strongly typed Html.Action<T>
method for rendering SurfaceController child actions regardless of area (so you don't have to specify).
All relates to #U4-1727
2013-02-19 06:11:58 +06:00
Shannon Deminick 7d1e9cfd72 Fixes: #U4-1727 2013-02-19 06:11:17 +06:00
Shannon Deminick 663fc4f954 Removes area routing for local surface controllers and BeginUmbracoForm, adds strongly typed Html.Action<T>
method for rendering SurfaceController child actions regardless of area (so you don't have to specify).
All relates to #U4-1727
2013-02-19 06:00:40 +06:00
Shannon Deminick 845595b01b Fixes: #U4-1727 2013-02-19 05:39:38 +06:00
Shannon Deminick 2fca8f3444 Fixes more examine initialization checks if the umbraco app is not ready/installed. 2013-02-19 05:06:54 +06:00
Shannon Deminick 9324ab8e0e Merge with 6.0.1 2013-02-19 04:11:30 +06:00
Shannon Deminick d01a39e0c6 Fixes merge issue 2013-02-19 04:10:01 +06:00
Shannon Deminick 73bd0137e3 Merge with 4.11.5 2013-02-19 03:57:24 +06:00
Shannon Deminick e6faf73f4f Fixes: #U4-552 2013-02-19 03:43:37 +06:00
Shannon Deminick e3f9e8c842 Fixes: #U4-552 2013-02-19 03:42:19 +06:00
Shannon Deminick 7a38726b26 Fixes: #U4-552 2013-02-19 03:40:36 +06:00
Shannon Deminick a475f72d50 Fixes: #U4-1695 2013-02-19 02:25:57 +06:00
Shannon Deminick 36cadf39e9 Fixes: #U4-1695 2013-02-19 02:22:00 +06:00
Shannon Deminick 9f301f8cc6 updates some code docs 2013-02-19 02:20:15 +06:00
Shannon Deminick e7c5d1f4f3 Fixes: #U4-1695 2013-02-19 02:19:53 +06:00
Shannon Deminick a559ef9f90 Fixes: #U4-1732 2013-02-19 00:59:21 +06:00
Shannon Deminick b45f6e0393 Fixes: #U4-1732 2013-02-19 00:53:20 +06:00
Shannon Deminick 91ee948b4e Obsolete's requestModule and Singleton 2013-02-19 00:50:38 +06:00
Shannon Deminick c1ed910a51 Fixes: #U4-1732 2013-02-19 00:50:22 +06:00
Morten Christensen b99ff6c981 Merge 2013-02-18 15:48:02 -01:00
Morten Christensen 81021f5821 Part of the fix for U4-1689
Adds an alternative to the naming of the media subfolders instead of using the PropertyId.
2013-02-18 15:46:18 -01:00
Sebastiaan Janssen 29724b352b Fixes U4-1451 2013-02-18 13:22:12 -01:00
Sebastiaan Janssen be83302b14 Fixes U4-1451 2013-02-18 13:22:12 -01:00
Sebastiaan Janssen 83d7ea9ef1 Ignoring wrong unit test for now 2013-02-18 12:53:15 -01:00
Sebastiaan Janssen 95024442de Copy the umbracoSettings for PublishMediaStoreTests as well 2013-02-18 12:22:53 -01:00
Sebastiaan Janssen 69f54b5f22 Copy the umbracoSettings for LibraryTests as well 2013-02-18 11:57:58 -01:00
Sebastiaan Janssen 3404f95b2e Forgot one trailing slash in previous commit 2013-02-18 11:42:45 -01:00
Sebastiaan Janssen e56738481b Adding trailing slash to failing routing tests.
The issue with these tests might again be because of the UmbracoSettings file, which has the trailing slash setting. But with the settings being reset after teardown the tests were still failing, so made these minor corrections which shoudl correspond to the default setting.
2013-02-18 11:38:07 -01:00
Sebastiaan Janssen cb59dc353b Update version to 4.11.5 2013-02-18 10:31:43 -01:00
Sebastiaan Janssen d1b75eac08 Update wrong config path in unit tests 2013-02-18 10:31:17 -01:00
Sebastiaan Janssen 1f7651d0e3 Set version to 6.0.1 2013-02-18 10:16:24 -01:00
Stephan 7414b3596e Core.Strings - fix some tests 2013-02-18 08:31:00 -01:00
Stephan a995c9557c Core.Strings - new IUrlSegmentProvider 2013-02-18 08:31:00 -01:00
Floris Robbemont 55f06a7ca6 Fixed issue: #U4-1726 2013-02-16 16:00:28 -01:00
Shannon Deminick e921dca9d6 Fixed up more unit tests and issue with publishing logic. 2013-02-15 20:53:44 +06:00
Shannon Deminick 9ad813d990 Fixes a couple issues with some routing tests. 2013-02-15 19:38:33 +06:00
Shannon Deminick 9fba3fa673 Fixes some resetting being done in test init... should only be done in teardown. 2013-02-15 19:23:16 +06:00
Sebastiaan Janssen 8fabd4e4ed Merge 2013-02-15 12:05:46 -01:00
Sebastiaan Janssen 564d92bed7 Possible fix for TeamCity 2013-02-15 12:05:25 -01:00
Shannon Deminick d73dd47e7b Merge 2013-02-15 18:56:24 +06:00
Shannon Deminick 95f103ccc2 Merge 2013-02-15 18:55:50 +06:00
Shannon Deminick a00278892a Merge 2013-02-15 18:54:53 +06:00
Shannon Deminick 196357f6c3 WIP - getting sorting search test going. 2013-02-15 18:54:37 +06:00
Stephan 7a736344f9 Core.Strings - reorg StringExtensions (no change to code) 2013-02-15 08:42:08 -01:00
Stephan a36824e796 U4-1441 - fix, fix and fix! 2013-02-19 17:43:13 -01:00
Stephan 6e2dc64001 U4-1611 - bugfix 2013-02-19 13:58:16 -01:00
Shannon Deminick 68d5acbe48 Fix merge issue 2013-02-14 23:55:39 +06:00
Shannon Deminick a6b9ceef7b Merge with 6.0.1 2013-02-14 23:38:59 +06:00
Shannon Deminick c21b232a33 Merge with 4.11.5 2013-02-14 23:34:58 +06:00
Stephan 0ace2fdae7 U4-1611 - fix xpath special chars escaping issues in published content store 2013-02-14 16:31:45 -01:00
Shannon Deminick dfb2a31f26 Fixes up examine config for internal indexes: #U4-1710 2013-02-14 23:29:11 +06:00
Stephan 5da3541584 U4-1441 - bugfix 2013-02-14 16:27:27 -01:00
Shannon Deminick ef86d2f1f1 Manually applies patch for #U4-1718 2013-02-14 23:26:29 +06:00
Stephan be98425956 U4-1611 - fix xpath special chars escaping issues in published content store 2013-02-14 16:23:56 -01:00
Stephan 61d1f87611 U4-1441 - bugfix 2013-02-14 16:34:17 -01:00
Stephan 8de579083c U4-1611 - fix xpath special chars escaping issues in published content store 2013-02-14 16:23:56 -01:00
Stephan 6a6b82d1e8 U4-1441 - bugfix 2013-02-14 16:22:42 -01:00
Shannon Deminick 598d66ac7f Imports patch to fix: #U4-1718 2013-02-14 23:14:43 +06:00
Shannon Deminick ac090c05ae WIP - updating UmbracoExamine to fix sort order sorting. 2013-02-14 23:06:28 +06:00
Shannon Deminick 527ef10cda Fixes: #U4-1718 2013-02-14 23:05:58 +06:00
Sebastiaan Janssen a10a6d1af8 Need to wrap the login javascript in a placeholder for Concorde 2013-02-14 09:06:15 -01:00
Sebastiaan Janssen 7640908781 Need to wrap the login javascript in a placeholder for Concorde 2013-02-14 09:06:15 -01:00
Shannon Deminick 766cf56a3f updated some copy is all and started creating a search test but need more info. 2013-02-14 06:33:48 +06:00
Shannon Deminick 73714c7cef Put legacy examine classes back in. 2013-02-14 06:06:54 +06:00
Shannon Deminick 0485c20331 Updated Examine.dll version with a few more fixes/updates. 2013-02-14 06:02:38 +06:00
Shannon Deminick d104ea1b57 Merge with 6.0.1 2013-02-14 02:37:23 +06:00
Shannon Deminick 41c952a2fa missing change 2013-02-14 02:36:56 +06:00
Shannon Deminick 6c09a58baf temp code 2013-02-14 02:36:32 +06:00
Morten Christensen b101e25e7a Correcting a check related to U4-1690.
Fixes a typo in an internal class and private method.
2013-02-13 08:05:04 -01:00
Shannon Deminick 8d2c5029af Merge 2013-02-13 06:14:04 +06:00
Shannon Deminick 8c97e367a2 Adds DatabaseServerRegistrar and ServerRegistrationEventHandler, we can now ensure that all server add themselves to the
database table automatically.
2013-02-13 06:12:43 +06:00
Shannon Deminick 6423914f01 Creates ServerRegistrationService 2013-02-13 04:22:46 +06:00
Shannon Deminick 3b25214433 Adds new database table + migration + unit test + fixes up unit tests to ensure PluginManager.Current = null; is done on teardown.
Created new ServerRegistrationRepository + unit tests + models
2013-02-13 03:29:32 +06:00
Morten Christensen 35a8c5e980 Merge 2013-02-12 12:49:00 -01:00
Morten Christensen 64031777d8 Corrects sorting in migrations 2013-02-12 12:48:47 -01:00
Shannon Deminick 102bf058bc Fixes failing unit tests due to adding check for if the application is configured and un-ignores a couple. 2013-02-12 18:59:07 +06:00
Shannon Deminick 7f51e01be7 Created strongly typed ICacheRefresher<T> so that now we can have cache refreshers execute against a
real instance object like IContent, this will dramatically increase performance for bulk publishing when not
in a load balanced environment. Updated methods on DistributedCache to refresh many instances at one time, this also
means we're not re-looking it back up again. Need to update media, users, templates, members and macros to use this new feature too.
2013-02-12 07:35:47 +06:00
Shannon Deminick cb3ac17f43 Ensures tree is synced on bulk publish, fixes Dimming on the content node. Starts adding ability to
make distributed calls that are strongly typed and can do more than one at a time.
2013-02-12 04:47:36 +06:00
Shannon Deminick 8dc5092763 Fixes: #U4-1697 - streamlines user cache invalidation/adds new UserCacheRefresher. 2013-02-12 04:13:29 +06:00
Shannon Deminick 4e6bdd1fc7 Fixed some med trust issues with UmbracoExamine. Created new framework for distributed cache providers with unit tests. Still uses the
old ICacheRefresher but now we can plugin 2 new providers - one for resolving a list of servers and the other to notify the servers of changes.
By default we have the configuration based providers which uses the umbracoSettings.
2013-02-12 03:46:27 +06:00
Shannon Deminick f741861014 WIP - refactored some of the lastest changes with publishing based on Morten's feedback. 2013-02-11 20:07:23 +06:00
Shannon Deminick 5e4a23ea84 Replaces all calls of Document.Publish to the lesser obsoleted method Document.SaveAndPublish which is what Publish was calling anyways. 2013-02-11 05:53:44 +06:00
Shannon Deminick ea54997bb7 Updates Document class to ensure that omitCacheRefresh is false for all unpublish operations. Removes all calls in the codebase
to library.UnPublishSingleNode as the logic will be automatically handled by events when un-publishing an item.
Obsoletes library calls - UnPublishSingleNode, UpdateDocumentCache since they are no longer needed to be called
explicitly, cache refreshing will happen automatically with event subscription.
2013-02-11 05:47:25 +06:00
Shannon Deminick da4f51fe2c Reviews all calls to library.RefreshContent(), adds notes where required and streamlines all library calls for
DistributedCache.Instance.RefreshAllPageCache();
2013-02-11 05:32:52 +06:00
Shannon Deminick fc9aa1d231 ensures all publishing occuring in Document class has 'false' set for omitcacherefresh. 2013-02-11 05:01:00 +06:00
Shannon Deminick ac43b40f33 Removes all remaining calls to library.UpdateDocumentCache ... this is handled automatically by events whenever a document is published. 2013-02-11 04:56:34 +06:00
Shannon Deminick 77201f3805 Fix merg issues. 2013-02-11 04:28:18 +06:00
Shannon Deminick 81f7754a45 Merge with 6.0.1 2013-02-11 04:18:33 +06:00
Shannon Deminick 2f9360ac08 Merge 2013-02-11 03:56:58 +06:00
Shannon Deminick c23be1fd96 Fixes #U4-414, #U4-1669 - publish dialog now uses new apis and ensures documents are validated during publishing. This also
enhances many other things in the publishing API including giving a status result for each item, ensuring that child items
do not try to get published when the parent item fails (based on a subset of rules)
2013-02-11 03:55:58 +06:00
Morten Christensen 1c7bb623f1 Implements the retrieval of ancestors, children, descendats and parent IMedia in the MediaService and as extensions to IMedia.
Corresponds to the IMedia implementation of U4-1638.
2013-02-09 11:12:51 -01:00
Morten Christensen 75de4e4e67 Implements the retrieval of ancestors, children, descendats and parent IContent in the ContentService and as extensions to IContent.
Corresponds to the IContent implementation of U4-1638.
2013-02-09 10:58:21 -01:00
Shannon Deminick ded940a757 Updates publishing strategy to allow for validating documents on publishing and reporting on that. Also depending on the
rules set, will not continue publishing it's children either. #U4-414
2013-02-09 06:23:51 +06:00
Shannon Deminick b80415b34e Fixes PublishingStrategy - It will still check if it's expired even if the event isn't cancelled. It now adheres
to some rules about publishing the children if a parent's publishing has failed or was cancelled. Have written unit
tests for these too.
2013-02-09 06:05:35 +06:00
Shannon Deminick 2ecc978591 Got publish strategy working to allow for publishing only descendants that have been previously published, or all descendants.
Added unit tests to support. Changed ServiceContext to accept a BasePublishingStrategy object as default and obsoleted the other
contructor... at least that interface should be easy to obsolete in favor of a base class.
2013-02-09 04:33:56 +06:00
Shannon Deminick de13f7e361 WIP ... Fixes: #U4-1666, Updates documentService to not have to manually
refresh content cache (and fix the unpublishing too since that logic wasn't correct)
Adds DebuggerDisplay support to ContentBase and Entity for better debugging info.
Adds new internal publishing methods to support publishing all children or only children previously published. This also adds new support
for getting a published result back even with bulk publishing.
Updates the publish dialog with new code and to use the new API based on issue #U4-1669.
Adds UmbracoUser property to AuthenticatedUmbracoController, Adds all common properties to the abstract UmbracoController.
Changes the legacy Document to allow content cache to be automatically refreshed (based on events)
2013-02-09 04:05:01 +06:00
Morten Christensen 319f257ee5 Minor change related to U4-1672 2013-02-08 18:54:18 -01:00
Morten Christensen 14d40697b2 Fixes U4-1662 2013-02-08 18:40:52 -01:00
Morten Christensen 6e6b1beffd Fixes U4-1664 2013-02-08 18:37:59 -01:00
Morten Christensen e22de5c9a0 Fixes U4-1666 2013-02-08 18:34:47 -01:00
Morten Christensen 1eea4dab33 Fixes U4-1661 2013-02-08 18:29:59 -01:00
abutland 0af4b3da82 Updated project file 2013-02-08 15:38:52 -01:00
abutland def651d98e Implemented an attribute for surface controllers to provide the restrictions to certain members as available in base. 2013-02-08 15:01:00 -01:00
Morten Christensen 83518de981 Adding no guard for testing purposes 2013-02-08 11:37:50 -01:00
Stephan 6d87174cc1 U4-1441 - improve logging 2013-02-08 07:54:16 -01:00
Stephan 2da18d4500 U4-1441 - improve logging 2013-02-08 07:54:16 -01:00
Stephan a03f5420fa U4-1441 - change trySkipIisCustomError config key 2013-02-08 07:36:35 -01:00
Stephan 9af9c3fe77 U4-1441 - change trySkipIisCustomError config key 2013-02-08 07:36:35 -01:00
Stephan 9cedf5da4c U4-1441 - make trySkipIisCustomError value a setting 2013-02-08 08:08:36 -01:00
Stephan d50396ce68 U4-1441 - change trySkipIisCustomError config key 2013-02-08 07:36:35 -01:00
Stephan f7d4080472 U4-1441 - make trySkipIisCustomError value a setting 2013-02-08 07:51:22 -01:00
Shannon Deminick 4ab14484ba Fixes: #U4-1664, #U4-1661, #U4-1662, #U4-1660
WIP - Updates much logic between editContent and ContentControl to ensure that the above issues are fixed and that we are not
double saving documents each time it is published. This also ensures that the Document.BeforeSave event is not double fired
when saving a document. Have changed over Document.SaveAndPublish to ensure that the cache does get refreshed automatically
when this is called - but now need to go through the rest of the codebase to make sure it's not being double refreshed. once that is
done then we will have streamlined the cache invalidation for content too.
Adds useful properties to the old BasePage like ApplicationContext, Services, etc...
2013-02-08 04:25:31 +06:00
Morten Christensen e24ff1b92b Updating the CreateDatabaseSchema method, so it can't be used if Umbraco is configured. Just to ensure that Richard doesn't accidentally break anything. 2013-02-07 13:56:00 -01:00
Morten Christensen 0c05cbc9db Updating the EmptyRecycleBin method in the services to account for a deleted structure.
Optimizing the CallTheGarbageMan method because it was sooo easy, and it would be stupid not to.
2013-02-07 13:31:39 -01:00
Stephan a0f662c114 Core.Strings - refactor + new IShortStringHelper 2013-02-07 13:30:50 -01:00
Shannon Deminick 975d84f3d0 Started on streamlining Content cache invalidation. 2013-02-07 06:43:49 +06:00
Shannon Deminick c0b708b1f4 Streamlines how Media cache gets invalidated - ensures Save() is called on media where it was needed,
cache now gets invalidated on events.
2013-02-07 05:53:59 +06:00
Shannon Deminick d93ca26181 Streamlines how Template cache gets invalidated - ensures Save() is called on templates where it was needed,
cache now gets invalidated on events.
2013-02-07 05:26:53 +06:00
Shannon Deminick cf8a0728d8 Streamlines how Member cache data gets invalidated 2013-02-07 04:57:44 +06:00
Shannon Deminick ea24e43c90 Changed cache invalidation for macros to be done via events not inline in the editor. 2013-02-07 04:45:05 +06:00
Shannon Deminick 75e747a2d2 Simplifies clearing cache for macro's all is done via the DistributedCache.Instance - hopefully all cache will be invalidated
via this method so that all cache types are simply invalidated with ICacheRefreshers and ApplicationEventHandlers. Currently we
have calls to clear cache in zillions of places and its near impossible to tell where/when it currently happens.
2013-02-07 04:26:48 +06:00
Shannon Deminick be398a4616 Adds a constant id for the macro distributed cache object,
adds extension method to DistrubutedCache to refresh the macro cache,
Changes all distrubuted cache calls for macro to use extension method.
2013-02-07 04:04:51 +06:00
Shannon Deminick 84bd89f00b Adds a constant id for the media distributed cache object,
adds extension method to DistrubutedCache to refresh the media cache,
Changes all distrubuted cache calls for media to use extension method.
2013-02-07 04:01:50 +06:00
Shannon Deminick a1c2352dca Adds a constant id for the member distributed cache object,
adds extension method to DistrubutedCache to refresh the member cache,
Changes all distrubuted cache calls for members to use extension method.
2013-02-07 03:58:47 +06:00
Shannon Deminick b6ec42334b Adds a constant id for the page distributed cache object, adds extension method to DistrubutedCache to refresh the page cache,
Changes all distrubuted cache calls for pages to use extension method.
2013-02-07 03:55:14 +06:00
Shannon Deminick 56fb570267 Adds a constant id for the template distributed cache object, adds extension method to DistrubutedCache to refresh the template cache,
Changes all distrubuted cache calls for templates to use extension method.
2013-02-07 03:49:45 +06:00
Shannon Deminick 510d8b9dda Ensures that all calls to 'dispatcher' are replaced with the new DistributedCache.Instance object. 2013-02-07 03:29:47 +06:00
Shannon Deminick d8e4895daa Moved legacy classes into single file LegacyClasses.cs 2013-02-07 03:24:32 +06:00
Shannon Deminick c20cd907b0 Migrated CacheRefresher and dispatcher to proper namespaces and cleaned up a bit. 2013-02-07 03:22:38 +06:00
Shannon Deminick c72b4f40bd Ensures Examine events is listening to the Trashed of content too with the new API. 2013-02-07 02:23:40 +06:00
Shannon Deminick f8d09a9ac3 Adds patch fixes for #U4-1653 2013-02-07 02:19:51 +06:00
Shannon Deminick 906d675dca Merge 2013-02-07 02:09:32 +06:00
Shannon Deminick 860ef73fab Merge 2013-02-07 02:07:43 +06:00
Shannon Deminick ec6158792a Adds patch fixes for #U4-1653 2013-02-07 02:07:07 +06:00
Shannon Deminick f1b3105202 Patch for #U4-1653 - media library cache refresh issue 2013-02-06 20:56:47 +06:00
Morten Christensen a399a8766d Correcting the order of calls in the test SetUp of StronglyTypedQueryTests 2013-02-06 12:53:47 -01:00
Morten Christensen 7f103724f3 Refactoring PetaPoco uses of ExecuteNon, ExecuteScalar and ExecuteReader to use the new WithRetry extension methods 2013-02-06 12:53:08 -01:00
Shannon Deminick 3ebb213916 Patches installer issue. 2013-02-06 19:18:42 +06:00
Shannon Deminick 97536086c0 Patches installer issue. 2013-02-06 19:14:34 +06:00
Morten Christensen 98ecf0e824 Adding package config file for umbraco.webservices proj 2013-02-06 10:37:32 -01:00
Morten Christensen 5fb11a77e7 Adding Mvc 4 as a nuget reference in the umbraco.webservices proj to get it to build. 2013-02-06 10:35:59 -01:00
Morten Christensen d7c72dc279 Merge with 6.0.1 2013-02-06 09:52:28 -01:00
Morten Christensen 0853f8da85 Fixes U4-1619 so MediaTypes are deleted the same way as DocumentTypes using the legacy api/backoffice. 2013-02-06 09:43:53 -01:00
Morten Christensen 32d36d66c9 Removing unused media events 2013-02-06 09:12:38 -01:00
Morten Christensen 2aef75a70a Fixing SaveAndPublish method related to U4-1624 2013-02-06 09:10:08 -01:00
Morten Christensen fc21d10192 Updating cleanup script 2013-02-06 09:04:56 -01:00
Morten Christensen c6bd94532d Fixing issue U4-1648 caused by incorrect sql statement 2013-02-06 09:04:46 -01:00
Morten Christensen 2c8c88e4b8 Merge 2013-02-06 07:31:44 -01:00
Shannon Deminick 9f7347a4f5 Updated LazyManyObjectsResolverBase to support removal. Moves cache refreshers to proper namespace and obsoletes old ones. Obsoletes
a couple of library cache clearing methods and moves them to CacheHelperExtensions. Fixes #U4-1653 for 6.1 and updates ExamineEvents to
ensure that Examine re-indexes media on all of the correct events (including Trashed). Changes for Caching are being done to begin work with
CD-148
2013-02-06 09:53:13 +06:00
Shannon Deminick 13e5590efa Obsoleted methods in old Casing class and redirects to use StringExtensions. Removes eroneous webforms files not needed in the Umbraco.Web prject
(didn't convert the related UI project ones to have code behinds though... one thing at a time and there's a lot of them to do... over time)
2013-02-06 05:56:49 +06:00
Shannon Deminick 77bffa69fd Couple more changes to DynamicXml 2013-02-06 03:58:53 +06:00
Shannon Deminick 763f8796e0 Merge 2013-02-06 03:37:38 +06:00
Shannon Deminick 3be13f57cf un-breaks #U4-1636 - now we have some different ways to return the raw xml values. will post on the issue. 2013-02-06 03:37:28 +06:00
Stephan a65ca205de U4-1441 - fix issue with IIS taking over custom errors 2013-02-05 16:29:10 -01:00
Stephan c8e08b8ef8 U4-1441 - fix issue with IIS taking over custom errors 2013-02-05 16:29:10 -01:00
Stephan 683d793460 U4-1441 - refactor (fix) legacy NotFoundHandler support 2013-02-06 12:46:54 -01:00
Morten Christensen d430efa7ab Updating logging in DatabaseContext 2013-02-05 14:38:58 -01:00
Morten Christensen 31a5363387 Adding fault handling extensions for IDbCommand.
Adding unit tests to verify retry strategies.
Adding a RetryPolicy factory for our standard configuration.
2013-02-05 14:31:55 -01:00
Morten Christensen ef20f228ec Correcting issue related to MediaXmlTest, which was fixed in v6. 2013-02-05 09:13:21 -01:00
Morten Christensen c828c6ede3 Updating schema result to account for foreign tables when determining the current schema. 2013-02-05 08:41:10 -01:00
Morten Christensen bc08feaa08 Merge 2013-02-05 07:25:41 -01:00
Stephan ef9ce720b2 Web.PublishedCache - create, migrate 2013-02-05 06:31:13 -01:00
Stephan 4c3d2c10ac Web.Routing - clear convoluted .RoutingContext.UmbracoContext.RoutingContext 2013-03-19 17:38:18 -01:00
Stephan 0db781b59f Web.Routing - fix configuration default 2013-03-19 17:37:35 -01:00
Stephan c94eb4328f Core.Xml - document + public XPathVariable 2013-03-19 17:34:28 -01:00
Shannon Deminick 47ab187780 Obsoletes base pages - umbraco.BasePage, etc... which is superceded by Umbraco.Web.UI.Pages classes 2013-02-05 06:05:57 +06:00
Shannon Deminick 020cc54da7 Obsoleted old ping.aspx class, changed the ping.aspx page to not actually have an inherited class. 2013-02-05 06:01:41 +06:00
Shannon Deminick dd0a18cf5b Removed ~/Umbraco/test.aspx - this literally didn't do anything, was never referenced anywhere and threw YSODs when the button was clicked. 2013-02-05 05:51:51 +06:00
Shannon Deminick f726ec740a Converted Umbraco.aspx, TreeInit.aspx to have proper web forms classes and obsoletes old ones.
Obsoletes umbWindow class as its not used in the codebase whatsoever.
2013-02-05 05:43:38 +06:00
Shannon Deminick db79b95d22 Fixes a bunch more unit tests due to resolution issues. 2013-02-05 05:08:43 +06:00
Shannon Deminick bac2b7643f Moves UmbracoUserControl to it's correct home and obsoletes the old one (even though its really new)
Publicizes UmbracoControl.
2013-02-05 05:00:16 +06:00
Shannon Deminick 11449688ba Fixes: #U4-1636 - We still use DynamicXml but we don't make a call to StripDashesInElementOrAttributeNames before creating the DynamicXml object, instead the
DynamicXml object itself will test whether the stripped values match or not. Have updated/created unit tests to confirm this functionality.
2013-02-05 04:29:01 +06:00
Shannon Deminick b080ebf697 Fixes failing unit tests due to not resetting Resolution before resetting the actual resolver classes. Now it is automatically impllied that
when you Reset a resolver class, Resolution is un-frozen.
2013-02-05 03:10:01 +06:00
Stephan 0b0784d40c U4-1441 - fix NotFoundHandler assembly loading 2013-02-04 16:10:43 -01:00
Stephan bfb36cac7c U4-1441 - fix issue with IIS taking over custom errors 2013-02-04 16:10:43 -01:00
Morten Christensen dd2a1207f4 Merge 2013-02-04 13:37:44 -01:00
Shannon Deminick 58b3ce749e Fixed Skinning step to point to correct user control 2013-02-04 20:23:57 +06:00
Morten Christensen 6c693ff7b1 Adding fault handling for sql connections, so we have a retry strategy in place. 2013-02-04 13:21:46 -01:00
Stephan 3e1120612b Update version number 2013-02-04 12:00:58 -01:00
Stephan 8d06d39a62 Create branch for 4.11.5 2013-02-04 11:59:30 -01:00
Morten Christensen f64d4c9272 Updating the get media in recycle bin query as the parent is not necessarily -21 2013-02-04 08:00:31 -01:00
Morten Christensen b2f6620d80 Merge 2013-02-04 07:57:36 -01:00
Morten Christensen 812d38878c Updating the get content in recycle bin query as the parent is not necessarily -20 2013-02-04 07:47:05 -01:00
Stephan da7fea47c6 U4-1441 - refactor (fix) legacy NotFoundHandler support 2013-02-03 14:34:04 -01:00
Stephan 95df864d01 U4-1441 - refactor (fix) legacy NotFoundHandler support 2013-02-03 14:34:04 -01:00
Stephan eaa36a248c datalayer - remove mess introduced in f312bd7ee03b 2013-02-05 14:36:56 -01:00
Shannon Deminick ca7fe6854b Moved all old installer legacy classes into single files called LegacyFiles... much less clutter in the old legacy folders. 2013-02-03 05:16:42 +06:00
Shannon Deminick 1be3af1e31 Working on #U4-1358 - moving Base page classes to their correct location/assembly. Migrated all installation webforms files and associated helper files to
their correct locations/namespaces/assemblies and obsoleted all of the old ones and ensure the old webforms files don't exist where the obsoleted ones were.
Fixes a security issue with the installer ajax service (used to be p.aspx, now is InstallerRestService.aspx)
2013-02-03 05:06:11 +06:00
Stephan b8bcb3820a Web.Routing - if setting template fails, keep the previous one 2013-02-02 13:29:02 -01:00
Stephan 571849f211 Tests.Routing - fix RenderRouteHandlerTests 2013-02-07 20:27:46 -01:00
Stephan c8bcbdb3e1 U4-1441 - improve logging 2013-02-07 19:24:33 -01:00
Stephan 32c187f023 U4-1441 - make trySkipIisCustomError value a setting 2013-02-07 13:30:06 -01:00
Stephan dda9519e5e Core.Models - fix typo in Template 2013-02-06 13:33:04 -01:00
Stephan 91ff702cf2 Core.IO - add 'verify' methods to complement 'validate' methods 2013-02-06 13:25:27 -01:00
Stephan f7f269aa79 Core.Resolution - minor doc + renaming (being picky...) 2013-02-06 13:03:44 -01:00
Sebastiaan Janssen 71ddaf04b9 Put in an explicit comment to not disable useAspNetMasterPages when switching to
MVC as the default render engine
2013-02-02 09:49:21 -01:00
Shannon Deminick 0d34b203d5 Merge 2013-02-02 07:06:51 +06:00
Shannon Deminick 34975183d2 Changed PublishedContentHelper to use 6.0 APIs instead of relying on the WebBootManager hack to set a delegate.
Fixed up a heap of failing unit tests.
2013-02-02 07:06:27 +06:00
Shannon Deminick 545a156942 Got most of #U4-1503 - External UmbracoExamine libraries built separately from the web app with the Build.bat command. Now
just need to get the output zipped up and then create some Nuget packages with dependencies.
2013-02-02 06:08:14 +06:00
Paul@PaulSony f9d5b28372 Updates to WPI XML paramters and manifest, handles connectionStrings 2013-02-02 06:21:20 +08:00
Shannon Deminick 8df7812165 Adds Examine xslt extensions to config by default. 2013-02-02 03:49:16 +06:00
Shannon Deminick d1ac2f11d1 Fixed naming conventions: TypedContentAtRoot and TypedMediaAtRoot instead of TypedContentsAtRoot and TypedMediasAtRoot. 2013-02-02 03:22:30 +06:00
Shannon Deminick 5d681c18fe Converted UmbracoExamine UmbracoContentService to use new data APIs and added a unit test for one of the converted methods. 2013-02-02 03:21:06 +06:00
Shannon Deminick a66d651c07 Converted over other IApplicationEventHandlers to use the simpler ApplicationEventHandler 2013-02-02 02:43:02 +06:00
Shannon Deminick e541995e01 Fixes: #U4-1623 and changes over ExamineEvents to use ApplicationEventHandler instead of IApplicationEventHandler. 2013-02-02 02:38:39 +06:00
Shannon Deminick 6ee17dad03 Updated configs to ensure that the correct (non-obsoleted) config section definition is used for Examine.
Updates Examine index configs to be simplified, don't need all of that config there!
Updates UmbracoExamine indexers to not initialize if the app/database is not ready.
Updates Examine event binders to not bind if the app/database is not ready.
Updates Examine events to use new 6.0+ events and removes binding entirely to the old api events (where we could)
2013-02-02 02:16:44 +06:00
Shannon Deminick e8d924cd2c Merge with 6.0.1 2013-02-01 19:43:10 +06:00
Shannon Deminick 6e1316cb95 Fixes up some merge issues. 2013-02-01 19:41:23 +06:00
Shannon Deminick f2442b25f6 Close 4.11.4 branch 2013-02-01 19:25:12 +06:00
Shannon Deminick bfb8912518 Merge with 4.11.4 2013-02-01 19:23:56 +06:00
Stephan fa2ea78bda Fix build after merge 2013-02-01 10:47:53 -01:00
Sebastiaan Janssen 300d3ff09b Added tag Release-4.11.4 for changeset e02f5aebb87e 2013-02-01 08:41:26 -01:00
Sebastiaan Janssen e6337b8f14 Properly reference uGoLive MyGet package 2013-02-01 08:38:13 -01:00
Morten Christensen 39d45ba4b0 Fixes U4-1618 2013-02-01 08:21:44 -01:00
Sebastiaan Janssen 2be785ace3 Merge 2013-02-01 08:16:18 -01:00
Sebastiaan Janssen 5e2d991fab Update uGoLive 2013-02-01 08:16:10 -01:00
Morten Christensen 536cb4caf1 Fixes U4-1571 2013-02-01 07:42:51 -01:00
Morten Christensen 27745ea141 Fixes U4-1483 2013-02-01 07:35:48 -01:00
Sebastiaan Janssen 5289c55740 Translation updates 2013-02-01 07:24:21 -01:00
Sebastiaan Janssen 791773fc8a Add some more translations 2013-02-01 07:23:33 -01:00
Stephan 1989a44d4f Web.UmbracoHelper - add ContentAtRoot, MediaAtRoot methods 2013-02-01 06:28:54 -01:00
Shannon Deminick 6b3de00e08 Merge with 6.0.1 2013-02-01 06:52:27 +06:00
Shannon Deminick 3179b2794b Merge with 4.11.4 2013-02-01 06:46:00 +06:00
Shannon Deminick 1da27e6c2b Removes all upgrade script stuff since we've deployed the fix in a package. 2013-02-01 06:42:42 +06:00
Shannon Deminick bea6031de1 Removes UpgradeScripts stuff from 4.11.4 ... now to go remove it from there too since I've moved the script to a package. 2013-02-01 06:34:28 +06:00
Shannon Deminick 3608242b25 Merge with 4.11.4 2013-02-01 06:22:28 +06:00
Shannon Deminick 5602701645 Fixes uGoLive id and changes dashboard ascx to use CDF to load scripts/styles and using the knockout version shipped in the core.
Removes duplicate tree from the config.
2013-02-01 06:05:39 +06:00
Shannon Deminick a909b7904e Fixes uGoLive ascx 2013-02-01 05:29:54 +06:00
Sebastiaan Janssen 6e0af6827e Fix weird merge issues 2013-01-31 14:35:18 -01:00
Sebastiaan Janssen 51ff861e44 Merge with 6.0.0 2013-01-31 14:09:24 -01:00
Sebastiaan Janssen aa092ab3f3 Closing 6.0.0 2013-01-31 11:41:34 -01:00
Sebastiaan Janssen aaaace8dd3 Added tag Release-6.0.0 for changeset 1719fbd857f2 2013-01-31 11:32:05 -01:00
Morten Christensen 44012398bf Merge 2013-01-31 11:23:19 -01:00
Morten Christensen f18c557fb4 Fixes bug related to U4-1460 - template was incorrectly updated when sorting nodes. 2013-01-31 11:22:54 -01:00
Morten Christensen 1249761ecd Fixes U4-1610 2013-01-31 11:22:15 -01:00
Sebastiaan Janssen db6da95421 Move script back up, there was no need to move it down :) 2013-01-31 10:50:56 -01:00
NielsHartvig@UMBRACORATI.localdomain 8473601f03 Fixes issue with db detection in install logger 2013-01-31 10:39:30 -01:00
Stephan 8b00e72bf6 Web.Routing - refactor url providing (U4-1321...) + new IUrlProvider 2013-01-31 10:06:25 -01:00
Sebastiaan Janssen ac2c3ff321 Move the install stats call down in the page so it doesn't block page load 2013-01-31 09:16:49 -01:00
Sebastiaan Janssen 7300686f34 Update to WebPI parameters 2013-01-31 08:53:55 -01:00
Sebastiaan Janssen 7e288f657b Pull in the latest translations 2013-01-31 08:29:55 -01:00
Sebastiaan Janssen ca44094a37 Remove RC from the version number 2013-01-31 08:23:58 -01:00
Morten Christensen c72b6d7ae5 Minor Typo 2013-01-31 08:04:20 -01:00
Morten Christensen 99c880a4c9 Added additional logging to migration runner. 2013-01-31 07:27:13 -01:00
Shannon Deminick 1b1abce7da Merge 2013-01-31 04:48:29 +06:00
Shannon Deminick fbc10be381 Reverted logic of Document to be what it used to be... Published and HasPublishedVersion() are the same and will
return the same thing, though we've kept the lazy loading and optimizations.
2013-01-31 04:46:51 +06:00
Shannon Deminick 61f2647b62 missing file 2013-01-31 04:26:47 +06:00
Shannon Deminick a5bea7fc59 Added the ability to automate any c# scripts for an upgrade process. I realize this is superceded already in 6.0
but we need a way to do this in 4.x too especially for this release since we need to run a script to fix some db
issues. I've added a framework using an UpgradeScriptManager and another install step + unit tests for some of the
UpgradeScriptManager methods.
2013-01-31 04:26:37 +06:00
NielsHartvig@UMBRACORATI.localdomain 00cf20a8d0 Adds support for install statistics 2013-01-30 19:41:36 -01:00
Morten Christensen b20bb7a5a2 Fixes unit tests using the ContentService.Save method. Because we are using .ToXml in the save method to save preview xml we need to setup the DataTypesResolver in the test setup. 2013-01-30 16:23:33 -01:00
Sebastiaan Janssen b9be5c2561 Also implement optimization in fdfa687e6f41 to v4: no need to try and republish
the child pages if the page you are trying to publish was already published
2013-01-30 15:01:38 -01:00
Stephan 56281d64b0 Tests.Routing - fix tests that were failing
due to Models.ITemplate, Resolution, database constraints...
2013-01-30 14:46:38 -01:00
Stephan 024a4ed8d0 Tests.Resolvers - add tests to ManyResolver 2013-02-02 10:34:20 -01:00
Stephan 789927a043 Web.Routing - fix resolvers naming 2013-02-02 10:22:19 -01:00
Stephan cc0ad0b089 Web.Routing - PublishedContentRequest template naming 2013-02-05 06:37:36 -01:00
Stephan a94f3b6211 Web - RoutesCache belongs to RoutingContext 2013-01-30 14:45:13 -01:00
Stephan 1340cc0b2e Web.Routing - published content request Is404 visibility 2013-01-30 14:45:11 -01:00
Stephan c8aedb381b Core.ObjectsResolution - add insert at beginning of list in many resolver 2013-01-30 14:45:08 -01:00
Morten Christensen a82c5c332a Merge 2013-01-30 14:22:53 -01:00
Morten Christensen 19869e6d5f Possible fix for U4-1539 Removing SaveXmlPreview from the Document class save methods.
The Save and SaveAndPublish methods in the ContentService now handle the saving of preview xml to the database.
2013-01-30 14:22:07 -01:00
Shannon Deminick 861d4a1b22 Merge 2013-01-30 19:16:18 +06:00
Shannon Deminick b722bce2ed Fixes: #U4-1593 - ensures that the content tree checks for the Published property not HasPublishedVersion() 2013-01-30 19:15:16 +06:00
Morten Christensen 0c19307fa3 Making a few optimizations based on the findings in v.4.11.4. 2013-01-30 12:11:10 -01:00
Shannon Deminick 97556de447 Changed methods created yesterday to internal so we can port to 6+ nicely. 2013-01-30 18:58:42 +06:00
Morten Christensen bd12cb3ae5 Merge 2013-01-30 11:19:49 -01:00
netaddicts ceb561c113 Makes sure preview is not using cached versions of any macro 2013-01-30 09:41:00 -01:00
Morten Christensen 14c0e9e149 Fixes U4-1584 so property types and related property data is deleted in a way that works for both Document, Media and Member. 2013-01-30 09:33:17 -01:00
Sebastiaan Janssen 1d6587bb6b Fixing U4-359 Previewing new nested pages doesn't work 2013-01-30 09:21:43 -01:00
Morten Christensen a2a925fd7a Fixes U4-1590 so members with a Date picker will save without errors.
Improves the saving of date values.
2013-01-30 08:43:23 -01:00
Morten Christensen 29ef529c57 Fixes U4-1592 so its possible to clear values when saving 2013-01-30 08:42:26 -01:00
Shannon Deminick 30fe0ecaf4 Fixes unit tests and logic for Umbraco_Route_User_Defined_Controller_Action 2013-01-30 05:55:40 +06:00
Stephan 64692e0041 Fix build after merge 2013-01-29 19:10:58 -01:00
Stephan f1039a18e4 Merge with 6.0.1 2013-01-29 18:51:58 -01:00
Stephan ea805a7af8 Merge with 6.0.0 2013-01-29 18:49:05 -01:00
Shannon Deminick 350bea7798 Merge 2013-01-29 21:26:36 +06:00
Shannon Deminick f9977a9fd8 Fixes: #U4-1170 - template with hyphen or dash 2013-01-29 21:19:16 +06:00
Morten Christensen ea4f89701c Merge 2013-01-29 12:59:14 -01:00
Morten Christensen f3bfe0177d Implementing the Media part of U4-1568 2013-01-29 12:58:02 -01:00
Sebastiaan@SEBVIRTUAL.SSG5-Serial 5dc80c55b2 Fixed some issues with the mysql syntax provider 2013-01-29 12:55:55 -01:00
Morten Christensen 14d5c9bee5 An extra fail safe check in the database step. We verify whether its an install or upgrade when a connectionstring is present. 2013-01-29 12:49:15 -01:00
Morten Christensen 1c08921f55 Implements U4-1568 so raising events for save methods is optional. 2013-01-29 12:45:42 -01:00
Morten Christensen 01bd247831 Correcting HasIdentity check for implementors of File, as the previous check only applies to Script and Stylesheet and not Template. 2013-01-29 12:16:13 -01:00
Morten Christensen a1c39171a5 Fixed CoreBootManagerTests to not initialize all resolvers for this specific test. 2013-01-29 12:15:21 -01:00
Sebastiaan Janssen bb430ddacd Fix MySQL connectionstring detection and rewrite 2013-01-29 11:30:20 -01:00
Sebastiaan Janssen 2fdb485203 Fix spelling error in membertype speechbubble 2013-01-29 10:50:54 -01:00
Morten Christensen 1e8b82f5df Fixes U4-1576. Ensures that structure is kept when moving content and media to and from the recycle bin.
Path and Level are updated accordingly.
2013-01-29 10:26:18 -01:00
Stephan 23b6cf1c24 fix build after merge 2013-01-29 08:27:03 -01:00
Morten Christensen c63f8bc3bd Fixes U4-1578 2013-01-29 08:04:27 -01:00
Shannon Deminick c9d55a4a5e Merge with 6.0.0 - Ensures 6.1 is in sync with 6.0 too 2013-01-29 10:15:49 +06:00
Shannon Deminick 9ae962492a Imports patch for PublishWithResult not being thread safe, removes the giant unnused SQL constants (we have them in history) 2013-01-29 10:11:06 +06:00
Shannon Deminick d404970c74 Fixes up minor merge issues, removes the unused giant SQL constants (we have them in our history) 2013-01-29 10:07:30 +06:00
Shannon Deminick 66bf667100 Merge with 4.11.4 2013-01-29 09:58:47 +06:00
Shannon Deminick 65980e8c76 Fixes: #U4-1546 - Moves IApplicationEventHandler to Umbraco.Core and creates UmbracoApplicationBase object in the Core. Changes
signatures of IApplicationEventHandler methods to accept an UmbracoApplicationBase object instead of UmbracoApplication. This allows
us to execute all IApplicationEventHandler's outside of the web context. Added unit test to support booting the application outside of the
web context.
2013-01-29 09:45:12 +06:00
Shannon Deminick a2b5b13432 Fixes missing 'using' reference 2013-01-29 08:38:34 +06:00
Shannon Deminick c5d1439422 Fixes: #U4-1458 - due to a null check on PublishedContentRequest on UmbracoContext 2013-01-29 08:35:09 +06:00
Shannon Deminick 7ffb3cfb7f Fixes: #U4-1458 - due to a null check on PublishedContentRequest on UmbracoContext 2013-01-29 08:35:09 +06:00
Shannon Deminick df1cfaba28 Applies patch for #U4-1536 2013-01-29 07:50:55 +06:00
Shannon Deminick 5e9f4559b6 Fixes: #U4-1536 2013-01-29 07:49:14 +06:00
Shannon Deminick 4bbb0441a6 Merge 2013-01-29 05:50:50 +06:00
Shannon Deminick 4cf1d7d9a4 Fixes: #U4-1577 - HasPublishedVersion checks for trashed 2013-01-29 05:48:18 +06:00
Shannon Deminick a6a3ddca75 Fixes: #U4-1580 - m_SQLOptimizedMany includes the 'trashed' flag which can be used by business logic. 2013-01-29 05:37:14 +06:00
Shannon Deminick 27cfa85d3a Fixes: #U4-1579 - moving a node doesn't update the descendants of that node's level or path. 2013-01-29 04:39:44 +06:00
Shannon Deminick a9e1e7b634 Updating: #U4-1491 - Updated HasPublishedVersion() to ensure it checks for 'newest' 2013-01-29 03:42:58 +06:00
Stephan 09f50da821 Web.Routing - migrate to Models.ITemplate, cleanup template logic 2013-01-28 18:36:58 -01:00
leekelleher 9f5f920c81 MNTP: Corrected a typo in the example XPath (additional apostrophe) 2013-01-28 17:18:20 +00:00
leekelleher 93bdfc8915 Fixed U4-1562 YSOD saving a Slider property editor set to DB type Nvarchar.
If the Int DbType isn't selected, the DataType will save as string/Nvarchar.
2013-01-28 17:13:18 +00:00
Morten Christensen d91019c9fe Merge 2013-01-28 15:38:27 -01:00
Morten Christensen bc99a6f6c0 Possible fix for U4-1466 which surfaced with the Standard MVC Starterkit package. 2013-01-28 15:37:18 -01:00
Sebastiaan Janssen 463c3cf1d5 Improve variable name and make it use camel case. 2013-01-28 15:03:05 -01:00
Sebastiaan Janssen 1e1d7ce1cd Fixes U4-1566 6.0.0-RC Exception when assigning HttpPostedFileBase type posted
file object to a property
2013-01-28 14:54:51 -01:00
Sebastiaan Janssen dfaebd8f5c Merge 2013-01-28 14:42:43 -01:00
Sebastiaan Janssen 0dfe8c08b9 Add App_Code, App_Data and App_Plugins folders to be created during app startup 2013-01-28 14:41:36 -01:00
Morten Christensen 0dbebaf12e Fixes U4-1557 so the name of a Media item is properly saved.
This has also be tested and verified for content.
2013-01-28 14:31:40 -01:00
Morten Christensen 72097c3ebc Merge 2013-01-28 14:03:52 -01:00
Morten Christensen 5d0aced9a7 Giving the install/upgrade a bit of TLC.
Fixes U4-1520
2013-01-28 14:01:38 -01:00
Shannon Deminick 2f00fa0791 Fixes: #U4-1547 - duplicate trees on upgrade in rare cases. 2013-01-28 19:36:06 +06:00
Sebastiaan Janssen 0689b928c2 Fixes U4-1510 Missing content in Umbraco 6 beta after publish 2013-01-28 11:15:30 -01:00
Morten Christensen 3907ea435a Merge 2013-01-28 08:14:51 -01:00
Stephan 09c19512d9 fix build 2013-01-27 13:32:04 -01:00
Stephan 212b86d8f6 merge from 4.11.4 2013-01-27 12:59:41 -01:00
Stephan a86b831735 Create 6.0.1 branch 2013-01-27 12:39:59 -01:00
Sebastiaan Janssen a11d924736 Fixes U4-1553 - YSOD when umbracoUrlName value is null 2013-01-26 15:50:53 -01:00
Sebastiaan Janssen 59c844eb8f Upgrade to MySQL connector 6.6.4.0 to fix U4-1519 2013-01-26 15:10:02 -01:00
Morten Christensen d0c5357625 Adding initialize call to the legacy conn.string being reconfigured. 2013-01-25 15:17:05 -01:00
Morten Christensen 7aabf459ea Adding schema validation to the DatabaseSchemaCreation class.
Helps determine if valid database exists and which version it corresponds to.
On startup the legacy connectionstring is used if one exists, so its not ignore but rather reconfigured.
Relates to U4-1520.
2013-01-25 15:05:42 -01:00
Morten Christensen 309f337461 Fixes U4-1549 2013-01-25 08:58:21 -01:00
Morten Christensen a17759f759 Fixes U4-1542 2013-01-25 07:50:22 -01:00
Morten Christensen 2374a7a167 Merge 2013-01-25 07:30:40 -01:00
Morten Christensen 086a0811cb Refactoring GetCreator/WriterProfile extension methods to use the service rather then repository, as it seems to cause threading issues per our threading test. 2013-01-25 07:30:25 -01:00
Shannon Deminick 427fff0c53 Fixes: #U4-1527 - imports patch rom 4.11.4 2013-01-25 06:13:47 +03:00
Shannon Deminick f9a0d91299 Fixes: #U4-1527 - Creates a public property on UmbracoHelper to return the currently assigned IPublishedContent of the UmbracoHelper. 2013-01-25 06:04:10 +03:00
Shannon Deminick 4351bd8b50 updated test proj file to re-include MediaXmlTest - but this is failing due to recent
changes.
2013-01-24 23:34:04 +03:00
Shannon Deminick da8dc72908 Merge 2013-01-24 23:31:17 +03:00
Shannon Deminick 2c96188775 Added missing MediaXmlTest 2013-01-24 23:31:07 +03:00
Morten Christensen d3f9e13eae Adding ncrunch ignore 2013-01-24 14:59:58 -01:00
Morten Christensen 82455136bb Missing files 2013-01-24 14:59:03 -01:00
Morten Christensen f6e354314b Minor optimization to SaveAndPublish method in ContentService. 2013-01-24 14:47:44 -01:00
Morten Christensen b7fedb664b Refactoring DatabaseSchemaCreation to allow for schema validation. 2013-01-24 14:47:24 -01:00
Morten Christensen 25f91cc0da Fixes U4-1534 so documents containing the tag datatype is properly copied.
Copying a document with a Tags datatype on it would only work if a new TagRelationship is created.
2013-01-24 13:49:41 -01:00
Morten Christensen 23141e1e8c Fixing broken media tests after having added ToXml and saving of xml to ContentXml table in the MediaService 2013-01-24 12:25:48 -01:00
netaddicts d5bde0d8df Makes sure preview is not using cached versions of any macro 2013-01-24 11:00:15 -01:00
Sebastiaan Janssen cc5ca0b5fe Fixing U4-359 Previewing new nested pages doesn't work 2013-01-30 09:21:43 -01:00
Shannon Deminick 0cb9cc6840 just cleaned up some code formatting. 2013-01-30 07:59:15 +06:00
Shannon Deminick d38d7b1ff4 Updates all code calling UnPublishSingleNode & UpdateDocumentCache to pass in the already existing Document object if there is one
instead of the ID... this'll save a another ton of SQL calls.
2013-01-30 07:59:03 +06:00
Shannon Deminick 2d87f933d5 Updates Document's Published property to return true if the document is 100% published (viewable on the front-end)
Reverts Document's HasPublishedVersion() to return true if the document has any published version (may or may not be viewable on the front-end)
Updates the Document's new UpdatePublishedOnDescendants to set both the Published and PathPublished fields.
Reverts some stuff in the editContent to use HasPublishedContent() to set the _documentHasPublishedVersion field.
Reverts the BaseContentTree to use the Published property now that it returns the correct value.
Updates the editContent method to use the UpdateDocumentCache overload accepting an object so there's not another N+1 SQL call made.
2013-01-30 07:57:31 +06:00
Shannon Deminick a734a0cff7 Fixes unit tests for Umbraco_Route_User_Defined_Controller_Action 2013-01-30 05:37:32 +06:00
Shannon Deminick d0ace55d03 Fixes: #U4-1593 - Content tree doesn't check for correct publish state. 2013-01-30 05:04:31 +06:00
Shannon Deminick 3fda0308ac Fixes: #U4-1594 - SQL for SqlOptimizedSingle not correct for published state
Fixes: #U4-1596 - new GetPathPublishedDescendants method on Document for optimizations
Fixes: #U4-1595 - Obsoletes HasPublishedVersion() method and ensures lazy loading of Published property,
as well as ensuring that the backing property is set correctly on first load (optmization)
Fixes: #U4-1597 - PathPublished property should be set in an optimized way and/or lazy loaded if it cannot be
2013-01-30 04:56:28 +06:00
Shannon Deminick d796b2afc1 Fixes: #U4-1170 - template with hyphen or dash 2013-01-29 21:19:16 +06:00
Shannon Deminick f95cfc2ee0 Changes v4.x config transforms 2013-01-29 21:18:17 +06:00
Morten Christensen b17dcd2b56 Fixes U4-1516 by ensuring that referenced templates are deleted prior to deleting the actual template.
Removing uncommented code from the Media class as well as from the ContentExtension class.
Added saving of Media Xml to MediaService upon saving.
Removing referenced media test from csproj as cs file was missing.
2013-01-24 09:50:27 -01:00
Stephan 197ab6357f Web.Routing - expose PublishedContentRequest.Template as a string 2013-01-24 08:51:27 -01:00
Morten Christensen e485c471cb Merge 2013-01-24 08:36:08 -01:00
Morten Christensen f00e8b4efc Adding update statement to template repository, so templates can be properly removed. 2013-01-24 08:18:22 -01:00
Shannon Deminick d45ba48b37 Removes unused directives for ExamineEvents. 2013-01-24 06:19:21 +03:00
Shannon Deminick c8807c3798 Fixes: #U4-1530. Backports ContentExtension changes from 6.1 required for Examine and media. Added unit tests to support and enhanced old unit test for ToXml for content
to test for more values to ensure nothing is broken. Updates ExamineEvents to ensure that no event binding occurs until the application is configured and the
database is ready. Updates ExamineEvents to ensure that data is indexed using the new 6.0 APIs, though this is a temporary fix and a better one will be implemented
in 6.1 since UmbracoExamine is in the source.
2013-01-24 06:16:44 +03:00
Stephan b3e3855931 Core.ObjectsResolution - cleanup 2013-01-23 16:44:38 -01:00
Shannon Deminick 82c2560822 Ensures all resolvers are sealed. Changes CacheRefreshersResolver, DataTypesResolver, MacroFieldEditorsResolver, PackageActionsResolver, ActionsResolver
to all be lazy resolvers as they are not needed instantly on app startup (not needed by the front-end) This will
make app startup a lot quicker. Fixes ActionsResolver to not use the PluginManager to resolve the types when it
is instantiating them since these are passed in the ctor. Updates all unit tests to use lazy delegate for these resolvers
and they are all passing.
2013-01-23 18:40:40 +03:00
Stephan f466bc7cfb Web.Routing - cleanup PublishedContentRequest 2013-01-23 14:08:17 -01:00
Stephan b77521cbc5 Web.Routing - cleanup template / rendering engine lookup 2013-01-23 14:08:15 -01:00
Stephan 58b91fe6a0 Web.Routing - reorganize finders for better backward compat. with pre-4.10 2013-01-23 14:08:14 -01:00
Stephan a95fbff597 Core.ObjectsResolution - create temp. dirty access to resolution for legacy code 2013-01-23 14:08:13 -01:00
Stephan 80ee18ee95 Core.ObjectsResolution - add unit tests 2013-01-23 14:07:02 -01:00
Shannon Deminick f467b8cb6c Adds more functionality for LazyManyObjectsResolverBase - adding type list delegates for lazy resolution. 2013-01-23 17:39:07 +03:00
Stephan 6146a0576c Core.ObjectsResolution - add unit tests, fix some bugs 2013-01-23 09:41:01 -01:00
Stephan 73df3ec0de Tests.Routing - get all tests to pass 2013-01-23 09:41:00 -01:00
Stephan d24e4834aa datalayer - bugfix SqlCE dababase clear & initialize 2013-01-23 09:41:00 -01:00
Stephan 38593ea36c Tests.Routing - rename some tests 2013-01-23 09:41:00 -01:00
Shannon Deminick aea1a03453 Updates ManyObjectsResolverBase to properly check for resolution freezing and fixes a few issues found regarding
inheritance in complex situations like the new LazyManyObjectsResolverBase.
Creates the new LazyManyObjectsResolverBase to lazily resolve types in order to create them. This is for
work item : #U4-1522
Adds unit test to support.
2013-01-23 07:45:00 +03:00
Shannon Deminick 1568e5f19c updated comments. 2013-01-23 01:44:01 +03:00
Shannon Deminick 8dff47db78 Merge 2013-01-23 01:39:45 +03:00
Shannon Deminick 987e48733a Merge 2013-01-23 01:39:25 +03:00
Morten Christensen a95c129116 Refactoring a few methods in the ContentService, so the omitCacheRefresh parameter isn't exposed in the new api, as its only relevant to the old api.
Correcting the calls from Document to the internal methods in the ContentService, which ensures that the cache isn't refreshed as its handled elsewhere.
Correcting broken unit test after having changed the GetDescendents method.
2013-01-22 11:23:33 -01:00
Morten Christensen 72ff03f142 Fixes U4-1512 by using the same safe alias method as in the legacy code base.
This should ensure that published content aliases has the same format as in v4.
2013-01-22 08:44:06 -01:00
Sebastiaan Janssen f4574b6014 Merge 2013-01-21 15:42:08 -01:00
Morten Christensen 2dde71abb3 Moving the sql ce binaries from the UmbracoCms.Core to UmbracoCms package as Lee K. has a point.
The Sql Ce binaries located in the Content/bin folder are only relevant when setting up a site.
2013-01-21 15:35:39 -01:00
Morten Christensen e55593fc34 Merge 2013-01-21 15:27:42 -01:00
Sebastiaan Janssen 1c6346233e Added tag Release-6.0.0-RC for changeset 56015ac26f5a 2013-01-21 15:27:38 -01:00
Morten Christensen 00e316b5bd Minor update to AssemblyInfo 2013-01-21 15:27:22 -01:00
Stephan 1b232f3214 Web.Routing - remove some unused legacy code 2013-01-18 16:08:01 -01:00
Stephan aa1ded5f1a Web.Routing - backward compatibility with legacy NotFoundHandler 2013-01-18 14:03:11 -01:00
Stephan e5a20f0c1b Web.Routing - rename things 2013-01-18 13:20:08 -01:00
Stephan 9d701cabf6 Web.Routing - sanitize PublishedContentRequest & pipeline 2013-01-18 13:13:06 -01:00
Stephan c6c522da04 Web.Routing - begin sanitizing PublishedContentRequest 2013-01-16 15:01:43 -01:00
Stephan 2251f39fcf Web.Routing - naming & cleanup, prepare for going public 2013-01-16 14:45:04 -01:00
Stephan 01b4e8d59c Core.ObjectsResolution - refactor, cleanup, sanitize, ensure we properly freeze 2013-01-16 13:31:04 -01:00
Stephan bfd8e96f71 Core.ObjectsResolution - cleanup + start making things public 2013-01-16 13:10:34 -01:00
Stephan e7b84b1637 Merge with 6.0.1 2013-01-29 06:46:07 -01:00
Stephan b8ac74a05d fix merges 2013-01-28 09:02:28 -01:00
Stephan 38624b1e59 fix build 2013-01-27 18:34:16 -01:00
Stephan a699d9e1de merge from 6.0.1 2013-01-27 16:02:59 -01:00
Shannon Deminick cda7a66ec8 updated 6.1 with the correct ExamineEvents class ... issue after up-merging from 6.0 2013-01-25 06:32:00 +03:00
Shannon Deminick 36a5313336 Merge with 6.0.0 2013-01-25 06:19:14 +03:00
Shannon Deminick fedcdcfcd5 Manually re-merged latest changes to ContentExtensions from 6.0 branch to include changes to check for
UseLegacyXmlSchema
2013-01-23 19:00:28 +03:00
Shannon Deminick 11964401c8 Merge 2013-01-23 18:54:42 +03:00
Shannon Deminick 48202cfa09 Merge with 6.0.0 2013-01-23 18:50:44 +03:00
Stephan 8cac3e9c5c merge with 6.0.0 2013-01-23 09:37:40 -01:00
Stephan 25c481b3ca merge with 6.0.0 2013-01-23 09:33:26 -01:00
pcw@pcw-PC.shout.local ac5142443a Fixed EncryptWithMachineKey to handle values longer than FormsAuthentication.Encrypt max length limit
http://issues.umbraco.org/issue/U4-1455
2013-01-15 20:40:28 +00:00
pcw@pcw-PC.shout.local 44360d83aa Fixed EncryptWithMachineKey to handle values longer than FormsAuthentication.Encrypt max length limit
http://issues.umbraco.org/issue/U4-1455
2013-01-15 20:20:05 +00:00
pcw@pcw-PC.shout.local 021cb817d4 Fixed EncryptWithMachineKey to handle values longer than FormsAuthentication.Encrypt max length limit
http://issues.umbraco.org/issue/U4-1455
2013-01-15 20:17:12 +00:00
pcw@pcw-PC.shout.local f4f91fba78 Fixed EncryptWithMachineKey to handle values longer than FormsAuthentication.Encrypt max length limit
http://issues.umbraco.org/issue/U4-1455
2013-01-15 20:09:29 +00:00
pcw@pcw-PC.shout.local dec5e8ad6c Fixed EncryptWithMachineKey to handle values longer than FormsAuthentication.Encrypt max length limit
http://issues.umbraco.org/issue/U4-1455
2013-01-15 20:07:07 +00:00
Max Rotvel 4321c8d24e Fix part of U4-1355 by making umbracoembed translatable and supply da lang files 2013-01-15 14:33:25 -01:00
Stephan 6cb3fcf9ad U4-1411 - fix post-4.9 regression in NotFoundHandler url 2013-01-08 16:41:31 -01:00
Sebastiaan Janssen e5878554bd Fixes U4-1482 Regression - RTE unable to edit hyperlink on image 2013-01-21 14:21:29 -01:00
Sebastiaan Janssen 44c8c4b5b8 Revert 024896ba7bcf as it's a breaking change 2013-01-18 08:47:38 -01:00
Shannon Deminick 6b254e1a20 Merge with 6.0.0 2013-01-07 16:42:27 +03:00
Shannon Deminick a00ceb24e1 Merge with 6.0.0 2013-01-07 04:46:34 +03:00
Shannon Deminick c587632ea0 Adds UmbracoExamine.PDF.Azure library 2013-01-07 04:45:23 +03:00
Shannon Deminick 8f2c662f27 Adds Examine.Azure and required nuget dependencies. 2013-01-07 03:06:33 +03:00
Shannon Deminick dc06e303fc Updated to new Examine version on MyGet, should fix build errors 2013-01-06 02:46:19 +03:00
Shannon Deminick dbf38fbeb8 Changed BaseWebTest to use same logic as BaseDatabaseFactoryTests since we need the ServiceContext now. Fixed a bunch of failing tests... still have some more to fix though. 2013-01-05 23:36:38 +03:00
Shannon Deminick 97ffed5ee7 Changes the web.config template over to use the correct (non-obsoleted) examine classes. These have been obsolete for quite some time
and no longer exist in the new UmbracoExamine codebase. This is a 'breaking' change however it only requres a config file update when upgrading.
2013-01-05 22:48:45 +03:00
Shannon Deminick 8b49d2d377 Removes all MyGet dependencies for UmbracoExamine (since it is in the core now).
Converts UmbracoContextService and UmbracoMediaService for UmbracoExamine to use the new data api's
to extract latest data. Currently had to hack a bit with a new class called LegacyLibrary because at the moment
we'll have a circular dependency with Umbraco.Web which needs to be fixed. Moves all Examine event management to
Umbraco.Web (again mainly because of circular dependencies, but makes sense to have it there). Fixes the ExamineEvents
to implement IApplicationEventHandler instead of IApplicationStartupHandler to ensure that all resolvers have been
initialized before attempting to initialize examine indexes. Updates Examine ILogService to use the LogHelper.
Adds some new ContentExtensions for IMedia since currently Examine needs xml structures, but have kept it internal.
2013-01-05 22:46:50 +03:00
Shannon Deminick 6513097d38 Added UmbracoExamine.PDF library and unit tests. 2013-01-05 04:43:15 +03:00
Shannon Deminick d1bf2c0ad7 More unit tests ported over for UmbracoExamine 2013-01-05 04:20:25 +03:00
Shannon Deminick 59152cbe80 Started migrating over unit tests for UmbracoExamine 2013-01-05 03:28:47 +03:00
Shannon Deminick 027f76af96 Working on #U4-1356 - Moving UmbracoExamine to core 2013-01-05 03:01:29 +03:00
Shannon Deminick eece4c194a Creating 6.1.0 branch 2013-01-04 05:50:00 +03:00
1246 changed files with 72875 additions and 24412 deletions
+2
View File
@@ -14,6 +14,7 @@ syntax: glob
obj/
[Rr]elease*/
_ReSharper*/
_NCrunch_*/
*.ncrunchsolution
*.ncrunchsolution.user
*.ncrunchproject
@@ -43,6 +44,7 @@ src\Umbraco.Web.UI\[Mm]acro[Ss]cripts\*
src\Umbraco.Web.UI\[Xx]slt\*
src\Umbraco.Web.UI\[Ii]mages\*
src\Umbraco.Web.UI\[Ss]cripts\*
src\Umbraco.Web.UI\Web.*.config.transformed
umbraco\presentation\umbraco\plugins\uComponents\uComponentsInstaller.ascx
umbraco\presentation\packages\uComponents\MultiNodePicker\CustomTreeService.asmx
+7 -1
View File
@@ -22,4 +22,10 @@ f6da531fbb4c251ff61d314e2a7effb13c71e74a Release-4.10.0
73711b806a4044dbf0d7d7c095ddfdda23b09932 Release-4.11.2
77db220b89e166b3c0736ed321ecfd6416cddbcd Release-4.11.2.1
54cde33b809dcb3a1f7e7ae0d5375f6dd0d89c8d Release-4.11.2.2
ff3bb24ea0c915878396a6ae27f1ff164e8ac150 Release-6.0.0-beta
ff3bb24ea0c915878396a6ae27f1ff164e8ac150 Release-6.0.0-beta
56015ac26f5ab60e3c61b1d09075297b660afa07 Release-6.0.0-RC
1719fbd857f28b376639ac2aa0abada0ef2e7560 Release-6.0.0
e02f5aebb87e3f07d27376647756caa9762931d8 Release-4.11.4
14338b0ab1738fbd8987677ecdb9a73d79fc229d release-4.11.6
b247b35d821144849f551e02da8ba719f91d5fb0 Release-6.0.2
aed55cba29009ad3db48880a7cfb66407ce9805f release-6.0.3
+4 -2
View File
@@ -1,6 +1,6 @@
@ECHO OFF
SET release=6.0.0
SET comment=RC
SET release=6.1.0
SET comment=beta
SET version=%release%
IF [%comment%] EQU [] (SET version=%release%) ELSE (SET version=%release%-%comment%)
@@ -16,6 +16,8 @@ echo This file is only here so that the containing folder will be included in th
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\media\dummy.txt
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\scripts\dummy.txt
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\usercontrols\dummy.txt
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\Views\Partials\dummy.txt
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\Views\MacroPartials\dummy.txt
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\xslt\dummy.txt
..\src\.nuget\NuGet.exe pack NuSpecs\UmbracoCms.Core.nuspec -Version %version%
+239 -152
View File
@@ -1,189 +1,276 @@
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!--
<!--
****************************************************
INCLUDES
*****************************************************
-->
<PropertyGroup>
<MSBuildCommunityTasksPath>..\MSBuildCommunityTasks</MSBuildCommunityTasksPath>
<UmbracoMSBuildTasksPath>..\UmbracoMSBuildTasks</UmbracoMSBuildTasksPath>
</PropertyGroup>
<Import Project="..\tools\UmbracoMSBuildTasks\Umbraco.MSBuild.Tasks.Targets" />
<Import Project="..\tools\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />
<PropertyGroup>
<MSBuildCommunityTasksPath>..\MSBuildCommunityTasks</MSBuildCommunityTasksPath>
<UmbracoMSBuildTasksPath>..\UmbracoMSBuildTasks</UmbracoMSBuildTasksPath>
</PropertyGroup>
<!--
<Import Project="..\tools\UmbracoMSBuildTasks\Umbraco.MSBuild.Tasks.Targets" />
<Import Project="..\tools\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />
<UsingTask TaskName="GenerateHash" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<ParameterGroup>
<InputFiles ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
<OutputFile ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
<Using Namespace="System.IO" />
<Using Namespace="System.Linq" />
<Using Namespace="System.Security.Cryptography" />
<Code Type="Fragment" Language="cs">
<![CDATA[
using (var ms = new MemoryStream())
{
foreach (var item in InputFiles)
{
string path = item.ItemSpec;
using (FileStream stream = new FileStream(path, FileMode.Open))
{
using (var cryptoProvider = new SHA1CryptoServiceProvider())
{
var fileHash = cryptoProvider.ComputeHash(stream);
using (TextWriter w = new StreamWriter(OutputFile, false))
{
w.WriteLine(string.Join("", fileHash.Select(b => b.ToString("x2"))));
}
}
}
}
}
]]>
</Code>
</Task>
</UsingTask>
<!--
****************************************************
VARIABLES
*****************************************************
-->
<!-- NB: BUILD_NUMBER is passed in by the build server -->
<PropertyGroup Condition="'$(BUILD_NUMBER)'!=''">
<DECIMAL_BUILD_NUMBER>.$(BUILD_NUMBER)</DECIMAL_BUILD_NUMBER>
</PropertyGroup>
<PropertyGroup Condition="'$(BUILD_RELEASE)'!=''">
<DECIMAL_BUILD_NUMBER>.$(BUILD_RELEASE)</DECIMAL_BUILD_NUMBER>
</PropertyGroup>
<PropertyGroup Condition="'$(BUILD_RELEASE)'!='' AND '$(BUILD_COMMENT)'!=''">
<DECIMAL_BUILD_NUMBER>.$(BUILD_RELEASE)-$(BUILD_COMMENT)</DECIMAL_BUILD_NUMBER>
</PropertyGroup>
<PropertyGroup>
<BuildConfiguration>Release</BuildConfiguration>
<BuildFolder>_BuildOutput\</BuildFolder>
<BuildZipFileName>UmbracoCms$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileName>
<BuildZipFileNameBin>UmbracoCms.AllBinaries$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileNameBin>
<BuildZipFileNameWebPi>UmbracoCms.WebPI$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileNameWebPi>
<IncludeSymbols>False</IncludeSymbols>
<BuildFolderRelativeToProjects>..\..\build\$(BuildFolder)</BuildFolderRelativeToProjects>
<BuildFolderAbsolutePath>$(MSBuildProjectDirectory)\$(BuildFolder)</BuildFolderAbsolutePath>
<SolutionBinFolder>$(BuildFolder)bin\</SolutionBinFolder>
<WebAppFolder>$(BuildFolder)WebApp\</WebAppFolder>
<WebPiFolder>$(BuildFolder)WebPi\</WebPiFolder>
<SolutionBinFolderRelativeToProjects>$(BuildFolderRelativeToProjects)bin\</SolutionBinFolderRelativeToProjects>
<SolutionBinFolderAbsolutePath>$(BuildFolderAbsolutePath)bin\</SolutionBinFolderAbsolutePath>
<WebAppFolderRelativeToProjects>$(BuildFolderRelativeToProjects)WebApp\</WebAppFolderRelativeToProjects>
<WebAppFolderAbsolutePath>$(BuildFolderAbsolutePath)WebApp\</WebAppFolderAbsolutePath>
<WebPiFolderRelativeToProjects>$(BuildFolderRelativeToProjects)WebPi\</WebPiFolderRelativeToProjects>
<WebPiFolderAbsolutePath>$(BuildFolderAbsolutePath)WebPi\</WebPiFolderAbsolutePath>
</PropertyGroup>
<!-- NB: BUILD_NUMBER is passed in by the build server -->
<PropertyGroup Condition="'$(BUILD_NUMBER)'!=''">
<DECIMAL_BUILD_NUMBER>.$(BUILD_NUMBER)</DECIMAL_BUILD_NUMBER>
</PropertyGroup>
<PropertyGroup Condition="'$(BUILD_RELEASE)'!=''">
<DECIMAL_BUILD_NUMBER>.$(BUILD_RELEASE)</DECIMAL_BUILD_NUMBER>
</PropertyGroup>
<PropertyGroup Condition="'$(BUILD_RELEASE)'!='' AND '$(BUILD_COMMENT)'!=''">
<DECIMAL_BUILD_NUMBER>.$(BUILD_RELEASE)-$(BUILD_COMMENT)</DECIMAL_BUILD_NUMBER>
</PropertyGroup>
<ItemGroup>
<SystemFolders Include="$(WebAppFolder)App_Plugins" />
<SystemFolders Include="$(WebAppFolder)App_Code" />
<SystemFolders Include="$(WebAppFolder)App_Data" />
<SystemFolders Include="$(WebAppFolder)media" />
<SystemFolders Include="$(WebAppFolder)masterpages" />
<SystemFolders Include="$(WebAppFolder)scripts" />
<SystemFolders Include="$(WebAppFolder)css" />
<SystemFolders Include="$(WebAppFolder)macroScripts" />
<SystemFolders Include="$(WebAppFolder)xslt" />
<SystemFolders Include="$(WebAppFolder)usercontrols" />
<SystemFolders Include="$(WebAppFolder)Views" />
</ItemGroup>
<PropertyGroup>
<BuildConfiguration>Release</BuildConfiguration>
<BuildFolder>_BuildOutput\</BuildFolder>
<BuildZipFileName>UmbracoCms$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileName>
<BuildZipFileNameBin>UmbracoCms.AllBinaries$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileNameBin>
<BuildZipFileNameWebPi>UmbracoCms.WebPI$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileNameWebPi>
<IncludeSymbols>False</IncludeSymbols>
<BuildFolderRelativeToProjects>..\..\build\$(BuildFolder)</BuildFolderRelativeToProjects>
<BuildFolderAbsolutePath>$(MSBuildProjectDirectory)\$(BuildFolder)</BuildFolderAbsolutePath>
<SolutionBinFolder>$(BuildFolder)bin\</SolutionBinFolder>
<WebAppFolder>$(BuildFolder)WebApp\</WebAppFolder>
<WebPiFolder>$(BuildFolder)WebPi\</WebPiFolder>
<SolutionBinFolderRelativeToProjects>$(BuildFolderRelativeToProjects)bin\</SolutionBinFolderRelativeToProjects>
<SolutionBinFolderAbsolutePath>$(BuildFolderAbsolutePath)bin\</SolutionBinFolderAbsolutePath>
<WebAppFolderRelativeToProjects>$(BuildFolderRelativeToProjects)WebApp\</WebAppFolderRelativeToProjects>
<WebAppFolderAbsolutePath>$(BuildFolderAbsolutePath)WebApp\</WebAppFolderAbsolutePath>
<WebPiFolderRelativeToProjects>$(BuildFolderRelativeToProjects)WebPi\</WebPiFolderRelativeToProjects>
<WebPiFolderAbsolutePath>$(BuildFolderAbsolutePath)WebPi\</WebPiFolderAbsolutePath>
<ExaminePDFPath>$(BuildFolderAbsolutePath)UmbracoExamine.PDF\</ExaminePDFPath>
<ExamineAzurePath>$(BuildFolderAbsolutePath)UmbracoExamine.Azure\</ExamineAzurePath>
<ExaminePDFAzurePath>$(BuildFolderAbsolutePath)UmbracoExamine.PDF.Azure\</ExaminePDFAzurePath>
</PropertyGroup>
<!--
<ItemGroup>
<SystemFolders Include="$(WebAppFolder)App_Plugins" />
<SystemFolders Include="$(WebAppFolder)App_Code" />
<SystemFolders Include="$(WebAppFolder)App_Data" />
<SystemFolders Include="$(WebAppFolder)Media" />
<SystemFolders Include="$(WebAppFolder)Masterpages" />
<SystemFolders Include="$(WebAppFolder)Scripts" />
<SystemFolders Include="$(WebAppFolder)Css" />
<SystemFolders Include="$(WebAppFolder)MacroScripts" />
<SystemFolders Include="$(WebAppFolder)Xslt" />
<SystemFolders Include="$(WebAppFolder)UserControls" />
<SystemFolders Include="$(WebAppFolder)Views" />
</ItemGroup>
<!--
****************************************************
TARGETS
*****************************************************
-->
<Target Name="Build" DependsOnTargets="ZipWebPiApp">
<Message Text="Build finished" />
<Target Name="Build" DependsOnTargets="GenerateWebPiHash">
<Message Text="Build finished" />
</Target>
<Target Name="CleanUp" DependsOnTargets="ZipWebPiApp">
<Message Text="Deleting $(BuildFolder)" Importance="high" />
<RemoveDir Directories="$(BuildFolder)" />
<Message Text="Finished deleting $(BuildFolder)" Importance="high" />
</Target>
<Target Name="ZipWebPiApp" DependsOnTargets="ZipWebApp" >
<!-- Clean folders -->
<RemoveDir Directories="$(WebPiFolder)" />
<MakeDir Directories="$(WebPiFolder)" />
<MakeDir Directories="$(WebPiFolder)umbraco" />
<!-- Copy fresh built umbraco files -->
<Exec Command="xcopy %22$(WebAppFolderAbsolutePath)*%22 %22$(WebPiFolderAbsolutePath)umbraco%22 /S /E /Y /I" />
<!-- Copy Web Pi template files -->
<Target Name="GenerateWebPiHash" DependsOnTargets="ZipWebPiApp">
<ItemGroup>
<WebPiFiles Include="..\src\WebPi\**\*.*" />
<WebPiFile Include="$(BuildZipFileNameWebPi)" />
</ItemGroup>
<Message Text="Calculating hash for $(BuildZipFileNameWebPi)" />
<GenerateHash InputFiles="@(WebPiFile)" OutputFile="webpihash.txt" />
</Target>
<Copy SourceFiles="@(WebPiFiles)"
DestinationFiles="@(WebPiFiles->'$(WebPiFolder)%(RecursiveDir)%(Filename)%(Extension)')" />
<Target Name="CleanUp" DependsOnTargets="ZipWebPiApp">
<Message Text="Deleting $(BuildFolder)" Importance="high" />
<RemoveDir Directories="$(BuildFolder)" />
<Message Text="Finished deleting $(BuildFolder)" Importance="high" />
</Target>
<!-- Zip the files -->
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipFileNameWebPi)%22 %22$(WebPiFolderAbsolutePath)*%22" />
</Target>
<Target Name="ZipWebApp" DependsOnTargets="CreateSystemFolders" >
<Message Text="Starting to zip to $(buildDate)-$(BuildZipFileName)" Importance="high" />
<Target Name="ZipWebPiApp" DependsOnTargets="ZipWebApp" >
<!-- Clean folders -->
<RemoveDir Directories="$(WebPiFolder)" />
<MakeDir Directories="$(WebPiFolder)" />
<MakeDir Directories="$(WebPiFolder)umbraco" />
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipFileNameBin)%22 %22$(SolutionBinFolderAbsolutePath)*%22" />
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipFileName)%22 %22$(WebAppFolderAbsolutePath)*%22" />
<Message Text="Finished zipping to build\$(BuildFolder)\$(buildDate)-$(BuildZipFileName)" Importance="high" />
</Target>
<!-- Copy fresh built umbraco files -->
<Exec Command="xcopy %22$(WebAppFolderAbsolutePath)*%22 %22$(WebPiFolderAbsolutePath)umbraco%22 /S /E /Y /I" />
<Target Name="CreateSystemFolders" DependsOnTargets="CopyLibraries" Inputs="@(SystemFolders)" Outputs="%(Identity).Dummy">
<MakeDir Directories="@(SystemFolders)" />
</Target>
<Target Name="CopyLibraries" DependsOnTargets="OffsetTimestamps" >
<!-- Copy SQL CE -->
<ItemGroup>
<SQLCE4Files
Include="..\src\packages\SqlServerCE.4.0.0.0\**\*.*"
Exclude="..\src\packages\SqlServerCE.4.0.0.0\lib\**\*;..\src\packages\SqlServerCE.4.0.0.0\**\*.nu*"
<!-- Copy Web Pi template files -->
<ItemGroup>
<WebPiFiles Include="..\src\WebPi\**\*.*" />
</ItemGroup>
<Copy SourceFiles="@(WebPiFiles)"
DestinationFiles="@(WebPiFiles->'$(WebPiFolder)%(RecursiveDir)%(Filename)%(Extension)')" />
<!-- Zip the files -->
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipFileNameWebPi)%22 %22$(WebPiFolderAbsolutePath)*%22" />
</Target>
<Target Name="ZipWebApp" DependsOnTargets="CreateSystemFolders" >
<Message Text="Starting to zip to $(buildDate)-$(BuildZipFileName)" Importance="high" />
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipFileNameBin)%22 %22$(SolutionBinFolderAbsolutePath)*%22" />
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipFileName)%22 %22$(WebAppFolderAbsolutePath)*%22" />
<Message Text="Finished zipping to build\$(BuildFolder)\$(buildDate)-$(BuildZipFileName)" Importance="high" />
</Target>
<Target Name="CreateSystemFolders" DependsOnTargets="CopyLibraries" Inputs="@(SystemFolders)" Outputs="%(Identity).Dummy">
<MakeDir Directories="@(SystemFolders)" />
</Target>
<Target Name="CopyLibraries" DependsOnTargets="OffsetTimestamps" >
<!-- Copy SQL CE -->
<ItemGroup>
<SQLCE4Files
Include="..\src\packages\SqlServerCE.4.0.0.0\**\*.*"
Exclude="..\src\packages\SqlServerCE.4.0.0.0\lib\**\*;..\src\packages\SqlServerCE.4.0.0.0\**\*.nu*"
/>
</ItemGroup>
</ItemGroup>
<Copy SourceFiles="@(SQLCE4Files)"
DestinationFiles="@(SQLCE4Files->'$(SolutionBinFolder)%(RecursiveDir)%(Filename)%(Extension)')"
OverwriteReadOnlyFiles="true"
SkipUnchangedFiles="false" />
<Copy SourceFiles="@(SQLCE4Files)"
DestinationFiles="@(SQLCE4Files->'$(SolutionBinFolder)%(RecursiveDir)%(Filename)%(Extension)')"
OverwriteReadOnlyFiles="true"
SkipUnchangedFiles="false" />
<Copy SourceFiles="@(SQLCE4Files)"
DestinationFiles="@(SQLCE4Files->'$(WebAppFolder)bin\%(RecursiveDir)%(Filename)%(Extension)')"
OverwriteReadOnlyFiles="true"
SkipUnchangedFiles="false" />
</Target>
<Copy SourceFiles="@(SQLCE4Files)"
DestinationFiles="@(SQLCE4Files->'$(WebAppFolder)bin\%(RecursiveDir)%(Filename)%(Extension)')"
OverwriteReadOnlyFiles="true"
SkipUnchangedFiles="false" />
<!-- Offset the modified timestamps on all umbraco dlls, as WebResources break if date is in the future, which, due to timezone offsets can happen. -->
<Target Name="OffsetTimestamps" DependsOnTargets="CopyTransformedWebConfig">
<CreateItem Include="$(BuildFolder)**\umbraco.*.dll">
<Output TaskParameter="Include" ItemName="FilesToOffsetTimestamp" />
</CreateItem>
<Message Text="Starting to offset timestamps" Importance="high" />
<Umbraco.MSBuild.Tasks.TimestampOffset Files="@(FilesToOffsetTimestamp)" Offset="-11" />
<Message Text="Finished offsetting timestamps" Importance="high" />
</Target>
<!-- Copy the transformed web.config file to the root -->
<Target Name="CopyTransformedWebConfig" DependsOnTargets="CopyXmlDocumentation">
<ItemGroup>
<WebConfigFile Include="..\src\Umbraco.Web.UI\web.$(BuildConfiguration).Config.transformed" />
</ItemGroup>
<Copy SourceFiles="@(WebConfigFile)"
DestinationFiles="$(WebAppFolder)Web.config"
OverwriteReadOnlyFiles="true"
SkipUnchangedFiles="false" />
</Target>
<!-- Copy the xml documentation to the bin folder -->
<Target Name="CopyXmlDocumentation" DependsOnTargets="CompileProjects">
<ItemGroup>
<XmlDocumentationFiles Include="$(SolutionBinFolder)*.xml" />
</ItemGroup>
<Copy SourceFiles="@(XmlDocumentationFiles)"
DestinationFiles="@(XmlDocumentationFiles->'$(WebAppFolder)bin\%(RecursiveDir)%(Filename)%(Extension)')"
OverwriteReadOnlyFiles="true"
SkipUnchangedFiles="false" />
<Message Text="CopyXmlDocumentation" />
</Target>
<Target Name="CompileProjects" DependsOnTargets="SetVersionNumber">
<Message Text="Compiling web project to build\$(BuildFolder)" Importance="high" />
<!-- For UseWPP_CopyWebApplication=True see http://stackoverflow.com/questions/1983575/copywebapplication-with-web-config-transformations -->
<MSBuild Projects="..\src\Umbraco.Web.UI\Umbraco.Web.UI.csproj" Properties="WarningLevel=0;Configuration=$(BuildConfiguration);UseWPP_CopyWebApplication=True;PipelineDependsOnBuild=False;OutDir=$(SolutionBinFolderAbsolutePath);WebProjectOutputDir=$(WebAppFolderAbsolutePath)" Targets="Clean;Build;" BuildInParallel="False" ToolsVersion="4.0" UnloadProjectsOnCompletion="False">
</MSBuild>
</Target>
<!-- DONE -->
<Message Text="Finished compiling projects" Importance="high" />
</Target>
<!-- Offset the modified timestamps on all umbraco dlls, as WebResources break if date is in the future, which, due to timezone offsets can happen. -->
<Target Name="OffsetTimestamps" DependsOnTargets="CopyTransformedWebConfig">
<CreateItem Include="$(BuildFolder)**\umbraco.*.dll">
<Output TaskParameter="Include" ItemName="FilesToOffsetTimestamp" />
</CreateItem>
<Message Text="Starting to offset timestamps" Importance="high" />
<Umbraco.MSBuild.Tasks.TimestampOffset Files="@(FilesToOffsetTimestamp)" Offset="-11" />
<Message Text="Finished offsetting timestamps" Importance="high" />
</Target>
<Target Name="SetVersionNumber" Condition="'$(BUILD_RELEASE)'!=''">
<!-- Copy the transformed web.config file to the root -->
<Target Name="CopyTransformedWebConfig" DependsOnTargets="CopyXmlDocumentation">
<ItemGroup>
<WebConfigFile Include="..\src\Umbraco.Web.UI\web.$(BuildConfiguration).Config.transformed" />
</ItemGroup>
<Copy SourceFiles="@(WebConfigFile)"
DestinationFiles="$(WebAppFolder)Web.config"
OverwriteReadOnlyFiles="true"
SkipUnchangedFiles="false" />
</Target>
<!-- Copy the xml documentation to the bin folder -->
<Target Name="CopyXmlDocumentation" DependsOnTargets="CompileProjects">
<ItemGroup>
<XmlDocumentationFiles Include="$(SolutionBinFolder)*.xml" />
</ItemGroup>
<Copy SourceFiles="@(XmlDocumentationFiles)"
DestinationFiles="@(XmlDocumentationFiles->'$(WebAppFolder)bin\%(RecursiveDir)%(Filename)%(Extension)')"
OverwriteReadOnlyFiles="true"
SkipUnchangedFiles="false" />
<Message Text="CopyXmlDocumentation" />
</Target>
<Target Name="CompileProjects" DependsOnTargets="CompileExternalExamineProjects">
<Message Text="Compiling web project to build\$(BuildFolder)" Importance="high" />
<!-- For UseWPP_CopyWebApplication=True see http://stackoverflow.com/questions/1983575/copywebapplication-with-web-config-transformations -->
<!-- Build the Umbraco.Web.UI project -->
<MSBuild Projects="..\src\Umbraco.Web.UI\Umbraco.Web.UI.csproj" Properties="WarningLevel=0;Configuration=$(BuildConfiguration);UseWPP_CopyWebApplication=True;PipelineDependsOnBuild=False;OutDir=$(SolutionBinFolderAbsolutePath);WebProjectOutputDir=$(WebAppFolderAbsolutePath)" Targets="Clean;Build;" BuildInParallel="False" ToolsVersion="4.0" UnloadProjectsOnCompletion="False">
</MSBuild>
<!-- DONE -->
<Message Text="Finished compiling projects" Importance="high" />
</Target>
<Target Name="CompileExternalExamineProjects" DependsOnTargets="SetVersionNumber">
<Message Text="Building externally shipped examine projects" Importance="high" />
<!-- First remove old files from the examine builds -->
<ItemGroup>
<FilesToDeleteBeforeBuild Include="$(ExaminePDFPath)*;$(ExamineAzurePath)*"/>
</ItemGroup>
<Delete Files="@(FilesToDeleteBeforeBuild)" />
<!--
Build the UmbracoExamine.PDF.Azure library ... this builds the 3 projects that we want to bundle separately so no need to build each one separately .
We'll just build this one and then manually copy the DLLs to where we want them.
-->
<MSBuild Projects="..\src\UmbracoExamine.PDF.Azure\UmbracoExamine.PDF.Azure.csproj" Properties="WarningLevel=0;Configuration=$(BuildConfiguration);PipelineDependsOnBuild=False;OutDir=$(ExaminePDFAzurePath);" Targets="Clean;Build;" BuildInParallel="False" ToolsVersion="4.0" UnloadProjectsOnCompletion="False">
</MSBuild>
<ItemGroup>
<ExaminePDFFiles Include="$(ExaminePDFAzurePath)**\UmbracoExamine.PDF.dll;$(ExaminePDFAzurePath)**\UmbracoExamine.PDF.pdf;$(ExaminePDFAzurePath)**\UmbracoExamine.PDF.xml;$(ExaminePDFAzurePath)**\itextsharp.dll" />
<ExamineAzureFiles Include="$(ExaminePDFAzurePath)**\UmbracoExamine.Azure.dll;$(ExaminePDFAzurePath)**\UmbracoExamine.Azure.pdb;$(ExaminePDFAzurePath)**\UmbracoExamine.Azure.xml" />
<ExaminePDFAzureFiles Include="$(ExaminePDFAzurePath)**\UmbracoExamine.Azure.PDF.dll;$(ExaminePDFAzurePath)**\UmbracoExamine.Azure.PDF.pdb;$(ExaminePDFAzurePath)**\UmbracoExamine.Azure.PDF.xml" />
</ItemGroup>
<!-- Now copy the built files to their correct deployment folders-->
<Copy SourceFiles="@(ExaminePDFFiles)"
DestinationFolder="$(ExaminePDFPath)"
OverwriteReadOnlyFiles="true"
SkipUnchangedFiles="false" />
<Copy SourceFiles="@(ExamineAzureFiles)"
DestinationFolder="$(ExamineAzurePath)"
OverwriteReadOnlyFiles="true"
SkipUnchangedFiles="false" />
<!-- Then just delete the files we don't want to ship in the UmbracoExamine.Azure.PDF folder -->
<ItemGroup>
<FilesToDeleteAfterBuild Include="$(ExaminePDFAzurePath)*" Exclude="$(ExaminePDFAzurePath)UmbracoExamine.PDF.Azure.dll;$(ExaminePDFAzurePath)UmbracoExamine.PDF.Azure.pdb;$(ExaminePDFAzurePath)UmbracoExamine.PDF.Azure.xml"/>
</ItemGroup>
<Delete Files="@(FilesToDeleteAfterBuild)" />
</Target>
<Target Name="SetVersionNumber" Condition="'$(BUILD_RELEASE)'!=''">
<!-- Match & replace 3 and 4 digit version numbers and -beta (if it's there) -->
<FileUpdate
<FileUpdate
Files="..\src\Umbraco.Core\Configuration\UmbracoVersion.cs"
Regex="(\d+)\.(\d+)\.(\d+)(.(\d+))?"
ReplacementText="$(BUILD_RELEASE)"/>
@@ -191,5 +278,5 @@
<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;"/>
</Target>
</Target>
</Project>
+1 -3
View File
@@ -16,7 +16,7 @@
<tags>umbraco</tags>
<dependencies>
<dependency id="Microsoft.AspNet.Mvc" version="[4.0.20710.0]" />
<dependency id="ServiceStack.Text" version="3.9.21" />
<dependency id="Microsoft.AspNet.WebApi" version="4.0.20710.0" />
<dependency id="Microsoft.AspNet.Mvc.FixedDisplayModes" version="1.0.0" />
</dependencies>
</metadata>
@@ -68,7 +68,5 @@
<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="..\_BuildOutput\WebApp\bin\amd64\**" target="Content\bin\amd64" />
<file src="..\_BuildOutput\WebApp\bin\x86\**" target="Content\bin\x86" />
</files>
</package>
+4 -2
View File
@@ -15,11 +15,13 @@
<language>en-US</language>
<tags>umbraco</tags>
<dependencies>
<dependency id="UmbracoCms.Core" version="$version$" />
<dependency id="UmbracoCms.Core" version="[$version$]" />
</dependencies>
</metadata>
<files>
<file src="..\_BuildOutput\WebApp\config\*.config" target="Content\config" />
<file src="..\_BuildOutput\WebApp\bin\amd64\**" target="Content\bin\amd64" />
<file src="..\_BuildOutput\WebApp\bin\x86\**" target="Content\bin\x86" />
<file src="..\_BuildOutput\WebApp\config\*.config" target="Content\config" />
<file src="..\_BuildOutput\WebApp\css\**" target="Content\css" />
<file src="..\_BuildOutput\WebApp\macroScripts\**" target="Content\macroScripts" />
<file src="..\_BuildOutput\WebApp\masterpages\**" target="Content\masterpages" />
+3
View File
@@ -21,4 +21,7 @@ if ($project) {
$projectDestinationPath = Split-Path $project.FullName -Parent
$umbracoFilesPath = Join-Path $rootPath "UmbracoFiles\*"
Copy-Item $umbracoFilesPath $projectDestinationPath -recurse -force
# Open readme.txt file
$DTE.ItemOperations.OpenFile($toolsPath + '\Readme.txt')
}
+41 -11
View File
@@ -21,29 +21,44 @@ echo ^<?xml version="1.0" encoding="utf-8"?^>^<packages^>^</packages^> >..\src\U
echo Removing plugin cache files
del ..\src\Umbraco.Web.UI\App_Data\TEMP\PluginCache\*.*
echo Removing cache files and examine index
del ..\src\Umbraco.Web.UI\App_Data\TEMP\*.*
echo Removing log files
del ..\src\Umbraco.Web.UI\App_Data\Logs\*.*
echo Removing packages
del ..\src\Umbraco.Web.UI\App_Data\packages\*.*
echo Removing previews
del ..\src\Umbraco.Web.UI\App_Data\preview\*.*
echo Removing app code files (typically added by starterkits)
del ..\src\Umbraco.Web.UI\App_Code\*.*
echo Removing xslt files
del ..\src\Umbraco.Web.UI\Xslt\*.*
del ..\src\Umbraco.Web.UI\xslt\*.*
echo Removing user control files
del ..\src\Umbraco.Web.UI\UserControls\*.*
echo Removing masterpage files
del ..\src\Umbraco.Web.UI\masterpages\*.*
echo Removing view files
del ..\src\Umbraco.Web.UI\Views\*.*
echo Removing razor files
del ..\src\Umbraco.Web.UI\MacroScripts\*.*
del ..\src\Umbraco.Web.UI\macroScripts\*.*
echo Removing media files
del ..\src\Umbraco.Web.UI\Media\*.*
del ..\src\Umbraco.Web.UI\media\*.*
echo Removing script files
del ..\src\Umbraco.Web.UI\Scripts\*.*
del ..\src\Umbraco.Web.UI\scripts\*.*
echo Removing css files
del ..\src\Umbraco.Web.UI\Css\*.*
del ..\src\Umbraco.Web.UI\css\*.*
echo "Umbraco install reverted to clean install"
pause
@@ -64,29 +79,44 @@ echo ^<?xml version="1.0" encoding="utf-8"?^>^<packages^>^</packages^> >..\src\U
echo Removing plugin cache files
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\TEMP\PluginCache\*.*) DO DEL %%A
echo Removing cache files and examine index
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\TEMP\*.*) DO DEL %%A
echo Removing log files
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\Logs\*.*) DO DEL %%A
echo Removing packages
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\packages\*.*) DO DEL %%A
echo Removing previews
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\preview\*.*) DO DEL %%A
echo Removing app code files (typically added by starterkits)
FOR %%A IN (..\src\Umbraco.Web.UI\App_Code\*.*) DO DEL %%A
echo Removing xslt files
FOR %%A IN (..\src\Umbraco.Web.UI\Xslt\*.*) DO DEL %%A
FOR %%A IN (..\src\Umbraco.Web.UI\xslt\*.*) DO DEL %%A
echo Removing masterpage files
FOR %%A IN (..\src\Umbraco.Web.UI\masterpages\*.*) DO DEL %%A
echo Removing user control files
FOR %%A IN (..\src\Umbraco.Web.UI\UserControls\*.*) DO DEL %%A
FOR %%A IN (..\src\Umbraco.Web.UI\usercontrols\*.*) DO DEL %%A
echo Removing view files
FOR %%A IN (..\src\Umbraco.Web.UI\Views\*.*) DO DEL %%A
echo Removing razor files
FOR %%A IN (..\src\Umbraco.Web.UI\MacroScripts\*.*) DO DEL %%A
FOR %%A IN (..\src\Umbraco.Web.UI\macroScripts\*.*) DO DEL %%A
echo Removing media files
FOR %%A IN (..\src\Umbraco.Web.UI\Media\*.*) DO DEL %%A
FOR %%A IN (..\src\Umbraco.Web.UI\media\*.*) DO DEL %%A
echo Removing script files
FOR %%A IN (..\src\Umbraco.Web.UI\Scripts\*.*) DO DEL %%A
FOR %%A IN (..\src\Umbraco.Web.UI\scripts\*.*) DO DEL %%A
echo Removing css files
FOR %%A IN (..\src\Umbraco.Web.UI\Css\*.*) DO DEL %%A
FOR %%A IN (..\src\Umbraco.Web.UI\css\*.*) DO DEL %%A
echo "Umbraco install reverted to clean install"
pause
+75 -18
View File
@@ -50,35 +50,90 @@ namespace SqlCE4Umbraco
/// </summary>
internal void ClearDatabase()
{
// drop constraints before tables to avoid exceptions
// looping on try/catching exceptions was not really nice
// http://stackoverflow.com/questions/536350/drop-all-the-tables-stored-procedures-triggers-constriants-and-all-the-depend
var localConnection = new SqlCeConnection(ConnectionString);
if (System.IO.File.Exists(ReplaceDataDirectory(localConnection.Database)))
{
var tables = new List<string>();
using (var reader = ExecuteReader("select table_name from information_schema.tables where TABLE_TYPE <> 'VIEW'"))
List<string> tables;
// drop foreign keys
// SQL may need "where constraint_catalog=DB_NAME() and ..."
tables = new List<string>();
using (var reader = ExecuteReader("select table_name from information_schema.table_constraints where constraint_type = 'FOREIGN KEY' order by table_name"))
{
while (reader.Read())
while (reader.Read()) tables.Add(reader.GetString("table_name").Trim());
}
foreach (var table in tables)
{
var constraints = new List<string>();
using (var reader = ExecuteReader("select constraint_name from information_schema.table_constraints where constraint_type = 'FOREIGN KEY' and table_name = '" + table + "' order by constraint_name"))
{
tables.Add(reader.GetString("TABLE_NAME"));
while (reader.Read()) constraints.Add(reader.GetString("constraint_name").Trim());
}
foreach (var constraint in constraints)
{
// SQL may need "[dbo].[table]"
ExecuteNonQuery("alter table [" + table + "] drop constraint [" + constraint + "]");
}
}
while(tables.Any())
// drop primary keys
// SQL may need "where constraint_catalog=DB_NAME() and ..."
tables = new List<string>();
using (var reader = ExecuteReader("select table_name from information_schema.table_constraints where constraint_type = 'PRIMARY KEY' order by table_name"))
{
for (var i = 0; i < tables.Count; i++)
{
var dropTable = "DROP TABLE " + tables[i];
while (reader.Read()) tables.Add(reader.GetString("table_name").Trim());
}
try
{
ExecuteNonQuery(dropTable);
tables.Remove(tables[i]);
}
catch (SqlHelperException ex)
{
//this will occur because there is no cascade option, so we just wanna try the next one
}
foreach (var table in tables)
{
var constraints = new List<string>();
using (var reader = ExecuteReader("select constraint_name from information_schema.table_constraints where constraint_type = 'PRIMARY KEY' and table_name = '" + table + "' order by constraint_name"))
{
while (reader.Read()) constraints.Add(reader.GetString("constraint_name").Trim());
}
foreach (var constraint in constraints)
{
// SQL may need "[dbo].[table]"
ExecuteNonQuery("alter table [" + table + "] drop constraint [" + constraint + "]");
}
}
// drop tables
tables = new List<string>();
using (var reader = ExecuteReader("select table_name from information_schema.tables where table_type <> 'VIEW' order by table_name"))
{
while (reader.Read()) tables.Add(reader.GetString("table_name").Trim());
}
foreach (var table in tables)
{
ExecuteNonQuery("drop table [" + table + "]");
}
}
}
/// <summary>
/// Drops all foreign keys on a table.
/// </summary>
/// <param name="table">The name of the table.</param>
/// <remarks>To be used in unit tests.</remarks>
internal void DropForeignKeys(string table)
{
var constraints = new List<string>();
using (var reader = ExecuteReader("select constraint_name from information_schema.table_constraints where constraint_type = 'FOREIGN KEY' and table_name = '" + table + "' order by constraint_name"))
{
while (reader.Read()) constraints.Add(reader.GetString("constraint_name").Trim());
}
foreach (var constraint in constraints)
{
// SQL may need "[dbo].[table]"
ExecuteNonQuery("alter table [" + table + "] drop constraint [" + constraint + "]");
}
}
@@ -94,7 +149,9 @@ namespace SqlCE4Umbraco
var dataDirectory = AppDomain.CurrentDomain.GetData("DataDirectory") as string;
if (!string.IsNullOrEmpty(dataDirectory))
{
path = path.Replace("|DataDirectory|", dataDirectory + System.IO.Path.DirectorySeparatorChar);
path = path.Contains(@"|\")
? path.Replace("|DataDirectory|", dataDirectory)
: path.Replace("|DataDirectory|", dataDirectory + System.IO.Path.DirectorySeparatorChar);
}
}
+4 -4
View File
@@ -9,14 +9,14 @@ namespace Umbraco.Core
/// <summary>
/// A resolver to return all IAction objects
/// </summary>
internal sealed class ActionsResolver : ManyObjectsResolverBase<ActionsResolver, IAction>
internal sealed class ActionsResolver : LazyManyObjectsResolverBase<ActionsResolver, IAction>
{
/// <summary>
/// Constructor
/// </summary>
/// <param name="packageActions"></param>
internal ActionsResolver(IEnumerable<Type> packageActions)
internal ActionsResolver(Func<IEnumerable<Type>> packageActions)
: base(packageActions)
{
@@ -34,9 +34,9 @@ namespace Umbraco.Core
}
protected override IEnumerable<IAction> CreateInstances()
{
{
var actions = new List<IAction>();
var foundIActions = PluginManager.Current.ResolveActions();
var foundIActions = InstanceTypes;
foreach (var type in foundIActions)
{
IAction typeInstance;
+85 -13
View File
@@ -1,9 +1,12 @@
using System;
using System.Configuration;
using System.Threading;
using System.Web;
using System.Web.Caching;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.ObjectResolution;
using Umbraco.Core.Services;
@@ -15,33 +18,53 @@ namespace Umbraco.Core
/// <remarks>
/// one per AppDomain, represents the global Umbraco application
/// </remarks>
public class ApplicationContext
public class ApplicationContext : IDisposable
{
/// <summary>
/// Constructor
/// </summary>
internal ApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext)
:this()
: this(dbContext, serviceContext, true)
{
if (dbContext == null) throw new ArgumentNullException("dbContext");
if (serviceContext == null) throw new ArgumentNullException("serviceContext");
_databaseContext = dbContext;
_services = serviceContext;
}
/// <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)
{
if (dbContext == null) throw new ArgumentNullException("dbContext");
if (serviceContext == null) throw new ArgumentNullException("serviceContext");
_databaseContext = dbContext;
_services = serviceContext;
}
/// <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()
{
//create a new application cache from the HttpRuntime.Cache
ApplicationCache = HttpRuntime.Cache == null
? new CacheHelper(new Cache())
: new CacheHelper(HttpRuntime.Cache);
internal ApplicationContext() : this(true)
{
}
/// <summary>
/// Constructor used to specify if we will enable application cache or not
/// </summary>
/// <param name="enableCache"></param>
internal ApplicationContext(bool enableCache)
{
//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);
}
/// <summary>
/// Singleton accessor
/// </summary>
@@ -186,5 +209,54 @@ namespace Umbraco.Core
}
internal set { _services = value; }
}
private volatile bool _disposed;
private readonly ReaderWriterLockSlim _disposalLocker = new ReaderWriterLockSlim();
/// <summary>
/// This will dispose and reset all resources used to run the application
/// </summary>
/// <remarks>
/// IMPORTANT: Never dispose this object if you require the Umbraco application to run, disposing this object
/// is generally used for unit testing and when your application is shutting down after you have booted Umbraco.
/// </remarks>
void IDisposable.Dispose()
{
// Only operate if we haven't already disposed
if (_disposed) return;
using (new WriteLock(_disposalLocker))
{
// Check again now we're inside the lock
if (_disposed) return;
//clear the cache
if (ApplicationCache != null)
{
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.Database != null)
{
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;
}
}
}
}
+119
View File
@@ -0,0 +1,119 @@
namespace Umbraco.Core
{
/// <summary>
/// A plugin type that allows developers to execute code during the Umbraco bootup process
/// </summary>
/// <remarks>
/// Allows you to override the methods that you would like to execute code for: ApplicationInitialized, ApplicationStarting, ApplicationStarted.
///
/// By default none of these methods will execute if the Umbraco application is not configured or if the Umbraco database is not configured, however
/// if you need these methods to execute even if either of these are not configured you can override the properties:
/// ExecuteWhenApplicationNotConfigured and ExecuteWhenDatabaseNotConfigured
/// </remarks>
public abstract class ApplicationEventHandler : IApplicationEventHandler
{
public void OnApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
if (ShouldExecute(applicationContext))
{
ApplicationInitialized(umbracoApplication, applicationContext);
}
}
public void OnApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
if (ShouldExecute(applicationContext))
{
ApplicationStarting(umbracoApplication, applicationContext);
}
}
public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
if (ShouldExecute(applicationContext))
{
ApplicationStarted(umbracoApplication, applicationContext);
}
}
/// <summary>
/// Overridable method to execute when the ApplicationContext is created and other static objects that require initialization have been setup
/// </summary>
/// <param name="umbracoApplication"></param>
/// <param name="applicationContext"></param>
protected virtual void ApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
}
/// <summary>
/// OVerridable method to execute when All resolvers have been initialized but resolution is not frozen so they can be modified in this method
/// </summary>
/// <param name="umbracoApplication"></param>
/// <param name="applicationContext"></param>
protected virtual void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
}
/// <summary>
/// Overridable method to execute when Bootup is completed, this allows you to perform any other bootup logic required for the application.
/// Resolution is frozen so now they can be used to resolve instances.
/// </summary>
/// <param name="umbracoApplication"></param>
/// <param name="applicationContext"></param>
protected virtual void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
}
/// <summary>
/// Determine if the methods should execute based on the configuration status of the application.
/// </summary>
/// <param name="applicationContext"></param>
/// <returns></returns>
private bool ShouldExecute(ApplicationContext applicationContext)
{
if (applicationContext.IsConfigured && applicationContext.DatabaseContext.IsDatabaseConfigured)
{
return true;
}
if (!applicationContext.IsConfigured && ExecuteWhenApplicationNotConfigured)
{
return true;
}
if (!applicationContext.DatabaseContext.IsDatabaseConfigured && ExecuteWhenDatabaseNotConfigured)
{
return true;
}
return false;
}
/// <summary>
/// A flag to determine if the overridable methods for this class will execute even if the
/// Umbraco application is not configured
/// </summary>
/// <remarks>
/// An Umbraco Application is not configured when it requires a new install or upgrade. When the latest version in the
/// assembly does not match the version in the config.
/// </remarks>
protected virtual bool ExecuteWhenApplicationNotConfigured
{
get { return false; }
}
/// <summary>
/// A flag to determine if the overridable methods for this class will execute even if the
/// Umbraco database is not configured
/// </summary>
/// <remarks>
/// The Umbraco database is not configured when we cannot connect to the database or when the database tables are not installed.
/// </remarks>
protected virtual bool ExecuteWhenDatabaseNotConfigured
{
get { return false; }
}
}
}
+51
View File
@@ -0,0 +1,51 @@
namespace Umbraco.Core.Cache
{
/// <summary>
/// Constants storing cache keys used in caching
/// </summary>
public static class CacheKeys
{
public const string ApplicationTreeCacheKey = "ApplicationTreeCache";
public const string ApplicationsCacheKey = "ApplicationCache";
public const string UserTypeCacheKey = "UserTypeCache";
public const string ContentItemCacheKey = "contentItem";
public const string MediaCacheKey = "UL_GetMedia";
public const string MacroXsltCacheKey = "macroXslt_";
public const string MacroCacheKey = "UmbracoMacroCache";
public const string MacroHtmlCacheKey = "macroHtml_";
public const string MacroControlCacheKey = "macroControl_";
public const string MacroHtmlDateAddedCacheKey = "macroHtml_DateAdded_";
public const string MacroControlDateAddedCacheKey = "macroControl_DateAdded_";
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";
public const string UserCacheKey = "UmbracoUser";
public const string ContentTypeCacheKey = "UmbracoContentType";
public const string ContentTypePropertiesCacheKey = "ContentType_PropertyTypes_Content:";
public const string PropertyTypeCacheKey = "UmbracoPropertyTypeCache";
public const string LanguageCacheKey = "UmbracoLanguageCache";
public const string DomainCacheKey = "UmbracoDomainList";
public const string StylesheetCacheKey = "UmbracoStylesheet";
public const string StylesheetPropertyCacheKey = "UmbracoStylesheetProperty";
public const string DataTypeCacheKey = "UmbracoDataTypeDefinition";
}
}
@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Web.Caching;
namespace Umbraco.Core.Cache
{
/// <summary>
/// An abstract class for implementing a cache helper
/// </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);
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);
}
}
@@ -0,0 +1,67 @@
using System;
using Umbraco.Core.Events;
using Umbraco.Core.Sync;
using umbraco.interfaces;
namespace Umbraco.Core.Cache
{
/// <summary>
/// A base class for cache refreshers to inherit from that ensures the correct events are raised
/// when cache refreshing occurs.
/// </summary>
/// <typeparam name="TInstanceType">The real cache refresher type, this is used for raising strongly typed events</typeparam>
public abstract class CacheRefresherBase<TInstanceType> : ICacheRefresher
where TInstanceType : ICacheRefresher
{
/// <summary>
/// An event that is raised when cache is updated on an individual server
/// </summary>
/// <remarks>
/// This event will fire on each server configured for an Umbraco project whenever a cache refresher
/// is updated.
/// </remarks>
public static event TypedEventHandler<TInstanceType, CacheRefresherEventArgs> CacheUpdated;
/// <summary>
/// Raises the event
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
protected static void OnCacheUpdated(TInstanceType sender, CacheRefresherEventArgs args)
{
if (CacheUpdated != null)
{
CacheUpdated(sender, args);
}
}
/// <summary>
/// Returns the real instance of the object ('this') for use in strongly typed events
/// </summary>
protected abstract TInstanceType Instance { get; }
public abstract Guid UniqueIdentifier { get; }
public abstract string Name { get; }
public virtual void RefreshAll()
{
OnCacheUpdated(Instance, new CacheRefresherEventArgs(null, MessageType.RefreshAll));
}
public virtual void Refresh(int id)
{
OnCacheUpdated(Instance, new CacheRefresherEventArgs(id, MessageType.RefreshById));
}
public virtual void Remove(int id)
{
OnCacheUpdated(Instance, new CacheRefresherEventArgs(id, MessageType.RemoveById));
}
public virtual void Refresh(Guid id)
{
OnCacheUpdated(Instance, new CacheRefresherEventArgs(id, MessageType.RefreshById));
}
}
}
@@ -0,0 +1,19 @@
using System;
using Umbraco.Core.Sync;
namespace Umbraco.Core.Cache
{
/// <summary>
/// Event args for cache refresher updates
/// </summary>
public class CacheRefresherEventArgs : EventArgs
{
public CacheRefresherEventArgs(object msgObject, MessageType type)
{
MessageType = type;
MessageObject = msgObject;
}
public object MessageObject { get; private set; }
public MessageType MessageType { get; private set; }
}
}
@@ -0,0 +1,356 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web.Caching;
using Umbraco.Core.Logging;
namespace Umbraco.Core.Cache
{
/// <summary>
/// A CacheProvider that wraps the logic of the HttpRuntime.Cache
/// </summary>
internal class HttpRuntimeCacheProvider : CacheProviderBase
{
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()
{
var cacheEnumerator = _cache.GetEnumerator();
while (cacheEnumerator.MoveNext())
{
_cache.Remove(cacheEnumerator.Key.ToString());
}
}
/// <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)
{
// 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); ;
}
}
/// <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)
{
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);
}
}
/// <summary>
/// Clears all objects in the System.Web.Cache with the System.Type specified
/// </summary>
public override void ClearCacheObjectTypes<T>()
{
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);
}
}
/// <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)
{
foreach (DictionaryEntry c in _cache)
{
if (c.Key is string && ((string)c.Key).InvariantStartsWith(keyStartsWith))
{
ClearCacheItem((string)c.Key);
}
}
}
/// <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);
}
}
}
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;
}
/// <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)
{
return GetCacheItem(cacheKey, CacheItemPriority.Normal, null, null, null, getCacheItem, Locker);
}
/// <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">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="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>
/// <returns></returns>
public override TT GetCacheItem<TT>(string cacheKey,
CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan? timeout,
Func<TT> getCacheItem)
{
return GetCacheItem(cacheKey, priority, refreshAction, 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="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);
}
/// <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)
{
lock (syncLock)
{
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);
}
}
}
}
return result.TryConvertTo<TT>().Result;
}
/// <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)
{
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)
{
//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);
}
}
}
}
+18
View File
@@ -0,0 +1,18 @@
using umbraco.interfaces;
namespace Umbraco.Core.Cache
{
/// <summary>
/// Strongly type cache refresher that is able to refresh cache of real instances of objects as well as IDs
/// </summary>
/// <typeparam name="T"></typeparam>
/// <remarks>
/// This is much better for performance when we're not running in a load balanced environment so we can refresh the cache
/// against a already resolved object instead of looking the object back up by id.
/// </remarks>
interface ICacheRefresher<T> : ICacheRefresher
{
void Refresh(T instance);
void Remove(T instance);
}
}
@@ -0,0 +1,16 @@
using umbraco.interfaces;
namespace Umbraco.Core.Cache
{
/// <summary>
/// A cache refresher that supports refreshing or removing cache based on a custom Json payload
/// </summary>
interface IJsonCacheRefresher : ICacheRefresher
{
/// <summary>
/// Refreshes, clears, etc... any cache based on the information provided in the json
/// </summary>
/// <param name="jsonPayload"></param>
void Refresh(string jsonPayload);
}
}
@@ -0,0 +1,20 @@
using Umbraco.Core.Sync;
using umbraco.interfaces;
namespace Umbraco.Core.Cache
{
/// <summary>
/// A base class for json cache refreshers that ensures the correct events are raised when
/// cache refreshing occurs.
/// </summary>
/// <typeparam name="TInstanceType">The real cache refresher type, this is used for raising strongly typed events</typeparam>
public abstract class JsonCacheRefresherBase<TInstanceType> : CacheRefresherBase<TInstanceType>, IJsonCacheRefresher
where TInstanceType : ICacheRefresher
{
public virtual void Refresh(string jsonPayload)
{
OnCacheUpdated(Instance, new CacheRefresherEventArgs(jsonPayload, MessageType.RefreshByJson));
}
}
}
@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Caching;
namespace Umbraco.Core.Cache
{
internal class NullCacheProvider : CacheProviderBase
{
public override void ClearAllCache()
{
}
public override void ClearCacheItem(string key)
{
}
public override void ClearCacheObjectTypes(string typeName)
{
}
public override void ClearCacheObjectTypes<T>()
{
}
public override void ClearCacheByKeySearch(string keyStartsWith)
{
}
public override void ClearCacheByKeyExpression(string regexString)
{
}
public override IEnumerable<T> GetCacheItemsByKeySearch<T>(string keyStartsWith)
{
return Enumerable.Empty<T>();
}
public override T GetCacheItem<T>(string cacheKey)
{
return default(T);
}
public override T GetCacheItem<T>(string cacheKey, Func<T> getCacheItem)
{
return getCacheItem();
}
public override T GetCacheItem<T>(string cacheKey, TimeSpan? timeout, Func<T> getCacheItem)
{
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)
{
}
}
}
@@ -0,0 +1,25 @@
using Umbraco.Core.Sync;
using umbraco.interfaces;
namespace Umbraco.Core.Cache
{
/// <summary>
/// A base class for cache refreshers to inherit from that ensures the correct events are raised
/// when cache refreshing occurs.
/// </summary>
/// <typeparam name="TInstanceType">The real cache refresher type, this is used for raising strongly typed events</typeparam>
/// <typeparam name="TEntityType">The entity type that this refresher can update cache for</typeparam>
public abstract class TypedCacheRefresherBase<TInstanceType, TEntityType> : CacheRefresherBase<TInstanceType>, ICacheRefresher<TEntityType>
where TInstanceType : ICacheRefresher
{
public virtual void Refresh(TEntityType instance)
{
OnCacheUpdated(Instance, new CacheRefresherEventArgs(instance, MessageType.RefreshByInstance));
}
public virtual void Remove(TEntityType instance)
{
OnCacheUpdated(Instance, new CacheRefresherEventArgs(instance, MessageType.RemoveByInstance));
}
}
}
+311 -77
View File
@@ -3,8 +3,10 @@ using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Caching;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
namespace Umbraco.Core
@@ -16,29 +18,33 @@ namespace Umbraco.Core
/// <remarks>
/// This class may be opened publicly at some point but needs a review of what is absoletely necessary.
/// </remarks>
public class CacheHelper
public class CacheHelper //: CacheProviderBase
{
private readonly Cache _cache;
private readonly bool _enableCache;
private readonly HttpRuntimeCacheProvider _httpCache;
private readonly NullCacheProvider _nullCache = new NullCacheProvider();
public CacheHelper(System.Web.Caching.Cache cache)
: this(cache, true)
{
_cache = cache;
}
private static readonly object Locker = new object();
/// <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>
internal CacheHelper(System.Web.Caching.Cache cache, bool enableCache)
{
_httpCache = new HttpRuntimeCacheProvider(cache);
_enableCache = enableCache;
}
public void ClearAllCache()
{
var cacheEnumerator = _cache.GetEnumerator();
while (cacheEnumerator.MoveNext())
{
_cache.Remove(cacheEnumerator.Key.ToString());
}
if (!_enableCache)
{
_nullCache.ClearAllCache();
}
else
{
_httpCache.ClearAllCache();
}
}
/// <summary>
@@ -47,12 +53,13 @@ namespace Umbraco.Core
/// <param name="key">Key</param>
public void ClearCacheItem(string key)
{
// NH 10 jan 2012
// Patch by the always wonderful Stéphane Gay to avoid cache null refs
lock (Locker)
if (!_enableCache)
{
if (_cache[key] == null) return;
_cache.Remove(key);;
_nullCache.ClearCacheItem(key);
}
else
{
_httpCache.ClearCacheItem(key);
}
}
@@ -64,54 +71,191 @@ namespace Umbraco.Core
/// <param name="typeName">The name of the System.Type which should be cleared from cache ex "System.Xml.XmlDocument"</param>
public void ClearCacheObjectTypes(string typeName)
{
try
if (!_enableCache)
{
lock (Locker)
{
foreach (var c in from DictionaryEntry c in _cache where _cache[c.Key.ToString()] != null && _cache[c.Key.ToString()].GetType().ToString() == typeName select c)
{
_cache.Remove(c.Key.ToString());
}
}
_nullCache.ClearCacheObjectTypes(typeName);
}
catch (Exception e)
else
{
LogHelper.Error<CacheHelper>("Cache clearing error", e);
_httpCache.ClearCacheObjectTypes(typeName);
}
}
/// <summary>
/// Clears all objects in the System.Web.Cache with the System.Type specified
/// </summary>
public void ClearCacheObjectTypes<T>()
{
if (!_enableCache)
{
_nullCache.ClearCacheObjectTypes<T>();
}
else
{
_httpCache.ClearCacheObjectTypes<T>();
}
}
/// <summary>
/// Clears all cache items that starts with the key passed.
/// </summary>
/// <param name="keyStartsWith">The start of the key</param>
public void ClearCacheByKeySearch(string keyStartsWith)
{
if (!_enableCache)
{
_nullCache.ClearCacheByKeySearch(keyStartsWith);
}
else
{
_httpCache.ClearCacheByKeySearch(keyStartsWith);
}
}
/// <summary>
/// Clears all cache items that have a key that matches the regular expression
/// </summary>
/// <param name="regexString"></param>
public void ClearCacheByKeyExpression(string regexString)
{
if (!_enableCache)
{
_nullCache.ClearCacheByKeyExpression(regexString);
}
else
{
_httpCache.ClearCacheByKeyExpression(regexString);
}
}
public IEnumerable<T> GetCacheItemsByKeySearch<T>(string keyStartsWith)
{
foreach (var c in from DictionaryEntry c in _cache where c.Key is string && ((string)c.Key).StartsWith(keyStartsWith) select c)
{
ClearCacheItem((string)c.Key);
}
if (!_enableCache)
{
return _nullCache.GetCacheItemsByKeySearch<T>(keyStartsWith);
}
else
{
return _httpCache.GetCacheItemsByKeySearch<T>(keyStartsWith);
}
}
/// <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 TT GetCacheItem<TT>(string cacheKey)
{
if (!_enableCache)
{
return _nullCache.GetCacheItem<TT>(cacheKey);
}
else
{
return _httpCache.GetCacheItem<TT>(cacheKey);
}
}
/// <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 TT GetCacheItem<TT>(string cacheKey, Func<TT> getCacheItem)
{
if (!_enableCache)
{
return _nullCache.GetCacheItem<TT>(cacheKey, getCacheItem);
}
else
{
return _httpCache.GetCacheItem<TT>(cacheKey, 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">This will set an absolute expiration from now until the timeout</param>
/// <param name="getCacheItem"></param>
/// <returns></returns>
public TT GetCacheItem<TT>(string cacheKey,
TimeSpan timeout, Func<TT> getCacheItem)
{
return GetCacheItem(cacheKey, null, timeout, getCacheItem);
if (!_enableCache)
{
return _nullCache.GetCacheItem<TT>(cacheKey, timeout, getCacheItem);
}
else
{
return _httpCache.GetCacheItem<TT>(cacheKey, 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 TT GetCacheItem<TT>(string cacheKey,
CacheItemRemovedCallback refreshAction, TimeSpan timeout,
Func<TT> getCacheItem)
{
return GetCacheItem(cacheKey, CacheItemPriority.Normal, refreshAction, timeout, getCacheItem);
if (!_enableCache)
{
return _nullCache.GetCacheItem<TT>(cacheKey, refreshAction, timeout, getCacheItem);
}
else
{
return _httpCache.GetCacheItem<TT>(cacheKey, 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="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>
/// <returns></returns>
public TT GetCacheItem<TT>(string cacheKey,
CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan timeout,
Func<TT> getCacheItem)
{
return GetCacheItem(cacheKey, priority, refreshAction, null, timeout, getCacheItem);
if (!_enableCache)
{
return _nullCache.GetCacheItem<TT>(cacheKey, priority, refreshAction, timeout, getCacheItem);
}
else
{
return _httpCache.GetCacheItem<TT>(cacheKey, priority, 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="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 TT GetCacheItem<TT>(string cacheKey,
CacheItemPriority priority,
CacheItemRemovedCallback refreshAction,
@@ -119,46 +263,136 @@ namespace Umbraco.Core
TimeSpan timeout,
Func<TT> getCacheItem)
{
return GetCacheItem(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem, Locker);
if (!_enableCache)
{
return _nullCache.GetCacheItem<TT>(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem);
}
else
{
return _httpCache.GetCacheItem<TT>(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem);
}
}
/// <summary>
/// This is used only for legacy purposes as I did not want to change all of the locking to one lock found on this object,
/// however, the reason this is used for legacy purposes is because I see zero reason to use different sync locks, just the one
/// lock (Locker) on this class should be sufficient.
/// </summary>
/// <typeparam name="TT"></typeparam>
/// <param name="cacheKey"></param>
/// <param name="priority"></param>
/// <param name="refreshAction"></param>
/// <param name="cacheDependency"></param>
/// <param name="timeout"></param>
/// <param name="getCacheItem"></param>
/// <param name="syncLock"></param>
/// <returns></returns>
internal 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)
{
lock (syncLock)
{
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, DateTime.Now.Add(timeout), TimeSpan.Zero, priority, refreshAction);
}
}
}
}
return (TT)result;
}
}
/// <summary>
/// Gets (and adds if necessary) an item from the cache
/// </summary>
/// <typeparam name="TT"></typeparam>
/// <param name="cacheKey"></param>
/// <param name="priority"></param>
/// <param name="cacheDependency"></param>
/// <param name="getCacheItem"></param>
/// <returns></returns>
public TT GetCacheItem<TT>(string cacheKey,
CacheItemPriority priority,
CacheDependency cacheDependency,
Func<TT> getCacheItem)
{
if (!_enableCache)
{
return _nullCache.GetCacheItem<TT>(cacheKey, priority, null, cacheDependency, null, getCacheItem);
}
else
{
return _httpCache.GetCacheItem<TT>(cacheKey, priority, null, cacheDependency, 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="getCacheItem"></param>
public void InsertCacheItem<T>(string cacheKey,
CacheItemPriority priority,
Func<T> getCacheItem)
{
if (!_enableCache)
{
_nullCache.InsertCacheItem<T>(cacheKey, priority, getCacheItem);
}
else
{
_httpCache.InsertCacheItem<T>(cacheKey, priority, 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 void InsertCacheItem<T>(string cacheKey,
CacheItemPriority priority,
TimeSpan timeout,
Func<T> getCacheItem)
{
if (!_enableCache)
{
_nullCache.InsertCacheItem<T>(cacheKey, priority, timeout, getCacheItem);
}
else
{
_httpCache.InsertCacheItem<T>(cacheKey, priority, 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 void InsertCacheItem<T>(string cacheKey,
CacheItemPriority priority,
CacheDependency cacheDependency,
TimeSpan timeout,
Func<T> getCacheItem)
{
if (!_enableCache)
{
_nullCache.InsertCacheItem<T>(cacheKey, priority, cacheDependency, timeout, getCacheItem);
}
else
{
_httpCache.InsertCacheItem<T>(cacheKey, priority, 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 void InsertCacheItem<T>(string cacheKey,
CacheItemPriority priority,
CacheItemRemovedCallback refreshAction,
CacheDependency cacheDependency,
TimeSpan? timeout,
Func<T> getCacheItem)
{
if (!_enableCache)
{
_nullCache.InsertCacheItem<T>(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem);
}
else
{
_httpCache.InsertCacheItem<T>(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem);
}
}
}
}
+2 -2
View File
@@ -17,7 +17,7 @@ namespace Umbraco.Core
/// Constructor
/// </summary>
/// <param name="refreshers"></param>
internal CacheRefreshersResolver(IEnumerable<Type> refreshers)
internal CacheRefreshersResolver(Func<IEnumerable<Type>> refreshers)
: base(refreshers)
{
@@ -31,7 +31,7 @@ namespace Umbraco.Core
{
get
{
EnsureIdsAreTracked();
EnsureIsInitialized();
return Values;
}
}
@@ -0,0 +1,35 @@
using System;
namespace Umbraco.Core.CodeAnnotations
{
/// <summary>
/// Attribute to add a Friendly Name string with an UmbracoObjectType enum value
/// </summary>
[AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = false)]
internal class FriendlyNameAttribute : Attribute
{
/// <summary>
/// friendly name value
/// </summary>
private readonly string _friendlyName;
/// <summary>
/// Initializes a new instance of the FriendlyNameAttribute class
/// Sets the friendly name value
/// </summary>
/// <param name="friendlyName">attribute value</param>
public FriendlyNameAttribute(string friendlyName)
{
this._friendlyName = friendlyName;
}
/// <summary>
/// Gets the friendly name
/// </summary>
/// <returns>string of friendly name</returns>
public override string ToString()
{
return this._friendlyName;
}
}
}
@@ -0,0 +1,26 @@
using System;
namespace Umbraco.Core.CodeAnnotations
{
/// <summary>
/// Attribute to associate a GUID string and Type with an UmbracoObjectType Enum value
/// </summary>
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
internal class UmbracoObjectTypeAttribute : Attribute
{
public UmbracoObjectTypeAttribute(string objectId)
{
ObjectId = new Guid(objectId);
}
public UmbracoObjectTypeAttribute(string objectId, Type modelType)
{
ObjectId = new Guid(objectId);
ModelType = modelType;
}
public Guid ObjectId { get; private set; }
public Type ModelType { get; private set; }
}
}
+167
View File
@@ -0,0 +1,167 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
namespace Umbraco.Core
{
/// <summary>
/// A thread-safe representation of a <see cref="HashSet{T}"/>.
/// Enumerating this collection is thread-safe and will only operate on a clone that is generated before returning the enumerator.
/// </summary>
/// <typeparam name="T"></typeparam>
[Serializable]
public class ConcurrentHashSet<T> : ICollection<T>
{
private readonly HashSet<T> _innerSet = new HashSet<T>();
private readonly ReaderWriterLockSlim _instanceLocker = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>
/// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
/// </returns>
/// <filterpriority>1</filterpriority>
public IEnumerator<T> GetEnumerator()
{
return GetThreadSafeClone().GetEnumerator();
}
/// <summary>
/// Returns an enumerator that iterates through a collection.
/// </summary>
/// <returns>
/// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection.
/// </returns>
/// <filterpriority>2</filterpriority>
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
/// <summary>
/// Removes the first occurrence of a specific object from the <see cref="T:System.Collections.Generic.ICollection`1"/>.
/// </summary>
/// <returns>
/// true if <paramref name="item"/> was successfully removed from the <see cref="T:System.Collections.Generic.ICollection`1"/>; otherwise, false. This method also returns false if <paramref name="item"/> is not found in the original <see cref="T:System.Collections.Generic.ICollection`1"/>.
/// </returns>
/// <param name="item">The object to remove from the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param><exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.</exception>
public bool Remove(T item)
{
using (new WriteLock(_instanceLocker))
{
return _innerSet.Remove(item);
}
}
/// <summary>
/// Gets the number of elements contained in the <see cref="T:System.Collections.ICollection"/>.
/// </summary>
/// <returns>
/// The number of elements contained in the <see cref="T:System.Collections.ICollection"/>.
/// </returns>
/// <filterpriority>2</filterpriority>
public int Count
{
get { return GetThreadSafeClone().Count; }
}
/// <summary>
/// Gets a value indicating whether the <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.
/// </summary>
/// <returns>
/// true if the <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only; otherwise, false.
/// </returns>
public bool IsReadOnly
{
get { return false; }
}
/// <summary>
/// Adds an item to the <see cref="T:System.Collections.Generic.ICollection`1"/>.
/// </summary>
/// <param name="item">The object to add to the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param><exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.</exception>
public void Add(T item)
{
using (new WriteLock(_instanceLocker))
{
_innerSet.Add(item);
}
}
/// <summary>
/// Attempts to add an item to the collection
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public bool TryAdd(T item)
{
var clone = GetThreadSafeClone();
if (clone.Contains(item)) return false;
using (new WriteLock(_instanceLocker))
{
//double check
if (_innerSet.Contains(item)) return false;
_innerSet.Add(item);
return true;
}
}
/// <summary>
/// Removes all items from the <see cref="T:System.Collections.Generic.ICollection`1"/>.
/// </summary>
/// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only. </exception>
public void Clear()
{
using (new WriteLock(_instanceLocker))
{
_innerSet.Clear();
}
}
/// <summary>
/// Determines whether the <see cref="T:System.Collections.Generic.ICollection`1"/> contains a specific value.
/// </summary>
/// <returns>
/// true if <paramref name="item"/> is found in the <see cref="T:System.Collections.Generic.ICollection`1"/>; otherwise, false.
/// </returns>
/// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param>
public bool Contains(T item)
{
return GetThreadSafeClone().Contains(item);
}
/// <summary>
/// Copies the elements of the <see cref="T:System.Collections.Concurrent.IProducerConsumerCollection`1"/> to an <see cref="T:System.Array"/>, starting at a specified index.
/// </summary>
/// <param name="array">The one-dimensional <see cref="T:System.Array"/> that is the destination of the elements copied from the <see cref="T:System.Collections.Concurrent.IProducerConsumerCollection`1"/>. The array must have zero-based indexing.</param><param name="index">The zero-based index in <paramref name="array"/> at which copying begins.</param><exception cref="T:System.ArgumentNullException"><paramref name="array"/> is a null reference (Nothing in Visual Basic).</exception><exception cref="T:System.ArgumentOutOfRangeException"><paramref name="index"/> is less than zero.</exception><exception cref="T:System.ArgumentException"><paramref name="index"/> is equal to or greater than the length of the <paramref name="array"/> -or- The number of elements in the source <see cref="T:System.Collections.Concurrent.ConcurrentQueue`1"/> is greater than the available space from <paramref name="index"/> to the end of the destination <paramref name="array"/>.</exception>
public void CopyTo(T[] array, int index)
{
var clone = GetThreadSafeClone();
clone.CopyTo(array, index);
}
private HashSet<T> GetThreadSafeClone()
{
HashSet<T> clone = null;
using (new WriteLock(_instanceLocker))
{
clone = new HashSet<T>(_innerSet, _innerSet.Comparer);
}
return clone;
}
/// <summary>
/// Copies the elements of the <see cref="T:System.Collections.ICollection"/> to an <see cref="T:System.Array"/>, starting at a particular <see cref="T:System.Array"/> index.
/// </summary>
/// <param name="array">The one-dimensional <see cref="T:System.Array"/> that is the destination of the elements copied from <see cref="T:System.Collections.ICollection"/>. The <see cref="T:System.Array"/> must have zero-based indexing. </param><param name="index">The zero-based index in <paramref name="array"/> at which copying begins. </param><exception cref="T:System.ArgumentNullException"><paramref name="array"/> is null. </exception><exception cref="T:System.ArgumentOutOfRangeException"><paramref name="index"/> is less than zero. </exception><exception cref="T:System.ArgumentException"><paramref name="array"/> is multidimensional.-or- The number of elements in the source <see cref="T:System.Collections.ICollection"/> is greater than the available space from <paramref name="index"/> to the end of the destination <paramref name="array"/>. </exception><exception cref="T:System.ArgumentException">The type of the source <see cref="T:System.Collections.ICollection"/> cannot be cast automatically to the type of the destination <paramref name="array"/>. </exception><filterpriority>2</filterpriority>
public void CopyTo(Array array, int index)
{
var clone = GetThreadSafeClone();
Array.Copy(clone.ToArray(), 0, array, index, clone.Count);
}
}
}
@@ -0,0 +1,32 @@
using System;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Configuration;
namespace Umbraco.Core.Configuration
{
/// <summary>
/// A case-insensitive configuration converter for enumerations.
/// </summary>
/// <typeparam name="T">The type of the enumeration.</typeparam>
internal class CaseInsensitiveEnumConfigConverter<T> : ConfigurationConverterBase
where T : struct
{
public override object ConvertFrom(ITypeDescriptorContext ctx, CultureInfo ci, object data)
{
if (data == null)
throw new ArgumentNullException("data");
//return Enum.Parse(typeof(T), (string)data, true);
T value;
if (Enum.TryParse((string)data, true, out value))
return value;
throw new Exception(string.Format("\"{0}\" is not valid {1} value. Valid values are: {2}.",
data, typeof(T).Name,
string.Join(", ", Enum.GetValues(typeof(T)).Cast<T>())));
}
}
}
@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Umbraco.Core.Configuration
{
/// <summary>
/// Indicates the configuration key for a section or a group.
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
internal sealed class ConfigurationKeyAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="ConfigurationKeyAttribute"/> class with a configuration key.
/// </summary>
/// <param name="configurationKey">The configurationkey.</param>
public ConfigurationKeyAttribute(string configurationKey)
{
ConfigurationKey = configurationKey;
}
/// <summary>
/// Gets or sets the configuration key.
/// </summary>
public string ConfigurationKey { get; private set; }
}
}
+106 -39
View File
@@ -28,24 +28,58 @@ namespace Umbraco.Core.Configuration
#region Private static fields
private static Version _version;
private static string _reservedUrlsCache;
private static readonly object Locker = new object();
//make this volatile so that we can ensure thread safety with a double check lock
private static volatile string _reservedUrlsCache;
private static string _reservedPathsCache;
private static StartsWithContainer _reservedList = new StartsWithContainer();
private static string _reservedPaths;
private static string _reservedUrls;
//ensure the built on (non-changeable) reserved paths are there at all times
private const string StaticReservedPaths = "~/app_plugins/,~/install/,";
private const string StaticReservedUrls = "~/config/splashes/booting.aspx,~/install/default.aspx,~/config/splashes/noNodes.aspx,~/VSEnterpriseHelper.axd,";
#endregion
/// <summary>
/// Used in unit testing to reset all config items that were set with property setters (i.e. did not come from config)
/// </summary>
private static void ResetInternal()
{
_reservedUrlsCache = null;
_reservedPaths = null;
_reservedUrls = null;
}
/// <summary>
/// Resets settings that were set programmatically, to their initial values.
/// </summary>
/// <remarks>To be used in unit tests.</remarks>
internal static void Reset()
{
ResetInternal();
}
/// <summary>
/// Gets the reserved urls from web.config.
/// </summary>
/// <value>The reserved urls.</value>
public static string ReservedUrls
{
get
{
return ConfigurationManager.AppSettings.ContainsKey("umbracoReservedUrls")
? ConfigurationManager.AppSettings["umbracoReservedUrls"]
: string.Empty;
{
if (_reservedUrls == null)
{
var urls = ConfigurationManager.AppSettings.ContainsKey("umbracoReservedUrls")
? ConfigurationManager.AppSettings["umbracoReservedUrls"]
: string.Empty;
//ensure the built on (non-changeable) reserved paths are there at all times
_reservedUrls = StaticReservedUrls + urls;
}
return _reservedUrls;
}
internal set { _reservedUrls = value; }
}
/// <summary>
@@ -56,10 +90,25 @@ namespace Umbraco.Core.Configuration
{
get
{
return ConfigurationManager.AppSettings.ContainsKey("umbracoReservedPaths")
? ConfigurationManager.AppSettings["umbracoReservedPaths"]
: string.Empty;
if (_reservedPaths == null)
{
var reservedPaths = StaticReservedPaths;
//always add the umbraco path to the list
if (ConfigurationManager.AppSettings.ContainsKey("umbracoPath")
&& !ConfigurationManager.AppSettings["umbracoPath"].IsNullOrWhiteSpace())
{
reservedPaths += ConfigurationManager.AppSettings["umbracoPath"].EnsureEndsWith(',');
}
var allPaths = ConfigurationManager.AppSettings.ContainsKey("umbracoReservedPaths")
? ConfigurationManager.AppSettings["umbracoReservedPaths"]
: string.Empty;
_reservedPaths = reservedPaths + allPaths;
}
return _reservedPaths;
}
internal set { _reservedPaths = value; }
}
/// <summary>
@@ -114,6 +163,9 @@ namespace Umbraco.Core.Configuration
/// This will return the MVC area that we will route all custom routes through like surface controllers, etc...
/// We will use the 'Path' (default ~/umbraco) to create it but since it cannot contain '/' and people may specify a path of ~/asdf/asdf/admin
/// we will convert the '/' to '-' and use that as the path. its a bit lame but will work.
///
/// We also make sure that the virtual directory (SystemDirectories.Root) is stripped off first, otherwise we'd end up with something
/// like "MyVirtualDirectory-Umbraco" instead of just "Umbraco".
/// </remarks>
internal static string UmbracoMvcArea
{
@@ -123,7 +175,7 @@ namespace Umbraco.Core.Configuration
{
throw new InvalidOperationException("Cannot create an MVC Area path without the umbracoPath specified");
}
return Path.TrimStart('~').TrimStart('/').Replace('/', '-').Trim();
return Path.TrimStart(SystemDirectories.Root).TrimStart('~').TrimStart('/').Replace('/', '-').Trim().ToLower();
}
}
@@ -170,7 +222,7 @@ namespace Umbraco.Core.Configuration
{
if (value.ToLower().Contains("SQLCE4Umbraco.SqlCEHelper".ToLower()))
{
ApplicationContext.Current.DatabaseContext.ConfigureDatabaseConnection();
ApplicationContext.Current.DatabaseContext.ConfigureEmbeddedDatabaseConnection();
}
else
{
@@ -201,6 +253,7 @@ namespace Umbraco.Core.Configuration
}
}
/// <summary>
/// Saves a setting into the configuration file.
/// </summary>
@@ -531,6 +584,16 @@ namespace Umbraco.Core.Configuration
return context.Request.Path.ToLower().IndexOf(SystemDirectories.Umbraco.ToLower() + "/liveediting.aspx") > -1;
}
public static bool RequestIsInUmbracoApplication(HttpContextBase context)
{
return context.Request.Path.ToLower().IndexOf(IOHelper.ResolveUrl(SystemDirectories.Umbraco).ToLower()) > -1;
}
public static bool RequestIsLiveEditRedirector(HttpContextBase context)
{
return context.Request.Path.ToLower().IndexOf(SystemDirectories.Umbraco.ToLower() + "/liveediting.aspx") > -1;
}
/// <summary>
/// Gets a value indicating whether umbraco should force a secure (https) connection to the backoffice.
/// </summary>
@@ -622,38 +685,42 @@ namespace Umbraco.Core.Configuration
/// </returns>
public static bool IsReservedPathOrUrl(string url)
{
// check if GlobalSettings.ReservedPaths and GlobalSettings.ReservedUrls are unchanged
if (!object.ReferenceEquals(_reservedPathsCache, GlobalSettings.ReservedPaths)
|| !object.ReferenceEquals(_reservedUrlsCache, GlobalSettings.ReservedUrls))
if (_reservedUrlsCache == null)
{
// store references to strings to determine changes
_reservedPathsCache = GlobalSettings.ReservedPaths;
_reservedUrlsCache = GlobalSettings.ReservedUrls;
string _root = SystemDirectories.Root.Trim().ToLower();
// add URLs and paths to a new list
StartsWithContainer _newReservedList = new StartsWithContainer();
foreach (string reservedUrl in _reservedUrlsCache.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries))
lock (Locker)
{
//resolves the url to support tilde chars
string reservedUrlTrimmed = IOHelper.ResolveUrl(reservedUrl).Trim().ToLower();
if (reservedUrlTrimmed.Length > 0)
_newReservedList.Add(reservedUrlTrimmed);
if (_reservedUrlsCache == null)
{
// store references to strings to determine changes
_reservedPathsCache = GlobalSettings.ReservedPaths;
_reservedUrlsCache = GlobalSettings.ReservedUrls;
string _root = SystemDirectories.Root.Trim().ToLower();
// add URLs and paths to a new list
StartsWithContainer _newReservedList = new StartsWithContainer();
foreach (string reservedUrl in _reservedUrlsCache.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries))
{
//resolves the url to support tilde chars
string reservedUrlTrimmed = IOHelper.ResolveUrl(reservedUrl).Trim().ToLower();
if (reservedUrlTrimmed.Length > 0)
_newReservedList.Add(reservedUrlTrimmed);
}
foreach (string reservedPath in _reservedPathsCache.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries))
{
bool trimEnd = !reservedPath.EndsWith("/");
//resolves the url to support tilde chars
string reservedPathTrimmed = IOHelper.ResolveUrl(reservedPath).Trim().ToLower();
if (reservedPathTrimmed.Length > 0)
_newReservedList.Add(reservedPathTrimmed + (reservedPathTrimmed.EndsWith("/") ? "" : "/"));
}
// use the new list from now on
_reservedList = _newReservedList;
}
}
foreach (string reservedPath in _reservedPathsCache.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries))
{
bool trimEnd = !reservedPath.EndsWith("/");
//resolves the url to support tilde chars
string reservedPathTrimmed = IOHelper.ResolveUrl(reservedPath).Trim().ToLower();
if (reservedPathTrimmed.Length > 0)
_newReservedList.Add(reservedPathTrimmed + (reservedPathTrimmed.EndsWith("/") ? "" : "/"));
}
// use the new list from now on
_reservedList = _newReservedList;
}
//The url should be cleaned up before checking:
@@ -0,0 +1,190 @@
using System.Configuration;
namespace Umbraco.Core.Configuration.InfrastructureSettings
{
public class Infrastructure : ConfigurationSection
{
private const string InfrastructureSectionName = "umbraco/infrastructure";
public static Infrastructure Instance
{
get { return (Infrastructure) ConfigurationManager.GetSection(InfrastructureSectionName); }
}
#region RepositoriesSection Property
internal const string RepositoriesPropertyName = "repositories";
[ConfigurationProperty(RepositoriesPropertyName, IsRequired = true, IsKey = false, IsDefaultCollection = false)]
public Repositories Repositories
{
get { return ((Repositories)base[RepositoriesPropertyName]); }
set { base[RepositoriesPropertyName] = value; }
}
#endregion
#region PublishingStrategy Property
internal const string PublishingStrategyPropertyName = "publishingStrategy";
[ConfigurationProperty(PublishingStrategyPropertyName, IsRequired = true, IsKey = false, IsDefaultCollection = false)]
public PublishingProvider PublishingStrategy
{
get { return ((PublishingProvider)base[PublishingStrategyPropertyName]); }
set { base[PublishingStrategyPropertyName] = value; }
}
#endregion
}
public class Repositories : ConfigurationElement
{
[ConfigurationProperty("", IsDefaultCollection = true, IsRequired = true)]
public RepositoryElementCollection Repository
{
get { return ((RepositoryElementCollection)(base[""])); }
}
}
[ConfigurationCollection(typeof(Repository), CollectionType = ConfigurationElementCollectionType.BasicMapAlternate, AddItemName = RepositoryPropertyName)]
public class RepositoryElementCollection : ConfigurationElementCollection
{
internal const string RepositoryPropertyName = "repository";
public override ConfigurationElementCollectionType CollectionType
{
get
{
return ConfigurationElementCollectionType.BasicMapAlternate;
}
}
protected override string ElementName
{
get
{
return RepositoryPropertyName;
}
}
protected override bool IsElementName(string elementName)
{
return elementName == RepositoryPropertyName;
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((Repository)element).InterfaceShortTypeName;
}
protected override ConfigurationElement CreateNewElement()
{
return new Repository();
}
#region Indexer
public Repository this[int index]
{
get { return (Repository)base.BaseGet(index); }
}
public Repository this[string interfaceShortTypeName]
{
get { return (Repository)base.BaseGet(interfaceShortTypeName); }
}
#endregion
#region Add
public void Add(Repository repository)
{
BaseAdd(repository);
}
#endregion
#region Remove
public void Remove(Repository repository)
{
BaseRemove(repository);
}
#endregion
#region GetItem
public Repository GetItemAt(int index)
{
return (Repository)BaseGet(index);
}
public Repository GetItemByKey(string interfaceShortTypeName)
{
return (Repository)BaseGet(interfaceShortTypeName);
}
#endregion
public bool ContainsKey(string interfaceShortName)
{
bool result = false;
object[] keys = this.BaseGetAllKeys();
foreach (object key in keys)
{
if ((string)key == interfaceShortName)
{
result = true;
break;
}
}
return result;
}
}
public class Repository : ConfigurationElement
{
internal const string InterfaceShortTypeNamePropertyName = "interfaceShortTypeName";
[ConfigurationPropertyAttribute(InterfaceShortTypeNamePropertyName, IsRequired = true, IsKey = true, IsDefaultCollection = false)]
public string InterfaceShortTypeName
{
get { return (string) base[InterfaceShortTypeNamePropertyName]; }
set { base[InterfaceShortTypeNamePropertyName] = value; }
}
internal const string RepositoryFullTypeNamePropertyName = "repositoryFullTypeName";
[ConfigurationPropertyAttribute(RepositoryFullTypeNamePropertyName, IsRequired = true, IsKey = false, IsDefaultCollection = false)]
public string RepositoryFullTypeName
{
get { return (string)base[RepositoryFullTypeNamePropertyName]; }
set { base[RepositoryFullTypeNamePropertyName] = value; }
}
internal const string CacheProviderFullTypeNamePropertyName = "cacheProviderFullTypeName";
[ConfigurationPropertyAttribute(CacheProviderFullTypeNamePropertyName, IsRequired = true, IsKey = false, IsDefaultCollection = false)]
public string CacheProviderFullTypeName
{
get { return (string)base[CacheProviderFullTypeNamePropertyName]; }
set { base[CacheProviderFullTypeNamePropertyName] = value; }
}
}
public class PublishingProvider : ConfigurationElement
{
internal const string TypePropertyName = "type";
[ConfigurationPropertyAttribute(TypePropertyName, IsRequired = true, IsKey = false, IsDefaultCollection = false)]
public string Type
{
get { return (string)base[TypePropertyName]; }
set { base[TypePropertyName] = value; }
}
}
}
@@ -0,0 +1,33 @@
using System.Configuration;
namespace Umbraco.Core.Configuration
{
// note - still must work on how to support read-only and ResetSection for collections
// note - still must work on how to spread config over files (aka DeepConfig in v5)
/// <summary>
/// Represents an Umbraco section within the configuration file.
/// </summary>
/// <remarks>
/// <para>The requirement for these sections is to be read-only.</para>
/// <para>However for unit tests purposes it is internally possible to override some values, and
/// then calling <c>>ResetSection</c> should cancel these changes and bring the section back to
/// what it was originally.</para>
/// <para>The <c>UmbracoSettings.For{T}</c> method will return a section, either one that
/// is in the configuration file, or a section that was created with default values.</para>
/// </remarks>
internal abstract class UmbracoConfigurationSection : ConfigurationSection
{
/// <summary>
/// Gets a value indicating whether the section actually is in the configuration file.
/// </summary>
protected bool IsPresent { get { return ElementInformation.IsPresent; } }
/// <summary>
/// Resets settings that were set programmatically, to their initial values.
/// </summary>
/// <remarks>>To be used in unit tests.</remarks>
internal protected virtual void ResetSection()
{ }
}
}
+248 -102
View File
@@ -6,9 +6,11 @@ using System.Threading;
using System.Web;
using System.Web.Caching;
using System.Xml;
using System.Configuration;
using System.Collections.Generic;
using Umbraco.Core.Logging;
using Umbraco.Core.CodeAnnotations;
namespace Umbraco.Core.Configuration
@@ -20,22 +22,48 @@ namespace Umbraco.Core.Configuration
//TODO: Re-enable logging !!!!
//TODO: We need to convert this to a real section, it's currently using HttpRuntime.Cache to detect cahnges, this is real poor, especially in a console app
/// <summary>
/// The UmbracoSettings Class contains general settings information for the entire Umbraco instance based on information from the /config/umbracoSettings.config file
/// </summary>
internal class UmbracoSettings
{
/// <summary>
private static bool GetKeyValue(string key, bool defaultValue)
{
bool value;
string stringValue = GetKey(key);
if (string.IsNullOrWhiteSpace(stringValue))
return defaultValue;
if (bool.TryParse(stringValue, out value))
return value;
return defaultValue;
}
private static int GetKeyValue(string key, int defaultValue)
{
int value;
string stringValue = GetKey(key);
if (string.IsNullOrWhiteSpace(stringValue))
return defaultValue;
if (int.TryParse(stringValue, out value))
return value;
return defaultValue;
}
/// <summary>
/// Used in unit testing to reset all config items that were set with property setters (i.e. did not come from config)
/// </summary>
internal static void ResetSetters()
private static void ResetInternal()
{
_addTrailingSlash = null;
_forceSafeAliases = null;
_useLegacySchema = null;
_useDomainPrefixes = null;
_umbracoLibraryCacheDuration = null;
SettingsFilePath = null;
SettingsFilePath = null;
}
internal const string TempFriendlyXmlChildContainerNodename = ""; // "children";
@@ -126,11 +154,32 @@ namespace Umbraco.Core.Configuration
{
EnsureSettingsDocument();
string attrName = null;
var pos = key.IndexOf('@');
if (pos > 0)
{
attrName = key.Substring(pos + 1);
key = key.Substring(0, pos - 1);
}
var node = UmbracoSettingsXmlDoc.DocumentElement.SelectSingleNode(key);
if (node == null || node.FirstChild == null || node.FirstChild.Value == null)
return string.Empty;
return node.FirstChild.Value;
}
if (node == null)
return string.Empty;
if (pos < 0)
{
if (node.FirstChild == null || node.FirstChild.Value == null)
return string.Empty;
return node.FirstChild.Value;
}
else
{
var attr = node.Attributes[attrName];
if (attr == null)
return string.Empty;
return attr.Value;
}
}
/// <summary>
/// Gets a value indicating whether the media library will create new directories in the /media directory.
@@ -203,6 +252,7 @@ namespace Umbraco.Core.Configuration
return value != null ? value.Attributes["assembly"].Value : "";
}
}
/// <summary>
/// Gets the type of an external logger that can be used to store log items in 3rd party systems
/// </summary>
@@ -351,24 +401,13 @@ namespace Umbraco.Core.Configuration
{
get
{
try
{
if (_useDomainPrefixes.HasValue)
return _useDomainPrefixes.Value;
bool result;
if (bool.TryParse(GetKey("/settings/requestHandler/useDomainPrefixes"), out result))
return result;
return false;
}
catch
{
return false;
}
// default: false
return _useDomainPrefixes ?? GetKeyValue("/settings/requestHandler/useDomainPrefixes", false);
}
// for unit tests only
internal set
{
_useDomainPrefixes = value;
// for unit tests only
_useDomainPrefixes = value;
}
}
@@ -382,31 +421,14 @@ namespace Umbraco.Core.Configuration
{
get
{
try
{
if (GlobalSettings.UseDirectoryUrls)
{
if (_addTrailingSlash.HasValue)
return _addTrailingSlash.Value;
bool result;
if (bool.TryParse(GetKey("/settings/requestHandler/addTrailingSlash"), out result))
return result;
return false;
}
else
{
return false;
}
}
catch
{
return false;
}
// default: false
return GlobalSettings.UseDirectoryUrls
&& (_addTrailingSlash ?? GetKeyValue("/settings/requestHandler/addTrailingSlash", false));
}
// for unit tests only
internal set
{
_addTrailingSlash = value;
// for unit tests only
_addTrailingSlash = value;
}
}
@@ -484,7 +506,7 @@ namespace Umbraco.Core.Configuration
private static IEnumerable<RazorDataTypeModelStaticMappingItem> _razorDataTypeModelStaticMapping;
private static readonly ReaderWriterLockSlim Lock = new ReaderWriterLockSlim();
public static IEnumerable<RazorDataTypeModelStaticMappingItem> RazorDataTypeModelStaticMapping
internal static IEnumerable<RazorDataTypeModelStaticMappingItem> RazorDataTypeModelStaticMapping
{
get
{
@@ -623,31 +645,33 @@ namespace Umbraco.Core.Configuration
{
get
{
if (_forceSafeAliases.HasValue)
return _forceSafeAliases.Value;
string forceSafeAlias = GetKey("/settings/content/ForceSafeAliases");
if (String.IsNullOrEmpty(forceSafeAlias))
return true;
else
{
try
{
return bool.Parse(forceSafeAlias);
}
catch
{
return true;
}
}
// default: true
return _forceSafeAliases ?? GetKeyValue("/settings/content/ForceSafeAliases", true);
}
internal set
{
//used for unit testing
// used for unit testing
_forceSafeAliases = value;
}
}
/// <summary>
/// Gets a value indicating whether to try to skip IIS custom errors.
/// </summary>
[UmbracoWillObsolete("Use UmbracoSettings.For<WebRouting>.TrySkipIisCustomErrors instead.")]
internal static bool TrySkipIisCustomErrors
{
get { return GetKeyValue("/settings/web.routing/@trySkipIisCustomErrors", false); }
}
/// <summary>
/// Gets a value indicating whether internal redirect preserves the template.
/// </summary>
[UmbracoWillObsolete("Use UmbracoSettings.For<WebRouting>.InternalRedirectPerservesTemplate instead.")]
internal static bool InternalRedirectPreservesTemplate
{
get { return GetKeyValue("/settings/web.routing/@internalRedirectPreservesTemplate", false); }
}
/// <summary>
/// Gets the allowed image file types.
@@ -677,26 +701,14 @@ namespace Umbraco.Core.Configuration
{
get
{
if (_umbracoLibraryCacheDuration.HasValue)
return _umbracoLibraryCacheDuration.Value;
string libraryCacheDuration = GetKey("/settings/content/UmbracoLibraryCacheDuration");
if (String.IsNullOrEmpty(libraryCacheDuration))
return 1800;
else
{
try
{
return int.Parse(libraryCacheDuration);
}
catch
{
return 1800;
}
}
// default: 1800
return _umbracoLibraryCacheDuration ?? GetKeyValue("/settings/content/UmbracoLibraryCacheDuration", 1800);
}
internal set { _umbracoLibraryCacheDuration = value; }
internal set
{
// for unit tests only
_umbracoLibraryCacheDuration = value;
}
}
/// <summary>
@@ -1052,27 +1064,12 @@ namespace Umbraco.Core.Configuration
{
get
{
try
{
if (_useLegacySchema.HasValue)
return _useLegacySchema.Value;
string value = GetKey("/settings/content/UseLegacyXmlSchema");
bool result;
if (!string.IsNullOrEmpty(value) && bool.TryParse(value, out result))
return result;
return true;
}
catch (Exception)
{
//default. TODO: When we change this to a real config section we won't have to worry about parse errors
// and should handle defaults with unit tests properly.
return false;
}
// default: true
return _useLegacySchema ?? GetKeyValue("/settings/content/UseLegacyXmlSchema", false);
}
internal set
{
//used for unit testing
// used for unit testing
_useLegacySchema = value;
}
}
@@ -1219,8 +1216,83 @@ namespace Umbraco.Core.Configuration
}
return _defaultRenderingEngine.Value;
}
//internal set
//{
// _defaultRenderingEngine = value;
// var node = UmbracoSettingsXmlDoc.DocumentElement.SelectSingleNode("/settings/templates/defaultRenderingEngine");
// node.InnerText = value.ToString();
//}
}
private static MacroErrorBehaviour? _macroErrorBehaviour;
/// <summary>
/// This configuration setting defines how to handle macro errors:
/// - Inline - Show error within macro as text (default and current Umbraco 'normal' behavior)
/// - Silent - Suppress error and hide macro
/// - Throw - Throw an exception and invoke the global error handler (if one is defined, if not you'll get a YSOD)
/// </summary>
/// <value>MacroErrorBehaviour enum defining how to handle macro errors.</value>
public static MacroErrorBehaviour MacroErrorBehaviour
{
get
{
if (_macroErrorBehaviour == null)
{
try
{
var behaviour = MacroErrorBehaviour.Inline;
var value = GetKey("/settings/content/MacroErrors");
if (value != null)
{
Enum<MacroErrorBehaviour>.TryParse(value, true, out behaviour);
}
_macroErrorBehaviour = behaviour;
}
catch (Exception ex)
{
LogHelper.Error<UmbracoSettings>("Could not load /settings/content/MacroErrors from umbracosettings.config", ex);
_macroErrorBehaviour = MacroErrorBehaviour.Inline;
}
}
return _macroErrorBehaviour.Value;
}
}
private static IconPickerBehaviour? _iconPickerBehaviour;
/// <summary>
/// This configuration setting defines how to show icons in the document type editor.
/// - ShowDuplicates - Show duplicates in files and sprites. (default and current Umbraco 'normal' behaviour)
/// - HideSpriteDuplicates - Show files on disk and hide duplicates from the sprite
/// - HideFileDuplicates - Show files in the sprite and hide duplicates on disk
/// </summary>
/// <value>MacroErrorBehaviour enum defining how to show icons in the document type editor.</value>
public static IconPickerBehaviour IconPickerBehaviour
{
get
{
if (_iconPickerBehaviour == null)
{
try
{
var behaviour = IconPickerBehaviour.ShowDuplicates;
var value = GetKey("/settings/content/DocumentTypeIconList");
if (value != null)
{
Enum<IconPickerBehaviour>.TryParse(value, true, out behaviour);
}
_iconPickerBehaviour = behaviour;
}
catch (Exception ex)
{
LogHelper.Error<UmbracoSettings>("Could not load /settings/content/DocumentTypeIconList from umbracosettings.config", ex);
_iconPickerBehaviour = IconPickerBehaviour.ShowDuplicates;
}
}
return _iconPickerBehaviour.Value;
}
}
/// <summary>
/// Configuration regarding webservices
@@ -1405,6 +1477,80 @@ namespace Umbraco.Core.Configuration
}
#endregion
}
}
}
#region Extensible settings
/// <summary>
/// Resets settings that were set programmatically, to their initial values.
/// </summary>
/// <remarks>To be used in unit tests.</remarks>
internal static void Reset()
{
ResetInternal();
using (new WriteLock(SectionsLock))
{
foreach (var section in Sections.Values)
section.ResetSection();
}
}
private static readonly ReaderWriterLockSlim SectionsLock = new ReaderWriterLockSlim();
private static readonly Dictionary<Type, UmbracoConfigurationSection> Sections = new Dictionary<Type, UmbracoConfigurationSection>();
/// <summary>
/// Gets the specified UmbracoConfigurationSection.
/// </summary>
/// <typeparam name="T">The type of the UmbracoConfigurationSectiont.</typeparam>
/// <returns>The UmbracoConfigurationSection of the specified type.</returns>
internal static T For<T>()
where T : UmbracoConfigurationSection, new()
{
var sectionType = typeof (T);
using (new WriteLock(SectionsLock))
{
if (Sections.ContainsKey(sectionType)) return Sections[sectionType] as T;
var attr = sectionType.GetCustomAttribute<ConfigurationKeyAttribute>(false);
if (attr == null)
throw new InvalidOperationException(string.Format("Type \"{0}\" is missing attribute ConfigurationKeyAttribute.", sectionType.FullName));
var sectionKey = attr.ConfigurationKey;
if (string.IsNullOrWhiteSpace(sectionKey))
throw new InvalidOperationException(string.Format("Type \"{0}\" ConfigurationKeyAttribute value is null or empty.", sectionType.FullName));
var section = GetSection(sectionType, sectionKey);
Sections[sectionType] = section;
return section as T;
}
}
private static UmbracoConfigurationSection GetSection(Type sectionType, string key)
{
if (!sectionType.Inherits<UmbracoConfigurationSection>())
throw new ArgumentException(string.Format(
"Type \"{0}\" does not inherit from UmbracoConfigurationSection.", sectionType.FullName), "sectionType");
var section = ConfigurationManager.GetSection(key);
if (section != null && section.GetType() != sectionType)
throw new InvalidCastException(string.Format("Section at key \"{0}\" is of type \"{1}\" and not \"{2}\".",
key, section.GetType().FullName, sectionType.FullName));
if (section != null) return section as UmbracoConfigurationSection;
section = Activator.CreateInstance(sectionType) as UmbracoConfigurationSection;
if (section == null)
throw new NullReferenceException(string.Format(
"Activator failed to create an instance of type \"{0}\" for key\"{1}\" and returned null.",
sectionType.FullName, key));
return section as UmbracoConfigurationSection;
}
#endregion
}
}
@@ -5,7 +5,7 @@ namespace Umbraco.Core.Configuration
{
public class UmbracoVersion
{
private static readonly Version Version = new Version("6.0.0");
private static readonly Version Version = new Version("6.1.0");
/// <summary>
/// Gets the current version of Umbraco.
@@ -23,7 +23,7 @@ namespace Umbraco.Core.Configuration
/// Gets the version comment (like beta or RC).
/// </summary>
/// <value>The version comment.</value>
public static string CurrentComment { get { return "RC"; } }
public static string CurrentComment { get { return "beta"; } }
// Get the version of the umbraco.dll by looking at a class in that dll
// Had to do it like this due to medium trust issues, see: http://haacked.com/archive/2010/11/04/assembly-location-and-medium-trust.aspx
@@ -0,0 +1,46 @@
namespace Umbraco.Core
{
public static partial class Constants
{
/// <summary>
/// Defines the alias identifiers for Umbraco's core application sections.
/// </summary>
public static class Applications
{
/// <summary>
/// Application alias for the content section.
/// </summary>
public const string Content = "content";
/// <summary>
/// Application alias for the developer section.
/// </summary>
public const string Developer = "developer";
/// <summary>
/// Application alias for the media section.
/// </summary>
public const string Media = "media";
/// <summary>
/// Application alias for the members section.
/// </summary>
public const string Members = "member";
/// <summary>
/// Application alias for the settings section.
/// </summary>
public const string Settings = "settings";
/// <summary>
/// Application alias for the translation section.
/// </summary>
public const string Translation = "translation";
/// <summary>
/// Application alias for the users section.
/// </summary>
public const string Users = "users";
}
}
}
+105
View File
@@ -0,0 +1,105 @@
namespace Umbraco.Core
{
public static partial class Constants
{
/// <summary>
/// Defines the identifiers for property-type alias conventions that are used within the Umbraco core.
/// </summary>
public static class Conventions
{
/// <summary>
/// Constants for Umbraco Content property aliases.
/// </summary>
public static class Content
{
/// <summary>
/// Property alias for the Content's Url (internal) redirect.
/// </summary>
public const string InternalRedirectId = "umbracoInternalRedirectId";
/// <summary>
/// Property alias for the Content's navigational hide, (not actually used in core code).
/// </summary>
public const string NaviHide = "umbracoNaviHide";
/// <summary>
/// Property alias for the Content's Url redirect.
/// </summary>
public const string Redirect = "umbracoRedirect";
/// <summary>
/// Property alias for the Content's Url alias.
/// </summary>
public const string UrlAlias = "umbracoUrlAlias";
/// <summary>
/// Property alias for the Content's Url name.
/// </summary>
public const string UrlName = "umbracoUrlName";
}
/// <summary>
/// Constants for Umbraco Media property aliases.
/// </summary>
public static class Media
{
/// <summary>
/// Property alias for the Media's file name.
/// </summary>
public const string File = "umbracoFile";
/// <summary>
/// Property alias for the Media's width.
/// </summary>
public const string Width = "umbracoWidth";
/// <summary>
/// Property alias for the Media's height.
/// </summary>
public const string Height = "umbracoHeight";
/// <summary>
/// Property alias for the Media's file size (in bytes).
/// </summary>
public const string Bytes = "umbracoBytes";
/// <summary>
/// Property alias for the Media's file extension.
/// </summary>
public const string Extension = "umbracoExtension";
}
/// <summary>
/// Defines the alias identifiers for Umbraco media types.
/// </summary>
public static class MediaTypes
{
/// <summary>
/// MediaType alias for a file.
/// </summary>
public const string File = "File";
/// <summary>
/// MediaType alias for a folder.
/// </summary>
public const string Folder = "Folder";
/// <summary>
/// MediaType alias for an image.
/// </summary>
public const string Image = "Image";
}
/// <summary>
/// Constants for Umbraco URLs/Querystrings.
/// </summary>
public static class Url
{
/// <summary>
/// Querystring parameter name used for Umbraco's alternative template functionality.
/// </summary>
public const string AltTemplate = "altTemplate";
}
}
}
}
+86
View File
@@ -0,0 +1,86 @@
namespace Umbraco.Core
{
public static partial class Constants
{
/// <summary>
/// Defines the identifiers for Umbraco object types as constants for easy centralized access/management.
/// </summary>
public static class ObjectTypes
{
/// <summary>
/// Guid for a Content Item object.
/// </summary>
public const string ContentItem = "10E2B09F-C28B-476D-B77A-AA686435E44A";
/// <summary>
/// Guid for a Content Item Type object.
/// </summary>
public const string ContentItemType = "7A333C54-6F43-40A4-86A2-18688DC7E532";
/// <summary>
/// Guid for the Content Recycle Bin.
/// </summary>
public const string ContentRecycleBin = "01BB7FF2-24DC-4C0C-95A2-C24EF72BBAC8";
/// <summary>
/// Guid for a DataType object.
/// </summary>
public const string DataType = "30A2A501-1978-4DDB-A57B-F7EFED43BA3C";
/// <summary>
/// Guid for a Document object.
/// </summary>
public const string Document = "C66BA18E-EAF3-4CFF-8A22-41B16D66A972";
/// <summary>
/// Guid for a Document Type object.
/// </summary>
public const string DocumentType = "A2CB7800-F571-4787-9638-BC48539A0EFB";
/// <summary>
/// Guid for a Media object.
/// </summary>
public const string Media = "B796F64C-1F99-4FFB-B886-4BF4BC011A9C";
/// <summary>
/// Guid for the Media Recycle Bin.
/// </summary>
public const string MediaRecycleBin = "CF3D8E34-1C1C-41e9-AE56-878B57B32113";
/// <summary>
/// Guid for a Media Type object.
/// </summary>
public const string MediaType = "4EA4382B-2F5A-4C2B-9587-AE9B3CF3602E";
/// <summary>
/// Guid for a Member object.
/// </summary>
public const string Member = "39EB0F98-B348-42A1-8662-E7EB18487560";
/// <summary>
/// Guid for a Member Group object.
/// </summary>
public const string MemberGroup = "366E63B9-880F-4E13-A61C-98069B029728";
/// <summary>
/// Guid for a Member Type object.
/// </summary>
public const string MemberType = "9B5416FB-E72F-45A9-A07B-5A9A2709CE43";
/// <summary>
/// Guid for a Stylesheet object.
/// </summary>
public const string Stylesheet = "9F68DA4F-A3A8-44C2-8226-DCBD125E4840";
/// <summary>
/// Guid for the System Root.
/// </summary>
public const string SystemRoot = "EA7D8624-4CFE-4578-A871-24AA946BF34D";
/// <summary>
/// Guid for a Template object.
/// </summary>
public const string Template = "6FBDE604-4178-42CE-A10B-8A2600A2F07D";
}
}
}
@@ -0,0 +1,186 @@
namespace Umbraco.Core
{
public static partial class Constants
{
/// <summary>
/// Defines the identifiers for Umbraco Property Editors as constants for easy centralized access/management.
/// </summary>
public static class PropertyEditors
{
/// <summary>
/// Guid for the Checkbox list datatype.
/// </summary>
public const string CheckBoxList = "B4471851-82B6-4C75-AFA4-39FA9C6A75E9";
/// <summary>
/// Guid for the Color Picker datatype.
/// </summary>
public const string ColorPicker = "F8D60F68-EC59-4974-B43B-C46EB5677985";
/// <summary>
/// Guid for the Content Picker datatype.
/// </summary>
public const string ContentPicker = "158AA029-24ED-4948-939E-C3DA209E5FBA";
/// <summary>
/// Guid for the Date datatype.
/// </summary>
public const string Date = "23E93522-3200-44E2-9F29-E61A6FCBB79A";
/// <summary>
/// Guid for the Date/Time datatype.
/// </summary>
public const string DateTime = "B6FB1622-AFA5-4BBF-A3CC-D9672A442222";
/// <summary>
/// Guid for the Dictionary Picker datatype.
/// </summary>
public const string DictionaryPicker = "17B70066-F764-407D-AB05-3717F1E1C513";
/// <summary>
/// Guid for the Dropdown list datatype.
/// </summary>
public const string DropDownList = "A74EA9C9-8E18-4D2A-8CF6-73C6206C5DA6";
/// <summary>
/// Guid for the Dropdown list multiple datatype.
/// </summary>
public const string DropDownListMultiple = "928639ED-9C73-4028-920C-1E55DBB68783";
/// <summary>
/// Guid for the Dropdown list multiple, publish keys datatype.
/// </summary>
public const string DropdownlistMultiplePublishKeys = "928639AA-9C73-4028-920C-1E55DBB68783";
/// <summary>
/// Guid for the Dropdown list, publishing keys datatype.
/// </summary>
public const string DropdownlistPublishingKeys = "A74EA9E1-8E18-4D2A-8CF6-73C6206C5DA6";
/// <summary>
/// Guid for the Folder browser datatype.
/// </summary>
public const string FolderBrowser = "CCCD4AE9-F399-4ED2-8038-2E88D19E810C";
/// <summary>
/// Guid for the Image Cropper datatype.
/// </summary>
public const string ImageCropper = "7A2D436C-34C2-410F-898F-4A23B3D79F54";
/// <summary>
/// Guid for the Integer datatype.
/// </summary>
public const string Integer = "1413AFCB-D19A-4173-8E9A-68288D2A73B8";
/// <summary>
/// Guid for the Macro Container datatype.
/// </summary>
public const string MacroContainer = "474FCFF8-9D2D-11DE-ABC6-AD7A56D89593";
/// <summary>
/// Guid for the Media Picker datatype.
/// </summary>
public const string MediaPicker = "EAD69342-F06D-4253-83AC-28000225583B";
/// <summary>
/// Guid for the Member Picker datatype.
/// </summary>
public const string MemberPicker = "39F533E4-0551-4505-A64B-E0425C5CE775";
/// <summary>
/// Guid for the Multi-Node Tree Picker datatype
/// </summary>
public const string MultiNodeTreePicker = "7E062C13-7C41-4AD9-B389-41D88AEEF87C";
/// <summary>
/// Guid for the Multiple Textstring datatype.
/// </summary>
public const string MultipleTextstring = "5359AD0B-06CC-4182-92BD-0A9117448D3F";
/// <summary>
/// Guid for the No edit datatype.
/// </summary>
public const string NoEdit = "6C738306-4C17-4D88-B9BD-6546F3771597";
/// <summary>
/// Guid for the Picker Relations datatype.
/// </summary>
public const string PickerRelations = "83396FF2-2E39-4A90-9066-17F5F3989374";
/// <summary>
/// Guid for the Radiobutton list datatype.
/// </summary>
public const string RadioButtonList = "A52C7C1C-C330-476E-8605-D63D3B84B6A6";
/// <summary>
/// Guid for the Related Links datatype.
/// </summary>
public const string RelatedLinks = "71B8AD1A-8DC2-425C-B6B8-FAA158075E63";
/// <summary>
/// Guid for the Slider datatype.
/// </summary>
public const string Slider = "29E790E6-26B3-438A-B21F-908663A0B19E";
/// <summary>
/// Guid for the Tags datatype.
/// </summary>
public const string Tags = "4023E540-92F5-11DD-AD8B-0800200C9A66";
/// <summary>
/// Guid for the Textbox datatype.
/// </summary>
public const string Textbox = "EC15C1E5-9D90-422A-AA52-4F7622C63BEA";
/// <summary>
/// Guid for the Textbox multiple datatype.
/// </summary>
public const string TextboxMultiple = "67DB8357-EF57-493E-91AC-936D305E0F2A";
/// <summary>
/// Guid for the TinyMCE v3 wysiwyg datatype.
/// </summary>
public const string TinyMCEv3 = "5E9B75AE-FACE-41C8-B47E-5F4B0FD82F83";
/// <summary>
/// Guid for the TinyMCE wysiwyg (deprecated, upgrade to tinymce v3!) datatype.
/// </summary>
public const string TinyMCE = "83722133-F80C-4273-BDB6-1BEFAA04A612";
/// <summary>
/// Guid for the True/False (Ja/Nej) datatype.
/// </summary>
public const string TrueFalse = "38B352C1-E9F8-4FD8-9324-9A2EAB06D97A";
/// <summary>
/// Guid for the Ultimate Picker datatype.
/// </summary>
public const string UltimatePicker = "CDBF0B5D-5CB2-445F-BC12-FCAAEC07CF2C";
/// <summary>
/// Guid for the UltraSimpleEditor datatype.
/// </summary>
public const string UltraSimpleEditor = "60B7DABF-99CD-41EB-B8E9-4D2E669BBDE9";
/// <summary>
/// Guid for the Umbraco Usercontrol Wrapper datatype.
/// </summary>
public const string UmbracoUserControlWrapper = "D15E1281-E456-4B24-AA86-1DDA3E4299D5";
/// <summary>
/// Guid for the Upload field datatype.
/// </summary>
public const string UploadField = "5032A6E6-69E3-491D-BB28-CD31CD11086C";
/// <summary>
/// Guid for the XPath CheckBoxList datatype.
/// </summary>
public const string XPathCheckBoxList = "34451D92-D270-49BA-8C7F-EE55BFEEE1CB";
/// <summary>
/// Guid for the XPath DropDownList datatype.
/// </summary>
public const string XPathDropDownList = "173A96AE-00ED-4A7C-9F76-4B53D4A0A1B9";
}
}
}
+26
View File
@@ -0,0 +1,26 @@
namespace Umbraco.Core
{
public static partial class Constants
{
/// <summary>
/// Defines the identifiers for Umbraco system nodes.
/// </summary>
public static class System
{
/// <summary>
/// The integer identifier for global system root node.
/// </summary>
public const int Root = -1;
/// <summary>
/// The integer identifier for content's recycle bin.
/// </summary>
public const int RecycleBinContent = -20;
/// <summary>
/// The integer identifier for media's recycle bin.
/// </summary>
public const int RecycleBinMedia = -21;
}
}
}
+10
View File
@@ -0,0 +1,10 @@
namespace Umbraco.Core
{
/// <summary>
/// Constants all the identifiers within the Umbraco core.
/// </summary>
public static partial class Constants
{
// generic constants can go here
}
}
+133 -45
View File
@@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.ObjectResolution;
@@ -9,10 +7,15 @@ using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Migrations;
using Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix;
using Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixZeroOne;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Publishing;
using Umbraco.Core.Macros;
using Umbraco.Core.Services;
using Umbraco.Core.Sync;
using Umbraco.Core.Strings;
using MigrationsVersionFourNineZero = Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionFourNineZero;
namespace Umbraco.Core
@@ -30,10 +33,21 @@ namespace Umbraco.Core
private bool _isInitialized = false;
private bool _isStarted = false;
private bool _isComplete = false;
private readonly UmbracoApplicationBase _umbracoApplication;
protected ApplicationContext ApplicationContext { get; private set; }
public virtual IBootManager Initialize()
protected UmbracoApplicationBase UmbracoApplication
{
get { return _umbracoApplication; }
}
public CoreBootManager(UmbracoApplicationBase umbracoApplication)
{
if (umbracoApplication == null) throw new ArgumentNullException("umbracoApplication");
_umbracoApplication = umbracoApplication;
}
public virtual IBootManager Initialize()
{
if (_isInitialized)
throw new InvalidOperationException("The boot manager has already been initialized");
@@ -49,22 +63,59 @@ namespace Umbraco.Core
new PetaPocoUnitOfWorkProvider(dbFactory),
new FileUnitOfWorkProvider(),
new PublishingStrategy());
//create the ApplicationContext
ApplicationContext = ApplicationContext.Current = new ApplicationContext(dbContext, serviceContext);
//initialize the DatabaseContext
dbContext.Initialize();
CreateApplicationContext(dbContext, serviceContext);
InitializeApplicationEventsResolver();
InitializeResolvers();
//initialize the DatabaseContext
dbContext.Initialize();
//now we need to call the initialize methods
ApplicationEventsResolver.Current.ApplicationEventHandlers
.ForEach(x => x.OnApplicationInitialized(UmbracoApplication, ApplicationContext));
_isInitialized = true;
return this;
}
/// <summary>
/// Creates and assigns the application context singleton
/// </summary>
/// <param name="dbContext"></param>
/// <param name="serviceContext"></param>
protected virtual void CreateApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext)
{
//create the ApplicationContext
ApplicationContext = ApplicationContext.Current = new ApplicationContext(dbContext, serviceContext);
}
/// <summary>
/// Special method to initialize the ApplicationEventsResolver and any modifications required for it such
/// as adding custom types to the resolver.
/// </summary>
protected virtual void InitializeApplicationEventsResolver()
{
//find and initialize the application startup handlers, we need to initialize this resolver here because
//it is a special resolver where they need to be instantiated first before any other resolvers in order to bind to
//events and to call their events during bootup.
//ApplicationStartupHandler.RegisterHandlers();
//... and set the special flag to let us resolve before frozen resolution
ApplicationEventsResolver.Current = new ApplicationEventsResolver(
PluginManager.Current.ResolveApplicationStartupHandlers())
{
CanResolveBeforeFrozen = true
};
//add custom types here that are internal
ApplicationEventsResolver.Current.AddType<PublishedContentHelper>();
}
/// <summary>
/// Fires after initialization and calls the callback to allow for customizations to occur
/// Fires after initialization and calls the callback to allow for customizations to occur &
/// Ensure that the OnApplicationStarting methods of the IApplicationEvents are called
/// </summary>
/// <param name="afterStartup"></param>
/// <returns></returns>
@@ -73,10 +124,14 @@ namespace Umbraco.Core
if (_isStarted)
throw new InvalidOperationException("The boot manager has already been initialized");
if (afterStartup != null)
{
afterStartup(ApplicationContext.Current);
}
//call OnApplicationStarting of each application events handler
ApplicationEventsResolver.Current.ApplicationEventHandlers
.ForEach(x => x.OnApplicationStarting(UmbracoApplication, ApplicationContext));
if (afterStartup != null)
{
afterStartup(ApplicationContext.Current);
}
_isStarted = true;
@@ -93,68 +148,89 @@ namespace Umbraco.Core
if (_isComplete)
throw new InvalidOperationException("The boot manager has already been completed");
//freeze resolution to not allow Resolvers to be modified
Resolution.Freeze();
FreezeResolution();
//stop the timer and log the output
_timer.Dispose();
if (afterComplete != null)
{
afterComplete(ApplicationContext.Current);
}
//call OnApplicationStarting of each application events handler
ApplicationEventsResolver.Current.ApplicationEventHandlers
.ForEach(x => x.OnApplicationStarted(UmbracoApplication, ApplicationContext));
//Now, startup all of our legacy startup handler
ApplicationEventsResolver.Current.InstantiateLegacyStartupHanlders();
if (afterComplete != null)
{
afterComplete(ApplicationContext.Current);
}
_isComplete = true;
// we're ready to serve content!
ApplicationContext.IsReady = true;
return this;
}
/// <summary>
/// Freeze resolution to not allow Resolvers to be modified
/// </summary>
protected virtual void FreezeResolution()
{
Resolution.Freeze();
}
/// <summary>
/// Create the resolvers
/// </summary>
protected virtual void InitializeResolvers()
{
//by default we'll use the standard configuration based sync
ServerRegistrarResolver.Current = new ServerRegistrarResolver(
new ConfigServerRegistrar());
//by default (outside of the web) we'll use the default server messenger without
//supplying a username/password, this will automatically disable distributed calls
// .. we'll override this in the WebBootManager
ServerMessengerResolver.Current = new ServerMessengerResolver(
new DefaultServerMessenger());
MappingResolver.Current = new MappingResolver(
() => PluginManager.Current.ResolveAssignedMapperTypes());
RepositoryResolver.Current = new RepositoryResolver(
new RepositoryFactory());
SqlSyntaxProvidersResolver.Current = new SqlSyntaxProvidersResolver(
new[] { typeof(MySqlSyntaxProvider), typeof(SqlCeSyntaxProvider), typeof(SqlServerSyntaxProvider) })
{
CanResolveBeforeFrozen = true
};
CacheRefreshersResolver.Current = new CacheRefreshersResolver(
PluginManager.Current.ResolveCacheRefreshers());
() => PluginManager.Current.ResolveCacheRefreshers());
DataTypesResolver.Current = new DataTypesResolver(
PluginManager.Current.ResolveDataTypes());
() => PluginManager.Current.ResolveDataTypes());
MacroFieldEditorsResolver.Current = new MacroFieldEditorsResolver(
PluginManager.Current.ResolveMacroRenderings());
() => PluginManager.Current.ResolveMacroRenderings());
PackageActionsResolver.Current = new PackageActionsResolver(
PluginManager.Current.ResolvePackageActions());
() => PluginManager.Current.ResolvePackageActions());
ActionsResolver.Current = new ActionsResolver(
PluginManager.Current.ResolveActions());
() => PluginManager.Current.ResolveActions());
MacroPropertyTypeResolver.Current = new MacroPropertyTypeResolver(
PluginManager.Current.ResolveMacroPropertyTypes());
//TODO: Y U NO WORK?
//MigrationResolver.Current = new MigrationResolver(
// PluginManager.Current.ResolveMigrationTypes());
//the database migration objects
MigrationResolver.Current = new MigrationResolver(
() => PluginManager.Current.ResolveMigrationTypes());
//the database migration objects
MigrationResolver.Current = new MigrationResolver(new List<Type>
{
typeof (MigrationsVersionFourNineZero.RemoveUmbracoAppConstraints),
typeof (DeleteAppTables),
typeof (EnsureAppsTreesUpdated),
typeof (MoveMasterContentTypeData),
typeof (NewCmsContentType2ContentTypeTable),
typeof (RemoveMasterContentTypeColumn),
typeof (RenameCmsTabTable),
typeof (RenameTabIdColumn),
typeof (UpdateCmsContentTypeAllowedContentTypeTable),
typeof (UpdateCmsContentTypeTable),
typeof (UpdateCmsContentVersionTable),
typeof (UpdateCmsPropertyTypeGroupTable)
});
PropertyEditorValueConvertersResolver.Current = new PropertyEditorValueConvertersResolver(
PluginManager.Current.ResolvePropertyEditorValueConverters());
@@ -162,6 +238,18 @@ namespace Umbraco.Core
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));
// use the Legacy one for now
ShortStringHelperResolver.Current = new ShortStringHelperResolver(
new LegacyShortStringHelper());
UrlSegmentProviderResolver.Current = new UrlSegmentProviderResolver(
typeof (DefaultUrlSegmentProvider));
}
}
}
+2 -2
View File
@@ -14,7 +14,7 @@ namespace Umbraco.Core
/// Constructor
/// </summary>
/// <param name="dataTypes"></param>
internal DataTypesResolver(IEnumerable<Type> dataTypes)
internal DataTypesResolver(Func<IEnumerable<Type>> dataTypes)
: base(dataTypes)
{
@@ -27,7 +27,7 @@ namespace Umbraco.Core
{
get
{
EnsureIdsAreTracked();
EnsureIsInitialized();
return Values;
}
}
+198 -40
View File
@@ -9,6 +9,7 @@ using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Migrations;
using Umbraco.Core.Persistence.Migrations.Initial;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core
@@ -21,14 +22,15 @@ namespace Umbraco.Core
/// </remarks>
public class DatabaseContext
{
private readonly IDatabaseFactory _factory;
private bool _configured;
private readonly IDatabaseFactory _factory;
private bool _configured;
private string _connectionString;
private string _providerName;
private DatabaseSchemaResult _result;
internal DatabaseContext(IDatabaseFactory factory)
internal DatabaseContext(IDatabaseFactory factory)
{
_factory = factory;
_factory = factory;
}
/// <summary>
@@ -107,10 +109,10 @@ namespace Umbraco.Core
/// <summary>
/// Configure a ConnectionString for the embedded database.
/// </summary>
public void ConfigureDatabaseConnection()
public void ConfigureEmbeddedDatabaseConnection()
{
const string providerName = "System.Data.SqlServerCe.4.0";
const string connectionString = "Datasource=|DataDirectory|Umbraco.sdf";
const string connectionString = @"Data Source=|DataDirectory|\Umbraco.sdf";
SaveConnectionString(connectionString, providerName);
@@ -149,14 +151,14 @@ namespace Umbraco.Core
{
string connectionString;
string providerName = "System.Data.SqlClient";
if(databaseProvider.ToLower().Contains("mysql"))
if (databaseProvider.ToLower().Contains("mysql"))
{
providerName = "MySql.Data.MySqlClient";
connectionString = string.Format("Server={0}; Database={1};Uid={2};Pwd={3}", server, databaseName, user, password);
}
else if(databaseProvider.ToLower().Contains("azure"))
else if (databaseProvider.ToLower().Contains("azure"))
{
connectionString = string.Format("Server=tcp:{0}.database.windows.net;Database={1};User ID={2}@{0};Password={3}", server, databaseName, user, password);
connectionString = BuildAzureConnectionString(server, databaseName, user, password);
}
else
{
@@ -167,6 +169,52 @@ namespace Umbraco.Core
Initialize(providerName);
}
internal string BuildAzureConnectionString(string server, string databaseName, string user, string password)
{
if (server.Contains(".") && ServerStartsWithTcp(server) == false)
server = string.Format("tcp:{0}", server);
if (server.Contains(".") == false && ServerStartsWithTcp(server))
{
string serverName = server.Contains(",")
? server.Substring(0, server.IndexOf(",", StringComparison.Ordinal))
: server;
var portAddition = string.Empty;
if (server.Contains(","))
portAddition = server.Substring(server.IndexOf(",", StringComparison.Ordinal));
server = string.Format("{0}.database.windows.net{1}", serverName, portAddition);
}
if (ServerStartsWithTcp(server) == false)
server = string.Format("tcp:{0}.database.windows.net", server);
if (server.Contains(",") == false)
server = string.Format("{0},1433", server);
if (user.Contains("@") == false)
{
var userDomain = server;
if (ServerStartsWithTcp(server))
userDomain = userDomain.Substring(userDomain.IndexOf(":", StringComparison.Ordinal) + 1);
if (userDomain.Contains("."))
userDomain = userDomain.Substring(0, userDomain.IndexOf(".", StringComparison.Ordinal));
user = string.Format("{0}@{1}", user, userDomain);
}
return string.Format("Server={0};Database={1};User ID={2};Password={3}", server, databaseName, user, password);
}
private static bool ServerStartsWithTcp(string server)
{
return server.ToLower().StartsWith("tcp:".ToLower());
}
/// <summary>
/// Saves the connection string as a proper .net ConnectionString and the legacy AppSettings key/value.
/// </summary>
@@ -204,7 +252,7 @@ namespace Umbraco.Core
// Update connectionString if it exists, or else create a new appSetting for the given key and value
var setting = connectionstrings.Descendants("add").FirstOrDefault(s => s.Attribute("name").Value == GlobalSettings.UmbracoConnectionName);
if (setting == null)
connectionstrings.Add(new XElement("add",
connectionstrings.Add(new XElement("add",
new XAttribute("name", GlobalSettings.UmbracoConnectionName),
new XAttribute("connectionString", connectionStringSettings),
new XAttribute("providerName", providerName)));
@@ -216,7 +264,7 @@ namespace Umbraco.Core
xml.Save(fileName, SaveOptions.DisableFormatting);
LogHelper.Info<DatabaseContext>("Configured new ConnectionString: " + connectionString);
LogHelper.Info<DatabaseContext>("Configured a new ConnectionString using the '" + providerName + "' provider.");
}
/// <summary>
@@ -230,7 +278,8 @@ namespace Umbraco.Core
/// </remarks>
internal void Initialize()
{
if (ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName] != null)
var databaseSettings = ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName];
if (databaseSettings != null && string.IsNullOrWhiteSpace(databaseSettings.ConnectionString) == false && string.IsNullOrWhiteSpace(databaseSettings.ProviderName) == false)
{
var providerName = "System.Data.SqlClient";
if (!string.IsNullOrEmpty(ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName].ProviderName))
@@ -239,23 +288,46 @@ namespace Umbraco.Core
_connectionString =
ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName].ConnectionString;
}
if (providerName.StartsWith("MySql"))
Initialize(providerName);
}
else if (ConfigurationManager.AppSettings.ContainsKey(GlobalSettings.UmbracoConnectionName) && string.IsNullOrEmpty(ConfigurationManager.AppSettings[GlobalSettings.UmbracoConnectionName]) == false)
{
//A valid connectionstring does not exist, but the legacy appSettings key was found, so we'll reconfigure the conn.string.
var legacyConnString = ConfigurationManager.AppSettings[GlobalSettings.UmbracoConnectionName];
if (legacyConnString.ToLowerInvariant().Contains("sqlce4umbraco"))
{
SyntaxConfig.SqlSyntaxProvider = MySqlSyntax.Provider;
ConfigureEmbeddedDatabaseConnection();
}
else if (providerName.Contains("SqlServerCe"))
else if (legacyConnString.ToLowerInvariant().Contains("tcp:"))
{
SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider;
//Must be sql azure
SaveConnectionString(legacyConnString, "System.Data.SqlClient");
Initialize("System.Data.SqlClient");
}
else if (legacyConnString.ToLowerInvariant().Contains("datalayer=mysql"))
{
//Must be MySql
//Need to strip the datalayer part off
var connectionStringWithoutDatalayer = string.Empty;
foreach (var variable in legacyConnString.Split(';').Where(x => x.ToLowerInvariant().StartsWith("datalayer") == false))
connectionStringWithoutDatalayer = string.Format("{0}{1};", connectionStringWithoutDatalayer, variable);
SaveConnectionString(connectionStringWithoutDatalayer, "MySql.Data.MySqlClient");
Initialize("MySql.Data.MySqlClient");
}
else
{
SyntaxConfig.SqlSyntaxProvider = SqlServerSyntax.Provider;
//Must be sql
SaveConnectionString(legacyConnString, "System.Data.SqlClient");
Initialize("System.Data.SqlClient");
}
_configured = true;
//Remove the legacy connection string, so we don't end up in a loop if something goes wrong.
GlobalSettings.RemoveSetting(GlobalSettings.UmbracoConnectionName);
}
else
{
@@ -265,50 +337,136 @@ namespace Umbraco.Core
internal void Initialize(string providerName)
{
if (providerName.StartsWith("MySql"))
{
SyntaxConfig.SqlSyntaxProvider = MySqlSyntax.Provider;
}
else if (providerName.Contains("SqlServerCe"))
{
SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider;
}
else
{
SyntaxConfig.SqlSyntaxProvider = SqlServerSyntax.Provider;
}
_providerName = providerName;
_configured = true;
try
{
SqlSyntaxContext.SqlSyntaxProvider =
SqlSyntaxProvidersResolver.Current.GetByProviderNameOrDefault(providerName);
_configured = true;
}
catch (Exception e)
{
_configured = false;
LogHelper.Info<DatabaseContext>("Initialization of the DatabaseContext failed with following error: " + e.Message);
LogHelper.Info<DatabaseContext>(e.StackTrace);
}
}
internal DatabaseSchemaResult ValidateDatabaseSchema()
{
if (_configured == false || (string.IsNullOrEmpty(_connectionString) || string.IsNullOrEmpty(ProviderName)))
return new DatabaseSchemaResult();
if (_result == null)
{
var database = new UmbracoDatabase(_connectionString, ProviderName);
var dbSchema = new DatabaseSchemaCreation(database);
_result = dbSchema.ValidateSchema();
}
return _result;
}
internal Result CreateDatabaseSchemaAndDataOrUpgrade()
{
if (_configured == false || (string.IsNullOrEmpty(_connectionString) || string.IsNullOrEmpty(ProviderName)))
{
return new Result{Message = "Database configuration is invalid", Success = false, Percentage = "10"};
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"
};
}
try
{
LogHelper.Info<DatabaseContext>("Database configuration status: Started");
var message = string.Empty;
var database = new UmbracoDatabase(_connectionString, ProviderName);
//If Configuration Status is empty its a new install - otherwise upgrade the existing
if (string.IsNullOrEmpty(GlobalSettings.ConfigurationStatus))
var supportsCaseInsensitiveQueries = SqlSyntaxContext.SqlSyntaxProvider.SupportsCaseInsensitiveQueries(database);
if (supportsCaseInsensitiveQueries == false)
{
database.CreateDatabaseSchema();
message = "<p>&nbsp;</p><p>The database you're trying to use does not support case insensitive queries. <br />We currently do not support these types of databases.</p>" +
"<p>You can fix this by changing the following two settings in your my.ini file in your MySQL installation directory:</p>" +
"<pre>lower_case_table_names=1\nlower_case_file_system=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>";
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 two settings in your my.ini file in your MySQL installation directory:</p>" +
"<pre>lower_case_table_names=1\nlower_case_file_system=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
{
var configuredVersion = new Version(GlobalSettings.ConfigurationStatus);
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 two settings in the my.ini file in their MySQL installation directory:</p>" +
"<pre>lower_case_table_names=1\nlower_case_file_system=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>";
}
}
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>";
}
else
{
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>";
}
return new Result { Message = "Installation completed!", Success = true, Percentage = "100" };
LogHelper.Info<DatabaseContext>("Database configuration status: " + message);
return new Result { Message = message, Success = true, Percentage = "100" };
}
catch (Exception ex)
{
return new Result { Message = ex.Message, Success = false, Percentage = "90" };
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"
};
}
}
@@ -5,7 +5,7 @@ namespace Umbraco.Core.Dictionary
/// <summary>
/// Resolves the current CultureDictionaryFactory
/// </summary>
internal class CultureDictionaryFactoryResolver : SingleObjectResolverBase<CultureDictionaryFactoryResolver, ICultureDictionaryFactory>
internal sealed class CultureDictionaryFactoryResolver : SingleObjectResolverBase<CultureDictionaryFactoryResolver, ICultureDictionaryFactory>
{
internal CultureDictionaryFactoryResolver(ICultureDictionaryFactory factory)
: base(factory)
+218 -120
View File
@@ -9,35 +9,106 @@ using System.Xml.XPath;
using System.Collections;
using System.IO;
using System.Web;
using Umbraco.Core;
namespace Umbraco.Core.Dynamics
{
[TypeConverter(typeof(DynamicXmlConverter))]
public class DynamicXml : DynamicObject, IEnumerable<DynamicXml>, IEnumerable<XElement>
{
/// <summary>
/// Returns the XElement used to create the DynamicXml structure
/// </summary>
public XElement BaseElement { get; set; }
/// <summary>
/// Returns the raw XElement used to create the DynamicXml structure if one was specified otherwise returns the
/// same value as BaseElement.
/// </summary>
/// <remarks>
/// This is purely used for when an instance of DynamicXml is created with the overload that supports
/// passing in both a raw xml version and a dash-stripped xml version. Otherwise this value is exactly the
/// same as BaseElement.
/// </remarks>
public XElement RawXmlElement { get; internal set; }
/// <summary>
/// Constructor
/// </summary>
/// <param name="baseElement"></param>
public DynamicXml(XElement baseElement)
{
this.BaseElement = baseElement;
if (baseElement == null) return;
//same
RawXmlElement = baseElement;
BaseElement = baseElement;
}
public DynamicXml(string xml)
/// <summary>
/// When this constructor is used the BaseElement becomes equivalent to the strippedXml structure
/// </summary>
/// <param name="strippedXml"></param>
/// <param name="rawXml"></param>
internal DynamicXml(XElement strippedXml, XElement rawXml)
{
var baseElement = XElement.Parse(xml);
this.BaseElement = baseElement;
if (rawXml == null) return;
if (strippedXml == null) return;
RawXmlElement = rawXml;
BaseElement = strippedXml;
}
/// <summary>
/// When this constructor is used the BaseElement becomes equivalent to the strippedXml structure
/// </summary>
/// <param name="strippedXml"></param>
/// <param name="rawXml"></param>
internal DynamicXml(string strippedXml, string rawXml)
{
if (rawXml == null) return;
if (strippedXml == null) return;
RawXmlElement = XElement.Parse(rawXml);
BaseElement = XElement.Parse(strippedXml);
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="xml"></param>
public DynamicXml(string xml)
{
if (xml.IsNullOrWhiteSpace()) return;
var baseElement = XElement.Parse(xml);
//same
RawXmlElement = baseElement;
BaseElement = baseElement;
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="xpni"></param>
public DynamicXml(XPathNodeIterator xpni)
{
if (xpni != null)
{
if (xpni.Current != null)
{
var xml = xpni.Current.OuterXml;
var baseElement = XElement.Parse(xml);
this.BaseElement = baseElement;
}
}
if (xpni == null) return;
if (xpni.Current == null) return;
//TODO: OuterXml is really bad for performance! Should actually use the XPathNodeIterator api
var xml = xpni.Current.OuterXml;
var baseElement = XElement.Parse(xml);
//same
RawXmlElement = baseElement;
BaseElement = baseElement;
}
/// <summary>
/// Returns the InnertText based on the BaseElement object
/// </summary>
public string InnerText
{
get
@@ -45,17 +116,34 @@ namespace Umbraco.Core.Dynamics
return BaseElement.Value;
}
}
/// <summary>
/// Returns the string representation of the BaseElement object
/// </summary>
/// <returns></returns>
public string ToXml()
{
return BaseElement.ToString(SaveOptions.DisableFormatting);
}
/// <summary>
/// Returns the string representation of the RawXmlElement object
/// </summary>
/// <returns></returns>
public string ToRawXml()
{
return RawXmlElement.ToString(SaveOptions.DisableFormatting);
}
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
{
int index = 0;
if (indexes.Length > 0)
{
index = (int)indexes[0];
result = new DynamicXml(this.BaseElement.Elements().ToList()[index]);
result = new DynamicXml(
RawXmlElement.Elements().ElementAt(index),
BaseElement.Elements().ElementAt(index));
return true;
}
return base.TryGetIndex(binder, indexes, out result);
@@ -64,12 +152,12 @@ namespace Umbraco.Core.Dynamics
{
if (args.Length == 0 && binder.Name == "ToXml")
{
result = this.BaseElement.ToString();
result = BaseElement.ToString();
return true;
}
if (args.Length == 1 && binder.Name == "XPath")
{
var elements = this.BaseElement.XPathSelectElements(args[0].ToString());
var elements = BaseElement.XPathSelectElements(args[0].ToString());
HandleIEnumerableXElement(elements, out result);
return true; //anyway
}
@@ -102,7 +190,9 @@ namespace Umbraco.Core.Dynamics
}
else if (attempt.Result.ObjectResult is IEnumerable<DynamicXml>)
{
result = ((IEnumerable<DynamicXml>)attempt.Result.ObjectResult).Select(x => new DynamicXml(x.BaseElement));
result = ((IEnumerable<DynamicXml>) attempt.Result.ObjectResult).Select(x => new DynamicXml(
x.RawXmlElement,
x.BaseElement));
}
}
}
@@ -123,55 +213,102 @@ namespace Umbraco.Core.Dynamics
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (BaseElement == null || binder == null)
if (RawXmlElement == null || binder == null)
{
result = null;
return false;
}
//Go ahead and try to fetch all of the elements matching the member name, and wrap them
var elements = BaseElement.Elements(binder.Name);
if (!elements.Any() && BaseElement.Name == "root" && BaseElement.Elements().Count() == 1)
{
//no elements matched, lets try first child
elements = BaseElement.Elements().ElementAt(0).Elements(binder.Name);
}
if (HandleIEnumerableXElement(elements, out result))
{
return true;
}
else
{
//Ok, so no elements matched, so lets try attributes
IEnumerable<string> attributes = BaseElement.Attributes(binder.Name).Select(attr => attr.Value);
int count = attributes.Count();
if (count > 0)
//Check if the name matches a node based on the BaseElement (which if the correct ctor is used, will be dash stripped)
var elementByNameAttempt = CheckNodeNameMatch(binder.Name, BaseElement);
if (elementByNameAttempt.Success)
{
if (HandleIEnumerableXElement(elementByNameAttempt.Result, out result))
{
if (count > 1)
result = attributes; //more than one attribute matched, lets return the collection
else
result = attributes.FirstOrDefault(); //only one attribute matched, lets just return it
return true;
}
}
return true; // return true because we matched
//Check if the name matches a node based on the BaseElement (which if the correct ctor is used, will be dash stripped)
var attributeByNameAttempt = CheckAttributeNameMatch(binder.Name, BaseElement);
if (attributeByNameAttempt.Success)
{
if (attributeByNameAttempt.Result.Count() > 1)
{
//more than one attribute matched, lets return the collection
result = attributeByNameAttempt.Result;
}
else
{
//no attributes matched, lets try first child
if (BaseElement.Name == "root" && BaseElement.Elements().Count() == 1)
{
attributes = BaseElement.Elements().ElementAt(0).Attributes(binder.Name).Select(attr => attr.Value);
count = attributes.Count();
if (count > 1)
result = attributes; //more than one attribute matched, lets return the collection
else
result = attributes.FirstOrDefault(); //only one attribute matched, lets just return it
//only one attribute matched, lets just return it
result = attributeByNameAttempt.Result.FirstOrDefault();
}
return true;
}
return true; // return true because we matched
}
return base.TryGetMember(binder, out result);
}
/// <summary>
/// Checks if the 'name' matches any attributes of xmlElement
/// </summary>
/// <param name="name">The name to match</param>
/// <param name="xmlElement">The xml element to check against</param>
/// <returns></returns>
private static Attempt<IEnumerable<string>> CheckAttributeNameMatch(string name, XElement xmlElement)
{
var attributes = xmlElement.Attributes(name).Select(attr => attr.Value).ToArray();
if (attributes.Any())
{
return new Attempt<IEnumerable<string>>(true, attributes);
}
if (!attributes.Any() && xmlElement.Name == "root" && xmlElement.Elements().Count() == 1)
{
//no elements matched and this node is called 'root' and only has one child... lets see if it matches.
var childElements = xmlElement.Elements().ElementAt(0).Attributes(name).Select(attr => attr.Value).ToArray();
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);
}
}
//no deal
return Attempt<IEnumerable<string>>.False;
}
/// <summary>
/// Checks if the 'name' matches any elements of xmlElement
/// </summary>
/// <param name="name">The name to match</param>
/// <param name="xmlElement">The xml element to check against</param>
/// <returns></returns>
private Attempt<IEnumerable<XElement>> CheckNodeNameMatch(string name, XElement xmlElement)
{
//Go ahead and try to fetch all of the elements matching the member name, and wrap them
var elements = xmlElement.Elements(name).ToArray();
//Check if we've got any matches, if so then return true
if (elements.Any())
{
return new Attempt<IEnumerable<XElement>>(true, elements);
}
if (!elements.Any() && xmlElement.Name == "root" && xmlElement.Elements().Count() == 1)
{
//no elements matched and this node is called 'root' and only has one child... lets see if it matches.
var childElements = xmlElement.Elements().ElementAt(0).Elements(name).ToArray();
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 base.TryGetMember(binder, out result);
//no deal
return Attempt<IEnumerable<XElement>>.False;
}
private bool HandleIEnumerableXElement(IEnumerable<XElement> elements, out object result)
@@ -193,7 +330,7 @@ namespace Umbraco.Core.Dynamics
//We have more than one matching element, so let's return the collection
//elements is IEnumerable<DynamicXml>
//but we want to be able to re-enter this code
XElement root = new XElement(XName.Get("root"));
var root = new XElement(XName.Get("root"));
root.Add(elements);
result = new DynamicXml(root);
@@ -205,10 +342,16 @@ namespace Umbraco.Core.Dynamics
result = null;
return false;
}
/// <summary>
/// Executes an XPath expression over the BaseElement object
/// </summary>
/// <param name="expression"></param>
/// <returns></returns>
public DynamicXml XPath(string expression)
{
var matched = this.BaseElement.XPathSelectElements(expression);
DynamicXml root = new DynamicXml("<results/>");
var matched = BaseElement.XPathSelectElements(expression);
var root = new DynamicXml("<results/>");
foreach (var element in matched)
{
root.BaseElement.Add(element);
@@ -217,7 +360,7 @@ namespace Umbraco.Core.Dynamics
}
/// <summary>
/// Return the string version of Xml
/// Return the string version of the BaseElement object
/// </summary>
/// <returns></returns>
public override string ToString()
@@ -231,23 +374,23 @@ namespace Umbraco.Core.Dynamics
}
public DynamicXml Find(string expression)
{
return new DynamicXml(this.BaseElement.XPathSelectElements(expression).FirstOrDefault());
return new DynamicXml(BaseElement.XPathSelectElements(expression).FirstOrDefault());
}
public DynamicXml Find(string attributeName, object value)
{
string expression = string.Format("//*[{0}='{1}']", attributeName, value);
return new DynamicXml(this.BaseElement.XPathSelectElements(expression).FirstOrDefault());
return new DynamicXml(BaseElement.XPathSelectElements(expression).FirstOrDefault());
}
IEnumerator<XElement> IEnumerable<XElement>.GetEnumerator()
{
return this.BaseElement.Elements().GetEnumerator();
return BaseElement.Elements().GetEnumerator();
}
public IEnumerator<DynamicXml> GetEnumerator()
{
return this.BaseElement.Elements().Select(e => new DynamicXml(e)).GetEnumerator();
return BaseElement.Elements().Select(e => new DynamicXml(e)).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
@@ -310,7 +453,7 @@ namespace Umbraco.Core.Dynamics
}
public bool IsPosition(int index)
{
if (this.BaseElement == null || this.BaseElement.Parent == null)
if (BaseElement == null || BaseElement.Parent == null)
{
return false;
}
@@ -318,7 +461,7 @@ namespace Umbraco.Core.Dynamics
}
public HtmlString IsPosition(int index, string valueIfTrue)
{
if (this.BaseElement == null || this.BaseElement.Parent == null)
if (BaseElement == null || BaseElement.Parent == null)
{
return new HtmlString(string.Empty);
}
@@ -326,7 +469,7 @@ namespace Umbraco.Core.Dynamics
}
public HtmlString IsPosition(int index, string valueIfTrue, string valueIfFalse)
{
if (this.BaseElement == null || this.BaseElement.Parent == null)
if (BaseElement == null || BaseElement.Parent == null)
{
return new HtmlString(valueIfFalse);
}
@@ -334,7 +477,7 @@ namespace Umbraco.Core.Dynamics
}
public bool IsModZero(int modulus)
{
if (this.BaseElement == null || this.BaseElement.Parent == null)
if (BaseElement == null || BaseElement.Parent == null)
{
return false;
}
@@ -342,7 +485,7 @@ namespace Umbraco.Core.Dynamics
}
public HtmlString IsModZero(int modulus, string valueIfTrue)
{
if (this.BaseElement == null || this.BaseElement.Parent == null)
if (BaseElement == null || BaseElement.Parent == null)
{
return new HtmlString(string.Empty);
}
@@ -350,7 +493,7 @@ namespace Umbraco.Core.Dynamics
}
public HtmlString IsModZero(int modulus, string valueIfTrue, string valueIfFalse)
{
if (this.BaseElement == null || this.BaseElement.Parent == null)
if (BaseElement == null || BaseElement.Parent == null)
{
return new HtmlString(valueIfFalse);
}
@@ -359,7 +502,7 @@ namespace Umbraco.Core.Dynamics
public bool IsNotModZero(int modulus)
{
if (this.BaseElement == null || this.BaseElement.Parent == null)
if (BaseElement == null || BaseElement.Parent == null)
{
return false;
}
@@ -367,7 +510,7 @@ namespace Umbraco.Core.Dynamics
}
public HtmlString IsNotModZero(int modulus, string valueIfTrue)
{
if (this.BaseElement == null || this.BaseElement.Parent == null)
if (BaseElement == null || this.BaseElement.Parent == null)
{
return new HtmlString(string.Empty);
}
@@ -573,7 +716,8 @@ namespace Umbraco.Core.Dynamics
}
public IEnumerable<DynamicXml> Descendants(Func<XElement, bool> func)
{
var flattenedNodes = this.BaseElement.Elements().Map(func, (XElement n) => { return n.Elements(); });
//var flattenedNodes = this.BaseElement.Elements().Map(func, n => n.Elements());
var flattenedNodes = this.BaseElement.Elements().SelectMany(n => n.Elements()).Where(func);
return flattenedNodes.ToList().ConvertAll(n => new DynamicXml(n));
}
public IEnumerable<DynamicXml> DescendantsOrSelf()
@@ -582,7 +726,8 @@ namespace Umbraco.Core.Dynamics
}
public IEnumerable<DynamicXml> DescendantsOrSelf(Func<XElement, bool> func)
{
var flattenedNodes = this.BaseElement.Elements().Map(func, (XElement n) => { return n.Elements(); });
//var flattenedNodes = this.BaseElement.Elements().Map(func, n => n.Elements());
var flattenedNodes = this.BaseElement.Elements().SelectMany(n => n.Elements()).Where(func);
var list = new List<DynamicXml>();
list.Add(this);
list.AddRange(flattenedNodes.ToList().ConvertAll(n => new DynamicXml(n)));
@@ -689,57 +834,10 @@ namespace Umbraco.Core.Dynamics
return test(this) ? new HtmlString(valueIfTrue) : new HtmlString(valueIfFalse);
}
[Obsolete("Use XmlHelper.StripDashesInElementOrAttributeNames instead")]
public static string StripDashesInElementOrAttributeNames(string xml)
{
using (MemoryStream outputms = new MemoryStream())
{
using (TextWriter outputtw = new StreamWriter(outputms))
{
using (MemoryStream ms = new MemoryStream())
{
using (TextWriter tw = new StreamWriter(ms))
{
tw.Write(xml);
tw.Flush();
ms.Position = 0;
using (TextReader tr = new StreamReader(ms))
{
bool IsInsideElement = false, IsInsideQuotes = false;
int ic = 0;
while ((ic = tr.Read()) != -1)
{
if (ic == (int)'<' && !IsInsideQuotes)
{
if (tr.Peek() != (int)'!')
{
IsInsideElement = true;
}
}
if (ic == (int)'>' && !IsInsideQuotes)
{
IsInsideElement = false;
}
if (ic == (int)'"')
{
IsInsideQuotes = !IsInsideQuotes;
}
if (!IsInsideElement || ic != (int)'-' || IsInsideQuotes)
{
outputtw.Write((char)ic);
}
}
}
}
}
outputtw.Flush();
outputms.Position = 0;
using (TextReader outputtr = new StreamReader(outputms))
{
return outputtr.ReadToEnd();
}
}
}
return XmlHelper.StripDashesInElementOrAttributeNames(xml);
}
@@ -7,6 +7,58 @@ using System.Xml.Linq;
namespace Umbraco.Core.Dynamics
{
/// <summary>
/// Used to return the raw xml string value from DynamicXml when using type converters
/// </summary>
public class RawXmlString
{
public string Value { get; private set; }
public RawXmlString(string value)
{
Value = value;
}
}
/// <summary>
/// Used to return the raw xml XElement value from DynamicXml when using type converters
/// </summary>
public class RawXElement
{
public XElement Value { get; private set; }
public RawXElement(XElement value)
{
Value = value;
}
}
/// <summary>
/// Used to return the raw xml XElement value from DynamicXml when using type converters
/// </summary>
public class RawXmlElement
{
public XmlElement Value { get; private set; }
public RawXmlElement(XmlElement value)
{
Value = value;
}
}
/// <summary>
/// Used to return the raw xml XmlDocument value from DynamicXml when using type converters
/// </summary>
public class RawXmlDocument
{
public XmlDocument Value { get; private set; }
public RawXmlDocument(XmlDocument value)
{
Value = value;
}
}
/// <summary>
/// A custom type converter for DynamicXml
/// </summary>
@@ -14,7 +66,17 @@ namespace Umbraco.Core.Dynamics
{
public override bool CanConvertTo(ITypeDescriptorContext context, Type sourceType)
{
var convertableTypes = new[] {typeof(string), typeof(XElement), typeof(XmlElement), typeof(XmlDocument)};
var convertableTypes = new[]
{
typeof(string),
typeof(XElement),
typeof(XmlElement),
typeof(XmlDocument),
typeof(RawXmlString),
typeof(RawXElement),
typeof(RawXmlElement),
typeof(RawXmlDocument)
};
return convertableTypes.Any(x => TypeHelper.IsTypeAssignableFrom(x, sourceType))
|| base.CanConvertFrom(context, sourceType);
@@ -34,6 +96,7 @@ namespace Umbraco.Core.Dynamics
{
return value.ToString();
}
//XElement
if (TypeHelper.IsTypeAssignableFrom<XElement>(destinationType))
{
@@ -53,6 +116,34 @@ namespace Umbraco.Core.Dynamics
xDoc.LoadXml(dxml.ToString());
return xDoc;
}
//RAW values:
//string
if (TypeHelper.IsTypeAssignableFrom<RawXmlString>(destinationType))
{
return new RawXmlString(dxml.ToRawXml());
}
//XElement
if (TypeHelper.IsTypeAssignableFrom<RawXElement>(destinationType))
{
return new RawXElement(dxml.RawXmlElement);
}
//XmlElement
if (TypeHelper.IsTypeAssignableFrom<RawXmlElement>(destinationType))
{
var xDoc = new XmlDocument();
xDoc.LoadXml(dxml.ToRawXml());
return new RawXmlElement(xDoc.DocumentElement);
}
//XmlDocument
if (TypeHelper.IsTypeAssignableFrom<RawXmlDocument>(destinationType))
{
var xDoc = new XmlDocument();
xDoc.LoadXml(dxml.ToRawXml());
return new RawXmlDocument(xDoc);
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
+31 -28
View File
@@ -5,36 +5,35 @@ using Umbraco.Core.Models;
namespace Umbraco.Core.Dynamics
{
[Obsolete("This class should not be used, it is just referenced by already obsoleted code and will be removed in the future")]
internal static class ExtensionMethods
{
public static IEnumerable<TSource> Map<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> selectorFunction,
Func<TSource, IEnumerable<TSource>> getChildrenFunction)
{
if (!source.Any())
{
return source;
}
// Add what we have to the stack
var flattenedList = source.Where(selectorFunction);
// Go through the input enumerable looking for children,
// and add those if we have them
foreach (TSource element in source)
{
var secondInner = getChildrenFunction(element);
if (secondInner.Any())
{
secondInner = secondInner.Map(selectorFunction, getChildrenFunction);
}
flattenedList = flattenedList.Concat(secondInner);
}
return flattenedList;
}
//public static IEnumerable<TSource> Map<TSource>(
// this IEnumerable<TSource> source,
// Func<TSource, bool> selectorFunction,
// Func<TSource, IEnumerable<TSource>> getChildrenFunction)
//{
// if (!source.Any())
// {
// return source;
// }
// // Add what we have to the stack
// var flattenedList = source.Where(selectorFunction);
// // Go through the input enumerable looking for children,
// // and add those if we have them
// foreach (TSource element in source)
// {
// var secondInner = getChildrenFunction(element);
// if (secondInner.Any())
// {
// secondInner = secondInner.Map(selectorFunction, getChildrenFunction);
// }
// flattenedList = flattenedList.Concat(secondInner);
// }
// return flattenedList;
//}
[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");
@@ -44,6 +43,7 @@ namespace Umbraco.Core.Dynamics
}
return false;
}
[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");
@@ -53,6 +53,7 @@ namespace Umbraco.Core.Dynamics
}
return false;
}
[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");
@@ -62,6 +63,7 @@ namespace Umbraco.Core.Dynamics
}
return false;
}
[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");
@@ -71,12 +73,13 @@ namespace Umbraco.Core.Dynamics
}
return false;
}
[Obsolete("This method should not be used and will be removed in the future")]
public static bool ContainsInsensitive(this string haystack, string needle)
{
if (haystack == null) throw new ArgumentNullException("haystack");
return haystack.IndexOf(needle, StringComparison.CurrentCultureIgnoreCase) >= 0;
}
[Obsolete("This method should not be used and will be removed in the future")]
public static bool HasValue(this string s)
{
return !string.IsNullOrWhiteSpace(s);
@@ -0,0 +1,4 @@
namespace Umbraco.Core.Events
{
internal class DatabaseCreationEventArgs : System.ComponentModel.CancelEventArgs{}
}
@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Umbraco.Core.Events
{
// Provides information on the macro that caused an error
public class MacroErrorEventArgs : System.EventArgs
{
/// <summary>
/// Name of the faulting macro.
/// </summary>
public string Name { get; set; }
/// <summary>
/// Alias of the faulting macro.
/// </summary>
public string Alias { get; set; }
/// <summary>
/// Filename, file path, fully qualified class name, or other key used by the macro engine to do it's processing of the faulting macro.
/// </summary>
public string ItemKey { get; set; }
/// <summary>
/// Exception raised.
/// </summary>
public Exception Exception { get; set; }
/// <summary>
/// Gets or sets the desired behaviour when a matching macro causes an error. See
/// <see cref="MacroErrorBehaviour"/> for definitions. By setting this in your event
/// you can override the default behaviour defined in UmbracoSettings.config.
/// </summary>
/// <value>Macro error behaviour enum.</value>
public MacroErrorBehaviour Behaviour { get; set; }
}
}
+21
View File
@@ -1,3 +1,5 @@
using Umbraco.Core.Models;
namespace Umbraco.Core.Events
{
public class NewEventArgs<TEntity> : CancellableObjectEventArgs<TEntity>
@@ -8,12 +10,26 @@ namespace Umbraco.Core.Events
ParentId = parentId;
}
public NewEventArgs(TEntity eventObject, bool canCancel, string @alias, TEntity parent)
: base(eventObject, canCancel)
{
Alias = alias;
Parent = parent;
}
public NewEventArgs(TEntity eventObject, string @alias, int parentId) : base(eventObject)
{
Alias = alias;
ParentId = parentId;
}
public NewEventArgs(TEntity eventObject, string @alias, TEntity parent)
: base(eventObject)
{
Alias = alias;
Parent = parent;
}
/// <summary>
/// The entity being created
/// </summary>
@@ -31,5 +47,10 @@ namespace Umbraco.Core.Events
/// Gets or Sets the Id of the parent.
/// </summary>
public int ParentId { get; private set; }
/// <summary>
/// Gets or Sets the parent IContent object.
/// </summary>
public TEntity Parent { get; private set; }
}
}
@@ -1,9 +1,8 @@
using Umbraco.Core;
using umbraco.interfaces;
namespace Umbraco.Web
namespace Umbraco.Core
{
/// <summary>
/// <summary>
/// Custom IApplicationStartupHandler that auto subscribes to the applications events
/// </summary>
public interface IApplicationEventHandler : IApplicationStartupHandler
@@ -11,23 +10,23 @@ namespace Umbraco.Web
/// <summary>
/// ApplicationContext is created and other static objects that require initialization have been setup
/// </summary>
/// <param name="httpApplication"></param>
/// <param name="umbracoApplication"></param>
/// <param name="applicationContext"></param>
void OnApplicationInitialized(UmbracoApplication httpApplication, ApplicationContext applicationContext);
void OnApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext);
/// <summary>
/// All resolvers have been initialized but resolution is not frozen so they can be modified in this method
/// </summary>
/// <param name="httpApplication"></param>
/// <param name="umbracoApplication"></param>
/// <param name="applicationContext"></param>
void OnApplicationStarting(UmbracoApplication httpApplication, ApplicationContext applicationContext);
void OnApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext);
/// <summary>
/// Bootup is completed, this allows you to perform any other bootup logic required for the application.
/// Resolution is frozen so now they can be used to resolve instances.
/// </summary>
/// <param name="httpApplication"></param>
/// <param name="umbracoApplication"></param>
/// <param name="applicationContext"></param>
void OnApplicationStarted(UmbracoApplication httpApplication, ApplicationContext applicationContext);
void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext);
}
}
+63 -48
View File
@@ -8,6 +8,7 @@ using System.IO;
using System.Configuration;
using System.Web;
using System.Text.RegularExpressions;
using System.Xml;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
@@ -136,25 +137,42 @@ namespace Umbraco.Core.IO
}
/// <summary>
/// Validates if the current filepath matches a directory where the user is allowed to edit a file
/// Verifies that the current filepath matches a directory where the user is allowed to edit a file.
/// </summary>
/// <param name="filePath">filepath </param>
/// <param name="validDir"></param>
/// <returns>true if valid, throws a FileSecurityException if not</returns>
internal static bool ValidateEditPath(string filePath, string validDir)
/// <param name="filePath">The filepath to validate.</param>
/// <param name="validDir">The valid directory.</param>
/// <returns>A value indicating whether the filepath is valid.</returns>
internal static bool VerifyEditPath(string filePath, string validDir)
{
if (!filePath.StartsWith(MapPath(SystemDirectories.Root)))
filePath = MapPath(filePath);
if (!validDir.StartsWith(MapPath(SystemDirectories.Root)))
validDir = MapPath(validDir);
if (!filePath.StartsWith(validDir))
throw new FileSecurityException(String.Format("The filepath '{0}' is not within an allowed directory for this type of files", filePath.Replace(MapPath(SystemDirectories.Root), "")));
return filePath.StartsWith(validDir);
}
/// <summary>
/// Validates that the current filepath matches a directory where the user is allowed to edit a file.
/// </summary>
/// <param name="filePath">The filepath to validate.</param>
/// <param name="validDir">The valid directory.</param>
/// <returns>True, if the filepath is valid, else an exception is thrown.</returns>
/// <exception cref="FileSecurityException">The filepath is invalid.</exception>
internal static bool ValidateEditPath(string filePath, string validDir)
{
if (!VerifyEditPath(filePath, validDir))
throw new FileSecurityException(String.Format("The filepath '{0}' is not within an allowed directory for this type of files", filePath.Replace(MapPath(SystemDirectories.Root), "")));
return true;
}
internal static bool ValidateEditPath(string filePath, IEnumerable<string> validDirs)
/// <summary>
/// Verifies that the current filepath matches one of several directories where the user is allowed to edit a file.
/// </summary>
/// <param name="filePath">The filepath to validate.</param>
/// <param name="validDirs">The valid directories.</param>
/// <returns>A value indicating whether the filepath is valid.</returns>
internal static bool VerifyEditPath(string filePath, IEnumerable<string> validDirs)
{
foreach (var dir in validDirs)
{
@@ -168,19 +186,49 @@ namespace Umbraco.Core.IO
return true;
}
throw new FileSecurityException(String.Format("The filepath '{0}' is not within an allowed directory for this type of files", filePath.Replace(MapPath(SystemDirectories.Root), "")));
return false;
}
internal static bool ValidateFileExtension(string filePath, List<string> validFileExtensions)
/// <summary>
/// Validates that the current filepath matches one of several directories where the user is allowed to edit a file.
/// </summary>
/// <param name="filePath">The filepath to validate.</param>
/// <param name="validDirs">The valid directories.</param>
/// <returns>True, if the filepath is valid, else an exception is thrown.</returns>
/// <exception cref="FileSecurityException">The filepath is invalid.</exception>
internal static bool ValidateEditPath(string filePath, IEnumerable<string> validDirs)
{
if (!VerifyEditPath(filePath, validDirs))
throw new FileSecurityException(String.Format("The filepath '{0}' is not within an allowed directory for this type of files", filePath.Replace(MapPath(SystemDirectories.Root), "")));
return true;
}
/// <summary>
/// Verifies that the current filepath has one of several authorized extensions.
/// </summary>
/// <param name="filePath">The filepath to validate.</param>
/// <param name="validFileExtensions">The valid extensions.</param>
/// <returns>A value indicating whether the filepath is valid.</returns>
internal static bool VerifyFileExtension(string filePath, List<string> validFileExtensions)
{
if (!filePath.StartsWith(MapPath(SystemDirectories.Root)))
filePath = MapPath(filePath);
var f = new FileInfo(filePath);
return validFileExtensions.Contains(f.Extension.Substring(1));
}
if (!validFileExtensions.Contains(f.Extension.Substring(1)))
/// <summary>
/// Validates that the current filepath has one of several authorized extensions.
/// </summary>
/// <param name="filePath">The filepath to validate.</param>
/// <param name="validFileExtensions">The valid extensions.</param>
/// <returns>True, if the filepath is valid, else an exception is thrown.</returns>
/// <exception cref="FileSecurityException">The filepath is invalid.</exception>
internal static bool ValidateFileExtension(string filePath, List<string> validFileExtensions)
{
if (!VerifyFileExtension(filePath, validFileExtensions))
throw new FileSecurityException(String.Format("The extension for the current file '{0}' is not of an allowed type for this editor. This is typically controlled from either the installed MacroEngines or based on configuration in /config/umbracoSettings.config", filePath.Replace(MapPath(SystemDirectories.Root), "")));
return true;
}
@@ -215,41 +263,8 @@ namespace Umbraco.Core.IO
/// <returns>A safe filename without any path specific chars.</returns>
internal static string SafeFileName(string filePath)
{
if (String.IsNullOrEmpty(filePath))
return String.Empty;
if (!String.IsNullOrWhiteSpace(filePath))
{
foreach (var character in Path.GetInvalidFileNameChars())
{
filePath = filePath.Replace(character, '-');
}
}
else
{
filePath = String.Empty;
}
// Adapted from: http://stackoverflow.com/a/4827510/5018
// Combined both Reserved Characters and Character Data
// from http://en.wikipedia.org/wiki/Percent-encoding
var stringBuilder = new StringBuilder();
const string reservedCharacters = "!*'();:@&=+$,/?%#[]-~{}\"<>\\^`| ";
foreach (var character in filePath)
{
if (reservedCharacters.IndexOf(character) == -1)
stringBuilder.Append(character);
else
stringBuilder.Append("-");
}
// Remove repeating dashes
// From: http://stackoverflow.com/questions/5111967/regex-to-remove-a-specific-repeated-character
var reducedString = Regex.Replace(stringBuilder.ToString(), "-+", "-");
return reducedString;
// use string extensions
return filePath.ToSafeFileName();
}
}
}
+9 -2
View File
@@ -1,8 +1,6 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Umbraco.Core.CodeAnnotations;
using Umbraco.Core.Configuration;
namespace Umbraco.Core.IO
@@ -27,6 +25,15 @@ namespace Umbraco.Core.IO
return propertyId.ToString() + seperator + fileName;
}
public string GetRelativePath(string subfolder, string fileName)
{
var seperator = UmbracoSettings.UploadAllowDirectories
? Path.DirectorySeparatorChar
: '-';
return subfolder + seperator + fileName;
}
public IEnumerable<string> GetThumbnails(string path)
{
var parentDirectory = System.IO.Path.GetDirectoryName(path);
+14 -4
View File
@@ -183,16 +183,26 @@ namespace Umbraco.Core.IO
}
}
private static string _root;
/// <summary>
/// Gets the root path of the application
/// </summary>
public static string Root
{
get
{
string appPath = HttpRuntime.AppDomainAppVirtualPath ?? string.Empty;
if (appPath == "/")
appPath = string.Empty;
if (_root == null)
{
string appPath = HttpRuntime.AppDomainAppVirtualPath ?? string.Empty;
if (appPath == "/")
appPath = string.Empty;
return appPath;
_root = appPath;
}
return _root;
}
//Only required for unit tests
internal set { _root = value; }
}
}
+24
View File
@@ -0,0 +1,24 @@
namespace Umbraco.Core
{
public enum IconPickerBehaviour
{
/// <summary>
/// Default umbraco behavior - show duplicates in files and sprites
/// </summary>
ShowDuplicates,
/// <summary>
/// If a file exists on disk with the same name as one in the sprite
/// then the file on disk overrules the one in the sprite, the
/// sprite icon will not be shown
/// </summary>
HideSpriteDuplicates,
/// <summary>
/// If a file exists on disk with the same name as one in the sprite
/// then the file in the sprite overrules the one on disk, the file
/// on disk will be shown
/// </summary>
HideFileDuplicates
}
}
@@ -64,23 +64,28 @@ namespace Umbraco.Core.Logging
{
_forceStop = true;
var windowsIdentity = WindowsIdentity.GetCurrent();
base.Append(new LoggingEvent(new LoggingEventData
{
Level = Level.Error,
Message =
"Unable to clear out the AsynchronousRollingFileAppender buffer in the allotted time, forcing a shutdown",
TimeStamp = DateTime.UtcNow,
Identity = "",
ExceptionString = "",
UserName = windowsIdentity != null ? windowsIdentity.Name : "",
Domain = AppDomain.CurrentDomain.FriendlyName,
ThreadName = Thread.CurrentThread.ManagedThreadId.ToString(),
LocationInfo =
new LocationInfo(this.GetType().Name, "OnClose", "AsynchronousRollingFileAppender.cs", "59"),
LoggerName = this.GetType().FullName,
Properties = new PropertiesDictionary(),
})
);
var logEvent = new LoggingEvent(new LoggingEventData
{
Level = global::log4net.Core.Level.Error,
Message =
"Unable to clear out the AsynchronousRollingFileAppender buffer in the allotted time, forcing a shutdown",
TimeStamp = DateTime.UtcNow,
Identity = "",
ExceptionString = "",
UserName = windowsIdentity != null ? windowsIdentity.Name : "",
Domain = AppDomain.CurrentDomain.FriendlyName,
ThreadName = Thread.CurrentThread.ManagedThreadId.ToString(),
LocationInfo =
new LocationInfo(this.GetType().Name, "OnClose", "AsynchronousRollingFileAppender.cs", "59"),
LoggerName = this.GetType().FullName,
Properties = new PropertiesDictionary(),
});
if (this.DateTimeStrategy != null)
{
base.Append(logEvent);
}
}
base.OnClose();
+23
View File
@@ -0,0 +1,23 @@
namespace Umbraco.Core
{
public enum MacroErrorBehaviour
{
/// <summary>
/// Default umbraco behavior - show an inline error within the
/// macro but allow the page to continue rendering.
/// </summary>
Inline,
/// <summary>
/// Silently eat the error and do not display the offending macro.
/// </summary>
Silent,
/// <summary>
/// Throw an exception which can be caught by the global error handler
/// defined in Application_OnError. If no such error handler is defined
/// then you'll see the Yellow Screen Of Death (YSOD) error page.
/// </summary>
Throw
}
}
@@ -1,11 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using Umbraco.Core.Macros;
using System.Linq;
using Umbraco.Core.ObjectResolution;
using umbraco.interfaces;
namespace Umbraco.Core.ObjectResolution
namespace Umbraco.Core.Macros
{
/// <summary>
/// A resolver to return all IMacroGuiRendering objects
@@ -14,18 +16,16 @@ namespace Umbraco.Core.ObjectResolution
/// Much of this classes methods are based on legacy code from umbraco.editorControls.macrocontainer.MacroControlFactory
/// this code should probably be reviewed and cleaned up if necessary.
/// </remarks>
internal sealed class MacroFieldEditorsResolver : ManyObjectsResolverBase<MacroFieldEditorsResolver, IMacroGuiRendering>
internal sealed class MacroFieldEditorsResolver : LazyManyObjectsResolverBase<MacroFieldEditorsResolver, IMacroGuiRendering>
{
/// <summary>
/// Constructor
/// </summary>
/// <param name="macroEditors"></param>
internal MacroFieldEditorsResolver(IEnumerable<Type> macroEditors)
internal MacroFieldEditorsResolver(Func<IEnumerable<Type>> macroEditors)
: base(macroEditors, ObjectLifetimeScope.Transient)
{
}
{ }
/// <summary>
/// Gets the <see cref="IMacroGuiRendering"/> implementations.
@@ -56,7 +56,7 @@ namespace Umbraco.Core.ObjectResolution
/// </remarks>
internal List<Type> MacroControlTypes
{
get { return InstanceTypes; }
get { return InstanceTypes.ToList(); }
}
/// <summary>
@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Umbraco.Core.IO;
namespace Umbraco.Core.Media
{
/// <summary>
/// Internal singleton to handle the numbering of subfolders within the Media-folder.
/// When this class is initiated it will look for numbered subfolders and select the highest number,
/// which will be the start point for the naming of the next subfolders. If no subfolders exists
/// then the starting point will be 1000, ie. /media/1000/koala.jpg
/// </summary>
internal class MediaSubfolderCounter
{
#region Singleton
private long _numberedFolder = 1000;//Default starting point
private static readonly ReaderWriterLockSlim ClearLock = new ReaderWriterLockSlim();
private static readonly Lazy<MediaSubfolderCounter> Lazy = new Lazy<MediaSubfolderCounter>(() => new MediaSubfolderCounter());
public static MediaSubfolderCounter Current { get { return Lazy.Value; } }
private MediaSubfolderCounter()
{
var folders = new List<long>();
var fs = FileSystemProviderManager.Current.GetFileSystemProvider<MediaFileSystem>();
var directories = fs.GetDirectories("");
foreach (var directory in directories)
{
long dirNum;
if (long.TryParse(directory, out dirNum))
{
folders.Add(dirNum);
}
}
var last = folders.OrderBy(x => x).LastOrDefault();
if(last != default(long))
_numberedFolder = last;
}
#endregion
/// <summary>
/// Returns an increment of the numbered media subfolders.
/// </summary>
/// <returns>A <see cref="System.Int64"/> value</returns>
public long Increment()
{
using (new ReadLock(ClearLock))
{
_numberedFolder = _numberedFolder + 1;
return _numberedFolder;
}
}
}
}
+45 -25
View File
@@ -1,7 +1,9 @@
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models
{
@@ -101,8 +103,11 @@ namespace Umbraco.Core.Models
}
set
{
_template = value;
OnPropertyChanged(TemplateSelector);
SetPropertyValueAndDetectChanges(o =>
{
_template = value;
return _template;
}, _template, TemplateSelector);
}
}
@@ -140,8 +145,11 @@ namespace Umbraco.Core.Models
get { return _published; }
internal set
{
_published = value;
OnPropertyChanged(PublishedSelector);
SetPropertyValueAndDetectChanges(o =>
{
_published = value;
return _published;
}, _published, PublishedSelector);
}
}
@@ -157,8 +165,11 @@ namespace Umbraco.Core.Models
get { return _language; }
set
{
_language = value;
OnPropertyChanged(LanguageSelector);
SetPropertyValueAndDetectChanges(o =>
{
_language = value;
return _language;
}, _language, LanguageSelector);
}
}
@@ -171,8 +182,11 @@ namespace Umbraco.Core.Models
get { return _releaseDate; }
set
{
_releaseDate = value;
OnPropertyChanged(ReleaseDateSelector);
SetPropertyValueAndDetectChanges(o =>
{
_releaseDate = value;
return _releaseDate;
}, _releaseDate, ReleaseDateSelector);
}
}
@@ -185,8 +199,11 @@ namespace Umbraco.Core.Models
get { return _expireDate; }
set
{
_expireDate = value;
OnPropertyChanged(ExpireDateSelector);
SetPropertyValueAndDetectChanges(o =>
{
_expireDate = value;
return _expireDate;
}, _expireDate, ExpireDateSelector);
}
}
@@ -199,8 +216,11 @@ namespace Umbraco.Core.Models
get { return _writer; }
set
{
_writer = value;
OnPropertyChanged(WriterSelector);
SetPropertyValueAndDetectChanges(o =>
{
_writer = value;
return _writer;
}, _writer, WriterSelector);
}
}
@@ -215,8 +235,11 @@ namespace Umbraco.Core.Models
get { return _nodeName; }
set
{
_nodeName = value;
OnPropertyChanged(NodeNameSelector);
SetPropertyValueAndDetectChanges(o =>
{
_nodeName = value;
return _nodeName;
}, _nodeName, NodeNameSelector);
}
}
@@ -280,19 +303,10 @@ namespace Umbraco.Core.Models
/// </summary>
/// <param name="isTrashed">Boolean indicating whether content is trashed (true) or not trashed (false)</param>
/// <param name="parentId"> </param>
public override void ChangeTrashedState(bool isTrashed, int parentId = -1)
public override void ChangeTrashedState(bool isTrashed, int parentId = -20)
{
Trashed = isTrashed;
//If Content is trashed the parent id should be set to that of the RecycleBin
if(isTrashed)
{
ParentId = -20;
}
else//otherwise set the parent id to the optional parameter, -1 being the fallback
{
ParentId = parentId;
}
ParentId = parentId;
//If the content is trashed and is published it should be marked as unpublished
if (isTrashed && Published)
@@ -312,6 +326,12 @@ namespace Umbraco.Core.Models
clone.Version = Guid.NewGuid();
clone.ResetIdentity();
foreach (var property in clone.Properties)
{
property.ResetIdentity();
property.Version = clone.Version;
}
return clone;
}
+38 -15
View File
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
@@ -13,6 +14,7 @@ namespace Umbraco.Core.Models
/// <summary>
/// Represents an abstract class for base Content properties and methods
/// </summary>
[DebuggerDisplay("Id: {Id}, Name: {Name}, ContentType: {ContentTypeBase.Alias}")]
public abstract class ContentBase : Entity, IContentBase
{
protected IContentTypeComposition ContentTypeBase;
@@ -118,8 +120,11 @@ namespace Umbraco.Core.Models
get { return _name; }
set
{
_name = value;
OnPropertyChanged(NameSelector);
SetPropertyValueAndDetectChanges(o =>
{
_name = value;
return _name;
}, _name, NameSelector);
}
}
@@ -132,8 +137,11 @@ namespace Umbraco.Core.Models
get { return _sortOrder; }
set
{
_sortOrder = value;
OnPropertyChanged(SortOrderSelector);
SetPropertyValueAndDetectChanges(o =>
{
_sortOrder = value;
return _sortOrder;
}, _sortOrder, SortOrderSelector);
}
}
@@ -146,8 +154,11 @@ namespace Umbraco.Core.Models
get { return _level; }
set
{
_level = value;
OnPropertyChanged(LevelSelector);
SetPropertyValueAndDetectChanges(o =>
{
_level = value;
return _level;
}, _level, LevelSelector);
}
}
@@ -160,8 +171,11 @@ namespace Umbraco.Core.Models
get { return _path; }
set
{
_path = value;
OnPropertyChanged(PathSelector);
SetPropertyValueAndDetectChanges(o =>
{
_path = value;
return _path;
}, _path, PathSelector);
}
}
@@ -174,8 +188,11 @@ namespace Umbraco.Core.Models
get { return _creatorId; }
set
{
_creatorId = value;
OnPropertyChanged(CreatorIdSelector);
SetPropertyValueAndDetectChanges(o =>
{
_creatorId = value;
return _creatorId;
}, _creatorId, CreatorIdSelector);
}
}
@@ -190,8 +207,11 @@ namespace Umbraco.Core.Models
get { return _trashed; }
internal set
{
_trashed = value;
OnPropertyChanged(TrashedSelector);
SetPropertyValueAndDetectChanges(o =>
{
_trashed = value;
return _trashed;
}, _trashed, TrashedSelector);
}
}
@@ -210,8 +230,11 @@ namespace Umbraco.Core.Models
get { return _contentTypeId; }
protected set
{
_contentTypeId = value;
OnPropertyChanged(DefaultContentTypeIdSelector);
SetPropertyValueAndDetectChanges(o =>
{
_contentTypeId = value;
return _contentTypeId;
}, _contentTypeId, DefaultContentTypeIdSelector);
}
}
@@ -401,6 +424,6 @@ namespace Umbraco.Core.Models
return Properties.Any(property => !property.IsValid()) == false;
}
public abstract void ChangeTrashedState(bool isTrashed, int parentId = -1);
public abstract void ChangeTrashedState(bool isTrashed, int parentId = -20);
}
}
+262 -111
View File
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
@@ -10,7 +11,9 @@ using System.Xml;
using System.Xml.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
using Umbraco.Core.Media;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Strings;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.UnitOfWork;
@@ -18,6 +21,90 @@ namespace Umbraco.Core.Models
{
public static class ContentExtensions
{
#region IContent
/// <summary>
/// Returns a list of the current contents ancestors, not including the content itself.
/// </summary>
/// <param name="content">Current content</param>
/// <returns>An enumerable list of <see cref="IContent"/> objects</returns>
public static IEnumerable<IContent> Ancestors(this IContent content)
{
return ApplicationContext.Current.Services.ContentService.GetAncestors(content);
}
/// <summary>
/// Returns a list of the current contents children.
/// </summary>
/// <param name="content">Current content</param>
/// <returns>An enumerable list of <see cref="IContent"/> objects</returns>
public static IEnumerable<IContent> Children(this IContent content)
{
return ApplicationContext.Current.Services.ContentService.GetChildren(content.Id);
}
/// <summary>
/// Returns a list of the current contents descendants, not including the content itself.
/// </summary>
/// <param name="content">Current content</param>
/// <returns>An enumerable list of <see cref="IContent"/> objects</returns>
public static IEnumerable<IContent> Descendants(this IContent content)
{
return ApplicationContext.Current.Services.ContentService.GetDescendants(content);
}
/// <summary>
/// Returns the parent of the current content.
/// </summary>
/// <param name="content">Current content</param>
/// <returns>An <see cref="IContent"/> object</returns>
public static IContent Parent(this IContent content)
{
return ApplicationContext.Current.Services.ContentService.GetById(content.ParentId);
}
#endregion
#region IMedia
/// <summary>
/// Returns a list of the current medias ancestors, not including the media itself.
/// </summary>
/// <param name="media">Current media</param>
/// <returns>An enumerable list of <see cref="IMedia"/> objects</returns>
public static IEnumerable<IMedia> Ancestors(this IMedia media)
{
return ApplicationContext.Current.Services.MediaService.GetAncestors(media);
}
/// <summary>
/// Returns a list of the current medias children.
/// </summary>
/// <param name="media">Current media</param>
/// <returns>An enumerable list of <see cref="IMedia"/> objects</returns>
public static IEnumerable<IMedia> Children(this IMedia media)
{
return ApplicationContext.Current.Services.MediaService.GetChildren(media.Id);
}
/// <summary>
/// Returns a list of the current medias descendants, not including the media itself.
/// </summary>
/// <param name="media">Current media</param>
/// <returns>An enumerable list of <see cref="IMedia"/> objects</returns>
public static IEnumerable<IMedia> Descendants(this IMedia media)
{
return ApplicationContext.Current.Services.MediaService.GetDescendants(media);
}
/// <summary>
/// Returns the parent of the current media.
/// </summary>
/// <param name="media">Current media</param>
/// <returns>An <see cref="IMedia"/> object</returns>
public static IMedia Parent(this IMedia media)
{
return ApplicationContext.Current.Services.MediaService.GetById(media.ParentId);
}
#endregion
/// <summary>
/// Set property values by alias with an annonymous object
/// </summary>
@@ -54,68 +141,25 @@ namespace Umbraco.Core.Models
}
}
/*
/// <summary>
/// Sets and uploads the file from a HttpPostedFileBase object as the property value
/// </summary>
/// <param name="media"><see cref="IMedia"/> to add property value to</param>
/// <param name="propertyTypeAlias">Alias of the property to save the value on</param>
/// <param name="value">The <see cref="HttpPostedFileBase"/> containing the file that will be uploaded</param>
public static void SetPropertyValue(this IMedia media, string propertyTypeAlias, HttpPostedFileBase value)
{
var name =
IOHelper.SafeFileName(
value.FileName.Substring(value.FileName.LastIndexOf(IOHelper.DirSepChar) + 1,
value.FileName.Length - value.FileName.LastIndexOf(IOHelper.DirSepChar) - 1)
.ToLower());
if(string.IsNullOrEmpty(name) == false)
SetFileOnContent(media, propertyTypeAlias, name, value.InputStream);
}
/// <summary>
/// Sets and uploads the file from a HttpPostedFile object as the property value
/// </summary>
/// <param name="media"><see cref="IMedia"/> to add property value to</param>
/// <param name="propertyTypeAlias">Alias of the property to save the value on</param>
/// <param name="value">The <see cref="HttpPostedFile"/> containing the file that will be uploaded</param>
public static void SetPropertyValue(this IMedia media, string propertyTypeAlias, HttpPostedFile value)
{
var name =
IOHelper.SafeFileName(
value.FileName.Substring(value.FileName.LastIndexOf(IOHelper.DirSepChar) + 1,
value.FileName.Length - value.FileName.LastIndexOf(IOHelper.DirSepChar) - 1)
.ToLower());
if (string.IsNullOrEmpty(name) == false)
SetFileOnContent(media, propertyTypeAlias, name, value.InputStream);
}
/// <summary>
/// Sets and uploads the file from a HttpPostedFileWrapper object as the property value
/// </summary>
/// <param name="media"><see cref="IMedia"/> to add property value to</param>
/// <param name="propertyTypeAlias">Alias of the property to save the value on</param>
/// <param name="value">The <see cref="HttpPostedFileWrapper"/> containing the file that will be uploaded</param>
public static void SetPropertyValue(this IMedia media, string propertyTypeAlias, HttpPostedFileWrapper value)
{
if (string.IsNullOrEmpty(value.FileName) == false)
SetFileOnContent(media, propertyTypeAlias, value.FileName, value.InputStream);
}
*/
/// <summary>
/// Sets and uploads the file from a HttpPostedFileBase object as the property value
/// </summary>
/// <param name="content"><see cref="IContent"/> to add property value to</param>
/// <param name="content"><see cref="IContentBase"/> to add property value to</param>
/// <param name="propertyTypeAlias">Alias of the property to save the value on</param>
/// <param name="value">The <see cref="HttpPostedFileBase"/> containing the file that will be uploaded</param>
public static void SetValue(this IContentBase content, string propertyTypeAlias, HttpPostedFileBase value)
{
// Ensure we get the filename without the path in IE in intranet mode
// http://stackoverflow.com/questions/382464/httppostedfile-filename-different-from-ie
var fileName = value.FileName;
if (fileName.LastIndexOf(@"\") > 0)
fileName = fileName.Substring(fileName.LastIndexOf(@"\") + 1);
var name =
IOHelper.SafeFileName(
value.FileName.Substring(value.FileName.LastIndexOf(IOHelper.DirSepChar) + 1,
value.FileName.Length - value.FileName.LastIndexOf(IOHelper.DirSepChar) - 1)
.ToLower());
fileName.Substring(fileName.LastIndexOf(IOHelper.DirSepChar) + 1,
fileName.Length - fileName.LastIndexOf(IOHelper.DirSepChar) - 1)
.ToLower());
if (string.IsNullOrEmpty(name) == false)
SetFileOnContent(content, propertyTypeAlias, name, value.InputStream);
@@ -124,16 +168,22 @@ namespace Umbraco.Core.Models
/// <summary>
/// Sets and uploads the file from a HttpPostedFile object as the property value
/// </summary>
/// <param name="content"><see cref="IContent"/> to add property value to</param>
/// <param name="content"><see cref="IContentBase"/> to add property value to</param>
/// <param name="propertyTypeAlias">Alias of the property to save the value on</param>
/// <param name="value">The <see cref="HttpPostedFile"/> containing the file that will be uploaded</param>
public static void SetValue(this IContentBase content, string propertyTypeAlias, HttpPostedFile value)
{
// Ensure we get the filename without the path in IE in intranet mode
// http://stackoverflow.com/questions/382464/httppostedfile-filename-different-from-ie
var fileName = value.FileName;
if (fileName.LastIndexOf(@"\") > 0)
fileName = fileName.Substring(fileName.LastIndexOf(@"\") + 1);
var name =
IOHelper.SafeFileName(
value.FileName.Substring(value.FileName.LastIndexOf(IOHelper.DirSepChar) + 1,
value.FileName.Length - value.FileName.LastIndexOf(IOHelper.DirSepChar) - 1)
.ToLower());
fileName.Substring(fileName.LastIndexOf(IOHelper.DirSepChar) + 1,
fileName.Length - fileName.LastIndexOf(IOHelper.DirSepChar) - 1)
.ToLower());
if (string.IsNullOrEmpty(name) == false)
SetFileOnContent(content, propertyTypeAlias, name, value.InputStream);
@@ -142,26 +192,52 @@ namespace Umbraco.Core.Models
/// <summary>
/// Sets and uploads the file from a HttpPostedFileWrapper object as the property value
/// </summary>
/// <param name="content"><see cref="IContent"/> to add property value to</param>
/// <param name="content"><see cref="IContentBase"/> to add property value to</param>
/// <param name="propertyTypeAlias">Alias of the property to save the value on</param>
/// <param name="value">The <see cref="HttpPostedFileWrapper"/> containing the file that will be uploaded</param>
public static void SetValue(this IContentBase content, string propertyTypeAlias, HttpPostedFileWrapper value)
{
if (string.IsNullOrEmpty(value.FileName) == false)
SetFileOnContent(content, propertyTypeAlias, value.FileName, value.InputStream);
// Ensure we get the filename without the path in IE in intranet mode
// http://stackoverflow.com/questions/382464/httppostedfile-filename-different-from-ie
var fileName = value.FileName;
if (fileName.LastIndexOf(@"\") > 0)
fileName = fileName.Substring(fileName.LastIndexOf(@"\") + 1);
var name = IOHelper.SafeFileName(fileName);
if (string.IsNullOrEmpty(name) == false)
SetFileOnContent(content, propertyTypeAlias, name, value.InputStream);
}
/// <summary>
/// Sets and uploads the file from a <see cref="Stream"/> as the property value
/// </summary>
/// <param name="content"><see cref="IContentBase"/> to add property value to</param>
/// <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)
{
var name = IOHelper.SafeFileName(fileName);
if (string.IsNullOrEmpty(name) == false && fileStream != null)
SetFileOnContent(content, propertyTypeAlias, name, fileStream);
}
private static void SetFileOnContent(IContentBase content, string propertyTypeAlias, string name, Stream fileStream)
{
var property = content.Properties.FirstOrDefault(x => x.Alias == propertyTypeAlias);
if(property == null)
if (property == null)
return;
bool supportsResizing = false;
var numberedFolder = MediaSubfolderCounter.Current.Increment();
string fileName = UmbracoSettings.UploadAllowDirectories
? Path.Combine(property.Id.ToString(), name)
: property.Id + "-" + name;
string extension = Path.GetExtension(name);
? Path.Combine(numberedFolder.ToString(CultureInfo.InvariantCulture), name)
: numberedFolder + "-" + name;
string extension = Path.GetExtension(name).Substring(1).ToLowerInvariant();
var fs = FileSystemProviderManager.Current.GetFileSystemProvider<MediaFileSystem>();
fs.AddFile(fileName, fileStream);
@@ -175,7 +251,7 @@ namespace Umbraco.Core.Models
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("5032a6e6-69e3-491d-bb28-cd31cd11086c");
var uploadFieldId = new Guid(Constants.PropertyEditors.UploadField);
if (property.PropertyType.DataTypeId == uploadFieldId)
{
//Get Prevalues by the DataType's Id: property.PropertyType.DataTypeId
@@ -204,7 +280,7 @@ namespace Umbraco.Core.Models
XmlNode uploadFieldConfigNode =
UmbracoSettings.ImageAutoFillImageProperties.SelectSingleNode(
string.Format("uploadField [@alias = \"{0}\"]", propertyTypeAlias));
if (uploadFieldConfigNode != null)
{
//Only add dimensions to web images
@@ -231,12 +307,12 @@ namespace Umbraco.Core.Models
private static void SetPropertyValue(IContentBase content, XmlNode uploadFieldConfigNode, string propertyAlias, string propertyValue)
{
XmlNode propertyNode = uploadFieldConfigNode.SelectSingleNode(propertyAlias);
if (propertyNode != null && string.IsNullOrEmpty(propertyNode.FirstChild.Value) == false)
if (propertyNode != null && string.IsNullOrEmpty(propertyNode.FirstChild.Value) == false && content.HasProperty(propertyNode.FirstChild.Value))
{
content.SetValue(propertyNode.FirstChild.Value, propertyValue);
}
}
private static string Resize(MediaFileSystem fileSystem, string path, string extension, int maxWidthHeight, string fileNameAddition)
{
var fileNameThumb = DoResize(fileSystem, path, extension, GetDimensions(fileSystem, path).Item1, GetDimensions(fileSystem, path).Item2, maxWidthHeight, fileNameAddition);
@@ -347,16 +423,20 @@ namespace Umbraco.Core.Models
return new Tuple<int, int, string>(widthTh, heightTh, newFileName);
}
/// <summary>
/// Gets the <see cref="IProfile"/> for the Creator of this media item.
/// </summary>
public static IProfile GetCreatorProfile(this IMedia media)
{
return ApplicationContext.Current.Services.UserService.GetProfileById(media.CreatorId);
}
/// <summary>
/// Gets the <see cref="IProfile"/> for the Creator of this content.
/// Gets the <see cref="IProfile"/> for the Creator of this content item.
/// </summary>
public static IProfile GetCreatorProfile(this IContent content)
public static IProfile GetCreatorProfile(this IContentBase content)
{
using (var repository = RepositoryResolver.Current.Factory.CreateUserRepository(
PetaPocoUnitOfWorkProvider.CreateUnitOfWork()))
{
return repository.GetProfileById(content.CreatorId);
}
return ApplicationContext.Current.Services.UserService.GetProfileById(content.CreatorId);
}
/// <summary>
@@ -364,11 +444,7 @@ namespace Umbraco.Core.Models
/// </summary>
public static IProfile GetWriterProfile(this IContent content)
{
using(var repository = RepositoryResolver.Current.Factory.CreateUserRepository(
PetaPocoUnitOfWorkProvider.CreateUnitOfWork()))
{
return repository.GetProfileById(content.WriterId);
}
return ApplicationContext.Current.Services.UserService.GetProfileById(content.WriterId);
}
/// <summary>
@@ -384,6 +460,47 @@ namespace Umbraco.Core.Models
return ApplicationContext.Current.Services.ContentService.HasPublishedVersion(content.Id);
}
/// <summary>
/// Creates the full xml representation for the <see cref="IContent"/> object and all of it's descendants
/// </summary>
/// <param name="content"><see cref="IContent"/> to generate xml for</param>
/// <returns>Xml representation of the passed in <see cref="IContent"/></returns>
internal static XElement ToDeepXml(this IContent content)
{
var xml = content.ToXml();
var descendants = content.Descendants().ToArray();
var currentChildren = descendants.Where(x => x.ParentId == content.Id);
AddChildXml(descendants, currentChildren, xml);
return xml;
}
/// <summary>
/// Used by ToDeepXml to recursively add children
/// </summary>
/// <param name="originalDescendants"></param>
/// <param name="currentChildren"></param>
/// <param name="currentXml"></param>
private static void AddChildXml(
IContent[] originalDescendants,
IEnumerable<IContent> currentChildren,
XElement currentXml)
{
foreach (var child in currentChildren)
{
//add the child's xml
var childXml = child.ToXml();
currentXml.Add(childXml);
//copy local (out of closure)
var c = child;
//get this item's children
var children = originalDescendants.Where(x => x.ParentId == c.Id);
//recurse and add it's children to the child xml element
AddChildXml(originalDescendants, children, childXml);
}
}
/// <summary>
/// Creates the xml representation for the <see cref="IContent"/> object
/// </summary>
@@ -391,43 +508,77 @@ namespace Umbraco.Core.Models
/// <returns>Xml representation of the passed in <see cref="IContent"/></returns>
public static XElement ToXml(this IContent content)
{
//nodeName should match Casing.SafeAliasWithForcingCheck(content.ContentType.Alias);
//var nodeName = content.ContentType.Alias.ToUmbracoAlias(StringAliasCaseType.CamelCase, true);
var nodeName = content.ContentType.Alias;
var niceUrl = content.Name.FormatUrl().ToLower();
//nodeName should match Casing.SafeAliasWithForcingCheck(content.ContentType.Alias);
var nodeName = UmbracoSettings.UseLegacyXmlSchema ? "node" : content.ContentType.Alias.ToSafeAliasWithForcingCheck();
var xml = new XElement(nodeName,
new XAttribute("id", content.Id),
new XAttribute("parentID", content.Level > 1 ? content.ParentId : -1),
new XAttribute("level", content.Level),
new XAttribute("writerID", content.WriterId),
new XAttribute("creatorID", content.CreatorId),
new XAttribute("nodeType", content.ContentType.Id),
new XAttribute("template", content.Template == null ? "0" : content.Template.Id.ToString()),
new XAttribute("sortOrder", content.SortOrder),
new XAttribute("createDate", content.CreateDate.ToString("s")),
new XAttribute("updateDate", content.UpdateDate.ToString("s")),
new XAttribute("nodeName", content.Name),
new XAttribute("urlName", niceUrl),//Format Url ?
new XAttribute("writerName", content.GetWriterProfile().Name),
new XAttribute("creatorName", content.GetCreatorProfile().Name),
new XAttribute("path", content.Path),
new XAttribute("isDoc", ""));
foreach (var property in content.Properties)
var x = content.ToXml(nodeName);
x.Add(new XAttribute("nodeType", content.ContentType.Id));
x.Add(new XAttribute("creatorName", content.GetCreatorProfile().Name));
x.Add(new XAttribute("writerName", content.GetWriterProfile().Name));
x.Add(new XAttribute("writerID", content.WriterId));
x.Add(new XAttribute("template", content.Template == null ? "0" : content.Template.Id.ToString()));
if (UmbracoSettings.UseLegacyXmlSchema)
{
if (property == null) continue;
xml.Add(property.ToXml());
//Check for umbracoUrlName convention
if (property.Alias == "umbracoUrlName" && property.Value.ToString().Trim() != string.Empty)
xml.SetAttributeValue("urlName", property.Value);
x.Add(new XAttribute("nodeTypeAlias", content.ContentType.Alias));
}
return xml;
return x;
}
/// <summary>
/// Creates the xml representation for the <see cref="IMedia"/> object
/// </summary>
/// <param name="media"><see cref="IContent"/> to generate xml for</param>
/// <returns>Xml representation of the passed in <see cref="IContent"/></returns>
public static XElement ToXml(this IMedia media)
{
//nodeName should match Casing.SafeAliasWithForcingCheck(content.ContentType.Alias);
var nodeName = UmbracoSettings.UseLegacyXmlSchema ? "node" : media.ContentType.Alias.ToSafeAliasWithForcingCheck();
var x = media.ToXml(nodeName);
x.Add(new XAttribute("nodeType", media.ContentType.Id));
x.Add(new XAttribute("writerName", media.GetCreatorProfile().Name));
x.Add(new XAttribute("writerID", media.CreatorId));
x.Add(new XAttribute("version", media.Version));
x.Add(new XAttribute("template", 0));
if (UmbracoSettings.UseLegacyXmlSchema)
{
x.Add(new XAttribute("nodeTypeAlias", media.ContentType.Alias));
}
return x;
}
/// <summary>
/// Creates the xml representation for the <see cref="IContentBase"/> object
/// </summary>
/// <param name="contentBase"><see cref="IContent"/> to generate xml for</param>
/// <param name="nodeName"></param>
/// <returns>Xml representation of the passed in <see cref="IContent"/></returns>
private static XElement ToXml(this IContentBase contentBase, string nodeName)
{
// note: that one will take care of umbracoUrlName
var url = contentBase.GetUrlSegment();
var xml = new XElement(nodeName,
new XAttribute("id", contentBase.Id),
new XAttribute("parentID", contentBase.Level > 1 ? contentBase.ParentId : -1),
new XAttribute("level", contentBase.Level),
new XAttribute("creatorID", contentBase.CreatorId),
new XAttribute("sortOrder", contentBase.SortOrder),
new XAttribute("createDate", contentBase.CreateDate.ToString("s")),
new XAttribute("updateDate", contentBase.UpdateDate.ToString("s")),
new XAttribute("nodeName", contentBase.Name),
new XAttribute("urlName", url),
new XAttribute("path", contentBase.Path),
new XAttribute("isDoc", ""));
foreach (var property in contentBase.Properties.Where(p => p != null))
xml.Add(property.ToXml());
return xml;
}
/// <summary>
/// Creates the xml representation for the <see cref="IContent"/> object
/// </summary>
+11 -4
View File
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models
{
@@ -47,8 +48,11 @@ namespace Umbraco.Core.Models
get { return _defaultTemplate; }
set
{
_defaultTemplate = value;
OnPropertyChanged(DefaultTemplateSelector);
SetPropertyValueAndDetectChanges(o =>
{
_defaultTemplate = value;
return _defaultTemplate;
}, _defaultTemplate, DefaultTemplateSelector);
}
}
@@ -61,8 +65,11 @@ namespace Umbraco.Core.Models
get { return _allowedTemplates; }
set
{
_allowedTemplates = value;
OnPropertyChanged(AllowedTemplatesSelector);
SetPropertyValueAndDetectChanges(o =>
{
_allowedTemplates = value;
return _allowedTemplates;
}, _allowedTemplates, AllowedTemplatesSelector);
}
}
+171 -38
View File
@@ -4,7 +4,6 @@ using System.Collections.Specialized;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Models
@@ -23,8 +22,8 @@ namespace Umbraco.Core.Models
private string _alias;
private string _description;
private int _sortOrder;
private string _icon;
private string _thumbnail;
private string _icon = "folder.png";
private string _thumbnail = "folder.png";
private int _creatorId;
private bool _allowedAsRoot;
private bool _isContainer;
@@ -32,6 +31,8 @@ namespace Umbraco.Core.Models
private PropertyGroupCollection _propertyGroups;
private PropertyTypeCollection _propertyTypes;
private IEnumerable<ContentTypeSort> _allowedContentTypes;
private bool _hasPropertyTypeBeenRemoved;
protected ContentTypeBase(int parentId)
{
@@ -69,6 +70,8 @@ namespace Umbraco.Core.Models
private static readonly PropertyInfo AllowedContentTypesSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, IEnumerable<ContentTypeSort>>(x => x.AllowedContentTypes);
private static readonly PropertyInfo PropertyGroupCollectionSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, PropertyGroupCollection>(x => x.PropertyGroups);
private static readonly PropertyInfo PropertyTypeCollectionSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, IEnumerable<PropertyType>>(x => x.PropertyTypes);
private static readonly PropertyInfo HasPropertyTypeBeenRemovedSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, bool>(x => x.HasPropertyTypeBeenRemoved);
protected void PropertyGroupsChanged(object sender, NotifyCollectionChangedEventArgs e)
{
@@ -112,8 +115,11 @@ namespace Umbraco.Core.Models
get { return _name; }
set
{
_name = value;
OnPropertyChanged(NameSelector);
SetPropertyValueAndDetectChanges(o =>
{
_name = value;
return _name;
}, _name, NameSelector);
}
}
@@ -126,8 +132,11 @@ namespace Umbraco.Core.Models
get { return _level; }
set
{
_level = value;
OnPropertyChanged(LevelSelector);
SetPropertyValueAndDetectChanges(o =>
{
_level = value;
return _level;
}, _level, LevelSelector);
}
}
@@ -140,8 +149,11 @@ namespace Umbraco.Core.Models
get { return _path; }
set
{
_path = value;
OnPropertyChanged(PathSelector);
SetPropertyValueAndDetectChanges(o =>
{
_path = value;
return _path;
}, _path, PathSelector);
}
}
@@ -154,13 +166,11 @@ namespace Umbraco.Core.Models
get { return _alias; }
set
{
//Ensures a valid ContentType alias
//Would have liked to use .ToUmbracoAlias() but that would break casing upon saving older/upgraded ContentTypes
var result = Regex.Replace(value, @"[^a-zA-Z0-9\s\.-]+", "", RegexOptions.Compiled);
result = result.Replace(" ", "");
_alias = result;
OnPropertyChanged(AliasSelector);
SetPropertyValueAndDetectChanges(o =>
{
_alias = value.ToSafeAlias();
return _alias;
}, _alias, AliasSelector);
}
}
@@ -173,8 +183,11 @@ namespace Umbraco.Core.Models
get { return _description; }
set
{
_description = value;
OnPropertyChanged(DescriptionSelector);
SetPropertyValueAndDetectChanges(o =>
{
_description = value;
return _description;
}, _description, DescriptionSelector);
}
}
@@ -187,8 +200,11 @@ namespace Umbraco.Core.Models
get { return _sortOrder; }
set
{
_sortOrder = value;
OnPropertyChanged(SortOrderSelector);
SetPropertyValueAndDetectChanges(o =>
{
_sortOrder = value;
return _sortOrder;
}, _sortOrder, SortOrderSelector);
}
}
@@ -201,8 +217,11 @@ namespace Umbraco.Core.Models
get { return _icon; }
set
{
_icon = value;
OnPropertyChanged(IconSelector);
SetPropertyValueAndDetectChanges(o =>
{
_icon = value;
return _icon;
}, _icon, IconSelector);
}
}
@@ -215,8 +234,11 @@ namespace Umbraco.Core.Models
get { return _thumbnail; }
set
{
_thumbnail = value;
OnPropertyChanged(ThumbnailSelector);
SetPropertyValueAndDetectChanges(o =>
{
_thumbnail = value;
return _thumbnail;
}, _thumbnail, ThumbnailSelector);
}
}
@@ -229,8 +251,11 @@ namespace Umbraco.Core.Models
get { return _creatorId; }
set
{
_creatorId = value;
OnPropertyChanged(CreatorIdSelector);
SetPropertyValueAndDetectChanges(o =>
{
_creatorId = value;
return _creatorId;
}, _creatorId, CreatorIdSelector);
}
}
@@ -243,8 +268,11 @@ namespace Umbraco.Core.Models
get { return _allowedAsRoot; }
set
{
_allowedAsRoot = value;
OnPropertyChanged(AllowedAsRootSelector);
SetPropertyValueAndDetectChanges(o =>
{
_allowedAsRoot = value;
return _allowedAsRoot;
}, _allowedAsRoot, AllowedAsRootSelector);
}
}
@@ -260,8 +288,11 @@ namespace Umbraco.Core.Models
get { return _isContainer; }
set
{
_isContainer = value;
OnPropertyChanged(IsContainerSelector);
SetPropertyValueAndDetectChanges(o =>
{
_isContainer = value;
return _isContainer;
}, _isContainer, IsContainerSelector);
}
}
@@ -275,8 +306,11 @@ namespace Umbraco.Core.Models
get { return _trashed; }
set
{
_trashed = value;
OnPropertyChanged(TrashedSelector);
SetPropertyValueAndDetectChanges(o =>
{
_trashed = value;
return _trashed;
}, _trashed, TrashedSelector);
}
}
@@ -289,8 +323,11 @@ namespace Umbraco.Core.Models
get { return _allowedContentTypes; }
set
{
_allowedContentTypes = value;
OnPropertyChanged(AllowedContentTypesSelector);
SetPropertyValueAndDetectChanges(o =>
{
_allowedContentTypes = value;
return _allowedContentTypes;
}, _allowedContentTypes, AllowedContentTypesSelector);
}
}
@@ -328,16 +365,116 @@ namespace Umbraco.Core.Models
}
}
/// <summary>
/// A boolean flag indicating if a property type has been removed from this instance.
/// </summary>
/// <remarks>
/// This is currently (specifically) used in order to know that we need to refresh the content cache which
/// needs to occur when a property has been removed from a content type
/// </remarks>
[IgnoreDataMember]
internal bool HasPropertyTypeBeenRemoved
{
get { return _hasPropertyTypeBeenRemoved; }
private set
{
_hasPropertyTypeBeenRemoved = value;
OnPropertyChanged(HasPropertyTypeBeenRemovedSelector);
}
}
/// <summary>
/// Checks whether a PropertyType with a given alias already exists
/// </summary>
/// <param name="propertyTypeAlias">Alias of the PropertyType</param>
/// <returns>Returns <c>True</c> if a PropertyType with the passed in alias exists, otherwise <c>False</c></returns>
public abstract bool PropertyTypeExists(string propertyTypeAlias);
/// <summary>
/// Adds a PropertyGroup.
/// This method will also check if a group already exists with the same name and link it to the parent.
/// </summary>
/// <param name="groupName">Name of the PropertyGroup to add</param>
/// <returns>Returns <c>True</c> if a PropertyGroup with the passed in name was added, otherwise <c>False</c></returns>
public abstract bool AddPropertyGroup(string groupName);
/// <summary>
/// Adds a PropertyType to a specific PropertyGroup
/// </summary>
/// <param name="propertyType"><see cref="PropertyType"/> to add</param>
/// <param name="propertyGroupName">Name of the PropertyGroup to add the PropertyType to</param>
/// <returns>Returns <c>True</c> if PropertyType was added, otherwise <c>False</c></returns>
public abstract bool AddPropertyType(PropertyType propertyType, string propertyGroupName);
/// <summary>
/// Adds a PropertyType, which does not belong to a PropertyGroup.
/// </summary>
/// <param name="propertyType"><see cref="PropertyType"/> to add</param>
/// <returns>Returns <c>True</c> if PropertyType was added, otherwise <c>False</c></returns>
public bool AddPropertyType(PropertyType propertyType)
{
if (PropertyTypeExists(propertyType.Alias) == false)
{
_propertyTypes.Add(propertyType);
_propertyTypes.CollectionChanged += PropertyTypesChanged;
return true;
}
return false;
}
/// <summary>
/// Moves a PropertyType to a specified PropertyGroup
/// </summary>
/// <param name="propertyTypeAlias">Alias of the PropertyType to move</param>
/// <param name="propertyGroupName">Name of the PropertyGroup to move the PropertyType to</param>
/// <returns></returns>
public bool MovePropertyType(string propertyTypeAlias, string propertyGroupName)
{
if (PropertyTypes.Any(x => x.Alias == propertyTypeAlias) == false || PropertyGroups.Any(x => x.Name == propertyGroupName) == false)
return false;
var propertyType = PropertyTypes.First(x => x.Alias == propertyTypeAlias);
//The PropertyType already belongs to a PropertyGroup, so we have to remove the PropertyType from that group
if (PropertyGroups.Any(x => x.PropertyTypes.Any(y => y.Alias == propertyTypeAlias)))
{
var oldPropertyGroup = PropertyGroups.First(x => x.PropertyTypes.Any(y => y.Alias == propertyTypeAlias));
oldPropertyGroup.PropertyTypes.RemoveItem(propertyTypeAlias);
}
propertyType.PropertyGroupId = new Lazy<int>(() => default(int));
propertyType.ResetDirtyProperties();
var propertyGroup = PropertyGroups.First(x => x.Name == propertyGroupName);
propertyGroup.PropertyTypes.Add(propertyType);
return true;
}
/// <summary>
/// Removes a PropertyType from the current ContentType
/// </summary>
/// <param name="propertyTypeAlias">Alias of the <see cref="PropertyType"/> to remove</param>
public void RemovePropertyType(string propertyTypeAlias)
{
//check if the property exist in one of our collections
if (PropertyGroups.Any(group => group.PropertyTypes.Any(pt => pt.Alias == propertyTypeAlias))
|| _propertyTypes.Any(x => x.Alias == propertyTypeAlias))
{
//set the flag that a property has been removed
HasPropertyTypeBeenRemoved = true;
}
foreach (var propertyGroup in PropertyGroups)
{
propertyGroup.PropertyTypes.RemoveItem(propertyTypeAlias);
}
if (_propertyTypes.Any(x => x.Alias == propertyTypeAlias))
{
_propertyTypes.RemoveItem(propertyTypeAlias);
}
}
/// <summary>
@@ -348,9 +485,5 @@ namespace Umbraco.Core.Models
{
_parentId = id;
}
//TODO Implement moving PropertyType between groups.
/*public bool MovePropertyTypeToGroup(string propertyTypeAlias, string groupName)
{}*/
}
}
@@ -14,6 +14,7 @@ namespace Umbraco.Core.Models
public abstract class ContentTypeCompositionBase : ContentTypeBase, IContentTypeComposition
{
private readonly List<IContentTypeComposition> _contentTypeComposition = new List<IContentTypeComposition>();
internal List<int> RemovedContentTypeKeyTracker = new List<int>();
protected ContentTypeCompositionBase(int parentId) : base(parentId)
{
@@ -44,7 +45,7 @@ namespace Umbraco.Core.Models
{
get
{
var groups = PropertyGroups.Union(ContentTypeComposition.SelectMany(x => x.CompositionPropertyGroups));
var groups = ContentTypeComposition.SelectMany(x => x.CompositionPropertyGroups).Union(PropertyGroups);
return groups;
}
}
@@ -57,8 +58,7 @@ namespace Umbraco.Core.Models
{
get
{
var propertyTypes =
PropertyTypes.Union(ContentTypeComposition.SelectMany(x => x.CompositionPropertyTypes));
var propertyTypes = ContentTypeComposition.SelectMany(x => x.CompositionPropertyTypes).Union(PropertyTypes);
return propertyTypes;
}
}
@@ -89,9 +89,11 @@ namespace Umbraco.Core.Models
/// <returns>True if ContentType was removed, otherwise returns False</returns>
public bool RemoveContentType(string alias)
{
if (!ContentTypeCompositionExists(alias))
if (ContentTypeCompositionExists(alias))
{
var contentTypeComposition = ContentTypeComposition.First(x => x.Alias == alias);
RemovedContentTypeKeyTracker.Add(contentTypeComposition.Id);
OnPropertyChanged(ContentTypeCompositionSelector);
return _contentTypeComposition.Remove(contentTypeComposition);
}
return false;
@@ -113,6 +115,83 @@ namespace Umbraco.Core.Models
return false;
}
/// <summary>
/// Checks whether a PropertyType with a given alias already exists
/// </summary>
/// <param name="propertyTypeAlias">Alias of the PropertyType</param>
/// <returns>Returns <c>True</c> if a PropertyType with the passed in alias exists, otherwise <c>False</c></returns>
public override bool PropertyTypeExists(string propertyTypeAlias)
{
return CompositionPropertyTypes.Any(x => x.Alias == propertyTypeAlias);
}
/// <summary>
/// Adds a PropertyGroup.
/// This method will also check if a group already exists with the same name and link it to the parent.
/// </summary>
/// <param name="groupName">Name of the PropertyGroup to add</param>
/// <returns>Returns <c>True</c> if a PropertyGroup with the passed in name was added, otherwise <c>False</c></returns>
public override bool AddPropertyGroup(string groupName)
{
if (PropertyGroups.Any(x => x.Name == groupName))
return false;
var propertyGroup = new PropertyGroup {Name = groupName, SortOrder = 0};
if (CompositionPropertyGroups.Any(x => x.Name == groupName))
{
var firstGroup = CompositionPropertyGroups.First(x => x.Name == groupName && x.ParentId.HasValue == false);
propertyGroup.SetLazyParentId(new Lazy<int?>(() => firstGroup.Id));
}
if (PropertyGroups.Any())
{
var last = PropertyGroups.Last();
propertyGroup.SortOrder = last.SortOrder + 1;
}
PropertyGroups.Add(propertyGroup);
return true;
}
/// <summary>
/// Adds a PropertyType to a specific PropertyGroup
/// </summary>
/// <param name="propertyType"><see cref="PropertyType"/> to add</param>
/// <param name="propertyGroupName">Name of the PropertyGroup to add the PropertyType to</param>
/// <returns>Returns <c>True</c> if PropertyType was added, otherwise <c>False</c></returns>
public override bool AddPropertyType(PropertyType propertyType, string propertyGroupName)
{
if (PropertyTypeExists(propertyType.Alias) == false)
{
if (PropertyGroups.Contains(propertyGroupName))
{
propertyType.PropertyGroupId = new Lazy<int>(() => PropertyGroups[propertyGroupName].Id);
PropertyGroups[propertyGroupName].PropertyTypes.Add(propertyType);
}
else
{
//If the PropertyGroup doesn't already exist we create a new one
var propertyTypes = new List<PropertyType> { propertyType };
var propertyGroup = new PropertyGroup(new PropertyTypeCollection(propertyTypes)) { Name = propertyGroupName, SortOrder = 1 };
//and check if its an inherited PropertyGroup, which exists in the composition
if (CompositionPropertyGroups.Any(x => x.Name == propertyGroupName))
{
var parentPropertyGroup = CompositionPropertyGroups.First(x => x.Name == propertyGroupName && x.ParentId.HasValue == false);
propertyGroup.SortOrder = parentPropertyGroup.SortOrder;
//propertyGroup.ParentId = parentPropertyGroup.Id;
propertyGroup.SetLazyParentId(new Lazy<int?>(() => parentPropertyGroup.Id));
}
PropertyGroups.Add(propertyGroup);
}
return true;
}
return false;
}
/// <summary>
/// Gets a list of ContentType aliases from the current composition
/// </summary>
@@ -0,0 +1,44 @@
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Services;
namespace Umbraco.Core.Models
{
internal static class ContentTypeExtensions
{
/// <summary>
/// Get all descendant content types
/// </summary>
/// <param name="contentType"></param>
/// <returns></returns>
public static IEnumerable<IContentTypeBase> Descendants(this IContentTypeBase contentType)
{
var contentTypeService = ApplicationContext.Current.Services.ContentTypeService;
var descendants = contentTypeService.GetContentTypeChildren(contentType.Id)
.FlattenList(type => contentTypeService.GetContentTypeChildren(type.Id));
return descendants;
}
/// <summary>
/// Get all descendant and self content types
/// </summary>
/// <param name="contentType"></param>
/// <returns></returns>
public static IEnumerable<IContentTypeBase> DescendantsAndSelf(this IContentTypeBase contentType)
{
var descendantsAndSelf = new[] { contentType }.Concat(contentType.Descendants());
return descendantsAndSelf;
}
///// <summary>
///// Returns the descendant content type Ids for the given content type
///// </summary>
///// <param name="contentType"></param>
///// <returns></returns>
//public static IEnumerable<int> DescendantIds(this IContentTypeBase contentType)
//{
// return ((ContentTypeService) ApplicationContext.Current.Services.ContentTypeService)
// .GetDescendantContentTypeIds(contentType.Id);
//}
}
}
@@ -8,6 +8,17 @@ namespace Umbraco.Core.Models
/// </summary>
public class ContentTypeSort : IValueObject
{
public ContentTypeSort()
{
}
public ContentTypeSort(Lazy<int> id, int sortOrder, string @alias)
{
Id = id;
SortOrder = sortOrder;
Alias = alias;
}
/// <summary>
/// Gets or sets the Id of the ContentType
/// </summary>
@@ -15,12 +15,12 @@ namespace Umbraco.Core.Models
public enum DataTypeDatabaseType
{
[EnumMember]
Integer,
[EnumMember]
Date,
Ntext,
[EnumMember]
Nvarchar,
[EnumMember]
Ntext /*, Object*/
Integer,
[EnumMember]
Date
}
}
+51 -21
View File
@@ -2,6 +2,7 @@
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models
{
@@ -52,8 +53,11 @@ namespace Umbraco.Core.Models
get { return _parentId; }
set
{
_parentId = value;
OnPropertyChanged(ParentIdSelector);
SetPropertyValueAndDetectChanges(o =>
{
_parentId = value;
return _parentId;
}, _parentId, ParentIdSelector);
}
}
@@ -66,8 +70,11 @@ namespace Umbraco.Core.Models
get { return _name; }
set
{
_name = value;
OnPropertyChanged(NameSelector);
SetPropertyValueAndDetectChanges(o =>
{
_name = value;
return _name;
}, _name, NameSelector);
}
}
@@ -80,8 +87,11 @@ namespace Umbraco.Core.Models
get { return _sortOrder; }
set
{
_sortOrder = value;
OnPropertyChanged(SortOrderSelector);
SetPropertyValueAndDetectChanges(o =>
{
_sortOrder = value;
return _sortOrder;
}, _sortOrder, SortOrderSelector);
}
}
@@ -94,8 +104,11 @@ namespace Umbraco.Core.Models
get { return _level; }
set
{
_level = value;
OnPropertyChanged(LevelSelector);
SetPropertyValueAndDetectChanges(o =>
{
_level = value;
return _level;
}, _level, LevelSelector);
}
}
@@ -108,8 +121,11 @@ namespace Umbraco.Core.Models
get { return _path; }
set
{
_path = value;
OnPropertyChanged(PathSelector);
SetPropertyValueAndDetectChanges(o =>
{
_path = value;
return _path;
}, _path, PathSelector);
}
}
@@ -122,8 +138,11 @@ namespace Umbraco.Core.Models
get { return _creatorId; }
set
{
_creatorId = value;
OnPropertyChanged(UserIdSelector);
SetPropertyValueAndDetectChanges(o =>
{
_creatorId = value;
return _creatorId;
}, _creatorId, UserIdSelector);
}
}
@@ -136,8 +155,11 @@ namespace Umbraco.Core.Models
get { return _trashed; }
internal set
{
_trashed = value;
OnPropertyChanged(TrashedSelector);
SetPropertyValueAndDetectChanges(o =>
{
_trashed = value;
return _trashed;
}, _trashed, TrashedSelector);
}
}
@@ -149,9 +171,12 @@ namespace Umbraco.Core.Models
{
get { return _controlId; }
private set
{
_controlId = value;
OnPropertyChanged(ControlIdSelector);
{
SetPropertyValueAndDetectChanges(o =>
{
_controlId = value;
return _controlId;
}, _controlId, ControlIdSelector);
}
}
@@ -163,16 +188,21 @@ namespace Umbraco.Core.Models
{
get { return _databaseType; }
set
{
_databaseType = value;
OnPropertyChanged(DatabaseTypeSelector);
{
SetPropertyValueAndDetectChanges(o =>
{
_databaseType = value;
return _databaseType;
}, _databaseType, DatabaseTypeSelector);
}
}
internal override void AddingEntity()
{
base.AddingEntity();
Key = Guid.NewGuid();
if(Key == default(Guid))
Key = Guid.NewGuid();
}
}
}
+16 -6
View File
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models
{
@@ -41,8 +42,11 @@ namespace Umbraco.Core.Models
get { return _parentId; }
set
{
_parentId = value;
OnPropertyChanged(ParentIdSelector);
SetPropertyValueAndDetectChanges(o =>
{
_parentId = value;
return _parentId;
}, _parentId, ParentIdSelector);
}
}
@@ -55,8 +59,11 @@ namespace Umbraco.Core.Models
get { return _itemKey; }
set
{
_itemKey = value;
OnPropertyChanged(ItemKeySelector);
SetPropertyValueAndDetectChanges(o =>
{
_itemKey = value;
return _itemKey;
}, _itemKey, ItemKeySelector);
}
}
@@ -69,8 +76,11 @@ namespace Umbraco.Core.Models
get { return _translations; }
set
{
_translations = value;
OnPropertyChanged(TranslationsSelector);
SetPropertyValueAndDetectChanges(o =>
{
_translations = value;
return _translations;
}, _translations, TranslationsSelector);
}
}
@@ -2,6 +2,7 @@
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models
{
@@ -40,8 +41,11 @@ namespace Umbraco.Core.Models
get { return _language; }
set
{
_language = value;
OnPropertyChanged(LanguageSelector);
SetPropertyValueAndDetectChanges(o =>
{
_language = value;
return _language;
}, _language, LanguageSelector);
}
}
@@ -54,8 +58,11 @@ namespace Umbraco.Core.Models
get { return _value; }
set
{
_value = value;
OnPropertyChanged(ValueSelector);
SetPropertyValueAndDetectChanges(o =>
{
_value = value;
return _value;
}, _value, ValueSelector);
}
}
}
+74 -62
View File
@@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.Serialization;
@@ -12,12 +10,24 @@ namespace Umbraco.Core.Models.EntityBase
/// </summary>
[Serializable]
[DataContract(IsReference = true)]
public abstract class Entity : IEntity, ICanBeDirty
[DebuggerDisplay("Id: {Id}")]
public abstract class Entity : TracksChangesEntityBase, IEntity, IRememberBeingDirty, ICanBeDirty
{
private bool _hasIdentity;
private int? _hash;
private int _id;
private Guid _key;
private DateTime _createDate;
private DateTime _updateDate;
private bool _wasCancelled;
private static readonly PropertyInfo IdSelector = ExpressionHelper.GetPropertyInfo<Entity, int>(x => x.Id);
private static readonly PropertyInfo KeySelector = ExpressionHelper.GetPropertyInfo<Entity, Guid>(x => x.Key);
private static readonly PropertyInfo CreateDateSelector = ExpressionHelper.GetPropertyInfo<Entity, DateTime>(x => x.CreateDate);
private static readonly PropertyInfo UpdateDateSelector = ExpressionHelper.GetPropertyInfo<Entity, DateTime>(x => x.UpdateDate);
private static readonly PropertyInfo HasIdentitySelector = ExpressionHelper.GetPropertyInfo<Entity, bool>(x => x.HasIdentity);
private static readonly PropertyInfo WasCancelledSelector = ExpressionHelper.GetPropertyInfo<Entity, bool>(x => x.WasCancelled);
/// <summary>
/// Integer Id
@@ -31,8 +41,12 @@ namespace Umbraco.Core.Models.EntityBase
}
set
{
_id = value;
HasIdentity = true;
SetPropertyValueAndDetectChanges(o =>
{
_id = value;
HasIdentity = true; //set the has Identity
return _id;
}, _id, IdSelector);
}
}
@@ -51,41 +65,71 @@ namespace Umbraco.Core.Models.EntityBase
return _key;
}
set { _key = value; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_key = value;
return _key;
}, _key, KeySelector);
}
}
/// <summary>
/// Gets or sets the Created Date
/// </summary>
[DataMember]
public DateTime CreateDate { get; set; }
public DateTime CreateDate
{
get { return _createDate; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_createDate = value;
return _createDate;
}, _createDate, CreateDateSelector);
}
}
/// <summary>
/// /// 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.
/// </summary>
[IgnoreDataMember]
internal bool WasCancelled
{
get { return _wasCancelled; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_wasCancelled = value;
return _wasCancelled;
}, _wasCancelled, WasCancelledSelector);
}
}
/// <summary>
/// Gets or sets the Modified Date
/// </summary>
[DataMember]
public DateTime UpdateDate { get; set; }
/// <summary>
/// Property changed event
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Method to call on a property setter.
/// </summary>
/// <param name="propertyInfo">The property info.</param>
protected virtual void OnPropertyChanged(PropertyInfo propertyInfo)
public DateTime UpdateDate
{
_propertyChangedInfo[propertyInfo.Name] = true;
if (PropertyChanged != null)
get { return _updateDate; }
set
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyInfo.Name));
SetPropertyValueAndDetectChanges(o =>
{
_updateDate = value;
return _updateDate;
}, _updateDate, UpdateDateSelector);
}
}
protected void ResetIdentity()
internal virtual void ResetIdentity()
{
_hasIdentity = false;
_id = default(int);
@@ -108,42 +152,6 @@ namespace Umbraco.Core.Models.EntityBase
UpdateDate = DateTime.Now;
}
/// <summary>
/// Tracks the properties that have changed
/// </summary>
private readonly IDictionary<string, bool> _propertyChangedInfo = new Dictionary<string, bool>();
/// <summary>
/// Indicates whether a specific property on the current entity is dirty.
/// </summary>
/// <param name="propertyName">Name of the property to check</param>
/// <returns>True if Property is dirty, otherwise False</returns>
public virtual bool IsPropertyDirty(string propertyName)
{
return _propertyChangedInfo.Any(x => x.Key == propertyName);
}
/// <summary>
/// Indicates whether the current entity is dirty.
/// </summary>
/// <returns>True if entity is dirty, otherwise False</returns>
public virtual bool IsDirty()
{
return _propertyChangedInfo.Any();
}
/// <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 virtual void ResetDirtyProperties()
{
_propertyChangedInfo.Clear();
}
/// <summary>
/// Indicates whether the current entity has an identity, eg. Id.
/// </summary>
@@ -155,7 +163,11 @@ namespace Umbraco.Core.Models.EntityBase
}
protected set
{
_hasIdentity = value;
SetPropertyValueAndDetectChanges(o =>
{
_hasIdentity = value;
return _hasIdentity;
}, _hasIdentity, HasIdentitySelector);
}
}
@@ -0,0 +1,13 @@
namespace Umbraco.Core.Models.EntityBase
{
/// <summary>
/// An interface that defines if the object is tracking property changes and that is is also
/// remembering what property changes had been made after the changes were committed.
/// </summary>
public interface IRememberBeingDirty : ICanBeDirty
{
bool WasDirty();
bool WasPropertyDirty(string propertyName);
void ForgetPreviouslyDirtyProperties();
}
}
@@ -3,29 +3,34 @@
public interface IUmbracoEntity : IAggregateRoot
{
/// <summary>
/// Gets or sets the Id of the Parent entity
/// Profile of the user who created this Entity
/// </summary>
int ParentId { get; set; }
/// <summary>
/// Gets or sets the sort order of the Entity
/// </summary>
int SortOrder { get; set; }
int CreatorId { get; set; }
/// <summary>
/// Gets or sets the level of the Entity
/// </summary>
int Level { get; set; }
/// <summary>
/// Gets or Sets the Name of the Entity
/// </summary>
string Name { get; set; }
/// <summary>
/// Gets or sets the Id of the Parent Entity
/// </summary>
int ParentId { get; set; }
/// <summary>
/// Gets or sets the path to the Entity
/// </summary>
string Path { get; set; }
/// <summary>
/// Profile of the user who created this Entity
/// Gets or sets the sort order of the Entity
/// </summary>
int CreatorId { get; set; }
int SortOrder { get; set; }
/// <summary>
/// Boolean indicating whether this Entity is Trashed or not.
@@ -0,0 +1,147 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
namespace Umbraco.Core.Models.EntityBase
{
/// <summary>
/// A base class for use to implement IRememberBeingDirty/ICanBeDirty
/// </summary>
public abstract class TracksChangesEntityBase : IRememberBeingDirty
{
/// <summary>
/// Tracks the properties that have changed
/// </summary>
private readonly 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)
/// </summary>
private IDictionary<string, bool> _lastPropertyChangedInfo = null;
/// <summary>
/// Property changed event
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Method to call on a property setter.
/// </summary>
/// <param name="propertyInfo">The property info.</param>
protected virtual void OnPropertyChanged(PropertyInfo propertyInfo)
{
_propertyChangedInfo[propertyInfo.Name] = true;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyInfo.Name));
}
}
/// <summary>
/// Indicates whether a specific property on the current entity is dirty.
/// </summary>
/// <param name="propertyName">Name of the property to check</param>
/// <returns>True if Property is dirty, otherwise False</returns>
public virtual bool IsPropertyDirty(string propertyName)
{
return _propertyChangedInfo.Any(x => x.Key == propertyName);
}
/// <summary>
/// Indicates whether the current entity is dirty.
/// </summary>
/// <returns>True if entity is dirty, otherwise False</returns>
public virtual bool IsDirty()
{
return _propertyChangedInfo.Any();
}
/// <summary>
/// Indicates that the entity had been changed and the changes were committed
/// </summary>
/// <returns></returns>
public bool WasDirty()
{
return _lastPropertyChangedInfo != null && _lastPropertyChangedInfo.Any();
}
/// <summary>
/// Indicates whether a specific property on the current entity was changed and the changes were committed
/// </summary>
/// <param name="propertyName">Name of the property to check</param>
/// <returns>True if Property was changed, otherwise False. Returns false if the entity had not been previously changed.</returns>
public virtual bool WasPropertyDirty(string propertyName)
{
return WasDirty() && _lastPropertyChangedInfo.Any(x => x.Key == propertyName);
}
/// <summary>
/// Resets the remembered dirty properties from before the last commit
/// </summary>
public void ForgetPreviouslyDirtyProperties()
{
_lastPropertyChangedInfo.Clear();
}
/// <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 virtual void ResetDirtyProperties()
{
ResetDirtyProperties(true);
}
/// <summary>
/// Resets dirty properties by clearing the dictionary used to track changes.
/// </summary>
/// <param name="rememberPreviouslyChangedProperties">
/// true if we are to remember the last changes made after resetting
/// </param>
/// <remarks>
/// Please note that resetting the dirty properties could potentially
/// obstruct the saving of a new or updated entity.
/// </remarks>
internal void ResetDirtyProperties(bool rememberPreviouslyChangedProperties)
{
if (rememberPreviouslyChangedProperties)
{
//copy the changed properties to the last changed properties
_lastPropertyChangedInfo = _propertyChangedInfo.ToDictionary(v => v.Key, v => v.Value);
}
_propertyChangedInfo.Clear();
}
/// <summary>
/// Used by inheritors to set the value of properties, this will detect if the property value actually changed and if it did
/// it will ensure that the property has a dirty flag set.
/// </summary>
/// <param name="setValue"></param>
/// <param name="value"></param>
/// <param name="propertySelector"></param>
/// <returns>returns true if the value changed</returns>
/// <remarks>
/// This is required because we don't want a property to show up as "dirty" if the value is the same. For example, when we
/// save a document type, nearly all properties are flagged as dirty just because we've 'reset' them, but they are all set
/// to the same value, so it's really not dirty.
/// </remarks>
internal bool SetPropertyValueAndDetectChanges<T>(Func<T, T> setValue, T value, PropertyInfo propertySelector)
{
var initVal = value;
var newVal = setValue(value);
if (!Equals(initVal, newVal))
{
OnPropertyChanged(propertySelector);
return true;
}
return false;
}
}
}
+32 -14
View File
@@ -1,5 +1,6 @@
using System;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
@@ -12,11 +13,17 @@ namespace Umbraco.Core.Models
[DataContract(IsReference = true)]
public abstract class File : Entity, IFile
{
private string _path;
private string _content = string.Empty; //initialize to empty string, not null
protected File(string path)
{
Path = path;
_path = path;
}
private static readonly PropertyInfo ContentSelector = ExpressionHelper.GetPropertyInfo<File, string>(x => x.Content);
private static readonly PropertyInfo PathSelector = ExpressionHelper.GetPropertyInfo<File, string>(x => x.Path);
/// <summary>
/// Gets or sets the Name of the File including extension
/// </summary>
@@ -48,29 +55,40 @@ namespace Umbraco.Core.Models
/// Gets or sets the Path to the File from the root of the site
/// </summary>
[DataMember]
public virtual string Path { get; set; }
public virtual string Path
{
get { return _path; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_path = value;
return _path;
}, _path, PathSelector);
}
}
/// <summary>
/// Gets or sets the Content of a File
/// </summary>
[DataMember]
public virtual string Content { get; set; }
public virtual string Content
{
get { return _content; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_content = value;
return _content;
}, _content, ContentSelector);
}
}
/// <summary>
/// Boolean indicating whether the file could be validated
/// </summary>
/// <returns>True if file is valid, otherwise false</returns>
public abstract bool IsValid();
/// <summary>
/// Indicates whether the current entity has an identity, which in this case is a path/name.
/// </summary>
/// <remarks>
/// Overrides the default Entity identity check.
/// </remarks>
public override bool HasIdentity
{
get { return string.IsNullOrEmpty(Path) == false; }
}
}
}
+3 -1
View File
@@ -1,10 +1,12 @@
using System;
using System.Diagnostics;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models
{
/// <summary>
/// Defines a Content object
/// </summary>
/// </summary>
public interface IContent : IContentBase
{
/// <summary>
+1 -6
View File
@@ -10,11 +10,6 @@ namespace Umbraco.Core.Models
/// </summary>
public interface IContentBase : IUmbracoEntity
{
/// <summary>
/// Gets or Sets the Name of the Content
/// </summary>
string Name { get; set; }
/// <summary>
/// Integer Id of the default ContentType
/// </summary>
@@ -83,6 +78,6 @@ namespace Umbraco.Core.Models
/// </summary>
/// <param name="isTrashed">Boolean indicating whether content is trashed (true) or not trashed (false)</param>
/// <param name="parentId"> </param>
void ChangeTrashedState(bool isTrashed, int parentId = -1);
void ChangeTrashedState(bool isTrashed, int parentId = -20);
}
}
+1
View File
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models
{
+38 -5
View File
@@ -15,11 +15,6 @@ namespace Umbraco.Core.Models
/// </summary>
string Alias { get; set; }
/// <summary>
/// Gets or Sets the Name of the ContentType
/// </summary>
string Name { get; set; }
/// <summary>
/// Gets or Sets the Description for the ContentType
/// </summary>
@@ -74,5 +69,43 @@ namespace Umbraco.Core.Models
/// </summary>
/// <param name="id">Id of the Parent</param>
void SetLazyParentId(Lazy<int> id);
/// <summary>
/// Checks whether a PropertyType with a given alias already exists
/// </summary>
/// <param name="propertyTypeAlias">Alias of the PropertyType</param>
/// <returns>Returns <c>True</c> if a PropertyType with the passed in alias exists, otherwise <c>False</c></returns>
bool PropertyTypeExists(string propertyTypeAlias);
/// <summary>
/// Adds a PropertyType to a specific PropertyGroup
/// </summary>
/// <param name="propertyType"><see cref="PropertyType"/> to add</param>
/// <param name="propertyGroupName">Name of the PropertyGroup to add the PropertyType to</param>
/// <returns>Returns <c>True</c> if PropertyType was added, otherwise <c>False</c></returns>
bool AddPropertyType(PropertyType propertyType, string propertyGroupName);
/// <summary>
/// Adds a PropertyType, which does not belong to a PropertyGroup.
/// </summary>
/// <param name="propertyType"><see cref="PropertyType"/> to add</param>
/// <returns>Returns <c>True</c> if PropertyType was added, otherwise <c>False</c></returns>
bool AddPropertyType(PropertyType propertyType);
/// <summary>
/// Adds a PropertyGroup.
/// This method will also check if a group already exists with the same name and link it to the parent.
/// </summary>
/// <param name="groupName">Name of the PropertyGroup to add</param>
/// <returns>Returns <c>True</c> if a PropertyGroup with the passed in name was added, otherwise <c>False</c></returns>
bool AddPropertyGroup(string groupName);
/// <summary>
/// Moves a PropertyType to a specified PropertyGroup
/// </summary>
/// <param name="propertyTypeAlias">Alias of the PropertyType to move</param>
/// <param name="propertyGroupName">Name of the PropertyGroup to move the PropertyType to</param>
/// <returns></returns>
bool MovePropertyType(string propertyTypeAlias, string propertyGroupName);
}
}
@@ -1,15 +1,11 @@
using System;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models
{
public interface IDataTypeDefinition : IUmbracoEntity
{
/// <summary>
/// Gets or sets the name of the current entity
/// </summary>
string Name { get; set; }
/// <summary>
/// Id of the DataType control
/// </summary>
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models
{
@@ -1,5 +1,6 @@
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models
{
+1
View File
@@ -1,6 +1,7 @@
using System.Globalization;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models
{
+3 -1
View File
@@ -1,4 +1,6 @@
namespace Umbraco.Core.Models
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models
{
public interface IMedia : IContentBase
{
+4 -2
View File
@@ -1,8 +1,10 @@
namespace Umbraco.Core.Models
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models
{
/// <summary>
/// Defines a ContentType, which Media is based on
/// </summary>
/// </summary
public interface IMediaType : IContentTypeComposition
{
+11 -4
View File
@@ -3,6 +3,7 @@ using System.Globalization;
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models
{
@@ -33,8 +34,11 @@ namespace Umbraco.Core.Models
get { return _isoCode; }
set
{
_isoCode = value;
OnPropertyChanged(IsoCodeSelector);
SetPropertyValueAndDetectChanges(o =>
{
_isoCode = value;
return _isoCode;
}, _isoCode, IsoCodeSelector);
}
}
@@ -47,8 +51,11 @@ namespace Umbraco.Core.Models
get { return _cultureName; }
set
{
_cultureName = value;
OnPropertyChanged(CultureNameSelector);
SetPropertyValueAndDetectChanges(o =>
{
_cultureName = value;
return _cultureName;
}, _cultureName, CultureNameSelector);
}
}
+172 -12
View File
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
@@ -12,81 +13,240 @@ namespace Umbraco.Core.Models
[DataContract(IsReference = true)]
internal class Macro : Entity, IMacro
{
private string _alias;
private string _name;
private bool _useInEditor;
private int _cacheDuration;
private bool _cacheByPage;
private bool _cacheByMember;
private bool _dontRender;
private string _scriptFile;
private string _scriptAssembly;
private string _python;
private string _xslt;
private List<IMacroProperty> _properties;
private static readonly PropertyInfo AliasSelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.Alias);
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.Name);
private static readonly PropertyInfo UseInEditorSelector = ExpressionHelper.GetPropertyInfo<Macro, bool>(x => x.UseInEditor);
private static readonly PropertyInfo CacheDurationSelector = ExpressionHelper.GetPropertyInfo<Macro, int>(x => x.CacheDuration);
private static readonly PropertyInfo CacheByPageSelector = ExpressionHelper.GetPropertyInfo<Macro, bool>(x => x.CacheByPage);
private static readonly PropertyInfo CacheByMemberSelector = ExpressionHelper.GetPropertyInfo<Macro, bool>(x => x.CacheByMember);
private static readonly PropertyInfo DontRenderSelector = ExpressionHelper.GetPropertyInfo<Macro, bool>(x => x.DontRender);
private static readonly PropertyInfo ScriptFileSelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.ScriptFile);
private static readonly PropertyInfo ScriptAssemblySelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.ScriptAssembly);
private static readonly PropertyInfo PythonSelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.Python);
private static readonly PropertyInfo XsltSelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.Xslt);
private static readonly PropertyInfo PropertiesSelector = ExpressionHelper.GetPropertyInfo<Macro, List<IMacroProperty>>(x => x.Properties);
/// <summary>
/// Gets or sets the alias of the Macro
/// </summary>
[DataMember]
public string Alias { get; set; }
public string Alias
{
get { return _alias; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_alias = value;
return _alias;
}, _alias, AliasSelector);
}
}
/// <summary>
/// Gets or sets the name of the Macro
/// </summary>
[DataMember]
public string Name { get; set; }
public string Name
{
get { return _name; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_name = value;
return _name;
}, _name, NameSelector);
}
}
/// <summary>
/// Gets or sets a boolean indicating whether the Macro can be used in an Editor
/// </summary>
[DataMember]
public bool UseInEditor { get; set; }
public bool UseInEditor
{
get { return _useInEditor; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_useInEditor = value;
return _useInEditor;
}, _useInEditor, UseInEditorSelector);
}
}
/// <summary>
/// Gets or sets the Cache Duration for the Macro
/// </summary>
[DataMember]
public int CacheDuration { get; set; }
public int CacheDuration
{
get { return _cacheDuration; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_cacheDuration = value;
return _cacheDuration;
}, _cacheDuration, CacheDurationSelector);
}
}
/// <summary>
/// Gets or sets a boolean indicating whether the Macro should be Cached by Page
/// </summary>
[DataMember]
public bool CacheByPage { get; set; }
public bool CacheByPage
{
get { return _cacheByPage; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_cacheByPage = value;
return _cacheByPage;
}, _cacheByPage, CacheByPageSelector);
}
}
/// <summary>
/// Gets or sets a boolean indicating whether the Macro should be Cached Personally
/// </summary>
[DataMember]
public bool CacheByMember { get; set; }
public bool CacheByMember
{
get { return _cacheByMember; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_cacheByMember = value;
return _cacheByMember;
}, _cacheByMember, CacheByMemberSelector);
}
}
/// <summary>
/// Gets or sets a boolean indicating whether the Macro should be rendered in an Editor
/// </summary>
[DataMember]
public bool DontRender { get; set; }
public bool DontRender
{
get { return _dontRender; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_dontRender = value;
return _dontRender;
}, _dontRender, DontRenderSelector);
}
}
/// <summary>
/// Gets or sets the path to the script file in use
/// </summary>
/// <remarks>Optional: Can only be one of three Script, Python or Xslt</remarks>
[DataMember]
public string ScriptFile { get; set; }
public string ScriptFile
{
get { return _scriptFile; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_scriptFile = value;
return _scriptFile;
}, _scriptFile, ScriptFileSelector);
}
}
/// <summary>
/// Gets or sets the name of the assembly, which should be used by the Macro
/// </summary>
/// <remarks>Will usually only be filled if the ScriptFile is a Usercontrol</remarks>
[DataMember]
public string ScriptAssembly { get; set; }
public string ScriptAssembly
{
get { return _scriptAssembly; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_scriptAssembly = value;
return _scriptAssembly;
}, _scriptAssembly, ScriptAssemblySelector);
}
}
/// <summary>
/// Gets or set the path to the Python file in use
/// </summary>
/// <remarks>Optional: Can only be one of three Script, Python or Xslt</remarks>
[DataMember]
public string Python { get; set; }
public string Python
{
get { return _python; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_python = value;
return _python;
}, _python, PythonSelector);
}
}
/// <summary>
/// Gets or sets the path to the Xslt file in use
/// </summary>
/// <remarks>Optional: Can only be one of three Script, Python or Xslt</remarks>
[DataMember]
public string Xslt { get; set; }
public string Xslt
{
get { return _xslt; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_xslt = value;
return _xslt;
}, _xslt, XsltSelector);
}
}
//TODO: This needs to be changed to a custom collection class so we can track the dirtyness of each property!
/// <summary>
/// Gets or sets a list of Macro Properties
/// </summary>
[DataMember]
public List<IMacroProperty> Properties { get; set; }
public List<IMacroProperty> Properties
{
get { return _properties; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_properties = value;
return _properties;
}, _properties, PropertiesSelector);
}
}
/// <summary>
/// Overridden this method in order to set a random Id
+62 -5
View File
@@ -1,5 +1,7 @@
using System;
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Models
{
@@ -8,25 +10,68 @@ namespace Umbraco.Core.Models
/// </summary>
[Serializable]
[DataContract(IsReference = true)]
internal class MacroProperty : IMacroProperty
internal class MacroProperty : TracksChangesEntityBase, IMacroProperty, IRememberBeingDirty
{
private string _alias;
private string _name;
private int _sortOrder;
private IMacroPropertyType _propertyType;
private static readonly PropertyInfo AliasSelector = ExpressionHelper.GetPropertyInfo<MacroProperty, string>(x => x.Alias);
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<MacroProperty, string>(x => x.Name);
private static readonly PropertyInfo SortOrderSelector = ExpressionHelper.GetPropertyInfo<MacroProperty, int>(x => x.SortOrder);
private static readonly PropertyInfo PropertyTypeSelector = ExpressionHelper.GetPropertyInfo<MacroProperty, IMacroPropertyType>(x => x.PropertyType);
/// <summary>
/// Gets or sets the Alias of the Property
/// </summary>
[DataMember]
public string Alias { get; set; }
public string Alias
{
get { return _alias; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_alias = value;
return _alias;
}, _alias, AliasSelector);
}
}
/// <summary>
/// Gets or sets the Name of the Property
/// </summary>
[DataMember]
public string Name { get; set; }
public string Name
{
get { return _name; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_name = value;
return _name;
}, _name, NameSelector);
}
}
/// <summary>
/// Gets or sets the Sort Order of the Property
/// </summary>
[DataMember]
public int SortOrder { get; set; }
public int SortOrder
{
get { return _sortOrder; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_sortOrder = value;
return _sortOrder;
}, _sortOrder, SortOrderSelector);
}
}
/// <summary>
/// Gets or sets the Type for this Property
@@ -36,6 +81,18 @@ namespace Umbraco.Core.Models
/// All types was previously contained in the database, but has been ported to code.
/// </remarks>
[DataMember]
public IMacroPropertyType PropertyType { get; set; }
public IMacroPropertyType PropertyType
{
get { return _propertyType; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_propertyType = value;
return _propertyType;
}, _propertyType, PropertyTypeSelector);
}
}
}
}
+4 -11
View File
@@ -1,5 +1,6 @@
using System;
using System.Runtime.Serialization;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models
{
@@ -111,19 +112,11 @@ namespace Umbraco.Core.Models
/// </summary>
/// <param name="isTrashed">Boolean indicating whether content is trashed (true) or not trashed (false)</param>
/// <param name="parentId"> </param>
public override void ChangeTrashedState(bool isTrashed, int parentId = -1)
public override void ChangeTrashedState(bool isTrashed, int parentId = -20)
{
Trashed = isTrashed;
//If Content is trashed the parent id should be set to that of the RecycleBin
if (isTrashed)
{
ParentId = -21;
}
else//otherwise set the parent id to the optional parameter, -1 being the fallback
{
ParentId = parentId;
}
//The Media Recycle Bin Id is -21 so we correct that here
ParentId = parentId == -20 ? -21 : parentId;
}
/// <summary>
+1
View File
@@ -1,5 +1,6 @@
using System;
using System.Runtime.Serialization;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models
{
+2 -1
View File
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models.Membership
{
@@ -12,7 +13,7 @@ namespace Umbraco.Core.Models.Membership
int SessionTimeout { get; set; }
int StartContentId { get; set; }
int StartMediaId { get; set; }
string Lanuguage { get; set; }
string Language { get; set; }
bool DefaultToLiveEditing { get; set; }
IEnumerable<string> Applications { get; set; }
bool NoConsole { get; set; }
@@ -1,7 +1,9 @@
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models.Membership
{
internal interface IUserType : IAggregateRoot
{
string Alias { get; set; }
+2 -1
View File
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models.Membership
{
@@ -88,7 +89,7 @@ namespace Umbraco.Core.Models.Membership
#region Implementation of IUser
[DataMember]
public string Lanuguage { get; set; }
public string Language { get; set; }
[DataMember]
public string Permissions { get; set; }
[DataMember]
@@ -1,6 +1,7 @@
using System;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models.Membership
{
+11 -4
View File
@@ -2,6 +2,7 @@
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models
{
@@ -82,8 +83,11 @@ namespace Umbraco.Core.Models
get { return _version; }
set
{
_version = value;
OnPropertyChanged(VersionSelector);
SetPropertyValueAndDetectChanges(o =>
{
_version = value;
return _version;
}, _version, VersionSelector);
}
}
@@ -108,8 +112,11 @@ namespace Umbraco.Core.Models
"Type validation failed. The value type: '{0}' does not match the DataType in PropertyType with alias: '{1}'",
value == null ? "null" : value.GetType().Name, Alias));
_value = value;
OnPropertyChanged(ValueSelector);
SetPropertyValueAndDetectChanges(o =>
{
_value = value;
return _value;
}, _value, ValueSelector);
}
}
+10 -1
View File
@@ -1,6 +1,7 @@
using System;
using System.Xml;
using System.Xml.Linq;
using Umbraco.Core.Configuration;
namespace Umbraco.Core.Models
{
@@ -13,11 +14,19 @@ namespace Umbraco.Core.Models
/// <returns>Xml of the property and its value</returns>
public static XElement ToXml(this Property property)
{
string nodeName = property.Alias.ToUmbracoAlias(StringAliasCaseType.CamelCase, true);
string nodeName = UmbracoSettings.UseLegacyXmlSchema ? "data" : property.Alias.ToSafeAlias();
var xd = new XmlDocument();
XmlNode xmlNode = xd.CreateNode(XmlNodeType.Element, nodeName, "");
//Add the property alias to the legacy schema
if (UmbracoSettings.UseLegacyXmlSchema)
{
var alias = xd.CreateAttribute("alias");
alias.Value = property.Alias.ToSafeAlias();
xmlNode.Attributes.Append(alias);
}
//This seems to fail during testing
xmlNode.AppendChild(property.PropertyType.DataType(property.Id).Data.ToXMl(xd));
+33 -8
View File
@@ -3,6 +3,7 @@ using System.Collections.Specialized;
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models
{
@@ -14,7 +15,7 @@ namespace Umbraco.Core.Models
public class PropertyGroup : Entity, IEquatable<PropertyGroup>
{
private string _name;
private int? _parentId;
private Lazy<int?> _parentId;
private int _sortOrder;
private PropertyTypeCollection _propertyTypes;
@@ -45,21 +46,33 @@ namespace Umbraco.Core.Models
get { return _name; }
set
{
_name = value;
OnPropertyChanged(NameSelector);
SetPropertyValueAndDetectChanges(o =>
{
_name = value;
return _name;
}, _name, NameSelector);
}
}
/// <summary>
/// Gets or sets the Name of the Group, which corresponds to the Tab-name in the UI
/// Gets or sets the Id of the Parent PropertyGroup.
/// </summary>
/// <remarks>
/// A Parent PropertyGroup corresponds to an inherited PropertyGroup from a composition.
/// If a PropertyType is inserted into an inherited group then a new group will be created with an Id reference to the parent.
/// </remarks>
[DataMember]
public int? ParentId
{
get { return _parentId; }
get
{
if (_parentId == null)
return default(int?);
return _parentId.Value;
}
set
{
_parentId = value;
_parentId = new Lazy<int?>(() => value);
OnPropertyChanged(ParentIdSelector);
}
}
@@ -73,8 +86,11 @@ namespace Umbraco.Core.Models
get { return _sortOrder; }
set
{
_sortOrder = value;
OnPropertyChanged(SortOrderSelector);
SetPropertyValueAndDetectChanges(o =>
{
_sortOrder = value;
return _sortOrder;
}, _sortOrder, SortOrderSelector);
}
}
@@ -92,6 +108,15 @@ namespace Umbraco.Core.Models
}
}
/// <summary>
/// Sets the ParentId from the lazy integer id
/// </summary>
/// <param name="id">Id of the Parent</param>
internal void SetLazyParentId(Lazy<int?> id)
{
_parentId = id;
}
public bool Equals(PropertyGroup other)
{
//Check whether the compared object is null.
+61 -27
View File
@@ -3,6 +3,7 @@ using System.Reflection;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models
{
@@ -18,7 +19,7 @@ namespace Umbraco.Core.Models
private string _alias;
private string _description;
private int _dataTypeDefinitionId;
private int _propertyGroupId;
private Lazy<int> _propertyGroupId;
private Guid _dataTypeId;
private DataTypeDatabaseType _dataTypeDatabaseType;
private bool _mandatory;
@@ -61,7 +62,7 @@ namespace Umbraco.Core.Models
private static readonly PropertyInfo HelpTextSelector = ExpressionHelper.GetPropertyInfo<PropertyType, string>(x => x.HelpText);
private static readonly PropertyInfo SortOrderSelector = ExpressionHelper.GetPropertyInfo<PropertyType, int>(x => x.SortOrder);
private static readonly PropertyInfo ValidationRegExpSelector = ExpressionHelper.GetPropertyInfo<PropertyType, string>(x => x.ValidationRegExp);
private static readonly PropertyInfo PropertyGroupIdSelector = ExpressionHelper.GetPropertyInfo<PropertyType, int>(x => x.PropertyGroupId);
private static readonly PropertyInfo PropertyGroupIdSelector = ExpressionHelper.GetPropertyInfo<PropertyType, Lazy<int>>(x => x.PropertyGroupId);
/// <summary>
/// Gets of Sets the Name of the PropertyType
@@ -72,8 +73,11 @@ namespace Umbraco.Core.Models
get { return _name; }
set
{
_name = value;
OnPropertyChanged(NameSelector);
SetPropertyValueAndDetectChanges(o =>
{
_name = value;
return _name;
}, _name, NameSelector);
}
}
@@ -86,8 +90,11 @@ namespace Umbraco.Core.Models
get { return _alias; }
set
{
_alias = value;
OnPropertyChanged(AliasSelector);
SetPropertyValueAndDetectChanges(o =>
{
_alias = value;
return _alias;
}, _alias, AliasSelector);
}
}
@@ -100,8 +107,11 @@ namespace Umbraco.Core.Models
get { return _description; }
set
{
_description = value;
OnPropertyChanged(DescriptionSelector);
SetPropertyValueAndDetectChanges(o =>
{
_description = value;
return _description;
}, _description, DescriptionSelector);
}
}
@@ -115,8 +125,11 @@ namespace Umbraco.Core.Models
get { return _dataTypeDefinitionId; }
set
{
_dataTypeDefinitionId = value;
OnPropertyChanged(DataTypeDefinitionIdSelector);
SetPropertyValueAndDetectChanges(o =>
{
_dataTypeDefinitionId = value;
return _dataTypeDefinitionId;
}, _dataTypeDefinitionId, DataTypeDefinitionIdSelector);
}
}
@@ -130,8 +143,11 @@ namespace Umbraco.Core.Models
get { return _dataTypeId; }
internal set
{
_dataTypeId = value;
OnPropertyChanged(DataTypeControlIdSelector);
SetPropertyValueAndDetectChanges(o =>
{
_dataTypeId = value;
return _dataTypeId;
}, _dataTypeId, DataTypeControlIdSelector);
}
}
@@ -144,8 +160,11 @@ namespace Umbraco.Core.Models
get { return _dataTypeDatabaseType; }
set
{
_dataTypeDatabaseType = value;
OnPropertyChanged(DataTypeDatabaseTypeSelector);
SetPropertyValueAndDetectChanges(o =>
{
_dataTypeDatabaseType = value;
return _dataTypeDatabaseType;
}, _dataTypeDatabaseType, DataTypeDatabaseTypeSelector);
}
}
@@ -153,13 +172,16 @@ namespace Umbraco.Core.Models
/// Gets or Sets the PropertyGroup's Id for which this PropertyType belongs
/// </summary>
[DataMember]
internal int PropertyGroupId
internal Lazy<int> PropertyGroupId
{
get { return _propertyGroupId; }
set
{
_propertyGroupId = value;
OnPropertyChanged(PropertyGroupIdSelector);
SetPropertyValueAndDetectChanges(o =>
{
_propertyGroupId = value;
return _propertyGroupId;
}, _propertyGroupId, PropertyGroupIdSelector);
}
}
@@ -172,8 +194,11 @@ namespace Umbraco.Core.Models
get { return _mandatory; }
set
{
_mandatory = value;
OnPropertyChanged(MandatorySelector);
SetPropertyValueAndDetectChanges(o =>
{
_mandatory = value;
return _mandatory;
}, _mandatory, MandatorySelector);
}
}
@@ -186,8 +211,11 @@ namespace Umbraco.Core.Models
get { return _helpText; }
set
{
_helpText = value;
OnPropertyChanged(HelpTextSelector);
SetPropertyValueAndDetectChanges(o =>
{
_helpText = value;
return _helpText;
}, _helpText, HelpTextSelector);
}
}
@@ -200,8 +228,11 @@ namespace Umbraco.Core.Models
get { return _sortOrder; }
set
{
_sortOrder = value;
OnPropertyChanged(SortOrderSelector);
SetPropertyValueAndDetectChanges(o =>
{
_sortOrder = value;
return _sortOrder;
}, _sortOrder, SortOrderSelector);
}
}
@@ -214,8 +245,11 @@ namespace Umbraco.Core.Models
get { return _validationRegExp; }
set
{
_validationRegExp = value;
OnPropertyChanged(ValidationRegExpSelector);
SetPropertyValueAndDetectChanges(o =>
{
_validationRegExp = value;
return _validationRegExp;
}, _validationRegExp, ValidationRegExpSelector);
}
}
//Note that Validation should eventually come from PropertyEditors like in v5
@@ -335,8 +369,8 @@ namespace Umbraco.Core.Models
if (Mandatory && (value == null || string.IsNullOrEmpty(value.ToString())))
return false;
//Check against Regular Expression for Legacy DataTypes
if(!string.IsNullOrEmpty(ValidationRegExp))
//Check against Regular Expression for Legacy DataTypes - Validation exists and value is not null:
if(string.IsNullOrEmpty(ValidationRegExp) == false && (value != null && string.IsNullOrEmpty(value.ToString()) == false))
{
var regexPattern = new Regex(ValidationRegExp);
return regexPattern.IsMatch(value.ToString());
@@ -0,0 +1,42 @@
using System;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.DatabaseAnnotations;
namespace Umbraco.Core.Models.Rdbms
{
[TableName("umbracoServer")]
[PrimaryKey("id")]
[ExplicitColumns]
internal class ServerRegistrationDto
{
[Column("id")]
[PrimaryKeyColumn(AutoIncrement = true)]
public int Id { get; set; }
[Column("address")]
[Length(500)]
public string Address { get; set; }
/// <summary>
/// A unique column in the database, a computer name must always be unique!
/// </summary>
[Column("computerName")]
[Length(255)]
[Index(IndexTypes.UniqueNonClustered, Name = "IX_computerName")]
public string ComputerName { get; set; }
[Column("registeredDate")]
[Constraint(Default = "getdate()")]
public DateTime DateRegistered { get; set; }
[Column("lastNotifiedDate")]
[Constraint(Default = "getdate()")]
public DateTime LastNotified { get; set; }
[Column("isActive")]
[Index(IndexTypes.NonClustered)]
public bool IsActive { get; set; }
}
}

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