Compare commits

...

194 Commits

Author SHA1 Message Date
Emil Wangaa d51082f651 Bumps version 2017-03-30 10:27:54 +02:00
Stephan f2fb275b34 Fix post-merge issues 2017-03-30 09:58:27 +02:00
Shannon c5f388f6bc Merge remote-tracking branch 'origin/dev-v7' into dev-v7.6
# Conflicts:
#	build/NuSpecs/UmbracoCms.Core.nuspec
#	src/Umbraco.Tests/packages.config
#	src/Umbraco.Web/Umbraco.Web.csproj
#	src/Umbraco.Web/packages.config
#	src/UmbracoExamine/UmbracoExamine.csproj
#	src/umbraco.MacroEngines/packages.config
#	src/umbraco.MacroEngines/umbraco.MacroEngines.csproj
2017-03-30 17:03:51 +11:00
Shannon 4419af427b Merge branch 'dev-v7.6' of https://github.com/umbraco/Umbraco-CMS into dev-v7.6 2017-03-30 17:02:04 +11:00
Shannon dbdee5fc2c U4-9655 Html Agility pack assembly binding needs to be updated via code, just in case 2017-03-30 17:01:30 +11:00
Shannon 25f5179b29 updates nuspec 2017-03-30 16:36:54 +11:00
Shannon 1a03bd9624 Logs an error if the index is rebuilding due to being corrupt 2017-03-30 15:49:45 +11:00
Shannon 6a1d60c5a7 U4-9692 Update to Examine 0.1.82 2017-03-30 15:43:06 +11:00
Shannon 4fef17190f adds notes 2017-03-30 11:03:07 +11:00
Warren Buckley 143b9c605b Merge pull request #1841 from umbraco/temp-CON-1296
Adds support for loading uninitialized trees in the treepicker
2017-03-29 13:31:44 +01:00
Emil Wangaa db809f30fe Reverted hideHeader value to true in treepicker.controller.js - should not have been changed 2017-03-29 14:00:36 +02:00
Claus dcb50d10c4 Merge pull request #1842 from umbraco/temp-U4-9685
fixes: U4-9685 Disable picking folders in the partial view picker
2017-03-29 13:28:33 +02:00
Mads Rasmussen a91a67ed8d fixes: U4-9685 Disable picking folders in the partial view picker 2017-03-29 11:37:30 +02:00
Shannon 1f3e568a0d fixes merge issues 2017-03-29 19:11:55 +11:00
Shannon cb539e82d0 Merge remote-tracking branch 'origin/dev-v7' into dev-v7.6
# Conflicts:
#	build/UmbracoVersion.txt
#	src/SolutionInfo.cs
#	src/Umbraco.Core/Configuration/UmbracoVersion.cs
#	src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs
#	src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
#	src/Umbraco.Web/Models/Mapping/MediaModelMapper.cs
#	src/UmbracoExamine/UmbracoMemberIndexer.cs
2017-03-29 18:11:51 +11:00
Shannon Deminick 1432d602ba Merge pull request #1838 from umbraco/temp-u4-9665
u4-9665
2017-03-29 18:06:28 +11:00
Shannon 841d2a7010 ensure change tracking is turned off on the dialog so the warning doesn't pop up 2017-03-29 17:51:31 +11:00
Shannon 7cdb48b6c9 bumps version 2017-03-29 16:35:37 +11:00
Shannon Deminick a667058422 Merge pull request #1828 from umbraco/temp-u4-9655
U4-9655 - update HtmlAgilityPack version in config
2017-03-29 16:33:37 +11:00
Shannon Deminick 4ffa6bb41b Merge pull request #1824 from umbraco/temp-u4-9617
U4-9617 - perf for published date
2017-03-29 16:29:31 +11:00
Shannon 77af16db55 Merge branch 'dev-v7' into temp-u4-9617
# Conflicts:
#	src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs
2017-03-29 16:29:18 +11:00
Emil Wangaa 2a44b73056 Adds support for loading uninitialized trees in the treepicker - is needed for CON-1296 to work 2017-03-28 21:19:12 +02:00
Stephan 85d85fa587 Merge pull request #1819 from umbraco/temp-u4-9623
U4-9323 - fix DataTypeDefinitionRepository prevalues cache
2017-03-28 17:37:04 +02:00
Stephan bd27ed739d Merge pull request #1810 from umbraco/temp-U4-9633
Fixes: U4-9633 Update the offline dashboard to new content and styles
2017-03-28 17:28:47 +02:00
Stephan 3938868115 U4-9665 - create partial view macro with file 2017-03-28 17:22:18 +02:00
Claus 140792430f Merge pull request #1823 from umbraco/temp-U4-9647
fixes: U4-9647 7.6.0-beta: New template editor not set $dirty on code…
2017-03-28 15:15:43 +02:00
Claus c04cf1fe2e Merge pull request #1822 from umbraco/temp-U4-9654
fixes: U4-9654 7.6.0-beta: Legacy icons are not resolved in new listv…
2017-03-28 14:32:48 +02:00
Claus d1d83c84a0 fixes icons on listviews. 2017-03-28 14:27:05 +02:00
Claus 98acc50e13 Merge pull request #1830 from abryukhov/patch-7
Adding new UI keys for v7.6 features
2017-03-28 13:56:46 +02:00
Claus 1a0a02463e Merge pull request #1835 from umbraco/temp-U4-9680
fixes: U4-9680 The font change has made the tiny editor boxes a littl…
2017-03-28 13:53:23 +02:00
Claus 96c499a47e Merge pull request #1833 from umbraco/temp-U4-9679
fixes: U4-9679 Inserting partial views in the new template editor is …
2017-03-28 13:46:24 +02:00
Claus f7e8aefeab Merge pull request #1834 from umbraco/temp-u4-9666
U4-9666 - hide deprecated prop editors for macro params
2017-03-28 13:38:42 +02:00
Claus dfa803293f Merge pull request #1826 from umbraco/temp-U4-9671
Fixes: U4-9671 Fix failing client side unit tests for the content picker and template editor
2017-03-28 13:23:55 +02:00
Claus 7ade64f855 Merge pull request #1802 from umbraco/temp-U4-9637
U4-9637 addDashboardSection package action shouldn't add the dashboar…
2017-03-28 13:12:26 +02:00
Shannon Deminick 346e8dcaf0 Merge pull request #1820 from umbraco/temp-u4-9615
U4-9615 - implement way to find listviews in path fast
2017-03-28 16:05:25 +11:00
Shannon ddfd07bf4a Fixes count query 2017-03-28 16:04:06 +11:00
Shannon a9fe46da0c makes HasContainerInPath public 2017-03-28 15:55:45 +11:00
Shannon aca1f0d186 Adds comments 2017-03-28 15:46:33 +11:00
Shannon 9eb415d398 U4-9682 Repository's have a double nested DeepCloneRuntimeCacheProvider set which means all entities are double deep cloned in and out of the cache and ensures that PreValueCollections are not also manually deep cloned. 2017-03-28 15:41:55 +11:00
Shannon 8f6b728534 Moves paging value to a constant 2017-03-28 13:37:10 +11:00
Shannon Deminick 2e0c09ab39 Merge pull request #1827 from umbraco/temp-u4-9598
U4-9598 - fix paging in UmbracoContentIndexer
2017-03-28 13:31:37 +11:00
Shannon Deminick f211344786 Merge pull request #1825 from umbraco/temp-u4-9604
U4-9604 - fix current HttpContext in ManyObjectsResolverBase
2017-03-28 13:11:09 +11:00
Mads Rasmussen f8764cdd20 fixes: U4-9680 The font change has made the tiny editor boxes a little to small. 2017-03-27 13:05:46 +02:00
Stephan 1d17bfd59a U4-9666 - hide deprecated prop editors for macro params 2017-03-27 12:25:58 +02:00
Mads Rasmussen 98ad6ad366 fixes: U4-9679 Inserting partial views in the new template editor is broken 2017-03-27 11:27:58 +02:00
Stephan 68702b98f5 U4-9604 - add nullcheck 2017-03-27 08:52:10 +02:00
Stephan f93caf277b Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into temp-u4-9604 2017-03-27 08:47:40 +02:00
Shannon Deminick 32db674397 Merge pull request #1813 from umbraco/temp-U4-9645
Fixes: U4-9645 RTE link dialogs should use the new picker dialog
2017-03-27 14:25:07 +11:00
Shannon Deminick e0a7698780 Merge pull request #1821 from andyneil/dev-v7-lang-fixes
Dev v7 lang fixes
2017-03-27 14:20:41 +11:00
Shannon Deminick 783c74d3ba Merge pull request #1829 from abryukhov/patch-6
Adding missing keys before v7.6
2017-03-27 14:12:08 +11:00
Alexander Bryukhov 96d7bc3898 Adding new UI keys for v7.6 features 2017-03-24 22:10:09 +07:00
Alexander Bryukhov 21963c03a2 Adding missing keys before v7.6 2017-03-24 21:59:02 +07:00
Stephan a2a9794fdb U4-9655 - update HtmlAgilityPack version in config 2017-03-24 14:47:27 +01:00
Stephan 879a132077 U4-9598 - fix paging in UmbracoContentIndexer 2017-03-24 13:05:06 +01:00
Mads Rasmussen 9650d314c6 fix failing unit tests for template editor 2017-03-24 11:35:44 +01:00
Mads Rasmussen fcc0c452bb add mock for getEntitiesByIds POST request 2017-03-24 11:34:08 +01:00
Stephan 606ebcae92 U4-9604 - fix current HttpContext in ManyObjectsResolverBase 2017-03-24 11:07:15 +01:00
Stephan af10ae9e34 U4-9617 - fix 2017-03-23 18:00:58 +01:00
Stephan a23c150738 U4-9617 - fix 2017-03-23 17:51:30 +01:00
Stephan 085a678266 U4-9617 - perf for published date 2017-03-23 17:44:07 +01:00
Mads Rasmussen c73fb6144b fixes: U4-9647 7.6.0-beta: New template editor not set $dirty on code change 2017-03-23 16:31:50 +01:00
mikkelhm bfd201efcc Bump version to 7.6-Beta5 2017-03-23 15:46:18 +01:00
Mads Rasmussen 5a2b4f031b fixes: U4-9654 7.6.0-beta: Legacy icons are not resolved in new listview picker 2017-03-23 15:00:30 +01:00
andyneil cf7cafeb4c Update wording to be more grammatically correct 2017-03-23 13:41:48 +00:00
andyneil 870657affa Update wording to be more grammatically correct 2017-03-23 13:41:23 +00:00
Stephan fe11d4770d U4-9615 - implement way to find listviews in path fast 2017-03-23 14:07:45 +01:00
Mads Rasmussen ac75d8148d fix color on tree header checkmark 2017-03-23 11:46:51 +01:00
Mads Rasmussen 4a32cddf08 make tree search box full width 2017-03-23 11:37:13 +01:00
Mads Rasmussen 7461e7c55b align styling of error and success messages for content (move/copy) and media (move) 2017-03-23 11:36:51 +01:00
Stephan c8fe9030c7 U4-9323 - fix DataTypeDefinitionRepository prevalues cache 2017-03-23 10:39:28 +01:00
Shannon 2ae236e98d Adds xml transform for partial view tree types 2017-03-23 18:48:41 +11:00
Shannon 802fb95784 Fixes issue with renaming PartialViewMacro and PartialViewTree controller names - this also fixes an issue that we were looking up these types over and over again and now we just do it once. 2017-03-23 18:44:28 +11:00
Shannon 0297fdb32f Fixes a bunch of the JS unit tests 2017-03-23 13:19:37 +11:00
Shannon Deminick 5bede4bf9f Merge pull request #1816 from umbraco/temp-u4-9664
u4-9664 - Enables HasAccess on the MediaTreeController to use a udi for checkin…
2017-03-23 12:54:11 +11:00
Shannon d37106576d Adds null checks to the ContentTreeController too 2017-03-23 12:53:48 +11:00
Shannon ed0f0f7942 Merge remote-tracking branch 'origin/dev-v7' into dev-v7.6
# Conflicts:
#	src/Umbraco.Core/Configuration/CoreDebug.cs
#	src/Umbraco.Core/Publishing/PublishingStrategy.cs
#	src/Umbraco.Core/Umbraco.Core.csproj
2017-03-23 12:24:16 +11:00
Shannon Deminick 3d81c73495 Merge pull request #1814 from umbraco/temp-u4-9658
U4-9658 - detect umbraco.config rogue content types, and fix
2017-03-23 12:16:10 +11:00
Shannon e7a540e717 Proper Exception handling 2017-03-23 12:15:14 +11:00
Shannon Deminick bb886c237e Merge pull request #1815 from umbraco/temp-u4-9610
U4-9610 - fix nullref in BulkPublishController
2017-03-23 11:28:03 +11:00
Shannon 6c1e271fa8 Fixes styling and fixing error message quotes to make it more clear 2017-03-23 11:27:46 +11:00
Shannon Deminick 4c1b807e4f Merge pull request #1812 from umbraco/temp-u4-6811
U4-6811 - fix preview set deletion
2017-03-23 11:06:33 +11:00
Shannon 3b22c0cdd7 Catches correct expected exception type, we'll log for other non expected errors. 2017-03-23 11:06:06 +11:00
mikkelhm 31d8f49d3b Enables HasAccess on the MediaTreeController to use a udi for checking access 2017-03-22 20:25:15 +01:00
Stephan 631404743f U4-9610 - fix nullref in BulkPublishController 2017-03-22 14:44:39 +01:00
Emil Wangaa 1e154e8bc9 Internal Beta04 version bump - needed for Forms 2017-03-22 14:32:35 +01:00
Stephan d5c9639170 U4-9658 - detect umbraco.config rogue content types, and fix 2017-03-22 13:58:40 +01:00
Mads Rasmussen b90cccbfff implement mini list view for media copy 2017-03-22 13:45:09 +01:00
Stephan 94b7c36d62 U4-6811 - fix preview set deletion 2017-03-22 12:16:33 +01:00
Mads Rasmussen 22f0641c54 implement mini list view for url picker 2017-03-22 11:58:11 +01:00
Mads Rasmussen e465a937c5 Implement mini list view for generic move overlay 2017-03-22 11:26:53 +01:00
Mads Rasmussen d2164bc94d Implement mini list view for generic copy overlay 2017-03-22 11:26:08 +01:00
Mads Rasmussen df9d09725b add entity helper so we don't have to hard code these values all over the place 2017-03-22 11:25:00 +01:00
Stephan 1ffdd1abd1 Merge pull request #1811 from umbraco/temp-U4-9660
U4-9660 EntityService is not using readonly uow where it could be
2017-03-22 11:20:29 +01:00
Claus a06de1b165 U4-9660 EntityService is not using readonly uow where it could be 2017-03-22 11:14:16 +01:00
Mads Rasmussen 0a56f46b12 Implement mini list view for content copy dialog 2017-03-22 10:44:55 +01:00
Mads Rasmussen 972f9b3546 implement mini list view for content move dialog 2017-03-22 10:43:10 +01:00
Shannon 0fd3af6828 Fixes release version of tinymceconfig 2017-03-22 18:32:28 +11:00
Shannon fafb207799 U4-8658 RTE Editor: Edit an existing image by clicking 'media picker' in toolbar, show a blank picker 2017-03-22 18:27:18 +11:00
Shannon b1aea424e8 U4-9659 Javascript error when inserting an image into the rich text editor from the media picker 2017-03-22 18:26:11 +11:00
Shannon Deminick 3598acaddc Merge pull request #1805 from umbraco/temp-u4-9644
u4-9644 fix local link selection in the rich text editor
2017-03-22 18:25:04 +11:00
Shannon 8e03a1ffca Updates tha a and img tags in the rte to use a data-udi attribute when udi's are used 2017-03-22 18:17:59 +11:00
Shannon Deminick ded8afa8fc Merge pull request #1808 from umbraco/temp-u4-9582
U4-9582
2017-03-22 13:56:54 +11:00
Mads Rasmussen dcd2b1eb6b Merge pull request #1807 from crgrieve/U4-9648
U4-9648 Remove the relevant query rather than the first one in list.
2017-03-21 19:59:57 +01:00
Stephan c04ef47be3 Merge pull request #1806 from umbraco/temp-u4-9640
U4-9640
2017-03-21 17:48:07 +01:00
Stephan 62f3c87e8a Merge remote-tracking branch 'origin/dev-v7.6' into temp-u4-9640 2017-03-21 17:12:29 +01:00
Stephan 1b9776ecfb Merge pull request #1800 from umbraco/temp-U4-9591
U4-9591 All PetaPoco Relators for 1:M mappings need to be reviewed to…
2017-03-21 16:52:12 +01:00
Warren Buckley 7b1efa718e Internal Beta03 version bump - needed for Forms for access to [FileUploadCleanupFilter] 2017-03-21 15:50:13 +00:00
Warren Buckley f60ad15f70 Marks Forms access to internals in Umbraco.Web assembly - needed for [FileUploadCleanupFilter] in Forms 2017-03-21 15:42:30 +00:00
Mads Rasmussen 28ab176466 Fixes: U4-9633 Update the offline dashboard to new content and styles 2017-03-21 15:28:55 +01:00
mikkelhm 3f3db006e7 When selecting a local link, also update the data-id to be the udi 2017-03-21 14:43:54 +01:00
Stephan 7801cdf9ff Merge remote-tracking branch 'origin/dev-v7.6' into temp-u4-9640 2017-03-21 13:14:18 +01:00
mikkelhm 836e1bba54 Revert "moves binding redirects to app pre init"
This reverts commit 5a953761b0.
2017-03-21 13:14:07 +01:00
mikkelhm de9c5b88ab Updates the legacy linkpicker to show udi links properly, i.e. translate them to nice internal urls 2017-03-21 11:48:50 +01:00
Stephan 77981f889f U4-9582 - perfs, cache converter prevalues 2017-03-21 11:10:52 +01:00
Stephan 0a132ed5ed U4-9582 - perfs, remove Yield method 2017-03-21 11:10:37 +01:00
Shannon 5a953761b0 moves binding redirects to app pre init 2017-03-21 20:41:07 +11:00
Shannon 27ee192c8f Fixes all the logic in the CodeFileController, propery null checking, proper handling of persisting everything including renames, removes code duplication 2017-03-21 18:39:45 +11:00
Shannon dfa58183c6 Fixes deleting partial view and script files 2017-03-21 18:38:54 +11:00
Shannon e8668f3ed4 Don't pass in a value for snippets if it's not there, it will show up as a "undefined" string otherwise, adds the redirect method to the contentEditingHelper 2017-03-21 18:38:32 +11:00
Shannon c84e3dac38 Adds notes, return false if the file is not actually deleted, adds test assertions 2017-03-21 18:37:46 +11:00
Shannon 72ab51ea60 Fixes angular file controllers to not sync the tree if an item is being created, redirects to the correct path if the file is renamed 2017-03-21 18:36:14 +11:00
Shannon 1bfb63fe86 Adds validation for file names 2017-03-21 18:35:13 +11:00
Shannon 2cf68ab263 dont' render files that are invalid (no name) 2017-03-21 18:30:39 +11:00
Shannon 215bc64a83 Fixes val-server directive since it wasn't picking up on ngModel changes 2017-03-21 18:20:22 +11:00
Shannon Deminick 1b17f4e9df Merge pull request #1804 from umbraco/temp-u4-9543
U4-9543 - fix shadow filesystem filter
2017-03-21 12:59:43 +11:00
Shannon 73f0b1992d Fixes up sorting when using relators 2017-03-21 12:37:35 +11:00
carole_grieve_eqtr 21f54dd4ff Remove the relevant query rather than the first one! 2017-03-20 17:55:48 +00:00
Stephan a5903ec419 U4-9640 - fix CodeFileController for scripts 2017-03-20 16:53:08 +01:00
Warren Buckley ac496b0cf6 Updates version to beta02 - after Warren forgot to merge & push AccessToInternals for Forms before public beta 2017-03-20 15:40:15 +00:00
Warren Buckley 6036136938 Merge branch 'dev-v7.6' of https://github.com/umbraco/Umbraco-CMS into dev-v7.6
# Conflicts:
#	build/UmbracoVersion.txt
#	src/SolutionInfo.cs
#	src/Umbraco.Core/Configuration/UmbracoVersion.cs
2017-03-20 14:55:29 +00:00
Stephan a9c7a7a405 U4-9640 - use IFileSystem 2017-03-20 15:53:34 +01:00
mikkelhm ce8286dadd Sets the udi as well as the id when selecting a local link in the rich text editor 2017-03-20 15:53:32 +01:00
Claus 532b177d2e Merge pull request #1793 from Phosworks/U4-8418
Fixes jquery selector bug, http://issues.umbraco.org/issue/U4-8418
2017-03-20 14:43:43 +01:00
mikkelhm 504aac0350 Fixes variable names when selecting a local link in the rich text editor 2017-03-20 14:32:43 +01:00
Stephan 454aad2170 U4-9543 - fix shadow filesystem filter 2017-03-20 13:01:03 +01:00
Shannon fd0cb7da23 Merge remote-tracking branch 'refs/remotes/origin/dev-v7.6' into temp-U4-9591 2017-03-20 18:28:38 +11:00
Shannon 4093fd9b79 U4-9637 addDashboardSection package action shouldn't add the dashboard if it already exists 2017-03-18 16:52:30 +11:00
Shannon 3d6f91cbef Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2017-03-18 15:47:56 +11:00
Shannon fffd508bb2 missing null check 2017-03-18 15:44:57 +11:00
Sebastiaan Janssen f4eb37d44d Missing null check (for unit test) 2017-03-17 12:11:28 +01:00
Sebastiaan Janssen c79aaa9c48 Bumps version 2017-03-17 11:49:42 +01:00
Sebastiaan Janssen e3bc6f148a New installer background image 2017-03-17 11:35:15 +01:00
Warren Buckley a43bd13e6a Merge pull request #1798 from umbraco/temp-U4-9621
Fixes: U4-9621 More UI color tweaks
2017-03-16 15:31:30 +00:00
Warren Buckley 6aa00c52dc Merge branch 'dev-v7.6' of https://github.com/umbraco/Umbraco-CMS into dev-v7.6 2017-03-16 15:08:33 +00:00
Stephan 333b35d8b9 U4-9606 - hard cap of 8 minidump files 2017-03-16 15:51:19 +01:00
Mads Rasmussen 30d5bfa7b4 move nonode css to less file, update grunt build + update no node colors + font 2017-03-16 15:49:59 +01:00
Claus 890673a197 Merge pull request #1797 from umbraco/temp-u4-9606
U4-9606 - New DumpOnTimeoutThreadAbort debug option
2017-03-16 15:38:01 +01:00
Claus 6344ad28aa adding sqlsyntax. 2017-03-16 14:52:50 +01:00
Claus eadc3c8c5a U4-9591 All PetaPoco Relators for 1:M mappings need to be reviewed to ensure there is a correct sort being used 2017-03-16 14:45:59 +01:00
Stephan 9b8db111dd Merge pull request #1790 from umbraco/temp-U4-9611
U4-9611 Create Property Value Converters for all new UDI Property Edi…
2017-03-16 14:36:17 +01:00
Stephan 7b506fadc6 U4-9611 - minor fix 2017-03-16 14:35:54 +01:00
Stephan 27539d4aad U4-9606 - always minidump on Monitor.ReliableEnter exceptions 2017-03-16 14:04:28 +01:00
Claus 1ce44565a3 Merge pull request #1764 from umbraco/temp-u4-9462
U4-9462 units of work cleanup
2017-03-16 13:12:32 +01:00
Stephan e70e651901 U4-9462 - minor fix 2017-03-16 13:10:53 +01:00
Mads Rasmussen 00b0515fc1 Revert "less bright and "dangerous" alerts, notifications and validation messages"
This reverts commit 691c13d1e1.
2017-03-16 10:31:48 +01:00
Morten Christensen d8c04b1f67 Merge pull request #1799 from umbraco/temp-U4-9632
U4-9632 Ensure GUID generation on updated entity types in v7.6 is unique
2017-03-16 10:09:31 +01:00
Shannon 172ef8c379 U4-7093 If allowManuallyChangingPassword=false on new install, installation doesn't work 2017-03-16 18:59:06 +11:00
Claus 7e1f045c09 U4-9632 Ensure GUID generation on updated entity types in v7.6 is unique
removing unused using statements from other migrations.
2017-03-16 08:19:03 +01:00
Sebastiaan Janssen d2fdf7b647 Check if MediaPicker is configured as single or multiple and give back appropriate result for each (IPublishedContent vs IEnumerable<IPublishedContent>) 2017-03-15 23:22:53 +01:00
Sebastiaan Janssen e1942d96d0 Incorporate Stephane's feedback: if we already know we're getting list of int or udi, we don't need to cast, or even test for the PropertyEditorAlias 2017-03-15 23:22:53 +01:00
Stephan 496e6c1711 U4-9462 - missed one safeXml.AcceptChanges 2017-03-15 14:50:42 +01:00
Mads Rasmussen c9fc0fbed1 Update installer gray buttons to purple buttons + align label with input 2017-03-15 14:35:11 +01:00
Stephan 3121ea6111 Merge branch 'dev-v7.6' into temp-u4-9462 2017-03-15 13:48:27 +01:00
Stephan 59ecc6e109 Merge branch 'dev-v7.6' into temp-U4-9611 2017-03-15 13:00:07 +01:00
Stephan eb42b9a4b6 Merge pull request #1796 from umbraco/temp-U4-6566
U4-6566 Membership provider `useLegacyEncoding` should default to `false`
2017-03-15 12:37:09 +01:00
Stephan 82660cf6af Merge branch 'dev-v7.6' into temp-U4-9611 2017-03-15 12:10:27 +01:00
Stephan 54afd3d954 Fix failing test 2017-03-15 12:08:52 +01:00
Mads Rasmussen 9ee3471153 add font smoothing to installer 2017-03-15 10:38:42 +01:00
Mads Rasmussen 691c13d1e1 less bright and "dangerous" alerts, notifications and validation messages 2017-03-15 10:26:05 +01:00
Stephan f7f23015d0 U4-9606 - missing file 2017-03-15 09:39:35 +01:00
Stephan e432b7061d U4-9606 - New DumpOnTimeoutThreadAbort debug option 2017-03-14 19:02:33 +01:00
Sebastiaan Janssen 241ccf00a5 U4-6566 Membership provider useLegacyEncoding should default to false 2017-03-14 17:05:24 +01:00
Sebastiaan Janssen 1a0046df95 Merge pull request #1795 from umbraco/temp-U4-9498
U4-9498 LocalLinks as UDI
2017-03-14 15:54:03 +01:00
Sebastiaan Janssen a2ca753dd9 Use RelatedLink class instead of weird extra inline class, convert UDI values 2017-03-14 10:26:13 +01:00
Sebastiaan Janssen 6f516a15aa Boyscout cleanup 2017-03-14 10:25:10 +01:00
Sebastiaan Janssen 223ed41c53 Use the extension method to get published content item - consistent with other PVCs 2017-03-14 10:24:31 +01:00
Sebastiaan Janssen d2a3932626 Merge branch 'dev-v7.6' into temp-U4-9611 2017-03-14 10:22:39 +01:00
Shannon 0a3220df85 Fixes null check, adds another test case 2017-03-14 16:26:17 +11:00
Shannon 9a57f463ce Updates LocalLinks to be UDI, this will support both INT and UDI as LocalLink but when a new LocalLink is picked, it will use the UDI so eventually the INT will be gone 2017-03-14 15:31:30 +11:00
Mads Rasmussen fdfae0f78a increase font size for template insert description 2017-03-13 22:43:24 +01:00
Mads Rasmussen 9ebe7f683a increase font size for validation label 2017-03-13 22:40:12 +01:00
Mads Rasmussen 185af08e75 increase header description font-size 2017-03-13 21:02:43 +01:00
Mads Rasmussen 874c679bfe update tree header 2017-03-13 20:53:55 +01:00
Mads Rasmussen 76a6449ffa increase font size on actions menu 2017-03-13 20:47:36 +01:00
Mads Rasmussen fd8e200bd7 make property editor placeholder lighter + increase font size 2017-03-13 20:38:02 +01:00
Mads Rasmussen aa7e739b0e increase sections label font size 2017-03-13 20:09:44 +01:00
Mads Rasmussen 97f379ff44 add more contrast to placeholder text 2017-03-13 20:06:57 +01:00
Sebastiaan Janssen 3904f9c503 Centralized getting an IPublishedContent item from a Udi in a single extension method so that we're not repeating that code all over the place all the time 2017-03-13 15:49:15 +01:00
Wincent fc92d40b3a Fixes jquery selector bug, http://issues.umbraco.org/issue/U4-8418 2017-03-13 11:25:02 +01:00
Sebastiaan Janssen 89c84676dd U4-9611 Create Property Value Converters for all new UDI Property Editors 2017-03-11 16:44:57 +01:00
Stephan 6439e2fdd0 Merge dev-v7.6 into temp-u4-9462 2017-03-09 15:29:26 +01:00
Stephan 4d24e7bef8 U4-9462 - more units of work cleanup 2017-02-21 13:19:58 +01:00
Stephan 8d5f7af780 U4-9462 - cleanup file unit of work 2017-02-21 13:19:58 +01:00
Stephan 08c8b84a10 U4-9462 - cleanup units of work, code, fixmes 2017-02-21 13:19:58 +01:00
255 changed files with 4996 additions and 3362 deletions
+1 -1
View File
@@ -33,7 +33,7 @@
<dependency id="ClientDependency-Mvc5" version="[1.8.0.0, 2.0.0)" />
<dependency id="AutoMapper" version="[3.3.1, 4.0.0)" />
<dependency id="Newtonsoft.Json" version="[9.0.1, 10.0.0)" />
<dependency id="Examine" version="[0.1.81, 1.0.0)" />
<dependency id="Examine" version="[0.1.82, 1.0.0)" />
<dependency id="ImageProcessor" version="[2.5.2, 3.0.0)" />
<dependency id="ImageProcessor.Web" version="[4.8.2, 5.0.0)" />
<dependency id="semver" version="[2.0.4, 3.0.0)" />
+2 -2
View File
@@ -58,7 +58,7 @@
<httpRuntime xdt:Transform="InsertIfMissing" />
<httpRuntime maxRequestLength="51200" fcnMode="Single" xdt:Transform="SetAttributes(fcnMode,maxRequestLength)" />
<httpRuntime targetFramework="4.5" xdt:Locator="Condition(count(@targetFramework) != 1)" xdt:Transform="SetAttributes(targetFramework)" />
<membership defaultProvider="DefaultMembershipProvider" xdt:Locator="Match(defaultProvider)" xdt:Transform="Remove" />
<roleManager defaultProvider="DefaultRoleProvider" xdt:Locator="Match(defaultProvider)" xdt:Transform="Remove"/>
<profile defaultProvider="DefaultProfileProvider" xdt:Locator="Match(defaultProvider)" xdt:Transform="Remove"/>>
@@ -337,7 +337,7 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="HtmlAgilityPack" publicKeyToken="bd319b19eaf3b43a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.4.9.0" newVersion="1.4.9.0" />
<bindingRedirect oldVersion="0.0.0.0-1.4.9.5" newVersion="1.4.9.5" />
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="AutoMapper" publicKeyToken="be96cd2c38ef1005" culture="neutral" />
+17 -7
View File
@@ -34,10 +34,15 @@
xdt:Transform="SetAttributes()" />
<add application="settings" alias="templates" title="Templates" type="Umbraco.Web.Trees.TemplatesTreeController, umbraco" iconClosed="icon-folder" iconOpen="icon-folder-open" sortOrder="1"
xdt:Locator="Match(application,alias)"
xdt:Transform="SetAttributes()" />
<add application="settings" alias="partialViews" title="Partial Views" silent="false" initialize="true" iconClosed="icon-folder" iconOpen="icon-folder" type="Umbraco.Web.Trees.PartialViewsTree, umbraco" sortOrder="2"
xdt:Locator="Match(application,alias)"
xdt:Transform="SetAttributes()" />
xdt:Transform="SetAttributes()" />
<add application="settings" alias="partialViews" type="Umbraco.Web.Trees.PartialViewsTree, umbraco"
xdt:Locator="Match(application,alias,type)"
xdt:Transform="Remove()" />
<add application="settings" alias="partialViews" title="Partial Views" silent="false" initialize="true" iconClosed="icon-folder" iconOpen="icon-folder" type="Umbraco.Web.Trees.PartialViewsTreeController, umbraco" sortOrder="2"
xdt:Locator="Match(application,alias)"
xdt:Transform="InsertIfMissing" />
<add application="settings" alias="scripts" title="Scripts" type="umbraco.loadScripts, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="4"
xdt:Locator="Match(application,alias)"
xdt:Transform="SetAttributes()" />
@@ -84,9 +89,14 @@
<add application="developer" alias="xslt" title="XSLT Files" type="umbraco.loadXslt, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="5"
xdt:Locator="Match(application,alias)"
xdt:Transform="SetAttributes()" />
<add application="developer" alias="partialViewMacros" type="Umbraco.Web.Trees.PartialViewMacrosTree, umbraco" silent="false" initialize="true" sortOrder="6" title="Partial View Macro Files" iconClosed="icon-folder" iconOpen="icon-folder"
xdt:Locator="Match(application,alias)"
xdt:Transform="SetAttributes()" />
<add application="developer" alias="partialViewMacros" type="Umbraco.Web.Trees.PartialViewMacrosTree, umbraco"
xdt:Locator="Match(application,alias,type)"
xdt:Transform="Remove()" />
<add application="developer" alias="partialViewMacros" type="Umbraco.Web.Trees.PartialViewMacrosTreeController, umbraco" silent="false" initialize="true" sortOrder="6" title="Partial View Macro Files" iconClosed="icon-folder" iconOpen="icon-folder"
xdt:Locator="Match(application,alias)"
xdt:Transform="InsertIfMissing" />
<add application="developer" alias="python"
xdt:Locator="Match(application,alias)"
xdt:Transform="Remove" />
+1 -1
View File
@@ -1,3 +1,3 @@
# Usage: on line 2 put the release version, on line 3 put the version comment (example: beta)
7.6.0
alpha075
beta06
+1 -1
View File
@@ -12,4 +12,4 @@ using System.Resources;
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("7.6.0")]
[assembly: AssemblyInformationalVersion("7.6.0-alpha075")]
[assembly: AssemblyInformationalVersion("7.6.0-beta06")]
+3 -3
View File
@@ -1,8 +1,6 @@
using System;
using System.Configuration;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.ObjectResolution;
@@ -163,7 +161,9 @@ namespace Umbraco.Core
/// </summary>
public static ApplicationContext Current { get; internal set; }
// fixme
/// <summary>
/// Gets the scope provider.
/// </summary>
internal IScopeProvider ScopeProvider { get { return _databaseContext == null ? null : _databaseContext.ScopeProvider; } }
/// <summary>
+12 -4
View File
@@ -17,9 +17,12 @@ namespace Umbraco.Core
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
}
private static readonly Regex Log4NetAssemblyPattern = new Regex("log4net, Version=([\\d\\.]+?), Culture=neutral, PublicKeyToken=null", RegexOptions.Compiled);
private static readonly Regex Log4NetAssemblyPattern = new Regex("log4net, Version=([\\d\\.]+?), Culture=neutral, PublicKeyToken=null");
private const string Log4NetReplacement = "log4net, Version=1.2.15.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a";
private static readonly Regex HtmlAgilityAssemblyPattern = new Regex("HtmlAgilityPack, Version=([\\d\\.]+?), Culture=neutral, PublicKeyToken=bd319b19eaf3b43a");
private const string HtmlAgilityReplacement = "HtmlAgilityPack, Version=1.4.9.5, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a";
/// <summary>
/// This is used to do an assembly binding redirect via code - normally required due to signature changes in assemblies
/// </summary>
@@ -28,13 +31,18 @@ namespace Umbraco.Core
/// <returns></returns>
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
//log4net:
// Use regex to match and replace
//log4net:
if (Log4NetAssemblyPattern.IsMatch(args.Name) && args.Name != Log4NetReplacement)
{
return Assembly.Load(Log4NetAssemblyPattern.Replace(args.Name, Log4NetReplacement));
}
//HtmlAgility:
if (HtmlAgilityAssemblyPattern.IsMatch(args.Name) && args.Name != HtmlAgilityReplacement)
{
return Assembly.Load(HtmlAgilityAssemblyPattern.Replace(args.Name, HtmlAgilityReplacement));
}
//AutoMapper:
// ensure the assembly is indeed AutoMapper and that the PublicKeyToken is null before trying to Load again
// do NOT just replace this with 'return Assembly', as it will cause an infinite loop -> stackoverflow
@@ -26,6 +26,9 @@ namespace Umbraco.Core.Cache
public DeepCloneRuntimeCacheProvider(IRuntimeCacheProvider innerProvider)
{
if (innerProvider.GetType() == typeof(DeepCloneRuntimeCacheProvider))
throw new InvalidOperationException("A " + typeof(DeepCloneRuntimeCacheProvider) + " cannot wrap another instance of " + typeof(DeepCloneRuntimeCacheProvider));
InnerProvider = innerProvider;
}
@@ -105,9 +108,11 @@ namespace Umbraco.Core.Cache
var value = result.Value; // force evaluation now - this may throw if cacheItem throws, and then nothing goes into cache
if (value == null) return null; // do not store null values (backward compat)
//Clone/reset to go into the cache
return CheckCloneableAndTracksChanges(value);
}, timeout, isSliding, priority, removedCallback, dependentFiles);
//Clone/reset to go out of the cache
return CheckCloneableAndTracksChanges(cached);
}
@@ -22,12 +22,12 @@ namespace Umbraco.Core.Cache
{
private static readonly TEntity[] EmptyEntities = new TEntity[0]; // const
private readonly RepositoryCachePolicyOptions _options;
public DefaultRepositoryCachePolicy(IRuntimeCacheProvider cache, RepositoryCachePolicyOptions options)
: base(cache)
{
{
if (options == null) throw new ArgumentNullException("options");
_options = options;
_options = options;
}
public override IRepositoryCachePolicy<TEntity, TId> Scoped(IRuntimeCacheProvider runtimeCache, IScope scope)
@@ -244,9 +244,7 @@ namespace Umbraco.Core.Cache
/// <inheritdoc />
public override void ClearAll()
{
// fixme the cache should NOT contain anything else so we can clean all, can't we?
Cache.ClearAllCache();
//Cache.ClearCacheByKeySearch(GetEntityTypeCacheKey());
}
}
}
@@ -18,10 +18,17 @@ namespace Umbraco.Core.Cache
// it is not *that* complicated but then RepositoryBase needs to have a TRepository generic
// type parameter and it all becomes convoluted - keeping it simple for the time being.
// fixme explain
/// <summary>
/// Creates a scoped version of this cache policy.
/// </summary>
/// <param name="runtimeCache">The global isolated runtime cache for this policy.</param>
/// <param name="scope">The scope.</param>
/// <remarks>When a policy is scoped, it means that it has been created with a scoped
/// isolated runtime cache, and now it needs to be wrapped into something that can apply
/// changes to the global isolated runtime cache.</remarks>
IRepositoryCachePolicy<TEntity, TId> Scoped(IRuntimeCacheProvider runtimeCache, IScope scope);
/// <summary>
/// <summary>
/// Gets an entity from the cache, else from the repository.
/// </summary>
/// <param name="id">The identifier.</param>
@@ -18,10 +18,14 @@ namespace Umbraco.Core.Configuration
{
var appSettings = System.Configuration.ConfigurationManager.AppSettings;
LogUncompletedScopes = string.Equals("true", appSettings["Umbraco.CoreDebug.LogUncompletedScopes"], StringComparison.OrdinalIgnoreCase);
DumpOnTimeoutThreadAbort = string.Equals("true", appSettings["Umbraco.CoreDebug.DumpOnTimeoutThreadAbort"], StringComparison.OrdinalIgnoreCase);
}
// when true, Scope logs the stack trace for any scope that gets disposed without being completed.
// this helps troubleshooting rogue scopes that we forget to complete
public bool LogUncompletedScopes { get; private set; }
// when true, the Logger creates a minidump of w3wp in ~/App_Data/MiniDump whenever it logs
// an error due to a ThreadAbortException that is due to a timeout.
public bool DumpOnTimeoutThreadAbort { get; private set; }
}
}
@@ -24,7 +24,7 @@ namespace Umbraco.Core.Configuration
/// Gets the version comment (like beta or RC).
/// </summary>
/// <value>The version comment.</value>
public static string CurrentComment { get { return "alpha075"; } }
public static string CurrentComment { get { return "beta06"; } }
// Get the version of the umbraco.dll by looking at a class in that dll
// Had to do it like this due to medium trust issues, see: http://haacked.com/archive/2010/11/04/assembly-location-and-medium-trust.aspx
+10
View File
@@ -89,6 +89,11 @@ namespace Umbraco.Core
/// </summary>
public const string Media = "B796F64C-1F99-4FFB-B886-4BF4BC011A9C";
/// <summary>
/// Guid for a Document object.
/// </summary>
public static readonly Guid MediaGuid = new Guid(Media);
/// <summary>
/// Guid for the Media Recycle Bin.
/// </summary>
@@ -148,6 +153,11 @@ namespace Umbraco.Core
/// </summary>
public const string Template = "6FBDE604-4178-42CE-A10B-8A2600A2F07D";
/// <summary>
/// Guid for a Template object.
/// </summary>
public static readonly Guid TemplateTypeGuid = new Guid(Template);
/// <summary>
/// Guid for a Lock object.
/// </summary>
-1
View File
@@ -173,7 +173,6 @@ namespace Umbraco.Core
return new ServiceContext(
new RepositoryFactory(ApplicationCache, ProfilingLogger.Logger, dbContext.SqlSyntax, UmbracoConfig.For.UmbracoSettings()),
new PetaPocoUnitOfWorkProvider(scopeProvider),
new FileUnitOfWorkProvider(scopeProvider),
ApplicationCache,
ProfilingLogger.Logger,
msgFactory);
+5 -35
View File
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlServerCe;
using System.IO;
@@ -34,7 +33,7 @@ namespace Umbraco.Core
private string _connectionString;
private string _providerName;
private DatabaseSchemaResult _result;
private DateTime? _connectionLastChecked = null;
private DateTime? _connectionLastChecked;
/// <summary>
/// The number of minutes to throttle the checks to CanConnect
@@ -99,10 +98,10 @@ namespace Umbraco.Core
SqlSyntaxContext.SqlSyntaxProvider = SqlSyntax;
var asDbFactory2 = factory as IDatabaseFactory2;
ScopeProvider = asDbFactory2 == null
? new ScopeProvider(new DatabaseFactoryWrapper(factory))
ScopeProvider = asDbFactory2 == null
? new ScopeProvider(new DatabaseFactoryWrapper(factory))
: new ScopeProvider(asDbFactory2);
_logger = logger;
_configured = true;
}
@@ -197,42 +196,13 @@ namespace Umbraco.Core
{
throw new InvalidOperationException("Cannot create a database instance, there is no available connection string");
}
return ScopeProvider.GetAmbientOrNoScope().Database;
//var scope = ScopeProvider.AmbientScope;
//return scope != null ? scope.Database : ScopeProvider.CreateNoScope().Database;
}
}
/// <summary>
/// Replaces the "ambient" database (if any) and by a new temp database.
/// </summary>
/// <remarks>
/// <para>The returned IDisposable *must* be diposed in order to properly dispose the temp database and
/// restore the original "ambient" database (if any).</para>
/// <para>This is to be used in background tasks to ensure that they have an "ambient" database which
/// will be properly removed from call context and does not interfere with anything else. In most case
/// it is not replacing anything, just temporarily installing a database in context.</para>
/// </remarks>
// fixme - this should just entirely be replaced by Scope?
/*
public virtual IDisposable UseSafeDatabase(bool force = false)
{
var factory = _factory as DefaultDatabaseFactory;
if (factory == null) throw new NotSupportedException();
if (DefaultDatabaseFactory.HasAmbientDatabase)
{
return force
? new UsingDatabase(DefaultDatabaseFactory.DetachAmbientDatabase(), factory.CreateDatabase())
: new UsingDatabase(null, null);
}
// create a new, temp, database (will be disposed with UsingDatabase)
return new UsingDatabase(null, factory.CreateDatabase());
}
*/
/// <summary>
/// Boolean indicating whether the database has been configured
/// </summary>
+135
View File
@@ -0,0 +1,135 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using Umbraco.Core.IO;
namespace Umbraco.Core.Diagnostics
{
// taken from https://blogs.msdn.microsoft.com/dondu/2010/10/24/writing-minidumps-in-c/
// and https://blogs.msdn.microsoft.com/dondu/2010/10/31/writing-minidumps-from-exceptions-in-c/
// which itself got it from http://blog.kalmbach-software.de/2008/12/13/writing-minidumps-in-c/
internal static class MiniDump
{
private static readonly object LockO = new object();
[Flags]
public enum Option : uint
{
// From dbghelp.h:
Normal = 0x00000000,
WithDataSegs = 0x00000001,
WithFullMemory = 0x00000002,
WithHandleData = 0x00000004,
FilterMemory = 0x00000008,
ScanMemory = 0x00000010,
WithUnloadedModules = 0x00000020,
WithIndirectlyReferencedMemory = 0x00000040,
FilterModulePaths = 0x00000080,
WithProcessThreadData = 0x00000100,
WithPrivateReadWriteMemory = 0x00000200,
WithoutOptionalData = 0x00000400,
WithFullMemoryInfo = 0x00000800,
WithThreadInfo = 0x00001000,
WithCodeSegs = 0x00002000,
WithoutAuxiliaryState = 0x00004000,
WithFullAuxiliaryState = 0x00008000,
WithPrivateWriteCopyMemory = 0x00010000,
IgnoreInaccessibleMemory = 0x00020000,
ValidTypeFlags = 0x0003ffff,
}
//typedef struct _MINIDUMP_EXCEPTION_INFORMATION {
// DWORD ThreadId;
// PEXCEPTION_POINTERS ExceptionPointers;
// BOOL ClientPointers;
//} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION;
[StructLayout(LayoutKind.Sequential, Pack = 4)] // Pack=4 is important! So it works also for x64!
public struct MiniDumpExceptionInformation
{
public uint ThreadId;
public IntPtr ExceptionPointers;
[MarshalAs(UnmanagedType.Bool)]
public bool ClientPointers;
}
//BOOL
//WINAPI
//MiniDumpWriteDump(
// __in HANDLE hProcess,
// __in DWORD ProcessId,
// __in HANDLE hFile,
// __in MINIDUMP_TYPE DumpType,
// __in_opt PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
// __in_opt PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
// __in_opt PMINIDUMP_CALLBACK_INFORMATION CallbackParam
// );
// Overload requiring MiniDumpExceptionInformation
[DllImport("dbghelp.dll", EntryPoint = "MiniDumpWriteDump", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
private static extern bool MiniDumpWriteDump(IntPtr hProcess, uint processId, SafeHandle hFile, uint dumpType, ref MiniDumpExceptionInformation expParam, IntPtr userStreamParam, IntPtr callbackParam);
// Overload supporting MiniDumpExceptionInformation == NULL
[DllImport("dbghelp.dll", EntryPoint = "MiniDumpWriteDump", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
private static extern bool MiniDumpWriteDump(IntPtr hProcess, uint processId, SafeHandle hFile, uint dumpType, IntPtr expParam, IntPtr userStreamParam, IntPtr callbackParam);
[DllImport("kernel32.dll", EntryPoint = "GetCurrentThreadId", ExactSpelling = true)]
private static extern uint GetCurrentThreadId();
private static bool Write(SafeHandle fileHandle, Option options, bool withException = false)
{
var currentProcess = Process.GetCurrentProcess();
var currentProcessHandle = currentProcess.Handle;
var currentProcessId = (uint)currentProcess.Id;
MiniDumpExceptionInformation exp;
exp.ThreadId = GetCurrentThreadId();
exp.ClientPointers = false;
exp.ExceptionPointers = IntPtr.Zero;
if (withException)
exp.ExceptionPointers = Marshal.GetExceptionPointers();
var bRet = exp.ExceptionPointers == IntPtr.Zero
? MiniDumpWriteDump(currentProcessHandle, currentProcessId, fileHandle, (uint) options, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero)
: MiniDumpWriteDump(currentProcessHandle, currentProcessId, fileHandle, (uint) options, ref exp, IntPtr.Zero, IntPtr.Zero);
return bRet;
}
public static bool Dump(Option options = Option.WithFullMemory, bool withException = false)
{
lock (LockO)
{
// work around "stack trace is not available while minidump debugging",
// by making sure a local var (that we can inspect) contains the stack trace.
// getting the call stack before it is unwound would require a special exception
// filter everywhere in our code = not!
var stacktrace = withException ? Environment.StackTrace : string.Empty;
var filepath = IOHelper.MapPath("~/App_Data/MiniDump");
if (Directory.Exists(filepath) == false)
Directory.CreateDirectory(filepath);
var filename = Path.Combine(filepath, string.Format("{0:yyyyMMddTHHmmss}.{1}.dmp", DateTime.UtcNow, Guid.NewGuid().ToString("N").Substring(0, 4)));
using (var stream = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite, FileShare.Write))
{
return Write(stream.SafeFileHandle, options, withException);
}
}
}
public static bool OkToDump()
{
lock (LockO)
{
var filepath = IOHelper.MapPath("~/App_Data/MiniDump");
if (Directory.Exists(filepath) == false) return true;
var count = Directory.GetFiles(filepath, "*.dmp").Length;
return count < 8;
}
}
}
}
-17
View File
@@ -295,22 +295,5 @@ namespace Umbraco.Core
return list1Groups.Count == list2Groups.Count
&& list1Groups.All(g => g.Count() == list2Groups[g.Key].Count());
}
///<summary>
/// Returns the items of the given enumerable as a pure enumerable.
/// <remarks>
/// When quering lists using methods such as <see cref="M:List.Where"/>, the result, despite appearing to look like and quack like an
/// <see cref="T:Enumerable{T}"/> the type is actually an instance of <see cref="T:System.Linq.Enumerable.WhereEnumerableIterator"/>
/// </remarks>
/// </summary>
///<param name="source">The item to find.</param>
///<returns>The index of the first matching item, or -1 if the item was not found.</returns>
internal static IEnumerable<T> Yield<T>(this IEnumerable<T> source)
{
foreach (var element in source)
{
yield return element;
}
}
}
}
@@ -16,13 +16,17 @@ namespace Umbraco.Core.Events
protected override void ScopeExitCompleted()
{
// fixme - we'd need to de-duplicate events somehow, etc - and the deduplication should be last in wins
// processing only the last instance of each event...
// this is probably far from perfect, because if eg a content is saved in a list
// and then as a single content, the two events will probably not be de-duplicated,
// but it's better than nothing
foreach (var e in GetEvents(EventDefinitionFilter.All))
foreach (var e in GetEvents(EventDefinitionFilter.LastIn))
{
e.RaiseEvent();
// fixme - not sure I like doing it here - but then where? how?
// separating concerns means that this should probably not be here,
// but then where should it be (without making things too complicated)?
var delete = e.Args as IDeletingMediaFilesEventArgs;
if (delete != null && delete.MediaFilesToDelete.Count > 0)
MediaFileSystem.DeleteMediaFiles(delete.MediaFilesToDelete);
@@ -35,13 +39,7 @@ namespace Umbraco.Core.Events
{
get
{
if (_mediaFileSystem != null) return _mediaFileSystem;
// fixme - insane! reading config goes cross AppDomain and serializes context?
using (new SafeCallContext())
{
return _mediaFileSystem = FileSystemProviderManager.Current.MediaFileSystem;
}
return _mediaFileSystem ?? (_mediaFileSystem = FileSystemProviderManager.Current.MediaFileSystem);
}
}
}
@@ -45,7 +45,8 @@ namespace Umbraco.Core.IO
private IScopeProviderInternal ScopeProvider
{
// fixme - 'course this is bad, but enough for now
// this is bad, but enough for now, and we'll refactor
// in v8 when we'll get rid of this class' singleton
// beware: means that we capture the "current" scope provider - take care in tests!
get { return ApplicationContext.Current == null ? null : ApplicationContext.Current.ScopeProvider as IScopeProviderInternal; }
}
+2 -26
View File
@@ -302,7 +302,7 @@ namespace Umbraco.Core.IO
{
var property = GetProperty(content, propertyTypeAlias);
var svalue = property.Value as string;
var oldpath = svalue == null ? null : GetRelativePath(svalue); // FIXME DELETE?
var oldpath = svalue == null ? null : GetRelativePath(svalue);
if (string.IsNullOrWhiteSpace(oldpath) == false && oldpath != filepath)
DeleteFile(oldpath, true);
property.Value = GetUrl(filepath);
@@ -466,27 +466,6 @@ namespace Umbraco.Core.IO
var dir = Path.GetDirectoryName(file);
DeleteDirectory(dir, true);
}
// I don't even understand...
/*
var relativeFilePath = GetRelativePath(file); // fixme - should be relative already
if (FileExists(relativeFilePath) == false) return;
var parentDirectory = Path.GetDirectoryName(relativeFilePath);
// don't want to delete the media folder if not using directories.
if (_contentSection.UploadAllowDirectories && parentDirectory != GetRelativePath("/"))
{
//issue U4-771: if there is a parent directory the recursive parameter should be true
DeleteDirectory(parentDirectory, string.IsNullOrEmpty(parentDirectory) == false);
}
else
{
DeleteFile(file, true);
}
*/
}
catch (Exception e)
{
@@ -549,7 +528,7 @@ namespace Umbraco.Core.IO
PropertyType propertyType)
{
// get the original image from the original stream
if (filestream.CanSeek) filestream.Seek(0, 0); // fixme - what if we cannot seek?
if (filestream.CanSeek) filestream.Seek(0, 0);
using (var image = Image.FromStream(filestream))
{
return GenerateThumbnails(image, filepath, propertyType);
@@ -658,9 +637,6 @@ namespace Umbraco.Core.IO
var rect = new Rectangle(0, 0, width, height);
graphics.DrawImage(originImage, rect, 0, 0, originImage.Width, originImage.Height, GraphicsUnit.Pixel);
// copy metadata
// fixme - er... no?
// get an encoder - based upon the file type
var extension = (Path.GetExtension(resizedFilepath) ?? "").TrimStart('.').ToLowerInvariant();
var encoders = ImageCodecInfo.GetImageEncoders();
+6 -2
View File
@@ -155,7 +155,9 @@ namespace Umbraco.Core.IO
if (directory == null) throw new InvalidOperationException("Could not get directory.");
Directory.CreateDirectory(directory); // ensure it exists
if (stream.CanSeek) // fixme - what else?
// if can seek, be safe and go back to start, else...
// hope that the stream hasn't been read already
if (stream.CanSeek)
stream.Seek(0, 0);
using (var destination = (Stream) File.Create(fullPath))
@@ -286,7 +288,9 @@ namespace Umbraco.Core.IO
var opath = path;
path = EnsureDirectorySeparatorChar(path);
// fixme - this part should go!
// TODO in v8 this should be cleaned up
// the first part should probably removed
// not sure what we are doing here - so if input starts with a (back) slash,
// we assume it's not a FS relative path and we try to convert it... but it
// really makes little sense?
+59 -26
View File
@@ -218,11 +218,11 @@ namespace Umbraco.Core.IO
var normPath = NormPath(path);
var shadows = Nodes.Where(kvp => IsChild(normPath, kvp.Key)).ToArray();
var files = filter != null ? _fs.GetFiles(path, filter) : _fs.GetFiles(path);
var regexFilter = FilterToRegex(filter);
var wildcard = filter == null ? null : new WildcardExpression(filter);
return files
.Except(shadows.Where(kvp => (kvp.Value.IsFile && kvp.Value.IsDelete) || kvp.Value.IsDir)
.Select(kvp => kvp.Key))
.Union(shadows.Where(kvp => kvp.Value.IsFile && kvp.Value.IsExist && FilterByRegex(kvp.Key, regexFilter)).Select(kvp => kvp.Key))
.Union(shadows.Where(kvp => kvp.Value.IsFile && kvp.Value.IsExist && (wildcard == null || wildcard.IsMatch(kvp.Key))).Select(kvp => kvp.Key))
.Distinct();
}
@@ -326,32 +326,65 @@ namespace Umbraco.Core.IO
_sfs.AddFile(path, physicalPath, overrideIfExists, copy);
Nodes[normPath] = new ShadowNode(false, false);
}
/// <summary>
/// Helper function for filtering keys by Regex if a filter is specified.
/// </summary>
/// <param name="input"></param>
/// <param name="regexFilter"></param>
/// <returns></returns>
internal static bool FilterByRegex(string input, string regexFilter)
{
if (regexFilter == null) return true;
return regexFilter != string.Empty && Regex.IsMatch(input, regexFilter);
}
/// <summary>
/// Transforms a filter pattern into a Regex pattern
/// </summary>
/// <param name="pattern"></param>
/// <returns></returns>
/// <remarks>
/// Appending '$' only if not containing wildcard is stupid and broken.
/// It is however what seems to be what they're doing in .NET so we need to match the functionality.
/// </remarks>
internal static string FilterToRegex(string pattern)
// copied from System.Web.Util.Wildcard internal
internal class WildcardExpression
{
if (pattern == null) return null;
return "^" + Regex.Escape(pattern).Replace("\\*", ".*").Replace("\\?", ".") + (pattern.Contains("*") ? string.Empty : "$");
private readonly string _pattern;
private readonly bool _caseInsensitive;
private Regex _regex;
private static Regex metaRegex = new Regex("[\\+\\{\\\\\\[\\|\\(\\)\\.\\^\\$]");
private static Regex questRegex = new Regex("\\?");
private static Regex starRegex = new Regex("\\*");
private static Regex commaRegex = new Regex(",");
private static Regex slashRegex = new Regex("(?=/)");
private static Regex backslashRegex = new Regex("(?=[\\\\:])");
public WildcardExpression(string pattern, bool caseInsensitive = true)
{
_pattern = pattern;
_caseInsensitive = caseInsensitive;
}
private void EnsureRegex(string pattern)
{
if (_regex != null) return;
var options = RegexOptions.None;
// match right-to-left (for speed) if the pattern starts with a *
if (pattern.Length > 0 && pattern[0] == '*')
options = RegexOptions.RightToLeft | RegexOptions.Singleline;
else
options = RegexOptions.Singleline;
// case insensitivity
if (_caseInsensitive)
options |= RegexOptions.IgnoreCase | RegexOptions.CultureInvariant;
// Remove regex metacharacters
pattern = metaRegex.Replace(pattern, "\\$0");
// Replace wildcard metacharacters with regex codes
pattern = questRegex.Replace(pattern, ".");
pattern = starRegex.Replace(pattern, ".*");
pattern = commaRegex.Replace(pattern, "\\z|\\A");
// anchor the pattern at beginning and end, and return the regex
_regex = new Regex("\\A" + pattern + "\\z", options);
}
public bool IsMatch(string input)
{
EnsureRegex(_pattern);
return _regex.IsMatch(input);
}
}
}
}
+39 -5
View File
@@ -7,6 +7,8 @@ using System.Threading;
using System.Web;
using log4net;
using log4net.Config;
using Umbraco.Core.Configuration;
using Umbraco.Core.Diagnostics;
namespace Umbraco.Core.Logging
{
@@ -57,23 +59,55 @@ namespace Umbraco.Core.Logging
internal ILog LoggerFor(object getTypeFromInstance)
{
if (getTypeFromInstance == null) throw new ArgumentNullException("getTypeFromInstance");
return LogManager.GetLogger(getTypeFromInstance.GetType());
}
public void Error(Type callingType, string message, Exception exception)
{
var logger = LogManager.GetLogger(callingType);
if (logger == null) return;
var dump = false;
if (IsTimeoutThreadAbortException(exception))
{
message += "\r\nThe thread has been aborted, because the request has timed out.";
// dump if configured, or if stacktrace contains Monitor.ReliableEnter
dump = UmbracoConfig.For.CoreDebug().DumpOnTimeoutThreadAbort || IsMonitorEnterThreadAbortException(exception);
// dump if it is ok to dump (might have a cap on number of dump...)
dump &= MiniDump.OkToDump();
}
logger.Error(message, exception);
if (dump)
{
try
{
var dumped = MiniDump.Dump(withException: true);
message += dumped
? "\r\nA minidump was created in App_Data/MiniDump"
: "\r\nFailed to create a minidump";
}
catch (Exception e)
{
message += string.Format("\r\nFailed to create a minidump ({0}: {1})", e.GetType().FullName, e.Message);
}
}
logger.Error(message, exception);
}
private static bool IsMonitorEnterThreadAbortException(Exception exception)
{
var abort = exception as ThreadAbortException;
if (abort == null) return false;
var stacktrace = abort.StackTrace;
return stacktrace.Contains("System.Threading.Monitor.ReliableEnter");
}
private static bool IsTimeoutThreadAbortException(Exception exception)
{
var abort = exception as ThreadAbortException;
@@ -105,7 +139,7 @@ namespace Umbraco.Core.Logging
if (showHttpTrace && HttpContext.Current != null)
{
HttpContext.Current.Trace.Warn(callingType.Name, string.Format(message, formatItems.Select(x => x.Invoke()).ToArray()));
}
}
var logger = LogManager.GetLogger(callingType);
if (logger == null || logger.IsWarnEnabled == false) return;
@@ -122,7 +156,7 @@ namespace Umbraco.Core.Logging
var logger = LogManager.GetLogger(callingType);
if (logger == null || logger.IsWarnEnabled == false) return;
var executedParams = formatItems.Select(x => x.Invoke()).ToArray();
logger.WarnFormat((message) + ". Exception: " + e, executedParams);
logger.WarnFormat((message) + ". Exception: " + e, executedParams);
}
/// <summary>
+54 -4
View File
@@ -1,5 +1,7 @@
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using Umbraco.Core.Logging;
namespace Umbraco.Core.Models
{
@@ -84,16 +86,64 @@ namespace Umbraco.Core.Models
public string Type { get; set; }
private Type _runtimeType;
/// <summary>
/// Returns the CLR type based on it's assembly name stored in the config
/// </summary>
/// <returns></returns>
public Type GetRuntimeType()
{
return _runtimeType ?? (_runtimeType = System.Type.GetType(Type));
}
if (_runtimeType != null)
return _runtimeType;
_runtimeType = TryGetType(Type);
return _runtimeType;
}
/// <summary>
/// Used to try to get and cache the tree type
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
internal static Type TryGetType(string type)
{
try
{
return ResolvedTypes.GetOrAdd(type, s =>
{
var result = System.Type.GetType(type);
if (result != null)
{
return result;
}
//we need to implement a bit of a hack here due to some trees being renamed and backwards compat
var parts = type.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length == 2)
{
if (parts[1].Trim() == "umbraco" && parts[0].StartsWith("Umbraco.Web.Trees") && parts[0].EndsWith("Controller") == false)
{
//if it's one of our controllers but it's not suffixed with "Controller" then add it and try again
var tempType = parts[0] + "Controller, umbraco";
result = System.Type.GetType(tempType);
if (result != null)
{
return result;
}
}
}
throw new InvalidOperationException("Could not resolve type");
});
}
catch (InvalidOperationException)
{
//swallow, this is our own exception, couldn't find the type
return null;
}
}
private static readonly ConcurrentDictionary<string, Type> ResolvedTypes = new ConcurrentDictionary<string, Type>();
}
}
+3
View File
@@ -274,6 +274,9 @@ namespace Umbraco.Core.Models
/// </summary>
public bool HasPublishedVersion { get { return PublishedVersionGuid != default(Guid); } }
[IgnoreDataMember]
internal DateTime PublishedDate { get; set; }
/// <summary>
/// Changes the Trashed state of the content object
/// </summary>
+12 -13
View File
@@ -7,7 +7,6 @@ using System.Xml.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Core.IO;
using Umbraco.Core.Media;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Services;
@@ -42,7 +41,7 @@ namespace Umbraco.Core.Models
/// * The item exists and is published
/// * A call to ContentService.Save is made
/// * The item has not been modified whatsoever apart from changing it's published status from published to saved
///
///
/// In this case, there is no reason to make any database changes at all
/// </remarks>
internal static bool RequiresSaving(this IContent entity)
@@ -62,7 +61,7 @@ namespace Umbraco.Core.Models
/// * The item exists and is published
/// * A call to ContentService.Save is made
/// * The item has not been modified whatsoever apart from changing it's published status from published to saved
///
///
/// In this case, there is no reason to make any database changes at all
/// </remarks>
internal static bool RequiresSaving(this IContent entity, PublishedState publishedState)
@@ -70,7 +69,7 @@ namespace Umbraco.Core.Models
var publishedChanged = entity.IsPropertyDirty("Published") && publishedState != PublishedState.Unpublished;
//check if any user prop has changed
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
if (publishedChanged && entity.Published == false && propertyValueChanged == false)
@@ -302,9 +301,9 @@ namespace Umbraco.Core.Models
return content.Path.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Contains(recycleBinId.ToInvariantString());
}
/// <summary>
/// Removes characters that are not valide XML characters from all entity properties
/// Removes characters that are not valide XML characters from all entity properties
/// of type string. See: http://stackoverflow.com/a/961504/5018
/// </summary>
/// <returns></returns>
@@ -456,7 +455,7 @@ namespace Umbraco.Core.Models
/// <param name="value">The uploaded <see cref="HttpPostedFileBase"/>.</param>
public static void SetValue(this IContentBase content, string propertyTypeAlias, HttpPostedFileBase value)
{
// ensure we get the filename without the path in IE in intranet mode
// ensure we get the filename without the path in IE in intranet mode
// http://stackoverflow.com/questions/382464/httppostedfile-filename-different-from-ie
var filename = value.FileName;
var pos = filename.LastIndexOf(@"\", StringComparison.InvariantCulture);
@@ -468,10 +467,10 @@ namespace Umbraco.Core.Models
if (pos > 0)
filename = filename.Substring(pos + 1);
// get a safe filename - should this be done by MediaHelper?
// get a safe & clean filename
filename = IOHelper.SafeFileName(filename);
if (string.IsNullOrWhiteSpace(filename)) return;
filename = filename.ToLower(); // fixme - er... why?
filename = filename.ToLower();
FileSystemProviderManager.Current.MediaFileSystem.SetUploadFile(content, propertyTypeAlias, filename, value.InputStream);
}
@@ -513,10 +512,10 @@ namespace Umbraco.Core.Models
{
if (filename == null || filestream == null) return;
// get a safe filename - should this be done by MediaHelper?
// get a safe & clean filename
filename = IOHelper.SafeFileName(filename);
if (string.IsNullOrWhiteSpace(filename)) return;
filename = filename.ToLower(); // fixme - er... why?
filename = filename.ToLower();
FileSystemProviderManager.Current.MediaFileSystem.SetUploadFile(content, propertyTypeAlias, filename, filestream);
}
@@ -548,7 +547,7 @@ namespace Umbraco.Core.Models
#endregion
#region User/Profile methods
/// <summary>
/// Gets the <see cref="IProfile"/> for the Creator of this media item.
/// </summary>
@@ -623,7 +622,7 @@ namespace Umbraco.Core.Models
///// <param name="tagGroup"></param>
///// <returns></returns>
///// <remarks>
///// The tags returned are only relavent for published content & saved media or members
///// The tags returned are only relavent for published content & saved media or members
///// </remarks>
//public static IEnumerable<ITag> GetTags(this IContentBase content, string propertyTypeAlias, string tagGroup = "default")
//{
@@ -1,85 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Services;
namespace Umbraco.Core.Models
{
//fixme: This whole thing needs to go, it's super hacky and doens't need to exist in the first place
internal static class ContentTypeExtensions
{
/// <summary>
/// Get all descendant content types
/// </summary>
/// <param name="contentType"></param>
/// <param name="contentTypeService"></param>
/// <returns></returns>
public static IEnumerable<IContentTypeBase> Descendants(this IContentTypeBase contentType, IContentTypeService contentTypeService)
{
if (contentType is IContentType)
{
var descendants = contentTypeService.GetContentTypeChildren(contentType.Id)
.SelectRecursive(type => contentTypeService.GetContentTypeChildren(type.Id));
return descendants;
}
if (contentType is IMediaType)
{
var descendants = contentTypeService.GetMediaTypeChildren(contentType.Id)
.SelectRecursive(type => contentTypeService.GetMediaTypeChildren(type.Id));
return descendants;
}
//No other content types have children (i.e. member types)
return Enumerable.Empty<IContentTypeBase>();
}
/// <summary>
/// Get all descendant content types
/// </summary>
/// <param name="contentType"></param>
/// <param name="contentTypeService"></param>
/// <returns></returns>
public static IEnumerable<IContentTypeBase> Descendants(this IContentTypeBase contentType, ContentTypeServiceBase contentTypeService)
{
var cService = contentTypeService as IContentTypeService;
return cService == null ? Enumerable.Empty<IContentTypeBase>() : contentType.Descendants(cService);
}
/// <summary>
/// Get all descendant and self content types
/// </summary>
/// <param name="contentType"></param>
/// <param name="contentTypeService"></param>
/// <returns></returns>
public static IEnumerable<IContentTypeBase> DescendantsAndSelf(this IContentTypeBase contentType, IContentTypeService contentTypeService)
{
var descendantsAndSelf = new[] { contentType }.Concat(contentType.Descendants(contentTypeService));
return descendantsAndSelf;
}
/// <summary>
/// Get all descendant and self content types
/// </summary>
/// <param name="contentType"></param>
/// <param name="contentTypeService"></param>
/// <returns></returns>
public static IEnumerable<IContentTypeBase> DescendantsAndSelf(this IContentTypeBase contentType, ContentTypeServiceBase contentTypeService)
{
var descendantsAndSelf = new[] { contentType }.Concat(contentType.Descendants(contentTypeService));
return descendantsAndSelf;
}
///// <summary>
///// Returns the descendant content type Ids for the given content type
///// </summary>
///// <param name="contentType"></param>
///// <returns></returns>
//public static IEnumerable<int> DescendantIds(this IContentTypeBase contentType)
//{
// return ((ContentTypeService) ApplicationContext.Current.Services.ContentTypeService)
// .GetDescendantContentTypeIds(contentType.Id);
//}
}
}
+4 -1
View File
@@ -49,7 +49,10 @@ namespace Umbraco.Core.Models
return path
.Replace('\\', System.IO.Path.DirectorySeparatorChar)
.Replace('/', System.IO.Path.DirectorySeparatorChar);
//.TrimStart(System.IO.Path.DirectorySeparatorChar);
//Don't strip the start - this was a bug fixed in 7.3, see ScriptRepositoryTests.PathTests
//.TrimStart(System.IO.Path.DirectorySeparatorChar)
//.TrimStart('/');
}
/// <summary>
@@ -179,7 +179,7 @@ namespace Umbraco.Core.Models.PublishedContent
}
if (contentType == null)
throw new Exception(string.Format("ContentTypeService failed to find a {0} type with alias \"{1}\".",
throw new InvalidOperationException(string.Format("ContentTypeService failed to find a {0} type with alias \"{1}\".",
itemType.ToString().ToLower(), alias));
return new PublishedContentType(contentType);
@@ -19,5 +19,8 @@ namespace Umbraco.Core.Models.Rdbms
[Column("newest")]
public bool Newest { get; set; }
[Column("updateDate")]
public DateTime VersionDate { get; set; }
}
}
@@ -22,6 +22,7 @@ namespace Umbraco.Core.ObjectResolution
private readonly string _httpContextKey;
private readonly List<Type> _instanceTypes = new List<Type>();
private IEnumerable<TResolved> _sortedValues;
private readonly Func<HttpContextBase> _httpContextGetter;
private int _defaultPluginWeight = 100;
@@ -42,12 +43,7 @@ namespace Umbraco.Core.ObjectResolution
if (logger == null) throw new ArgumentNullException("logger");
CanResolveBeforeFrozen = false;
if (scope == ObjectLifetimeScope.HttpRequest)
{
if (HttpContext.Current == null)
throw new InvalidOperationException("Use alternative constructor accepting a HttpContextBase object in order to set the lifetime scope to HttpRequest when HttpContext.Current is null");
CurrentHttpContext = new HttpContextWrapper(HttpContext.Current);
}
_httpContextGetter = () => new HttpContextWrapper(HttpContext.Current);
ServiceProvider = serviceProvider;
Logger = logger;
@@ -84,7 +80,7 @@ namespace Umbraco.Core.ObjectResolution
LifetimeScope = ObjectLifetimeScope.HttpRequest;
_httpContextKey = GetType().FullName;
ServiceProvider = serviceProvider;
CurrentHttpContext = httpContext;
_httpContextGetter = () => httpContext;
_instanceTypes = new List<Type>();
InitializeAppInstances();
@@ -160,7 +156,16 @@ namespace Umbraco.Core.ObjectResolution
/// Gets or sets the <see cref="HttpContextBase"/> used to initialize this object, if any.
/// </summary>
/// <remarks>If not null, then <c>LifetimeScope</c> will be <c>ObjectLifetimeScope.HttpRequest</c>.</remarks>
protected HttpContextBase CurrentHttpContext { get; private set; }
protected HttpContextBase CurrentHttpContext
{
get
{
var context = _httpContextGetter == null ? null : _httpContextGetter();
if (context == null)
throw new InvalidOperationException("Cannot use this resolver with lifetime 'HttpRequest' when there is no current HttpContext. Either use the ctor accepting an HttpContextBase, or use the resolver from within a request exclusively.");
return context;
}
}
/// <summary>
/// Returns the service provider used to instantiate objects
@@ -196,7 +201,7 @@ namespace Umbraco.Core.ObjectResolution
/// <summary>
/// Gets or sets the default type weight.
/// </summary>
/// <remarks>Determines the weight of types that do not have a <c>WeightAttribute</c> set on
/// <remarks>Determines the weight of types that do not have a <c>WeightAttribute</c> set on
/// them, when calling <c>GetSortedValues</c>.</remarks>
protected virtual int DefaultPluginWeight
{
@@ -276,7 +281,7 @@ namespace Umbraco.Core.ObjectResolution
/// Removes a type.
/// </summary>
/// <param name="value">The type to remove.</param>
/// <exception cref="InvalidOperationException">the resolver does not support removing types, or
/// <exception cref="InvalidOperationException">the resolver does not support removing types, or
/// the type is not a valid type for the resolver.</exception>
public virtual void RemoveType(Type value)
{
@@ -296,7 +301,7 @@ namespace Umbraco.Core.ObjectResolution
/// Removes a type.
/// </summary>
/// <typeparam name="T">The type to remove.</typeparam>
/// <exception cref="InvalidOperationException">the resolver does not support removing types, or
/// <exception cref="InvalidOperationException">the resolver does not support removing types, or
/// the type is not a valid type for the resolver.</exception>
public void RemoveType<T>()
where T : TResolved
@@ -309,7 +314,7 @@ namespace Umbraco.Core.ObjectResolution
/// </summary>
/// <param name="types">The types to add.</param>
/// <remarks>The types are appended at the end of the list.</remarks>
/// <exception cref="InvalidOperationException">the resolver does not support adding types, or
/// <exception cref="InvalidOperationException">the resolver does not support adding types, or
/// a type is not a valid type for the resolver, or a type is already in the collection of types.</exception>
protected void AddTypes(IEnumerable<Type> types)
{
@@ -336,7 +341,7 @@ namespace Umbraco.Core.ObjectResolution
/// </summary>
/// <param name="value">The type to add.</param>
/// <remarks>The type is appended at the end of the list.</remarks>
/// <exception cref="InvalidOperationException">the resolver does not support adding types, or
/// <exception cref="InvalidOperationException">the resolver does not support adding types, or
/// the type is not a valid type for the resolver, or the type is already in the collection of types.</exception>
public virtual void AddType(Type value)
{
@@ -362,7 +367,7 @@ namespace Umbraco.Core.ObjectResolution
/// </summary>
/// <typeparam name="T">The type to add.</typeparam>
/// <remarks>The type is appended at the end of the list.</remarks>
/// <exception cref="InvalidOperationException">the resolver does not support adding types, or
/// <exception cref="InvalidOperationException">the resolver does not support adding types, or
/// the type is not a valid type for the resolver, or the type is already in the collection of types.</exception>
public void AddType<T>()
where T : TResolved
@@ -404,7 +409,7 @@ namespace Umbraco.Core.ObjectResolution
/// </summary>
/// <param name="index">The zero-based index at which the type should be inserted.</param>
/// <param name="value">The type to insert.</param>
/// <exception cref="InvalidOperationException">the resolver does not support inserting types, or
/// <exception cref="InvalidOperationException">the resolver does not support inserting types, or
/// the type is not a valid type for the resolver, or the type is already in the collection of types.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> is out of range.</exception>
public virtual void InsertType(int index, Type value)
@@ -430,7 +435,7 @@ namespace Umbraco.Core.ObjectResolution
/// Inserts a type at the beginning of the list.
/// </summary>
/// <param name="value">The type to insert.</param>
/// <exception cref="InvalidOperationException">the resolver does not support inserting types, or
/// <exception cref="InvalidOperationException">the resolver does not support inserting types, or
/// the type is not a valid type for the resolver, or the type is already in the collection of types.</exception>
public virtual void InsertType(Type value)
{
@@ -464,7 +469,7 @@ namespace Umbraco.Core.ObjectResolution
/// </summary>
/// <param name="existingType">The existing type before which to insert.</param>
/// <param name="value">The type to insert.</param>
/// <exception cref="InvalidOperationException">the resolver does not support inserting types, or
/// <exception cref="InvalidOperationException">the resolver does not support inserting types, or
/// one of the types is not a valid type for the resolver, or the existing type is not in the collection,
/// or the new type is already in the collection of types.</exception>
public virtual void InsertTypeBefore(Type existingType, Type value)
@@ -498,7 +503,7 @@ namespace Umbraco.Core.ObjectResolution
/// </summary>
/// <typeparam name="TExisting">The existing type before which to insert.</typeparam>
/// <typeparam name="T">The type to insert.</typeparam>
/// <exception cref="InvalidOperationException">the resolver does not support inserting types, or
/// <exception cref="InvalidOperationException">the resolver does not support inserting types, or
/// one of the types is not a valid type for the resolver, or the existing type is not in the collection,
/// or the new type is already in the collection of types.</exception>
public void InsertTypeBefore<TExisting, T>()
@@ -72,6 +72,9 @@ namespace Umbraco.Core.Persistence.Factories
content.PublishedVersionGuid = publishedDto == null
? (dto.DocumentPublishedReadOnlyDto == null ? default(Guid) : dto.DocumentPublishedReadOnlyDto.VersionId)
: publishedDto.VersionId;
content.PublishedDate = publishedDto == null
? (dto.DocumentPublishedReadOnlyDto == null ? default(DateTime) : dto.DocumentPublishedReadOnlyDto.VersionDate)
: publishedDto.VersionDate;
//on initial construction we don't want to have dirty properties tracked
// http://issues.umbraco.org/issue/U4-1946
@@ -1,6 +1,5 @@
using System.Linq;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenSixZero
@@ -1,6 +1,5 @@
using System.Linq;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenSixZero
@@ -1,6 +1,5 @@
using System;
using System.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.SqlSyntax;
@@ -44,7 +43,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenSixZero
private static string UpdateMacroGuids(Database database)
{
var updates = database.Query<dynamic>("SELECT id, macroAlias FROM cmsMacro")
.Select(macro => Tuple.Create((int) macro.id, ((string) macro.macroAlias).ToGuid()))
.Select(macro => Tuple.Create((int) macro.id, ("macro____" + (string) macro.macroAlias).ToGuid()))
.ToList();
foreach (var update in updates)
@@ -58,7 +57,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenSixZero
var updates = database.Query<dynamic>(@"SELECT cmsMacroProperty.id id, macroPropertyAlias propertyAlias, cmsMacro.macroAlias macroAlias
FROM cmsMacroProperty
JOIN cmsMacro ON cmsMacroProperty.macro=cmsMacro.id")
.Select(prop => Tuple.Create((int) prop.id, ((string) prop.macroAlias + "____" + (string) prop.propertyAlias).ToGuid()))
.Select(prop => Tuple.Create((int) prop.id, ("macro____" + (string) prop.macroAlias + "____" + (string) prop.propertyAlias).ToGuid()))
.ToList();
foreach (var update in updates)
@@ -1,6 +1,5 @@
using System;
using System.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.SqlSyntax;
@@ -32,7 +31,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenSixZero
private static string UpdateRelationTypeGuids(Database database)
{
var updates = database.Query<dynamic>("SELECT id, alias, name FROM umbracoRelationType")
.Select(relationType => Tuple.Create((int) relationType.id, ((string) relationType.alias + "____" + (string) relationType.name).ToGuid()))
.Select(relationType => Tuple.Create((int) relationType.id, ("relationType____" + (string) relationType.alias + "____" + (string) relationType.name).ToGuid()))
.ToList();
foreach (var update in updates)
@@ -1,5 +1,4 @@
using System.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.SqlSyntax;
@@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.SqlSyntax;
@@ -513,11 +513,13 @@ namespace Umbraco.Core.Persistence.Repositories
dto.DocumentPublishedReadOnlyDto = new DocumentPublishedReadOnlyDto
{
VersionId = dto.VersionId,
VersionDate = dto.UpdateDate,
Newest = true,
NodeId = dto.NodeId,
Published = true
Published = true
};
((Content)entity).PublishedVersionGuid = dto.VersionId;
((Content) entity).PublishedVersionGuid = dto.VersionId;
((Content) entity).PublishedDate = dto.UpdateDate;
}
entity.ResetDirtyProperties();
@@ -688,22 +690,26 @@ namespace Umbraco.Core.Persistence.Repositories
dto.DocumentPublishedReadOnlyDto = new DocumentPublishedReadOnlyDto
{
VersionId = dto.VersionId,
VersionDate = dto.UpdateDate,
Newest = true,
NodeId = dto.NodeId,
Published = true
};
((Content)entity).PublishedVersionGuid = dto.VersionId;
((Content) entity).PublishedVersionGuid = dto.VersionId;
((Content) entity).PublishedDate = dto.UpdateDate;
}
else if (publishedStateChanged)
{
dto.DocumentPublishedReadOnlyDto = new DocumentPublishedReadOnlyDto
{
VersionId = default(Guid),
VersionId = default (Guid),
VersionDate = default (DateTime),
Newest = false,
NodeId = dto.NodeId,
Published = false
};
((Content)entity).PublishedVersionGuid = default(Guid);
((Content) entity).PublishedVersionGuid = default(Guid);
((Content) entity).PublishedDate = default (DateTime);
}
entity.ResetDirtyProperties();
@@ -975,7 +981,7 @@ order by umbracoNode.{2}, umbracoNode.parentID, umbracoNode.sortOrder",
}
//order by update date DESC, if there is corrupted published flags we only want the latest!
var publishedSql = new Sql(@"SELECT cmsDocument.nodeId, cmsDocument.published, cmsDocument.versionId, cmsDocument.newest
var publishedSql = new Sql(@"SELECT cmsDocument.nodeId, cmsDocument.published, cmsDocument.versionId, cmsDocument.updateDate, cmsDocument.newest
FROM cmsDocument INNER JOIN cmsContentVersion ON cmsContentVersion.VersionId = cmsDocument.versionId
WHERE cmsDocument.published = 1 AND cmsDocument.nodeId IN
(" + parsedOriginalSql + @")
@@ -101,7 +101,8 @@ namespace Umbraco.Core.Persistence.Repositories
var translator = new SqlTranslator<PropertyType>(sqlClause, query);
var sql = translator.Translate()
.OrderBy<PropertyTypeDto>(x => x.PropertyTypeGroupId, SqlSyntax);
//must be sorted this way for the relator to work
.OrderBy<PropertyTypeGroupDto>(x => x.Id, SqlSyntax);
var dtos = Database.Fetch<PropertyTypeGroupDto, PropertyTypeDto, DataTypeDto, PropertyTypeGroupDto>(new GroupPropertyTypeRelator().Map, sql);
@@ -468,7 +469,8 @@ AND umbracoNode.id <> @id",
.LeftJoin<DataTypeDto>()
.On<PropertyTypeDto, DataTypeDto>(left => left.DataTypeId, right => right.DataTypeId)
.Where<PropertyTypeGroupDto>(x => x.ContentTypeNodeId == id)
.OrderBy<PropertyTypeGroupDto>(x => x.Id);
//must be sorted this way for the relator to work
.OrderBy<PropertyTypeGroupDto>(x => x.Id, SqlSyntax);
var dtos = Database.Fetch<PropertyTypeGroupDto, PropertyTypeDto, DataTypeDto, PropertyTypeGroupDto>(new GroupPropertyTypeRelator().Map, sql);
@@ -1250,5 +1252,19 @@ WHERE cmsContentType." + aliasColumn + @" LIKE @pattern",
while (aliases.Contains(test = alias + i)) i++;
return test;
}
/// <summary>
/// Given the path of a content item, this will return true if the content item exists underneath a list view content item
/// </summary>
/// <param name="contentPath"></param>
/// <returns></returns>
public bool HasContainerInPath(string contentPath)
{
var ids = contentPath.Split(',').Select(int.Parse);
var sql = new Sql(@"SELECT COUNT(*) FROM cmsContentType
INNER JOIN cmsContent ON cmsContentType.nodeId=cmsContent.contentType
WHERE cmsContent.nodeId IN (@ids) AND cmsContentType.isContainer=@isContainer", new { ids, isContainer = true });
return Database.ExecuteScalar<int>(sql) > 0;
}
}
}
@@ -276,47 +276,33 @@ AND umbracoNode.id <> @id",
public PreValueCollection GetPreValuesCollectionByDataTypeId(int dataTypeId)
{
var cached = IsolatedCache.GetCacheItemsByKeySearch<PreValueCollection>(GetPrefixedCacheKey(dataTypeId));
if (cached != null && cached.Any())
{
//return from the cache, ensure it's a cloned result
return (PreValueCollection)cached.First().DeepClone();
}
return GetAndCachePreValueCollection(dataTypeId);
}
internal static string GetCacheKeyRegex(int preValueId)
{
return CacheKeys.DataTypePreValuesCacheKey + @"[-\d]+-([\d]*,)*" + preValueId + @"(?!\d)[,\d$]*";
var collection = GetCachedPreValueCollection(dataTypeId);
return collection;
}
/// <summary>
/// Gets a specific PreValue by its Id
/// </summary>
/// <param name="preValueId">Id of the PreValue to retrieve the value from</param>
/// <returns>PreValue as a string</returns>
public string GetPreValueAsString(int preValueId)
{
//We need to see if we can find the cached PreValueCollection based on the cache key above
var collections = IsolatedCache.GetCacheItemsByKeySearch<PreValueCollection>(CacheKeys.DataTypePreValuesCacheKey + "_");
var cached = IsolatedCache.GetCacheItemsByKeyExpression<PreValueCollection>(GetCacheKeyRegex(preValueId));
if (cached != null && cached.Any())
{
//return from the cache
var collection = cached.First();
var preVal = collection.FormatAsDictionary().Single(x => x.Value.Id == preValueId);
return preVal.Value.Value;
}
var preValue = collections.SelectMany(x => x.FormatAsDictionary().Values).FirstOrDefault(x => x.Id == preValueId);
if (preValue != null)
return preValue.Value;
//go and find the data type id for the pre val id passed in
var dto = Database.FirstOrDefault<DataTypePreValueDto>("WHERE id = @preValueId", new { preValueId = preValueId });
var dto = Database.FirstOrDefault<DataTypePreValueDto>("WHERE id = @preValueId", new { preValueId });
if (dto == null)
{
return string.Empty;
}
// go cache the collection
var preVals = GetAndCachePreValueCollection(dto.DataTypeNodeId);
//return the single value for this id
var pv = preVals.FormatAsDictionary().Single(x => x.Value.Id == preValueId);
return pv.Value.Value;
var collection = GetCachedPreValueCollection(dto.DataTypeNodeId);
if (collection == null)
return string.Empty;
preValue = collection.FormatAsDictionary().Values.FirstOrDefault(x => x.Id == preValueId);
return preValue == null ? string.Empty : preValue.Value;
}
public void AddOrUpdatePreValues(int dataTypeId, IDictionary<string, PreValue> values)
@@ -441,40 +427,28 @@ AND umbracoNode.id <> @id",
sortOrder++;
}
}
private string GetPrefixedCacheKey(int dataTypeId)
private static string GetPrefixedCacheKey(int dataTypeId)
{
return CacheKeys.DataTypePreValuesCacheKey + dataTypeId + "-";
return CacheKeys.DataTypePreValuesCacheKey + "_" + dataTypeId;
}
private PreValueCollection GetAndCachePreValueCollection(int dataTypeId)
private PreValueCollection GetCachedPreValueCollection(int datetypeId)
{
//go get the data
var dtos = Database.Fetch<DataTypePreValueDto>("WHERE datatypeNodeId = @Id", new { Id = dataTypeId });
var list = dtos.Select(x => new Tuple<PreValue, string, int>(new PreValue(x.Id, x.Value, x.SortOrder), x.Alias, x.SortOrder)).ToList();
var collection = PreValueConverter.ConvertToPreValuesCollection(list);
//now create the cache key, this needs to include all pre-value ids so that we can use this cached item in the GetPreValuesAsString method
//the key will be: "UmbracoPreValDATATYPEID-CSVOFPREVALIDS
var key = GetPrefixedCacheKey(dataTypeId)
+ string.Join(",", collection.FormatAsDictionary().Select(x => x.Value.Id).ToArray());
//store into cache
IsolatedCache.InsertCacheItem(key, () => collection,
//30 mins
new TimeSpan(0, 0, 30),
//sliding is true
true);
return collection;
var key = GetPrefixedCacheKey(datetypeId);
return IsolatedCache.GetCacheItem<PreValueCollection>(key, () =>
{
var dtos = Database.Fetch<DataTypePreValueDto>("WHERE datatypeNodeId = @Id", new { Id = datetypeId });
var list = dtos.Select(x => new Tuple<PreValue, string, int>(new PreValue(x.Id, x.Value, x.SortOrder), x.Alias, x.SortOrder)).ToList();
var collection = PreValueConverter.ConvertToPreValuesCollection(list);
return collection;
}, TimeSpan.FromMinutes(20), isSliding: true);
}
private string EnsureUniqueNodeName(string nodeName, int id = 0)
{
var sql = new Sql();
sql.Select("*")
@@ -575,7 +549,7 @@ AND umbracoNode.id <> @id",
}
//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
// 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
@@ -595,10 +569,10 @@ AND umbracoNode.id <> @id",
{
throw new InvalidOperationException("Cannot update a pre value for a data type that has no identity");
}
//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
// 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
@@ -613,7 +587,7 @@ AND umbracoNode.id <> @id",
Database.Update(dto);
}
}
internal static class PreValueConverter
@@ -41,6 +41,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
var sql = GetBaseQuery(false)
.Where(GetBaseWhereClause(), new { Id = id })
//must be sorted this way for the relator to work
.OrderBy<DictionaryDto>(x => x.UniqueId, SqlSyntax);
var dto = Database.Fetch<DictionaryDto, LanguageTextDto, DictionaryDto>(new DictionaryLanguageTextRelator().Map, sql).FirstOrDefault();
@@ -64,6 +65,9 @@ namespace Umbraco.Core.Persistence.Repositories
sql.Where("cmsDictionary.pk in (@ids)", new { ids = ids });
}
//must be sorted this way for the relator to work
sql.OrderBy<DictionaryDto>(x => x.UniqueId, SqlSyntax);
return Database.Fetch<DictionaryDto, LanguageTextDto, DictionaryDto>(new DictionaryLanguageTextRelator().Map, sql)
.Select(dto => ConvertFromDto(dto));
}
@@ -73,6 +77,7 @@ namespace Umbraco.Core.Persistence.Repositories
var sqlClause = GetBaseQuery(false);
var translator = new SqlTranslator<IDictionaryItem>(sqlClause, query);
var sql = translator.Translate();
//must be sorted this way for the relator to work
sql.OrderBy<DictionaryDto>(x => x.UniqueId, SqlSyntax);
return Database.Fetch<DictionaryDto, LanguageTextDto, DictionaryDto>(new DictionaryLanguageTextRelator().Map, sql)
@@ -94,9 +99,9 @@ namespace Umbraco.Core.Persistence.Repositories
else
{
sql.Select("*")
.From<DictionaryDto>(SqlSyntax)
.LeftJoin<LanguageTextDto>(SqlSyntax)
.On<DictionaryDto, LanguageTextDto>(SqlSyntax, left => left.UniqueId, right => right.UniqueId);
.From<DictionaryDto>(SqlSyntax)
.LeftJoin<LanguageTextDto>(SqlSyntax)
.On<DictionaryDto, LanguageTextDto>(SqlSyntax, left => left.UniqueId, right => right.UniqueId);
}
return sql;
}
@@ -270,6 +275,8 @@ namespace Umbraco.Core.Persistence.Repositories
var translator = new SqlTranslator<IDictionaryItem>(sqlClause, Query<IDictionaryItem>.Builder);
var sql = translator.Translate();
//must be sorted this way for the relator to work
sql.OrderBy<DictionaryDto>(x => x.UniqueId, SqlSyntax);
return Database.Fetch<DictionaryDto, LanguageTextDto, DictionaryDto>(new DictionaryLanguageTextRelator().Map, sql)
@@ -297,6 +304,9 @@ namespace Umbraco.Core.Persistence.Repositories
protected override IEnumerable<DictionaryDto> PerformFetch(Sql sql)
{
//must be sorted this way for the relator to work
sql.OrderBy<DictionaryDto>(x => x.UniqueId, SqlSyntax);
return Database.Fetch<DictionaryDto, LanguageTextDto, DictionaryDto>(new DictionaryLanguageTextRelator().Map, sql);
}
@@ -349,6 +359,9 @@ namespace Umbraco.Core.Persistence.Repositories
protected override IEnumerable<DictionaryDto> PerformFetch(Sql sql)
{
//must be sorted this way for the relator to work
sql.OrderBy<DictionaryDto>(x => x.UniqueId, SqlSyntax);
return Database.Fetch<DictionaryDto, LanguageTextDto, DictionaryDto>(new DictionaryLanguageTextRelator().Map, sql);
}
@@ -8,6 +8,13 @@ namespace Umbraco.Core.Persistence.Repositories
{
public interface IContentTypeRepository : IContentTypeCompositionRepository<IContentType>
{
/// <summary>
/// Given the path of a content item, this will return true if the content item exists underneath a list view content item
/// </summary>
/// <param name="contentPath"></param>
/// <returns></returns>
bool HasContainerInPath(string contentPath);
/// <summary>
/// Gets all entities of the specified <see cref="PropertyType"/> query
/// </summary>
@@ -37,6 +37,9 @@ namespace Umbraco.Core.Persistence.Repositories
private IMacro GetBySql(Sql sql)
{
//must be sorted this way for the relator to work
sql.OrderBy<MacroDto>(x => x.Id, SqlSyntax);
var macroDto = Database.Fetch<MacroDto, MacroPropertyDto, MacroDto>(new MacroPropertyRelator().Map, sql).FirstOrDefault();
if (macroDto == null)
return null;
@@ -68,7 +71,10 @@ namespace Umbraco.Core.Persistence.Repositories
private IEnumerable<IMacro> GetAllNoIds()
{
var sql = GetBaseQuery(false);
var sql = GetBaseQuery(false)
//must be sorted this way for the relator to work
.OrderBy<MacroDto>(x => x.Id, SqlSyntax);
return ConvertFromDtos(Database.Fetch<MacroDto, MacroPropertyDto, MacroDto>(new MacroPropertyRelator().Map, sql))
.ToArray();// we don't want to re-iterate again!
}
@@ -92,6 +98,9 @@ namespace Umbraco.Core.Persistence.Repositories
var translator = new SqlTranslator<IMacro>(sqlClause, query);
var sql = translator.Translate();
//must be sorted this way for the relator to work
sql.OrderBy<MacroDto>(x => x.Id, SqlSyntax);
var dtos = Database.Fetch<MacroDto, MacroPropertyDto, MacroDto>(new MacroPropertyRelator().Map, sql);
foreach (var dto in dtos)
@@ -114,13 +123,13 @@ namespace Umbraco.Core.Persistence.Repositories
return sql;
}
private static Sql GetBaseQuery()
private Sql GetBaseQuery()
{
var sql = new Sql();
sql.Select("*")
.From<MacroDto>()
.LeftJoin<MacroPropertyDto>()
.On<MacroDto, MacroPropertyDto>(left => left.Id, right => right.Macro);
.From<MacroDto>()
.LeftJoin<MacroPropertyDto>()
.On<MacroDto, MacroPropertyDto>(left => left.Id, right => right.Macro);
return sql;
}
@@ -46,7 +46,9 @@ namespace Umbraco.Core.Persistence.Repositories
var statement = string.Join(" OR ", ids.Select(x => string.Format("umbracoNode.id='{0}'", x)));
sql.Where(statement);
}
sql.OrderByDescending<NodeDto>(x => x.NodeId, SqlSyntax);
//must be sorted this way for the relator to work
sql.OrderBy<MemberTypeReadOnlyDto>(x => x.UniqueId, SqlSyntax);
var dtos =
Database.Fetch<MemberTypeReadOnlyDto, PropertyTypeReadOnlyDto, PropertyTypeGroupReadOnlyDto, MemberTypeReadOnlyDto>(
@@ -62,7 +64,8 @@ namespace Umbraco.Core.Persistence.Repositories
var subquery = translator.Translate();
var sql = GetBaseQuery(false)
.Append(new Sql("WHERE umbracoNode.id IN (" + subquery.SQL + ")", subquery.Arguments))
.OrderBy<NodeDto>(x => x.SortOrder, SqlSyntax);
//must be sorted this way for the relator to work
.OrderBy<MemberTypeReadOnlyDto>(x => x.UniqueId, SqlSyntax);
var dtos =
Database.Fetch<MemberTypeReadOnlyDto, PropertyTypeReadOnlyDto, PropertyTypeGroupReadOnlyDto, MemberTypeReadOnlyDto>(
@@ -31,7 +31,7 @@ namespace Umbraco.Core.Persistence.Repositories
/// </summary>
protected internal new IScopeUnitOfWork UnitOfWork
{
get { return (IScopeUnitOfWork)base.UnitOfWork; }
get { return base.UnitOfWork; }
}
protected UmbracoDatabase Database
@@ -75,10 +75,5 @@ namespace Umbraco.Core.Persistence.Repositories
Database.Execute(delete, new { Id = GetEntityId(entity) });
}
}
protected virtual TId GetEntityId(TEntity entity)
{
return (TId)(object)entity.Id;
}
}
}
@@ -40,7 +40,10 @@ namespace Umbraco.Core.Persistence.Repositories
}
var factory = new PublicAccessEntryFactory();
//MUST be ordered by this GUID ID for the AccessRulesRelator to work
sql.OrderBy<AccessDto>(dto => dto.Id, SqlSyntax);
var dtos = Database.Fetch<AccessDto, AccessRuleDto, AccessDto>(new AccessRulesRelator().Map, sql);
return dtos.Select(factory.BuildEntity);
}
@@ -52,7 +55,10 @@ namespace Umbraco.Core.Persistence.Repositories
var sql = translator.Translate();
var factory = new PublicAccessEntryFactory();
//MUST be ordered by this GUID ID for the AccessRulesRelator to work
sql.OrderBy<AccessDto>(dto => dto.Id, SqlSyntax);
var dtos = Database.Fetch<AccessDto, AccessRuleDto, AccessDto>(new AccessRulesRelator().Map, sql);
return dtos.Select(factory.BuildEntity);
}
@@ -63,9 +69,8 @@ namespace Umbraco.Core.Persistence.Repositories
sql.Select("*")
.From<AccessDto>(SqlSyntax)
.LeftJoin<AccessRuleDto>(SqlSyntax)
.On<AccessDto, AccessRuleDto>(SqlSyntax, left => left.Id, right => right.AccessId)
//MUST be ordered by this GUID ID for the AccessRulesRelator to work
.OrderBy<AccessDto>(dto => dto.Id, SqlSyntax);
.On<AccessDto, AccessRuleDto>(SqlSyntax, left => left.Id, right => right.AccessId);
return sql;
}
@@ -13,10 +13,10 @@ namespace Umbraco.Core.Persistence.Repositories
{
internal abstract class RepositoryBase : DisposableObject
{
private readonly IUnitOfWork _work;
private readonly IScopeUnitOfWork _work;
private readonly CacheHelper _globalCache;
protected RepositoryBase(IUnitOfWork work, CacheHelper cache, ILogger logger)
protected RepositoryBase(IScopeUnitOfWork work, CacheHelper cache, ILogger logger)
{
if (work == null) throw new ArgumentNullException("work");
if (cache == null) throw new ArgumentNullException("cache");
@@ -29,7 +29,7 @@ namespace Umbraco.Core.Persistence.Repositories
/// <summary>
/// Returns the Unit of Work added to the repository
/// </summary>
protected internal IUnitOfWork UnitOfWork
protected internal IScopeUnitOfWork UnitOfWork
{
get { return _work; }
}
@@ -76,7 +76,7 @@ namespace Umbraco.Core.Persistence.Repositories
internal abstract class RepositoryBase<TId, TEntity> : RepositoryBase, IRepositoryQueryable<TId, TEntity>, IUnitOfWorkRepository
where TEntity : class, IAggregateRoot
{
protected RepositoryBase(IUnitOfWork work, CacheHelper cache, ILogger logger)
protected RepositoryBase(IScopeUnitOfWork work, CacheHelper cache, ILogger logger)
: base(work, cache, logger)
{
}
@@ -102,7 +102,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
if (_isolatedCache != null) return _isolatedCache;
var scope = ((ScopeUnitOfWork) UnitOfWork).Scope; // fixme cast!
var scope = UnitOfWork.Scope;
IsolatedRuntimeCache provider;
switch (scope.RepositoryCacheMode)
{
@@ -179,14 +179,17 @@ namespace Umbraco.Core.Persistence.Repositories
if (GlobalCache == CacheHelper.NoCache)
return _cachePolicy = NoRepositoryCachePolicy<TEntity, TId>.Instance;
// create the cache policy using IsolatedCache which is either global
// or scoped depending on the repository cache mode for the current scope
_cachePolicy = CreateCachePolicy(IsolatedCache);
var scope = ((ScopeUnitOfWork) UnitOfWork).Scope; // fixme cast!
var scope = UnitOfWork.Scope;
switch (scope.RepositoryCacheMode)
{
case RepositoryCacheMode.Default:
break;
case RepositoryCacheMode.Scoped:
_cachePolicy = _cachePolicy.Scoped(GetIsolatedCache(GlobalCache.IsolatedRuntimeCache), scope);
var globalIsolatedCache = GetIsolatedCache(GlobalCache.IsolatedRuntimeCache);
_cachePolicy = _cachePolicy.Scoped(globalIsolatedCache, scope);
break;
default:
throw new Exception("oops: cache mode.");
@@ -21,7 +21,9 @@ namespace Umbraco.Core.Persistence.Repositories
: base(work, CacheHelper.NoCache, logger, sqlSyntax)
{
// managing the cache our own way (no policy etc)
// fixme - ServerRegistrationRepository does *not* implement scoped cache at the moment!
// note: this means that the ServerRegistrationRepository does *not* implement scoped cache,
// and this is because the repository is special and should not participate in scopes
// (cleanup in v8)
_globalCache = globalCache;
}
@@ -39,6 +39,8 @@ namespace Umbraco.Core.Persistence.Repositories
{
var sql = GetBaseQuery(false);
sql.Where(GetBaseWhereClause(), new { Id = id });
//must be sorted this way for the relator to work
sql.OrderBy<UserDto>(x => x.Id, SqlSyntax);
var dto = Database.Fetch<UserDto, User2AppDto, UserDto>(new UserSectionRelator().Map, sql).FirstOrDefault();
@@ -60,7 +62,10 @@ namespace Umbraco.Core.Persistence.Repositories
{
sql.Where("umbracoUser.id in (@ids)", new {ids = ids});
}
//must be sorted this way for the relator to work
sql.OrderBy<UserDto>(x => x.Id, SqlSyntax);
return ConvertFromDtos(Database.Fetch<UserDto, User2AppDto, UserDto>(new UserSectionRelator().Map, sql))
.ToArray(); // important so we don't iterate twice, if we don't do this we can end up with null values in cache if we were caching.
}
@@ -71,6 +76,9 @@ namespace Umbraco.Core.Persistence.Repositories
var translator = new SqlTranslator<IUser>(sqlClause, query);
var sql = translator.Translate();
//must be sorted this way for the relator to work
sql.OrderBy<UserDto>(x => x.Id, SqlSyntax);
var dtos = Database.Fetch<UserDto, User2AppDto, UserDto>(new UserSectionRelator().Map, sql)
.DistinctBy(x => x.Id);
@@ -96,13 +104,13 @@ namespace Umbraco.Core.Persistence.Repositories
return sql;
}
private static Sql GetBaseQuery(string columns)
private Sql GetBaseQuery(string columns)
{
var sql = new Sql();
sql.Select(columns)
.From<UserDto>()
.LeftJoin<User2AppDto>()
.On<UserDto, User2AppDto>(left => left.Id, right => right.UserId);
.From<UserDto>()
.LeftJoin<User2AppDto>()
.On<UserDto, User2AppDto>(left => left.Id, right => right.UserId);
return sql;
}
@@ -300,6 +308,8 @@ namespace Umbraco.Core.Persistence.Repositories
var innerSql = GetBaseQuery("umbracoUser.id");
innerSql.Where("umbracoUser2app.app = " + SqlSyntax.GetQuotedValue(sectionAlias));
sql.Where(string.Format("umbracoUser.id IN ({0})", innerSql.SQL));
//must be sorted this way for the relator to work
sql.OrderBy<UserDto>(x => x.Id, SqlSyntax);
return ConvertFromDtos(Database.Fetch<UserDto, User2AppDto, UserDto>(new UserSectionRelator().Map, sql));
}
@@ -32,7 +32,7 @@ namespace Umbraco.Core.Persistence
//if (sqlSyntax == null) throw new ArgumentNullException("sqlSyntax");
if (settings == null) throw new ArgumentNullException("settings");
_cacheHelper = cacheHelper;
_cacheHelper = cacheHelper;
//IMPORTANT: We will force the DeepCloneRuntimeCacheProvider to be used here which is a wrapper for the underlying
// runtime cache to ensure that anything that can be deep cloned in/out is done so, this also ensures that our tracks
@@ -49,7 +49,12 @@ namespace Umbraco.Core.Persistence
_cacheHelper.IsolatedRuntimeCache.CacheFactory = type =>
{
var cache = origFactory(type);
return new DeepCloneRuntimeCacheProvider(cache);
//if the result is already a DeepCloneRuntimeCacheProvider then return it, otherwise
//wrap the result with a DeepCloneRuntimeCacheProvider
return cache is DeepCloneRuntimeCacheProvider
? cache
: new DeepCloneRuntimeCacheProvider(cache);
};
}
@@ -71,7 +76,7 @@ namespace Umbraco.Core.Persistence
{
}
[Obsolete("Use the ctor specifying all dependencies instead, NOTE: disableAllCache has zero effect")]
[Obsolete("Use the ctor specifying all dependencies instead, NOTE: disableAllCache has zero effect")]
public RepositoryFactory(bool disableAllCache, CacheHelper cacheHelper)
: this(cacheHelper, LoggerResolver.Current.Logger, SqlSyntaxContext.SqlSyntaxProvider, UmbracoConfig.For.UmbracoSettings())
{
@@ -86,7 +91,7 @@ namespace Umbraco.Core.Persistence
{
}
#endregion
public virtual IExternalLoginRepository CreateExternalLoginRepository(IScopeUnitOfWork uow)
@@ -235,12 +240,13 @@ namespace Umbraco.Core.Persistence
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual IStylesheetRepository CreateStylesheetRepository(IUnitOfWork uow, IDatabaseUnitOfWork db)
{
// note: the second unit of work is ignored.
return new StylesheetRepository(uow, FileSystemProviderManager.Current.StylesheetsFileSystem);
}
public virtual ITemplateRepository CreateTemplateRepository(IScopeUnitOfWork uow)
{
return new TemplateRepository(uow,
return new TemplateRepository(uow,
_cacheHelper,
_logger, _sqlSyntax,
FileSystemProviderManager.Current.MasterPagesFileSystem,
@@ -279,7 +285,7 @@ namespace Umbraco.Core.Persistence
}
public virtual IUserRepository CreateUserRepository(IScopeUnitOfWork uow)
{
{
return new UserRepository(
uow,
//Need to cache users - we look up user information more than anything in the back office!
@@ -1,20 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Scoping;
namespace Umbraco.Core.Persistence.UnitOfWork
{
internal class FileUnitOfWork : ScopeUnitOfWork
{
// fixme
// soon as FileUnitOfWork inherits from ScopeUnitOfWork it does not make any sense anymore to keep this class around?!
public FileUnitOfWork(IScopeProvider scopeProvider, IsolationLevel isolationLevel = IsolationLevel.Unspecified)
: base(scopeProvider, isolationLevel)
{ }
}
}
@@ -4,10 +4,15 @@ using Umbraco.Core.Scoping;
namespace Umbraco.Core.Persistence.UnitOfWork
{
// note: the concept of "file unit of work" does not make sense anymore in v7.6
// and we should probably remove this class, which is not used anywhere, but for
// the time being we keep it here - just not to break too many things.
/// <summary>
/// Represents a Unit of Work Provider for creating a file unit of work
/// </summary>
public class FileUnitOfWorkProvider : ScopeUnitOfWorkProvider // fixme - what's the point?
[Obsolete("Use the ScopeUnitOfWorkProvider instead.", false)]
public class FileUnitOfWorkProvider : ScopeUnitOfWorkProvider
{
[Obsolete("Use the ctor specifying a IScopeProvider instead")]
public FileUnitOfWorkProvider()
@@ -18,11 +23,8 @@ namespace Umbraco.Core.Persistence.UnitOfWork
: base(scopeProvider)
{ }
// fixme - returning a IScopeUnitOfWork instead of a IUnitOfWork here is a breaking change!
// this is bad, we're going to end up creating // units of work which is ... really bad
public override IScopeUnitOfWork GetUnitOfWork()
{
// fixme - no point returning a FileUnitOfWork if its equivalent to ScopeUnitOfWork
return new ScopeUnitOfWork(ScopeProvider);
}
}
@@ -18,19 +18,9 @@ namespace Umbraco.Core.Persistence.UnitOfWork
// creates a unit of work
// support specifying an isolation level
// support auto-commit - beware!
// fixme - should we be able to specify ALL scope options?
// fixme - that isolation level thing is a pain because of the above existing method
IScopeUnitOfWork GetUnitOfWork(bool commit);
IScopeUnitOfWork GetUnitOfWork(IsolationLevel isolationLevel, bool commit = false);
// creates a readonly unit of work
// the readonly unit of work will not accept operations, and will auto-complete
// of course it would be a bad idea to use it for anything else than reading
// fixme - implement that one FOR REAL not as an extension method
// the extension method was a ugly hack
// or maybe we want a autocommit flag in the ctor?
//IScopeUnitOfWork GetReadOnlyUnitOfWork();
//IScopeUnitOfWork GetReadOnlyUnitOfWork(bool autocommit = false);
// support auto-commit - but beware! it will be committed, whatever happens
// TODO in v8 this should all be merged as one single method with optional args
IScopeUnitOfWork GetUnitOfWork(bool readOnly);
IScopeUnitOfWork GetUnitOfWork(IsolationLevel isolationLevel, bool readOnly = false);
}
}
@@ -16,6 +16,7 @@ namespace Umbraco.Core.Persistence.UnitOfWork
private readonly IsolationLevel _isolationLevel;
private readonly IScopeProvider _scopeProvider;
private bool _completeScope;
private readonly bool _readOnly;
private IScope _scope;
private Guid _key;
@@ -29,11 +30,11 @@ namespace Umbraco.Core.Persistence.UnitOfWork
/// </summary>
/// <param name="scopeProvider"></param>
/// <param name="isolationLevel"></param>
/// <param name="commit"></param>
/// <param name="readOnly"></param>
/// <remarks>
/// This should normally not be used directly and should be created with the UnitOfWorkProvider
/// </remarks>
internal ScopeUnitOfWork(IScopeProvider scopeProvider, IsolationLevel isolationLevel = IsolationLevel.Unspecified, bool commit = false)
internal ScopeUnitOfWork(IScopeProvider scopeProvider, IsolationLevel isolationLevel = IsolationLevel.Unspecified, bool readOnly = false)
{
_scopeProvider = scopeProvider;
_isolationLevel = isolationLevel;
@@ -43,7 +44,7 @@ namespace Umbraco.Core.Persistence.UnitOfWork
// be false by default
// if set to true... the UnitOfWork is "auto-commit" which means that even in the case of
// an exception, the scope would still be completed - ppl should use it with great care!
_completeScope = commit;
_completeScope = _readOnly = readOnly;
}
/// <summary>
@@ -53,6 +54,9 @@ namespace Umbraco.Core.Persistence.UnitOfWork
/// <param name="repository">The <see cref="IUnitOfWorkRepository" /> participating in the transaction</param>
public void RegisterAdded(IEntity entity, IUnitOfWorkRepository repository)
{
if (_readOnly)
throw new NotSupportedException("This unit of work is read-only.");
_operations.Enqueue(new Operation
{
Entity = entity,
@@ -68,7 +72,10 @@ namespace Umbraco.Core.Persistence.UnitOfWork
/// <param name="repository">The <see cref="IUnitOfWorkRepository" /> participating in the transaction</param>
public void RegisterChanged(IEntity entity, IUnitOfWorkRepository repository)
{
_operations.Enqueue(
if (_readOnly)
throw new NotSupportedException("This unit of work is read-only.");
_operations.Enqueue(
new Operation
{
Entity = entity,
@@ -84,7 +91,10 @@ namespace Umbraco.Core.Persistence.UnitOfWork
/// <param name="repository">The <see cref="IUnitOfWorkRepository" /> participating in the transaction</param>
public void RegisterRemoved(IEntity entity, IUnitOfWorkRepository repository)
{
_operations.Enqueue(
if (_readOnly)
throw new NotSupportedException("This unit of work is read-only.");
_operations.Enqueue(
new Operation
{
Entity = entity,
@@ -116,6 +126,9 @@ namespace Umbraco.Core.Persistence.UnitOfWork
{
// this happens in a scope-managed transaction
if (_readOnly)
throw new NotSupportedException("This unit of work is read-only.");
// in case anything goes wrong
_completeScope = false;
@@ -24,48 +24,28 @@ namespace Umbraco.Core.Persistence.UnitOfWork
return new ScopeUnitOfWork(ScopeProvider);
}
/// <summary>
/// Creates a Unit of work with a new UmbracoDatabase instance for the work item/transaction.
/// </summary>
/// <returns></returns>
/// <remarks>
/// Each PetaPoco UOW uses it's own Database object, not the shared Database object that comes from
/// the ApplicationContext.Current.DatabaseContext.Database. This is because each transaction should use it's own Database
/// and we Dispose of this Database object when the UOW is disposed.
/// fixme NO we dispose of it when the transaction completes
/// fixme just inheritdoc!
/// </remarks>
/// <inheritdoc />
public virtual IScopeUnitOfWork GetUnitOfWork()
{
return new ScopeUnitOfWork(ScopeProvider);
}
/// <summary>
/// Creates a Unit of work with a new UmbracoDatabase instance for the work item/transaction.
/// </summary>
/// <returns></returns>
/// <remarks>
/// Each PetaPoco UOW uses it's own Database object, not the shared Database object that comes from
/// the ApplicationContext.Current.DatabaseContext.Database. This is because each transaction should use it's own Database
/// and we Dispose of this Database object when the UOW is disposed.
/// fixme NO
/// fixme just inheritdoc!
/// </remarks>
/// <inheritdoc />
public IScopeUnitOfWork GetUnitOfWork(IsolationLevel isolationLevel)
{
return new ScopeUnitOfWork(ScopeProvider, isolationLevel);
}
/// <inheritdoc />
public IScopeUnitOfWork GetUnitOfWork(bool commit)
public IScopeUnitOfWork GetUnitOfWork(bool readOnly)
{
return new ScopeUnitOfWork(ScopeProvider, commit: commit);
return new ScopeUnitOfWork(ScopeProvider, readOnly: readOnly);
}
/// <inheritdoc />
public IScopeUnitOfWork GetUnitOfWork(IsolationLevel isolationLevel, bool commit)
public IScopeUnitOfWork GetUnitOfWork(IsolationLevel isolationLevel, bool readOnly)
{
return new ScopeUnitOfWork(ScopeProvider, isolationLevel, commit: commit);
return new ScopeUnitOfWork(ScopeProvider, isolationLevel, readOnly: readOnly);
}
}
}
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
using Umbraco.Core.Manifest;
using Umbraco.Core.ObjectResolution;
@@ -17,11 +19,13 @@ namespace Umbraco.Core.PropertyEditors
internal class ParameterEditorResolver : LazyManyObjectsResolverBase<ParameterEditorResolver, IParameterEditor>
{
private readonly ManifestBuilder _builder;
private readonly IContentSection _contentSection;
public ParameterEditorResolver(IServiceProvider serviceProvider, ILogger logger, Func<IEnumerable<Type>> typeListProducerList, ManifestBuilder builder)
: base(serviceProvider, logger, typeListProducerList, ObjectLifetimeScope.Application)
{
_builder = builder;
_contentSection = UmbracoConfig.For.UmbracoSettings().Content;
}
/// <summary>
@@ -31,20 +35,27 @@ namespace Umbraco.Core.PropertyEditors
{
get
{
//This will by default include all property editors and parameter editors but we need to filter this
//list to ensure that none of the property editors that do not have the IsParameterEditor flag set to true
//are filtered.
var filtered = Values.Select(x => x as PropertyEditor)
.WhereNotNull()
.Where(x => x.IsParameterEditor == false);
return Values
//exclude the non parameter editor c# property editors
.Except(filtered)
//include the manifest parameter editors
.Union(_builder.ParameterEditors)
//include the manifest prop editors that are parameter editors
// all property editors and parameter editors
// except property editors where !IsParameterEditor
var values = Values
.Where(x => x is PropertyEditor == false || ((PropertyEditor) x).IsParameterEditor);
// union all manifest parameter editors
values = values
.Union(_builder.ParameterEditors);
// union all manifest property editors where IsParameterEditor
values = values
.Union(_builder.PropertyEditors.Where(x => x.IsParameterEditor));
if (_contentSection.ShowDeprecatedPropertyEditors == false)
{
// except deprecated property editors
values = values
.Where(x => x is PropertyEditor == false || ((PropertyEditor) x).IsDeprecated == false);
}
return values;
}
}
@@ -1,4 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models;
@@ -88,13 +89,26 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
/// </returns>
private bool IsRangeDataType(int dataTypeId)
{
// ** This must be cached (U4-8862) **
var enableRange =
_dataTypeService.GetPreValuesCollectionByDataTypeId(dataTypeId)
.PreValuesAsDictionary.FirstOrDefault(
x => string.Equals(x.Key, "enableRange", StringComparison.InvariantCultureIgnoreCase)).Value;
// GetPreValuesCollectionByDataTypeId is cached at repository level;
// still, the collection is deep-cloned so this is kinda expensive,
// better to cache here + trigger refresh in DataTypeCacheRefresher
return enableRange != null && enableRange.Value.TryConvertTo<bool>().Result;
return Storages.GetOrAdd(dataTypeId, id =>
{
var preValue = _dataTypeService.GetPreValuesCollectionByDataTypeId(id)
.PreValuesAsDictionary
.FirstOrDefault(x => string.Equals(x.Key, "enableRange", StringComparison.InvariantCultureIgnoreCase))
.Value;
return preValue != null && preValue.Value.TryConvertTo<bool>().Result;
});
}
private static readonly ConcurrentDictionary<int, bool> Storages = new ConcurrentDictionary<int, bool>();
internal static void ClearCaches()
{
Storages.Clear();
}
}
}
@@ -1,9 +1,12 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Events;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Services;
@@ -74,18 +77,26 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
/// </returns>
private bool JsonStorageType(int dataTypeId)
{
// ** This must be cached (U4-8862) **
var storageType =
_dataTypeService.GetPreValuesCollectionByDataTypeId(dataTypeId)
.PreValuesAsDictionary.FirstOrDefault(
x => string.Equals(x.Key, "storageType", StringComparison.InvariantCultureIgnoreCase)).Value;
// GetPreValuesCollectionByDataTypeId is cached at repository level;
// still, the collection is deep-cloned so this is kinda expensive,
// better to cache here + trigger refresh in DataTypeCacheRefresher
if (storageType.Value.InvariantEquals("Json"))
return Storages.GetOrAdd(dataTypeId, id =>
{
return true;
}
var preValue = _dataTypeService.GetPreValuesCollectionByDataTypeId(id)
.PreValuesAsDictionary
.FirstOrDefault(x => string.Equals(x.Key, "storageType", StringComparison.InvariantCultureIgnoreCase))
.Value;
return false;
return preValue != null && preValue.Value.InvariantEquals("json");
});
}
private static readonly ConcurrentDictionary<int, bool> Storages = new ConcurrentDictionary<int, bool>();
internal static void ClearCaches()
{
Storages.Clear();
}
}
}
+4 -3
View File
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Events;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
@@ -12,7 +13,8 @@ namespace Umbraco.Core.Publishing
{
public PublishStatus(IContent content, PublishStatusType statusType, EventMessages eventMessages)
: base(content, statusType, eventMessages)
{
{
InvalidProperties = Enumerable.Empty<Property>();
}
/// <summary>
@@ -20,8 +22,7 @@ namespace Umbraco.Core.Publishing
/// </summary>
public PublishStatus(IContent content, EventMessages eventMessages)
: this(content, PublishStatusType.Success, eventMessages)
{
}
{ }
public IContent ContentItem
{
@@ -51,7 +51,7 @@ namespace Umbraco.Core.Publishing
/// </summary>
/// <param name="uow"></param>
/// <param name="content"><see cref="IContent"/> to publish</param>
/// <param name="userId">Id of the User issueing the publish operation</param>
/// <param name="userId">Id of the User issueing the publish operation</param>
Attempt<PublishStatus> IPublishingStrategy2.Publish(IScopeUnitOfWork uow, IContent content, int userId)
{
var evtMsgs = _eventMessagesFactory.Get();
@@ -124,26 +124,26 @@ namespace Umbraco.Core.Publishing
/// By default this is set to true which means that it will publish any content item in the list that is completely unpublished and
/// not visible on the front-end. If set to false, this will only publish content that is live on the front-end but has new versions
/// that have yet to be published.
/// </param>
/// </param>
/// <returns></returns>
/// <remarks>
///
///
/// This method becomes complex once we start to be able to cancel events or stop publishing a content item in any way because if a
/// content item is not published then it's children shouldn't be published either. This rule will apply for the following conditions:
/// * If a document fails to be published, do not proceed to publish it's children if:
/// ** The document does not have a publish version
/// ** The document does have a published version but the includeUnpublishedDocuments = false
///
///
/// In order to do this, we will order the content by level and begin by publishing each item at that level, then proceed to the next
/// level and so on. If we detect that the above rule applies when the document publishing is cancelled we'll add it to the list of
/// level and so on. If we detect that the above rule applies when the document publishing is cancelled we'll add it to the list of
/// parentsIdsCancelled so that it's children don't get published.
///
///
/// Its important to note that all 'root' documents included in the list *will* be published regardless of the rules mentioned
/// above (unless it is invalid)!! By 'root' documents we are referring to documents in the list with the minimum value for their 'level'.
/// In most cases the 'root' documents will only be one document since under normal circumstance we only publish one document and
/// above (unless it is invalid)!! By 'root' documents we are referring to documents in the list with the minimum value for their 'level'.
/// In most cases the 'root' documents will only be one document since under normal circumstance we only publish one document and
/// its children. The reason we have to do this is because if a user is publishing a document and it's children, it is implied that
/// the user definitely wants to publish it even if it has never been published before.
///
///
/// </remarks>
IEnumerable<Attempt<PublishStatus>> IPublishingStrategy2.PublishWithChildren(IScopeUnitOfWork uow,
IEnumerable<IContent> content, int userId, bool includeUnpublishedDocuments)
@@ -157,7 +157,7 @@ namespace Umbraco.Core.Publishing
//group by levels and iterate over the sorted ascending level.
//TODO: This will cause all queries to execute, they will not be lazy but I'm not really sure being lazy actually made
// much difference because we iterate over them all anyways?? Morten?
// much difference because we iterate over them all anyways?? Morten?
// Because we're grouping I think this will execute all the queries anyways so need to fetch it all first.
var fetchedContent = content.ToArray();
@@ -174,7 +174,7 @@ namespace Umbraco.Core.Publishing
var levelGroups = fetchedContent.GroupBy(x => x.Level);
foreach (var level in levelGroups.OrderBy(x => x.Key))
{
//set the first level flag, used to ensure that all documents at the first level will
//set the first level flag, used to ensure that all documents at the first level will
//be published regardless of the rules mentioned in the remarks.
if (!firstLevel.HasValue)
{
@@ -224,7 +224,10 @@ namespace Umbraco.Core.Publishing
_logger.Info<PublishingStrategy>(
string.Format("Content '{0}' with Id '{1}' will not be published because some of it's content is not passing validation rules.",
item.Name, item.Id));
statuses.Add(Attempt.Fail(new PublishStatus(item, PublishStatusType.FailedContentInvalid, evtMsgs)));
statuses.Add(Attempt.Fail(new PublishStatus(item, PublishStatusType.FailedContentInvalid, evtMsgs)
{
InvalidProperties = ((ContentBase)item).LastInvalidProperties
}));
//Does this document apply to our rule to cancel it's children being published?
CheckCancellingOfChildPublishing(item, parentsIdsCancelled, includeUnpublishedDocuments);
@@ -296,11 +299,11 @@ namespace Umbraco.Core.Publishing
/// <param name="includeUnpublishedDocuments"></param>
/// <remarks>
/// See remarks on method: PublishWithChildrenInternal
/// </remarks>
/// </remarks>
private void CheckCancellingOfChildPublishing(IContent content, List<int> parentsIdsCancelled, bool includeUnpublishedDocuments)
{
//Does this document apply to our rule to cancel it's children being published?
//TODO: We're going back to the service layer here... not sure how to avoid this? And this will add extra overhead to
//TODO: We're going back to the service layer here... not sure how to avoid this? And this will add extra overhead to
// any document that fails to publish...
var hasPublishedVersion = ApplicationContext.Current.Services.ContentService.HasPublishedVersion(content.Id);
@@ -176,6 +176,7 @@ namespace Umbraco.Core.Scoping
}
}
// this is for tests exclusively until we have a proper accessor in v8
internal static Func<IDictionary> HttpContextItemsGetter { get; set; }
private static IDictionary HttpContextItems
@@ -324,6 +324,14 @@ namespace Umbraco.Core.Security
throw new MembershipPasswordException("Change password canceled due to password validation failure.");
}
//Special case to allow changing password without validating existing credentials
//This is used during installation only
if (AllowManuallyChangingPassword == false && ApplicationContext.Current != null
&& ApplicationContext.Current.IsConfigured == false && oldPassword == "default")
{
return PerformChangePassword(username, oldPassword, newPassword);
}
if (AllowManuallyChangingPassword == false)
{
if (ValidateUser(username, oldPassword) == false) return false;
@@ -358,9 +358,8 @@ namespace Umbraco.Core.Services
{
var applicationAlias = (string)addElement.Attribute("application");
var type = (string)addElement.Attribute("type");
var assembly = (string)addElement.Attribute("assembly");
var clrType = Type.GetType(type);
var clrType = ApplicationTree.TryGetType(type);
if (clrType == null)
{
_logger.Warn<ApplicationTreeService>("The tree definition: " + addElement.ToString() + " could not be resolved to a .Net object type");
File diff suppressed because it is too large Load Diff
+151 -134
View File
@@ -1,22 +1,15 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Threading;
using AutoMapper;
using Umbraco.Core.Auditing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Events;
using Umbraco.Core.Exceptions;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Services
@@ -76,6 +69,7 @@ namespace Umbraco.Core.Services
}
catch (Exception ex)
{
uow.Commit();
return Attempt.Fail(new OperationStatus<EntityContainer, OperationStatusType>(null, OperationStatusType.FailedExceptionThrown, evtMsgs), ex);
}
}
@@ -113,6 +107,7 @@ namespace Umbraco.Core.Services
}
catch (Exception ex)
{
uow.Commit();
return Attempt.Fail(new OperationStatus<EntityContainer, OperationStatusType>(null, OperationStatusType.FailedExceptionThrown, evtMsgs), ex);
}
}
@@ -139,7 +134,7 @@ namespace Umbraco.Core.Services
TypedEventHandler<IContentTypeService, SaveEventArgs<EntityContainer>> savedEvent,
EntityContainer container,
Guid containerObjectType,
string objectTypeName,
string objectTypeName,
string savedEventName,
int userId)
{
@@ -159,10 +154,9 @@ namespace Umbraco.Core.Services
using (var uow = UowProvider.GetUnitOfWork())
{
// fixme - how does it work w/name?!
if (uow.Events.DispatchCancelable(savingEvent, this, new SaveEventArgs<EntityContainer>(container, evtMsgs)))
//if (savingEvent.IsRaisedEventCancelled(new SaveEventArgs<EntityContainer>(container, evtMsgs), this, UowProvider))
{
uow.Commit();
return OperationStatus.Cancelled(evtMsgs);
}
@@ -189,7 +183,7 @@ namespace Umbraco.Core.Services
private EntityContainer GetContainer(int containerId, Guid containerObjectType)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repo = RepositoryFactory.CreateEntityContainerRepository(uow, containerObjectType);
return repo.Get(containerId);
@@ -198,7 +192,7 @@ namespace Umbraco.Core.Services
public IEnumerable<EntityContainer> GetMediaTypeContainers(int[] containerIds)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.MediaTypeContainerGuid);
return repo.GetAll(containerIds);
@@ -207,7 +201,7 @@ namespace Umbraco.Core.Services
public IEnumerable<EntityContainer> GetMediaTypeContainers(string name, int level)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.MediaTypeContainerGuid);
return repo.Get(name, level);
@@ -236,7 +230,7 @@ namespace Umbraco.Core.Services
public IEnumerable<EntityContainer> GetContentTypeContainers(int[] containerIds)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DocumentTypeContainerGuid);
return repo.GetAll(containerIds);
@@ -265,7 +259,7 @@ namespace Umbraco.Core.Services
private EntityContainer GetContainer(Guid containerId, Guid containerObjectType)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repo = RepositoryFactory.CreateEntityContainerRepository(uow, containerObjectType);
return repo.Get(containerId);
@@ -274,7 +268,7 @@ namespace Umbraco.Core.Services
public IEnumerable<EntityContainer> GetContentTypeContainers(string name, int level)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DocumentTypeContainerGuid);
return repo.Get(name, level);
@@ -288,7 +282,11 @@ namespace Umbraco.Core.Services
{
var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DocumentTypeContainerGuid);
var container = repo.Get(containerId);
if (container == null) return OperationStatus.NoOperation(evtMsgs); // fixme commit?
if (container == null)
{
uow.Commit();
return OperationStatus.NoOperation(evtMsgs);
}
if (uow.Events.DispatchCancelable(DeletingContentTypeContainer, this, new DeleteEventArgs<EntityContainer>(container, evtMsgs)))
{
@@ -314,7 +312,11 @@ namespace Umbraco.Core.Services
var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.MediaTypeContainerGuid);
var container = repo.Get(containerId);
if (container == null) return OperationStatus.NoOperation(evtMsgs); // fixme commit?
if (container == null)
{
uow.Commit();
return OperationStatus.NoOperation(evtMsgs);
}
if (uow.Events.DispatchCancelable(DeletingMediaTypeContainer, this, new DeleteEventArgs<EntityContainer>(container, evtMsgs)))
{
@@ -340,7 +342,7 @@ namespace Umbraco.Core.Services
/// <returns></returns>
public IEnumerable<string> GetAllPropertyTypeAliases()
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateContentTypeRepository(uow);
return repository.GetAllPropertyTypeAliases();
@@ -357,7 +359,7 @@ namespace Umbraco.Core.Services
/// <returns></returns>
public IEnumerable<string> GetAllContentTypeAliases(params Guid[] objectTypes)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateContentTypeRepository(uow);
return repository.GetAllContentTypeAliases(objectTypes);
@@ -454,7 +456,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IContentType"/></returns>
public IContentType GetContentType(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateContentTypeRepository(uow);
return repository.Get(id);
@@ -468,7 +470,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IContentType"/></returns>
public IContentType GetContentType(string alias)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateContentTypeRepository(uow);
return repository.Get(alias);
@@ -482,7 +484,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IContentType"/></returns>
public IContentType GetContentType(Guid id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateContentTypeRepository(uow);
return repository.Get(id);
@@ -496,7 +498,7 @@ namespace Umbraco.Core.Services
/// <returns>An Enumerable list of <see cref="IContentType"/> objects</returns>
public IEnumerable<IContentType> GetAllContentTypes(params int[] ids)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateContentTypeRepository(uow);
return repository.GetAll(ids);
@@ -510,7 +512,7 @@ namespace Umbraco.Core.Services
/// <returns>An Enumerable list of <see cref="IContentType"/> objects</returns>
public IEnumerable<IContentType> GetAllContentTypes(IEnumerable<Guid> ids)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateContentTypeRepository(uow);
return repository.GetAll(ids.ToArray());
@@ -524,7 +526,7 @@ namespace Umbraco.Core.Services
/// <returns>An Enumerable list of <see cref="IContentType"/> objects</returns>
public IEnumerable<IContentType> GetContentTypeChildren(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateContentTypeRepository(uow);
var query = Query<IContentType>.Builder.Where(x => x.ParentId == id);
@@ -539,7 +541,7 @@ namespace Umbraco.Core.Services
/// <returns>An Enumerable list of <see cref="IContentType"/> objects</returns>
public IEnumerable<IContentType> GetContentTypeChildren(Guid id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateContentTypeRepository(uow);
@@ -557,7 +559,7 @@ namespace Umbraco.Core.Services
/// <returns>True if the content type has any children otherwise False</returns>
public bool HasChildren(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateContentTypeRepository(uow);
@@ -573,7 +575,7 @@ namespace Umbraco.Core.Services
/// <returns>True if the content type has any children otherwise False</returns>
public bool HasChildren(Guid id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateContentTypeRepository(uow);
@@ -584,6 +586,27 @@ namespace Umbraco.Core.Services
}
}
public override IEnumerable<IContentTypeBase> GetDescendants(IContentTypeBase contentType)
{
var ctype = contentType as IContentType;
if (ctype != null) return GetDescendants(ctype);
var mtype = contentType as IMediaType;
if (mtype != null) return GetDescendants(mtype);
return Enumerable.Empty<IContentTypeBase>();
}
public IEnumerable<IContentType> GetDescendants(IContentType contentType)
{
return GetContentTypeChildren(contentType.Id)
.SelectRecursive(type => GetContentTypeChildren(type.Id));
}
public IEnumerable<IMediaType> GetDescendants(IMediaType contentType)
{
return GetMediaTypeChildren(contentType.Id)
.SelectRecursive(type => GetMediaTypeChildren(type.Id));
}
/// <summary>
/// This is called after an IContentType is saved and is used to update the content xml structures in the database
/// if they are required to be updated.
@@ -591,42 +614,39 @@ namespace Umbraco.Core.Services
/// <param name="contentTypes">A tuple of a content type and a boolean indicating if it is new (HasIdentity was false before committing)</param>
private void UpdateContentXmlStructure(params IContentTypeBase[] contentTypes)
{
var toUpdate = GetContentTypesForXmlUpdates(contentTypes).ToArray();
if (toUpdate.Any())
if (toUpdate.Any() == false) return;
var firstType = toUpdate.First();
//if it is a content type then call the rebuilding methods or content
if (firstType is IContentType)
{
var firstType = toUpdate.First();
//if it is a content type then call the rebuilding methods or content
if (firstType is IContentType)
var typedContentService = _contentService as ContentService;
if (typedContentService != null)
{
var typedContentService = _contentService as ContentService;
if (typedContentService != null)
{
typedContentService.RePublishAll(toUpdate.Select(x => x.Id).ToArray());
}
else
{
//this should never occur, the content service should always be typed but we'll check anyways.
_contentService.RePublishAll();
}
typedContentService.RePublishAll(toUpdate.Select(x => x.Id).ToArray());
}
else if (firstType is IMediaType)
else
{
//if it is a media type then call the rebuilding methods for media
var typedContentService = _mediaService as MediaService;
if (typedContentService != null)
{
typedContentService.RebuildXmlStructures(toUpdate.Select(x => x.Id).ToArray());
}
//this should never occur, the content service should always be typed but we'll check anyways.
_contentService.RePublishAll();
}
}
else if (firstType is IMediaType)
{
//if it is a media type then call the rebuilding methods for media
var typedContentService = _mediaService as MediaService;
if (typedContentService != null)
{
typedContentService.RebuildXmlStructures(toUpdate.Select(x => x.Id).ToArray());
}
}
}
public int CountContentTypes()
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateContentTypeRepository(uow);
return repository.Count(Query<IContentType>.Builder);
@@ -635,7 +655,7 @@ namespace Umbraco.Core.Services
public int CountMediaTypes()
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaTypeRepository(uow);
return repository.Count(Query<IMediaType>.Builder);
@@ -753,16 +773,15 @@ namespace Umbraco.Core.Services
repository.AddOrUpdate(contentType);
uow.Commit();
}
UpdateContentXmlStructure(contentType); // fixme wtf here?
UpdateContentXmlStructure(contentType);
uow.Events.Dispatch(SavedContentType, this, new SaveEventArgs<IContentType>(contentType, false));
Audit(uow, AuditType.Save, "Save ContentType performed by user", userId, contentType.Id);
uow.Commit();
}
}
using (var scope = UowProvider.ScopeProvider.CreateScope()) // fixme what a mess
{
scope.Events.Dispatch(SavedContentType, this, new SaveEventArgs<IContentType>(contentType, false));
scope.Complete();
}
Audit(AuditType.Save, "Save ContentType performed by user", userId, contentType.Id);
}
/// <summary>
@@ -783,7 +802,7 @@ namespace Umbraco.Core.Services
uow.Commit();
return;
}
var repository = RepositoryFactory.CreateContentTypeRepository(uow);
foreach (var contentType in asArray)
@@ -798,16 +817,15 @@ namespace Umbraco.Core.Services
//save it all in one go
uow.Commit();
}
UpdateContentXmlStructure(asArray.Cast<IContentTypeBase>().ToArray()); // fixme wtf
UpdateContentXmlStructure(asArray.Cast<IContentTypeBase>().ToArray());
uow.Events.Dispatch(SavedContentType, this, new SaveEventArgs<IContentType>(asArray, false));
Audit(uow, AuditType.Save, "Save ContentTypes performed by user", userId, -1);
uow.Commit();
}
}
using (var scope = UowProvider.ScopeProvider.CreateScope()) // fixme what a mess
{
scope.Events.Dispatch(SavedContentType, this, new SaveEventArgs<IContentType>(asArray, false));
scope.Complete();
}
Audit(AuditType.Save, "Save ContentTypes performed by user", userId, -1);
}
/// <summary>
@@ -817,7 +835,7 @@ namespace Umbraco.Core.Services
/// <param name="userId">Optional id of the user issueing the delete</param>
/// <remarks>Deleting a <see cref="IContentType"/> will delete all the <see cref="IContent"/> objects based on this <see cref="IContentType"/></remarks>
public void Delete(IContentType contentType, int userId = 0)
{
{
using (new WriteLock(Locker))
{
using (var uow = UowProvider.GetUnitOfWork())
@@ -829,20 +847,20 @@ namespace Umbraco.Core.Services
}
var repository = RepositoryFactory.CreateContentTypeRepository(uow);
//If we are deleting this content type, we are also deleting it's descendents!
var deletedContentTypes = new List<IContentType>() {contentType};
deletedContentTypes.AddRange(contentType.Descendants((IContentTypeService)this).OfType<IContentType>());
var deletedContentTypes = new List<IContentType> {contentType};
deletedContentTypes.AddRange(GetDescendants(contentType));
_contentService.DeleteContentOfTypes(deletedContentTypes.Select(x => x.Id), userId);
repository.Delete(contentType);
uow.Commit();
uow.Events.Dispatch(DeletedContentType, this, new DeleteEventArgs<IContentType>(deletedContentTypes.DistinctBy(x => x.Id), false));
}
Audit(AuditType.Delete, string.Format("Delete ContentType performed by user"), userId, contentType.Id);
Audit(uow, AuditType.Delete, string.Format("Delete ContentType performed by user"), userId, contentType.Id);
uow.Commit();
}
}
}
@@ -857,7 +875,7 @@ namespace Umbraco.Core.Services
public void Delete(IEnumerable<IContentType> contentTypes, int userId = 0)
{
var asArray = contentTypes.ToArray();
using (new WriteLock(Locker))
{
using (var uow = UowProvider.GetUnitOfWork())
@@ -874,22 +892,21 @@ namespace Umbraco.Core.Services
var deletedContentTypes = new List<IContentType>(asArray);
foreach (var contentType in asArray)
{
deletedContentTypes.AddRange(contentType.Descendants((IContentTypeService)this).OfType<IContentType>());
deletedContentTypes.AddRange(GetDescendants(contentType));
}
_contentService.DeleteContentOfTypes(deletedContentTypes.Select(x => x.Id), userId);
_contentService.DeleteContentOfTypes(deletedContentTypes.Select(x => x.Id), userId);
foreach (var contentType in asArray)
{
repository.Delete(contentType);
}
uow.Commit();
uow.Events.Dispatch(DeletedContentType, this, new DeleteEventArgs<IContentType>(deletedContentTypes.DistinctBy(x => x.Id), false));
}
Audit(AuditType.Delete, string.Format("Delete ContentTypes performed by user"), userId, -1);
Audit(uow, AuditType.Delete, string.Format("Delete ContentTypes performed by user"), userId, -1);
uow.Commit();
}
}
}
@@ -900,7 +917,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IMediaType"/></returns>
public IMediaType GetMediaType(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaTypeRepository(uow);
return repository.Get(id);
@@ -914,7 +931,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IMediaType"/></returns>
public IMediaType GetMediaType(string alias)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaTypeRepository(uow);
return repository.Get(alias);
@@ -928,7 +945,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IMediaType"/></returns>
public IMediaType GetMediaType(Guid id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaTypeRepository(uow);
return repository.Get(id);
@@ -942,7 +959,7 @@ namespace Umbraco.Core.Services
/// <returns>An Enumerable list of <see cref="IMediaType"/> objects</returns>
public IEnumerable<IMediaType> GetAllMediaTypes(params int[] ids)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaTypeRepository(uow);
return repository.GetAll(ids);
@@ -956,7 +973,7 @@ namespace Umbraco.Core.Services
/// <returns>An Enumerable list of <see cref="IMediaType"/> objects</returns>
public IEnumerable<IMediaType> GetAllMediaTypes(IEnumerable<Guid> ids)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaTypeRepository(uow);
return repository.GetAll(ids.ToArray());
@@ -970,7 +987,7 @@ namespace Umbraco.Core.Services
/// <returns>An Enumerable list of <see cref="IMediaType"/> objects</returns>
public IEnumerable<IMediaType> GetMediaTypeChildren(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaTypeRepository(uow);
var query = Query<IMediaType>.Builder.Where(x => x.ParentId == id);
@@ -985,7 +1002,7 @@ namespace Umbraco.Core.Services
/// <returns>An Enumerable list of <see cref="IMediaType"/> objects</returns>
public IEnumerable<IMediaType> GetMediaTypeChildren(Guid id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaTypeRepository(uow);
var found = GetMediaType(id);
@@ -1002,7 +1019,7 @@ namespace Umbraco.Core.Services
/// <returns>True if the media type has any children otherwise False</returns>
public bool MediaTypeHasChildren(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaTypeRepository(uow);
var query = Query<IMediaType>.Builder.Where(x => x.ParentId == id);
@@ -1017,7 +1034,7 @@ namespace Umbraco.Core.Services
/// <returns>True if the media type has any children otherwise False</returns>
public bool MediaTypeHasChildren(Guid id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaTypeRepository(uow);
var found = GetMediaType(id);
@@ -1035,7 +1052,10 @@ namespace Umbraco.Core.Services
using (var uow = UowProvider.GetUnitOfWork())
{
if (uow.Events.DispatchCancelable(MovingMediaType, this, new MoveEventArgs<IMediaType>(evtMsgs, new MoveEventInfo<IMediaType>(toMove, toMove.Path, containerId))))
{
uow.Commit();
return Attempt.Fail(new OperationStatus<MoveOperationStatusType>(MoveOperationStatusType.FailedCancelledByEvent, evtMsgs));
}
var containerRepository = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.MediaTypeContainerGuid);
var repository = RepositoryFactory.CreateMediaTypeRepository(uow);
@@ -1052,8 +1072,8 @@ namespace Umbraco.Core.Services
}
catch (DataOperationException<MoveOperationStatusType> ex)
{
return Attempt.Fail(
new OperationStatus<MoveOperationStatusType>(ex.Operation, evtMsgs));
uow.Commit();
return Attempt.Fail(new OperationStatus<MoveOperationStatusType>(ex.Operation, evtMsgs));
}
uow.Commit();
uow.Events.Dispatch(MovedMediaType, this, new MoveEventArgs<IMediaType>(false, evtMsgs, moveInfo.ToArray()));
@@ -1071,7 +1091,10 @@ namespace Umbraco.Core.Services
using (var uow = UowProvider.GetUnitOfWork())
{
if (uow.Events.DispatchCancelable(MovingContentType, this, new MoveEventArgs<IContentType>(evtMsgs, new MoveEventInfo<IContentType>(toMove, toMove.Path, containerId))))
{
uow.Commit();
return Attempt.Fail(new OperationStatus<MoveOperationStatusType>(MoveOperationStatusType.FailedCancelledByEvent, evtMsgs));
}
var containerRepository = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DocumentTypeContainerGuid);
var repository = RepositoryFactory.CreateContentTypeRepository(uow);
@@ -1088,8 +1111,8 @@ namespace Umbraco.Core.Services
}
catch (DataOperationException<MoveOperationStatusType> ex)
{
return Attempt.Fail(
new OperationStatus<MoveOperationStatusType>(ex.Operation, evtMsgs));
uow.Commit();
return Attempt.Fail(new OperationStatus<MoveOperationStatusType>(ex.Operation, evtMsgs));
}
uow.Commit();
uow.Events.Dispatch(MovedContentType, this, new MoveEventArgs<IContentType>(false, evtMsgs, moveInfo.ToArray()));
@@ -1135,6 +1158,7 @@ namespace Umbraco.Core.Services
}
catch (DataOperationException<MoveOperationStatusType> ex)
{
uow.Commit();
return Attempt.Fail(new OperationStatus<IMediaType, MoveOperationStatusType>(null, ex.Operation, evtMsgs));
}
uow.Commit();
@@ -1179,6 +1203,7 @@ namespace Umbraco.Core.Services
}
catch (DataOperationException<MoveOperationStatusType> ex)
{
uow.Commit();
return Attempt.Fail(new OperationStatus<IContentType, MoveOperationStatusType>(null, ex.Operation, evtMsgs));
}
uow.Commit();
@@ -1203,23 +1228,21 @@ namespace Umbraco.Core.Services
uow.Commit();
return;
}
var repository = RepositoryFactory.CreateMediaTypeRepository(uow);
ValidateLocked(mediaType); // throws if invalid
mediaType.CreatorId = userId;
repository.AddOrUpdate(mediaType);
uow.Commit();
}
UpdateContentXmlStructure(mediaType); // fixme wtf
UpdateContentXmlStructure(mediaType);
using (var scope = UowProvider.ScopeProvider.CreateScope()) // fixme what a mess
{
scope.Events.Dispatch(SavedMediaType, this, new SaveEventArgs<IMediaType>(mediaType, false));
scope.Complete();
uow.Events.Dispatch(SavedMediaType, this, new SaveEventArgs<IMediaType>(mediaType, false));
Audit(uow, AuditType.Save, "Save MediaType performed by user", userId, mediaType.Id);
uow.Commit();
}
Audit(AuditType.Save, "Save MediaType performed by user", userId, mediaType.Id);
}
}
@@ -1231,7 +1254,7 @@ namespace Umbraco.Core.Services
public void Save(IEnumerable<IMediaType> mediaTypes, int userId = 0)
{
var asArray = mediaTypes.ToArray();
using (new WriteLock(Locker))
{
using (var uow = UowProvider.GetUnitOfWork())
@@ -1241,7 +1264,7 @@ namespace Umbraco.Core.Services
uow.Commit();
return;
}
var repository = RepositoryFactory.CreateMediaTypeRepository(uow);
foreach (var mediaType in asArray)
@@ -1256,15 +1279,14 @@ namespace Umbraco.Core.Services
//save it all in one go
uow.Commit();
}
UpdateContentXmlStructure(asArray.Cast<IContentTypeBase>().ToArray()); // fixme wtf
using (var scope = UowProvider.ScopeProvider.CreateScope()) // fixme what a mess
{
scope.Events.Dispatch(SavedMediaType, this, new SaveEventArgs<IMediaType>(asArray, false));
scope.Complete();
UpdateContentXmlStructure(asArray.Cast<IContentTypeBase>().ToArray());
uow.Events.Dispatch(SavedMediaType, this, new SaveEventArgs<IMediaType>(asArray, false));
Audit(uow, AuditType.Save, "Save MediaTypes performed by user", userId, -1);
uow.Commit();
}
Audit(AuditType.Save, "Save MediaTypes performed by user", userId, -1);
}
}
@@ -1292,17 +1314,17 @@ namespace Umbraco.Core.Services
//If we are deleting this content type, we are also deleting it's descendents!
var deletedMediaTypes = new List<IMediaType> { mediaType };
deletedMediaTypes.AddRange(mediaType.Descendants((IContentTypeService)this).OfType<IMediaType>());
deletedMediaTypes.AddRange(GetDescendants(mediaType));
_mediaService.DeleteMediaOfTypes(deletedMediaTypes.Select(x => x.Id), userId);
repository.Delete(mediaType);
uow.Commit();
uow.Events.Dispatch(DeletedMediaType, this, new DeleteEventArgs<IMediaType>(deletedMediaTypes.DistinctBy(x => x.Id), false));
}
Audit(AuditType.Delete, "Delete MediaType performed by user", userId, mediaType.Id);
Audit(uow, AuditType.Delete, "Delete MediaType performed by user", userId, mediaType.Id);
uow.Commit();
}
}
}
@@ -1317,7 +1339,7 @@ namespace Umbraco.Core.Services
//TODO: Share all of this logic with the Delete IContentType methods, no need for code duplication
var asArray = mediaTypes.ToArray();
using (new WriteLock(Locker))
{
using (var uow = UowProvider.GetUnitOfWork())
@@ -1329,12 +1351,12 @@ namespace Umbraco.Core.Services
}
var repository = RepositoryFactory.CreateMediaTypeRepository(uow);
//If we are deleting this content type, we are also deleting it's descendents!
var deletedMediaTypes = new List<IMediaType>(asArray);
foreach (var mediaType in asArray)
{
deletedMediaTypes.AddRange(mediaType.Descendants((IContentTypeService)this).OfType<IMediaType>());
deletedMediaTypes.AddRange(GetDescendants(mediaType));
}
_mediaService.DeleteMediaOfTypes(deletedMediaTypes.Select(x => x.Id), userId);
@@ -1344,12 +1366,11 @@ namespace Umbraco.Core.Services
repository.Delete(mediaType);
}
uow.Commit();
uow.Events.Dispatch(DeletedMediaType, this, new DeleteEventArgs<IMediaType>(deletedMediaTypes.DistinctBy(x => x.Id), false));
}
Audit(AuditType.Delete, "Delete MediaTypes performed by user", userId, -1);
Audit(uow, AuditType.Delete, "Delete MediaTypes performed by user", userId, -1);
uow.Commit();
}
}
}
@@ -1408,14 +1429,10 @@ namespace Umbraco.Core.Services
return dtd.ToString();
}
private void Audit(AuditType type, string message, int userId, int objectId)
private void Audit(IScopeUnitOfWork uow, AuditType type, string message, int userId, int objectId)
{
using (var uow = UowProvider.GetUnitOfWork())
{
var auditRepo = RepositoryFactory.CreateAuditRepository(uow);
auditRepo.AddOrUpdate(new AuditItem(objectId, message, type, userId));
uow.Commit();
}
var auditRepo = RepositoryFactory.CreateAuditRepository(uow);
auditRepo.AddOrUpdate(new AuditItem(objectId, message, type, userId));
}
#region Event Handlers
@@ -5,6 +5,7 @@ using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Services
@@ -13,9 +14,8 @@ namespace Umbraco.Core.Services
{
public ContentTypeServiceBase(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory)
: base(provider, repositoryFactory, logger, eventMessagesFactory)
{
}
{ }
/// <summary>
/// This is called after an content type is saved and is used to update the content xml structures in the database
/// if they are required to be updated.
@@ -33,7 +33,7 @@ namespace Umbraco.Core.Services
// - a content type changes it's alias OR
// - if a content type has it's property removed OR
// - if a content type has a property whose alias has changed
//here we need to check if the alias of the content type changed or if one of the properties was removed.
//here we need to check if the alias of the content type changed or if one of the properties was removed.
var dirty = contentType as IRememberBeingDirty;
if (dirty == null) continue;
@@ -50,25 +50,45 @@ namespace Umbraco.Core.Services
&& (dirty.WasPropertyDirty("Alias") || dirty.WasPropertyDirty("HasPropertyTypeBeenRemoved") || hasAnyPropertiesChangedAlias))
{
//If the alias was changed then we only need to update the xml structures for content of the current content type.
//If a property was deleted or a property alias was changed then we need to update the xml structures for any
//If a property was deleted or a property alias was changed then we need to update the xml structures for any
// content of the current content type and any of the content type's child content types.
if (dirty.WasPropertyDirty("Alias")
&& dirty.WasPropertyDirty("HasPropertyTypeBeenRemoved") == false && hasAnyPropertiesChangedAlias == false)
{
//if only the alias changed then only update the current content type
//if only the alias changed then only update the current content type
toUpdate.Add(contentType);
}
else
{
//if a property was deleted or alias changed, then update all content of the current content type
// and all of it's desscendant doc types.
toUpdate.AddRange(contentType.DescendantsAndSelf(this));
// and all of it's desscendant doc types.
toUpdate.Add(contentType);
toUpdate.AddRange(GetDescendants(contentType));
}
}
}
return toUpdate;
}
public virtual IEnumerable<IContentTypeBase> GetDescendants(IContentTypeBase contentType)
{
return Enumerable.Empty<IContentTypeBase>();
}
/// <summary>
/// Given the path of a content item, this will return true if the content item exists underneath a list view content item
/// </summary>
/// <param name="contentPath"></param>
/// <returns></returns>
public bool HasContainerInPath(string contentPath)
{
using (var uow = UowProvider.GetUnitOfWork())
{
// can use same repo for both content and media
var repository = RepositoryFactory.CreateContentTypeRepository(uow);
return repository.HasContainerInPath(contentPath);
}
}
}
}
+32 -33
View File
@@ -66,7 +66,7 @@ namespace Umbraco.Core.Services
public EntityContainer GetContainer(int containerId)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DataTypeContainerGuid);
return repo.Get(containerId);
@@ -75,7 +75,7 @@ namespace Umbraco.Core.Services
public EntityContainer GetContainer(Guid containerId)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DataTypeContainerGuid);
return repo.Get(containerId);
@@ -84,7 +84,7 @@ namespace Umbraco.Core.Services
public IEnumerable<EntityContainer> GetContainers(string name, int level)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DataTypeContainerGuid);
return repo.Get(name, level);
@@ -108,7 +108,7 @@ namespace Umbraco.Core.Services
public IEnumerable<EntityContainer> GetContainers(int[] containerIds)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DataTypeContainerGuid);
return repo.GetAll(containerIds);
@@ -181,7 +181,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IDataTypeDefinition"/></returns>
public IDataTypeDefinition GetDataTypeDefinitionByName(string name)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateDataTypeDefinitionRepository(uow);
return repository.GetByQuery(new Query<IDataTypeDefinition>().Where(x => x.Name == name)).FirstOrDefault();
@@ -195,7 +195,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IDataTypeDefinition"/></returns>
public IDataTypeDefinition GetDataTypeDefinitionById(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateDataTypeDefinitionRepository(uow);
return repository.Get(id);
@@ -209,7 +209,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IDataTypeDefinition"/></returns>
public IDataTypeDefinition GetDataTypeDefinitionById(Guid id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateDataTypeDefinitionRepository(uow);
var query = Query<IDataTypeDefinition>.Builder.Where(x => x.Key == id);
@@ -238,7 +238,7 @@ namespace Umbraco.Core.Services
/// <returns>Collection of <see cref="IDataTypeDefinition"/> objects with a matching contorl id</returns>
public IEnumerable<IDataTypeDefinition> GetDataTypeDefinitionByPropertyEditorAlias(string propertyEditorAlias)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateDataTypeDefinitionRepository(uow);
var query = Query<IDataTypeDefinition>.Builder.Where(x => x.PropertyEditorAlias == propertyEditorAlias);
@@ -253,7 +253,7 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of <see cref="IDataTypeDefinition"/> objects</returns>
public IEnumerable<IDataTypeDefinition> GetAllDataTypeDefinitions(params int[] ids)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateDataTypeDefinitionRepository(uow);
return repository.GetAll(ids);
@@ -267,7 +267,7 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of string values</returns>
public IEnumerable<string> GetPreValuesByDataTypeId(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateDataTypeDefinitionRepository(uow);
//now convert the collection to a string list
@@ -284,7 +284,7 @@ namespace Umbraco.Core.Services
/// <returns></returns>
public PreValueCollection GetPreValuesCollectionByDataTypeId(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateDataTypeDefinitionRepository(uow);
return repository.GetPreValuesCollectionByDataTypeId(id);
@@ -298,7 +298,7 @@ namespace Umbraco.Core.Services
/// <returns>PreValue as a string</returns>
public string GetPreValueAsString(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateDataTypeDefinitionRepository(uow);
return repository.GetPreValueAsString(id);
@@ -313,7 +313,10 @@ namespace Umbraco.Core.Services
using (var uow = UowProvider.GetUnitOfWork())
{
if (uow.Events.DispatchCancelable(Moving, this, new MoveEventArgs<IDataTypeDefinition>(evtMsgs, new MoveEventInfo<IDataTypeDefinition>(toMove, toMove.Path, parentId))))
{
uow.Commit();
return Attempt.Fail(new OperationStatus<MoveOperationStatusType>(MoveOperationStatusType.FailedCancelledByEvent, evtMsgs));
}
var containerRepository = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DataTypeContainerGuid);
var repository = RepositoryFactory.CreateDataTypeDefinitionRepository(uow);
@@ -366,13 +369,12 @@ namespace Umbraco.Core.Services
dataTypeDefinition.CreatorId = userId;
repository.AddOrUpdate(dataTypeDefinition);
uow.Commit();
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IDataTypeDefinition>(dataTypeDefinition, false));
}
// FIXME transaction!
Audit(AuditType.Save, "Save DataTypeDefinition performed by user", userId, dataTypeDefinition.Id);
Audit(uow, AuditType.Save, "Save DataTypeDefinition performed by user", userId, dataTypeDefinition.Id);
uow.Commit();
}
}
/// <summary>
@@ -411,13 +413,13 @@ namespace Umbraco.Core.Services
dataTypeDefinition.CreatorId = userId;
repository.AddOrUpdate(dataTypeDefinition);
}
uow.Commit();
if (raiseEvents)
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IDataTypeDefinition>(dataTypeDefinitions, false));
}
Audit(AuditType.Save, string.Format("Save DataTypeDefinition performed by user"), userId, -1);
Audit(uow, AuditType.Save, string.Format("Save DataTypeDefinition performed by user"), userId, -1);
uow.Commit();
}
}
/// <summary>
@@ -487,7 +489,6 @@ namespace Umbraco.Core.Services
using (var uow = UowProvider.GetUnitOfWork())
{
var repository = RepositoryFactory.CreateDataTypeDefinitionRepository(uow);
repository.AddOrUpdatePreValues(dataTypeDefinition, values);
uow.Commit();
}
@@ -504,7 +505,10 @@ namespace Umbraco.Core.Services
using (var uow = UowProvider.GetUnitOfWork())
{
if (uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IDataTypeDefinition>(dataTypeDefinition)))
{
uow.Commit();
return;
}
// if preValues contain the data type, override the data type definition accordingly
if (values != null && values.ContainsKey(Constants.PropertyEditors.PreValueKeys.DataValueType))
@@ -520,12 +524,11 @@ namespace Umbraco.Core.Services
//add/update the prevalues
repository.AddOrUpdatePreValues(dataTypeDefinition, values);
Audit(uow, AuditType.Save, string.Format("Save DataTypeDefinition performed by user"), userId, dataTypeDefinition.Id);
uow.Commit();
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IDataTypeDefinition>(dataTypeDefinition, false));
}
Audit(AuditType.Save, string.Format("Save DataTypeDefinition performed by user"), userId, dataTypeDefinition.Id);
}
/// <summary>
@@ -542,18 +545,20 @@ namespace Umbraco.Core.Services
using (var uow = UowProvider.GetUnitOfWork())
{
if (uow.Events.DispatchCancelable(Deleting, this, new DeleteEventArgs<IDataTypeDefinition>(dataTypeDefinition)))
{
uow.Commit();
return;
}
var repository = RepositoryFactory.CreateDataTypeDefinitionRepository(uow);
repository.Delete(dataTypeDefinition);
Audit(uow, AuditType.Delete, "Delete DataTypeDefinition performed by user", userId, dataTypeDefinition.Id);
uow.Commit();
uow.Events.Dispatch(Deleted, this, new DeleteEventArgs<IDataTypeDefinition>(dataTypeDefinition, false));
}
Audit(AuditType.Delete, "Delete DataTypeDefinition performed by user", userId, dataTypeDefinition.Id);
}
/// <summary>
@@ -577,14 +582,10 @@ namespace Umbraco.Core.Services
return DataTypesResolver.Current.DataTypes;
}
private void Audit(AuditType type, string message, int userId, int objectId)
private void Audit(IScopeUnitOfWork uow, AuditType type, string message, int userId, int objectId)
{
using (var uow = UowProvider.GetUnitOfWork())
{
var auditRepo = RepositoryFactory.CreateAuditRepository(uow);
auditRepo.AddOrUpdate(new AuditItem(objectId, message, type, userId));
uow.Commit();
}
var auditRepo = RepositoryFactory.CreateAuditRepository(uow);
auditRepo.AddOrUpdate(new AuditItem(objectId, message, type, userId));
}
#region Event Handlers
@@ -624,7 +625,5 @@ namespace Umbraco.Core.Services
/// </summary>
public static event TypedEventHandler<IDataTypeService, MoveEventArgs<IDataTypeDefinition>> Moved;
#endregion
}
}
+11 -5
View File
@@ -19,7 +19,7 @@ namespace Umbraco.Core.Services
public bool Exists(string domainName)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repo = RepositoryFactory.CreateDomainRepository(uow);
return repo.Exists(domainName);
@@ -33,7 +33,10 @@ namespace Umbraco.Core.Services
using (var uow = UowProvider.GetUnitOfWork())
{
if (uow.Events.DispatchCancelable(Deleting, this, new DeleteEventArgs<IDomain>(domain, evtMsgs)))
{
uow.Commit();
return OperationStatus.Cancelled(evtMsgs);
}
var repository = RepositoryFactory.CreateDomainRepository(uow);
repository.Delete(domain);
@@ -49,7 +52,7 @@ namespace Umbraco.Core.Services
public IDomain GetByName(string name)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateDomainRepository(uow);
return repository.GetByName(name);
@@ -58,7 +61,7 @@ namespace Umbraco.Core.Services
public IDomain GetById(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repo = RepositoryFactory.CreateDomainRepository(uow);
return repo.Get(id);
@@ -67,7 +70,7 @@ namespace Umbraco.Core.Services
public IEnumerable<IDomain> GetAll(bool includeWildcards)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repo = RepositoryFactory.CreateDomainRepository(uow);
return repo.GetAll(includeWildcards);
@@ -76,7 +79,7 @@ namespace Umbraco.Core.Services
public IEnumerable<IDomain> GetAssignedDomains(int contentId, bool includeWildcards)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repo = RepositoryFactory.CreateDomainRepository(uow);
return repo.GetAssignedDomains(contentId, includeWildcards);
@@ -90,7 +93,10 @@ namespace Umbraco.Core.Services
using (var uow = UowProvider.GetUnitOfWork())
{
if (uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IDomain>(domainEntity, evtMsgs)))
{
uow.Commit();
return OperationStatus.Cancelled(evtMsgs);
}
var repository = RepositoryFactory.CreateDomainRepository(uow);
repository.AddOrUpdate(domainEntity);
+23 -44
View File
@@ -79,7 +79,7 @@ namespace Umbraco.Core.Services
{
var result = _runtimeCache.GetCacheItem<int?>(CacheKeys.IdToKeyCacheKey + key, () =>
{
using (var uow = UowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork(readOnly:true))
{
switch (umbracoObjectType)
{
@@ -92,7 +92,6 @@ namespace Umbraco.Core.Services
case UmbracoObjectTypes.Member:
case UmbracoObjectTypes.DataType:
case UmbracoObjectTypes.DocumentTypeContainer:
uow.Commit();
return uow.Database.ExecuteScalar<int?>(new Sql().Select("id").From<NodeDto>().Where<NodeDto>(dto => dto.UniqueId == key));
case UmbracoObjectTypes.RecycleBin:
case UmbracoObjectTypes.Stylesheet:
@@ -119,7 +118,7 @@ namespace Umbraco.Core.Services
{
var result = _runtimeCache.GetCacheItem<Guid?>(CacheKeys.KeyToIdCacheKey + id, () =>
{
using (var uow = UowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork(readOnly:true))
{
switch (umbracoObjectType)
{
@@ -131,7 +130,6 @@ namespace Umbraco.Core.Services
case UmbracoObjectTypes.DocumentType:
case UmbracoObjectTypes.Member:
case UmbracoObjectTypes.DataType:
uow.Commit();
return uow.Database.ExecuteScalar<Guid?>(new Sql().Select("uniqueID").From<NodeDto>().Where<NodeDto>(dto => dto.NodeId == id));
case UmbracoObjectTypes.RecycleBin:
case UmbracoObjectTypes.Stylesheet:
@@ -185,11 +183,10 @@ namespace Umbraco.Core.Services
{
if (loadBaseType)
{
using (var uow = UowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork(readOnly:true))
{
var repository = RepositoryFactory.CreateEntityRepository(uow);
var ret = repository.Get(id);
uow.Commit();
return ret;
}
}
@@ -207,11 +204,10 @@ namespace Umbraco.Core.Services
if (loadBaseType)
{
var objectTypeId = umbracoObjectType.GetGuid();
using (var uow = UowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork(readOnly:true))
{
var repository = RepositoryFactory.CreateEntityRepository(uow);
var ret = repository.GetByKey(key, objectTypeId);
uow.Commit();
return ret;
}
}
@@ -241,11 +237,10 @@ namespace Umbraco.Core.Services
if (loadBaseType)
{
var objectTypeId = umbracoObjectType.GetGuid();
using (var uow = UowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork(readOnly:true))
{
var repository = RepositoryFactory.CreateEntityRepository(uow);
var ret = repository.Get(id, objectTypeId);
uow.Commit();
return ret;
}
}
@@ -276,11 +271,10 @@ namespace Umbraco.Core.Services
{
if (loadBaseType)
{
using (var uow = UowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork(readOnly:true))
{
var repository = RepositoryFactory.CreateEntityRepository(uow);
var ret = repository.Get(id);
uow.Commit();
return ret;
}
}
@@ -303,7 +297,7 @@ namespace Umbraco.Core.Services
/// <returns>An <see cref="IUmbracoEntity"/></returns>
public virtual IUmbracoEntity GetParent(int id)
{
using (var uow = UowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork(readOnly:true))
{
var repository = RepositoryFactory.CreateEntityRepository(uow);
var entity = repository.Get(id);
@@ -311,7 +305,6 @@ namespace Umbraco.Core.Services
if (entity.ParentId == -1 || entity.ParentId == -20 || entity.ParentId == -21)
return null;
var ret = repository.Get(entity.ParentId);
uow.Commit();
return ret;
}
}
@@ -324,7 +317,7 @@ namespace Umbraco.Core.Services
/// <returns>An <see cref="IUmbracoEntity"/></returns>
public virtual IUmbracoEntity GetParent(int id, UmbracoObjectTypes umbracoObjectType)
{
using (var uow = UowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork(readOnly:true))
{
var repository = RepositoryFactory.CreateEntityRepository(uow);
var entity = repository.Get(id);
@@ -334,7 +327,6 @@ namespace Umbraco.Core.Services
var objectTypeId = umbracoObjectType.GetGuid();
var ret = repository.Get(entity.ParentId, objectTypeId);
uow.Commit();
return ret;
}
}
@@ -346,13 +338,12 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of <see cref="IUmbracoEntity"/> objects</returns>
public virtual IEnumerable<IUmbracoEntity> GetChildren(int parentId)
{
using (var uow = UowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork(readOnly:true))
{
var repository = RepositoryFactory.CreateEntityRepository(uow);
var query = Query<IUmbracoEntity>.Builder.Where(x => x.ParentId == parentId);
var contents = repository.GetByQuery(query);
uow.Commit();
return contents;
}
}
@@ -366,13 +357,12 @@ namespace Umbraco.Core.Services
public virtual IEnumerable<IUmbracoEntity> GetChildren(int parentId, UmbracoObjectTypes umbracoObjectType)
{
var objectTypeId = umbracoObjectType.GetGuid();
using (var uow = UowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork(readOnly:true))
{
var repository = RepositoryFactory.CreateEntityRepository(uow);
var query = Query<IUmbracoEntity>.Builder.Where(x => x.ParentId == parentId);
var contents = repository.GetByQuery(query, objectTypeId);
uow.Commit();
return contents;
}
}
@@ -393,7 +383,7 @@ namespace Umbraco.Core.Services
string orderBy = "SortOrder", Direction orderDirection = Direction.Ascending, string filter = "")
{
var objectTypeId = umbracoObjectType.GetGuid();
using (var uow = UowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork(readOnly:true))
{
var repository = RepositoryFactory.CreateEntityRepository(uow);
var query = Query<IUmbracoEntity>.Builder.Where(x => x.ParentId == parentId && x.Trashed == false);
@@ -405,7 +395,6 @@ namespace Umbraco.Core.Services
}
var contents = repository.GetPagedResultsByQuery(query, objectTypeId, pageIndex, pageSize, out totalRecords, orderBy, orderDirection, filterQuery);
uow.Commit();
return contents;
}
}
@@ -426,7 +415,7 @@ namespace Umbraco.Core.Services
string orderBy = "path", Direction orderDirection = Direction.Ascending, string filter = "")
{
var objectTypeId = umbracoObjectType.GetGuid();
using (var uow = UowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork(readOnly:true))
{
var repository = RepositoryFactory.CreateEntityRepository(uow);
@@ -442,7 +431,6 @@ namespace Umbraco.Core.Services
}
var contents = repository.GetPagedResultsByQuery(query, objectTypeId, pageIndex, pageSize, out totalRecords, orderBy, orderDirection, filterQuery);
uow.Commit();
return contents;
}
}
@@ -463,7 +451,7 @@ namespace Umbraco.Core.Services
string orderBy = "path", Direction orderDirection = Direction.Ascending, string filter = "", bool includeTrashed = true)
{
var objectTypeId = umbracoObjectType.GetGuid();
using (var uow = UowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork(readOnly:true))
{
var repository = RepositoryFactory.CreateEntityRepository(uow);
@@ -481,7 +469,6 @@ namespace Umbraco.Core.Services
}
var contents = repository.GetPagedResultsByQuery(query, objectTypeId, pageIndex, pageSize, out totalRecords, orderBy, orderDirection, filterQuery);
uow.Commit();
return contents;
}
}
@@ -493,7 +480,7 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of <see cref="IUmbracoEntity"/> objects</returns>
public virtual IEnumerable<IUmbracoEntity> GetDescendents(int id)
{
using (var uow = UowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork(readOnly:true))
{
var repository = RepositoryFactory.CreateEntityRepository(uow);
var entity = repository.Get(id);
@@ -501,7 +488,6 @@ namespace Umbraco.Core.Services
var query = Query<IUmbracoEntity>.Builder.Where(x => x.Path.StartsWith(pathMatch) && x.Id != id);
var entities = repository.GetByQuery(query);
uow.Commit();
return entities;
}
}
@@ -515,14 +501,13 @@ namespace Umbraco.Core.Services
public virtual IEnumerable<IUmbracoEntity> GetDescendents(int id, UmbracoObjectTypes umbracoObjectType)
{
var objectTypeId = umbracoObjectType.GetGuid();
using (var uow = UowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork(readOnly:true))
{
var repository = RepositoryFactory.CreateEntityRepository(uow);
var entity = repository.Get(id);
var query = Query<IUmbracoEntity>.Builder.Where(x => x.Path.StartsWith(entity.Path) && x.Id != id);
var entities = repository.GetByQuery(query, objectTypeId);
uow.Commit();
return entities;
}
}
@@ -541,11 +526,10 @@ namespace Umbraco.Core.Services
}
var objectTypeId = umbracoObjectType.GetGuid();
using (var uow = UowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork(readOnly:true))
{
var repository = RepositoryFactory.CreateEntityRepository(uow);
var entities = repository.GetByQuery(_rootEntityQuery, objectTypeId);
uow.Commit();
return entities;
}
}
@@ -585,11 +569,10 @@ namespace Umbraco.Core.Services
});
var objectTypeId = umbracoObjectType.GetGuid();
using (var uow = UowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork(readOnly:true))
{
var repository = RepositoryFactory.CreateEntityRepository(uow);
var ret = repository.GetAll(objectTypeId, ids);
uow.Commit();
return ret;
}
}
@@ -605,11 +588,10 @@ namespace Umbraco.Core.Services
});
var objectTypeId = umbracoObjectType.GetGuid();
using (var uow = UowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork(readOnly:true))
{
var repository = RepositoryFactory.CreateEntityRepository(uow);
var ret = repository.GetAll(objectTypeId, keys);
uow.Commit();
return ret;
}
}
@@ -631,11 +613,10 @@ namespace Umbraco.Core.Services
("The passed in type is not supported");
});
using (var uow = UowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork(readOnly:true))
{
var repository = RepositoryFactory.CreateEntityRepository(uow);
var ret = repository.GetAll(objectTypeId, ids);
uow.Commit();
return ret;
}
}
@@ -647,7 +628,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="UmbracoObjectTypes"/></returns>
public virtual UmbracoObjectTypes GetObjectType(int id)
{
using (var uow = UowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var sql = new Sql().Select("nodeObjectType").From<NodeDto>().Where<NodeDto>(x => x.NodeId == id);
var nodeObjectTypeId = uow.Database.ExecuteScalar<Guid>(sql);
@@ -663,7 +644,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="UmbracoObjectTypes"/></returns>
public virtual UmbracoObjectTypes GetObjectType(Guid key)
{
using (var uow = UowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var sql = new Sql().Select("nodeObjectType").From<NodeDto>().Where<NodeDto>(x => x.UniqueId == key);
var nodeObjectTypeId = uow.Database.ExecuteScalar<Guid>(sql);
@@ -721,22 +702,20 @@ namespace Umbraco.Core.Services
public bool Exists(Guid key)
{
using (var uow = UowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork(readOnly:true))
{
var repository = RepositoryFactory.CreateEntityRepository(uow);
var exists = repository.Exists(key);
uow.Commit();
return exists;
}
}
public bool Exists(int id)
{
using (var uow = UowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork(readOnly:true))
{
var repository = RepositoryFactory.CreateEntityRepository(uow);
var exists = repository.Exists(id);
uow.Commit();
return exists;
}
}
+109 -123
View File
@@ -15,31 +15,21 @@ using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Services
{
// note
// file unit of work are just IUnitOfWork which is not IDisposable
// they don't really participate in the scope etc ;(
// FIXME not anymore now that Shan's made FileUnitOfWork a normal UOW? then WTF?
/// <summary>
/// Represents the File Service, which is an easy access to operations involving <see cref="IFile"/> objects like Scripts, Stylesheets and Templates
/// </summary>
public class FileService : ScopeRepositoryService, IFileService
{
private readonly IScopeUnitOfWorkProvider _fileUowProvider;
private const string PartialViewHeader = "@inherits Umbraco.Web.Mvc.UmbracoTemplatePage";
private const string PartialViewMacroHeader = "@inherits Umbraco.Web.Macros.PartialViewMacroPage";
public FileService(
IScopeUnitOfWorkProvider fileProvider,
IDatabaseUnitOfWorkProvider dataProvider,
IDatabaseUnitOfWorkProvider provider,
RepositoryFactory repositoryFactory,
ILogger logger,
IEventMessagesFactory eventMessagesFactory)
: base(dataProvider, repositoryFactory, logger, eventMessagesFactory)
{
_fileUowProvider = fileProvider;
}
: base(provider, repositoryFactory, logger, eventMessagesFactory)
{ }
#region Stylesheets
@@ -50,11 +40,9 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of <see cref="Stylesheet"/> objects</returns>
public IEnumerable<Stylesheet> GetStylesheets(params string[] names)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
// FIXME is it ok to use the same UOW here twice?
// review everywhere in this file!!
var repository = RepositoryFactory.CreateStylesheetRepository(uow, uow);
var repository = RepositoryFactory.CreateStylesheetRepository(uow);
return repository.GetAll(names);
}
}
@@ -66,9 +54,9 @@ namespace Umbraco.Core.Services
/// <returns>A <see cref="Stylesheet"/> object</returns>
public Stylesheet GetStylesheetByName(string name)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateStylesheetRepository(uow, uow);
var repository = RepositoryFactory.CreateStylesheetRepository(uow);
return repository.Get(name);
}
}
@@ -88,13 +76,14 @@ namespace Umbraco.Core.Services
return;
}
var repository = RepositoryFactory.CreateStylesheetRepository(uow, uow);
var repository = RepositoryFactory.CreateStylesheetRepository(uow);
repository.AddOrUpdate(stylesheet);
uow.Commit();
uow.Events.Dispatch(SavedStylesheet, this, new SaveEventArgs<Stylesheet>(stylesheet, false));
}
Audit(AuditType.Save, "Save Stylesheet performed by user", userId, -1);
uow.Events.Dispatch(SavedStylesheet, this, new SaveEventArgs<Stylesheet>(stylesheet, false));
Audit(uow, AuditType.Save, "Save Stylesheet performed by user", userId, -1);
uow.Commit();
}
}
/// <summary>
@@ -106,7 +95,7 @@ namespace Umbraco.Core.Services
{
using (var uow = UowProvider.GetUnitOfWork())
{
var repository = RepositoryFactory.CreateStylesheetRepository(uow, uow);
var repository = RepositoryFactory.CreateStylesheetRepository(uow);
var stylesheet = repository.Get(path);
if (stylesheet == null)
{
@@ -121,12 +110,12 @@ namespace Umbraco.Core.Services
}
repository.Delete(stylesheet);
uow.Commit();
uow.Events.Dispatch(DeletedStylesheet, this, new DeleteEventArgs<Stylesheet>(stylesheet, false));
}
Audit(AuditType.Delete, string.Format("Delete Stylesheet performed by user"), userId, -1);
Audit(uow, AuditType.Delete, string.Format("Delete Stylesheet performed by user"), userId, -1);
uow.Commit();
}
}
/// <summary>
@@ -136,9 +125,9 @@ namespace Umbraco.Core.Services
/// <returns>True if Stylesheet is valid, otherwise false</returns>
public bool ValidateStylesheet(Stylesheet stylesheet)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateStylesheetRepository(uow, uow);
var repository = RepositoryFactory.CreateStylesheetRepository(uow);
return repository.ValidateStylesheet(stylesheet);
}
}
@@ -152,7 +141,7 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of <see cref="Script"/> objects</returns>
public IEnumerable<Script> GetScripts(params string[] names)
{
using (var uow = _fileUowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateScriptRepository(uow);
return repository.GetAll(names);
@@ -166,7 +155,7 @@ namespace Umbraco.Core.Services
/// <returns>A <see cref="Script"/> object</returns>
public Script GetScriptByName(string name)
{
using (var uow = _fileUowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateScriptRepository(uow);
return repository.Get(name);
@@ -180,7 +169,7 @@ namespace Umbraco.Core.Services
/// <param name="userId"></param>
public void SaveScript(Script script, int userId = 0)
{
using (var uow = _fileUowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork())
{
if (uow.Events.DispatchCancelable(SavingScript, this, new SaveEventArgs<Script>(script)))
{
@@ -190,12 +179,12 @@ namespace Umbraco.Core.Services
var repository = RepositoryFactory.CreateScriptRepository(uow);
repository.AddOrUpdate(script);
uow.Commit();
uow.Events.Dispatch(SavedScript, this, new SaveEventArgs<Script>(script, false));
}
Audit(AuditType.Save, "Save Script performed by user", userId, -1);
Audit(uow, AuditType.Save, "Save Script performed by user", userId, -1);
uow.Commit();
}
}
/// <summary>
@@ -205,7 +194,7 @@ namespace Umbraco.Core.Services
/// <param name="userId"></param>
public void DeleteScript(string path, int userId = 0)
{
using (var uow = _fileUowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork())
{
var repository = RepositoryFactory.CreateScriptRepository(uow);
var script = repository.Get(path);
@@ -222,12 +211,12 @@ namespace Umbraco.Core.Services
}
repository.Delete(script);
uow.Commit();
uow.Events.Dispatch(DeletedScript, this, new DeleteEventArgs<Script>(script, false));
}
Audit(AuditType.Delete, string.Format("Delete Script performed by user"), userId, -1);
Audit(uow, AuditType.Delete, string.Format("Delete Script performed by user"), userId, -1);
uow.Commit();
}
}
/// <summary>
@@ -237,7 +226,7 @@ namespace Umbraco.Core.Services
/// <returns>True if Script is valid, otherwise false</returns>
public bool ValidateScript(Script script)
{
using (var uow = _fileUowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateScriptRepository(uow);
return repository.ValidateScript(script);
@@ -246,7 +235,7 @@ namespace Umbraco.Core.Services
public void CreateScriptFolder(string folderPath)
{
using (var uow = _fileUowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork())
{
var repository = RepositoryFactory.CreateScriptRepository(uow);
((ScriptRepository)repository).AddFolder(folderPath);
@@ -256,7 +245,7 @@ namespace Umbraco.Core.Services
public void DeleteScriptFolder(string folderPath)
{
using (var uow = _fileUowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork())
{
var repository = RepositoryFactory.CreateScriptRepository(uow);
((ScriptRepository)repository).DeleteFolder(folderPath);
@@ -308,12 +297,12 @@ namespace Umbraco.Core.Services
var repository = RepositoryFactory.CreateTemplateRepository(uow);
repository.AddOrUpdate(template);
uow.Commit();
uow.Events.Dispatch(SavedTemplate, this, new SaveEventArgs<ITemplate>(template, false, evtMsgs));
}
Audit(AuditType.Save, "Save Template performed by user", userId, template.Id);
Audit(uow, AuditType.Save, "Save Template performed by user", userId, template.Id);
uow.Commit();
}
return Attempt.Succeed(new OperationStatus<ITemplate, OperationStatusType>(template, OperationStatusType.Success, evtMsgs));
}
@@ -338,7 +327,7 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of <see cref="ITemplate"/> objects</returns>
public IEnumerable<ITemplate> GetTemplates(params string[] aliases)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateTemplateRepository(uow);
return repository.GetAll(aliases).OrderBy(x => x.Name);
@@ -351,7 +340,7 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of <see cref="ITemplate"/> objects</returns>
public IEnumerable<ITemplate> GetTemplates(int masterTemplateId)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateTemplateRepository(uow);
return repository.GetChildren(masterTemplateId).OrderBy(x => x.Name);
@@ -365,7 +354,7 @@ namespace Umbraco.Core.Services
/// <returns>The <see cref="ITemplate"/> object matching the alias, or null.</returns>
public ITemplate GetTemplate(string alias)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateTemplateRepository(uow);
return repository.Get(alias);
@@ -379,7 +368,7 @@ namespace Umbraco.Core.Services
/// <returns>The <see cref="ITemplate"/> object matching the identifier, or null.</returns>
public ITemplate GetTemplate(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateTemplateRepository(uow);
return repository.Get(id);
@@ -393,7 +382,7 @@ namespace Umbraco.Core.Services
/// <returns>The <see cref="ITemplate"/> object matching the identifier, or null.</returns>
public ITemplate GetTemplate(Guid id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateTemplateRepository(uow);
var query = Query<ITemplate>.Builder.Where(x => x.Key == id);
@@ -403,7 +392,7 @@ namespace Umbraco.Core.Services
public IEnumerable<ITemplate> GetTemplateDescendants(string alias)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateTemplateRepository(uow);
return repository.GetDescendants(alias);
@@ -417,7 +406,7 @@ namespace Umbraco.Core.Services
/// <returns></returns>
public IEnumerable<ITemplate> GetTemplateDescendants(int masterTemplateId)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateTemplateRepository(uow);
return repository.GetDescendants(masterTemplateId);
@@ -431,7 +420,7 @@ namespace Umbraco.Core.Services
/// <returns></returns>
public IEnumerable<ITemplate> GetTemplateChildren(string alias)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateTemplateRepository(uow);
return repository.GetChildren(alias);
@@ -445,7 +434,7 @@ namespace Umbraco.Core.Services
/// <returns></returns>
public IEnumerable<ITemplate> GetTemplateChildren(int masterTemplateId)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateTemplateRepository(uow);
return repository.GetChildren(masterTemplateId);
@@ -461,7 +450,7 @@ namespace Umbraco.Core.Services
[EditorBrowsable(EditorBrowsableState.Never)]
public TemplateNode GetTemplateNode(string alias)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateTemplateRepository(uow);
return repository.GetTemplateNode(alias);
@@ -478,7 +467,7 @@ namespace Umbraco.Core.Services
[EditorBrowsable(EditorBrowsableState.Never)]
public TemplateNode FindTemplateInTree(TemplateNode anyNode, string alias)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateTemplateRepository(uow);
return repository.FindTemplateInTree(anyNode, alias);
@@ -502,12 +491,12 @@ namespace Umbraco.Core.Services
var repository = RepositoryFactory.CreateTemplateRepository(uow);
repository.AddOrUpdate(template);
uow.Commit();
uow.Events.Dispatch(SavedTemplate, this, new SaveEventArgs<ITemplate>(template, false));
}
Audit(AuditType.Save, "Save Template performed by user", userId, template.Id);
Audit(uow, AuditType.Save, "Save Template performed by user", userId, template.Id);
uow.Commit();
}
}
/// <summary>
@@ -529,12 +518,12 @@ namespace Umbraco.Core.Services
{
repository.AddOrUpdate(template);
}
uow.Commit();
uow.Events.Dispatch(SavedTemplate, this, new SaveEventArgs<ITemplate>(templates, false));
}
Audit(AuditType.Save, "Save Template performed by user", userId, -1);
Audit(uow, AuditType.Save, "Save Template performed by user", userId, -1);
uow.Commit();
}
}
/// <summary>
@@ -552,7 +541,7 @@ namespace Umbraco.Core.Services
/// </remarks>
public RenderingEngine DetermineTemplateRenderingEngine(ITemplate template)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateTemplateRepository(uow);
return repository.DetermineTemplateRenderingEngine(template);
@@ -566,12 +555,10 @@ namespace Umbraco.Core.Services
/// <param name="userId"></param>
public void DeleteTemplate(string alias, int userId = 0)
{
// fixme - WHY outside of UOW?!
// v8 - that should be part of the uow / scope
var template = GetTemplate(alias);
if (template == null)
{
return;
}
using (var uow = UowProvider.GetUnitOfWork())
{
@@ -584,12 +571,12 @@ namespace Umbraco.Core.Services
}
repository.Delete(template);
uow.Commit();
uow.Events.Dispatch(DeletedTemplate, this, new DeleteEventArgs<ITemplate>(template, false));
}
Audit(AuditType.Delete, "Delete Template performed by user", userId, template.Id);
Audit(uow, AuditType.Delete, "Delete Template performed by user", userId, template.Id);
uow.Commit();
}
}
/// <summary>
@@ -599,7 +586,7 @@ namespace Umbraco.Core.Services
/// <returns>True if Script is valid, otherwise false</returns>
public bool ValidateTemplate(ITemplate template)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateTemplateRepository(uow);
return repository.ValidateTemplate(template);
@@ -608,7 +595,7 @@ namespace Umbraco.Core.Services
public Stream GetTemplateFileContentStream(string filepath)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateTemplateRepository(uow);
return repository.GetFileContentStream(filepath);
@@ -617,17 +604,17 @@ namespace Umbraco.Core.Services
public void SetTemplateFileContent(string filepath, Stream content)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork())
{
var repository = RepositoryFactory.CreateTemplateRepository(uow);
repository.SetFileContent(filepath, content);
// fixme - no need to commit... always committing?????
uow.Commit();
}
}
public long GetTemplateFileSize(string filepath)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateTemplateRepository(uow);
return repository.GetFileSize(filepath);
@@ -638,7 +625,7 @@ namespace Umbraco.Core.Services
public Stream GetStylesheetFileContentStream(string filepath)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateStylesheetRepository(uow);
return repository.GetFileContentStream(filepath);
@@ -647,16 +634,17 @@ namespace Umbraco.Core.Services
public void SetStylesheetFileContent(string filepath, Stream content)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork())
{
var repository = RepositoryFactory.CreateStylesheetRepository(uow);
repository.SetFileContent(filepath, content);
uow.Commit();
}
}
public long GetStylesheetFileSize(string filepath)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateStylesheetRepository(uow);
return repository.GetFileSize(filepath);
@@ -665,7 +653,7 @@ namespace Umbraco.Core.Services
public Stream GetScriptFileContentStream(string filepath)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateScriptRepository(uow);
return repository.GetFileContentStream(filepath);
@@ -674,16 +662,17 @@ namespace Umbraco.Core.Services
public void SetScriptFileContent(string filepath, Stream content)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork())
{
var repository = RepositoryFactory.CreateScriptRepository(uow);
repository.SetFileContent(filepath, content);
uow.Commit();
}
}
public long GetScriptFileSize(string filepath)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateScriptRepository(uow);
return repository.GetFileSize(filepath);
@@ -692,7 +681,7 @@ namespace Umbraco.Core.Services
public Stream GetXsltFileContentStream(string filepath)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateXsltFileRepository(uow);
return repository.GetFileContentStream(filepath);
@@ -701,16 +690,17 @@ namespace Umbraco.Core.Services
public void SetXsltFileContent(string filepath, Stream content)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork())
{
var repository = RepositoryFactory.CreateXsltFileRepository(uow);
repository.SetFileContent(filepath, content);
uow.Commit();
}
}
public long GetXsltFileSize(string filepath)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateXsltFileRepository(uow);
return repository.GetFileSize(filepath);
@@ -737,9 +727,9 @@ namespace Umbraco.Core.Services
public void CreatePartialViewFolder(string folderPath)
{
var uow = _fileUowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreatePartialViewRepository(uow))
using (var uow = UowProvider.GetUnitOfWork())
{
var repository = RepositoryFactory.CreatePartialViewRepository(uow);
((PartialViewRepository)repository).AddFolder(folderPath);
uow.Commit();
}
@@ -747,9 +737,9 @@ namespace Umbraco.Core.Services
public void CreatePartialViewMacroFolder(string folderPath)
{
var uow = _fileUowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreatePartialViewMacroRepository(uow))
using (var uow = UowProvider.GetUnitOfWork())
{
var repository = RepositoryFactory.CreatePartialViewMacroRepository(uow);
((PartialViewMacroRepository)repository).AddFolder(folderPath);
uow.Commit();
}
@@ -757,7 +747,7 @@ namespace Umbraco.Core.Services
public void DeletePartialViewFolder(string folderPath)
{
using (var uow = _fileUowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork())
{
var repository = RepositoryFactory.CreatePartialViewRepository(uow);
((PartialViewRepository)repository).DeleteFolder(folderPath);
@@ -767,7 +757,7 @@ namespace Umbraco.Core.Services
public void DeletePartialViewMacroFolder(string folderPath)
{
using (var uow = _fileUowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork())
{
var repository = RepositoryFactory.CreatePartialViewMacroRepository(uow);
((PartialViewMacroRepository)repository).DeleteFolder(folderPath);
@@ -777,7 +767,7 @@ namespace Umbraco.Core.Services
public IPartialView GetPartialView(string path)
{
using (var uow = _fileUowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreatePartialViewRepository(uow);
return repository.Get(path);
@@ -786,7 +776,7 @@ namespace Umbraco.Core.Services
public IPartialView GetPartialViewMacro(string path)
{
using (var uow = _fileUowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreatePartialViewMacroRepository(uow);
return repository.Get(path);
@@ -795,7 +785,7 @@ namespace Umbraco.Core.Services
public IEnumerable<IPartialView> GetPartialViewMacros(params string[] names)
{
using (var uow = _fileUowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreatePartialViewMacroRepository(uow);
return repository.GetAll(names).OrderBy(x => x.Name);
@@ -804,7 +794,7 @@ namespace Umbraco.Core.Services
public IXsltFile GetXsltFile(string path)
{
using (var uow = _fileUowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateXsltFileRepository(uow);
return repository.Get(path);
@@ -813,7 +803,7 @@ namespace Umbraco.Core.Services
public IEnumerable<IXsltFile> GetXsltFiles(params string[] names)
{
using (var uow = _fileUowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateXsltFileRepository(uow);
return repository.GetAll(names).OrderBy(x => x.Name);
@@ -845,16 +835,16 @@ namespace Umbraco.Core.Services
}
using (var uow = _fileUowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork())
{
var repository = GetPartialViewRepository(partialViewType, uow);
repository.AddOrUpdate(partialView);
uow.Commit();
uow.Events.Dispatch(CreatedPartialView, this, new NewEventArgs<IPartialView>(partialView, false, partialView.Alias, -1));
}
Audit(AuditType.Save, string.Format("Save {0} performed by user", partialViewType), userId, -1);
Audit(uow, AuditType.Save, string.Format("Save {0} performed by user", partialViewType), userId, -1);
uow.Commit();
}
return Attempt<IPartialView>.Succeed(partialView);
}
@@ -871,14 +861,14 @@ namespace Umbraco.Core.Services
private bool DeletePartialViewMacro(string path, PartialViewType partialViewType, int userId = 0)
{
using (var uow = _fileUowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork())
{
var repository = GetPartialViewRepository(partialViewType, uow);
var partialView = repository.Get(path);
if (partialView == null)
{
uow.Commit();
return true;
return false;
}
if (uow.Events.DispatchCancelable(DeletingPartialView, this, new DeleteEventArgs<IPartialView>(partialView)))
@@ -888,12 +878,12 @@ namespace Umbraco.Core.Services
}
repository.Delete(partialView);
uow.Commit();
uow.Events.Dispatch(DeletedPartialView, this, new DeleteEventArgs<IPartialView>(partialView, false));
}
Audit(AuditType.Delete, string.Format("Delete {0} performed by user", partialViewType), userId, -1);
Audit(uow, AuditType.Delete, string.Format("Delete {0} performed by user", partialViewType), userId, -1);
uow.Commit();
}
return true;
@@ -911,7 +901,7 @@ namespace Umbraco.Core.Services
private Attempt<IPartialView> SavePartialView(IPartialView partialView, PartialViewType partialViewType, int userId = 0)
{
using (var uow = _fileUowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork())
{
if (uow.Events.DispatchCancelable(SavingPartialView, this, new SaveEventArgs<IPartialView>(partialView)))
{
@@ -921,18 +911,19 @@ namespace Umbraco.Core.Services
var repository = GetPartialViewRepository(partialViewType, uow);
repository.AddOrUpdate(partialView);
uow.Commit();
uow.Events.Dispatch(SavedPartialView, this, new SaveEventArgs<IPartialView>(partialView, false));
}
Audit(AuditType.Save, string.Format("Save {0} performed by user", partialViewType), userId, -1);
uow.Events.Dispatch(SavedPartialView, this, new SaveEventArgs<IPartialView>(partialView, false));
Audit(uow, AuditType.Save, string.Format("Save {0} performed by user", partialViewType), userId, -1);
uow.Commit();
}
return Attempt.Succeed(partialView);
}
public bool ValidatePartialView(PartialView partialView)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreatePartialViewRepository(uow);
return repository.ValidatePartialView(partialView);
@@ -941,7 +932,7 @@ namespace Umbraco.Core.Services
public bool ValidatePartialViewMacro(PartialView partialView)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreatePartialViewMacroRepository(uow);
return repository.ValidatePartialView(partialView);
@@ -981,7 +972,7 @@ namespace Umbraco.Core.Services
public Stream GetPartialViewMacroFileContentStream(string filepath)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = GetPartialViewRepository(PartialViewType.PartialViewMacro, uow);
return repository.GetFileContentStream(filepath);
@@ -1039,7 +1030,6 @@ namespace Umbraco.Core.Services
public void SetPartialViewMacroFileContent(string filepath, Stream content)
{
// FIXME FTW would we use a READONLY unit of work to SET FILE CONTENT
using (var uow = UowProvider.GetUnitOfWork())
{
var repository = GetPartialViewRepository(PartialViewType.PartialViewMacro, uow);
@@ -1050,7 +1040,7 @@ namespace Umbraco.Core.Services
public long GetPartialViewMacroFileSize(string filepath)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = GetPartialViewRepository(PartialViewType.PartialViewMacro, uow);
return repository.GetFileSize(filepath);
@@ -1059,7 +1049,7 @@ namespace Umbraco.Core.Services
public Stream GetPartialViewFileContentStream(string filepath)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = GetPartialViewRepository(PartialViewType.PartialView, uow);
return repository.GetFileContentStream(filepath);
@@ -1078,7 +1068,7 @@ namespace Umbraco.Core.Services
public long GetPartialViewFileSize(string filepath)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = GetPartialViewRepository(PartialViewType.PartialView, uow);
return repository.GetFileSize(filepath);
@@ -1087,14 +1077,10 @@ namespace Umbraco.Core.Services
#endregion
private void Audit(AuditType type, string message, int userId, int objectId)
private void Audit(IScopeUnitOfWork uow, AuditType type, string message, int userId, int objectId)
{
using (var uow = UowProvider.GetUnitOfWork())
{
var repository = RepositoryFactory.CreateAuditRepository(uow);
repository.AddOrUpdate(new AuditItem(objectId, message, type, userId));
uow.Commit();
}
var repository = RepositoryFactory.CreateAuditRepository(uow);
repository.AddOrUpdate(new AuditItem(objectId, message, type, userId));
}
//TODO Method to change name and/or alias of view/masterpage template
@@ -11,6 +11,13 @@ namespace Umbraco.Core.Services
/// </summary>
public interface IContentTypeService : IService
{
/// <summary>
/// Given the path of a content item, this will return true if the content item exists underneath a list view content item
/// </summary>
/// <param name="contentPath"></param>
/// <returns></returns>
bool HasContainerInPath(string contentPath);
int CountContentTypes();
int CountMediaTypes();
@@ -1,14 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Auditing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Events;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Services
@@ -18,12 +15,9 @@ namespace Umbraco.Core.Services
/// </summary>
public class LocalizationService : ScopeRepositoryService, ILocalizationService
{
public LocalizationService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory)
: base(provider, repositoryFactory, logger, eventMessagesFactory)
{
}
{ }
/// <summary>
/// Adds or updates a translation for a dictionary item and language
@@ -110,7 +104,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IDictionaryItem"/></returns>
public IDictionaryItem GetDictionaryItemById(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateDictionaryRepository(uow);
//ensure the lazy Language callback is assigned
@@ -128,7 +122,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="DictionaryItem"/></returns>
public IDictionaryItem GetDictionaryItemById(Guid id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateDictionaryRepository(uow);
//ensure the lazy Language callback is assigned
@@ -146,7 +140,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IDictionaryItem"/></returns>
public IDictionaryItem GetDictionaryItemByKey(string key)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateDictionaryRepository(uow);
//ensure the lazy Language callback is assigned
@@ -164,7 +158,7 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of <see cref="IDictionaryItem"/> objects</returns>
public IEnumerable<IDictionaryItem> GetDictionaryItemChildren(Guid parentId)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateDictionaryRepository(uow);
var query = Query<IDictionaryItem>.Builder.Where(x => x.ParentId == parentId);
@@ -183,7 +177,7 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of <see cref="IDictionaryItem"/> objects</returns>
public IEnumerable<IDictionaryItem> GetDictionaryItemDescendants(Guid? parentId)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateDictionaryRepository(uow);
//ensure the lazy Language callback is assigned
@@ -200,7 +194,7 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of <see cref="IDictionaryItem"/> objects</returns>
public IEnumerable<IDictionaryItem> GetRootDictionaryItems()
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateDictionaryRepository(uow);
var query = Query<IDictionaryItem>.Builder.Where(x => x.ParentId == null);
@@ -219,7 +213,7 @@ namespace Umbraco.Core.Services
/// <returns>True if a <see cref="IDictionaryItem"/> exists, otherwise false</returns>
public bool DictionaryItemExists(string key)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateDictionaryRepository(uow);
return repository.Get(key) != null;
@@ -242,14 +236,14 @@ namespace Umbraco.Core.Services
}
var repository = RepositoryFactory.CreateDictionaryRepository(uow);
repository.AddOrUpdate(dictionaryItem);
uow.Commit();
//ensure the lazy Language callback is assigned
EnsureDictionaryItemLanguageCallback(dictionaryItem);
uow.Commit(); // FIXME do we need this? what's the func above doing?
uow.Events.Dispatch(SavedDictionaryItem, this, new SaveEventArgs<IDictionaryItem>(dictionaryItem, false));
}
Audit(AuditType.Save, "Save DictionaryItem performed by user", userId, dictionaryItem.Id);
// ensure the lazy Language callback is assigned (not using the uow)
EnsureDictionaryItemLanguageCallback(dictionaryItem);
uow.Events.Dispatch(SavedDictionaryItem, this, new SaveEventArgs<IDictionaryItem>(dictionaryItem, false));
Audit(uow, AuditType.Save, "Save DictionaryItem performed by user", userId, dictionaryItem.Id);
uow.Commit();
}
}
/// <summary>
@@ -270,11 +264,12 @@ namespace Umbraco.Core.Services
var repository = RepositoryFactory.CreateDictionaryRepository(uow);
repository.Delete(dictionaryItem);
uow.Commit();
uow.Events.Dispatch(DeletedDictionaryItem, this, new DeleteEventArgs<IDictionaryItem>(dictionaryItem, false));
}
Audit(AuditType.Delete, "Delete DictionaryItem performed by user", userId, dictionaryItem.Id);
uow.Events.Dispatch(DeletedDictionaryItem, this, new DeleteEventArgs<IDictionaryItem>(dictionaryItem, false));
Audit(uow, AuditType.Delete, "Delete DictionaryItem performed by user", userId, dictionaryItem.Id);
uow.Commit();
}
}
/// <summary>
@@ -284,7 +279,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="Language"/></returns>
public ILanguage GetLanguageById(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateLanguageRepository(uow);
return repository.Get(id);
@@ -298,7 +293,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="Language"/></returns>
public ILanguage GetLanguageByCultureCode(string cultureName)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateLanguageRepository(uow);
return repository.GetByCultureName(cultureName);
@@ -312,7 +307,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="Language"/></returns>
public ILanguage GetLanguageByIsoCode(string isoCode)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateLanguageRepository(uow);
return repository.GetByIsoCode(isoCode);
@@ -325,7 +320,7 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of <see cref="ILanguage"/> objects</returns>
public IEnumerable<ILanguage> GetAllLanguages()
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateLanguageRepository(uow);
return repository.GetAll();
@@ -348,11 +343,12 @@ namespace Umbraco.Core.Services
}
var repository = RepositoryFactory.CreateLanguageRepository(uow);
repository.AddOrUpdate(language);
uow.Commit();
uow.Events.Dispatch(SavedLanguage, this, new SaveEventArgs<ILanguage>(language, false));
}
Audit(AuditType.Save, "Save Language performed by user", userId, language.Id);
uow.Events.Dispatch(SavedLanguage, this, new SaveEventArgs<ILanguage>(language, false));
Audit(uow, AuditType.Save, "Save Language performed by user", userId, language.Id);
uow.Commit();
}
}
/// <summary>
@@ -372,27 +368,24 @@ namespace Umbraco.Core.Services
var repository = RepositoryFactory.CreateLanguageRepository(uow);
repository.Delete(language);
uow.Commit();
uow.Events.Dispatch(DeletedLanguage, this, new DeleteEventArgs<ILanguage>(language, false));
}
Audit(AuditType.Delete, "Delete Language performed by user", userId, language.Id);
uow.Events.Dispatch(DeletedLanguage, this, new DeleteEventArgs<ILanguage>(language, false));
Audit(uow, AuditType.Delete, "Delete Language performed by user", userId, language.Id);
uow.Commit();
}
}
private void Audit(AuditType type, string message, int userId, int objectId)
private void Audit(IScopeUnitOfWork uow, AuditType type, string message, int userId, int objectId)
{
using (var uow = UowProvider.GetUnitOfWork())
{
var repository = RepositoryFactory.CreateAuditRepository(uow);
repository.AddOrUpdate(new AuditItem(objectId, message, type, userId));
uow.Commit();
}
var repository = RepositoryFactory.CreateAuditRepository(uow);
repository.AddOrUpdate(new AuditItem(objectId, message, type, userId));
}
/// <summary>
/// This is here to take care of a hack - the DictionaryTranslation model contains an ILanguage reference which we don't want but
/// This is here to take care of a hack - the DictionaryTranslation model contains an ILanguage reference which we don't want but
/// we cannot remove it because it would be a large breaking change, so we need to make sure it's resolved lazily. This is because
/// if developers have a lot of dictionary items and translations, the caching and cloning size gets much much larger because of
/// if developers have a lot of dictionary items and translations, the caching and cloning size gets much much larger because of
/// the large object graphs. So now we don't cache or clone the attached ILanguage
/// </summary>
private void EnsureDictionaryItemLanguageCallback(IDictionaryItem d)
+14 -18
View File
@@ -57,7 +57,7 @@ namespace Umbraco.Core.Services
/// <returns>An <see cref="IMacro"/> object</returns>
public IMacro GetByAlias(string alias)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMacroRepository(uow);
var q = new Query<IMacro>();
@@ -91,7 +91,7 @@ namespace Umbraco.Core.Services
public IEnumerable<IMacro> GetAll(params int[] ids)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMacroRepository(uow);
return repository.GetAll(ids);
@@ -100,7 +100,7 @@ namespace Umbraco.Core.Services
public IEnumerable<IMacro> GetAll(params Guid[] ids)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMacroRepository(uow);
return repository.GetAll(ids);
@@ -109,7 +109,7 @@ namespace Umbraco.Core.Services
public IMacro GetById(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMacroRepository(uow);
return repository.Get(id);
@@ -118,7 +118,7 @@ namespace Umbraco.Core.Services
public IMacro GetById(Guid id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMacroRepository(uow);
return repository.Get(id);
@@ -151,12 +151,12 @@ namespace Umbraco.Core.Services
}
var repository = RepositoryFactory.CreateMacroRepository(uow);
repository.Delete(macro);
uow.Commit();
uow.Events.Dispatch(Deleted, this, new DeleteEventArgs<IMacro>(macro, false));
}
Audit(AuditType.Delete, "Delete Macro performed by user", userId, -1);
Audit(uow, AuditType.Delete, "Delete Macro performed by user", userId, -1);
uow.Commit();
}
}
/// <summary>
@@ -181,12 +181,12 @@ namespace Umbraco.Core.Services
var repository = RepositoryFactory.CreateMacroRepository(uow);
repository.AddOrUpdate(macro);
uow.Commit();
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IMacro>(macro, false));
}
Audit(AuditType.Save, "Save Macro performed by user", userId, -1);
Audit(uow, AuditType.Save, "Save Macro performed by user", userId, -1);
uow.Commit();
}
}
///// <summary>
@@ -208,14 +208,10 @@ namespace Umbraco.Core.Services
// return MacroPropertyTypeResolver.Current.MacroPropertyTypes.FirstOrDefault(x => x.Alias == alias);
//}
private void Audit(AuditType type, string message, int userId, int objectId)
private void Audit(IScopeUnitOfWork uow, AuditType type, string message, int userId, int objectId)
{
using (var uow = UowProvider.GetUnitOfWork())
{
var repository = RepositoryFactory.CreateAuditRepository(uow);
repository.AddOrUpdate(new AuditItem(objectId, message, type, userId));
uow.Commit();
}
var repository = RepositoryFactory.CreateAuditRepository(uow);
repository.AddOrUpdate(new AuditItem(objectId, message, type, userId));
}
#region Event Handlers
+140 -164
View File
@@ -11,7 +11,6 @@ using Umbraco.Core.Configuration;
using Umbraco.Core.Events;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Media;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence;
@@ -28,7 +27,7 @@ namespace Umbraco.Core.Services
public class MediaService : ScopeRepositoryService, IMediaService, IMediaServiceOperations
{
//Support recursive locks because some of the methods that require locking call other methods that require locking.
//Support recursive locks because some of the methods that require locking call other methods that require locking.
//for example, the Move method needs to be locked but this calls the Save method which also needs to be locked.
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
@@ -67,9 +66,7 @@ namespace Umbraco.Core.Services
var parent = GetById(media.ParentId);
media.Path = string.Concat(parent.IfNotNull(x => x.Path, media.ParentId.ToString()), ",", media.Id);
//we are using GetReadOnlyUnitOfWork because this actually doesn't write anything!
// fixme - IS IT EVEN DOING ANYTHING WITH REPO? NO! SO USE A SCOPE INSTEAD!
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork())
{
if (uow.Events.DispatchCancelable(Creating, this, new NewEventArgs<IMedia>(media, mediaTypeAlias, parentId)))
{
@@ -79,15 +76,12 @@ namespace Umbraco.Core.Services
}
media.CreatorId = userId;
uow.Events.Dispatch(Created, this, new NewEventArgs<IMedia>(media, false, mediaTypeAlias, parentId));
Audit(AuditType.New, string.Format("Media '{0}' was created", name), media.CreatorId, media.Id);
Audit(uow, AuditType.New, string.Format("Media '{0}' was created", name), media.CreatorId, media.Id);
uow.Commit();
return media;
}
}
/// <summary>
@@ -112,9 +106,7 @@ namespace Umbraco.Core.Services
var media = new Models.Media(name, parent, mediaType);
media.Path = string.Concat(parent.Path, ",", media.Id);
//we are using GetReadOnlyUnitOfWork because this actually doesn't write anything!
// fixme
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork())
{
if (uow.Events.DispatchCancelable(Creating, this, new NewEventArgs<IMedia>(media, mediaTypeAlias, parent)))
{
@@ -127,7 +119,8 @@ namespace Umbraco.Core.Services
uow.Events.Dispatch(Created, this, new NewEventArgs<IMedia>(media, false, mediaTypeAlias, parent));
Audit(AuditType.New, string.Format("Media '{0}' was created", name), media.CreatorId, media.Id);
Audit(uow, AuditType.New, string.Format("Media '{0}' was created", name), media.CreatorId, media.Id);
uow.Commit();
return media;
}
@@ -157,12 +150,14 @@ namespace Umbraco.Core.Services
// out that in these 'WithIdentity' methods, the Saving/Saved events were not fired, wtf. Anyways, they're added now.
if (uow.Events.DispatchCancelable(Creating, this, new NewEventArgs<IMedia>(media, mediaTypeAlias, parentId)))
{
uow.Commit();
media.WasCancelled = true;
return media;
}
if (uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IMedia>(media)))
{
uow.Commit();
media.WasCancelled = true;
return media;
}
@@ -170,21 +165,19 @@ namespace Umbraco.Core.Services
var repository = RepositoryFactory.CreateMediaRepository(uow);
media.CreatorId = userId;
repository.AddOrUpdate(media);
repository.AddOrUpdateContentXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, _userService, m));
// generate preview for blame history?
if (UmbracoConfig.For.UmbracoSettings().Content.GlobalPreviewStorageEnabled)
{
repository.AddOrUpdatePreviewXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, _userService, m));
}
uow.Commit();
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IMedia>(media, false));
uow.Events.Dispatch(Created, this, new NewEventArgs<IMedia>(media, false, mediaTypeAlias, parentId));
}
Audit(AuditType.New, string.Format("Media '{0}' was created with Id {1}", name, media.Id), media.CreatorId, media.Id);
Audit(uow, AuditType.New, string.Format("Media '{0}' was created with Id {1}", name, media.Id), media.CreatorId, media.Id);
uow.Commit();
}
return media;
}
@@ -215,17 +208,18 @@ namespace Umbraco.Core.Services
// out that in these 'WithIdentity' methods, the Saving/Saved events were not fired, wtf. Anyways, they're added now.
if (uow.Events.DispatchCancelable(Creating, this, new NewEventArgs<IMedia>(media, mediaTypeAlias, parent)))
{
uow.Commit();
media.WasCancelled = true;
return media;
}
if (uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IMedia>(media)))
{
uow.Commit();
media.WasCancelled = true;
return media;
}
var repository = RepositoryFactory.CreateMediaRepository(uow);
media.CreatorId = userId;
repository.AddOrUpdate(media);
@@ -236,13 +230,12 @@ namespace Umbraco.Core.Services
repository.AddOrUpdatePreviewXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, _userService, m));
}
uow.Commit();
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IMedia>(media, false));
uow.Events.Dispatch(Created, this, new NewEventArgs<IMedia>(media, false, mediaTypeAlias, parent));
}
Audit(AuditType.New, string.Format("Media '{0}' was created with Id {1}", name, media.Id), media.CreatorId, media.Id);
Audit(uow, AuditType.New, string.Format("Media '{0}' was created with Id {1}", name, media.Id), media.CreatorId, media.Id);
uow.Commit();
}
return media;
}
@@ -254,7 +247,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IMedia"/></returns>
public IMedia GetById(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaRepository(uow);
return repository.Get(id);
@@ -286,7 +279,7 @@ namespace Umbraco.Core.Services
public int Count(string contentTypeAlias = null)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaRepository(uow);
return repository.Count(contentTypeAlias);
@@ -295,7 +288,7 @@ namespace Umbraco.Core.Services
public int CountChildren(int parentId, string contentTypeAlias = null)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaRepository(uow);
return repository.CountChildren(parentId, contentTypeAlias);
@@ -304,7 +297,7 @@ namespace Umbraco.Core.Services
public int CountDescendants(int parentId, string contentTypeAlias = null)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaRepository(uow);
return repository.CountDescendants(parentId, contentTypeAlias);
@@ -320,7 +313,7 @@ namespace Umbraco.Core.Services
{
if (ids.Any() == false) return Enumerable.Empty<IMedia>();
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaRepository(uow);
return repository.GetAll(ids.ToArray());
@@ -334,7 +327,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IMedia"/></returns>
public IMedia GetById(Guid key)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaRepository(uow);
var query = Query<IMedia>.Builder.Where(x => x.Key == key);
@@ -349,7 +342,7 @@ namespace Umbraco.Core.Services
/// <returns>An Enumerable list of <see cref="IMedia"/> objects</returns>
public IEnumerable<IMedia> GetByLevel(int level)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaRepository(uow);
var query = Query<IMedia>.Builder.Where(x => x.Level == level && x.Path.StartsWith("-21") == false);
@@ -364,7 +357,7 @@ namespace Umbraco.Core.Services
/// <returns>An <see cref="IMedia"/> item</returns>
public IMedia GetByVersion(Guid versionId)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaRepository(uow);
return repository.GetByVersion(versionId);
@@ -378,7 +371,7 @@ namespace Umbraco.Core.Services
/// <returns>An Enumerable list of <see cref="IMedia"/> objects</returns>
public IEnumerable<IMedia> GetVersions(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaRepository(uow);
return repository.GetAllVersions(id);
@@ -407,7 +400,7 @@ namespace Umbraco.Core.Services
if (ids.Any() == false)
return new List<IMedia>();
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaRepository(uow);
return repository.GetAll(ids);
@@ -421,7 +414,7 @@ namespace Umbraco.Core.Services
/// <returns>An Enumerable list of <see cref="IMedia"/> objects</returns>
public IEnumerable<IMedia> GetChildren(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaRepository(uow);
var query = Query<IMedia>.Builder.Where(x => x.ParentId == id);
@@ -494,7 +487,7 @@ namespace Umbraco.Core.Services
Mandate.ParameterCondition(pageIndex >= 0, "pageIndex");
Mandate.ParameterCondition(pageSize > 0, "pageSize");
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaRepository(uow);
@@ -558,7 +551,7 @@ namespace Umbraco.Core.Services
{
Mandate.ParameterCondition(pageIndex >= 0, "pageIndex");
Mandate.ParameterCondition(pageSize > 0, "pageSize");
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaRepository(uow);
var query = Query<IMedia>.Builder;
@@ -602,7 +595,7 @@ namespace Umbraco.Core.Services
if (media.ValidatePath() == false)
throw new InvalidDataException(string.Format("The content item {0} has an invalid path: {1} with parentID: {2}", media.Id, media.Path, media.ParentId));
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaRepository(uow);
var pathMatch = media.Path + ",";
@@ -642,7 +635,7 @@ namespace Umbraco.Core.Services
/// <returns>An Enumerable list of <see cref="IMedia"/> objects</returns>
public IEnumerable<IMedia> GetMediaOfMediaType(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaRepository(uow);
var query = Query<IMedia>.Builder.Where(x => x.ContentTypeId == id);
@@ -656,7 +649,7 @@ namespace Umbraco.Core.Services
/// <returns>An Enumerable list of <see cref="IMedia"/> objects</returns>
public IEnumerable<IMedia> GetRootMedia()
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaRepository(uow);
var query = Query<IMedia>.Builder.Where(x => x.ParentId == -1);
@@ -670,7 +663,7 @@ namespace Umbraco.Core.Services
/// <returns>An Enumerable list of <see cref="IMedia"/> objects</returns>
public IEnumerable<IMedia> GetMediaInRecycleBin()
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaRepository(uow);
var query = Query<IMedia>.Builder.Where(x => x.Path.Contains("-21"));
@@ -707,11 +700,11 @@ namespace Umbraco.Core.Services
var sql = createSql(umbracoFileValue);
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var propertyDataDto = uow.Database.Fetch<PropertyDataDto, PropertyTypeDto>(sql).FirstOrDefault();
// If the stripped-down url returns null, we try again with the original url.
// If the stripped-down url returns null, we try again with the original url.
// Previously, the function would fail on e.g. "my_x_image.jpg"
if (propertyDataDto == null)
{
@@ -754,7 +747,7 @@ namespace Umbraco.Core.Services
/// <returns>True if the media has any children otherwise False</returns>
public bool HasChildren(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaRepository(uow);
var query = Query<IMedia>.Builder.Where(x => x.ParentId == id);
@@ -784,14 +777,13 @@ namespace Umbraco.Core.Services
return;
}
using (var scope = UowProvider.ScopeProvider.CreateScope())
using (var uow = UowProvider.GetUnitOfWork())
{
scope.Complete(); // always complete
var originalPath = media.Path;
if (scope.Events.DispatchCancelable(Moving, this, new MoveEventArgs<IMedia>(new MoveEventInfo<IMedia>(media, originalPath, parentId)), "Moving"))
if (uow.Events.DispatchCancelable(Moving, this, new MoveEventArgs<IMedia>(new MoveEventInfo<IMedia>(media, originalPath, parentId)), "Moving"))
{
uow.Commit();
return;
}
@@ -800,15 +792,13 @@ namespace Umbraco.Core.Services
{
media.ChangeTrashedState(false, parentId);
}
Save(media, userId,
//no events!
false);
Save(media, userId, false); //no events!
//used to track all the moved entities to be given to the event
var moveInfo = new List<MoveEventInfo<IMedia>>
{
new MoveEventInfo<IMedia>(media, originalPath, parentId)
};
{
new MoveEventInfo<IMedia>(media, originalPath, parentId)
};
//Ensure that relevant properties are updated on children
var children = GetChildren(media.Id).ToArray();
@@ -818,14 +808,13 @@ namespace Umbraco.Core.Services
var parentLevel = media.Level;
var parentTrashed = media.Trashed;
var updatedDescendants = UpdatePropertiesOnChildren(children, parentPath, parentLevel, parentTrashed, moveInfo);
Save(updatedDescendants, userId,
//no events!
false);
Save(updatedDescendants, userId, false); //no events!
}
scope.Events.Dispatch(Moved, this, new MoveEventArgs<IMedia>(false, moveInfo.ToArray()), "Moved");
uow.Events.Dispatch(Moved, this, new MoveEventArgs<IMedia>(false, moveInfo.ToArray()), "Moved");
Audit(AuditType.Move, "Move Media performed by user", userId, media.Id);
Audit(uow, AuditType.Move, "Move Media performed by user", userId, media.Id);
uow.Commit();
}
}
}
@@ -854,31 +843,35 @@ namespace Umbraco.Core.Services
//TODO: IT would be much nicer to mass delete all in one trans in the repo level!
var evtMsgs = EventMessagesFactory.Get();
using (var scope = UowProvider.ScopeProvider.CreateScope())
using (var uow = UowProvider.GetUnitOfWork())
{
scope.Complete(); // always
if (scope.Events.DispatchCancelable(Deleting, this, new DeleteEventArgs<IMedia>(media, evtMsgs)))
return OperationStatus.Cancelled(evtMsgs);
var ret = DeleteUow(uow, media, userId, evtMsgs);
uow.Commit();
return ret;
}
}
private Attempt<OperationStatus> DeleteUow(IScopeUnitOfWork uow, IMedia media, int userId, EventMessages evtMsgs)
{
if (uow.Events.DispatchCancelable(Deleting, this, new DeleteEventArgs<IMedia>(media, evtMsgs)))
{
return OperationStatus.Cancelled(evtMsgs);
}
//Delete children before deleting the 'possible parent'
// delete children first
var children = GetChildren(media.Id);
foreach (var child in children)
{
Delete(child, userId);
DeleteUow(uow, child, userId, evtMsgs);
}
using (var uow = UowProvider.GetUnitOfWork())
{
var repository = RepositoryFactory.CreateMediaRepository(uow);
repository.Delete(media);
uow.Commit();
var repository = RepositoryFactory.CreateMediaRepository(uow);
repository.Delete(media);
var args = new DeleteEventArgs<IMedia>(media, false, evtMsgs);
uow.Events.Dispatch(Deleted, this, args);
}
var args = new DeleteEventArgs<IMedia>(media, false, evtMsgs);
uow.Events.Dispatch(Deleted, this, args);
Audit(AuditType.Delete, "Delete Media performed by user", userId, media.Id);
Audit(uow, AuditType.Delete, "Delete Media performed by user", userId, media.Id);
return OperationStatus.Success(evtMsgs);
}
@@ -895,10 +888,10 @@ namespace Umbraco.Core.Services
using (var uow = UowProvider.GetUnitOfWork())
{
if (raiseEvents)
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IMedia>(media, evtMsgs)))
{
if (uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IMedia>(media, evtMsgs)))
return OperationStatus.Cancelled(evtMsgs);
uow.Commit();
return OperationStatus.Cancelled(evtMsgs);
}
if (string.IsNullOrWhiteSpace(media.Name))
@@ -916,13 +909,12 @@ namespace Umbraco.Core.Services
repository.AddOrUpdatePreviewXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, _userService, m));
}
uow.Commit();
if (raiseEvents)
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IMedia>(media, false, evtMsgs));
}
Audit(AuditType.Save, "Save Media performed by user", userId, media.Id);
Audit(uow, AuditType.Save, "Save Media performed by user", userId, media.Id);
uow.Commit();
}
return OperationStatus.Success(evtMsgs);
}
@@ -940,10 +932,10 @@ namespace Umbraco.Core.Services
using (var uow = UowProvider.GetUnitOfWork())
{
if (raiseEvents)
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IMedia>(asArray, evtMsgs)))
{
if (uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IMedia>(asArray, evtMsgs)))
return OperationStatus.Cancelled(evtMsgs);
uow.Commit();
return OperationStatus.Cancelled(evtMsgs);
}
var repository = RepositoryFactory.CreateMediaRepository(uow);
@@ -959,14 +951,12 @@ namespace Umbraco.Core.Services
}
}
//commit the whole lot in one go
uow.Commit();
if (raiseEvents)
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IMedia>(asArray, false, evtMsgs));
}
Audit(AuditType.Save, "Save Media items performed by user", userId, -1);
Audit(uow, AuditType.Save, "Save Media items performed by user", userId, -1);
uow.Commit();
}
return OperationStatus.Success(evtMsgs);
}
@@ -978,18 +968,14 @@ namespace Umbraco.Core.Services
{
using (new WriteLock(Locker))
{
Dictionary<int, IEnumerable<Property>> entities;
List<string> files;
bool success;
var nodeObjectType = new Guid(Constants.ObjectTypes.Media);
using (var uow = UowProvider.GetUnitOfWork())
{
var repository = RepositoryFactory.CreateMediaRepository(uow);
entities = repository.GetEntitiesInRecycleBin().ToDictionary(key => key.Id, val => (IEnumerable<Property>)val.Properties);
var entities = repository.GetEntitiesInRecycleBin().ToDictionary(key => key.Id, val => (IEnumerable<Property>)val.Properties);
files = ((MediaRepository)repository).GetFilesInRecycleBinForUploadField();
uow.Commit();
var files = ((MediaRepository)repository).GetFilesInRecycleBinForUploadField();
if (uow.Events.DispatchCancelable(EmptyingRecycleBin, this, new RecycleBinEventArgs(nodeObjectType, entities, files)))
{
@@ -997,17 +983,19 @@ namespace Umbraco.Core.Services
return;
}
success = repository.EmptyRecycleBin();
// FIXME shouldn't we commit here?!
var success = repository.EmptyRecycleBin();
uow.Events.Dispatch(EmptiedRecycleBin, this, new RecycleBinEventArgs(nodeObjectType, entities, files, success));
Audit(uow, AuditType.Delete, "Empty Media Recycle Bin performed by user", 0, -21);
uow.Commit();
}
}
Audit(AuditType.Delete, "Empty Media Recycle Bin performed by user", 0, -21);
}
/// <summary>
/// Deletes all content of the specified types. All Descendants of deleted content that is not of these types is moved to Recycle Bin.
/// </summary>
/// </summary>
/// <param name="mediaTypeIds">Id of the <see cref="IContentType"/></param>
/// <param name="userId">Optional Id of the user issueing the delete operation</param>
public void DeleteMediaOfTypes(IEnumerable<int> mediaTypeIds, int userId = 0)
@@ -1032,12 +1020,8 @@ namespace Umbraco.Core.Services
//Determine the items that will need to be recycled (that are children of these content items but not of these content types)
var mediaToRecycle = this.TrackTrashedForDeleteContentOfTypes(mediaTypeIds, rootItems, repository);
// do it INSIDE the UOW because nested UOW kinda should work
// fixme - and then we probably don't need the whole mess?
// nesting UOW works, it's just that the outer one NEEDS to be flushed beforehand
// nevertheless, it would be nicer to create a global scope and inner uow
//move each item to the bin starting with the deepest items
// move each item to the bin starting with the deepest items
// nesting uow - technically supported though not ideal
foreach (var child in mediaToRecycle.OrderByDescending(x => x.Level))
{
MoveToRecycleBinDo(child, userId, true);
@@ -1048,12 +1032,10 @@ namespace Umbraco.Core.Services
Delete(content, userId);
}
uow.Commit();
Audit(AuditType.Delete,
Audit(uow, AuditType.Delete,
string.Format("Delete Media of Types {0} performed by user", string.Join(",", mediaTypeIds)),
userId, Constants.System.Root);
uow.Commit();
}
}
@@ -1105,13 +1087,13 @@ namespace Umbraco.Core.Services
{
uow.Commit();
return OperationStatus.Cancelled(evtMsgs);
}
}
var moveInfo = new List<MoveEventInfo<IMedia>>
{
new MoveEventInfo<IMedia>(media, originalPath, Constants.System.RecycleBinMedia)
};
//get descendents to process of the content item that is being moved to trash - must be done before changing the state below,
//get descendents to process of the content item that is being moved to trash - must be done before changing the state below,
//must be processed with shallowest levels first
var descendants = ignoreDescendants ? Enumerable.Empty<IMedia>() : GetDescendants(media).OrderBy(x => x.Level);
@@ -1120,7 +1102,7 @@ namespace Umbraco.Core.Services
repository.DeleteContentXml(media);
media.ChangeTrashedState(true, Constants.System.RecycleBinMedia);
repository.AddOrUpdate(media);
//Loop through descendants to update their trash state, but ensuring structure by keeping the ParentId
foreach (var descendant in descendants)
{
@@ -1131,12 +1113,11 @@ namespace Umbraco.Core.Services
moveInfo.Add(new MoveEventInfo<IMedia>(descendant, descendant.Path, descendant.ParentId));
}
uow.Commit();
uow.Events.Dispatch(Trashed, this, new MoveEventArgs<IMedia>(false, evtMsgs, moveInfo.ToArray()), "Trashed");
}
Audit(AuditType.Move, "Move Media to Recycle Bin performed by user", userId, media.Id);
Audit(uow, AuditType.Move, "Move Media to Recycle Bin performed by user", userId, media.Id);
uow.Commit();
}
return OperationStatus.Success(evtMsgs);
}
@@ -1166,19 +1147,22 @@ namespace Umbraco.Core.Services
/// <param name="userId">Optional Id of the User deleting versions of a Content object</param>
public void DeleteVersions(int id, DateTime versionDate, int userId = 0)
{
using (var uow = UowProvider.GetUnitOfWork())
{
if (uow.Events.DispatchCancelable(DeletingVersions, this, new DeleteRevisionsEventArgs(id, dateToRetain: versionDate)))
return;
var repository = RepositoryFactory.CreateMediaRepository(uow);
repository.DeleteVersions(id, versionDate);
DeleteVersions(uow, id, versionDate, userId);
uow.Commit();
uow.Events.Dispatch(DeletedVersions, this, new DeleteRevisionsEventArgs(id, false, dateToRetain: versionDate));
}
}
Audit(AuditType.Delete, "Delete Media by version date performed by user", userId, -1);
private void DeleteVersions(IScopeUnitOfWork uow, int id, DateTime versionDate, int userId = 0)
{
if (uow.Events.DispatchCancelable(DeletingVersions, this, new DeleteRevisionsEventArgs(id, dateToRetain: versionDate)))
return;
var repository = RepositoryFactory.CreateMediaRepository(uow);
repository.DeleteVersions(id, versionDate);
uow.Events.Dispatch(DeletedVersions, this, new DeleteRevisionsEventArgs(id, false, dateToRetain: versionDate));
Audit(uow, AuditType.Delete, "Delete Media by version date performed by user", userId, -1);
}
/// <summary>
@@ -1191,28 +1175,28 @@ namespace Umbraco.Core.Services
/// <param name="userId">Optional Id of the User deleting versions of a Content object</param>
public void DeleteVersion(int id, Guid versionId, bool deletePriorVersions, int userId = 0)
{
using (var scope = UowProvider.ScopeProvider.CreateScope())
{
scope.Complete(); // always
if (scope.Events.DispatchCancelable(DeletingVersions, this, new DeleteRevisionsEventArgs(id, specificVersion: versionId)))
return;
}
if (deletePriorVersions)
{
var content = GetByVersion(versionId);
DeleteVersions(id, content.UpdateDate, userId);
}
using (var uow = UowProvider.GetUnitOfWork())
{
if (uow.Events.DispatchCancelable(DeletingVersions, this, new DeleteRevisionsEventArgs(id, specificVersion: versionId)))
{
uow.Commit();
return;
}
if (deletePriorVersions)
{
var content = GetByVersion(versionId);
DeleteVersions(uow, id, content.UpdateDate, userId);
}
var repository = RepositoryFactory.CreateMediaRepository(uow);
repository.DeleteVersion(versionId);
uow.Commit();
uow.Events.Dispatch(DeletedVersions, this, new DeleteRevisionsEventArgs(id, false, specificVersion: versionId));
}
Audit(AuditType.Delete, "Delete Media by version performed by user", userId, -1);
uow.Events.Dispatch(DeletedVersions, this, new DeleteRevisionsEventArgs(id, false, specificVersion: versionId));
Audit(uow, AuditType.Delete, "Delete Media by version performed by user", userId, -1);
uow.Commit();
}
}
/// <summary>
@@ -1251,13 +1235,10 @@ namespace Umbraco.Core.Services
using (var uow = UowProvider.GetUnitOfWork())
{
if (raiseEvents)
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IMedia>(asArray)))
{
if (uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IMedia>(asArray)))
{
uow.Commit();
return false;
}
uow.Commit();
return false;
}
var repository = RepositoryFactory.CreateMediaRepository(uow);
@@ -1285,13 +1266,12 @@ namespace Umbraco.Core.Services
}
}
uow.Commit();
if (raiseEvents)
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IMedia>(asArray, false));
}
Audit(AuditType.Sort, "Sorting Media performed by user", userId, 0);
Audit(uow, AuditType.Sort, "Sorting Media performed by user", userId, 0);
uow.Commit();
}
return true;
}
@@ -1309,7 +1289,7 @@ namespace Umbraco.Core.Services
Mandate.ParameterCondition(pageIndex >= 0, "pageIndex");
Mandate.ParameterCondition(pageSize > 0, "pageSize");
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaRepository(uow);
return repository.GetPagedXmlEntriesByPath(path, pageIndex, pageSize, null, out totalRecords);
@@ -1329,10 +1309,10 @@ namespace Umbraco.Core.Services
{
var repository = RepositoryFactory.CreateMediaRepository(uow);
repository.RebuildXmlStructures(media => _entitySerializer.Serialize(this, _dataTypeService, _userService, media), contentTypeIds: contentTypeIds.Length == 0 ? null : contentTypeIds);
Audit(uow, AuditType.Publish, "MediaService.RebuildXmlStructures completed, the xml has been regenerated in the database", 0, -1);
uow.Commit();
}
Audit(AuditType.Publish, "MediaService.RebuildXmlStructures completed, the xml has been regenerated in the database", 0, -1);
}
/// <summary>
@@ -1381,7 +1361,7 @@ namespace Umbraco.Core.Services
{
Mandate.ParameterNotNullOrEmpty(mediaTypeAlias, "mediaTypeAlias");
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaTypeRepository(uow);
var query = Query<IMediaType>.Builder.Where(x => x.Alias == mediaTypeAlias);
@@ -1399,14 +1379,10 @@ namespace Umbraco.Core.Services
}
}
private void Audit(AuditType type, string message, int userId, int objectId)
private void Audit(IScopeUnitOfWork uow, AuditType type, string message, int userId, int objectId)
{
using (var uow = UowProvider.GetUnitOfWork())
{
var repository = RepositoryFactory.CreateAuditRepository(uow);
repository.AddOrUpdate(new AuditItem(objectId, message, type, userId));
uow.Commit();
}
var repository = RepositoryFactory.CreateAuditRepository(uow);
repository.AddOrUpdate(new AuditItem(objectId, message, type, userId));
}
/// <summary>
@@ -1468,7 +1444,7 @@ namespace Umbraco.Core.Services
/// <summary>
/// Occurs before Delete
/// </summary>
/// </summary>
public static event TypedEventHandler<IMediaService, DeleteRevisionsEventArgs> DeletingVersions;
/// <summary>
+13 -16
View File
@@ -1,11 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Events;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.UnitOfWork;
@@ -40,12 +37,12 @@ namespace Umbraco.Core.Services
scope.Complete(); // always complete
scope.Events.Dispatch(Saved, this, new SaveEventArgs<IMemberGroup>(e.SavedEntities, false));
}
}
}
#endregion
public IEnumerable<IMemberGroup> GetAll()
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberGroupRepository(uow);
return repository.GetAll();
@@ -54,7 +51,7 @@ namespace Umbraco.Core.Services
public IMemberGroup GetById(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberGroupRepository(uow);
return repository.Get(id);
@@ -63,7 +60,7 @@ namespace Umbraco.Core.Services
public IMemberGroup GetByName(string name)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberGroupRepository(uow);
return repository.GetByName(name);
@@ -74,13 +71,10 @@ namespace Umbraco.Core.Services
{
using (var uow = UowProvider.GetUnitOfWork())
{
if (raiseEvents)
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IMemberGroup>(memberGroup)))
{
if (uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IMemberGroup>(memberGroup)))
{
uow.Commit();
return;
}
uow.Commit();
return;
}
var repository = RepositoryFactory.CreateMemberGroupRepository(uow);
@@ -90,7 +84,7 @@ namespace Umbraco.Core.Services
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IMemberGroup>(memberGroup, false));
}
}
public void Delete(IMemberGroup memberGroup)
@@ -98,7 +92,10 @@ namespace Umbraco.Core.Services
using (var uow = UowProvider.GetUnitOfWork())
{
if (uow.Events.DispatchCancelable(Deleting, this, new DeleteEventArgs<IMemberGroup>(memberGroup)))
return; // FIXME COMMIT
{
uow.Commit();
return;
}
var repository = RepositoryFactory.CreateMemberGroupRepository(uow);
repository.Delete(memberGroup);
uow.Commit();
@@ -118,7 +115,7 @@ namespace Umbraco.Core.Services
/// <summary>
/// Occurs before Save of a member group
/// </summary>
/// </summary>
/// <remarks>
/// We need to proxy these events because the events need to take place at the repo level
/// </remarks>
+61 -67
View File
@@ -4,17 +4,14 @@ using System.ComponentModel;
using System.Threading;
using System.Web.Security;
using System.Xml.Linq;
using Umbraco.Core.Auditing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Events;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
using System.Linq;
using Umbraco.Core.Security;
@@ -50,7 +47,7 @@ namespace Umbraco.Core.Services
/// <returns>Alias of the default MemberType</returns>
public string GetDefaultMemberType()
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberTypeRepository(uow);
@@ -76,7 +73,7 @@ namespace Umbraco.Core.Services
/// <returns><c>True</c> if the Member exists otherwise <c>False</c></returns>
public bool Exists(string username)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberRepository(uow);
return repository.Exists(username);
@@ -123,7 +120,7 @@ namespace Umbraco.Core.Services
/// <returns><c>True</c> if the Member exists otherwise <c>False</c></returns>
public bool Exists(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberRepository(uow);
return repository.Exists(id);
@@ -137,7 +134,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IMember"/></returns>
public IMember GetById(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberRepository(uow);
return repository.Get(id);
@@ -153,7 +150,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IMember"/></returns>
public IMember GetByKey(Guid id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberRepository(uow);
var query = Query<IMember>.Builder.Where(x => x.Key == id);
@@ -168,7 +165,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IEnumerable{IMember}"/></returns>
public IEnumerable<IMember> GetMembersByMemberType(string memberTypeAlias)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberRepository(uow);
var query = Query<IMember>.Builder.Where(x => x.ContentTypeAlias == memberTypeAlias);
@@ -183,7 +180,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IEnumerable{IMember}"/></returns>
public IEnumerable<IMember> GetMembersByMemberType(int memberTypeId)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberRepository(uow);
repository.Get(memberTypeId);
@@ -199,7 +196,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IEnumerable{IMember}"/></returns>
public IEnumerable<IMember> GetMembersByGroup(string memberGroupName)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberRepository(uow);
return repository.GetByMemberGroup(memberGroupName);
@@ -214,7 +211,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IEnumerable{IMember}"/></returns>
public IEnumerable<IMember> GetAllMembers(params int[] ids)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberRepository(uow);
return repository.GetAll(ids);
@@ -229,8 +226,6 @@ namespace Umbraco.Core.Services
{
using (new WriteLock(Locker))
{
var memberList = new List<IMember>();
using (var uow = UowProvider.GetUnitOfWork())
{
var repository = RepositoryFactory.CreateMemberRepository(uow);
@@ -246,9 +241,8 @@ namespace Umbraco.Core.Services
}
foreach (var member in members)
{
//Permantly delete the member
// FIXME implies a nested UOW = bad so ?
Delete(member);
// permantly delete the member
Delete(uow, member);
}
uow.Commit();
@@ -277,7 +271,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IEnumerable{IMember}"/></returns>
public IEnumerable<IMember> FindMembersByDisplayName(string displayNameToMatch, long pageIndex, int pageSize, out long totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberRepository(uow);
var query = new Query<IMember>();
@@ -328,7 +322,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IEnumerable{IMember}"/></returns>
public IEnumerable<IMember> FindByEmail(string emailStringToMatch, long pageIndex, int pageSize, out long totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberRepository(uow);
var query = new Query<IMember>();
@@ -379,7 +373,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IEnumerable{IMember}"/></returns>
public IEnumerable<IMember> FindByUsername(string login, long pageIndex, int pageSize, out long totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberRepository(uow);
var query = new Query<IMember>();
@@ -418,7 +412,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IEnumerable{IMember}"/></returns>
public IEnumerable<IMember> GetMembersByPropertyValue(string propertyTypeAlias, string value, StringPropertyMatchType matchType = StringPropertyMatchType.Exact)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberRepository(uow);
@@ -467,7 +461,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IEnumerable{IMember}"/></returns>
public IEnumerable<IMember> GetMembersByPropertyValue(string propertyTypeAlias, int value, ValuePropertyMatchType matchType = ValuePropertyMatchType.Exact)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberRepository(uow);
@@ -506,7 +500,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IEnumerable{IMember}"/></returns>
public IEnumerable<IMember> GetMembersByPropertyValue(string propertyTypeAlias, bool value)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberRepository(uow);
@@ -524,7 +518,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IEnumerable{IMember}"/></returns>
public IEnumerable<IMember> GetMembersByPropertyValue(string propertyTypeAlias, DateTime value, ValuePropertyMatchType matchType = ValuePropertyMatchType.Exact)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberRepository(uow);
@@ -572,10 +566,10 @@ namespace Umbraco.Core.Services
var repository = RepositoryFactory.CreateMemberRepository(uow);
repository.RebuildXmlStructures(member => _entitySerializer.Serialize(_dataTypeService, member),
contentTypeIds: memberTypeIds.Length == 0 ? null : memberTypeIds);
Audit(uow, AuditType.Publish, "MemberService.RebuildXmlStructures completed, the xml has been regenerated in the database", 0, -1);
uow.Commit();
}
Audit(AuditType.Publish, "MemberService.RebuildXmlStructures completed, the xml has been regenerated in the database", 0, -1);
}
/// <summary>
@@ -590,11 +584,10 @@ namespace Umbraco.Core.Services
Mandate.ParameterCondition(pageIndex >= 0, "pageIndex");
Mandate.ParameterCondition(pageSize > 0, "pageSize");
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateMemberRepository(uow))
using (var uow = UowProvider.GetUnitOfWork(readOnly:true))
{
var contents = repository.GetPagedXmlEntriesByPath("-1", pageIndex, pageSize, null, out totalRecords);
return contents;
var repository = RepositoryFactory.CreateMemberRepository(uow);
return repository.GetPagedXmlEntriesByPath("-1", pageIndex, pageSize, null, out totalRecords);
}
}
@@ -614,7 +607,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="System.int"/> with number of Members for passed in type</returns>
public int GetCount(MemberCountType countType)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberRepository(uow);
@@ -666,7 +659,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IEnumerable{IMember}"/></returns>
public IEnumerable<IMember> GetAll(long pageIndex, int pageSize, out long totalRecords)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberRepository(uow);
return repository.GetPagedResultsByQuery(null, pageIndex, pageSize, out totalRecords, "LoginName", Direction.Ascending, true);
@@ -693,7 +686,7 @@ namespace Umbraco.Core.Services
public IEnumerable<IMember> GetAll(long pageIndex, int pageSize, out long totalRecords,
string orderBy, Direction orderDirection, bool orderBySystemField, string memberTypeAlias, string filter)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
IQuery<IMember> filterQuery = null;
if (filter.IsNullOrWhiteSpace() == false)
@@ -725,7 +718,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="System.int"/> with number of Members</returns>
public int Count(string memberTypeAlias = null)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberRepository(uow);
return repository.Count(memberTypeAlias);
@@ -906,7 +899,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IMember"/></returns>
public IMember GetByEmail(string email)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberRepository(uow);
var query = Query<IMember>.Builder.Where(x => x.Email.Equals(email));
@@ -925,7 +918,7 @@ namespace Umbraco.Core.Services
// a caching mechanism since this method is used by all the membership providers and could be
// called quite a bit when dealing with members.
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberRepository(uow);
var query = Query<IMember>.Builder.Where(x => x.Username.Equals(username));
@@ -941,21 +934,27 @@ namespace Umbraco.Core.Services
{
using (var uow = UowProvider.GetUnitOfWork())
{
if (uow.Events.DispatchCancelable(Deleting, this, new DeleteEventArgs<IMember>(member)))
{
uow.Commit();
return;
}
var repository = RepositoryFactory.CreateMemberRepository(uow);
repository.Delete(member);
Delete(uow, member);
uow.Commit();
var args = new DeleteEventArgs<IMember>(member, false);
uow.Events.Dispatch(Deleted, this, args);
}
}
private void Delete(IScopeUnitOfWork uow, IMember member)
{
if (uow.Events.DispatchCancelable(Deleting, this, new DeleteEventArgs<IMember>(member)))
{
uow.Commit();
return;
}
var repository = RepositoryFactory.CreateMemberRepository(uow);
repository.Delete(member);
uow.Commit();
var args = new DeleteEventArgs<IMember>(member, false);
uow.Events.Dispatch(Deleted, this, args);
}
/// <summary>
/// Saves an <see cref="IMember"/>
/// </summary>
@@ -1011,14 +1010,12 @@ namespace Umbraco.Core.Services
{
using (var uow = UowProvider.GetUnitOfWork())
{
if (raiseEvents)
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IMember>(asArray)))
{
if (uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<IMember>(asArray)))
{
uow.Commit();
return;
}
uow.Commit();
return;
}
var repository = RepositoryFactory.CreateMemberRepository(uow);
foreach (var member in asArray)
{
@@ -1058,7 +1055,7 @@ namespace Umbraco.Core.Services
public IEnumerable<string> GetAllRoles()
{
using (var uow = UowProvider.GetUnitOfWork())
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberGroupRepository(uow);
var result = repository.GetAll();
@@ -1068,7 +1065,7 @@ namespace Umbraco.Core.Services
public IEnumerable<string> GetAllRoles(int memberId)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberGroupRepository(uow);
var result = repository.GetMemberGroupsForMember(memberId);
@@ -1078,7 +1075,7 @@ namespace Umbraco.Core.Services
public IEnumerable<string> GetAllRoles(string username)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberGroupRepository(uow);
var result = repository.GetMemberGroupsForMember(username);
@@ -1088,7 +1085,7 @@ namespace Umbraco.Core.Services
public IEnumerable<IMember> GetMembersInRole(string roleName)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberRepository(uow);
return repository.GetByMemberGroup(roleName);
@@ -1097,7 +1094,7 @@ namespace Umbraco.Core.Services
public IEnumerable<IMember> FindMembersInRole(string roleName, string usernameToMatch, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberRepository(uow);
return repository.FindMembersInRole(roleName, usernameToMatch, matchType);
@@ -1119,7 +1116,7 @@ namespace Umbraco.Core.Services
List<IMemberGroup> found;
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberGroupRepository(uow);
var qry = new Query<IMemberGroup>().Where(g => g.Name == roleName);
@@ -1199,7 +1196,7 @@ namespace Umbraco.Core.Services
private IMemberType FindMemberTypeByAlias(string memberTypeAlias)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork())
{
var repository = RepositoryFactory.CreateMemberTypeRepository(uow);
var query = Query<IMemberType>.Builder.Where(x => x.Alias == memberTypeAlias);
@@ -1213,19 +1210,16 @@ namespace Umbraco.Core.Services
if (contentType == null)
throw new Exception(string.Format("MemberType matching the passed in Alias: '{0}' was null", memberTypeAlias));
uow.Commit();
return contentType;
}
}
private void Audit(AuditType type, string message, int userId, int objectId)
private void Audit(IScopeUnitOfWork uow, AuditType type, string message, int userId, int objectId)
{
using (var uow = UowProvider.GetUnitOfWork())
{
var repository = RepositoryFactory.CreateAuditRepository(uow);
repository.AddOrUpdate(new AuditItem(objectId, message, type, userId));
uow.Commit();
}
var repository = RepositoryFactory.CreateAuditRepository(uow);
repository.AddOrUpdate(new AuditItem(objectId, message, type, userId));
}
#region Event Handlers
+8 -14
View File
@@ -2,12 +2,10 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Umbraco.Core.Auditing;
using Umbraco.Core.Events;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Services
@@ -18,7 +16,6 @@ namespace Umbraco.Core.Services
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim();
public MemberTypeService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory, IMemberService memberService)
: base(provider, repositoryFactory, logger, eventMessagesFactory)
{
@@ -28,7 +25,7 @@ namespace Umbraco.Core.Services
public IEnumerable<IMemberType> GetAll(params int[] ids)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberTypeRepository(uow);
return repository.GetAll(ids);
@@ -42,7 +39,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IMemberType"/></returns>
public IMemberType Get(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberTypeRepository(uow);
return repository.Get(id);
@@ -56,7 +53,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IMemberType"/></returns>
public IMemberType Get(Guid key)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberTypeRepository(uow);
return repository.Get(key);
@@ -70,7 +67,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IMemberType"/></returns>
public IMemberType Get(string alias)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberTypeRepository(uow);
return repository.Get(alias);
@@ -97,10 +94,10 @@ namespace Umbraco.Core.Services
var repository = RepositoryFactory.CreateMemberTypeRepository(uow);
memberType.CreatorId = userId;
repository.AddOrUpdate(memberType);
uow.Commit(); // flush, so that the db contains the saved value
uow.Commit(); // fixme double?
UpdateContentXmlStructure(memberType);
uow.Commit();
uow.Commit(); // actually commit uow
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IMemberType>(memberType, false));
}
@@ -126,13 +123,10 @@ namespace Umbraco.Core.Services
memberType.CreatorId = userId;
repository.AddOrUpdate(memberType);
}
uow.Commit(); // fixme double?
uow.Commit(); // flush, so that the db contains the saved values
UpdateContentXmlStructure(asArray.Cast<IContentTypeBase>().ToArray());
//save it all in one go
uow.Commit();
uow.Commit(); // actually commit uow
uow.Events.Dispatch(Saved, this, new SaveEventArgs<IMemberType>(asArray, false));
}
@@ -24,7 +24,7 @@ namespace Umbraco.Core.Services
/// <returns></returns>
public IEnumerable<PublicAccessEntry> GetAll()
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repo = RepositoryFactory.CreatePublicAccessRepository(uow);
return repo.GetAll();
@@ -69,7 +69,7 @@ namespace Umbraco.Core.Services
//start with the deepest id
ids.Reverse();
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
//This will retrieve from cache!
var repo = RepositoryFactory.CreatePublicAccessRepository(uow);
@@ -220,7 +220,10 @@ namespace Umbraco.Core.Services
using (var uow = UowProvider.GetUnitOfWork())
{
if (uow.Events.DispatchCancelable(Saving, this, new SaveEventArgs<PublicAccessEntry>(entry, evtMsgs)))
{
uow.Commit();
return OperationStatus.Cancelled(evtMsgs);
}
var repo = RepositoryFactory.CreatePublicAccessRepository(uow);
repo.AddOrUpdate(entry);
@@ -243,7 +246,10 @@ namespace Umbraco.Core.Services
using (var uow = UowProvider.GetUnitOfWork())
{
if (uow.Events.DispatchCancelable(Deleting, this, new DeleteEventArgs<PublicAccessEntry>(entry, evtMsgs)))
{
uow.Commit();
return OperationStatus.Cancelled(evtMsgs);
}
var repo = RepositoryFactory.CreatePublicAccessRepository(uow);
repo.Delete(entry);
+19 -33
View File
@@ -29,7 +29,7 @@ namespace Umbraco.Core.Services
/// <returns>A <see cref="Relation"/> object</returns>
public IRelation GetById(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateRelationRepository(uow);
return repository.Get(id);
@@ -43,7 +43,7 @@ namespace Umbraco.Core.Services
/// <returns>A <see cref="RelationType"/> object</returns>
public IRelationType GetRelationTypeById(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateRelationTypeRepository(uow);
return repository.Get(id);
@@ -57,7 +57,7 @@ namespace Umbraco.Core.Services
/// <returns>A <see cref="RelationType"/> object</returns>
public IRelationType GetRelationTypeById(Guid id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateRelationTypeRepository(uow);
return repository.Get(id);
@@ -71,7 +71,7 @@ namespace Umbraco.Core.Services
/// <returns>A <see cref="RelationType"/> object</returns>
public IRelationType GetRelationTypeByAlias(string alias)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateRelationTypeRepository(uow);
var query = new Query<IRelationType>().Where(x => x.Alias == alias);
@@ -86,7 +86,7 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of <see cref="Relation"/> objects</returns>
public IEnumerable<IRelation> GetAllRelations(params int[] ids)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateRelationRepository(uow);
return repository.GetAll(ids);
@@ -110,7 +110,7 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of <see cref="Relation"/> objects</returns>
public IEnumerable<IRelation> GetAllRelationsByRelationType(int relationTypeId)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateRelationRepository(uow);
var query = new Query<IRelation>().Where(x => x.RelationTypeId == relationTypeId);
@@ -125,7 +125,7 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of <see cref="RelationType"/> objects</returns>
public IEnumerable<IRelationType> GetAllRelationTypes(params int[] ids)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateRelationTypeRepository(uow);
return repository.GetAll(ids);
@@ -139,7 +139,7 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of <see cref="Relation"/> objects</returns>
public IEnumerable<IRelation> GetByParentId(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateRelationRepository(uow);
var query = new Query<IRelation>().Where(x => x.ParentId == id);
@@ -175,7 +175,7 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of <see cref="Relation"/> objects</returns>
public IEnumerable<IRelation> GetByChildId(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateRelationRepository(uow);
var query = new Query<IRelation>().Where(x => x.ChildId == id);
@@ -212,7 +212,7 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of <see cref="Relation"/> objects</returns>
public IEnumerable<IRelation> GetByParentOrChildId(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateRelationRepository(uow);
var query = new Query<IRelation>().Where(x => x.ParentId == id || x.ChildId == id);
@@ -222,7 +222,7 @@ namespace Umbraco.Core.Services
public IEnumerable<IRelation> GetByParentOrChildId(int id, string relationTypeAlias)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var typeRepository = RepositoryFactory.CreateRelationTypeRepository(uow);
var rtQuery = new Query<IRelationType>().Where(x => x.Alias == relationTypeAlias);
@@ -243,7 +243,7 @@ namespace Umbraco.Core.Services
public IEnumerable<IRelation> GetByRelationTypeName(string relationTypeName)
{
List<int> relationTypeIds = null;
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateRelationTypeRepository(uow);
var query = new Query<IRelationType>().Where(x => x.Name == relationTypeName);
@@ -268,7 +268,7 @@ namespace Umbraco.Core.Services
public IEnumerable<IRelation> GetByRelationTypeAlias(string relationTypeAlias)
{
List<int> relationTypeIds = null;
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateRelationTypeRepository(uow);
var query = new Query<IRelationType>().Where(x => x.Alias == relationTypeAlias);
@@ -292,7 +292,7 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of <see cref="Relation"/> objects</returns>
public IEnumerable<IRelation> GetByRelationTypeId(int relationTypeId)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateRelationRepository(uow);
var query = new Query<IRelation>().Where(x => x.RelationTypeId == relationTypeId);
@@ -423,8 +423,6 @@ namespace Umbraco.Core.Services
uow.Events.Dispatch(SavedRelation, this, new SaveEventArgs<IRelation>(relation, false));
return relation;
}
}
/// <summary>
@@ -456,8 +454,6 @@ namespace Umbraco.Core.Services
uow.Events.Dispatch(SavedRelation, this, new SaveEventArgs<IRelation>(relation, false));
return relation;
}
}
/// <summary>
@@ -467,7 +463,7 @@ namespace Umbraco.Core.Services
/// <returns>Returns <c>True</c> if any relations exists for the given <see cref="RelationType"/>, otherwise <c>False</c></returns>
public bool HasRelations(IRelationType relationType)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateRelationRepository(uow);
var query = new Query<IRelation>().Where(x => x.RelationTypeId == relationType.Id);
@@ -482,7 +478,7 @@ namespace Umbraco.Core.Services
/// <returns>Returns <c>True</c> if any relations exists with the given Id, otherwise <c>False</c></returns>
public bool IsRelated(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateRelationRepository(uow);
var query = new Query<IRelation>().Where(x => x.ParentId == id || x.ChildId == id);
@@ -498,7 +494,7 @@ namespace Umbraco.Core.Services
/// <returns>Returns <c>True</c> if any relations exists with the given Ids, otherwise <c>False</c></returns>
public bool AreRelated(int parentId, int childId)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateRelationRepository(uow);
var query = new Query<IRelation>().Where(x => x.ParentId == parentId && x.ChildId == childId);
@@ -532,7 +528,7 @@ namespace Umbraco.Core.Services
/// <returns>Returns <c>True</c> if any relations exists with the given Ids and relation type, otherwise <c>False</c></returns>
public bool AreRelated(int parentId, int childId, IRelationType relationType)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateRelationRepository(uow);
var query = new Query<IRelation>().Where(x => x.ParentId == parentId && x.ChildId == childId && x.RelationTypeId == relationType.Id);
@@ -582,8 +578,6 @@ namespace Umbraco.Core.Services
uow.Commit();
uow.Events.Dispatch(SavedRelation, this, new SaveEventArgs<IRelation>(relation, false));
}
}
/// <summary>
@@ -604,8 +598,6 @@ namespace Umbraco.Core.Services
uow.Commit();
uow.Events.Dispatch(SavedRelationType, this, new SaveEventArgs<IRelationType>(relationType, false));
}
}
/// <summary>
@@ -625,9 +617,7 @@ namespace Umbraco.Core.Services
repository.Delete(relation);
uow.Commit();
uow.Events.Dispatch(DeletedRelation, this, new DeleteEventArgs<IRelation>(relation, false));
}
}
/// <summary>
@@ -647,9 +637,7 @@ namespace Umbraco.Core.Services
repository.Delete(relationType);
uow.Commit();
uow.Events.Dispatch(DeletedRelationType, this, new DeleteEventArgs<IRelationType>(relationType, false));
}
}
/// <summary>
@@ -671,16 +659,14 @@ namespace Umbraco.Core.Services
}
uow.Commit();
uow.Events.Dispatch(DeletedRelation, this, new DeleteEventArgs<IRelation>(relations, false));
}
}
#region Private Methods
private IEnumerable<IRelation> GetRelationsByListOfTypeIds(IEnumerable<int> relationTypeIds)
{
var relations = new List<IRelation>();
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateRelationRepository(uow);
foreach (var relationTypeId in relationTypeIds)
+2 -4
View File
@@ -2,13 +2,11 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Xml.Linq;
using Umbraco.Core.Cache;
using Umbraco.Core.Events;
using Umbraco.Core.IO;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.UnitOfWork;
using File = System.IO.File;
@@ -19,7 +17,7 @@ namespace Umbraco.Core.Services
private readonly IUserService _userService;
private IEnumerable<Section> _allAvailableSections;
private readonly IApplicationTreeService _applicationTreeService;
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
private readonly IScopeUnitOfWorkProvider _uowProvider;
private readonly CacheHelper _cache;
internal const string AppConfigFileName = "applications.config";
private static string _appConfig;
@@ -29,7 +27,7 @@ namespace Umbraco.Core.Services
public SectionService(
IUserService userService,
IApplicationTreeService applicationTreeService,
IDatabaseUnitOfWorkProvider uowProvider,
IScopeUnitOfWorkProvider uowProvider,
CacheHelper cache)
{
if (applicationTreeService == null) throw new ArgumentNullException("applicationTreeService");
+16 -41
View File
@@ -1,12 +1,10 @@
using System;
using System.ComponentModel;
using Umbraco.Core.Logging;
using System.IO;
using System.Linq;
using Umbraco.Core.IO;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.UnitOfWork;
using Umbraco.Core.Publishing;
using Umbraco.Core.Events;
namespace Umbraco.Core.Services
@@ -15,7 +13,7 @@ namespace Umbraco.Core.Services
/// These are used currently to return the temporary 'operation' interfaces for services
/// which are used to return a status from operational methods so we can determine if things are
/// cancelled, etc...
///
///
/// These will be obsoleted in v8 since all real services methods will be changed to have the correct result.
/// </summary>
public static class ServiceWithResultExtensions
@@ -37,11 +35,11 @@ namespace Umbraco.Core.Services
/// </summary>
public class ServiceContext
{
private Lazy<IMigrationEntryService> _migrationEntryService;
private Lazy<IPublicAccessService> _publicAccessService;
private Lazy<ITaskService> _taskService;
private Lazy<IDomainService> _domainService;
private Lazy<IAuditService> _auditService;
private Lazy<IMigrationEntryService> _migrationEntryService;
private Lazy<IPublicAccessService> _publicAccessService;
private Lazy<ITaskService> _taskService;
private Lazy<IDomainService> _domainService;
private Lazy<IAuditService> _auditService;
private Lazy<ILocalizedTextService> _localizedTextService;
private Lazy<ITagService> _tagService;
private Lazy<IContentService> _contentService;
@@ -150,49 +148,30 @@ namespace Umbraco.Core.Services
if (redirectUrlService != null) _redirectUrlService = new Lazy<IRedirectUrlService>(() => redirectUrlService);
}
// fixme - but this is obsoleting a new method?!!?!!?
[Obsolete("The IPublishingStrategy parameter is no longer required and not used")]
[EditorBrowsable(EditorBrowsableState.Never)]
public ServiceContext(
RepositoryFactory repositoryFactory,
IScopeUnitOfWorkProvider dbUnitOfWorkProvider,
IScopeUnitOfWorkProvider fileUnitOfWorkProvider,
IPublishingStrategy publishingStrategy,
CacheHelper cache,
ILogger logger,
IEventMessagesFactory eventMessagesFactory)
: this(repositoryFactory, dbUnitOfWorkProvider, fileUnitOfWorkProvider, cache, logger, eventMessagesFactory)
{ }
// fixme CLEAN THIS
/// <summary>
/// Creates a service context with a RepositoryFactory which is used to construct Services
/// </summary>
/// <param name="repositoryFactory"></param>
/// <param name="dbUnitOfWorkProvider"></param>
/// <param name="fileUnitOfWorkProvider"></param>
/// <param name="provider"></param>
/// <param name="cache"></param>
/// <param name="logger"></param>
/// <param name="eventMessagesFactory"></param>
public ServiceContext(
RepositoryFactory repositoryFactory,
IScopeUnitOfWorkProvider dbUnitOfWorkProvider,
IScopeUnitOfWorkProvider fileUnitOfWorkProvider,
CacheHelper cache,
IScopeUnitOfWorkProvider provider,
CacheHelper cache,
ILogger logger,
IEventMessagesFactory eventMessagesFactory)
{
if (repositoryFactory == null) throw new ArgumentNullException("repositoryFactory");
if (dbUnitOfWorkProvider == null) throw new ArgumentNullException("dbUnitOfWorkProvider");
if (fileUnitOfWorkProvider == null) throw new ArgumentNullException("fileUnitOfWorkProvider");
if (provider == null) throw new ArgumentNullException("provider");
if (cache == null) throw new ArgumentNullException("cache");
if (logger == null) throw new ArgumentNullException("logger");
if (eventMessagesFactory == null) throw new ArgumentNullException("eventMessagesFactory");
EventMessagesFactory = eventMessagesFactory;
BuildServiceCache(dbUnitOfWorkProvider, fileUnitOfWorkProvider, cache,
BuildServiceCache(provider, cache,
repositoryFactory,
logger, eventMessagesFactory);
}
@@ -201,8 +180,7 @@ namespace Umbraco.Core.Services
/// Builds the various services
/// </summary>
private void BuildServiceCache(
IScopeUnitOfWorkProvider dbUnitOfWorkProvider,
IScopeUnitOfWorkProvider fileUnitOfWorkProvider,
IScopeUnitOfWorkProvider provider,
CacheHelper cache,
RepositoryFactory repositoryFactory,
ILogger logger,
@@ -210,9 +188,6 @@ namespace Umbraco.Core.Services
{
EventMessagesFactory = eventMessagesFactory;
var provider = dbUnitOfWorkProvider;
var fileProvider = fileUnitOfWorkProvider;
if (_migrationEntryService == null)
_migrationEntryService = new Lazy<IMigrationEntryService>(() => new MigrationEntryService(provider, repositoryFactory, logger, eventMessagesFactory));
@@ -233,7 +208,7 @@ namespace Umbraco.Core.Services
if (_localizedTextService == null)
{
_localizedTextService = new Lazy<ILocalizedTextService>(() => new LocalizedTextService(
new Lazy<LocalizedTextServiceFileSources>(() =>
{
@@ -266,7 +241,7 @@ namespace Umbraco.Core.Services
}),
logger));
}
if (_notificationService == null)
_notificationService = new Lazy<INotificationService>(() => new NotificationService(provider, _userService.Value, _contentService.Value, logger));
@@ -293,7 +268,7 @@ namespace Umbraco.Core.Services
_dataTypeService = new Lazy<IDataTypeService>(() => new DataTypeService(provider, repositoryFactory, logger, eventMessagesFactory));
if (_fileService == null)
_fileService = new Lazy<IFileService>(() => new FileService(fileProvider, provider, repositoryFactory, logger, eventMessagesFactory));
_fileService = new Lazy<IFileService>(() => new FileService(provider, repositoryFactory, logger, eventMessagesFactory));
if (_localizationService == null)
_localizationService = new Lazy<ILocalizationService>(() => new LocalizationService(provider, repositoryFactory, logger, eventMessagesFactory));
@@ -304,7 +279,7 @@ namespace Umbraco.Core.Services
_contentService.Value, _contentTypeService.Value, _mediaService.Value, _dataTypeService.Value, _memberService.Value, _memberTypeService.Value,
//TODO: Consider making this an isolated cache instead of using the global one
cache.RuntimeCache));
if (_packagingService == null)
_packagingService = new Lazy<IPackagingService>(() => new PackagingService(logger, _contentService.Value, _contentTypeService.Value, _mediaService.Value, _macroService.Value, _dataTypeService.Value, _fileService.Value, _localizationService.Value, _entityService.Value, _userService.Value, repositoryFactory, provider));
+39 -48
View File
@@ -1,8 +1,6 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.SqlClient;
using System.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Events;
@@ -38,12 +36,12 @@ namespace Umbraco.Core.Services
/// <summary>
/// Gets the default MemberType alias
/// </summary>
/// <remarks>By default we'll return the 'writer', but we need to check it exists. If it doesn't we'll
/// <remarks>By default we'll return the 'writer', but we need to check it exists. If it doesn't we'll
/// return the first type that is not an admin, otherwise if there's only one we will return that one.</remarks>
/// <returns>Alias of the default MemberType</returns>
public string GetDefaultMemberType()
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateUserTypeRepository(uow);
@@ -76,7 +74,7 @@ namespace Umbraco.Core.Services
/// <returns><c>True</c> if the User exists otherwise <c>False</c></returns>
public bool Exists(string username)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateUserRepository(uow);
return repository.Exists(username);
@@ -118,7 +116,7 @@ namespace Umbraco.Core.Services
/// <summary>
/// Creates and persists a Member
/// </summary>
/// <remarks>Using this method will persist the Member object before its returned
/// <remarks>Using this method will persist the Member object before its returned
/// meaning that it will have an Id available (unlike the CreateMember method)</remarks>
/// <param name="username">Username of the Member to create</param>
/// <param name="email">Email of the Member to create</param>
@@ -182,7 +180,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IUser"/></returns>
public IUser GetById(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateUserRepository(uow);
return repository.Get(id);
@@ -212,7 +210,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IUser"/></returns>
public IUser GetByEmail(string email)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateUserRepository(uow);
var query = Query<IUser>.Builder.Where(x => x.Email.Equals(email));
@@ -227,7 +225,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IUser"/></returns>
public IUser GetByUsername(string username)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateUserRepository(uow);
var query = Query<IUser>.Builder.Where(x => x.Username.Equals(username));
@@ -305,9 +303,7 @@ namespace Umbraco.Core.Services
repository.Delete(user);
uow.Commit();
uow.Events.Dispatch(DeletedUser, this, new DeleteEventArgs<IUser>(user, false));
}
}
}
@@ -315,20 +311,16 @@ namespace Umbraco.Core.Services
/// Saves an <see cref="IUser"/>
/// </summary>
/// <param name="entity"><see cref="IUser"/> to Save</param>
/// <param name="raiseEvents">Optional parameter to raise events.
/// <param name="raiseEvents">Optional parameter to raise events.
/// Default is <c>True</c> otherwise set to <c>False</c> to not raise events</param>
public void Save(IUser entity, bool raiseEvents = true)
{
using (var uow = UowProvider.GetUnitOfWork())
{
if (raiseEvents)
if (raiseEvents && uow.Events.DispatchCancelable(SavingUser, this, new SaveEventArgs<IUser>(entity)))
{
if (uow.Events.DispatchCancelable(SavingUser, this, new SaveEventArgs<IUser>(entity)))
{
uow.Commit();
return;
}
uow.Commit();
return;
}
if (string.IsNullOrWhiteSpace(entity.Username))
@@ -345,29 +337,34 @@ namespace Umbraco.Core.Services
repository.AddOrUpdate(entity);
try
{
uow.Commit(); // fixme? would throw on dispose not here
// try to flush the unit of work
// ie executes the SQL but does not commit the trx yet
// so we are *not* catching commit exceptions
uow.Commit();
if (raiseEvents)
uow.Events.Dispatch(SavedUser, this, new SaveEventArgs<IUser>(entity, false));
}
catch (DbException ex)
{
//Special case, if we are upgrading and an exception occurs, just continue
// if we are upgrading and an exception occurs, log and swallow it
if (IsUpgrading == false) throw;
Logger.WarnWithException<UserService>("An error occurred attempting to save a user instance during upgrade, normally this warning can be ignored", ex);
return;
// we don't want the uow to rollback its scope! and yet
// we cannot try and uow.Commit() again as it would fail again,
// we have to bypass the uow entirely and complete its inner scope.
// (when the uow disposes, it won't complete the scope again, just dispose it)
uow.Scope.Complete();
}
}
}
/// <summary>
/// Saves a list of <see cref="IUser"/> objects
/// </summary>
/// <param name="entities"><see cref="IEnumerable{IUser}"/> to save</param>
/// <param name="raiseEvents">Optional parameter to raise events.
/// <param name="raiseEvents">Optional parameter to raise events.
/// Default is <c>True</c> otherwise set to <c>False</c> to not raise events</param>
public void Save(IEnumerable<IUser> entities, bool raiseEvents = true)
{
@@ -416,7 +413,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IEnumerable{IUser}"/></returns>
public IEnumerable<IUser> FindByEmail(string emailStringToMatch, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateUserRepository(uow);
var query = new Query<IUser>();
@@ -457,7 +454,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IEnumerable{IUser}"/></returns>
public IEnumerable<IUser> FindByUsername(string login, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateUserRepository(uow);
var query = new Query<IUser>();
@@ -499,7 +496,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="System.int"/> with number of Users for passed in type</returns>
public int GetCount(MemberCountType countType)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateUserRepository(uow);
@@ -545,7 +542,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IEnumerable{IMember}"/></returns>
public IEnumerable<IUser> GetAll(int pageIndex, int pageSize, out int totalRecords)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateUserRepository(uow);
return repository.GetPagedResultsByQuery(null, pageIndex, pageSize, out totalRecords, member => member.Username);
@@ -554,7 +551,7 @@ namespace Umbraco.Core.Services
internal IEnumerable<IUser> GetNextUsers(int id, int count)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = (UserRepository)RepositoryFactory.CreateUserRepository(uow);
return repository.GetNextUsers(id, count);
@@ -594,7 +591,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IUser"/></returns>
public IUser GetUserById(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateUserRepository(uow);
return repository.Get(id);
@@ -641,7 +638,7 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of <see cref="IUserType"/></returns>
public IEnumerable<IUserType> GetAllUserTypes(params int[] ids)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateUserTypeRepository(uow);
return repository.GetAll(ids);
@@ -655,7 +652,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IUserType"/></returns>
public IUserType GetUserTypeByAlias(string alias)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateUserTypeRepository(uow);
var query = Query<IUserType>.Builder.Where(x => x.Alias == alias);
@@ -670,7 +667,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IUserType"/></returns>
public IUserType GetUserTypeById(int id)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateUserTypeRepository(uow);
return repository.Get(id);
@@ -684,7 +681,7 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IUserType"/></returns>
public IUserType GetUserTypeByName(string name)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateUserTypeRepository(uow);
var query = Query<IUserType>.Builder.Where(x => x.Name == name);
@@ -696,28 +693,24 @@ namespace Umbraco.Core.Services
/// Saves a UserType
/// </summary>
/// <param name="userType">UserType to save</param>
/// <param name="raiseEvents">Optional parameter to raise events.
/// <param name="raiseEvents">Optional parameter to raise events.
/// Default is <c>True</c> otherwise set to <c>False</c> to not raise events</param>
public void SaveUserType(IUserType userType, bool raiseEvents = true)
{
using (var uow = UowProvider.GetUnitOfWork())
{
if (raiseEvents)
if (raiseEvents && uow.Events.DispatchCancelable(SavingUserType, this, new SaveEventArgs<IUserType>(userType)))
{
if (uow.Events.DispatchCancelable(SavingUserType, this, new SaveEventArgs<IUserType>(userType)))
{
uow.Commit();
return;
}
uow.Commit();
return;
}
var repository = RepositoryFactory.CreateUserTypeRepository(uow);
repository.AddOrUpdate(userType);
uow.Commit();
if (raiseEvents)
uow.Events.Dispatch(SavedUserType, this, new SaveEventArgs<IUserType>(userType, false));
}
}
/// <summary>
@@ -737,9 +730,7 @@ namespace Umbraco.Core.Services
repository.Delete(userType);
uow.Commit();
uow.Events.Dispatch(DeletedUserType, this, new DeleteEventArgs<IUserType>(userType, false));
}
}
/// <summary>
@@ -804,7 +795,7 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of <see cref="EntityPermission"/></returns>
public IEnumerable<EntityPermission> GetPermissions(IUser user, params int[] nodeIds)
{
using (var uow = UowProvider.GetUnitOfWork(commit: true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateUserRepository(uow);
var explicitPermissions = repository.GetUserPermissionsForEntities(user.Id, nodeIds);
+2 -3
View File
@@ -199,6 +199,7 @@
<Compile Include="Configuration\BaseRest\ExtensionElementCollection.cs" />
<Compile Include="Configuration\BaseRest\MethodElement.cs" />
<Compile Include="Configuration\ContentXmlStorage.cs" />
<Compile Include="Configuration\CoreDebug.cs" />
<Compile Include="Configuration\Dashboard\AccessElement.cs" />
<Compile Include="Configuration\Dashboard\AccessItem.cs" />
<Compile Include="Configuration\Dashboard\AccessType.cs" />
@@ -219,7 +220,6 @@
<Compile Include="Configuration\Dashboard\SectionElement.cs" />
<Compile Include="Configuration\Dashboard\TabCollection.cs" />
<Compile Include="Configuration\Dashboard\TabElement.cs" />
<Compile Include="Configuration\CoreDebug.cs" />
<Compile Include="Configuration\FileSystemProviderElement.cs" />
<Compile Include="Configuration\FileSystemProviderElementCollection.cs" />
<Compile Include="Configuration\FileSystemProvidersSection.cs" />
@@ -323,6 +323,7 @@
<Compile Include="DateTimeExtensions.cs" />
<Compile Include="DecimalExtensions.cs" />
<Compile Include="DelegateExtensions.cs" />
<Compile Include="Diagnostics\MiniDump.cs" />
<Compile Include="Deploy\ArtifactBase.cs" />
<Compile Include="Deploy\ArtifactDependency.cs" />
<Compile Include="Deploy\ArtifactDependencyCollection.cs" />
@@ -698,7 +699,6 @@
<Compile Include="Models\ContentPreviewEntity.cs" />
<Compile Include="Models\ContentTypeBase.cs" />
<Compile Include="Models\ContentTypeCompositionBase.cs" />
<Compile Include="Models\ContentTypeExtensions.cs" />
<Compile Include="Models\ContentTypeSort.cs" />
<Compile Include="Models\ContentXmlEntity.cs" />
<Compile Include="Models\DeepCloneHelper.cs" />
@@ -1196,7 +1196,6 @@
<Compile Include="Persistence\SqlSyntax\SqlSyntaxProviders.cs" />
<Compile Include="Persistence\TransactionType.cs" />
<Compile Include="Persistence\UmbracoDatabase.cs" />
<Compile Include="Persistence\UnitOfWork\FileUnitOfWork.cs" />
<Compile Include="Persistence\UnitOfWork\FileUnitOfWorkProvider.cs" />
<Compile Include="Persistence\UnitOfWork\IDatabaseUnitOfWork.cs" />
<Compile Include="Persistence\UnitOfWork\IDatabaseUnitOfWorkProvider.cs" />
@@ -1,4 +1,6 @@
using System;
using System.IO;
using System.Text;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
@@ -51,6 +53,30 @@ namespace Umbraco.Tests.IO
}
[Test]
public void Media_Fs_Safe_Delete()
{
var fs = FileSystemProviderManager.Current.GetFileSystemProvider<MediaFileSystem>();
var ms = new MemoryStream(Encoding.UTF8.GetBytes("test"));
var virtPath = fs.GetMediaPath("file.txt", Guid.NewGuid(), Guid.NewGuid());
fs.AddFile(virtPath, ms);
// ~/media/1234/file.txt exists
var physPath = IOHelper.MapPath(Path.Combine("media", virtPath));
Assert.IsTrue(File.Exists(physPath));
// ~/media/1234/file.txt is gone
fs.DeleteMediaFiles(new [] { virtPath });
Assert.IsFalse(File.Exists(physPath));
// ~/media/1234 is gone
physPath = Path.GetDirectoryName(physPath);
Assert.IsFalse(Directory.Exists(physPath));
// ~/media exists
physPath = Path.GetDirectoryName(physPath);
Assert.IsTrue(Directory.Exists(physPath));
}
public void Singleton_Typed_File_System()
{
var fs1 = FileSystemProviderManager.Current.GetFileSystemProvider<MediaFileSystem>();
@@ -805,101 +805,6 @@ namespace Umbraco.Tests.IO
Assert.AreEqual(3, sfsFiles.Length);
}
[Test]
[Ignore("Does not work on all environments, Directory.GetFiles is broken.")]
public void ShadowGetFilesUsingWildcardAndSingleCharacterFilter()
{
// Arrange
var path = IOHelper.MapPath("FileSysTests");
Directory.CreateDirectory(path);
Directory.CreateDirectory(path + "/ShadowTests");
Directory.CreateDirectory(path + "/ShadowSystem");
var fs = new PhysicalFileSystem(path + "/ShadowTests/", "ignore");
var sfs = new PhysicalFileSystem(path + "/ShadowSystem/", "ignore");
var ss = new ShadowFileSystem(fs, sfs);
// Act
File.WriteAllText(path + "/ShadowTests/f2.txt", "foo");
File.WriteAllText(path + "/ShadowTests/f2.doc", "foo");
File.WriteAllText(path + "/ShadowTests/f2.docx", "foo");
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo")))
ss.AddFile("f1.txt", ms);
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo")))
ss.AddFile("f1.doc", ms);
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo")))
ss.AddFile("f1.docx", ms);
// Assert
// ensure we get 6 files from the shadow
var getFiles = ss.GetFiles(string.Empty);
Assert.AreEqual(6, getFiles.Count());
var getFilesWithWildcardSinglecharFilter = ss.GetFiles(string.Empty, "*.d?c");
Assert.AreEqual(4, getFilesWithWildcardSinglecharFilter.Count());
var getFilesWithWildcardSinglecharFilter2 = ss.GetFiles(string.Empty, "*.d?cx");
Assert.AreEqual(2, getFilesWithWildcardSinglecharFilter2.Count());
var fsFiles = fs.GetFiles(string.Empty).ToArray();
Assert.AreEqual(3, fsFiles.Length);
var sfsFiles = sfs.GetFiles(string.Empty).ToArray();
Assert.AreEqual(3, sfsFiles.Length);
}
[Test]
[Ignore("Does not work on all environments, Directory.GetFiles is broken.")]
public void ShadowFileSystemFilterIsAsBrokenAsRealFileSystemFilter()
{
// Arrange
var path = IOHelper.MapPath("FileSysTests");
Directory.CreateDirectory(path);
Directory.CreateDirectory(path + "/filter");
// create files on disk and create a "fake" list of files to verify filters against
File.WriteAllText(path + "/filter/f1.txt", "foo");
File.WriteAllText(path + "/filter/f1.doc", "foo");
File.WriteAllText(path + "/filter/f1.docx", "foo");
var files = new string[]
{
"f1.txt",
"f1.doc",
"f1.docx",
};
var filter1 = "";
var filter2 = "*";
var filter3 = "*.doc";
var filter4 = "*.d?c";
var filter5 = "f1.doc";
var filter6 = "f1.d?c";
var filter7 = "**.d?c";
var filter8 = "f*.doc";
// Act & Assert
var result1Disk = Directory.GetFiles(path + "/filter/", filter1).Select(Path.GetFileName).OrderBy(x => x).ToArray();
var result1Fake = files.Where(x => ShadowFileSystem.FilterByRegex(x, ShadowFileSystem.FilterToRegex(filter1))).OrderBy(x => x).ToArray();
Assert.AreEqual(result1Disk, result1Fake);
var result2Disk = Directory.GetFiles(path + "/filter/", filter2).Select(Path.GetFileName).OrderBy(x => x).ToArray();
var result2Fake = files.Where(x => ShadowFileSystem.FilterByRegex(x, ShadowFileSystem.FilterToRegex(filter2))).OrderBy(x => x).ToArray();
Assert.AreEqual(result2Disk, result2Fake);
var result3Disk = Directory.GetFiles(path + "/filter/", filter3).Select(Path.GetFileName).OrderBy(x => x).ToArray();
var result3Fake = files.Where(x => ShadowFileSystem.FilterByRegex(x, ShadowFileSystem.FilterToRegex(filter3))).OrderBy(x => x).ToArray();
Assert.AreEqual(result3Disk, result3Fake);
var result4Disk = Directory.GetFiles(path + "/filter/", filter4).Select(Path.GetFileName).OrderBy(x => x).ToArray();
var result4Fake = files.Where(x => ShadowFileSystem.FilterByRegex(x, ShadowFileSystem.FilterToRegex(filter4))).OrderBy(x => x).ToArray();
Assert.AreEqual(result4Disk, result4Fake);
var result5Disk = Directory.GetFiles(path + "/filter/", filter5).Select(Path.GetFileName).OrderBy(x => x).ToArray();
var result5Fake = files.Where(x => ShadowFileSystem.FilterByRegex(x, ShadowFileSystem.FilterToRegex(filter5))).OrderBy(x => x).ToArray();
Assert.AreEqual(result5Disk, result5Fake);
var result6Disk = Directory.GetFiles(path + "/filter/", filter6).Select(Path.GetFileName).OrderBy(x => x).ToArray();
var result6Fake = files.Where(x => ShadowFileSystem.FilterByRegex(x, ShadowFileSystem.FilterToRegex(filter6))).OrderBy(x => x).ToArray();
Assert.AreEqual(result6Disk, result6Fake);
var result7Disk = Directory.GetFiles(path + "/filter/", filter7).Select(Path.GetFileName).OrderBy(x => x).ToArray();
var result7Fake = files.Where(x => ShadowFileSystem.FilterByRegex(x, ShadowFileSystem.FilterToRegex(filter7))).OrderBy(x => x).ToArray();
Assert.AreEqual(result7Disk, result7Fake);
var result8Disk = Directory.GetFiles(path + "/filter/", filter8).Select(Path.GetFileName).OrderBy(x => x).ToArray();
var result8Fake = files.Where(x => ShadowFileSystem.FilterByRegex(x, ShadowFileSystem.FilterToRegex(filter8))).OrderBy(x => x).ToArray();
Assert.AreEqual(result8Disk, result8Fake);
}
/// <summary>
/// Returns the full paths of the files on the disk.
/// Note that this will be the *actual* path of the file, meaning a file existing on the initialized FS
@@ -4,8 +4,6 @@ using Umbraco.Core.Logging;
namespace Umbraco.Tests.Logging
{
// FIXME how come some C# 6 features are working here ?!
public class ConsoleLogger : ILogger
{
public void Error(Type callingType, string message, Exception exception)
@@ -63,7 +63,7 @@ namespace Umbraco.Tests.Persistence
//assign the db context
dbContext,
//assign the service context
new ServiceContext(repositoryFactory, new PetaPocoUnitOfWorkProvider(scopeProvider), new FileUnitOfWorkProvider(scopeProvider), cacheHelper, _logger, evtMsgs),
new ServiceContext(repositoryFactory, new PetaPocoUnitOfWorkProvider(scopeProvider), cacheHelper, _logger, evtMsgs),
cacheHelper,
new ProfilingLogger(_logger, Mock.Of<IProfiler>()))
{
@@ -46,23 +46,6 @@ namespace Umbraco.Tests.Persistence.Repositories
return new EntityContainerRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), SqlSyntax, Constants.ObjectTypes.DataTypeContainerGuid);
}
[TestCase("UmbracoPreVal87-21,3,48", 3, true)]
[TestCase("UmbracoPreVal87-21,33,48", 3, false)]
[TestCase("UmbracoPreVal87-21,33,48", 33, true)]
[TestCase("UmbracoPreVal87-21,3,48", 33, false)]
[TestCase("UmbracoPreVal87-21,3,48", 21, true)]
[TestCase("UmbracoPreVal87-21,3,48", 48, true)]
[TestCase("UmbracoPreVal87-22,33,48", 2, false)]
[TestCase("UmbracoPreVal87-22,33,48", 22, true)]
[TestCase("UmbracoPreVal87-22,33,44", 4, false)]
[TestCase("UmbracoPreVal87-22,33,44", 44, true)]
[TestCase("UmbracoPreVal87-22,333,44", 33, false)]
[TestCase("UmbracoPreVal87-22,333,44", 333, true)]
public void Pre_Value_Cache_Key_Tests(string cacheKey, int preValueId, bool outcome)
{
Assert.AreEqual(outcome, Regex.IsMatch(cacheKey, DataTypeDefinitionRepository.GetCacheKeyRegex(preValueId)));
}
[Test]
public void Can_Move()
{
@@ -537,7 +520,7 @@ namespace Umbraco.Tests.Persistence.Repositories
}
var cached = cache.IsolatedRuntimeCache.GetCache<IDataTypeDefinition>().Result
.GetCacheItemsByKeySearch<PreValueCollection>(CacheKeys.DataTypePreValuesCacheKey + dtd.Id + "-");
.GetCacheItemsByKeySearch<PreValueCollection>(CacheKeys.DataTypePreValuesCacheKey + "_" + dtd.Id);
Assert.IsNotNull(cached);
Assert.AreEqual(1, cached.Count());
@@ -581,7 +564,7 @@ namespace Umbraco.Tests.Persistence.Repositories
}
var cached = cache.IsolatedRuntimeCache.GetCache<IDataTypeDefinition>().Result
.GetCacheItemsByKeySearch<PreValueCollection>(CacheKeys.DataTypePreValuesCacheKey + dtd.Id + "-");
.GetCacheItemsByKeySearch<PreValueCollection>(CacheKeys.DataTypePreValuesCacheKey + "_" + dtd.Id);
Assert.IsNotNull(cached);
Assert.AreEqual(1, cached.Count());
@@ -237,6 +237,14 @@ namespace Umbraco.Tests.Persistence.Repositories
Assert.AreEqual("test-path-1.js", script.Path);
Assert.AreEqual("/scripts/test-path-1.js", script.VirtualPath);
//ensure you can prefix the same path as the root path name
script = new Script("scripts/path-2/test-path-2.js") { Content = "// script" };
repository.AddOrUpdate(script);
unitOfWork.Commit();
Assert.IsTrue(_fileSystem.FileExists("scripts/path-2/test-path-2.js"));
Assert.AreEqual("scripts\\path-2\\test-path-2.js", script.Path);
Assert.AreEqual("/scripts/scripts/path-2/test-path-2.js", script.VirtualPath);
script = new Script("path-2/test-path-2.js") { Content = "// script" };
repository.AddOrUpdate(script);
unitOfWork.Commit();
@@ -54,7 +54,7 @@ namespace Umbraco.Tests.Scoping
public void Teardown()
{
if (_cacheHandler != null)
_cacheHandler.Destroy();
_cacheHandler.Unbind();
_cacheHandler = null;
ServerRegistrarResolver.Reset();
@@ -90,7 +90,7 @@ namespace Umbraco.Tests.Scoping
Assert.AreEqual(user.Id, globalCached.Id);
Assert.AreEqual("name", globalCached.Name);
_cacheHandler = new CacheRefresherEventHandler();
_cacheHandler = new CacheRefresherEventHandler(true);
_cacheHandler.OnApplicationStarted(null, ApplicationContext);
Assert.IsNull(scopeProvider.AmbientScope);
@@ -171,7 +171,7 @@ namespace Umbraco.Tests.Scoping
Assert.AreEqual(lang.Id, globalCached.Id);
Assert.AreEqual("fr-FR", globalCached.IsoCode);
_cacheHandler = new CacheRefresherEventHandler();
_cacheHandler = new CacheRefresherEventHandler(true);
_cacheHandler.OnApplicationStarted(null, ApplicationContext);
Assert.IsNull(scopeProvider.AmbientScope);
@@ -263,7 +263,7 @@ namespace Umbraco.Tests.Scoping
Assert.AreEqual(item.Id, globalCached.Id);
Assert.AreEqual("item-key", globalCached.ItemKey);
_cacheHandler = new CacheRefresherEventHandler();
_cacheHandler = new CacheRefresherEventHandler(true);
_cacheHandler.OnApplicationStarted(null, ApplicationContext);
Assert.IsNull(scopeProvider.AmbientScope);
+62 -15
View File
@@ -1,11 +1,15 @@
using System;
using System.Collections;
using Moq;
using NUnit.Framework;
using umbraco;
using Umbraco.Core;
using Umbraco.Core.Events;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Publishing;
using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
using Umbraco.Core.Sync;
using Umbraco.Tests.Cache.DistributedCache;
using Umbraco.Tests.TestHelpers;
@@ -42,9 +46,14 @@ namespace Umbraco.Tests.Scoping
public void Teardown()
{
if (_cacheHandler != null)
_cacheHandler.Destroy();
_cacheHandler.Unbind();
_cacheHandler = null;
_onPublishedAssertAction = null;
content.HttpContextItemsGetter = null;
ContentService.Published -= OnPublishedAssert;
SafeXmlReaderWriter.Cloning = null;
ServerRegistrarResolver.Reset();
ServerMessengerResolver.Reset();
CacheRefreshersResolver.Reset();
@@ -63,7 +72,7 @@ namespace Umbraco.Tests.Scoping
var contentType = new ContentType(-1) { Alias = "contenttype", Name = "test"};
ApplicationContext.Services.ContentTypeService.Save(contentType);
_cacheHandler = new CacheRefresherEventHandler();
_cacheHandler = new CacheRefresherEventHandler(true);
_cacheHandler.OnApplicationStarted(null, ApplicationContext);
var xml = content.Instance.XmlContent;
@@ -84,12 +93,23 @@ namespace Umbraco.Tests.Scoping
Assert.IsNotNull(node);
}
private void OnPublishedAssert(IPublishingStrategy sender, PublishEventArgs<IContent> args)
{
if (_onPublishedAssertAction != null)
_onPublishedAssertAction();
}
private Action _onPublishedAssertAction;
[TestCase(true)]
[TestCase(false)]
public void TestScope(bool complete)
{
content.TestingUpdateSitemapProvider = false;
var httpContextItems = new Hashtable();
content.HttpContextItemsGetter = () => httpContextItems;
var settings = SettingsForTests.GenerateMockSettings();
var contentMock = Mock.Get(settings.Content);
contentMock.Setup(x => x.XmlCacheEnabled).Returns(false);
@@ -98,11 +118,12 @@ namespace Umbraco.Tests.Scoping
var contentType = new ContentType(-1) { Alias = "contenttype", Name = "test"};
ApplicationContext.Services.ContentTypeService.Save(contentType);
_cacheHandler = new CacheRefresherEventHandler();
_cacheHandler = new CacheRefresherEventHandler(true);
_cacheHandler.OnApplicationStarted(null, ApplicationContext);
var xml = content.Instance.XmlContent;
Assert.IsNotNull(xml);
Assert.AreSame(xml, httpContextItems[content.XmlContextContentItemKey]);
var beforeXml = xml;
var beforeOuterXml = beforeXml.OuterXml;
var item = new Content("name", -1, contentType);
@@ -110,6 +131,21 @@ namespace Umbraco.Tests.Scoping
Console.WriteLine("Xml Before:");
Console.WriteLine(xml.OuterXml);
var evented = 0;
_onPublishedAssertAction = () =>
{
evented++;
xml = content.Instance.XmlContent;
Assert.IsNotNull(xml);
Assert.AreNotSame(beforeXml, xml);
Console.WriteLine("Xml Event:");
Console.WriteLine(xml.OuterXml);
var node = xml.GetElementById(item.Id.ToString());
Assert.IsNotNull(node);
};
ContentService.Published += OnPublishedAssert;
using (var scope = ApplicationContext.Current.ScopeProvider.CreateScope())
{
ApplicationContext.Services.ContentService.SaveAndPublishWithStatus(item); // should create an xml clone
@@ -119,25 +155,38 @@ namespace Umbraco.Tests.Scoping
// this should never change
Assert.AreEqual(beforeOuterXml, beforeXml.OuterXml);
// this does not change, other thread don't see the changes
xml = content.Instance.XmlContentInternal;
Assert.IsNotNull(xml);
Assert.AreSame(beforeXml, xml);
Console.WriteLine("XmlInternal During:");
Console.WriteLine(xml.OuterXml);
Assert.AreEqual(beforeOuterXml, xml.OuterXml);
// this does not change during the scope (only in events)
// because it is the events that trigger the changes
xml = content.Instance.XmlContent;
Assert.IsNotNull(xml);
Console.WriteLine("Xml After:");
Console.WriteLine(xml.OuterXml);
Assert.AreEqual(beforeOuterXml, xml.OuterXml); // fixme - should it change?
Assert.AreSame(beforeXml, xml);
// note
// this means that, as long as ppl don't create scopes, they'll see their
// changes right after SaveAndPublishWithStatus, but if they create scopes,
// they will have to wail until the scope is completed, ie wait until the
// events trigger, to use eg GetUrl etc
if (complete)
scope.Complete();
}
// fixme - refactor when we have events dispatching,
// the xml clone should prob be only created when the scope completes
Assert.AreEqual(complete ? 2 : 0, evented);
// this should never change
Assert.AreEqual(beforeOuterXml, beforeXml.OuterXml);
xml = content.Instance.XmlContent;
Assert.IsNotNull(xml);
Console.WriteLine("AFTER");
Console.WriteLine("Xml After:");
Console.WriteLine(xml.OuterXml);
if (complete)
{
@@ -146,6 +195,7 @@ namespace Umbraco.Tests.Scoping
}
else
{
Assert.AreSame(beforeXml, xml);
Assert.AreEqual(beforeOuterXml, xml.OuterXml); // nothing has changed!
}
}
@@ -164,7 +214,7 @@ namespace Umbraco.Tests.Scoping
var contentType = new ContentType(-1) { Alias = "contenttype", Name = "test" };
ApplicationContext.Services.ContentTypeService.Save(contentType);
_cacheHandler = new CacheRefresherEventHandler();
_cacheHandler = new CacheRefresherEventHandler(true);
_cacheHandler.OnApplicationStarted(null, ApplicationContext);
var xml = content.Instance.XmlContent;
@@ -199,7 +249,7 @@ namespace Umbraco.Tests.Scoping
Assert.IsNotNull(xml);
Console.WriteLine("Xml InScope (before complete):");
Console.WriteLine(xml.OuterXml);
Assert.AreEqual(beforeOuterXml, xml.OuterXml); // fixme - should it change?
Assert.AreEqual(beforeOuterXml, xml.OuterXml);
if (complete)
scope.Complete();
@@ -208,7 +258,7 @@ namespace Umbraco.Tests.Scoping
Assert.IsNotNull(xml);
Console.WriteLine("Xml InScope (after complete):");
Console.WriteLine(xml.OuterXml);
Assert.AreEqual(beforeOuterXml, xml.OuterXml); // fixme - should it change?
Assert.AreEqual(beforeOuterXml, xml.OuterXml);
}
var scopeProvider = ApplicationContext.Current.ScopeProvider as IScopeProviderInternal;
@@ -220,9 +270,6 @@ namespace Umbraco.Tests.Scoping
// limited number of clones!
Assert.AreEqual(complete ? 1 : 0, clones);
// fixme - refactor when we have events dispatching,
// the xml clone should prob be only created when the scope completes
// this should never change
Assert.AreEqual(beforeOuterXml, beforeXml.OuterXml);
@@ -342,13 +342,13 @@ namespace Umbraco.Tests.Services
public void Get_Descendants()
{
// Arrange
var contentTypeService = ServiceContext.ContentTypeService;
var contentTypeService = (ContentTypeService) ServiceContext.ContentTypeService;
var hierarchy = CreateContentTypeHierarchy();
contentTypeService.Save(hierarchy, 0); //ensure they are saved!
var master = hierarchy.First();
//Act
var descendants = master.Descendants(contentTypeService);
var descendants = contentTypeService.GetDescendants(master);
//Assert
Assert.AreEqual(10, descendants.Count());
@@ -358,13 +358,13 @@ namespace Umbraco.Tests.Services
public void Get_Descendants_And_Self()
{
// Arrange
var contentTypeService = ServiceContext.ContentTypeService;
var contentTypeService = (ContentTypeService) ServiceContext.ContentTypeService;
var hierarchy = CreateContentTypeHierarchy();
contentTypeService.Save(hierarchy, 0); //ensure they are saved!
var master = hierarchy.First();
//Act
var descendants = master.DescendantsAndSelf(contentTypeService);
var descendants = new[] {master}.Concat(contentTypeService.GetDescendants(master));
//Assert
Assert.AreEqual(11, descendants.Count());
@@ -63,9 +63,8 @@ namespace Umbraco.Tests.TestHelpers
var path = TestHelper.CurrentAssemblyDirectory;
AppDomain.CurrentDomain.SetData("DataDirectory", path);
// fixme - in theory we should not need this
// it's done in base.Initialize() and no idea why we do things
// in this order here... not going to change it now though...
// we probably don't need this here, as it's done in base.Initialize() already,
// but these test classes are all weird, not going to change it now - v8
SafeCallContext.Clear();
_dbFactory = new DefaultDatabaseFactory(
@@ -105,7 +104,7 @@ namespace Umbraco.Tests.TestHelpers
//assign the db context
new DatabaseContext(scopeProvider, Logger, SqlSyntax, GetDbProviderName()),
//assign the service context
new ServiceContext(repositoryFactory, new PetaPocoUnitOfWorkProvider(scopeProvider), new FileUnitOfWorkProvider(scopeProvider), CacheHelper, Logger, evtMsgs),
new ServiceContext(repositoryFactory, new PetaPocoUnitOfWorkProvider(scopeProvider), CacheHelper, Logger, evtMsgs),
CacheHelper,
ProfilingLogger)
{
@@ -355,7 +354,7 @@ namespace Umbraco.Tests.TestHelpers
onFail(ex);
}
}
protected DatabaseContext DatabaseContext
{
get { return ApplicationContext.DatabaseContext; }
@@ -170,7 +170,7 @@ namespace Umbraco.Tests.TestHelpers
//assign the db context
new DatabaseContext(scopeProvider, Logger, sqlSyntax, Constants.DatabaseProviders.SqlCe),
//assign the service context
new ServiceContext(repoFactory, new PetaPocoUnitOfWorkProvider(scopeProvider), new FileUnitOfWorkProvider(scopeProvider), CacheHelper, Logger, evtMsgs),
new ServiceContext(repoFactory, new PetaPocoUnitOfWorkProvider(scopeProvider), CacheHelper, Logger, evtMsgs),
CacheHelper,
ProfilingLogger)
{
+3 -2
View File
@@ -58,8 +58,8 @@
<Reference Include="AutoMapper.Net4, Version=3.3.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.Net4.dll</HintPath>
</Reference>
<Reference Include="Examine, Version=0.1.81.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Examine.0.1.81\lib\net45\Examine.dll</HintPath>
<Reference Include="Examine, Version=0.1.82.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Examine.0.1.82\lib\net45\Examine.dll</HintPath>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
@@ -594,6 +594,7 @@
<Compile Include="Plugins\TypeFinderTests.cs" />
<Compile Include="Routing\UmbracoModuleTests.cs" />
<Compile Include="VersionExtensionTests.cs" />
<Compile Include="Web\TemplateUtilitiesTests.cs" />
<Compile Include="Web\WebExtensionMethodTests.cs" />
<Compile Include="XmlExtensionsTests.cs" />
<Compile Include="XmlHelperTests.cs" />
@@ -0,0 +1,69 @@
using System;
using System.Linq;
using System.Web;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Profiling;
using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web;
using Umbraco.Web.Routing;
using Umbraco.Web.Security;
using Umbraco.Web.Templates;
namespace Umbraco.Tests.Web
{
[TestFixture]
public class TemplateUtilitiesTests
{
[TestCase("", "")]
[TestCase("hello href=\"{localLink:1234}\" world ", "hello href=\"/my-test-url\" world ")]
[TestCase("hello href=\"{localLink:umb://document-type/9931BDE0-AAC3-4BAB-B838-909A7B47570E}\" world ", "hello href=\"/my-test-url\" world ")]
[TestCase("hello href=\"{localLink:umb://document-type/9931BDE0AAC34BABB838909A7B47570E}\" world ", "hello href=\"/my-test-url\" world ")]
//this one has an invalid char so won't match
[TestCase("hello href=\"{localLink:umb^://document-type/9931BDE0-AAC3-4BAB-B838-909A7B47570E}\" world ", "hello href=\"{localLink:umb^://document-type/9931BDE0-AAC3-4BAB-B838-909A7B47570E}\" world ")]
public void ParseLocalLinks(string input, string result)
{
var serviceCtxMock = MockHelper.GetMockedServiceContext();
//setup a mock entity service from the service context to return an integer for a GUID
var entityService = Mock.Get(serviceCtxMock.EntityService);
entityService.Setup(x => x.GetIdForKey(It.IsAny<Guid>(), It.IsAny<UmbracoObjectTypes>()))
.Returns((Guid id, UmbracoObjectTypes objType) =>
{
return Attempt.Succeed(1234);
});
//setup a mock url provider which we'll use fo rtesting
var testUrlProvider = new Mock<IUrlProvider>();
testUrlProvider.Setup(x => x.GetUrl(It.IsAny<UmbracoContext>(), It.IsAny<int>(), It.IsAny<Uri>(), It.IsAny<UrlProviderMode>()))
.Returns((UmbracoContext umbCtx, int id, Uri url, UrlProviderMode mode) =>
{
return "/my-test-url";
});
using (var appCtx = new ApplicationContext(new DatabaseContext(new Mock<IScopeProviderInternal>().Object, Mock.Of<ILogger>(), Mock.Of<ISqlSyntaxProvider>(), "test"),
serviceCtxMock,
CacheHelper.CreateDisabledCacheHelper(),
new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>())))
using (var umbCtx = UmbracoContext.EnsureContext(
Mock.Of<HttpContextBase>(), appCtx, new Mock<WebSecurity>(null, null).Object,
//setup a quick mock of the WebRouting section
Mock.Of<IUmbracoSettingsSection>(section => section.WebRouting == Mock.Of<IWebRoutingSection>(routingSection => routingSection.UrlProviderMode == "AutoLegacy")),
//pass in the custom url provider
new[]{ testUrlProvider.Object },
true))
{
var output = TemplateUtilities.ParseInternalLinks(input, umbCtx.UrlProvider);
Assert.AreEqual(result, output);
}
}
}
}
+1 -1
View File
@@ -2,7 +2,7 @@
<packages>
<package id="AspNetWebApi.SelfHost" version="4.0.20710.0" targetFramework="net45" />
<package id="AutoMapper" version="3.3.1" targetFramework="net45" />
<package id="Examine" version="0.1.81" targetFramework="net45" />
<package id="Examine" version="0.1.82" targetFramework="net45" />
<package id="log4net" version="2.0.5" targetFramework="net45" />
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net45" />
+13 -3
View File
@@ -11,17 +11,17 @@ module.exports = function (grunt) {
//TODO: Too much watching, this brings windows to it's knees when in dev mode
//run by the watch task
grunt.registerTask('watch-js', ['jshint:dev', 'concat', 'copy:app', 'copy:mocks', 'copy:canvasdesigner', 'copy:vs', 'karma:unit']);
grunt.registerTask('watch-less', ['recess:build', 'recess:installer', 'recess:canvasdesigner', 'postcss', 'copy:canvasdesigner', 'copy:assets', 'copy:vs']);
grunt.registerTask('watch-less', ['recess:build', 'recess:installer', 'recess:nonodes', 'recess:canvasdesigner', 'postcss', 'copy:canvasdesigner', 'copy:assets', 'copy:vs']);
grunt.registerTask('watch-html', ['copy:views', 'copy:vs']);
grunt.registerTask('watch-installer', ['concat:install', 'concat:installJs', 'copy:installer', 'copy:vs']);
grunt.registerTask('watch-canvasdesigner', ['copy:canvasdesigner', 'concat:canvasdesignerJs', 'copy:vs']);
grunt.registerTask('watch-test', ['jshint:dev', 'karma:unit']);
//triggered from grunt
grunt.registerTask('build', ['concat', 'recess:build', 'recess:installer', 'recess:canvasdesigner', 'postcss', 'bower-install-simple', 'bower', 'copy', 'clean:post']);
grunt.registerTask('build', ['concat', 'recess:build', 'recess:installer', 'recess:nonodes', 'recess:canvasdesigner', 'postcss', 'bower-install-simple', 'bower', 'copy', 'clean:post']);
//triggered from grunt dev vs or grunt vs
grunt.registerTask('build-dev', ['clean:pre', 'concat', 'recess:build', 'recess:installer', 'postcss', 'bower-install-simple', 'bower', 'copy']);
grunt.registerTask('build-dev', ['clean:pre', 'concat', 'recess:build', 'recess:installer', 'recess:nonodes', 'postcss', 'bower-install-simple', 'bower', 'copy']);
//utillity tasks
grunt.registerTask('docs', ['ngdocs']);
@@ -293,6 +293,16 @@ module.exports = function (grunt) {
compress: true
}
},
nonodes: {
files: {
'<%= distdir %>/assets/css/nonodes.style.min.css':
['src/less/pages/nonodes.less']
},
options: {
compile: true,
compress: true
}
},
installer: {
files: {
'<%= distdir %>/assets/css/installer.css':
@@ -172,8 +172,17 @@ tinymce.PluginManager.add('umbracolink', function(editor) {
//locallink detection, we do this here, to avoid poluting the dialogservice
//so the dialog service can just expect to get a node-like structure
if(currentTarget.url.indexOf("localLink:") > 0){
currentTarget.id = currentTarget.url.substring(currentTarget.url.indexOf(":")+1,currentTarget.url.length-1);
if (currentTarget.url.indexOf("localLink:") > 0) {
var linkId = currentTarget.url.substring(currentTarget.url.indexOf(":") + 1, currentTarget.url.length - 1);
//we need to check if this is an INT or a UDI
var parsedIntId = parseInt(linkId, 10);
if (isNaN(parsedIntId)) {
//it's a UDI
currentTarget.udi = linkId;
}
else {
currentTarget.id = linkId;
}
}
}
@@ -182,27 +191,34 @@ tinymce.PluginManager.add('umbracolink', function(editor) {
callback: function (data) {
if (data) {
var href = data.url;
// We want to use the Udi. If it is set, we use it, else fallback to id, and finally to null
var hasUdi = data.udi ? true : false;
var id = hasUdi ? data.udi : (data.id ? data.id : null);
//Create a json obj used to create the attributes for the tag
function createElemAttributes() {
var a = {
href: href,
title: data.name,
target: data.target ? data.target : null,
rel: data.rel ? data.rel : null
};
if (hasUdi) {
a["data-udi"] = data.udi;
}
else if (data.id) {
a["data-id"] = data.id;
}
}
function insertLink() {
if (anchorElm) {
dom.setAttribs(anchorElm, {
href: href,
title: data.name,
target: data.target ? data.target : null,
rel: data.rel ? data.rel : null,
'data-id': data.id ? data.id : null
});
dom.setAttribs(anchorElm, createElemAttributes());
selection.select(anchorElm);
editor.execCommand('mceEndTyping');
} else {
editor.execCommand('mceInsertLink', false, {
href: href,
title: data.name,
target: data.target ? data.target : null,
rel: data.rel ? data.rel : null,
'data-id': data.id ? data.id : null
});
editor.execCommand('mceInsertLink', false, createElemAttributes());
}
}
@@ -212,9 +228,11 @@ tinymce.PluginManager.add('umbracolink', function(editor) {
}
//if we have an id, it must be a locallink:id, aslong as the isMedia flag is not set
if(data.id && (angular.isUndefined(data.isMedia) || !data.isMedia)){
href = "/{localLink:" + data.id + "}";
insertLink();
if (id && (angular.isUndefined(data.isMedia) || !data.isMedia)){
href = "/{localLink:" + id + "}";
insertLink();
return;
}

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