Compare commits

..

275 Commits

Author SHA1 Message Date
Sebastiaan Janssen 8baaae4da6 Merge branch '7.2.7' into master-v7 2015-07-15 12:58:48 +02:00
Sebastiaan Janssen ed05a3223f Update Examine NuGet dependency 2015-07-15 12:52:24 +02:00
Shannon 25e3134e35 Fixes unit tests 2015-07-15 12:33:47 +02:00
Shannon f1b9b98f5d Updates to latest examine 2015-07-15 12:32:11 +02:00
Sebastiaan Janssen d2f7eda074 Fixes unit test that failed because HostingEnvironment.ApplicationID is null in unit tests 2015-07-15 10:58:38 +02:00
Stephan 3062eedb4f content - ensure backward compatibility 2015-07-14 19:28:15 +02:00
Stephan 1e3dd4c5cd Cleanup new umbracoApplicationUrl config 2015-07-14 19:28:14 +02:00
Sebastiaan Janssen a7871abbd9 Update Examine and ClientDependency to latest version 2015-07-14 16:50:45 +02:00
Stephan bf3a08cf85 DisposableObject - cleanup & use 2015-07-14 15:56:23 +02:00
Sebastiaan Janssen 7bc208e490 U4-6825 Can't blank out values using the built-in EditProfile snippet
#U4-6825 Fixed
2015-07-14 15:32:08 +02:00
Shannon 6aa633c8c5 changes app timeout to 1.5 mins 2015-07-13 17:10:35 +02:00
Stephan 9be2f99e7b Scheduler - does not run tasks if not MainDom 2015-07-13 14:53:07 +02:00
Stephan 2d5bfc0fe2 Use MainDom status to protect umbraco.config
Conflicts:
	src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlCacheFilePersister.cs
	src/Umbraco.Web/umbraco.presentation/content.cs
2015-07-13 14:52:55 +02:00
Stephan c01f864e37 ApplicationContext - manage MainDom
Conflicts:
	src/Umbraco.Core/ApplicationContext.cs
	src/Umbraco.Core/Umbraco.Core.csproj
2015-07-13 14:41:07 +02:00
Stephan a8be796d68 Bugfix content for LB 2015-07-13 14:17:00 +02:00
Stephan 4acbdbe896 Move WaitOneAsync from AsyncLock to WaitHandleExtensions
Conflicts:
	src/Umbraco.Core/AsyncLock.cs
	src/Umbraco.Core/Umbraco.Core.csproj
2015-07-13 14:16:43 +02:00
Stephan 34a9eef8b8 BackgroundTaskRunner - add Hosted option, refactor some tasks
Conflicts:
	src/Umbraco.Web/Scheduling/BackgroundTaskRunner.cs
2015-07-13 14:13:47 +02:00
Stephan 0f56fa4baa Bugfix content xml doctype issue 2015-07-13 14:08:50 +02:00
Shannon 82a8404b2e Updates TemplateRenderer to not use singletons and to ensure that the http context values are copied back if anything fails 2015-07-09 18:30:52 +02:00
Shannon bce8affe16 removes unused method 2015-07-09 15:19:47 +02:00
Shannon 4bbd8097a2 Merge branch '7.2.7' of https://github.com/umbraco/Umbraco-CMS into 7.2.7 2015-07-09 15:08:41 +02:00
Shannon da9c810d78 Updates examine initialization of its IIndexCriteria to be lazy, this will save a few db calls on startup and ensure they are excuted at the very last possible time. 2015-07-09 14:32:50 +02:00
Shannon 431d066300 Changes the ApplicationEventHandler to check if the db is configured instead of being connected to which can cause issues if SQLCE file is locked by another app domain on startup. Then we verify in the CoreBootManager that the db can be connected to with a retry policy. Changes the db context CanConnect method to not store a static value since it might later be able to be connected to. 2015-07-09 14:31:59 +02:00
Shannon 6d50bd891a moves the ApplicationContext.IsConfigured to a lazy initializer 2015-07-09 14:30:32 +02:00
Stephan 1d00e3c5d8 UmbracoApplication - log unhandled exceptions
Conflicts:
	src/Umbraco.Core/UmbracoApplicationBase.cs
2015-07-08 21:33:22 +02:00
Shannon e69422c8d8 Fixes tests (backports cache fix by name) 2015-07-08 18:14:31 +02:00
Shannon a277ac2fe4 udpates some logging stuff which will also make logging faster. 2015-07-08 17:55:08 +02:00
Shannon 1067b1e245 BackgroundTaskRunner - refactor recurring tasks, improve shutdown
Conflicts:
	src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlCacheFilePersister.cs
	src/Umbraco.Web/Scheduling/LogScrubber.cs
	src/Umbraco.Web/Scheduling/Scheduler.cs
	src/Umbraco.Web/Umbraco.Web.csproj
2015-07-08 17:41:20 +02:00
Shannon 7987f13a11 U4-6788 - refactor OriginalRequestUrl into UmbracoApplicationUrl
and fixes merge issues.
2015-07-08 17:32:36 +02:00
Shannon ccda1bdd73 Refactor scheduled tasks & publishing cancellation 2015-07-08 17:23:15 +02:00
Shannon 76a6f2d2d0 Updates scheduled tasks to be async with cancellation token 2015-07-08 17:23:00 +02:00
Shannon 69428b2281 Scheduled publishing is executing request async with cancellation token 2015-07-08 17:22:44 +02:00
Shannon 7cd39918a0 another log entry 2015-07-08 16:54:38 +02:00
Shannon 9a626c9da6 Merge branch '7.2.7' of https://github.com/umbraco/Umbraco-CMS into 7.2.7 2015-07-08 16:45:42 +02:00
Shannon 0520797c09 more logging 2015-07-08 16:45:34 +02:00
Stephan 9b85ba5b90 Resolution - better logging when freezing 2015-07-08 16:32:43 +02:00
Shannon ca738979ce Adds some more detailed logging. 2015-07-08 16:27:06 +02:00
Shannon 8cfb56adf4 adds machine name logging to startup 2015-07-08 13:28:15 +02:00
Shannon 053346d79b fixes merge 2015-07-08 11:54:10 +02:00
Shannon 044c9c95f8 Merge branch 'dev-v7-U4-6677' of https://github.com/bjarnef/Umbraco-CMS into bjarnef-dev-v7-U4-6677
Conflicts:
	src/Umbraco.Web.UI.Client/src/less/panel.less

Conflicts:
	src/Umbraco.Web.UI.Client/src/less/panel.less
2015-07-08 11:49:09 +02:00
Shannon b23ea69b3e Fixes: U4-6636 Left navbar (section-bar) is unnecessary wide on mobile devices
Conflicts:
	src/Umbraco.Web.UI.Client/src/less/grid.less
2015-07-08 11:48:17 +02:00
Shannon 46f9c5ff05 Fixes: U4-5052 (U7) Previewing a published page changes icon in content tree to the little green plus indicating changes need to be published even though no changes have been made. 2015-07-08 11:46:03 +02:00
Shannon 3bc4b50d74 updates version 2015-07-08 11:36:50 +02:00
Shannon 1a2849dfb0 fixes merge issues 2015-07-08 11:35:55 +02:00
Shannon bcb5883230 Fixes: U4-3514 Add dropdown list of tabs, if more then 6 tabs
Conflicts:
	src/Umbraco.Web.UI.Client/bower.json
	src/Umbraco.Web.UI.Client/gruntFile.js
2015-07-08 11:16:46 +02:00
Shannon 18080c1cfb Fixes: U4-6796 BackOfficeIdentity gets assigned inadvertently for front-end requests if using ui.Text to localize 2015-07-08 11:13:49 +02:00
Shannon 2600a3887e Fixes issue with upgrading - potential file lock issues and also file check for access.config
Conflicts:
	src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/MovePublicAccessXmlDataToDb.cs
2015-07-08 11:13:24 +02:00
Shannon 45bec2a67d Fixes date picker: U4-6715 i can't seem to remove a "publish-at" date? - date picker is more robust now and does proper validity checking/feedback 2015-07-08 11:12:19 +02:00
Shannon da7456fd2a Fixes up unit test for testing back office request to ensure that the GlobalSettings.Path is consistent with a vdir 2015-07-08 11:11:17 +02:00
Shannon 275ba00e24 Fix IsBackOfficeRequest returning false for virtual directory paths - U4-6346 2015-07-08 11:10:30 +02:00
Shannon d00bf4649d Fix for JsSource on legacy trees not supporting virtual paths (~/) - U4-6346
Conflicts:
	src/umbraco.cms/Actions/Action.cs
2015-07-08 11:10:18 +02:00
Shannon 04976f8063 U4-6202 - cache clearing by object type
Conflicts:
	src/Umbraco.Core/Cache/ObjectCacheRuntimeCacheProvider.cs
2015-07-08 11:08:19 +02:00
Shannon 3e7c9fc81e Fixes: U4-6202 Cache not clearing by object type properly
Conflicts:
	src/Umbraco.Core/Cache/ObjectCacheRuntimeCacheProvider.cs
2015-07-08 11:07:53 +02:00
Shannon a1f4d7b16f Fixes: U4-5798 The database configuration failed with the following message: The incoming request has too many parameters. The server supports a maximum of 2100 parameters. 2015-07-08 11:05:30 +02:00
Shannon 811ef4a444 Fixes: U4-5673 SQL Azure cannot drop clustered index on upgrade 2015-07-08 11:03:42 +02:00
Shannon 69ac621f5a Fixes: U4-5670 Umbraco.DropDown List pre value with alias ** already exists for this data type 2015-07-08 11:03:10 +02:00
Shannon 610582df38 U4-5162 - do not cache macro if previewing 2015-07-08 11:02:30 +02:00
Sebastiaan Janssen 181f7c1819 Adds close button to the preview 2015-06-09 18:19:26 +02:00
Sebastiaan Janssen 73fbe7d78c Merge branch 'dev-v7' into master-v7 2015-06-03 14:53:37 +02:00
Sebastiaan Janssen f100d82e2c Bump version 2015-06-03 14:03:04 +02:00
Shannon 60ce993c09 Fixes change password dashboard to have autocomplete = off and to not show plain text passwords. 2015-06-03 12:20:20 +02:00
Shannon c07021d2a0 Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2015-06-02 22:41:06 +02:00
Shannon 744ee39904 Changes the IIS header removal to BeginRequest instead of PreSendRequestHeaders since that is not a recommended practice 2015-06-02 22:40:57 +02:00
Shannon Deminick d669bf64c0 Merge pull request #698 from Nicholas-Westby/dev-v7
Fixes U4-6665 (Localization Bug)
2015-06-02 21:29:16 +02:00
Shannon ff277cd99c Fixes: U4-6654 NullReferenceException downloading translation xml 2015-06-02 21:13:29 +02:00
Shannon Deminick 30cd303a13 Merge pull request #697 from wp-manaosoftware/dev-7-angularthrowexception
U4-6621 - fix issue AngularJS throws exception that locationEvent was…
2015-06-02 21:04:08 +02:00
Shannon 60ce987507 Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2015-06-02 20:53:55 +02:00
Shannon a231899052 Fixes: U4-6635 with label overlaying the folder icon when the folder icons are small. 2015-06-02 20:53:46 +02:00
Shannon Deminick 7ddcccb0c5 Merge pull request #685 from gavinfaux/U4-6618
Back office insecure content warning loading Google Web Fonts when running over HTTPS
2015-06-02 20:16:12 +02:00
Nicholas-Westby db824d8daf Fixes U4-6665 (Localization Bug)
Fix for localization not working some of the time: http://issues.umbraco.org/issue/U4-6665
2015-05-29 21:02:07 -07:00
Warm a1a30240f6 U4-6621 - fix issue AngularJS throws exception that locationEvent was not defined when leaved a page without saving 2015-05-29 10:40:48 +07:00
Shannon Deminick 7c4a189aa3 Merge pull request #696 from tomfulton/fix/u4-6655
Fix U4-6655:  RTE Macro not rendering in backoffice when "macroAlias" is not first attribute
2015-05-26 08:01:40 +10:00
Tom Fulton 4ec66bc868 Fix U4-6655: RTE Macro not rendering in backoffice when "macroAlias" is not first attribute
Loosens UMBRACO_MACRO regex parsing to fix, add tests
2015-05-22 20:40:30 -06:00
Stephan fa8fe8ec66 BackgroundTaskRunner - few fixes 2015-05-21 21:54:30 +02:00
Stephan a76ba9a0a7 BackgroundTaskRunner - more fixes 2015-05-21 19:37:22 +02:00
Stephan b804ff6107 Explicit exception on cache reentry 2015-05-21 16:09:20 +02:00
Shannon 72046a6ab9 removes test - expected behavior 2015-05-21 16:36:09 +10:00
Shannon ea2303c327 commits cache tests with recursive key lookup 2015-05-21 16:13:58 +10:00
Shannon 4c4117a052 Fixes BackgroundTaskRunner - moves the OnStopped call to where it should be. Un-ignores tests - these need to execute and cannot be ignored. They are not long running but if there are issues then they will timeout - DO NOT IGNORE. if the build server has issues with these then it's our logic that is at fault. 2015-05-21 13:05:58 +10:00
Stephan 521b8076d2 U4-6638 - bugfix BackgroundTaskRunner 2015-05-20 20:56:05 +02:00
Stephan 1def88d764 U4-6626 2015-05-20 18:26:08 +02:00
Stephan 910c349f7c Bugfix StyleSheet concatenation causing LOH GC issues 2015-05-20 17:00:32 +02:00
Shannon 6cfb5bc678 Have made the buttons always left aligned with the editing section, seems better since it's consistent on all screens and less right hand motion to click a button 2015-05-20 16:13:36 +10:00
Shannon a3b5996372 Fixes save/publish button placement on small screens 2015-05-20 16:01:44 +10:00
Shannon 31b4560daa Merge branch 'sebastian-claesson-dev-v7' into dev-v7 2015-05-20 15:08:45 +10:00
Shannon 2f2dd9c9b6 Merge branch 'dev-v7' of https://github.com/sebastian-claesson/Umbraco-CMS into sebastian-claesson-dev-v7 2015-05-20 15:07:48 +10:00
Shannon Deminick 02599e1254 Merge pull request #694 from Alain-es/datepicker-custom-format
Datepicker custom format
2015-05-20 14:48:36 +10:00
Stephan ac7ff31a67 U4-6626 - XmlCache, bugfix locks 2015-05-19 20:08:52 +02:00
Stephan 009f071f48 XmlCache - comments 2015-05-19 14:04:32 +02:00
Stephan e0ecb3291d XmlCache - bugfix running with file cache disabled 2015-05-19 10:20:36 +02:00
Stephan dbaf7c0190 U4-6597 - fix issue with caches that would cache exceptions 2015-05-19 09:24:38 +02:00
Stephan 16e06b6d4d Revert 444a028, 0e5a469 and 9d8f33e 2015-05-19 09:24:25 +02:00
Shannon 444a028e30 adds tests for caching exceptions and only caching one time and fixes HttpRequestCacheProvider to work with them. 2015-05-19 15:57:11 +10:00
Shannon 0e5a469577 Fixes: U4-6597 Umbraco fails to reconnect to a SQL Server if it started up when SQL server was offline - however this requires some review. 2015-05-19 14:29:25 +10:00
Shannon 9d8f33e98e Fixes: U4-6597 Umbraco fails to reconnect to a SQL Server if it started up when SQL server was offline - however this requires some review. 2015-05-19 14:25:31 +10:00
Alain-es 2abb3177af Datepicker custom format 2015-05-18 15:57:27 +01:00
Alain-es 43f99e11a5 Datepicker custom format 2015-05-18 15:54:50 +01:00
Sebastian Claesson Hoffback d1d9878ab6 Fix content-edit-view on mobile devices
The content editing view did not work at all on small screens. The label
took to much space, leaving the controller with almost none. Now the
label and the controller get its own row on smaller screens. Much
cleaner look and you can acctually edit a page on a small screen. Note:
Grids still don't work well.
2015-05-18 13:59:42 +02:00
Sebastian Claesson Hoffback e9753c72a7 Merge pull request #1 from umbraco/dev-v7
Merge Shannons changes
2015-05-18 12:13:33 +02:00
Shannon 3b791c75f6 Fixes: U4-5020 Login view on mobile screen is too big 2015-05-18 20:09:03 +10:00
Shannon Deminick 35cb4d5690 Merge pull request #693 from sebastian-claesson/dev-v7
Fixed login-view on mobile devices
2015-05-18 19:37:33 +10:00
Sebastian Claesson Hoffback adde7c2f50 Fixed login-view on mobile devices
On smaller screens the login-view was too far to the right.

