Compare commits

..

704 Commits

Author SHA1 Message Date
Sebastiaan Janssen 75c2b07ad3 Update ModelsBuilder dependency for the NuGet package 2016-03-18 16:32:05 +01:00
Sebastiaan Janssen 969fe30f6e Merge pull request #1186 from umbraco/temp-U4-8043
U4-8043 - reboot app when PureLive models go wrong
2016-03-18 16:26:52 +01:00
Stephan 0f90d357cf U4-8043 - reboot application when PureLive models go wrong 2016-03-18 16:14:06 +01:00
Stephan d955daab0f Upgrade ModelsBuilder to 3.0.2 2016-03-18 16:13:19 +01:00
Shannon 617b17ca9e puts back in the current node permission check - since we use this for Create 2016-03-18 15:43:14 +01:00
Shannon 9e3d7a1cce updates default pipeline marker stage for the preview middleware, updates MembershipHelper to not throw an exception if the Role manager is disabled. 2016-03-18 11:05:39 +01:00
Warren Buckley f04071d7c7 Merge pull request #1180 from umbraco/temp-U4-8165
U4-8165 Ensure browsers are not caching service requests
2016-03-18 09:53:12 +00:00
Shannon Deminick 2cce9395da Merge pull request #1181 from mittonp/dev-v7
French translations for Grid.
2016-03-18 10:15:50 +01:00
Mitton 6ad56863d4 Grid translation - French 2016-03-18 06:15:37 +02:00
Mitton 2703fa7ea2 Grid translation - French 2016-03-18 06:12:44 +02:00
Shannon b3c6654d41 bumps version 2016-03-17 17:31:36 +01:00
Shannon 0071651621 fixes keyboard shortcut after refactor 2016-03-17 16:36:13 +01:00
Shannon Deminick 4dbc27f1fe Merge pull request #1178 from bjarnef/dev-U4-8163
U4-8163 - Don't set dirty on form for examine dashboard search
2016-03-17 11:31:36 +01:00
Shannon 3f8bbc2f02 Merge branch 'pynej-view-save-restore-cursor' into dev-v7 2016-03-17 11:29:29 +01:00
Shannon 999be9c578 Merge branch 'view-save-restore-cursor' of https://github.com/pynej/Umbraco-CMS into pynej-view-save-restore-cursor 2016-03-17 11:26:09 +01:00
Claus b36b1693dd Fixes broken regex. 2016-03-17 10:33:04 +01:00
Simon Busborg 99b2192ab7 Fixes U4-8181 It is not possible to scroll in an overlay in Chrome 49 on a Retina Mac
By removing animated -half-second fadeIn it resolves the issue where it's not possible to scroll in dialogs on a retina screen ¯\_(ツ)_/¯
2016-03-17 09:58:57 +01:00
Shannon 5230f55f44 moves attribute 2016-03-16 14:52:40 +01:00
Shannon f93fee28dd U4-8165 Ensure browsers are not caching service requests 2016-03-16 14:51:04 +01:00
Shannon Deminick fc7cfea4ad Merge pull request #1179 from umbraco/temp-U4-8175
U4-8175 - fix PropertyType.PropertyGroupId inconsistencies
2016-03-16 14:18:03 +01:00
Stephan bc5f651c64 U4-8154 - bugfix test 2016-03-16 13:46:51 +01:00
Stephan ecdca378c6 U4-8175 - fix PropertyType.PropertyGroupId inconsistencies 2016-03-16 13:41:58 +01:00
Stephan 4628c1f858 U4-8154 - bugfix test 2016-03-16 13:16:56 +01:00
Shannon Deminick 5af4d02f44 Merge pull request #1177 from umbraco/temp-U4-7109
U4-7109 - could not change language in Culture and Hostnames
2016-03-16 10:48:35 +01:00
Shannon 2f9b526465 Only apply preview auth if Umbraco is fully configured 2016-03-16 10:41:33 +01:00
Stephan 800e02bccf Bugfix model mapper for PropertyTypeDisplay 2016-03-16 10:19:06 +01:00
Shannon Deminick 693b0dba24 Merge pull request #1161 from umbraco/temp-U4-4219
U4-4219 Can't Preview protected pages
2016-03-16 10:18:06 +01:00
Stephan 2004f6a51e U4-8154 - bugfix 2016-03-16 10:10:31 +01:00
Claus f650b6238c Merge branch 'arknu-U4-8026' into dev-v7 2016-03-16 07:57:59 +01:00
Claus 7c179a7868 U4-8026 Fixes up unit tests 2016-03-16 07:56:41 +01:00
bjarnef 7a7e0edfa7 Don't set dirty on form for examine dashboard search 2016-03-15 23:59:11 +01:00
bjarnef 69adec1d68 Merge branch 'dev-v7' of https://github.com/bjarnef/Umbraco-CMS into dev-v7 2016-03-15 20:23:58 +01:00
Stephan 0cf6548f86 U4-7109 - could not change language in Culture and Hostnames 2016-03-15 17:26:05 +01:00
Sebastiaan Janssen 111ee66b60 Update ModelsBuilder dependency for the NuGet package 2016-03-15 17:15:39 +01:00
Stephan fedcd6f970 Merge pull request #1176 from umbraco/temp-U4-8168
U4-8168 Cannot re-order/move locked property types - such as the lock…
2016-03-15 16:29:57 +01:00
Stephan 8e82ff5450 Merge pull request #1173 from umbraco/temp-U4-8012
U4-8012 Generic properties tab disappears on the edit Member Type win…
2016-03-15 16:24:21 +01:00
Stephan 81459c3659 Merge pull request #1174 from umbraco/temp-U4-8065
U4-8065 Inherited from is empty - reverts 10617d1bd52bdac57534a7d7b8…
2016-03-15 16:08:26 +01:00
Rune Hem Strand 8907c9855b Merge pull request #1172 from umbraco/temp-U4-7185
Temp u4 7185
2016-03-15 16:02:47 +01:00
Stephan e1bf30ec26 Merge pull request #1175 from umbraco/temp-U4-8106
U4-8106 Content type inheritance can be broken by compositions
2016-03-15 15:53:37 +01:00
Shannon 6bb9c5b81c U4-8168 Cannot re-order/move locked property types - such as the locked/system member type properties 2016-03-15 15:43:21 +01:00
Shannon 6aafbfb245 U4-8106 Content type inheritance can be broken by compositions 2016-03-15 15:25:05 +01:00
Shannon d5fe8c11c8 U4-8065 Inherited from is empty - reverts 10617d1bd5, turns out this is why we needed that property value 2016-03-15 15:08:53 +01:00
Shannon 3fdb122e91 U4-8012 Generic properties tab disappears on the edit Member Type window after upgrade to 7.4 2016-03-15 14:44:03 +01:00
Shannon Deminick 710dda164f Merge pull request #1166 from umbraco/temp-U4-7708
U4-7708 Using a RTE Macro Partial Form (SurfaceController) & Doctype …
2016-03-15 13:57:27 +01:00
Claus 07d0d82bd1 Merge branch 'U4-8026' of git://github.com/arknu/Umbraco-CMS into arknu-U4-8026 2016-03-15 13:47:10 +01:00
Claus 91eb3ea59e Merge pull request #1152 from AndyButland/u4-7888
Fixed U4-7888 - Cannot change default template for document type
2016-03-15 13:43:07 +01:00
Rune Strand 096f1b6ff9 add selected state to umbFolderGrid 2016-03-15 13:18:48 +01:00
Rune Strand f24c0d3e7a Update umbBreadcrumb to use custom controller 2016-03-15 13:18:48 +01:00
Rune Hem Strand 104338c817 A little bit of foldergrid+ 2016-03-15 13:18:48 +01:00
Mads Rasmussen 568f098445 umbOverlay first draft 2016-03-15 13:18:48 +01:00
Mads Rasmussen f46d595f00 fix example on umbStickyBar 2016-03-15 13:18:48 +01:00
Mads Rasmussen 46826ad590 add docs for umbPagination 2016-03-15 13:18:48 +01:00
Mads Rasmussen a8bd34b77e add docs for umbMediaGrid 2016-03-15 13:18:48 +01:00
Mads Rasmussen 40774cfff2 rename umbContentGrid controller 2016-03-15 13:18:48 +01:00
Mads Rasmussen 5dde898205 change controller name on umbGenerateAlias 2016-03-15 13:18:48 +01:00
Mads Rasmussen 249287e101 fix umbKeyboardShortcutsOverview example 2016-03-15 13:18:48 +01:00
Mads Rasmussen 3e458e2ba6 add documentation for umbEmptyState 2016-03-15 13:18:48 +01:00
Mads Rasmussen 4f293a8be1 fix umbTooltip example 2016-03-15 13:18:48 +01:00
Mads Rasmussen 3b9d9ab8c4 change umbChildSelector controller name 2016-03-15 13:18:48 +01:00
Mads Rasmussen 83f875dadd fix umbConfirmAction example 2016-03-15 13:18:48 +01:00
Mads Rasmussen 89df81d3df update umbButtonGroup example to match newest code 2016-03-15 13:18:48 +01:00
Mads Rasmussen 2e4ee42c90 fix small issue with umbButton example 2016-03-15 13:18:48 +01:00
Mads Rasmussen a03858a726 fix examples in umbEditorHeader 2016-03-15 13:18:48 +01:00
Mads Rasmussen 253174d4b3 umbEditorSubHeader: move some example pieces to other directive examples to make it less overwhelming 2016-03-15 13:18:48 +01:00
Mads Rasmussen 947889fae6 update umbFooterContent directives example with a form element 2016-03-15 13:18:48 +01:00
Mads Rasmussen 7ee0b582dd update umbEditorFooter example with a form element 2016-03-15 13:18:48 +01:00
Mads Rasmussen 7bec4efc60 update umbEditorView with a better example 2016-03-15 13:18:48 +01:00
Mads Rasmussen 571d8086c8 update umbContentGrid docs to match latest directive changes 2016-03-15 13:18:48 +01:00
Rune Strand 8abeefe6bb Fix merge conflict 2016-03-15 13:18:48 +01:00
Mads Rasmussen 0aaf3eea02 added documentation for umbChildSelector 2016-03-15 13:18:48 +01:00
Mads Rasmussen 8fc84f9b09 added documentation to umbLockedField 2016-03-15 13:18:48 +01:00
Mads Rasmussen 493b98a771 added documentation to umbGenerateAlias 2016-03-15 13:18:48 +01:00
Mads Rasmussen 114a9b4d33 added documentation for umbFolderGrid 2016-03-15 13:18:48 +01:00
Mads Rasmussen 824b1e7c08 added documentation for umbContentGrid 2016-03-15 13:18:48 +01:00
Mads Rasmussen dfa9b297db added documentation for umbStickyBar 2016-03-15 13:18:48 +01:00
Mads Rasmussen adceb24651 added documentation for umbConfirmAction 2016-03-15 13:18:48 +01:00
Mads Rasmussen c7f1a1419a added documentation for umbTooltip 2016-03-15 13:18:48 +01:00
Mads Rasmussen 8878b5e21c added documentation for umbButtonGroup 2016-03-15 13:18:48 +01:00
Mads Rasmussen 6ebb1d1b4b added documentation for umbButton 2016-03-15 13:18:48 +01:00
Mads Rasmussen 583cd2d1e9 added documentation for sub header directives 2016-03-15 13:18:48 +01:00
Mads Rasmussen 86c6b01e73 added documentation for editor directives 2016-03-15 13:18:48 +01:00
Mads Rasmussen 1170e222e3 added umbBreadcrumbs documentation - first draft 2016-03-15 13:18:48 +01:00
Mads Rasmussen fe004db7d5 added umbLoadIndicator documentation - first draft 2016-03-15 13:18:48 +01:00
Mads Rasmussen 9e75ffb332 added umbKeyboardShortcutsOverview documentation - first draft 2016-03-15 13:18:48 +01:00
Mads Rasmussen d0bb6b7aa4 fix broken directives overview + set marker on deprecated directives 2016-03-15 13:18:48 +01:00
Claus c306f94a6a Merge pull request #1154 from pynej/fix-stylesheet-tree-sync
Fix for issue causing the entire stylesheets tree to reload when …
2016-03-15 12:46:59 +01:00
Claus 11b2ec89fd Merge pull request #1167 from umbraco/temp-U4-8154
U4-8154 - bugfix Sql query expressions parsing
2016-03-15 12:36:52 +01:00
Claus 89596f00f1 Merge pull request #1151 from arknu/icon-transparency
Fix transparency for image icons in the tray
2016-03-15 09:54:36 +01:00
Claus 4fa6e70e72 Merge pull request #1140 from jamescoxhead/U4-7746
U4-7746 - use flat icon in partial views tree
2016-03-15 09:22:18 +01:00
Warren Buckley a5a0a84d46 Merge pull request #1163 from umbraco/temp-U4-7767
U4-7767 List View Filter needs debounce - many requests to handler me…
2016-03-14 16:12:19 +00:00
Warren Buckley 839431e6fa Merge pull request #1170 from umbraco/temp-U4-8157
U4-8157 Right-click on root node returns console error when it doesn'…
2016-03-14 14:28:39 +00:00
Stephan 5369a6fc56 Upgrade ModelsBuilder to 3.0.1 2016-03-14 13:37:49 +01:00
Claus 8a078e258f U4-8157 Right-click on root node returns console error when it doesn't has any actions
Ensured we don't use throw to stop the program flow if no menuUrl is defined on the node. It is a likely scenario that some root node don't have right click actions so its better to handle this.
2016-03-14 12:15:15 +01:00
Sebastiaan Janssen fb42574c34 Revert "U4-5334 Richtext editor inserts extra p - tags to html output" - apparently it does just as much harm as it does good
This reverts commit 9ad3b6a337.
2016-03-12 21:02:05 +01:00
Sebastiaan Janssen 9ad3b6a337 U4-5334 Richtext editor inserts extra p - tags to html output
#U4-5334 Fixed
2016-03-12 12:58:53 +01:00
Jeremy Pyne 91da14b0c6 Second fix for partial views. 2016-03-11 14:56:55 -05:00
Jeremy Pyne f361e286ed This minor fix will restore the editors cursor in CoreArea editor boxes when they save the item. There is a check included to prevent this behavior is the server level code changes the file for some reason as then the cursor location could act unpredictably, so instead we just let it reset to the beginning of the file. 2016-03-11 14:44:21 -05:00
Stephan 65b16fbfe5 U4-8154 - bugfix Sql query expressions parsing 2016-03-11 14:18:08 +01:00
Stephan 6ad2853bce Merge pull request #1165 from umbraco/temp-U4-7949
U4-7949 The task runner has completed YSOD when using the Umbraco Pac…
2016-03-10 18:29:08 +01:00
Shannon e60e4e52fc U4-7708 Using a RTE Macro Partial Form (SurfaceController) & Doctype Hijack Controller causes problem with submissions 2016-03-10 18:00:14 +01:00
Sebastiaan Janssen b2407eab98 Merge pull request #1107 from bjarnef/dev-v7-tinymce-font-icons
Change icons for richtext editor config
2016-03-10 17:47:46 +01:00
Shannon 778c7a836b Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2016-03-10 15:52:43 +01:00
Shannon 11f9cdead0 U4-6366 Issue assigning member roles on MemberService.Saved event 2016-03-10 15:52:34 +01:00
Sebastiaan Janssen a1076d5443 Merge pull request #1160 from umbraco/temp-U4-6438
U4-6438 - fix dynamic extension methods when type loading goes bad
2016-03-10 15:49:15 +01:00
Shannon 4a11bf68f3 U4-7949 The task runner has completed YSOD when using the Umbraco Package installer 2016-03-10 15:23:52 +01:00
Sebastiaan Janssen fa64e73a43 Merge pull request #1164 from umbraco/temp-U4-5797
U4-5797 - fix PublishedContentType cache refresh for compositions
2016-03-10 14:04:46 +01:00
Stephan adf3e2dfe0 U4-5797 - fix PublishedContentType cache refresh for compositions 2016-03-10 13:59:50 +01:00
Shannon c4c86cf5ce U4-7767 List View Filter needs debounce - many requests to handler method 2016-03-10 13:02:20 +01:00
Sebastiaan Janssen 479aba8e1d Fixes unit test.. in the correct branch this time 2016-03-10 11:47:51 +01:00
Shannon 0c474e2aba U4-7670 True/false fields on Macro Picker don't save their setting nor read existing setting. - another null check required. 2016-03-10 10:06:20 +01:00
Shannon Deminick 4f5b34cdfe Merge pull request #1162 from pynej/codemirror-js-error
Fix for missing doc.setLine() function breaking code mirror editor.
2016-03-10 09:58:16 +01:00
Warren Buckley 0cb7f220ea Merge pull request #1149 from umbraco/temp-U4-4700
U4-4700 List View Doesn't Respect User Permissions
2016-03-10 08:52:38 +00:00
Jeremy Pyne 0995b2cb5a Fix for missing doc.setLine() function breaking code mirror editor. 2016-03-09 14:55:15 -05:00
Shannon af1fe425a2 udpates ext method to specify an explicit marker stage, updates UmbracoDefaultOwinStartup to be more flexible with the methods to override. 2016-03-09 19:37:37 +01:00
Shannon 22385d40db U4-4219 Can't Preview protected pages 2016-03-09 17:35:50 +01:00
Stephan 1b37475144 U4-6438 - fix dynamic extension methods when type loading goes bad 2016-03-09 15:55:41 +01:00
Shannon be0bacd895 Ensures all angular views are cache busted so browser cache is not an issue after upgrading. 2016-03-08 17:23:54 +01:00
Shannon a2564bd0c3 ensures that requests are only made for ids that haven't already been queried. 2016-03-08 16:18:33 +01:00
Shannon 402a5c9d56 fixes bool check 2016-03-08 15:57:59 +01:00
Shannon 2a2f22c7d9 fixes js null issue with boolean.controller 2016-03-08 15:53:45 +01:00
Shannon 372a768dca U4-4700 List view doesn't respect user permissions - makes the buttons show/hide based on the selected items instead of the current item. 2016-03-08 15:53:22 +01:00
Sebastiaan Janssen f6e48243a6 U4-8088 NuGet upgrade of UmbracoCms pacakage doesn't add ModelsBuilder keys to web.config 2016-03-08 13:39:35 +01:00
Warren Buckley 94ea677ec0 Merge pull request #1146 from umbraco/temp-U4-7641
U4-7641 - enable content type copy
2016-03-08 09:38:16 +00:00
Sebastiaan Janssen 55e7159f7d Forgot to remove them from the nuspec files 2016-03-08 10:35:57 +01:00
Sebastiaan Janssen 390a94e323 U4-8054 Issue with NuGet Uninstall.ps1 (running on updates)
#U4-8054 Fixed
2016-03-08 10:34:19 +01:00
Shannon Deminick 19fb920aa1 Merge pull request #1150 from umbraco/temp-U4-7823
U4-7823 - stop flooding the log with errors getting media 0
2016-03-07 17:58:49 +01:00
Shannon Deminick f35e1604ca Merge pull request #1141 from umbraco/temp-U4-8030
U4-8030 - Fix RenderModelBinder issue with surface
2016-03-07 17:53:31 +01:00
Shannon b9765c3bec fixes RenderModelBinder to use base implementation,adds unit tests 2016-03-07 17:52:28 +01:00
Shannon d5a57c505c adds RenderModelBinderTests 2016-03-07 16:53:57 +01:00
Shannon 5f365241a8 updates RenderModelBinder to simply check for IPublishedContent or IRenderModel 2016-03-07 16:29:40 +01:00
Shannon 9c121f0044 Fixes RenderModelBinder to inherit from DefaultModelBinder and use the default logic if the model in the route values is not IRenderModel 2016-03-07 16:26:30 +01:00
Shannon f13bc07ddc Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2016-03-07 15:13:41 +01:00
Shannon a707d23692 Allows for specifying explicit product names by overriding the property in MigrationStartupHander 2016-03-07 15:13:31 +01:00
Simon Busborg 0929b7d42c Fixes U4-8113 Styling for property labels affect package meta data labels 2016-03-07 14:55:18 +01:00
Simon Busborg 35a9272b68 Fixes U4-8036 Umbraco.MultiNodeTreePicker checkbox doesn't appear after selecting something from list view 2016-03-07 14:45:30 +01:00
Shannon Deminick 112453a032 Merge pull request #1144 from umbraco/temp-U4-8077
U4-8077 - ensure product name in migration event handlers
2016-03-07 14:09:29 +01:00
Simon Busborg bba7367ba6 Fixes U4-8058 Labels are changed to block-level elements 2016-03-07 12:12:35 +01:00
bjarnef 367073e02e Merge remote-tracking branch 'refs/remotes/umbraco/dev-v7' into dev-v7 2016-03-03 17:58:36 +01:00
Jeremy Pyne 83e679ba5e Fix for issue causing the entire stylesheets tree to reload when selecting a item. 2016-03-02 16:00:33 -05:00
Sebastiaan Janssen 05c35b22bd Merge pull request #1148 from umbraco/temp-U4-7040
U4-7040 - Fix bug with permissions cache refresh
2016-03-02 15:03:47 +01:00
AndyButland 1a4322eb48 Fix issue with database field check that led to default template for content type not being set 2016-02-29 09:04:50 +00:00
Asbjørn Riis-Knudsen 4d950fb4d4 Fix transparency for image icons in the tray 2016-02-28 17:40:58 +01:00
Stephan 0d191fb8bd U4-7823 - stop flooding the log with errors getting media 0 2016-02-26 11:35:24 +01:00
Mads Rasmussen f6318fb6f3 Merge pull request #1147 from lars-erik/fix-u4-8082-nested-forms-and-submit-bug
Fixes: U4-8082 New overlays post forms in IE / Edge
2016-02-26 10:08:51 +01:00
Warren Buckley c7a3efadb1 Remove debug JSON in the view 2016-02-25 21:09:12 +00:00
Warren Buckley 956425dfbf Now updated so the create button hides if we do not have the Create permission 'C' 2016-02-25 21:06:25 +00:00
Warren Buckley c616354522 After reading src code for contentEditorHelper.configureContentEditorButtons it makes the same assumption that if the publish action 'U' is present then the user can also unpublish aka 'Z' 2016-02-25 20:49:56 +00:00
Stephan 17b29357d4 U4-7040 - Fix bug with permissions cache refresh 2016-02-25 17:43:38 +01:00
Stephan 36246b96d4 Fix bug with permissions cache refresh 2016-02-25 17:39:34 +01:00
Stephan 7d8791ec86 Fix ActionButtonsResolver (need review) 2016-02-25 17:05:44 +01:00
Stephan f349a9ae3e U4-7641 - bugfix 2016-02-25 16:26:20 +01:00
Warren Buckley 2719e2c231 WIP - ListView that grabs the current nodes permission from the editorState & use a neater object to return to the view rather than the lovely Magic String CHARs. Need help understanding that I don't get all the permissions to be expected 2016-02-25 15:19:42 +00:00
Lars-Erik Aabech 57a766098d Removed nested form and changed buttons to type="button" + action instead of ng-submit on form. 2016-02-25 16:04:37 +01:00
Stephan dafde545b0 U4-7641 - bugfix + implement for media types 2016-02-25 16:02:04 +01:00
Stephan 610538261e U4-7641 - enable content type copy 2016-02-25 15:26:03 +01:00
Simon Busborg f78cb8a970 Merge pull request #1119 from jchurchley/dev-v7
Fixes U4-7963 Listview columns not evenly spaced in Chrome
2016-02-25 14:52:17 +01:00
Asbjørn Riis-Knudsen e8f84cfec0 Add parens around all BinaryExpressions to make sure that errors such U4-8026 do not happen 2016-02-25 12:20:58 +01:00
Sebastiaan Janssen def276de01 Merge pull request #1143 from umbraco/temp-U4-8027
U4-8027 - fix ApplicationContext request cache (was null cache)
2016-02-25 10:46:31 +01:00
Stephan 293b170a56 U4-8027 - fix ApplicationContext request cache (was null cache) 2016-02-24 14:16:48 +01:00
Stephan 9f7b82e20f U4-8077 - ensure product name in migration event handlers 2016-02-24 13:59:15 +01:00
Warren Buckley 6ba4efc416 Merge pull request #1142 from umbraco/temp-U4-7570
Temp u4 7570
2016-02-24 11:12:59 +00:00
Simon Busborg 981fb39af6 Fixed crop slider 2016-02-24 09:14:13 +01:00
Sebastiaan Janssen c64f6f894e U4-8024 Unable to use MvcBuildViews since 7.4.0 upgrade because 'umbraco.cms.presentation.create.controls.content' has been removed
Removes files for which the codebehind no longer exists
2016-02-23 17:23:55 +01:00
Simon Busborg 3e73c2da43 Fixed width of cropper 2016-02-23 16:31:10 +01:00
Mads Rasmussen 26a8d23039 Fixes: U4-8063 Content type editor: Keyboard shortcut overview should close on escape 2016-02-23 15:09:27 +01:00
Mads Rasmussen 2632ef740c Fixes: U4-7570 Hide image, focal point and remove link until image has loaded 2016-02-23 13:55:05 +01:00
Sebastiaan Janssen f024dba864 Merge pull request #1139 from umbraco/temp-U4-8017
U4-8017 - fix issues with MySql InitColumnTypeMap
2016-02-22 19:05:41 +01:00
Stephan 9758851a4b Fix SqlCeSyntaxProviderTests 2016-02-22 18:55:49 +01:00
Stephan 04b3532e9d U4-8030 - Fix RenderModelBinder issue with surface 2016-02-22 18:38:06 +01:00
Sebastiaan Janssen 38e56f0fea Might make the build server happy? 2016-02-22 17:57:44 +01:00
Sebastiaan Janssen 462baf91e4 Merge pull request #1137 from umbraco/temp-U4-7914
U4-7914 - add PublishedContentRequest.Preparing event
2016-02-22 17:45:50 +01:00
James Coxhead 01bcd3b623 Changed partial views icon to icon-article 2016-02-22 16:15:31 +00:00
James Coxhead 64fd95bd22 Updated tree icons for partial views and partial view macros 2016-02-22 16:13:25 +00:00
Stephan f1366c7d29 U4-8017 - fix issues with MySql InitColumnTypeMap 2016-02-19 13:33:11 +01:00
Warren Buckley baaa9340e4 Merge pull request #1131 from umbraco/temp-U4-7918
Fixes U4-7918 Make icon picker for document type and list views consistent
2016-02-19 12:03:27 +00:00
Mads Rasmussen 183a5b5c43 U4-7472: fix macro parameter column width 2016-02-19 09:52:29 +01:00
Mads Rasmussen 1a0c095f40 Merge pull request #932 from engern/MacroParamSortOrder
Fixes U4-7472 - Should be possible to sort macro parameters
2016-02-19 09:27:27 +01:00
Stephan ffada74aa4 Improve RenderModelBinder error msg when same type, different assemblies 2016-02-18 16:04:45 +01:00
Mads Rasmussen f2fc70f731 Merge pull request #982 from abryukhov/patch-4
U4-7616 - Nodes sort dialog - additional date formats
2016-02-18 14:19:06 +01:00
Simon Busborg 866b0113e7 Fixes grunt break 2016-02-18 12:43:09 +01:00
Simon Busborg 06c49daca7 Merge branch 'dev-v7-login-retina-umbraco-logo' of git://github.com/bjarnef/Umbraco-CMS into bjarnef-dev-v7-login-retina-umbraco-logo
# Conflicts:
#	src/Umbraco.Web.UI.Client/src/less/pages/login.less
2016-02-18 12:42:17 +01:00
Stephan 9293008b94 U4-7914 - add PublishedContentRequest.Preparing event 2016-02-18 11:36:48 +01:00
Mads Rasmussen dbb9386d22 Fixes: U4-7660 [7.4 Fix] Added a default value to the Umbaco.TrueFalse datatype. Thanks Jeremy Pyne 2016-02-18 11:20:04 +01:00
Mads Rasmussen 51ed441b85 Merge branch 'u4-5123' of https://github.com/AndyButland/Umbraco-CMS into AndyButland-u4-5123
# Conflicts:
#	src/Umbraco.Web/PropertyEditors/ListViewPropertyEditor.cs
2016-02-18 10:00:22 +01:00
Simon Busborg f566fec665 Merge branch 'Acentrage-U4-6700' into dev-v7 2016-02-17 15:26:51 +01:00
Mads Rasmussen 9d92781a97 Merge pull request #949 from kgiszewski/dev-v7
Fix u4-7534
2016-02-17 15:04:14 +01:00
Simon Busborg 123bfe5afe Fixed merge conflict 2016-02-17 14:31:30 +01:00
Shannon Deminick 3383d2a2ac Merge pull request #1135 from umbraco/temp-U4-7601
U4-7601 - filter published content by composition
2016-02-17 13:31:07 +01:00
Sebastiaan Janssen d9f38a20af Merge remote-tracking branch 'origin/7.3.8' into dev-v7 2016-02-17 13:28:52 +01:00
Sebastiaan Janssen a91669abc0 Fixes unit tests 2016-02-17 13:28:11 +01:00
Stephan cc6dfd0c55 U4-7601 - refactor PR, case insensitive 2016-02-17 12:55:40 +01:00
Stephan d4802fcef6 Merge branch 'feature/is-composed-of' of https://github.com/AndyButland/Umbraco-CMS into temp-U4-7601 2016-02-17 12:44:18 +01:00
Sebastiaan Janssen 35c3208b77 Fixes merge error 2016-02-17 12:30:42 +01:00
Shannon 3b9db8a92f tries fixing test for appveyor 2016-02-17 12:25:40 +01:00
Sebastiaan Janssen 7debe17c58 Merge remote-tracking branch 'origin/7.3.8' into dev-v7
Conflicts:
	src/Umbraco.Web.UI/packages.config
2016-02-17 11:56:24 +01:00
Sebastiaan Janssen 1bfc1229bd Merge pull request #1134 from umbraco/temp-738-U4-7996
Upgrade SQL CE to hopefully fix SQL CE data loss bug
2016-02-17 11:54:25 +01:00
Shannon f941456af6 fixes namespace 2016-02-17 11:48:32 +01:00
Shannon 828e88e6f2 Merge remote-tracking branch 'origin/7.3.8' into dev-v7
Conflicts:
	src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs
	src/Umbraco.Web/Mvc/UmbracoViewPageOfTModel.cs
2016-02-17 11:46:33 +01:00
Sebastiaan Janssen 3d6fd2d785 Updates to SQL CE 4.0.0.1 2016-02-17 11:44:33 +01:00
Shannon e56881abc6 adds unit tests for new ext methods 2016-02-17 11:21:15 +01:00
Shannon d32991c30a re-organizing some namespaces for tests 2016-02-17 10:59:48 +01:00
Shannon 8758f9649b checks for null before assigning culture 2016-02-17 10:57:20 +01:00
Sebastiaan Janssen 07902e840f Merge pull request #1133 from rodyvansambeek/patch-2
Changed allow upload whitelist to disallow extensions
2016-02-17 10:53:05 +01:00
rodyvansambeek e807ee7d64 Changed allow upload whitelist to disallow extensions
It is not possible to upload files in 7.4.0 with an extension different then the imageTypes in the Umbraco.Sys.ServerVariables.umbracoSettings.imageFileTypes, in the single upload this was changed after beta 7.4.0-beta1 to Umbraco.Sys.ServerVariables.umbracoSettings.disallowedUploadFiles. However the change was not added to the drag-drop-uploader. This fixes that.
2016-02-17 10:30:57 +01:00
Shannon 6f0f1ab2c3 fixes wrong constant used 2016-02-17 10:22:37 +01:00
Shannon cd28240172 Moves strings to constants, adds ControllerContextExtensions to get the UmbracoContext from the hierarchy of ControllerContext's, changes RenderModelBinder to use this method to get the UmbracoContext, changes UmbracoViewPageOfTModel to use this method to get the UmbracoContext, adds RouteDataExtensions to get the UmbracoContext from routedata, adds extension methods on the HttpContext to get the UmbracoContext from it.
Conflicts:
	src/Umbraco.Web/Mvc/RenderModelBinder.cs
2016-02-17 10:22:22 +01:00
Sebastiaan Janssen 85ca85fd42 Merge pull request #1129 from umbraco/temp-U4-7577
U4-7577 Remove dependency on UmbracoContext in CreateServiceContext /…
2016-02-16 17:32:38 +01:00
Sebastiaan Janssen 4a10178697 Merge pull request #1123 from umbraco/temp-U4-8000
U4-8000 NullReferenceException in RenderModelBinder when performing an async controller action
2016-02-16 17:28:49 +01:00
Shannon ccba7f14a0 tries fixing test for appveyor 2016-02-16 16:26:21 +01:00
Sebastiaan Janssen b797e0d0c5 Merge pull request #1127 from umbraco/temp-U4-7953
U4-7953 Creating Templates via new DocType have camelCased aliases, b…
2016-02-16 15:39:35 +01:00
Sebastiaan Janssen 8220b033f3 Merge pull request #1125 from umbraco/temp-U4-7954
U4-7954 Error upgrading database to 7.4.0 - [ FK_cmsPropertyTypeGroup…
2016-02-16 15:20:53 +01:00
Shannon 6fffc8b45e U4-7577 Remove dependency on UmbracoContext in CreateServiceContext / RequestLifespanMessagesFactory 2016-02-16 15:07:42 +01:00
Shannon b550b3dde3 Merge remote-tracking branch 'origin/7.3.8' into dev-v7 2016-02-16 14:52:14 +01:00
Shannon 7002291c41 adds tests for ShouldAuthenticateRequest for app configurations 2016-02-16 14:51:15 +01:00
Shannon 51bbf7ceb5 U4-7494 Installation Fails for 7.3.3 - Intermittent - Value cannot be null. Parameter name: sqlSyntax 2016-02-16 14:22:59 +01:00
Shannon 93d9f09fcc U4-7953 Creating Templates via new DocType have camelCased aliases, but from the Template section have PascalCase aliases 2016-02-16 14:20:29 +01:00
Sebastiaan Janssen 42a68cb770 U4-7494 Installation Fails for 7.3.3 - Intermittent - Value cannot be null. Parameter name: sqlSyntax 2016-02-16 14:00:28 +01:00
Shannon 1c2dec00fc bumps version 2016-02-16 13:32:03 +01:00
Shannon fcea4c7fdd Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2016-02-16 13:30:21 +01:00
Shannon b6ef4bf6b5 Merge branch '7.3.8' into dev-v7
Conflicts:
	build/UmbracoVersion.txt
	src/SolutionInfo.cs
	src/Umbraco.Core/Configuration/UmbracoVersion.cs
	src/Umbraco.Core/Umbraco.Core.csproj
	src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
2016-02-16 13:29:59 +01:00
Shannon 82297a6ff1 U4-7929 Label datatype strips leading zeros 2016-02-16 13:23:37 +01:00
Warren Buckley 3bf79f0a23 Merge pull request #1102 from umbraco/temp-U4-7837
Fixes: U4-7837 Changing document type should refresh the current node
2016-02-16 12:22:56 +00:00
Shannon 3f5aa3aa2b U4-7954 Error upgrading database to 7.4.0 - [ FK_cmsPropertyTypeGroup_cmsPropertyTypeGroup_id ] doesn't exist 2016-02-16 12:17:21 +01:00
Shannon cc5ac1a84c bumps version 2016-02-16 11:57:10 +01:00
Shannon 6373add383 U4-7922 Preview is not working 2016-02-16 11:53:54 +01:00
Shannon 180099b718 U4-7890 XSLT Macro's not working - "Cannot use this obsoleted overload when the current provider" 2016-02-16 11:52:16 +01:00
Shannon 65f15125e1 U4-7939 - fix routes cache 2016-02-16 11:48:09 +01:00
Shannon f026201c68 fixes wrong constant used 2016-02-16 11:35:38 +01:00
Shannon 640b2c0ee0 Moves strings to constants, adds ControllerContextExtensions to get the UmbracoContext from the hierarchy of ControllerContext's, changes RenderModelBinder to use this method to get the UmbracoContext, changes UmbracoViewPageOfTModel to use this method to get the UmbracoContext, adds RouteDataExtensions to get the UmbracoContext from routedata, adds extension methods on the HttpContext to get the UmbracoContext from it. 2016-02-16 11:17:47 +01:00
Shannon Deminick bef7ad1196 Merge pull request #1120 from lars-erik/fix-silly-long-grid-translation
Grid translations
2016-02-16 10:12:02 +01:00
Shannon Deminick 33c6c8b473 Merge pull request #1121 from umbraco/temp-U4-7950
Fixes another reported bug for U4-7950
2016-02-16 10:05:09 +01:00
Sebastiaan Janssen 0a26e482aa Fixes another reported bug for U4-7950 2016-02-16 09:01:28 +01:00
Lars-Erik Aabech d0de54e2d3 Grid translations:
Fixed a silly long translation of "Add content".
Added missing keys.
Fixed a few spelling mistakes.
2016-02-16 08:50:07 +01:00
bjarnef 6effcdfce9 Merge remote-tracking branch 'refs/remotes/umbraco/dev-v7' into dev-v7 2016-02-15 18:52:30 +01:00
Stephan cbdabaa3b1 Merge pull request #1118 from umbraco/temp-U4-7950
Use CultureInfo.CurrentCulture if UmbracoContext.PublishedContentRequ…
2016-02-15 15:21:00 +01:00
John Churchley 65c97040b3 Fix Chrome issue listview columns not evenly spaced
http://issues.umbraco.org/issue/U4-7963#
2016-02-15 12:17:13 +00:00
Simon Busborg a33d7da211 Fixes: U4-7945 Grid's Reorder bar covers content
http://issues.umbraco.org/issue/U4-7945
2016-02-15 12:55:44 +01:00
Sebastiaan Janssen f31b6d9c2c Use CultureInfo.CurrentCulture if UmbracoContext.PublishedContentRequest is not available 2016-02-15 08:27:07 +01:00
Sebastiaan Janssen 367c945b42 Merge pull request #1117 from s-moon/patch-1
Minor text changes.
2016-02-14 11:08:19 +01:00
Stephen Moon b962fcdbc3 Minor text changes. 2016-02-13 21:31:13 +00:00
Simon Busborg 0f8a13d60a 7 in a row instead of 8, bumped font-size on icons to 30 2016-02-12 10:17:42 +01:00
Simon Busborg 5c1502c806 Removes umb-control-group when no icons displayed 2016-02-12 10:13:30 +01:00
Simon Busborg 3cdebf4427 Fixes U4-7918 Make icon picker for document type and list views consistent 2016-02-12 09:38:37 +01:00
Shannon e4e7c18460 Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2016-02-11 18:07:42 +01:00
Shannon 5f246c533c Fixes issue when there are zero instructions in the db table and we've never synced before, in this case it will always cold boot because it will never saved the last synced, in this scenario also the indexes will not build because we've cleared the collection before they can run. 2016-02-11 18:07:31 +01:00
Sebastiaan Janssen 5323543ec0 Merge pull request #1115 from abryukhov/patch-3
Update UI language ru.xml
2016-02-11 17:36:28 +01:00
Shannon d44542694b Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2016-02-11 17:31:49 +01:00
Shannon 016a14e5c7 Fixes the image cropper where if you don't have any crops, save an image to a content item, then when you go create a new crop in the data type it wouldn't show up on the front-end or in the back office. 2016-02-11 17:31:37 +01:00
Alexander Bryukhov 52f4dfec80 Update UI language ru.xml
According new keys added to the 7.4.0 nightly build 164 (models builder keys)
2016-02-11 22:29:33 +06:00
Sebastiaan Janssen 4f6e023d77 Make sure that everybody working on the source actually gets these assembly references in web.config 2016-02-11 17:11:02 +01:00
Shannon 5e46750cc4 nuspec and version 2016-02-11 16:34:15 +01:00
Shannon d028b133f5 nuspec updated with MB 2016-02-11 16:27:58 +01:00
Shannon ca6821104b updated to MB 3.0.0 final 2016-02-11 16:26:21 +01:00
Shannon 1ea8c8280c Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2016-02-11 15:54:10 +01:00
Shannon 17ff952b52 Fixes the URL creating for media in the back office to use an IMedia instead of published media (since it's not published yet at the time) 2016-02-11 15:54:00 +01:00
Sebastiaan Janssen b4f64975a2 Merge pull request #1113 from umbraco/temp-U4-7936
U4-7936 Clicking the Recycle Bin shows "Session expired" login screen
2016-02-11 15:48:24 +01:00
Sebastiaan Janssen 1d8a5cf795 Merge pull request #1114 from umbraco/temp-u4-7729
U4-7729 7.4.0-Beta Cannot drag and Drop PDF on Media Section
2016-02-11 15:34:41 +01:00
Shannon dccee93700 fixes up some null checks and fixes up some string null checks - casting XElement to (string) explicitly avoids null reference exceptions when the XElement isn't actually present. 2016-02-11 15:11:11 +01:00
Per Ploug efeafb4471 U4-7729 7.4.0-Beta Cannot drag and Drop PDF on Media Section 2016-02-11 14:42:47 +01:00
Shannon Deminick 496efde5b3 Merge pull request #1093 from jonrandahl/patch-1
Update PackagingService.cs
2016-02-11 14:18:23 +01:00
Shannon Deminick 2b56854652 Merge pull request #1112 from umbraco/temp-U4-7939
U4-7939 - fix routes cache
2016-02-11 14:15:13 +01:00
Shannon 04e1d8c2bd U4-7936 Clicking the Recycle Bin shows "Session expired" login screen 2016-02-11 14:04:14 +01:00
Simon Busborg c7a7dd6ed5 Fixed disabled buttons 2016-02-11 13:12:13 +01:00
Sebastiaan Janssen 1eedbba97a Merge pull request #920 from darrenferguson/dev-v7
change the text "Reload nodes" to just "Reload" my editors don't know…
2016-02-11 12:04:45 +01:00
Stephan d6b46e7e78 U4-7939 - fix routes cache 2016-02-11 11:53:03 +01:00
Shannon 1b03a8f06c Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2016-02-11 11:51:11 +01:00
Shannon 726bef1edf adds notes 2016-02-11 11:50:59 +01:00
Sebastiaan Janssen 33aa04bb2f Updates ImageProcessor.Web 2016-02-11 10:35:52 +01:00
Rune Hem Strand a79333080a Merge pull request #1111 from umbraco/U4-7933
Fixes issue U4-7933
2016-02-11 09:49:09 +01:00
Sebastiaan Janssen d1f513df69 Updates ImageProcessor 2016-02-10 17:09:40 +01:00
Shannon 54ddbc264d Fixes U4-7906 2016-02-10 16:39:05 +01:00
Shannon 89f6089f8e U4-7873 - fix GetCulture issue with languages 2016-02-10 16:22:06 +01:00
Shannon Deminick cf0b72fd77 Merge pull request #1026 from christofur/U4-7763
U4-7763 Fix - added mock and references required for 'dev' Grunt task
2016-02-10 15:54:59 +01:00
Niels Hartvig 2c32530701 Too fast, removed the extra amp 2016-02-10 15:47:52 +01:00
Niels Hartvig d6d945a96e Adds animationprocessmode=false to avoid issues with anim gifs 2016-02-10 15:46:18 +01:00
Shannon Deminick 4b6aee7fd9 Merge pull request #1109 from abryukhov/patch-3
Update UI language ru.xml
2016-02-10 15:44:42 +01:00
Niels Hartvig 8bbeeb2eaf Fixes issue 7933 2016-02-10 15:38:49 +01:00
Shannon Deminick 5648617809 Merge pull request #1098 from umbraco/temp-U4-7891
U4-7891 Image Cropper needs a property value converter to return a strongly typed model, json or a string when requested.
2016-02-10 15:32:55 +01:00
Shannon 0a33b37f2d Fixes issue with U4-7695 and not merging crop values with pre-values properly 2016-02-10 15:31:04 +01:00
Sebastiaan Janssen 157bf0d1eb Include modelsbuilder App_Plugins files in csproj so that the build actually includes them 2016-02-10 14:57:41 +01:00
Shannon 2721c5cb12 adds dynamic caseinsensitive support for the image cropper model 2016-02-10 14:54:00 +01:00
Shannon fd984bd613 Ensures media.Url works properly 2016-02-10 14:53:58 +01:00
Shannon fe0ed2ceea Adds some notes and ensures that the ImageCropperValueConverter shadows the correct one. 2016-02-10 14:53:57 +01:00
Shannon 0829bae5b2 Fixes TextStringValueConverter to include the text box and multi-textbox (since it's like that in the Core one that this overrides), adds new converter for Image cropper including ToString converter & custom type converter to convert from the strongly typed object to JObject, adds test to support this, adds equatable methods for the strongly typed model so it can be easily compared. Ensures that the webboot manager does not include the core value converter for image cropper. 2016-02-10 14:53:56 +01:00
Stephan c3c1567c2e Merge pull request #1100 from umbraco/temp-U4-7881
U4-7881 - fix errors with compositions
2016-02-10 14:53:45 +01:00
Shannon 4a8b59bdfa putting back in ContentTypeId on PropertyTypeDisplay, turns out this IS used when we remove a composition, we need to know which properties are related to which type. have also fixed another potential bug regarding compositions + generic properties, before we were not setting the ContentTypeId correct for a composition property type on the generic properties tab. 2016-02-10 14:34:33 +01:00
Shannon af543c56ec moves model to correct namespace 2016-02-10 13:31:36 +01:00
Claus 4113def0b6 Fixes: U4-7881 version 7.4 beta - cannot add composition doctype to a doctype that has already been saved 2016-02-10 13:08:36 +01:00
Shannon Deminick c346e62176 Merge pull request #1108 from umbraco/temp-U4-7799
Fixes: U4-7799 ModelsBuilder button in Content Type Editor should sav…
2016-02-10 13:05:38 +01:00
Sebastiaan Janssen 94fdbb1983 U4-7669 Update Newtonsoft.Json dependency to v8.0.1 from v6.0.5 2016-02-10 13:04:50 +01:00
Shannon f32e688c1a Fixes the MB re-generate button - this will only be shown when the models are out of date. 2016-02-10 13:04:04 +01:00
Mads Rasmussen 0303196f42 show Ulog error message when models builder fails 2016-02-10 11:47:01 +01:00
Mads Rasmussen c8faf17017 Fixes: U4-7799 ModelsBuilder button in Content Type Editor should save the current content type 2016-02-10 11:47:00 +01:00
Sebastiaan Janssen b2cba310b9 U4-7720 Media grid doesn't display preview for animated gif
In preparation of an updated ImageProcessor build, everything that displays animated gifs in the backoffice can run into this issue, so we show the first frame only everywhere (better than just a broken image)
2016-02-10 11:39:00 +01:00
Sebastiaan Janssen 95522afda8 Merge pull request #1110 from umbraco/temp-U4-7925
U4-7925 Add dependency injection to Umbraco.Web.Trees.TreeController*
2016-02-10 10:57:15 +01:00
Shannon 1b84e33392 reinstall the RC2 version 2016-02-10 10:43:41 +01:00
Shannon 065ed5ed78 updates nuspec 2016-02-10 10:28:57 +01:00
Shannon 9e931b84db U4-7925 Add dependency injection to Umbraco.Web.Trees.TreeController* 2016-02-10 10:26:09 +01:00
Shannon be449a96f7 updates to MB rc2 2016-02-10 10:26:08 +01:00
Alexander Bryukhov a22bfb927a Update UI language ru.xml
According new keys added to the 7.4.0 nightly build 162
2016-02-09 22:18:11 +06:00
Sebastiaan Janssen 5b92b30f64 Don't include the uninstall file in nuspec, it's missing so the package won't build 2016-02-09 17:16:04 +01:00
Sebastiaan Janssen 5e8200ecb2 U4-7909 7.4-rc1 is missing references because it's using portable class libraries now
#U4-7909 Fixed
2016-02-09 17:10:43 +01:00
Sebastiaan Janssen 9b5ea3da21 Can't have an uninstall as it runs during Update-Package, removing configuration settings like umbracoConfigurationStatus triggering the fresh install screen all user settings are also reverted :/ 2016-02-09 17:10:14 +01:00
Sebastiaan Janssen d495b96434 U4-7924 NuGet web.config transform changes targetFramework 2016-02-09 16:29:20 +01:00
Sebastiaan Janssen 79edf81434 Just whitespace, formatting document 2016-02-09 16:00:02 +01:00
Sebastiaan Janssen b3620f1ca4 U4-7924 NuGet web.config transform removes <codedom>
#U4-7924 Fixed
2016-02-09 15:39:48 +01:00
Stephan b6a9734755 Fix ModelsBuilder integration 2016-02-09 11:46:26 +01:00
Shannon c4cedaddd2 Merge remote-tracking branch 'origin/master-v7' into dev-v7 2016-02-09 11:00:57 +01:00
Shannon b5a2b3dbbd U4-7922 Preview is not working 2016-02-09 10:56:15 +01:00
Mads Rasmussen dc4266852f Fixes: U4-7915 7.4 RC1: Cannot change grid background 2016-02-09 09:57:41 +01:00
Simon Busborg 881e8daafd Merge pull request #1104 from abryukhov/patch-3
Update UI language ru.xml
2016-02-08 18:51:20 +01:00
bjarnef 5176b68935 Merge remote-tracking branch 'refs/remotes/umbraco/dev-v7' into dev-v7-tinymce-font-icons 2016-02-08 15:07:36 +01:00
bjarnef 0bfc5f1272 Change icons in tinymce config 2016-02-08 15:07:16 +01:00
Claus 54c1d25296 Fixes: U4-6407 Change Document Type feature on a node doesn't support compositions 2016-02-08 14:39:16 +01:00
Mads Rasmussen 624d3a9b82 fixes: U4-7905 val-highlight directive not highlighting error fields (red border) in 7.4.0 2016-02-08 13:35:59 +01:00
Mads Rasmussen d46d23b372 Fixes: U4-7732 Grid changes do not trigger Unsaved Changes notification 2016-02-08 12:07:45 +01:00
Mads Rasmussen aeba68782c fixes: U4-7903 Using shortcut for "add property" removes "add property"-field for other tabs in document type editor && U4-7904 Add property using shortcut - submit button text is missing 2016-02-08 10:54:58 +01:00
Mads Rasmussen ac60c63104 Fixes: U4-7900 The new content type editor: If you hit save while it generates an alias, the alias will be generatingAlias 2016-02-08 10:20:09 +01:00
Claus 6e0e48b6e4 Merge pull request #1103 from arknu/U4-7819
U4-7819: Use correct messages when saving Media and Member types
2016-02-08 09:24:42 +01:00
Alexander Bryukhov 0ea15ae22e Update UI language ru.xml
According new / changed keys of 7.4 nightly build 161
2016-02-07 11:37:06 +06:00
Asbjørn Riis-Knudsen 54548ffc68 U4-7819: Use correct messages when saving Media and Member types 2016-02-06 17:34:36 +01:00
bjarnef 39c18d4201 Merge branch 'dev-v7' of https://github.com/bjarnef/Umbraco-CMS into dev-v7 2016-02-05 15:54:48 +01:00
Claus fdc50f0635 Merge pull request #1101 from KevinJump/dev-v7-GetContent/MediaContainer-Fix
Fix GetContentTypeContainer and GetMediaTypeContainer
2016-02-05 15:15:56 +01:00
bjarnef 66ea8ae604 Merge remote-tracking branch 'refs/remotes/umbraco/dev-v7' into dev-v7 2016-02-05 14:55:53 +01:00
Claus 44f2a9e96f Fixes: U4-7837 Changing document type should refresh the current node 2016-02-05 14:37:01 +01:00
Kevin Jump 11743ea322 Fix GetContentTypeContainer and GetMediaTypeContainer to use correct guid
updated to use DocumentTypeContainerGuid,  MediaTypeContainerGuid
contstants in calls.
2016-02-05 13:20:10 +00:00
Simon Busborg 4d74ec7785 Makes editor types tabs accessible. 2016-02-05 11:49:41 +01:00
Sebastiaan Janssen aa704a2065 Umbraco.ModelsBuilder.AspNet.dll is no longer needed 2016-02-05 11:28:12 +01:00
Mads Rasmussen 08844ea098 close user dialog when clicking on edit, history links and logout 2016-02-05 11:08:34 +01:00
Claus 3449b1efd3 Toggle password fields after successfully changing the password. 2016-02-05 10:43:37 +01:00
Claus 00d012162f Added a bunch of missing translations in user overlay. 2016-02-05 10:38:15 +01:00
Shannon 966be0f342 updates nuspec 2016-02-04 20:28:05 +01:00
Shannon 0347a93dcf Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2016-02-04 20:23:20 +01:00
Shannon 25482f53ef updates to MB RC1 2016-02-04 20:23:11 +01:00
Sebastiaan Janssen 7e762d9114 Apparently we ship this in the zip version 2016-02-04 20:21:32 +01:00
Mads Rasmussen 82699a8ac9 Fixes: U4-7898 Validation for locked alias still not working 2016-02-04 20:08:19 +01:00
Shannon 0ea68f4f42 added logic for media and member type angular callbacks that existed for content types - assuming this is important and should be there for all content types. Added alias information to validation message returned from server. 2016-02-04 19:40:29 +01:00
Shannon 2cd4e9aa99 makes media types the same as the other content types 2016-02-04 19:26:16 +01:00
Shannon 8e3454d24f Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2016-02-04 19:17:00 +01:00
Shannon e352c65420 fixes server side validation issue for content types 2016-02-04 19:16:45 +01:00
Sebastiaan Janssen 04a12567bc Merge pull request #1090 from umbraco/temp-U4-3447
U4-3447 Nuget package does not install correctly with "Web Site" projects
2016-02-04 19:12:45 +01:00
Sebastiaan Janssen 16caeb96bd Another build warning that can be removed 2016-02-04 18:36:26 +01:00
Sebastiaan Janssen fbd5bdbd1d Surely nobody on their dev machines has the "trust" node in their web.configs any more, no more need to transform that one (gave warning during build.bat) 2016-02-04 18:35:16 +01:00
Sebastiaan Janssen e3983bb427 Depend on latest modelsbuilder 2016-02-04 18:32:21 +01:00
Sebastiaan Janssen c4389a3820 Fixes dashboard transform, works now 2016-02-04 18:32:20 +01:00
Sebastiaan Janssen 1f8274e807 These deletes still need to be there because some of these files don't get overwritten automatically for .. I don't know what reason really. 2016-02-04 18:32:20 +01:00
Shannon 9978b0d8ea Merge branch 'dev-v7' into temp-U4-3447 2016-02-04 18:30:58 +01:00
Shannon 0d9fef5457 changes to use StripWhitespace to fix tests 2016-02-04 18:09:17 +01:00
Shannon Deminick 7449e3bf1d Merge pull request #1096 from umbraco/temp-U4-7895
U4-7895 - routing fails when path contains dots
2016-02-04 17:44:39 +01:00
Shannon Deminick e6550b543d Merge pull request #1099 from robertjf/dev-v7
U4-7897 Minor update to MembershipProviderBase.DecryptPassword() to remove code smell
2016-02-04 17:38:59 +01:00
Shannon Deminick 1552a08b46 Merge pull request #1097 from umbraco/temp-U4-7887
U4-7887 - default to database connection timeout
2016-02-04 17:30:02 +01:00
Robert Foster c9d2d574f8 brought PasswordFormat switch in DecryptPassword in line with other useages. 2016-02-05 03:29:33 +11:00
Sebastiaan Janssen 4807bc4f2f Shoot, can't remove that one, else it'll also remove the "Welcome" section 2016-02-04 17:20:30 +01:00
Sebastiaan Janssen 87a2589853 Update old reference of System.Web.Mvc 2016-02-04 17:19:07 +01:00
Sebastiaan Janssen 6f400df775 The "Change password" dashboard will throw js errors if it's still there (the matching js files are not there any more) 2016-02-04 17:18:34 +01:00
Sebastiaan Janssen 68eaca6f66 Still shouldn't forget to build if you're using a web app (no need for website projects though) 2016-02-04 16:43:50 +01:00
Sebastiaan Janssen 166429cf68 Fixes the "No license field." error, see:
https://github.com/npm/npm/issues/4473#issuecomment-103453246
2016-02-04 16:10:35 +01:00
Mads Rasmussen 48adc259d9 fix content type editor property preview background in firefox 2016-02-04 15:19:20 +01:00
Stephan 42c23dadc9 U4-7887 - default to database connection timeout 2016-02-04 14:51:19 +01:00
Stephan fb9471359c U4-7895 - routing fails when path contains dots 2016-02-04 13:03:53 +01:00
Mads Rasmussen 4e0b018a8b Merge branch 'AndyButland-u4-7840' into dev-v7 2016-02-04 11:46:15 +01:00
Mads Rasmussen f94b5cc462 small fixes to U4-7840 2016-02-04 11:45:31 +01:00
Mads Rasmussen fee98f8144 Merge branch 'u4-7840' of https://github.com/AndyButland/Umbraco-CMS into AndyButland-u4-7840 2016-02-04 11:20:30 +01:00
Shannon Deminick aa31e293ec Merge pull request #1086 from umbraco/temp-U4-7598
U4-7598 - fix migrations during 4.7 to 7.4 upgrade
2016-02-04 11:10:45 +01:00
Shannon f8045840ee Merge remote-tracking branch 'origin/master-v7' into dev-v7 2016-02-04 11:04:05 +01:00
Shannon e2985d74e5 U4-7890 XSLT Macro's not working - "Cannot use this obsoleted overload when the current provider" 2016-02-04 11:01:54 +01:00
Mads Rasmussen 7d15b26a8f Fixes: U4-7818 Moved Document Type Reverts to Prior Location on Save 2016-02-04 10:41:06 +01:00
Rune Strand a77ebb1160 Add max resolution for the Image editor in Grid Layouts to avoid performance hit when using high res images. 2016-02-04 10:25:01 +01:00
Claus 6a1e54b221 Fixes: U4-7691 - refactor 2016-02-03 15:39:18 +01:00
Shannon Deminick 864ca4e40e Merge pull request #1094 from umbraco/temp-U4-7691
Fixes: U4-7691 7.4 beta - Document composition is not working with me…
2016-02-03 15:26:43 +01:00
Claus 24d42e6bd1 Fixes: U4-7691 7.4 beta - Document composition is not working with media types
Media type compositions weren't getting added since it only looked up through the content type service.
2016-02-03 15:02:44 +01:00
bjarnef 6fc794ca2e Merge branch 'dev-v7' of https://github.com/bjarnef/Umbraco-CMS into dev-v7 2016-02-03 14:42:14 +01:00
Jon R. Humphrey 8b4d34a1e8 Update PackagingService.cs
I've made the changes to the code after running into the "sequence contains no matching element" error in my Starter Kit package install. We knew that there were no calls to .First()., .Last(), or .Single() in our code based on search results and checking for this call, however we were able to deduce that the issue was that we were including a new ImageCropper DataType without values based on Jeavon's [example:] [https://umbraco.com/follow-us/blog-archive/2014/5/30/developing-a-website-with-responsive-images-using-the-umbraco-v714-image-cropper/]

I know it's a simple fix but if it helps anyone else not run into the same thing then that's perfect!

Thank you for all your hard work on Umbraco, maybe someday I can do more!
2016-02-03 13:21:36 +00:00
Shannon 65c3f8c513 Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2016-02-03 14:16:38 +01:00
Shannon 1d326a76a3 fixes tab replace 2016-02-03 14:16:24 +01:00
Mads Rasmussen 625f976f14 Merge pull request #1088 from bjarnef/dev-v7-U4-6121
U4-6121 - Sorting in Related Links was not working correctly
2016-02-03 14:01:31 +01:00
Shannon 67c3ea7c00 Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2016-02-03 13:44:03 +01:00
Shannon 797eb34f36 Fixes merge issues and tests 2016-02-03 13:43:51 +01:00
Mads Rasmussen 5f2150ddf7 remove word-break from meta because it hides property alias 2016-02-03 13:28:23 +01:00
Claus c4981b50e5 Merge pull request #1092 from umbraco/temp-U4-7744
Fixes: U4-7744 Better validation message when Reordering tabs
2016-02-03 13:21:47 +01:00
Simon Busborg 00a7c97c5e Fixed background and word-break in member type builder 2016-02-03 13:13:56 +01:00
Simon Busborg eb7fa9528a Merge pull request #1081 from umbraco/temp-U4-7675
Fixes: U4-7675 Changing doc type icon doesn't set dirty property for form
2016-02-03 12:55:12 +01:00
Claus 27d2b631a9 Merge pull request #1080 from umbraco/temp-U4-7871
Fixes: U4-7871 Media picker - add functionality to go to media item w…
2016-02-03 12:51:08 +01:00
Claus bf1086ca39 Merge pull request #1089 from umbraco/temp-U4-7884
Fixes: U4-7884 Prevent new content type editor form from saving when hitting enter from inputs
2016-02-03 12:44:55 +01:00
Shannon e423864781 Merge remote-tracking branch 'origin/master-v7' into dev-v7
Conflicts:
	build/UmbracoVersion.txt
	src/SolutionInfo.cs
	src/Umbraco.Core/Cache/FullDataSetRepositoryCachePolicy.cs
	src/Umbraco.Core/Cache/FullDataSetRepositoryCachePolicyFactory.cs
	src/Umbraco.Core/Configuration/UmbracoVersion.cs
	src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs
	src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs
	src/Umbraco.Core/Persistence/Repositories/DomainRepository.cs
	src/Umbraco.Core/Persistence/Repositories/LanguageRepository.cs
	src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs
	src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs
	src/Umbraco.Core/Persistence/Repositories/PublicAccessRepository.cs
	src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs
	src/Umbraco.Core/Umbraco.Core.csproj
	src/Umbraco.Tests/Cache/FullDataSetCachePolicyTests.cs
	src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js
	src/Umbraco.Web.UI.Client/src/less/hacks.less
	src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
	src/Umbraco.Web/WebBootManager.cs
2016-02-03 12:30:11 +01:00
Shannon aed4649ff5 changes version to RC1 2016-02-03 12:16:07 +01:00
Shannon Deminick 36119848e7 Merge pull request #1085 from umbraco/temp-U4-7861
U4-7861 - fix moving a content type
2016-02-03 12:13:31 +01:00
Shannon Deminick 8080746004 Merge pull request #1091 from umbraco/temp-U4-7885
U4-7885 - fix YSOD when saving a member type
2016-02-03 11:59:24 +01:00
Mads Rasmussen edaa335b18 Fixes: U4-7744 Better validation message when Reordering tabs 2016-02-03 11:55:19 +01:00
Simon Busborg ae9fba87b5 Removed white background from member types builder 2016-02-03 11:46:33 +01:00
Claus 076efad616 Merge pull request #1084 from umbraco/temp-U4-7713
U4-7713 - fix CountPublished
2016-02-03 11:45:15 +01:00
Stephan df3aaf43d3 U4-7885 - fix YSOD when saving a member type 2016-02-03 11:33:34 +01:00
Shannon Deminick 75fe61f134 Removes TEMP removal
This can cause issues if the site is running
2016-02-03 11:30:06 +01:00
Shannon 5d5c6ed33a fixes ysod with media types and member types 2016-02-03 11:21:01 +01:00
Shannon d01bd5bd40 adjust install/uninstall 2016-02-03 11:07:20 +01:00
Shannon 03f88b3866 fixes uninstall 2016-02-03 11:05:27 +01:00
Shannon 78c2708116 U4-3447 Nuget package does not install correctly with "Web Site" projects 2016-02-03 10:39:53 +01:00
Mads Rasmussen e22c6d9c04 fix member types html indention 2016-02-03 10:16:39 +01:00
Shannon 08e9579481 U4-7863 Remove Nuget requirement: Microsoft.Net.Http - this is not used, nor is it required (it also installs a bunch of other packages we don't need) 2016-02-03 10:14:53 +01:00
Mads Rasmussen 61ba602b4b prevent enter submit in member types 2016-02-03 10:05:01 +01:00
Mads Rasmussen bd393dffd4 fix media types html indention 2016-02-03 09:59:08 +01:00
Mads Rasmussen 573890b7ce prevent enter submit in media types 2016-02-03 09:56:14 +01:00
Mads Rasmussen 7d4fbe4267 fix document type html indention 2016-02-03 09:50:59 +01:00
Mads Rasmussen cb978e2fee prevent enter submit in document type editor 2016-02-03 09:44:10 +01:00
bjarnef 4e75575b40 Sorting was not working correctly 2016-02-03 03:38:53 +01:00
bjarnef d7174146e3 Merge remote-tracking branch 'refs/remotes/umbraco/dev-v7' into dev-v7 2016-02-03 03:04:48 +01:00
Stephan 325f92f6ca U4-7598 - fix migrations during 4.7 to 7.4 upgrade 2016-02-02 18:53:08 +01:00
Shannon 856c345905 Merge branch '7.3.7' of https://github.com/umbraco/Umbraco-CMS into 7.3.7 2016-02-02 18:01:56 +01:00
Shannon b2cd5dfb85 adds null check to session id - might not exist in old cookies 2016-02-02 18:01:36 +01:00
Sebastiaan Janssen 462f7a59b5 Merge pull request #1078 from dawoe/U4-7872
Use product name in migration runner instead of Umbraco productname
2016-02-02 17:06:56 +01:00
Shannon 22689d24ec changes port 2016-02-02 17:05:21 +01:00
Shannon Deminick ee303957b8 Merge pull request #1078 from dawoe/U4-7872
Use product name in migration runner instead of Umbraco productname
2016-02-02 17:04:45 +01:00
Shannon 4055afdf05 Merge branch '7.3.7' of https://github.com/umbraco/Umbraco-CMS into 7.3.7 2016-02-02 16:52:08 +01:00
Shannon a1c70a219a ensures correct sort order for content type queries + test 2016-02-02 16:51:57 +01:00
Stephan 3f23b06e24 U4-7861 - fix moving a content type 2016-02-02 16:40:01 +01:00
Sebastiaan Janssen 3151515855 U4-7072 Grid TinyMce with style_formats throws "Cannot assign to read only property 'name' 2016-02-02 16:09:02 +01:00
Shannon 25df9da715 bumps Version 2016-02-02 16:00:28 +01:00
Shannon 9c2f438476 fixes tests 2016-02-02 15:43:44 +01:00
Simon Busborg a763602aeb Fixes: U4-7072 Grid TinyMce with style_formats throws "Cannot assign to read only property 'name' 2016-02-02 15:38:12 +01:00
Shannon 0de3be42cf U4-7869 Examine & SQL Azure - Timeouts - ensure the other reader is executed with retry. 2016-02-02 15:33:22 +01:00
Shannon 1545e0eed7 Merge branch '7.3.7' of https://github.com/umbraco/Umbraco-CMS into 7.3.7 2016-02-02 15:14:56 +01:00
Shannon 42a7ed6877 U4-7821 KeepUserLoggedIn with a long umbracoTimeOutInMinutes has logout issues 2016-02-02 15:14:47 +01:00
Sebastiaan Janssen 98b8aedc4d U4-7849 Unclear error message when applying public access 2016-02-02 15:13:57 +01:00
Simon Busborg 4812f1d603 Fixes: U4-7725 Backend / Full witdth image / Settings / Set a background image - Is out of focus. 2016-02-02 15:11:50 +01:00
Rune Strand 137de20cef Remove gradient from btnDanger 2016-02-02 14:30:57 +01:00
Rune Hem Strand 8ce8199820 Merge pull request #1072 from umbraco/temp-U4-7851
fixes U4-7851 Grid layout RTE formats not being applied.
2016-02-02 14:14:10 +01:00
Simon Busborg bb52467f90 Fixes: U4-7703 TinyMCE - can't add additional css via custom config (v7.3.4)
http://issues.umbraco.org/issue/U4-7703
2016-02-02 14:08:12 +01:00
Stephan 8791f7ee97 U4-7713 - fix CountPublished 2016-02-02 13:52:55 +01:00
Rune Strand e9af8bfee1 click in grid RTE format dropdown no longer looses focus from the editor 2016-02-02 13:37:52 +01:00
Shannon c7a2b54d1c Merge branch '7.3.7' of https://github.com/umbraco/Umbraco-CMS into 7.3.7 2016-02-02 12:13:03 +01:00
Shannon 6583ff4439 U4-7821 KeepUserLoggedIn with a long umbracoTimeOutInMinutes has logout issues 2016-02-02 12:12:51 +01:00
Sebastiaan Janssen 7b08b3e936 Merged branch 7.3.7 into 7.3.7 2016-02-02 11:55:40 +01:00
Sebastiaan Janssen bd2fc71dc5 U4-7276 When creating folders in the "Partials" view folder a YSOD appears (Umbraco 7.3 and 7.4) 2016-02-02 11:55:24 +01:00
Mads Rasmussen 4360d49531 fix file indention 2016-02-02 11:42:36 +01:00
Mads Rasmussen ae26a19d4a Fixes: U4-7675 Changing doc type icon doesn't set dirty property for form 2016-02-02 11:41:52 +01:00
Shannon 0af97f63e2 U4-7857 Flexible Load Balancing does not sync with the correct timeout threshold 2016-02-02 11:11:47 +01:00
Rune Strand da732359af Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2016-02-02 10:18:36 +01:00
Rune Strand c659e1ff8f Adds button states for hover, focus and active 2016-02-02 10:15:57 +01:00
Simon Busborg fd92884ce5 Merge pull request #1075 from webprofijt/U4-7687
Fixes: U4-7687 Create dialog briefly shows 'no allowed document types…
2016-02-02 08:54:50 +01:00
Shannon 1db635f24c Updates DeepCloneableList to support behaviors, for the FullDataSetCachePolicy we only want to clone when writing to cache, not when reading, the cloning will then be done on individual items after filtering by the FullDataSetRepositoryCachePolicy 2016-02-02 01:32:36 +01:00
Shannon 6e27b3d6d4 Fixes up the FullDataSetRepositoryCachePolicy to handle individual items, updates and removes correctly, splits up it's logic so it's not overriding the DefaultRepositoryCachePolicy since that is just different. Adds tests. 2016-02-02 00:47:18 +01:00
Shannon 1dea0edcf1 re-includes the static cache for published property types, this cache is much more than a simple cache of content type infos, it is also the cache for associated converters which is required for all front-end rendering. Fixes the issue of not setting the xpath cache level corectly. 2016-02-01 22:50:38 +01:00
Shannon 1abab41955 Fixes perf issue with DeepCloneHelper - so we cache the actual property types instead of re-reflecting each time 2016-02-01 21:45:34 +01:00
Mads Rasmussen b22ae28acc Fixes: U4-7871 Media picker - add functionality to go to media item when an image has been picked 2016-02-01 18:24:30 +01:00
Claus 2718d895fa Merge pull request #1079 from umbraco/temp-U4-7832
Fixes: U4-7832 double data bindings
2016-02-01 15:31:53 +01:00
Mads Rasmussen f4e6913e6e Fixes: U4-7832 double data bindings 2016-02-01 15:14:38 +01:00
Dave Woestenborghs 647fbea066 Use product name in migration runner instead of Umbraco productname
Fixes http://issues.umbraco.org/issue/U4-7872
2016-02-01 11:48:32 +01:00
Sebastiaan Janssen b69bd8617f Merged branch dev-v7 into dev-v7 2016-02-01 09:28:31 +01:00
Sebastiaan Janssen 924d2a0d88 U4-7669 Update Newtonsoft.Json dependency to v8.0.1 from v6.0.5
#U4-7669 Fixed
2016-02-01 09:28:20 +01:00
Claus 17fdc7d246 Merge pull request #1077 from abryukhov/patch-3
Update UI language ru.xml
2016-01-31 12:26:12 +01:00
Alexander Bryukhov 10fc60def3 Update UI language ru.xml
Based on keys added in 7.4 nightly build 155
2016-01-31 12:05:07 +06:00
AndyButland 1362df8e64 Provided means of setting which bulk actions are allowed on list views; only enable selection of multiple items in list view if at least one bulk action is available 2016-01-30 20:48:21 +01:00
Arnoud de Vries b6962296c3 Fixes: U4-7687 Create dialog briefly shows 'no allowed document types' text 2016-01-30 15:51:17 +01:00
Shannon cf022ca6a4 Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2016-01-28 19:35:20 +01:00
Shannon e2bf27e53f U4-7857 Flexible Load Balancing does not sync with the correct timeout threshold 2016-01-28 19:35:11 +01:00
Shannon d1be38be64 reverts profiler changes, we'll inlcude in 7.4 2016-01-28 18:37:56 +01:00
Shannon 8916c68a0c reverts profiler changes, we'll inlcude in 7.4 2016-01-28 18:35:29 +01:00
Shannon 6faa7e2fc9 dont' have RebuildOnAppStart set for dev purposes! 2016-01-28 18:31:47 +01:00
Claus db6f492aac Merge pull request #1056 from umbraco/temp-U4-7695
U4-7695 Media items are not updated when a new crop is added to Image…
2016-01-28 18:30:37 +01:00
Shannon a6093f41bd Fixes installer login for user and adds notes 2016-01-28 18:02:22 +01:00
Simon Busborg a1dcd2739b Merge branch 'abryukhov-patch-5' into dev-v7 2016-01-28 15:32:35 +01:00
Simon Busborg ef4bb3e341 Merge branch 'patch-5' of git://github.com/abryukhov/Umbraco-CMS into abryukhov-patch-5
# Conflicts:
#	src/Umbraco.Web.UI/umbraco/config/lang/ru.xml
2016-01-28 15:29:56 +01:00
Shannon Deminick 8c90e2fd58 Merge pull request #1066 from umbraco/temp-U4-7847
Fixes: U4-7847 Do not allow folders to be created underneath content types (or data types)
2016-01-28 15:22:03 +01:00
Shannon a1156472fb Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2016-01-28 15:16:37 +01:00
Shannon d526ff43f2 Merge branch 'temp-RepoCachePerf' into dev-v7 2016-01-28 15:16:02 +01:00
Simon Busborg dc6c15e150 Merge pull request #1058 from greystate/fix-querybuilder-button
U4-7842 Query Builder "Sort by" direction button changes case when clicked
2016-01-28 15:16:01 +01:00
Claus 0bc6b600a5 Merge pull request #1073 from umbraco/temp-U4-7806
Fixes: U4-7806 Possible to interactive with property editor "preview"…
2016-01-28 15:10:54 +01:00
Simon Busborg fb4cf18873 Merge pull request #1053 from abryukhov/patch-7
Latest update UI language ru.xml
2016-01-28 15:03:59 +01:00
Simon Busborg edd47814ee Merge pull request #1042 from abryukhov/patch-6
Update UI language ru.xml
2016-01-28 15:02:14 +01:00
Stephan 107e66e4da Merge pull request #1071 from umbraco/temp-U4-7682
U4-7682 Add option to DatabaseServerMessengerOptions to force a Cold …
2016-01-28 14:33:02 +01:00
Simon Busborg ec0a9493e2 removed whitespace issue 2016-01-28 14:25:40 +01:00
Mads Rasmussen 549a8380c3 Fixes: U4-7806 Possible to interactive with property editor "preview" in document type editor 2016-01-28 14:23:53 +01:00
Simon Busborg e0ba030b1f fixes U4-7851 Grid layout RTE formats not being applied. 2016-01-28 14:19:46 +01:00
Shannon 256849f8a6 adds nicer profiling during startup for app event handlers. 2016-01-28 14:19:38 +01:00
Stephan c9c451be65 U4-7682 Minor review adjustments 2016-01-28 14:19:32 +01:00
Shannon 1fcea083e7 Ensures no profiling occurs when not in debug mode 2016-01-28 14:10:13 +01:00
Shannon 85d6ee5713 Merge branch '7.3.6' of https://github.com/umbraco/Umbraco-CMS into 7.3.6 2016-01-28 13:50:55 +01:00
Shannon ec81583741 Fixes case sensitive matching on alias in TemplateRepository 2016-01-28 13:50:45 +01:00
Sebastiaan Janssen 332da9bf2d Merge pull request #1070 from umbraco/temp-RepoCachePerf736
Temp repo cache perf736
2016-01-28 12:15:24 +01:00
Shannon a0036d925e U4-7682 Add option to DatabaseServerMessengerOptions to force a Cold Boot if there are too many instructions 2016-01-28 12:14:30 +01:00
Shannon 81a99d6f7d adds null check and ensures that SetInternalRedirectPublishedContent cannot be called with a null result 2016-01-28 10:19:51 +01:00
Shannon e912238574 Saw there was another place with the incorrect case for the column name AllowedId 2016-01-28 09:32:01 +01:00
Shannon Deminick 2d17603703 Merge pull request #1068 from glennweb/dev-v7
Incorrect case for column AllowedId in select query.
2016-01-28 09:30:37 +01:00
glennweb 5d3e580cda Saw there was another place with the incorrect case for the column name AllowedId 2016-01-28 15:12:14 +10:00
glennweb 93aadc196f Fixed incorrect case property in select statement causing case sensitive database's to throw error.
https://our.umbraco.org/forum/core/general/49619-Went-wrong-in-a-moment-Invalid-column-name
2016-01-28 15:07:18 +10:00
Shannon 9a830e5de6 fixes tests 2016-01-27 19:44:36 +01:00
Shannon 5f43b360ec Merge remote-tracking branch 'origin/dev-v7' into temp-RepoCachePerf 2016-01-27 19:44:04 +01:00
Shannon 7d9ba0e36e manually backports changes from 7.4 fixes 2016-01-27 19:42:06 +01:00
Shannon 6c5e09fd84 Ensures that the main content type repositories are returning the correct result from their GetAll methods. Fixes the FullDataSetRepositoryCachePolicy to ensure that any request with Ids actually returns the result of GetAll and then filters to ensure caching is correct. 2016-01-27 19:26:08 +01:00
Shannon 5d96534678 fixes tests 2016-01-27 19:20:24 +01:00
bjarnef 5a2ebec473 Merge remote-tracking branch 'refs/remotes/umbraco/dev-v7' into dev-v7 2016-01-27 18:55:38 +01:00
Shannon 0cefdcbc20 Fixes ContentTypeBaseRepository - there were several hack in place to query by GUID but this is totally irrelavent because we are caching them all so the result should be from the GetAll(), so this removes all of those hacks which greatly simplifies things. This fixes the MapContentTypes and MapMediaTypes methods - before this was looking up a collection and then recursing back to Get(int) (but we already have all of the data we need), then it was storing a lot of arrays in memory to build up an Entity when it's much faster to just iterate forward only and build up the entity. This saves 5 SQL calls on startup. 2016-01-27 18:55:10 +01:00
Shannon 02b74a5059 Fixes FullDataSetRepositoryCachePolicy so that whenever Ids are requested, it retrieves all of the items and then post filters - ensuring there's no additional trips to the database. Fixes MemberTypeRepository so that calls to PerformGet(int) are wrapping the GetAll() call. 2016-01-27 18:51:37 +01:00
Sebastiaan Janssen 2913a0f624 With only LineFeeds then...? 2016-01-27 17:15:30 +01:00
Sebastiaan Janssen 1c58360891 Another attempt at fixing unit tests 2016-01-27 15:47:37 +01:00
Shannon 49fc068b38 Merge remote-tracking branch 'origin/7.3.6' into dev-v7
Conflicts:
	build/UmbracoVersion.txt
	src/SolutionInfo.cs
	src/Umbraco.Core/Configuration/UmbracoVersion.cs
	src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs
	src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs
	src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs
	src/Umbraco.Core/Persistence/Repositories/Interfaces/IMediaTypeRepository.cs
	src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs
	src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs
	src/Umbraco.Core/Umbraco.Core.csproj
	src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
	src/Umbraco.Web/UmbracoContext.cs
2016-01-27 15:42:06 +01:00
Mads Rasmussen b671595608 fix tab indention 2016-01-27 15:34:15 +01:00
Mads Rasmussen 4bc51feccd fix semicolons 2016-01-27 15:31:29 +01:00
Sebastiaan Janssen 1d5696a08b Merged branch dev-v7 into dev-v7 2016-01-27 15:30:54 +01:00
Sebastiaan Janssen bd2b6e0f93 Should hopefully fix unit tests 2016-01-27 15:30:34 +01:00
Mads Rasmussen 98c65ff8f4 U4-7847 Do not allow folders to be created underneath content types (or data types) 2016-01-27 15:29:53 +01:00
Shannon 3addffbd34 Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2016-01-27 15:23:10 +01:00
Shannon dbb7e3825d Fixes events for containers 2016-01-27 15:22:58 +01:00
Claus 1d1dd87d44 Merge pull request #1059 from umbraco/temp-U4-7832-U4-7772
Fixes: U4-7772 Cursor jumps when editing alias in new ContentType edi…
2016-01-27 15:12:23 +01:00
Simon Busborg 592ccd29e3 Merge pull request #1065 from umbraco/temp-U4-7846
Fixes: U4-7846 Media grid missing min-height on item + make media item sizes as attr so they can be set outside the directive
2016-01-27 15:01:24 +01:00
Shannon 0ea9ce1363 Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2016-01-27 14:31:12 +01:00
Shannon cc4c7b0d88 Adds events for creating/deleting containers 2016-01-27 14:30:57 +01:00
Claus 800df325a9 Merge pull request #1063 from umbraco/temp-U4-2670
U4-2670 Add event to modify the model before being sent to render
2016-01-27 14:30:40 +01:00
Mads Rasmussen 1c04aa377c fix tab indention 2016-01-27 14:21:27 +01:00
Simon Busborg 1f1aeaf446 Merge pull request #1064 from umbraco/temp-U4-7845
Fixes: U4-7845 Show drop zone in media section + fix recycle bin for …
2016-01-27 14:19:22 +01:00
Mads Rasmussen 38e9193573 Fixes: U4-7846 Media grid missing min-height on item + make media item sizes as attr so they can be set outside the directive 2016-01-27 14:18:53 +01:00
Shannon Deminick 409d6dd71c Merge pull request #1062 from umbraco/temp-U4-7844
U4-7844 - Add support for models in controllers
2016-01-27 13:54:45 +01:00
Mads Rasmussen 9c5d5f4318 Fixes: U4-7845 Show drop zone in media section + fix recycle bin for content section + localise texts 2016-01-27 13:25:54 +01:00
Shannon e8dfa056b0 U4-2670 Add event to modify the model before being sent to render 2016-01-27 13:20:13 +01:00
Stephan 81754b37a4 Add support for models in controllers 2016-01-27 12:05:22 +01:00
bjarnef 02e5056987 Change value of vertical-align property. 2016-01-27 09:36:25 +01:00
Claus c33b488006 Ensuring we only do the base SetupNode stuff if its actually a media type and not a folder requested. 2016-01-27 09:27:56 +01:00
Mads Rasmussen 43e49b75de Add extra div to media grid to fix firefox issue in chrome 2016-01-27 09:21:58 +01:00
Simon Busborg e050090f0f Merge pull request #1061 from bjarnef/dev-v7-tinymce-config-indent
Indent of toolbar options in TinyMCE config
2016-01-27 09:15:34 +01:00
bjarnef 5e88fbfad0 Indent of toolbar options in TinyMCE config 2016-01-26 23:52:16 +01:00
Mads Rasmussen c9f71ce067 Fixes: U4-7772 Cursor jumps when editing alias in new ContentType editor + U4-7832 Editing property alias chomps 1st character 2016-01-26 21:07:15 +01:00
Chriztian Steinmeier 21190bc0c6 Change the initial wording of the sort-direction button
Keep it lowercased as that's what it actually toggles between when
clicked
2016-01-26 19:36:12 +01:00
Sebastiaan Janssen 2f8c43c689 Merge pull request #1057 from umbraco/temp-U4-7836
U4-7836 YSOD when upgrading Umbraco with error during AddUserDataClaims
2016-01-26 19:25:04 +01:00
Shannon 7a25cb52b2 updates the repository cache policies so that we aren't keeping everything in cache unnecessarily 2016-01-26 19:13:42 +01:00
Shannon 19bc97a7fd Removes the static (hack) cache for content types for creating published content 2016-01-26 18:56:29 +01:00
bjarnef df958223b0 Merge remote-tracking branch 'refs/remotes/umbraco/dev-v7' into dev-v7 2016-01-26 18:17:00 +01:00
Shannon 72900ef3b3 U4-7813 Enable MiniProfiler to profiler during startup
Conflicts:
	src/Umbraco.Core/Umbraco.Core.csproj
2016-01-26 17:56:25 +01:00
Shannon 74ddd09c5d U4-7836 YSOD when upgrading Umbraco with error during AddUserDataClaims - this also ensures that no empty/null sections can be added to the user object since this is where the original exception was coming from. 2016-01-26 17:05:46 +01:00
Mads Rasmussen fd58c3b3c6 Fixes: U4-7815 List view - bug when custom list view has been created. 2016-01-26 16:09:48 +01:00
Sebastiaan Janssen e461cb92da U4-7787 Shorthand use of ?altTemplate= doesn't work
#U4-7787 Fixed
2016-01-26 16:07:44 +01:00
Shannon ba2fd96e88 U4-7695 Media items are not updated when a new crop is added to Image Cropper 2016-01-26 15:54:17 +01:00
Shannon 7cdaacf149 adds assert 2016-01-26 14:26:16 +01:00
Shannon 7cfdc81555 Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2016-01-26 14:24:18 +01:00
Shannon aeb6babad0 fixes template unit tests 2016-01-26 14:24:07 +01:00
Simon Busborg 24f38e0c0e Fixed illustration width in safari 2016-01-26 14:18:07 +01:00
Simon Busborg 8cb9d6858e U4-7722 Show checkmark when hover image in media grid 2016-01-26 14:18:06 +01:00
Claus 17629ea1b5 Merge pull request #1055 from umbraco/temp-U4-7698
Ensures that all property data is deleted for a doc type when it is b…
2016-01-26 14:13:46 +01:00
Shannon 779e7d7667 fixes ContentTypeRepositoryTest 2016-01-26 13:46:55 +01:00
Shannon 7117c6f085 Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2016-01-26 13:44:05 +01:00
Shannon ba9ebd394b fixes MediaTypeRepositoryTest's 2016-01-26 13:43:56 +01:00
Simon Busborg 3ed340bde1 Fixes weird skew in media grid 2016-01-26 13:29:39 +01:00
Shannon 7d616cf937 Ensures that all property data is deleted for a doc type when it is being deleted, updates the ChangeDocType to not use the legacy EnsuredPage, updates the non-legacy EnsuredPage.ClientTools to support the legacy logic. 2016-01-26 12:13:53 +01:00
Mads Rasmussen fa1c227136 U4-7724 Click on remove file(s) link, on an item in the media section, doesn't set dirty for form 2016-01-26 12:01:04 +01:00
bjarnef 738f24d6c9 Hide search input behind split slider
Ensure search input is covered by the split slider, when it is dragged
all the way to the left similar to how tree nodes is covered.
2016-01-26 11:38:04 +01:00
Shannon c33ad3eed7 U4-7825 Remove Microsoft.AspNet.WebHelpers and Microsoft.AspNet.WebPages.Data dependencies from nuget 2016-01-26 11:31:35 +01:00
Shannon Deminick 3e5050ee9a Merge pull request #1054 from umbraco/temp-U4-7701
Fixes: U4-7701 Unable to Delete Member in Member Section
2016-01-26 11:26:33 +01:00
Shannon Deminick 7dce1ee39a Merge pull request #1052 from umbraco/temp-U4-7642
U4-7642 - bugfix aggressive refactoring
2016-01-26 11:11:33 +01:00
Mads Rasmussen f30c05b37f add/remove semicolons 2016-01-26 10:47:36 +01:00
Mads Rasmussen 7fce8583c8 Fixes: U4-7701 Unable to Delete Member in Member Section 2016-01-26 10:34:31 +01:00
Alexander Bryukhov 3a17dd06d8 Latest update UI language ru.xml
Only two new keys in the "sort" section translated. For full merged ru.xml file merge there are two more PRs (#1042 & #983)
2016-01-26 12:44:39 +06:00
Stephan 9d10362e7a U4-7642 - bugfix aggressive refactoring 2016-01-25 18:17:48 +01:00
Shannon 3712a80031 fixes composition check in change doc type 2016-01-25 16:43:20 +01:00
Shannon Deminick 930bada737 Merge pull request #1043 from umbraco/temp-U4-7716
U4-7716 Content type editor - YSOD when adding a property with the sa…
2016-01-25 16:08:07 +01:00
Shannon 95eb5f88f3 fixes merge issues 2016-01-25 16:07:57 +01:00
Shannon 56f0d67639 Merge branch 'dev-v7' into temp-U4-7716
Conflicts:
	src/Umbraco.Web/Editors/ContentTypeControllerBase.cs
2016-01-25 15:54:50 +01:00
bjarnef 0be5c31d4a Adjust styling for sort table + localize 2016-01-25 15:31:07 +01:00
Simon Busborg ca03967662 U4-7644 Misleading description of choosing package file
has to have correction
2016-01-25 15:24:11 +01:00
Simon Busborg 91413c2a89 U4-7644 Misleading description of choosing package file
I'm not a multi language talent, so I've taken the liberty only to correct the danish and english version. since `.umb`doesn't exists anymore, I've deleted that extension from the sentence.
2016-01-25 15:18:26 +01:00
Claus bd109d3700 Merge branch 'bjarnef-dev-v7-resizable-handle-border' into dev-v7 2016-01-25 15:10:29 +01:00
bjarnef d9de5e5f29 Remove top and bottom border for resizable handle 2016-01-25 15:09:50 +01:00
Claus 63635ec9fb Merge branch 'cyfer13-dev-v7' into dev-v7
Edited: No need to convert to string before passing on the value.
2016-01-25 14:11:00 +01:00
Claus d32380294a Merge branch 'dev-v7' of https://github.com/cyfer13/Umbraco-CMS into cyfer13-dev-v7 2016-01-25 13:53:01 +01:00
Shannon 8ea6f1168e Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2016-01-25 12:26:53 +01:00
Shannon 7595da7645 adds a null check 2016-01-25 12:26:11 +01:00
Mads Rasmussen f33af2930e Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2016-01-25 12:18:29 +01:00
Mads Rasmussen 08cfececd9 Fixes: U4-7824 Remove media section dropzone and folders in recycle bin 2016-01-25 12:17:26 +01:00
Shannon 1aab6c217f Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2016-01-25 12:11:10 +01:00
Shannon 396194ae01 bumps MB nuget version 2016-01-25 12:10:40 +01:00
Mads Rasmussen baea34b6a4 Merge pull request #1051 from umbraco/temp-U4-7820
Fixes: U4-7820 List view card layout can not go to item
2016-01-25 11:32:27 +01:00
Shannon Deminick 742ee57835 Merge pull request #1049 from umbraco/temp-U4-7700
Fixes: U4-7700 7.4 beta Backoffice Routing problem for Custom Sections or Installed Packages with a custom section
2016-01-25 11:19:46 +01:00
Shannon 2e4941053c more null checks 2016-01-25 11:19:18 +01:00
Shannon 1118d95773 added a null check 2016-01-25 11:14:06 +01:00
Mads Rasmussen e91b53e66d back ported: https://github.com/Umbraco/Umbraco-CMS/commit/2d0f198f58071f5113d5c3437f10f2b85220c348 2016-01-25 11:09:20 +01:00
Mads Rasmussen f981fe60ff Fixes: U4-7820 List view card layout can not go to item 2016-01-25 10:30:13 +01:00
bjarnef 1217d9f0b3 Merge remote-tracking branch 'refs/remotes/umbraco/dev-v7' into dev-v7 2016-01-24 23:25:29 +01:00
Claus bbb187f2c8 Merge pull request #1044 from umbraco/temp-U4-7783
U4-7783 Member can edit / show on profile don't exist any more in 7.4.0
2016-01-24 22:19:01 +01:00
Claus 10617d1bd5 Agree, these should not be needed - removing. 2016-01-24 22:18:18 +01:00
Claus 7ac1c8ab6f forgot a few console.log's. 2016-01-24 15:43:43 +01:00
Claus 4372c9df40 remove refs. 2016-01-24 15:40:23 +01:00
Claus c4e8e20f02 Reverted to only update exactly what is needed for this to work.
Switched away from ugly xpath - using linq.
2016-01-24 15:36:29 +01:00
Chad Rosenthal 09d038fcde U4-4652 - added decimal/double to contentbase 2016-01-23 21:32:08 -07:00
Shannon b5e8cb29dd ensure appctx and security isn't nulled on disposal (it's an application singleton it doesn't need to be nulled), creates new CreateContext method for creating standalone UmbracoContext instances. 2016-01-23 12:38:08 +01:00
Shannon 20dc4f5bc4 fixes merge issue/build 2016-01-23 12:27:40 +01:00
bjarnef 1301897f39 Merge remote-tracking branch 'refs/remotes/umbraco/dev-v7' into dev-v7 2016-01-22 22:02:51 +01:00
Shannon 2c399860ca Fixes DisposableTimer so that the profiled step is disposed - and thus tracked/timed properly! 2016-01-22 17:27:46 +01:00
Shannon c7185dcef0 Fixes DisposableTimer so that the profiled step is disposed - and thus tracked/timed properly! 2016-01-22 17:27:27 +01:00
Shannon 5ab61e7638 U4-7816 The IsolatedCache instance in the RepositoryFactory differs from the ApplicationContext singleton instance 2016-01-22 17:09:44 +01:00
Shannon 4dc4c36581 U4-7811 Content type repositories should use FullDataSetRepositoryCachePolicyFactory for performance
Conflicts:
	src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs
	src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs
	src/Umbraco.Core/Persistence/Repositories/Interfaces/IMediaTypeRepository.cs
	src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs
2016-01-22 17:08:21 +01:00
Shannon fe774f557c Fixes ms value: U4-7810 DatabaseServerRegistrar should not execute as soon as a request is made, this slows down app start 2016-01-22 17:06:14 +01:00
Shannon 3ecb9d0f86 U4-7807 Domain, language, public access cache (GetAll) caches not working when there are no items 2016-01-22 17:05:27 +01:00
Shannon f78a425985 U4-7816 The IsolatedCache instance in the RepositoryFactory differs from the ApplicationContext singleton instance 2016-01-22 16:37:47 +01:00
Claus 291d92bfc9 Fixes: U4-7700 7.4 beta Backoffice Routing problem for Custom Sections or Installed Packages with a custom section
Reverting the lowercasing happening in the angular routing and navigation.
Ensuring tree section registrations are updated instead of added in trees.config. The lowercasing was introduced to compensate for this.
2016-01-22 13:38:43 +01:00
Shannon ffce67e4fd nuget update 2016-01-22 13:34:16 +01:00
Shannon 4f85985a09 updates mb nuget 2016-01-22 12:45:57 +01:00
Shannon Deminick 5efbec1a2e Merge pull request #1046 from umbraco/temp-U4-7739
U4-7739 - added more options to ViewHelper.GetDefaultFileContent
2016-01-22 12:38:03 +01:00
Shannon 4bb6b2e230 Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2016-01-22 12:26:04 +01:00
Shannon c365b1569b updates to latest myget MB package 2016-01-22 12:25:39 +01:00
Mads Rasmussen b38edd1921 Merge pull request #1040 from umbraco/temp-U4-7707
U4-7707 Can't unassign assigned composition from content type until i…
2016-01-22 12:13:04 +01:00
Shannon dfa45e70f4 Fixes ms value: U4-7810 DatabaseServerRegistrar should not execute as soon as a request is made, this slows down app start 2016-01-22 12:11:32 +01:00
Shannon 1f29d85f83 U4-7813 Enable MiniProfiler to profiler during startup 2016-01-22 11:46:10 +01:00
Stephan 2a6b559b6e U4-7739 - added more options to ViewHelper.GetDefaultFileContent 2016-01-22 10:41:54 +01:00
bjarnef 6d34fe416d Merge remote-tracking branch 'refs/remotes/umbraco/dev-v7' into dev-v7 2016-01-21 20:38:52 +01:00
Shannon c7805f0af1 Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2016-01-21 19:33:55 +01:00
Shannon 07d50464cc U4-7811 Content type repositories should use FullDataSetRepositoryCachePolicyFactory for performance 2016-01-21 19:33:47 +01:00
Mads Rasmussen 8373955bf0 Auto focus folder name when creating folders in document types 2016-01-21 19:11:43 +01:00
Mads Rasmussen ca5f317a90 Fixes: U4-7797 Remove context-menu divider when there only is one action 2016-01-21 19:10:29 +01:00
Shannon d86db6b2cd U4-7810 DatabaseServerRegistrar should not execute as soon as a request is made, this slows down app start 2016-01-21 18:36:04 +01:00
bjarnef a884ece8b1 Merge remote-tracking branch 'refs/remotes/umbraco/dev-v7' into dev-v7 2016-01-21 18:15:50 +01:00
Shannon b15f0a9c54 U4-7807 Domain, language, public access cache (GetAll) caches not working when there are no items 2016-01-21 17:46:47 +01:00
Shannon 48667bb50a fixes more mapping, adds more tests. 2016-01-21 16:25:19 +01:00
Shannon ad5043295f cleans up more mappings, adds unit tests 2016-01-21 15:59:58 +01:00
Shannon 0c0518ff7b ensures that abstract models have a DataContract 2016-01-21 15:06:57 +01:00
Shannon 52b1a09de0 abstracts out the DocumentType, MemberType and MediaType editor models, since some contain different props than each other and now member properties contain different properties than each other. So we have a lot of generic insanity going on... it works though. 2016-01-21 15:01:55 +01:00
Sebastiaan Janssen e456761bb9 Merge pull request #1039 from ig-ealbert/japanesev7-2
Added translations and removed unused entries
2016-01-21 13:06:46 +01:00
Mads Rasmussen be1b770df8 Fixes: U4-7665 When adding tab without save and remove it again "Add another tab" should be shown again 2016-01-21 12:00:29 +01:00
Shannon a8e43a3908 U4-7716 Content type editor - YSOD when adding a property with the same alias as it's parent 2016-01-21 11:39:46 +01:00
Alexander Bryukhov 47ea3828a1 Update UI language ru.xml
According the latest keyas added/updated in 7.4 beta2
2016-01-21 13:36:37 +06:00
Mads Rasmussen 504235d6db add memberCanEdit and showOnMemberProfile to property settings overlay in member types 2016-01-20 21:30:12 +01:00
bjarnef 0ffcc9b889 Merge remote-tracking branch 'refs/remotes/umbraco/dev-v7' into dev-v7 2016-01-20 19:21:58 +01:00
Shannon 177e61834c U4-7707 Can't unassign assigned composition from content type until it has been saved 2016-01-20 18:52:05 +01:00
Shannon 2d0f198f58 U4-7546 Cannot delete document type - fanoe starter kit Text Page 2016-01-20 18:26:30 +01:00
Shannon 6ad568c81a changes config template with new MB config option 2016-01-20 18:18:33 +01:00
ig-ealbert 25dd891938 Added translations and removed unused entries 2016-01-20 12:10:02 -05:00
Shannon Deminick 2ef673bc84 Merge pull request #1038 from umbraco/temp-U4-7768
U4-7768 - Fixes validation issue with new CTs and invalid server side…
2016-01-20 18:08:58 +01:00
Shannon adc3c1e927 updates to latest MB 2016-01-20 18:08:34 +01:00
Shannon e2eaf7d58e Updates how the editor validators work 2016-01-20 17:42:09 +01:00
Shannon 38a6f8c4a9 creates new EditorValidationResolver for external validators to work (internal for now), bumps version 2016-01-20 16:57:31 +01:00
Shannon 8fc44699bc U4-7768 - Fixes validation issue with new CTs and invalid server side validation, adds validation check for all ct aliases across all types 2016-01-20 16:07:47 +01:00
Sebastiaan Janssen 277b67ac84 Merge pull request #1029 from umbraco/temp-U4-7557
U4-7557 Support folders for import/export, packaging
2016-01-20 15:45:21 +01:00
Shannon fda3111e43 fixes nuget dll ref 2016-01-20 15:24:57 +01:00
Shannon 5c2bd5748d Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7
Conflicts:
	build/NuSpecs/UmbracoCms.Core.nuspec
2016-01-20 15:02:12 +01:00
Sebastiaan Janssen 348bee885e Finish last bit for U4-7683 2016-01-20 15:01:25 +01:00
Shannon dd5523de42 updates package dependency for MB 2016-01-20 14:55:56 +01:00
Shannon 4bb9dfb4c9 Ensure that the raw ct alias is passed in with additionaldata 2016-01-20 14:47:32 +01:00
Sebastiaan Janssen 5440353fb3 Merge pull request #1031 from umbraco/temp-U4-7683
Fixes: U4-7683 Search on Property Editors/Data Types in new Content Type Editor should display two results - resuse / available
2016-01-20 14:37:15 +01:00
Sebastiaan Janssen 9f365727e0 Bumps version 2016-01-20 14:10:31 +01:00
Sebastiaan Janssen df3e96e86a Merge remote-tracking branch 'origin/7.3.6' into dev-v7
# Conflicts:
#	build/NuSpecs/UmbracoCms.Core.nuspec
2016-01-20 14:09:40 +01:00
Sebastiaan Janssen 74d73cfe94 U4-7796 Get UrlRewritingNet from the official NuGet location
#U4-7796 Fixed
2016-01-20 13:57:35 +01:00
Shannon 1fd76731cd fixes merge issue, updates MB 2016-01-20 13:54:16 +01:00
Shannon 4e1e240f54 Merge remote-tracking branch 'origin/dev-v7' into temp-U4-7747
Conflicts:
	src/Umbraco.Web.UI.Client/src/views/documenttypes/edit.controller.js
2016-01-20 13:38:17 +01:00
Shannon 85207b3d5c removes MB dependencies from Umbraco.Web proj, we don't want circular references and this is not required since MB can take care of injecting the server vars. 2016-01-20 13:37:47 +01:00
Shannon 8b80a22018 Merge branch 'temp-U4-7748' into temp-U4-7747 2016-01-20 13:32:40 +01:00
Shannon 9c58e82169 publicized required method for externally setting template markup, removes logic from core for this 2016-01-20 12:47:09 +01:00
Shannon 42fbcb6f41 Bumps version so that the MB core can reference updated code 2016-01-20 11:45:33 +01:00
Shannon 2571e5c683 Moves MB nuget reference to UmbracoCms nuget package - otherwise we have a circular nuget reference! 2016-01-20 11:40:53 +01:00
Mads Rasmussen c16aa5bbf0 Fixes: U4-7745 7.4 Property Editor & Keyboard Shortcuts 2016-01-20 11:35:46 +01:00
Sebastiaan Janssen dad0cf20eb Merge pull request #1035 from ig-ealbert/japanesev7
Added translations for v7 only entries
2016-01-20 11:23:01 +01:00
Shannon fe563b0828 adds AdditionalData to the event args so we can use that to check for specific keys/values when consuming events and maintain compatibility. 2016-01-20 11:19:04 +01:00
Sebastiaan Janssen 9e8821594a Merge remote-tracking branch 'origin/7.3.6' into dev-v7 2016-01-20 10:55:24 +01:00
Sebastiaan Janssen 7fb9d430a9 changes default upload limit to 50 mb 2016-01-20 10:54:43 +01:00
Shannon 76dd7f8909 changes default upload limit to 50 mb 2016-01-20 10:48:10 +01:00
Sebastiaan Janssen 7cd8ba13c0 U4-7781 Setting a user's start node causes YSOD
#U4-7781 Fixed
2016-01-20 10:45:40 +01:00
Shannon 9a0e85af10 Creates new CreateTemplateForContentType for use with the content type editor, I need to somehow add some additional information to the event raised there so that we can listen to that event in MB in order to create the default template markup. 2016-01-19 21:38:11 +01:00
bjarnef ee3131b63d Merge remote-tracking branch 'refs/remotes/umbraco/dev-v7' into dev-v7 2016-01-19 21:03:42 +01:00
ig-ealbert 00aed2b33d Added translations for v7 only entries 2016-01-19 14:58:48 -05:00
bjarnef 4fd7182388 Merge remote-tracking branch 'refs/remotes/umbraco/dev-v7' into dev-v7 2016-01-19 20:56:36 +01:00
Shannon 173f3cb32a ensures the default language has the correct build models translation 2016-01-19 19:58:48 +01:00
Shannon d0df31be8b Ensures the build models buttons work and are enabled for content types, media types and member types 2016-01-19 19:57:38 +01:00
Shannon e857b0a5f4 Updates the strange TypeFinder GetTypeByName method to use BuildManager by default. 2016-01-19 15:58:38 +01:00
Simon Busborg e5f5e16f9a Added ng-cloak to fix flickeren in http://issues.umbraco.org/issue/U4-7762
Fixes flickering in U4-7762 Move document or media briefly show error- and success placeholders + odd position of checkmark at root level
2016-01-19 15:17:39 +01:00
Simon Busborg e51ef64b66 Fixes: U4-7770 List view icon on content node not displayed properly 2016-01-19 14:54:37 +01:00
Simon Busborg 76ff12f681 Fixes: U4-7762 Move document or media briefly show error- and success placeholders + odd position of checkmark at root level 2016-01-19 14:54:37 +01:00
Shannon 068a08cfcd Merge remote-tracking branch 'origin/dev-v7' into temp-U4-7748 2016-01-19 14:48:36 +01:00
Shannon Deminick 329636abab Merge pull request #1032 from umbraco/temp-U4-7775
Fixes: U4-7775 Ctrl + S doesn't work in new document type editor
2016-01-19 14:47:11 +01:00
Shannon caef155805 U4-7748 Models Builder - needs to be in control of the models-out-of-date status 2016-01-19 14:46:19 +01:00
Mads Rasmussen ff876266cf Fixes: U4-7775 Ctrl + S doesn't work in new document type editor 2016-01-19 13:50:50 +01:00
Stephan 9f360c2b9b Fix test broken by PR #1027 2016-01-19 12:52:43 +01:00
Sebastiaan Janssen 0621019918 Adds .models extension for the zip release 2016-01-19 12:31:22 +01:00
Mads Rasmussen 28aa928655 add loader to overlay 2016-01-19 12:29:14 +01:00
Simon Busborg cff6a74f16 Merge pull request #1030 from umbraco/temp-U4-7524
Fixes: U4-7524 Markdown editor - doesn't save content changes after using buttons.
2016-01-19 12:21:13 +01:00
Simon Busborg 853bd3947b Merge branch 'markdowneditor-fix' of git://github.com/pynej/Umbraco-CMS into pynej-markdowneditor-fix
# Conflicts:
#	src/Umbraco.Web.UI.Client/src/views/propertyeditors/markdowneditor/markdowneditor.controller.js
2016-01-19 12:18:24 +01:00
Mads Rasmussen 9ea492f5b7 Fix tab indent 2016-01-19 11:51:49 +01:00
Mads Rasmussen 05044dc871 Fixes: U4-7683 Search on Property Editors/Data Types in new Content Type Editor should display two results - resuse / available 2016-01-19 11:49:52 +01:00
Shannon Deminick 19fae702a9 Merge pull request #1027 from umbraco/temp-u4-7754
U4-7754 - fix UmbracoViewPage with models
2016-01-19 11:18:51 +01:00
Sebastiaan Janssen 994ded8518 Merge remote-tracking branch 'origin/7.3.6' into dev-v7
# Conflicts:
#	build/NuSpecs/UmbracoCms.Core.nuspec
#	src/Umbraco.Web.UI/packages.config
2016-01-19 11:10:18 +01:00
Sebastiaan Janssen 1888888650 Update ImageProcessor, this time also in the nuspec file 2016-01-19 11:07:17 +01:00
Shannon db26eac99b Merge remote-tracking branch 'origin/dev-v7' into temp-U4-7557 2016-01-19 11:00:00 +01:00
Stephan a1b98b6e31 U4-7754 - fix UmbracoViewPage with models 2016-01-18 17:35:26 +01:00
Chris Perks 698617dc60 Added mock for externalLoginInfo, and dependency references required to run 'dev' Grunt task 2016-01-18 14:41:35 +00:00
Simon Busborg a6b7e26606 Fixes U4-7761 Typo on Allowed Templates label 2016-01-18 12:58:34 +01:00
Mads Rasmussen 2074df58fb Fixes: U4-7765 disable folder select + only allow images in grid image picker 2016-01-18 12:02:41 +01:00
Mads Rasmussen e6ab111f4d Fixes: U4-7676 Don't show "Reorder" link in initial row-view for grid 2016-01-18 11:29:23 +01:00
Simon Busborg c9936da37f Fixes U4-7759 Imagepicker setting in Grid broken in 7.4-beta2 2016-01-18 10:10:03 +01:00
Shannon 4ce4bd25c4 Fixes package installer and export - doesn't import any folders for child doc types, doesn't export folders for child doc types, ensures that parent doc types are added as compositions (this was never working) and changed the list<string> to hashset<string> so it's always unique. 2016-01-15 11:07:21 +01:00
Shannon ce3028446b Moves all serialization logic, including the part for folders into the EntityXmlSerializer where it needs to be, updates the data type repo to ensure paths are udpated correctly when moving, removes folder logic from other packaging logic, it's purely the responsibility of the serializer. adds new methods to content type and data type services to return an entities total folder collection. 2016-01-14 19:33:53 +01:00
Shannon 73f1458190 Fixes the Move content type command to ensure that all paths are updated correctly. 2016-01-14 18:25:14 +01:00
Shannon 684788cb62 Merge remote-tracking branch 'origin/dev-v7' into temp-U4-7557 2016-01-14 18:12:09 +01:00
Alexander Bryukhov 6a1b8f00eb Correcing one key translation 2015-12-28 23:47:28 +06:00
Alexander Bryukhov 4574e4291b Missed keys 2015-12-28 23:45:15 +06:00
Alexander Bryukhov aae15bf0b4 ru.xml - UI lang file
Added / updated keys for 7.4
2015-12-28 23:40:15 +06:00
Alexander Bryukhov ae85b7bf2b Nodes sort dialog - adding date formats
Adding dates processing for 'dd.MM.yyyy' formats
2015-12-28 23:00:08 +06:00
Jeremy Pyne 9dbdae3b90 Added Markdown package and code to MarkdownEditorValueConverter to automatically convert the markdown text to Html when rendered in the front end. 2015-12-22 11:49:13 -05:00
Jeremy Pyne 9649e6d9bf Add code to manually update the model. 2015-12-22 11:17:53 -05:00
Jeremy Pyne 0d7363af23 Fix for MarkdownEditor no seeing changes from button clicks. 2015-12-22 10:47:04 -05:00
AndyButland b52c480da3 Added IPublishedContent extension method for filtering nodes based on composition alias
Created unit test for IsComposedOf
2015-12-22 16:27:12 +01:00
kgiszewski dada91f006 Fix u4-7534 2015-12-14 13:35:46 -05:00
engern 348694d9d4 Use same color as the rest 2015-11-29 12:22:22 +01:00
engern 855e3b3dcc Add the possibility to sort the macro parameters 2015-11-29 12:06:19 +01:00
engern 5a8ea4aa41 Merge branch 'dev-v7' of https://github.com/engern/Umbraco-CMS into dev-v7 2015-11-29 09:38:36 +01:00
engern 4bd465f666 Merge remote-tracking branch 'refs/remotes/umbraco/dev-v7' into dev-v7 2015-11-29 09:38:20 +01:00
Tommy Enger ad591c07cf Merge pull request #1 from umbraco/dev-v7
Update from original
2015-11-29 09:37:54 +01:00
Darren Ferguson 1cd00cb6f6 change the text "Reload nodes" to just "Reload" my editors don't know what a node is! 2015-11-20 18:11:13 +00:00
bjarnef cd3aaa47ca Add retina version of Umbraco logo in login screen 2015-11-19 00:25:05 +01:00
AndyButland a05cc03254 Allows position of the list view child items tab to be positioned within the tab list 2015-11-15 21:18:21 +01:00
545 changed files with 17289 additions and 6826 deletions
+5 -5
View File
@@ -15,11 +15,11 @@ If you're interested in making changes to Belle make sure to read the [Belle Rea
**More than 177,000 sites trust Umbraco**
For the first time on the Microsoft platform a free user and developer friendly CMS that makes it quick and easy to create websites - or a breeze to build complex web applications. Umbraco has award-winning integration capabilities and supports ASP.NET MVC or Web Forms, including User and Custom Controls, out of the box. It's a developers dream and your users will love it too.
For the first time on the Microsoft platform, there is a free user and developer friendly CMS that makes it quick and easy to create websites - or a breeze to build complex web applications. Umbraco has award-winning integration capabilities and supports ASP.NET MVC or Web Forms, including User and Custom Controls, out of the box. It's a developer's dream and your users will love it too.
Used by more than 177,000 active websites including [http://daviscup.com](http://daviscup.com), [http://heinz.com](http://heinz.com), [http://peugeot.com](http://peugeot.com), [http://www.hersheys.com/](http://www.hersheys.com/) and **The Official ASP.NET and IIS.NET website from Microsoft** ([http://asp.net](http://asp.net) / [http://iis.net](http://iis.net)) you can be sure that the technology is proven, stable and scales.
Used by more than 177,000 active websites including [http://daviscup.com](http://daviscup.com), [http://heinz.com](http://heinz.com), [http://peugeot.com](http://peugeot.com), [http://www.hersheys.com/](http://www.hersheys.com/) and **The Official ASP.NET and IIS.NET website from Microsoft** ([http://asp.net](http://asp.net) / [http://iis.net](http://iis.net)), you can be sure that the technology is proven, stable and scales.
To view more examples please visit [http://umbraco.com/why-umbraco/#caseStudies](http://umbraco.com/why-umbraco/#caseStudies)
To view more examples, please visit [http://umbraco.com/why-umbraco/#caseStudies](http://umbraco.com/why-umbraco/#caseStudies)
## Downloading ##
@@ -35,6 +35,6 @@ If you want to contribute back to Umbraco you should check out our [guide to con
## Found a bug? ##
Another way you can contribute to Umbraco is by providing issue reports, for information on how to submit an issue report refer to our [online guide for reporting issues](http://our.umbraco.org/contribute/report-an-issue-or-request-a-feature).
Another way you can contribute to Umbraco is by providing issue reports. For information on how to submit an issue report refer to our [online guide for reporting issues](http://our.umbraco.org/contribute/report-an-issue-or-request-a-feature).
To view existing issues please visit [http://issues.umbraco.org](http://issues.umbraco.org)
To view existing issues, please visit [http://issues.umbraco.org](http://issues.umbraco.org).
-8
View File
@@ -21,14 +21,6 @@ ECHO Building Umbraco %version%
ReplaceIISExpressPortNumber.exe ..\src\Umbraco.Web.UI\Umbraco.Web.UI.csproj %release%
ECHO Installing the Microsoft.Bcl.Build package before anything else, otherwise you'd have to run build.cmd twice
SET nuGetFolder=%CD%\..\src\packages\
..\src\.nuget\NuGet.exe sources Remove -Name MyGetUmbracoCore >NUL
..\src\.nuget\NuGet.exe sources Add -Name MyGetUmbracoCore -Source https://www.myget.org/F/umbracocore/api/v2/ >NUL
..\src\.nuget\NuGet.exe install ..\src\Umbraco.Web.UI\packages.config -OutputDirectory %nuGetFolder% -Verbosity quiet
..\src\.nuget\NuGet.exe install ..\src\umbraco.businesslogic\packages.config -OutputDirectory %nuGetFolder% -Verbosity quiet
..\src\.nuget\NuGet.exe install ..\src\Umbraco.Core\packages.config -OutputDirectory %nuGetFolder% -Verbosity quiet
ECHO Removing the belle build folder and bower_components folder to make sure everything is clean as a whistle
RD ..\src\Umbraco.Web.UI.Client\build /Q /S
RD ..\src\Umbraco.Web.UI.Client\bower_components /Q /S
+2 -2
View File
@@ -175,8 +175,8 @@
<!-- Copy SQL CE -->
<ItemGroup>
<SQLCE4Files
Include="..\src\packages\SqlServerCE.4.0.0.0\**\*.*"
Exclude="..\src\packages\SqlServerCE.4.0.0.0\lib\**\*;..\src\packages\SqlServerCE.4.0.0.0\**\*.nu*"
Include="..\src\packages\SqlServerCE.4.0.0.1\**\*.*"
Exclude="..\src\packages\SqlServerCE.4.0.0.1\lib\**\*;..\src\packages\SqlServerCE.4.0.0.1\**\*.nu*"
/>
</ItemGroup>
+21 -24
View File
@@ -17,11 +17,10 @@
<dependencies>
<dependency id="Microsoft.AspNet.Mvc" version="[5.2.3,6.0.0)" />
<dependency id="Microsoft.AspNet.WebApi" version="[5.2.3,6.0.0)" />
<dependency id="Microsoft.Net.Http" version="[2.2.29, 3.0.0)" />
<dependency id="Microsoft.AspNet.Identity.Owin" version="[2.2.1, 3.0.0)" />
<dependency id="Microsoft.Owin.Security.Cookies" version="[3.0.1, 4.0.0)" />
<dependency id="Microsoft.Owin.Security.OAuth" version="[3.0.1, 4.0.0)" />
<dependency id="Microsoft.Owin.Host.SystemWeb" version="[3.0.1, 4.0.0)" />
<dependency id="Microsoft.Owin.Host.SystemWeb" version="[3.0.1, 4.0.0)" />
<dependency id="MiniProfiler" version="[2.1.0, 3.0.0)" />
<dependency id="HtmlAgilityPack" version="[1.4.9, 2.0.0)" />
<dependency id="Lucene.Net" version="[2.9.4.1, 3.0.0.0)" />
@@ -31,14 +30,13 @@
<dependency id="ClientDependency" version="[1.8.4, 2.0.0)" />
<dependency id="ClientDependency-Mvc5" version="[1.8.0, 2.0.0)" />
<dependency id="AutoMapper" version="[3.0.0, 3.1.0)" />
<dependency id="Newtonsoft.Json" version="[6.0.8, 7.0.0)" />
<dependency id="Newtonsoft.Json" version="[6.0.8, 9.0.0)" />
<dependency id="Examine" version="[0.1.68, 1.0.0)" />
<dependency id="ImageProcessor" version="[2.3.2, 3.0.0)" />
<dependency id="ImageProcessor.Web" version="[4.5.0, 5.0.0)" />
<dependency id="ImageProcessor" version="[2.3.3, 3.0.0)" />
<dependency id="ImageProcessor.Web" version="[4.5.3, 5.0.0)" />
<dependency id="semver" version="[1.1.2, 2.0.0)" />
<dependency id="Microsoft.AspNet.WebHelpers" version="[3.2.3, 4.0.0)" />
<dependency id="Microsoft.AspNet.WebPages.Data" version="[3.2.3, 4.0.0)" />
<dependency id="Umbraco.ModelsBuilder.AspNet" version="[2.2.0-beta003, 3.0.0)" />
<dependency id="UrlRewritingNet" version="[2.0.7, 3.0.0)" />
<dependency id="Markdown" version="[1.14.4, 2.0.0)" />
</dependencies>
</metadata>
<files>
@@ -73,35 +71,34 @@
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Web.UI.xml" target="lib\Umbraco.Web.UI.xml" />
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.dll" target="lib\UmbracoExamine.dll" />
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.xml" target="lib\UmbracoExamine.xml" />
<file src="..\_BuildOutput\WebApp\bin\UrlRewritingNet.UrlRewriter.dll" target="lib\UrlRewritingNet.UrlRewriter.dll" />
<file src="tools\install.core.ps1" target="tools\install.ps1" />
<!-- Added to be able to produce a symbols package -->
<file src="..\_BuildOutput\bin\SQLCE4Umbraco.pdb" target="lib" />
<!-- Added to be able to produce a symbols package -->
<file src="..\_BuildOutput\bin\SQLCE4Umbraco.pdb" target="lib" />
<file src="..\..\src\SQLCE4Umbraco\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\SQLCE4Umbraco" />
<file src="..\_BuildOutput\bin\businesslogic.pdb" target="lib" />
<file src="..\_BuildOutput\bin\businesslogic.pdb" target="lib" />
<file src="..\..\src\umbraco.businesslogic\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.businesslogic" />
<file src="..\_BuildOutput\bin\cms.pdb" target="lib" />
<file src="..\_BuildOutput\bin\cms.pdb" target="lib" />
<file src="..\..\src\umbraco.cms\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.cms" />
<file src="..\_BuildOutput\bin\controls.pdb" target="lib" />
<file src="..\_BuildOutput\bin\controls.pdb" target="lib" />
<file src="..\..\src\umbraco.controls\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.controls" />
<file src="..\_BuildOutput\bin\interfaces.pdb" target="lib" />
<file src="..\_BuildOutput\bin\interfaces.pdb" target="lib" />
<file src="..\..\src\umbraco.interfaces\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.interfaces" />
<file src="..\_BuildOutput\bin\Umbraco.Core.pdb" target="lib" />
<file src="..\_BuildOutput\bin\Umbraco.Core.pdb" target="lib" />
<file src="..\..\src\Umbraco.Core\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\Umbraco.Core" />
<file src="..\_BuildOutput\bin\umbraco.DataLayer.pdb" target="lib" />
<file src="..\_BuildOutput\bin\umbraco.DataLayer.pdb" target="lib" />
<file src="..\..\src\umbraco.datalayer\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.datalayer" />
<file src="..\_BuildOutput\bin\umbraco.editorControls.pdb" target="lib" />
<file src="..\_BuildOutput\bin\umbraco.editorControls.pdb" target="lib" />
<file src="..\..\src\umbraco.editorControls\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.editorControls" />
<file src="..\_BuildOutput\bin\umbraco.MacroEngines.pdb" target="lib" />
<file src="..\_BuildOutput\bin\umbraco.MacroEngines.pdb" target="lib" />
<file src="..\..\src\umbraco.MacroEngines\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.MacroEngines" />
<file src="..\_BuildOutput\bin\umbraco.providers.pdb" target="lib" />
<file src="..\_BuildOutput\bin\umbraco.providers.pdb" target="lib" />
<file src="..\..\src\umbraco.providers\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.providers" />
<file src="..\_BuildOutput\bin\umbraco.pdb" target="lib" />
<file src="..\_BuildOutput\bin\umbraco.pdb" target="lib" />
<file src="..\..\src\Umbraco.Web\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\Umbraco.Web" />
<file src="..\_BuildOutput\bin\Umbraco.Web.UI.pdb" target="lib" />
<file src="..\_BuildOutput\bin\Umbraco.Web.UI.pdb" target="lib" />
<file src="..\..\src\Umbraco.Web.UI\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\Umbraco.Web.UI" />
<file src="..\_BuildOutput\bin\UmbracoExamine.pdb" target="lib" />
<file src="..\..\src\UmbracoExamine\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\UmbracoExamine" />
<file src="..\_BuildOutput\bin\UmbracoExamine.pdb" target="lib" />
<file src="..\..\src\UmbracoExamine\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\UmbracoExamine" />
</files>
</package>
+2 -1
View File
@@ -16,7 +16,8 @@
<tags>umbraco</tags>
<dependencies>
<dependency id="UmbracoCms.Core" version="[$version$]" />
<dependency id="Newtonsoft.Json" version="[6.0.5, 7.0.0)" />
<dependency id="Newtonsoft.Json" version="[6.0.8, 9.0.0)" />
<dependency id="Umbraco.ModelsBuilder" version="[3.0.2, 4.0.0)" />
</dependencies>
</metadata>
<files>
@@ -77,4 +77,8 @@
<section alias="uGoLiveDashboardSection" xdt:Locator="Match(alias)" xdt:Transform="Remove" />
<section alias="ExamineManagement" xdt:Locator="Match(alias)" xdt:Transform="Remove" />
<section alias="StartupDashboardSection">
<tab caption="Change Password" xdt:Locator="Match(caption)" xdt:Transform="Remove" />
</section>
</dashBoard>
+1
View File
@@ -10,6 +10,7 @@
Don't forget to build!
When upgrading your website using NuGet you should answer "No" to the questions to overwrite the Web.config
file (and config files in the config folder).
+1
View File
@@ -10,6 +10,7 @@
Don't forget to build!
We've done our best to transform your configuration files but in case something is not quite right: remember we
backed up your files in App_Data\NuGetBackup so you can find the original files before they were transformed.
+182 -27
View File
@@ -7,8 +7,8 @@
<section name="ExamineLuceneIndexSets" type="Examine.LuceneEngine.Config.IndexSets, Examine" requirePermission="false" xdt:Locator="Match(name)" xdt:Transform="SetAttributes(type,requirePermission)" />
<sectionGroup name="applicationSettings" xdt:Locator="Match(name)">
<section name="umbraco.presentation.Properties.Settings" xdt:Locator="Match(name)" xdt:Transform="Remove" />
</sectionGroup>
<section name="umbraco.presentation.Properties.Settings" xdt:Locator="Match(name)" xdt:Transform="Remove" />
</sectionGroup>
<sectionGroup name="system.web.webPages.razor" xdt:Locator="Match(name)" xdt:Transform="Remove" />
<sectionGroup name="umbracoConfiguration" xdt:Locator="Match(name)" xdt:Transform="InsertIfMissing">
<section name="settings" type="Umbraco.Core.Configuration.UmbracoSettings.UmbracoSettingsSection, Umbraco.Core" requirePermission="false" xdt:Locator="Match(name)" xdt:Transform="InsertIfMissing" />
@@ -21,8 +21,10 @@
<appSettings xdt:Transform="InsertIfMissing" />
<appSettings>
<add key="owin:appStartup" value="UmbracoDefaultOwinStartup" xdt:Locator="Match(key)" xdt:Transform="InsertIfMissing" />
<add key="Umbraco.ModelsBuilder.Enable" value="false" xdt:Locator="Match(key)" xdt:Transform="InsertIfMissing" />
<add key="Umbraco.ModelsBuilder.ModelsMode" value="Nothing" xdt:Locator="Match(key)" xdt:Transform="InsertIfMissing" />
</appSettings>
<umbracoConfiguration xdt:Transform="InsertIfMissing">
<settings configSource="config\umbracoSettings.config" xdt:Locator="Match(configSource)" xdt:Transform="InsertIfMissing" />
<BaseRestExtensions configSource="config\BaseRestExtensions.config" xdt:Locator="Match(configSource)" xdt:Transform="InsertIfMissing" />
@@ -37,7 +39,7 @@
<DbProviderFactories xdt:Transform="InsertIfMissing">
<remove invariant="System.Data.SqlServerCe.4.0" xdt:Locator="Match(invariant)" xdt:Transform="InsertIfMissing" />
<add name="Microsoft SQL Server Compact Data Provider 4.0" invariant="System.Data.SqlServerCe.4.0" description=".NET Framework Data Provider for Microsoft SQL Server Compact" type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe" xdt:Locator="Match(invariant)" xdt:Transform="SetAttributes(invariant,description,type)" />
<remove invariant="MySql.Data.MySqlClient" xdt:Locator="Match(invariant)" xdt:Transform="InsertIfMissing" />
<remove invariant="MySql.Data.MySqlClient" xdt:Locator="Match(invariant)" xdt:Transform="InsertIfMissing" />
<add invariant="MySql.Data.MySqlClient" xdt:Locator="Match(invariant)" xdt:Transform="Remove" />
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data" xdt:Locator="Match(invariant)" xdt:Transform="InsertIfMissing" />
<add invariant="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data" xdt:Locator="Match(invariant)" xdt:Transform="SetAttributes(type)" />
@@ -48,13 +50,15 @@
<system.web xdt:Transform="InsertIfMissing" />
<system.web>
<siteMap xdt:Transform="Remove" />
<siteMap xdt:Transform="InsertIfMissing">
<siteMap xdt:Transform="InsertIfMissing">
<providers xdt:Transform="InsertIfMissing">
<remove name="MySqlSiteMapProvider" xdt:Transform="InsertIfMissing" />
</providers>
</siteMap>
</siteMap>
<httpRuntime xdt:Transform="InsertIfMissing" />
<httpRuntime targetFramework="4.5" maxRequestLength="1048576" fcnMode="Single" xdt:Transform="SetAttributes(targetFramework,fcnMode,maxRequestLength)" />
<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"/>>
@@ -63,8 +67,7 @@
<compilation>
<assemblies xdt:Transform="InsertIfMissing" />
<assemblies>
<add assembly="System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)"
xdt:Transform="InsertIfMissing" />
<add assembly="System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Web.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
@@ -78,6 +81,56 @@
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<add assembly="System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<add assembly="System.Web.WebPages, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<add assembly="System.Collections, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Collections.Concurrent, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.ComponentModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.ComponentModel.Annotations, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.ComponentModel.EventBasedAsync, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Diagnostics.Contracts, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Diagnostics.Debug, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Diagnostics.Tools, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Diagnostics.Tracing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Dynamic.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Globalization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.IO, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Linq.Expressions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Linq.Parallel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Linq.Queryable, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Net.NetworkInformation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Net.Primitives, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Net.Requests, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.ObjectModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Reflection, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Reflection.Emit, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Reflection.Emit.ILGeneration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Reflection.Emit.Lightweight, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Reflection.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Reflection.Primitives, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Resources.ResourceManager, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Runtime.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Runtime.InteropServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Runtime.InteropServices.WindowsRuntime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Runtime.Numerics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Runtime.Serialization.Json, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Runtime.Serialization.Primitives, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Runtime.Serialization.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Security.Principal, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.ServiceModel.Duplex, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.ServiceModel.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.ServiceModel.NetTcp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.ServiceModel.Primitives, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.ServiceModel.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Text.Encoding, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Text.Encoding.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Text.RegularExpressions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Threading, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Threading.Tasks, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Threading.Tasks.Parallel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Xml.ReaderWriter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Xml.XDocument, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
<add assembly="System.Xml.XmlSerializer, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
</assemblies>
</compilation>
@@ -86,11 +139,113 @@
<remove assembly="System.Web.Http" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Net.Http" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Runtime" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Collections" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Collections.Concurrent" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.ComponentModel" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.ComponentModel.Annotations" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.ComponentModel.EventBasedAsync" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Diagnostics.Contracts" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Diagnostics.Debug" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Diagnostics.Tools" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Diagnostics.Tracing" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Dynamic.Runtime" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Globalization" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.IO" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Linq" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Linq.Expressions" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Linq.Parallel" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Linq.Queryable" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Net.NetworkInformation" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Net.Primitives" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Net.Requests" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.ObjectModel" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Reflection" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Reflection.Emit" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Reflection.Emit.ILGeneration" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Reflection.Emit.Lightweight" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Reflection.Extensions" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Reflection.Primitives" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Resources.ResourceManager" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Runtime" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Runtime.Extensions" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Runtime.InteropServices" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Runtime.InteropServices.WindowsRuntime" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Runtime.Numerics" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Runtime.Serialization.Json" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Runtime.Serialization.Primitives" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Runtime.Serialization.Xml" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Security.Principal" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.ServiceModel.Duplex" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.ServiceModel.Http" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.ServiceModel.NetTcp" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.ServiceModel.Primitives" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.ServiceModel.Security" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Text.Encoding" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Text.Encoding.Extensions" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Text.RegularExpressions" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Threading" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Threading.Tasks" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Threading.Tasks.Parallel" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Xml.ReaderWriter" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Xml.XDocument" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
<remove assembly="System.Xml.XmlSerializer" xdt:Locator="Match(assembly)" xdt:Transform="Remove" />
</assemblies>
</compilation>
<compilation>
<assemblies>
<remove assembly="System.Web.Http" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Net.Http" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Runtime" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Collections" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Collections.Concurrent" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.ComponentModel" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.ComponentModel.Annotations" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.ComponentModel.EventBasedAsync" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Diagnostics.Contracts" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Diagnostics.Debug" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Diagnostics.Tools" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Diagnostics.Tracing" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Dynamic.Runtime" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Globalization" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.IO" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Linq" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Linq.Expressions" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Linq.Parallel" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Linq.Queryable" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Net.NetworkInformation" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Net.Primitives" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Net.Requests" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.ObjectModel" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Reflection" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Reflection.Emit" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Reflection.Emit.ILGeneration" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Reflection.Emit.Lightweight" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Reflection.Extensions" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Reflection.Primitives" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Resources.ResourceManager" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Runtime" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Runtime.Extensions" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Runtime.InteropServices" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Runtime.InteropServices.WindowsRuntime" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Runtime.Numerics" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Runtime.Serialization.Json" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Runtime.Serialization.Primitives" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Runtime.Serialization.Xml" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Security.Principal" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.ServiceModel.Duplex" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.ServiceModel.Http" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.ServiceModel.NetTcp" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.ServiceModel.Primitives" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.ServiceModel.Security" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Text.Encoding" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Text.Encoding.Extensions" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Text.RegularExpressions" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Threading" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Threading.Tasks" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Threading.Tasks.Parallel" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Xml.ReaderWriter" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Xml.XDocument" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
<remove assembly="System.Xml.XmlSerializer" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
</assemblies>
</compilation>
@@ -125,6 +280,8 @@
<add name="umbracoRequestModule" xdt:Locator="Match(name)" xdt:Transform="Remove" />
<add name="viewstateMoverModule" xdt:Locator="Match(name)" xdt:Transform="Remove" />
<add name="umbracoBaseRequestModule" xdt:Locator="Match(name)" xdt:Transform="Remove" />
<!-- Note, we're removing the one that starts with a space here, don't correct it -->
<!-- This to fix a quirk we for a lot of releases where we added it with the space by default -->
<add name=" UmbracoModule" xdt:Locator="Match(name)" xdt:Transform="Remove" />
<add name="UmbracoModule" type="Umbraco.Web.UmbracoModule,umbraco" xdt:Locator="Match(name)" xdt:Transform="InsertIfMissing" />
</modules>
@@ -146,19 +303,17 @@
<security xdt:Transform="InsertIfMissing">
<requestFiltering xdt:Transform="InsertIfMissing">
<requestLimits maxAllowedContentLength="1073741824" xdt:Transform="InsertIfMissing" />
<requestLimits maxAllowedContentLength="52428800" xdt:Transform="InsertIfMissing" />
</requestFiltering>
</security>
</system.webServer>
<system.codedom xdt:Transform="Remove" />
</system.webServer>
<runtime xdt:Transform="InsertIfMissing" />
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1" xdt:Transform="InsertIfMissing" />
</runtime>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='HtmlAgilityPack')" xdt:Transform="Remove" />
@@ -171,7 +326,7 @@
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='Microsoft.Owin.Security.OAuth')" xdt:Transform="Remove" />
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='Microsoft.Owin.Security')" xdt:Transform="Remove" />
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='Microsoft.Owin.Security.Cookies')" xdt:Transform="Remove" />
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Net.Http.Formatting')" xdt:Transform="Remove" />
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Net.Http.Formatting')" xdt:Transform="Remove" />
</assemblyBinding>
</runtime>
@@ -180,7 +335,7 @@
<dependentAssembly>
<assemblyIdentity name="HtmlAgilityPack" publicKeyToken="bd319b19eaf3b43a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.4.9.0" newVersion="1.4.9.0" />
</dependentAssembly>
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0"/>
@@ -191,12 +346,12 @@
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.1" newVersion="4.0.0.1" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="System.Web.WebPages.Razor" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
@@ -208,16 +363,16 @@
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
@@ -225,19 +380,19 @@
</runtime>
<system.web.webPages.razor xdt:Transform="Remove" />
<location path="umbraco" xdt:Locator="Match(path)" xdt:Transform="InsertIfMissing" />
<location path="umbraco" xdt:Locator="Match(path)">
<system.webServer xdt:Transform="InsertIfMissing">
<urlCompression doStaticCompression="false" doDynamicCompression="false" dynamicCompressionBeforeCache="false" xdt:Transform="SetAttributes(doStaticCompression,doDynamicCompression,dynamicCompressionBeforeCache)" />
<urlCompression doStaticCompression="false" doDynamicCompression="false" dynamicCompressionBeforeCache="false" xdt:Transform="SetAttributes(doStaticCompression,doDynamicCompression,dynamicCompressionBeforeCache)" />
</system.webServer>
</location>
<location path="App_Plugins" xdt:Locator="Match(path)" xdt:Transform="InsertIfMissing" />
<location path="App_Plugins" xdt:Locator="Match(path)">
<system.webServer xdt:Transform="InsertIfMissing">
<urlCompression doStaticCompression="false" doDynamicCompression="false" dynamicCompressionBeforeCache="false" xdt:Transform="SetAttributes(doStaticCompression,doDynamicCompression,dynamicCompressionBeforeCache)" />
<urlCompression doStaticCompression="false" doDynamicCompression="false" dynamicCompressionBeforeCache="false" xdt:Transform="SetAttributes(doStaticCompression,doDynamicCompression,dynamicCompressionBeforeCache)" />
</system.webServer>
</location>
</configuration>
+28 -10
View File
@@ -1,18 +1,30 @@
param($rootPath, $toolsPath, $package, $project)
param($installPath, $toolsPath, $package, $project)
Write-Host "installPath:" "${installPath}"
Write-Host "toolsPath:" "${toolsPath}"
Write-Host " "
if ($project) {
$dateTime = Get-Date -Format yyyyMMdd-HHmmss
$backupPath = Join-Path (Split-Path $project.FullName -Parent) "\App_Data\NuGetBackup\$dateTime"
# Create paths and list them
$projectPath = (Get-Item $project.Properties.Item("FullPath").Value).FullName
Write-Host "projectPath:" "${projectPath}"
$backupPath = Join-Path $projectPath "App_Data\NuGetBackup\$dateTime"
Write-Host "backupPath:" "${backupPath}"
$copyLogsPath = Join-Path $backupPath "CopyLogs"
$projectDestinationPath = Split-Path $project.FullName -Parent
Write-Host "copyLogsPath:" "${copyLogsPath}"
$umbracoBinFolder = Join-Path $projectPath "bin"
Write-Host "umbracoBinFolder:" "${umbracoBinFolder}"
# Create backup folder and logs folder if it doesn't exist yet
New-Item -ItemType Directory -Force -Path $backupPath
New-Item -ItemType Directory -Force -Path $copyLogsPath
# After backing up, remove all umbraco dlls from bin folder in case dll files are included in the VS project
# See: http://issues.umbraco.org/issue/U4-4930
$umbracoBinFolder = Join-Path $projectDestinationPath "bin"
if(Test-Path $umbracoBinFolder) {
$umbracoBinBackupPath = Join-Path $backupPath "bin"
@@ -20,7 +32,7 @@ if ($project) {
robocopy $umbracoBinFolder $umbracoBinBackupPath /e /LOG:$copyLogsPath\UmbracoBinBackup.log
# Delete files Umbraco brings in
# Delete files Umbraco ships with
if(Test-Path $umbracoBinFolder\businesslogic.dll) { Remove-Item $umbracoBinFolder\businesslogic.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\cms.dll) { Remove-Item $umbracoBinFolder\cms.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\controls.dll) { Remove-Item $umbracoBinFolder\controls.dll -Force -Confirm:$false }
@@ -36,16 +48,18 @@ if ($project) {
if(Test-Path $umbracoBinFolder\umbraco.DataLayer.dll) { Remove-Item $umbracoBinFolder\umbraco.DataLayer.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\umbraco.editorControls.dll) { Remove-Item $umbracoBinFolder\umbraco.editorControls.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\umbraco.MacroEngines.dll) { Remove-Item $umbracoBinFolder\umbraco.MacroEngines.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Umbraco.ModelsBuilder.dll) { Remove-Item $umbracoBinFolder\Umbraco.ModelsBuilder.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Umbraco.ModelsBuilder.AspNet.dll) { Remove-Item $umbracoBinFolder\Umbraco.ModelsBuilder.AspNet.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\umbraco.providers.dll) { Remove-Item $umbracoBinFolder\umbraco.providers.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Umbraco.Web.UI.dll) { Remove-Item $umbracoBinFolder\Umbraco.Web.UI.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\UmbracoExamine.dll) { Remove-Item $umbracoBinFolder\UmbracoExamine.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\UrlRewritingNet.UrlRewriter.dll) { Remove-Item $umbracoBinFolder\UrlRewritingNet.UrlRewriter.dll -Force -Confirm:$false }
# Delete files Umbraco depends upon
$amd64Folder = Join-Path $projectDestinationPath "bin\amd64"
$amd64Folder = Join-Path $umbracoBinFolder "amd64"
if(Test-Path $amd64Folder) { Remove-Item $amd64Folder -Force -Recurse -Confirm:$false }
$x86Folder = Join-Path $projectDestinationPath "bin\x86"
if(Test-Path $x86Folder) { Remove-Item $x86Folder -Force -Recurse -Confirm:$false }
$x86Folder = Join-Path $umbracoBinFolder "x86"
if(Test-Path $x86Folder) { Remove-Item $x86Folder -Force -Recurse -Confirm:$false }
if(Test-Path $umbracoBinFolder\AutoMapper.dll) { Remove-Item $umbracoBinFolder\AutoMapper.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\AutoMapper.Net4.dll) { Remove-Item $umbracoBinFolder\AutoMapper.Net4.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\ClientDependency.Core.dll) { Remove-Item $umbracoBinFolder\ClientDependency.Core.dll -Force -Confirm:$false }
@@ -59,6 +73,8 @@ if ($project) {
if(Test-Path $umbracoBinFolder\Lucene.Net.dll) { Remove-Item $umbracoBinFolder\Lucene.Net.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Microsoft.AspNet.Identity.Core.dll) { Remove-Item $umbracoBinFolder\Microsoft.AspNet.Identity.Core.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Microsoft.AspNet.Identity.Owin.dll) { Remove-Item $umbracoBinFolder\Microsoft.AspNet.Identity.Owin.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Microsoft.CodeAnalysis.CSharp.dll) { Remove-Item $umbracoBinFolder\Microsoft.CodeAnalysis.CSharp.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Microsoft.CodeAnalysis.dll) { Remove-Item $umbracoBinFolder\Microsoft.CodeAnalysis.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Microsoft.Owin.dll) { Remove-Item $umbracoBinFolder\Microsoft.Owin.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Microsoft.Owin.Host.SystemWeb.dll) { Remove-Item $umbracoBinFolder\Microsoft.Owin.Host.SystemWeb.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Microsoft.Owin.Security.dll) { Remove-Item $umbracoBinFolder\Microsoft.Owin.Security.dll -Force -Confirm:$false }
@@ -72,6 +88,8 @@ if ($project) {
if(Test-Path $umbracoBinFolder\Newtonsoft.Json.dll) { Remove-Item $umbracoBinFolder\Newtonsoft.Json.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Owin.dll) { Remove-Item $umbracoBinFolder\Owin.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Semver.dll) { Remove-Item $umbracoBinFolder\Semver.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\System.Collections.Immutable.dll) { Remove-Item $umbracoBinFolder\System.Collections.Immutable.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\System.Reflection.Metadata.dll) { Remove-Item $umbracoBinFolder\System.Reflection.Metadata.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\System.Net.Http.Extensions.dll) { Remove-Item $umbracoBinFolder\System.Net.Http.Extensions.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\System.Net.Http.Formatting.dll) { Remove-Item $umbracoBinFolder\System.Net.Http.Formatting.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\System.Net.Http.Primitives.dll) { Remove-Item $umbracoBinFolder\System.Net.Http.Primitives.dll -Force -Confirm:$false }
@@ -82,6 +100,6 @@ if ($project) {
if(Test-Path $umbracoBinFolder\System.Web.Razor.dll) { Remove-Item $umbracoBinFolder\System.Web.Razor.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\System.Web.WebPages.dll) { Remove-Item $umbracoBinFolder\System.Web.WebPages.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\System.Web.WebPages.Deployment.dll) { Remove-Item $umbracoBinFolder\System.Web.WebPages.Deployment.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\System.Web.WebPages.Razor.dll) { Remove-Item $umbracoBinFolder\System.Web.WebPages.Razor.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\System.Web.WebPages.Razor.dll) { Remove-Item $umbracoBinFolder\System.Web.WebPages.Razor.dll -Force -Confirm:$false }
}
}
+35 -31
View File
@@ -1,21 +1,33 @@
param($rootPath, $toolsPath, $package, $project)
param($installPath, $toolsPath, $package, $project)
Write-Host "installPath:" "${installPath}"
Write-Host "toolsPath:" "${toolsPath}"
Write-Host " "
if ($project) {
$dateTime = Get-Date -Format yyyyMMdd-HHmmss
$backupPath = Join-Path (Split-Path $project.FullName -Parent) "\App_Data\NuGetBackup\$dateTime"
# Create paths and list them
$projectPath = (Get-Item $project.Properties.Item("FullPath").Value).FullName
Write-Host "projectPath:" "${projectPath}"
$backupPath = Join-Path $projectPath "App_Data\NuGetBackup\$dateTime"
Write-Host "backupPath:" "${backupPath}"
$copyLogsPath = Join-Path $backupPath "CopyLogs"
$projectDestinationPath = Split-Path $project.FullName -Parent
Write-Host "copyLogsPath:" "${copyLogsPath}"
$webConfigSource = Join-Path $projectPath "Web.config"
Write-Host "webConfigSource:" "${webConfigSource}"
$configFolder = Join-Path $projectPath "Config"
Write-Host "configFolder:" "${configFolder}"
# Create backup folder and logs folder if it doesn't exist yet
New-Item -ItemType Directory -Force -Path $backupPath
New-Item -ItemType Directory -Force -Path $copyLogsPath
# Create a backup of original web.config
$webConfigSource = Join-Path $projectDestinationPath "Web.config"
Copy-Item $webConfigSource $backupPath -Force
# Backup config files folder
$configFolder = Join-Path $projectDestinationPath "Config"
# Backup config files folder
if(Test-Path $configFolder) {
$umbracoBackupPath = Join-Path $backupPath "Config"
New-Item -ItemType Directory -Force -Path $umbracoBackupPath
@@ -24,32 +36,24 @@ if ($project) {
}
# Copy umbraco and umbraco_files from package to project folder
# This is only done when these folders already exist because we
# only want to do this for upgrades
$umbracoFolder = Join-Path $projectDestinationPath "Umbraco"
if(Test-Path $umbracoFolder) {
$umbracoFolderSource = Join-Path $rootPath "UmbracoFiles\Umbraco"
$umbracoBackupPath = Join-Path $backupPath "Umbraco"
New-Item -ItemType Directory -Force -Path $umbracoBackupPath
robocopy $umbracoFolder $umbracoBackupPath /e /LOG:$copyLogsPath\UmbracoBackup.log
robocopy $umbracoFolderSource $umbracoFolder /is /it /e /xf UI.xml /LOG:$copyLogsPath\UmbracoCopy.log
}
$umbracoFolder = Join-Path $projectPath "Umbraco"
New-Item -ItemType Directory -Force -Path $umbracoFolder
$umbracoFolderSource = Join-Path $installPath "UmbracoFiles\Umbraco"
$umbracoBackupPath = Join-Path $backupPath "Umbraco"
New-Item -ItemType Directory -Force -Path $umbracoBackupPath
robocopy $umbracoFolder $umbracoBackupPath /e /LOG:$copyLogsPath\UmbracoBackup.log
robocopy $umbracoFolderSource $umbracoFolder /is /it /e /xf UI.xml /LOG:$copyLogsPath\UmbracoCopy.log
$umbracoClientFolder = Join-Path $projectDestinationPath "Umbraco_Client"
if(Test-Path $umbracoClientFolder) {
$umbracoClientFolderSource = Join-Path $rootPath "UmbracoFiles\Umbraco_Client"
$umbracoClientBackupPath = Join-Path $backupPath "Umbraco_Client"
New-Item -ItemType Directory -Force -Path $umbracoClientBackupPath
robocopy $umbracoClientFolder $umbracoClientBackupPath /e /LOG:$copyLogsPath\UmbracoClientBackup.log
robocopy $umbracoClientFolderSource $umbracoClientFolder /is /it /e /LOG:$copyLogsPath\UmbracoClientCopy.log
}
$umbracoClientFolder = Join-Path $projectPath "Umbraco_Client"
New-Item -ItemType Directory -Force -Path $umbracoClientFolder
$umbracoClientFolderSource = Join-Path $installPath "UmbracoFiles\Umbraco_Client"
$umbracoClientBackupPath = Join-Path $backupPath "Umbraco_Client"
New-Item -ItemType Directory -Force -Path $umbracoClientBackupPath
robocopy $umbracoClientFolder $umbracoClientBackupPath /e /LOG:$copyLogsPath\UmbracoClientBackup.log
robocopy $umbracoClientFolderSource $umbracoClientFolder /is /it /e /LOG:$copyLogsPath\UmbracoClientCopy.log
$copyWebconfig = $true
$destinationWebConfig = Join-Path $projectDestinationPath "Web.config"
$destinationWebConfig = Join-Path $projectPath "Web.config"
if(Test-Path $destinationWebConfig)
{
@@ -71,11 +75,11 @@ if ($project) {
if($copyWebconfig -eq $true)
{
$packageWebConfigSource = Join-Path $rootPath "UmbracoFiles\Web.config"
$packageWebConfigSource = Join-Path $installPath "UmbracoFiles\Web.config"
Copy-Item $packageWebConfigSource $destinationWebConfig -Force
}
$installFolder = Join-Path $projectDestinationPath "Install"
$installFolder = Join-Path $projectPath "Install"
if(Test-Path $installFolder) {
Remove-Item $installFolder -Force -Recurse -Confirm:$false
}
+1 -2
View File
@@ -1,3 +1,2 @@
# Usage: on line 2 put the release version, on line 3 put the version comment (example: beta)
7.4.0
beta2
7.4.2
+8 -6
View File
@@ -47,13 +47,15 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<Private>True</Private>
<HintPath>..\packages\SqlServerCE.4.0.0.0\lib\System.Data.SqlServerCe.dll</HintPath>
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Private>False</Private>
</Reference>
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<Private>True</Private>
<HintPath>..\packages\SqlServerCE.4.0.0.0\lib\System.Data.SqlServerCe.Entity.dll</HintPath>
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.Entity.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Private>False</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
+1 -1
View File
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="SqlServerCE" version="4.0.0.0" targetFramework="net40" />
<package id="SqlServerCE" version="4.0.0.1" targetFramework="net45" />
</packages>
+2 -2
View File
@@ -11,5 +11,5 @@ using System.Resources;
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("7.4.0")]
[assembly: AssemblyInformationalVersion("7.4.0-beta2")]
[assembly: AssemblyFileVersion("7.4.2")]
[assembly: AssemblyInformationalVersion("7.4.2")]
@@ -7,14 +7,22 @@ using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Cache
{
/// <summary>
/// Interface describing this cache provider as a wrapper for another
/// </summary>
internal interface IRuntimeCacheProviderWrapper
{
IRuntimeCacheProvider InnerProvider { get; }
}
/// <summary>
/// A wrapper for any IRuntimeCacheProvider that ensures that all inserts and returns
/// are a deep cloned copy of the item when the item is IDeepCloneable and that tracks changes are
/// reset if the object is TracksChangesEntityBase
/// </summary>
internal class DeepCloneRuntimeCacheProvider : IRuntimeCacheProvider
internal class DeepCloneRuntimeCacheProvider : IRuntimeCacheProvider, IRuntimeCacheProviderWrapper
{
internal IRuntimeCacheProvider InnerProvider { get; private set; }
public IRuntimeCacheProvider InnerProvider { get; private set; }
public DeepCloneRuntimeCacheProvider(IRuntimeCacheProvider innerProvider)
{
@@ -11,35 +11,35 @@ namespace Umbraco.Core.Cache
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TId"></typeparam>
internal class DefaultRepositoryCachePolicy<TEntity, TId> : DisposableObject, IRepositoryCachePolicy<TEntity, TId>
/// <remarks>
/// This cache policy uses sliding expiration and caches instances for 5 minutes. However if allow zero count is true, then we use the
/// default policy with no expiry.
/// </remarks>
internal class DefaultRepositoryCachePolicy<TEntity, TId> : RepositoryCachePolicyBase<TEntity, TId>
where TEntity : class, IAggregateRoot
{
private readonly RepositoryCachePolicyOptions _options;
protected IRuntimeCacheProvider Cache { get; private set; }
private Action _action;
public DefaultRepositoryCachePolicy(IRuntimeCacheProvider cache, RepositoryCachePolicyOptions options)
{
if (cache == null) throw new ArgumentNullException("cache");
: base(cache)
{
if (options == null) throw new ArgumentNullException("options");
_options = options;
Cache = cache;
_options = options;
}
public string GetCacheIdKey(object id)
protected string GetCacheIdKey(object id)
{
if (id == null) throw new ArgumentNullException("id");
return string.Format("{0}{1}", GetCacheTypeKey(), id);
}
public string GetCacheTypeKey()
protected string GetCacheTypeKey()
{
return string.Format("uRepo_{0}_", typeof(TEntity).Name);
}
public void CreateOrUpdate(TEntity entity, Action<TEntity> persistMethod)
public override void CreateOrUpdate(TEntity entity, Action<TEntity> persistMethod)
{
if (entity == null) throw new ArgumentNullException("entity");
if (persistMethod == null) throw new ArgumentNullException("persistMethod");
@@ -54,7 +54,9 @@ namespace Umbraco.Core.Cache
//just to be safe, we cannot cache an item without an identity
if (entity.HasIdentity)
{
Cache.InsertCacheItem(GetCacheIdKey(entity.Id), () => entity);
Cache.InsertCacheItem(GetCacheIdKey(entity.Id), () => entity,
timeout: TimeSpan.FromMinutes(5),
isSliding: true);
}
//If there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
@@ -79,24 +81,29 @@ namespace Umbraco.Core.Cache
}
}
public void Remove(TEntity entity, Action<TEntity> persistMethod)
public override void Remove(TEntity entity, Action<TEntity> persistMethod)
{
if (entity == null) throw new ArgumentNullException("entity");
if (persistMethod == null) throw new ArgumentNullException("persistMethod");
persistMethod(entity);
//set the disposal action
var cacheKey = GetCacheIdKey(entity.Id);
SetCacheAction(() =>
try
{
Cache.ClearCacheItem(cacheKey);
//If there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
Cache.ClearCacheItem(GetCacheTypeKey());
});
persistMethod(entity);
}
finally
{
//set the disposal action
var cacheKey = GetCacheIdKey(entity.Id);
SetCacheAction(() =>
{
Cache.ClearCacheItem(cacheKey);
//If there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
Cache.ClearCacheItem(GetCacheTypeKey());
});
}
}
public TEntity Get(TId id, Func<TId, TEntity> getFromRepo)
public override TEntity Get(TId id, Func<TId, TEntity> getFromRepo)
{
if (getFromRepo == null) throw new ArgumentNullException("getFromRepo");
@@ -113,13 +120,13 @@ namespace Umbraco.Core.Cache
return entity;
}
public TEntity Get(TId id)
public override TEntity Get(TId id)
{
var cacheKey = GetCacheIdKey(id);
return Cache.GetCacheItem<TEntity>(cacheKey);
}
public bool Exists(TId id, Func<TId, bool> getFromRepo)
public override bool Exists(TId id, Func<TId, bool> getFromRepo)
{
if (getFromRepo == null) throw new ArgumentNullException("getFromRepo");
@@ -128,7 +135,7 @@ namespace Umbraco.Core.Cache
return fromCache != null || getFromRepo(id);
}
public virtual TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> getFromRepo)
public override TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> getFromRepo)
{
if (getFromRepo == null) throw new ArgumentNullException("getFromRepo");
@@ -158,8 +165,7 @@ namespace Umbraco.Core.Cache
else if (_options.GetAllCacheAllowZeroCount)
{
//if the repository allows caching a zero count, then check the zero count cache
var zeroCount = Cache.GetCacheItem<TEntity[]>(GetCacheTypeKey());
if (zeroCount != null && zeroCount.Any() == false)
if (HasZeroCountCache())
{
//there is a zero count cache so return an empty list
return new TEntity[] {};
@@ -179,28 +185,27 @@ namespace Umbraco.Core.Cache
return entityCollection;
}
/// <summary>
/// Looks up the zero count cache, must return null if it doesn't exist
/// </summary>
/// <returns></returns>
protected bool HasZeroCountCache()
{
var zeroCount = Cache.GetCacheItem<TEntity[]>(GetCacheTypeKey());
return (zeroCount != null && zeroCount.Any() == false);
}
/// <summary>
/// Performs the lookup for all entities of this type from the cache
/// </summary>
/// <returns></returns>
protected virtual TEntity[] GetAllFromCache()
protected TEntity[] GetAllFromCache()
{
var allEntities = Cache.GetCacheItemsByKeySearch<TEntity>(GetCacheTypeKey())
.WhereNotNull()
.ToArray();
return allEntities.Any() ? allEntities : new TEntity[] {};
}
/// <summary>
/// The disposal performs the caching
/// </summary>
protected override void DisposeResources()
{
if (_action != null)
{
_action();
}
}
}
/// <summary>
/// Sets the action to execute on disposal for a single entity
@@ -216,7 +221,9 @@ namespace Umbraco.Core.Cache
//just to be safe, we cannot cache an item without an identity
if (entity.HasIdentity)
{
Cache.InsertCacheItem(cacheKey, () => entity);
Cache.InsertCacheItem(cacheKey, () => entity,
timeout: TimeSpan.FromMinutes(5),
isSliding: true);
}
});
}
@@ -235,6 +242,7 @@ namespace Umbraco.Core.Cache
{
//there was nothing returned but we want to cache a zero count result so add an TEntity[] to the cache
// to signify that there is a zero count cache
//NOTE: Don't set expiry/sliding for a zero count
Cache.InsertCacheItem(GetCacheTypeKey(), () => new TEntity[] {});
}
else
@@ -247,20 +255,14 @@ namespace Umbraco.Core.Cache
//just to be safe, we cannot cache an item without an identity
if (localCopy.HasIdentity)
{
Cache.InsertCacheItem(GetCacheIdKey(entity.Id), () => localCopy);
Cache.InsertCacheItem(GetCacheIdKey(entity.Id), () => localCopy,
timeout: TimeSpan.FromMinutes(5),
isSliding: true);
}
}
}
});
}
/// <summary>
/// Sets the action to execute on disposal
/// </summary>
/// <param name="action"></param>
protected void SetCacheAction(Action action)
{
_action = action;
}
}
}
@@ -1,3 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Collections;
using Umbraco.Core.Models.EntityBase;
@@ -9,11 +11,157 @@ namespace Umbraco.Core.Cache
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TId"></typeparam>
internal class FullDataSetRepositoryCachePolicy<TEntity, TId> : DefaultRepositoryCachePolicy<TEntity, TId>
internal class FullDataSetRepositoryCachePolicy<TEntity, TId> : RepositoryCachePolicyBase<TEntity, TId>
where TEntity : class, IAggregateRoot
{
public FullDataSetRepositoryCachePolicy(IRuntimeCacheProvider cache) : base(cache, new RepositoryCachePolicyOptions())
private readonly Func<TEntity, TId> _getEntityId;
private readonly Func<IEnumerable<TEntity>> _getAllFromRepo;
private readonly bool _expires;
public FullDataSetRepositoryCachePolicy(IRuntimeCacheProvider cache, Func<TEntity, TId> getEntityId, Func<IEnumerable<TEntity>> getAllFromRepo, bool expires)
: base(cache)
{
_getEntityId = getEntityId;
_getAllFromRepo = getAllFromRepo;
_expires = expires;
}
private bool? _hasZeroCountCache;
protected string GetCacheTypeKey()
{
return string.Format("uRepo_{0}_", typeof(TEntity).Name);
}
public override void CreateOrUpdate(TEntity entity, Action<TEntity> persistMethod)
{
if (entity == null) throw new ArgumentNullException("entity");
if (persistMethod == null) throw new ArgumentNullException("persistMethod");
try
{
persistMethod(entity);
//set the disposal action
SetCacheAction(() =>
{
//Clear all
Cache.ClearCacheItem(GetCacheTypeKey());
});
}
catch
{
//set the disposal action
SetCacheAction(() =>
{
//Clear all
Cache.ClearCacheItem(GetCacheTypeKey());
});
throw;
}
}
public override void Remove(TEntity entity, Action<TEntity> persistMethod)
{
if (entity == null) throw new ArgumentNullException("entity");
if (persistMethod == null) throw new ArgumentNullException("persistMethod");
try
{
persistMethod(entity);
}
finally
{
//set the disposal action
SetCacheAction(() =>
{
//Clear all
Cache.ClearCacheItem(GetCacheTypeKey());
});
}
}
public override TEntity Get(TId id, Func<TId, TEntity> getFromRepo)
{
//Force get all with cache
var found = GetAll(new TId[] { }, ids => _getAllFromRepo().WhereNotNull());
//we don't have anything in cache (this should never happen), just return from the repo
if (found == null) return getFromRepo(id);
var entity = found.FirstOrDefault(x => _getEntityId(x).Equals(id));
if (entity == null) return null;
//We must ensure to deep clone each one out manually since the deep clone list only clones one way
return (TEntity)entity.DeepClone();
}
public override TEntity Get(TId id)
{
//Force get all with cache
var found = GetAll(new TId[] { }, ids => _getAllFromRepo().WhereNotNull());
//we don't have anything in cache (this should never happen), just return null
if (found == null) return null;
var entity = found.FirstOrDefault(x => _getEntityId(x).Equals(id));
if (entity == null) return null;
//We must ensure to deep clone each one out manually since the deep clone list only clones one way
return (TEntity)entity.DeepClone();
}
public override bool Exists(TId id, Func<TId, bool> getFromRepo)
{
//Force get all with cache
var found = GetAll(new TId[] { }, ids => _getAllFromRepo().WhereNotNull());
//we don't have anything in cache (this should never happen), just return from the repo
return found == null
? getFromRepo(id)
: found.Any(x => _getEntityId(x).Equals(id));
}
public override TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> getFromRepo)
{
//process getting all including setting the cache callback
var result = PerformGetAll(getFromRepo);
//now that the base result has been calculated, they will all be cached.
// Now we can just filter by ids if they have been supplied
return (ids.Any()
? result.Where(x => ids.Contains(_getEntityId(x))).ToArray()
: result)
//We must ensure to deep clone each one out manually since the deep clone list only clones one way
.Select(x => (TEntity)x.DeepClone())
.ToArray();
}
private TEntity[] PerformGetAll(Func<TId[], IEnumerable<TEntity>> getFromRepo)
{
var allEntities = GetAllFromCache();
if (allEntities.Any())
{
return allEntities;
}
//check the zero count cache
if (HasZeroCountCache())
{
//there is a zero count cache so return an empty list
return new TEntity[] { };
}
//we need to do the lookup from the repo
var entityCollection = getFromRepo(new TId[] { })
//ensure we don't include any null refs in the returned collection!
.WhereNotNull()
.ToArray();
//set the disposal action
SetCacheAction(entityCollection);
return entityCollection;
}
/// <summary>
@@ -21,37 +169,61 @@ namespace Umbraco.Core.Cache
/// </summary>
/// <param name="cacheKey"></param>
/// <param name="entity"></param>
protected override void SetCacheAction(string cacheKey, TEntity entity)
protected void SetCacheAction(string cacheKey, TEntity entity)
{
//do nothing
//No-op
}
/// <summary>
/// Sets the action to execute on disposal for an entity collection
/// </summary>
/// <param name="ids"></param>
/// <param name="entityCollection"></param>
protected override void SetCacheAction(TId[] ids, TEntity[] entityCollection)
protected void SetCacheAction(TEntity[] entityCollection)
{
//for this type of caching policy, we don't want to cache any GetAll request containing specific Ids
if (ids.Any()) return;
//set the disposal action
SetCacheAction(() =>
{
//We want to cache the result as a single collection
Cache.InsertCacheItem(GetCacheTypeKey(), () => new DeepCloneableList<TEntity>(entityCollection));
if (_expires)
{
Cache.InsertCacheItem(GetCacheTypeKey(), () => new DeepCloneableList<TEntity>(entityCollection),
timeout: TimeSpan.FromMinutes(5),
isSliding: true);
}
else
{
Cache.InsertCacheItem(GetCacheTypeKey(), () => new DeepCloneableList<TEntity>(entityCollection));
}
});
}
/// <summary>
/// Looks up the zero count cache, must return null if it doesn't exist
/// </summary>
/// <returns></returns>
protected bool HasZeroCountCache()
{
if (_hasZeroCountCache.HasValue)
return _hasZeroCountCache.Value;
_hasZeroCountCache = Cache.GetCacheItem<DeepCloneableList<TEntity>>(GetCacheTypeKey()) != null;
return _hasZeroCountCache.Value;
}
/// <summary>
/// This policy will cache the full data set as a single collection
/// </summary>
/// <returns></returns>
protected override TEntity[] GetAllFromCache()
protected TEntity[] GetAllFromCache()
{
var found = Cache.GetCacheItem<DeepCloneableList<TEntity>>(GetCacheTypeKey());
//This method will get called before checking for zero count cache, so we'll just set the flag here
_hasZeroCountCache = found != null;
return found == null ? new TEntity[] { } : found.WhereNotNull().ToArray();
}
}
}
@@ -1,3 +1,5 @@
using System;
using System.Collections.Generic;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Cache
@@ -11,15 +13,21 @@ namespace Umbraco.Core.Cache
where TEntity : class, IAggregateRoot
{
private readonly IRuntimeCacheProvider _runtimeCache;
public FullDataSetRepositoryCachePolicyFactory(IRuntimeCacheProvider runtimeCache)
private readonly Func<TEntity, TId> _getEntityId;
private readonly Func<IEnumerable<TEntity>> _getAllFromRepo;
private readonly bool _expires;
public FullDataSetRepositoryCachePolicyFactory(IRuntimeCacheProvider runtimeCache, Func<TEntity, TId> getEntityId, Func<IEnumerable<TEntity>> getAllFromRepo, bool expires)
{
_runtimeCache = runtimeCache;
_getEntityId = getEntityId;
_getAllFromRepo = getAllFromRepo;
_expires = expires;
}
public virtual IRepositoryCachePolicy<TEntity, TId> CreatePolicy()
{
return new FullDataSetRepositoryCachePolicy<TEntity, TId>(_runtimeCache);
return new FullDataSetRepositoryCachePolicy<TEntity, TId>(_runtimeCache, _getEntityId, _getAllFromRepo, _expires);
}
}
}
@@ -10,9 +10,7 @@ namespace Umbraco.Core.Cache
TEntity Get(TId id, Func<TId, TEntity> getFromRepo);
TEntity Get(TId id);
bool Exists(TId id, Func<TId, bool> getFromRepo);
string GetCacheIdKey(object id);
string GetCacheTypeKey();
void CreateOrUpdate(TEntity entity, Action<TEntity> persistMethod);
void Remove(TEntity entity, Action<TEntity> persistMethod);
TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> getFromRepo);
@@ -12,7 +12,7 @@ namespace Umbraco.Core.Cache
/// </remarks>
public class IsolatedRuntimeCache
{
private readonly Func<Type, IRuntimeCacheProvider> _cacheFactory;
internal Func<Type, IRuntimeCacheProvider> CacheFactory { get; set; }
/// <summary>
/// Constructor that allows specifying a factory for the type of runtime isolated cache to create
@@ -20,7 +20,7 @@ namespace Umbraco.Core.Cache
/// <param name="cacheFactory"></param>
public IsolatedRuntimeCache(Func<Type, IRuntimeCacheProvider> cacheFactory)
{
_cacheFactory = cacheFactory;
CacheFactory = cacheFactory;
}
private readonly ConcurrentDictionary<Type, IRuntimeCacheProvider> _isolatedCache = new ConcurrentDictionary<Type, IRuntimeCacheProvider>();
@@ -32,7 +32,7 @@ namespace Umbraco.Core.Cache
/// <returns></returns>
public IRuntimeCacheProvider GetOrCreateCache<T>()
{
return _isolatedCache.GetOrAdd(typeof(T), type => _cacheFactory(type));
return _isolatedCache.GetOrAdd(typeof(T), type => CacheFactory(type));
}
/// <summary>
@@ -41,7 +41,7 @@ namespace Umbraco.Core.Cache
/// <returns></returns>
public IRuntimeCacheProvider GetOrCreateCache(Type type)
{
return _isolatedCache.GetOrAdd(type, t => _cacheFactory(t));
return _isolatedCache.GetOrAdd(type, t => CacheFactory(t));
}
/// <summary>
@@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Cache
{
internal abstract class RepositoryCachePolicyBase<TEntity, TId> : DisposableObject, IRepositoryCachePolicy<TEntity, TId>
where TEntity : class, IAggregateRoot
{
private Action _action;
protected RepositoryCachePolicyBase(IRuntimeCacheProvider cache)
{
if (cache == null) throw new ArgumentNullException("cache");
Cache = cache;
}
protected IRuntimeCacheProvider Cache { get; private set; }
/// <summary>
/// The disposal performs the caching
/// </summary>
protected override void DisposeResources()
{
if (_action != null)
{
_action();
}
}
/// <summary>
/// Sets the action to execute on disposal
/// </summary>
/// <param name="action"></param>
protected void SetCacheAction(Action action)
{
_action = action;
}
public abstract TEntity Get(TId id, Func<TId, TEntity> getFromRepo);
public abstract TEntity Get(TId id);
public abstract bool Exists(TId id, Func<TId, bool> getFromRepo);
public abstract void CreateOrUpdate(TEntity entity, Action<TEntity> persistMethod);
public abstract void Remove(TEntity entity, Action<TEntity> persistMethod);
public abstract TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> getFromRepo);
}
}
@@ -18,7 +18,7 @@ namespace Umbraco.Core.Cache
protected override void SetCacheAction(TId[] ids, TEntity[] entityCollection)
{
//do nothing
//no-op
}
}
}
+44 -46
View File
@@ -18,12 +18,8 @@ namespace Umbraco.Core
/// </summary>
public class CacheHelper
{
private readonly IsolatedRuntimeCache _isolatedCacheManager;
private readonly ICacheProvider _requestCache;
private static readonly ICacheProvider NullRequestCache = new NullCacheProvider();
private readonly ICacheProvider _staticCache;
private static readonly ICacheProvider NullStaticCache = new NullCacheProvider();
private readonly IRuntimeCacheProvider _runtimeCache;
private static readonly IRuntimeCacheProvider NullRuntimeCache = new NullCacheProvider();
/// <summary>
@@ -90,45 +86,33 @@ namespace Umbraco.Core
if (staticCacheProvider == null) throw new ArgumentNullException("staticCacheProvider");
if (requestCacheProvider == null) throw new ArgumentNullException("requestCacheProvider");
if (isolatedCacheManager == null) throw new ArgumentNullException("isolatedCacheManager");
_runtimeCache = httpCacheProvider;
_staticCache = staticCacheProvider;
_requestCache = requestCacheProvider;
_isolatedCacheManager = isolatedCacheManager;
RuntimeCache = httpCacheProvider;
StaticCache = staticCacheProvider;
RequestCache = requestCacheProvider;
IsolatedRuntimeCache = isolatedCacheManager;
}
/// <summary>
/// Returns the current Request cache
/// </summary>
public ICacheProvider RequestCache
{
get { return _requestCache; }
}
public ICacheProvider RequestCache { get; internal set; }
/// <summary>
/// Returns the current Runtime cache
/// </summary>
public ICacheProvider StaticCache
{
get { return _staticCache; }
}
public ICacheProvider StaticCache { get; internal set; }
/// <summary>
/// Returns the current Runtime cache
/// </summary>
public IRuntimeCacheProvider RuntimeCache
{
get { return _runtimeCache; }
}
public IRuntimeCacheProvider RuntimeCache { get; internal set; }
/// <summary>
/// Returns the current Isolated Runtime cache manager
/// </summary>
public IsolatedRuntimeCache IsolatedRuntimeCache
{
get { return _isolatedCacheManager; }
}
#region Legacy Runtime/Http Cache accessors
public IsolatedRuntimeCache IsolatedRuntimeCache { get; internal set; }
#region Legacy Runtime/Http Cache accessors
/// <summary>
/// Clears the item in umbraco's runtime cache
@@ -137,8 +121,8 @@ namespace Umbraco.Core
[EditorBrowsable(EditorBrowsableState.Never)]
public void ClearAllCache()
{
_runtimeCache.ClearAllCache();
_isolatedCacheManager.ClearAllCaches();
RuntimeCache.ClearAllCache();
IsolatedRuntimeCache.ClearAllCaches();
}
/// <summary>
@@ -149,7 +133,7 @@ namespace Umbraco.Core
[EditorBrowsable(EditorBrowsableState.Never)]
public void ClearCacheItem(string key)
{
_runtimeCache.ClearCacheItem(key);
RuntimeCache.ClearCacheItem(key);
}
@@ -161,7 +145,7 @@ namespace Umbraco.Core
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
public void ClearCacheObjectTypes(string typeName)
{
_runtimeCache.ClearCacheObjectTypes(typeName);
RuntimeCache.ClearCacheObjectTypes(typeName);
}
/// <summary>
@@ -171,7 +155,7 @@ namespace Umbraco.Core
[EditorBrowsable(EditorBrowsableState.Never)]
public void ClearCacheObjectTypes<T>()
{
_runtimeCache.ClearCacheObjectTypes<T>();
RuntimeCache.ClearCacheObjectTypes<T>();
}
/// <summary>
@@ -182,7 +166,7 @@ namespace Umbraco.Core
[EditorBrowsable(EditorBrowsableState.Never)]
public void ClearCacheByKeySearch(string keyStartsWith)
{
_runtimeCache.ClearCacheByKeySearch(keyStartsWith);
RuntimeCache.ClearCacheByKeySearch(keyStartsWith);
}
/// <summary>
@@ -193,14 +177,14 @@ namespace Umbraco.Core
[EditorBrowsable(EditorBrowsableState.Never)]
public void ClearCacheByKeyExpression(string regexString)
{
_runtimeCache.ClearCacheByKeyExpression(regexString);
RuntimeCache.ClearCacheByKeyExpression(regexString);
}
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
[EditorBrowsable(EditorBrowsableState.Never)]
public IEnumerable<T> GetCacheItemsByKeySearch<T>(string keyStartsWith)
{
return _runtimeCache.GetCacheItemsByKeySearch<T>(keyStartsWith);
return RuntimeCache.GetCacheItemsByKeySearch<T>(keyStartsWith);
}
/// <summary>
@@ -213,7 +197,7 @@ namespace Umbraco.Core
[EditorBrowsable(EditorBrowsableState.Never)]
public TT GetCacheItem<TT>(string cacheKey)
{
return _runtimeCache.GetCacheItem<TT>(cacheKey);
return RuntimeCache.GetCacheItem<TT>(cacheKey);
}
/// <summary>
@@ -227,7 +211,7 @@ namespace Umbraco.Core
[EditorBrowsable(EditorBrowsableState.Never)]
public TT GetCacheItem<TT>(string cacheKey, Func<TT> getCacheItem)
{
return _runtimeCache.GetCacheItem<TT>(cacheKey, getCacheItem);
return RuntimeCache.GetCacheItem<TT>(cacheKey, getCacheItem);
}
@@ -244,7 +228,7 @@ namespace Umbraco.Core
public TT GetCacheItem<TT>(string cacheKey,
TimeSpan timeout, Func<TT> getCacheItem)
{
return _runtimeCache.GetCacheItem<TT>(cacheKey, getCacheItem, timeout);
return RuntimeCache.GetCacheItem<TT>(cacheKey, getCacheItem, timeout);
}
@@ -263,7 +247,7 @@ namespace Umbraco.Core
CacheItemRemovedCallback refreshAction, TimeSpan timeout,
Func<TT> getCacheItem)
{
return _runtimeCache.GetCacheItem<TT>(cacheKey, getCacheItem, timeout, removedCallback: refreshAction);
return RuntimeCache.GetCacheItem<TT>(cacheKey, getCacheItem, timeout, removedCallback: refreshAction);
}
@@ -283,7 +267,7 @@ namespace Umbraco.Core
CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan timeout,
Func<TT> getCacheItem)
{
return _runtimeCache.GetCacheItem<TT>(cacheKey, getCacheItem, timeout, false, priority, refreshAction);
return RuntimeCache.GetCacheItem<TT>(cacheKey, getCacheItem, timeout, false, priority, refreshAction);
}
@@ -306,7 +290,7 @@ namespace Umbraco.Core
TimeSpan timeout,
Func<TT> getCacheItem)
{
var cache = _runtimeCache as HttpRuntimeCacheProvider;
var cache = GetHttpRuntimeCacheProvider(RuntimeCache);
if (cache != null)
{
var result = cache.GetCacheItem(cacheKey, () => getCacheItem(), timeout, false, priority, refreshAction, cacheDependency);
@@ -330,7 +314,7 @@ namespace Umbraco.Core
CacheDependency cacheDependency,
Func<TT> getCacheItem)
{
var cache = _runtimeCache as HttpRuntimeCacheProvider;
var cache = GetHttpRuntimeCacheProvider(RuntimeCache);
if (cache != null)
{
var result = cache.GetCacheItem(cacheKey, () => getCacheItem(), null, false, priority, null, cacheDependency);
@@ -352,7 +336,7 @@ namespace Umbraco.Core
CacheItemPriority priority,
Func<T> getCacheItem)
{
_runtimeCache.InsertCacheItem<T>(cacheKey, getCacheItem, priority: priority);
RuntimeCache.InsertCacheItem<T>(cacheKey, getCacheItem, priority: priority);
}
@@ -371,7 +355,7 @@ namespace Umbraco.Core
TimeSpan timeout,
Func<T> getCacheItem)
{
_runtimeCache.InsertCacheItem<T>(cacheKey, getCacheItem, timeout, priority: priority);
RuntimeCache.InsertCacheItem<T>(cacheKey, getCacheItem, timeout, priority: priority);
}
/// <summary>
@@ -390,7 +374,7 @@ namespace Umbraco.Core
TimeSpan timeout,
Func<T> getCacheItem)
{
var cache = _runtimeCache as HttpRuntimeCacheProvider;
var cache = GetHttpRuntimeCacheProvider(RuntimeCache);
if (cache != null)
{
cache.InsertCacheItem(cacheKey, () => getCacheItem(), timeout, false, priority, null, cacheDependency);
@@ -416,7 +400,7 @@ namespace Umbraco.Core
TimeSpan? timeout,
Func<T> getCacheItem)
{
var cache = _runtimeCache as HttpRuntimeCacheProvider;
var cache = GetHttpRuntimeCacheProvider(RuntimeCache);
if (cache != null)
{
cache.InsertCacheItem(cacheKey, () => getCacheItem(), timeout, false, priority, refreshAction, cacheDependency);
@@ -425,6 +409,20 @@ namespace Umbraco.Core
}
#endregion
}
private HttpRuntimeCacheProvider GetHttpRuntimeCacheProvider(IRuntimeCacheProvider runtimeCache)
{
HttpRuntimeCacheProvider cache;
var wrapper = RuntimeCache as IRuntimeCacheProviderWrapper;
if (wrapper != null)
{
cache = wrapper.InnerProvider as HttpRuntimeCacheProvider;
}
else
{
cache = RuntimeCache as HttpRuntimeCacheProvider;
}
return cache;
}
}
}
@@ -14,18 +14,24 @@ namespace Umbraco.Core.Collections
/// <typeparam name="T"></typeparam>
internal class DeepCloneableList<T> : List<T>, IDeepCloneable, IRememberBeingDirty
{
/// <summary>
/// Initializes a new instance of the <see cref="T:System.Collections.Generic.List`1"/> class that is empty and has the default initial capacity.
/// </summary>
public DeepCloneableList()
private readonly ListCloneBehavior _listCloneBehavior;
public DeepCloneableList(ListCloneBehavior listCloneBehavior)
{
_listCloneBehavior = listCloneBehavior;
}
public DeepCloneableList(IEnumerable<T> collection, ListCloneBehavior listCloneBehavior) : base(collection)
{
_listCloneBehavior = listCloneBehavior;
}
/// <summary>
/// Initializes a new instance of the <see cref="T:System.Collections.Generic.List`1"/> class that contains elements copied from the specified collection and has sufficient capacity to accommodate the number of elements copied.
/// Default behavior is CloneOnce
/// </summary>
/// <param name="collection">The collection whose elements are copied to the new list.</param><exception cref="T:System.ArgumentNullException"><paramref name="collection"/> is null.</exception>
public DeepCloneableList(IEnumerable<T> collection) : base(collection)
/// <param name="collection"></param>
public DeepCloneableList(IEnumerable<T> collection)
: this(collection, ListCloneBehavior.CloneOnce)
{
}
@@ -35,20 +41,47 @@ namespace Umbraco.Core.Collections
/// <returns></returns>
public object DeepClone()
{
var newList = new DeepCloneableList<T>();
foreach (var item in this)
switch (_listCloneBehavior)
{
var dc = item as IDeepCloneable;
if (dc != null)
{
newList.Add((T) dc.DeepClone());
}
else
{
newList.Add(item);
}
case ListCloneBehavior.CloneOnce:
//we are cloning once, so create a new list in none mode
// and deep clone all items into it
var newList = new DeepCloneableList<T>(ListCloneBehavior.None);
foreach (var item in this)
{
var dc = item as IDeepCloneable;
if (dc != null)
{
newList.Add((T)dc.DeepClone());
}
else
{
newList.Add(item);
}
}
return newList;
case ListCloneBehavior.None:
//we are in none mode, so just return a new list with the same items
return new DeepCloneableList<T>(this, ListCloneBehavior.None);
case ListCloneBehavior.Always:
//always clone to new list
var newList2 = new DeepCloneableList<T>(ListCloneBehavior.Always);
foreach (var item in this)
{
var dc = item as IDeepCloneable;
if (dc != null)
{
newList2.Add((T)dc.DeepClone());
}
else
{
newList2.Add(item);
}
}
return newList2;
default:
throw new ArgumentOutOfRangeException();
}
return newList;
}
public bool IsDirty()
@@ -0,0 +1,20 @@
namespace Umbraco.Core.Collections
{
internal enum ListCloneBehavior
{
/// <summary>
/// When set, DeepClone will clone the items one time and the result list behavior will be None
/// </summary>
CloneOnce,
/// <summary>
/// When set, DeepClone will not clone any items
/// </summary>
None,
/// <summary>
/// When set, DeepClone will always clone all items
/// </summary>
Always
}
}
@@ -6,7 +6,7 @@ namespace Umbraco.Core.Configuration
{
public class UmbracoVersion
{
private static readonly Version Version = new Version("7.4.0");
private static readonly Version Version = new Version("7.4.2");
/// <summary>
/// Gets the current version of Umbraco.
@@ -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 "beta2"; } }
public static string CurrentComment { get { return ""; } }
// 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
+6
View File
@@ -10,6 +10,12 @@ namespace Umbraco.Core
/// </summary>
public static class Web
{
public const string UmbracoContextDataToken = "umbraco-context";
public const string UmbracoDataToken = "umbraco";
public const string PublishedDocumentRequestDataToken = "umbraco-doc-request";
public const string CustomRouteDataToken = "umbraco-custom-route";
public const string UmbracoRouteDefinitionDataToken = "umbraco-route-def";
/// <summary>
/// The preview cookie name
/// </summary>
+12 -3
View File
@@ -136,7 +136,10 @@ namespace Umbraco.Core
{
try
{
x.OnApplicationInitialized(UmbracoApplication, ApplicationContext);
using (ProfilingLogger.DebugDuration<CoreBootManager>(string.Format("Executing {0} in ApplicationInitialized", x.GetType())))
{
x.OnApplicationInitialized(UmbracoApplication, ApplicationContext);
}
}
catch (Exception ex)
{
@@ -299,7 +302,10 @@ namespace Umbraco.Core
{
try
{
x.OnApplicationStarting(UmbracoApplication, ApplicationContext);
using (ProfilingLogger.DebugDuration<CoreBootManager>(string.Format("Executing {0} in ApplicationStarting", x.GetType())))
{
x.OnApplicationStarting(UmbracoApplication, ApplicationContext);
}
}
catch (Exception ex)
{
@@ -350,7 +356,10 @@ namespace Umbraco.Core
{
try
{
x.OnApplicationStarted(UmbracoApplication, ApplicationContext);
using (ProfilingLogger.DebugDuration<CoreBootManager>(string.Format("Executing {0} in ApplicationStarted", x.GetType())))
{
x.OnApplicationStarted(UmbracoApplication, ApplicationContext);
}
}
catch (Exception ex)
{
+44 -21
View File
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Web;
@@ -12,6 +13,12 @@ namespace Umbraco.Core
/// </summary>
public class DisposableTimer : DisposableObject
{
private readonly ILogger _logger;
private readonly LogType? _logType;
private readonly IProfiler _profiler;
private readonly Type _loggerType;
private readonly string _endMessage;
private readonly IDisposable _profilerStep;
private readonly Stopwatch _stopwatch = Stopwatch.StartNew();
private readonly Action<long> _callback;
@@ -25,25 +32,12 @@ namespace Umbraco.Core
if (logger == null) throw new ArgumentNullException("logger");
if (loggerType == null) throw new ArgumentNullException("loggerType");
_callback = x =>
{
if (profiler != null)
{
profiler.DisposeIfDisposable();
}
switch (logType)
{
case LogType.Debug:
logger.Debug(loggerType, () => endMessage + " (took " + x + "ms)");
break;
case LogType.Info:
logger.Info(loggerType, () => endMessage + " (took " + x + "ms)");
break;
default:
throw new ArgumentOutOfRangeException("logType");
}
};
_logger = logger;
_logType = logType;
_profiler = profiler;
_loggerType = loggerType;
_endMessage = endMessage;
switch (logType)
{
case LogType.Debug:
@@ -58,7 +52,7 @@ namespace Umbraco.Core
if (profiler != null)
{
profiler.Step(loggerType, startMessage);
_profilerStep = profiler.Step(loggerType, startMessage);
}
}
@@ -223,7 +217,36 @@ namespace Umbraco.Core
/// </summary>
protected override void DisposeResources()
{
_callback.Invoke(Stopwatch.ElapsedMilliseconds);
if (_profiler != null)
{
_profiler.DisposeIfDisposable();
}
if (_profilerStep != null)
{
_profilerStep.Dispose();
}
if (_logType.HasValue && _endMessage.IsNullOrWhiteSpace() == false && _loggerType != null && _logger != null)
{
switch (_logType)
{
case LogType.Debug:
_logger.Debug(_loggerType, () => _endMessage + " (took " + Stopwatch.ElapsedMilliseconds + "ms)");
break;
case LogType.Info:
_logger.Info(_loggerType, () => _endMessage + " (took " + Stopwatch.ElapsedMilliseconds + "ms)");
break;
default:
throw new ArgumentOutOfRangeException("logType");
}
}
if (_callback != null)
{
_callback.Invoke(Stopwatch.ElapsedMilliseconds);
}
}
}
@@ -0,0 +1,93 @@
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Reflection;
namespace Umbraco.Core.Dynamics
{
/// <summary>
/// This will check enable dynamic access to properties and methods in a case insensitive manner
/// </summary>
/// <typeparam name="T"></typeparam>
/// <remarks>
/// This works by using reflection on the type - the reflection lookup is lazy so it will not execute unless a dynamic method needs to be accessed
/// </remarks>
public abstract class CaseInsensitiveDynamicObject<T> : DynamicObject
where T: class
{
/// <summary>
/// Used for dynamic access for case insensitive property access
/// </summary>`
private static readonly Lazy<IDictionary<string, Func<T, object>>> CaseInsensitivePropertyAccess = new Lazy<IDictionary<string, Func<T, object>>>(() =>
{
var props = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public)
.DistinctBy(x => x.Name);
return props.Select(propInfo =>
{
var name = propInfo.Name.ToLowerInvariant();
Func<T, object> getVal = propInfo.GetValue;
return new KeyValuePair<string, Func<T, object>>(name, getVal);
}).ToDictionary(x => x.Key, x => x.Value);
});
/// <summary>
/// Used for dynamic access for case insensitive property access
/// </summary>
private static readonly Lazy<IDictionary<string, Tuple<ParameterInfo[], Func<T, object[], object>>>> CaseInsensitiveMethodAccess
= new Lazy<IDictionary<string, Tuple<ParameterInfo[], Func<T, object[], object>>>>(() =>
{
var props = typeof(T).GetMethods(BindingFlags.Instance | BindingFlags.Public)
.Where(x => x.IsSpecialName == false && x.IsVirtual == false)
.DistinctBy(x => x.Name);
return props.Select(methodInfo =>
{
var name = methodInfo.Name.ToLowerInvariant();
Func<T, object[], object> getVal = methodInfo.Invoke;
var val = new Tuple<ParameterInfo[], Func<T, object[], object>>(methodInfo.GetParameters(), getVal);
return new KeyValuePair<string, Tuple<ParameterInfo[], Func<T, object[], object>>>(name, val);
}).ToDictionary(x => x.Key, x => x.Value);
});
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
var name = binder.Name.ToLowerInvariant();
if (CaseInsensitiveMethodAccess.Value.ContainsKey(name) == false)
return base.TryInvokeMember(binder, args, out result);
var val = CaseInsensitiveMethodAccess.Value[name];
var parameters = val.Item1;
var callback = val.Item2;
var fullArgs = new List<object>(args);
if (args.Length <= parameters.Length)
{
//need to fill them up if they're optional
for (var i = args.Length; i < parameters.Length; i++)
{
if (parameters[i].IsOptional)
{
fullArgs.Add(parameters[i].DefaultValue);
}
}
if (fullArgs.Count == parameters.Length)
{
result = callback((T)(object)this, fullArgs.ToArray());
return true;
}
}
return base.TryInvokeMember(binder, args, out result);
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
var name = binder.Name.ToLowerInvariant();
if (CaseInsensitivePropertyAccess.Value.ContainsKey(name) == false)
return base.TryGetMember(binder, out result);
result = CaseInsensitivePropertyAccess.Value[name]((T)(object)this);
return true;
}
}
}
@@ -64,7 +64,7 @@ namespace Umbraco.Core.Dynamics
/// </summary>
public class DynamicXmlConverter : TypeConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context, Type sourceType)
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
var convertableTypes = new[]
{
@@ -78,8 +78,8 @@ namespace Umbraco.Core.Dynamics
typeof(RawXmlDocument)
};
return convertableTypes.Any(x => TypeHelper.IsTypeAssignableFrom(x, sourceType))
|| base.CanConvertFrom(context, sourceType);
return convertableTypes.Any(x => TypeHelper.IsTypeAssignableFrom(x, destinationType))
|| base.CanConvertFrom(context, destinationType);
}
public override object ConvertTo(
@@ -5,8 +5,10 @@ using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Linq.Expressions;
using System.Text;
using System.Web.Services.Description;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
namespace Umbraco.Core.Dynamics
{
@@ -20,6 +22,20 @@ namespace Umbraco.Core.Dynamics
/// </summary>
private static readonly ConcurrentDictionary<Tuple<Type, string, int>, MethodInfo[]> MethodCache = new ConcurrentDictionary<Tuple<Type, string, int>, MethodInfo[]>();
private static IEnumerable<Type> GetTypes(Assembly a)
{
try
{
return TypeFinder.GetTypesWithFormattedException(a);
}
catch (ReflectionTypeLoadException ex)
{
// is this going to flood the log?
LogHelper.Error(typeof (ExtensionMethodFinder), "Failed to get types.", ex);
return Enumerable.Empty<Type>();
}
}
/// <summary>
/// Returns the enumerable of all extension method info's in the app domain = USE SPARINGLY!!!
/// </summary>
@@ -36,7 +52,7 @@ namespace Umbraco.Core.Dynamics
// assemblies that contain extension methods
.Where(a => a.IsDefined(typeof (ExtensionAttribute), false))
// types that contain extension methods
.SelectMany(a => a.GetTypes()
.SelectMany(a => GetTypes(a)
.Where(t => t.IsDefined(typeof (ExtensionAttribute), false) && t.IsSealed && t.IsGenericType == false && t.IsNested == false))
// actual extension methods
.SelectMany(t => t.GetMethods(BindingFlags.Static | BindingFlags.Public)
@@ -45,9 +61,9 @@ namespace Umbraco.Core.Dynamics
.Concat(typeof (Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public))
//If we don't do this then we'll be scanning all assemblies each time!
.ToArray(),
//only cache for 5 minutes
timeout: TimeSpan.FromMinutes(5),
timeout: TimeSpan.FromMinutes(5),
//each time this is accessed it will be for 5 minutes longer
isSliding:true);
@@ -57,7 +73,7 @@ namespace Umbraco.Core.Dynamics
/// Returns all extension methods found matching the definition
/// </summary>
/// <param name="runtimeCache">
/// The runtime cache is used to temporarily cache all extension methods found in the app domain so that
/// The runtime cache is used to temporarily cache all extension methods found in the app domain so that
/// while we search for individual extension methods, the process will be reasonably 'quick'. We then statically
/// cache the MethodInfo's that we are looking for and then the runtime cache will expire and give back all that memory.
/// </param>
@@ -78,7 +94,7 @@ namespace Umbraco.Core.Dynamics
{
var candidates = GetAllExtensionMethodsInAppDomain(runtimeCache);
// filter by name
// filter by name
var filtr1 = candidates.Where(m => m.Name == name);
// filter by args count
@@ -102,7 +118,7 @@ namespace Umbraco.Core.Dynamics
return filtr3.ToArray();
});
}
private static MethodInfo DetermineMethodFromParams(IEnumerable<MethodInfo> methods, Type genericType, IEnumerable<object> args)
@@ -123,12 +139,12 @@ namespace Umbraco.Core.Dynamics
types = method.GetParameters().Select(pi => pi.ParameterType).Skip(1)
});
//This type comparer will check
//This type comparer will check
var typeComparer = new DelegateEqualityComparer<Type>(
//Checks if the argument type passed in can be assigned from the parameter type in the method. For
//Checks if the argument type passed in can be assigned from the parameter type in the method. For
// example, if the argument type is HtmlHelper<MyModel> but the method parameter type is HtmlHelper then
// it will match because the argument is assignable to that parameter type and will be able to execute
TypeHelper.IsTypeAssignableFrom,
TypeHelper.IsTypeAssignableFrom,
//This will not ever execute but if it does we need to get the hash code of the string because the hash
// code of a type is random
type => type.FullName.GetHashCode());
@@ -159,7 +175,7 @@ namespace Umbraco.Core.Dynamics
.ToArray();
var methods = GetAllExtensionMethods(runtimeCache, thisType, name, args.Length).ToArray();
return DetermineMethodFromParams(methods, genericType, args);
}
}
@@ -1,5 +1,8 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Security.Permissions;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.Events
{
@@ -11,11 +14,19 @@ namespace Umbraco.Core.Events
{
private bool _cancel;
public CancellableEventArgs(bool canCancel, EventMessages messages, IDictionary<string, object> additionalData)
{
CanCancel = canCancel;
Messages = messages;
AdditionalData = new ReadOnlyDictionary<string, object>(additionalData);
}
public CancellableEventArgs(bool canCancel, EventMessages eventMessages)
{
if (eventMessages == null) throw new ArgumentNullException("eventMessages");
CanCancel = canCancel;
Messages = eventMessages;
AdditionalData = new ReadOnlyDictionary<string, object>(new Dictionary<string, object>());
}
public CancellableEventArgs(bool canCancel)
@@ -23,6 +34,7 @@ namespace Umbraco.Core.Events
CanCancel = canCancel;
//create a standalone messages
Messages = new EventMessages();
AdditionalData = new ReadOnlyDictionary<string, object>(new Dictionary<string, object>());
}
public CancellableEventArgs(EventMessages eventMessages)
@@ -78,5 +90,14 @@ namespace Umbraco.Core.Events
/// Returns the EventMessages object which is used to add messages to the message collection for this event
/// </summary>
public EventMessages Messages { get; private set; }
/// <summary>
/// In some cases raised evens might need to contain additional arbitrary readonly data which can be read by event subscribers
/// </summary>
/// <remarks>
/// This allows for a bit of flexibility in our event raising - it's not pretty but we need to maintain backwards compatibility
/// so we cannot change the strongly typed nature for some events.
/// </remarks>
public ReadOnlyDictionary<string, object> AdditionalData { get; private set; }
}
}
@@ -1,3 +1,4 @@
using System.Collections.Generic;
using System.Security.Permissions;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
@@ -11,8 +12,13 @@ namespace Umbraco.Core.Events
[HostProtection(SecurityAction.LinkDemand, SharedState = true)]
public class CancellableObjectEventArgs<T> : CancellableEventArgs
{
public CancellableObjectEventArgs(T eventObject, bool canCancel, EventMessages messages, IDictionary<string, object> additionalData)
: base(canCancel, messages, additionalData)
{
EventObject = eventObject;
}
public CancellableObjectEventArgs(T eventObject, bool canCancel, EventMessages eventMessages)
public CancellableObjectEventArgs(T eventObject, bool canCancel, EventMessages eventMessages)
: base(canCancel, eventMessages)
{
EventObject = eventObject;
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Umbraco.Core.Events
+63 -24
View File
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.ComponentModel;
using Semver;
using Umbraco.Core.Configuration;
using Umbraco.Core.Persistence.Migrations;
namespace Umbraco.Core.Events
@@ -13,23 +14,49 @@ namespace Umbraco.Core.Events
/// </summary>
/// <param name="eventObject"></param>
/// <param name="targetVersion"></param>
/// <param name="productName"></param>
/// <param name="canCancel"></param>
/// <param name="configuredVersion"></param>
public MigrationEventArgs(IList<IMigration> eventObject, SemVersion configuredVersion, SemVersion targetVersion, bool canCancel)
: base(eventObject, canCancel)
{
ConfiguredSemVersion = configuredVersion;
TargetSemVersion = targetVersion;
}
public MigrationEventArgs(IList<IMigration> eventObject, SemVersion configuredVersion, SemVersion targetVersion, string productName, bool canCancel)
: this(eventObject, null, configuredVersion, targetVersion, productName, canCancel)
{ }
[Obsolete("Use constructor accepting UmbracoVersion instances instead")]
/// <summary>
/// Constructor accepting multiple migrations that are used in the migration runner
/// </summary>
/// <param name="eventObject"></param>
/// <param name="targetVersion"></param>
/// <param name="canCancel"></param>
/// <param name="configuredVersion"></param>
[Obsolete("Use constructor accepting a product name instead.")]
[EditorBrowsable(EditorBrowsableState.Never)]
public MigrationEventArgs(IList<IMigration> eventObject, SemVersion configuredVersion, SemVersion targetVersion, bool canCancel)
: this(eventObject, null, configuredVersion, targetVersion, GlobalSettings.UmbracoMigrationName, canCancel)
{ }
[Obsolete("Use constructor accepting SemVersion instances and a product name instead.")]
[EditorBrowsable(EditorBrowsableState.Never)]
public MigrationEventArgs(IList<IMigration> eventObject, Version configuredVersion, Version targetVersion, bool canCancel)
: base(eventObject, canCancel)
{
ConfiguredSemVersion = new SemVersion(configuredVersion);
TargetSemVersion = new SemVersion(targetVersion);
}
: this(eventObject, null, new SemVersion(configuredVersion), new SemVersion(targetVersion), GlobalSettings.UmbracoMigrationName, canCancel)
{ }
/// <summary>
/// Constructor accepting multiple migrations that are used in the migration runner
/// </summary>
/// <param name="eventObject"></param>
/// <param name="migrationContext"></param>
/// <param name="targetVersion"></param>
/// <param name="productName"></param>
/// <param name="canCancel"></param>
/// <param name="configuredVersion"></param>
internal MigrationEventArgs(IList<IMigration> eventObject, MigrationContext migrationContext, SemVersion configuredVersion, SemVersion targetVersion, string productName, bool canCancel)
: base(eventObject, canCancel)
{
MigrationContext = migrationContext;
ConfiguredSemVersion = configuredVersion;
TargetSemVersion = targetVersion;
ProductName = productName;
}
/// <summary>
/// Constructor accepting multiple migrations that are used in the migration runner
@@ -39,12 +66,15 @@ namespace Umbraco.Core.Events
/// <param name="targetVersion"></param>
/// <param name="canCancel"></param>
/// <param name="configuredVersion"></param>
[Obsolete("Use constructor accepting a product name instead.")]
[EditorBrowsable(EditorBrowsableState.Never)]
internal MigrationEventArgs(IList<IMigration> eventObject, MigrationContext migrationContext, SemVersion configuredVersion, SemVersion targetVersion, bool canCancel)
: base(eventObject, canCancel)
{
MigrationContext = migrationContext;
ConfiguredSemVersion = configuredVersion;
TargetSemVersion = targetVersion;
ProductName = GlobalSettings.UmbracoMigrationName;
}
/// <summary>
@@ -53,21 +83,28 @@ namespace Umbraco.Core.Events
/// <param name="eventObject"></param>
/// <param name="configuredVersion"></param>
/// <param name="targetVersion"></param>
public MigrationEventArgs(IList<IMigration> eventObject, SemVersion configuredVersion, SemVersion targetVersion)
: base(eventObject)
{
ConfiguredSemVersion = configuredVersion;
TargetSemVersion = targetVersion;
}
/// <param name="productName"></param>
public MigrationEventArgs(IList<IMigration> eventObject, SemVersion configuredVersion, SemVersion targetVersion, string productName)
: this(eventObject, null, configuredVersion, targetVersion, productName, false)
{ }
[Obsolete("Use constructor accepting UmbracoVersion instances instead")]
/// <summary>
/// Constructor accepting multiple migrations that are used in the migration runner
/// </summary>
/// <param name="eventObject"></param>
/// <param name="configuredVersion"></param>
/// <param name="targetVersion"></param>
[Obsolete("Use constructor accepting a product name instead.")]
[EditorBrowsable(EditorBrowsableState.Never)]
public MigrationEventArgs(IList<IMigration> eventObject, SemVersion configuredVersion, SemVersion targetVersion)
: this(eventObject, null, configuredVersion, targetVersion, GlobalSettings.UmbracoMigrationName, false)
{ }
[Obsolete("Use constructor accepting SemVersion instances and a product name instead.")]
[EditorBrowsable(EditorBrowsableState.Never)]
public MigrationEventArgs(IList<IMigration> eventObject, Version configuredVersion, Version targetVersion)
: base(eventObject)
{
ConfiguredSemVersion = new SemVersion(configuredVersion);
TargetSemVersion = new SemVersion(targetVersion);
}
: this(eventObject, null, new SemVersion(configuredVersion), new SemVersion(targetVersion), GlobalSettings.UmbracoMigrationName, false)
{ }
/// <summary>
/// Returns all migrations that were used in the migration runner
@@ -95,6 +132,8 @@ namespace Umbraco.Core.Events
public SemVersion TargetSemVersion { get; private set; }
public string ProductName { get; private set; }
internal MigrationContext MigrationContext { get; private set; }
}
}
+30 -6
View File
@@ -4,6 +4,18 @@ namespace Umbraco.Core.Events
{
public class SaveEventArgs<TEntity> : CancellableObjectEventArgs<IEnumerable<TEntity>>
{
/// <summary>
/// Constructor accepting multiple entities that are used in the saving operation
/// </summary>
/// <param name="eventObject"></param>
/// <param name="canCancel"></param>
/// <param name="messages"></param>
/// <param name="additionalData"></param>
public SaveEventArgs(IEnumerable<TEntity> eventObject, bool canCancel, EventMessages messages, IDictionary<string, object> additionalData)
: base(eventObject, canCancel, messages, additionalData)
{
}
/// <summary>
/// Constructor accepting multiple entities that are used in the saving operation
/// </summary>
@@ -25,12 +37,24 @@ namespace Umbraco.Core.Events
{
}
/// <summary>
/// Constructor accepting a single entity instance
/// </summary>
/// <param name="eventObject"></param>
/// <param name="eventMessages"></param>
public SaveEventArgs(TEntity eventObject, EventMessages eventMessages)
/// <summary>
/// Constructor accepting a single entity instance
/// </summary>
/// <param name="eventObject"></param>
/// <param name="canCancel"></param>
/// <param name="messages"></param>
/// <param name="additionalData"></param>
public SaveEventArgs(TEntity eventObject, bool canCancel, EventMessages messages, IDictionary<string, object> additionalData)
: base(new List<TEntity> { eventObject }, canCancel, messages, additionalData)
{
}
/// <summary>
/// Constructor accepting a single entity instance
/// </summary>
/// <param name="eventObject"></param>
/// <param name="eventMessages"></param>
public SaveEventArgs(TEntity eventObject, EventMessages eventMessages)
: base(new List<TEntity> { eventObject }, eventMessages)
{
}
+47 -10
View File
@@ -7,7 +7,7 @@ using Umbraco.Core.Models;
namespace Umbraco.Core.IO
{
internal class ViewHelper
public class ViewHelper
{
private readonly IFileSystem _viewFileSystem;
@@ -66,21 +66,58 @@ namespace Umbraco.Core.IO
return viewContent;
}
internal static string GetDefaultFileContent(string layoutPageAlias = null, string modelClassName = null)
public static string GetDefaultFileContent(string layoutPageAlias = null, string modelClassName = null, string modelNamespace = null, string modelNamespaceAlias = null)
{
var design = @"@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@{
Layout = null;
}";
var content = new StringBuilder();
if (layoutPageAlias.IsNullOrWhiteSpace() == false)
design = design.Replace("null", string.Format("\"{0}.cshtml\"", layoutPageAlias));
if (string.IsNullOrWhiteSpace(modelNamespaceAlias))
modelNamespaceAlias = "ContentModels";
// either
// @inherits Umbraco.Web.Mvc.UmbracoTemplatePage
// @inherits Umbraco.Web.Mvc.UmbracoTemplatePage<ModelClass>
// @inherits Umbraco.Web.Mvc.UmbracoTemplatePage<ContentModels.ModelClass>
content.Append("@inherits Umbraco.Web.Mvc.UmbracoTemplatePage");
if (modelClassName.IsNullOrWhiteSpace() == false)
design = design.Replace(".UmbracoTemplatePage", string.Format(".UmbracoTemplatePage<{0}>", modelClassName));
{
content.Append("<");
if (modelNamespace.IsNullOrWhiteSpace() == false)
{
content.Append(modelNamespaceAlias);
content.Append(".");
}
content.Append(modelClassName);
content.Append(">");
}
content.Append("\r\n");
// if required, add
// @using ContentModels = ModelNamespace;
if (modelClassName.IsNullOrWhiteSpace() == false && modelNamespace.IsNullOrWhiteSpace() == false)
{
content.Append("@using ");
content.Append(modelNamespaceAlias);
content.Append(" = ");
content.Append(modelNamespace);
content.Append(";\r\n");
}
return design;
// either
// Layout = null;
// Layout = "layoutPage.cshtml";
content.Append("@{\r\n\tLayout = ");
if (layoutPageAlias.IsNullOrWhiteSpace())
{
content.Append("null");
}
else
{
content.Append("\"");
content.Append(layoutPageAlias);
content.Append(".cshtml\"");
}
content.Append(";\r\n}");
return content.ToString();
}
private string SaveTemplateToFile(ITemplate template)
+21 -2
View File
@@ -367,8 +367,27 @@ namespace Umbraco.Core.Models
/// <param name="value">Value to set for the Property</param>
public virtual void SetPropertyValue(string propertyTypeAlias, long value)
{
string val = value.ToString();
SetValueOnProperty(propertyTypeAlias, val);
SetValueOnProperty(propertyTypeAlias, value);
}
/// <summary>
/// Sets the <see cref="System.Decimal"/> value of a Property
/// </summary>
/// <param name="propertyTypeAlias">Alias of the PropertyType</param>
/// <param name="value">Value to set for the Property</param>
public virtual void SetPropertyValue(string propertyTypeAlias, decimal value)
{
SetValueOnProperty(propertyTypeAlias, value);
}
/// <summary>
/// Sets the <see cref="System.Double"/> value of a Property
/// </summary>
/// <param name="propertyTypeAlias">Alias of the PropertyType</param>
/// <param name="value">Value to set for the Property</param>
public virtual void SetPropertyValue(string propertyTypeAlias, double value)
{
SetValueOnProperty(propertyTypeAlias, value);
}
/// <summary>
+6
View File
@@ -53,6 +53,9 @@ namespace Umbraco.Core.Models
/// <summary>
/// Gets or sets the alias of the default Template.
/// TODO: This should be ignored from cloning!!!!!!!!!!!!!!
/// - but to do that we have to implement callback hacks, this needs to be fixed in v8,
/// we should not store direct entity
/// </summary>
[IgnoreDataMember]
public ITemplate DefaultTemplate
@@ -79,6 +82,9 @@ namespace Umbraco.Core.Models
/// <summary>
/// Gets or Sets a list of Templates which are allowed for the ContentType
/// TODO: This should be ignored from cloning!!!!!!!!!!!!!!
/// - but to do that we have to implement callback hacks, this needs to be fixed in v8,
/// we should not store direct entity
/// </summary>
[DataMember]
public IEnumerable<ITemplate> AllowedTemplates
+3 -6
View File
@@ -487,11 +487,8 @@ namespace Umbraco.Core.Models
var oldPropertyGroup = PropertyGroups.FirstOrDefault(x =>
x.PropertyTypes.Any(y => y.Alias == propertyTypeAlias));
// reset PropertyGroupId, which will be re-evaluated when the content type
// is saved - what is important is group.PropertyTypes - see code in
// ContentTypeBaseRepository.PersistUpdatedBaseContentType
propertyType.PropertyGroupId = new Lazy<int>(() => default(int));
propertyType.ResetDirtyProperties(); // PropertyGroupId must not be dirty
// set new group
propertyType.PropertyGroupId = newPropertyGroup == null ? null : new Lazy<int>(() => newPropertyGroup.Id, false);
// remove from old group, if any - add to new group, if any
if (oldPropertyGroup != null)
@@ -540,7 +537,7 @@ namespace Umbraco.Core.Models
// re-assign the group's properties to no group
foreach (var property in group.PropertyTypes)
{
property.PropertyGroupId = new Lazy<int>(() => 0);
property.PropertyGroupId = null;
_propertyTypes.Add(property);
}
+99 -61
View File
@@ -9,10 +9,30 @@ namespace Umbraco.Core.Models
{
public static class DeepCloneHelper
{
/// <summary>
/// Stores the metadata for the properties for a given type so we know how to create them
/// </summary>
private struct ClonePropertyInfo
{
public ClonePropertyInfo(PropertyInfo propertyInfo) : this()
{
if (propertyInfo == null) throw new ArgumentNullException("propertyInfo");
PropertyInfo = propertyInfo;
}
public PropertyInfo PropertyInfo { get; private set; }
public bool IsDeepCloneable { get; set; }
public Type GenericListType { get; set; }
public bool IsList
{
get { return GenericListType != null; }
}
}
/// <summary>
/// Used to avoid constant reflection (perf)
/// </summary>
private static readonly ConcurrentDictionary<Type, PropertyInfo[]> PropCache = new ConcurrentDictionary<Type, PropertyInfo[]>();
private static readonly ConcurrentDictionary<Type, ClonePropertyInfo[]> PropCache = new ConcurrentDictionary<Type, ClonePropertyInfo[]>();
/// <summary>
/// Used to deep clone any reference properties on the object (should be done after a MemberwiseClone for which the outcome is 'output')
@@ -30,81 +50,99 @@ namespace Umbraco.Core.Models
throw new InvalidOperationException("Both the input and output types must be the same");
}
//get the property metadata from cache so we only have to figure this out once per type
var refProperties = PropCache.GetOrAdd(inputType, type =>
inputType.GetProperties()
.Where(x =>
//is not attributed with the ignore clone attribute
x.GetCustomAttribute<DoNotCloneAttribute>() == null
.Select<PropertyInfo, ClonePropertyInfo?>(propertyInfo =>
{
if (
//is not attributed with the ignore clone attribute
propertyInfo.GetCustomAttribute<DoNotCloneAttribute>() != null
//reference type but not string
&& x.PropertyType.IsValueType == false && x.PropertyType != typeof (string)
|| propertyInfo.PropertyType.IsValueType || propertyInfo.PropertyType == typeof (string)
//settable
&& x.CanWrite
|| propertyInfo.CanWrite == false
//non-indexed
&& x.GetIndexParameters().Any() == false)
|| propertyInfo.GetIndexParameters().Any())
{
return null;
}
if (TypeHelper.IsTypeAssignableFrom<IDeepCloneable>(propertyInfo.PropertyType))
{
return new ClonePropertyInfo(propertyInfo) { IsDeepCloneable = true };
}
if (TypeHelper.IsTypeAssignableFrom<IEnumerable>(propertyInfo.PropertyType)
&& TypeHelper.IsTypeAssignableFrom<string>(propertyInfo.PropertyType) == false)
{
if (propertyInfo.PropertyType.IsGenericType
&& (propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(IEnumerable<>)
|| propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(ICollection<>)
|| propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(IList<>)))
{
//if it is a IEnumerable<>, IList<T> or ICollection<> we'll use a List<>
var genericType = typeof(List<>).MakeGenericType(propertyInfo.PropertyType.GetGenericArguments());
return new ClonePropertyInfo(propertyInfo) { GenericListType = genericType };
}
if (propertyInfo.PropertyType.IsArray
|| (propertyInfo.PropertyType.IsInterface && propertyInfo.PropertyType.IsGenericType == false))
{
//if its an array, we'll create a list to work with first and then convert to array later
//otherwise if its just a regular derivitave of IEnumerable, we can use a list too
return new ClonePropertyInfo(propertyInfo) { GenericListType = typeof(List<object>) };
}
//skip instead of trying to create instance of abstract or interface
if (propertyInfo.PropertyType.IsAbstract || propertyInfo.PropertyType.IsInterface)
{
return null;
}
//its a custom IEnumerable, we'll try to create it
try
{
var custom = Activator.CreateInstance(propertyInfo.PropertyType);
//if it's an IList we can work with it, otherwise we cannot
var newList = custom as IList;
if (newList == null)
{
return null;
}
return new ClonePropertyInfo(propertyInfo) {GenericListType = propertyInfo.PropertyType};
}
catch (Exception)
{
//could not create this type so we'll skip it
return null;
}
}
return new ClonePropertyInfo(propertyInfo);
})
.Where(x => x.HasValue)
.Select(x => x.Value)
.ToArray());
foreach (var propertyInfo in refProperties)
foreach (var clonePropertyInfo in refProperties)
{
if (TypeHelper.IsTypeAssignableFrom<IDeepCloneable>(propertyInfo.PropertyType))
if (clonePropertyInfo.IsDeepCloneable)
{
//this ref property is also deep cloneable so clone it
var result = (IDeepCloneable)propertyInfo.GetValue(input, null);
var result = (IDeepCloneable)clonePropertyInfo.PropertyInfo.GetValue(input, null);
if (result != null)
{
//set the cloned value to the property
propertyInfo.SetValue(output, result.DeepClone(), null);
clonePropertyInfo.PropertyInfo.SetValue(output, result.DeepClone(), null);
}
}
else if (TypeHelper.IsTypeAssignableFrom<IEnumerable>(propertyInfo.PropertyType)
&& TypeHelper.IsTypeAssignableFrom<string>(propertyInfo.PropertyType) == false)
else if (clonePropertyInfo.IsList)
{
IList newList;
if (propertyInfo.PropertyType.IsGenericType
&& (propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(IEnumerable<>)
|| propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(ICollection<>)
|| propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(IList<>)))
{
//if it is a IEnumerable<>, IList<T> or ICollection<> we'll use a List<>
var genericType = typeof(List<>).MakeGenericType(propertyInfo.PropertyType.GetGenericArguments());
newList = (IList)Activator.CreateInstance(genericType);
}
else if (propertyInfo.PropertyType.IsArray
|| (propertyInfo.PropertyType.IsInterface && propertyInfo.PropertyType.IsGenericType == false))
{
//if its an array, we'll create a list to work with first and then convert to array later
//otherwise if its just a regular derivitave of IEnumerable, we can use a list too
newList = new List<object>();
}
else
{
//skip instead of trying to create instance of abstract or interface
if (propertyInfo.PropertyType.IsAbstract || propertyInfo.PropertyType.IsInterface)
{
continue;
}
//its a custom IEnumerable, we'll try to create it
try
{
var custom = Activator.CreateInstance(propertyInfo.PropertyType);
//if it's an IList we can work with it, otherwise we cannot
newList = custom as IList;
if (newList == null)
{
continue;
}
}
catch (Exception)
{
//could not create this type so we'll skip it
continue;
}
}
var enumerable = (IEnumerable)propertyInfo.GetValue(input, null);
var enumerable = (IEnumerable)clonePropertyInfo.PropertyInfo.GetValue(input, null);
if (enumerable == null) continue;
var newList = (IList)Activator.CreateInstance(clonePropertyInfo.GenericListType);
var isUsableType = true;
//now clone each item
@@ -136,21 +174,21 @@ namespace Umbraco.Core.Models
continue;
}
if (propertyInfo.PropertyType.IsArray)
if (clonePropertyInfo.PropertyInfo.PropertyType.IsArray)
{
//need to convert to array
var arr = (object[])Activator.CreateInstance(propertyInfo.PropertyType, newList.Count);
var arr = (object[])Activator.CreateInstance(clonePropertyInfo.PropertyInfo.PropertyType, newList.Count);
for (int i = 0; i < newList.Count; i++)
{
arr[i] = newList[i];
}
//set the cloned collection
propertyInfo.SetValue(output, arr, null);
clonePropertyInfo.PropertyInfo.SetValue(output, arr, null);
}
else
{
//set the cloned collection
propertyInfo.SetValue(output, newList, null);
clonePropertyInfo.PropertyInfo.SetValue(output, newList, null);
}
}
+7 -1
View File
@@ -7,6 +7,12 @@ namespace Umbraco.Core.Models
/// </summary
public interface IMediaType : IContentTypeComposition
{
/// <summary>
/// Creates a deep clone of the current entity with its identity/alias and it's property identities reset
/// </summary>
/// <param name="newAlias"></param>
/// <returns></returns>
IMediaType DeepCloneWithResetIdentities(string newAlias);
}
}
@@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
using Umbraco.Core.PropertyEditors.ValueConverters;
namespace Umbraco.Core.Models
{
internal static class MediaExtensions
{
/// <summary>
/// Hack: we need to put this in a real place, this is currently just used to render the urls for a media item in the back office
/// </summary>
/// <returns></returns>
public static string GetUrl(this IMedia media, string propertyAlias, ILogger logger)
{
var propertyType = media.PropertyTypes.FirstOrDefault(x => x.Alias.InvariantEquals(propertyAlias));
if (propertyType != null)
{
var val = media.Properties[propertyType];
if (val != null)
{
var jsonString = val.Value as string;
if (jsonString != null)
{
if (propertyType.PropertyEditorAlias == Constants.PropertyEditors.ImageCropperAlias)
{
if (jsonString.DetectIsJson())
{
try
{
var json = JsonConvert.DeserializeObject<JObject>(jsonString);
if (json["src"] != null)
{
return json["src"].Value<string>();
}
}
catch (Exception ex)
{
logger.Error<ImageCropperValueConverter>("Could not parse the string " + jsonString + " to a json object", ex);
return string.Empty;
}
}
else
{
return jsonString;
}
}
else if (propertyType.PropertyEditorAlias == Constants.PropertyEditors.UploadFieldAlias)
{
return jsonString;
}
//hrm, without knowing what it is, just adding a string here might not be very nice
}
}
}
return string.Empty;
}
/// <summary>
/// Hack: we need to put this in a real place, this is currently just used to render the urls for a media item in the back office
/// </summary>
/// <returns></returns>
public static string[] GetUrls(this IMedia media, IContentSection contentSection, ILogger logger)
{
var links = new List<string>();
var autoFillProperties = contentSection.ImageAutoFillProperties.ToArray();
if (autoFillProperties.Any())
{
links.AddRange(
autoFillProperties
.Select(field => media.GetUrl(field.Alias, logger))
.Where(link => link.IsNullOrWhiteSpace() == false));
}
return links.ToArray();
}
}
}
+25
View File
@@ -38,5 +38,30 @@ namespace Umbraco.Core.Models
: base(parent, alias)
{
}
/// <summary>
/// Creates a deep clone of the current entity with its identity/alias and it's property identities reset
/// </summary>
/// <returns></returns>
public IMediaType DeepCloneWithResetIdentities(string alias)
{
var clone = (MediaType)DeepClone();
clone.Alias = alias;
clone.Key = Guid.Empty;
foreach (var propertyGroup in clone.PropertyGroups)
{
propertyGroup.ResetIdentity();
propertyGroup.ResetDirtyProperties(false);
}
foreach (var propertyType in clone.PropertyTypes)
{
propertyType.ResetIdentity();
propertyType.ResetDirtyProperties(false);
}
clone.ResetIdentity();
clone.ResetDirtyProperties(false);
return clone;
}
}
}
+2 -1
View File
@@ -221,8 +221,9 @@ namespace Umbraco.Core.Models
}
/// <summary>
/// Gets or Sets the PropertyGroup's Id for which this PropertyType belongs
/// Gets or sets the identifier of the PropertyGroup this PropertyType belongs to.
/// </summary>
/// <remarks>For generic properties, the value is <c>null</c>.</remarks>
[DataMember]
internal Lazy<int> PropertyGroupId
{
@@ -1,9 +1,6 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Web.Caching;
using System.Web.UI;
using Umbraco.Core.Cache;
namespace Umbraco.Core.Models.PublishedContent
@@ -16,6 +13,7 @@ namespace Umbraco.Core.Models.PublishedContent
public class PublishedContentType
{
private readonly PublishedPropertyType[] _propertyTypes;
private readonly HashSet<string> _compositionAliases;
// fast alias-to-index xref containing both the raw alias and its lowercase version
private readonly Dictionary<string, int> _indexes = new Dictionary<string, int>();
@@ -27,6 +25,7 @@ namespace Umbraco.Core.Models.PublishedContent
{
Id = contentType.Id;
Alias = contentType.Alias;
_compositionAliases = new HashSet<string>(contentType.CompositionAliases(), StringComparer.InvariantCultureIgnoreCase);
_propertyTypes = contentType.CompositionPropertyTypes
.Select(x => new PublishedPropertyType(this, x))
.ToArray();
@@ -34,10 +33,11 @@ namespace Umbraco.Core.Models.PublishedContent
}
// internal so it can be used for unit tests
internal PublishedContentType(int id, string alias, IEnumerable<PublishedPropertyType> propertyTypes)
internal PublishedContentType(int id, string alias, IEnumerable<string> compositionAliases, IEnumerable<PublishedPropertyType> propertyTypes)
{
Id = id;
Alias = alias;
_compositionAliases = new HashSet<string>(compositionAliases, StringComparer.InvariantCultureIgnoreCase);
_propertyTypes = propertyTypes.ToArray();
foreach (var propertyType in _propertyTypes)
propertyType.ContentType = this;
@@ -45,8 +45,8 @@ namespace Umbraco.Core.Models.PublishedContent
}
// create detached content type - ie does not match anything in the DB
internal PublishedContentType(string alias, IEnumerable<PublishedPropertyType> propertyTypes)
: this (0, alias, propertyTypes)
internal PublishedContentType(string alias, IEnumerable<string> compositionAliases, IEnumerable<PublishedPropertyType> propertyTypes)
: this(0, alias, compositionAliases, propertyTypes)
{ }
private void InitializeIndexes()
@@ -63,6 +63,7 @@ namespace Umbraco.Core.Models.PublishedContent
public int Id { get; private set; }
public string Alias { get; private set; }
public HashSet<string> CompositionAliases { get { return _compositionAliases; } }
#endregion
@@ -113,10 +114,25 @@ namespace Umbraco.Core.Models.PublishedContent
internal static void ClearContentType(int id)
{
Logging.LogHelper.Debug<PublishedContentType>("Clear content type w/id {0}.", () => id);
// requires a predicate because the key does not contain the ID
// faster than key strings comparisons anyway
// we don't support "get all" at the moment - so, cheating
var all = ApplicationContext.Current.ApplicationCache.StaticCache.GetCacheItemsByKeySearch<PublishedContentType>("PublishedContentType_").ToArray();
// the one we want to clear
var clr = all.FirstOrDefault(x => x.Id == id);
if (clr == null) return;
// those that have that one in their composition aliases
// note: CompositionAliases contains all recursive aliases
var oth = all.Where(x => x.CompositionAliases.InvariantContains(clr.Alias)).Select(x => x.Id);
// merge ids
var ids = oth.Concat(new[] { clr.Id }).ToArray();
// clear them all at once
// we don't support "clear many at once" at the moment - so, cheating
ApplicationContext.Current.ApplicationCache.StaticCache.ClearCacheObjectTypes<PublishedContentType>(
(key, value) => value.Id == id);
(key, value) => ids.Contains(value.Id));
}
internal static void ClearDataType(int id)
@@ -164,6 +164,9 @@ namespace Umbraco.Core.Models.PublishedContent
private void InitializeConverters()
{
//TODO: Look at optimizing this method, it gets run for every property type for the document being rendered at startup,
// every precious second counts!
var converters = PropertyValueConvertersResolver.Current.Converters.ToArray();
var defaultConvertersWithAttributes = PropertyValueConvertersResolver.Current.DefaultConverters;
@@ -230,13 +233,13 @@ namespace Umbraco.Core.Models.PublishedContent
{
_sourceCacheLevel = converterMeta.GetPropertyCacheLevel(this, PropertyCacheValue.Source);
_objectCacheLevel = converterMeta.GetPropertyCacheLevel(this, PropertyCacheValue.Object);
_objectCacheLevel = converterMeta.GetPropertyCacheLevel(this, PropertyCacheValue.XPath);
_xpathCacheLevel = converterMeta.GetPropertyCacheLevel(this, PropertyCacheValue.XPath);
}
else
{
_sourceCacheLevel = GetCacheLevel(_converter, PropertyCacheValue.Source);
_objectCacheLevel = GetCacheLevel(_converter, PropertyCacheValue.Object);
_objectCacheLevel = GetCacheLevel(_converter, PropertyCacheValue.XPath);
_xpathCacheLevel = GetCacheLevel(_converter, PropertyCacheValue.XPath);
}
if (_objectCacheLevel < _sourceCacheLevel) _objectCacheLevel = _sourceCacheLevel;
if (_xpathCacheLevel < _sourceCacheLevel) _xpathCacheLevel = _sourceCacheLevel;
@@ -164,7 +164,7 @@ namespace Umbraco.Core.Persistence.Factories
Name = typeDto.Name,
SortOrder = typeDto.SortOrder,
ValidationRegExp = typeDto.ValidationRegExp,
PropertyGroupId = new Lazy<int>(() => default(int)),
PropertyGroupId = null,
CreateDate = dto.CreateDate,
UpdateDate = dto.CreateDate
};
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
@@ -27,18 +28,21 @@ namespace Umbraco.Core.Persistence.Migrations
private readonly IMigration[] _migrations;
[Obsolete("Use the ctor that specifies all dependencies instead")]
[EditorBrowsable(EditorBrowsableState.Never)]
public MigrationRunner(Version currentVersion, Version targetVersion, string productName)
: this(LoggerResolver.Current.Logger, currentVersion, targetVersion, productName)
{
}
[Obsolete("Use the ctor that specifies all dependencies instead")]
[EditorBrowsable(EditorBrowsableState.Never)]
public MigrationRunner(ILogger logger, Version currentVersion, Version targetVersion, string productName)
: this(logger, currentVersion, targetVersion, productName, null)
{
}
[Obsolete("Use the ctor that specifies all dependencies instead")]
[EditorBrowsable(EditorBrowsableState.Never)]
public MigrationRunner(ILogger logger, Version currentVersion, Version targetVersion, string productName, params IMigration[] migrations)
: this(ApplicationContext.Current.Services.MigrationEntryService, logger, new SemVersion(currentVersion), new SemVersion(targetVersion), productName, migrations)
{
@@ -92,7 +96,7 @@ namespace Umbraco.Core.Persistence.Migrations
: OrderedDowngradeMigrations(foundMigrations).ToList();
if (Migrating.IsRaisedEventCancelled(new MigrationEventArgs(migrations, _currentVersion, _targetVersion, true), this))
if (Migrating.IsRaisedEventCancelled(new MigrationEventArgs(migrations, _currentVersion, _targetVersion, _productName, true), this))
{
_logger.Warn<MigrationRunner>("Migration was cancelled by an event");
return false;
@@ -121,7 +125,7 @@ namespace Umbraco.Core.Persistence.Migrations
throw;
}
Migrated.RaiseEvent(new MigrationEventArgs(migrations, migrationContext, _currentVersion, _targetVersion, false), this);
Migrated.RaiseEvent(new MigrationEventArgs(migrations, migrationContext, _currentVersion, _targetVersion, _productName, false), this);
return true;
}
@@ -289,7 +293,7 @@ namespace Umbraco.Core.Persistence.Migrations
//NOTE: We CANNOT do this as part of the transaction!!! This is because when upgrading to 7.3, we cannot
// create the migrations table and then add data to it in the same transaction without issuing things like GO
// commands and since we need to support all Dbs, we need to just do this after the fact.
var exists = _migrationEntryService.FindEntry(GlobalSettings.UmbracoMigrationName, _targetVersion);
var exists = _migrationEntryService.FindEntry(_productName, _targetVersion);
if (exists == null)
{
_migrationEntryService.CreateEntry(_productName, _targetVersion);
@@ -308,4 +312,4 @@ namespace Umbraco.Core.Persistence.Migrations
/// </summary>
public static event TypedEventHandler<MigrationRunner, MigrationEventArgs> Migrated;
}
}
}
@@ -37,9 +37,9 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven
if (!dataTypeIds.Any()) return string.Empty;
var propertyData =
database.Fetch<PropertyDataDto>(
"WHERE propertyTypeId in (SELECT id from cmsPropertyType where dataTypeID IN (@dataTypeIds))", new { dataTypeIds = dataTypeIds });
// need to use dynamic, as PropertyDataDto has new properties
var propertyData = database.Fetch<dynamic>("SELECT * FROM cmsPropertyData"
+ " WHERE propertyTypeId in (SELECT id from cmsPropertyType where dataTypeID IN (@dataTypeIds))", new { dataTypeIds = dataTypeIds });
if (!propertyData.Any()) return string.Empty;
var nodesIdsWithProperty = propertyData.Select(x => x.NodeId).Distinct().ToArray();
@@ -71,13 +71,16 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven
xml = new XmlDocument();
xml.LoadXml(data.Text);
}
catch (Exception ex)
catch (Exception ex)
{
Logger.Error<UpdateRelatedLinksData>("The data stored for property id " + data.Id + " on document " + data.NodeId +
" is not valid XML, the data will be removed because it cannot be converted to the new format. The value was: " + data.Text, ex);
int dataId = data.id;
int dataNodeId = data.nodeId;
string dataText = data.dataNText;
Logger.Error<UpdateRelatedLinksData>("The data stored for property id " + dataId + " on document " + dataNodeId +
" is not valid XML, the data will be removed because it cannot be converted to the new format. The value was: " + dataText, ex);
data.Text = "";
database.Update(data);
data.dataNText = "";
database.Update("cmsPropertyData", "id", data, new[] { "dataNText" });
UpdateXmlTable(propertyTypes, data, cmsContentXmlEntries, database);
@@ -91,11 +94,11 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven
{
var title = node.Attributes["title"].Value;
var type = node.Attributes["type"].Value;
var newwindow = node.Attributes["newwindow"].Value.Equals("1") ? true : false;
var newwindow = node.Attributes["newwindow"].Value.Equals("1");
var lnk = node.Attributes["link"].Value;
//create the links in the format the new prop editor expects it to be
var link = new ExpandoObject() as IDictionary<string, Object>;
var link = new ExpandoObject() as IDictionary<string, object>;
link.Add("title", title);
link.Add("caption", title);
link.Add("link", lnk);
@@ -110,9 +113,9 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven
}
//store the serialized data
data.Text = JsonConvert.SerializeObject(links);
data.dataNText = JsonConvert.SerializeObject(links);
database.Update(data);
database.Update("cmsPropertyData", "id", data, new[] { "dataNText" });
UpdateXmlTable(propertyTypes, data, cmsContentXmlEntries, database);
@@ -1,4 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
@@ -33,45 +35,57 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFourZer
// fill in the data in a way that is consistent over all environments
// (ie cannot use random guids, http://issues.umbraco.org/issue/U4-6942)
Execute.Code(UpdateGuids);
}
}
foreach (var data in Context.Database.Query<dynamic>(@"
private static string UpdateGuids(Database database)
{
var updates = new List<Tuple<Guid, int>>();
foreach (var data in database.Query<dynamic>(@"
SELECT cmsPropertyTypeGroup.id grId, cmsPropertyTypeGroup.text grName, cmsContentType.alias ctAlias, umbracoNode.nodeObjectType nObjType
FROM cmsPropertyTypeGroup
INNER JOIN cmsContentType
ON cmsPropertyTypeGroup.contentTypeNodeId = cmsContentType.nodeId
INNER JOIN umbracoNode
ON cmsContentType.nodeId = umbracoNode.id"))
{
Guid guid;
// see BaseDataCreation... built-in groups have their own guids
if (data.grId == 3)
{
Guid guid;
// see BaseDataCreation... built-in groups have their own guids
if (data.grId == 3)
{
guid = new Guid(Constants.PropertyTypeGroups.Image);
}
else if (data.grId == 4)
{
guid = new Guid(Constants.PropertyTypeGroups.File);
}
else if (data.grId == 5)
{
guid = new Guid(Constants.PropertyTypeGroups.Contents);
}
else if (data.grId == 11)
{
guid = new Guid(Constants.PropertyTypeGroups.Membership);
}
else
{
// create a consistent guid from
// group name + content type alias + object type
string guidSource = data.grName + data.ctAlias + data.nObjType;
guid = guidSource.ToGuid();
}
// set the Unique Id to the one we've generated
Update.Table("cmsPropertyTypeGroup").Set(new { uniqueID = guid }).Where(new { id = data.grId });
guid = new Guid(Constants.PropertyTypeGroups.Image);
}
else if (data.grId == 4)
{
guid = new Guid(Constants.PropertyTypeGroups.File);
}
else if (data.grId == 5)
{
guid = new Guid(Constants.PropertyTypeGroups.Contents);
}
else if (data.grId == 11)
{
guid = new Guid(Constants.PropertyTypeGroups.Membership);
}
else
{
// create a consistent guid from
// group name + content type alias + object type
string guidSource = data.grName + data.ctAlias + data.nObjType;
guid = guidSource.ToGuid();
}
// set the Unique Id to the one we've generated
// but not within the foreach loop (as we already have a data reader open)
updates.Add(Tuple.Create(guid, data.grId));
}
foreach (var update in updates)
database.Execute("UPDATE cmsPropertyTypeGroup SET uniqueID=@uid WHERE id=@id", new { uid = update.Item1, id = update.Item2 });
return string.Empty;
}
public override void Down()
@@ -20,7 +20,17 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFourZer
if (columns.Any(x => x.TableName.InvariantEquals("cmsPropertyTypeGroup") && x.ColumnName.InvariantEquals("parentGroupId")) == false)
return;
Delete.ForeignKey("FK_cmsPropertyTypeGroup_cmsPropertyTypeGroup_id").OnTable("cmsPropertyTypeGroup");
//This constraing can be based on old aliases, before removing them, check they exist
var constraints = SqlSyntax.GetConstraintsPerColumn(Context.Database).Distinct().ToArray();
if (constraints.Any(x => x.Item1.InvariantEquals("cmsPropertyTypeGroup") && x.Item3.InvariantEquals("FK_cmsPropertyTypeGroup_cmsPropertyTypeGroup_id")))
{
Delete.ForeignKey("FK_cmsPropertyTypeGroup_cmsPropertyTypeGroup_id").OnTable("cmsPropertyTypeGroup");
}
if (constraints.Any(x => x.Item1.InvariantEquals("cmsPropertyTypeGroup") && x.Item3.InvariantEquals("FK_cmsPropertyTypeGroup_cmsPropertyTypeGroup")))
{
Delete.ForeignKey("FK_cmsPropertyTypeGroup_cmsPropertyTypeGroup").OnTable("cmsPropertyTypeGroup");
}
Delete.Column("parentGroupId").FromTable("cmsPropertyTypeGroup");
}
@@ -33,36 +33,40 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixZeroOne
// won't exist yet
var propertyTypes = database.Fetch<dynamic>("SELECT * FROM cmsPropertyType WHERE propertyTypeGroupId > 0");
var propertyGroups = database.Fetch<PropertyTypeGroupDto>("WHERE id > 0");
// need to use dynamic, as PropertyTypeGroupDto has new properties
var propertyGroups = database.Fetch<dynamic>("SELECT * FROM cmsPropertyTypeGroup WHERE id > 0");
foreach (var propertyType in propertyTypes)
{
// get the PropertyTypeGroup of the current PropertyType, skip if not found
var propertyTypeGroup = propertyGroups.FirstOrDefault(x => x.Id == propertyType.propertyTypeGroupId);
var propertyTypeGroup = propertyGroups.FirstOrDefault(x => x.id == propertyType.propertyTypeGroupId);
if (propertyTypeGroup == null) continue;
// if the PropretyTypeGroup belongs to the same content type as the PropertyType, then fine
if (propertyTypeGroup.ContentTypeNodeId == propertyType.contentTypeId) continue;
if (propertyTypeGroup.contenttypeNodeId == propertyType.contentTypeId) continue;
// else we want to assign the PropertyType to a proper PropertyTypeGroup
// ie one that does belong to the same content - look for it
var okPropertyTypeGroup = propertyGroups.FirstOrDefault(x =>
x.Text == propertyTypeGroup.Text && // same name
x.ContentTypeNodeId == propertyType.contentTypeId); // but for proper content type
x.text == propertyTypeGroup.text && // same name
x.contenttypeNodeId == propertyType.contentTypeId); // but for proper content type
if (okPropertyTypeGroup == null)
{
// does not exist, create a new PropertyTypeGroup,
var propertyGroup = new PropertyTypeGroupDto
// does not exist, create a new PropertyTypeGroup
// cannot use a PropertyTypeGroupDto because of the new (not-yet-existing) uniqueID property
// cannot use a dynamic because database.Insert fails to set the value of property
var propertyGroup = new PropertyTypeGroupDtoTemp
{
ContentTypeNodeId = propertyType.contentTypeId,
Text = propertyTypeGroup.Text,
SortOrder = propertyTypeGroup.SortOrder
id = 0,
contenttypeNodeId = propertyType.contentTypeId,
text = propertyTypeGroup.text,
sortorder = propertyTypeGroup.sortorder
};
// save + add to list of groups
int id = Convert.ToInt16(database.Insert(propertyGroup));
propertyGroup.Id = id;
int id = Convert.ToInt16(database.Insert("cmsPropertyTypeGroup", "id", propertyGroup));
propertyGroup.id = id;
propertyGroups.Add(propertyGroup);
// update the PropertyType to use the new PropertyTypeGroup
@@ -71,7 +75,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixZeroOne
else
{
// exists, update PropertyType to use the PropertyTypeGroup
propertyType.propertyTypeGroupId = okPropertyTypeGroup.Id;
propertyType.propertyTypeGroupId = okPropertyTypeGroup.id;
}
database.Update("cmsPropertyType", "id", propertyType);
}
@@ -79,5 +83,13 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixZeroOne
return string.Empty;
}
private class PropertyTypeGroupDtoTemp
{
public int id { get; set; }
public int contenttypeNodeId { get; set; }
public string text { get; set; }
public int sortorder { get; set; }
}
}
}
+1 -1
View File
@@ -834,7 +834,7 @@ namespace Umbraco.Core.Persistence
var pd = PocoData.ForType(typeof(T));
try
{
r = cmd.ExecuteReader();
r = cmd.ExecuteReaderWithRetry();
OnExecutedCommand(cmd);
}
catch (Exception x)
@@ -128,6 +128,34 @@ namespace Umbraco.Core.Persistence.Querying
right = Visit(b.Right);
}
}
else if (operand == "=")
{
// deal with (x == true|false) - most common
var constRight = b.Right as ConstantExpression;
if (constRight != null && constRight.Type == typeof (bool))
return ((bool) constRight.Value) ? VisitNotNot(b.Left) : VisitNot(b.Left);
right = Visit(b.Right);
// deal with (true|false == x) - why not
var constLeft = b.Left as ConstantExpression;
if (constLeft != null && constLeft.Type == typeof (bool))
return ((bool) constLeft.Value) ? VisitNotNot(b.Right) : VisitNot(b.Right);
left = Visit(b.Left);
}
else if (operand == "<>")
{
// deal with (x != true|false) - most common
var constRight = b.Right as ConstantExpression;
if (constRight != null && constRight.Type == typeof(bool))
return ((bool) constRight.Value) ? VisitNot(b.Left) : VisitNotNot(b.Left);
right = Visit(b.Right);
// deal with (true|false != x) - why not
var constLeft = b.Left as ConstantExpression;
if (constLeft != null && constLeft.Type == typeof(bool))
return ((bool) constLeft.Value) ? VisitNot(b.Right) : VisitNotNot(b.Right);
left = Visit(b.Left);
}
else
{
left = Visit(b.Left);
@@ -152,7 +180,7 @@ namespace Umbraco.Core.Persistence.Querying
case "COALESCE":
return string.Format("{0}({1},{2})", operand, left, right);
default:
return left + " " + operand + " " + right;
return "(" + left + " " + operand + " " + right + ")";
}
}
@@ -231,25 +259,47 @@ namespace Umbraco.Core.Persistence.Querying
switch (u.NodeType)
{
case ExpressionType.Not:
var o = Visit(u.Operand);
//use a Not equal operator instead of <> since we don't know that <> works in all sql servers
switch (u.Operand.NodeType)
{
case ExpressionType.MemberAccess:
//In this case it wil be a false property , i.e. x => !Trashed
SqlParameters.Add(true);
return string.Format("NOT ({0} = @0)", o);
default:
//In this case it could be anything else, such as: x => !x.Path.StartsWith("-20")
return string.Format("NOT ({0})", o);
}
return VisitNot(u.Operand);
default:
return Visit(u.Operand);
}
}
private string VisitNot(Expression exp)
{
var o = Visit(exp);
// use a "NOT (...)" syntax instead of "<>" since we don't know whether "<>" works in all sql servers
// also, x.StartsWith(...) translates to "x LIKE '...%'" which we cannot "<>" and have to "NOT (...")
switch (exp.NodeType)
{
case ExpressionType.MemberAccess:
// false property , i.e. x => !Trashed
SqlParameters.Add(true);
return string.Format("NOT ({0} = @{1})", o, SqlParameters.Count - 1);
default:
// could be anything else, such as: x => !x.Path.StartsWith("-20")
return "NOT (" + o + ")";
}
}
private string VisitNotNot(Expression exp)
{
var o = Visit(exp);
switch (exp.NodeType)
{
case ExpressionType.MemberAccess:
// true property, i.e. x => Trashed
SqlParameters.Add(true);
return string.Format("({0} = @{1})", o, SqlParameters.Count - 1);
default:
// could be anything else, such as: x => x.Path.StartsWith("-20")
return o;
}
}
protected virtual string VisitNewArray(NewArrayExpression na)
{
@@ -18,8 +18,11 @@ namespace Umbraco.Core.Persistence.Relators
// Is this the same DictionaryItem as the current one we're processing
if (Current != null && Current.Id == a.Id)
{
// Yes, just add this User2AppDto to the current item's collection
Current.User2AppDtos.Add(p);
if (p.AppAlias.IsNullOrWhiteSpace() == false)
{
// Yes, just add this User2AppDto to the current item's collection
Current.User2AppDtos.Add(p);
}
// Return null to indicate we're not done with this User yet
return null;
@@ -35,7 +38,7 @@ namespace Umbraco.Core.Persistence.Relators
Current = a;
Current.User2AppDtos = new List<User2AppDto>();
//this can be null since we are doing a left join
if (p.AppAlias != null)
if (p.AppAlias.IsNullOrWhiteSpace() == false)
{
Current.User2AppDtos.Add(p);
}
@@ -155,8 +155,8 @@ namespace Umbraco.Core.Persistence.Repositories
"DELETE FROM cmsContentVersion WHERE ContentId = @Id",
"DELETE FROM cmsContentXml WHERE nodeId = @Id",
"DELETE FROM cmsContent WHERE nodeId = @Id",
"DELETE FROM umbracoNode WHERE id = @Id",
"DELETE FROM umbracoAccess WHERE nodeId = @Id"
"DELETE FROM umbracoAccess WHERE nodeId = @Id",
"DELETE FROM umbracoNode WHERE id = @Id"
};
return list;
}
@@ -689,8 +689,7 @@ namespace Umbraco.Core.Persistence.Repositories
public int CountPublished()
{
var sql = GetBaseQuery(true).Where<NodeDto>(x => x.Trashed == false)
.Where<DocumentDto>(x => x.Published == true)
.Where<DocumentDto>(x => x.Newest == true);
.Where<DocumentDto>(x => x.Published == true);
return Database.ExecuteScalar<int>(sql);
}
@@ -33,14 +33,11 @@ namespace Umbraco.Core.Persistence.Repositories
protected ContentTypeBaseRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{
_guidRepo = new GuidReadOnlyContentTypeBaseRepository(this, work, cache, logger, sqlSyntax);
}
private readonly GuidReadOnlyContentTypeBaseRepository _guidRepo;
public IEnumerable<MoveEventInfo<TEntity>> Move(TEntity toMove, EntityContainer container)
{
var parentId = -1;
var parentId = Constants.System.Root;
if (container != null)
{
// Check on paths
@@ -57,27 +54,36 @@ namespace Umbraco.Core.Persistence.Repositories
new MoveEventInfo<TEntity>(toMove, toMove.Path, parentId)
};
//do the move to a new parent
// get the level delta (old pos to new pos)
var levelDelta = container == null
? 1 - toMove.Level
: container.Level + 1 - toMove.Level;
// move to parent (or -1), update path, save
toMove.ParentId = parentId;
//schedule it for updating in the transaction
var toMovePath = toMove.Path + ","; // save before changing
toMove.Path = (container == null ? Constants.System.Root.ToString() : container.Path) + "," + toMove.Id;
toMove.Level = container == null ? 1 : container.Level + 1;
AddOrUpdate(toMove);
//update all descendants
var descendants = this.GetByQuery(
new Query<TEntity>().Where(type => type.Path.StartsWith(toMove.Path + ",")));
foreach (var descendant in descendants)
//update all descendants, update in order of level
var descendants = GetByQuery(new Query<TEntity>().Where(type => type.Path.StartsWith(toMovePath)));
var paths = new Dictionary<int, string>();
paths[toMove.Id] = toMove.Path;
foreach (var descendant in descendants.OrderBy(x => x.Level))
{
moveInfo.Add(new MoveEventInfo<TEntity>(descendant, descendant.Path, descendant.ParentId));
//all we're doing here is setting the parent Id to be dirty so that it resets the path/level/etc...
descendant.ParentId = descendant.ParentId;
//schedule it for updating in the transaction
descendant.Path = paths[descendant.Id] = paths[descendant.ParentId] + "," + descendant.Id;
descendant.Level += levelDelta;
AddOrUpdate(descendant);
}
return moveInfo;
}
/// <summary>
/// Returns the content type ids that match the query
/// </summary>
@@ -279,7 +285,7 @@ AND umbracoNode.id <> @id",
{
//Find PropertyTypes for the removed ContentType
var propertyTypes = Database.Fetch<PropertyTypeDto>("WHERE contentTypeId = @Id", new { Id = key });
//Loop through the Content that is based on the current ContentType in order to remove the Properties that are
//Loop through the Content that is based on the current ContentType in order to remove the Properties that are
//based on the PropertyTypes that belong to the removed ContentType.
foreach (var contentDto in contentDtos)
{
@@ -403,7 +409,7 @@ AND umbracoNode.id <> @id",
AssignDataTypeFromPropertyEditor(propertyType);
}
//validate the alias!
//validate the alias!
ValidateAlias(propertyType);
var propertyTypeDto = propertyGroupFactory.BuildPropertyTypeDto(tabId, propertyType);
@@ -577,14 +583,13 @@ AND umbracoNode.id <> @id",
}
}
public static IEnumerable<IMediaType> GetMediaTypes<TRepo, TId>(
TId[] mediaTypeIds, Database db, ISqlSyntaxProvider sqlSyntax,
public static IEnumerable<IMediaType> GetMediaTypes<TRepo>(
Database db, ISqlSyntaxProvider sqlSyntax,
TRepo contentTypeRepository)
where TRepo : IReadRepository<TId, TEntity>
where TId: struct
where TRepo : IReadRepository<int, TEntity>
{
IDictionary<TId, IEnumerable<TId>> allParentMediaTypeIds;
var mediaTypes = MapMediaTypes(mediaTypeIds, db, sqlSyntax, out allParentMediaTypeIds)
IDictionary<int, List<int>> allParentMediaTypeIds;
var mediaTypes = MapMediaTypes(db, sqlSyntax, out allParentMediaTypeIds)
.ToArray();
MapContentTypeChildren(mediaTypes, db, sqlSyntax, contentTypeRepository, allParentMediaTypeIds);
@@ -592,16 +597,15 @@ AND umbracoNode.id <> @id",
return mediaTypes;
}
public static IEnumerable<IContentType> GetContentTypes<TRepo, TId>(
TId[] contentTypeIds, Database db, ISqlSyntaxProvider sqlSyntax,
public static IEnumerable<IContentType> GetContentTypes<TRepo>(
Database db, ISqlSyntaxProvider sqlSyntax,
TRepo contentTypeRepository,
ITemplateRepository templateRepository)
where TRepo : IReadRepository<TId, TEntity>
where TId : struct
where TRepo : IReadRepository<int, TEntity>
{
IDictionary<TId, IEnumerable<AssociatedTemplate>> allAssociatedTemplates;
IDictionary<TId, IEnumerable<TId>> allParentContentTypeIds;
var contentTypes = MapContentTypes(contentTypeIds, db, sqlSyntax, out allAssociatedTemplates, out allParentContentTypeIds)
IDictionary<int, List<AssociatedTemplate>> allAssociatedTemplates;
IDictionary<int, List<int>> allParentContentTypeIds;
var contentTypes = MapContentTypes(db, sqlSyntax, out allAssociatedTemplates, out allParentContentTypeIds)
.ToArray();
if (contentTypes.Any())
@@ -616,12 +620,11 @@ AND umbracoNode.id <> @id",
return contentTypes;
}
internal static void MapContentTypeChildren<TRepo, TId>(IContentTypeComposition[] contentTypes,
internal static void MapContentTypeChildren<TRepo>(IContentTypeComposition[] contentTypes,
Database db, ISqlSyntaxProvider sqlSyntax,
TRepo contentTypeRepository,
IDictionary<TId, IEnumerable<TId>> allParentContentTypeIds)
where TRepo : IReadRepository<TId, TEntity>
where TId : struct
IDictionary<int, List<int>> allParentContentTypeIds)
where TRepo : IReadRepository<int, TEntity>
{
//NOTE: SQL call #2
@@ -643,25 +646,22 @@ AND umbracoNode.id <> @id",
var allParentIdsAsArray = allParentContentTypeIds.SelectMany(x => x.Value).Distinct().ToArray();
if (allParentIdsAsArray.Any())
{
var allParentContentTypes = contentTypeRepository.GetAll(allParentIdsAsArray).ToArray();
var allParentContentTypes = contentTypes.Where(x => allParentIdsAsArray.Contains(x.Id)).ToArray();
foreach (var contentType in contentTypes)
{
//TODO: this is pretty hacky right now but i don't have time to refactor/fix running queries based on ints and Guids
// (i.e. for v8) but we need queries by GUIDs now so this is how it's gonna have to be
var entityId = typeof(TId) == typeof(int) ? contentType.Id : (object)contentType.Key;
{
var entityId = contentType.Id;
var parentContentTypes = allParentContentTypes.Where(x =>
{
//TODO: this is pretty hacky right now but i don't have time to refactor/fix running queries based on ints and Guids
// (i.e. for v8) but we need queries by GUIDs now so this is how it's gonna have to be
var parentEntityId = typeof(TId) == typeof(int) ? x.Id : (object)x.Key;
var parentEntityId = x.Id;
return allParentContentTypeIds[(TId)entityId].Contains((TId)parentEntityId);
return allParentContentTypeIds[entityId].Contains(parentEntityId);
});
foreach (var parentContentType in parentContentTypes)
{
var result = contentType.AddContentType(parentContentType);
//Do something if adding fails? (Should hopefully not be possible unless someone created a circular reference)
//Do something if adding fails? (Should hopefully not be possible unless someone created a circular reference)
}
//on initial construction we don't want to have dirty properties tracked
@@ -674,13 +674,12 @@ AND umbracoNode.id <> @id",
}
internal static void MapContentTypeTemplates<TRepo, TId>(IContentType[] contentTypes,
internal static void MapContentTypeTemplates<TRepo>(IContentType[] contentTypes,
Database db,
TRepo contentTypeRepository,
ITemplateRepository templateRepository,
IDictionary<TId, IEnumerable<AssociatedTemplate>> associatedTemplates)
where TRepo : IReadRepository<TId, TEntity>
where TId: struct
IDictionary<int, List<AssociatedTemplate>> associatedTemplates)
where TRepo : IReadRepository<int, TEntity>
{
if (associatedTemplates == null || associatedTemplates.Any() == false) return;
@@ -697,11 +696,9 @@ AND umbracoNode.id <> @id",
foreach (var contentType in contentTypes)
{
//TODO: this is pretty hacky right now but i don't have time to refactor/fix running queries based on ints and Guids
// (i.e. for v8) but we need queries by GUIDs now so this is how it's gonna have to be
var entityId = typeof(TId) == typeof(int) ? contentType.Id : (object)contentType.Key;
var associatedTemplateIds = associatedTemplates[(TId)entityId].Select(x => x.TemplateId)
var entityId = contentType.Id;
var associatedTemplateIds = associatedTemplates[entityId].Select(x => x.TemplateId)
.Distinct()
.ToArray();
@@ -713,19 +710,14 @@ AND umbracoNode.id <> @id",
}
internal static IEnumerable<IMediaType> MapMediaTypes<TId>(TId[] mediaTypeIds, Database db, ISqlSyntaxProvider sqlSyntax,
out IDictionary<TId, IEnumerable<TId>> parentMediaTypeIds)
where TId : struct
internal static IEnumerable<IMediaType> MapMediaTypes(Database db, ISqlSyntaxProvider sqlSyntax,
out IDictionary<int, List<int>> parentMediaTypeIds)
{
Mandate.That(mediaTypeIds.Any(), () => new InvalidOperationException("must be at least one content type id specified"));
Mandate.ParameterNotNull(db, "db");
//ensure they are unique
mediaTypeIds = mediaTypeIds.Distinct().ToArray();
var sql = @"SELECT cmsContentType.pk as ctPk, cmsContentType.alias as ctAlias, cmsContentType.allowAtRoot as ctAllowAtRoot, cmsContentType.description as ctDesc,
cmsContentType.icon as ctIcon, cmsContentType.isContainer as ctIsContainer, cmsContentType.nodeId as ctId, cmsContentType.thumbnail as ctThumb,
AllowedTypes.allowedId as ctaAllowedId, AllowedTypes.SortOrder as ctaSortOrder, AllowedTypes.alias as ctaAlias,
AllowedTypes.AllowedId as ctaAllowedId, AllowedTypes.SortOrder as ctaSortOrder, AllowedTypes.alias as ctaAlias,
ParentTypes.parentContentTypeId as chtParentId, ParentTypes.parentContentTypeKey as chtParentKey,
umbracoNode.createDate as nCreateDate, umbracoNode." + sqlSyntax.GetQuotedColumnName("level") + @" as nLevel, umbracoNode.nodeObjectType as nObjectType, umbracoNode.nodeUser as nUser,
umbracoNode.parentID as nParentId, umbracoNode." + sqlSyntax.GetQuotedColumnName("path") + @" as nPath, umbracoNode.sortOrder as nSortOrder, umbracoNode." + sqlSyntax.GetQuotedColumnName("text") + @" as nName, umbracoNode.trashed as nTrashed,
@@ -734,40 +726,23 @@ AND umbracoNode.id <> @id",
INNER JOIN umbracoNode
ON cmsContentType.nodeId = umbracoNode.id
LEFT JOIN (
SELECT cmsContentTypeAllowedContentType.Id, cmsContentTypeAllowedContentType.AllowedId, cmsContentType.alias, cmsContentTypeAllowedContentType.SortOrder
FROM cmsContentTypeAllowedContentType
SELECT cmsContentTypeAllowedContentType.Id, cmsContentTypeAllowedContentType.AllowedId, cmsContentType.alias, cmsContentTypeAllowedContentType.SortOrder
FROM cmsContentTypeAllowedContentType
INNER JOIN cmsContentType
ON cmsContentTypeAllowedContentType.AllowedId = cmsContentType.nodeId
) AllowedTypes
ON AllowedTypes.Id = cmsContentType.nodeId
LEFT JOIN (
SELECT cmsContentType2ContentType.parentContentTypeId, umbracoNode.uniqueID AS parentContentTypeKey, cmsContentType2ContentType.childContentTypeId
FROM cmsContentType2ContentType
FROM cmsContentType2ContentType
INNER JOIN umbracoNode
ON cmsContentType2ContentType.parentContentTypeId = umbracoNode." + sqlSyntax.GetQuotedColumnName("id") + @"
) ParentTypes
ON ParentTypes.childContentTypeId = cmsContentType.nodeId
WHERE (umbracoNode.nodeObjectType = @nodeObjectType)";
if (mediaTypeIds.Any())
{
//TODO: This is all sorts of hacky but i don't have time to refactor a lot to get both ints and guids working nicely... this will
// work for the time being.
if (typeof(TId) == typeof(int))
{
sql = sql + " AND (umbracoNode.id IN (@contentTypeIds))";
}
else if (typeof(TId) == typeof(Guid))
{
sql = sql + " AND (umbracoNode.uniqueID IN (@contentTypeIds))";
}
}
//NOTE: we are going to assume there's not going to be more than 2100 content type ids since that is the max SQL param count!
if ((mediaTypeIds.Length - 1) > 2000)
throw new InvalidOperationException("Cannot perform this lookup, too many sql parameters");
var result = db.Fetch<dynamic>(sql, new { nodeObjectType = new Guid(Constants.ObjectTypes.MediaType), contentTypeIds = mediaTypeIds });
) ParentTypes
ON ParentTypes.childContentTypeId = cmsContentType.nodeId
WHERE (umbracoNode.nodeObjectType = @nodeObjectType)
ORDER BY ctId";
var result = db.Fetch<dynamic>(sql, new { nodeObjectType = new Guid(Constants.ObjectTypes.MediaType) });
if (result.Any() == false)
{
@@ -775,95 +750,118 @@ AND umbracoNode.id <> @id",
return Enumerable.Empty<IMediaType>();
}
parentMediaTypeIds = new Dictionary<TId, IEnumerable<TId>>();
parentMediaTypeIds = new Dictionary<int, List<int>>();
var mappedMediaTypes = new List<IMediaType>();
foreach (var contentTypeId in mediaTypeIds)
//loop through each result and fill in our required values, each row will contain different requried data than the rest.
// it is much quicker to iterate each result and populate instead of looking up the values over and over in the result like
// we used to do.
var queue = new Queue<dynamic>(result);
var currAllowedContentTypes = new List<ContentTypeSort>();
while (queue.Count > 0)
{
//the current content type id that we're working with
var ct = queue.Dequeue();
var currentCtId = contentTypeId;
//first we want to get the main content type data this is 1 : 1 with umbraco node data
var ct = result
.Where(x =>
{
//TODO: This is a bit hacky right now but don't have time to do a nice refactor to support both GUID and Int queries, so this is
// how it is for now.
return (typeof (TId) == typeof (int))
? x.ctId == currentCtId
: x.nUniqueId == currentCtId;
})
.Select(x => new { x.ctPk, x.ctId, x.ctAlias, x.ctAllowAtRoot, x.ctDesc, x.ctIcon, x.ctIsContainer, x.ctThumb, x.nName, x.nCreateDate, x.nLevel, x.nObjectType, x.nUser, x.nParentId, x.nPath, x.nSortOrder, x.nTrashed, x.nUniqueId })
.DistinctBy(x => (int)x.ctId)
.FirstOrDefault();
if (ct == null)
//check for allowed content types
int? allowedCtId = ct.ctaAllowedId;
int? allowedCtSort = ct.ctaSortOrder;
string allowedCtAlias = ct.ctaAlias;
if (allowedCtId.HasValue && allowedCtSort.HasValue && allowedCtAlias != null)
{
continue;
var ctSort = new ContentTypeSort(new Lazy<int>(() => allowedCtId.Value), allowedCtSort.Value, allowedCtAlias);
if (currAllowedContentTypes.Contains(ctSort) == false)
{
currAllowedContentTypes.Add(ctSort);
}
}
var contentTypeDto = new ContentTypeDto
//always ensure there's a list for this content type
if (parentMediaTypeIds.ContainsKey(ct.ctId) == false)
parentMediaTypeIds[ct.ctId] = new List<int>();
//check for parent ids and assign to the outgoing collection
int? parentId = ct.chtParentId;
if (parentId.HasValue)
{
Alias = ct.ctAlias,
AllowAtRoot = ct.ctAllowAtRoot,
Description = ct.ctDesc,
Icon = ct.ctIcon,
IsContainer = ct.ctIsContainer,
NodeId = ct.ctId,
PrimaryKey = ct.ctPk,
Thumbnail = ct.ctThumb,
//map the underlying node dto
NodeDto = new NodeDto
{
CreateDate = ct.nCreateDate,
Level = (short)ct.nLevel,
NodeId = ct.ctId,
NodeObjectType = ct.nObjectType,
ParentId = ct.nParentId,
Path = ct.nPath,
SortOrder = ct.nSortOrder,
Text = ct.nName,
Trashed = ct.nTrashed,
UniqueId = ct.nUniqueId,
UserId = ct.nUser
}
};
var associatedParentIds = parentMediaTypeIds[ct.ctId];
if (associatedParentIds.Contains(parentId.Value) == false)
associatedParentIds.Add(parentId.Value);
}
//now create the media type object
if (queue.Count == 0 || queue.Peek().ctId != ct.ctId)
{
//it's the last in the queue or the content type is changing (moving to the next one)
var mediaType = CreateForMapping(ct, currAllowedContentTypes);
mappedMediaTypes.Add(mediaType);
var factory = new ContentTypeFactory();
var mediaType = factory.BuildMediaTypeEntity(contentTypeDto);
//map the allowed content types
//map the child content type ids
MapCommonContentTypeObjects(mediaType, currentCtId, result, parentMediaTypeIds);
mappedMediaTypes.Add(mediaType);
//Here we need to reset the current variables, we're now collecting data for a different content type
currAllowedContentTypes = new List<ContentTypeSort>();
}
}
return mappedMediaTypes;
}
internal static IEnumerable<IContentType> MapContentTypes<TId>(TId[] contentTypeIds, Database db, ISqlSyntaxProvider sqlSyntax,
out IDictionary<TId, IEnumerable<AssociatedTemplate>> associatedTemplates,
out IDictionary<TId, IEnumerable<TId>> parentContentTypeIds)
where TId : struct
private static IMediaType CreateForMapping(dynamic currCt, List<ContentTypeSort> currAllowedContentTypes)
{
// * create the DTO object
// * create the content type object
// * map the allowed content types
// * add to the outgoing list
var contentTypeDto = new ContentTypeDto
{
Alias = currCt.ctAlias,
AllowAtRoot = currCt.ctAllowAtRoot,
Description = currCt.ctDesc,
Icon = currCt.ctIcon,
IsContainer = currCt.ctIsContainer,
NodeId = currCt.ctId,
PrimaryKey = currCt.ctPk,
Thumbnail = currCt.ctThumb,
//map the underlying node dto
NodeDto = new NodeDto
{
CreateDate = currCt.nCreateDate,
Level = (short)currCt.nLevel,
NodeId = currCt.ctId,
NodeObjectType = currCt.nObjectType,
ParentId = currCt.nParentId,
Path = currCt.nPath,
SortOrder = currCt.nSortOrder,
Text = currCt.nName,
Trashed = currCt.nTrashed,
UniqueId = currCt.nUniqueId,
UserId = currCt.nUser
}
};
//now create the content type object
var factory = new ContentTypeFactory();
var mediaType = factory.BuildMediaTypeEntity(contentTypeDto);
//map the allowed content types
mediaType.AllowedContentTypes = currAllowedContentTypes;
return mediaType;
}
internal static IEnumerable<IContentType> MapContentTypes(Database db, ISqlSyntaxProvider sqlSyntax,
out IDictionary<int, List<AssociatedTemplate>> associatedTemplates,
out IDictionary<int, List<int>> parentContentTypeIds)
{
Mandate.ParameterNotNull(db, "db");
//ensure they are unique
contentTypeIds = contentTypeIds.Distinct().ToArray();
var sql = @"SELECT cmsDocumentType.IsDefault as dtIsDefault, cmsDocumentType.templateNodeId as dtTemplateId,
cmsContentType.pk as ctPk, cmsContentType.alias as ctAlias, cmsContentType.allowAtRoot as ctAllowAtRoot, cmsContentType.description as ctDesc,
cmsContentType.icon as ctIcon, cmsContentType.isContainer as ctIsContainer, cmsContentType.nodeId as ctId, cmsContentType.thumbnail as ctThumb,
AllowedTypes.allowedId as ctaAllowedId, AllowedTypes.SortOrder as ctaSortOrder, AllowedTypes.alias as ctaAlias,
AllowedTypes.AllowedId as ctaAllowedId, AllowedTypes.SortOrder as ctaSortOrder, AllowedTypes.alias as ctaAlias,
ParentTypes.parentContentTypeId as chtParentId,ParentTypes.parentContentTypeKey as chtParentKey,
umbracoNode.createDate as nCreateDate, umbracoNode." + sqlSyntax.GetQuotedColumnName("level") + @" as nLevel, umbracoNode.nodeObjectType as nObjectType, umbracoNode.nodeUser as nUser,
umbracoNode.parentID as nParentId, umbracoNode." + sqlSyntax.GetQuotedColumnName("path") + @" as nPath, umbracoNode.sortOrder as nSortOrder, umbracoNode." + sqlSyntax.GetQuotedColumnName("text") + @" as nName, umbracoNode.trashed as nTrashed,
umbracoNode.uniqueID as nUniqueId,
umbracoNode.uniqueID as nUniqueId,
Template.alias as tAlias, Template.nodeId as tId,Template.text as tText
FROM cmsContentType
INNER JOIN umbracoNode
@@ -871,8 +869,8 @@ AND umbracoNode.id <> @id",
LEFT JOIN cmsDocumentType
ON cmsDocumentType.contentTypeNodeId = cmsContentType.nodeId
LEFT JOIN (
SELECT cmsContentTypeAllowedContentType.Id, cmsContentTypeAllowedContentType.AllowedId, cmsContentType.alias, cmsContentTypeAllowedContentType.SortOrder
FROM cmsContentTypeAllowedContentType
SELECT cmsContentTypeAllowedContentType.Id, cmsContentTypeAllowedContentType.AllowedId, cmsContentType.alias, cmsContentTypeAllowedContentType.SortOrder
FROM cmsContentTypeAllowedContentType
INNER JOIN cmsContentType
ON cmsContentTypeAllowedContentType.AllowedId = cmsContentType.nodeId
) AllowedTypes
@@ -885,33 +883,15 @@ AND umbracoNode.id <> @id",
ON Template.nodeId = cmsDocumentType.templateNodeId
LEFT JOIN (
SELECT cmsContentType2ContentType.parentContentTypeId, umbracoNode.uniqueID AS parentContentTypeKey, cmsContentType2ContentType.childContentTypeId
FROM cmsContentType2ContentType
FROM cmsContentType2ContentType
INNER JOIN umbracoNode
ON cmsContentType2ContentType.parentContentTypeId = umbracoNode." + sqlSyntax.GetQuotedColumnName("id") + @"
) ParentTypes
ON ParentTypes.childContentTypeId = cmsContentType.nodeId
WHERE (umbracoNode.nodeObjectType = @nodeObjectType)";
if (contentTypeIds.Any())
{
//TODO: This is all sorts of hacky but i don't have time to refactor a lot to get both ints and guids working nicely... this will
// work for the time being.
if (typeof(TId) == typeof(int))
{
sql = sql + " AND (umbracoNode.id IN (@contentTypeIds))";
}
else if (typeof(TId) == typeof(Guid))
{
sql = sql + " AND (umbracoNode.uniqueID IN (@contentTypeIds))";
}
}
//NOTE: we are going to assume there's not going to be more than 2100 content type ids since that is the max SQL param count!
if ((contentTypeIds.Length - 1) > 2000)
throw new InvalidOperationException("Cannot perform this lookup, too many sql parameters");
var result = db.Fetch<dynamic>(sql, new { nodeObjectType = new Guid(Constants.ObjectTypes.DocumentType), contentTypeIds = contentTypeIds });
) ParentTypes
ON ParentTypes.childContentTypeId = cmsContentType.nodeId
WHERE (umbracoNode.nodeObjectType = @nodeObjectType)
ORDER BY ctId";
var result = db.Fetch<dynamic>(sql, new { nodeObjectType = new Guid(Constants.ObjectTypes.DocumentType)});
if (result.Any() == false)
{
@@ -920,170 +900,139 @@ AND umbracoNode.id <> @id",
return Enumerable.Empty<IContentType>();
}
parentContentTypeIds = new Dictionary<TId, IEnumerable<TId>>();
associatedTemplates = new Dictionary<TId, IEnumerable<AssociatedTemplate>>();
parentContentTypeIds = new Dictionary<int, List<int>>();
associatedTemplates = new Dictionary<int, List<AssociatedTemplate>>();
var mappedContentTypes = new List<IContentType>();
foreach (var contentTypeId in contentTypeIds)
var queue = new Queue<dynamic>(result);
var currDefaultTemplate = -1;
var currAllowedContentTypes = new List<ContentTypeSort>();
while (queue.Count > 0)
{
//the current content type id that we're working with
var ct = queue.Dequeue();
var currentCtId = contentTypeId;
//first we want to get the main content type data this is 1 : 1 with umbraco node data
var ct = result
.Where(x =>
{
//TODO: This is a bit hacky right now but don't have time to do a nice refactor to support both GUID and Int queries, so this is
// how it is for now.
return (typeof(TId) == typeof(int))
? x.ctId == currentCtId
: x.nUniqueId == currentCtId;
})
.Select(x => new { x.ctPk, x.ctId, x.ctAlias, x.ctAllowAtRoot, x.ctDesc, x.ctIcon, x.ctIsContainer, x.ctThumb, x.nName, x.nCreateDate, x.nLevel, x.nObjectType, x.nUser, x.nParentId, x.nPath, x.nSortOrder, x.nTrashed, x.nUniqueId })
.DistinctBy(x => (int)x.ctId)
.FirstOrDefault();
if (ct == null)
//check for default templates
bool? isDefaultTemplate = Convert.ToBoolean(ct.dtIsDefault);
int? templateId = ct.dtTemplateId;
if (currDefaultTemplate == -1 && isDefaultTemplate.HasValue && isDefaultTemplate.Value && templateId.HasValue)
{
continue;
currDefaultTemplate = templateId.Value;
}
//get the unique list of associated templates
var defaultTemplates = result
.Where(x =>
{
//TODO: This is a bit hacky right now but don't have time to do a nice refactor to support both GUID and Int queries, so this is
// how it is for now.
return (typeof(TId) == typeof(int))
? x.ctId == currentCtId
: x.nUniqueId == currentCtId;
})
//use a tuple so that distinct checks both values (in some rare cases the dtIsDefault will not compute as bool?, so we force it with Convert.ToBoolean)
.Select(x => new Tuple<bool?, int?>(Convert.ToBoolean(x.dtIsDefault), x.dtTemplateId))
.Where(x => x.Item1.HasValue && x.Item2.HasValue)
.Distinct()
.OrderByDescending(x => x.Item1.Value)
.ToArray();
//if there isn't one set to default explicitly, we'll pick the first one
var defaultTemplate = defaultTemplates.FirstOrDefault(x => x.Item1.Value)
?? defaultTemplates.FirstOrDefault();
//always ensure there's a list for this content type
if (associatedTemplates.ContainsKey(ct.ctId) == false)
associatedTemplates[ct.ctId] = new List<AssociatedTemplate>();
var dtDto = new ContentTypeTemplateDto
//check for associated templates and assign to the outgoing collection
if (ct.tId != null)
{
//create the content type dto
ContentTypeDto = new ContentTypeDto
var associatedTemplate = new AssociatedTemplate(ct.tId, ct.tAlias, ct.tText);
var associatedList = associatedTemplates[ct.ctId];
if (associatedList.Contains(associatedTemplate) == false)
associatedList.Add(associatedTemplate);
}
//check for allowed content types
int? allowedCtId = ct.ctaAllowedId;
int? allowedCtSort = ct.ctaSortOrder;
string allowedCtAlias = ct.ctaAlias;
if (allowedCtId.HasValue && allowedCtSort.HasValue && allowedCtAlias != null)
{
var ctSort = new ContentTypeSort(new Lazy<int>(() => allowedCtId.Value), allowedCtSort.Value, allowedCtAlias);
if (currAllowedContentTypes.Contains(ctSort) == false)
{
Alias = ct.ctAlias,
AllowAtRoot = ct.ctAllowAtRoot,
Description = ct.ctDesc,
Icon = ct.ctIcon,
IsContainer = ct.ctIsContainer,
NodeId = ct.ctId,
PrimaryKey = ct.ctPk,
Thumbnail = ct.ctThumb,
//map the underlying node dto
NodeDto = new NodeDto
{
CreateDate = ct.nCreateDate,
Level = (short)ct.nLevel,
NodeId = ct.ctId,
NodeObjectType = ct.nObjectType,
ParentId = ct.nParentId,
Path = ct.nPath,
SortOrder = ct.nSortOrder,
Text = ct.nName,
Trashed = ct.nTrashed,
UniqueId = ct.nUniqueId,
UserId = ct.nUser
}
},
ContentTypeNodeId = ct.ctId,
IsDefault = defaultTemplate != null,
TemplateNodeId = defaultTemplate != null ? defaultTemplate.Item2.Value : 0,
};
currAllowedContentTypes.Add(ctSort);
}
}
// We will map a subset of the associated template - alias, id, name
//always ensure there's a list for this content type
if (parentContentTypeIds.ContainsKey(ct.ctId) == false)
parentContentTypeIds[ct.ctId] = new List<int>();
associatedTemplates.Add(currentCtId, result
.Where(x =>
{
//TODO: This is a bit hacky right now but don't have time to do a nice refactor to support both GUID and Int queries, so this is
// how it is for now.
return (typeof(TId) == typeof(int))
? x.ctId == currentCtId
: x.nUniqueId == currentCtId;
})
.Where(x => x.tId != null)
.Select(x => new AssociatedTemplate(x.tId, x.tAlias, x.tText))
.Distinct()
.ToArray());
//check for parent ids and assign to the outgoing collection
int? parentId = ct.chtParentId;
if (parentId.HasValue)
{
var associatedParentIds = parentContentTypeIds[ct.ctId];
//now create the content type object
if (associatedParentIds.Contains(parentId.Value) == false)
associatedParentIds.Add(parentId.Value);
}
var factory = new ContentTypeFactory();
var contentType = factory.BuildContentTypeEntity(dtDto.ContentTypeDto);
// NOTE
// that was done by the factory but makes little sense, moved here, so
// now we have to reset dirty props again (as the factory does it) and yet,
// we are not managing allowed templates... the whole thing is weird.
((ContentType) contentType).DefaultTemplateId = dtDto.TemplateNodeId;
contentType.ResetDirtyProperties(false);
if (queue.Count == 0 || queue.Peek().ctId != ct.ctId)
{
//it's the last in the queue or the content type is changing (moving to the next one)
var contentType = CreateForMapping(ct, currAllowedContentTypes, currDefaultTemplate);
mappedContentTypes.Add(contentType);
//map the allowed content types
//map the child content type ids
MapCommonContentTypeObjects(contentType, currentCtId, result, parentContentTypeIds);
mappedContentTypes.Add(contentType);
//Here we need to reset the current variables, we're now collecting data for a different content type
currDefaultTemplate = -1;
currAllowedContentTypes = new List<ContentTypeSort>();
}
}
return mappedContentTypes;
}
private static void MapCommonContentTypeObjects<T, TId>(T contentType, TId currentCtId, List<dynamic> result, IDictionary<TId, IEnumerable<TId>> parentContentTypeIds)
where T : IContentTypeBase
where TId : struct
private static IContentType CreateForMapping(dynamic currCt, List<ContentTypeSort> currAllowedContentTypes, int currDefaultTemplate)
{
//map the allowed content types
contentType.AllowedContentTypes = result
.Where(x =>
{
//TODO: This is a bit hacky right now but don't have time to do a nice refactor to support both GUID and Int queries, so this is
// how it is for now.
return (typeof(TId) == typeof(int))
? x.ctId == currentCtId
: x.nUniqueId == currentCtId;
})
//use tuple so we can use distinct on all vals
.Select(x => new Tuple<int?, int?, string>(x.ctaAllowedId, x.ctaSortOrder, x.ctaAlias))
.Where(x => x.Item1.HasValue && x.Item2.HasValue && x.Item3 != null)
.Distinct()
.Select(x => new ContentTypeSort(new Lazy<int>(() => x.Item1.Value), x.Item2.Value, x.Item3))
.ToList();
// * set the default template to the first one if a default isn't found
// * create the DTO object
// * create the content type object
// * map the allowed content types
// * add to the outgoing list
//map the child content type ids
parentContentTypeIds.Add(currentCtId, result
.Where(x =>
var dtDto = new ContentTypeTemplateDto
{
//create the content type dto
ContentTypeDto = new ContentTypeDto
{
//TODO: This is a bit hacky right now but don't have time to do a nice refactor to support both GUID and Int queries, so this is
// how it is for now.
return (typeof(TId) == typeof(int))
? x.ctId == currentCtId
: x.nUniqueId == currentCtId;
})
.Select(x =>
{
//TODO: This is a bit hacky right now but don't have time to do a nice refactor to support both GUID and Int queries, so this is
// how it is for now.
return (typeof(TId) == typeof(int))
? (TId?)x.chtParentId
: (TId?)x.chtParentKey;
})
.Where(x => x.HasValue)
.Distinct()
.Select(x => x.Value).ToList());
Alias = currCt.ctAlias,
AllowAtRoot = currCt.ctAllowAtRoot,
Description = currCt.ctDesc,
Icon = currCt.ctIcon,
IsContainer = currCt.ctIsContainer,
NodeId = currCt.ctId,
PrimaryKey = currCt.ctPk,
Thumbnail = currCt.ctThumb,
//map the underlying node dto
NodeDto = new NodeDto
{
CreateDate = currCt.nCreateDate,
Level = (short)currCt.nLevel,
NodeId = currCt.ctId,
NodeObjectType = currCt.nObjectType,
ParentId = currCt.nParentId,
Path = currCt.nPath,
SortOrder = currCt.nSortOrder,
Text = currCt.nName,
Trashed = currCt.nTrashed,
UniqueId = currCt.nUniqueId,
UserId = currCt.nUser
}
},
ContentTypeNodeId = currCt.ctId,
IsDefault = currDefaultTemplate != -1,
TemplateNodeId = currDefaultTemplate != -1 ? currDefaultTemplate : 0,
};
//now create the content type object
var factory = new ContentTypeFactory();
var contentType = factory.BuildContentTypeEntity(dtDto.ContentTypeDto);
// NOTE
// that was done by the factory but makes little sense, moved here, so
// now we have to reset dirty props again (as the factory does it) and yet,
// we are not managing allowed templates... the whole thing is weird.
((ContentType)contentType).DefaultTemplateId = dtDto.TemplateNodeId;
contentType.ResetDirtyProperties(false);
//map the allowed content types
contentType.AllowedContentTypes = currAllowedContentTypes;
return contentType;
}
internal static void MapGroupsAndProperties(int[] contentTypeIds, Database db, ISqlSyntaxProvider sqlSyntax,
@@ -1101,14 +1050,14 @@ AND umbracoNode.id <> @id",
// therefore the union of the two contains all of the property type and property group information we need
// NOTE: MySQL requires a SELECT * FROM the inner union in order to be able to sort . lame.
var sqlBuilder = new StringBuilder(@"SELECT PG.contenttypeNodeId as contentTypeId,
PT.ptUniqueId as ptUniqueID, PT.ptId, PT.ptAlias, PT.ptDesc,PT.ptMandatory,PT.ptName,PT.ptSortOrder,PT.ptRegExp,
var sqlBuilder = new StringBuilder(@"SELECT PG.contenttypeNodeId as contentTypeId,
PT.ptUniqueId as ptUniqueID, PT.ptId, PT.ptAlias, PT.ptDesc,PT.ptMandatory,PT.ptName,PT.ptSortOrder,PT.ptRegExp,
PT.dtId,PT.dtDbType,PT.dtPropEdAlias,
PG.id as pgId, PG.uniqueID as pgKey, PG.sortorder as pgSortOrder, PG." + sqlSyntax.GetQuotedColumnName("text") + @" as pgText
FROM cmsPropertyTypeGroup as PG
LEFT JOIN
(
SELECT PT.uniqueID as ptUniqueId, PT.id as ptId, PT.Alias as ptAlias, PT." + sqlSyntax.GetQuotedColumnName("Description") + @" as ptDesc,
SELECT PT.uniqueID as ptUniqueId, PT.id as ptId, PT.Alias as ptAlias, PT." + sqlSyntax.GetQuotedColumnName("Description") + @" as ptDesc,
PT.mandatory as ptMandatory, PT.Name as ptName, PT.sortOrder as ptSortOrder, PT.validationRegExp as ptRegExp,
PT.propertyTypeGroupId as ptGroupId,
DT.dbType as dtDbType, DT.nodeId as dtId, DT.propertyEditorAlias as dtPropEdAlias
@@ -1118,11 +1067,11 @@ AND umbracoNode.id <> @id",
) as PT
ON PT.ptGroupId = PG.id
WHERE (PG.contenttypeNodeId in (@contentTypeIds))
UNION
SELECT PT.contentTypeId as contentTypeId,
PT.uniqueID as ptUniqueID, PT.id as ptId, PT.Alias as ptAlias, PT." + sqlSyntax.GetQuotedColumnName("Description") + @" as ptDesc,
PT.uniqueID as ptUniqueID, PT.id as ptId, PT.Alias as ptAlias, PT." + sqlSyntax.GetQuotedColumnName("Description") + @" as ptDesc,
PT.mandatory as ptMandatory, PT.Name as ptName, PT.sortOrder as ptSortOrder, PT.validationRegExp as ptRegExp,
DT.nodeId as dtId, DT.dbType as dtDbType, DT.propertyEditorAlias as dtPropEdAlias,
PG.id as pgId, PG.uniqueID as pgKey, PG.sortorder as pgSortOrder, PG." + sqlSyntax.GetQuotedColumnName("text") + @" as pgText
@@ -1216,71 +1165,20 @@ AND umbracoNode.id <> @id",
}
/// <summary>
/// Inner repository to support the GUID lookups and keep the caching consistent
/// </summary>
internal class GuidReadOnlyContentTypeBaseRepository : PetaPocoRepositoryBase<Guid, TEntity>
{
private readonly ContentTypeBaseRepository<TEntity> _parentRepo;
public GuidReadOnlyContentTypeBaseRepository(
ContentTypeBaseRepository<TEntity> parentRepo,
IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{
_parentRepo = parentRepo;
}
protected override TEntity PerformGet(Guid id)
{
return _parentRepo.PerformGet(id);
}
protected override IEnumerable<TEntity> PerformGetAll(params Guid[] ids)
{
return _parentRepo.PerformGetAll(ids);
}
protected override Sql GetBaseQuery(bool isCount)
{
return _parentRepo.GetBaseQuery(isCount);
}
protected override string GetBaseWhereClause()
{
return "umbracoNode.uniqueID = @Id";
}
#region No implementation required
protected override IEnumerable<TEntity> PerformGetByQuery(IQuery<TEntity> query)
{
throw new NotImplementedException();
}
protected override IEnumerable<string> GetDeleteClauses()
{
throw new NotImplementedException();
}
protected override Guid NodeObjectTypeId
{
get { throw new NotImplementedException(); }
}
protected override void PersistNewItem(TEntity entity)
{
throw new NotImplementedException();
}
protected override void PersistUpdatedItem(TEntity entity)
{
throw new NotImplementedException();
}
#endregion
}
protected abstract TEntity PerformGet(Guid id);
protected abstract TEntity PerformGet(string alias);
protected abstract IEnumerable<TEntity> PerformGetAll(params Guid[] ids);
protected abstract bool PerformExists(Guid id);
/// <summary>
/// Gets an Entity by alias
/// </summary>
/// <param name="alias"></param>
/// <returns></returns>
public TEntity Get(string alias)
{
return PerformGet(alias);
}
/// <summary>
/// Gets an Entity by Id
@@ -1289,7 +1187,7 @@ AND umbracoNode.id <> @id",
/// <returns></returns>
public TEntity Get(Guid id)
{
return _guidRepo.Get(id);
return PerformGet(id);
}
/// <summary>
@@ -1297,9 +1195,12 @@ AND umbracoNode.id <> @id",
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
public IEnumerable<TEntity> GetAll(params Guid[] ids)
/// <remarks>
/// Ensure explicit implementation, we don't want to have any accidental calls to this since it is essentially the same signature as the main GetAll when there are no parameters
/// </remarks>
IEnumerable<TEntity> IReadRepository<Guid, TEntity>.GetAll(params Guid[] ids)
{
return _guidRepo.GetAll(ids);
return PerformGetAll(ids);
}
/// <summary>
@@ -1309,7 +1210,21 @@ AND umbracoNode.id <> @id",
/// <returns></returns>
public bool Exists(Guid id)
{
return _guidRepo.Exists(id);
return PerformExists(id);
}
public string GetUniqueAlias(string alias)
{
// alias is unique accross ALL content types!
var aliasColumn = SqlSyntax.GetQuotedColumnName("alias");
var aliases = Database.Fetch<string>(@"SELECT cmsContentType." + aliasColumn + @" FROM cmsContentType
INNER JOIN umbracoNode ON cmsContentType.nodeId = umbracoNode.id
WHERE cmsContentType." + aliasColumn + @" LIKE @pattern",
new { pattern = alias + "%", objectType = NodeObjectTypeId });
var i = 1;
string test;
while (aliases.Contains(test = alias + i)) i++;
return test;
}
}
}
}
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Cache;
using Umbraco.Core.Events;
using Umbraco.Core.Exceptions;
using Umbraco.Core.Logging;
@@ -28,42 +29,54 @@ namespace Umbraco.Core.Persistence.Repositories
: base(work, cache, logger, sqlSyntax)
{
_templateRepository = templateRepository;
}
}
private FullDataSetRepositoryCachePolicyFactory<IContentType, int> _cachePolicyFactory;
protected override IRepositoryCachePolicyFactory<IContentType, int> CachePolicyFactory
{
get
{
//Use a FullDataSet cache policy - this will cache the entire GetAll result in a single collection
return _cachePolicyFactory ?? (_cachePolicyFactory = new FullDataSetRepositoryCachePolicyFactory<IContentType, int>(
RuntimeCache, GetEntityId, () => PerformGetAll(),
//allow this cache to expire
expires:true));
}
}
protected override IContentType PerformGet(int id)
{
var contentTypes = ContentTypeQueryMapper.GetContentTypes(
new[] {id}, Database, SqlSyntax, this, _templateRepository);
var contentType = contentTypes.SingleOrDefault();
return contentType;
//use the underlying GetAll which will force cache all content types
return GetAll().FirstOrDefault(x => x.Id == id);
}
protected override IEnumerable<IContentType> PerformGetAll(params int[] ids)
{
if (ids.Any())
{
return ContentTypeQueryMapper.GetContentTypes(ids, Database, SqlSyntax, this, _templateRepository);
}
else
{
var sql = new Sql().Select("id").From<NodeDto>(SqlSyntax).Where<NodeDto>(dto => dto.NodeObjectType == NodeObjectTypeId);
var allIds = Database.Fetch<int>(sql).ToArray();
return ContentTypeQueryMapper.GetContentTypes(allIds, Database, SqlSyntax, this, _templateRepository);
//NOTE: This logic should never be executed according to our cache policy
return ContentTypeQueryMapper.GetContentTypes(Database, SqlSyntax, this, _templateRepository)
.Where(x => ids.Contains(x.Id));
}
return ContentTypeQueryMapper.GetContentTypes(Database, SqlSyntax, this, _templateRepository);
}
protected override IEnumerable<IContentType> PerformGetByQuery(IQuery<IContentType> query)
{
var sqlClause = GetBaseQuery(false);
var translator = new SqlTranslator<IContentType>(sqlClause, query);
var sql = translator.Translate()
.OrderBy<NodeDto>(x => x.Text, SqlSyntax);
var sql = translator.Translate();
var dtos = Database.Fetch<ContentTypeTemplateDto, ContentTypeDto, NodeDto>(sql);
return dtos.Any()
? GetAll(dtos.DistinctBy(x => x.ContentTypeDto.NodeId).Select(x => x.ContentTypeDto.NodeId).ToArray())
: Enumerable.Empty<IContentType>();
return
//This returns a lookup from the GetAll cached looup
(dtos.Any()
? GetAll(dtos.DistinctBy(x => x.ContentTypeDto.NodeId).Select(x => x.ContentTypeDto.NodeId).ToArray())
: Enumerable.Empty<IContentType>())
//order the result by name
.OrderBy(x => x.Name);
}
/// <summary>
@@ -87,7 +100,30 @@ namespace Umbraco.Core.Persistence.Repositories
{
return Database.Fetch<string>("SELECT DISTINCT Alias FROM cmsPropertyType ORDER BY Alias");
}
/// <summary>
/// Gets all content type aliases
/// </summary>
/// <param name="objectTypes">
/// If this list is empty, it will return all content type aliases for media, members and content, otherwise
/// it will only return content type aliases for the object types specified
/// </param>
/// <returns></returns>
public IEnumerable<string> GetAllContentTypeAliases(params Guid[] objectTypes)
{
var sql = new Sql().Select("cmsContentType.alias")
.From<ContentTypeDto>(SqlSyntax)
.InnerJoin<NodeDto>(SqlSyntax)
.On<ContentTypeDto, NodeDto>(SqlSyntax, dto => dto.NodeId, dto => dto.NodeId);
if (objectTypes.Any())
{
sql = sql.Where("umbracoNode.nodeObjectType IN (@objectTypes)", objectTypes);
}
return Database.Fetch<string>(sql);
}
protected override Sql GetBaseQuery(bool isCount)
{
var sql = new Sql();
@@ -151,6 +187,22 @@ namespace Umbraco.Core.Persistence.Repositories
PersistDeletedItem((IEntity)child);
}
//Before we call the base class methods to run all delete clauses, we need to first
// delete all of the property data associated with this document type. Normally this will
// be done in the ContentTypeService by deleting all associated content first, but in some cases
// like when we switch a document type, there is property data left over that is linked
// to the previous document type. So we need to ensure it's removed.
var sql = new Sql().Select("DISTINCT cmsPropertyData.propertytypeid")
.From<PropertyDataDto>(SqlSyntax)
.InnerJoin<PropertyTypeDto>(SqlSyntax)
.On<PropertyDataDto, PropertyTypeDto>(SqlSyntax, dto => dto.PropertyTypeId, dto => dto.Id)
.InnerJoin<ContentTypeDto>(SqlSyntax)
.On<ContentTypeDto, PropertyTypeDto>(SqlSyntax, dto => dto.NodeId, dto => dto.ContentTypeId)
.Where<ContentTypeDto>(dto => dto.NodeId == entity.Id);
//Delete all cmsPropertyData where propertytypeid EXISTS in the subquery above
Database.Execute(SqlSyntax.GetDeleteSubquery("cmsPropertyData", "propertytypeid", sql));
base.PersistDeletedItem(entity);
}
@@ -232,25 +284,33 @@ namespace Umbraco.Core.Persistence.Repositories
protected override IContentType PerformGet(Guid id)
{
var contentTypes = ContentTypeQueryMapper.GetContentTypes(
new[] { id }, Database, SqlSyntax, this, _templateRepository);
//use the underlying GetAll which will force cache all content types
return GetAll().FirstOrDefault(x => x.Key == id);
}
var contentType = contentTypes.SingleOrDefault();
return contentType;
protected override IContentType PerformGet(string alias)
{
//use the underlying GetAll which will force cache all content types
return GetAll().FirstOrDefault(x => x.Alias.InvariantEquals(alias));
}
protected override IEnumerable<IContentType> PerformGetAll(params Guid[] ids)
{
//use the underlying GetAll which will force cache all content types
if (ids.Any())
{
return ContentTypeQueryMapper.GetContentTypes(ids, Database, SqlSyntax, this, _templateRepository);
return GetAll().Where(x => ids.Contains(x.Key));
}
else
{
var sql = new Sql().Select("id").From<NodeDto>(SqlSyntax).Where<NodeDto>(dto => dto.NodeObjectType == NodeObjectTypeId);
var allIds = Database.Fetch<int>(sql).ToArray();
return ContentTypeQueryMapper.GetContentTypes(allIds, Database, SqlSyntax, this, _templateRepository);
return GetAll();
}
}
protected override bool PerformExists(Guid id)
{
return GetAll().FirstOrDefault(x => x.Key == id) != null;
}
}
}
@@ -348,21 +348,29 @@ AND umbracoNode.id <> @id",
new MoveEventInfo<IDataTypeDefinition>(toMove, toMove.Path, parentId)
};
var origPath = toMove.Path;
//do the move to a new parent
toMove.ParentId = parentId;
//set the updated path
toMove.Path = string.Concat(container == null ? parentId.ToInvariantString() : container.Path, ",", toMove.Id);
//schedule it for updating in the transaction
AddOrUpdate(toMove);
//update all descendants
//update all descendants from the original path, update in order of level
var descendants = this.GetByQuery(
new Query<IDataTypeDefinition>().Where(type => type.Path.StartsWith(toMove.Path + ",")));
foreach (var descendant in descendants)
new Query<IDataTypeDefinition>().Where(type => type.Path.StartsWith(origPath + ",")));
var lastParent = toMove;
foreach (var descendant in descendants.OrderBy(x => x.Level))
{
moveInfo.Add(new MoveEventInfo<IDataTypeDefinition>(descendant, descendant.Path, descendant.ParentId));
//all we're doing here is setting the parent Id to be dirty so that it resets the path/level/etc...
descendant.ParentId = descendant.ParentId + 1;
descendant.ParentId = descendant.ParentId - 1;
descendant.ParentId = lastParent.Id;
descendant.Path = string.Concat(lastParent.Path, ",", descendant.Id);
//schedule it for updating in the transaction
AddOrUpdate(descendant);
}
@@ -29,7 +29,8 @@ namespace Umbraco.Core.Persistence.Repositories
get
{
//Use a FullDataSet cache policy - this will cache the entire GetAll result in a single collection
return _cachePolicyFactory ?? (_cachePolicyFactory = new FullDataSetRepositoryCachePolicyFactory<IDomain, int>(RuntimeCache));
return _cachePolicyFactory ?? (_cachePolicyFactory = new FullDataSetRepositoryCachePolicyFactory<IDomain, int>(
RuntimeCache, GetEntityId, () => PerformGetAll(), false));
}
}
@@ -18,9 +18,16 @@ namespace Umbraco.Core.Persistence.Repositories
/// </summary>
internal class EntityContainerRepository : PetaPocoRepositoryBase<int, EntityContainer>
{
public EntityContainerRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
private readonly Guid _containerObjectType;
public EntityContainerRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, Guid containerObjectType)
: base(work, cache, logger, sqlSyntax)
{ }
{
var allowedContainers = new[] {Constants.ObjectTypes.DocumentTypeContainerGuid, Constants.ObjectTypes.MediaTypeContainerGuid, Constants.ObjectTypes.DataTypeContainerGuid};
_containerObjectType = containerObjectType;
if (allowedContainers.Contains(_containerObjectType) == false)
throw new InvalidOperationException("No container type exists with ID: " + _containerObjectType);
}
/// <summary>
/// Do not cache anything
@@ -32,7 +39,7 @@ namespace Umbraco.Core.Persistence.Repositories
protected override EntityContainer PerformGet(int id)
{
var sql = GetBaseQuery(false).Where(GetBaseWhereClause(), new { id });
var sql = GetBaseQuery(false).Where(GetBaseWhereClause(), new { id = id, NodeObjectType = NodeObjectTypeId });
var nodeDto = Database.Fetch<NodeDto>(sql).FirstOrDefault();
return nodeDto == null ? null : CreateEntity(nodeDto);
@@ -47,15 +54,25 @@ namespace Umbraco.Core.Persistence.Repositories
return nodeDto == null ? null : CreateEntity(nodeDto);
}
public IEnumerable<EntityContainer> Get(string name, int level, Guid umbracoObjectTypeId)
public IEnumerable<EntityContainer> Get(string name, int level)
{
var sql = GetBaseQuery(false).Where("text=@name AND level=@level AND nodeObjectType=@umbracoObjectTypeId", new { name, level, umbracoObjectTypeId });
var sql = GetBaseQuery(false).Where("text=@name AND level=@level AND nodeObjectType=@umbracoObjectTypeId", new { name, level, umbracoObjectTypeId = NodeObjectTypeId });
return Database.Fetch<NodeDto>(sql).Select(CreateEntity);
}
protected override IEnumerable<EntityContainer> PerformGetAll(params int[] ids)
{
throw new NotImplementedException();
//we need to batch these in groups of 2000 so we don't exceed the max 2100 limit
return ids.InGroupsOf(2000).SelectMany(@group =>
{
var sql = GetBaseQuery(false)
.Where("nodeObjectType=@umbracoObjectTypeId", new { umbracoObjectTypeId = NodeObjectTypeId })
.Where(string.Format("{0} IN (@ids)", SqlSyntax.GetQuotedColumnName("id")), new { ids = @group });
sql.OrderBy<NodeDto>(x => x.Level, SqlSyntax);
return Database.Fetch<NodeDto>(sql).Select(CreateEntity);
});
}
protected override IEnumerable<EntityContainer> PerformGetByQuery(IQuery<EntityContainer> query)
@@ -99,7 +116,7 @@ namespace Umbraco.Core.Persistence.Repositories
protected override string GetBaseWhereClause()
{
return "umbracoNode.id = @id"; //" and nodeObjectType = @NodeObjectType";
return "umbracoNode.id = @id and nodeObjectType = @NodeObjectType";
}
protected override IEnumerable<string> GetDeleteClauses()
@@ -109,11 +126,13 @@ namespace Umbraco.Core.Persistence.Repositories
protected override Guid NodeObjectTypeId
{
get { throw new NotImplementedException(); }
get { return _containerObjectType; }
}
protected override void PersistDeletedItem(EntityContainer entity)
{
EnsureContainerType(entity);
var nodeDto = Database.FirstOrDefault<NodeDto>(new Sql().Select("*")
.From<NodeDto>(SqlSyntax)
.Where<NodeDto>(dto => dto.NodeId == entity.Id && dto.NodeObjectType == entity.ContainerObjectType));
@@ -143,6 +162,8 @@ namespace Umbraco.Core.Persistence.Repositories
protected override void PersistNewItem(EntityContainer entity)
{
EnsureContainerType(entity);
entity.Name = entity.Name.Trim();
Mandate.ParameterNotNullOrEmpty(entity.Name, "entity.Name");
@@ -202,6 +223,8 @@ namespace Umbraco.Core.Persistence.Repositories
//
protected override void PersistUpdatedItem(EntityContainer entity)
{
EnsureContainerType(entity);
entity.Name = entity.Name.Trim();
Mandate.ParameterNotNullOrEmpty(entity.Name, "entity.Name");
@@ -251,5 +274,13 @@ namespace Umbraco.Core.Persistence.Repositories
entity.SortOrder = 0;
entity.ResetDirtyProperties();
}
private void EnsureContainerType(EntityContainer entity)
{
if (entity.ContainerObjectType != NodeObjectTypeId)
{
throw new InvalidOperationException("The container type does not match the repository object type");
}
}
}
}
@@ -0,0 +1,11 @@
using System;
using Umbraco.Core.Models;
namespace Umbraco.Core.Persistence.Repositories
{
public interface IContentTypeCompositionRepository<TEntity> : IRepositoryQueryable<int, TEntity>, IReadRepository<Guid, TEntity>
where TEntity : IContentTypeComposition
{
TEntity Get(string alias);
}
}
@@ -6,7 +6,7 @@ using Umbraco.Core.Persistence.Querying;
namespace Umbraco.Core.Persistence.Repositories
{
public interface IContentTypeRepository : IRepositoryQueryable<int, IContentType>, IReadRepository<Guid, IContentType>
public interface IContentTypeRepository : IContentTypeCompositionRepository<IContentType>
{
/// <summary>
/// Gets all entities of the specified <see cref="PropertyType"/> query
@@ -22,5 +22,23 @@ namespace Umbraco.Core.Persistence.Repositories
IEnumerable<string> GetAllPropertyTypeAliases();
IEnumerable<MoveEventInfo<IContentType>> Move(IContentType toMove, EntityContainer container);
/// <summary>
/// Gets all content type aliases
/// </summary>
/// <param name="objectTypes">
/// If this list is empty, it will return all content type aliases for media, members and content, otherwise
/// it will only return content type aliases for the object types specified
/// </param>
/// <returns></returns>
IEnumerable<string> GetAllContentTypeAliases(params Guid[] objectTypes);
/// <summary>
/// Derives a unique alias from an existing alias.
/// </summary>
/// <param name="alias">The original alias.</param>
/// <returns>The original alias with a number appended to it, so that it is unique.</returns>
/// /// <remarks>Unique accross all content, media and member types.</remarks>
string GetUniqueAlias(string alias);
}
}
@@ -1,12 +1,11 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using Umbraco.Core.Events;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence.Querying;
namespace Umbraco.Core.Persistence.Repositories
{
public interface IMediaTypeRepository : IRepositoryQueryable<int, IMediaType>, IReadRepository<Guid, IMediaType>
public interface IMediaTypeRepository : IContentTypeCompositionRepository<IMediaType>
{
/// <summary>
/// Gets all entities of the specified <see cref="PropertyType"/> query
@@ -16,5 +15,13 @@ namespace Umbraco.Core.Persistence.Repositories
IEnumerable<IMediaType> GetByQuery(IQuery<PropertyType> query);
IEnumerable<MoveEventInfo<IMediaType>> Move(IMediaType toMove, EntityContainer container);
/// <summary>
/// Derives a unique alias from an existing alias.
/// </summary>
/// <param name="alias">The original alias.</param>
/// <returns>The original alias with a number appended to it, so that it is unique.</returns>
/// <remarks>Unique accross all content, media and member types.</remarks>
string GetUniqueAlias(string alias);
}
}
@@ -3,7 +3,7 @@ using Umbraco.Core.Models;
namespace Umbraco.Core.Persistence.Repositories
{
public interface IMemberTypeRepository : IRepositoryQueryable<int, IMemberType>, IReadRepository<Guid, IMemberType>
public interface IMemberTypeRepository : IContentTypeCompositionRepository<IMemberType>
{
}
@@ -30,7 +30,8 @@ namespace Umbraco.Core.Persistence.Repositories
get
{
//Use a FullDataSet cache policy - this will cache the entire GetAll result in a single collection
return _cachePolicyFactory ?? (_cachePolicyFactory = new FullDataSetRepositoryCachePolicyFactory<ILanguage, int>(RuntimeCache));
return _cachePolicyFactory ?? (_cachePolicyFactory = new FullDataSetRepositoryCachePolicyFactory<ILanguage, int>(
RuntimeCache, GetEntityId, () => PerformGetAll(), false));
}
}
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Cache;
using Umbraco.Core.Events;
using Umbraco.Core.Exceptions;
using Umbraco.Core.Logging;
@@ -26,41 +27,53 @@ namespace Umbraco.Core.Persistence.Repositories
: base(work, cache, logger, sqlSyntax)
{
}
private FullDataSetRepositoryCachePolicyFactory<IMediaType, int> _cachePolicyFactory;
protected override IRepositoryCachePolicyFactory<IMediaType, int> CachePolicyFactory
{
get
{
//Use a FullDataSet cache policy - this will cache the entire GetAll result in a single collection
return _cachePolicyFactory ?? (_cachePolicyFactory = new FullDataSetRepositoryCachePolicyFactory<IMediaType, int>(
RuntimeCache, GetEntityId, () => PerformGetAll(),
//allow this cache to expire
expires: true));
}
}
protected override IMediaType PerformGet(int id)
{
var contentTypes = ContentTypeQueryMapper.GetMediaTypes(
new[] { id }, Database, SqlSyntax, this);
var contentType = contentTypes.SingleOrDefault();
return contentType;
//use the underlying GetAll which will force cache all content types
return GetAll().FirstOrDefault(x => x.Id == id);
}
protected override IEnumerable<IMediaType> PerformGetAll(params int[] ids)
{
if (ids.Any())
{
return ContentTypeQueryMapper.GetMediaTypes(ids, Database, SqlSyntax, this);
}
else
{
var sql = new Sql().Select("id").From<NodeDto>(SqlSyntax).Where<NodeDto>(dto => dto.NodeObjectType == NodeObjectTypeId);
var allIds = Database.Fetch<int>(sql).ToArray();
return ContentTypeQueryMapper.GetMediaTypes(allIds, Database, SqlSyntax, this);
//NOTE: This logic should never be executed according to our cache policy
return ContentTypeQueryMapper.GetMediaTypes(Database, SqlSyntax, this)
.Where(x => ids.Contains(x.Id));
}
return ContentTypeQueryMapper.GetMediaTypes(Database, SqlSyntax, this);
}
protected override IEnumerable<IMediaType> PerformGetByQuery(IQuery<IMediaType> query)
{
var sqlClause = GetBaseQuery(false);
var translator = new SqlTranslator<IMediaType>(sqlClause, query);
var sql = translator.Translate()
.OrderBy<NodeDto>(x => x.Text, SqlSyntax);
var sql = translator.Translate();
var dtos = Database.Fetch<ContentTypeDto, NodeDto>(sql);
return dtos.Any()
? GetAll(dtos.DistinctBy(x => x.NodeId).Select(x => x.NodeId).ToArray())
: Enumerable.Empty<IMediaType>();
return
//This returns a lookup from the GetAll cached looup
(dtos.Any()
? GetAll(dtos.DistinctBy(x => x.NodeId).Select(x => x.NodeId).ToArray())
: Enumerable.Empty<IMediaType>())
//order the result by name
.OrderBy(x => x.Name);
}
/// <summary>
@@ -149,28 +162,36 @@ namespace Umbraco.Core.Persistence.Repositories
entity.ResetDirtyProperties();
}
protected override IMediaType PerformGet(Guid id)
{
var contentTypes = ContentTypeQueryMapper.GetMediaTypes(
new[] { id }, Database, SqlSyntax, this);
var contentType = contentTypes.SingleOrDefault();
return contentType;
//use the underlying GetAll which will force cache all content types
return GetAll().FirstOrDefault(x => x.Key == id);
}
protected override IEnumerable<IMediaType> PerformGetAll(params Guid[] ids)
{
//use the underlying GetAll which will force cache all content types
if (ids.Any())
{
return ContentTypeQueryMapper.GetMediaTypes(ids, Database, SqlSyntax, this);
return GetAll().Where(x => ids.Contains(x.Key));
}
else
{
var sql = new Sql().Select("id").From<NodeDto>(SqlSyntax).Where<NodeDto>(dto => dto.NodeObjectType == NodeObjectTypeId);
var allIds = Database.Fetch<int>(sql).ToArray();
return ContentTypeQueryMapper.GetMediaTypes(allIds, Database, SqlSyntax, this);
return GetAll();
}
}
protected override bool PerformExists(Guid id)
{
return GetAll().FirstOrDefault(x => x.Key == id) != null;
}
protected override IMediaType PerformGet(string alias)
{
//use the underlying GetAll which will force cache all content types
return GetAll().FirstOrDefault(x => x.Alias.InvariantEquals(alias));
}
}
}
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using log4net;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models;
@@ -26,25 +27,23 @@ namespace Umbraco.Core.Persistence.Repositories
{
}
#region Overrides of RepositoryBase<int, IMemberType>
private FullDataSetRepositoryCachePolicyFactory<IMemberType, int> _cachePolicyFactory;
protected override IRepositoryCachePolicyFactory<IMemberType, int> CachePolicyFactory
{
get
{
//Use a FullDataSet cache policy - this will cache the entire GetAll result in a single collection
return _cachePolicyFactory ?? (_cachePolicyFactory = new FullDataSetRepositoryCachePolicyFactory<IMemberType, int>(
RuntimeCache, GetEntityId, () => PerformGetAll(),
//allow this cache to expire
expires: true));
}
}
protected override IMemberType PerformGet(int id)
{
var sql = GetBaseQuery(false);
sql.Where(GetBaseWhereClause(), new { Id = id });
sql.OrderByDescending<NodeDto>(x => x.NodeId, SqlSyntax);
var dtos =
Database.Fetch<MemberTypeReadOnlyDto, PropertyTypeReadOnlyDto, PropertyTypeGroupReadOnlyDto, MemberTypeReadOnlyDto>(
new PropertyTypePropertyGroupRelator().Map, sql);
if (dtos == null || dtos.Any() == false)
return null;
var factory = new MemberTypeReadOnlyFactory();
var member = factory.BuildEntity(dtos.First());
return member;
//use the underlying GetAll which will force cache all content types
return GetAll().FirstOrDefault(x => x.Id == id);
}
protected override IEnumerable<IMemberType> PerformGetAll(params int[] ids)
@@ -52,10 +51,11 @@ namespace Umbraco.Core.Persistence.Repositories
var sql = GetBaseQuery(false);
if (ids.Any())
{
//NOTE: This logic should never be executed according to our cache policy
var statement = string.Join(" OR ", ids.Select(x => string.Format("umbracoNode.id='{0}'", x)));
sql.Where(statement);
}
sql.OrderByDescending<NodeDto>(x => x.NodeId);
sql.OrderByDescending<NodeDto>(x => x.NodeId, SqlSyntax);
var dtos =
Database.Fetch<MemberTypeReadOnlyDto, PropertyTypeReadOnlyDto, PropertyTypeGroupReadOnlyDto, MemberTypeReadOnlyDto>(
@@ -71,7 +71,7 @@ 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);
.OrderBy<NodeDto>(x => x.SortOrder, SqlSyntax);
var dtos =
Database.Fetch<MemberTypeReadOnlyDto, PropertyTypeReadOnlyDto, PropertyTypeGroupReadOnlyDto, MemberTypeReadOnlyDto>(
@@ -79,11 +79,7 @@ namespace Umbraco.Core.Persistence.Repositories
return BuildFromDtos(dtos);
}
#endregion
#region Overrides of PetaPocoRepositoryBase<int, IMemberType>
protected override Sql GetBaseQuery(bool isCount)
{
var sql = new Sql();
@@ -157,11 +153,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
get { return new Guid(Constants.ObjectTypes.MemberType); }
}
#endregion
#region Unit of Work Implementation
protected override void PersistNewItem(IMemberType entity)
{
ValidateAlias(entity);
@@ -232,8 +224,6 @@ namespace Umbraco.Core.Persistence.Repositories
entity.ResetDirtyProperties();
}
#endregion
/// <summary>
/// Override so we can specify explicit db type's on any property types that are built-in.
@@ -256,38 +246,33 @@ namespace Umbraco.Core.Persistence.Repositories
protected override IMemberType PerformGet(Guid id)
{
var sql = GetBaseQuery(false);
sql.Where("umbracoNode.uniqueID = @Id", new { Id = id });
sql.OrderByDescending<NodeDto>(x => x.NodeId);
var dtos =
Database.Fetch<MemberTypeReadOnlyDto, PropertyTypeReadOnlyDto, PropertyTypeGroupReadOnlyDto, MemberTypeReadOnlyDto>(
new PropertyTypePropertyGroupRelator().Map, sql);
if (dtos == null || dtos.Any() == false)
return null;
var factory = new MemberTypeReadOnlyFactory();
var member = factory.BuildEntity(dtos.First());
return member;
//use the underlying GetAll which will force cache all content types
return GetAll().FirstOrDefault(x => x.Key == id);
}
protected override IEnumerable<IMemberType> PerformGetAll(params Guid[] ids)
{
var sql = GetBaseQuery(false);
//use the underlying GetAll which will force cache all content types
if (ids.Any())
{
var statement = string.Join(" OR ", ids.Select(x => string.Format("umbracoNode.uniqueID='{0}'", x)));
sql.Where(statement);
return GetAll().Where(x => ids.Contains(x.Key));
}
sql.OrderByDescending<NodeDto>(x => x.NodeId, SqlSyntax);
else
{
return GetAll();
}
}
var dtos =
Database.Fetch<MemberTypeReadOnlyDto, PropertyTypeReadOnlyDto, PropertyTypeGroupReadOnlyDto, MemberTypeReadOnlyDto>(
new PropertyTypePropertyGroupRelator().Map, sql);
protected override bool PerformExists(Guid id)
{
return GetAll().FirstOrDefault(x => x.Key == id) != null;
}
return BuildFromDtos(dtos);
protected override IMemberType PerformGet(string alias)
{
//use the underlying GetAll which will force cache all content types
return GetAll().FirstOrDefault(x => x.Alias.InvariantEquals(alias));
}
/// <summary>
@@ -26,7 +26,8 @@ namespace Umbraco.Core.Persistence.Repositories
get
{
//Use a FullDataSet cache policy - this will cache the entire GetAll result in a single collection
return _cachePolicyFactory ?? (_cachePolicyFactory = new FullDataSetRepositoryCachePolicyFactory<PublicAccessEntry, Guid>(RuntimeCache));
return _cachePolicyFactory ?? (_cachePolicyFactory = new FullDataSetRepositoryCachePolicyFactory<PublicAccessEntry, Guid>(
RuntimeCache, GetEntityId, () => PerformGetAll(), false));
}
}
@@ -82,7 +82,11 @@ namespace Umbraco.Core.Persistence.Repositories
{
}
protected virtual TId GetEntityId(TEntity entity)
{
return (TId)(object)entity.Id;
}
/// <summary>
/// The runtime cache used for this repo by default is the isolated cache for this type
@@ -179,7 +183,8 @@ namespace Umbraco.Core.Persistence.Repositories
using (var p = CachePolicyFactory.CreatePolicy())
{
return p.GetAll(ids, PerformGetAll);
var result = p.GetAll(ids, PerformGetAll);
return result;
}
}
@@ -51,7 +51,8 @@ namespace Umbraco.Core.Persistence.Repositories
get
{
//Use a FullDataSet cache policy - this will cache the entire GetAll result in a single collection
return _cachePolicyFactory ?? (_cachePolicyFactory = new FullDataSetRepositoryCachePolicyFactory<ITemplate, int>(RuntimeCache));
return _cachePolicyFactory ?? (_cachePolicyFactory = new FullDataSetRepositoryCachePolicyFactory<ITemplate, int>(
RuntimeCache, GetEntityId, () => PerformGetAll(), false));
}
}
@@ -475,7 +476,7 @@ namespace Umbraco.Core.Persistence.Repositories
if (aliases.Any() == false) return base.GetAll();
//return from base.GetAll, this is all cached
return base.GetAll().Where(x => aliases.Contains(x.Alias));
return base.GetAll().Where(x => aliases.InvariantContains(x.Alias));
}
public IEnumerable<ITemplate> GetChildren(int masterTemplateId)
@@ -488,7 +489,7 @@ namespace Umbraco.Core.Persistence.Repositories
var parent = all.FirstOrDefault(x => x.Id == masterTemplateId);
if (parent == null) return Enumerable.Empty<ITemplate>();
var children = all.Where(x => x.MasterTemplateAlias == parent.Alias);
var children = all.Where(x => x.MasterTemplateAlias.InvariantEquals(parent.Alias));
return children;
}
@@ -497,7 +498,7 @@ namespace Umbraco.Core.Persistence.Repositories
//return from base.GetAll, this is all cached
return base.GetAll().Where(x => alias.IsNullOrWhiteSpace()
? x.MasterTemplateAlias.IsNullOrWhiteSpace()
: x.MasterTemplateAlias == alias);
: x.MasterTemplateAlias.InvariantEquals(alias));
}
public IEnumerable<ITemplate> GetDescendants(int masterTemplateId)
@@ -532,7 +533,7 @@ namespace Umbraco.Core.Persistence.Repositories
var descendants = new List<ITemplate>();
if (alias.IsNullOrWhiteSpace() == false)
{
var parent = all.FirstOrDefault(x => x.Alias == alias);
var parent = all.FirstOrDefault(x => x.Alias.InvariantEquals(alias));
if (parent == null) return Enumerable.Empty<ITemplate>();
//recursively add all children
AddChildren(all, descendants, parent.Alias);
@@ -552,7 +553,7 @@ namespace Umbraco.Core.Persistence.Repositories
private void AddChildren(ITemplate[] all, List<ITemplate> descendants, string masterAlias)
{
var c = all.Where(x => x.MasterTemplateAlias == masterAlias).ToArray();
var c = all.Where(x => x.MasterTemplateAlias.InvariantEquals(masterAlias)).ToArray();
descendants.AddRange(c);
if (c.Any() == false) return;
//recurse through all children
@@ -573,7 +574,7 @@ namespace Umbraco.Core.Persistence.Repositories
//first get all template objects
var allTemplates = base.GetAll().ToArray();
var selfTemplate = allTemplates.SingleOrDefault(x => x.Alias == alias);
var selfTemplate = allTemplates.SingleOrDefault(x => x.Alias.InvariantEquals(alias));
if (selfTemplate == null)
{
return null;
@@ -582,11 +583,11 @@ namespace Umbraco.Core.Persistence.Repositories
var top = selfTemplate;
while (top.MasterTemplateAlias.IsNullOrWhiteSpace() == false)
{
top = allTemplates.Single(x => x.Alias == top.MasterTemplateAlias);
top = allTemplates.Single(x => x.Alias.InvariantEquals(top.MasterTemplateAlias));
}
var topNode = new TemplateNode(allTemplates.Single(x => x.Id == top.Id));
var childTemplates = allTemplates.Where(x => x.MasterTemplateAlias == top.Alias);
var childTemplates = allTemplates.Where(x => x.MasterTemplateAlias.InvariantEquals(top.Alias));
//This now creates the hierarchy recursively
topNode.Children = CreateChildren(topNode, childTemplates, allTemplates);
@@ -598,7 +599,7 @@ namespace Umbraco.Core.Persistence.Repositories
private static TemplateNode WalkTree(TemplateNode current, string alias)
{
//now walk the tree to find the node
if (current.Template.Alias == alias)
if (current.Template.Alias.InvariantEquals(alias))
{
return current;
}
@@ -730,7 +731,7 @@ namespace Umbraco.Core.Persistence.Repositories
//get this node's children
var local = childTemplate;
var kids = allTemplates.Where(x => x.MasterTemplateAlias == local.Alias);
var kids = allTemplates.Where(x => x.MasterTemplateAlias.InvariantEquals(local.Alias));
//recurse
child.Children = CreateChildren(child, kids, allTemplates);
@@ -760,7 +761,7 @@ namespace Umbraco.Core.Persistence.Repositories
private bool AliasAlreadExists(ITemplate template)
{
var sql = GetBaseQuery(true).Where<TemplateDto>(x => x.Alias == template.Alias && x.NodeId != template.Id);
var sql = GetBaseQuery(true).Where<TemplateDto>(x => x.Alias.InvariantEquals(template.Alias) && x.NodeId != template.Id);
var count = Database.ExecuteScalar<int>(sql);
return count > 0;
}
@@ -31,29 +31,27 @@ 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
// changes entities are reset.
if ((_cacheHelper.RuntimeCache is DeepCloneRuntimeCacheProvider) == false)
{
var originalHelper = cacheHelper;
_cacheHelper = new CacheHelper(
new DeepCloneRuntimeCacheProvider(originalHelper.RuntimeCache),
originalHelper.StaticCache,
originalHelper.RequestCache,
new IsolatedRuntimeCache(type =>
{
var cache = originalHelper.IsolatedRuntimeCache.GetOrCreateCache(type);
return (cache is DeepCloneRuntimeCacheProvider) == false
//wrap the original if it's not DeepCloneRuntimeCacheProvider
? new DeepCloneRuntimeCacheProvider(cache)
: cache;
}));
var origRuntimeCache = cacheHelper.RuntimeCache;
_cacheHelper.RuntimeCache = new DeepCloneRuntimeCacheProvider(origRuntimeCache);
}
//If the factory for isolated cache doesn't return DeepCloneRuntimeCacheProvider, then ensure it does
if (_cacheHelper.IsolatedRuntimeCache.CacheFactory.Method.ReturnType != typeof (DeepCloneRuntimeCacheProvider))
{
var origFactory = cacheHelper.IsolatedRuntimeCache.CacheFactory;
_cacheHelper.IsolatedRuntimeCache.CacheFactory = type =>
{
var cache = origFactory(type);
return new DeepCloneRuntimeCacheProvider(cache);
};
}
_noCache = CacheHelper.CreateDisabledCacheHelper();
_logger = logger;
_sqlSyntax = sqlSyntax;
@@ -327,12 +325,13 @@ namespace Umbraco.Core.Persistence
_logger, _sqlSyntax);
}
internal virtual EntityContainerRepository CreateEntityContainerRepository(IDatabaseUnitOfWork uow)
internal virtual EntityContainerRepository CreateEntityContainerRepository(IDatabaseUnitOfWork uow, Guid containerObjectType)
{
return new EntityContainerRepository(
uow,
_cacheHelper,
_logger, _sqlSyntax);
_logger, _sqlSyntax,
containerObjectType);
}
}
}
@@ -28,6 +28,8 @@ namespace Umbraco.Core.Persistence.SqlSyntax
GuidColumnDefinition = "char(36)";
DefaultValueFormat = "DEFAULT {0}";
InitColumnTypeMap();
}
public override IEnumerable<string> GetTablesInSchema(Database db)
@@ -12,9 +12,9 @@ namespace Umbraco.Core.Persistence
/// Represents the Umbraco implementation of the PetaPoco Database object
/// </summary>
/// <remarks>
/// Currently this object exists for 'future proofing' our implementation. By having our own inheritied implementation we
/// Currently this object exists for 'future proofing' our implementation. By having our own inheritied implementation we
/// can then override any additional execution (such as additional loggging, functionality, etc...) that we need to without breaking compatibility since we'll always be exposing
/// this object instead of the base PetaPoco database object.
/// this object instead of the base PetaPoco database object.
/// </remarks>
public class UmbracoDatabase : Database, IDisposeOnRequestEnd
{
@@ -111,7 +111,9 @@ namespace Umbraco.Core.Persistence
public override IDbConnection OnConnectionOpened(IDbConnection connection)
{
// wrap the connection with a profiling connection that tracks timings
// propagate timeout if none yet
// wrap the connection with a profiling connection that tracks timings
return new StackExchange.Profiling.Data.ProfiledDbConnection(connection as DbConnection, MiniProfiler.Current);
}
@@ -121,6 +123,14 @@ namespace Umbraco.Core.Persistence
base.OnException(x);
}
public override void OnExecutingCommand(IDbCommand cmd)
{
// if no timeout is specified, and the connection has a longer timeout, use it
if (OneTimeCommandTimeout == 0 && CommandTimeout == 0 && cmd.Connection.ConnectionTimeout > 30)
cmd.CommandTimeout = cmd.Connection.ConnectionTimeout;
base.OnExecutingCommand(cmd);
}
public override void OnExecutedCommand(IDbCommand cmd)
{
if (EnableSqlTrace)
@@ -8,6 +8,7 @@ namespace Umbraco.Core.PropertyEditors
/// <summary>
/// Manages the list of IPropertyEditorValueConverter's
/// </summary>
[Obsolete("IPropertyEditorValueConverter is obsolete, but we need to support them until v8, to resolve the correct converter types use: PropertyValueConvertersResolver")]
internal sealed class PropertyEditorValueConvertersResolver : ManyObjectsResolverBase<PropertyEditorValueConvertersResolver, IPropertyEditorValueConverter>
{
/// <summary>
@@ -12,6 +12,9 @@ using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
/// <summary>
/// This ensures that the grid config is merged in with the front-end value
/// </summary>
[DefaultPropertyValueConverter(typeof(JsonValueConverter))] //this shadows the JsonValueConverter
[PropertyValueType(typeof(JToken))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
@@ -90,7 +93,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
}
catch (Exception ex)
{
LogHelper.Error<JsonValueConverter>("Could not parse the string " + sourceString + " to a json object", ex);
LogHelper.Error<GridValueConverter>("Could not parse the string " + sourceString + " to a json object", ex);
}
}
@@ -0,0 +1,125 @@
using System;
using System.Globalization;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Services;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
/// <summary>
/// This ensures that the cropper config (pre-values/crops) are merged in with the front-end value.
/// </summary>
[DefaultPropertyValueConverter(typeof (JsonValueConverter))] //this shadows the JsonValueConverter
[PropertyValueType(typeof (JToken))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class ImageCropperValueConverter : JsonValueConverter
{
private readonly IDataTypeService _dataTypeService;
public ImageCropperValueConverter()
{
_dataTypeService = ApplicationContext.Current.Services.DataTypeService;
}
public ImageCropperValueConverter(IDataTypeService dataTypeService)
{
if (dataTypeService == null) throw new ArgumentNullException("dataTypeService");
_dataTypeService = dataTypeService;
}
public override bool IsConverter(PublishedPropertyType propertyType)
{
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.ImageCropperAlias);
}
internal static void MergePreValues(JObject currentValue, IDataTypeService dataTypeService, int dataTypeId)
{
//need to lookup the pre-values for this data type
//TODO: Change all singleton access to use ctor injection in v8!!!
var dt = dataTypeService.GetPreValuesCollectionByDataTypeId(dataTypeId);
if (dt != null && dt.IsDictionaryBased && dt.PreValuesAsDictionary.ContainsKey("crops"))
{
var cropsString = dt.PreValuesAsDictionary["crops"].Value;
JArray preValueCrops;
try
{
preValueCrops = JsonConvert.DeserializeObject<JArray>(cropsString);
}
catch (Exception ex)
{
LogHelper.Error<ImageCropperValueConverter>("Could not parse the string " + cropsString + " to a json object", ex);
return;
}
//now we need to merge the crop values - the alias + width + height comes from pre-configured pre-values,
// however, each crop can store it's own coordinates
JArray existingCropsArray;
if (currentValue["crops"] != null)
{
existingCropsArray = (JArray)currentValue["crops"];
}
else
{
currentValue["crops"] = existingCropsArray = new JArray();
}
foreach (var preValueCrop in preValueCrops.Where(x => x.HasValues))
{
var found = existingCropsArray.FirstOrDefault(x =>
{
if (x.HasValues && x["alias"] != null)
{
return x["alias"].Value<string>() == preValueCrop["alias"].Value<string>();
}
return false;
});
if (found != null)
{
found["width"] = preValueCrop["width"];
found["height"] = preValueCrop["height"];
}
else
{
existingCropsArray.Add(preValueCrop);
}
}
}
}
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
if (source == null) return null;
var sourceString = source.ToString();
if (sourceString.DetectIsJson())
{
JObject obj;
try
{
obj = JsonConvert.DeserializeObject<JObject>(sourceString, new JsonSerializerSettings
{
Culture = CultureInfo.InvariantCulture,
FloatParseHandling = FloatParseHandling.Decimal
});
}
catch (Exception ex)
{
LogHelper.Error<ImageCropperValueConverter>("Could not parse the string " + sourceString + " to a json object", ex);
return sourceString;
}
MergePreValues(obj, _dataTypeService, propertyType.DataTypeId);
return obj;
}
//it's not json, just return the string
return sourceString;
}
}
}
@@ -0,0 +1,28 @@
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
/// <summary>
/// We need this property converter so that we always force the value of a label to be a string
/// </summary>
/// <remarks>
/// Without a property converter defined for the label type, the value will be converted with
/// the `ConvertUsingDarkMagic` method which will try to parse the value into it's correct type, but this
/// can cause issues if the string is detected as a number and then strips leading zeros.
/// Example: http://issues.umbraco.org/issue/U4-7929
/// </remarks>
[DefaultPropertyValueConverter]
[PropertyValueType(typeof (string))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class LabelValueConverter : PropertyValueConverterBase
{
public override bool IsConverter(PublishedPropertyType propertyType)
{
return Constants.PropertyEditors.NoEditAlias.Equals(propertyType.PropertyEditorAlias);
}
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
return source == null ? string.Empty : source.ToString();
}
}
}
@@ -103,10 +103,18 @@ namespace Umbraco.Core.Security
var backOfficeIdentity = http.User.Identity as UmbracoBackOfficeIdentity;
if (backOfficeIdentity != null) return backOfficeIdentity;
//Check if there's more than one identity assigned and see if it's a UmbracoBackOfficeIdentity and use that
var claimsPrincipal = http.User as ClaimsPrincipal;
if (claimsPrincipal != null)
{
backOfficeIdentity = claimsPrincipal.Identities.OfType<UmbracoBackOfficeIdentity>().FirstOrDefault();
if (backOfficeIdentity != null) return backOfficeIdentity;
}
//Otherwise convert to a UmbracoBackOfficeIdentity if it's auth'd and has the back office session
var claimsIdentity = http.User.Identity as ClaimsIdentity;
if (claimsIdentity != null && claimsIdentity.IsAuthenticated)
{
{
try
{
return UmbracoBackOfficeIdentity.FromClaimsIdentity(claimsIdentity);
@@ -167,74 +175,18 @@ namespace Umbraco.Core.Security
/// This clears the forms authentication cookie for webapi since cookies are handled differently
/// </summary>
/// <param name="response"></param>
[Obsolete("Use OWIN IAuthenticationManager.SignOut instead")]
[Obsolete("Use OWIN IAuthenticationManager.SignOut instead", true)]
[EditorBrowsable(EditorBrowsableState.Never)]
public static void UmbracoLogoutWebApi(this HttpResponseMessage response)
{
if (response == null) throw new ArgumentNullException("response");
//remove the cookie
var authCookie = new CookieHeaderValue(UmbracoConfig.For.UmbracoSettings().Security.AuthCookieName, "")
{
Expires = DateTime.Now.AddYears(-1),
Path = "/"
};
//remove the preview cookie too
var prevCookie = new CookieHeaderValue(Constants.Web.PreviewCookieName, "")
{
Expires = DateTime.Now.AddYears(-1),
Path = "/"
};
//remove the external login cookie too
var extLoginCookie = new CookieHeaderValue(Constants.Security.BackOfficeExternalCookieName, "")
{
Expires = DateTime.Now.AddYears(-1),
Path = "/"
};
response.Headers.AddCookies(new[] { authCookie, prevCookie, extLoginCookie });
throw new NotSupportedException("This method is not supported and should not be used, it has been removed in Umbraco 7.4");
}
[Obsolete("Use WebSecurity.SetPrincipalForRequest")]
[Obsolete("Use WebSecurity.SetPrincipalForRequest", true)]
[EditorBrowsable(EditorBrowsableState.Never)]
public static FormsAuthenticationTicket UmbracoLoginWebApi(this HttpResponseMessage response, IUser user)
{
if (response == null) throw new ArgumentNullException("response");
//remove the external login cookie
var extLoginCookie = new CookieHeaderValue(Constants.Security.BackOfficeExternalCookieName, "")
{
Expires = DateTime.Now.AddYears(-1),
Path = "/"
};
var userDataString = JsonConvert.SerializeObject(Mapper.Map<UserData>(user));
var ticket = new FormsAuthenticationTicket(
4,
user.Username,
DateTime.Now,
DateTime.Now.AddMinutes(GlobalSettings.TimeOutInMinutes),
true,
userDataString,
"/"
);
// Encrypt the cookie using the machine key for secure transport
var encrypted = FormsAuthentication.Encrypt(ticket);
//add the cookie
var authCookie = new CookieHeaderValue(UmbracoConfig.For.UmbracoSettings().Security.AuthCookieName, encrypted)
{
//Umbraco has always persisted it's original cookie for 1 day so we'll keep it that way
Expires = DateTime.Now.AddMinutes(1440),
Path = "/",
Secure = GlobalSettings.UseSSL,
HttpOnly = true
};
response.Headers.AddCookies(new[] { authCookie, extLoginCookie });
return ticket;
throw new NotSupportedException("This method is not supported and should not be used, it has been removed in Umbraco 7.4");
}
/// <summary>
@@ -9,6 +9,12 @@ namespace Umbraco.Core.Security
{
public class BackOfficeClaimsIdentityFactory : ClaimsIdentityFactory<BackOfficeIdentityUser, int>
{
public BackOfficeClaimsIdentityFactory()
{
SecurityStampClaimType = Constants.Security.SessionIdClaimType;
UserNameClaimType = ClaimTypes.Name;
}
/// <summary>
/// Create a ClaimsIdentity from a user
/// </summary>
@@ -20,7 +26,7 @@ namespace Umbraco.Core.Security
var umbracoIdentity = new UmbracoBackOfficeIdentity(baseIdentity,
//set a new session id
new UserData(Guid.NewGuid().ToString("N"))
new UserData
{
Id = user.Id,
Username = user.UserName,
@@ -29,7 +35,8 @@ namespace Umbraco.Core.Security
Culture = user.Culture,
Roles = user.Roles.Select(x => x.RoleId).ToArray(),
StartContentNode = user.StartContentId,
StartMediaNode = user.StartMediaId
StartMediaNode = user.StartMediaId,
SessionId = user.SecurityStamp
});
return umbracoIdentity;
@@ -759,12 +759,13 @@ namespace Umbraco.Core.Security
//This is the correct way to implement this (as per the sql membership provider)
switch ((int)PasswordFormat)
switch (PasswordFormat)
{
case 0:
case MembershipPasswordFormat.Clear:
return pass;
case 1:
case MembershipPasswordFormat.Hashed:
throw new ProviderException("Provider can not decrypt hashed password");
case MembershipPasswordFormat.Encrypted:
default:
var bytes = DecryptPassword(Convert.FromBase64String(pass));
return bytes == null ? null : Encoding.Unicode.GetString(bytes, 16, bytes.Length - 16);
@@ -209,17 +209,19 @@ namespace Umbraco.Core.Security
if (HasClaim(x => x.Type == ClaimTypes.Locality) == false)
AddClaim(new Claim(ClaimTypes.Locality, Culture, ClaimValueTypes.String, Issuer, Issuer, this));
////TODO: Not sure why this is null sometimes, it shouldn't be. Somewhere it's not being set
/// I think it's due to some bug I had in chrome, we'll see
//if (UserData.SessionId.IsNullOrWhiteSpace())
//{
// UserData.SessionId = Guid.NewGuid().ToString();
//}
if (HasClaim(x => x.Type == Constants.Security.SessionIdClaimType) == false)
if (HasClaim(x => x.Type == Constants.Security.SessionIdClaimType) == false && SessionId.IsNullOrWhiteSpace() == false)
{
AddClaim(new Claim(Constants.Security.SessionIdClaimType, SessionId, ClaimValueTypes.String, Issuer, Issuer, this));
//The security stamp claim is also required... this is because this claim type is hard coded
// by the SecurityStampValidator, see: https://katanaproject.codeplex.com/workitem/444
if (HasClaim(x => x.Type == Microsoft.AspNet.Identity.Constants.DefaultSecurityStampClaimType) == false)
{
AddClaim(new Claim(Microsoft.AspNet.Identity.Constants.DefaultSecurityStampClaimType, SessionId, ClaimValueTypes.String, Issuer, Issuer, this));
}
}
//Add each app as a separate claim
if (HasClaim(x => x.Type == Constants.Security.AllowedApplicationsClaimType) == false)
{
+2 -5
View File
@@ -20,7 +20,7 @@ namespace Umbraco.Core.Security
/// Use this constructor to create/assign new UserData to the ticket
/// </summary>
/// <param name="sessionId">
/// A unique id that is assigned to this ticket
/// The security stamp for the user
/// </param>
public UserData(string sessionId)
{
@@ -30,8 +30,7 @@ namespace Umbraco.Core.Security
}
/// <summary>
/// This is used to Id the current ticket which we can then use to mitigate csrf attacks
/// and other things that require request validation.
/// This is the 'security stamp' for validation
/// </summary>
[DataMember(Name = "sessionId")]
public string SessionId { get; set; }
@@ -42,8 +41,6 @@ namespace Umbraco.Core.Security
[DataMember(Name = "roles")]
public string[] Roles { get; set; }
//public int SessionTimeout { get; set; }
[DataMember(Name = "username")]
public string Username { get; set; }
@@ -0,0 +1,52 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
namespace Umbraco.Core.Serialization
{
/// <summary>
/// This is required if we want to force JSON.Net to not use .Net TypeConverters during serialization/deserialization
/// </summary>
/// <typeparam name="T"></typeparam>
/// <remarks>
/// In some cases thsi is required if your model has an explicit type converter, see: http://stackoverflow.com/a/31328131/694494
///
/// NOTE: I was going to use this for the ImageCropDataSetConverter to convert to String, which would have worked by putting this attribute:
/// [JsonConverter(typeof(NoTypeConverterJsonConverter{ImageCropDataSet}))] on top of the ImageCropDataSet class, however it turns out we
/// don't require this because to convert to string, we just override ToString().
/// I'll leave this class here for the future though.
/// </remarks>
internal class NoTypeConverterJsonConverter<T> : JsonConverter
{
static readonly IContractResolver resolver = new NoTypeConverterContractResolver();
private class NoTypeConverterContractResolver : DefaultContractResolver
{
protected override JsonContract CreateContract(Type objectType)
{
if (typeof(T).IsAssignableFrom(objectType))
{
var contract = this.CreateObjectContract(objectType);
contract.Converter = null; // Also null out the converter to prevent infinite recursion.
return contract;
}
return base.CreateContract(objectType);
}
}
public override bool CanConvert(Type objectType)
{
return typeof(T).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return JsonSerializer.CreateDefault(new JsonSerializerSettings { ContractResolver = resolver }).Deserialize(reader, objectType);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
JsonSerializer.CreateDefault(new JsonSerializerSettings { ContractResolver = resolver }).Serialize(writer, value);
}
}
}
@@ -8,7 +8,6 @@ using Umbraco.Core.Events;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Cache;
using File = System.IO.File;
namespace Umbraco.Core.Services
@@ -84,7 +83,7 @@ namespace Umbraco.Core.Services
// based on the ApplicationTreeRegistrar - and as noted there this is not an ideal way to do things but were stuck like this
// currently because of the legacy assemblies and types not in the Core.
//Get all the trees not registered in the config
//Get all the trees not registered in the config (those not matching by alias casing will be detected as "unregistered")
var unregistered = _allAvailableTrees
.Where(x => list.Any(l => l.Alias == x.Alias) == false)
.ToArray();
@@ -93,19 +92,46 @@ namespace Umbraco.Core.Services
if (hasChanges == false) return false;
//add the unregistered ones to the list and re-save the file if any changes were found
//add or edit the unregistered ones and re-save the file if any changes were found
var count = 0;
foreach (var tree in unregistered)
{
doc.Root.Add(new XElement("add",
new XAttribute("initialize", tree.Initialize),
new XAttribute("sortOrder", tree.SortOrder),
new XAttribute("alias", tree.Alias),
new XAttribute("application", tree.ApplicationAlias),
new XAttribute("title", tree.Title),
new XAttribute("iconClosed", tree.IconClosed),
new XAttribute("iconOpen", tree.IconOpened),
new XAttribute("type", tree.Type)));
var existingElement = doc.Root.Elements("add").SingleOrDefault(x =>
string.Equals(x.Attribute("alias").Value, tree.Alias,
StringComparison.InvariantCultureIgnoreCase) &&
string.Equals(x.Attribute("application").Value, tree.ApplicationAlias,
StringComparison.InvariantCultureIgnoreCase));
if (existingElement != null)
{
existingElement.SetAttributeValue("alias", tree.Alias);
}
else
{
if (tree.Title.IsNullOrWhiteSpace())
{
doc.Root.Add(new XElement("add",
new XAttribute("initialize", tree.Initialize),
new XAttribute("sortOrder", tree.SortOrder),
new XAttribute("alias", tree.Alias),
new XAttribute("application", tree.ApplicationAlias),
new XAttribute("iconClosed", tree.IconClosed),
new XAttribute("iconOpen", tree.IconOpened),
new XAttribute("type", tree.Type)));
}
else
{
doc.Root.Add(new XElement("add",
new XAttribute("initialize", tree.Initialize),
new XAttribute("sortOrder", tree.SortOrder),
new XAttribute("alias", tree.Alias),
new XAttribute("application", tree.ApplicationAlias),
new XAttribute("title", tree.Title),
new XAttribute("iconClosed", tree.IconClosed),
new XAttribute("iconOpen", tree.IconOpened),
new XAttribute("type", tree.Type)));
}
}
count++;
}
@@ -124,11 +150,7 @@ namespace Umbraco.Core.Services
}
}
}
return list;
}, new TimeSpan(0, 10, 0));
}
@@ -351,13 +373,15 @@ namespace Umbraco.Core.Services
{
list.Add(new ApplicationTree(
addElement.Attribute("initialize") == null || Convert.ToBoolean(addElement.Attribute("initialize").Value),
addElement.Attribute("sortOrder") != null ? Convert.ToByte(addElement.Attribute("sortOrder").Value) : (byte)0,
addElement.Attribute("application").Value,
addElement.Attribute("alias").Value,
addElement.Attribute("title").Value,
addElement.Attribute("iconClosed").Value,
addElement.Attribute("iconOpen").Value,
addElement.Attribute("type").Value));
addElement.Attribute("sortOrder") != null
? Convert.ToByte(addElement.Attribute("sortOrder").Value)
: (byte)0,
(string)addElement.Attribute("application"),
(string)addElement.Attribute("alias"),
(string)addElement.Attribute("title"),
(string)addElement.Attribute("iconClosed"),
(string)addElement.Attribute("iconOpen"),
(string)addElement.Attribute("type")));
}
}
+16 -8
View File
@@ -910,7 +910,7 @@ namespace Umbraco.Core.Services
new MoveEventArgs<IContent>(evtMsgs, new MoveEventInfo<IContent>(content, originalPath, Constants.System.RecycleBinContent)),
this))
{
return Attempt.Fail(OperationStatus.Cancelled(evtMsgs));
return OperationStatus.Cancelled(evtMsgs);
}
var moveInfo = new List<MoveEventInfo<IContent>>
@@ -957,7 +957,7 @@ namespace Umbraco.Core.Services
Audit(AuditType.Move, "Move Content to Recycle Bin performed by user", userId, content.Id);
return Attempt.Succeed(OperationStatus.Success(evtMsgs));
return OperationStatus.Success(evtMsgs);
}
}
@@ -1080,7 +1080,7 @@ namespace Umbraco.Core.Services
new SaveEventArgs<IContent>(asArray, evtMsgs),
this))
{
return Attempt.Fail(OperationStatus.Cancelled(evtMsgs));
return OperationStatus.Cancelled(evtMsgs);
}
}
using (new WriteLock(Locker))
@@ -1124,7 +1124,7 @@ namespace Umbraco.Core.Services
Audit(AuditType.Save, "Bulk Save content performed by user", userId == -1 ? 0 : userId, Constants.System.Root);
return Attempt.Succeed(OperationStatus.Success(evtMsgs));
return OperationStatus.Success(evtMsgs);
}
}
@@ -1147,7 +1147,7 @@ namespace Umbraco.Core.Services
new DeleteEventArgs<IContent>(content, evtMsgs),
this))
{
return Attempt.Fail(OperationStatus.Cancelled(evtMsgs));
return OperationStatus.Cancelled(evtMsgs);
}
//Make sure that published content is unpublished before being deleted
@@ -1178,7 +1178,7 @@ namespace Umbraco.Core.Services
Audit(AuditType.Delete, "Delete Content performed by user", userId, content.Id);
return Attempt.Succeed(OperationStatus.Success(evtMsgs));
return OperationStatus.Success(evtMsgs);
}
}
@@ -1227,6 +1227,13 @@ namespace Umbraco.Core.Services
/// <param name="userId">Optional Id of the user issueing the delete operation</param>
public void DeleteContentOfType(int contentTypeId, int userId = 0)
{
//TODO: This currently this is called from the ContentTypeService but that needs to change,
// if we are deleting a content type, we should just delete the data and do this operation slightly differently.
// This method will recursively go lookup every content item, check if any of it's descendants are
// of a different type, move them to the recycle bin, then permanently delete the content items.
// The main problem with this is that for every content item being deleted, events are raised...
// which we need for many things like keeping caches in sync, but we can surely do this MUCH better.
using (new WriteLock(Locker))
{
using (var uow = UowProvider.GetUnitOfWork())
@@ -1709,6 +1716,7 @@ namespace Umbraco.Core.Services
}
}
//TODO: All of this needs to be moved to the repository
private void PerformMove(IContent content, int parentId, int userId, ICollection<MoveEventInfo<IContent>> moveInfo)
{
//add a tracking item to use in the Moved event
@@ -2042,7 +2050,7 @@ namespace Umbraco.Core.Services
new SaveEventArgs<IContent>(content, evtMsgs),
this))
{
return Attempt.Fail(OperationStatus.Cancelled(evtMsgs));
return OperationStatus.Cancelled(evtMsgs);
}
}
@@ -2074,7 +2082,7 @@ namespace Umbraco.Core.Services
Audit(AuditType.Save, "Save Content performed by user", userId, content.Id);
return Attempt.Succeed(OperationStatus.Success(evtMsgs));
return OperationStatus.Success(evtMsgs);
}
}
+332 -94
View File
@@ -29,7 +29,7 @@ namespace Umbraco.Core.Services
private readonly IContentService _contentService;
private readonly IMediaService _mediaService;
//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);
@@ -44,10 +44,11 @@ namespace Umbraco.Core.Services
#region Containers
public Attempt<int> CreateContentTypeContainer(int parentId, string name, int userId = 0)
public Attempt<OperationStatus<EntityContainer, OperationStatusType>> CreateContentTypeContainer(int parentId, string name, int userId = 0)
{
var evtMsgs = EventMessagesFactory.Get();
var uow = UowProvider.GetUnitOfWork();
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow))
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DocumentTypeContainerGuid))
{
try
{
@@ -57,22 +58,34 @@ namespace Umbraco.Core.Services
ParentId = parentId,
CreatorId = userId
};
if (SavingContentTypeContainer.IsRaisedEventCancelled(
new SaveEventArgs<EntityContainer>(container, evtMsgs),
this))
{
return Attempt.Fail(new OperationStatus<EntityContainer, OperationStatusType>(container, OperationStatusType.FailedCancelledByEvent, evtMsgs));
}
repo.AddOrUpdate(container);
uow.Commit();
return Attempt.Succeed(container.Id);
SavedContentTypeContainer.RaiseEvent(new SaveEventArgs<EntityContainer>(container, evtMsgs), this);
//TODO: Audit trail ?
return Attempt.Succeed(new OperationStatus<EntityContainer, OperationStatusType>(container, OperationStatusType.Success, evtMsgs));
}
catch (Exception ex)
{
return Attempt<int>.Fail(ex);
return Attempt.Fail(new OperationStatus<EntityContainer, OperationStatusType>(null, OperationStatusType.FailedExceptionThrown, evtMsgs), ex);
}
//TODO: Audit trail ?
}
}
public Attempt<int> CreateMediaTypeContainer(int parentId, string name, int userId = 0)
public Attempt<OperationStatus<EntityContainer, OperationStatusType>> CreateMediaTypeContainer(int parentId, string name, int userId = 0)
{
var evtMsgs = EventMessagesFactory.Get();
var uow = UowProvider.GetUnitOfWork();
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow))
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.MediaTypeContainerGuid))
{
try
{
@@ -82,130 +95,239 @@ namespace Umbraco.Core.Services
ParentId = parentId,
CreatorId = userId
};
if (SavingMediaTypeContainer.IsRaisedEventCancelled(
new SaveEventArgs<EntityContainer>(container, evtMsgs),
this))
{
return Attempt.Fail(new OperationStatus<EntityContainer, OperationStatusType>(container, OperationStatusType.FailedCancelledByEvent, evtMsgs));
}
repo.AddOrUpdate(container);
uow.Commit();
return Attempt.Succeed(container.Id);
SavedMediaTypeContainer.RaiseEvent(new SaveEventArgs<EntityContainer>(container, evtMsgs), this);
//TODO: Audit trail ?
return Attempt.Succeed(new OperationStatus<EntityContainer, OperationStatusType>(container, OperationStatusType.Success, evtMsgs));
}
catch (Exception ex)
{
return Attempt<int>.Fail(ex);
return Attempt.Fail(new OperationStatus<EntityContainer, OperationStatusType>(null, OperationStatusType.FailedExceptionThrown, evtMsgs), ex);
}
//TODO: Audit trail ?
}
}
public void SaveContentTypeContainer(EntityContainer container, int userId = 0)
public Attempt<OperationStatus> SaveContentTypeContainer(EntityContainer container, int userId = 0)
{
SaveContainer(container, Constants.ObjectTypes.DocumentTypeGuid, "document type", userId);
return SaveContainer(
SavingContentTypeContainer, SavedContentTypeContainer,
container, Constants.ObjectTypes.DocumentTypeContainerGuid, "document type", userId);
}
public void SaveMediaTypeContainer(EntityContainer container, int userId = 0)
public Attempt<OperationStatus> SaveMediaTypeContainer(EntityContainer container, int userId = 0)
{
SaveContainer(container, Constants.ObjectTypes.MediaTypeGuid, "media type", userId);
return SaveContainer(
SavingMediaTypeContainer, SavedMediaTypeContainer,
container, Constants.ObjectTypes.MediaTypeContainerGuid, "media type", userId);
}
private void SaveContainer(EntityContainer container, Guid containedObjectType, string objectTypeName, int userId)
private Attempt<OperationStatus> SaveContainer(
TypedEventHandler<IContentTypeService, SaveEventArgs<EntityContainer>> savingEvent,
TypedEventHandler<IContentTypeService, SaveEventArgs<EntityContainer>> savedEvent,
EntityContainer container,
Guid containerObjectType,
string objectTypeName, int userId)
{
if (container.ContainedObjectType != containedObjectType)
throw new InvalidOperationException("Not a " + objectTypeName + " container.");
var evtMsgs = EventMessagesFactory.Get();
if (container.ContainedObjectType != containerObjectType)
{
var ex = new InvalidOperationException("Not a " + objectTypeName + " container.");
return OperationStatus.Exception(evtMsgs, ex);
}
if (container.HasIdentity && container.IsPropertyDirty("ParentId"))
throw new InvalidOperationException("Cannot save a container with a modified parent, move the container instead.");
{
var ex = new InvalidOperationException("Cannot save a container with a modified parent, move the container instead.");
return OperationStatus.Exception(evtMsgs, ex);
}
if (savingEvent.IsRaisedEventCancelled(
new SaveEventArgs<EntityContainer>(container, evtMsgs),
this))
{
return OperationStatus.Cancelled(evtMsgs);
}
var uow = UowProvider.GetUnitOfWork();
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow))
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow, containerObjectType))
{
repo.AddOrUpdate(container);
uow.Commit();
//TODO: Audit trail ?
}
savedEvent.RaiseEvent(new SaveEventArgs<EntityContainer>(container, evtMsgs), this);
//TODO: Audit trail ?
return OperationStatus.Success(evtMsgs);
}
public EntityContainer GetContentTypeContainer(int containerId)
{
return GetContainer(containerId, Constants.ObjectTypes.DocumentTypeGuid);
return GetContainer(containerId, Constants.ObjectTypes.DocumentTypeContainerGuid);
}
public EntityContainer GetMediaTypeContainer(int containerId)
{
return GetContainer(containerId, Constants.ObjectTypes.MediaTypeGuid);
return GetContainer(containerId, Constants.ObjectTypes.MediaTypeContainerGuid);
}
private EntityContainer GetContainer(int containerId, Guid containedObjectType)
private EntityContainer GetContainer(int containerId, Guid containerObjectType)
{
var uow = UowProvider.GetUnitOfWork();
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow))
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow, containerObjectType))
{
var container = repo.Get(containerId);
return container != null && container.ContainedObjectType == containedObjectType
? container
: null;
return container;
}
}
public IEnumerable<EntityContainer> GetMediaTypeContainers(int[] containerIds)
{
var uow = UowProvider.GetUnitOfWork();
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.MediaTypeContainerGuid))
{
return repo.GetAll(containerIds);
}
}
public IEnumerable<EntityContainer> GetMediaTypeContainers(string name, int level)
{
var uow = UowProvider.GetUnitOfWork();
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow))
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.MediaTypeContainerGuid))
{
return repo.Get(name, level, Constants.ObjectTypes.MediaTypeContainerGuid);
return repo.Get(name, level);
}
}
public IEnumerable<EntityContainer> GetMediaTypeContainers(IMediaType mediaType)
{
var ancestorIds = mediaType.Path.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(x =>
{
var asInt = x.TryConvertTo<int>();
if (asInt) return asInt.Result;
return int.MinValue;
})
.Where(x => x != int.MinValue && x != mediaType.Id)
.ToArray();
return GetMediaTypeContainers(ancestorIds);
}
public EntityContainer GetContentTypeContainer(Guid containerId)
{
return GetContainer(containerId, Constants.ObjectTypes.DocumentTypeGuid);
return GetContainer(containerId, Constants.ObjectTypes.DocumentTypeContainerGuid);
}
public EntityContainer GetMediaTypeContainer(Guid containerId)
{
return GetContainer(containerId, Constants.ObjectTypes.MediaTypeGuid);
}
private EntityContainer GetContainer(Guid containerId, Guid containedObjectType)
public IEnumerable<EntityContainer> GetContentTypeContainers(int[] containerIds)
{
var uow = UowProvider.GetUnitOfWork();
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow))
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DocumentTypeContainerGuid))
{
return repo.GetAll(containerIds);
}
}
public IEnumerable<EntityContainer> GetContentTypeContainers(IContentType contentType)
{
var ancestorIds = contentType.Path.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries)
.Select(x =>
{
var asInt = x.TryConvertTo<int>();
if (asInt) return asInt.Result;
return int.MinValue;
})
.Where(x => x != int.MinValue && x != contentType.Id)
.ToArray();
return GetContentTypeContainers(ancestorIds);
}
public EntityContainer GetMediaTypeContainer(Guid containerId)
{
return GetContainer(containerId, Constants.ObjectTypes.MediaTypeContainerGuid);
}
private EntityContainer GetContainer(Guid containerId, Guid containerObjectType)
{
var uow = UowProvider.GetUnitOfWork();
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow, containerObjectType))
{
var container = repo.Get(containerId);
return container != null && container.ContainedObjectType == containedObjectType
? container
: null;
return container;
}
}
public IEnumerable<EntityContainer> GetContentTypeContainers(string name, int level)
{
var uow = UowProvider.GetUnitOfWork();
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow))
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DocumentTypeContainerGuid))
{
return repo.Get(name, level, Constants.ObjectTypes.DocumentTypeContainerGuid);
return repo.Get(name, level);
}
}
public void DeleteContentTypeContainer(int containerId, int userId = 0)
public Attempt<OperationStatus> DeleteContentTypeContainer(int containerId, int userId = 0)
{
var evtMsgs = EventMessagesFactory.Get();
var uow = UowProvider.GetUnitOfWork();
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow))
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DocumentTypeContainerGuid))
{
var container = repo.Get(containerId);
if (container == null) return;
if (container.ContainedObjectType != Constants.ObjectTypes.DocumentTypeGuid) return;
if (container == null) return OperationStatus.NoOperation(evtMsgs);
if (DeletingContentTypeContainer.IsRaisedEventCancelled(
new DeleteEventArgs<EntityContainer>(container, evtMsgs),
this))
{
return Attempt.Fail(new OperationStatus(OperationStatusType.FailedCancelledByEvent, evtMsgs));
}
repo.Delete(container);
uow.Commit();
DeletedContentTypeContainer.RaiseEvent(new DeleteEventArgs<EntityContainer>(container, evtMsgs), this);
return OperationStatus.Success(evtMsgs);
//TODO: Audit trail ?
}
}
public void DeleteMediaTypeContainer(int containerId, int userId = 0)
public Attempt<OperationStatus> DeleteMediaTypeContainer(int containerId, int userId = 0)
{
var evtMsgs = EventMessagesFactory.Get();
var uow = UowProvider.GetUnitOfWork();
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow))
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.MediaTypeContainerGuid))
{
var container = repo.Get(containerId);
if (container == null) return;
if (container.ContainedObjectType != Constants.ObjectTypes.MediaTypeGuid) return;
if (container == null) return OperationStatus.NoOperation(evtMsgs);
if (DeletingMediaTypeContainer.IsRaisedEventCancelled(
new DeleteEventArgs<EntityContainer>(container, evtMsgs),
this))
{
return Attempt.Fail(new OperationStatus(OperationStatusType.FailedCancelledByEvent, evtMsgs));
}
repo.Delete(container);
uow.Commit();
DeletedMediaTypeContainer.RaiseEvent(new DeleteEventArgs<EntityContainer>(container, evtMsgs), this);
return OperationStatus.Success(evtMsgs);
//TODO: Audit trail ?
}
}
@@ -224,6 +346,22 @@ namespace Umbraco.Core.Services
}
}
/// <summary>
/// Gets all content type aliases
/// </summary>
/// <param name="objectTypes">
/// If this list is empty, it will return all content type aliases for media, members and content, otherwise
/// it will only return content type aliases for the object types specified
/// </param>
/// <returns></returns>
public IEnumerable<string> GetAllContentTypeAliases(params Guid[] objectTypes)
{
using (var repository = RepositoryFactory.CreateContentTypeRepository(UowProvider.GetUnitOfWork()))
{
return repository.GetAllContentTypeAliases(objectTypes);
}
}
/// <summary>
/// Copies a content type as a child under the specified parent if specified (otherwise to the root)
/// </summary>
@@ -242,7 +380,7 @@ namespace Umbraco.Core.Services
/// <returns></returns>
public IContentType Copy(IContentType original, string alias, string name, int parentId = -1)
{
IContentType parent = null;
IContentType parent = null;
if (parentId > 0)
{
parent = GetContentType(parentId);
@@ -276,7 +414,7 @@ namespace Umbraco.Core.Services
Mandate.ParameterNotNullOrEmpty(alias, "alias");
if (parent != null)
{
Mandate.That(parent.HasIdentity, () => new InvalidOperationException("The parent content type must have an identity"));
Mandate.That(parent.HasIdentity, () => new InvalidOperationException("The parent content type must have an identity"));
}
var clone = original.DeepCloneWithResetIdentities(alias);
@@ -302,7 +440,7 @@ namespace Umbraco.Core.Services
//set to root
clone.ParentId = -1;
}
Save(clone);
return clone;
}
@@ -329,10 +467,7 @@ namespace Umbraco.Core.Services
{
using (var repository = RepositoryFactory.CreateContentTypeRepository(UowProvider.GetUnitOfWork()))
{
var query = Query<IContentType>.Builder.Where(x => x.Alias == alias);
var contentTypes = repository.GetByQuery(query);
return contentTypes.FirstOrDefault();
return repository.Get(alias);
}
}
@@ -370,7 +505,7 @@ namespace Umbraco.Core.Services
public IEnumerable<IContentType> GetAllContentTypes(IEnumerable<Guid> ids)
{
using (var repository = RepositoryFactory.CreateContentTypeRepository(UowProvider.GetUnitOfWork()))
{
{
return repository.GetAll(ids.ToArray());
}
}
@@ -464,7 +599,7 @@ namespace Umbraco.Core.Services
{
//this should never occur, the content service should always be typed but we'll check anyways.
_contentService.RePublishAll();
}
}
}
else if (firstType is IMediaType)
{
@@ -473,10 +608,10 @@ namespace Umbraco.Core.Services
if (typedContentService != null)
{
typedContentService.RebuildXmlStructures(toUpdate.Select(x => x.Id).ToArray());
}
}
}
}
}
public int CountContentTypes()
@@ -526,14 +661,17 @@ namespace Umbraco.Core.Services
var contentType = compositionContentType as IContentType;
var mediaType = compositionContentType as IMediaType;
var memberType = compositionContentType as IMemberType; // should NOT do it here but... v8!
IContentTypeComposition[] allContentTypes;
if (contentType != null)
allContentTypes = GetAllContentTypes().Cast<IContentTypeComposition>().ToArray();
else if (mediaType != null)
allContentTypes = GetAllMediaTypes().Cast<IContentTypeComposition>().ToArray();
else if (memberType != null)
return; // no compositions on members, always validate
else
throw new Exception("Composition is neither IContentType nor IMediaType?");
throw new Exception("Composition is neither IContentType nor IMediaType nor IMemberType?");
var compositionAliases = compositionContentType.CompositionAliases();
var compositions = allContentTypes.Where(x => compositionAliases.Any(y => x.Alias.Equals(y)));
@@ -549,7 +687,7 @@ namespace Umbraco.Core.Services
dependencies.Add(indirectReference);
//Get all compositions for the current indirect reference
var directReferences = indirectReference.ContentTypeComposition;
foreach (var directReference in directReferences)
{
if (directReference.Id == compositionContentType.Id || directReference.Alias.Equals(compositionContentType.Alias)) continue;
@@ -569,7 +707,7 @@ namespace Umbraco.Core.Services
if (contentTypeDependency == null) continue;
var intersect = contentTypeDependency.PropertyTypes.Select(x => x.Alias.ToLowerInvariant()).Intersect(propertyTypeAliases).ToArray();
if (intersect.Length == 0) continue;
throw new InvalidCompositionException(compositionContentType.Alias, intersect.ToArray());
}
}
@@ -581,7 +719,7 @@ namespace Umbraco.Core.Services
/// <param name="userId">Optional id of the user saving the ContentType</param>
public void Save(IContentType contentType, int userId = 0)
{
if (SavingContentType.IsRaisedEventCancelled(new SaveEventArgs<IContentType>(contentType), this))
if (SavingContentType.IsRaisedEventCancelled(new SaveEventArgs<IContentType>(contentType), this))
return;
using (new WriteLock(Locker))
@@ -611,7 +749,7 @@ namespace Umbraco.Core.Services
{
var asArray = contentTypes.ToArray();
if (SavingContentType.IsRaisedEventCancelled(new SaveEventArgs<IContentType>(asArray), this))
if (SavingContentType.IsRaisedEventCancelled(new SaveEventArgs<IContentType>(asArray), this))
return;
using (new WriteLock(Locker))
@@ -647,12 +785,19 @@ 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)
{
if (DeletingContentType.IsRaisedEventCancelled(new DeleteEventArgs<IContentType>(contentType), this))
{
if (DeletingContentType.IsRaisedEventCancelled(new DeleteEventArgs<IContentType>(contentType), this))
return;
using (new WriteLock(Locker))
{
//TODO: This needs to change, if we are deleting a content type, we should just delete the data,
// this method will recursively go lookup every content item, check if any of it's descendants are
// of a different type, move them to the recycle bin, then permanently delete the content items.
// The main problem with this is that for every content item being deleted, events are raised...
// which we need for many things like keeping caches in sync, but we can surely do this MUCH better.
_contentService.DeleteContentOfType(contentType.Id);
var uow = UowProvider.GetUnitOfWork();
@@ -680,7 +825,7 @@ namespace Umbraco.Core.Services
{
var asArray = contentTypes.ToArray();
if (DeletingContentType.IsRaisedEventCancelled(new DeleteEventArgs<IContentType>(asArray), this))
if (DeletingContentType.IsRaisedEventCancelled(new DeleteEventArgs<IContentType>(asArray), this))
return;
using (new WriteLock(Locker))
@@ -706,7 +851,7 @@ namespace Umbraco.Core.Services
Audit(AuditType.Delete, string.Format("Delete ContentTypes performed by user"), userId, -1);
}
}
/// <summary>
/// Gets an <see cref="IMediaType"/> object by its Id
/// </summary>
@@ -729,10 +874,7 @@ namespace Umbraco.Core.Services
{
using (var repository = RepositoryFactory.CreateMediaTypeRepository(UowProvider.GetUnitOfWork()))
{
var query = Query<IMediaType>.Builder.Where(x => x.Alias == alias);
var contentTypes = repository.GetByQuery(query);
return contentTypes.FirstOrDefault();
return repository.Get(alias);
}
}
@@ -842,7 +984,7 @@ namespace Umbraco.Core.Services
public Attempt<OperationStatus<MoveOperationStatusType>> MoveMediaType(IMediaType toMove, int containerId)
{
var evtMsgs = EventMessagesFactory.Get();
if (MovingMediaType.IsRaisedEventCancelled(
new MoveEventArgs<IMediaType>(evtMsgs, new MoveEventInfo<IMediaType>(toMove, toMove.Path, containerId)),
this))
@@ -854,7 +996,7 @@ namespace Umbraco.Core.Services
var moveInfo = new List<MoveEventInfo<IMediaType>>();
var uow = UowProvider.GetUnitOfWork();
using (var containerRepository = RepositoryFactory.CreateEntityContainerRepository(uow))
using (var containerRepository = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.MediaTypeContainerGuid))
using (var repository = RepositoryFactory.CreateMediaTypeRepository(uow))
{
try
@@ -863,7 +1005,7 @@ namespace Umbraco.Core.Services
if (containerId > 0)
{
container = containerRepository.Get(containerId);
if (container == null || container.ContainedObjectType != Constants.ObjectTypes.MediaTypeGuid)
if (container == null)
throw new DataOperationException<MoveOperationStatusType>(MoveOperationStatusType.FailedParentNotFound);
}
moveInfo.AddRange(repository.Move(toMove, container));
@@ -897,7 +1039,7 @@ namespace Umbraco.Core.Services
var moveInfo = new List<MoveEventInfo<IContentType>>();
var uow = UowProvider.GetUnitOfWork();
using (var containerRepository = RepositoryFactory.CreateEntityContainerRepository(uow))
using (var containerRepository = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DocumentTypeContainerGuid))
using (var repository = RepositoryFactory.CreateContentTypeRepository(uow))
{
try
@@ -906,7 +1048,7 @@ namespace Umbraco.Core.Services
if (containerId > 0)
{
container = containerRepository.Get(containerId);
if (container == null || container.ContainedObjectType != Constants.ObjectTypes.DocumentTypeGuid)
if (container == null)
throw new DataOperationException<MoveOperationStatusType>(MoveOperationStatusType.FailedParentNotFound);
}
moveInfo.AddRange(repository.Move(toMove, container));
@@ -925,6 +1067,92 @@ namespace Umbraco.Core.Services
new OperationStatus<MoveOperationStatusType>(MoveOperationStatusType.Success, evtMsgs));
}
public Attempt<OperationStatus<IMediaType, MoveOperationStatusType>> CopyMediaType(IMediaType toCopy, int containerId)
{
var evtMsgs = EventMessagesFactory.Get();
IMediaType copy;
var uow = UowProvider.GetUnitOfWork();
using (var containerRepository = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.MediaTypeContainerGuid))
using (var repository = RepositoryFactory.CreateMediaTypeRepository(uow))
{
try
{
if (containerId > 0)
{
var container = containerRepository.Get(containerId);
if (container == null)
throw new DataOperationException<MoveOperationStatusType>(MoveOperationStatusType.FailedParentNotFound);
}
var alias = repository.GetUniqueAlias(toCopy.Alias);
copy = toCopy.DeepCloneWithResetIdentities(alias);
copy.Name = copy.Name + " (copy)"; // might not be unique
// if it has a parent, and the parent is a content type, unplug composition
// all other compositions remain in place in the copied content type
if (copy.ParentId > 0)
{
var parent = repository.Get(copy.ParentId);
if (parent != null)
copy.RemoveContentType(parent.Alias);
}
copy.ParentId = containerId;
repository.AddOrUpdate(copy);
}
catch (DataOperationException<MoveOperationStatusType> ex)
{
return Attempt.Fail(new OperationStatus<IMediaType, MoveOperationStatusType>(null, ex.Operation, evtMsgs));
}
uow.Commit();
}
return Attempt.Succeed(new OperationStatus<IMediaType, MoveOperationStatusType>(copy, MoveOperationStatusType.Success, evtMsgs));
}
public Attempt<OperationStatus<IContentType, MoveOperationStatusType>> CopyContentType(IContentType toCopy, int containerId)
{
var evtMsgs = EventMessagesFactory.Get();
IContentType copy;
var uow = UowProvider.GetUnitOfWork();
using (var containerRepository = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DocumentTypeContainerGuid))
using (var repository = RepositoryFactory.CreateContentTypeRepository(uow))
{
try
{
if (containerId > 0)
{
var container = containerRepository.Get(containerId);
if (container == null)
throw new DataOperationException<MoveOperationStatusType>(MoveOperationStatusType.FailedParentNotFound);
}
var alias = repository.GetUniqueAlias(toCopy.Alias);
copy = toCopy.DeepCloneWithResetIdentities(alias);
copy.Name = copy.Name + " (copy)"; // might not be unique
// if it has a parent, and the parent is a content type, unplug composition
// all other compositions remain in place in the copied content type
if (copy.ParentId > 0)
{
var parent = repository.Get(copy.ParentId);
if (parent != null)
copy.RemoveContentType(parent.Alias);
}
copy.ParentId = containerId;
repository.AddOrUpdate(copy);
}
catch (DataOperationException<MoveOperationStatusType> ex)
{
return Attempt.Fail(new OperationStatus<IContentType, MoveOperationStatusType>(null, ex.Operation, evtMsgs));
}
uow.Commit();
}
return Attempt.Succeed(new OperationStatus<IContentType, MoveOperationStatusType>(copy, MoveOperationStatusType.Success, evtMsgs));
}
/// <summary>
/// Saves a single <see cref="IMediaType"/> object
/// </summary>
@@ -932,7 +1160,7 @@ namespace Umbraco.Core.Services
/// <param name="userId">Optional Id of the user saving the MediaType</param>
public void Save(IMediaType mediaType, int userId = 0)
{
if (SavingMediaType.IsRaisedEventCancelled(new SaveEventArgs<IMediaType>(mediaType), this))
if (SavingMediaType.IsRaisedEventCancelled(new SaveEventArgs<IMediaType>(mediaType), this))
return;
using (new WriteLock(Locker))
@@ -944,7 +1172,7 @@ namespace Umbraco.Core.Services
mediaType.CreatorId = userId;
repository.AddOrUpdate(mediaType);
uow.Commit();
}
UpdateContentXmlStructure(mediaType);
@@ -983,7 +1211,7 @@ namespace Umbraco.Core.Services
}
//save it all in one go
uow.Commit();
uow.Commit();
}
UpdateContentXmlStructure(asArray.Cast<IContentTypeBase>().ToArray());
@@ -1001,7 +1229,7 @@ namespace Umbraco.Core.Services
/// <remarks>Deleting a <see cref="IMediaType"/> will delete all the <see cref="IMedia"/> objects based on this <see cref="IMediaType"/></remarks>
public void Delete(IMediaType mediaType, int userId = 0)
{
if (DeletingMediaType.IsRaisedEventCancelled(new DeleteEventArgs<IMediaType>(mediaType), this))
if (DeletingMediaType.IsRaisedEventCancelled(new DeleteEventArgs<IMediaType>(mediaType), this))
return;
using (new WriteLock(Locker))
{
@@ -1031,7 +1259,7 @@ namespace Umbraco.Core.Services
{
var asArray = mediaTypes.ToArray();
if (DeletingMediaType.IsRaisedEventCancelled(new DeleteEventArgs<IMediaType>(asArray), this))
if (DeletingMediaType.IsRaisedEventCancelled(new DeleteEventArgs<IMediaType>(asArray), this))
return;
using (new WriteLock(Locker))
{
@@ -1053,7 +1281,7 @@ namespace Umbraco.Core.Services
}
Audit(AuditType.Delete, string.Format("Delete MediaTypes performed by user"), userId, -1);
}
}
}
/// <summary>
@@ -1120,19 +1348,29 @@ namespace Umbraco.Core.Services
uow.Commit();
}
}
#region Event Handlers
/// <summary>
/// Occurs before Delete
/// </summary>
public static event TypedEventHandler<IContentTypeService, DeleteEventArgs<IContentType>> DeletingContentType;
public static event TypedEventHandler<IContentTypeService, SaveEventArgs<EntityContainer>> SavingContentTypeContainer;
public static event TypedEventHandler<IContentTypeService, SaveEventArgs<EntityContainer>> SavedContentTypeContainer;
public static event TypedEventHandler<IContentTypeService, DeleteEventArgs<EntityContainer>> DeletingContentTypeContainer;
public static event TypedEventHandler<IContentTypeService, DeleteEventArgs<EntityContainer>> DeletedContentTypeContainer;
public static event TypedEventHandler<IContentTypeService, SaveEventArgs<EntityContainer>> SavingMediaTypeContainer;
public static event TypedEventHandler<IContentTypeService, SaveEventArgs<EntityContainer>> SavedMediaTypeContainer;
public static event TypedEventHandler<IContentTypeService, DeleteEventArgs<EntityContainer>> DeletingMediaTypeContainer;
public static event TypedEventHandler<IContentTypeService, DeleteEventArgs<EntityContainer>> DeletedMediaTypeContainer;
/// <summary>
/// Occurs before Delete
/// </summary>
public static event TypedEventHandler<IContentTypeService, DeleteEventArgs<IContentType>> DeletingContentType;
/// <summary>
/// Occurs after Delete
/// </summary>
public static event TypedEventHandler<IContentTypeService, DeleteEventArgs<IContentType>> DeletedContentType;
/// <summary>
/// Occurs before Delete
/// </summary>
@@ -1142,7 +1380,7 @@ namespace Umbraco.Core.Services
/// Occurs after Delete
/// </summary>
public static event TypedEventHandler<IContentTypeService, DeleteEventArgs<IMediaType>> DeletedMediaType;
/// <summary>
/// Occurs before Save
/// </summary>
+98 -27
View File
@@ -29,10 +29,11 @@ namespace Umbraco.Core.Services
#region Containers
public Attempt<int> CreateContainer(int parentId, string name, int userId = 0)
public Attempt<OperationStatus<EntityContainer, OperationStatusType>> CreateContainer(int parentId, string name, int userId = 0)
{
var evtMsgs = EventMessagesFactory.Get();
var uow = UowProvider.GetUnitOfWork();
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow))
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DataTypeContainerGuid))
{
try
{
@@ -42,77 +43,141 @@ namespace Umbraco.Core.Services
ParentId = parentId,
CreatorId = userId
};
if (SavingContainer.IsRaisedEventCancelled(
new SaveEventArgs<EntityContainer>(container, evtMsgs),
this))
{
return Attempt.Fail(new OperationStatus<EntityContainer, OperationStatusType>(container, OperationStatusType.FailedCancelledByEvent, evtMsgs));
}
repo.AddOrUpdate(container);
uow.Commit();
return Attempt.Succeed(container.Id);
SavedContainer.RaiseEvent(new SaveEventArgs<EntityContainer>(container, evtMsgs), this);
//TODO: Audit trail ?
return Attempt.Succeed(new OperationStatus<EntityContainer, OperationStatusType>(container, OperationStatusType.Success, evtMsgs));
}
catch (Exception ex)
{
return Attempt<int>.Fail(ex);
return Attempt.Fail(new OperationStatus<EntityContainer, OperationStatusType>(null, OperationStatusType.FailedExceptionThrown, evtMsgs), ex);
}
//TODO: Audit trail ?
}
}
public EntityContainer GetContainer(int containerId)
{
var uow = UowProvider.GetUnitOfWork();
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow))
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DataTypeContainerGuid))
{
var container = repo.Get(containerId);
return container != null && container.ContainedObjectType == Constants.ObjectTypes.DataTypeGuid
? container
: null;
return container;
}
}
public EntityContainer GetContainer(Guid containerId)
{
var uow = UowProvider.GetUnitOfWork();
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow))
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DataTypeContainerGuid))
{
var container = repo.Get(containerId);
return container != null && container.ContainedObjectType == Constants.ObjectTypes.DataTypeGuid
? container
: null;
return container;
}
}
public IEnumerable<EntityContainer> GetContainers(string name, int level)
{
var uow = UowProvider.GetUnitOfWork();
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow))
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DataTypeContainerGuid))
{
return repo.Get(name, level, Constants.ObjectTypes.DataTypeContainerGuid);
return repo.Get(name, level);
}
}
public void SaveContainer(EntityContainer container, int userId = 0)
public IEnumerable<EntityContainer> GetContainers(IDataTypeDefinition dataTypeDefinition)
{
if (container.ContainedObjectType != Constants.ObjectTypes.DataTypeGuid)
throw new InvalidOperationException("Not a data type container.");
var ancestorIds = dataTypeDefinition.Path.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(x =>
{
var asInt = x.TryConvertTo<int>();
if (asInt) return asInt.Result;
return int.MinValue;
})
.Where(x => x != int.MinValue && x != dataTypeDefinition.Id)
.ToArray();
return GetContainers(ancestorIds);
}
public IEnumerable<EntityContainer> GetContainers(int[] containerIds)
{
var uow = UowProvider.GetUnitOfWork();
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DataTypeContainerGuid))
{
return repo.GetAll(containerIds);
}
}
public Attempt<OperationStatus> SaveContainer(EntityContainer container, int userId = 0)
{
var evtMsgs = EventMessagesFactory.Get();
if (container.ContainedObjectType != Constants.ObjectTypes.DataTypeGuid)
{
var ex = new InvalidOperationException("Not a " + Constants.ObjectTypes.DataTypeGuid + " container.");
return OperationStatus.Exception(evtMsgs, ex);
}
if (container.HasIdentity && container.IsPropertyDirty("ParentId"))
throw new InvalidOperationException("Cannot save a container with a modified parent, move the container instead.");
{
var ex = new InvalidOperationException("Cannot save a container with a modified parent, move the container instead.");
return OperationStatus.Exception(evtMsgs, ex);
}
if (SavingContainer.IsRaisedEventCancelled(
new SaveEventArgs<EntityContainer>(container, evtMsgs),
this))
{
return OperationStatus.Cancelled(evtMsgs);
}
var uow = UowProvider.GetUnitOfWork();
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow))
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DataTypeContainerGuid))
{
repo.AddOrUpdate(container);
uow.Commit();
//TODO: Audit trail ?
}
SavedContainer.RaiseEvent(new SaveEventArgs<EntityContainer>(container, evtMsgs), this);
//TODO: Audit trail ?
return OperationStatus.Success(evtMsgs);
}
public void DeleteContainer(int containerId, int userId = 0)
public Attempt<OperationStatus> DeleteContainer(int containerId, int userId = 0)
{
var evtMsgs = EventMessagesFactory.Get();
var uow = UowProvider.GetUnitOfWork();
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow))
using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DataTypeContainerGuid))
{
var container = repo.Get(containerId);
if (container == null) return;
if (container.ContainedObjectType != Constants.ObjectTypes.DataTypeGuid) return;
if (container == null) return OperationStatus.NoOperation(evtMsgs);
if (DeletingContainer.IsRaisedEventCancelled(
new DeleteEventArgs<EntityContainer>(container, evtMsgs),
this))
{
return Attempt.Fail(new OperationStatus(OperationStatusType.FailedCancelledByEvent, evtMsgs));
}
repo.Delete(container);
uow.Commit();
DeletedContainer.RaiseEvent(new DeleteEventArgs<EntityContainer>(container, evtMsgs), this);
return OperationStatus.Success(evtMsgs);
//TODO: Audit trail ?
}
}
@@ -261,7 +326,7 @@ namespace Umbraco.Core.Services
var moveInfo = new List<MoveEventInfo<IDataTypeDefinition>>();
var uow = UowProvider.GetUnitOfWork();
using (var containerRepository = RepositoryFactory.CreateEntityContainerRepository(uow))
using (var containerRepository = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DataTypeContainerGuid))
using (var repository = RepositoryFactory.CreateDataTypeDefinitionRepository(uow))
{
try
@@ -270,7 +335,7 @@ namespace Umbraco.Core.Services
if (parentId > 0)
{
container = containerRepository.Get(parentId);
if (container == null || container.ContainedObjectType != Constants.ObjectTypes.DataTypeGuid)
if (container == null)
throw new DataOperationException<MoveOperationStatusType>(MoveOperationStatusType.FailedParentNotFound);
}
moveInfo.AddRange(repository.Move(toMove, container));
@@ -518,6 +583,12 @@ namespace Umbraco.Core.Services
}
#region Event Handlers
public static event TypedEventHandler<IDataTypeService, SaveEventArgs<EntityContainer>> SavingContainer;
public static event TypedEventHandler<IDataTypeService, SaveEventArgs<EntityContainer>> SavedContainer;
public static event TypedEventHandler<IDataTypeService, DeleteEventArgs<EntityContainer>> DeletingContainer;
public static event TypedEventHandler<IDataTypeService, DeleteEventArgs<EntityContainer>> DeletedContainer;
/// <summary>
/// Occurs before Delete
/// </summary>
+4 -4
View File
@@ -33,7 +33,7 @@ namespace Umbraco.Core.Services
new DeleteEventArgs<IDomain>(domain, evtMsgs),
this))
{
return Attempt.Fail(OperationStatus.Cancelled(evtMsgs));
return OperationStatus.Cancelled(evtMsgs);
}
var uow = UowProvider.GetUnitOfWork();
@@ -45,7 +45,7 @@ namespace Umbraco.Core.Services
var args = new DeleteEventArgs<IDomain>(domain, false, evtMsgs);
Deleted.RaiseEvent(args, this);
return Attempt.Succeed(OperationStatus.Success(evtMsgs));
return OperationStatus.Success(evtMsgs);
}
public IDomain GetByName(string name)
@@ -91,7 +91,7 @@ namespace Umbraco.Core.Services
new SaveEventArgs<IDomain>(domainEntity, evtMsgs),
this))
{
return Attempt.Fail(OperationStatus.Cancelled(evtMsgs));
return OperationStatus.Cancelled(evtMsgs);
}
var uow = UowProvider.GetUnitOfWork();
@@ -102,7 +102,7 @@ namespace Umbraco.Core.Services
}
Saved.RaiseEvent(new SaveEventArgs<IDomain>(domainEntity, false, evtMsgs), this);
return Attempt.Succeed(OperationStatus.Success(evtMsgs));
return OperationStatus.Success(evtMsgs);
}
#region Event Handlers
@@ -2,7 +2,7 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net.Http.Formatting;
using System.Web;
using System.Xml;
using System.Xml.Linq;
using Umbraco.Core.Configuration;
@@ -140,18 +140,6 @@ namespace Umbraco.Core.Services
/// <param name="dataTypeDefinition">IDataTypeDefinition type to export</param>
/// <returns><see cref="XElement"/> containing the xml representation of the IDataTypeDefinition object</returns>
public XElement Serialize(IDataTypeService dataTypeService, IDataTypeDefinition dataTypeDefinition)
{
return Serialize(dataTypeService, dataTypeDefinition, string.Empty);
}
/// <summary>
/// Exports an <see cref="IDataTypeDefinition"/> item to xml as an <see cref="XElement"/>
/// </summary>
/// <param name="dataTypeService"></param>
/// <param name="dataTypeDefinition">IDataTypeDefinition type to export</param>
/// <param name="folders">The path of folders for this data type separated by a backslash, for example: `SEO/Meta`</param>
/// <returns><see cref="XElement"/> containing the xml representation of the IDataTypeDefinition object</returns>
public XElement Serialize(IDataTypeService dataTypeService, IDataTypeDefinition dataTypeDefinition, string folders)
{
var prevalues = new XElement("PreValues");
var prevalueList = dataTypeService.GetPreValuesCollectionByDataTypeId(dataTypeDefinition.Id)
@@ -175,8 +163,20 @@ namespace Umbraco.Core.Services
xml.Add(new XAttribute("Id", dataTypeDefinition.PropertyEditorAlias));
xml.Add(new XAttribute("Definition", dataTypeDefinition.Key));
xml.Add(new XAttribute("DatabaseType", dataTypeDefinition.DatabaseType.ToString()));
if(string.IsNullOrWhiteSpace(folders) == false)
xml.Add(new XAttribute("Folders", folders));
var folderNames = string.Empty;
if (dataTypeDefinition.Level != 1)
{
//get url encoded folder names
var folders = dataTypeService.GetContainers(dataTypeDefinition)
.OrderBy(x => x.Level)
.Select(x => HttpUtility.UrlEncode(x.Name));
folderNames = string.Join("/", folders.ToArray());
}
if (string.IsNullOrWhiteSpace(folderNames) == false)
xml.Add(new XAttribute("Folders", folderNames));
return xml;
}
@@ -267,11 +267,15 @@ namespace Umbraco.Core.Services
structure.Add(new XElement("MediaType", allowedType.Alias));
}
var genericProperties = new XElement("GenericProperties");
var genericProperties = new XElement("GenericProperties"); // actually, all of them
foreach (var propertyType in mediaType.PropertyTypes)
{
var definition = dataTypeService.GetDataTypeDefinitionById(propertyType.DataTypeDefinitionId);
var propertyGroup = mediaType.PropertyGroups.FirstOrDefault(x => x.Id == propertyType.PropertyGroupId.Value);
var propertyGroup = propertyType.PropertyGroupId == null // true generic property
? null
: mediaType.PropertyGroups.FirstOrDefault(x => x.Id == propertyType.PropertyGroupId.Value);
var genericProperty = new XElement("GenericProperty",
new XElement("Name", propertyType.Name),
new XElement("Alias", propertyType.Alias),
@@ -337,21 +341,10 @@ namespace Umbraco.Core.Services
/// Exports an <see cref="IContentType"/> item to xml as an <see cref="XElement"/>
/// </summary>
/// <param name="dataTypeService"></param>
/// <param name="contentTypeService"></param>
/// <param name="contentType">Content type to export</param>
/// <returns><see cref="XElement"/> containing the xml representation of the IContentType object</returns>
public XElement Serialize(IDataTypeService dataTypeService, IContentType contentType)
{
return Serialize(dataTypeService, contentType, string.Empty);
}
/// <summary>
/// Exports an <see cref="IContentType"/> item to xml as an <see cref="XElement"/>
/// </summary>
/// <param name="dataTypeService"></param>
/// <param name="contentType">Content type to export</param>
/// <param name="folders">The path of folders for this content type separated by a backslash, for example: `SEO/Meta`</param>
/// <returns><see cref="XElement"/> containing the xml representation of the IContentType object</returns>
public XElement Serialize(IDataTypeService dataTypeService, IContentType contentType, string folders)
public XElement Serialize(IDataTypeService dataTypeService, IContentTypeService contentTypeService, IContentType contentType)
{
var info = new XElement("Info",
new XElement("Name", contentType.Name),
@@ -392,14 +385,14 @@ namespace Umbraco.Core.Services
structure.Add(new XElement("DocumentType", allowedType.Alias));
}
var genericProperties = new XElement("GenericProperties");
var genericProperties = new XElement("GenericProperties"); // actually, all of them
foreach (var propertyType in contentType.PropertyTypes)
{
var definition = dataTypeService.GetDataTypeDefinitionById(propertyType.DataTypeDefinitionId);
var propertyGroup = propertyType.PropertyGroupId == null
? null
: contentType.PropertyGroups.FirstOrDefault(x => x.Id == propertyType.PropertyGroupId.Value);
var propertyGroup = propertyType.PropertyGroupId == null // true generic property
? null
: contentType.PropertyGroups.FirstOrDefault(x => x.Id == propertyType.PropertyGroupId.Value);
var genericProperty = new XElement("GenericProperty",
new XElement("Name", propertyType.Name),
@@ -431,8 +424,20 @@ namespace Umbraco.Core.Services
genericProperties,
tabs);
if(string.IsNullOrWhiteSpace(folders) == false)
xml.Add(new XAttribute("Folders", folders));
var folderNames = string.Empty;
//don't add folders if this is a child doc type
if (contentType.Level != 1 && masterContentType == null)
{
//get url encoded folder names
var folders = contentTypeService.GetContentTypeContainers(contentType)
.OrderBy(x => x.Level)
.Select(x => HttpUtility.UrlEncode(x.Name));
folderNames = string.Join("/", folders.ToArray());
}
if (string.IsNullOrWhiteSpace(folderNames) == false)
xml.Add(new XAttribute("Folders", folderNames));
return xml;
}
+104 -66
View File
@@ -23,34 +23,22 @@ namespace Umbraco.Core.Services
/// <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 : IFileService
public class FileService : RepositoryService, IFileService
{
private readonly RepositoryFactory _repositoryFactory;
private readonly IUnitOfWorkProvider _fileUowProvider;
private readonly IDatabaseUnitOfWorkProvider _dataUowProvider;
private const string PartialViewHeader = "@inherits Umbraco.Web.Mvc.UmbracoTemplatePage";
private const string PartialViewMacroHeader = "@inherits Umbraco.Web.Macros.PartialViewMacroPage";
[Obsolete("Use the constructors that specify all dependencies instead")]
public FileService()
: this(new RepositoryFactory())
{ }
[Obsolete("Use the constructors that specify all dependencies instead")]
public FileService(RepositoryFactory repositoryFactory)
: this(new FileUnitOfWorkProvider(), new PetaPocoUnitOfWorkProvider(), repositoryFactory)
public FileService(
IUnitOfWorkProvider fileProvider,
IDatabaseUnitOfWorkProvider dataProvider,
RepositoryFactory repositoryFactory,
ILogger logger,
IEventMessagesFactory eventMessagesFactory)
: base(dataProvider, repositoryFactory, logger, eventMessagesFactory)
{
}
public FileService(IUnitOfWorkProvider fileProvider, IDatabaseUnitOfWorkProvider dataProvider, RepositoryFactory repositoryFactory)
{
if (fileProvider == null) throw new ArgumentNullException("fileProvider");
if (dataProvider == null) throw new ArgumentNullException("dataProvider");
if (repositoryFactory == null) throw new ArgumentNullException("repositoryFactory");
_repositoryFactory = repositoryFactory;
_fileUowProvider = fileProvider;
_dataUowProvider = dataProvider;
_fileUowProvider = fileProvider;
}
@@ -62,7 +50,7 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of <see cref="Stylesheet"/> objects</returns>
public IEnumerable<Stylesheet> GetStylesheets(params string[] names)
{
using (var repository = _repositoryFactory.CreateStylesheetRepository(_fileUowProvider.GetUnitOfWork(), _dataUowProvider.GetUnitOfWork()))
using (var repository = RepositoryFactory.CreateStylesheetRepository(_fileUowProvider.GetUnitOfWork(), UowProvider.GetUnitOfWork()))
{
return repository.GetAll(names);
}
@@ -75,7 +63,7 @@ namespace Umbraco.Core.Services
/// <returns>A <see cref="Stylesheet"/> object</returns>
public Stylesheet GetStylesheetByName(string name)
{
using (var repository = _repositoryFactory.CreateStylesheetRepository(_fileUowProvider.GetUnitOfWork(), _dataUowProvider.GetUnitOfWork()))
using (var repository = RepositoryFactory.CreateStylesheetRepository(_fileUowProvider.GetUnitOfWork(), UowProvider.GetUnitOfWork()))
{
return repository.Get(name);
}
@@ -92,7 +80,7 @@ namespace Umbraco.Core.Services
return;
var uow = _fileUowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateStylesheetRepository(uow, _dataUowProvider.GetUnitOfWork()))
using (var repository = RepositoryFactory.CreateStylesheetRepository(uow, UowProvider.GetUnitOfWork()))
{
repository.AddOrUpdate(stylesheet);
uow.Commit();
@@ -111,7 +99,7 @@ namespace Umbraco.Core.Services
public void DeleteStylesheet(string path, int userId = 0)
{
var uow = _fileUowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateStylesheetRepository(uow, _dataUowProvider.GetUnitOfWork()))
using (var repository = RepositoryFactory.CreateStylesheetRepository(uow, UowProvider.GetUnitOfWork()))
{
var stylesheet = repository.Get(path);
if (stylesheet == null) return;
@@ -137,7 +125,7 @@ namespace Umbraco.Core.Services
{
var uow = _fileUowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateStylesheetRepository(uow, _dataUowProvider.GetUnitOfWork()))
using (var repository = RepositoryFactory.CreateStylesheetRepository(uow, UowProvider.GetUnitOfWork()))
{
return repository.ValidateStylesheet(stylesheet);
}
@@ -152,7 +140,7 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of <see cref="Script"/> objects</returns>
public IEnumerable<Script> GetScripts(params string[] names)
{
using (var repository = _repositoryFactory.CreateScriptRepository(_fileUowProvider.GetUnitOfWork()))
using (var repository = RepositoryFactory.CreateScriptRepository(_fileUowProvider.GetUnitOfWork()))
{
return repository.GetAll(names);
}
@@ -165,7 +153,7 @@ namespace Umbraco.Core.Services
/// <returns>A <see cref="Script"/> object</returns>
public Script GetScriptByName(string name)
{
using (var repository = _repositoryFactory.CreateScriptRepository(_fileUowProvider.GetUnitOfWork()))
using (var repository = RepositoryFactory.CreateScriptRepository(_fileUowProvider.GetUnitOfWork()))
{
return repository.Get(name);
}
@@ -182,7 +170,7 @@ namespace Umbraco.Core.Services
return;
var uow = _fileUowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateScriptRepository(uow))
using (var repository = RepositoryFactory.CreateScriptRepository(uow))
{
repository.AddOrUpdate(script);
uow.Commit();
@@ -201,7 +189,7 @@ namespace Umbraco.Core.Services
public void DeleteScript(string path, int userId = 0)
{
var uow = _fileUowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateScriptRepository(uow))
using (var repository = RepositoryFactory.CreateScriptRepository(uow))
{
var script = repository.Get(path);
if (script == null) return;
@@ -226,7 +214,7 @@ namespace Umbraco.Core.Services
public bool ValidateScript(Script script)
{
var uow = _fileUowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateScriptRepository(uow))
using (var repository = RepositoryFactory.CreateScriptRepository(uow))
{
return repository.ValidateScript(script);
}
@@ -235,7 +223,7 @@ namespace Umbraco.Core.Services
public void CreateScriptFolder(string folderPath)
{
var uow = _fileUowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateScriptRepository(uow))
using (var repository = RepositoryFactory.CreateScriptRepository(uow))
{
((ScriptRepository)repository).AddFolder(folderPath);
uow.Commit();
@@ -245,7 +233,7 @@ namespace Umbraco.Core.Services
public void DeleteScriptFolder(string folderPath)
{
var uow = _fileUowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateScriptRepository(uow))
using (var repository = RepositoryFactory.CreateScriptRepository(uow))
{
((ScriptRepository)repository).DeleteFolder(folderPath);
uow.Commit();
@@ -256,6 +244,56 @@ namespace Umbraco.Core.Services
#region Templates
/// <summary>
/// Creates a template for a content type
/// </summary>
/// <param name="contentTypeAlias"></param>
/// <param name="contentTypeName"></param>
/// <param name="userId"></param>
/// <returns>
/// The template created
/// </returns>
public Attempt<OperationStatus<ITemplate, OperationStatusType>> CreateTemplateForContentType(string contentTypeAlias, string contentTypeName, int userId = 0)
{
var template = new Template(contentTypeName,
//NOTE: We are NOT passing in the content type alias here, we want to use it's name since we don't
// want to save template file names as camelCase, the Template ctor will clean the alias as
// `alias.ToCleanString(CleanStringType.UnderscoreAlias)` which has been the default.
// This fixes: http://issues.umbraco.org/issue/U4-7953
contentTypeName);
var evtMsgs = EventMessagesFactory.Get();
//NOTE: This isn't pretty but we need to maintain backwards compatibility so we cannot change
// the event args here. The other option is to create a different event with different event
// args specifically for this method... which also isn't pretty. So for now, we'll use this
// dictionary approach to store 'additional data' in.
var additionalData = new Dictionary<string, object>
{
{"CreateTemplateForContentType", true},
{"ContentTypeAlias", contentTypeAlias},
};
if (SavingTemplate.IsRaisedEventCancelled(
new SaveEventArgs<ITemplate>(template, true, evtMsgs, additionalData),
this))
{
return Attempt.Fail(new OperationStatus<ITemplate, OperationStatusType>(template, OperationStatusType.FailedCancelledByEvent, evtMsgs));
}
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateTemplateRepository(uow))
{
repository.AddOrUpdate(template);
uow.Commit();
SavedTemplate.RaiseEvent(new SaveEventArgs<ITemplate>(template, false, evtMsgs), this);
}
Audit(AuditType.Save, string.Format("Save Template performed by user"), userId, template.Id);
return Attempt.Succeed(new OperationStatus<ITemplate, OperationStatusType>(template, OperationStatusType.Success, evtMsgs));
}
public ITemplate CreateTemplateWithIdentity(string name, string content, ITemplate masterTemplate = null, int userId = 0)
{
var template = new Template(name, name)
@@ -276,7 +314,7 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of <see cref="ITemplate"/> objects</returns>
public IEnumerable<ITemplate> GetTemplates(params string[] aliases)
{
using (var repository = _repositoryFactory.CreateTemplateRepository(_dataUowProvider.GetUnitOfWork()))
using (var repository = RepositoryFactory.CreateTemplateRepository(UowProvider.GetUnitOfWork()))
{
return repository.GetAll(aliases).OrderBy(x => x.Name);
}
@@ -288,7 +326,7 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of <see cref="ITemplate"/> objects</returns>
public IEnumerable<ITemplate> GetTemplates(int masterTemplateId)
{
using (var repository = _repositoryFactory.CreateTemplateRepository(_dataUowProvider.GetUnitOfWork()))
using (var repository = RepositoryFactory.CreateTemplateRepository(UowProvider.GetUnitOfWork()))
{
return repository.GetChildren(masterTemplateId).OrderBy(x => x.Name);
}
@@ -301,7 +339,7 @@ namespace Umbraco.Core.Services
/// <returns>The <see cref="ITemplate"/> object matching the alias, or null.</returns>
public ITemplate GetTemplate(string alias)
{
using (var repository = _repositoryFactory.CreateTemplateRepository(_dataUowProvider.GetUnitOfWork()))
using (var repository = RepositoryFactory.CreateTemplateRepository(UowProvider.GetUnitOfWork()))
{
return repository.Get(alias);
}
@@ -314,7 +352,7 @@ namespace Umbraco.Core.Services
/// <returns>The <see cref="ITemplate"/> object matching the identifier, or null.</returns>
public ITemplate GetTemplate(int id)
{
using (var repository = _repositoryFactory.CreateTemplateRepository(_dataUowProvider.GetUnitOfWork()))
using (var repository = RepositoryFactory.CreateTemplateRepository(UowProvider.GetUnitOfWork()))
{
return repository.Get(id);
}
@@ -327,7 +365,7 @@ namespace Umbraco.Core.Services
/// <returns>The <see cref="ITemplate"/> object matching the identifier, or null.</returns>
public ITemplate GetTemplate(Guid id)
{
using (var repository = _repositoryFactory.CreateTemplateRepository(_dataUowProvider.GetUnitOfWork()))
using (var repository = RepositoryFactory.CreateTemplateRepository(UowProvider.GetUnitOfWork()))
{
var query = Query<ITemplate>.Builder.Where(x => x.Key == id);
return repository.GetByQuery(query).SingleOrDefault();
@@ -336,7 +374,7 @@ namespace Umbraco.Core.Services
public IEnumerable<ITemplate> GetTemplateDescendants(string alias)
{
using (var repository = _repositoryFactory.CreateTemplateRepository(_dataUowProvider.GetUnitOfWork()))
using (var repository = RepositoryFactory.CreateTemplateRepository(UowProvider.GetUnitOfWork()))
{
return repository.GetDescendants(alias);
}
@@ -349,7 +387,7 @@ namespace Umbraco.Core.Services
/// <returns></returns>
public IEnumerable<ITemplate> GetTemplateDescendants(int masterTemplateId)
{
using (var repository = _repositoryFactory.CreateTemplateRepository(_dataUowProvider.GetUnitOfWork()))
using (var repository = RepositoryFactory.CreateTemplateRepository(UowProvider.GetUnitOfWork()))
{
return repository.GetDescendants(masterTemplateId);
}
@@ -362,7 +400,7 @@ namespace Umbraco.Core.Services
/// <returns></returns>
public IEnumerable<ITemplate> GetTemplateChildren(string alias)
{
using (var repository = _repositoryFactory.CreateTemplateRepository(_dataUowProvider.GetUnitOfWork()))
using (var repository = RepositoryFactory.CreateTemplateRepository(UowProvider.GetUnitOfWork()))
{
return repository.GetChildren(alias);
}
@@ -375,7 +413,7 @@ namespace Umbraco.Core.Services
/// <returns></returns>
public IEnumerable<ITemplate> GetTemplateChildren(int masterTemplateId)
{
using (var repository = _repositoryFactory.CreateTemplateRepository(_dataUowProvider.GetUnitOfWork()))
using (var repository = RepositoryFactory.CreateTemplateRepository(UowProvider.GetUnitOfWork()))
{
return repository.GetChildren(masterTemplateId);
}
@@ -390,7 +428,7 @@ namespace Umbraco.Core.Services
[EditorBrowsable(EditorBrowsableState.Never)]
public TemplateNode GetTemplateNode(string alias)
{
using (var repository = _repositoryFactory.CreateTemplateRepository(_dataUowProvider.GetUnitOfWork()))
using (var repository = RepositoryFactory.CreateTemplateRepository(UowProvider.GetUnitOfWork()))
{
return repository.GetTemplateNode(alias);
}
@@ -406,7 +444,7 @@ namespace Umbraco.Core.Services
[EditorBrowsable(EditorBrowsableState.Never)]
public TemplateNode FindTemplateInTree(TemplateNode anyNode, string alias)
{
using (var repository = _repositoryFactory.CreateTemplateRepository(_dataUowProvider.GetUnitOfWork()))
using (var repository = RepositoryFactory.CreateTemplateRepository(UowProvider.GetUnitOfWork()))
{
return repository.FindTemplateInTree(anyNode, alias);
}
@@ -422,8 +460,8 @@ namespace Umbraco.Core.Services
if (SavingTemplate.IsRaisedEventCancelled(new SaveEventArgs<ITemplate>(template), this))
return;
var uow = _dataUowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateTemplateRepository(uow))
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateTemplateRepository(uow))
{
repository.AddOrUpdate(template);
uow.Commit();
@@ -444,8 +482,8 @@ namespace Umbraco.Core.Services
if (SavingTemplate.IsRaisedEventCancelled(new SaveEventArgs<ITemplate>(templates), this))
return;
var uow = _dataUowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateTemplateRepository(uow))
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateTemplateRepository(uow))
{
foreach (var template in templates)
{
@@ -474,8 +512,8 @@ namespace Umbraco.Core.Services
/// </remarks>
public RenderingEngine DetermineTemplateRenderingEngine(ITemplate template)
{
var uow = _dataUowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateTemplateRepository(uow))
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateTemplateRepository(uow))
{
return repository.DetermineTemplateRenderingEngine(template);
}
@@ -488,8 +526,8 @@ namespace Umbraco.Core.Services
/// <param name="userId"></param>
public void DeleteTemplate(string alias, int userId = 0)
{
var uow = _dataUowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateTemplateRepository(uow))
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateTemplateRepository(uow))
{
var template = repository.Get(alias);
if (template == null) return;
@@ -513,8 +551,8 @@ namespace Umbraco.Core.Services
/// <returns>True if Script is valid, otherwise false</returns>
public bool ValidateTemplate(ITemplate template)
{
var uow = _dataUowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateTemplateRepository(uow))
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateTemplateRepository(uow))
{
return repository.ValidateTemplate(template);
}
@@ -543,7 +581,7 @@ namespace Umbraco.Core.Services
public void DeletePartialViewFolder(string folderPath)
{
var uow = _fileUowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreatePartialViewRepository(uow))
using (var repository = RepositoryFactory.CreatePartialViewRepository(uow))
{
((PartialViewRepository)repository).DeleteFolder(folderPath);
uow.Commit();
@@ -553,7 +591,7 @@ namespace Umbraco.Core.Services
public void DeletePartialViewMacroFolder(string folderPath)
{
var uow = _fileUowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreatePartialViewMacroRepository(uow))
using (var repository = RepositoryFactory.CreatePartialViewMacroRepository(uow))
{
((PartialViewMacroRepository)repository).DeleteFolder(folderPath);
uow.Commit();
@@ -562,7 +600,7 @@ namespace Umbraco.Core.Services
public IPartialView GetPartialView(string path)
{
using (var repository = _repositoryFactory.CreatePartialViewRepository(_fileUowProvider.GetUnitOfWork()))
using (var repository = RepositoryFactory.CreatePartialViewRepository(_fileUowProvider.GetUnitOfWork()))
{
return repository.Get(path);
}
@@ -570,7 +608,7 @@ namespace Umbraco.Core.Services
public IPartialView GetPartialViewMacro(string path)
{
using (var repository = _repositoryFactory.CreatePartialViewMacroRepository(_fileUowProvider.GetUnitOfWork()))
using (var repository = RepositoryFactory.CreatePartialViewMacroRepository(_fileUowProvider.GetUnitOfWork()))
{
return repository.Get(path);
}
@@ -706,8 +744,8 @@ namespace Umbraco.Core.Services
public bool ValidatePartialView(PartialView partialView)
{
var uow = _dataUowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreatePartialViewRepository(uow))
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreatePartialViewRepository(uow))
{
return repository.ValidatePartialView(partialView);
}
@@ -715,8 +753,8 @@ namespace Umbraco.Core.Services
public bool ValidatePartialViewMacro(PartialView partialView)
{
var uow = _dataUowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreatePartialViewMacroRepository(uow))
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreatePartialViewMacroRepository(uow))
{
return repository.ValidatePartialView(partialView);
}
@@ -746,9 +784,9 @@ namespace Umbraco.Core.Services
switch (partialViewType)
{
case PartialViewType.PartialView:
return _repositoryFactory.CreatePartialViewRepository(uow);
return RepositoryFactory.CreatePartialViewRepository(uow);
case PartialViewType.PartialViewMacro:
return _repositoryFactory.CreatePartialViewMacroRepository(uow);
return RepositoryFactory.CreatePartialViewMacroRepository(uow);
}
throw new ArgumentOutOfRangeException("partialViewType");
}
@@ -757,8 +795,8 @@ namespace Umbraco.Core.Services
private void Audit(AuditType type, string message, int userId, int objectId)
{
var uow = _dataUowProvider.GetUnitOfWork();
using (var auditRepo = _repositoryFactory.CreateAuditRepository(uow))
var uow = UowProvider.GetUnitOfWork();
using (var auditRepo = RepositoryFactory.CreateAuditRepository(uow))
{
auditRepo.AddOrUpdate(new AuditItem(objectId, message, type, userId));
uow.Commit();
@@ -21,18 +21,23 @@ namespace Umbraco.Core.Services
/// <returns></returns>
Attempt<string[]> ValidateComposition(IContentTypeComposition compo);
Attempt<int> CreateContentTypeContainer(int parentId, string name, int userId = 0);
Attempt<int> CreateMediaTypeContainer(int parentId, string name, int userId = 0);
void SaveContentTypeContainer(EntityContainer container, int userId = 0);
void SaveMediaTypeContainer(EntityContainer container, int userId = 0);
Attempt<OperationStatus<EntityContainer, OperationStatusType>> CreateContentTypeContainer(int parentId, string name, int userId = 0);
Attempt<OperationStatus<EntityContainer, OperationStatusType>> CreateMediaTypeContainer(int parentId, string name, int userId = 0);
Attempt<OperationStatus> SaveContentTypeContainer(EntityContainer container, int userId = 0);
Attempt<OperationStatus> SaveMediaTypeContainer(EntityContainer container, int userId = 0);
EntityContainer GetContentTypeContainer(int containerId);
EntityContainer GetContentTypeContainer(Guid containerId);
IEnumerable<EntityContainer> GetContentTypeContainers(int[] containerIds);
IEnumerable<EntityContainer> GetContentTypeContainers(IContentType contentType);
IEnumerable<EntityContainer> GetContentTypeContainers(string folderName, int level);
EntityContainer GetMediaTypeContainer(int containerId);
EntityContainer GetMediaTypeContainer(Guid containerId);
IEnumerable<EntityContainer> GetMediaTypeContainers(int[] containerIds);
IEnumerable<EntityContainer> GetMediaTypeContainers(string folderName, int level);
void DeleteMediaTypeContainer(int folderId, int userId = 0);
void DeleteContentTypeContainer(int containerId, int userId = 0);
IEnumerable<EntityContainer> GetMediaTypeContainers(IMediaType mediaType);
Attempt<OperationStatus> DeleteMediaTypeContainer(int folderId, int userId = 0);
Attempt<OperationStatus> DeleteContentTypeContainer(int containerId, int userId = 0);
/// <summary>
/// Gets all property type aliases.
@@ -40,6 +45,16 @@ namespace Umbraco.Core.Services
/// <returns></returns>
IEnumerable<string> GetAllPropertyTypeAliases();
/// <summary>
/// Gets all content type aliases
/// </summary>
/// <param name="objectTypes">
/// If this list is empty, it will return all content type aliases for media, members and content, otherwise
/// it will only return content type aliases for the object types specified
/// </param>
/// <returns></returns>
IEnumerable<string> GetAllContentTypeAliases(params Guid[] objectTypes);
/// <summary>
/// Copies a content type as a child under the specified parent if specified (otherwise to the root)
/// </summary>
@@ -276,5 +291,7 @@ namespace Umbraco.Core.Services
Attempt<OperationStatus<MoveOperationStatusType>> MoveMediaType(IMediaType toMove, int containerId);
Attempt<OperationStatus<MoveOperationStatusType>> MoveContentType(IContentType toMove, int containerId);
Attempt<OperationStatus<IMediaType, MoveOperationStatusType>> CopyMediaType(IMediaType toCopy, int containerId);
Attempt<OperationStatus<IContentType, MoveOperationStatusType>> CopyContentType(IContentType toCopy, int containerId);
}
}
@@ -10,12 +10,14 @@ namespace Umbraco.Core.Services
/// </summary>
public interface IDataTypeService : IService
{
Attempt<int> CreateContainer(int parentId, string name, int userId = 0);
void SaveContainer(EntityContainer container, int userId = 0);
Attempt<OperationStatus<EntityContainer, OperationStatusType>> CreateContainer(int parentId, string name, int userId = 0);
Attempt<OperationStatus> SaveContainer(EntityContainer container, int userId = 0);
EntityContainer GetContainer(int containerId);
EntityContainer GetContainer(Guid containerId);
IEnumerable<EntityContainer> GetContainers(string folderName, int level);
void DeleteContainer(int containerId, int userId = 0);
IEnumerable<EntityContainer> GetContainers(IDataTypeDefinition dataTypeDefinition);
IEnumerable<EntityContainer> GetContainers(int[] containerIds);
Attempt<OperationStatus> DeleteContainer(int containerId, int userId = 0);
/// <summary>
/// Gets a <see cref="IDataTypeDefinition"/> by its Name
@@ -160,5 +162,6 @@ namespace Umbraco.Core.Services
string GetPreValueAsString(int id);
Attempt<OperationStatus<MoveOperationStatusType>> Move(IDataTypeDefinition toMove, int parentId);
}
}
+11
View File
@@ -187,6 +187,17 @@ namespace Umbraco.Core.Services
/// <param name="userId">Optional id of the user saving the template</param>
void SaveTemplate(ITemplate template, int userId = 0);
/// <summary>
/// Creates a template for a content type
/// </summary>
/// <param name="contentTypeAlias"></param>
/// <param name="contentTypeName"></param>
/// <param name="userId"></param>
/// <returns>
/// The template created
/// </returns>
Attempt<OperationStatus<ITemplate, OperationStatusType>> CreateTemplateForContentType(string contentTypeAlias, string contentTypeName, int userId = 0);
ITemplate CreateTemplateWithIdentity(string name, string content, ITemplate masterTemplate = null, int userId = 0);
/// <summary>
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
+8 -8
View File
@@ -747,7 +747,7 @@ namespace Umbraco.Core.Services
if (Deleting.IsRaisedEventCancelled(
new DeleteEventArgs<IMedia>(media, evtMsgs), this))
{
return Attempt.Fail(OperationStatus.Cancelled(evtMsgs));
return OperationStatus.Cancelled(evtMsgs);
}
//Delete children before deleting the 'possible parent'
@@ -772,7 +772,7 @@ namespace Umbraco.Core.Services
Audit(AuditType.Delete, "Delete Media performed by user", userId, media.Id);
return Attempt.Succeed(OperationStatus.Success(evtMsgs));
return OperationStatus.Success(evtMsgs);
}
/// <summary>
@@ -791,7 +791,7 @@ namespace Umbraco.Core.Services
new SaveEventArgs<IMedia>(media, evtMsgs),
this))
{
return Attempt.Fail(OperationStatus.Cancelled(evtMsgs));
return OperationStatus.Cancelled(evtMsgs);
}
}
@@ -816,7 +816,7 @@ namespace Umbraco.Core.Services
Audit(AuditType.Save, "Save Media performed by user", userId, media.Id);
return Attempt.Succeed(OperationStatus.Success(evtMsgs));
return OperationStatus.Success(evtMsgs);
}
/// <summary>
@@ -836,7 +836,7 @@ namespace Umbraco.Core.Services
new SaveEventArgs<IMedia>(asArray, evtMsgs),
this))
{
return Attempt.Fail(OperationStatus.Cancelled(evtMsgs));
return OperationStatus.Cancelled(evtMsgs);
}
}
@@ -864,7 +864,7 @@ namespace Umbraco.Core.Services
Audit(AuditType.Save, "Save Media items performed by user", userId, -1);
return Attempt.Succeed(OperationStatus.Success(evtMsgs));
return OperationStatus.Success(evtMsgs);
}
/// <summary>
@@ -966,7 +966,7 @@ namespace Umbraco.Core.Services
if (Trashing.IsRaisedEventCancelled(
new MoveEventArgs<IMedia>(new MoveEventInfo<IMedia>(media, originalPath, Constants.System.RecycleBinMedia)), this))
{
return Attempt.Fail(OperationStatus.Cancelled(evtMsgs));
return OperationStatus.Cancelled(evtMsgs);
}
var moveInfo = new List<MoveEventInfo<IMedia>>
@@ -1008,7 +1008,7 @@ namespace Umbraco.Core.Services
Audit(AuditType.Move, "Move Media to Recycle Bin performed by user", userId, media.Id);
return Attempt.Succeed(OperationStatus.Success(evtMsgs));
return OperationStatus.Success(evtMsgs);
}
/// <summary>
@@ -69,10 +69,7 @@ namespace Umbraco.Core.Services
{
using (var repository = RepositoryFactory.CreateMemberTypeRepository(UowProvider.GetUnitOfWork()))
{
var query = Query<IMemberType>.Builder.Where(x => x.Alias == alias);
var contentTypes = repository.GetByQuery(query);
return contentTypes.FirstOrDefault();
return repository.Get(alias);
}
}

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