Related issue: http://issues.umbraco.org/issue/U4-5020
2015-05-18 11:34:13 +02:00
Shannon Deminick 62943d391f Merge pull request #692 from bjarnef/dev-v7-U4-6629
Fix changes in user section labels
2015-05-18 13:47:13 +10:00
Shannon Deminick 0942eb839d Merge pull request #691 from Vrijdagonline/dev-v7
Updating Dutch Translations
2015-05-18 11:38:29 +10:00
bjarnef 21a4dfe33e Fix changes in user section labels
Fixed translation in da.xml according to change in en.xml  from 7.2.4 to
7.2.5
2015-05-17 22:16:39 +02:00
Stephan 8121fc42e5 U4-6626 - fix log level 2015-05-17 21:47:31 +02:00
Stephan c356ed1df8 Logger - add AppDomain.Id to log 2015-05-17 18:48:26 +02:00
Stephan 92f56ccedd U4-6626 - XmlCache, bugfix locks 2015-05-17 18:48:25 +02:00
Stephan 7cbe2410e4 Do not flood the log when installing a new version 2015-05-17 18:48:21 +02:00
Arjan Woldring 1dda3ce45d Updating Dutch Translations
Missing keys added, deleted keys deleted, reorderded some keys based on
the english one and corrected couple of wrong translations.
2015-05-16 19:06:04 +02:00
Shannon Deminick 1e29a4a8ca Merge pull request #688 from sebastian-claesson/dev-v7
Swedish was using the wrong format for variables
2015-05-15 15:46:17 +10:00
Sebastian Claesson Hoffback 01de0bd6a1 Swedish was using the wrong format for variables
The swedish translation was using {0} instead of %0%. Leading to alot of
texts being weirdly formated.
2015-05-15 07:22:11 +02:00
Shannon Deminick 4d0d29c004 Merge pull request #686 from Aaen/dev-v7
Change translation for add row for fix issue U4-6564
2015-05-14 07:57:12 +10:00
Shannon Deminick 741c2bb085 Merge pull request #687 from sebastian-claesson/dev-v7
Swedish translation for the grid-editor
2015-05-14 07:54:16 +10:00
Sebastian Claesson Hoffback 2c809857af Swedish translation for the grid-editor
Swedish translation was completly missing for the grid-editor
2015-05-13 14:59:27 +02:00
Dennis Aaen 236d6ee302 Change translation for add row for fix issue U4-6564 2015-05-13 13:27:37 +02:00
Gavin Faux 3094dea5d4 Back office insecure content warning loading Google Web Fonts when running over HTTPS
Amend to use https://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js
2015-05-13 09:45:20 +01:00
Shannon f829b0b16c Fixes text not overlayed on top of icon for folders in folder browser 2015-05-13 10:56:25 +10:00
Shannon 5d1340e864 Merge branch 'dev-v7' into master-v7 2015-05-13 10:15:11 +10:00
Sebastiaan Janssen a42526b890 This file just keeps being marked as "changed" by git, committing it so I don't have to discard changes all the time 2015-05-12 11:15:02 +02:00
Shannon 3a36513307 Fixes: U4-6609 SQL Exception when trying to delete a template that isn't assigned to any doc type 2015-05-12 17:59:06 +10:00
Shannon 0548a32405 adds some simple docs to umb settings 2015-05-12 17:32:26 +10:00
Shannon 433950dd59 Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2015-05-12 12:39:57 +10:00
Shannon ad8926668e Fixes: U4-6588 UmbracoSettings Error404 support Guids and Xpath - To achieve this, had to create an Id -> Key and Key -> Id method on EntityService including a cache for it which means updating all relavent cache refreshers to clear this cache when things are removed. Moved the logic for parsing an Umbraco XPath query (with tokens) to a stand-alone testable class (though haven't written tests), move the logic for looking up a not found page to the NotFoundHandlerHelper (instead of legacy 'library'). Fixes the $root query, since I don't think that ever worked. I've tested $root now for both MNTP and for the not found handler and it works. 2015-05-12 12:39:46 +10:00
Sebastiaan Janssen 4ebc0fe4cf U4-6383 Download all translation tasks as XML Error
#U4-6383 Fixed Due in version 7.2.5
2015-05-11 21:33:52 +02:00
Shannon 1b1455067e Fixes: U4-6606 maxInvalidPasswordAttempts work for the UsersMembershipProvider doesn't work any more 2015-05-11 19:44:59 +10:00
Shannon 795de94a5f Fixes: U4-6102 After renaming Grid row configurations all data is lost for renames. So now we have warnings for both deletes and renames. 2015-05-11 18:46:26 +10:00
Shannon d6699ab3b3 Fixes: U4-6102 After renaming Grid row configurations all data is lost, also ensures that all events are unsubscribed on destroy 2015-05-11 16:18:35 +10:00
Shannon d94b334375 Moves login logging to the provider level 2015-05-11 12:22:56 +10:00
Shannon a4a49b1466 Revert "Fixes MVC 4.0.0.1 problem once and for all." - All MVC ref's are 4.0.0.0, no web config transforms (also there was never a 4.0.0.1 version of System.Net.Http). Everything works on my machine now, even with 4.0.0.1 installed in the GAC. 2015-05-11 11:45:13 +10:00
Shannon Deminick 2c92cd9ca9 Merge pull request #683 from umbraco/U4-6603
U4-6603 Log failed login attempts
2015-05-11 09:07:24 +10:00
Sebastiaan Janssen c34605937c U4-6603 Log failed login attempts
#U4-6603 Fixed
2015-05-10 17:47:32 +02:00
Shannon Deminick 2a9d3df822 Merge pull request #682 from hfloyd/dev-v7
English Language file updates (Umbraco/config/lang)
2015-05-08 08:48:38 +10:00
Heather Floyd 3b849987bf Small fixes to 'en' language file. Update of 'en-us' language file to match 'en' language file. 2015-05-07 16:41:12 -04:00
Shannon 8443513b2b fixes sorting with multipletextbox 2015-05-07 13:39:28 +10:00
Shannon fec9d066f0 Merge branch 'property-editor-fixes' of https://github.com/pynej/Umbraco-CMS into pynej-property-editor-fixes
Conflicts:
	src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js
	src/Umbraco.Web.UI.Client/src/views/propertyeditors/markdowneditor/markdowneditor.controller.js
	src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.html
	src/Umbraco.Web/PropertyEditors/ContentPickerPropertyEditor.cs
2015-05-07 13:24:59 +10:00
Shannon a69c7dd1fc Manually merges PR: 564 2015-05-07 13:09:29 +10:00
Shannon 4e6a3458d0 Fixes: U4-6600 Label on files not just folders in file browser (media) and fixes up the last image rendered in the photo browser, as well as the overlays, whitespace and overflow and vertical alignment. 2015-05-07 12:57:23 +10:00
Shannon a5bb8ba8ee Merge branch 'iamphill-media-label' into dev-v7 2015-05-07 12:01:44 +10:00
Shannon d4f3dbcfc0 Merge branch 'media-label' of https://github.com/iamphill/Umbraco-CMS into iamphill-media-label 2015-05-07 12:01:31 +10:00
Shannon 6a0656fbb0 fixes spacing for radio/check boxes (U4-6036) tested in ie, ff and chrome 2015-05-07 11:59:10 +10:00
Shannon Deminick 9dc0999ebd Merge pull request #595 from redmorello/U4-6036
U4 6036 - Checkbox and Radio button styling incorrect in backend
2015-05-07 11:49:30 +10:00
Shannon 813f1a1f2d Fixes: U4-6035 Properrty.WasDirty() always returns false 2015-05-07 11:43:53 +10:00
Shannon e45b0a53b8 Merge branch 'aaronpowell-master-v7' into dev-v7 2015-05-07 11:07:16 +10:00
Shannon 685635c568 Merge branch 'master-v7' of https://github.com/aaronpowell/Umbraco-CMS into aaronpowell-master-v7 2015-05-07 11:06:55 +10:00
Shannon Deminick a3e37de1ad Merge pull request #633 from bjarnef/dev-v7-U4-4507
U4-4507 - Make expand arrow in sections as a toggle
2015-05-07 11:02:08 +10:00
Shannon Deminick 692a8f807e Merge pull request #638 from bjarnef/dev-v7-U4-6276
Fix for U4-6276 - Keep headline at same position
2015-05-07 10:51:32 +10:00
Shannon f4bdcae411 Fixes: U4-6236 umbraco 7 macro parameters saving "null" 2015-05-07 10:47:36 +10:00
Shannon Deminick 3a726348d2 Merge pull request #673 from kgiszewski/dev-v7
Fix for U4-6530
2015-05-07 10:21:42 +10:00
Shannon Deminick d8b029eba6 Merge pull request #680 from WebCentrum/dev-v7-gridsort
U4-6593 - After sort, reset the TinyMCE editors with previous settings
2015-05-07 10:13:29 +10:00
Shannon 7c01670caf fixes mem leaks by not unsubscribing from events 2015-05-07 09:11:39 +10:00
Shannon 3ce5ff882e Fixes U4-5213 in a better way using a query string so it's clear where it redirects to 2015-05-07 09:11:25 +10:00
Shannon 6e7aa19073 Fixes U4-5213 in a better way using a query string so it's clear where it redirects to 2015-05-07 09:00:43 +10:00
Shannon 1cac4ed075 Fixes MVC 4.0.0.1 problem once and for all. 2015-05-07 08:10:45 +10:00
Stephan e358390211 Bugfix Xml cache - bad, bad Stephan 2015-05-06 11:10:04 +02:00
Sebastiaan Janssen 2e6c643dde Bump version 2015-05-06 11:08:25 +02:00
Sebastiaan Janssen d84b8aa675 Fix duplication of the mysql DbProviderFactory when using NuGet 2015-05-06 11:04:09 +02:00
Shannon Deminick 41a0c1f491 Merge pull request #679 from WebCentrum/dev-v7-loginredir
U4-5213 - Login redirect to originally requested URL
2015-05-06 17:46:07 +10:00
Shannon e8d4777d74 re-formatted some of the PR 2015-05-06 17:36:46 +10:00
Shannon e03ef76fcd Merge branch 'Jeavon-U4-5480' into dev-v7 2015-05-06 17:35:13 +10:00
Shannon 781ca34e34 Merge branch 'U4-5480' of https://github.com/Jeavon/Umbraco-CMS into Jeavon-U4-5480 2015-05-06 17:34:59 +10:00
Shannon d01e963365 Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7
Conflicts:
	src/Umbraco.Web.UI/packages.config
2015-05-06 17:28:05 +10:00
Shannon 821daa82c4 Fixes: U4-6474 Update to latest examine v0.1.63 2015-05-06 17:14:10 +10:00
Sebastiaan Janssen a51dd93ffe Expressed version range was wrong 2015-05-06 08:58:45 +02:00
Allyen 8299243129 U4-6593 - After sort, reset the TinyMCE editors with previous settings 2015-05-05 22:07:18 +02:00
Sebastiaan Janssen 4144590189 Upgrade to latest MySql.Data and loosen up NuGet dependency 2015-05-05 12:15:28 +02:00
Allyen 2f4ff6aaae Login redirect to originally requested URL 2015-05-04 11:49:07 +02:00
Sebastiaan Janssen ab0e549c70 We got rid of macroRenderings project ages ago, why is this file still here? 2015-05-01 14:27:49 +02:00
Sebastiaan Janssen be065b2fa3 Generate symbols nupkg (apparently you can create it from an existing NuSpec file, very cool)
Making sure that all pdbs ARE actually generated in Release mode (the AllBinaries file was missing loads of files)
Generate all and include all xml doc files too
Corrects WebPI zip, also shouldn't include dotLess.Core.dll
2015-05-01 14:27:26 +02:00
Sebastiaan Janssen f0dfd0dce2 U4-6568 NuGet 7.2.4 missing Microsoft.Threading.Tasks.dll and Microsoft.Threading.Tasks.Extensions.dll
#U4-6568 Fixed Due in version 7.2.5
2015-04-29 16:15:24 +02:00
Shannon da579c91e1 Fixes: U4-6460 7.2.2 -> 7.2.4 update fails with "an item with the same key has already been added" error 2015-04-27 13:40:41 +10:00
Shannon 550d690a31 Fixes: U4-6559 ServerVariables parsing - An Item with the same key has already been added 2015-04-27 12:41:19 +10:00
Shannon Deminick 40b75b7cf5 Merge pull request #672 from alecrt/dev-v7
U4-6295 - Fix for BusinessLogic.Log.CleanLogs task error
2015-04-27 10:56:33 +10:00
Shannon Deminick 0b28a68678 Merge pull request #675 from abjerner/patch-6
listview.html: the arrows for symbolizing ascending and descending are wrong
2015-04-27 10:53:52 +10:00
Anders Bjerner 5f27355247 listview.html: the arrows for symbolizing ascending and descending are wrong 2015-04-26 14:44:25 +02:00
Sebastiaan Janssen 356ea6824f U4-6547 Re: U4-6096 German Translator file broken again in V7.2.4
#U4-6547 Fixed Due in version 7.2.5
2015-04-23 16:59:57 +02:00
Sebastiaan Janssen 7ffb73e467 Updates Examine dependency 2015-04-23 16:45:24 +02:00
Sebastiaan Janssen 57c3665d0f Show different ReadMe for fresh install vs. upgrade installs 2015-04-23 16:01:23 +02:00
Sebastiaan Janssen 8037f929aa Ignore more slow tests 2015-04-23 15:35:42 +02:00
Sebastiaan Janssen fec3e57ed6 Ignore tests that don't run to completion on slower build server 2015-04-23 15:19:18 +02:00
Sebastiaan Janssen 5106ffab97 Mark as Release Candidate 2015-04-23 15:00:12 +02:00
Sebastiaan Janssen 9f569171c3 Suppress error (it's useless information) 2015-04-23 14:59:13 +02:00
Sebastiaan Janssen d607041ca4 U4-6450 Creating Partial View Macro without 'Create Macro' selected still tries to create a macro
#U4-6450 Fixed
2015-04-23 14:55:57 +02:00
Sebastiaan Janssen b3daf7f55d Merge branch 'dev-v7-xmllock' into dev-v7 2015-04-23 14:23:23 +02:00
Sebastiaan Janssen a77d3bc4ac Adds some more defaults tests 2015-04-23 14:22:42 +02:00
kgiszewski dc3e144493 Fix for U4-6530 2015-04-20 10:28:35 -04:00
alecrt f20fed3ce8 Fix for U4-6295 - BusinessLogic.Log.CleanLogs task error 2015-04-18 19:00:03 +02:00
Stephan c4aa87d73d Backport Xml concurrency fixes 2015-04-13 19:12:03 +02:00
Stephan 57909489cb AsyncLock - import 2015-04-13 19:12:00 +02:00
Shannon c78b371965 updates the BackgroundTaskRunnerAwaiter so that it exits if the runner is not running when it is ctor'd, adds diags. 2015-04-09 17:59:34 +10:00
Shannon c525be3e44 Completes: U4-6474 Update to latest examine v0.1.62 2015-04-09 15:33:58 +10:00
Shannon cc804bd3bd removes duplicate test 2015-04-08 17:57:00 +10:00
Shannon 24dc8309f1 sets ConfigureAwait(false) for XmlCacheFilePersister await calls and BackgroundTaskRunner await calls since these are always on background threads, no synchronizing with any context. 2015-04-08 17:15:21 +10:00
Shannon ce81f9b1b1 we'll try these tests again 2015-04-08 17:08:06 +10:00
Shannon 3f70761d49 this should fix one of the tests 2015-04-08 17:01:38 +10:00
Shannon dee45146a4 applies a max timout for BackgroundTaskRunnerTests 2015-04-08 16:55:34 +10:00
Shannon b35397b464 uses property type ctor overload to accept an alias which prob should have been there all along since in most cases you need an alias to create one (same prob goes for property groups, etc... but oh well). Adds a couple tests for case insensitive comparisons in PropertyCollection 2015-04-08 16:33:16 +10:00
Shannon 147cc92ac5 Updates BackgroundTaskRunner & tests: removes the need for most Thread.Sleep which is error prone, this is done by updating the GetAwaiter() method to be a custom awaiter so we can await the entire background task running operations. We then add a property called CurrentThraedingTask which then allows awaiting the current Task instance. Adds error handling to all event handlers for the task runner. Changes events to be TypedEventHandlers 2015-04-08 16:28:42 +10:00
Shannon 3230fce76a fixes lock on PropertyCollection, should just be a normal lock 2015-04-08 11:47:16 +10:00
Shannon 1d22c1e81e fixes get hash code on Entity base class 2015-04-08 11:47:00 +10:00
Shannon ece2e2359e Updates PropertyGroup's equality comparisons to: check the base comparison, then check for a case insensitive comparison with name, fixes GetHashCode to be consistent with the Equals method. 2015-04-08 11:31:14 +10:00
Shannon 8cbe53f49d Updates PropertyType to have a ctor overload accepting an alias when one already exists. Updates it's equality comparisons to: check the base comparison, then check for a case insensitive comparison with alias, fixes GetHashCode to be consistent with the Equals method. 2015-04-08 11:30:35 +10:00
Shannon Deminick cac3ddc3c8 Merge pull request #666 from JimBobSquarePants/dev-v7
Remove Content Service Setter case sensitivity
2015-04-08 10:07:34 +10:00
Shannon 0eac50ceba Fixes: U4-6506 Grid config in package.manifest doesn't allow for multiple grid editors and adds tests 2015-04-07 17:24:35 +10:00
Shannon d5e735ac14 Fixes singleton accessors and adds ctor which would allow unit testability. 2015-04-07 12:07:54 +10:00
Shannon Deminick 8d841d3537 Merge pull request #667 from AndyButland/u4-1733
U4-1733 - Added overloads to RedirectToUmbracoPage methods to allow passing of a querystring
2015-04-07 11:05:05 +10:00
Sebastiaan Janssen 5f175874b2 Fixes tests and adds a few 2015-04-02 17:52:59 +02:00
Sebastiaan Janssen fa053426c3 Don't disableFindContentByIdPath when in preview mode 2015-04-02 17:16:56 +02:00
AndyButland 437e7f0ffc Removed unused usings from previous commit 2015-04-01 23:29:43 +02:00
AndyButland afa6c35bb5 Added overloads to RedirectToUmbracoPage methods to allow passing of a querystring 2015-04-01 23:27:20 +02:00
James South 8d00dbf648 Remove Content Service Setter case sensitivity
Makes property alias key checking case-insensitive bringing behaviour in
line with IPublishedContent getters.
2015-04-01 12:37:28 +01:00
Stephan cd26a1ad21 U4-6479 - fix GetCulture for unpublished content + add tests 2015-04-01 12:59:01 +02:00
Shannon 437ab4aaf1 Fixes installer permission steps - this cannot just arbitrarily write to the umbraco xml cache file 2015-04-01 17:44:27 +11:00
Shannon 051e9366e5 updates js undefined check 2015-04-01 13:39:54 +11:00
Shannon Deminick 46c6503320 Merge pull request #665 from magnuskragelund/dev-v7-U4-6469-mntp-referencing-deleted-nodes
fixes bug when trying to render a deleted node in multinode tree picker
2015-04-01 13:36:18 +11:00
Shannon 1cf2fc7870 updates sln docs and removes pdf test bits 2015-04-01 11:22:10 +11:00
Shannon cf1c38dcaa fixes build 2015-03-31 17:04:32 +11:00
Shannon 73d7cd4856 updates sln file to remove the PDF proj and removes the sln folder containing umbraco examine libs 2015-03-31 14:27:18 +11:00
Shannon 1b87fd074c Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2015-03-31 13:49:39 +11:00
Shannon 33f21e0528 Updates build and solution to exclude UmbracoExamine.PDF, removes files for UmbracoExamine.PDF, updates links to license in nuspec files 2015-03-31 13:49:28 +11:00
Sebastiaan Janssen 0b5a2452c2 U4-6476 Examine Issue: The CancellationTokenSource has been disposed.
#U4-6476 Fixed Due in version 7.2.5
2015-03-30 14:38:59 +02:00
Shannon cc8962f090 Removes the old umbracoexamine.azure libs 2015-03-30 20:07:26 +11:00
Shannon f6b9fdba72 Removes old docs folder 2015-03-30 20:06:51 +11:00
Shannon e0effec3b4 fixes pdf build to only have it's required files in the zip 2015-03-30 19:13:13 +11:00
Shannon 76a2f433d9 simplifies build since we don't have the examine azure stuff 2015-03-30 18:42:47 +11:00
Shannon a2bfca4d3a Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2015-03-30 17:40:46 +11:00
Shannon fb24becd0d completes: U4-6468 Move all 'Strategies' in the Web project that performs Core data operations to the Core project 2015-03-30 17:40:36 +11:00
Shannon 58857c5d83 Moves publishing strategies into CacheRefresherEventHandler where the event handlers are supposed to exist. 2015-03-30 17:36:54 +11:00
Shannon 7a31d6cae3 better exception logging for examine 2015-03-30 17:23:28 +11:00
Shannon Deminick 021bb6d367 Merge pull request #661 from kgiszewski/dev-v7
Fix for U4-6462
2015-03-30 16:27:19 +11:00
Shannon Deminick 0742108ec1 Merge pull request #662 from AndyButland/u4-6412
U4-6412 - Ensures footer breadcrumb in content and media returned in correct order
2015-03-30 10:44:08 +11:00
Magnus Kragelund 1c3a7b95fc fixes bug when trying to render a deleted node in multinode tree picker 2015-03-27 11:02:35 +01:00
Shannon fda72b2acc changes the MaxWaitMilliseconds tp 30000 to be consistent with the 7.3 branch 2015-03-27 15:19:31 +11:00
Shannon ec742d1f66 removes the usages of ILogger and ProfilerLogger since this is not for 7.3.0, will need to re-fix for 7.3 branch. 2015-03-27 14:56:12 +11:00
Shannon 4bdac1475f fixes log scrub interval with ms with updated background tasks 2015-03-27 14:52:38 +11:00
Stephan 58ce04e26b cleanup 2015-03-27 14:49:31 +11:00
Shannon 4c3de920c6 Removes the 'else' so that 'wait' is always checked. 2015-03-27 14:49:31 +11:00
Stephan be37026587 refactor latched background tasks, now use a task for xml
Conflicts:
	src/Umbraco.Web.UI/config/ClientDependency.config
2015-03-27 14:49:25 +11:00
Stephan a73b7a5849 refactor Scheduler to use new BackgroundTaskRunner capabilities
Conflicts:
	src/Umbraco.Web/Scheduling/Scheduler.cs
2015-03-27 14:48:47 +11:00
Stephan b7436dc55f refactor BackgroundTaskRunner 2015-03-27 14:47:42 +11:00
Shannon bc068b201d Updates BackgroundTaskRunner to ensure canceled or skipped tasks are disposed, updated tests to reflect 2015-03-27 14:47:42 +11:00
Shannon 912b01c9aa Updates BackgroundTaskRunner to support more complex options including the ability to only execute the last/final task in the queue. Added tests to support, updated the 'content' object to use this option so that only the last task in the queue will execute so that file persisting doesn't get queued but the correctly queued data will be written. 2015-03-27 14:47:42 +11:00
Shannon a82035061c Updates BackgroundTaskRunner to support async operations. Updates the content xml cache file persisting to use a IBackgroundTask instead of the strange queuing for persistence - which was super strange because in many cases another request thread will actually be the thread that is persisting the xml file than the request thread that requested it created. This implementation is far better, the xml file will be persisted on a non request thread and will handle multiple documents being published at the same time guaranteeing that the latest published version is the one persisted. The file persistence is also web aware (due to how BackgroundTaskRunner works) so during app shutdown the file will still be written if it's currently being processed. 2015-03-27 14:47:41 +11:00
AndyButland 0c107fd869 Ensures footer breadcrumb in content and media returned in correct order 2015-03-25 21:52:39 +01:00
kgiszewski 6419f301f7 Fix for U4-6462 2015-03-25 16:30:47 -04:00
Sebastiaan Janssen e775471013 Set disableFindContentByIdPath=false for local debugging of Umb source (the release config was already correct) 2015-03-25 17:08:53 +01:00
Shannon Deminick cc109d1ed0 Merge pull request #660 from perosb/U4-6444
Fix for U4-6444
2015-03-25 09:16:49 +11:00
Sebastiaan Janssen 9dfccd86fd U4-2499 Remove the possibility for accessing pages with nodeid's or give a redirect option
#U4-2499 Fixed Due in version 7.2.5
2015-03-24 20:09:48 +01:00
Per Osbeck ffaf1f96b9 Fix for U4-6444 2015-03-24 09:28:53 +01:00
Shannon Deminick aa3c1d645b Merge pull request #659 from robertjf/dev-v7
Issue#U4-6448 typo fix in pageIndex Mandate checks
2015-03-24 12:45:35 +11:00
Robert Foster c6b393f2e8 typo fix in pageIndex Mandate checks 2015-03-24 12:30:28 +11:00
Shannon Deminick 344d909e6b Merge pull request #657 from webprofijt/packageinstaller-spelling
Fix some spelling mistakes in package installer
2015-03-23 09:45:56 +11:00
Arnoud de Vries e3925f18ef Fix some spelling mistakes in package installer 2015-03-22 16:29:53 +01:00
Sebastiaan Janssen 53a4d063e0 U4-464 The embedded passwordStrength.js file is GPL-licensed
#U4-464 Fixed Due in version 7.2.5
2015-03-22 13:13:51 +01:00
Sebastiaan Janssen 907e5e7ca4 Bump version 2015-03-20 11:25:59 +01:00
Sebastiaan Janssen 94e281e951 Merge branch '7.2.4' into dev-v7 2015-03-20 11:23:30 +01:00
Sebastiaan Janssen c867f609f1 Merge branch '7.2.4' into master-v7 2015-03-20 11:05:00 +01:00
Sebastiaan Janssen 8c4eba7837 "It's simple until you make it complicated"
- So now this logic has been un-complicated: look for the web.config file, if it exists and has a umbracoConfigurationStatus appSetting then don't overwrite the web.config, the user is upgrading umbraco and config transforms can do their thing. Otherwise, copy in a fresh web.config with all the required Umbraco bits.
2015-03-20 10:16:53 +01:00
Shannon 08a2ec6883 Fixes: U4-6436 Localization in the back office doesn't work immediately after app restart 2015-03-20 18:15:31 +11:00
Shannon b02e0c0232 Fixes: U4-6433 Usercontrol loaded after package installation not executing 2015-03-20 17:47:33 +11:00
Shannon fff0151b62 Updates build process to: Ensure the AssemblyFileVersion is set to the real umbraco version, AssemblyInformationalVersion is set to the real umbraco version including the pre-release name if there is one, AssemblyCopyright has the correct year. 2015-03-20 09:31:14 +11:00
Sebastiaan Janssen 69879dc8f8 Merge branch 'dev-v7' into master-v7 2015-03-19 15:10:59 +01:00
Sebastiaan Janssen 90fdbb007e Bump version 2015-03-19 14:45:00 +01:00
hartvig f663a13391 Updates installer with a new number of tattoos
Kudos to Mike Perry for being #3: https://twitter.com/nvmy13t/status/574733012904099840
2015-03-09 08:52:21 +01:00
bjarnef df5c5e78ff Headline was cuttet off in Firefox
In Firefox 35.0.1 the headline was cuttet off. The 1.4 line-height in
commit 824212f6c9 ensure the headline
isn't cuttet off. However line-height: normal act as fallback as 1em it
too little and cause the text might be cuttet off.
2015-02-16 20:58:40 +01:00
bjarnef 5579823b2d Remove padding-left from h1 in modal-left
Removed left-padding from h1 in umb-modal-left to align it with the
other text in the modal.
2015-02-16 00:11:41 +01:00
bjarnef 824212f6c9 Keep headline at same position
I made a small change to make sure the headline is in same position
regardless it is editable or readonly.
2015-02-15 22:20:34 +01:00
bjarnef 7091cb6012 Change code for help videos
Change code for in help.controller.js as it was.
2015-02-05 10:52:55 +01:00
bjarnef a721f6836f Pointer cursor for sections in IE10
IE10 displayed a text cursor for tray and help section. Added cursor:
pointer; to make sure a pointer cursor is displayed.
2015-02-05 03:31:41 +01:00
bjarnef 83840ba6dd U4-4507 - Make expand arrow in sections as a toggle
I have made some suggestions, so the right arrow act as a toggle button,
so you easily can collapse the extra overflow-sections. Furthermore I
have made some changes, so when you click userDialog or helpDialog other
open dialogs close and also sections. When you click a section or expand
it also close dialogs, so you don't have to close those dialogs first.
2015-02-04 21:55:19 +01:00
Aaron Powell b8097219fb Implementing a test for U4-6035 2014-12-21 17:56:33 +11:00
redmorello e5ec935128 Update forms.less
Removed negative left margin from checkbox and radio button inputs.
2014-12-18 11:08:44 +00:00
redmorello 3ea16e66d4 Update forms.less
Removed negative left margin from input and radio button inputs.
2014-12-18 11:07:08 +00:00
Phil Hughes 562367e9a2 Label on files not just folders 2014-12-16 15:25:13 +00:00
Jeavon Leopold ee386d06da Fix for U4-5480 "Bad value for attribute rel on element img in Richtext editor" by removing the attributes in the RTE value converter so they don't render on the front end site but still exist in the Umbraco UI 2014-10-01 18:48:23 +01:00
305 changed files with 8352 additions and 5598 deletions
+2 -4
View File
@@ -23,7 +23,7 @@ ReplaceIISExpressPortNumber.exe ..\src\Umbraco.Web.UI\Umbraco.Web.UI.csproj %rel
ECHO Installing the Microsoft.Bcl.Build package before anything else, otherwise you'd have to run build.cmd twice
SET nuGetFolder=%CD%\..\src\packages\
..\src\.nuget\NuGet.exe sources Remove -Name MyGetUmbracoCore
..\src\.nuget\NuGet.exe sources Remove -Name MyGetUmbracoCore >NUL
..\src\.nuget\NuGet.exe sources Add -Name MyGetUmbracoCore -Source https://www.myget.org/F/umbracocore/api/v2/ >NUL
..\src\.nuget\NuGet.exe install ..\src\Umbraco.Web.UI\packages.config -OutputDirectory %nuGetFolder%
..\src\.nuget\NuGet.exe install ..\src\umbraco.businesslogic\packages.config -OutputDirectory %nuGetFolder%
@@ -49,14 +49,12 @@ ECHO Setting node_modules folder to hidden to prevent VS13 from crashing on it w
attrib +h ..\src\Umbraco.Web.UI.Client\node_modules
ECHO Adding Web.config transform files to the NuGet package
REN .\_BuildOutput\WebApp\MacroScripts\Web.config Web.config.transform
REN .\_BuildOutput\WebApp\Views\Web.config Web.config.transform
REN .\_BuildOutput\WebApp\Xslt\Web.config Web.config.transform
ECHO Packing the NuGet release files
..\src\.nuget\NuGet.exe Pack NuSpecs\UmbracoCms.Core.nuspec -Version %version%
..\src\.nuget\NuGet.exe Pack NuSpecs\UmbracoCms.Core.nuspec -Version %version% -Symbols
..\src\.nuget\NuGet.exe Pack NuSpecs\UmbracoCms.nuspec -Version %version%
..\src\.nuget\NuGet.exe Pack NuSpecs\UmbracoExamine.PDF.nuspec
IF ERRORLEVEL 1 GOTO :showerror
+90 -113
View File
@@ -1,4 +1,3 @@
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!--
@@ -14,18 +13,18 @@
<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">
<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" />
<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 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)
@@ -48,11 +47,11 @@
}
}
]]>
</Code>
</Code>
</Task>
</UsingTask>
</UsingTask>
<!--
****************************************************
VARIABLES
@@ -76,23 +75,19 @@
<BuildZipFileName>UmbracoCms$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileName>
<BuildZipFileNameBin>UmbracoCms.AllBinaries$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileNameBin>
<BuildZipFileNameWebPi>UmbracoCms.WebPI$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileNameWebPi>
<BuildZipExaminePDFName>UmbracoExamine.PDF.0.6.0.zip</BuildZipExaminePDFName>
<IncludeSymbols>False</IncludeSymbols>
<BuildFolderRelativeToProjects>..\..\build\$(BuildFolder)</BuildFolderRelativeToProjects>
<BuildFolderAbsolutePath>$(MSBuildProjectDirectory)\$(BuildFolder)</BuildFolderAbsolutePath>
<SolutionBinFolder>$(BuildFolder)bin\</SolutionBinFolder>
<WebAppFolder>$(BuildFolder)WebApp\</WebAppFolder>
<WebPiFolder>$(BuildFolder)WebPi\</WebPiFolder>
<ConfigsFolder>$(BuildFolder)Configs\</ConfigsFolder>
<ConfigsFolder>$(BuildFolder)Configs\</ConfigsFolder>
<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>
@@ -114,16 +109,16 @@
*****************************************************
-->
<Target Name="Build" DependsOnTargets="GenerateWebPiHash">
<Target Name="Build" DependsOnTargets="GenerateWebPiHash">
<Message Text="Build finished" />
</Target>
<Target Name="GenerateWebPiHash" DependsOnTargets="ZipWebPiApp">
<ItemGroup>
</Target>
<Target Name="GenerateWebPiHash" DependsOnTargets="ZipWebPiApp">
<ItemGroup>
<WebPiFile Include="$(BuildZipFileNameWebPi)" />
</ItemGroup>
<Message Text="Calculating hash for $(BuildZipFileNameWebPi)" />
<GenerateHash InputFiles="@(WebPiFile)" OutputFile="webpihash.txt" />
</ItemGroup>
<Message Text="Calculating hash for $(BuildZipFileNameWebPi)" />
<GenerateHash InputFiles="@(WebPiFile)" OutputFile="webpihash.txt" />
</Target>
<Target Name="CleanUp" DependsOnTargets="ZipWebPiApp">
@@ -150,10 +145,10 @@
DestinationFiles="@(WebPiFiles->'$(WebPiFolder)%(RecursiveDir)%(Filename)%(Extension)')" />
<!-- Zip the files -->
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipFileNameWebPi)%22 %22$(WebPiFolderAbsolutePath)*%22" />
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipFileNameWebPi)%22 %22$(WebPiFolderAbsolutePath)*%22 -x!dotLess.Core.dll" />
</Target>
<Target Name="ZipWebApp" DependsOnTargets="ZipUmbracoExaminePDF" >
<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 -x!dotLess.Core.dll" />
@@ -162,14 +157,6 @@
<Message Text="Finished zipping to build\$(BuildFolder)\$(buildDate)-$(BuildZipFileName)" Importance="high" />
</Target>
<Target Name="ZipUmbracoExaminePDF" DependsOnTargets="CreateSystemFolders" >
<Message Text="Starting to zip to $(buildDate)-$(BuildZipExaminePDFName)" Importance="high" />
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipExaminePDFName)%22 %22$(ExaminePDFPath)*%22" />
<Message Text="Finished zipping to build\$(BuildFolder)\$(buildDate)-$(BuildZipExaminePDFName)" Importance="high" />
</Target>
<Target Name="CreateSystemFolders" DependsOnTargets="CopyBelleBuild" Inputs="@(SystemFolders)" Outputs="%(Identity).Dummy">
<MakeDir Directories="@(SystemFolders)" />
</Target>
@@ -177,14 +164,14 @@
<Target Name="CopyBelleBuild" DependsOnTargets="CopyLibraries" >
<ItemGroup>
<BelleFiles Include="..\src\Umbraco.Web.UI.Client\build\belle\**\*.*" Exclude="..\src\Umbraco.Web.UI.Client\build\belle\index.html" />
</ItemGroup>
<Copy SourceFiles="@(BelleFiles)"
DestinationFiles="@(BelleFiles->'$(WebAppFolder)umbraco\%(RecursiveDir)%(Filename)%(Extension)')"
OverwriteReadOnlyFiles="true"
SkipUnchangedFiles="false" />
</ItemGroup>
<Copy SourceFiles="@(BelleFiles)"
DestinationFiles="@(BelleFiles->'$(WebAppFolder)umbraco\%(RecursiveDir)%(Filename)%(Extension)')"
OverwriteReadOnlyFiles="true"
SkipUnchangedFiles="false" />
</Target>
<Target Name="CopyLibraries" DependsOnTargets="OffsetTimestamps" >
<!-- Copy SQL CE -->
<ItemGroup>
@@ -217,7 +204,7 @@
</Target>
<!-- Copy the transformed web.config file to the root -->
<Target Name="CopyTransformedWebConfig" DependsOnTargets="CopyTransformedConfig">
<Target Name="CopyTransformedWebConfig" DependsOnTargets="CopyTransformedConfig">
<ItemGroup>
<WebConfigFile Include="..\src\Umbraco.Web.UI\web.$(BuildConfiguration).Config.transformed" />
</ItemGroup>
@@ -226,24 +213,24 @@
DestinationFiles="$(WebAppFolder)Web.config"
OverwriteReadOnlyFiles="true"
SkipUnchangedFiles="false" />
</Target>
<!-- Copy the config files and rename them to *.config.transform -->
<Target Name="CopyTransformedConfig" DependsOnTargets="CopyXmlDocumentation">
</Target>
<!-- Copy the config files and rename them to *.config.transform -->
<Target Name="CopyTransformedConfig" DependsOnTargets="CopyXmlDocumentation">
<ItemGroup>
<ConfigFiles Include="$(WebAppFolder)config\*.config;$(WebAppFolder)config\*.js" />
<WebConfigTransformFile Include="$(WebAppFolder)Web.config" />
</ItemGroup>
<Copy SourceFiles="@(ConfigFiles)"
DestinationFiles="@(ConfigFiles->'$(ConfigsFolder)\%(RecursiveDir)%(Filename)%(Extension)')"
OverwriteReadOnlyFiles="true"
SkipUnchangedFiles="false" />
<Copy SourceFiles="@(WebConfigTransformFile)"
DestinationFiles="$(ConfigsFolder)Web.config.transform"
OverwriteReadOnlyFiles="true"
SkipUnchangedFiles="false" />
<ConfigFiles Include="$(WebAppFolder)config\*.config;$(WebAppFolder)config\*.js" />
<WebConfigTransformFile Include="$(WebAppFolder)Web.config" />
</ItemGroup>
<Copy SourceFiles="@(ConfigFiles)"
DestinationFiles="@(ConfigFiles->'$(ConfigsFolder)\%(RecursiveDir)%(Filename)%(Extension)')"
OverwriteReadOnlyFiles="true"
SkipUnchangedFiles="false" />
<Copy SourceFiles="@(WebConfigTransformFile)"
DestinationFiles="$(ConfigsFolder)Web.config.transform"
OverwriteReadOnlyFiles="true"
SkipUnchangedFiles="false" />
</Target>
<!-- Copy the xml documentation to the bin folder -->
@@ -261,66 +248,31 @@
<!-- Unlike 2010, the VS2012 build targets file doesn't clean up the umbraco.presentation dir, do it manually -->
<Target Name="CleanupPresentation" DependsOnTargets="CompileProjects">
<ItemGroup>
<PresentationFolderToDelete Include="$(WebAppFolder)umbraco.presentation" />
<ItemGroup>
<PresentationFolderToDelete Include="$(WebAppFolder)umbraco.presentation" />
</ItemGroup>
<RemoveDir Directories="@(PresentationFolderToDelete)" />
<RemoveDir Directories="@(PresentationFolderToDelete)" />
</Target>
<Target Name="CompileProjects" DependsOnTargets="CompileExternalExamineProjects">
<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 -->
<!-- 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;Rebuild;" 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)'!=''">
<PropertyGroup>
<NewVersion>$(BUILD_RELEASE)</NewVersion>
<NewVersion Condition="'$(BUILD_COMMENT)'!=''">$(BUILD_RELEASE)-$(BUILD_COMMENT)</NewVersion>
</PropertyGroup>
<!-- Match & replace 3 and 4 digit version numbers and -beta (if it's there) -->
<PropertyGroup>
<NewVersion>$(BUILD_RELEASE)</NewVersion>
<NewVersion Condition="'$(BUILD_COMMENT)'!=''">$(BUILD_RELEASE)-$(BUILD_COMMENT)</NewVersion>
</PropertyGroup>
<!-- Match & replace 3 and 4 digit version numbers and -beta (if it's there) -->
<FileUpdate
Files="..\src\Umbraco.Core\Configuration\UmbracoVersion.cs"
Regex="(\d+)\.(\d+)\.(\d+)(.(\d+))?"
@@ -329,10 +281,35 @@
<FileUpdate Files="..\src\Umbraco.Core\Configuration\UmbracoVersion.cs"
Regex="CurrentComment { get { return &quot;(.+)?&quot;"
ReplacementText="CurrentComment { get { return &quot;$(BUILD_COMMENT)&quot;"/>
<XmlPoke XmlInputPath=".\NuSpecs\build\UmbracoCms.props"
Namespaces="&lt;Namespace Prefix='x' Uri='http://schemas.microsoft.com/developer/msbuild/2003' /&gt;"
Query="//x:UmbracoVersion"
Value="$(NewVersion)" />
<!--This updates the AssemblyFileVersion for the solution to the umbraco version-->
<FileUpdate
Files="..\src\SolutionInfo.cs"
Regex="AssemblyFileVersion\(&quot;(.+)?&quot;\)"
ReplacementText="AssemblyFileVersion(&quot;$(BUILD_RELEASE)&quot;)"/>
<!--This updates the AssemblyInformationalVersion for the solution to the umbraco version and comment-->
<FileUpdate
Condition="'$(BUILD_COMMENT)'!=''"
Files="..\src\SolutionInfo.cs"
Regex="AssemblyInformationalVersion\(&quot;(.+)?&quot;\)"
ReplacementText="AssemblyInformationalVersion(&quot;$(BUILD_RELEASE)-$(BUILD_COMMENT)&quot;)"/>
<FileUpdate
Condition="'$(BUILD_COMMENT)'==''"
Files="..\src\SolutionInfo.cs"
Regex="AssemblyInformationalVersion\(&quot;(.+)?&quot;\)"
ReplacementText="AssemblyInformationalVersion(&quot;$(BUILD_RELEASE)&quot;)"/>
<!--This updates the copyright year-->
<FileUpdate
Condition="'$(BUILD_COMMENT)'==''"
Files="..\src\SolutionInfo.cs"
Regex="AssemblyCopyright\(&quot;Copyright © Umbraco (\d{4})&quot;\)"
ReplacementText="AssemblyCopyright(&quot;Copyright © Umbraco $([System.DateTime]::Now.ToString(`yyyy`))&quot;)"/>
<XmlPoke XmlInputPath=".\NuSpecs\build\UmbracoCms.props"
Namespaces="&lt;Namespace Prefix='x' Uri='http://schemas.microsoft.com/developer/msbuild/2003' /&gt;"
Query="//x:UmbracoVersion"
Value="$(NewVersion)" />
</Target>
</Project>
@@ -1,73 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>UmbracoCms.Core.AllBinaries</id>
<version>6.1.2</version>
<title>Umbraco Cms Core All Binaries</title>
<authors>Morten Christensen</authors>
<owners>Umbraco HQ</owners>
<licenseUrl>http://umbraco.codeplex.com/license</licenseUrl>
<projectUrl>http://umbraco.com/</projectUrl>
<iconUrl>http://umbraco.com/media/357769/100px_transparent.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Contains the core assemblies and all of the dependant assemblies needed to run Umbraco Cms. This package only contains assemblies and can be used for package development. Use the UmbracoCms-package to setup Umbraco in Visual Studio as an ASP.NET project.</description>
<summary>Contains the core assemblies and all of the dependant assemblies needed to run Umbraco Cms</summary>
<language>en-US</language>
<tags>umbraco</tags>
</metadata>
<files>
<file src="..\_BuildOutput\bin\businesslogic.dll" target="lib\businesslogic.dll" />
<file src="..\_BuildOutput\bin\AutoMapper.dll" target="lib\AutoMapper.dll" />
<file src="..\_BuildOutput\bin\AutoMapper.Net4.dll" target="lib\AutoMapper.Net4.dll" />
<file src="..\_BuildOutput\bin\businesslogic.dll" target="lib\businesslogic.dll" />
<file src="..\_BuildOutput\bin\ClientDependency.Core.dll" target="lib\ClientDependency.Core.dll" />
<file src="..\_BuildOutput\bin\ClientDependency.Core.Mvc.dll" target="lib\ClientDependency.Core.Mvc.dll" />
<file src="..\_BuildOutput\bin\cms.dll" target="lib\cms.dll" />
<file src="..\_BuildOutput\bin\controls.dll" target="lib\controls.dll" />
<file src="..\_BuildOutput\bin\CookComputing.XmlRpcV2.dll" target="lib\CookComputing.XmlRpcV2.dll" />
<file src="..\_BuildOutput\bin\Examine.dll" target="lib\Examine.dll" />
<file src="..\_BuildOutput\bin\HtmlAgilityPack.dll" target="lib\HtmlAgilityPack.dll" />
<file src="..\_BuildOutput\bin\ICSharpCode.SharpZipLib.dll" target="lib\ICSharpCode.SharpZipLib.dll" />
<file src="..\_BuildOutput\bin\ImageProcessor.dll" target="lib\ImageProcessor.dll" />
<file src="..\_BuildOutput\bin\ImageProcessor.Web.dll" target="lib\ImageProcessor.Web.dll" />
<file src="..\_BuildOutput\bin\interfaces.dll" target="lib\interfaces.dll" />
<file src="..\_BuildOutput\bin\log4net.dll" target="lib\log4net.dll" />
<file src="..\_BuildOutput\bin\Lucene.Net.dll" target="lib\Lucene.Net.dll" />
<file src="..\_BuildOutput\bin\Microsoft.ApplicationBlocks.Data.dll" target="lib\Microsoft.ApplicationBlocks.Data.dll" />
<file src="..\_BuildOutput\bin\Microsoft.Threading.Tasks.dll" target="lib\Microsoft.Threading.Tasks.dll" />
<file src="..\_BuildOutput\bin\Microsoft.Threading.Tasks.Extensions.dll" target="lib\Microsoft.Threading.Tasks.Extensions.dll" />
<file src="..\_BuildOutput\bin\Microsoft.Web.Infrastructure.dll" target="lib\Microsoft.Web.Infrastructure.dll" />
<file src="..\_BuildOutput\bin\Microsoft.Web.Mvc.FixedDisplayModes.dll" target="lib\Microsoft.Web.Mvc.FixedDisplayModes.dll" />
<file src="..\_BuildOutput\bin\MiniProfiler.dll" target="lib\MiniProfiler.dll" />
<file src="..\_BuildOutput\bin\MySql.Data.dll" target="lib\MySql.Data.dll" />
<file src="..\_BuildOutput\bin\Newtonsoft.Json.dll" target="lib\Newtonsoft.Json.dll" />
<file src="..\_BuildOutput\bin\NuGet.Core.dll" target="lib\NuGet.Core.dll" />
<file src="..\_BuildOutput\bin\SQLCE4Umbraco.dll" target="lib\SQLCE4Umbraco.dll" />
<file src="..\_BuildOutput\bin\System.Data.SqlServerCe.dll" target="lib\System.Data.SqlServerCe.dll" />
<file src="..\_BuildOutput\bin\System.Data.SqlServerCe.Entity.dll" target="lib\System.Data.SqlServerCe.Entity.dll" />
<file src="..\_BuildOutput\bin\System.Net.Http.dll" target="lib\System.Net.Http.dll" />
<file src="..\_BuildOutput\bin\System.Net.Http.Extensions.dll" target="lib\System.Net.Http.Extensions.dll" />
<file src="..\_BuildOutput\bin\System.Net.Http.Formatting.dll" target="lib\System.Net.Http.Formatting.dll" />
<file src="..\_BuildOutput\bin\System.Net.Http.Primitives.dll" target="lib\System.Net.Http.Primitives.dll" />
<file src="..\_BuildOutput\bin\System.Net.Http.WebRequest.dll" target="lib\System.Net.Http.WebRequest.dll" />
<file src="..\_BuildOutput\bin\System.Web.Helpers.dll" target="lib\System.Web.Helpers.dll" />
<file src="..\_BuildOutput\bin\System.Web.Http.dll" target="lib\System.Web.Http.dll" />
<file src="..\_BuildOutput\bin\System.Web.Http.WebHost.dll" target="lib\System.Web.Http.WebHost.dll" />
<file src="..\_BuildOutput\bin\System.Web.Mvc.dll" target="lib\System.Web.Mvc.dll" />
<file src="..\_BuildOutput\bin\System.Web.Razor.dll" target="lib\System.Web.Razor.dll" />
<file src="..\_BuildOutput\bin\System.Web.WebPages.Administration.dll" target="lib\System.Web.WebPages.Administration.dll" />
<file src="..\_BuildOutput\bin\System.Web.WebPages.Deployment.dll" target="lib\System.Web.WebPages.Deployment.dll" />
<file src="..\_BuildOutput\bin\System.Web.WebPages.dll" target="lib\System.Web.WebPages.dll" />
<file src="..\_BuildOutput\bin\System.Web.WebPages.Razor.dll" target="lib\System.Web.WebPages.Razor.dll" />
<file src="..\_BuildOutput\bin\TidyNet.dll" target="lib\TidyNet.dll" />
<file src="..\_BuildOutput\bin\Umbraco.Core.dll" target="lib\Umbraco.Core.dll" />
<file src="..\_BuildOutput\bin\umbraco.DataLayer.dll" target="lib\umbraco.DataLayer.dll" />
<file src="..\_BuildOutput\bin\umbraco.dll" target="lib\umbraco.dll" />
<file src="..\_BuildOutput\bin\umbraco.editorControls.dll" target="lib\umbraco.editorControls.dll" />
<file src="..\_BuildOutput\bin\umbraco.MacroEngines.dll" target="lib\umbraco.MacroEngines.dll" />
<file src="..\_BuildOutput\bin\umbraco.providers.dll" target="lib\umbraco.providers.dll" />
<file src="..\_BuildOutput\bin\Umbraco.Web.UI.dll" target="lib\Umbraco.Web.UI.dll" />
<file src="..\_BuildOutput\bin\UmbracoExamine.dll" target="lib\UmbracoExamine.dll" />
<file src="..\_BuildOutput\bin\UrlRewritingNet.UrlRewriter.dll" target="lib\UrlRewritingNet.UrlRewriter.dll" />
</files>
</package>
@@ -1,71 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>UmbracoCms.Core</id>
<version>7.0.0</version>
<title>Umbraco Cms Core Binaries</title>
<authors>Umbraco HQ</authors>
<owners>Umbraco HQ</owners>
<licenseUrl>http://umbraco.codeplex.com/license</licenseUrl>
<projectUrl>http://umbraco.com/</projectUrl>
<iconUrl>http://umbraco.com/media/357769/100px_transparent.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Contains the core assemblies needed to run Umbraco Cms. This package only contains assemblies and can be used for package development. Use the UmbracoCms-package to setup Umbraco in Visual Studio as an ASP.NET project.</description>
<summary>Contains the core assemblies needed to run Umbraco Cms</summary>
<language>en-US</language>
<tags>umbraco</tags>
</metadata>
<files>
<file src="..\..\src\SQLCE4Umbraco\obj\Debug\SQLCE4Umbraco.dll" target="lib" />
<file src="..\..\src\SQLCE4Umbraco\obj\Debug\SQLCE4Umbraco.pdb" target="lib" />
<file src="..\..\src\SQLCE4Umbraco\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\SQLCE4Umbraco" />
<file src="..\..\src\umbraco.businesslogic\obj\Debug\businesslogic.dll" target="lib" />
<file src="..\..\src\umbraco.businesslogic\obj\Debug\businesslogic.pdb" target="lib" />
<file src="..\..\src\umbraco.businesslogic\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.businesslogic" />
<file src="..\..\src\umbraco.cms\obj\Debug\cms.dll" target="lib" />
<file src="..\..\src\umbraco.cms\obj\Debug\cms.pdb" target="lib" />
<file src="..\..\src\umbraco.cms\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.cms" />
<file src="..\..\src\umbraco.controls\obj\Debug\controls.dll" target="lib" />
<file src="..\..\src\umbraco.controls\obj\Debug\controls.pdb" target="lib" />
<file src="..\..\src\umbraco.controls\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.controls" />
<file src="..\..\src\umbraco.interfaces\obj\Debug\interfaces.dll" target="lib" />
<file src="..\..\src\umbraco.interfaces\obj\Debug\interfaces.pdb" target="lib" />
<file src="..\..\src\umbraco.interfaces\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.interfaces" />
<file src="..\..\src\Umbraco.Core\obj\Debug\Umbraco.Core.dll" target="lib" />
<file src="..\..\src\Umbraco.Core\obj\Debug\Umbraco.Core.pdb" target="lib" />
<file src="..\..\src\Umbraco.Core\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\Umbraco.Core" />
<file src="..\..\src\umbraco.datalayer\obj\Debug\umbraco.DataLayer.dll" target="lib" />
<file src="..\..\src\umbraco.datalayer\obj\Debug\umbraco.DataLayer.pdb" target="lib" />
<file src="..\..\src\umbraco.datalayer\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.datalayer" />
<file src="..\..\src\umbraco.editorControls\obj\Debug\umbraco.editorControls.dll" target="lib" />
<file src="..\..\src\umbraco.editorControls\obj\Debug\umbraco.editorControls.pdb" target="lib" />
<file src="..\..\src\umbraco.editorControls\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.editorControls" />
<file src="..\..\src\umbraco.MacroEngines\obj\Debug\umbraco.MacroEngines.dll" target="lib" />
<file src="..\..\src\umbraco.MacroEngines\obj\Debug\umbraco.MacroEngines.pdb" target="lib" />
<file src="..\..\src\umbraco.MacroEngines\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.MacroEngines" />
<file src="..\..\src\umbraco.providers\obj\Debug\umbraco.providers.dll" target="lib" />
<file src="..\..\src\umbraco.providers\obj\Debug\umbraco.providers.pdb" target="lib" />
<file src="..\..\src\umbraco.providers\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.providers" />
<file src="..\..\src\Umbraco.Web\obj\Debug\umbraco.dll" target="lib" />
<file src="..\..\src\Umbraco.Web\obj\Debug\umbraco.pdb" target="lib" />
<file src="..\..\src\Umbraco.Web\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\Umbraco.Web" />
<file src="..\..\src\bin\Debug\Umbraco.Web.UI.dll" target="lib" />
<file src="..\..\src\bin\Debug\Umbraco.Web.UI.pdb" target="lib" />
<file src="..\..\src\Umbraco.Web.UI\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\Umbraco.Web.UI" />
<file src="..\..\src\UmbracoExamine\obj\Debug\UmbracoExamine.dll" target="lib" />
<file src="..\..\src\UmbracoExamine\obj\Debug\UmbracoExamine.pdb" target="lib" />
<file src="..\..\src\UmbracoExamine\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\UmbracoExamine" />
</files>
</package>
+35 -4
View File
@@ -6,7 +6,7 @@
<title>Umbraco Cms Core Binaries</title>
<authors>Umbraco HQ</authors>
<owners>Umbraco HQ</owners>
<licenseUrl>http://umbraco.codeplex.com/license</licenseUrl>
<licenseUrl>http://opensource.org/licenses/MIT</licenseUrl>
<projectUrl>http://umbraco.com/</projectUrl>
<iconUrl>http://umbraco.com/media/357769/100px_transparent.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
@@ -26,13 +26,13 @@
<dependency id="HtmlAgilityPack" version="[1.4.6, 2.0.0)" />
<dependency id="Lucene.Net" version="[2.9.4.1, 3.0.0.0)" />
<dependency id="SharpZipLib" version="[0.86.0, 1.0.0)" />
<dependency id="MySql.Data" version="[6.6.5]" />
<dependency id="MySql.Data" version="[6.9.6, 7.0.0)" />
<dependency id="xmlrpcnet" version="[2.5.0, 3.0.0)" />
<dependency id="ClientDependency" version="[1.8.3.1, 2.0.0)" />
<dependency id="ClientDependency" version="[1.8.4, 2.0.0)" />
<dependency id="ClientDependency-Mvc" version="[1.8.0, 2.0.0)" />
<dependency id="AutoMapper" version="[3.0.0, 4.0.0)" />
<dependency id="Newtonsoft.Json" version="[6.0.5, 7.0.0)" />
<dependency id="Examine" version="[0.1.60, 1.0.0)" />
<dependency id="Examine" version="[0.1.65, 1.0.0)" />
<dependency id="ImageProcessor" version="[1.9.5, 3.0.0)" />
<dependency id="ImageProcessor.Web" version="[3.3.1, 5.0.0)" />
</dependencies>
@@ -49,6 +49,7 @@
<file src="..\_BuildOutput\WebApp\bin\log4net.dll" target="lib\log4net.dll" />
<file src="..\_BuildOutput\WebApp\bin\Microsoft.ApplicationBlocks.Data.dll" target="lib\Microsoft.ApplicationBlocks.Data.dll" />
<file src="..\_BuildOutput\WebApp\bin\SQLCE4Umbraco.dll" target="lib\SQLCE4Umbraco.dll" />
<file src="..\_BuildOutput\WebApp\bin\SQLCE4Umbraco.xml" target="lib\SQLCE4Umbraco.xml" />
<file src="..\_BuildOutput\WebApp\bin\System.Data.SqlServerCe.dll" target="lib\System.Data.SqlServerCe.dll" />
<file src="..\_BuildOutput\WebApp\bin\System.Data.SqlServerCe.Entity.dll" target="lib\System.Data.SqlServerCe.Entity.dll" />
<file src="..\_BuildOutput\WebApp\bin\TidyNet.dll" target="lib\TidyNet.dll" />
@@ -65,8 +66,38 @@
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.dll" target="lib\umbraco.providers.dll" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.xml" target="lib\umbraco.providers.xml" />
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Web.UI.dll" target="lib\Umbraco.Web.UI.dll" />
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Web.UI.xml" target="lib\Umbraco.Web.UI.xml" />
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.dll" target="lib\UmbracoExamine.dll" />
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.xml" target="lib\UmbracoExamine.xml" />
<file src="..\_BuildOutput\WebApp\bin\UrlRewritingNet.UrlRewriter.dll" target="lib\UrlRewritingNet.UrlRewriter.dll" />
<file src="tools\install.core.ps1" target="tools\install.ps1" />
<!-- Added to be able to produce a symbols package -->
<file src="..\_BuildOutput\bin\SQLCE4Umbraco.pdb" target="lib" />
<file src="..\..\src\SQLCE4Umbraco\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\SQLCE4Umbraco" />
<file src="..\_BuildOutput\bin\businesslogic.pdb" target="lib" />
<file src="..\..\src\umbraco.businesslogic\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.businesslogic" />
<file src="..\_BuildOutput\bin\cms.pdb" target="lib" />
<file src="..\..\src\umbraco.cms\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.cms" />
<file src="..\_BuildOutput\bin\controls.pdb" target="lib" />
<file src="..\..\src\umbraco.controls\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.controls" />
<file src="..\_BuildOutput\bin\interfaces.pdb" target="lib" />
<file src="..\..\src\umbraco.interfaces\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.interfaces" />
<file src="..\_BuildOutput\bin\Umbraco.Core.pdb" target="lib" />
<file src="..\..\src\Umbraco.Core\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\Umbraco.Core" />
<file src="..\_BuildOutput\bin\umbraco.DataLayer.pdb" target="lib" />
<file src="..\..\src\umbraco.datalayer\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.datalayer" />
<file src="..\_BuildOutput\bin\umbraco.editorControls.pdb" target="lib" />
<file src="..\..\src\umbraco.editorControls\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.editorControls" />
<file src="..\_BuildOutput\bin\umbraco.MacroEngines.pdb" target="lib" />
<file src="..\..\src\umbraco.MacroEngines\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.MacroEngines" />
<file src="..\_BuildOutput\bin\umbraco.providers.pdb" target="lib" />
<file src="..\..\src\umbraco.providers\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.providers" />
<file src="..\_BuildOutput\bin\umbraco.pdb" target="lib" />
<file src="..\..\src\Umbraco.Web\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\Umbraco.Web" />
<file src="..\_BuildOutput\bin\Umbraco.Web.UI.pdb" target="lib" />
<file src="..\..\src\Umbraco.Web.UI\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\Umbraco.Web.UI" />
<file src="..\_BuildOutput\bin\UmbracoExamine.pdb" target="lib" />
<file src="..\..\src\UmbracoExamine\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\UmbracoExamine" />
</files>
</package>
+2 -1
View File
@@ -6,7 +6,7 @@
<title>Umbraco Cms</title>
<authors>Umbraco HQ</authors>
<owners>Umbraco HQ</owners>
<licenseUrl>http://umbraco.codeplex.com/license</licenseUrl>
<licenseUrl>http://opensource.org/licenses/MIT</licenseUrl>
<projectUrl>http://umbraco.com/</projectUrl>
<iconUrl>http://umbraco.com/media/357769/100px_transparent.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
@@ -34,6 +34,7 @@
<file src="..\_BuildOutput\WebApp\umbraco_client\**" target="UmbracoFiles\umbraco_client" />
<file src="tools\install.ps1" target="tools\install.ps1" />
<file src="tools\Readme.txt" target="tools\Readme.txt" />
<file src="tools\ReadmeUpgrade.txt" target="tools\ReadmeUpgrade.txt" />
<file src="tools\Web.config.install.xdt" target="Content\Web.config.install.xdt" />
<file src="tools\applications.config.install.xdt" target="Content\config\applications.config.install.xdt" />
<file src="tools\ClientDependency.config.install.xdt" target="Content\config\ClientDependency.config.install.xdt" />
+1 -1
View File
@@ -5,7 +5,7 @@
<version>0.7.0</version>
<authors>Umbraco HQ</authors>
<owners>Umbraco HQ</owners>
<licenseUrl>http://umbraco.codeplex.com/license</licenseUrl>
<licenseUrl>http://opensource.org/licenses/MIT</licenseUrl>
<projectUrl>http://umbraco.com/</projectUrl>
<iconUrl>http://umbraco.com/media/357769/100px_transparent.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
-10
View File
@@ -8,21 +8,11 @@
----------------------------------------------------
A note about running Umbraco from Visual Studio.
Don't forget to build!
When upgrading your website using NuGet you should answer "No" to the questions to overwrite the Web.config
file (and config files in the config folder).
We've done our best to transform your configuration files but in case something is not quite right: remember we
backed up your files in App_Data\NuGetBackup so you can find the original files before they were transformed.
We've overwritten all the files in the Umbraco and Umbraco_Client folder, these have been backed up in
App_Data\NuGetBackup. We didn't overwrite the UI.xml file nor did we remove any files or folders that you or
a package might have added. Only the existing files were overwritten. If you customized anything then make
sure to do a compare and merge with the NuGetBackup folder.
This NuGet package includes build targets that extend the creation of a deploy package, which is generated by
Publishing from Visual Studio. The targets will only work once Publishing is configured, so if you don't use
Publish this won't affect you.
+33
View File
@@ -0,0 +1,33 @@
_ _ __ __ ____ _____ _____ ____
| | | | \/ | _ \| __ \ /\ / ____/ __ \
| | | | \ / | |_) | |__) | / \ | | | | | |
| | | | |\/| | _ <| _ / / /\ \| | | | | |
| |__| | | | | |_) | | \ \ / ____ | |___| |__| |
\____/|_| |_|____/|_| \_/_/ \_\_____\____/
----------------------------------------------------
Don't forget to build!
When upgrading your website using NuGet you should answer "No" to the questions to overwrite the Web.config
file (and config files in the config folder).
We've done our best to transform your configuration files but in case something is not quite right: remember we
backed up your files in App_Data\NuGetBackup so you can find the original files before they were transformed.
We've overwritten all the files in the Umbraco and Umbraco_Client folder, these have been backed up in
App_Data\NuGetBackup. We didn't overwrite the UI.xml file nor did we remove any files or folders that you or
a package might have added. Only the existing files were overwritten. If you customized anything then make
sure to do a compare and merge with the NuGetBackup folder.
This NuGet package includes build targets that extend the creation of a deploy package, which is generated by
Publishing from Visual Studio. The targets will only work once Publishing is configured, so if you don't use
Publish this won't affect you.
The following items will now be automatically included when creating a deploy package or publishing to the file
system: umbraco, umbraco_client, config\splashes and global.asax.
Please read the release notes on our.umbraco.org:
http://our.umbraco.org/contribute/releases
- Umbraco
+4 -2
View File
@@ -37,8 +37,10 @@
<DbProviderFactories xdt:Transform="InsertIfMissing">
<remove invariant="System.Data.SqlServerCe.4.0" xdt:Locator="Match(invariant)" xdt:Transform="InsertIfMissing" />
<add name="Microsoft SQL Server Compact Data Provider 4.0" invariant="System.Data.SqlServerCe.4.0" description=".NET Framework Data Provider for Microsoft SQL Server Compact" type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe" xdt:Locator="Match(invariant)" xdt:Transform="SetAttributes(invariant,description,type)" />
<remove invariant="MySql.Data.MySqlClient" xdt:Locator="Match(invariant)" xdt:Transform="InsertIfMissing" />
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data" xdt:Locator="Match(invariant)" xdt:Transform="SetAttributes(invariant,description,type)" />
<remove invariant="MySql.Data.MySqlClient" xdt:Locator="Match(invariant)" xdt:Transform="InsertIfMissing" />
<add invariant="MySql.Data.MySqlClient" xdt:Locator="Match(invariant)" xdt:Transform="Remove" />
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data" xdt:Locator="Match(invariant)" xdt:Transform="InsertIfMissing" />
<add invariant="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data" xdt:Locator="Match(invariant)" xdt:Transform="SetAttributes(type)" />
</DbProviderFactories>
</system.data>
<clientDependency xdt:Transform="RemoveAttributes(version)" />
+10 -3
View File
@@ -73,13 +73,20 @@ if ($project) {
{
$packageWebConfigSource = Join-Path $rootPath "UmbracoFiles\Web.config"
Copy-Item $packageWebConfigSource $destinationWebConfig -Force
}
}
$installFolder = Join-Path $projectDestinationPath "Install"
if(Test-Path $installFolder) {
Remove-Item $installFolder -Force -Recurse -Confirm:$false
}
# Open readme.txt file
$DTE.ItemOperations.OpenFile($toolsPath + '\Readme.txt')
# Open appropriate readme
if($copyWebconfig -eq $true)
{
$DTE.ItemOperations.OpenFile($toolsPath + '\Readme.txt')
}
else
{
$DTE.ItemOperations.OpenFile($toolsPath + '\ReadmeUpgrade.txt')
}
}
+1 -1
View File
@@ -1,2 +1,2 @@
# Usage: on line 2 put the release version, on line 3 put the version comment (example: beta)
7.2.4
7.2.7
-13
View File
@@ -1,13 +0,0 @@
Umbraco CMS version 4.5 is licensed under the OSI approved MIT License:
Copyright (c) 2007-2010 umbraco I/S.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Umbraco versions prior to 4.5 were licensed under a combination of MIT and a propriatary UI license. The license history can be found here:
http://umbraco.codeplex.com/license
-33
View File
@@ -1,33 +0,0 @@
Umbraco - the simple, flexible and friendly ASP.NET CMS
=======================================================
For the first time on the Microsoft platform a free user and developer friendly cms that makes it quick and easy to create websites - or a breeze to build complex web applications. umbraco got award-winning integration capabilities and supports your ASP.NET User and Custom Controls out of the box. It's a developers dream and your users will love it too. Used by more than 57.000 active websites including Heinz.com, Peugeot.com, NAIAS.com and Microsofts documentinteropinitiative.org website you can be sure that the technology is proven, stable and scales.
More info at http://umbraco.com
Exploring the repository
========================
Most contributors will work on their own fork and should pick the branch in which they need their fix. For more information see:
http://our.umbraco.org/contribute/guidelines-for-core-contribution
Exploring the source
====================
The Umbraco source code is never required for you to start building sites. If you are not using the source code for debugging purposes or to contribute to the source then please download the binaries listed at http://umbraco.codeplex.com
With that said, the Umbraco solution can be opened in Visual Studio 2010 with SP1 installed or Visual Studio 2012.
Contributing
============
Umbraco is Open Source which means you can contribute to make it great!
Read all about it at http://our.umbraco.org/contribute
Forums
======
We have a forum running on http://our.umbraco.org for friendly community support.
Documentation
=============
Our documentation section provides help on installing and using Umbraco including API reference documentation: http://our.umbraco.org/documentation
Submitting Issues
=================
Another way you can contribute to Umbraco is by providing issue reports, for information on how to submit an issue report refer to our online guide at http://our.umbraco.org/contribute/report-an-issue-or-request-a-feature
+6 -3
View File
@@ -1,8 +1,8 @@
using System.Reflection;
using System.Reflection;
using System.Resources;
[assembly: AssemblyCompany("umbraco")]
[assembly: AssemblyCopyright("Copyright © Umbraco 2012")]
[assembly: AssemblyCompany("Umbraco")]
[assembly: AssemblyCopyright("Copyright © Umbraco 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -10,3 +10,6 @@ using System.Resources;
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("7.2.7")]
[assembly: AssemblyInformationalVersion("7.2.7")]
+71 -58
View File
@@ -1,15 +1,12 @@
using System;
using System.Configuration;
using System.Threading;
using System.Web;
using System.Web.Caching;
using Umbraco.Core.Cache;
using System.Threading.Tasks;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
using Umbraco.Core.ObjectResolution;
using Umbraco.Core.Services;
using Umbraco.Core.Sync;
namespace Umbraco.Core
{
@@ -36,6 +33,8 @@ namespace Umbraco.Core
_databaseContext = dbContext;
_services = serviceContext;
ApplicationCache = cache;
Init();
}
/// <summary>
@@ -45,6 +44,8 @@ namespace Umbraco.Core
public ApplicationContext(CacheHelper cache)
{
ApplicationCache = cache;
Init();
}
/// <summary>
@@ -60,13 +61,13 @@ namespace Umbraco.Core
/// </remarks>
public static ApplicationContext EnsureContext(ApplicationContext appContext, bool replaceContext)
{
if (ApplicationContext.Current != null)
if (Current != null)
{
if (!replaceContext)
return ApplicationContext.Current;
return Current;
}
ApplicationContext.Current = appContext;
return ApplicationContext.Current;
Current = appContext;
return Current;
}
/// <summary>
@@ -85,14 +86,14 @@ namespace Umbraco.Core
/// </remarks>
public static ApplicationContext EnsureContext(DatabaseContext dbContext, ServiceContext serviceContext, CacheHelper cache, bool replaceContext)
{
if (ApplicationContext.Current != null)
if (Current != null)
{
if (!replaceContext)
return ApplicationContext.Current;
return Current;
}
var ctx = new ApplicationContext(dbContext, serviceContext, cache);
ApplicationContext.Current = ctx;
return ApplicationContext.Current;
Current = ctx;
return Current;
}
/// <summary>
@@ -141,57 +142,75 @@ namespace Umbraco.Core
// GlobalSettings.CurrentVersion returns the hard-coded "current version"
// the system is configured if they match
// if they don't, install runs, updates web.config (presumably) and updates GlobalSettings.ConfiguredStatus
//
// then there is Application["umbracoNeedConfiguration"] which makes no sense... getting rid of it... SD: I have actually remove that now!
//
public bool IsConfigured
{
// todo - we should not do this - ok for now
get
{
return Configured;
}
get { return _configured.Value; }
}
/// <summary>
/// The original/first url that the web application executes
/// The application url.
/// </summary>
/// <remarks>
/// we need to set the initial url in our ApplicationContext, this is so our keep alive service works and this must
/// exist on a global context because the keep alive service doesn't run in a web context.
/// we are NOT going to put a lock on this because locking will slow down the application and we don't really care
/// if two threads write to this at the exact same time during first page hit.
/// see: http://issues.umbraco.org/issue/U4-2059
/// The application url is the url that should be used by services to talk to the application,
/// eg keep alive or scheduled publishing services. It must exist on a global context because
/// some of these services may not run within a web context.
/// The format of the application url is:
/// - has a scheme (http or https)
/// - has the SystemDirectories.Umbraco path
/// - does not end with a slash
/// It is initialized on the first request made to the server, by UmbracoModule.EnsureApplicationUrl:
/// - if umbracoSettings:settings/web.routing/@umbracoApplicationUrl is set, use the value (new setting)
/// - if umbracoSettings:settings/scheduledTasks/@baseUrl is set, use the value (backward compatibility)
/// - otherwise, use the url of the (first) request.
/// Not locking, does not matter if several threads write to this.
/// See also issues:
/// - http://issues.umbraco.org/issue/U4-2059
/// - http://issues.umbraco.org/issue/U4-6788
/// - http://issues.umbraco.org/issue/U4-5728
/// - http://issues.umbraco.org/issue/U4-5391
/// </remarks>
internal string OriginalRequestUrl { get; set; }
internal string UmbracoApplicationUrl
{
get
{
// if initialized, return
if (_umbracoApplicationUrl != null) return _umbracoApplicationUrl;
/// <summary>
/// Checks if the version configured matches the assembly version
/// </summary>
private bool Configured
{
get
{
try
{
string configStatus = ConfigurationStatus;
string currentVersion = UmbracoVersion.Current.ToString(3);
// try settings
ServerEnvironmentHelper.TrySetApplicationUrlFromSettings(this, UmbracoConfig.For.UmbracoSettings());
// and return what we have, may be null
return _umbracoApplicationUrl;
}
set
{
_umbracoApplicationUrl = value;
}
}
if (currentVersion != configStatus)
{
LogHelper.Info<ApplicationContext>("CurrentVersion different from configStatus: '" + currentVersion + "','" + configStatus + "'");
}
internal string _umbracoApplicationUrl; // internal for tests
return (configStatus == currentVersion);
}
catch
{
return false;
}
}
}
private Lazy<bool> _configured;
internal MainDom MainDom { get; private set; }
private void Init()
{
MainDom = new MainDom();
MainDom.Acquire();
//Create the lazy value to resolve whether or not the application is 'configured'
_configured = new Lazy<bool>(() =>
{
var configStatus = ConfigurationStatus;
var currentVersion = UmbracoVersion.Current.ToString(3);
var ok = configStatus == currentVersion;
if (ok == false)
{
LogHelper.Debug<ApplicationContext>("CurrentVersion different from configStatus: '" + currentVersion + "','" + configStatus + "'");
}
return ok;
});
}
private string ConfigurationStatus
{
@@ -208,12 +227,6 @@ namespace Umbraco.Core
}
}
private void AssertIsReady()
{
if (!this.IsReady)
throw new Exception("ApplicationContext is not ready yet.");
}
private void AssertIsNotReady()
{
if (this.IsReady)
+2 -2
View File
@@ -74,7 +74,7 @@ namespace Umbraco.Core
/// <returns></returns>
private bool ShouldExecute(ApplicationContext applicationContext)
{
if (applicationContext.IsConfigured && applicationContext.DatabaseContext.CanConnect)
if (applicationContext.IsConfigured && applicationContext.DatabaseContext.IsDatabaseConfigured)
{
return true;
}
@@ -84,7 +84,7 @@ namespace Umbraco.Core
return true;
}
if (!applicationContext.DatabaseContext.CanConnect && ExecuteWhenDatabaseNotConfigured)
if (!applicationContext.DatabaseContext.IsDatabaseConfigured && ExecuteWhenDatabaseNotConfigured)
{
return true;
}
+185
View File
@@ -0,0 +1,185 @@
using System;
using System.Runtime.ConstrainedExecution;
using System.Threading;
using System.Threading.Tasks;
namespace Umbraco.Core
{
// http://blogs.msdn.com/b/pfxteam/archive/2012/02/12/10266988.aspx
//
// notes:
// - this is NOT a reader/writer lock
// - this is NOT a recursive lock
//
// using a named Semaphore here and not a Mutex because mutexes have thread
// affinity which does not work with async situations
//
// it is important that managed code properly release the Semaphore before
// going down else it will maintain the lock - however note that when the
// whole process (w3wp.exe) goes down and all handles to the Semaphore have
// been closed, the Semaphore system object is destroyed - so in any case
// an iisreset should clean up everything
//
internal class AsyncLock
{
private readonly SemaphoreSlim _semaphore;
private readonly Semaphore _semaphore2;
private readonly IDisposable _releaser;
private readonly Task<IDisposable> _releaserTask;
public AsyncLock()
: this (null)
{ }
public AsyncLock(string name)
{
// WaitOne() waits until count > 0 then decrements count
// Release() increments count
// initial count: the initial count value
// maximum count: the max value of count, and then Release() throws
if (string.IsNullOrWhiteSpace(name))
{
// anonymous semaphore
// use one unique releaser, that will not release the semaphore when finalized
// because the semaphore is destroyed anyway if the app goes down
_semaphore = new SemaphoreSlim(1, 1); // create a local (to the app domain) semaphore
_releaser = new SemaphoreSlimReleaser(_semaphore);
_releaserTask = Task.FromResult(_releaser);
}
else
{
// named semaphore
// use dedicated releasers, that will release the semaphore when finalized
// because the semaphore is system-wide and we cannot leak counts
_semaphore2 = new Semaphore(1, 1, name); // create a system-wide named semaphore
}
}
private IDisposable CreateReleaser()
{
// for anonymous semaphore, use the unique releaser, else create a new one
return _semaphore != null
? _releaser // (IDisposable)new SemaphoreSlimReleaser(_semaphore)
: new NamedSemaphoreReleaser(_semaphore2);
}
public Task<IDisposable> LockAsync()
{
var wait = _semaphore != null
? _semaphore.WaitAsync()
: _semaphore2.WaitOneAsync();
return wait.IsCompleted
? _releaserTask ?? Task.FromResult(CreateReleaser()) // anonymous vs named
: wait.ContinueWith((_, state) => (((AsyncLock) state).CreateReleaser()),
this, CancellationToken.None,
TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
}
public Task<IDisposable> LockAsync(int millisecondsTimeout)
{
var wait = _semaphore != null
? _semaphore.WaitAsync(millisecondsTimeout)
: _semaphore2.WaitOneAsync(millisecondsTimeout);
return wait.IsCompleted
? _releaserTask ?? Task.FromResult(CreateReleaser()) // anonymous vs named
: wait.ContinueWith((_, state) => (((AsyncLock)state).CreateReleaser()),
this, CancellationToken.None,
TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
}
public IDisposable Lock()
{
if (_semaphore != null)
_semaphore.Wait();
else
_semaphore2.WaitOne();
return _releaser ?? CreateReleaser(); // anonymous vs named
}
public IDisposable Lock(int millisecondsTimeout)
{
var entered = _semaphore != null
? _semaphore.Wait(millisecondsTimeout)
: _semaphore2.WaitOne(millisecondsTimeout);
if (entered == false)
throw new TimeoutException("Failed to enter the lock within timeout.");
return _releaser ?? CreateReleaser(); // anonymous vs named
}
// note - before making those classes some structs, read
// about "impure methods" and mutating readonly structs...
private class NamedSemaphoreReleaser : CriticalFinalizerObject, IDisposable
{
private readonly Semaphore _semaphore;
internal NamedSemaphoreReleaser(Semaphore semaphore)
{
_semaphore = semaphore;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
// critical
_semaphore.Release();
}
// we WANT to release the semaphore because it's a system object
// ie a critical non-managed resource - so we inherit from CriticalFinalizerObject
// which means that the finalizer "should" run in all situations
// however... that can fail with System.ObjectDisposedException because the
// underlying handle was closed... because we cannot guarantee that the semaphore
// is not gone already... unless we get a GCHandle = GCHandle.Alloc(_semaphore);
// which should keep it around and then we free the handle?
// so... I'm not sure this is safe really...
~NamedSemaphoreReleaser()
{
Dispose(false);
}
}
private class SemaphoreSlimReleaser : IDisposable
{
private readonly SemaphoreSlim _semaphore;
internal SemaphoreSlimReleaser(SemaphoreSlim semaphore)
{
_semaphore = semaphore;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (disposing)
{
// normal
_semaphore.Release();
}
}
~SemaphoreSlimReleaser()
{
Dispose(false);
}
}
}
}
+3
View File
@@ -54,5 +54,8 @@ namespace Umbraco.Core.Cache
public const string DataTypeCacheKey = "UmbracoDataTypeDefinition";
public const string DataTypePreValuesCacheKey = "UmbracoPreVal";
public const string IdToKeyCacheKey = "UI2K";
public const string KeyToIdCacheKey = "UK2I";
}
}
@@ -12,7 +12,7 @@ namespace Umbraco.Core.Cache
protected const string CacheItemPrefix = "umbrtmche";
// an object that represent a value that has not been created yet
protected readonly object ValueNotCreated = new object();
protected internal static readonly object ValueNotCreated = new object();
// manupulate the underlying cache entries
// these *must* be called from within the appropriate locks
@@ -30,21 +30,58 @@ namespace Umbraco.Core.Cache
return string.Format("{0}-{1}", CacheItemPrefix, key);
}
protected object GetSafeLazyValue(Lazy<object> lazy, bool onlyIfValueIsCreated = false)
protected internal static Lazy<object> GetSafeLazy(Func<object> getCacheItem)
{
// try to generate the value and if it fails,
// wrap in an ExceptionHolder - would be much simpler
// to just use lazy.IsValueFaulted alas that field is
// internal
return new Lazy<object>(() =>
{
try
{
return getCacheItem();
}
catch (Exception e)
{
return new ExceptionHolder(e);
}
});
}
protected internal static object GetSafeLazyValue(Lazy<object> lazy, bool onlyIfValueIsCreated = false)
{
// if onlyIfValueIsCreated, do not trigger value creation
// must return something, though, to differenciate from null values
if (onlyIfValueIsCreated && lazy.IsValueCreated == false) return ValueNotCreated;
// if execution has thrown then lazy.IsValueCreated is false
// and lazy.IsValueFaulted is true (but internal) so we use our
// own exception holder (see Lazy<T> source code) to return null
if (lazy.Value is ExceptionHolder) return null;
// we have a value and execution has not thrown so returning
// here does not throw - unless we're re-entering, take care of it
try
{
// if onlyIfValueIsCreated, do not trigger value creation
// must return something, though, to differenciate from null values
if (onlyIfValueIsCreated && lazy.IsValueCreated == false) return ValueNotCreated;
return lazy.Value;
}
catch
catch (InvalidOperationException e)
{
return null;
throw new InvalidOperationException("The method that computes a value for the cache has tried to read that value from the cache.", e);
}
}
internal class ExceptionHolder
{
public ExceptionHolder(Exception e)
{
Exception = e;
}
public Exception Exception { get; private set; }
}
#region Clear
public virtual void ClearAllCache()
@@ -53,7 +90,7 @@ namespace Umbraco.Core.Cache
{
foreach (var entry in GetDictionaryEntries()
.ToArray())
RemoveEntry((string) entry.Key);
RemoveEntry((string)entry.Key);
}
}
@@ -68,6 +105,9 @@ namespace Umbraco.Core.Cache
public virtual void ClearCacheObjectTypes(string typeName)
{
var type = TypeFinder.GetTypeByName(typeName);
if (type == null) return;
var isInterface = type.IsInterface;
using (WriteLock)
{
foreach (var entry in GetDictionaryEntries()
@@ -77,16 +117,20 @@ namespace Umbraco.Core.Cache
// remove null values as well, does not hurt
// get non-created as NonCreatedValue & exceptions as null
var value = GetSafeLazyValue((Lazy<object>)x.Value, true);
return value == null || value.GetType().ToString().InvariantEquals(typeName);
// if T is an interface remove anything that implements that interface
// otherwise remove exact types (not inherited types)
return value == null || (isInterface ? (type.IsInstanceOfType(value)) : (value.GetType() == type));
})
.ToArray())
RemoveEntry((string) entry.Key);
RemoveEntry((string)entry.Key);
}
}
public virtual void ClearCacheObjectTypes<T>()
{
var typeOfT = typeof(T);
var isInterface = typeOfT.IsInterface;
using (WriteLock)
{
foreach (var entry in GetDictionaryEntries()
@@ -97,16 +141,20 @@ namespace Umbraco.Core.Cache
// compare on exact type, don't use "is"
// get non-created as NonCreatedValue & exceptions as null
var value = GetSafeLazyValue((Lazy<object>)x.Value, true);
return value == null || value.GetType() == typeOfT;
// if T is an interface remove anything that implements that interface
// otherwise remove exact types (not inherited types)
return value == null || (isInterface ? (value is T) : (value.GetType() == typeOfT));
})
.ToArray())
RemoveEntry((string) entry.Key);
RemoveEntry((string)entry.Key);
}
}
public virtual void ClearCacheObjectTypes<T>(Func<string, T, bool> predicate)
{
var typeOfT = typeof(T);
var isInterface = typeOfT.IsInterface;
var plen = CacheItemPrefix.Length + 1;
using (WriteLock)
{
@@ -119,11 +167,14 @@ namespace Umbraco.Core.Cache
// get non-created as NonCreatedValue & exceptions as null
var value = GetSafeLazyValue((Lazy<object>)x.Value, true);
if (value == null) return true;
return value.GetType() == typeOfT
// if T is an interface remove anything that implements that interface
// otherwise remove exact types (not inherited types)
return (isInterface ? (value is T) : (value.GetType() == typeOfT))
// run predicate on the 'public key' part only, ie without prefix
&& predicate(((string)x.Key).Substring(plen), (T)value);
&& predicate(((string)x.Key).Substring(plen), (T)value);
}))
RemoveEntry((string) entry.Key);
RemoveEntry((string)entry.Key);
}
}
@@ -135,7 +186,7 @@ namespace Umbraco.Core.Cache
foreach (var entry in GetDictionaryEntries()
.Where(x => ((string)x.Key).Substring(plen).InvariantStartsWith(keyStartsWith))
.ToArray())
RemoveEntry((string) entry.Key);
RemoveEntry((string)entry.Key);
}
}
@@ -147,7 +198,7 @@ namespace Umbraco.Core.Cache
foreach (var entry in GetDictionaryEntries()
.Where(x => Regex.IsMatch(((string)x.Key).Substring(plen), regexString))
.ToArray())
RemoveEntry((string) entry.Key);
RemoveEntry((string)entry.Key);
}
}
@@ -102,20 +102,27 @@ namespace Umbraco.Core.Cache
// cannot create value within the lock, so if result.IsValueCreated is false, just
// do nothing here - means that if creation throws, a race condition could cause
// more than one thread to reach the return statement below and throw - accepted.
if (result == null || GetSafeLazyValue(result, true) == null) // get non-created as NonCreatedValue & exceptions as null
{
result = new Lazy<object>(getCacheItem);
result = GetSafeLazy(getCacheItem);
ContextItems[cacheKey] = result;
}
}
// this may throw if getCacheItem throws, but this is the only place where
// it would throw as everywhere else we use GetLazySaveValue() to hide exceptions
// and pretend exceptions were never inserted into cache to begin with.
return result.Value;
// using GetSafeLazy and GetSafeLazyValue ensures that we don't cache
// exceptions (but try again and again) and silently eat them - however at
// some point we have to report them - so need to re-throw here
// this does not throw anymore
//return result.Value;
var value = result.Value; // will not throw (safe lazy)
var eh = value as ExceptionHolder;
if (eh != null) throw eh.Exception; // throw once!
return value;
}
#endregion
#region Insert
@@ -20,16 +20,22 @@ namespace Umbraco.Core.Cache
private readonly System.Web.Caching.Cache _cache;
/// <summary>
/// Used for debugging
/// </summary>
internal Guid InstanceId { get; private set; }
public HttpRuntimeCacheProvider(System.Web.Caching.Cache cache)
{
_cache = cache;
InstanceId = Guid.NewGuid();
}
protected override IEnumerable<DictionaryEntry> GetDictionaryEntries()
{
const string prefix = CacheItemPrefix + "-";
return _cache.Cast<DictionaryEntry>()
.Where(x => x.Key is string && ((string) x.Key).StartsWith(prefix));
.Where(x => x.Key is string && ((string)x.Key).StartsWith(prefix));
}
protected override void RemoveEntry(string key)
@@ -129,19 +135,27 @@ namespace Umbraco.Core.Cache
if (result == null || GetSafeLazyValue(result, true) == null) // get non-created as NonCreatedValue & exceptions as null
{
result = new Lazy<object>(getCacheItem);
result = GetSafeLazy(getCacheItem);
var absolute = isSliding ? System.Web.Caching.Cache.NoAbsoluteExpiration : (timeout == null ? System.Web.Caching.Cache.NoAbsoluteExpiration : DateTime.Now.Add(timeout.Value));
var sliding = isSliding == false ? System.Web.Caching.Cache.NoSlidingExpiration : (timeout ?? System.Web.Caching.Cache.NoSlidingExpiration);
lck.UpgradeToWriteLock();
//NOTE: 'Insert' on System.Web.Caching.Cache actually does an add or update!
_cache.Insert(cacheKey, result, dependency, absolute, sliding, priority, removedCallback);
}
}
// this may throw if getCacheItem throws, but this is the only place where
// it would throw as everywhere else we use GetLazySaveValue() to hide exceptions
// and pretend exceptions were never inserted into cache to begin with.
return result.Value;
// using GetSafeLazy and GetSafeLazyValue ensures that we don't cache
// exceptions (but try again and again) and silently eat them - however at
// some point we have to report them - so need to re-throw here
// this does not throw anymore
//return result.Value;
value = result.Value; // will not throw (safe lazy)
var eh = value as ExceptionHolder;
if (eh != null) throw eh.Exception; // throw once!
return value;
}
public object GetCacheItem(string cacheKey, Func<object> getCacheItem, TimeSpan? timeout, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
@@ -173,17 +187,18 @@ namespace Umbraco.Core.Cache
// NOTE - here also we must insert a Lazy<object> but we can evaluate it right now
// and make sure we don't store a null value.
var result = new Lazy<object>(getCacheItem);
var result = GetSafeLazy(getCacheItem);
var value = result.Value; // force evaluation now - this may throw if cacheItem throws, and then nothing goes into cache
if (value == null) return; // do not store null values (backward compat)
cacheKey = GetCacheKey(cacheKey);
cacheKey = GetCacheKey(cacheKey);
var absolute = isSliding ? System.Web.Caching.Cache.NoAbsoluteExpiration : (timeout == null ? System.Web.Caching.Cache.NoAbsoluteExpiration : DateTime.Now.Add(timeout.Value));
var sliding = isSliding == false ? System.Web.Caching.Cache.NoSlidingExpiration : (timeout ?? System.Web.Caching.Cache.NoSlidingExpiration);
using (new WriteLock(_locker))
{
//NOTE: 'Insert' on System.Web.Caching.Cache actually does an add or update!
_cache.Insert(cacheKey, result, dependency, absolute, sliding, priority, removedCallback);
}
}
+38
View File
@@ -8,13 +8,51 @@ namespace Umbraco.Core.Cache
/// </summary>
public interface ICacheProvider
{
/// <summary>
/// Removes all items from the cache.
/// </summary>
void ClearAllCache();
/// <summary>
/// Removes an item from the cache, identified by its key.
/// </summary>
/// <param name="key">The key of the item.</param>
void ClearCacheItem(string key);
/// <summary>
/// Removes items from the cache, of a specified type.
/// </summary>
/// <param name="typeName">The name of the type to remove.</param>
/// <remarks>
/// <para>If the type is an interface, then all items of a type implementing that interface are
/// removed. Otherwise, only items of that exact type are removed (items of type inheriting from
/// the specified type are not removed).</para>
/// <para>Performs a case-sensitive search.</para>
/// </remarks>
void ClearCacheObjectTypes(string typeName);
/// <summary>
/// Removes items from the cache, of a specified type.
/// </summary>
/// <typeparam name="T">The type of the items to remove.</typeparam>
/// <remarks>If the type is an interface, then all items of a type implementing that interface are
/// removed. Otherwise, only items of that exact type are removed (items of type inheriting from
/// the specified type are not removed).</remarks>
void ClearCacheObjectTypes<T>();
/// <summary>
/// Removes items from the cache, of a specified type, satisfying a predicate.
/// </summary>
/// <typeparam name="T">The type of the items to remove.</typeparam>
/// <param name="predicate">The predicate to satisfy.</param>
/// <remarks>If the type is an interface, then all items of a type implementing that interface are
/// removed. Otherwise, only items of that exact type are removed (items of type inheriting from
/// the specified type are not removed).</remarks>
void ClearCacheObjectTypes<T>(Func<string, T, bool> predicate);
void ClearCacheByKeySearch(string keyStartsWith);
void ClearCacheByKeyExpression(string regexString);
IEnumerable<object> GetCacheItemsByKeySearch(string keyStartsWith);
IEnumerable<object> GetCacheItemsByKeyExpression(string regexString);
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Runtime.Caching;
using System.Text.RegularExpressions;
using System.Threading;
@@ -16,30 +17,19 @@ namespace Umbraco.Core.Cache
/// </summary>
internal class ObjectCacheRuntimeCacheProvider : IRuntimeCacheProvider
{
private readonly ReaderWriterLockSlim _locker = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
internal ObjectCache MemoryCache;
// an object that represent a value that has not been created yet
protected readonly object ValueNotCreated = new object();
/// <summary>
/// Used for debugging
/// </summary>
internal Guid InstanceId { get; private set; }
public ObjectCacheRuntimeCacheProvider()
{
MemoryCache = new MemoryCache("in-memory");
}
protected object GetSafeLazyValue(Lazy<object> lazy, bool onlyIfValueIsCreated = false)
{
try
{
// if onlyIfValueIsCreated, do not trigger value creation
// must return something, though, to differenciate from null values
if (onlyIfValueIsCreated && lazy.IsValueCreated == false) return ValueNotCreated;
return lazy.Value;
}
catch
{
return null;
}
InstanceId = Guid.NewGuid();
}
#region Clear
@@ -59,11 +49,14 @@ namespace Umbraco.Core.Cache
{
if (MemoryCache[key] == null) return;
MemoryCache.Remove(key);
}
}
}
public virtual void ClearCacheObjectTypes(string typeName)
{
var type = TypeFinder.GetTypeByName(typeName);
if (type == null) return;
var isInterface = type.IsInterface;
using (new WriteLock(_locker))
{
foreach (var key in MemoryCache
@@ -72,8 +65,11 @@ namespace Umbraco.Core.Cache
// x.Value is Lazy<object> and not null, its value may be null
// remove null values as well, does not hurt
// get non-created as NonCreatedValue & exceptions as null
var value = GetSafeLazyValue((Lazy<object>)x.Value, true);
return value == null || value.GetType().ToString().InvariantEquals(typeName);
var value = DictionaryCacheProviderBase.GetSafeLazyValue((Lazy<object>)x.Value, true);
// if T is an interface remove anything that implements that interface
// otherwise remove exact types (not inherited types)
return value == null || (isInterface ? (type.IsInstanceOfType(value)) : (value.GetType() == type));
})
.Select(x => x.Key)
.ToArray()) // ToArray required to remove
@@ -85,15 +81,20 @@ namespace Umbraco.Core.Cache
{
using (new WriteLock(_locker))
{
var typeOfT = typeof (T);
var typeOfT = typeof(T);
var isInterface = typeOfT.IsInterface;
foreach (var key in MemoryCache
.Where(x =>
{
// x.Value is Lazy<object> and not null, its value may be null
// remove null values as well, does not hurt
// get non-created as NonCreatedValue & exceptions as null
var value = GetSafeLazyValue((Lazy<object>)x.Value, true);
return value == null || value.GetType() == typeOfT;
var value = DictionaryCacheProviderBase.GetSafeLazyValue((Lazy<object>)x.Value, true);
// if T is an interface remove anything that implements that interface
// otherwise remove exact types (not inherited types)
return value == null || (isInterface ? (value is T) : (value.GetType() == typeOfT));
})
.Select(x => x.Key)
.ToArray()) // ToArray required to remove
@@ -106,16 +107,20 @@ namespace Umbraco.Core.Cache
using (new WriteLock(_locker))
{
var typeOfT = typeof(T);
var isInterface = typeOfT.IsInterface;
foreach (var key in MemoryCache
.Where(x =>
{
// x.Value is Lazy<object> and not null, its value may be null
// remove null values as well, does not hurt
// get non-created as NonCreatedValue & exceptions as null
var value = GetSafeLazyValue((Lazy<object>)x.Value, true);
var value = DictionaryCacheProviderBase.GetSafeLazyValue((Lazy<object>)x.Value, true);
if (value == null) return true;
return value.GetType() == typeOfT
&& predicate(x.Key, (T) value);
// if T is an interface remove anything that implements that interface
// otherwise remove exact types (not inherited types)
return (isInterface ? (value is T) : (value.GetType() == typeOfT))
&& predicate(x.Key, (T)value);
})
.Select(x => x.Key)
.ToArray()) // ToArray required to remove
@@ -132,7 +137,7 @@ namespace Umbraco.Core.Cache
.Select(x => x.Key)
.ToArray()) // ToArray required to remove
MemoryCache.Remove(key);
}
}
}
public virtual void ClearCacheByKeyExpression(string regexString)
@@ -144,7 +149,7 @@ namespace Umbraco.Core.Cache
.Select(x => x.Key)
.ToArray()) // ToArray required to remove
MemoryCache.Remove(key);
}
}
}
#endregion
@@ -161,7 +166,7 @@ namespace Umbraco.Core.Cache
.ToArray(); // evaluate while locked
}
return entries
.Select(x => GetSafeLazyValue((Lazy<object>)x.Value)) // return exceptions as null
.Select(x => DictionaryCacheProviderBase.GetSafeLazyValue((Lazy<object>)x.Value)) // return exceptions as null
.Where(x => x != null) // backward compat, don't store null values in the cache
.ToList();
}
@@ -176,7 +181,7 @@ namespace Umbraco.Core.Cache
.ToArray(); // evaluate while locked
}
return entries
.Select(x => GetSafeLazyValue((Lazy<object>)x.Value)) // return exceptions as null
.Select(x => DictionaryCacheProviderBase.GetSafeLazyValue((Lazy<object>)x.Value)) // return exceptions as null
.Where(x => x != null) // backward compat, don't store null values in the cache
.ToList();
}
@@ -188,7 +193,7 @@ namespace Umbraco.Core.Cache
{
result = MemoryCache.Get(cacheKey) as Lazy<object>; // null if key not found
}
return result == null ? null : GetSafeLazyValue(result); // return exceptions as null
return result == null ? null : DictionaryCacheProviderBase.GetSafeLazyValue(result); // return exceptions as null
}
public object GetCacheItem(string cacheKey, Func<object> getCacheItem)
@@ -196,7 +201,7 @@ namespace Umbraco.Core.Cache
return GetCacheItem(cacheKey, getCacheItem, null);
}
public object GetCacheItem(string cacheKey, Func<object> getCacheItem, TimeSpan? timeout, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal,CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
public object GetCacheItem(string cacheKey, Func<object> getCacheItem, TimeSpan? timeout, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
{
// see notes in HttpRuntimeCacheProvider
@@ -205,17 +210,23 @@ namespace Umbraco.Core.Cache
using (var lck = new UpgradeableReadLock(_locker))
{
result = MemoryCache.Get(cacheKey) as Lazy<object>;
if (result == null || GetSafeLazyValue(result, true) == null) // get non-created as NonCreatedValue & exceptions as null
if (result == null || DictionaryCacheProviderBase.GetSafeLazyValue(result, true) == null) // get non-created as NonCreatedValue & exceptions as null
{
result = new Lazy<object>(getCacheItem);
result = DictionaryCacheProviderBase.GetSafeLazy(getCacheItem);
var policy = GetPolicy(timeout, isSliding, removedCallback, dependentFiles);
lck.UpgradeToWriteLock();
//NOTE: This does an add or update
MemoryCache.Set(cacheKey, result, policy);
}
}
return result.Value;
//return result.Value;
var value = result.Value; // will not throw (safe lazy)
var eh = value as DictionaryCacheProviderBase.ExceptionHolder;
if (eh != null) throw eh.Exception; // throw once!
return value;
}
#endregion
@@ -227,11 +238,12 @@ namespace Umbraco.Core.Cache
// NOTE - here also we must insert a Lazy<object> but we can evaluate it right now
// and make sure we don't store a null value.
var result = new Lazy<object>(getCacheItem);
var result = DictionaryCacheProviderBase.GetSafeLazy(getCacheItem);
var value = result.Value; // force evaluation now
if (value == null) return; // do not store null values (backward compat)
var policy = GetPolicy(timeout, isSliding, removedCallback, dependentFiles);
//NOTE: This does an add or update
MemoryCache.Set(cacheKey, result, policy);
}
@@ -252,7 +264,7 @@ namespace Umbraco.Core.Cache
{
policy.ChangeMonitors.Add(new HostFileChangeMonitor(dependentFiles.ToList()));
}
if (removedCallback != null)
{
policy.RemovedCallback = arguments =>
@@ -283,6 +295,6 @@ namespace Umbraco.Core.Cache
}
return policy;
}
}
}
@@ -34,7 +34,7 @@ namespace Umbraco.Core.Configuration
{
get
{
var converted = ObjectExtensions.TryConvertTo<T>(RawValue);
var converted = RawValue.TryConvertTo<T>();
if (converted.Success == false)
throw new InvalidCastException("Could not convert value " + RawValue + " to type " + typeof(T));
return converted.Result;
@@ -1,8 +1,9 @@
using System.Xml.Linq;
using System;
using System.Xml.Linq;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class ContentErrorPageElement : InnerTextConfigurationElement<int>, IContentErrorPage
internal class ContentErrorPageElement : InnerTextConfigurationElement<string>, IContentErrorPage
{
public ContentErrorPageElement(XElement rawXml)
: base(rawXml)
@@ -14,7 +15,43 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
}
public bool HasContentId
{
get { return ContentId != int.MinValue; }
}
public bool HasContentKey
{
get { return ContentKey != Guid.Empty; }
}
public int ContentId
{
get
{
int parsed;
if (int.TryParse(Value, out parsed))
{
return parsed;
}
return int.MinValue;
}
}
public Guid ContentKey
{
get
{
Guid parsed;
if (Guid.TryParse(Value, out parsed))
{
return parsed;
}
return Guid.Empty;
}
}
public string ContentXPath
{
get { return Value; }
}
@@ -1,8 +1,14 @@
namespace Umbraco.Core.Configuration.UmbracoSettings
using System;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
public interface IContentErrorPage
{
int ContentId { get; }
Guid ContentKey { get; }
string ContentXPath { get; }
bool HasContentId { get; }
bool HasContentKey { get; }
string Culture { get; set; }
}
}
@@ -8,7 +8,11 @@
bool DisableAlternativeTemplates { get; }
bool DisableFindContentByIdPath { get; }
string UrlProviderMode { get; }
string UmbracoApplicationUrl { get; }
}
}
@@ -21,12 +21,22 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
{
get { return (bool) base["disableAlternativeTemplates"]; }
}
[ConfigurationProperty("disableFindContentByIdPath", DefaultValue = "false")]
public bool DisableFindContentByIdPath
{
get { return (bool) base["disableFindContentByIdPath"]; }
}
[ConfigurationProperty("urlProviderMode", DefaultValue = "AutoLegacy")]
public string UrlProviderMode
{
get { return (string)base["urlProviderMode"]; }
get { return (string) base["urlProviderMode"]; }
}
[ConfigurationProperty("umbracoApplicationUrl", DefaultValue = null)]
public string UmbracoApplicationUrl
{
get { return (string)base["umbracoApplicationUrl"]; }
}
}
}
@@ -5,7 +5,7 @@ namespace Umbraco.Core.Configuration
{
public class UmbracoVersion
{
private static readonly Version Version = new Version("7.2.4");
private static readonly Version Version = new Version("7.2.7");
/// <summary>
/// Gets the current version of Umbraco.
+9 -18
View File
@@ -192,73 +192,64 @@ namespace Umbraco.Core
{
{
Comments,
new PropertyType(PropertyEditors.TextboxMultipleAlias, DataTypeDatabaseType.Ntext, true)
new PropertyType(PropertyEditors.TextboxMultipleAlias, DataTypeDatabaseType.Ntext, true, Comments)
{
Alias = Comments,
Name = CommentsLabel
}
},
{
FailedPasswordAttempts,
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Integer, true)
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Integer, true, FailedPasswordAttempts)
{
Alias = FailedPasswordAttempts,
Name = FailedPasswordAttemptsLabel
}
},
{
IsApproved,
new PropertyType(PropertyEditors.TrueFalseAlias, DataTypeDatabaseType.Integer, true)
new PropertyType(PropertyEditors.TrueFalseAlias, DataTypeDatabaseType.Integer, true, IsApproved)
{
Alias = IsApproved,
Name = IsApprovedLabel
}
},
{
IsLockedOut,
new PropertyType(PropertyEditors.TrueFalseAlias, DataTypeDatabaseType.Integer, true)
new PropertyType(PropertyEditors.TrueFalseAlias, DataTypeDatabaseType.Integer, true, IsLockedOut)
{
Alias = IsLockedOut,
Name = IsLockedOutLabel
}
},
{
LastLockoutDate,
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, true)
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, true, LastLockoutDate)
{
Alias = LastLockoutDate,
Name = LastLockoutDateLabel
}
},
{
LastLoginDate,
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, true)
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, true, LastLoginDate)
{
Alias = LastLoginDate,
Name = LastLoginDateLabel
}
},
{
LastPasswordChangeDate,
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, true)
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, true, LastPasswordChangeDate)
{
Alias = LastPasswordChangeDate,
Name = LastPasswordChangeDateLabel
}
},
{
PasswordAnswer,
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Nvarchar, true)
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Nvarchar, true, PasswordAnswer)
{
Alias = PasswordAnswer,
Name = PasswordAnswerLabel
}
},
{
PasswordQuestion,
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Nvarchar, true)
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Nvarchar, true, PasswordQuestion)
{
Alias = PasswordQuestion,
Name = PasswordQuestionLabel
}
}
+93 -12
View File
@@ -2,10 +2,12 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Web;
using AutoMapper;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Exceptions;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.Mapping;
@@ -66,7 +68,9 @@ namespace Umbraco.Core
InitializeProfilerResolver();
_timer = DisposableTimer.DebugDuration<CoreBootManager>("Umbraco application starting", "Umbraco application startup complete");
_timer = DisposableTimer.TraceDuration<CoreBootManager>(
string.Format("Umbraco {0} application starting on {1}", UmbracoVersion.Current, NetworkHelper.MachineName),
"Umbraco application startup complete");
CreateApplicationCache();
@@ -95,9 +99,25 @@ namespace Umbraco.Core
InitializeModelMappers();
//now we need to call the initialize methods
ApplicationEventsResolver.Current.ApplicationEventHandlers
.ForEach(x => x.OnApplicationInitialized(UmbracoApplication, ApplicationContext));
using (DisposableTimer.DebugDuration<CoreBootManager>(
() => string.Format("Executing {0} IApplicationEventHandler.OnApplicationInitialized", ApplicationEventsResolver.Current.ApplicationEventHandlers.Count()),
() => "Finished executing IApplicationEventHandler.OnApplicationInitialized"))
{
//now we need to call the initialize methods
ApplicationEventsResolver.Current.ApplicationEventHandlers
.ForEach(x =>
{
try
{
x.OnApplicationInitialized(UmbracoApplication, ApplicationContext);
}
catch (Exception ex)
{
LogHelper.Error<CoreBootManager>("An error occurred running OnApplicationInitialized for handler " + x.GetType(), ex);
throw;
}
});
}
_isInitialized = true;
@@ -201,11 +221,27 @@ namespace Umbraco.Core
if (_isStarted)
throw new InvalidOperationException("The boot manager has already been initialized");
//call OnApplicationStarting of each application events handler
ApplicationEventsResolver.Current.ApplicationEventHandlers
.ForEach(x => x.OnApplicationStarting(UmbracoApplication, ApplicationContext));
using (DisposableTimer.DebugDuration<CoreBootManager>(
() => string.Format("Executing {0} IApplicationEventHandler.OnApplicationStarting", ApplicationEventsResolver.Current.ApplicationEventHandlers.Count()),
() => "Finished executing IApplicationEventHandler.OnApplicationStarting"))
{
//call OnApplicationStarting of each application events handler
ApplicationEventsResolver.Current.ApplicationEventHandlers
.ForEach(x =>
{
try
{
x.OnApplicationStarting(UmbracoApplication, ApplicationContext);
}
catch (Exception ex)
{
LogHelper.Error<CoreBootManager>("An error occurred running OnApplicationStarting for handler " + x.GetType(), ex);
throw;
}
});
}
if (afterStartup != null)
if (afterStartup != null)
{
afterStartup(ApplicationContext.Current);
}
@@ -226,10 +262,29 @@ namespace Umbraco.Core
throw new InvalidOperationException("The boot manager has already been completed");
FreezeResolution();
//call OnApplicationStarting of each application events handler
ApplicationEventsResolver.Current.ApplicationEventHandlers
.ForEach(x => x.OnApplicationStarted(UmbracoApplication, ApplicationContext));
//Here we need to make sure the db can be connected to
EnsureDatabaseConnection();
using (DisposableTimer.DebugDuration<CoreBootManager>(
() => string.Format("Executing {0} IApplicationEventHandler.OnApplicationStarted", ApplicationEventsResolver.Current.ApplicationEventHandlers.Count()),
() => "Finished executing IApplicationEventHandler.OnApplicationStarted"))
{
//call OnApplicationStarting of each application events handler
ApplicationEventsResolver.Current.ApplicationEventHandlers
.ForEach(x =>
{
try
{
x.OnApplicationStarted(UmbracoApplication, ApplicationContext);
}
catch (Exception ex)
{
LogHelper.Error<CoreBootManager>("An error occurred running OnApplicationStarted for handler " + x.GetType(), ex);
throw;
}
});
}
//Now, startup all of our legacy startup handler
ApplicationEventsResolver.Current.InstantiateLegacyStartupHandlers();
@@ -249,6 +304,32 @@ namespace Umbraco.Core
return this;
}
/// <summary>
/// We cannot continue if the db cannot be connected to
/// </summary>
private void EnsureDatabaseConnection()
{
if (ApplicationContext.IsConfigured == false) return;
if (ApplicationContext.DatabaseContext.IsDatabaseConfigured == false) return;
var currentTry = 0;
while (currentTry < 5)
{
if (ApplicationContext.DatabaseContext.CanConnect)
break;
//wait and retry
Thread.Sleep(1000);
currentTry++;
}
if (currentTry == 5)
{
throw new UmbracoStartupFailedException("Umbraco cannot start. A connection string is configured but the Umbraco cannot connect to the database.");
}
}
/// <summary>
/// Freeze resolution to not allow Resolvers to be modified
/// </summary>
+3 -17
View File
@@ -26,8 +26,6 @@ namespace Umbraco.Core
{
private readonly IDatabaseFactory _factory;
private bool _configured;
private bool _canConnect;
private volatile bool _connectCheck = false;
private readonly object _locker = new object();
private string _connectionString;
private string _providerName;
@@ -67,21 +65,9 @@ namespace Umbraco.Core
get
{
if (IsDatabaseConfigured == false) return false;
//double check lock so that it is only checked once and is fast
if (_connectCheck == false)
{
lock (_locker)
{
if (_canConnect == false)
{
_canConnect = DbConnectionExtensions.IsConnectionAvailable(ConnectionString, DatabaseProvider);
_connectCheck = true;
}
}
}
return _canConnect;
var canConnect = DbConnectionExtensions.IsConnectionAvailable(ConnectionString, DatabaseProvider);
LogHelper.Info<DatabaseContext>("CanConnect = " + canConnect);
return canConnect;
}
}
+28 -39
View File
@@ -4,69 +4,58 @@ using System.Threading;
namespace Umbraco.Core
{
/// <summary>
/// Abstract implementation of logic commonly required to safely handle disposable unmanaged resources.
/// Abstract implementation of IDisposable.
/// </summary>
/// <remarks>
/// Can also be used as a pattern for when inheriting is not possible.
///
/// See also: https://msdn.microsoft.com/en-us/library/b1yfkh5e%28v=vs.110%29.aspx
/// See also: https://lostechies.com/chrispatterson/2012/11/29/idisposable-done-right/
///
/// Note: if an object's ctor throws, it will never be disposed, and so if that ctor
/// has allocated disposable objects, it should take care of disposing them.
/// </remarks>
public abstract class DisposableObject : IDisposable
{
private bool _disposed;
private readonly ReaderWriterLockSlim _disposalLocker = new ReaderWriterLockSlim();
private readonly object _locko = new object();
/// <summary>
/// Gets a value indicating whether this instance is disposed.
/// </summary>
/// <value>
/// <c>true</c> if this instance is disposed; otherwise, <c>false</c>.
/// </value>
public bool IsDisposed
{
get { return _disposed; }
}
// gets a value indicating whether this instance is disposed.
// for internal tests only (not thread safe)
//TODO make this internal + rename "Disposed" when we can break compatibility
public bool IsDisposed { get { return _disposed; } }
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
/// <filterpriority>2</filterpriority>
// implements IDisposable
public void Dispose()
{
Dispose(true);
// Use SupressFinalize in case a subclass of this type implements a finalizer.
GC.SuppressFinalize(this);
}
// finalizer
~DisposableObject()
{
// Run dispose but let the class know it was due to the finalizer running.
Dispose(false);
}
protected virtual void Dispose(bool disposing)
//TODO make this private, non-virtual when we can break compatibility
protected virtual void Dispose(bool disposing)
{
// Only operate if we haven't already disposed
if (IsDisposed || !disposing) return;
lock (_locko)
{
if (_disposed) return;
_disposed = true;
}
using (new WriteLock(_disposalLocker))
{
// Check again now we're inside the lock
if (IsDisposed) return;
DisposeUnmanagedResources();
// Call to actually release resources. This method is only
// kept separate so that the entire disposal logic can be used as a VS snippet
DisposeResources();
// Indicate that the instance has been disposed.
_disposed = true;
}
if (disposing)
DisposeResources();
}
/// <summary>
/// Handles the disposal of resources. Derived from abstract class <see cref="DisposableObject"/> which handles common required locking logic.
/// </summary>
protected abstract void DisposeResources();
protected virtual void DisposeUnmanagedResources()
{
}
{ }
}
}
@@ -0,0 +1,18 @@
using System;
namespace Umbraco.Core.Exceptions
{
/// <summary>
/// An exception that is thrown if the umbraco application cannnot boot
/// </summary>
public class UmbracoStartupFailedException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="T:System.Exception"/> class with a specified error message.
/// </summary>
/// <param name="message">The message that describes the error. </param>
public UmbracoStartupFailedException(string message) : base(message)
{
}
}
}
+45
View File
@@ -0,0 +1,45 @@
using System.Web;
namespace Umbraco.Core
{
public static class HttpContextExtensions
{
public static string GetCurrentRequestIpAddress(this HttpContextBase httpContext)
{
if (httpContext == null)
{
return "Unknown, httpContext is null";
}
if (httpContext.Request == null)
{
return "Unknown, httpContext.Request is null";
}
if (httpContext.Request.ServerVariables == null)
{
return "Unknown, httpContext.Request.ServerVariables is null";
}
// From: http://stackoverflow.com/a/740431/5018
try
{
var ipAddress = httpContext.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (string.IsNullOrEmpty(ipAddress))
return httpContext.Request.ServerVariables["REMOTE_ADDR"];
var addresses = ipAddress.Split(',');
if (addresses.Length != 0)
return addresses[0];
return httpContext.Request.ServerVariables["REMOTE_ADDR"];
}
catch (System.Exception ex)
{
//This try catch is to just always ensure that no matter what we're not getting any exceptions caused since
// that would cause people to not be able to login
return string.Format("Unknown, exception occurred trying to resolve IP {0}", ex);
}
}
}
}
+5 -1
View File
@@ -1,4 +1,5 @@
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Web;
@@ -40,9 +41,12 @@ namespace Umbraco.Core.Logging
/// <returns></returns>
private static string PrefixThreadId(string generateMessageFormat)
{
return "[Thread " + Thread.CurrentThread.ManagedThreadId + "] " + generateMessageFormat;
return (_prefixThreadId ?? (_prefixThreadId = "[P" + Process.GetCurrentProcess().Id + "/T" + Thread.CurrentThread.ManagedThreadId + "/D" + AppDomain.CurrentDomain.Id + "] "))
+ generateMessageFormat;
}
private static string _prefixThreadId = null;
#region Error
/// <summary>
/// Adds an error log
+1 -1
View File
@@ -12,7 +12,7 @@ namespace Umbraco.Core.Macros
internal class MacroTagParser
{
private static readonly Regex MacroRteContent = new Regex(@"(<!--\s*?)(<\?UMBRACO_MACRO.*?/>)(\s*?-->)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
private static readonly Regex MacroPersistedFormat = new Regex(@"(<\?UMBRACO_MACRO macroAlias=[""']([^""\'\n\r]+?)[""'].+?)(?:/>|>.*?</\?UMBRACO_MACRO>)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
private static readonly Regex MacroPersistedFormat = new Regex(@"(<\?UMBRACO_MACRO (?:.+)?macroAlias=[""']([^""\'\n\r]+?)[""'].+?)(?:/>|>.*?</\?UMBRACO_MACRO>)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
/// <summary>
/// This formats the persisted string to something useful for the rte so that the macro renders properly since we
+185
View File
@@ -0,0 +1,185 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.MemoryMappedFiles;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Hosting;
using Umbraco.Core.Logging;
using Umbraco.Core.ObjectResolution;
namespace Umbraco.Core
{
// represents the main domain
class MainDom : IRegisteredObject
{
#region Vars
// our own lock for local consistency
private readonly object _locko = new object();
// async lock representing the main domain lock
private readonly AsyncLock _asyncLock;
private IDisposable _asyncLocker;
// event wait handle used to notify current main domain that it should
// release the lock because a new domain wants to be the main domain
private readonly EventWaitHandle _signal;
// indicates whether...
private volatile bool _isMainDom; // we are the main domain
private volatile bool _signaled; // we have been signaled
// actions to run before releasing the main domain
private readonly SortedList<int, Action> _callbacks = new SortedList<int, Action>();
private const int LockTimeoutMilliseconds = 90000; // (1.5 * 60 * 1000) == 1 min 30 seconds
#endregion
#region Ctor
// initializes a new instance of MainDom
public MainDom()
{
var appId = string.Empty;
// HostingEnvironment.ApplicationID is null in unit tests, making ReplaceNonAlphanumericChars fail
if (HostingEnvironment.ApplicationID != null)
appId = HostingEnvironment.ApplicationID.ReplaceNonAlphanumericChars(string.Empty);
var lockName = "UMBRACO-" + appId + "-MAINDOM-LCK";
_asyncLock = new AsyncLock(lockName);
var eventName = "UMBRACO-" + appId + "-MAINDOM-EVT";
_signal = new EventWaitHandle(false, EventResetMode.AutoReset, eventName);
}
#endregion
// register a main domain consumer
public bool Register(Action release, int weight = 100)
{
return Register(null, release, weight);
}
// register a main domain consumer
public bool Register(Action install, Action release, int weight = 100)
{
lock (_locko)
{
if (_signaled) return false;
if (install != null)
install();
if (release != null)
_callbacks.Add(weight, release);
return true;
}
}
// handles the signal requesting that the main domain is released
private void OnSignal(string source)
{
// once signaled, we stop waiting, but then there is the hosting environment
// so we have to make sure that we only enter that method once
lock (_locko)
{
LogHelper.Debug<MainDom>("Signaled" + (_signaled ? " (again)" : "") + " (" + source + ").");
if (_signaled) return;
if (_isMainDom == false) return; // probably not needed
_signaled = true;
}
try
{
LogHelper.Debug<MainDom>("Stopping...");
foreach (var callback in _callbacks.Values)
{
try
{
callback(); // no timeout on callbacks
}
catch (Exception e)
{
LogHelper.Error<MainDom>("Error while running callback, remaining callbacks will not run.", e);
throw;
}
}
LogHelper.Debug<MainDom>("Stopped.");
}
finally
{
// in any case...
_isMainDom = false;
_asyncLocker.Dispose();
LogHelper.Debug<MainDom>("Released MainDom.");
}
}
// acquires the main domain
public bool Acquire()
{
lock (_locko) // we don't want the hosting environment to interfere by signaling
{
// if signaled, too late to acquire, give up
// the handler is not installed so that would be the hosting environment
if (_signaled)
{
LogHelper.Debug<MainDom>("Cannot acquire MainDom (signaled).");
return false;
}
LogHelper.Debug<MainDom>("Acquiring MainDom...");
// signal other instances that we want the lock, then wait one the lock,
// which may timeout, and this is accepted - see comments below
// signal, then wait for the lock, then make sure the event is
// resetted (maybe there was noone listening..)
_signal.Set();
// if more than 1 instance reach that point, one will get the lock
// and the other one will timeout, which is accepted
_asyncLocker = _asyncLock.Lock(LockTimeoutMilliseconds);
_isMainDom = true;
// we need to reset the event, because otherwise we would end up
// signaling ourselves and commiting suicide immediately.
// only 1 instance can reach that point, but other instances may
// have started and be trying to get the lock - they will timeout,
// which is accepted
_signal.Reset();
_signal.WaitOneAsync()
.ContinueWith(_ => OnSignal("signal"));
HostingEnvironment.RegisterObject(this);
LogHelper.Debug<MainDom>("Acquired MainDom.");
return true;
}
}
// gets a value indicating whether we are the main domain
public bool IsMainDom
{
get { return _isMainDom; }
}
// IRegisteredObject
public void Stop(bool immediate)
{
try
{
OnSignal("environment"); // will run once
}
finally
{
HostingEnvironment.UnregisterObject(this);
}
}
}
}
@@ -0,0 +1,35 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Core.IO;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Serialization;
namespace Umbraco.Core.Manifest
{
/// <summary>
/// Ensures that virtual paths are taken care of
/// </summary>
internal class GridEditorConverter : JsonCreationConverter<GridEditor>
{
protected override GridEditor Create(Type objectType, JObject jObject)
{
return new GridEditor();
}
protected override void Deserialize(JObject jObject, GridEditor target, JsonSerializer serializer)
{
base.Deserialize(jObject, target, serializer);
if (target.View.IsNullOrWhiteSpace() == false && target.View.StartsWith("~/"))
{
target.View = IOHelper.ResolveUrl(target.View);
}
if (target.Render.IsNullOrWhiteSpace() == false && target.Render.StartsWith("~/"))
{
target.Render = IOHelper.ResolveUrl(target.Render);
}
}
}
}
+20 -3
View File
@@ -39,7 +39,8 @@ namespace Umbraco.Core.Manifest
internal static IEnumerable<GridEditor> GetGridEditors(JArray jsonEditors)
{
return JsonConvert.DeserializeObject<IEnumerable<GridEditor>>(
jsonEditors.ToString());
jsonEditors.ToString(),
new GridEditorConverter());
}
/// <summary>
@@ -209,14 +210,30 @@ namespace Umbraco.Core.Manifest
}
}
}
//replace virtual paths for each property editor
if (deserialized["gridEditors"] != null)
{
foreach (JObject p in deserialized["gridEditors"])
{
if (p["view"] != null)
{
ReplaceVirtualPaths(p["view"]);
}
if (p["render"] != null)
{
ReplaceVirtualPaths(p["render"]);
}
}
}
var manifest = new PackageManifest()
{
JavaScriptInitialize = jConfig,
StylesheetInitialize = cssConfig,
PropertyEditors = propEditors.Any() ? (JArray)deserialized["propertyEditors"] : new JArray(),
ParameterEditors = propEditors.Any() ? (JArray)deserialized["parameterEditors"] : new JArray(),
GridEditors = propEditors.Any() ? (JArray)deserialized["gridEditors"] : new JArray()
ParameterEditors = paramEditors.Any() ? (JArray)deserialized["parameterEditors"] : new JArray(),
GridEditors = gridEditors.Any() ? (JArray)deserialized["gridEditors"] : new JArray()
};
result.Add(manifest);
}
+1 -68
View File
@@ -337,74 +337,7 @@ namespace Umbraco.Core.Models
ChangePublishedState(PublishedState.Unpublished);
}
}
/// <summary>
/// Indicates whether a specific property on the current <see cref="IContent"/> entity is dirty.
/// </summary>
/// <param name="propertyName">Name of the property to check</param>
/// <returns>True if Property is dirty, otherwise False</returns>
public override bool IsPropertyDirty(string propertyName)
{
bool existsInEntity = base.IsPropertyDirty(propertyName);
if (existsInEntity)
return true;
return Properties.Any(x => x.IsPropertyDirty(propertyName));
}
/// <summary>
/// Indicates whether the current entity is dirty.
/// </summary>
/// <returns>True if entity is dirty, otherwise False</returns>
public override bool IsDirty()
{
return IsEntityDirty() || IsAnyUserPropertyDirty();
}
/// <summary>
/// Returns true if only the entity properties are direty
/// </summary>
/// <returns></returns>
public bool IsEntityDirty()
{
return base.IsDirty();
}
/// <summary>
/// Returns true if any of the properties are dirty
/// </summary>
/// <returns></returns>
public bool IsAnyUserPropertyDirty()
{
return Properties.Any(x => x.IsDirty());
}
/// <summary>
/// Returns a list of all dirty user defined properties
/// </summary>
/// <returns></returns>
public IEnumerable<string> GetDirtyUserProperties()
{
return Properties.Where(x => x.IsDirty()).Select(x => x.Alias);
}
/// <summary>
/// Resets dirty properties by clearing the dictionary used to track changes.
/// </summary>
/// <remarks>
/// Please note that resetting the dirty properties could potentially
/// obstruct the saving of a new or updated entity.
/// </remarks>
public override void ResetDirtyProperties()
{
base.ResetDirtyProperties();
foreach (var property in Properties)
{
property.ResetDirtyProperties();
}
}
/// <summary>
/// Method to call when Entity is being saved
/// </summary>
+87 -2
View File
@@ -436,7 +436,7 @@ namespace Umbraco.Core.Models
return;
}
var propertyType = PropertyTypes.FirstOrDefault(x => x.Alias == propertyTypeAlias);
var propertyType = PropertyTypes.FirstOrDefault(x => x.Alias.InvariantEquals(propertyTypeAlias));
if (propertyType == null)
{
throw new Exception(String.Format("No PropertyType exists with the supplied alias: {0}", propertyTypeAlias));
@@ -466,6 +466,8 @@ namespace Umbraco.Core.Models
public abstract void ChangeTrashedState(bool isTrashed, int parentId = -20);
#region Dirty property handling
/// <summary>
/// We will override this method to ensure that when we reset the dirty properties that we
/// also reset the dirty changes made to the content's Properties (user defined)
@@ -480,6 +482,89 @@ namespace Umbraco.Core.Models
prop.ResetDirtyProperties(rememberPreviouslyChangedProperties);
}
}
/// <summary>
/// Indicates whether the current entity is dirty.
/// </summary>
/// <returns>True if entity is dirty, otherwise False</returns>
public override bool IsDirty()
{
return IsEntityDirty() || this.IsAnyUserPropertyDirty();
}
/// <summary>
/// Indicates whether the current entity was dirty.
/// </summary>
/// <returns>True if entity was dirty, otherwise False</returns>
public override bool WasDirty()
{
return WasEntityDirty() || this.WasAnyUserPropertyDirty();
}
/// <summary>
/// Returns true if only the entity properties are dirty
/// </summary>
/// <returns></returns>
public bool IsEntityDirty()
{
return base.IsDirty();
}
/// <summary>
/// Returns true if only the entity properties were dirty
/// </summary>
/// <returns></returns>
public bool WasEntityDirty()
{
return base.WasDirty();
}
/// <summary>
/// Indicates whether a specific property on the current <see cref="IContent"/> entity is dirty.
/// </summary>
/// <param name="propertyName">Name of the property to check</param>
/// <returns>
/// True if any of the class properties are dirty or
/// True if any of the user defined PropertyType properties are dirty based on their alias,
/// otherwise False
/// </returns>
public override bool IsPropertyDirty(string propertyName)
{
bool existsInEntity = base.IsPropertyDirty(propertyName);
if (existsInEntity)
return true;
if (Properties.Contains(propertyName))
{
return Properties[propertyName].IsDirty();
}
return false;
}
/// <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 any of the class properties are dirty or
/// True if any of the user defined PropertyType properties are dirty based on their alias,
/// otherwise False
/// </returns>
public override bool WasPropertyDirty(string propertyName)
{
bool existsInEntity = base.WasPropertyDirty(propertyName);
if (existsInEntity)
return true;
if (Properties.Contains(propertyName))
{
return Properties[propertyName].WasDirty();
}
return false;
}
#endregion
}
}
+24 -8
View File
@@ -77,10 +77,9 @@ namespace Umbraco.Core.Models
/// </remarks>
internal static bool RequiresSaving(this IContent entity, PublishedState publishedState)
{
var dirtyEntity = (ICanBeDirty)entity;
var publishedChanged = dirtyEntity.IsPropertyDirty("Published") && publishedState != PublishedState.Unpublished;
var publishedChanged = entity.IsPropertyDirty("Published") && publishedState != PublishedState.Unpublished;
//check if any user prop has changed
var propertyValueChanged = ((Content)entity).IsAnyUserPropertyDirty();
var propertyValueChanged = entity.IsAnyUserPropertyDirty();
//We need to know if any other property apart from Published was changed here
//don't create a new version if the published state has changed to 'Save' but no data has actually been changed
@@ -114,6 +113,25 @@ namespace Umbraco.Core.Models
return ShouldCreateNewVersion(entity, publishedState);
}
/// <summary>
/// Returns a list of all dirty user defined properties
/// </summary>
/// <returns></returns>
public static IEnumerable<string> GetDirtyUserProperties(this IContentBase entity)
{
return entity.Properties.Where(x => x.IsDirty()).Select(x => x.Alias);
}
public static bool IsAnyUserPropertyDirty(this IContentBase entity)
{
return entity.Properties.Any(x => x.IsDirty());
}
public static bool WasAnyUserPropertyDirty(this IContentBase entity)
{
return entity.Properties.Any(x => x.WasDirty());
}
/// <summary>
/// Determines if a new version should be created
/// </summary>
@@ -128,15 +146,13 @@ namespace Umbraco.Core.Models
/// </remarks>
internal static bool ShouldCreateNewVersion(this IContent entity, PublishedState publishedState)
{
var dirtyEntity = (ICanBeDirty)entity;
//check if the published state has changed or the language
var publishedChanged = dirtyEntity.IsPropertyDirty("Published") && publishedState != PublishedState.Unpublished;
var langChanged = dirtyEntity.IsPropertyDirty("Language");
var publishedChanged = entity.IsPropertyDirty("Published") && publishedState != PublishedState.Unpublished;
var langChanged = entity.IsPropertyDirty("Language");
var contentChanged = publishedChanged || langChanged;
//check if any user prop has changed
var propertyValueChanged = ((Content)entity).IsAnyUserPropertyDirty();
var propertyValueChanged = entity.IsAnyUserPropertyDirty();
//return true if published or language has changed
if (contentChanged)
+10 -4
View File
@@ -17,7 +17,6 @@ namespace Umbraco.Core.Models.EntityBase
public abstract class Entity : TracksChangesEntityBase, IEntity, IRememberBeingDirty, ICanBeDirty
{
private bool _hasIdentity;
private int? _hash;
private int _id;
private Guid _key;
private DateTime _createDate;
@@ -175,6 +174,7 @@ namespace Umbraco.Core.Models.EntityBase
}
}
//TODO: Make this NOT virtual or even exist really!
public virtual bool SameIdentityAs(IEntity other)
{
if (ReferenceEquals(null, other))
@@ -195,11 +195,13 @@ namespace Umbraco.Core.Models.EntityBase
return SameIdentityAs(other);
}
//TODO: Make this NOT virtual or even exist really!
public virtual Type GetRealType()
{
return GetType();
}
//TODO: Make this NOT virtual or even exist really!
public virtual bool SameIdentityAs(Entity other)
{
if (ReferenceEquals(null, other))
@@ -226,9 +228,13 @@ namespace Umbraco.Core.Models.EntityBase
public override int GetHashCode()
{
if (!_hash.HasValue)
_hash = !HasIdentity ? new int?(base.GetHashCode()) : new int?(Id.GetHashCode() * 397 ^ GetType().GetHashCode());
return _hash.Value;
unchecked
{
var hashCode = HasIdentity.GetHashCode();
hashCode = (hashCode * 397) ^ Id;
hashCode = (hashCode * 397) ^ GetType().GetHashCode();
return hashCode;
}
}
public virtual object DeepClone()
@@ -78,7 +78,7 @@ namespace Umbraco.Core.Models.EntityBase
/// Indicates that the entity had been changed and the changes were committed
/// </summary>
/// <returns></returns>
public bool WasDirty()
public virtual bool WasDirty()
{
return _lastPropertyChangedInfo != null && _lastPropertyChangedInfo.Any();
}
+15 -1
View File
@@ -137,9 +137,23 @@ namespace Umbraco.Core.Models
new DelegateEqualityComparer<object>(
(o, o1) =>
{
//Custom comparer for enumerable if it is enumerable
if (o == null && o1 == null) return true;
//custom comparer for strings.
if (o is string || o1 is string)
{
//if one is null and another is empty then they are the same
if ((o as string).IsNullOrWhiteSpace() && (o1 as string).IsNullOrWhiteSpace())
{
return true;
}
if (o == null || o1 == null) return false;
return o.Equals(o1);
}
if (o == null || o1 == null) return false;
//Custom comparer for enumerable if it is enumerable
var enum1 = o as IEnumerable;
var enum2 = o1 as IEnumerable;
if (enum1 != null && enum2 != null)
+12 -8
View File
@@ -16,12 +16,14 @@ namespace Umbraco.Core.Models
[DataContract(IsReference = true)]
public class PropertyCollection : KeyedCollection<string, Property>, INotifyCollectionChanged, IDeepCloneable
{
private readonly ReaderWriterLockSlim _addLocker = new ReaderWriterLockSlim();
private readonly object _addLocker = new object();
internal Action OnAdd;
internal Func<Property, bool> ValidateAdd { get; set; }
internal PropertyCollection()
{}
: base(StringComparer.InvariantCultureIgnoreCase)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="PropertyCollection"/> class with a delegate responsible for validating the addition of <see cref="Property"/> instances.
@@ -29,11 +31,13 @@ namespace Umbraco.Core.Models
/// <param name="validationCallback">The validation callback.</param>
/// <remarks></remarks>
internal PropertyCollection(Func<Property, bool> validationCallback)
: this()
{
ValidateAdd = validationCallback;
}
public PropertyCollection(IEnumerable<Property> properties)
: this()
{
Reset(properties);
}
@@ -78,7 +82,7 @@ namespace Umbraco.Core.Models
internal new void Add(Property item)
{
using (new WriteLock(_addLocker))
lock (_addLocker)
{
var key = GetKeyForItem(item);
if (key != null)
@@ -113,14 +117,14 @@ namespace Umbraco.Core.Models
/// <remarks></remarks>
public new bool Contains(string propertyTypeAlias)
{
return this.Any(x => x.Alias == propertyTypeAlias);
return base.Contains(propertyTypeAlias);
}
public int IndexOfKey(string key)
{
for (var i = 0; i < this.Count; i++)
{
if (this[i].Alias == key)
if (this[i].Alias.InvariantEquals(key))
{
return i;
}
@@ -145,7 +149,7 @@ namespace Umbraco.Core.Models
{
get
{
return this.FirstOrDefault(x => x.Alias == propertyType.Alias);
return this.FirstOrDefault(x => x.Alias.InvariantEquals(propertyType.Alias));
}
}
@@ -165,7 +169,7 @@ namespace Umbraco.Core.Models
/// <param name="propertyTypes">List of PropertyType</param>
protected internal void EnsurePropertyTypes(IEnumerable<PropertyType> propertyTypes)
{
if(/*!this.Any() &&*/ propertyTypes != null)
if (/*!this.Any() &&*/ propertyTypes != null)
{
foreach (var propertyType in propertyTypes)
{
@@ -180,7 +184,7 @@ namespace Umbraco.Core.Models
/// <param name="propertyTypes">List of PropertyType</param>
protected internal void EnsureCleanPropertyTypes(IEnumerable<PropertyType> propertyTypes)
{
if(propertyTypes != null)
if (propertyTypes != null)
{
//Remove PropertyTypes that doesn't exist in the list of new PropertyTypes
var aliases = this.Select(p => p.Alias).Except(propertyTypes.Select(x => x.Alias)).ToList();
+6 -11
View File
@@ -120,27 +120,22 @@ namespace Umbraco.Core.Models
public bool Equals(PropertyGroup other)
{
//Check whether the compared object is null.
if (Object.ReferenceEquals(other, null)) return false;
//Check whether the compared object references the same data.
if (Object.ReferenceEquals(this, other)) return true;
if (base.Equals(other)) return true;
//Check whether the PropertyGroup's properties are equal.
return Id.Equals(other.Id) && Name.Equals(other.Name);
return Name.InvariantEquals(other.Name);
}
public override int GetHashCode()
{
//Get hash code for the Name field if it is not null.
int hashName = Name == null ? 0 : Name.GetHashCode();
int baseHash = base.GetHashCode();
//Get hash code for the Id field.
int hashId = Id.GetHashCode();
//Get hash code for the Alias field.
int nameHash = Name.ToLowerInvariant().GetHashCode();
//Calculate the hash code for the product.
return hashName ^ hashId;
return baseHash ^ nameHash;
}
}
+44 -18
View File
@@ -38,11 +38,21 @@ namespace Umbraco.Core.Models
_propertyEditorAlias = dataTypeDefinition.PropertyEditorAlias;
_dataTypeDatabaseType = dataTypeDefinition.DatabaseType;
}
public PropertyType(IDataTypeDefinition dataTypeDefinition, string propertyTypeAlias)
: this(dataTypeDefinition)
{
SetAlias(propertyTypeAlias);
}
internal PropertyType(string propertyEditorAlias, DataTypeDatabaseType dataTypeDatabaseType)
public PropertyType(string propertyEditorAlias, DataTypeDatabaseType dataTypeDatabaseType)
: this(propertyEditorAlias, dataTypeDatabaseType, false)
{
PropertyEditorAlias = propertyEditorAlias;
}
public PropertyType(string propertyEditorAlias, DataTypeDatabaseType dataTypeDatabaseType, string propertyTypeAlias)
: this(propertyEditorAlias, dataTypeDatabaseType, false, propertyTypeAlias)
{
}
/// <summary>
@@ -58,6 +68,21 @@ namespace Umbraco.Core.Models
_dataTypeDatabaseType = dataTypeDatabaseType;
}
/// <summary>
/// Used internally to assign an explicity database type for this property type regardless of what the underlying data type/property editor is.
/// </summary>
/// <param name="propertyEditorAlias"></param>
/// <param name="dataTypeDatabaseType"></param>
/// <param name="isExplicitDbType"></param>
/// <param name="propertyTypeAlias"></param>
internal PropertyType(string propertyEditorAlias, DataTypeDatabaseType dataTypeDatabaseType, bool isExplicitDbType, string propertyTypeAlias)
{
_isExplicitDbType = isExplicitDbType;
_propertyEditorAlias = propertyEditorAlias;
_dataTypeDatabaseType = dataTypeDatabaseType;
SetAlias(propertyTypeAlias);
}
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<PropertyType, string>(x => x.Name);
private static readonly PropertyInfo AliasSelector = ExpressionHelper.GetPropertyInfo<PropertyType, string>(x => x.Alias);
private static readonly PropertyInfo DescriptionSelector = ExpressionHelper.GetPropertyInfo<PropertyType, string>(x => x.Description);
@@ -96,15 +121,9 @@ namespace Umbraco.Core.Models
get { return _alias; }
set
{
//NOTE: WE are doing this because we don't want to do a ToSafeAlias when the alias is the special case of
// being prefixed with Constants.PropertyEditors.InternalGenericPropertiesPrefix
// which is used internally
SetPropertyValueAndDetectChanges(o =>
{
_alias = value.StartsWith(Constants.PropertyEditors.InternalGenericPropertiesPrefix)
? value
: value.ToCleanString(CleanStringType.Alias | CleanStringType.UmbracoCase);
SetAlias(value);
return _alias;
}, _alias, AliasSelector);
}
@@ -284,6 +303,17 @@ namespace Umbraco.Core.Models
}
}
private void SetAlias(string value)
{
//NOTE: WE are doing this because we don't want to do a ToSafeAlias when the alias is the special case of
// being prefixed with Constants.PropertyEditors.InternalGenericPropertiesPrefix
// which is used internally
_alias = value.StartsWith(Constants.PropertyEditors.InternalGenericPropertiesPrefix)
? value
: value.ToCleanString(CleanStringType.Alias | CleanStringType.UmbracoCase);
}
/// <summary>
/// Create a new Property object from a "raw" database value.
/// </summary>
@@ -431,26 +461,22 @@ namespace Umbraco.Core.Models
public bool Equals(PropertyType other)
{
//Check whether the compared object is null.
if (ReferenceEquals(other, null)) return false;
//Check whether the compared object references the same data.
if (ReferenceEquals(this, other)) return true;
if (base.Equals(other)) return true;
//Check whether the PropertyType's properties are equal.
return Alias.Equals(other.Alias) && Name.Equals(other.Name);
return Alias.InvariantEquals(other.Alias);
}
public override int GetHashCode()
{
//Get hash code for the Name field if it is not null.
int hashName = Name == null ? 0 : Name.GetHashCode();
int baseHash = base.GetHashCode();
//Get hash code for the Alias field.
int hashAlias = Alias.GetHashCode();
int hashAlias = Alias.ToLowerInvariant().GetHashCode();
//Calculate the hash code for the product.
return hashName ^ hashAlias;
return baseHash ^ hashAlias;
}
public override object DeepClone()
@@ -112,7 +112,7 @@ namespace Umbraco.Core.ObjectResolution
/// <exception cref="InvalidOperationException">resolution is already frozen.</exception>
public static void Freeze()
{
LogHelper.Debug(typeof(Resolution), "Freezing resolution");
LogHelper.Debug(typeof (Resolution), "Freezing resolution");
using (new WriteLock(ConfigurationLock))
{
@@ -121,9 +121,20 @@ namespace Umbraco.Core.ObjectResolution
_isFrozen = true;
}
if (Frozen != null)
Frozen(null, null);
LogHelper.Debug(typeof(Resolution), "Resolution is frozen");
if (Frozen == null) return;
try
{
Frozen(null, null);
}
catch (Exception e)
{
LogHelper.Error(typeof (Resolution), "Exception in Frozen event handler.", e);
throw;
}
}
/// <summary>
@@ -105,9 +105,9 @@ namespace Umbraco.Core.Persistence.Factories
propDbType.Result,
//This flag tells the property type that it has an explicit dbtype and that it cannot be changed
// which is what we want for the built-in properties.
propDbType.Success)
propDbType.Success,
typeDto.Alias)
{
Alias = typeDto.Alias,
DataTypeDefinitionId = typeDto.DataTypeId,
Description = typeDto.Description,
Id = typeDto.Id.Value,
@@ -158,9 +158,9 @@ namespace Umbraco.Core.Persistence.Factories
propDbType.Result,
//This flag tells the property type that it has an explicit dbtype and that it cannot be changed
// which is what we want for the built-in properties.
propDbType.Success)
propDbType.Success,
typeDto.Alias)
{
Alias = typeDto.Alias,
DataTypeDefinitionId = typeDto.DataTypeId,
Description = typeDto.Description,
HelpText = typeDto.HelpText,
@@ -34,15 +34,20 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven
if (Context.CurrentDatabaseProvider == DatabaseProviders.MySql)
{
Delete.ForeignKey().FromTable("cmsTagRelationship").ForeignColumn("nodeId").ToTable("umbracoNode").PrimaryColumn("id");
//check for another strange really old one that might have existed
if (constraints.Any(x => x.Item1 == "cmsTagRelationship" && x.Item2 == "tagId"))
{
Delete.ForeignKey().FromTable("cmsTagRelationship").ForeignColumn("tagId").ToTable("cmsTags").PrimaryColumn("id");
}
}
else
{
//Before we try to delete this constraint, we'll see if it exists first, some older schemas never had it and some older schema's had this named
// differently than the default.
var constraint = constraints
.SingleOrDefault(x => x.Item1 == "cmsTagRelationship" && x.Item2 == "nodeId" && x.Item3.InvariantStartsWith("PK_") == false);
if (constraint != null)
var constraintMatches = constraints.Where(x => x.Item1 == "cmsTagRelationship" && x.Item2 == "nodeId" && x.Item3.InvariantStartsWith("PK_") == false);
foreach (var constraint in constraintMatches)
{
Delete.ForeignKey(constraint.Item3).OnTable("cmsTagRelationship");
}
@@ -42,11 +42,33 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero
Create.Index("IX_cmsDocument_newest").OnTable("cmsDocument").OnColumn("newest").Ascending().WithOptions().NonClustered();
}
//TODO: We need to fix this for SQL Azure since it does not let you drop any clustered indexes
// Issue: http://issues.umbraco.org/issue/U4-5673
// Some work around notes:
// http://stackoverflow.com/questions/15872347/alter-clustered-index-column
// https://social.msdn.microsoft.com/Forums/azure/en-US/5cc4b302-fa42-4c62-956a-bbf79dbbd040/changing-clustered-index-in-azure?forum=ssdsgetstarted
//We need to do this for SQL Azure V2 since it does not let you drop any clustered indexes
// Issue: http://issues.umbraco.org/issue/U4-5673
if (Context.CurrentDatabaseProvider == DatabaseProviders.SqlServer || Context.CurrentDatabaseProvider == DatabaseProviders.SqlAzure)
{
var version = Context.Database.ExecuteScalar<string>("SELECT @@@@VERSION");
if (version.Contains("Microsoft SQL Azure"))
{
var parts = version.Split(new[] { '-' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).ToArray();
if (parts.Length > 1)
{
if (parts[1].StartsWith("11."))
{
//we want to drop the umbracoUserLogins_Index index since it is named incorrectly and then re-create it so
// it follows the standard naming convention
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("umbracoUserLogins_Index")))
{
//It's the old version that doesn't support dropping a clustered index on a table, so we need to do some manual work.
ExecuteSqlAzureSqlForChangingIndex();
}
return;
}
}
}
}
//we want to drop the umbracoUserLogins_Index index since it is named incorrectly and then re-create it so
// it follows the standard naming convention
@@ -67,5 +89,28 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero
Delete.Index("IX_cmsDocument_published").OnTable("cmsDocument");
Delete.Index("IX_cmsDocument_newest").OnTable("cmsDocument");
}
private void ExecuteSqlAzureSqlForChangingIndex()
{
Context.Database.Execute(@"CREATE TABLE ""umbracoUserLogins_temp""
(
contextID uniqueidentifier NOT NULL,
userID int NOT NULL,
[timeout] bigint NOT NULL
);
CREATE CLUSTERED INDEX ""IX_umbracoUserLogins_Index"" ON ""umbracoUserLogins_temp"" (""contextID"");
INSERT INTO ""umbracoUserLogins_temp"" SELECT * FROM ""umbracoUserLogins""
DROP TABLE ""umbracoUserLogins""
CREATE TABLE ""umbracoUserLogins""
(
contextID uniqueidentifier NOT NULL,
userID int NOT NULL,
[timeout] bigint NOT NULL
);
CREATE CLUSTERED INDEX ""IX_umbracoUserLogins_Index"" ON ""umbracoUserLogins"" (""contextID"");
INSERT INTO ""umbracoUserLogins"" SELECT * FROM ""umbracoUserLogins_temp""
DROP TABLE ""umbracoUserLogins_temp""");
}
}
}
@@ -66,7 +66,7 @@ namespace Umbraco.Core.Persistence.Repositories
protected virtual PropertyType CreatePropertyType(string propertyEditorAlias, DataTypeDatabaseType dbType, string propertyTypeAlias)
{
return new PropertyType(propertyEditorAlias, dbType);
return new PropertyType(propertyEditorAlias, dbType, propertyTypeAlias);
}
protected void PersistNewBaseContentType(ContentTypeDto dto, IContentTypeComposition entity)
@@ -451,8 +451,7 @@ AND umbracoNode.id <> @id",
var list = new List<PropertyType>();
foreach (var dto in dtos.Where(x => (x.PropertyTypeGroupId > 0) == false))
{
var propType = CreatePropertyType(dto.DataTypeDto.PropertyEditorAlias, dto.DataTypeDto.DbType.EnumParse<DataTypeDatabaseType>(true), dto.Alias);
propType.Alias = dto.Alias;
var propType = CreatePropertyType(dto.DataTypeDto.PropertyEditorAlias, dto.DataTypeDto.DbType.EnumParse<DataTypeDatabaseType>(true), dto.Alias);
propType.DataTypeDefinitionId = dto.DataTypeId;
propType.Description = dto.Description;
propType.Id = dto.Id;
@@ -1041,10 +1040,9 @@ AND umbracoNode.id <> @id",
.Select(group => new PropertyGroup(new PropertyTypeCollection(
result
.Where(row => row.pgId == group.GroupId && row.ptId != null)
.Select(row => new PropertyType(row.dtPropEdAlias, Enum<DataTypeDatabaseType>.Parse(row.dtDbType))
.Select(row => new PropertyType(row.dtPropEdAlias, Enum<DataTypeDatabaseType>.Parse(row.dtDbType), row.ptAlias)
{
//fill in the rest of the property type properties
Alias = row.ptAlias,
Description = row.ptDesc,
DataTypeDefinitionId = row.dtId,
Id = row.ptId,
@@ -1070,10 +1068,9 @@ AND umbracoNode.id <> @id",
.Where(x => x.pgId == null)
//filter based on the current content type
.Where(x => x.contentTypeId == currId)
.Select(row => new PropertyType(row.dtPropEdAlias, Enum<DataTypeDatabaseType>.Parse(row.dtDbType))
.Select(row => new PropertyType(row.dtPropEdAlias, Enum<DataTypeDatabaseType>.Parse(row.dtDbType), row.ptAlias)
{
//fill in the rest of the property type properties
Alias = row.ptAlias,
Description = row.ptDesc,
DataTypeDefinitionId = row.dtId,
Id = row.ptId,
@@ -493,15 +493,10 @@ AND umbracoNode.id <> @id",
throw new InvalidOperationException("Cannot insert a pre value for a data type that has no identity");
}
//Cannot add a duplicate alias
var exists = Database.ExecuteScalar<int>(@"SELECT COUNT(*) FROM cmsDataTypePreValues
WHERE alias = @alias
AND datatypeNodeId = @dtdid",
new { alias = entity.Alias, dtdid = entity.DataType.Id });
if (exists > 0)
{
throw new DuplicateNameException("A pre value with the alias " + entity.Alias + " already exists for this data type");
}
//NOTE: We used to check that the Alias was unique for the given DataTypeNodeId prevalues list, BUT
// in reality there is no need to check the uniqueness of this alias because the only way that this code executes is
// based on an IDictionary<string, PreValue> dictionary being passed to this repository and a dictionary
// must have unique aliases by definition, so there is no need for this additional check
var dto = new DataTypePreValueDto
{
@@ -519,17 +514,12 @@ AND datatypeNodeId = @dtdid",
{
throw new InvalidOperationException("Cannot update a pre value for a data type that has no identity");
}
//Cannot change to a duplicate alias
var exists = Database.ExecuteScalar<int>(@"SELECT COUNT(*) FROM cmsDataTypePreValues
WHERE alias = @alias
AND datatypeNodeId = @dtdid
AND id <> @id",
new { id = entity.Id, alias = entity.Alias, dtdid = entity.DataType.Id });
if (exists > 0)
{
throw new DuplicateNameException("A pre value with the alias " + entity.Alias + " already exists for this data type");
}
//NOTE: We used to check that the Alias was unique for the given DataTypeNodeId prevalues list, BUT
// this causes issues when sorting the pre-values (http://issues.umbraco.org/issue/U4-5670) but in reality
// there is no need to check the uniqueness of this alias because the only way that this code executes is
// based on an IDictionary<string, PreValue> dictionary being passed to this repository and a dictionary
// must have unique aliases by definition, so there is no need for this additional check
var dto = new DataTypePreValueDto
{
@@ -258,7 +258,8 @@ namespace Umbraco.Core.Persistence.Repositories
return new PropertyType(propertyEditorAlias, propDbType.Result,
//This flag tells the property type that it has an explicit dbtype and that it cannot be changed
// which is what we want for the built-in properties.
propDbType.Success);
propDbType.Success,
propertyTypeAlias);
}
/// <summary>
+4 -8
View File
@@ -606,14 +606,10 @@ namespace Umbraco.Core
/// <returns></returns>
internal IEnumerable<T> CreateInstances<T>(IEnumerable<Type> types, bool throwException = false)
{
//Have removed logging because it doesn't really need to be logged since the time taken is generally 0ms.
//we want to know if it fails ever, not how long it took if it is only 0.
var typesAsArray = types.ToArray();
//using (DisposableTimer.DebugDuration<PluginManager>(
// String.Format("Starting instantiation of {0} objects of type {1}", typesAsArray.Length, typeof(T).FullName),
// String.Format("Completed instantiation of {0} objects of type {1}", typesAsArray.Length, typeof(T).FullName)))
//{
LogHelper.Debug<PluginManager>(string.Format("Instantiating {0} objects of type {1}", typesAsArray.Length, typeof (T).FullName));
var instances = new List<T>();
foreach (var t in typesAsArray)
{
@@ -634,7 +630,7 @@ namespace Umbraco.Core
}
}
return instances;
//}
}
/// <summary>
@@ -4,6 +4,7 @@ using System.Configuration.Provider;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Configuration;
using System.Web.Hosting;
using System.Web.Security;
@@ -893,5 +894,15 @@ namespace Umbraco.Core.Security
return sb.ToString();
}
/// <summary>
/// Returns the current request IP address for logging if there is one
/// </summary>
/// <returns></returns>
protected string GetCurrentRequestIpAddress()
{
var httpContext = HttpContext.Current == null ? (HttpContextBase) null : new HttpContextWrapper(HttpContext.Current);
return httpContext.GetCurrentRequestIpAddress();
}
}
}
+2 -2
View File
@@ -500,7 +500,7 @@ namespace Umbraco.Core.Services
public IEnumerable<IContent> GetPagedChildren(int id, int pageIndex, int pageSize, out int totalChildren,
string orderBy, Direction orderDirection, string filter = "")
{
Mandate.ParameterCondition(pageIndex >= 0, "pageSize");
Mandate.ParameterCondition(pageIndex >= 0, "pageIndex");
Mandate.ParameterCondition(pageSize > 0, "pageSize");
using (var repository = _repositoryFactory.CreateContentRepository(_uowProvider.GetUnitOfWork()))
{
@@ -530,7 +530,7 @@ namespace Umbraco.Core.Services
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
public IEnumerable<IContent> GetPagedDescendants(int id, int pageIndex, int pageSize, out int totalChildren, string orderBy = "Path", Direction orderDirection = Direction.Ascending, string filter = "")
{
Mandate.ParameterCondition(pageIndex >= 0, "pageSize");
Mandate.ParameterCondition(pageIndex >= 0, "pageIndex");
Mandate.ParameterCondition(pageSize > 0, "pageSize");
using (var repository = _repositoryFactory.CreateContentRepository(_uowProvider.GetUnitOfWork()))
{
+81 -1
View File
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Umbraco.Core.Cache;
using Umbraco.Core.CodeAnnotations;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
@@ -19,12 +20,13 @@ namespace Umbraco.Core.Services
private readonly IMediaService _mediaService;
private readonly IMemberService _memberService;
private readonly IMemberTypeService _memberTypeService;
private readonly IRuntimeCacheProvider _runtimeCache;
private readonly IDataTypeService _dataTypeService;
private readonly Dictionary<string, Tuple<UmbracoObjectTypes, Func<int, IUmbracoEntity>>> _supportedObjectTypes;
public EntityService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory,
IContentService contentService, IContentTypeService contentTypeService, IMediaService mediaService, IDataTypeService dataTypeService,
IMemberService memberService, IMemberTypeService memberTypeService)
IMemberService memberService, IMemberTypeService memberTypeService, IRuntimeCacheProvider runtimeCache)
{
_uowProvider = provider;
_repositoryFactory = repositoryFactory;
@@ -34,6 +36,7 @@ namespace Umbraco.Core.Services
_dataTypeService = dataTypeService;
_memberService = memberService;
_memberTypeService = memberTypeService;
_runtimeCache = runtimeCache;
_supportedObjectTypes = new Dictionary<string, Tuple<UmbracoObjectTypes, Func<int, IUmbracoEntity>>>
{
@@ -45,6 +48,83 @@ namespace Umbraco.Core.Services
{typeof (IMember).FullName, new Tuple<UmbracoObjectTypes, Func<int, IUmbracoEntity>>(UmbracoObjectTypes.Member, _memberService.GetById)},
{typeof (IMemberType).FullName, new Tuple<UmbracoObjectTypes, Func<int, IUmbracoEntity>>(UmbracoObjectTypes.MemberType, _memberTypeService.Get)}
};
}
/// <summary>
/// Returns the integer id for a given GUID
/// </summary>
/// <param name="key"></param>
/// <param name="umbracoObjectType"></param>
/// <returns></returns>
public Attempt<int> GetIdForKey(Guid key, UmbracoObjectTypes umbracoObjectType)
{
var result = _runtimeCache.GetCacheItem<int?>(CacheKeys.IdToKeyCacheKey + key, () =>
{
using (var uow = _uowProvider.GetUnitOfWork())
{
switch (umbracoObjectType)
{
case UmbracoObjectTypes.Document:
case UmbracoObjectTypes.MemberType:
case UmbracoObjectTypes.Media:
case UmbracoObjectTypes.Template:
case UmbracoObjectTypes.MediaType:
case UmbracoObjectTypes.DocumentType:
case UmbracoObjectTypes.Member:
case UmbracoObjectTypes.DataType:
return uow.Database.ExecuteScalar<int?>(new Sql().Select("id").From<NodeDto>().Where<NodeDto>(dto => dto.UniqueId == key));
case UmbracoObjectTypes.RecycleBin:
case UmbracoObjectTypes.Stylesheet:
case UmbracoObjectTypes.MemberGroup:
case UmbracoObjectTypes.ContentItem:
case UmbracoObjectTypes.ContentItemType:
case UmbracoObjectTypes.ROOT:
case UmbracoObjectTypes.Unknown:
default:
throw new NotSupportedException();
}
}
});
return result.HasValue ? Attempt.Succeed(result.Value) : Attempt<int>.Fail();
}
/// <summary>
/// Returns the GUID for a given integer id
/// </summary>
/// <param name="id"></param>
/// <param name="umbracoObjectType"></param>
/// <returns></returns>
public Attempt<Guid> GetKeyForId(int id, UmbracoObjectTypes umbracoObjectType)
{
var result = _runtimeCache.GetCacheItem<Guid?>(CacheKeys.KeyToIdCacheKey + id, () =>
{
using (var uow = _uowProvider.GetUnitOfWork())
{
switch (umbracoObjectType)
{
case UmbracoObjectTypes.Document:
case UmbracoObjectTypes.MemberType:
case UmbracoObjectTypes.Media:
case UmbracoObjectTypes.Template:
case UmbracoObjectTypes.MediaType:
case UmbracoObjectTypes.DocumentType:
case UmbracoObjectTypes.Member:
case UmbracoObjectTypes.DataType:
return uow.Database.ExecuteScalar<Guid?>(new Sql().Select("uniqueID").From<NodeDto>().Where<NodeDto>(dto => dto.NodeId == id));
case UmbracoObjectTypes.RecycleBin:
case UmbracoObjectTypes.Stylesheet:
case UmbracoObjectTypes.MemberGroup:
case UmbracoObjectTypes.ContentItem:
case UmbracoObjectTypes.ContentItemType:
case UmbracoObjectTypes.ROOT:
case UmbracoObjectTypes.Unknown:
default:
throw new NotSupportedException();
}
}
});
return result.HasValue ? Attempt.Succeed(result.Value) : Attempt<Guid>.Fail();
}
public IUmbracoEntity GetByKey(Guid key, bool loadBaseType = true)
@@ -7,6 +7,21 @@ namespace Umbraco.Core.Services
{
public interface IEntityService
{
/// <summary>
/// Returns the integer id for a given GUID
/// </summary>
/// <param name="key"></param>
/// <param name="umbracoObjectType"></param>
/// <returns></returns>
Attempt<int> GetIdForKey(Guid key, UmbracoObjectTypes umbracoObjectType);
/// <summary>
/// Returns the GUID for a given integer id
/// </summary>
/// <param name="id"></param>
/// <param name="umbracoObjectType"></param>
/// <returns></returns>
Attempt<Guid> GetKeyForId(int id, UmbracoObjectTypes umbracoObjectType);
/// <summary>
/// Gets an UmbracoEntity by its Id, and optionally loads the complete object graph.
@@ -85,14 +85,14 @@ namespace Umbraco.Core.Services
}
//get the lazy value from cache
result.Add(culture, new Lazy<XDocument>(() => _cache.GetCacheItem<XDocument>(
string.Format("{0}-{1}", typeof(LocalizedTextServiceFileSources).Name, culture.Name), () =>
result[culture] = new Lazy<XDocument>(() => _cache.GetCacheItem<XDocument>(
string.Format("{0}-{1}", typeof (LocalizedTextServiceFileSources).Name, culture.Name), () =>
{
using (var fs = localCopy.OpenRead())
{
return XDocument.Load(fs);
}
}, isSliding: true, timeout: TimeSpan.FromMinutes(10), dependentFiles: new[] { localCopy.FullName })));
}, isSliding: true, timeout: TimeSpan.FromMinutes(10), dependentFiles: new[] {localCopy.FullName}));
}
return result;
});
+2 -2
View File
@@ -408,7 +408,7 @@ namespace Umbraco.Core.Services
public IEnumerable<IMedia> GetPagedChildren(int id, int pageIndex, int pageSize, out int totalChildren,
string orderBy, Direction orderDirection, string filter = "")
{
Mandate.ParameterCondition(pageIndex >= 0, "pageSize");
Mandate.ParameterCondition(pageIndex >= 0, "pageIndex");
Mandate.ParameterCondition(pageSize > 0, "pageSize");
using (var repository = _repositoryFactory.CreateMediaRepository(_uowProvider.GetUnitOfWork()))
{
@@ -437,7 +437,7 @@ namespace Umbraco.Core.Services
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
public IEnumerable<IMedia> GetPagedDescendants(int id, int pageIndex, int pageSize, out int totalChildren, string orderBy = "Path", Direction orderDirection = Direction.Ascending, string filter = "")
{
Mandate.ParameterCondition(pageIndex >= 0, "pageSize");
Mandate.ParameterCondition(pageIndex >= 0, "pageIndex");
Mandate.ParameterCondition(pageSize > 0, "pageSize");
using (var repository = _repositoryFactory.CreateMediaRepository(_uowProvider.GetUnitOfWork()))
{
+6 -12
View File
@@ -1221,44 +1221,38 @@ namespace Umbraco.Core.Services
Name = "Membership",
Id = --identity
};
propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.TextboxAlias, DataTypeDatabaseType.Ntext)
propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.TextboxAlias, DataTypeDatabaseType.Ntext, Constants.Conventions.Member.Comments)
{
Alias = Constants.Conventions.Member.Comments,
Name = Constants.Conventions.Member.CommentsLabel,
SortOrder = 0,
Id = --identity
});
propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.TrueFalseAlias, DataTypeDatabaseType.Integer)
propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.TrueFalseAlias, DataTypeDatabaseType.Integer, Constants.Conventions.Member.IsApproved)
{
Alias = Constants.Conventions.Member.IsApproved,
Name = Constants.Conventions.Member.IsApprovedLabel,
SortOrder = 3,
Id = --identity
});
propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.TrueFalseAlias, DataTypeDatabaseType.Integer)
propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.TrueFalseAlias, DataTypeDatabaseType.Integer, Constants.Conventions.Member.IsLockedOut)
{
Alias = Constants.Conventions.Member.IsLockedOut,
Name = Constants.Conventions.Member.IsLockedOutLabel,
SortOrder = 4,
Id = --identity
});
propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date)
propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, Constants.Conventions.Member.LastLockoutDate)
{
Alias = Constants.Conventions.Member.LastLockoutDate,
Name = Constants.Conventions.Member.LastLockoutDateLabel,
SortOrder = 5,
Id = --identity
});
propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date)
propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, Constants.Conventions.Member.LastLoginDate)
{
Alias = Constants.Conventions.Member.LastLoginDate,
Name = Constants.Conventions.Member.LastLoginDateLabel,
SortOrder = 6,
Id = --identity
});
propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date)
propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, Constants.Conventions.Member.LastPasswordChangeDate)
{
Alias = Constants.Conventions.Member.LastPasswordChangeDate,
Name = Constants.Conventions.Member.LastPasswordChangeDateLabel,
SortOrder = 7,
Id = --identity
@@ -648,9 +648,8 @@ namespace Umbraco.Core.Services
if (dataTypeDefinition == null) continue;
}
var propertyType = new PropertyType(dataTypeDefinition)
var propertyType = new PropertyType(dataTypeDefinition, property.Element("Alias").Value)
{
Alias = property.Element("Alias").Value,
Name = property.Element("Name").Value,
Description = property.Element("Description").Value,
Mandatory = property.Element("Mandatory").Value.ToLowerInvariant().Equals("true"),
+2 -1
View File
@@ -167,7 +167,8 @@ namespace Umbraco.Core.Services
if (_entityService == null)
_entityService = new Lazy<IEntityService>(() => new EntityService(
provider, repositoryFactory.Value,
_contentService.Value, _contentTypeService.Value, _mediaService.Value, _dataTypeService.Value, _memberService.Value, _memberTypeService.Value));
_contentService.Value, _contentTypeService.Value, _mediaService.Value, _dataTypeService.Value, _memberService.Value, _memberTypeService.Value,
cache.RuntimeCache));
if (_relationService == null)
_relationService = new Lazy<IRelationService>(() => new RelationService(provider, repositoryFactory.Value, _entityService.Value));
+27 -2
View File
@@ -1,4 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Events;
@@ -207,6 +208,9 @@ namespace Umbraco.Core.Services
}
}
//TODO: Remove this in 7.3, we need to track this in a db column!
private readonly ConcurrentDictionary<int, int> _failedLoginAttempts = new ConcurrentDictionary<int, int>();
/// <summary>
/// Get an <see cref="IUser"/> by username
/// </summary>
@@ -217,7 +221,18 @@ namespace Umbraco.Core.Services
using (var repository = _repositoryFactory.CreateUserRepository(_uowProvider.GetUnitOfWork()))
{
var query = Query<IUser>.Builder.Where(x => x.Username.Equals(username));
return repository.GetByQuery(query).FirstOrDefault();
var user = repository.GetByQuery(query).FirstOrDefault();
if (user != null)
{
//check if they have any failed logins and merge
int failedAttempts;
if (_failedLoginAttempts.TryGetValue(user.Id, out failedAttempts))
{
user.FailedPasswordAttempts = failedAttempts;
}
}
return user;
}
}
@@ -284,6 +299,9 @@ namespace Umbraco.Core.Services
}
else
{
int failedAttempts;
_failedLoginAttempts.TryRemove(user.Id, out failedAttempts);
if (DeletingUser.IsRaisedEventCancelled(new DeleteEventArgs<IUser>(user), this))
return;
@@ -317,6 +335,8 @@ namespace Umbraco.Core.Services
{
repository.AddOrUpdate(entity);
uow.Commit();
_failedLoginAttempts.AddOrUpdate(entity.Id, i => entity.FailedPasswordAttempts, (i, i1) => entity.FailedPasswordAttempts);
}
if (raiseEvents)
@@ -342,10 +362,15 @@ namespace Umbraco.Core.Services
{
foreach (var member in entities)
{
repository.AddOrUpdate(member);
repository.AddOrUpdate(member);
}
//commit the whole lot in one go
uow.Commit();
foreach (var member in entities)
{
_failedLoginAttempts.AddOrUpdate(member.Id, i => member.FailedPasswordAttempts, (i, i1) => member.FailedPasswordAttempts);
}
}
if (raiseEvents)
@@ -5,6 +5,7 @@ using Umbraco.Core.Services;
namespace Umbraco.Core.Strategies
{
//TODO: This should just exist in the content service/repo!
public sealed class RelateOnCopyHandler : ApplicationEventHandler
{
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
@@ -1,10 +1,9 @@
using System;
using System.Linq;
using System.Web;
using System.Xml;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
namespace Umbraco.Core.Sync
{
@@ -13,58 +12,73 @@ namespace Umbraco.Core.Sync
/// </summary>
internal static class ServerEnvironmentHelper
{
/// <summary>
/// Returns the current umbraco base url for the current server depending on it's environment
/// status. This will attempt to determine the internal umbraco base url that can be used by the current
/// server to send a request to itself if it is in a load balanced environment.
/// </summary>
/// <returns>The full base url including schema (i.e. http://myserver:80/umbraco ) - or <c>null</c> if the url
/// cannot be determined at the moment (usually because the first request has not properly completed yet).</returns>
public static string GetCurrentServerUmbracoBaseUrl(ApplicationContext appContext, IUmbracoSettingsSection settings)
public static void TrySetApplicationUrlFromSettings(ApplicationContext appContext, IUmbracoSettingsSection settings)
{
// try umbracoSettings:settings/web.routing/@umbracoApplicationUrl
// which is assumed to:
// - end with SystemDirectories.Umbraco
// - contain a scheme
// - end or not with a slash, it will be taken care of
// eg "http://www.mysite.com/umbraco"
var url = settings.WebRouting.UmbracoApplicationUrl;
if (url.IsNullOrWhiteSpace() == false)
{
appContext.UmbracoApplicationUrl = url.TrimEnd('/');
LogHelper.Info(typeof(ServerEnvironmentHelper), "ApplicationUrl: " + appContext.UmbracoApplicationUrl + " (using web.routing/@umbracoApplicationUrl)");
return;
}
// try umbracoSettings:settings/scheduledTasks/@baseUrl
// which is assumed to:
// - end with SystemDirectories.Umbraco
// - NOT contain any scheme (because, legacy)
// - end or not with a slash, it will be taken care of
// eg "mysite.com/umbraco"
url = settings.ScheduledTasks.BaseUrl;
if (url.IsNullOrWhiteSpace() == false)
{
var ssl = GlobalSettings.UseSSL ? "s" : "";
url = "http" + ssl + "://" + url;
appContext.UmbracoApplicationUrl = url.TrimEnd('/');
LogHelper.Info(typeof(ServerEnvironmentHelper), "ApplicationUrl: " + appContext.UmbracoApplicationUrl + " (using scheduledTasks/@baseUrl)");
return;
}
// try servers
var status = GetStatus(settings);
if (status == CurrentServerEnvironmentStatus.Single)
{
// single install, return null if no config/original url, else use config/original url as base
// use http or https as appropriate
return GetBaseUrl(appContext, settings);
}
return;
// no server, nothing we can do
var servers = settings.DistributedCall.Servers.ToArray();
if (servers.Length == 0)
return;
if (servers.Any() == false)
{
// cannot be determined, return null if no config/original url, else use config/original url as base
// use http or https as appropriate
return GetBaseUrl(appContext, settings);
}
// we have servers, look for this server
foreach (var server in servers)
{
var appId = server.AppId;
var serverName = server.ServerName;
// skip if no data
if (appId.IsNullOrWhiteSpace() && serverName.IsNullOrWhiteSpace())
{
continue;
}
// if this server, build and return the url
if ((appId.IsNullOrWhiteSpace() == false && appId.Trim().InvariantEquals(HttpRuntime.AppDomainAppId))
|| (serverName.IsNullOrWhiteSpace() == false && serverName.Trim().InvariantEquals(NetworkHelper.MachineName)))
{
//match by appId or computer name! return the url configured
return string.Format("{0}://{1}:{2}/{3}",
// match by appId or computer name, return the url configured
url = string.Format("{0}://{1}:{2}/{3}",
server.ForceProtocol.IsNullOrWhiteSpace() ? "http" : server.ForceProtocol,
server.ServerAddress,
server.ForcePortnumber.IsNullOrWhiteSpace() ? "80" : server.ForcePortnumber,
IOHelper.ResolveUrl(SystemDirectories.Umbraco).TrimStart('/'));
appContext.UmbracoApplicationUrl = url.TrimEnd('/');
LogHelper.Info(typeof(ServerEnvironmentHelper), "ApplicationUrl: " + appContext.UmbracoApplicationUrl + " (using distributedCall/servers)");
}
}
// cannot be determined, return null if no config/original url, else use config/original url as base
// use http or https as appropriate
return GetBaseUrl(appContext, settings);
}
/// <summary>
@@ -113,21 +127,5 @@ namespace Umbraco.Core.Sync
return CurrentServerEnvironmentStatus.Slave;
}
private static string GetBaseUrl(ApplicationContext appContext, IUmbracoSettingsSection settings)
{
return (
// is config empty?
settings.ScheduledTasks.BaseUrl.IsNullOrWhiteSpace()
// is the orig req empty?
? appContext.OriginalRequestUrl.IsNullOrWhiteSpace()
// we've got nothing
? null
//the orig req url is not null, use that
: string.Format("http{0}://{1}", GlobalSettings.UseSSL ? "s" : "", appContext.OriginalRequestUrl)
// the config has been specified, use that
: string.Format("http{0}://{1}", GlobalSettings.UseSSL ? "s" : "", settings.ScheduledTasks.BaseUrl))
.EnsureEndsWith('/');
}
}
}
+19 -7
View File
@@ -137,7 +137,7 @@ namespace Umbraco.Core
}
return _allAssemblies;
}
}
}
/// <summary>
@@ -226,7 +226,7 @@ namespace Umbraco.Core
}
return LocalFilteredAssemblyCache;
}
}
}
/// <summary>
@@ -451,7 +451,7 @@ namespace Umbraco.Core
var allTypes = GetTypesWithFormattedException(a)
.ToArray();
var attributedTypes = new Type[] {};
var attributedTypes = new Type[] { };
try
{
//now filter the types based on the onlyConcreteClasses flag, not interfaces, not static classes but have
@@ -480,7 +480,8 @@ namespace Umbraco.Core
//now we need to include types that may be inheriting from sub classes of the attribute type being searched for
//so we will search in assemblies that reference those types too.
foreach (var subTypesInAssembly in allAttributeTypes.GroupBy(x => x.Assembly)){
foreach (var subTypesInAssembly in allAttributeTypes.GroupBy(x => x.Assembly))
{
//So that we are not scanning too much, we need to group the sub types:
// * if there is more than 1 sub type in the same assembly then we should only search on the 'lowest base' type.
@@ -610,7 +611,7 @@ namespace Umbraco.Core
catch (TypeLoadException ex)
{
LogHelper.Error(typeof(TypeFinder), string.Format("Could not query types on {0} assembly, this is most likely due to this assembly not being compatible with the current Umbraco version", a), ex);
continue;
continue;
}
//add the types to our list to return
@@ -618,7 +619,7 @@ namespace Umbraco.Core
{
foundAssignableTypes.Add(t);
}
//now we need to include types that may be inheriting from sub classes of the type being searched for
//so we will search in assemblies that reference those types too.
foreach (var subTypesInAssembly in allSubTypes.GroupBy(x => x.Assembly))
@@ -699,7 +700,18 @@ namespace Umbraco.Core
#endregion
//TODO: This isn't very elegant, and will have issues since the AppDomain.CurrentDomain
// doesn't actualy load in all assemblies, only the types that have been referenced so far.
// However, in a web context, the BuildManager will have executed which will force all assemblies
// to be loaded so it's fine for now.
internal static Type GetTypeByName(string typeName)
{
var type = Type.GetType(typeName);
if (type != null) return type;
return AppDomain.CurrentDomain.GetAssemblies()
.Select(x => x.GetType(typeName))
.FirstOrDefault(x => x != null);
}
}
}
+8 -1
View File
@@ -64,7 +64,7 @@
</Reference>
<Reference Include="MySql.Data">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\MySql.Data.6.6.5\lib\net40\MySql.Data.dll</HintPath>
<HintPath>..\packages\MySql.Data.6.9.6\lib\net45\MySql.Data.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@@ -136,6 +136,7 @@
<Compile Include="ApplicationContext.cs" />
<Compile Include="ApplicationEventHandler.cs" />
<Compile Include="AssemblyExtensions.cs" />
<Compile Include="AsyncLock.cs" />
<Compile Include="Attempt{T}.cs" />
<Compile Include="Auditing\AuditTrail.cs" />
<Compile Include="Auditing\Audit.cs" />
@@ -311,9 +312,13 @@
<Compile Include="Events\SaveEventArgs.cs" />
<Compile Include="Events\SendToPublishEventArgs.cs" />
<Compile Include="Exceptions\InvalidCompositionException.cs" />
<Compile Include="Exceptions\UmbracoStartupFailedException.cs" />
<Compile Include="HideFromTypeFinderAttribute.cs" />
<Compile Include="HttpContextExtensions.cs" />
<Compile Include="IApplicationEventHandler.cs" />
<Compile Include="IDisposeOnRequestEnd.cs" />
<Compile Include="MainDom.cs" />
<Compile Include="Manifest\GridEditorConverter.cs" />
<Compile Include="Media\Exif\BitConverterEx.cs" />
<Compile Include="Media\Exif\ExifBitConverter.cs" />
<Compile Include="Media\Exif\ExifEnums.cs" />
@@ -1211,9 +1216,11 @@
<Compile Include="UriExtensions.cs" />
<Compile Include="SystemUtilities.cs" />
<Compile Include="UrlHelperExtensions.cs" />
<Compile Include="WaitHandleExtensions.cs" />
<Compile Include="WriteLock.cs" />
<Compile Include="XmlExtensions.cs" />
<Compile Include="XmlHelper.cs" />
<Compile Include="Xml\UmbracoXPathPathSyntaxParser.cs" />
<Compile Include="Xml\XPath\MacroNavigator.cs" />
<Compile Include="Xml\XPath\INavigableContentType.cs" />
<Compile Include="Xml\XPath\NavigableNavigator.cs" />
+47 -3
View File
@@ -36,6 +36,19 @@ namespace Umbraco.Core
//don't output the MVC version header (security)
MvcHandler.DisableMvcResponseHeader = true;
//take care of unhandled exceptions - there is nothing we can do to
// prevent the entire w3wp process to go down but at least we can try
// and log the exception
AppDomain.CurrentDomain.UnhandledException += (_, args) =>
{
var exception = (Exception) args.ExceptionObject;
var isTerminating = args.IsTerminating; // always true?
var msg = "Unhandled exception in AppDomain";
if (isTerminating) msg += " (terminating)";
LogHelper.Error<UmbracoApplicationBase>(msg, exception);
};
//boot up the application
GetBootManager()
.Initialize()
@@ -73,7 +86,18 @@ namespace Umbraco.Core
protected virtual void OnApplicationStarting(object sender, EventArgs e)
{
if (ApplicationStarting != null)
ApplicationStarting(sender, e);
{
try
{
ApplicationStarting(sender, e);
}
catch (Exception ex)
{
LogHelper.Error<UmbracoApplicationBase>("An error occurred in an ApplicationStarting event handler", ex);
throw;
}
}
}
/// <summary>
@@ -84,7 +108,17 @@ namespace Umbraco.Core
protected virtual void OnApplicationStarted(object sender, EventArgs e)
{
if (ApplicationStarted != null)
ApplicationStarted(sender, e);
{
try
{
ApplicationStarted(sender, e);
}
catch (Exception ex)
{
LogHelper.Error<UmbracoApplicationBase>("An error occurred in an ApplicationStarted event handler", ex);
throw;
}
}
}
/// <summary>
@@ -95,7 +129,17 @@ namespace Umbraco.Core
private void OnApplicationInit(object sender, EventArgs e)
{
if (ApplicationInit != null)
ApplicationInit(sender, e);
{
try
{
ApplicationInit(sender, e);
}
catch (Exception ex)
{
LogHelper.Error<UmbracoApplicationBase>("An error occurred in an ApplicationInit event handler", ex);
throw;
}
}
}
/// <summary>
+1 -1
View File
@@ -49,7 +49,7 @@ namespace Umbraco.Core
var urlPath = fullUrlPath.TrimStart(appPath).EnsureStartsWith('/');
//check if this is in the umbraco back office
var isUmbracoPath = urlPath.InvariantStartsWith(GlobalSettings.Path.EnsureStartsWith('/'));
var isUmbracoPath = urlPath.InvariantStartsWith(GlobalSettings.Path.EnsureStartsWith('/').TrimStart(appPath.EnsureStartsWith('/')).EnsureStartsWith('/'));
//if not, then def not back office
if (isUmbracoPath == false) return false;
+44
View File
@@ -0,0 +1,44 @@
using System.Threading;
using System.Threading.Tasks;
namespace Umbraco.Core
{
internal static class WaitHandleExtensions
{
// http://stackoverflow.com/questions/25382583/waiting-on-a-named-semaphore-with-waitone100-vs-waitone0-task-delay100
// http://blog.nerdbank.net/2011/07/c-await-for-waithandle.html
// F# has a AwaitWaitHandle method that accepts a time out... and seems pretty complex...
// version below should be OK
public static Task WaitOneAsync(this WaitHandle handle, int millisecondsTimeout = Timeout.Infinite)
{
var tcs = new TaskCompletionSource<object>();
var callbackHandleInitLock = new object();
lock (callbackHandleInitLock)
{
RegisteredWaitHandle callbackHandle = null;
// ReSharper disable once RedundantAssignment
callbackHandle = ThreadPool.RegisterWaitForSingleObject(
handle,
(state, timedOut) =>
{
tcs.SetResult(null);
// we take a lock here to make sure the outer method has completed setting the local variable callbackHandle.
lock (callbackHandleInitLock)
{
// ReSharper disable once PossibleNullReferenceException
// ReSharper disable once AccessToModifiedClosure
callbackHandle.Unregister(null);
}
},
/*state:*/ null,
/*millisecondsTimeOutInterval:*/ millisecondsTimeout,
/*executeOnlyOnce:*/ true);
}
return tcs.Task;
}
}
}
@@ -0,0 +1,117 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Umbraco.Core.Xml
{
/// <summary>
/// This is used to parse our customize Umbraco XPath expressions (i.e. that include special tokens like $site) into
/// a real XPath statement
/// </summary>
internal class UmbracoXPathPathSyntaxParser
{
/// <summary>
/// Parses custom umbraco xpath expression
/// </summary>
/// <param name="xpathExpression">The Xpath expression</param>
/// <param name="nodeContextId">
/// The current node id context of executing the query - null if there is no current node, in which case
/// some of the parameters like $current, $parent, $site will be disabled
/// </param>
/// <param name="getPath">The callback to create the nodeId path, given a node Id</param>
/// <param name="publishedContentExists">The callback to return whether a published node exists based on Id</param>
/// <returns></returns>
public static string ParseXPathQuery(
string xpathExpression,
int? nodeContextId,
Func<int, IEnumerable<string>> getPath,
Func<int, bool> publishedContentExists)
{
//TODO: This should probably support some of the old syntax and token replacements, currently
// it does not, there is a ticket raised here about it: http://issues.umbraco.org/issue/U4-6364
// previous tokens were: "$currentPage", "$ancestorOrSelf", "$parentPage" and I beleive they were
// allowed 'inline', not just at the beginning... whether or not we want to support that is up
// for discussion.
Mandate.ParameterNotNullOrEmpty(xpathExpression, "xpathExpression");
Mandate.ParameterNotNull(getPath, "getPath");
Mandate.ParameterNotNull(publishedContentExists, "publishedContentExists");
//no need to parse it
if (xpathExpression.StartsWith("$") == false)
return xpathExpression;
//get nearest published item
Func<IEnumerable<string>, int> getClosestPublishedAncestor = (path =>
{
foreach (var i in path)
{
int idAsInt;
if (int.TryParse(i, out idAsInt))
{
var exists = publishedContentExists(int.Parse(i));
if (exists)
return idAsInt;
}
}
return -1;
});
const string rootXpath = "descendant::*[@id={0}]";
//parseable items:
var vars = new Dictionary<string, Func<string, string>>();
//These parameters must have a node id context
if (nodeContextId.HasValue)
{
vars.Add("$current", q =>
{
var closestPublishedAncestorId = getClosestPublishedAncestor(getPath(nodeContextId.Value));
return q.Replace("$current", string.Format(rootXpath, closestPublishedAncestorId));
});
vars.Add("$parent", q =>
{
//remove the first item in the array if its the current node
//this happens when current is published, but we are looking for its parent specifically
var path = getPath(nodeContextId.Value).ToArray();
if (path[0] == nodeContextId.ToString())
{
path = path.Skip(1).ToArray();
}
var closestPublishedAncestorId = getClosestPublishedAncestor(path);
return q.Replace("$parent", string.Format(rootXpath, closestPublishedAncestorId));
});
vars.Add("$site", q =>
{
var closestPublishedAncestorId = getClosestPublishedAncestor(getPath(nodeContextId.Value));
return q.Replace("$site", string.Format(rootXpath, closestPublishedAncestorId) + "/ancestor-or-self::*[@level = 1]");
});
}
//TODO: This used to just replace $root with string.Empty BUT, that would never work
// the root is always "/root . Need to confirm with Per why this was string.Empty before!
vars.Add("$root", q => q.Replace("$root", "/root"));
foreach (var varible in vars)
{
if (xpathExpression.StartsWith(varible.Key))
{
xpathExpression = varible.Value(xpathExpression);
break;
}
}
return xpathExpression;
}
}
}
+28
View File
@@ -1,6 +1,9 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;
@@ -13,6 +16,31 @@ namespace Umbraco.Core
/// </summary>
internal static class XmlExtensions
{
/// <summary>
/// Saves the xml document async
/// </summary>
/// <param name="xdoc"></param>
/// <param name="filename"></param>
/// <returns></returns>
public static async Task SaveAsync(this XmlDocument xdoc, string filename)
{
if (xdoc.DocumentElement == null)
throw new XmlException("Cannot save xml document, there is no root element");
using (var fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.Read, bufferSize: 4096, useAsync: true))
using (var xmlWriter = XmlWriter.Create(fs, new XmlWriterSettings
{
Async = true,
Encoding = Encoding.UTF8,
Indent = true
}))
{
//NOTE: There are no nice methods to write it async, only flushing it async. We
// could implement this ourselves but it'd be a very manual process.
xdoc.WriteTo(xmlWriter);
await xmlWriter.FlushAsync().ConfigureAwait(false);
}
}
public static bool HasAttribute(this XmlAttributeCollection attributes, string attributeName)
{
+16 -16
View File
@@ -1,19 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AutoMapper" version="3.0.0" targetFramework="net45" />
<package id="HtmlAgilityPack" version="1.4.6" targetFramework="net45" />
<package id="log4net-mediumtrust" version="2.0.0" targetFramework="net40" />
<package id="Microsoft.AspNet.Mvc" version="4.0.30506.0" targetFramework="net40" />
<package id="Microsoft.AspNet.Razor" version="2.0.30506.0" targetFramework="net40" />
<package id="Microsoft.AspNet.WebApi.Client" version="4.0.30506.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="2.0.30506.0" targetFramework="net40" />
<package id="Microsoft.Bcl" version="1.1.9" targetFramework="net45" />
<package id="Microsoft.Bcl.Build" version="1.0.14" targetFramework="net45" />
<package id="Microsoft.Net.Http" version="2.2.22" targetFramework="net45" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net40" />
<package id="MiniProfiler" version="2.1.0" targetFramework="net45" />
<package id="MySql.Data" version="6.6.5" targetFramework="net40" />
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net45" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net40" />
<package id="SqlServerCE" version="4.0.0.0" targetFramework="net40" />
<package id="AutoMapper" version="3.0.0" targetFramework="net45" userInstalled="true" />
<package id="HtmlAgilityPack" version="1.4.6" targetFramework="net45" userInstalled="true" />
<package id="log4net-mediumtrust" version="2.0.0" targetFramework="net4" userInstalled="true" />
<package id="Microsoft.AspNet.Mvc" version="4.0.30506.0" targetFramework="net4" userInstalled="true" />
<package id="Microsoft.AspNet.Razor" version="2.0.30506.0" targetFramework="net4" userInstalled="true" />
<package id="Microsoft.AspNet.WebApi.Client" version="4.0.30506.0" targetFramework="net45" userInstalled="true" />
<package id="Microsoft.AspNet.WebPages" version="2.0.30506.0" targetFramework="net4" userInstalled="true" />
<package id="Microsoft.Bcl" version="1.1.9" targetFramework="net45" userInstalled="true" />
<package id="Microsoft.Bcl.Build" version="1.0.14" targetFramework="net45" userInstalled="true" />
<package id="Microsoft.Net.Http" version="2.2.22" targetFramework="net45" userInstalled="true" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net4" userInstalled="true" />
<package id="MiniProfiler" version="2.1.0" targetFramework="net45" userInstalled="true" />
<package id="MySql.Data" version="6.9.6" targetFramework="net45" userInstalled="true" />
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net45" userInstalled="true" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net4" userInstalled="true" />
<package id="SqlServerCE" version="4.0.0.0" targetFramework="net4" userInstalled="true" />
</packages>
+79 -1
View File
@@ -1,4 +1,5 @@
using System.Linq;
using System;
using System.Linq;
using System.Web.UI;
using NUnit.Framework;
using Umbraco.Core.Cache;
@@ -21,6 +22,83 @@ namespace Umbraco.Tests.Cache
public virtual void TearDown()
{
Provider.ClearAllCache();
}
[Test]
public void Throws_On_Reentry()
{
// don't run for StaticCacheProvider - not making sense
if (GetType() == typeof (StaticCacheProviderTests))
Assert.Ignore("Do not run for StaticCacheProvider.");
Exception exception = null;
var result = Provider.GetCacheItem("blah", () =>
{
try
{
var result2 = Provider.GetCacheItem("blah");
}
catch (Exception e)
{
exception = e;
}
return "value";
});
Assert.IsNotNull(exception);
Assert.IsAssignableFrom<InvalidOperationException>(exception);
}
[Test]
public void Does_Not_Cache_Exceptions()
{
var counter = 0;
object result;
try
{
result = Provider.GetCacheItem("Blah", () =>
{
counter++;
throw new Exception("Do not cache this");
});
}
catch (Exception){}
try
{
result = Provider.GetCacheItem("Blah", () =>
{
counter++;
throw new Exception("Do not cache this");
});
}
catch (Exception){}
Assert.Greater(counter, 1);
}
[Test]
public void Ensures_Delegate_Result_Is_Cached_Once()
{
var counter = 0;
object result;
result = Provider.GetCacheItem("Blah", () =>
{
counter++;
return "";
});
result = Provider.GetCacheItem("Blah", () =>
{
counter++;
return "";
});
Assert.AreEqual(counter, 1);
}
[Test]
@@ -1,4 +1,5 @@
using System.Web;
using System;
using System.Web;
using NUnit.Framework;
using Umbraco.Core.Cache;
@@ -29,5 +30,29 @@ namespace Umbraco.Tests.Cache
{
get { return _provider; }
}
[Test]
public void DoesNotCacheExceptions()
{
string value;
Assert.Throws<Exception>(() => { value = (string)_provider.GetCacheItem("key", () => GetValue(1)); });
Assert.Throws<Exception>(() => { value = (string)_provider.GetCacheItem("key", () => GetValue(2)); });
// does not throw
value = (string)_provider.GetCacheItem("key", () => GetValue(3));
Assert.AreEqual("succ3", value);
// cache
value = (string)_provider.GetCacheItem("key", () => GetValue(4));
Assert.AreEqual("succ3", value);
}
private static string GetValue(int i)
{
Console.WriteLine("get" + i);
if (i < 3)
throw new Exception("fail");
return "succ" + i;
}
}
}
@@ -108,12 +108,11 @@ namespace Umbraco.Tests.CodeFirst.Definitions
//Check if a PropertyType with the same alias already exists, as we don't want to override existing ones
if(group.PropertyTypes.Contains(definition.Alias)) continue;
var propertyType = new PropertyType(definition.DataTypeDefinition)
var propertyType = new PropertyType(definition.DataTypeDefinition, definition.Alias)
{
Mandatory = definition.Mandatory,
ValidationRegExp = definition.ValidationRegExp,
SortOrder = definition.Order,
Alias = definition.Alias,
Name = definition.Name
};
@@ -28,10 +28,16 @@ namespace Umbraco.Tests.Configurations.UmbracoSettings
Assert.IsTrue(SettingsSection.Content.Error404Collection.Count() == 3);
Assert.IsTrue(SettingsSection.Content.Error404Collection.ElementAt(0).Culture == "default");
Assert.IsTrue(SettingsSection.Content.Error404Collection.ElementAt(0).ContentId == 1047);
Assert.IsTrue(SettingsSection.Content.Error404Collection.ElementAt(0).HasContentId);
Assert.IsFalse(SettingsSection.Content.Error404Collection.ElementAt(0).HasContentKey);
Assert.IsTrue(SettingsSection.Content.Error404Collection.ElementAt(1).Culture == "en-US");
Assert.IsTrue(SettingsSection.Content.Error404Collection.ElementAt(1).ContentId == 1048);
Assert.IsTrue(SettingsSection.Content.Error404Collection.ElementAt(1).ContentXPath == "$site/error [@name = 'error']");
Assert.IsFalse(SettingsSection.Content.Error404Collection.ElementAt(1).HasContentId);
Assert.IsFalse(SettingsSection.Content.Error404Collection.ElementAt(1).HasContentKey);
Assert.IsTrue(SettingsSection.Content.Error404Collection.ElementAt(2).Culture == "en-UK");
Assert.IsTrue(SettingsSection.Content.Error404Collection.ElementAt(2).ContentId == 1049);
Assert.IsTrue(SettingsSection.Content.Error404Collection.ElementAt(2).ContentKey == new Guid("8560867F-B88F-4C74-A9A4-679D8E5B3BFC"));
Assert.IsTrue(SettingsSection.Content.Error404Collection.ElementAt(2).HasContentKey);
Assert.IsFalse(SettingsSection.Content.Error404Collection.ElementAt(2).HasContentId);
}
[Test]
@@ -17,5 +17,16 @@ namespace Umbraco.Tests.Configurations.UmbracoSettings
Assert.IsTrue(SettingsSection.WebRouting.UrlProviderMode == "AutoLegacy");
}
[Test]
public void DisableAlternativeTemplates()
{
Assert.IsTrue(SettingsSection.WebRouting.DisableAlternativeTemplates == false);
}
[Test]
public void DisableFindContentByIdPath()
{
Assert.IsTrue(SettingsSection.WebRouting.DisableFindContentByIdPath == false);
}
}
}
@@ -42,8 +42,8 @@
</error404>-->
<error404>
<errorPage culture="default">1047</errorPage>
<errorPage culture="en-US">1048</errorPage>
<errorPage culture="en-UK">1049</errorPage>
<errorPage culture="en-US">$site/error [@name = 'error']</errorPage>
<errorPage culture="en-UK">8560867F-B88F-4C74-A9A4-679D8E5B3BFC</errorPage>
</error404>
<!--<error404>1</error404>-->
</errors>
@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;
using umbraco.cms.businesslogic.language;
using umbraco.cms.businesslogic.web;
using Umbraco.Tests.Services;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
using Umbraco.Web.Routing;
namespace Umbraco.Tests.Integration
{
[DatabaseTestBehavior(DatabaseBehavior.NewDbFileAndSchemaPerTest)]
[TestFixture, RequiresSTA]
public class GetCultureTests : BaseServiceTest
{
protected override void FreezeResolution()
{
SiteDomainHelperResolver.Current = new SiteDomainHelperResolver(new SiteDomainHelper());
base.FreezeResolution();
}
[Test]
public void GetCulture()
{
var contentTypeService = ServiceContext.ContentTypeService;
var contentType = MockedContentTypes.CreateSimpleContentType("umbBlah", "test Doc Type");
contentTypeService.Save(contentType);
var contentService = ServiceContext.ContentService;
var c1 = contentService.CreateContentWithIdentity("content", -1, "umbBlah");
var c2 = contentService.CreateContentWithIdentity("content", c1, "umbBlah");
var c3 = contentService.CreateContentWithIdentity("content", c1, "umbBlah");
var c4 = contentService.CreateContentWithIdentity("content", c3, "umbBlah");
var langs = Language.GetAllAsList();
foreach (var l in langs.Skip(1))
l.Delete();
Language.MakeNew("fr-FR");
Language.MakeNew("de-DE");
var langEn = Language.GetByCultureCode("en-US");
var langFr = Language.GetByCultureCode("fr-FR");
var langDe = Language.GetByCultureCode("de-DE");
var domains = Domain.GetDomains(true); // we want wildcards too here
foreach (var d in domains)
d.Delete();
Domain.MakeNew("domain1.com/", c1.Id, langEn.id);
Domain.MakeNew("domain1.fr/", c1.Id, langFr.id);
Domain.MakeNew("*100112", c3.Id, langDe.id);
var content = c2;
var culture = Web.Models.ContentExtensions.GetCulture(null, ServiceContext.LocalizationService, ServiceContext.ContentService, content.Id, content.Path,
new Uri("http://domain1.com/"));
Assert.AreEqual("en-US", culture.Name);
content = c2;
culture = Web.Models.ContentExtensions.GetCulture(null, ServiceContext.LocalizationService, ServiceContext.ContentService, content.Id, content.Path,
new Uri("http://domain1.fr/"));
Assert.AreEqual("fr-FR", culture.Name);
content = c4;
culture = Web.Models.ContentExtensions.GetCulture(null, ServiceContext.LocalizationService, ServiceContext.ContentService, content.Id, content.Path,
new Uri("http://domain1.fr/"));
Assert.AreEqual("de-DE", culture.Name);
}
}
}
@@ -109,6 +109,29 @@ namespace Umbraco.Tests.Macros
<p>asdfasdf</p>".Replace(Environment.NewLine, string.Empty), result.Replace(Environment.NewLine, string.Empty));
}
[Test]
public void Format_RTE_Data_For_Editor_With_Params_When_MacroAlias_Not_First()
{
var content = @"<p>asdfasdf</p>
<p>asdfsadf</p>
<?UMBRACO_MACRO test1=""value1"" test2=""value2"" macroAlias=""Map"" />
<p>asdfasdf</p>";
var result = MacroTagParser.FormatRichTextPersistedDataForEditor(content, new Dictionary<string, string>() { { "test1", "value1" }, { "test2", "value2" } });
// Assert.AreEqual(@"<p>asdfasdf</p>
//<p>asdfsadf</p>
//<div class=""umb-macro-holder Map mceNonEditable"" test1=""value1"" test2=""value2"">
//<!-- <?UMBRACO_MACRO macroAlias=""Map"" test1=""value1"" test2=""value2"" /> -->
//<ins>Macro alias: <strong>Map</strong></ins></div>
//<p>asdfasdf</p>".Replace(Environment.NewLine, string.Empty), result.Replace(Environment.NewLine, string.Empty));
Assert.AreEqual(@"<p>asdfasdf</p>
<p>asdfsadf</p>
<div class=""umb-macro-holder mceNonEditable"" test1=""value1"" test2=""value2"">
<!-- <?UMBRACO_MACRO test1=""value1"" test2=""value2"" macroAlias=""Map"" /> -->
<ins>Macro alias: <strong>Map</strong></ins></div>
<p>asdfasdf</p>".Replace(Environment.NewLine, string.Empty), result.Replace(Environment.NewLine, string.Empty));
}
[Test]
public void Format_RTE_Data_For_Editor_With_Params_Closing_Tag()
{
@@ -77,7 +77,7 @@ namespace Umbraco.Tests.Manifest
alias: 'Test.Test2',
name: 'Test 2',
config: { key1: 'some default val' },
view: '/hello/world.cshtml',
view: '~/hello/world.cshtml',
icon: 'helloworld'
},
{
@@ -85,7 +85,7 @@ namespace Umbraco.Tests.Manifest
name: 'Test 3',
config: { key1: 'some default val' },
view: '/hello/world.html',
render: '/hello/world.cshtml',
render: '~/hello/world.cshtml',
icon: 'helloworld'
}
]");
@@ -314,6 +314,105 @@ namespace Umbraco.Tests.Manifest
//}
[Test]
public void Create_Manifests_Editors()
{
var package1 = @"{
propertyEditors: [],
javascript: ['~/test.js', '~/test2.js']}";
var package2 = "{css: ['~/style.css', '~/folder-name/sdsdsd/stylesheet.css']}";
var package3 = @"{
'javascript': [ ],
'css': [ ],
'gridEditors': [
{
'name': 'Small Hero',
'alias': 'small-hero',
'view': '/App_Plugins/MyPlugin/small-hero/editortemplate.html',
'render': '/Views/Partials/Grid/Editors/SmallHero.cshtml',
'icon': 'icon-presentation',
'config': {
'image': {
'size': {
'width': 1200,
'height': 185
}
},
'link': {
'maxNumberOfItems': 1,
'minNumberOfItems': 0
}
}
},
{
'name': 'Document Links By Category',
'alias': 'document-links-by-category',
'view': '/App_Plugins/MyPlugin/document-links-by-category/editortemplate.html',
'render': '/Views/Partials/Grid/Editors/DocumentLinksByCategory.cshtml',
'icon': 'icon-umb-members'
}
]
}";
var package4 = @"{'propertyEditors': [
{
alias: 'Test.Test1',
name: 'Test 1',
editor: {
view: '~/App_Plugins/MyPackage/PropertyEditors/MyEditor.html',
valueType: 'int',
validation: {
'required': true,
'Regex': '\\d*'
}
},
prevalues: {
fields: [
{
label: 'Some config 1',
key: 'key1',
view: '~/App_Plugins/MyPackage/PropertyEditors/Views/pre-val1.html',
validation: {
required: true
}
},
{
label: 'Some config 2',
key: 'key2',
view: '~/App_Plugins/MyPackage/PropertyEditors/Views/pre-val2.html'
}
]
}
}
]}";
var package5 = @"{'parameterEditors': [
{
alias: 'parameter1',
name: 'My Parameter',
view: '~/App_Plugins/MyPackage/PropertyEditors/MyEditor.html'
},
{
alias: 'parameter2',
name: 'Another parameter',
config: { key1: 'some config val' },
view: '~/App_Plugins/MyPackage/PropertyEditors/CsvEditor.html'
}
]}";
var result = ManifestParser.CreateManifests(package1, package2, package3, package4, package5).ToArray();
var paramEditors = result.SelectMany(x => ManifestParser.GetParameterEditors(x.ParameterEditors)).ToArray();
var propEditors = result.SelectMany(x => ManifestParser.GetPropertyEditors(x.PropertyEditors)).ToArray();
var gridEditors = result.SelectMany(x => ManifestParser.GetGridEditors(x.GridEditors)).ToArray();
Assert.AreEqual(2, gridEditors.Count());
Assert.AreEqual(2, paramEditors.Count());
Assert.AreEqual(1, propEditors.Count());
}
[Test]
public void Create_Manifest_With_Line_Comments()
{
@@ -42,14 +42,14 @@ namespace Umbraco.Tests.Migrations.Upgrades
"tags1", "tags1",
new PropertyTypeCollection(new[]
{
new PropertyType("test", DataTypeDatabaseType.Ntext) {Alias = "tags1", Name = "tags1", SortOrder = 1, DataTypeDefinitionId = 1041},
new PropertyType("test", DataTypeDatabaseType.Ntext, "tags1") {Name = "tags1", SortOrder = 1, DataTypeDefinitionId = 1041},
}));
var contentTypeWith2Tags = MockedContentTypes.CreateSimpleContentType(
"tags2", "tags2",
new PropertyTypeCollection(new[]
{
new PropertyType("test", DataTypeDatabaseType.Ntext) {Alias = "tags1", Name = "tags1", SortOrder = 1, DataTypeDefinitionId = 1041},
new PropertyType("test", DataTypeDatabaseType.Ntext) {Alias = "tags2", Name = "tags2", SortOrder = 1, DataTypeDefinitionId = 1041}
new PropertyType("test", DataTypeDatabaseType.Ntext, "tags1") {Name = "tags1", SortOrder = 1, DataTypeDefinitionId = 1041},
new PropertyType("test", DataTypeDatabaseType.Ntext, "tags2") {Name = "tags2", SortOrder = 1, DataTypeDefinitionId = 1041}
}));
contentTypeRepository.AddOrUpdate(contentTypeWith1Tag);
@@ -11,6 +11,27 @@ namespace Umbraco.Tests.Models.Collections
[TestFixture]
public class PropertyCollectionTests : BaseUmbracoConfigurationTest
{
[Test]
public void Property_Adds_Case_Insensitive_Compare()
{
var collection = new PropertyCollection();
collection.Add(new Property(new PropertyType("propEditor", DataTypeDatabaseType.Nvarchar, "test")));
collection.Add(new Property(new PropertyType("propEditor", DataTypeDatabaseType.Nvarchar, "Test")));
Assert.AreEqual(1, collection.Count);
}
[Test]
public void Property_Contains_Case_Insensitive_Compare()
{
var collection = new PropertyCollection();
collection.Add(new Property(new PropertyType("propEditor", DataTypeDatabaseType.Nvarchar, "test")));
Assert.IsTrue(collection.Contains("Test"));
}
[Test]
public void SimpleOrder_Returns_Null_On_FirstOrDefault_When_Empty()
{
+45 -21
View File
@@ -63,8 +63,8 @@ namespace Umbraco.Tests.Models
{
var contentType = MockedContentTypes.CreateSimpleContentType();
//add non-grouped properties
contentType.AddPropertyType(new PropertyType("test", DataTypeDatabaseType.Ntext) { Alias = "nonGrouped1", Name = "Non Grouped 1", Description = "", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -88 });
contentType.AddPropertyType(new PropertyType("test", DataTypeDatabaseType.Ntext) { Alias = "nonGrouped2", Name = "Non Grouped 2", Description = "", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -88 });
contentType.AddPropertyType(new PropertyType("test", DataTypeDatabaseType.Ntext, "nonGrouped1") { Name = "Non Grouped 1", Description = "", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -88 });
contentType.AddPropertyType(new PropertyType("test", DataTypeDatabaseType.Ntext, "nonGrouped2") { Name = "Non Grouped 2", Description = "", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -88 });
//ensure that nothing is marked as dirty
contentType.ResetDirtyProperties(false);
@@ -337,7 +337,7 @@ namespace Umbraco.Tests.Models
var asDirty = (ICanBeDirty)clone;
Assert.IsFalse(asDirty.IsPropertyDirty("Properties"));
clone.Properties.Add(new Property(1, Guid.NewGuid(), new PropertyType("test", DataTypeDatabaseType.Ntext) {Alias = "blah"}, "blah"));
clone.Properties.Add(new Property(1, Guid.NewGuid(), new PropertyType("test", DataTypeDatabaseType.Ntext, "blah"), "blah"));
Assert.IsTrue(asDirty.IsPropertyDirty("Properties"));
}
@@ -476,9 +476,8 @@ namespace Umbraco.Tests.Models
var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1);
// Act
contentType.PropertyGroups["Content"].PropertyTypes.Add(new PropertyType("test", DataTypeDatabaseType.Ntext)
contentType.PropertyGroups["Content"].PropertyTypes.Add(new PropertyType("test", DataTypeDatabaseType.Ntext, "subtitle")
{
Alias = "subtitle",
Name = "Subtitle",
Description = "Optional subtitle",
HelpText = "",
@@ -500,9 +499,9 @@ namespace Umbraco.Tests.Models
var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1);
// Act
var propertyType = new PropertyType("test", DataTypeDatabaseType.Ntext)
var propertyType = new PropertyType("test", DataTypeDatabaseType.Ntext, "subtitle")
{
Alias = "subtitle", Name = "Subtitle", Description = "Optional subtitle", HelpText = "", Mandatory = false, SortOrder = 3, DataTypeDefinitionId = -88
Name = "Subtitle", Description = "Optional subtitle", HelpText = "", Mandatory = false, SortOrder = 3, DataTypeDefinitionId = -88
};
contentType.PropertyGroups["Content"].PropertyTypes.Add(propertyType);
content.Properties.Add(new Property(propertyType){Value = "This is a subtitle Test"});
@@ -520,9 +519,8 @@ namespace Umbraco.Tests.Models
var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1);
// Act
var propertyType = new PropertyType("test", DataTypeDatabaseType.Ntext)
var propertyType = new PropertyType("test", DataTypeDatabaseType.Ntext, "subtitle")
{
Alias = "subtitle",
Name = "Subtitle",
Description = "Optional subtitle",
HelpText = "",
@@ -551,9 +549,9 @@ namespace Umbraco.Tests.Models
var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1);
// Act - note that the PropertyType's properties like SortOrder is not updated through the Content object
var propertyType = new PropertyType("test", DataTypeDatabaseType.Ntext)
var propertyType = new PropertyType("test", DataTypeDatabaseType.Ntext, "title")
{
Alias = "title", Name = "Title", Description = "Title description added", HelpText = "", Mandatory = false, SortOrder = 10, DataTypeDefinitionId = -88
Name = "Title", Description = "Title description added", HelpText = "", Mandatory = false, SortOrder = 10, DataTypeDefinitionId = -88
};
content.Properties.Add(new Property(propertyType));
@@ -703,6 +701,37 @@ namespace Umbraco.Tests.Models
Assert.That(contentType.WasPropertyDirty("Alias"), Is.True);
}
[Test]
public void After_Committing_Changes_Was_Dirty_Is_True_On_Changed_Property()
{
// Arrange
var contentType = MockedContentTypes.CreateTextpageContentType();
contentType.ResetDirtyProperties(); //reset
var content = MockedContent.CreateTextpageContent(contentType, "test", -1);
content.ResetDirtyProperties();
// Act
content.SetPropertyValue("title", "new title");
Assert.That(content.IsEntityDirty(), Is.False);
Assert.That(content.IsDirty(), Is.True);
Assert.That(content.IsPropertyDirty("title"), Is.True);
Assert.That(content.IsAnyUserPropertyDirty(), Is.True);
Assert.That(content.GetDirtyUserProperties().Count(), Is.EqualTo(1));
Assert.That(content.Properties[0].IsDirty(), Is.True);
Assert.That(content.Properties["title"].IsDirty(), Is.True);
content.ResetDirtyProperties(); //this would be like committing the entity
// Assert
Assert.That(content.WasDirty(), Is.True);
Assert.That(content.Properties[0].WasDirty(), Is.True);
Assert.That(content.WasPropertyDirty("title"), Is.True);
Assert.That(content.Properties["title"].IsDirty(), Is.False);
Assert.That(content.Properties["title"].WasDirty(), Is.True);
}
[Test]
public void If_Not_Committed_Was_Dirty_Is_False()
{
@@ -739,9 +768,8 @@ namespace Umbraco.Tests.Models
contentType.ResetDirtyProperties();
// Act
var propertyType = new PropertyType("test", DataTypeDatabaseType.Ntext)
var propertyType = new PropertyType("test", DataTypeDatabaseType.Ntext, "subtitle")
{
Alias = "subtitle",
Name = "Subtitle",
Description = "Optional subtitle",
HelpText = "",
@@ -766,9 +794,8 @@ namespace Umbraco.Tests.Models
new PropertyTypeCollection(
new List<PropertyType>
{
new PropertyType("test", DataTypeDatabaseType.Ntext)
new PropertyType("test", DataTypeDatabaseType.Ntext, "coauthor")
{
Alias = "coauthor",
Name = "Co-Author",
Description = "Name of the Co-Author",
HelpText = "",
@@ -799,9 +826,8 @@ namespace Umbraco.Tests.Models
new PropertyTypeCollection(
new List<PropertyType>
{
new PropertyType("test", DataTypeDatabaseType.Ntext)
new PropertyType("test", DataTypeDatabaseType.Ntext, "coauthor")
{
Alias = "coauthor",
Name = "Co-Author",
Description = "Name of the Co-Author",
HelpText = "",
@@ -834,9 +860,8 @@ namespace Umbraco.Tests.Models
var mixin1 = MockedContentTypes.CreateSimpleContentType("mixin1", "Mixin1", new PropertyTypeCollection(
new List<PropertyType>
{
new PropertyType("test", DataTypeDatabaseType.Ntext)
new PropertyType("test", DataTypeDatabaseType.Ntext, "coauthor")
{
Alias = "coauthor",
Name = "Co-Author",
Description = "Name of the Co-Author",
HelpText = "",
@@ -848,9 +873,8 @@ namespace Umbraco.Tests.Models
var mixin2 = MockedContentTypes.CreateSimpleContentType("mixin2", "Mixin2", new PropertyTypeCollection(
new List<PropertyType>
{
new PropertyType("test", DataTypeDatabaseType.Ntext)
new PropertyType("test", DataTypeDatabaseType.Ntext, "author")
{
Alias = "author",
Name = "Author",
Description = "Name of the Author",
HelpText = "",
+2 -2
View File
@@ -45,7 +45,7 @@ namespace Umbraco.Tests.Models
}
//add a property type without a property group
contentType.PropertyTypeCollection.Add(
new PropertyType("test", DataTypeDatabaseType.Ntext) { Alias = "title2", Name = "Title2", Description = "", HelpText = "", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -88 });
new PropertyType("test", DataTypeDatabaseType.Ntext, "title2") { Name = "Title2", Description = "", HelpText = "", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -88 });
contentType.AllowedTemplates = new[] { new Template("-1,2", "Name", "name") { Id = 200 }, new Template("-1,3", "Name2", "name2") { Id = 201 } };
contentType.AllowedContentTypes = new[] { new ContentTypeSort(new Lazy<int>(() => 888), 8, "sub"), new ContentTypeSort(new Lazy<int>(() => 889), 9, "sub2") };
@@ -239,7 +239,7 @@ namespace Umbraco.Tests.Models
var asDirty = (ICanBeDirty)clone;
Assert.IsFalse(asDirty.IsPropertyDirty("PropertyTypes"));
clone.AddPropertyType(new PropertyType("test", DataTypeDatabaseType.Nvarchar) { Alias = "blah" });
clone.AddPropertyType(new PropertyType("test", DataTypeDatabaseType.Nvarchar, "blah"));
Assert.IsTrue(asDirty.IsPropertyDirty("PropertyTypes"));
Assert.IsFalse(asDirty.IsPropertyDirty("PropertyGroups"));
clone.AddPropertyGroup("hello");
@@ -132,8 +132,8 @@ namespace Umbraco.Tests.Models.Mapping
var idSeed = 1;
var contentType = MockedContentTypes.CreateSimpleContentType();
//add non-grouped properties
contentType.AddPropertyType(new PropertyType(Constants.PropertyEditors.TextboxAlias, DataTypeDatabaseType.Ntext) { Alias = "nonGrouped1", Name = "Non Grouped 1", Description = "", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -88 });
contentType.AddPropertyType(new PropertyType(Constants.PropertyEditors.TextboxAlias, DataTypeDatabaseType.Ntext) { Alias = "nonGrouped2", Name = "Non Grouped 2", Description = "", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -88 });
contentType.AddPropertyType(new PropertyType(Constants.PropertyEditors.TextboxAlias, DataTypeDatabaseType.Ntext, "nonGrouped1") { Name = "Non Grouped 1", Description = "", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -88 });
contentType.AddPropertyType(new PropertyType(Constants.PropertyEditors.TextboxAlias, DataTypeDatabaseType.Ntext, "nonGrouped2") { Name = "Non Grouped 2", Description = "", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -88 });
//set ids or it wont work
contentType.Id = idSeed;
foreach (var p in contentType.PropertyTypes)
@@ -15,10 +15,9 @@ namespace Umbraco.Tests.Models
var pg = new PropertyGroup(
new PropertyTypeCollection(new[]
{
new PropertyType("TestPropertyEditor", DataTypeDatabaseType.Nvarchar)
new PropertyType("TestPropertyEditor", DataTypeDatabaseType.Nvarchar, "test")
{
Id = 3,
Alias = "test",
CreateDate = DateTime.Now,
DataTypeDefinitionId = 5,
PropertyEditorAlias = "propTest",
@@ -32,10 +31,9 @@ namespace Umbraco.Tests.Models
ValidationRegExp = "xxxx",
DataTypeDatabaseType = DataTypeDatabaseType.Nvarchar
},
new PropertyType("TestPropertyEditor", DataTypeDatabaseType.Nvarchar)
new PropertyType("TestPropertyEditor", DataTypeDatabaseType.Nvarchar, "test2")
{
Id = 4,
Alias = "test2",
CreateDate = DateTime.Now,
DataTypeDefinitionId = 6,
PropertyEditorAlias = "propTest",
@@ -96,10 +94,9 @@ namespace Umbraco.Tests.Models
var pg = new PropertyGroup(
new PropertyTypeCollection(new[]
{
new PropertyType("TestPropertyEditor", DataTypeDatabaseType.Nvarchar)
new PropertyType("TestPropertyEditor", DataTypeDatabaseType.Nvarchar, "test")
{
Id = 3,
Alias = "test",
CreateDate = DateTime.Now,
DataTypeDefinitionId = 5,
PropertyEditorAlias = "propTest",
@@ -113,10 +110,9 @@ namespace Umbraco.Tests.Models
ValidationRegExp = "xxxx",
DataTypeDatabaseType = DataTypeDatabaseType.Nvarchar
},
new PropertyType("TestPropertyEditor2", DataTypeDatabaseType.Nvarchar)
new PropertyType("TestPropertyEditor2", DataTypeDatabaseType.Nvarchar, "test2")
{
Id = 4,
Alias = "test2",
CreateDate = DateTime.Now,
DataTypeDefinitionId = 6,
PropertyEditorAlias = "propTest",
@@ -12,10 +12,9 @@ namespace Umbraco.Tests.Models
[Test]
public void Can_Deep_Clone()
{
var pt = new PropertyType("TestPropertyEditor", DataTypeDatabaseType.Nvarchar)
var pt = new PropertyType("TestPropertyEditor", DataTypeDatabaseType.Nvarchar, "test")
{
Id = 3,
Alias = "test",
CreateDate = DateTime.Now,
DataTypeDefinitionId = 5,
PropertyEditorAlias = "propTest",
@@ -62,10 +61,9 @@ namespace Umbraco.Tests.Models
{
var ss = new SerializationService(new JsonNetSerializer());
var pt = new PropertyType("TestPropertyEditor", DataTypeDatabaseType.Nvarchar)
var pt = new PropertyType("TestPropertyEditor", DataTypeDatabaseType.Nvarchar, "test")
{
Id = 3,
Alias = "test",
CreateDate = DateTime.Now,
DataTypeDefinitionId = 5,
PropertyEditorAlias = "propTest",
@@ -176,9 +176,8 @@ namespace Umbraco.Tests.Persistence
}
contentType = MockedContentTypes.CreateSimpleContentType("umbMandatory" + Guid.NewGuid().ToString("N"), "Mandatory Doc Type", true);
contentType.PropertyGroups.First().PropertyTypes.Add(
new PropertyType("test", DataTypeDatabaseType.Ntext)
new PropertyType("test", DataTypeDatabaseType.Ntext, "tags")
{
Alias = "tags",
DataTypeDefinitionId = 1041
});
contentTypeService.Save(contentType);
@@ -135,9 +135,8 @@ namespace Umbraco.Tests.Persistence.Repositories
var contentType = repository.Get(NodeDto.NodeIdSeed + 1);
contentType.Thumbnail = "Doc2.png";
contentType.PropertyGroups["Content"].PropertyTypes.Add(new PropertyType("test", DataTypeDatabaseType.Ntext)
contentType.PropertyGroups["Content"].PropertyTypes.Add(new PropertyType("test", DataTypeDatabaseType.Ntext, "subtitle")
{
Alias = "subtitle",
Name = "Subtitle",
Description = "Optional Subtitle",
HelpText = "",
@@ -342,9 +341,8 @@ namespace Umbraco.Tests.Persistence.Repositories
var contentType = repository.Get(NodeDto.NodeIdSeed + 1);
// Act
var urlAlias = new PropertyType("test", DataTypeDatabaseType.Nvarchar)
var urlAlias = new PropertyType("test", DataTypeDatabaseType.Nvarchar, "urlAlias")
{
Alias = "urlAlias",
Name = "Url Alias",
Description = "",
HelpText = "",
@@ -445,7 +443,7 @@ namespace Umbraco.Tests.Persistence.Repositories
// Act
var propertyGroup = contentType.PropertyGroups.First(x => x.Name == "Meta");
propertyGroup.PropertyTypes.Add(new PropertyType("test", DataTypeDatabaseType.Ntext) { Alias = "metaAuthor", Name = "Meta Author", Description = "", HelpText = "", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -88 });
propertyGroup.PropertyTypes.Add(new PropertyType("test", DataTypeDatabaseType.Ntext, "metaAuthor") { Name = "Meta Author", Description = "", HelpText = "", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -88 });
repository.AddOrUpdate(contentType);
unitOfWork.Commit();
@@ -472,7 +470,7 @@ namespace Umbraco.Tests.Persistence.Repositories
unitOfWork.Commit();
var propertyGroup = contentType.PropertyGroups.First(x => x.Name == "Meta");
propertyGroup.PropertyTypes.Add(new PropertyType("test", DataTypeDatabaseType.Ntext) { Alias = "metaAuthor", Name = "Meta Author", Description = "", HelpText = "", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -88 });
propertyGroup.PropertyTypes.Add(new PropertyType("test", DataTypeDatabaseType.Ntext, "metaAuthor") { Name = "Meta Author", Description = "", HelpText = "", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -88 });
repository.AddOrUpdate(contentType);
unitOfWork.Commit();
@@ -511,7 +509,7 @@ namespace Umbraco.Tests.Persistence.Repositories
contentType.RemovePropertyType("keywords");
//Add PropertyType
var propertyGroup = contentType.PropertyGroups.First(x => x.Name == "Meta");
propertyGroup.PropertyTypes.Add(new PropertyType("test", DataTypeDatabaseType.Ntext) { Alias = "metaAuthor", Name = "Meta Author", Description = "", HelpText = "", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -88 });
propertyGroup.PropertyTypes.Add(new PropertyType("test", DataTypeDatabaseType.Ntext, "metaAuthor") { Name = "Meta Author", Description = "", HelpText = "", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -88 });
repository.AddOrUpdate(contentType);
unitOfWork.Commit();
@@ -81,9 +81,8 @@ namespace Umbraco.Tests.Persistence.Repositories
var mediaType = repository.Get(NodeDto.NodeIdSeed);
mediaType.Thumbnail = "Doc2.png";
mediaType.PropertyGroups["Media"].PropertyTypes.Add(new PropertyType("test", DataTypeDatabaseType.Ntext)
mediaType.PropertyGroups["Media"].PropertyTypes.Add(new PropertyType("test", DataTypeDatabaseType.Ntext, "subtitle")
{
Alias = "subtitle",
Name = "Subtitle",
Description = "Optional Subtitle",
HelpText = "",
@@ -78,9 +78,8 @@ namespace Umbraco.Tests.PublishedContent
var mType = MockedContentTypes.CreateImageMediaType("image2");
//lets add an RTE to this
mType.PropertyGroups.First().PropertyTypes.Add(
new PropertyType("test", DataTypeDatabaseType.Nvarchar)
new PropertyType("test", DataTypeDatabaseType.Nvarchar, "content")
{
Alias = "content",
Name = "Rich Text",
DataTypeDefinitionId = -87 //tiny mce
});
@@ -3,10 +3,12 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Umbraco.Core.Models;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web;
using Umbraco.Web.Routing;
using umbraco.cms.businesslogic.web;
using umbraco.cms.businesslogic.language;
using Language = umbraco.cms.businesslogic.language.Language;
namespace Umbraco.Tests.Routing
{
@@ -14,6 +16,13 @@ namespace Umbraco.Tests.Routing
[TestFixture]
class DomainsAndCulturesTests : BaseRoutingTest
{
protected override void FreezeResolution()
{
SiteDomainHelperResolver.Current = new SiteDomainHelperResolver(new SiteDomainHelper());
base.FreezeResolution();
}
public override void Initialize()
{
base.Initialize();
@@ -235,5 +244,32 @@ namespace Umbraco.Tests.Routing
Assert.AreEqual(expectedCulture, pcr.Culture.Name);
Assert.AreEqual(pcr.PublishedContent.Id, expectedNode);
}
#region Cases
[TestCase(10011, "http://domain1.com/", "en-US")]
[TestCase(100111, "http://domain1.com/", "en-US")]
[TestCase(10011, "http://domain1.fr/", "fr-FR")]
[TestCase(100111, "http://domain1.fr/", "fr-FR")]
[TestCase(1001121, "http://domain1.fr/", "de-DE")]
#endregion
public void GetCulture(int nodeId, string currentUrl, string expectedCulture)
{
var langEn = Language.GetByCultureCode("en-US");
var langFr = Language.GetByCultureCode("fr-FR");
var langDe = Language.GetByCultureCode("de-DE");
Domain.MakeNew("domain1.com/", 1001, langEn.id);
Domain.MakeNew("domain1.fr/", 1001, langFr.id);
Domain.MakeNew("*100112", 100112, langDe.id);
var routingContext = GetRoutingContext("http://anything/");
var umbracoContext = routingContext.UmbracoContext;
var content = umbracoContext.ContentCache.GetById(nodeId);
Assert.IsNotNull(content);
var culture = Web.Models.ContentExtensions.GetCulture(umbracoContext, null, null, content.Id, content.Path, new Uri(currentUrl));
Assert.AreEqual(expectedCulture, culture.Name);
}
}
}
File diff suppressed because it is too large Load Diff

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