Compare commits

...

173 Commits

Author SHA1 Message Date
Morten Christensen 72e0e72d16 Minor tweaks to ExecutionMigrationStep and PackageMigrationsContext.
Adds tests for ExecutionMigrationStep and PackageMigrationsContext.
2016-06-13 00:48:27 +02:00
Morten Christensen 5fdec15a22 Code cleanup 2016-06-13 00:47:39 +02:00
Morten Christensen 9ac72b7232 Fixing merge issue in InstallStatus method 2016-06-12 14:16:01 +02:00
Morten Christensen a13eba0ac5 Merge pull request #1307 from Shazwazza/package-migrations
Package migrations
2016-06-12 13:25:48 +02:00
Shannon d03aa54dfc Merge remote-tracking branch 'umbraco/dev-v7' into package-migrations
# Conflicts:
#	src/Umbraco.Web/Install/InstallHelper.cs
2016-06-12 11:07:59 +02:00
Shannon 38e59373c6 U4-8569 Saving a member type changes the UniqueId of custom properties and tabs
This fixes the tab/group unique id mappings
2016-06-08 09:47:06 +02:00
Shannon 50f4bbdd1e U4-8569 Saving a member type changes the UniqueId of custom properties
This fixes the member property type UniqueID SQL and mapping.
This ensures that the main repositories fully assert/compare all fetched properties.
2016-06-07 12:20:10 +02:00
Simon Busborg 111ef37bfb Merge pull request #1286 from bjarnef/dev-v7-U4-8525
Fix tiny issues with dropzone border and sticky header
2016-06-06 12:04:48 +02:00
Shannon Deminick 6681e48c57 Merge pull request #1301 from dampee/dev-v7
update examine documentation links
2016-06-03 11:41:41 +02:00
Damiaan 7b101caf0b update examine documentation links 2016-06-03 11:36:07 +02:00
Shannon aff03997d9 Moves static event binding for prop editors to startup handlers 2016-06-01 11:27:08 +02:00
Sebastiaan Janssen cff7dbc81a Temp u4 8495 (#1293)
* U4-8495 Create YML file for AppVeyor

* Secret token needs to be in single quotes

* Secure token instead of a configuration variable should make the slack notification work

* Only post to Slack when build fails
2016-05-31 15:21:37 +02:00
Sebastiaan Janssen 1121362ca9 Merge pull request #1295 from umbraco/temp-U4-8511
U4-8511 Update moment.js to the version to 2.10.3 for release
2016-05-30 16:08:51 +02:00
Sebastiaan Janssen 6ad4390d20 Merge pull request #1294 from umbraco/temp-U4-8331
Fixes: U4-8331 Umbraco.MultipleMediaPicker 'pick only images' should not allow a folder to be picked
2016-05-30 14:57:14 +02:00
Mads Rasmussen 8d5742acb7 Merge pull request #1281 from umbraco/temp-U4-8445
U4-8445 Validation on the Email field for Members will not allow the …
2016-05-30 14:41:46 +02:00
Shannon 4aa4a03013 U4-8511 Update moment.js to the version to 2.10.3 for release 2016-05-30 14:25:47 +02:00
Mads Rasmussen 9190855bcf add configuration to disable folder select 2016-05-30 14:08:30 +02:00
Sebastiaan Janssen 720a46686b U4-8500 Get c# docs building (#1291)
fetches docfx, builds the metadata and builds the docs with the correct filters
builds the UI docs from the same powershell script
2016-05-30 12:02:13 +02:00
Mads Rasmussen 11c1b5a2c4 Merge pull request #1126 from KevinJump/dev-v7-StylesheetProperties-U4-7160
U4-7160: Stylesheet RegEx to capture multi class properties
2016-05-30 10:51:30 +02:00
Simon Busborg 885d14bcb6 Fixes: U4-8455 IE11 - Image Cropper stretches the image when zooming 2016-05-30 10:01:39 +02:00
Mads Rasmussen 654f130105 Merge pull request #1275 from bjarnef/dev-v7-U4-8489
Ensure correct font is used for icon-check
2016-05-30 09:56:05 +02:00
Mads Rasmussen 2f445543f4 Merge pull request #1263 from lars-erik/U4-8443
U4-8443 - Immediately create node from list view when only one available document type
2016-05-30 09:39:38 +02:00
Simon Busborg 216c70becc Merge pull request #1273 from gkonings/disable-submit-overlay
U4-8332
disable/enable submit button on overlay window
2016-05-30 09:35:42 +02:00
Simon Busborg 7046fca333 Merge pull request #1274 from bjarnef/dev-v7-U4-8486
Fixes some styling for login screen on narrow screen sizes
2016-05-30 09:27:42 +02:00
Simon Busborg 43ece1aba4 Merge pull request #1272 from gkonings/slider-default-round
Removed required attribute from slider-handle
2016-05-30 09:19:28 +02:00
bjarnef cd3140af21 Fix tiny issues with dropzone border to the left for fixed header and header jump by 1px when it get sticky. 2016-05-26 21:13:25 +02:00
Mads Rasmussen b3b4cd4654 Fixes: U4-8480 Allow deleting empty tab when creating a doctype 2016-05-25 15:30:35 +02:00
Shannon def8ee4962 fixes ysod when indexing grid content when the value is not a string (sub json value) 2016-05-25 14:38:24 +02:00
Shannon 8cea391a3f U4-8514 Fix installation issue when there are stale cookies on localhost 2016-05-25 14:36:00 +02:00
Shannon 1e38089bb4 U4-8514 Fix installation issue when there are stale cookies on localhost 2016-05-25 13:58:56 +02:00
Shannon 81d1ac74d2 U4-8513 Fix the RestartApplicationPool extension to null out the current identity 2016-05-25 13:56:42 +02:00
Claus 247a5f415d added a check to create macroScripts folder if it doesn't exist when creating a scripting file. 2016-05-25 12:12:52 +02:00
Shannon Deminick 8d5dabdfff Merge pull request #1282 from umbraco/temp-U4-7332
U4-7332 Default gravatar link broken
2016-05-25 12:00:38 +02:00
Shannon 85a54c6492 fixes the delete part of U4-8491 2016-05-25 11:20:35 +02:00
Sebastiaan Janssen 7f3f11ab58 Merge pull request #1279 from umbraco/temp-U4-8491
U4-8491 Moving/Deleting Media does not sync/refresh the tree
2016-05-24 17:22:51 +02:00
Sebastiaan Janssen f817eefd5c Merge pull request #1280 from umbraco/temp-U4-8358
U4-8358 Writers can't schedule publish/unpublish times
2016-05-24 16:25:55 +02:00
Sebastiaan Janssen 6cb817fc01 U4-7332 Default gravatar link broken 2016-05-24 16:20:20 +02:00
Stephan 7fad91d86f Merge branch 'AndyButland-u4-8290' into dev-v7 2016-05-24 15:56:21 +02:00
Stephan 42021a56b2 U4-8290 - minor cleanup & refactoring 2016-05-24 15:55:26 +02:00
Shannon f29b5aade7 only removes the buggy formatters/parsers if the attribute is type="email" 2016-05-24 15:07:35 +02:00
Shannon 3ea01b7dab U4-8445 Validation on the Email field for Members will not allow the entry of root domains greater than four characters. 2016-05-24 15:04:46 +02:00
Stephan 0a4a230c07 Merge branch 'u4-8290' of https://github.com/AndyButland/Umbraco-CMS into AndyButland-u4-8290 2016-05-24 08:15:47 +02:00
Shannon 877b7d4af7 U4-8358 Writers can't schedule publish/unpublish times 2016-05-23 19:23:59 +02:00
Shannon 9cf5ac2f95 U4-8491 Moving/Deleting Media does not sync/refresh the tree 2016-05-23 17:44:45 +02:00
Sebastiaan Janssen c902649768 U4-8438 Umbraco 7.4.3 NuGet package missing file 2016-05-23 10:47:54 +02:00
Sebastiaan Janssen bbe37ea6b9 U4-8349 Cannot create Scripting Files in Umbraco 7.4.0 2016-05-23 08:55:51 +02:00
Sebastiaan Janssen 57b19e7017 Forgot semicolon, whoops! 2016-05-23 08:47:36 +02:00
Sebastiaan Janssen 43d791f9a5 U4-6504 SmtpClient Not Properly Disposed, Causing Emails to Fail Periodically 2016-05-23 08:27:30 +02:00
bjarnef b74bf661b8 Added quotes 2016-05-21 23:57:30 +02:00
bjarnef 3c9de3b20c Ensure correct font is used for icon-check 2016-05-21 23:43:37 +02:00
bjarnef ccd42ad1d4 Fix some issues in landscape mode 2016-05-21 22:42:58 +02:00
bjarnef a8712fb4cf Added a comment 2016-05-21 21:51:28 +02:00
bjarnef d7cb79513f Adjust login for narrow screen sizes. 2016-05-21 21:49:00 +02:00
Gerard Konings 3897d0f764 disable submitbutton
disable submitbutton on overlay, so you can enable it later on
2016-05-20 22:44:18 +02:00
Gerard Konings 2ffbdec14b Removed required attribute from slider-handle
Removed required attribute. Slider defaults to round, so doesn’t need
to be required
2016-05-20 22:40:26 +02:00
Sebastiaan Janssen 8c7390280e Updates this migration to only run when upgrading from 7.3.0 and higher 2016-05-20 16:36:22 +02:00
Sebastiaan Janssen e54d374eb2 Add cmsPreviewXml table if it doesn't yet exist 2016-05-20 15:54:39 +02:00
Stephan aea26e67b1 Merge pull request #1255 from umbraco/better-memory-xmlcache
This fixes the LoadContentFromDatabase method
2016-05-19 17:03:23 +02:00
Shannon 06ae15ee7c reverts the cloning change 2016-05-19 16:12:12 +02:00
Shannon 95871fde7c updates naming conventions 2016-05-19 15:22:49 +02:00
Shannon 6b954d962f Merge branch 'lars-erik-test-bases-refactoring' into dev-v7 2016-05-19 11:48:14 +02:00
Shannon 2bd81ccb90 Merge branch 'test-bases-refactoring' of https://github.com/lars-erik/Umbraco-CMS into lars-erik-test-bases-refactoring 2016-05-19 11:48:01 +02:00
Stephan 08ae03a2d4 Merge branch 'dev-v7' into better-memory-xmlcache 2016-05-17 19:10:38 +02:00
Shannon 512c19a132 U4-8461 ERROR umbraco.presentation.webservices.nodeSorter - Could not update content sort order 2016-05-17 13:27:45 +02:00
Shannon 1e468cda5d Removes unused method, ensures that Cloning only occurs once per request (sort of hacky). Before if you have a few nodes that are published but have pending changes, then perform a sort, then the xml will be cloned for as many times as there were content changes. 2016-05-17 13:26:47 +02:00
Mads Rasmussen adebd4acd6 Merge pull request #1169 from AndyButland/u4-7468
Fixes U4 7468 - mis-assigned translator when sending to translation
2016-05-17 13:18:15 +02:00
Shannon d826f04b54 Ensures sort order is accurate to what is in the database 2016-05-17 12:17:05 +02:00
Simon Busborg 4752a83135 Fixes: U4-8362 Inserting image in a grid with Firefox shows full-size rather than scaled image 2016-05-17 11:02:07 +02:00
Mads Rasmussen 6a593d8b5e Merge pull request #1245 from greystate/U4-8377
Fix for U4-8377
2016-05-17 10:42:12 +02:00
Mads Rasmussen 38bc38486a Merge pull request #1229 from bjarnef/dev-v7-U4-8300
Wrap text "Include all child nodes" in a label
2016-05-17 10:13:06 +02:00
Mads Rasmussen b3f50368e5 Merge pull request #1228 from bjarnef/dev-v7-U4-8330
Fix line-height when using custom icon font as section icon
2016-05-17 09:19:38 +02:00
Shannon f130e86c88 U4-8448 Background task runner missing a null check during shutdown 2016-05-12 12:27:02 +02:00
Shannon 8d5556d4bc Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2016-05-12 11:16:46 +02:00
Shannon 4d0dc90042 Revert "RteMacroRenderingValueConverter should return an IHtmlString"
This reverts commit 7e9a14be83.
2016-05-12 11:16:39 +02:00
Claus acb1aeabda Merge pull request #1261 from umbraco/temp-U4-8371
U4-8371 Dont ship with the {machinename} token for Examine
2016-05-12 10:55:52 +02:00
Claus f5e433fd3c Merge pull request #1260 from umbraco/temp-U4-7295
U4-7295 Examine search with the data in the grid should be easier OOTB
2016-05-12 10:52:18 +02:00
Lars-Erik Aabech 597b4c3dd2 Added button to create only available doctype
Hides dropdown when listViewAllowedTypes.length > 1
Shows button for single when listViewAllowedTypes.length === 1
2016-05-11 21:44:22 +02:00
Simon Busborg a3efb74ad3 Merge pull request #1240 from arknu/decimal-parsing
U4-8365: Fix decimal property value converter to work on non EN-US cultures
2016-05-11 13:33:48 +02:00
Simon Busborg 924eac1b95 Merge pull request #1235 from bjarnef/dev-v7-U4-8347
Fix localization of listview buttons/links actions.
2016-05-11 10:06:51 +02:00
Shannon fb55b0a60b U4-8371 Dont ship with the {machinename} token for Examine 2016-05-10 18:32:32 +02:00
Shannon 7ae1060f50 U4-7295 Examine search with the data in the grid should be easier OOTB 2016-05-10 18:25:18 +02:00
Shannon Deminick d11ae23fe3 Merge pull request #1259 from umbraco/temp-u4-8413
U4-8413 - fix missing ServersLock object
2016-05-10 13:51:10 +02:00
Stephan 271f4e7a4a U4-8413 - fix missing ServersLock object 2016-05-10 12:29:13 +02:00
AndyButland 4f3d82cf10 Change field to which data is saved for a data type if provided in prevalues and handle potential mis-matched types on display 2016-05-10 10:50:59 +02:00
Simon Busborg 50e92b80f9 Changed from int to Nvarchar for the multimediapicker 2016-05-09 14:35:55 +02:00
Simon Busborg 9cd33abd5b Merge pull request #1130 from jamescoxhead/U4-7315
U4-7315 Make new media picker default in new installs
2016-05-09 14:30:29 +02:00
AndyButland 7b6bcd24ae Added value type as a pre-value to the label property editor 2016-05-08 23:39:47 +02:00
AndyButland 7858521c8b Converted usage of property editor value type strings to constants 2016-05-08 22:05:23 +02:00
Shannon Deminick f79a1f1a71 Merge pull request #1253 from umbraco/temp-u4-8406
U4-8406 - restart app pool by unloading domain and support read-only …
2016-05-04 16:51:41 +02:00
Shannon 0d11b15b3f This fixes the LoadContentFromDatabase method - before this was storing every single xml node in memory in dictionaries (x2) and then performing the re-organization of all nodes afterwords to construct a document, now we just read each row and organize the document accordingly, 2016-05-04 16:36:43 +02:00
Stephan 5f8747b4d3 U4-1780 - detect colliding urls (#1243)
* U4-1780 - detect colliding urls

* U4-1780 - fix error message

* U4-1780 - fix XmlHelper issue with sortOrder

* U4-1780 - bugfix
2016-05-04 12:45:20 +02:00
Stephan 67996cdb64 U4-8406 - restart app pool by unloading domain and support read-only web.config 2016-05-04 08:45:50 +02:00
Shannon 31d910432a Moves some logic to PackageMigrationsContext, ensures that the dest version for each package is based on it's maximum available version found in it's migrations. 2016-05-04 08:43:41 +02:00
Shannon 0e67976cc6 Migrations are detected and running now including the installer UI 2016-05-04 08:43:19 +02:00
Shannon 85399a97a6 adds another check to app context for HasPendingPackageMigrations, updates the installer auth checks and adds a new installer route which will be redirected to instead of the normal installer route when there are pending migrations. 2016-05-04 08:39:52 +02:00
Shannon cb7e12215e First step done - detect if package migrations need to run on startup and redirect to the installer 2016-05-04 08:39:30 +02:00
Claus 729b179473 Merge pull request #1242 from umbraco/temp-u4-8370
U4-8370 - fix broken upgrade
2016-05-03 12:54:47 +02:00
Claus 20b67e47be Fixed property name to match property of the dynamic. 2016-05-03 12:54:22 +02:00
Shannon Deminick 52b6e04ad4 Merge pull request #1248 from rustyswayne/dev-v7
Appends forum link to developer comment for reference when evaluating code removal.
2016-05-03 11:35:56 +02:00
Claus 1186b7cb47 Merge pull request #1246 from umbraco/temp-u4-2508
U4-2508 - improve culture detection in 404 situation
2016-05-03 11:02:31 +02:00
Shannon f03daf819e Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2016-05-02 23:06:45 +02:00
Shannon febaddaaef U4-8394 When persisting the xml cache file it double loads the full xml structure into memory before writing it to a file 2016-05-02 23:05:46 +02:00
rs@merchello.com 029e50dd3c Appends comment and forum reference to developer comment for reference when evaluating code removal. 2016-05-02 13:17:13 -07:00
Simon Busborg 2a87c926f3 Merge pull request #1234 from bjarnef/dev-v7-U4-8343
Localize "unsaved changes" dialog.
2016-05-02 10:44:47 +02:00
Simon Busborg f7ee47a37f Fixes U4-8029 Editor settings for "Grid Layouts" is too wide and text overflows 2016-05-02 10:18:37 +02:00
Stephan 6dea69c5a1 U4-2508 - improve culture detection in 404 situation 2016-04-27 19:09:49 +02:00
Chriztian Steinmeier 066ef6809b Change the language keys necessary for the fix 2016-04-26 23:36:42 +02:00
Mads Rasmussen 4b682e0669 Merge pull request #1201 from bjarnef/dev-v7-U4-8022
U4-8022 - Fix issues with tree icons + legacy icons
2016-04-25 21:13:14 +02:00
Mads Rasmussen 4886631d54 Merge pull request #1202 from bjarnef/dev-v7-U4-7967
U4-7967 - Fix errors when saving document type when no icon is selected
2016-04-25 20:14:11 +02:00
Stephan 2c3c0eae12 U4-8370 - fix broken upgrade 2016-04-25 17:10:10 +02:00
Claus a5c427bae7 Merge pull request #1241 from umbraco/temp-u4-5699
U4-5699 - update template alias in gui after saving
2016-04-25 14:29:03 +02:00
Stephan fb99e375d0 U4-5699 - update template alias in gui after saving 2016-04-25 14:14:55 +02:00
Stephan 7e9a14be83 RteMacroRenderingValueConverter should return an IHtmlString 2016-04-25 11:18:22 +02:00
Claus 9b39f712be U4-3411 Adding new language doesn't sync the tree 2016-04-25 10:11:54 +02:00
bjarnef fcdf212c4c Rename area alias 2016-04-24 18:42:46 +02:00
Asbjørn Riis-Knudsen deb74939af U4-8365: Fix decimal property value converter to work on non EN-US cultures 2016-04-23 17:54:37 +02:00
Shannon Deminick b28a4a410c Merge pull request #1239 from soreng/patch-1
Update ICacheProvider.cs
2016-04-23 16:18:38 +02:00
Søren Gregersen bad1372313 Update ICacheProvider.cs
Not really an abstract class... :)
2016-04-23 15:58:18 +02:00
Shannon 7e13781d8b fixes merge issue 2016-04-20 16:04:35 +02:00
Shannon 72cef006d3 bumps version 2016-04-20 15:56:06 +02:00
Shannon 6124126835 Fixes the custom field sorting, no longer has a sub query for order by, now supports both mysql and sqlce, adds a unit test (should add more though) 2016-04-20 15:50:38 +02:00
Shannon 7e71dcd2ae Merge remote-tracking branch 'origin/dev-v7.5' into dev-v7 2016-04-20 12:56:03 +02:00
bjarnef 9174029126 Fix localization of listview buttons/links actions. 2016-04-18 22:33:38 +02:00
bjarnef 3564e70259 Localize "unsaved changes" dialog. 2016-04-18 20:42:19 +02:00
Lars-Erik Aabech 1d428045b6 Don't remove virtual on SetupApplicationContext. Might be many external inheritors. 2016-04-18 15:35:09 +02:00
bjarnef e9bf41e869 Wrap text "Include all child nodes" in a label 2016-04-14 23:22:26 +02:00
bjarnef 054fd9ecef Fix line-height when using custom icon font as section icon. 2016-04-14 22:18:14 +02:00
Shannon Deminick a015032442 fixed typo 2016-04-13 16:45:47 +02:00
Shannon Deminick 38f6a7a8b6 fixed typo 2016-04-13 16:45:01 +02:00
Shannon c3b4a9128a ensures all GetPagedDescendant methods are mocked - fixes tests. 2016-04-13 15:47:21 +02:00
Shannon dbff25bd6d Merge branch 'dev-v7' into dev-v7.5 2016-04-13 15:16:28 +02:00
Shannon c9c391e477 fixed type, decimal sorting now works 2016-04-13 15:05:23 +02:00
Shannon 10bb16316d Updates sorting code to support decimals - need to test on MySql 2016-04-13 14:49:37 +02:00
Shannon 82b4b4e668 Merge remote-tracking branch 'origin/7.5-ListViewCustomFieldSorting' into dev-v7.5
Conflicts:
	src/Umbraco.Web/WebApi/Filters/DisableBrowserCacheAttribute.cs
2016-04-13 14:44:22 +02:00
Shannon ce0ecd8114 Ensures that the emails sent our are in the culture of the user, fixes issue of logging in after resetting password and then logging out again 2016-04-13 14:35:40 +02:00
Shannon e610a5ef54 Changes the password reset link to be a real link (not an angular deep link), this means there is less logging of the reset code in a query string and less visibility of it, this also means that the validation of the code happens instantly. The premise for this is the same as how we deal with external authentication requests and uses ViewData/TempData with redirects. Fixes the models to have the correct attributes to be able to directly json serialize them. 2016-04-13 13:51:12 +02:00
Shannon f279000d00 removes unecessary methods from user.service.js, ensures correct error msg when resetting password on the server, fixes email copy and allows for non-html emails if the copy is plain text, removes the need for more than one email msg in the lang files and uses the correct way to replace tokens, 2016-04-12 19:54:04 +02:00
Shannon d424b13ac4 Fixes some styling, wording and validation 2016-04-12 18:59:39 +02:00
Shannon 1361e017a2 Merge branch 'u4-222' of https://github.com/AndyButland/Umbraco-CMS into AndyButland-u4-222
Conflicts:
	src/Umbraco.Core/Security/BackOfficeUserManager.cs
	src/Umbraco.Web.UI.Client/src/less/pages/login.less
	src/Umbraco.Web.UI.Client/src/routes.js
	src/Umbraco.Web.UI.Client/src/views/common/dialogs/login.controller.js
	src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml
	src/Umbraco.Web.UI/web.Template.config
	src/Umbraco.Web/Editors/AuthenticationController.cs
	src/Umbraco.Web/Editors/BackOfficeController.cs
	src/Umbraco.Web/Umbraco.Web.csproj
2016-04-12 18:07:25 +02:00
Claus 76054bb783 Enabling sorting by the Name column.
OrderDirection is only reversed if reclicking the same sort column.
2016-04-12 15:36:28 +02:00
Lars-Erik Aabech ae913ede6f Virtualized creating of application context
Closed setting up of application context
Opens up a whole bunch of doors. :)
2016-04-10 00:07:03 +02:00
Shannon e2954fbf39 refactors interface methods so they are not breaking existing signatures and not overlapping based on optional parameters 2016-04-06 13:23:39 +02:00
Shannon 75be22a778 Fixes tests, adds null checks 2016-04-06 12:05:52 +02:00
Shannon 6856540a7c fixes bool parameter for members 2016-04-06 09:49:53 +02:00
Shannon b9b3d62994 fixes boolean isSystem for media 2016-04-06 09:44:33 +02:00
Shannon dac7b93209 fixes GetChildren non bool argument to work as a bool again. 2016-04-06 09:17:05 +02:00
Shannon 90a66aeebd fixes merge / build 2016-04-05 16:32:46 +02:00
Shannon f485755082 Merge branch 'aadfPT-dev-v7' into 7.5-ListViewCustomFieldSorting 2016-04-05 16:21:10 +02:00
Shannon c20984dca7 Merge branch 'dev-v7' of https://github.com/aadfPT/Umbraco-CMS into aadfPT-dev-v7
Conflicts:
	src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs
	src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs
	src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs
	src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs
	src/Umbraco.Core/Services/ContentService.cs
	src/Umbraco.Core/Services/IContentService.cs
	src/Umbraco.Core/Services/IMediaService.cs
	src/Umbraco.Core/Services/IMemberService.cs
	src/Umbraco.Core/Services/MediaService.cs
	src/Umbraco.Core/Services/MemberService.cs
	src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs
	src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs
	src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs
	src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js
	src/Umbraco.Web.UI.Client/src/common/resources/media.resource.js
	src/Umbraco.Web.UI.Client/src/common/resources/member.resource.js
	src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/list/list.listviewlayout.controller.js
	src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js
	src/Umbraco.Web/Editors/ContentController.cs
	src/Umbraco.Web/Editors/MediaController.cs
	src/Umbraco.Web/Editors/MemberController.cs
	src/Umbraco.Web/WebApi/Filters/DisableBrowserCacheAttribute.cs
	src/UmbracoExamine/UmbracoMemberIndexer.cs
2016-04-05 16:20:39 +02:00
Shannon 80d7443bd3 fix build 2016-04-05 16:00:49 +02:00
Shannon ed7c682a68 Merge branch 'AndyButland-u4-6003b' into 7.5-ListViewCustomFieldSorting 2016-04-05 15:31:41 +02:00
Shannon ef3f15ec9b Merge branch 'u4-6003b' of https://github.com/AndyButland/Umbraco-CMS into AndyButland-u4-6003b
Conflicts:
	src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs
	src/Umbraco.Core/Persistence/Repositories/Interfaces/IContentRepository.cs
	src/Umbraco.Core/Persistence/Repositories/Interfaces/IMediaRepository.cs
	src/Umbraco.Core/Persistence/Repositories/Interfaces/IMemberRepository.cs
	src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs
	src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs
	src/Umbraco.Core/Services/ContentService.cs
	src/Umbraco.Core/Services/IContentService.cs
	src/Umbraco.Core/Services/IMediaService.cs
	src/Umbraco.Core/Services/IMemberService.cs
	src/Umbraco.Core/Services/MediaService.cs
	src/Umbraco.Core/Services/MemberService.cs
	src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs
	src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs
	src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs
	src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js
	src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html
	src/Umbraco.Web/Editors/MemberController.cs
	src/UmbracoExamine/UmbracoMemberIndexer.cs
2016-04-05 15:31:33 +02:00
André Ferreira c147db1334 Merge branch 'dev-v7' of https://github.com/aadfPT/Umbraco-CMS into dev-v7 2016-04-01 11:29:33 +01:00
André Ferreira bd2a40d214 U4-6003 List View - Order By Custom Property Fix
Original work done on https://github.com/umbraco/Umbraco-CMS/pull/711 but ported to the latest version

Content below for reference
With the current implementation of the list view you can only sort by system columns (Name, SortOrder etc.) and not custom columns you have added to your document types. This PR allows that.

The crux of it is a sub-query added to the ORDER BY clause when we are ordering by a custom field. This looks up the field's value from the most recent content version.

Provided here and not in the previous pull request is:

MySQL support
Have done some performance testing. On a local laptop with 1000 nodes in a list view, it's sorting in around 220-250ms. It's a little slower that sorting on native properties like node name, but still perfectly usable - there's no significant delay you see in use.
Please note also:

GetPagedResultsByQuery() in VersionableRepositoryBase was previously doing an ORDER BY in SQL and then repeating this via LINQ to Objects. I couldn't see that this second ordering was necessary so removed it, but wanted to flag here in case I've missed something around why this was necessary.
The PR also includes small amends to fix or hide sorting on a couple of the default columns for the member amd media list views.
2016-04-01 11:28:51 +01:00
André Ferreira 9376731533 Adhering to Umbraco's Coding Standards 2016-04-01 11:24:30 +01:00
André Ferreira d560223eca Fixes to make it work 2016-03-29 20:13:53 +01:00
André Ferreira 54394f2ce9 fixes 2016-03-28 10:35:05 +01:00
André Ferreira 4f141e8b27 Fixing column sort on columns with custom headers 2016-03-28 10:35:04 +01:00
bjarnef 30e9a1ef82 Don't set dirty when just filtering icons. 2016-03-28 02:29:03 +02:00
bjarnef 0c9dcc1f5a Fix errors when saving document type when no icon is selected. 2016-03-28 01:47:01 +02:00
bjarnef 233e3d9387 Fix issues with tree icons + legacy icons 2016-03-27 19:07:09 +02:00
AndyButland e3411f7212 Provided a check that a language was selected when sending to translation such that a message is returned to the user rather than an unexpected error 2016-03-12 19:26:45 +01:00
AndyButland 64ad8f660f Fixed issue with misasigned task assignee on send to translation 2016-03-12 19:17:51 +01:00
Lesley b72d52bf90 Fix U4-8029
The div was too wide so description text was unreadable.
2016-02-18 17:16:01 +00:00
James Coxhead 3ce2b0e6a0 Updated database installer to use new media picker instead of legacy picker 2016-02-16 14:06:08 +00:00
Kevin Jump 95863ad618 Stylesheet RegEx to capture multi class properties
Change the RegEx in Stylesheet Helper to capture mutli element classes
as stylesheet properties (See U4-7160)

Previously single class names "H1", "P", ".test" all work but multi
".btn btn-default" fail - this change fixes that
2016-02-16 11:36:56 +00:00
AndyButland af244917f6 Fixed issue with ordering by custom property from inherited or composed doc type 2015-06-14 11:24:03 +02:00
AndyButland 7008d6b2fb Fix to issue with ordering by custom date field 2015-06-13 00:15:51 +02:00
AndyButland a1ae0f70bb Moved custom column list view order by sql variations into syntax providers 2015-06-12 09:15:36 +02:00
AndyButland 58f2694a90 Removed option to sort by media last edited date as currently only base table fields can be sorted and this isn't one. Trying to do so currently triggers an error. 2015-06-12 09:15:26 +02:00
AndyButland b9ff327536 Removed ability to sort member list view system fields other than those on the base table (others aren't handled so error) 2015-06-12 09:15:12 +02:00
AndyButland 5954c370ed Fixed issue with sorting on default member list view column of username 2015-06-12 09:15:05 +02:00
AndyButland 968927d472 Enabled sorting for custom columns on list view 2015-06-12 09:14:47 +02:00
283 changed files with 7417 additions and 13502 deletions
+7 -1
View File
@@ -132,4 +132,10 @@ src/umbraco.sln.ide/*
build/UmbracoCms.*/
src/.vs/
src/Umbraco.Web.UI/umbraco/js/install.loader.js
src/Umbraco.Tests/media
src/Umbraco.Tests/media
tools/docfx/*
apidocs/_site/*
apidocs/api/*
build/docs.zip
build/ui-docs.zip
build/csharp-docs.zip
+18
View File
@@ -0,0 +1,18 @@
apiRules:
- include:
uidRegex: ^Umbraco\.Core
- exclude:
uidRegex: ^umbraco\.Web\.org
- include:
uidRegex: ^Umbraco\.Web
- exclude:
hasAttribute:
uid: System.ComponentModel.EditorBrowsableAttribute
ctorArguments:
- System.ComponentModel.EditorBrowsableState.Never
- exclude:
uidRegex: ^umbraco\.
- exclude:
uidRegex: ^CookComputing\.
- exclude:
uidRegex: ^.*$
+75
View File
@@ -0,0 +1,75 @@
{
"metadata": [
{
"src": [
{
"files": [
"Umbraco.Core/Umbraco.Core.csproj",
"Umbraco.Web/Umbraco.Web.csproj"
],
"exclude": [
"**/obj/**",
"**/bin/**",
"_site/**"
],
"cwd": "../src"
}
],
"dest": "../apidocs/api",
"filter": "../apidocs/docfx.filter.yml"
}
],
"build": {
"content": [
{
"files": [
"api/**.yml",
"api/index.md"
]
},
{
"files": [
"articles/**.md",
"articles/**/toc.yml",
"toc.yml",
"*.md"
],
"exclude": [
"obj/**",
"_site/**"
]
}
],
"resource": [
{
"files": [
"images/**"
],
"exclude": [
"obj/**",
"_site/**"
]
}
],
"overwrite": [
{
"files": [
"**.md"
],
"exclude": [
"obj/**",
"_site/**"
]
}
],
"globalMetadata": {
"_appTitle": "Umbraco c# Api docs",
"_enableSearch": true,
"_disableContribution": false
},
"dest": "_site",
"template": [
"default", "umbracotemplate"
]
}
}
+7
View File
@@ -0,0 +1,7 @@
# Umbraco c# API reference
## Quick Links:
### [Umbraco.Core](api/Umbraco.Core.html) docs
### [Umbraco.Web](api/Umbraco.Web.html) docs
+5
View File
@@ -0,0 +1,5 @@
- name: Umbraco.Core Documentation
href: https://our.umbraco.org/apidocs/csharp/api/Umbraco.Core.html
- name: Umbraco.Web Documentation
href: https://our.umbraco.org/apidocs/csharp/api/Umbraco.Web.html
@@ -0,0 +1,257 @@
{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}
{{^_disableContribution}}
{{#sourceurl}}<a href="{{sourceurl}}" class="btn btn-primary pull-right mobile-hide">{{__global.viewSource}}</a>{{/sourceurl}}
{{/_disableContribution}}
<h1 id="{{id}}" data-uid="{{uid}}">{{>partials/title}}</h1>
<div class="markdown level0 summary">{{{summary}}}</div>
<div class="markdown level0 conceptual">{{{conceptual}}}</div>
{{#inheritance.0}}
<div class="inheritance">
<h5>{{__global.inheritance}}</h5>
{{#inheritance}}
<div class="level{{index}}">{{{specName.0.value}}}</div>
{{/inheritance}}
<div class="level{{item.level}}"><span class="xref">{{item.name.0.value}}</span></div>
</div>
{{/inheritance.0}}
<h6><strong>{{__global.namespace}}</strong>:{{namespace}}</h6>
<h6><strong>{{__global.assembly}}</strong>:{{assemblies.0}}.dll</h6>
<h5 id="{{id}}_syntax">{{__global.syntax}}</h5>
<div class="codewrapper">
<pre><code class="lang-{{_lang}} hljs">{{syntax.content.0.value}}</code></pre>
</div>
{{#syntax.parameters.0}}
<h5 class="parameters">{{__global.parameters}}</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{{__global.type}}</th>
<th>{{__global.name}}</th>
<th>{{__global.description}}</th>
</tr>
</thead>
<tbody>
{{/syntax.parameters.0}}
{{#syntax.parameters}}
<tr>
<td>{{{type.specName.0.value}}}</td>
<td><em>{{{id}}}</em></td>
<td>{{{description}}}</td>
</tr>
{{/syntax.parameters}}
{{#syntax.parameters.0}}
</tbody>
</table>
{{/syntax.parameters.0}}
{{#syntax.return}}
<h5 class="returns">{{__global.returns}}</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{{__global.type}}</th>
<th>{{__global.description}}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{{type.specName.0.value}}}</td>
<td>{{{description}}}</td>
</tr>
</tbody>
</table>
{{/syntax.return}}
{{#syntax.typeParameters.0}}
<h5 class="typeParameters">{{__global.typeParameters}}</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{{__global.name}}</th>
<th>{{__global.description}}</th>
</tr>
</thead>
<tbody>
{{/syntax.typeParameters.0}}
{{#syntax.typeParameters}}
<tr>
<td><em>{{{id}}}</em></td>
<td>{{{description}}}</td>
</tr>
{{/syntax.typeParameters}}
{{#syntax.typeParameters.0}}
</tbody>
</table>
{{/syntax.typeParameters.0}}
{{#remarks}}
<h5 id="{{id}}_remarks"><strong>{{__global.remarks}}</strong></h5>
<div class="markdown level0 remarks">{{{remarks}}}</div>
{{/remarks}}
{{#example.0}}
<h5 id="{{id}}_examples"><strong>{{__global.examples}}</strong></h5>
{{/example.0}}
{{#example}}
{{{.}}}
{{/example}}
{{#children}}
<h3 id="{{id}}">{{>partials/classSubtitle}}</h3>
{{#children}}
{{^_disableContribution}}
{{#sourceurl}}
<span class="small pull-right mobile-hide">
<a href="{{sourceurl}}">{{__global.viewSource}}</a>
</span>{{/sourceurl}}
{{/_disableContribution}}
<h4 id="{{id}}" data-uid="{{uid}}">{{name.0.value}}</h4>
<div class="markdown level1 summary">{{{summary}}}</div>
<div class="markdown level1 conceptual">{{{conceptual}}}</div>
<h5 class="decalaration">{{__global.declaration}}</h5>
{{#syntax}}
<div class="codewrapper">
<pre><code class="lang-{{_lang}} hljs">{{syntax.content.0.value}}</code></pre>
</div>
{{#parameters.0}}
<h5 class="parameters">{{__global.parameters}}</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{{__global.type}}</th>
<th>{{__global.name}}</th>
<th>{{__global.description}}</th>
</tr>
</thead>
<tbody>
{{/parameters.0}}
{{#parameters}}
<tr>
<td>{{{type.specName.0.value}}}</td>
<td><em>{{{id}}}</em></td>
<td>{{{description}}}</td>
</tr>
{{/parameters}}
{{#parameters.0}}
</tbody>
</table>
{{/parameters.0}}
{{#return}}
<h5 class="returns">{{__global.returns}}</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{{__global.type}}</th>
<th>{{__global.description}}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{{type.specName.0.value}}}</td>
<td>{{{description}}}</td>
</tr>
</tbody>
</table>
{{/return}}
{{#typeParameters.0}}
<h5 class="typeParameters">{{__global.typeParameters}}</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{{__global.name}}</th>
<th>{{__global.description}}</th>
</tr>
</thead>
<tbody>
{{/typeParameters.0}}
{{#typeParameters}}
<tr>
<td><em>{{{id}}}</em></td>
<td>{{{description}}}</td>
</tr>
{{/typeParameters}}
{{#typeParameters.0}}
</tbody>
</table>
{{/typeParameters.0}}
{{#fieldValue}}
<h5 class="fieldValue">{{__global.fieldValue}}</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{{__global.type}}</th>
<th>{{__global.description}}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{{type.specName.0.value}}}</td>
<td>{{{description}}}</td>
</tr>
</tbody>
</table>
{{/fieldValue}}
{{#propertyValue}}
<h5 class="propertyValue">{{__global.propertyValue}}</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{{__global.type}}</th>
<th>{{__global.description}}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{{type.specName.0.value}}}</td>
<td>{{{description}}}</td>
</tr>
</tbody>
</table>
{{/propertyValue}}
{{#eventType}}
<h5 class="eventType">{{__global.eventType}}</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{{__global.type}}</th>
<th>{{__global.description}}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{{type.specName.0.value}}}</td>
<td>{{{description}}}</td>
</tr>
</tbody>
</table>
{{/eventType}}
{{/syntax}}
{{#remarks}}
<h5 id="{{id}}_remarks">{{__global.remarks}}</h5>
<div class="markdown level1 remarks">{{{remarks}}}</div>
{{/remarks}}
{{#example.0}}
<h5 id="{{id}}_examples">{{__global.examples}}</h5>
{{/example.0}}
{{#example}}
{{{.}}}
{{/example}}
{{#exceptions.0}}
<h5 class="exceptions">{{__global.exceptions}}</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{{__global.type}}</th>
<th>{{__global.condition}}</th>
</tr>
</thead>
<tbody>
{{/exceptions.0}}
{{#exceptions}}
<tr>
<td>{{{type.specName.0.value}}}</td>
<td>{{{description}}}</td>
</tr>
{{/exceptions}}
{{#exceptions.0}}
</tbody>
</table>
{{/exceptions.0}}
{{/children}}
{{/children}}
@@ -0,0 +1,13 @@
{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
<span>Copyright © 2016 Umbraco<br>Generated by <strong>DocFX</strong></span>
</div>
</div>
</footer>
@@ -0,0 +1,18 @@
{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>{{#title}}{{title}}{{/title}}{{^title}}{{>partials/title}}{{/title}} {{#_appTitle}}| {{_appTitle}} {{/_appTitle}}</title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="{{#title}}{{title}}{{/title}}{{^title}}{{>partials/title}}{{/title}} {{#_appTitle}}| {{_appTitle}} {{/_appTitle}}">
<meta name="generator" content="docfx {{_docfxVersion}}">
{{#_description}}<meta name="description" content="{{_description}}">{{/_description}}
<link rel="icon" type="image/png" href="https://our.umbraco.org/assets/images/app-icons/favicon.png">
<link rel="stylesheet" href="{{_rel}}styles/docfx.vendor.css">
<link rel="stylesheet" href="{{_rel}}styles/docfx.css">
<link rel="stylesheet" href="{{_rel}}styles/main.css">
<meta property="docfx:navrel" content="{{_navRel}}">
<meta property="docfx:tocrel" content="{{_tocRel}}">
{{#_enableSearch}}<meta property="docfx:rel" content="{{_rel}}">{{/_enableSearch}}
</head>
@@ -0,0 +1,18 @@
{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}
{{^_disableContribution}}
{{#sourceurl}}
<a href="{{sourceurl}}" class="btn btn-primary pull-right mobile-hide">{{__global.viewSource}}</a>
{{/sourceurl}}
{{/_disableContribution}}
<h1 id="{{id}}" data-uid="{{uid}}">{{>partials/title}}</h1>
<div class="markdown level0 summary">{{{summary}}}</div>
<div class="markdown level0 conceptual">{{{conceptual}}}</div>
<div class="markdown level0 remarks">{{{remarks}}}</div>
{{#children}}
<h3 id="{{id}}">{{>partials/namespaceSubtitle}}</h3>
{{#children}}
<h4>{{{specName.0.value}}}</h4>
<section>{{{summary}}}</section>
{{/children}}
{{/children}}
@@ -0,0 +1,22 @@
{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}
<nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/" alt="Our Umbraco"></a>
</div>
<div class="collapse navbar-collapse" id="navbar">
<form class="navbar-form navbar-right" role="search" id="search">
<div class="form-group">
<input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
</div>
</form>
</div>
</div>
</nav>
@@ -0,0 +1,101 @@
{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}
{{^_disableContribution}}
{{#sourceurl}}<a href="{{sourceurl}}" class="btn btn-primary pull-right mobile-hide">View Source</a>{{/sourceurl}}
{{/_disableContribution}}
<h1 id="{{htmlId}}" data-uid="{{uid}}" class="text-capitalize">{{name}}</h1>
{{#summary}}
<div class="markdown level0 summary">{{{summary}}}</div>
{{/summary}}
{{#description}}
<div class="markdown level0 description">{{{description}}}</div>
{{/description}}
{{#conceptual}}
<div class="markdown level0 conceptual">{{{conceptual}}}</div>
{{/conceptual}}
{{#children}}
{{^_disableContribution}}
{{#sourceurl}}
<span class="small pull-right mobile-hide">
<a href="{{sourceurl}}">View Source</a>
</span>{{/sourceurl}}
{{/_disableContribution}}
<h3 id="{{htmlId}}" data-uid="{{uid}}" class="text-capitalize">{{operationId}}</h3>
{{#summary}}
<div class="markdown level1 summary">{{{summary}}}</div>
{{/summary}}
{{#description}}
<div class="markdown level1 description">{{{description}}}</div>
{{/description}}
{{#conceptual}}
<div class="markdown level1 conceptual">{{{conceptual}}}</div>
{{/conceptual}}
<h5>Request</h5>
<div class="codewrapper">
<pre><code class="lang-restApi hljs">{{operation}} {{path}}</code></pre>
</div>
{{#parameters.0}}
<h5>Parameters</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Value</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
{{/parameters.0}}
{{#parameters}}
<tr>
<td><em>{{#required}}*{{/required}}{{name}}</em></td>
<td>{{type}}</td>
<td>{{default}}</td>
<td>{{{description}}}</td>
</tr>
{{/parameters}}
{{#parameters.0}}
</tbody>
</table>
{{/parameters.0}}
{{#responses.0}}
<div class="responses">
<h5>Responses</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Status Code</th>
<th>Description</th>
<th>Samples</th>
</tr>
</thead>
<tbody>
{{/responses.0}}
{{#responses}}
<tr>
<td><span class="status">{{statusCode}}</span></td>
<td>{{{description}}}</td>
<td class="sample-response">
{{#examples}}
<div class="mime-type">
<i>Mime type: </i><span class="mime">{{mimeType}}</span>
</div>
<pre class="response-content"><code class="lang-js json hljs">{{content}}</code></pre>
{{/examples}}
</td>
</tr>
{{/responses}}
{{#responses.0}}
</tbody>
</table>
</div>
{{/responses.0}}
{{#footer}}
<div class="markdown level1 api-footer">{{{footer}}}</div>
{{/footer}}
{{/children}}
{{#footer}}
<div class="markdown level0 api-footer">{{{footer}}}</div>
{{/footer}}
+73
View File
@@ -0,0 +1,73 @@
body {
color: rgba(0,0,0,.8);
}
.navbar-inverse {
background: #a3db78;
}
.navbar-inverse .navbar-nav>li>a, .navbar-inverse .navbar-text {
color: rgba(0,0,0,.8);
}
.navbar-inverse {
border-color: transparent;
}
.sidetoc {
background-color: #f5fbf1;
}
body .toc {
background-color: #f5fbf1;
}
.sidefilter {
background-color: #daf0c9;
}
.subnav {
background-color: #f5fbf1;
}
.navbar-inverse .navbar-nav>.active>a {
color: rgba(0,0,0,.8);
background-color: #daf0c9;
}
.navbar-inverse .navbar-nav>.active>a:focus, .navbar-inverse .navbar-nav>.active>a:hover {
color: rgba(0,0,0,.8);
background-color: #daf0c9;
}
.btn-primary {
color: rgba(0,0,0,.8);
background-color: #fff;
border-color: rgba(0,0,0,.8);
}
.btn-primary:hover {
background-color: #daf0c9;
color: rgba(0,0,0,.8);
border-color: rgba(0,0,0,.8);
}
.toc .nav > li > a {
color: rgba(0,0,0,.8);
}
button, a {
color: #f36f21;
}
button:hover,
button:focus,
a:hover,
a:focus {
color: #143653;
text-decoration: none;
}
.navbar-header .navbar-brand {
background: url(https://our.umbraco.org/assets/images/logo.svg) left center no-repeat;
background-size: 40px auto;
width:50px;
}
.toc .nav > li.active > a {
color: #f36f21;
}
+51
View File
@@ -0,0 +1,51 @@
version: '{build}'
shallow_clone: true
build_script:
- cmd: >-
cd build
SET "release="
FOR /F "skip=1 delims=" %%i IN (UmbracoVersion.txt) DO IF NOT DEFINED release SET "release=%%i"
SET PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%PATH%
ECHO %PATH%
ECHO Building Release %release% build%APPVEYOR_BUILD_NUMBER%
SET nuGetFolder=%CD%\..\src\packages\
..\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
IF EXIST ..\src\umbraco.businesslogic\packages.config ..\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
SET MSBUILD="C:\Program Files (x86)\MSBuild\14.0\Bin\MsBuild.exe"
%MSBUILD% "../src/Umbraco.Tests/Umbraco.Tests.csproj" /verbosity:minimal
build.bat %release% build%APPVEYOR_BUILD_NUMBER%
ECHO %PATH%
test:
assemblies: src\Umbraco.Tests\bin\Debug\Umbraco.Tests.dll
artifacts:
- path: build\UmbracoCms.*
notifications:
- provider: Slack
auth_token:
secure: v2csJi2V5ghR0rPdODK8GJdOGNCA+XaK84iQ9MdPOClqB+VU+40ybdKp6gPirGSH
channel: '#build-umbraco-core'
on_build_success: false
on_build_failure: true
on_build_status_changed: false
-170
View File
@@ -1,170 +0,0 @@
/* File : TOC.css
// Author : Eric Woodruff (Eric@EWoodruff.us)
// Updated : 09/07/2007
//
// Stylesheet for the table of content
*/
*
{
margin: 0px 0px 0px 0px;
padding: 0px 0px 0px 0px;
}
body
{
font-family: Segoe UI, Arial, Verdana, Helvetica, sans-serif;
font-size: 0.9em;
background-color: white;
color: White;
overflow: hidden;
}
input
{
padding:5px;
margin: 3px 0px 3px 0px
}
img
{
border: 0;
margin-left: 5px;
margin-right: 2px;
}
img.TreeNodeImg
{
cursor: pointer;
}
img.TOCLink
{
cursor: pointer;
margin-left: 0;
margin-right: 0;
}
a.SelectedNode, a.UnselectedNode
{
color: #333;
text-decoration: none;
padding: 1px 3px 1px 3px;
white-space: nowrap;
}
a.SelectedNode
{
background-color: #ffffff;
border: solid 1px #999999;
padding: 0px 2px 0px 2px;
}
a.UnselectedNode:hover, a.SelectedNode:hover
{
background-color: #cccccc;
border: solid 1px #999999;
padding: 0px 2px 0px 2px;
}
.Visible
{
display: block;
margin-left: 2em;
}
.Hidden
{
display: none;
}
.Tree
{
background-color: #fff;
color: #333;
width: 300px;
overflow: auto;
}
.TreeNode, .TreeItem
{
white-space: nowrap;
margin: 2px 2px 2px 2px;
}
.TOCDiv
{
position: relative;
float: left;
width: 300px;
height: 100%;
}
.TOCSizer
{
clear: none;
float: left;
width: 10px;
height: 100%;
background-image: url("Splitter.gif");
background-position:center center;
background-repeat:no-repeat;
position: relative;
cursor: w-resize;
border-left: solid 1px #CCC;
}
.TopicContent
{
position: relative;
float: right;
background-color: white;
height: 100%;
}
.SearchOpts
{
padding: 5px 5px 10px 5px;
color: black;
width: 300px;
border-bottom: solid lightgrey 1px;
height: 110px !important;
}
.NavOpts
{
padding: 5px 5px 6px 5px;
color: black;
width: 300px;
border-bottom: solid lightgrey 1px;
}
.NavOpts img {
display:inline-block;
margin: 0px 5px 0px 5px;
}
.IndexOpts
{
padding: 5px 5px 6px 5px;
color: black;
width: 300px;
border-bottom: solid lightgrey 1px;
}
.IndexItem
{
white-space: nowrap;
margin: 2px 2px 2px 2px;
}
.IndexSubItem
{
white-space: nowrap;
margin: 2px 2px 2px 12px;
}
.PaddedText
{
margin: 10px 10px 10px 10px;
}
-172
View File
@@ -1,172 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<!-- The configuration and platform will be used to determine which
assemblies to include from solution and project documentation
sources -->
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{cb4d85f1-7390-40ee-b41f-a724bb8fddea}</ProjectGuid>
<SHFBSchemaVersion>1.9.5.0</SHFBSchemaVersion>
<!-- AssemblyName, Name, and RootNamespace are not used by SHFB but Visual
Studio adds them anyway -->
<AssemblyName>Documentation</AssemblyName>
<RootNamespace>Documentation</RootNamespace>
<Name>Documentation</Name>
<!-- SHFB properties -->
<FrameworkVersion>.NET Framework 4.5</FrameworkVersion>
<OutputPath>.\Output\</OutputPath>
<HtmlHelpName>UmbracoClassLibrary</HtmlHelpName>
<Language>en-US</Language>
<BuildAssemblerVerbosity>OnlyErrors</BuildAssemblerVerbosity>
<BuildLogFile>csharp-api-docs.log</BuildLogFile>
<HelpFileFormat>Website</HelpFileFormat>
<IndentHtml>True</IndentHtml>
<KeepLogFile>False</KeepLogFile>
<DisableCodeBlockComponent>False</DisableCodeBlockComponent>
<CppCommentsFixup>False</CppCommentsFixup>
<CleanIntermediates>True</CleanIntermediates>
<SyntaxFilters>CSharp</SyntaxFilters>
<SdkLinkTarget>Blank</SdkLinkTarget>
<RootNamespaceContainer>False</RootNamespaceContainer>
<PresentationStyle>VS2010</PresentationStyle>
<Preliminary>False</Preliminary>
<NamingMethod>Guid</NamingMethod>
<HelpTitle>Umbraco .Net Class Library</HelpTitle>
<ContentPlacement>AboveNamespaces</ContentPlacement>
<VisibleItems>Attributes, InheritedMembers, InheritedFrameworkMembers, Protected, SealedProtected</VisibleItems>
<ComponentConfigurations />
<DocumentationSources>
<DocumentationSource sourceFile="..\..\src\Umbraco.Core\Umbraco.Core.csproj" />
<DocumentationSource sourceFile="..\..\src\Umbraco.Core\bin\Release\Umbraco.Core.xml" />
<DocumentationSource sourceFile="..\..\src\Umbraco.Web\Umbraco.Web.csproj" />
<DocumentationSource sourceFile="..\..\src\Umbraco.Web\bin\Release\umbraco.xml" /></DocumentationSources>
<WebsiteSdkLinkType>None</WebsiteSdkLinkType>
<HtmlSdkLinkType>None</HtmlSdkLinkType>
<IncludeFavorites>False</IncludeFavorites>
<BinaryTOC>True</BinaryTOC>
<MissingTags>Summary, AutoDocumentCtors, AutoDocumentDispose</MissingTags>
<TransformComponentArguments>
<Argument Key="logoFile" Value="" />
<Argument Key="logoHeight" Value="" />
<Argument Key="logoWidth" Value="" />
<Argument Key="logoAltText" Value="" />
<Argument Key="logoPlacement" Value="left" />
<Argument Key="logoAlignment" Value="left" />
</TransformComponentArguments>
<ApiFilter>
<Filter entryType="Namespace" fullName="CookComputing.Blogger" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="CookComputing.MetaWeblog" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="dashboardUtilities" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="presentation.umbraco.webservices" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco" isExposed="False" xmlns="">
<Filter entryType="Class" fullName="umbraco.content" filterName="content" isExposed="True" />
<Filter entryType="Delegate" fullName="umbraco.content.ContentCacheDatabaseLoadXmlStringEventHandler" filterName="content.ContentCacheDatabaseLoadXmlStringEventHandler" isExposed="False" />
<Filter entryType="Delegate" fullName="umbraco.content.ContentCacheLoadNodeEventHandler" filterName="content.ContentCacheLoadNodeEventHandler" isExposed="False" />
<Filter entryType="Delegate" fullName="umbraco.content.DocumentCacheEventHandler" filterName="content.DocumentCacheEventHandler" isExposed="False" />
<Filter entryType="Delegate" fullName="umbraco.content.RefreshContentEventHandler" filterName="content.RefreshContentEventHandler" isExposed="False" />
<Filter entryType="Class" fullName="umbraco.ContentExtensions" filterName="ContentExtensions" isExposed="True" />
<Filter entryType="Class" fullName="umbraco.ContentTypeExtensions" filterName="ContentTypeExtensions" isExposed="True" />
<Filter entryType="Class" fullName="umbraco.item" filterName="item" isExposed="True" />
<Filter entryType="Class" fullName="umbraco.library" filterName="library" isExposed="True" />
<Filter entryType="Class" fullName="umbraco.macro" filterName="macro" isExposed="True" />
<Filter entryType="Class" fullName="umbraco.MacroCacheContent" filterName="MacroCacheContent" isExposed="True" />
<Filter entryType="Class" fullName="umbraco.MacroRenderingEventArgs" filterName="MacroRenderingEventArgs" isExposed="True" />
<Filter entryType="Class" fullName="umbraco.MediaExtensions" filterName="MediaExtensions" isExposed="True" />
<Filter entryType="Class" fullName="umbraco.MemberExtensions" filterName="MemberExtensions" isExposed="True" />
<Filter entryType="Class" fullName="umbraco.page" filterName="page" isExposed="True" />
<Filter entryType="Class" fullName="umbraco.PreValueExtensions" filterName="PreValueExtensions" isExposed="True" />
<Filter entryType="Class" fullName="umbraco.RelationTypeExtensions" filterName="RelationTypeExtensions" isExposed="True" />
<Filter entryType="Class" fullName="umbraco.template" filterName="template" isExposed="True" />
<Filter entryType="Class" fullName="umbraco.UmbracoObjectTypeExtensions" filterName="UmbracoObjectTypeExtensions" isExposed="True" />
<Filter entryType="Class" fullName="umbraco.uQuery" filterName="uQuery" isExposed="True" />
<Filter entryType="Interface" fullName="umbraco.uQuery.IGetProperty" filterName="uQuery.IGetProperty" isExposed="True" />
<Filter entryType="Class" fullName="umbraco.uQuery.Members" filterName="uQuery.Members" isExposed="True" />
<Filter entryType="Enumeration" fullName="umbraco.uQuery.UmbracoObjectType" filterName="uQuery.UmbracoObjectType" isExposed="True" />
</Filter>
<Filter entryType="Namespace" fullName="umbraco.cms.presentation" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.create.controls" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.developer" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.developer.RelationTypes" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.developer.RelationTypes.TreeMenu" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.members" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.settings" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.settings.modal" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.settings.scripts" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.settings.stylesheet" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.cms.presentation.user" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.controls" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.controls.GenericProperties" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.controls.Images" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.controls.Tree" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.developer" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.dialogs" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.js" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.layoutControls" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.NodeFactory" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.actions" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.channels" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.channels.businesslogic" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.create" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.developer.packages" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.dialogs" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.masterpages" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.members" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.nodeFactory" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.org.umbraco.update" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.plugins.tinymce3" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.preview" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.Search" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.settings" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.templateControls" isExposed="False" xmlns="">
<Filter entryType="Class" fullName="umbraco.presentation.templateControls.Item" filterName="Item" isExposed="True" />
<Filter entryType="Class" fullName="umbraco.presentation.templateControls.ItemRenderer" filterName="ItemRenderer" isExposed="True" />
<Filter entryType="Class" fullName="umbraco.presentation.templateControls.Macro" filterName="Macro" isExposed="True" />
<Filter entryType="Enumeration" fullName="umbraco.presentation.templateControls.Macro.RenderEvents" filterName="Macro.RenderEvents" isExposed="False" />
</Filter>
<Filter entryType="Namespace" fullName="umbraco.presentation.tinymce3" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.translation" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.channels" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.controls" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.create" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.developer.Xslt" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.dialogs" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.masterpages" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.members" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.plugins.tinymce3" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.Search" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.translation" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco.webservices" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.umbraco_client.tinymce3.plugins.spellchecker" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.urlRewriter" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.Web.UI" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.presentation.webservices" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.scripting" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.settings" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="Umbraco.Web.org.umbraco.our" isExposed="False" xmlns="" />
<Filter entryType="Namespace" fullName="umbraco.webservices" isExposed="False" xmlns="" /></ApiFilter>
</PropertyGroup>
<!-- There are no properties for these groups. AnyCPU needs to appear in
order for Visual Studio to perform the build. The others are optional
common platform types that may appear. -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|Win32' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|Win32' ">
</PropertyGroup>
<!-- Import the SHFB build targets -->
<Import Project="$(SHFBROOT)\SandcastleHelpFileBuilder.targets" />
</Project>
+20
View File
@@ -0,0 +1,20 @@
@ECHO OFF
SETLOCAL
SET release=%1
ECHO Installing Npm NuGet Package
SET nuGetFolder=%CD%\..\src\packages\
ECHO Configured packages folder: %nuGetFolder%
ECHO Current folder: %CD%
%CD%\..\src\.nuget\NuGet.exe install Npm.js -OutputDirectory %nuGetFolder% -Verbosity quiet
for /f "delims=" %%A in ('dir %nuGetFolder%node.js.* /b') do set "nodePath=%nuGetFolder%%%A\"
for /f "delims=" %%A in ('dir %nuGetFolder%npm.js.* /b') do set "npmPath=%nuGetFolder%%%A\tools\"
ECHO Adding Npm and Node to path
REM SETLOCAL is on, so changes to the path not persist to the actual user's path
PATH=%npmPath%;%nodePath%;%PATH%
Powershell.exe -ExecutionPolicy Unrestricted -File .\BuildDocs.ps1
+91 -18
View File
@@ -1,27 +1,100 @@
##We cannot continue if sandcastle is not installed determined by env variable: SHFBROOT
$PSScriptFilePath = (Get-Item $MyInvocation.MyCommand.Path);
$RepoRoot = (get-item $PSScriptFilePath).Directory.Parent.FullName;
$SolutionRoot = Join-Path -Path $RepoRoot "src";
$ToolsRoot = Join-Path -Path $RepoRoot "tools";
$DocFx = Join-Path -Path $ToolsRoot "docfx\docfx.exe"
$DocFxFolder = (Join-Path -Path $ToolsRoot "docfx")
$DocFxJson = Join-Path -Path $RepoRoot "apidocs\docfx.json"
$7Zip = Join-Path -Path $ToolsRoot "7zip\7za.exe"
$DocFxSiteOutput = Join-Path -Path $RepoRoot "apidocs\_site\*.*"
$NgDocsSiteOutput = Join-Path -Path $RepoRoot "src\Umbraco.Web.UI.Client\docs\api\*.*"
$ProgFiles86 = [Environment]::GetEnvironmentVariable("ProgramFiles(x86)");
$MSBuild = "$ProgFiles86\MSBuild\14.0\Bin\MSBuild.exe"
if (-not (Test-Path Env:\SHFBROOT))
{
throw "The docs cannot be build, install Sandcastle help file builder"
################ Do the UI docs
"Changing to Umbraco.Web.UI.Client folder"
cd ..
cd src\Umbraco.Web.UI.Client
Write-Host $(Get-Location)
"Creating build folder so MSBuild doesn't run the whole grunt build"
if (-Not (Test-Path "build")) {
md "build"
}
$PSScriptFilePath = (Get-Item $MyInvocation.MyCommand.Path).FullName
$BuildRoot = Split-Path -Path $PSScriptFilePath -Parent
$OutputPath = Join-Path -Path $BuildRoot -ChildPath "ApiDocs\Output"
$ProjFile = Join-Path -Path $BuildRoot -ChildPath "ApiDocs\csharp-api-docs.shfbproj"
"Installing node"
# Check if Install-Product exists, should only exist on the build server
if (Get-Command Install-Product -errorAction SilentlyContinue)
{
Install-Product node ''
}
"Building docs with project file: $ProjFile"
"Installing node modules"
& npm install
$MSBuild = "$Env:SYSTEMROOT\Microsoft.NET\Framework\v4.0.30319\msbuild.exe"
"Installing grunt"
& npm install -g grunt-cli
# build it!
& $MSBuild "$ProjFile"
"Moving back to build folder"
cd ..
cd ..
cd build
Write-Host $(Get-Location)
# remove files left over
Remove-Item $BuildRoot\* -include csharp-api-docs.shfbproj_*
& grunt --gruntfile ../src/umbraco.web.ui.client/gruntfile.js docs
# copy our custom styles in
Copy-Item $BuildRoot\ApiDocs\TOC.css $OutputPath\TOC.css
# change baseUrl
$BaseUrl = "https://our.umbraco.org/apidocs/ui/"
$IndexPath = "../src/umbraco.web.ui.client/docs/api/index.html"
(Get-Content $IndexPath).replace('location.href.replace(rUrl, indexFile)', "`'" + $BaseUrl + "`'") | Set-Content $IndexPath
# zip it
""
"Done!"
& $7Zip a -tzip ui-docs.zip $NgDocsSiteOutput -r
################ Do the c# docs
# Build the solution in debug mode
$SolutionPath = Join-Path -Path $SolutionRoot -ChildPath "umbraco.sln"
& $MSBuild "$SolutionPath" /p:Configuration=Debug /maxcpucount /t:Clean
if (-not $?)
{
throw "The MSBuild process returned an error code."
}
& $MSBuild "$SolutionPath" /p:Configuration=Debug /maxcpucount
if (-not $?)
{
throw "The MSBuild process returned an error code."
}
# Go get docfx if we don't hae it
$FileExists = Test-Path $DocFx
If ($FileExists -eq $False) {
If(!(Test-Path $DocFxFolder))
{
New-Item $DocFxFolder -type directory
}
$DocFxZip = Join-Path -Path $ToolsRoot "docfx\docfx.zip"
$DocFxSource = "https://github.com/dotnet/docfx/releases/download/v1.9.4/docfx.zip"
Invoke-WebRequest $DocFxSource -OutFile $DocFxZip
#unzip it
& $7Zip e $DocFxZip "-o$DocFxFolder"
}
#clear site
If(Test-Path(Join-Path -Path $RepoRoot "apidocs\_site"))
{
Remove-Item $DocFxSiteOutput -recurse
}
# run it!
& $DocFx metadata $DocFxJson
& $DocFx build $DocFxJson
# zip it
& $7Zip a -tzip csharp-docs.zip $DocFxSiteOutput -r
+21 -1
View File
@@ -77,8 +77,28 @@ if ($project) {
{
$packageWebConfigSource = Join-Path $installPath "UmbracoFiles\Web.config"
Copy-Item $packageWebConfigSource $destinationWebConfig -Force
}
# Copy files that don't get automatically copied for Website projects
# We do this here, when copyWebconfig is true because we only want to do it for new installs
# If this is an upgrade then the files should already be there
$splashesSource = Join-Path $installPath "UmbracoFiles\Config\splashes\*.*"
$splashesDestination = Join-Path $projectPath "Config\splashes\"
New-Item $splashesDestination -Type directory
Copy-Item $splashesSource $splashesDestination -Force
$sqlCe64Source = Join-Path $installPath "UmbracoFiles\bin\amd64\*"
$sqlCe64Destination = Join-Path $projectPath "bin\amd64\"
Copy-Item $sqlCe64Source $sqlCe64Destination -Force
$sqlCex86Source = Join-Path $installPath "UmbracoFiles\bin\x86\*"
$sqlCex86Destination = Join-Path $projectPath "bin\x86\"
Copy-Item $sqlCex86source $sqlCex86Destination -Force
$umbracoUIXMLSource = Join-Path $installPath "UmbracoFiles\Umbraco\Config\Create\UI.xml"
$umbracoUIXMLDestination = Join-Path $projectPath "Umbraco\Config\Create\UI.xml"
Copy-Item $umbracoUIXMLSource $umbracoUIXMLDestination -Force
}
$installFolder = Join-Path $projectPath "Install"
if(Test-Path $installFolder) {
Remove-Item $installFolder -Force -Recurse -Confirm:$false
+1 -1
View File
@@ -1,2 +1,2 @@
# Usage: on line 2 put the release version, on line 3 put the version comment (example: beta)
7.4.3
7.5.0
+2 -2
View File
@@ -11,5 +11,5 @@ using System.Resources;
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("7.4.3")]
[assembly: AssemblyInformationalVersion("7.4.3")]
[assembly: AssemblyFileVersion("7.5.0")]
[assembly: AssemblyInformationalVersion("7.5.0")]
+22 -8
View File
@@ -1,18 +1,22 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.ObjectResolution;
using Umbraco.Core.Packaging;
using Umbraco.Core.Persistence.Migrations;
using Umbraco.Core.Profiling;
using Umbraco.Core.Services;
using Umbraco.Core.Sync;
namespace Umbraco.Core
{
/// <summary>
/// <summary>
/// the Umbraco Application context
/// </summary>
/// <remarks>
@@ -183,6 +187,7 @@ namespace Umbraco.Core
readonly ManualResetEventSlim _isReadyEvent = new ManualResetEventSlim(false);
private DatabaseContext _databaseContext;
private ServiceContext _services;
private PackageMigrationsContext _packageMigrationsContext;
public bool IsReady
{
@@ -212,17 +217,19 @@ namespace Umbraco.Core
public bool IsConfigured
{
get { return _configured.Value; }
get { return _umbracoVersionConfigured.Value; }
}
/// <summary>
/// If the db is configured, there is a database context and there is an umbraco schema, but we are not 'configured' , then it means we are upgrading
/// If the db is configured, there is a database context and there is an umbraco schema,
/// but we are: (not 'configured' OR there's pending migrations), then it means we are upgrading
/// </summary>
public bool IsUpgrading
{
get
{
if (IsConfigured == false
if ((IsConfigured == false || PackageMigrationsContext.HasPendingPackageMigrations)
&& DatabaseContext != null
&& DatabaseContext.IsDatabaseConfigured)
{
@@ -268,7 +275,8 @@ namespace Umbraco.Core
// ReSharper disable once InconsistentNaming
internal string _umbracoApplicationUrl;
private Lazy<bool> _configured;
private Lazy<bool> _umbracoVersionConfigured;
internal MainDom MainDom { get; private set; }
private void Init()
@@ -277,7 +285,7 @@ namespace Umbraco.Core
MainDom.Acquire();
//Create the lazy value to resolve whether or not the application is 'configured'
_configured = new Lazy<bool>(() =>
_umbracoVersionConfigured = new Lazy<bool>(() =>
{
try
{
@@ -318,9 +326,10 @@ namespace Umbraco.Core
LogHelper.Error<ApplicationContext>("Error determining if application is configured, returning false", ex);
return false;
}
});
});
}
_packageMigrationsContext = new PackageMigrationsContext(DatabaseContext, Services.MigrationEntryService, ProfilingLogger.Logger);
}
private string ConfigurationStatus
{
@@ -343,6 +352,11 @@ namespace Umbraco.Core
throw new Exception("ApplicationContext has already been initialized.");
}
internal PackageMigrationsContext PackageMigrationsContext
{
get { return _packageMigrationsContext; }
}
/// <summary>
/// Gets the current DatabaseContext
/// </summary>
+2 -2
View File
@@ -4,7 +4,7 @@ using System.Collections.Generic;
namespace Umbraco.Core.Cache
{
/// <summary>
/// An abstract class for implementing a basic cache provider
/// An interface for implementing a basic cache provider
/// </summary>
public interface ICacheProvider
{
@@ -65,4 +65,4 @@ namespace Umbraco.Core.Cache
object GetCacheItem(string cacheKey, Func<object> getCacheItem);
}
}
}
@@ -6,6 +6,8 @@
bool HideDisabledUsersInBackoffice { get; }
bool AllowPasswordReset { get; }
string AuthCookieName { get; }
string AuthCookieDomain { get; }
@@ -28,6 +28,18 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
}
}
[ConfigurationProperty("allowPasswordReset")]
internal InnerTextConfigurationElement<bool> AllowPasswordReset
{
get
{
return new OptionalInnerTextConfigurationElement<bool>(
(InnerTextConfigurationElement<bool>)this["allowPasswordReset"],
//set the default
true);
}
}
[ConfigurationProperty("authCookieName")]
internal InnerTextConfigurationElement<string> AuthCookieName
{
@@ -62,6 +74,11 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
get { return HideDisabledUsersInBackoffice; }
}
bool ISecuritySection.AllowPasswordReset
{
get { return AllowPasswordReset; }
}
string ISecuritySection.AuthCookieName
{
get { return AuthCookieName; }
@@ -6,7 +6,7 @@ namespace Umbraco.Core.Configuration
{
public class UmbracoVersion
{
private static readonly Version Version = new Version("7.4.3");
private static readonly Version Version = new Version("7.5.0");
/// <summary>
/// Gets the current version of Umbraco.
@@ -32,12 +32,7 @@ namespace Umbraco.Core.Configuration
public static SemVersion GetSemanticVersion()
{
return new SemVersion(
Current.Major,
Current.Minor,
Current.Build,
CurrentComment.IsNullOrWhiteSpace() ? null : CurrentComment,
Current.Revision > 0 ? Current.Revision.ToInvariantString() : null);
return Current.GetSemanticVersion();
}
}
}
+4 -1
View File
@@ -143,7 +143,10 @@ namespace Umbraco.Core
/// </summary>
public const string LockObject = "87A9F1FF-B1E4-4A25-BABB-465A4A47EC41";
/// <summary>
/// Guid for a Lock object.
/// </summary>
public static readonly Guid LockObjectGuid = new Guid(LockObject);
}
}
}
+13 -4
View File
@@ -11,7 +11,7 @@ namespace Umbraco.Core
{
/// <summary>
/// Used to prefix generic properties that are internal content properties
/// </summary>
/// </summary>
public const string InternalGenericPropertiesPrefix = "_umb_";
/// <summary>
@@ -74,7 +74,7 @@ namespace Umbraco.Core
/// </summary>
[Obsolete("GUIDs are no longer used to reference Property Editors, use the Alias constant instead. This will be removed in future versions")]
public const string DictionaryPicker = "17B70066-F764-407D-AB05-3717F1E1C513";
/// <summary>
/// Guid for the Dropdown list datatype.
/// </summary>
@@ -352,7 +352,7 @@ namespace Umbraco.Core
/// </summary>
[Obsolete("GUIDs are no longer used to reference Property Editors, use the Alias constant instead. This will be removed in future versions")]
public const string UltimatePicker = "CDBF0B5D-5CB2-445F-BC12-FCAAEC07CF2C";
/// <summary>
/// Guid for the UltraSimpleEditor datatype.
/// </summary>
@@ -369,7 +369,7 @@ namespace Umbraco.Core
/// </summary>
[Obsolete("GUIDs are no longer used to reference Property Editors, use the Alias constant instead. This will be removed in future versions")]
public const string UmbracoUserControlWrapper = "D15E1281-E456-4B24-AA86-1DDA3E4299D5";
/// <summary>
/// Guid for the Upload field datatype.
/// </summary>
@@ -419,6 +419,15 @@ namespace Umbraco.Core
/// Alias for the email address property editor
/// </summary>
public const string EmailAddressAlias = "Umbraco.EmailAddress";
public static class PreValueKeys
{
/// <summary>
/// Pre-value name used to indicate a field that can be used to override the database field to which data for the associated
/// property is saved
/// </summary>
public const string DataValueType = "umbracoDataValueType";
}
}
}
}
+6 -1
View File
@@ -500,7 +500,12 @@ namespace Umbraco.Core
//the database migration objects
MigrationResolver.Current = new MigrationResolver(
ProfilingLogger.Logger,
() => PluginManager.ResolveTypes<IMigration>());
() => PluginManager.ResolveTypes<IMigration>())
{
//This needs to be resolved before it's frozen because we need to find migrations to determine
// if Umbraco IsConfigured
CanResolveBeforeFrozen = true
};
// todo: remove once we drop IPropertyEditorValueConverter support.
PropertyEditorValueConvertersResolver.Current = new PropertyEditorValueConvertersResolver(
+2
View File
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
@@ -155,6 +156,7 @@ namespace Umbraco.Core.Models
/// Language of the data contained within this Content object.
/// </summary>
[Obsolete("This is not used and will be removed from the codebase in future versions")]
[EditorBrowsable(EditorBrowsableState.Never)]
public string Language
{
get { return _language; }
@@ -6,10 +6,6 @@ namespace Umbraco.Core.Models
/// <summary>
/// Enum of the various DbTypes for which the Property values are stored
/// </summary>
/// <remarks>
/// Object is added to support complex values from PropertyEditors,
/// but will be saved under the Ntext column.
/// </remarks>
[Serializable]
[DataContract]
public enum DataTypeDatabaseType
+2
View File
@@ -1,4 +1,5 @@
using System;
using System.ComponentModel;
using System.Diagnostics;
using Umbraco.Core.Persistence.Mappers;
@@ -21,6 +22,7 @@ namespace Umbraco.Core.Models
bool Published { get; }
[Obsolete("This will be removed in future versions")]
[EditorBrowsable(EditorBrowsableState.Never)]
string Language { get; set; }
/// <summary>
+1 -2
View File
@@ -1,5 +1,4 @@
using System;
using Semver;
using Semver;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Models
+48 -4
View File
@@ -124,10 +124,54 @@ namespace Umbraco.Core.Models
bool typeValidation = _propertyType.IsPropertyTypeValid(value);
if (typeValidation == false)
throw new Exception(
string.Format(
"Type validation failed. The value type: '{0}' does not match the DataType in PropertyType with alias: '{1}'",
value == null ? "null" : value.GetType().Name, Alias));
{
// Normally we'll throw an exception here. However if the property is of a type that can have it's data field (dataInt, dataVarchar etc.)
// changed, we might have a value of the now "wrong" type. As of May 2016 Label is the only built-in property editor that supports this.
// In that case we should try to parse the value and return null if that's not possible rather than throwing an exception.
if (value != null && _propertyType.CanHaveDataValueTypeChanged())
{
var stringValue = value.ToString();
switch (_propertyType.DataTypeDatabaseType)
{
case DataTypeDatabaseType.Nvarchar:
case DataTypeDatabaseType.Ntext:
value = stringValue;
break;
case DataTypeDatabaseType.Integer:
int integerValue;
if (int.TryParse(stringValue, out integerValue) == false)
{
// Edge case, but if changed from decimal --> integer, the above tryparse will fail. So we'll try going
// via decimal too to return the integer value rather than zero.
decimal decimalForIntegerValue;
if (decimal.TryParse(stringValue, out decimalForIntegerValue))
{
integerValue = (int)decimalForIntegerValue;
}
}
value = integerValue;
break;
case DataTypeDatabaseType.Decimal:
decimal decimalValue;
decimal.TryParse(stringValue, out decimalValue);
value = decimalValue;
break;
case DataTypeDatabaseType.Date:
DateTime dateValue;
DateTime.TryParse(stringValue, out dateValue);
value = dateValue;
break;
}
}
else
{
throw new Exception(
string.Format(
"Type validation failed. The value type: '{0}' does not match the DataType in PropertyType with alias: '{1}'",
value == null ? "null" : value.GetType().Name, Alias));
}
}
SetPropertyValueAndDetectChanges(o =>
{
+14
View File
@@ -1,5 +1,6 @@
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
@@ -425,6 +426,19 @@ namespace Umbraco.Core.Models
return false;
}
/// <summary>
/// Checks the underlying property editor prevalues to see if the one that allows changing of the database field
/// to which data is saved (dataInt, dataVarchar etc.) is included. If so that means the field could be changed when the data
/// type is saved.
/// </summary>
/// <returns></returns>
internal bool CanHaveDataValueTypeChanged()
{
var propertyEditor = PropertyEditorResolver.Current.GetByAlias(_propertyEditorAlias);
return propertyEditor.PreValueEditor.Fields
.SingleOrDefault(x => x.Key == Constants.PropertyEditors.PreValueKeys.DataValueType) != null;
}
/// <summary>
/// Validates the Value from a Property according to the validation settings
/// </summary>
@@ -1,4 +1,5 @@
using Umbraco.Core.Persistence;
using System;
using Umbraco.Core.Persistence;
namespace Umbraco.Core.Models.Rdbms
{
@@ -18,5 +19,8 @@ namespace Umbraco.Core.Models.Rdbms
[Column("contenttypeNodeId")]
public int ContentTypeNodeId { get; set; }
[Column("PropertyGroupUniqueID")]
public Guid UniqueId { get; set; }
}
}
@@ -51,5 +51,8 @@ namespace Umbraco.Core.Models.Rdbms
[Column("dbType")]
public string DbType { get; set; }
[Column("UniqueID")]
public Guid UniqueId { get; set; }
}
}
@@ -0,0 +1,114 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Semver;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.Migrations;
using Umbraco.Core.Services;
namespace Umbraco.Core.Packaging
{
internal class PackageMigrationsContext
{
private readonly DatabaseContext _dbContext;
private readonly IMigrationEntryService _migrationEntryService;
private readonly ILogger _logger;
public PackageMigrationsContext(DatabaseContext dbContext,
IMigrationEntryService migrationEntryService,
ILogger logger)
{
_dbContext = dbContext;
_migrationEntryService = migrationEntryService;
_logger = logger;
ResetPendingPackageMigrations();
}
//List of product names and their maximum sem version registered in migrations
private Lazy<ReadOnlyDictionary<string, SemVersion>> _packageVersionsConfigured;
/// <summary>
/// Called to initialize or when package migrations have executed - since an app restart is mandatory
/// </summary>
internal void ResetPendingPackageMigrations()
{
_packageVersionsConfigured = new Lazy<ReadOnlyDictionary<string, SemVersion>>(() =>
{
var result = new Dictionary<string, SemVersion>();
//The versions are the same in config, but are they the same in the database. We can only check this
// if we have a db context available, if we don't then we are not installed anyways
if (_dbContext.IsDatabaseConfigured && _dbContext.CanConnect)
{
//Now we can check if there are any package migrations that haven't been executed.
//Find and group the packages that have migrations.
//Then we need to determine if there are outstanding migrations that need to be run based on the
// migration versions stored in the db compared to the available migrations.
var packageMigrations = MigrationResolver.Current.MigrationMetaData
.Where(x => x.ProductName != GlobalSettings.UmbracoMigrationName)
.GroupBy(x => x.ProductName)
.ToArray();
var packageMigrationProductNames = packageMigrations.Select(x => x.Key).Distinct().ToArray();
var allPackageDbEntries = _migrationEntryService.FindEntries(packageMigrationProductNames)
.ToArray();
foreach (var packageMigration in packageMigrations)
{
var packageDbVersions = allPackageDbEntries
.Where(x => x.MigrationName.InvariantEquals(packageMigration.Key))
.Select(x => x.Version);
var notExecuted = packageMigration
.Select(x => x.TargetVersion.GetSemanticVersion())
.Except(packageDbVersions)
.ToArray();
if (notExecuted.Any())
{
var maxVersion = notExecuted.Max();
result.Add(packageMigration.Key, maxVersion);
_logger.Debug<ApplicationContext>(
string.Format("The migration {0} for version: '{1} has not been executed, there is no record in the database",
packageMigration.Key,
maxVersion.ToSemanticString()));
}
}
}
return new ReadOnlyDictionary<string, SemVersion>(result);
});
}
/// <summary>
/// Returns true if there are pending package migrations that need to be executed
/// </summary>
internal bool HasPendingPackageMigrations
{
get { return _packageVersionsConfigured.Value.Any(); }
}
/// <summary>
/// Returns the list of package migration names that need to be executed
/// </summary>
internal ReadOnlyDictionary<string, SemVersion> GetPendingPackageMigrations()
{
return _packageVersionsConfigured.Value;
}
/// <summary>
/// Returns the list of package migration names and versions that need to be executed
/// with the following format: PackageProductName (2.0.0)
/// </summary>
/// <returns></returns>
internal IEnumerable<string> GetPendingPackageMigrationFriendlyNames()
{
return _packageVersionsConfigured.Value.Select(x => string.Format("{0} ({1})", x.Key, x.Value));
}
}
}
@@ -75,6 +75,7 @@ namespace Umbraco.Core.Persistence.Factories
group.Id = groupDto.Id.Value;
}
group.Key = groupDto.UniqueId;
group.Name = groupDto.Text;
group.SortOrder = groupDto.SortOrder;
group.PropertyTypes = new PropertyTypeCollection();
@@ -114,7 +115,8 @@ namespace Umbraco.Core.Persistence.Factories
ValidationRegExp = typeDto.ValidationRegExp,
PropertyGroupId = new Lazy<int>(() => tempGroupDto.Id.Value),
CreateDate = memberType.CreateDate,
UpdateDate = memberType.UpdateDate
UpdateDate = memberType.UpdateDate,
Key = typeDto.UniqueId
};
//on initial construction we don't want to have dirty properties tracked
// http://issues.umbraco.org/issue/U4-1946
@@ -166,7 +168,8 @@ namespace Umbraco.Core.Persistence.Factories
ValidationRegExp = typeDto.ValidationRegExp,
PropertyGroupId = null,
CreateDate = dto.CreateDate,
UpdateDate = dto.CreateDate
UpdateDate = dto.CreateDate,
Key = typeDto.UniqueId
};
propertyTypes.Add(propertyType);
@@ -134,13 +134,16 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1043, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1043", SortOrder = 2, UniqueId = new Guid("1df9f033-e6d4-451f-b8d2-e0cbc50a836f"), Text = "Image Cropper", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1044, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1044", SortOrder = 0, UniqueId = new Guid("d59be02f-1df9-4228-aa1e-01917d806cda"), Text = Constants.Conventions.MemberTypes.DefaultAlias, NodeObjectType = new Guid(Constants.ObjectTypes.MemberType), CreateDate = DateTime.Now });
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1045, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1045", SortOrder = 2, UniqueId = new Guid("7E3962CC-CE20-4FFC-B661-5897A894BA7E"), Text = "Multiple Media Picker", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
//TODO: We're not creating these for 7.0
//_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1039, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1039", SortOrder = 2, UniqueId = new Guid("06f349a9-c949-4b6a-8660-59c10451af42"), Text = "Ultimate Picker", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
//_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1038, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1038", SortOrder = 2, UniqueId = new Guid("1251c96c-185c-4e9b-93f4-b48205573cbd"), Text = "Simple Editor", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
//_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1042, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1042", SortOrder = 2, UniqueId = new Guid("0a452bd5-83f9-4bc3-8403-1286e13fb77e"), Text = "Macro Container", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
// all lock objects
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = Constants.System.ServersLock, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1," + Constants.System.ServersLock, SortOrder = 1, UniqueId = new Guid("0AF5E610-A310-4B6F-925F-E928D5416AF7"), Text = "LOCK: Servers", NodeObjectType = Constants.ObjectTypes.LockObjectGuid, CreateDate = DateTime.Now });
}
private void CreateCmsContentTypeData()
@@ -237,8 +240,8 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 14, DataTypeId = -42, PropertyEditorAlias = Constants.PropertyEditors.DropDownListAlias, DbType = "Integer" });
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 15, DataTypeId = -43, PropertyEditorAlias = Constants.PropertyEditors.CheckBoxListAlias, DbType = "Nvarchar" });
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 16, DataTypeId = 1034, PropertyEditorAlias = Constants.PropertyEditors.ContentPickerAlias, DbType = "Integer" });
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 17, DataTypeId = 1035, PropertyEditorAlias = Constants.PropertyEditors.MediaPickerAlias, DbType = "Integer" });
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 18, DataTypeId = 1036, PropertyEditorAlias = Constants.PropertyEditors.MemberPickerAlias, DbType = "Integer" });
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 17, DataTypeId = 1035, PropertyEditorAlias = Constants.PropertyEditors.MultipleMediaPickerAlias, DbType = "Nvarchar" });
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 21, DataTypeId = 1040, PropertyEditorAlias = Constants.PropertyEditors.RelatedLinksAlias, DbType = "Ntext" });
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 22, DataTypeId = 1041, PropertyEditorAlias = Constants.PropertyEditors.TagsAlias, DbType = "Ntext" });
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 24, DataTypeId = 1043, PropertyEditorAlias = Constants.PropertyEditors.ImageCropperAlias, DbType = "Ntext" });
@@ -33,6 +33,11 @@ namespace Umbraco.Core.Persistence.Migrations
get { return Values; }
}
public IEnumerable<MigrationAttribute> MigrationMetaData
{
get { return Values.SelectMany(x => x.GetType().GetCustomAttributes<MigrationAttribute>(false)).WhereNotNull(); }
}
/// <summary>
/// This will ctor the IMigration instances
@@ -94,7 +94,6 @@ namespace Umbraco.Core.Persistence.Migrations
var migrations = isUpgrade
? OrderedUpgradeMigrations(foundMigrations).ToList()
: OrderedDowngradeMigrations(foundMigrations).ToList();
if (Migrating.IsRaisedEventCancelled(new MigrationEventArgs(migrations, _currentVersion, _targetVersion, _productName, true), this))
{
@@ -298,7 +297,6 @@ namespace Umbraco.Core.Persistence.Migrations
{
_migrationEntryService.CreateEntry(_productName, _targetVersion);
}
}
}
@@ -0,0 +1,32 @@
using System.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionFourOneZero
{
[Migration("4.1.0", 0, GlobalSettings.UmbracoMigrationName)]
public class AddPreviewXmlTable : MigrationBase
{
public AddPreviewXmlTable(ISqlSyntaxProvider sqlSyntax, ILogger logger)
: base(sqlSyntax, logger)
{
}
public override void Up()
{
var tableName = "cmsPreviewXml";
var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
if (tables.InvariantContains(tableName)) return;
Create.Table(tableName)
.WithColumn("nodeId").AsInt32().NotNullable()
.WithColumn("versionId").AsGuid().NotNullable()
.WithColumn("timestamp").AsDateTime().NotNullable()
.WithColumn("xml").AsString();
}
public override void Down()
{ }
}
}
@@ -32,17 +32,19 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven
{
if (database != null)
{
var dtSql = new Sql().Select("nodeId").From<DataTypeDto>().Where<DataTypeDto>(dto => dto.PropertyEditorAlias == Constants.PropertyEditors.RelatedLinksAlias);
var dtSql = new Sql().Select("nodeId")
.From<DataTypeDto>(SqlSyntax)
.Where<DataTypeDto>(dto => dto.PropertyEditorAlias == Constants.PropertyEditors.RelatedLinksAlias);
var dataTypeIds = database.Fetch<int>(dtSql);
if (dataTypeIds.Any() == false) return string.Empty;
if (!dataTypeIds.Any()) return string.Empty;
// need to use dynamic, as PropertyDataDto has new properties
// need to use dynamic, as PropertyDataDto has new properties (eg decimal...) in further versions that don't exist yet
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;
+ " WHERE propertyTypeId in (SELECT id from cmsPropertyType where dataTypeID IN (@dataTypeIds))", new { /*dataTypeIds =*/ dataTypeIds });
if (propertyData.Any() == false) return string.Empty;
var nodesIdsWithProperty = propertyData.Select(x => x.NodeId).Distinct().ToArray();
var nodesIdsWithProperty = propertyData.Select(x => (int) x.contentNodeId).Distinct().ToArray();
var cmsContentXmlEntries = new List<ContentXmlDto>();
//We're doing an "IN" query here but SQL server only supports 2100 query parameters so we're going to split on that
@@ -54,32 +56,32 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven
cmsContentXmlEntries.AddRange(database.Fetch<ContentXmlDto>("WHERE nodeId in (@nodeIds)", new { nodeIds = batch }));
}
var propertyTypeIds = propertyData.Select(x => x.PropertyTypeId).Distinct();
var propertyTypeIds = propertyData.Select(x => (int) x.propertytypeid).Distinct();
//NOTE: We are writing the full query because we've added a column to the PropertyTypeDto in later versions so one of the columns
// won't exist yet
var propertyTypes = database.Fetch<PropertyTypeDto>("SELECT * FROM cmsPropertyType WHERE id in (@propertyTypeIds)", new { propertyTypeIds = propertyTypeIds });
foreach (var data in propertyData)
{
if (string.IsNullOrEmpty(data.Text) == false)
if (string.IsNullOrEmpty(data.dataNtext) == false)
{
XmlDocument xml;
//fetch the current data (that's in xml format)
try
{
xml = new XmlDocument();
xml.LoadXml(data.Text);
xml.LoadXml(data.dataNtext);
}
catch (Exception 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 +
int dataNodeId = data.contentNodeId;
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.dataNText = "";
data.dataNtext = "";
database.Update("cmsPropertyData", "id", data, new[] { "dataNText" });
UpdateXmlTable(propertyTypes, data, cmsContentXmlEntries, database);
@@ -113,7 +115,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven
}
//store the serialized data
data.dataNText = JsonConvert.SerializeObject(links);
data.dataNtext = JsonConvert.SerializeObject(links);
database.Update("cmsPropertyData", "id", data, new[] { "dataNText" });
@@ -130,20 +132,20 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven
throw new DataLossException("Cannot downgrade from a version 7 database to a prior version, the database schema has already been modified");
}
private static void UpdateXmlTable(List<PropertyTypeDto> propertyTypes, PropertyDataDto data, List<ContentXmlDto> cmsContentXmlEntries, Database database)
private static void UpdateXmlTable(List<PropertyTypeDto> propertyTypes, dynamic data, List<ContentXmlDto> cmsContentXmlEntries, Database database)
{
//now we need to update the cmsContentXml table
var propertyType = propertyTypes.SingleOrDefault(x => x.Id == data.PropertyTypeId);
var propertyType = propertyTypes.SingleOrDefault(x => x.Id == data.propertytypeid);
if (propertyType != null)
{
var xmlItem = cmsContentXmlEntries.SingleOrDefault(x => x.NodeId == data.NodeId);
var xmlItem = cmsContentXmlEntries.SingleOrDefault(x => x.NodeId == data.contentNodeId);
if (xmlItem != null)
{
var x = XElement.Parse(xmlItem.Xml);
var prop = x.Element(propertyType.Alias);
if (prop != null)
{
prop.ReplaceAll(new XCData(data.Text));
prop.ReplaceAll(new XCData(data.dataNtext));
database.Update(xmlItem);
}
}
@@ -0,0 +1,57 @@
using System;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFiveZero
{
// This migration exists for 7.3.0 but it seems like it was not always running properly
// if you're upgrading from 7.3.0 or higher than we add this migration, if you're upgrading
// from 7.3.0 or lower then you will already get this migration in the migration to get to 7.3.0
[Migration("7.3.0", "7.5.0", 10, GlobalSettings.UmbracoMigrationName)]
public class EnsureServersLockObject : MigrationBase
{
public EnsureServersLockObject(ISqlSyntaxProvider sqlSyntax, ILogger logger)
: base(sqlSyntax, logger)
{ }
public override void Up()
{
// that lock object should have been part of BaseDataCreation since 7.3.0 but
// for some reason it was not, so it was created during migrations but not during
// new installs, so for ppl that upgrade, make sure they have it
EnsureLockObject(Constants.System.ServersLock, "0AF5E610-A310-4B6F-925F-E928D5416AF7", "LOCK: Servers");
}
public override void Down()
{
// not implemented
}
private void EnsureLockObject(int id, string uniqueId, string text)
{
var exists = Context.Database.Exists<NodeDto>(id);
if (exists) return;
Insert
.IntoTable("umbracoNode")
.EnableIdentityInsert()
.Row(new
{
id = id, // NodeId
trashed = false,
parentId = -1,
nodeUser = 0,
level = 1,
path = "-1," + id,
sortOrder = 0,
uniqueId = new Guid(uniqueId),
text = text,
nodeObjectType = new Guid(Constants.ObjectTypes.LockObject),
createDate = DateTime.Now
});
}
}
}
@@ -105,6 +105,7 @@ namespace Umbraco.Core.Persistence.Repositories
#region Overrides of PetaPocoRepositoryBase<IContent>
protected override Sql GetBaseQuery(bool isCount)
{
var sqlx = string.Format("LEFT OUTER JOIN {0} {1} ON ({1}.{2}={0}.{2} AND {1}.{3}=1)",
@@ -241,8 +242,8 @@ namespace Umbraco.Core.Persistence.Repositories
// see: http://issues.umbraco.org/issue/U4-6322 & http://issues.umbraco.org/issue/U4-5982
var descendants = GetPagedResultsByQuery<DocumentDto, Content>(query, pageIndex, pageSize, out total,
new Tuple<string, string>("cmsDocument", "nodeId"),
ProcessQuery, "Path", Direction.Ascending);
ProcessQuery, "Path", Direction.Ascending, true);
var xmlItems = (from descendant in descendants
let xml = serializer(descendant)
select new ContentXmlDto { NodeId = descendant.Id, Xml = xml.ToDataString() }).ToArray();
@@ -766,10 +767,11 @@ namespace Umbraco.Core.Persistence.Repositories
/// <param name="totalRecords">Total records query would return without paging</param>
/// <param name="orderBy">Field to order by</param>
/// <param name="orderDirection">Direction to order by</param>
/// <param name="orderBySystemField">Flag to indicate when ordering by system field</param>
/// <param name="filter">Search text filter</param>
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
public IEnumerable<IContent> GetPagedResultsByQuery(IQuery<IContent> query, long pageIndex, int pageSize, out long totalRecords,
string orderBy, Direction orderDirection, string filter = "")
string orderBy, Direction orderDirection, bool orderBySystemField, string filter = "")
{
//NOTE: This uses the GetBaseQuery method but that does not take into account the required 'newest' field which is
@@ -788,7 +790,7 @@ namespace Umbraco.Core.Persistence.Repositories
return GetPagedResultsByQuery<DocumentDto, Content>(query, pageIndex, pageSize, out totalRecords,
new Tuple<string, string>("cmsDocument", "nodeId"),
ProcessQuery, orderBy, orderDirection,
ProcessQuery, orderBy, orderDirection, orderBySystemField,
filterCallback);
}
@@ -84,9 +84,10 @@ namespace Umbraco.Core.Persistence.Repositories
/// <param name="totalRecords">Total records query would return without paging</param>
/// <param name="orderBy">Field to order by</param>
/// <param name="orderDirection">Direction to order by</param>
/// <param name="orderBySystemField">Flag to indicate when ordering by system field</param>
/// <param name="filter">Search text filter</param>
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
IEnumerable<IContent> GetPagedResultsByQuery(IQuery<IContent> query, long pageIndex, int pageSize, out long totalRecords,
string orderBy, Direction orderDirection, string filter = "");
string orderBy, Direction orderDirection, bool orderBySystemField, string filter = "");
}
}
@@ -9,7 +9,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
public interface IMediaRepository : IRepositoryVersionable<int, IMedia>, IRecycleBinRepository<IMedia>, IDeleteMediaFilesRepository
{
/// <summary>
/// Used to add/update published xml for the media item
/// </summary>
@@ -33,9 +33,10 @@ namespace Umbraco.Core.Persistence.Repositories
/// <param name="totalRecords">Total records query would return without paging</param>
/// <param name="orderBy">Field to order by</param>
/// <param name="orderDirection">Direction to order by</param>
/// <param name="orderBySystemField">Flag to indicate when ordering by system field</param>
/// <param name="filter">Search text filter</param>
/// <returns>An Enumerable list of <see cref="IMedia"/> objects</returns>
IEnumerable<IMedia> GetPagedResultsByQuery(IQuery<IMedia> query, long pageIndex, int pageSize, out long totalRecords,
string orderBy, Direction orderDirection, string filter = "");
string orderBy, Direction orderDirection, bool orderBySystemField, string filter = "");
}
}
@@ -44,16 +44,17 @@ namespace Umbraco.Core.Persistence.Repositories
/// <summary>
/// Gets paged member results
/// </summary>
/// <param name="query"></param>
/// <param name="pageIndex"></param>
/// <param name="pageSize"></param>
/// <param name="totalRecords"></param>
/// <param name="orderBy"></param>
/// <param name="orderDirection"></param>
/// <param name="filter"></param>
/// <param name="query">The query.</param>
/// <param name="pageIndex">Index of the page.</param>
/// <param name="pageSize">Size of the page.</param>
/// <param name="totalRecords">The total records.</param>
/// <param name="orderBy">The order by column</param>
/// <param name="orderDirection">The order direction.</param>
/// <param name="orderBySystemField">Flag to indicate when ordering by system field</param>
/// <param name="filter">Search query</param>
/// <returns></returns>
IEnumerable<IMember> GetPagedResultsByQuery(IQuery<IMember> query, long pageIndex, int pageSize, out long totalRecords,
string orderBy, Direction orderDirection, string filter = "");
string orderBy, Direction orderDirection, bool orderBySystemField, string filter = "");
//IEnumerable<IMember> GetPagedResultsByQuery<TDto>(
// Sql sql, int pageIndex, int pageSize, out int totalRecords,
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using Semver;
using Umbraco.Core.Models;
@@ -7,5 +8,9 @@ namespace Umbraco.Core.Persistence.Repositories
public interface IMigrationEntryRepository : IRepositoryQueryable<int, IMigrationEntry>
{
IMigrationEntry FindEntry(string migrationName, SemVersion version);
IEnumerable<IMigrationEntry> FindEntries(SemVersion version, IEnumerable<string> migrationNames);
IEnumerable<IMigrationEntry> FindEntries(IEnumerable<string> migrationNames);
IEnumerable<IMigrationEntry> FindEntries(string migrationName);
}
}
@@ -232,7 +232,7 @@ namespace Umbraco.Core.Persistence.Repositories
var processed = 0;
do
{
var descendants = GetPagedResultsByQuery(query, pageIndex, pageSize, out total, "Path", Direction.Ascending);
var descendants = GetPagedResultsByQuery(query, pageIndex, pageSize, out total, "Path", Direction.Ascending, true);
var xmlItems = (from descendant in descendants
let xml = serializer(descendant)
@@ -442,10 +442,11 @@ namespace Umbraco.Core.Persistence.Repositories
/// <param name="totalRecords">Total records query would return without paging</param>
/// <param name="orderBy">Field to order by</param>
/// <param name="orderDirection">Direction to order by</param>
/// <param name="orderBySystemField">Flag to indicate when ordering by system field</param>
/// <param name="filter">Search text filter</param>
/// <returns>An Enumerable list of <see cref="IMedia"/> objects</returns>
public IEnumerable<IMedia> GetPagedResultsByQuery(IQuery<IMedia> query, long pageIndex, int pageSize, out long totalRecords,
string orderBy, Direction orderDirection, string filter = "")
string orderBy, Direction orderDirection, bool orderBySystemField, string filter = "")
{
var args = new List<object>();
var sbWhere = new StringBuilder();
@@ -459,7 +460,7 @@ namespace Umbraco.Core.Persistence.Repositories
return GetPagedResultsByQuery<ContentVersionDto, Models.Media>(query, pageIndex, pageSize, out totalRecords,
new Tuple<string, string>("cmsContentVersion", "contentId"),
ProcessQuery, orderBy, orderDirection,
ProcessQuery, orderBy, orderDirection, orderBySystemField,
filterCallback);
}
@@ -468,7 +469,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
//NOTE: This doesn't allow properties to be part of the query
var dtos = Database.Fetch<ContentVersionDto, ContentDto, NodeDto>(sql);
var ids = dtos.Select(x => x.ContentDto.ContentTypeId).ToArray();
//content types
@@ -74,7 +74,7 @@ namespace Umbraco.Core.Persistence.Repositories
}
return ProcessQuery(sql);
}
protected override IEnumerable<IMember> PerformGetByQuery(IQuery<IMember> query)
@@ -95,7 +95,7 @@ namespace Umbraco.Core.Persistence.Repositories
baseQuery.Append(new Sql("WHERE umbracoNode.id IN (" + sql.SQL + ")", sql.Arguments))
.OrderBy<NodeDto>(x => x.SortOrder);
return ProcessQuery(baseQuery);
return ProcessQuery(baseQuery);
}
else
{
@@ -103,7 +103,7 @@ namespace Umbraco.Core.Persistence.Repositories
var sql = translator.Translate()
.OrderBy<NodeDto>(x => x.SortOrder);
return ProcessQuery(sql);
return ProcessQuery(sql);
}
}
@@ -118,7 +118,7 @@ namespace Umbraco.Core.Persistence.Repositories
sql.Select(isCount ? "COUNT(*)" : "*")
.From<MemberDto>()
.InnerJoin<ContentVersionDto>()
.On<ContentVersionDto, MemberDto>(left => left.NodeId, right => right.NodeId)
.On<ContentVersionDto, MemberDto>(left => left.NodeId, right => right.NodeId)
.InnerJoin<ContentDto>()
.On<ContentVersionDto, ContentDto>(left => left.NodeId, right => right.NodeId)
//We're joining the type so we can do a query against the member type - not sure if this adds much overhead or not?
@@ -269,7 +269,7 @@ namespace Umbraco.Core.Persistence.Repositories
//Ensure that strings don't contain characters that are invalid in XML
entity.SanitizeEntityPropertiesForXmlStorage();
var dirtyEntity = (ICanBeDirty) entity;
var dirtyEntity = (ICanBeDirty)entity;
//Look up parent to get and set the correct Path and update SortOrder if ParentId has changed
if (dirtyEntity.IsPropertyDirty("ParentId"))
@@ -308,9 +308,9 @@ namespace Umbraco.Core.Persistence.Repositories
//Updates the current version - cmsContentVersion
//Assumes a Version guid exists and Version date (modified date) has been set/updated
Database.Update(dto.ContentVersionDto);
//Updates the cmsMember entry if it has changed
//NOTE: these cols are the REAL column names in the db
var changedCols = new List<string>();
@@ -330,13 +330,13 @@ namespace Umbraco.Core.Persistence.Repositories
//only update the changed cols
if (changedCols.Count > 0)
{
Database.Update(dto, changedCols);
Database.Update(dto, changedCols);
}
//TODO ContentType for the Member entity
//Create the PropertyData for this version - cmsPropertyData
var propertyFactory = new PropertyFactory(entity.ContentType.CompositionPropertyTypes.ToArray(), entity.Version, entity.Id);
var propertyFactory = new PropertyFactory(entity.ContentType.CompositionPropertyTypes.ToArray(), entity.Version, entity.Id);
var keyDictionary = new Dictionary<int, int>();
//Add Properties
@@ -447,7 +447,7 @@ namespace Umbraco.Core.Persistence.Repositories
var processed = 0;
do
{
var descendants = GetPagedResultsByQuery(query, pageIndex, pageSize, out total, "Path", Direction.Ascending);
var descendants = GetPagedResultsByQuery(query, pageIndex, pageSize, out total, "Path", Direction.Ascending, true);
var xmlItems = (from descendant in descendants
let xml = serializer(descendant)
@@ -559,7 +559,7 @@ namespace Umbraco.Core.Persistence.Repositories
var grpQry = new Query<IMemberGroup>().Where(group => group.Name.Equals(groupName));
var memberGroup = _memberGroupRepository.GetByQuery(grpQry).FirstOrDefault();
if (memberGroup == null) return Enumerable.Empty<IMember>();
var subQuery = new Sql().Select("Member").From<Member2MemberGroupDto>().Where<Member2MemberGroupDto>(dto => dto.MemberGroup == memberGroup.Id);
var sql = GetBaseQuery(false)
@@ -568,7 +568,7 @@ namespace Umbraco.Core.Persistence.Repositories
.Append(new Sql("WHERE umbracoNode.id IN (" + subQuery.SQL + ")", subQuery.Arguments))
.OrderByDescending<ContentVersionDto>(x => x.VersionDate)
.OrderBy<NodeDto>(x => x.SortOrder);
return ProcessQuery(sql);
}
@@ -593,7 +593,7 @@ namespace Umbraco.Core.Persistence.Repositories
//get the COUNT base query
var fullSql = GetBaseQuery(true)
.Append(new Sql("WHERE umbracoNode.id IN (" + sql.SQL + ")", sql.Arguments));
return Database.ExecuteScalar<int>(fullSql);
}
@@ -603,18 +603,19 @@ namespace Umbraco.Core.Persistence.Repositories
/// <param name="query">
/// The where clause, if this is null all records are queried
/// </param>
/// <param name="pageIndex"></param>
/// <param name="pageSize"></param>
/// <param name="totalRecords"></param>
/// <param name="orderBy"></param>
/// <param name="orderDirection"></param>
/// <param name="filter"></param>
/// <param name="pageIndex">Index of the page.</param>
/// <param name="pageSize">Size of the page.</param>
/// <param name="totalRecords">The total records.</param>
/// <param name="orderBy">The order by column</param>
/// <param name="orderDirection">The order direction.</param>
/// <param name="orderBySystemField">Flag to indicate when ordering by system field</param>
/// <param name="filter">Search query</param>
/// <returns></returns>
/// <remarks>
/// The query supplied will ONLY work with data specifically on the cmsMember table because we are using PetaPoco paging (SQL paging)
/// </remarks>
public IEnumerable<IMember> GetPagedResultsByQuery(IQuery<IMember> query, long pageIndex, int pageSize, out long totalRecords,
string orderBy, Direction orderDirection, string filter = "")
string orderBy, Direction orderDirection, bool orderBySystemField, string filter = "")
{
var args = new List<object>();
var sbWhere = new StringBuilder();
@@ -625,14 +626,14 @@ namespace Umbraco.Core.Persistence.Repositories
"OR (cmsMember.LoginName LIKE @0" + args.Count + "))");
args.Add("%" + filter + "%");
filterCallback = () => new Tuple<string, object[]>(sbWhere.ToString().Trim(), args.ToArray());
}
}
return GetPagedResultsByQuery<MemberDto, Member>(query, pageIndex, pageSize, out totalRecords,
new Tuple<string, string>("cmsMember", "nodeId"),
ProcessQuery, orderBy, orderDirection,
ProcessQuery, orderBy, orderDirection, orderBySystemField,
filterCallback);
}
public void AddOrUpdateContentXml(IMember content, Func<IMember, XElement> xml)
{
_contentXmlRepository.AddOrUpdate(new ContentXmlEntity<IMember>(content, xml));
@@ -682,7 +683,7 @@ namespace Umbraco.Core.Persistence.Repositories
var dtosWithContentTypes = dtos
//This select into and null check are required because we don't have a foreign damn key on the contentType column
// http://issues.umbraco.org/issue/U4-5503
.Select(x => new {dto = x, contentType = contentTypes.FirstOrDefault(ct => ct.Id == x.ContentVersionDto.ContentDto.ContentTypeId)})
.Select(x => new { dto = x, contentType = contentTypes.FirstOrDefault(ct => ct.Id == x.ContentVersionDto.ContentDto.ContentTypeId) })
.Where(x => x.contentType != null)
.ToArray();
@@ -694,12 +695,12 @@ namespace Umbraco.Core.Persistence.Repositories
d.dto.ContentVersionDto.ContentDto.NodeDto.CreateDate,
d.contentType));
var propertyData = GetPropertyCollection(sql, docDefs);
var propertyData = GetPropertyCollection(sql, docDefs);
return dtosWithContentTypes.Select(d => CreateMemberFromDto(
d.dto,
contentTypes.First(ct => ct.Id == d.dto.ContentVersionDto.ContentDto.ContentTypeId),
propertyData[d.dto.NodeId]));
propertyData[d.dto.NodeId]));
}
/// <summary>
@@ -94,11 +94,11 @@ namespace Umbraco.Core.Persistence.Repositories
}
sql.Select("umbracoNode.*", "cmsContentType.*", "cmsPropertyType.id AS PropertyTypeId", "cmsPropertyType.Alias",
"cmsPropertyType.Name", "cmsPropertyType.Description", "cmsPropertyType.mandatory",
"cmsPropertyType.Name", "cmsPropertyType.Description", "cmsPropertyType.mandatory", "cmsPropertyType.UniqueID",
"cmsPropertyType.validationRegExp", "cmsPropertyType.dataTypeId", "cmsPropertyType.sortOrder AS PropertyTypeSortOrder",
"cmsPropertyType.propertyTypeGroupId AS PropertyTypesGroupId", "cmsMemberType.memberCanEdit", "cmsMemberType.viewOnProfile",
"cmsDataType.propertyEditorAlias", "cmsDataType.dbType", "cmsPropertyTypeGroup.id AS PropertyTypeGroupId",
"cmsPropertyTypeGroup.text AS PropertyGroupName",
"cmsPropertyTypeGroup.text AS PropertyGroupName", "cmsPropertyTypeGroup.uniqueID AS PropertyGroupUniqueID",
"cmsPropertyTypeGroup.sortorder AS PropertyGroupSortOrder", "cmsPropertyTypeGroup.contenttypeNodeId")
.From<NodeDto>()
.InnerJoin<ContentTypeDto>().On<ContentTypeDto, NodeDto>(left => left.NodeId, right => right.NodeId)
@@ -128,5 +128,53 @@ namespace Umbraco.Core.Persistence.Repositories
return result == null ? null : factory.BuildEntity(result);
}
public IEnumerable<IMigrationEntry> FindEntries(SemVersion version, IEnumerable<string> migrationNames)
{
if (migrationNames.Any() == false) return Enumerable.Empty<IMigrationEntry>();
var versionString = version.ToString();
var sql = new Sql().Select("*")
.From<MigrationDto>(SqlSyntax)
.Where(
SqlSyntax.GetQuotedColumnName("version") + "=@versionString AND " +
SqlSyntax.GetQuotedColumnName("name") + " IN (@names)", new {names = migrationNames, versionString});
var result = Database.Fetch<MigrationDto>(sql);
var factory = new MigrationEntryFactory();
return result.Select(factory.BuildEntity);
}
public IEnumerable<IMigrationEntry> FindEntries(IEnumerable<string> migrationNames)
{
if (migrationNames.Any() == false) return Enumerable.Empty<IMigrationEntry>();
var sql = new Sql().Select("*")
.From<MigrationDto>(SqlSyntax)
.Where(
SqlSyntax.GetQuotedColumnName("name") + " IN (@names)", new { names = migrationNames });
var result = Database.Fetch<MigrationDto>(sql);
var factory = new MigrationEntryFactory();
return result.Select(factory.BuildEntity);
}
public IEnumerable<IMigrationEntry> FindEntries(string migrationName)
{
var sql = new Sql().Select("*")
.From<MigrationDto>(SqlSyntax)
.Where<MigrationDto>(x => x.Name.InvariantEquals(migrationName));
var result = Database.Fetch<MigrationDto>(sql);
var factory = new MigrationEntryFactory();
return result.Select(factory.BuildEntity);
}
}
}
@@ -25,6 +25,8 @@ using Umbraco.Core.IO;
namespace Umbraco.Core.Persistence.Repositories
{
using SqlSyntax;
internal abstract class VersionableRepositoryBase<TId, TEntity> : PetaPocoRepositoryBase<TId, TEntity>
where TEntity : class, IAggregateRoot
{
@@ -61,11 +63,11 @@ namespace Umbraco.Core.Persistence.Repositories
public virtual void DeleteVersion(Guid versionId)
{
var dto = Database.FirstOrDefault<ContentVersionDto>("WHERE versionId = @VersionId", new { VersionId = versionId });
if(dto == null) return;
if (dto == null) return;
//Ensure that the lastest version is not deleted
var latestVersionDto = Database.FirstOrDefault<ContentVersionDto>("WHERE ContentId = @Id ORDER BY VersionDate DESC", new { Id = dto.NodeId });
if(latestVersionDto.VersionId == dto.VersionId)
if (latestVersionDto.VersionId == dto.VersionId)
return;
using (var transaction = Database.GetTransaction())
@@ -83,7 +85,7 @@ namespace Umbraco.Core.Persistence.Repositories
var list =
Database.Fetch<ContentVersionDto>(
"WHERE versionId <> @VersionId AND (ContentId = @Id AND VersionDate < @VersionDate)",
new {VersionId = latestVersionDto.VersionId, Id = id, VersionDate = versionDate});
new { VersionId = latestVersionDto.VersionId, Id = id, VersionDate = versionDate });
if (list.Any() == false) return;
using (var transaction = Database.GetTransaction())
@@ -244,25 +246,68 @@ namespace Umbraco.Core.Persistence.Repositories
return filteredSql;
}
private Sql GetSortedSqlForPagedResults(Sql sql, Direction orderDirection, string orderBy)
private Sql GetSortedSqlForPagedResults(Sql sql, Direction orderDirection, string orderBy, bool orderBySystemField)
{
//copy to var so that the original isn't changed
var sortedSql = new Sql(sql.SQL, sql.Arguments);
// Apply order according to parameters
if (string.IsNullOrEmpty(orderBy) == false)
if (orderBySystemField)
{
var orderByParams = new[] { GetDatabaseFieldNameForOrderBy(orderBy) };
if (orderDirection == Direction.Ascending)
// Apply order according to parameters
if (string.IsNullOrEmpty(orderBy) == false)
{
sortedSql.OrderBy(orderByParams);
var orderByParams = new[] { GetDatabaseFieldNameForOrderBy(orderBy) };
if (orderDirection == Direction.Ascending)
{
sortedSql.OrderBy(orderByParams);
}
else
{
sortedSql.OrderByDescending(orderByParams);
}
}
else
{
sortedSql.OrderByDescending(orderByParams);
}
return sortedSql;
}
else
{
// Sorting by a custom field, so set-up sub-query for ORDER BY clause to pull through valie
// from most recent content version for the given order by field
var sortedInt = string.Format(SqlSyntax.ConvertIntegerToOrderableString, "dataInt");
var sortedDate = string.Format(SqlSyntax.ConvertDateToOrderableString, "dataDate");
var sortedString = string.Format("COALESCE({0},'')", "dataNvarchar");
var sortedDecimal = string.Format(SqlSyntax.ConvertDecimalToOrderableString, "dataDecimal");
var innerJoinTempTable = string.Format(@"INNER JOIN (
SELECT CASE
WHEN dataInt Is Not Null THEN {0}
WHEN dataDecimal Is Not Null THEN {1}
WHEN dataDate Is Not Null THEN {2}
ELSE {3}
END AS CustomPropVal,
cd.nodeId AS CustomPropValContentId
FROM cmsDocument cd
INNER JOIN cmsPropertyData cpd ON cpd.contentNodeId = cd.nodeId AND cpd.versionId = cd.versionId
INNER JOIN cmsPropertyType cpt ON cpt.Id = cpd.propertytypeId
WHERE cpt.Alias = @{4} AND cd.newest = 1) AS CustomPropData
ON CustomPropData.CustomPropValContentId = umbracoNode.id
", sortedInt, sortedDecimal, sortedDate, sortedString, sortedSql.Arguments.Length);
//insert this just above the LEFT OUTER JOIN
var newSql = sortedSql.SQL.Insert(sortedSql.SQL.IndexOf("LEFT OUTER JOIN"), innerJoinTempTable);
var newArgs = sortedSql.Arguments.ToList();
newArgs.Add(orderBy);
sortedSql = new Sql(newSql, newArgs.ToArray());
sortedSql.OrderBy("CustomPropData.CustomPropVal");
if (orderDirection == Direction.Descending)
{
sortedSql.Append(" DESC");
}
}
return sortedSql;
}
/// <summary>
@@ -279,13 +324,15 @@ namespace Umbraco.Core.Persistence.Repositories
/// <param name="processQuery">A callback to process the query result</param>
/// <param name="orderBy">The order by column</param>
/// <param name="orderDirection">The order direction.</param>
/// <param name="orderBySystemField">Flag to indicate when ordering by system field</param>
/// <returns></returns>
/// <exception cref="System.ArgumentNullException">orderBy</exception>
protected IEnumerable<TEntity> GetPagedResultsByQuery<TDto, TContentBase>(IQuery<TEntity> query, long pageIndex, int pageSize, out long totalRecords,
Tuple<string, string> nodeIdSelect,
Func<Sql, IEnumerable<TEntity>> processQuery,
string orderBy,
string orderBy,
Direction orderDirection,
bool orderBySystemField,
Func<Tuple<string, object[]>> defaultFilter = null)
where TContentBase : class, IAggregateRoot, TEntity
{
@@ -297,18 +344,18 @@ namespace Umbraco.Core.Persistence.Repositories
if (query == null) query = new Query<TEntity>();
var translator = new SqlTranslator<TEntity>(sqlBase, query);
var sqlQuery = translator.Translate();
// Note we can't do multi-page for several DTOs like we can multi-fetch and are doing in PerformGetByQuery,
// but actually given we are doing a Get on each one (again as in PerformGetByQuery), we only need the node Id.
// So we'll modify the SQL.
var sqlNodeIds = new Sql(
sqlQuery.SQL.Replace("SELECT *", string.Format("SELECT {0}.{1}",nodeIdSelect.Item1, nodeIdSelect.Item2)),
sqlQuery.SQL.Replace("SELECT *", string.Format("SELECT {0}.{1}", nodeIdSelect.Item1, nodeIdSelect.Item2)),
sqlQuery.Arguments);
//get sorted and filtered sql
var sqlNodeIdsWithSort = GetSortedSqlForPagedResults(
GetFilteredSqlForPagedResults(sqlNodeIds, defaultFilter),
orderDirection, orderBy);
orderDirection, orderBy, orderBySystemField);
// Get page of results and total count
IEnumerable<TEntity> result;
@@ -324,7 +371,7 @@ namespace Umbraco.Core.Persistence.Repositories
var args = sqlNodeIdsWithSort.Arguments;
string sqlStringCount, sqlStringPage;
Database.BuildPageQueries<TDto>(pageIndex * pageSize, pageSize, sqlNodeIdsWithSort.SQL, ref args, out sqlStringCount, out sqlStringPage);
//if this is for sql server, the sqlPage will start with a SELECT * but we don't want that, we only want to return the nodeId
sqlStringPage = sqlStringPage
.Replace("SELECT *",
@@ -333,7 +380,7 @@ namespace Umbraco.Core.Persistence.Repositories
"SELECT " + nodeIdSelect.Item2);
//We need to make this an inner join on the paged query
var splitQuery = sqlQuery.SQL.Split(new[] {"WHERE "}, StringSplitOptions.None);
var splitQuery = sqlQuery.SQL.Split(new[] { "WHERE " }, StringSplitOptions.None);
var withInnerJoinSql = new Sql(splitQuery[0])
.Append("INNER JOIN (")
//join the paged query with the paged query arguments
@@ -345,23 +392,9 @@ namespace Umbraco.Core.Persistence.Repositories
//get sorted and filtered sql
var fullQuery = GetSortedSqlForPagedResults(
GetFilteredSqlForPagedResults(withInnerJoinSql, defaultFilter),
orderDirection, orderBy);
var content = processQuery(fullQuery)
.Cast<TContentBase>()
.AsQueryable();
// Now we need to ensure this result is also ordered by the same order by clause
var orderByProperty = GetEntityPropertyNameForOrderBy(orderBy);
if (orderDirection == Direction.Ascending)
{
result = content.OrderBy(orderByProperty);
}
else
{
result = content.OrderByDescending(orderByProperty);
}
GetFilteredSqlForPagedResults(withInnerJoinSql, defaultFilter),
orderDirection, orderBy, orderBySystemField);
return processQuery(fullQuery);
}
else
{
@@ -394,9 +427,9 @@ INNER JOIN
(" + string.Format(parsedOriginalSql, "cmsContent.nodeId, cmsContentVersion.VersionId") + @") as docData
ON cmsPropertyData.versionId = docData.VersionId AND cmsPropertyData.contentNodeId = docData.nodeId
LEFT OUTER JOIN cmsDataTypePreValues
ON cmsPropertyType.dataTypeId = cmsDataTypePreValues.datatypeNodeId", docSql.Arguments);
ON cmsPropertyType.dataTypeId = cmsDataTypePreValues.datatypeNodeId", docSql.Arguments);
var allPropertyData = Database.Fetch<PropertyDataDto>(propSql);
var allPropertyData = Database.Fetch<PropertyDataDto>(propSql);
//This is a lazy access call to get all prevalue data for the data types that make up all of these properties which we use
// below if any property requires tag support
@@ -414,7 +447,7 @@ WHERE EXISTS(
ON cmsPropertyType.contentTypeId = docData.contentType
WHERE a.id = b.id)", docSql.Arguments);
return Database.Fetch<DataTypePreValueDto>(preValsSql);
return Database.Fetch<DataTypePreValueDto>(preValsSql);
});
var result = new Dictionary<int, PropertyCollection>();
@@ -432,8 +465,8 @@ WHERE EXISTS(
var propertyDataDtos = allPropertyData.Where(x => x.NodeId == def.Id).Distinct();
var propertyFactory = new PropertyFactory(compositionProperties, def.Version, def.Id, def.CreateDate, def.VersionDate);
var properties = propertyFactory.BuildEntity(propertyDataDtos.ToArray()).ToArray();
var properties = propertyFactory.BuildEntity(propertyDataDtos.ToArray()).ToArray();
var newProperties = properties.Where(x => x.HasIdentity == false && x.PropertyType.HasIdentity);
foreach (var property in newProperties)
@@ -481,7 +514,7 @@ WHERE EXISTS(
Logger.Warn<VersionableRepositoryBase<TId, TEntity>>("The query returned multiple property sets for document definition " + def.Id + ", " + def.Composition.Name);
}
result[def.Id] = new PropertyCollection(properties);
}
}
}
return result;
@@ -521,6 +554,9 @@ WHERE EXISTS(
case "OWNER":
//TODO: This isn't going to work very nicely because it's going to order by ID, not by letter
return "umbracoNode.nodeUser";
// Members only
case "USERNAME":
return "cmsMember.LoginName";
default:
//ensure invalid SQL cannot be submitted
return Regex.Replace(orderBy, @"[^\w\.,`\[\]@-]", "");
@@ -69,6 +69,10 @@ namespace Umbraco.Core.Persistence.SqlSyntax
bool SupportsClustered();
bool SupportsIdentityInsert();
bool? SupportsCaseInsensitiveQueries(Database db);
string ConvertIntegerToOrderableString { get; }
string ConvertDateToOrderableString { get; }
string ConvertDecimalToOrderableString { get; }
IEnumerable<string> GetTablesInSchema(Database db);
IEnumerable<ColumnInfo> GetColumnsInSchema(Database db);
@@ -18,7 +18,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
public MySqlSyntaxProvider(ILogger logger)
{
_logger = logger;
AutoIncrementDefinition = "AUTO_INCREMENT";
IntColumnDefinition = "int(11)";
BoolColumnDefinition = "tinyint(1)";
@@ -26,7 +26,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
TimeColumnDefinition = "time";
DecimalColumnDefinition = "decimal(38,6)";
GuidColumnDefinition = "char(36)";
DefaultValueFormat = "DEFAULT {0}";
InitColumnTypeMap();
@@ -326,13 +326,13 @@ ORDER BY TABLE_NAME, INDEX_NAME",
{
case SystemMethods.NewGuid:
return null; // NOT SUPPORTED!
//return "NEWID()";
//return "NEWID()";
case SystemMethods.CurrentDateTime:
return "CURRENT_TIMESTAMP";
//case SystemMethods.NewSequentialId:
// return "NEWSEQUENTIALID()";
//case SystemMethods.CurrentUTCDateTime:
// return "GETUTCDATE()";
//case SystemMethods.NewSequentialId:
// return "NEWSEQUENTIALID()";
//case SystemMethods.CurrentUTCDateTime:
// return "GETUTCDATE()";
}
return null;
@@ -360,6 +360,9 @@ ORDER BY TABLE_NAME, INDEX_NAME",
public override string DropIndex { get { return "DROP INDEX {0} ON {1}"; } }
public override string RenameColumn { get { return "ALTER TABLE {0} CHANGE {1} {2}"; } }
public override string ConvertIntegerToOrderableString { get { return "LPAD(FORMAT({0}, 0), 8, '0')"; } }
public override string ConvertDateToOrderableString { get { return "DATE_FORMAT({0}, '%Y%m%d')"; } }
public override string ConvertDecimalToOrderableString { get { return "LPAD(FORMAT({0}, 9), 20, '0')"; } }
public override bool? SupportsCaseInsensitiveQueries(Database db)
{
@@ -208,7 +208,6 @@ ORDER BY TABLE_NAME, INDEX_NAME");
public override string DropIndex { get { return "DROP INDEX {1}.{0}"; } }
}
}
@@ -322,7 +322,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
GetQuotedColumnName(foreignKey.ForeignColumns.First()),
GetQuotedTableName(foreignKey.PrimaryTable),
GetQuotedColumnName(foreignKey.PrimaryColumns.First()),
FormatCascade("DELETE", foreignKey.OnDelete),
FormatCascade("DELETE", foreignKey.OnDelete),
FormatCascade("UPDATE", foreignKey.OnUpdate));
}
@@ -331,7 +331,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
var sb = new StringBuilder();
foreach (var column in columns)
{
sb.Append(Format(column) +",\n");
sb.Append(Format(column) + ",\n");
}
return sb.ToString().TrimEnd(",\n");
}
@@ -431,11 +431,11 @@ namespace Umbraco.Core.Persistence.SqlSyntax
return GetSpecialDbType(column.DbType);
}
Type type = column.Type.HasValue
Type type = column.Type.HasValue
? DbTypeMap.ColumnDbTypeMap.First(x => x.Value == column.Type.Value).Key
: column.PropertyType;
if (type == typeof (string))
if (type == typeof(string))
{
var valueOrDefault = column.Size != default(int) ? column.Size : DefaultStringLength;
return string.Format(StringLengthColumnDefinitionFormat, valueOrDefault);
@@ -536,5 +536,9 @@ namespace Umbraco.Core.Persistence.SqlSyntax
public virtual string CreateConstraint { get { return "ALTER TABLE {0} ADD CONSTRAINT {1} {2} ({3})"; } }
public virtual string DeleteConstraint { get { return "ALTER TABLE {0} DROP CONSTRAINT {1}"; } }
public virtual string CreateForeignKeyConstraint { get { return "ALTER TABLE {0} ADD CONSTRAINT {1} FOREIGN KEY ({2}) REFERENCES {3} ({4}){5}{6}"; } }
public virtual string ConvertIntegerToOrderableString { get { return "REPLACE(STR({0}, 8), SPACE(1), '0')"; } }
public virtual string ConvertDateToOrderableString { get { return "CONVERT(nvarchar, {0}, 102)"; } }
public virtual string ConvertDecimalToOrderableString { get { return "REPLACE(STR({0}, 20, 9), SPACE(1), '0')"; } }
}
}
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq;
using System.Text;
using StackExchange.Profiling;
using Umbraco.Core.Logging;
@@ -128,15 +129,25 @@ namespace Umbraco.Core.Persistence
// 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;
if (EnableSqlTrace)
{
var sb = new StringBuilder();
sb.Append(cmd.CommandText);
foreach (DbParameter p in cmd.Parameters)
{
sb.Append(" - ");
sb.Append(p.Value);
}
_logger.Debug<UmbracoDatabase>(sb.ToString());
}
base.OnExecutingCommand(cmd);
}
public override void OnExecutedCommand(IDbCommand cmd)
{
if (EnableSqlTrace)
{
_logger.Debug<UmbracoDatabase>(cmd.CommandText);
}
if (_enableCount)
{
SqlCount++;
@@ -19,7 +19,7 @@ namespace Umbraco.Core.PropertyEditors
EditorView = editorView;
//defaults
ValueType = "string";
ValueType = PropertyEditorValueTypes.String;
Icon = Constants.Icons.PropertyEditor;
Group = "common";
}
@@ -33,7 +33,7 @@ namespace Umbraco.Core.PropertyEditors
Name = name;
//defaults
ValueType = "string";
ValueType = PropertyEditorValueTypes.String;
Icon = Constants.Icons.PropertyEditor;
Group = "common";
}
@@ -0,0 +1,34 @@
using System;
namespace Umbraco.Core.PropertyEditors
{
public static class PropertyEditorValueTypes
{
// mapped to DataTypeDatabaseType in DataTypeService.OverrideDatabaseTypeIfProvidedInPreValues
// BUT what about those that are not mapped?
//
// also mapped to DataTypeDatabaseType in PropertyValueEditor
// and this time the "+" are mapped
public const string Date = "DATE"; // +Date
public const string DateTime = "DATETIME"; // Date
public const string Decimal = "DECIMAL"; // Decimal
public const string Integer = "INT"; // Integer
[Obsolete("Use Integer.", false)]
public const string IntegerAlternative = "INTEGER"; // +Integer
public const string Json = "JSON"; // +NText
public const string Text = "TEXT"; // NText
public const string Time = "TIME"; // +Date
public const string String = "STRING"; // NVarchar
public const string Xml = "XML"; // +NText
}
}
@@ -25,7 +25,7 @@ namespace Umbraco.Core.PropertyEditors
/// </summary>
public PropertyValueEditor()
{
ValueType = "string";
ValueType = PropertyEditorValueTypes.String;
//set a default for validators
Validators = new List<IPropertyValidator>();
}
@@ -123,30 +123,35 @@ namespace Umbraco.Core.PropertyEditors
}
/// <summary>
/// Returns the true DataTypeDatabaseType from the string representation ValueType
/// Returns the true DataTypeDatabaseType from the string representation ValueType.
/// </summary>
/// <returns></returns>
public DataTypeDatabaseType GetDatabaseType()
{
switch (ValueType.ToUpper(CultureInfo.InvariantCulture))
return GetDatabaseType(ValueType);
}
public static DataTypeDatabaseType GetDatabaseType(string valueType)
{
switch (valueType.ToUpperInvariant())
{
case "INT":
case "INTEGER":
case PropertyEditorValueTypes.Integer:
case PropertyEditorValueTypes.IntegerAlternative:
return DataTypeDatabaseType.Integer;
case "DECIMAL":
case PropertyEditorValueTypes.Decimal:
return DataTypeDatabaseType.Decimal;
case "STRING":
case PropertyEditorValueTypes.String:
return DataTypeDatabaseType.Nvarchar;
case "TEXT":
case "JSON":
case "XML":
case PropertyEditorValueTypes.Text:
case PropertyEditorValueTypes.Json:
case PropertyEditorValueTypes.Xml:
return DataTypeDatabaseType.Ntext;
case "DATETIME":
case "DATE":
case "TIME":
case PropertyEditorValueTypes.DateTime:
case PropertyEditorValueTypes.Date:
case PropertyEditorValueTypes.Time:
return DataTypeDatabaseType.Date;
default:
throw new FormatException("The ValueType does not match a known value type");
throw new ArgumentException("Not a valid value type.", "valueType");
}
}
@@ -238,7 +243,7 @@ namespace Umbraco.Core.PropertyEditors
public virtual object ConvertEditorToDb(ContentPropertyData editorValue, object currentValue)
{
//if it's json but it's empty json, then return null
if (ValueType.InvariantEquals("JSON") && editorValue.Value != null && editorValue.Value.ToString().DetectIsEmptyJson())
if (ValueType.InvariantEquals(PropertyEditorValueTypes.Json) && editorValue.Value != null && editorValue.Value.ToString().DetectIsEmptyJson())
{
return null;
}
@@ -22,7 +22,7 @@ namespace Umbraco.Core.PropertyEditors
{
var asString = value.ToString();
if (editor.ValueEditor.ValueType.InvariantEquals("JSON"))
if (editor.ValueEditor.ValueType.InvariantEquals(PropertyEditorValueTypes.Json))
{
if (asString.DetectIsEmptyJson())
{
@@ -1,4 +1,5 @@
using Umbraco.Core.Models.PublishedContent;
using System.Globalization;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
@@ -20,7 +21,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
if (sourceString != null)
{
decimal d;
return (decimal.TryParse(sourceString, out d)) ? d : 0M;
return (decimal.TryParse(sourceString, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out d)) ? d : 0M;
}
// in the database an a decimal is an a decimal
@@ -26,7 +26,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
{
var propertyEditor = PropertyEditorResolver.Current.GetByAlias(propertyType.PropertyEditorAlias);
if (propertyEditor == null) return false;
return propertyEditor.ValueEditor.ValueType.InvariantEquals("json");
return propertyEditor.ValueEditor.ValueType.InvariantEquals(PropertyEditorValueTypes.Json);
}
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
@@ -35,6 +35,9 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
// as xml in the database, it's always been new line delimited. Will ask Stephen about this.
// In the meantime, we'll do this xml check, see if it parses and if not just continue with
// splitting by newline
//
// RS: SD/Stephan Please consider post before deciding to remove
//// https://our.umbraco.org/forum/contributing-to-umbraco-cms/76989-keep-the-xml-values-in-the-multipletextstringvalueconverter
var values = new List<string>();
var pos = sourceString.IndexOf("<value>", StringComparison.Ordinal);
while (pos >= 0)
@@ -118,6 +118,8 @@ namespace Umbraco.Core.Security
//custom identity factory for creating the identity object for which we auth against in the back office
manager.ClaimsIdentityFactory = new BackOfficeClaimsIdentityFactory();
manager.EmailService = new EmailService();
//NOTE: Not implementing these, if people need custom 2 factor auth, they'll need to implement their own UserStore to suport it
//// Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user
@@ -132,7 +134,6 @@ namespace Umbraco.Core.Security
// BodyFormat = "Your security code is: {0}"
//});
//manager.EmailService = new EmailService();
//manager.SmsService = new SmsService();
}
+26
View File
@@ -0,0 +1,26 @@
using System.Net.Mail;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
namespace Umbraco.Core.Security
{
public class EmailService : IIdentityMessageService
{
public async Task SendAsync(IdentityMessage message)
{
using (var client = new SmtpClient())
using (var mailMessage = new MailMessage())
{
mailMessage.Body = message.Body;
mailMessage.To.Add(message.Destination);
mailMessage.Subject = message.Subject;
//TODO: This check could be nicer but that is the way it is currently
mailMessage.IsBodyHtml = message.Body.IsNullOrWhiteSpace() == false
&& message.Body.Contains("<") && message.Body.Contains("/>");
await client.SendMailAsync(mailMessage);
}
}
}
}
-12
View File
@@ -1,12 +0,0 @@
using Semver;
namespace Umbraco.Core
{
public static class SemVersionExtensions
{
public static string ToSemanticString(this SemVersion semVersion)
{
return semVersion.ToString().Replace("--", "-").Replace("-+", "+");
}
}
}
+57 -46
View File
@@ -231,7 +231,7 @@ namespace Umbraco.Core.Services
public IContent CreateContentWithIdentity(string name, int parentId, string contentTypeAlias, int userId = 0)
{
var contentType = FindContentTypeByAlias(contentTypeAlias);
var content = new Content(name, parentId, contentType);
var content = new Content(name, parentId, contentType);
//NOTE: I really hate the notion of these Creating/Created events - they are so inconsistent, I've only just found
// out that in these 'WithIdentity' methods, the Saving/Saved events were not fired, wtf. Anyways, they're added now.
@@ -487,22 +487,10 @@ namespace Umbraco.Core.Services
public IEnumerable<IContent> GetPagedChildren(int id, int pageIndex, int pageSize, out int totalChildren,
string orderBy, Direction orderDirection, string filter = "")
{
Mandate.ParameterCondition(pageIndex >= 0, "pageIndex");
Mandate.ParameterCondition(pageSize > 0, "pageSize");
using (var repository = RepositoryFactory.CreateContentRepository(UowProvider.GetUnitOfWork()))
{
var query = Query<IContent>.Builder;
//if the id is System Root, then just get all
if (id != Constants.System.Root)
{
query.Where(x => x.ParentId == id);
}
long total;
var contents = repository.GetPagedResultsByQuery(query, pageIndex, pageSize, out total, orderBy, orderDirection, filter);
totalChildren = Convert.ToInt32(total);
return contents;
}
long total;
var result = GetPagedChildren(id, Convert.ToInt64(pageIndex), pageSize, out total, orderBy, orderDirection, true, filter);
totalChildren = Convert.ToInt32(total);
return result;
}
/// <summary>
@@ -518,6 +506,24 @@ namespace Umbraco.Core.Services
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
public IEnumerable<IContent> GetPagedChildren(int id, long pageIndex, int pageSize, out long totalChildren,
string orderBy, Direction orderDirection, string filter = "")
{
return GetPagedChildren(id, pageIndex, pageSize, out totalChildren, orderBy, orderDirection, true, filter);
}
/// <summary>
/// Gets a collection of <see cref="IContent"/> objects by Parent Id
/// </summary>
/// <param name="id">Id of the Parent to retrieve Children from</param>
/// <param name="pageIndex">Page index (zero based)</param>
/// <param name="pageSize">Page size</param>
/// <param name="totalChildren">Total records query would return without paging</param>
/// <param name="orderBy">Field to order by</param>
/// <param name="orderDirection">Direction to order by</param>
/// <param name="orderBySystemField">Flag to indicate when ordering by system field</param>
/// <param name="filter">Search text filter</param>
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
public IEnumerable<IContent> GetPagedChildren(int id, long pageIndex, int pageSize, out long totalChildren,
string orderBy, Direction orderDirection, bool orderBySystemField, string filter)
{
Mandate.ParameterCondition(pageIndex >= 0, "pageIndex");
Mandate.ParameterCondition(pageSize > 0, "pageSize");
@@ -530,7 +536,7 @@ namespace Umbraco.Core.Services
{
query.Where(x => x.ParentId == id);
}
var contents = repository.GetPagedResultsByQuery(query, pageIndex, pageSize, out totalChildren, orderBy, orderDirection, filter);
var contents = repository.GetPagedResultsByQuery(query, pageIndex, pageSize, out totalChildren, orderBy, orderDirection, orderBySystemField, filter);
return contents;
}
@@ -540,22 +546,10 @@ namespace Umbraco.Core.Services
[EditorBrowsable(EditorBrowsableState.Never)]
public IEnumerable<IContent> GetPagedDescendants(int id, int pageIndex, int pageSize, out int totalChildren, string orderBy = "Path", Direction orderDirection = Direction.Ascending, string filter = "")
{
Mandate.ParameterCondition(pageIndex >= 0, "pageIndex");
Mandate.ParameterCondition(pageSize > 0, "pageSize");
using (var repository = RepositoryFactory.CreateContentRepository(UowProvider.GetUnitOfWork()))
{
var query = Query<IContent>.Builder;
//if the id is System Root, then just get all
if (id != Constants.System.Root)
{
query.Where(x => x.Path.SqlContains(string.Format(",{0},", id), TextColumnType.NVarchar));
}
long total;
var contents = repository.GetPagedResultsByQuery(query, pageIndex, pageSize, out total, orderBy, orderDirection, filter);
totalChildren = Convert.ToInt32(total);
return contents;
}
long total;
var result = GetPagedDescendants(id, Convert.ToInt64(pageIndex), pageSize, out total, orderBy, orderDirection, true, filter);
totalChildren = Convert.ToInt32(total);
return result;
}
/// <summary>
@@ -568,8 +562,25 @@ namespace Umbraco.Core.Services
/// <param name="orderBy">Field to order by</param>
/// <param name="orderDirection">Direction to order by</param>
/// <param name="filter">Search text filter</param>
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
public IEnumerable<IContent> GetPagedDescendants(int id, long pageIndex, int pageSize, out long totalChildren, string orderBy = "Path", Direction orderDirection = Direction.Ascending, string filter = "")
{
return GetPagedDescendants(id, pageIndex, pageSize, out totalChildren, orderBy, orderDirection, true, filter);
}
/// <summary>
/// Gets a collection of <see cref="IContent"/> objects by Parent Id
/// </summary>
/// <param name="id">Id of the Parent to retrieve Descendants from</param>
/// <param name="pageIndex">Page number</param>
/// <param name="pageSize">Page size</param>
/// <param name="totalChildren">Total records query would return without paging</param>
/// <param name="orderBy">Field to order by</param>
/// <param name="orderDirection">Direction to order by</param>
/// <param name="orderBySystemField">Flag to indicate when ordering by system field</param>
/// <param name="filter">Search text filter</param>
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
public IEnumerable<IContent> GetPagedDescendants(int id, long pageIndex, int pageSize, out long totalChildren, string orderBy, Direction orderDirection, bool orderBySystemField, string filter)
{
Mandate.ParameterCondition(pageIndex >= 0, "pageIndex");
Mandate.ParameterCondition(pageSize > 0, "pageSize");
@@ -582,7 +593,7 @@ namespace Umbraco.Core.Services
{
query.Where(x => x.Path.SqlContains(string.Format(",{0},", id), TextColumnType.NVarchar));
}
var contents = repository.GetPagedResultsByQuery(query, pageIndex, pageSize, out totalChildren, orderBy, orderDirection, filter);
var contents = repository.GetPagedResultsByQuery(query, pageIndex, pageSize, out totalChildren, orderBy, orderDirection, orderBySystemField, filter);
return contents;
}
@@ -906,7 +917,7 @@ namespace Umbraco.Core.Services
{
var originalPath = content.Path;
if (Trashing.IsRaisedEventCancelled(
if (Trashing.IsRaisedEventCancelled(
new MoveEventArgs<IContent>(evtMsgs, new MoveEventInfo<IContent>(content, originalPath, Constants.System.RecycleBinContent)),
this))
{
@@ -1022,7 +1033,7 @@ namespace Umbraco.Core.Services
/// <returns>True if unpublishing succeeded, otherwise False</returns>
public bool UnPublish(IContent content, int userId = 0)
{
return ((IContentServiceOperations) this).UnPublish(content, userId).Success;
return ((IContentServiceOperations)this).UnPublish(content, userId).Success;
}
/// <summary>
@@ -1143,7 +1154,7 @@ namespace Umbraco.Core.Services
using (new WriteLock(Locker))
{
if (Deleting.IsRaisedEventCancelled(
if (Deleting.IsRaisedEventCancelled(
new DeleteEventArgs<IContent>(content, evtMsgs),
this))
{
@@ -1168,10 +1179,10 @@ namespace Umbraco.Core.Services
{
repository.Delete(content);
uow.Commit();
var args = new DeleteEventArgs<IContent>(content, false, evtMsgs);
Deleted.RaiseEvent(args, this);
//remove any flagged media files
repository.DeleteMediaFiles(args.MediaFilesToDelete);
}
@@ -1350,7 +1361,7 @@ namespace Umbraco.Core.Services
/// <param name="userId">Optional Id of the User deleting the Content</param>
public void MoveToRecycleBin(IContent content, int userId = 0)
{
((IContentServiceOperations) this).MoveToRecycleBin(content, userId);
((IContentServiceOperations)this).MoveToRecycleBin(content, userId);
}
/// <summary>
@@ -1654,7 +1665,7 @@ namespace Umbraco.Core.Services
//TODO: This should not be an inner operation, but if we do this, it cannot raise events and cannot be cancellable!
_publishingStrategy.PublishingFinalized(shouldBePublished, false);
}
Audit(AuditType.Sort, "Sorting content performed by user", userId, 0);
@@ -1902,13 +1913,13 @@ namespace Umbraco.Core.Services
content = newest;
var evtMsgs = EventMessagesFactory.Get();
var published = content.Published ? content : GetPublishedVersion(content.Id); // get the published version
if (published == null)
{
return Attempt.Succeed(new UnPublishStatus(content, UnPublishedStatusType.SuccessAlreadyUnPublished, evtMsgs)); // already unpublished
}
var unpublished = _publishingStrategy.UnPublish(content, userId);
if (unpublished == false) return Attempt.Fail(new UnPublishStatus(content, UnPublishedStatusType.FailedCancelledByEvent, evtMsgs));
@@ -2046,7 +2057,7 @@ namespace Umbraco.Core.Services
if (raiseEvents)
{
if (Saving.IsRaisedEventCancelled(
if (Saving.IsRaisedEventCancelled(
new SaveEventArgs<IContent>(content, evtMsgs),
this))
{
+4 -1
View File
@@ -504,6 +504,10 @@ namespace Umbraco.Core.Services
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IDataTypeDefinition>(dataTypeDefinition), this))
return;
// if preValues contain the data type, override the data type definition accordingly
if (values != null && values.ContainsKey(Constants.PropertyEditors.PreValueKeys.DataValueType))
dataTypeDefinition.DatabaseType = PropertyValueEditor.GetDatabaseType(values[Constants.PropertyEditors.PreValueKeys.DataValueType].Value);
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateDataTypeDefinitionRepository(uow))
{
@@ -523,7 +527,6 @@ namespace Umbraco.Core.Services
Audit(AuditType.Save, string.Format("Save DataTypeDefinition performed by user"), userId, dataTypeDefinition.Id);
}
/// <summary>
/// Deletes an <see cref="IDataTypeDefinition"/>
/// </summary>
+33 -3
View File
@@ -219,6 +219,21 @@ namespace Umbraco.Core.Services
IEnumerable<IContent> GetPagedChildren(int id, long pageIndex, int pageSize, out long totalRecords,
string orderBy = "SortOrder", Direction orderDirection = Direction.Ascending, string filter = "");
/// <summary>
/// Gets a collection of <see cref="IContent"/> objects by Parent Id
/// </summary>
/// <param name="id">Id of the Parent to retrieve Children from</param>
/// <param name="pageIndex">Page number</param>
/// <param name="pageSize">Page size</param>
/// <param name="totalRecords">Total records query would return without paging</param>
/// <param name="orderBy">Field to order by</param>
/// <param name="orderDirection">Direction to order by</param>
/// <param name="orderBySystemField">Flag to indicate when ordering by system field</param>
/// <param name="filter">Search text filter</param>
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
IEnumerable<IContent> GetPagedChildren(int id, long pageIndex, int pageSize, out long totalRecords,
string orderBy, Direction orderDirection, bool orderBySystemField, string filter);
[Obsolete("Use the overload with 'long' parameter types instead")]
[EditorBrowsable(EditorBrowsableState.Never)]
IEnumerable<IContent> GetPagedDescendants(int id, int pageIndex, int pageSize, out int totalRecords,
@@ -237,7 +252,22 @@ namespace Umbraco.Core.Services
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
IEnumerable<IContent> GetPagedDescendants(int id, long pageIndex, int pageSize, out long totalRecords,
string orderBy = "Path", Direction orderDirection = Direction.Ascending, string filter = "");
/// <summary>
/// Gets a collection of <see cref="IContent"/> objects by Parent Id
/// </summary>
/// <param name="id">Id of the Parent to retrieve Descendants from</param>
/// <param name="pageIndex">Page number</param>
/// <param name="pageSize">Page size</param>
/// <param name="totalRecords">Total records query would return without paging</param>
/// <param name="orderBy">Field to order by</param>
/// <param name="orderDirection">Direction to order by</param>
/// <param name="orderBySystemField">Flag to indicate when ordering by system field</param>
/// <param name="filter">Search text filter</param>
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
IEnumerable<IContent> GetPagedDescendants(int id, long pageIndex, int pageSize, out long totalRecords,
string orderBy, Direction orderDirection, bool orderBySystemField, string filter);
/// <summary>
/// Gets a collection of an <see cref="IContent"/> objects versions by its Id
/// </summary>
@@ -268,7 +298,7 @@ namespace Umbraco.Core.Services
/// </summary>
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
IEnumerable<IContent> GetContentInRecycleBin();
/// <summary>
/// Saves a single <see cref="IContent"/> object
/// </summary>
@@ -467,7 +497,7 @@ namespace Umbraco.Core.Services
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise save events.</param>
/// <returns>True if publishing succeeded, otherwise False</returns>
Attempt<PublishStatus> SaveAndPublishWithStatus(IContent content, int userId = 0, bool raiseEvents = true);
/// <summary>
/// Permanently deletes an <see cref="IContent"/> object.
/// </summary>
+31 -1
View File
@@ -137,6 +137,21 @@ namespace Umbraco.Core.Services
IEnumerable<IMedia> GetPagedChildren(int id, long pageIndex, int pageSize, out long totalRecords,
string orderBy = "SortOrder", Direction orderDirection = Direction.Ascending, string filter = "");
/// <summary>
/// Gets a collection of <see cref="IMedia"/> objects by Parent Id
/// </summary>
/// <param name="id">Id of the Parent to retrieve Children from</param>
/// <param name="pageIndex">Page number</param>
/// <param name="pageSize">Page size</param>
/// <param name="totalRecords">Total records query would return without paging</param>
/// <param name="orderBy">Field to order by</param>
/// <param name="orderDirection">Direction to order by</param>
/// <param name="orderBySystemField">Flag to indicate when ordering by system field</param>
/// <param name="filter">Search text filter</param>
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
IEnumerable<IMedia> GetPagedChildren(int id, long pageIndex, int pageSize, out long totalRecords,
string orderBy, Direction orderDirection, bool orderBySystemField, string filter);
[Obsolete("Use the overload with 'long' parameter types instead")]
[EditorBrowsable(EditorBrowsableState.Never)]
IEnumerable<IMedia> GetPagedDescendants(int id, int pageIndex, int pageSize, out int totalRecords,
@@ -156,6 +171,21 @@ namespace Umbraco.Core.Services
IEnumerable<IMedia> GetPagedDescendants(int id, long pageIndex, int pageSize, out long totalRecords,
string orderBy = "Path", Direction orderDirection = Direction.Ascending, string filter = "");
/// <summary>
/// Gets a collection of <see cref="IMedia"/> objects by Parent Id
/// </summary>
/// <param name="id">Id of the Parent to retrieve Descendants from</param>
/// <param name="pageIndex">Page number</param>
/// <param name="pageSize">Page size</param>
/// <param name="totalRecords">Total records query would return without paging</param>
/// <param name="orderBy">Field to order by</param>
/// <param name="orderDirection">Direction to order by</param>
/// <param name="orderBySystemField">Flag to indicate when ordering by system field</param>
/// <param name="filter">Search text filter</param>
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
IEnumerable<IMedia> GetPagedDescendants(int id, long pageIndex, int pageSize, out long totalRecords,
string orderBy, Direction orderDirection, bool orderBySystemField, string filter);
/// <summary>
/// Gets descendants of a <see cref="IMedia"/> object by its Id
/// </summary>
@@ -220,7 +250,7 @@ namespace Umbraco.Core.Services
/// <param name="media">The <see cref="IMedia"/> to delete</param>
/// <param name="userId">Id of the User deleting the Media</param>
void Delete(IMedia media, int userId = 0);
/// <summary>
/// Saves a single <see cref="IMedia"/> object
/// </summary>
+23 -7
View File
@@ -34,14 +34,30 @@ namespace Umbraco.Core.Services
/// <param name="pageIndex">Current page index</param>
/// <param name="pageSize">Size of the page</param>
/// <param name="totalRecords">Total number of records found (out)</param>
/// <param name="orderBy"></param>
/// <param name="orderDirection"></param>
/// <param name="orderBy">Field to order by</param>
/// <param name="orderDirection">Direction to order by</param>
/// <param name="memberTypeAlias"></param>
/// <param name="filter"></param>
/// <param name="filter">Search text filter</param>
/// <returns><see cref="IEnumerable{T}"/></returns>
IEnumerable<IMember> GetAll(long pageIndex, int pageSize, out long totalRecords,
string orderBy, Direction orderDirection, string memberTypeAlias = null, string filter = "");
/// <summary>
/// Gets a list of paged <see cref="IMember"/> objects
/// </summary>
/// <remarks>An <see cref="IMember"/> can be of type <see cref="IMember"/> </remarks>
/// <param name="pageIndex">Current page index</param>
/// <param name="pageSize">Size of the page</param>
/// <param name="totalRecords">Total number of records found (out)</param>
/// <param name="orderBy">Field to order by</param>
/// <param name="orderDirection">Direction to order by</param>
/// <param name="orderBySystemField">Flag to indicate when ordering by system field</param>
/// <param name="memberTypeAlias"></param>
/// <param name="filter">Search text filter</param>
/// <returns><see cref="IEnumerable{T}"/></returns>
IEnumerable<IMember> GetAll(long pageIndex, int pageSize, out long totalRecords,
string orderBy, Direction orderDirection, bool orderBySystemField, string memberTypeAlias, string filter);
/// <summary>
/// Creates an <see cref="IMember"/> object without persisting it
/// </summary>
@@ -91,7 +107,7 @@ namespace Umbraco.Core.Services
/// <param name="memberType">MemberType the Member should be based on</param>
/// <returns><see cref="IMember"/></returns>
IMember CreateMemberWithIdentity(string username, string email, string name, IMemberType memberType);
/// <summary>
/// This is simply a helper method which essentially just wraps the MembershipProvider's ChangePassword method
/// </summary>
@@ -115,7 +131,7 @@ namespace Umbraco.Core.Services
/// <param name="id">Id of the Member</param>
/// <returns><c>True</c> if the Member exists otherwise <c>False</c></returns>
bool Exists(int id);
/// <summary>
/// Gets a Member by the unique key
/// </summary>
@@ -160,7 +176,7 @@ namespace Umbraco.Core.Services
/// <param name="ids">Optional list of Member Ids</param>
/// <returns><see cref="IEnumerable{IMember}"/></returns>
IEnumerable<IMember> GetAllMembers(params int[] ids);
/// <summary>
/// Delete Members of the specified MemberType id
/// </summary>
@@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using Semver;
using Umbraco.Core.Models;
@@ -23,6 +22,28 @@ namespace Umbraco.Core.Services
/// <returns></returns>
IMigrationEntry FindEntry(string migrationName, SemVersion version);
/// <summary>
/// Finds migration entries by name
/// </summary>
/// <param name="migrationName"></param>
/// <returns></returns>
IEnumerable<IMigrationEntry> FindEntries(string migrationName);
/// <summary>
/// Finds migration entries by list of product names
/// </summary>
/// <param name="migrationNames"></param>
/// <returns></returns>
IEnumerable<IMigrationEntry> FindEntries(IEnumerable<string> migrationNames);
/// <summary>
/// Finds migrations by version and list of product names
/// </summary>
/// <param name="version"></param>
/// <param name="migrationNames"></param>
/// <returns></returns>
IEnumerable<IMigrationEntry> FindEntries(SemVersion version, IEnumerable<string> migrationNames);
/// <summary>
/// Gets all entries for a given migration name
/// </summary>
+53 -39
View File
@@ -35,7 +35,7 @@ namespace Umbraco.Core.Services
private readonly EntityXmlSerializer _entitySerializer = new EntityXmlSerializer();
private readonly IDataTypeService _dataTypeService;
private readonly IUserService _userService;
public MediaService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory, IDataTypeService dataTypeService, IUserService userService)
: base(provider, repositoryFactory, logger, eventMessagesFactory)
{
@@ -397,19 +397,10 @@ namespace Umbraco.Core.Services
public IEnumerable<IMedia> GetPagedChildren(int id, int pageIndex, int pageSize, out int totalChildren,
string orderBy, Direction orderDirection, string filter = "")
{
Mandate.ParameterCondition(pageIndex >= 0, "pageIndex");
Mandate.ParameterCondition(pageSize > 0, "pageSize");
using (var repository = RepositoryFactory.CreateMediaRepository(UowProvider.GetUnitOfWork()))
{
var query = Query<IMedia>.Builder;
query.Where(x => x.ParentId == id);
long total;
var medias = repository.GetPagedResultsByQuery(query, pageIndex, pageSize, out total, orderBy, orderDirection, filter);
totalChildren = Convert.ToInt32(total);
return medias;
}
long total;
var result = GetPagedChildren(id, Convert.ToInt64(pageIndex), pageSize, out total, orderBy, orderDirection, true, filter);
totalChildren = Convert.ToInt32(total);
return result;
}
/// <summary>
@@ -424,7 +415,25 @@ namespace Umbraco.Core.Services
/// <param name="filter">Search text filter</param>
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
public IEnumerable<IMedia> GetPagedChildren(int id, long pageIndex, int pageSize, out long totalChildren,
string orderBy, Direction orderDirection, string filter = "")
string orderBy, Direction orderDirection, string filter = "")
{
return GetPagedChildren(id, pageIndex, pageSize, out totalChildren, orderBy, orderDirection, true, filter);
}
/// <summary>
/// Gets a collection of <see cref="IMedia"/> objects by Parent Id
/// </summary>
/// <param name="id">Id of the Parent to retrieve Children from</param>
/// <param name="pageIndex">Page index (zero based)</param>
/// <param name="pageSize">Page size</param>
/// <param name="totalChildren">Total records query would return without paging</param>
/// <param name="orderBy">Field to order by</param>
/// <param name="orderDirection">Direction to order by</param>
/// <param name="orderBySystemField">Flag to indicate when ordering by system field</param>
/// <param name="filter">Search text filter</param>
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
public IEnumerable<IMedia> GetPagedChildren(int id, long pageIndex, int pageSize, out long totalChildren,
string orderBy, Direction orderDirection, bool orderBySystemField, string filter)
{
Mandate.ParameterCondition(pageIndex >= 0, "pageIndex");
Mandate.ParameterCondition(pageSize > 0, "pageSize");
@@ -432,8 +441,8 @@ namespace Umbraco.Core.Services
{
var query = Query<IMedia>.Builder;
query.Where(x => x.ParentId == id);
var medias = repository.GetPagedResultsByQuery(query, pageIndex, pageSize, out totalChildren, orderBy, orderDirection, filter);
var medias = repository.GetPagedResultsByQuery(query, pageIndex, pageSize, out totalChildren, orderBy, orderDirection, orderBySystemField, filter);
return medias;
}
@@ -443,22 +452,10 @@ namespace Umbraco.Core.Services
[EditorBrowsable(EditorBrowsableState.Never)]
public IEnumerable<IMedia> GetPagedDescendants(int id, int pageIndex, int pageSize, out int totalChildren, string orderBy = "Path", Direction orderDirection = Direction.Ascending, string filter = "")
{
Mandate.ParameterCondition(pageIndex >= 0, "pageIndex");
Mandate.ParameterCondition(pageSize > 0, "pageSize");
using (var repository = RepositoryFactory.CreateMediaRepository(UowProvider.GetUnitOfWork()))
{
var query = Query<IMedia>.Builder;
//if the id is -1, then just get all
if (id != -1)
{
query.Where(x => x.Path.SqlContains(string.Format(",{0},", id), TextColumnType.NVarchar));
}
long total;
var contents = repository.GetPagedResultsByQuery(query, pageIndex, pageSize, out total, orderBy, orderDirection, filter);
totalChildren = Convert.ToInt32(total);
return contents;
}
long total;
var result = GetPagedDescendants(id, Convert.ToInt64(pageIndex), pageSize, out total, orderBy, orderDirection, true, filter);
totalChildren = Convert.ToInt32(total);
return result;
}
/// <summary>
@@ -473,6 +470,23 @@ namespace Umbraco.Core.Services
/// <param name="filter">Search text filter</param>
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
public IEnumerable<IMedia> GetPagedDescendants(int id, long pageIndex, int pageSize, out long totalChildren, string orderBy = "Path", Direction orderDirection = Direction.Ascending, string filter = "")
{
return GetPagedDescendants(id, pageIndex, pageSize, out totalChildren, orderBy, orderDirection, true, filter);
}
/// <summary>
/// Gets a collection of <see cref="IContent"/> objects by Parent Id
/// </summary>
/// <param name="id">Id of the Parent to retrieve Descendants from</param>
/// <param name="pageIndex">Page number</param>
/// <param name="pageSize">Page size</param>
/// <param name="totalChildren">Total records query would return without paging</param>
/// <param name="orderBy">Field to order by</param>
/// <param name="orderDirection">Direction to order by</param>
/// <param name="orderBySystemField">Flag to indicate when ordering by system field</param>
/// <param name="filter">Search text filter</param>
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
public IEnumerable<IMedia> GetPagedDescendants(int id, long pageIndex, int pageSize, out long totalChildren, string orderBy, Direction orderDirection, bool orderBySystemField, string filter)
{
Mandate.ParameterCondition(pageIndex >= 0, "pageIndex");
Mandate.ParameterCondition(pageSize > 0, "pageSize");
@@ -485,7 +499,7 @@ namespace Umbraco.Core.Services
{
query.Where(x => x.Path.SqlContains(string.Format(",{0},", id), TextColumnType.NVarchar));
}
var contents = repository.GetPagedResultsByQuery(query, pageIndex, pageSize, out totalChildren, orderBy, orderDirection, filter);
var contents = repository.GetPagedResultsByQuery(query, pageIndex, pageSize, out totalChildren, orderBy, orderDirection, orderBySystemField, filter);
return contents;
}
@@ -727,7 +741,7 @@ namespace Umbraco.Core.Services
/// <param name="userId">Id of the User deleting the Media</param>
public void MoveToRecycleBin(IMedia media, int userId = 0)
{
((IMediaServiceOperations) this).MoveToRecycleBin(media, userId);
((IMediaServiceOperations)this).MoveToRecycleBin(media, userId);
}
/// <summary>
@@ -744,7 +758,7 @@ namespace Umbraco.Core.Services
//TODO: IT would be much nicer to mass delete all in one trans in the repo level!
var evtMsgs = EventMessagesFactory.Get();
if (Deleting.IsRaisedEventCancelled(
if (Deleting.IsRaisedEventCancelled(
new DeleteEventArgs<IMedia>(media, evtMsgs), this))
{
return OperationStatus.Cancelled(evtMsgs);
@@ -1025,7 +1039,7 @@ namespace Umbraco.Core.Services
((IMediaServiceOperations)this).Delete(media, userId);
}
/// <summary>
/// Permanently deletes versions from an <see cref="IMedia"/> object prior to a specific date.
@@ -1081,7 +1095,7 @@ namespace Umbraco.Core.Services
Audit(AuditType.Delete, "Delete Media by version performed by user", userId, -1);
}
/// <summary>
/// Saves a single <see cref="IMedia"/> object
/// </summary>
@@ -1090,7 +1104,7 @@ namespace Umbraco.Core.Services
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise events.</param>
public void Save(IMedia media, int userId = 0, bool raiseEvents = true)
{
((IMediaServiceOperations)this).Save (media, userId, raiseEvents);
((IMediaServiceOperations)this).Save(media, userId, raiseEvents);
}
/// <summary>
+55 -49
View File
@@ -30,7 +30,7 @@ namespace Umbraco.Core.Services
private readonly EntityXmlSerializer _entitySerializer = new EntityXmlSerializer();
private readonly IDataTypeService _dataTypeService;
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim();
public MemberService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory, IMemberGroupService memberGroupService, IDataTypeService dataTypeService)
: base(provider, repositoryFactory, logger, eventMessagesFactory)
{
@@ -52,7 +52,7 @@ namespace Umbraco.Core.Services
{
using (var repository = RepositoryFactory.CreateMemberTypeRepository(UowProvider.GetUnitOfWork()))
{
var types = repository.GetAll(new int[]{}).Select(x => x.Alias).ToArray();
var types = repository.GetAll(new int[] { }).Select(x => x.Alias).ToArray();
if (types.Any() == false)
{
@@ -289,7 +289,7 @@ namespace Umbraco.Core.Services
throw new ArgumentOutOfRangeException("matchType");
}
return repository.GetPagedResultsByQuery(query, pageIndex, pageSize, out totalRecords, "Name", Direction.Ascending);
return repository.GetPagedResultsByQuery(query, pageIndex, pageSize, out totalRecords, "Name", Direction.Ascending, true);
}
}
@@ -340,7 +340,7 @@ namespace Umbraco.Core.Services
throw new ArgumentOutOfRangeException("matchType");
}
return repository.GetPagedResultsByQuery(query, pageIndex, pageSize, out totalRecords, "Email", Direction.Ascending);
return repository.GetPagedResultsByQuery(query, pageIndex, pageSize, out totalRecords, "Email", Direction.Ascending, true);
}
}
@@ -391,7 +391,7 @@ namespace Umbraco.Core.Services
throw new ArgumentOutOfRangeException("matchType");
}
return repository.GetPagedResultsByQuery(query, pageIndex, pageSize, out totalRecords, "LoginName", Direction.Ascending);
return repository.GetPagedResultsByQuery(query, pageIndex, pageSize, out totalRecords, "LoginName", Direction.Ascending, true);
}
}
@@ -688,7 +688,7 @@ namespace Umbraco.Core.Services
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateMemberRepository(uow))
{
return repository.GetPagedResultsByQuery(null, pageIndex, pageSize, out totalRecords, "LoginName", Direction.Ascending);
return repository.GetPagedResultsByQuery(null, pageIndex, pageSize, out totalRecords, "LoginName", Direction.Ascending, true);
}
}
@@ -698,23 +698,29 @@ namespace Umbraco.Core.Services
string orderBy, Direction orderDirection, string memberTypeAlias = null, string filter = "")
{
long total;
var result = GetAll(Convert.ToInt64(pageIndex), pageSize, out total, orderBy, orderDirection, memberTypeAlias, filter);
var result = GetAll(Convert.ToInt64(pageIndex), pageSize, out total, orderBy, orderDirection, true, memberTypeAlias, filter);
totalRecords = Convert.ToInt32(total);
return result;
}
public IEnumerable<IMember> GetAll(long pageIndex, int pageSize, out long totalRecords,
string orderBy, Direction orderDirection, string memberTypeAlias = null, string filter = "")
{
return GetAll(pageIndex, pageSize, out totalRecords, orderBy, orderDirection, true, memberTypeAlias, filter);
}
public IEnumerable<IMember> GetAll(long pageIndex, int pageSize, out long totalRecords,
string orderBy, Direction orderDirection, bool orderBySystemField, string memberTypeAlias, string filter)
{
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateMemberRepository(uow))
{
if (memberTypeAlias == null)
{
return repository.GetPagedResultsByQuery(null, pageIndex, pageSize, out totalRecords, orderBy, orderDirection, filter);
return repository.GetPagedResultsByQuery(null, pageIndex, pageSize, out totalRecords, orderBy, orderDirection, orderBySystemField, filter);
}
var query = new Query<IMember>().Where(x => x.ContentTypeAlias == memberTypeAlias);
return repository.GetPagedResultsByQuery(query, pageIndex, pageSize, out totalRecords, orderBy, orderDirection, filter);
return repository.GetPagedResultsByQuery(query, pageIndex, pageSize, out totalRecords, orderBy, orderDirection, orderBySystemField, filter);
}
}
@@ -1253,52 +1259,52 @@ namespace Umbraco.Core.Services
var memType = new MemberType(-1);
var propGroup = new PropertyGroup
{
Name = "Membership",
Id = --identity
};
{
Name = "Membership",
Id = --identity
};
propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.TextboxAlias, DataTypeDatabaseType.Ntext, Constants.Conventions.Member.Comments)
{
Name = Constants.Conventions.Member.CommentsLabel,
SortOrder = 0,
Id = --identity,
Key = identity.ToGuid()
});
{
Name = Constants.Conventions.Member.CommentsLabel,
SortOrder = 0,
Id = --identity,
Key = identity.ToGuid()
});
propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.TrueFalseAlias, DataTypeDatabaseType.Integer, Constants.Conventions.Member.IsApproved)
{
Name = Constants.Conventions.Member.IsApprovedLabel,
SortOrder = 3,
Id = --identity,
Key = identity.ToGuid()
});
{
Name = Constants.Conventions.Member.IsApprovedLabel,
SortOrder = 3,
Id = --identity,
Key = identity.ToGuid()
});
propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.TrueFalseAlias, DataTypeDatabaseType.Integer, Constants.Conventions.Member.IsLockedOut)
{
Name = Constants.Conventions.Member.IsLockedOutLabel,
SortOrder = 4,
Id = --identity,
Key = identity.ToGuid()
});
{
Name = Constants.Conventions.Member.IsLockedOutLabel,
SortOrder = 4,
Id = --identity,
Key = identity.ToGuid()
});
propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, Constants.Conventions.Member.LastLockoutDate)
{
Name = Constants.Conventions.Member.LastLockoutDateLabel,
SortOrder = 5,
Id = --identity,
Key = identity.ToGuid()
});
{
Name = Constants.Conventions.Member.LastLockoutDateLabel,
SortOrder = 5,
Id = --identity,
Key = identity.ToGuid()
});
propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, Constants.Conventions.Member.LastLoginDate)
{
Name = Constants.Conventions.Member.LastLoginDateLabel,
SortOrder = 6,
Id = --identity,
Key = identity.ToGuid()
});
{
Name = Constants.Conventions.Member.LastLoginDateLabel,
SortOrder = 6,
Id = --identity,
Key = identity.ToGuid()
});
propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, Constants.Conventions.Member.LastPasswordChangeDate)
{
Name = Constants.Conventions.Member.LastPasswordChangeDateLabel,
SortOrder = 7,
Id = --identity,
Key = identity.ToGuid()
});
{
Name = Constants.Conventions.Member.LastPasswordChangeDateLabel,
SortOrder = 7,
Id = --identity,
Key = identity.ToGuid()
});
memType.PropertyGroups.Add(propGroup);
@@ -60,6 +60,33 @@ namespace Umbraco.Core.Services
}
}
public IEnumerable<IMigrationEntry> FindEntries(string migrationName)
{
var uow = UowProvider.GetUnitOfWork();
using (var repo = RepositoryFactory.CreateMigrationEntryRepository(uow))
{
return repo.FindEntries(migrationName);
}
}
public IEnumerable<IMigrationEntry> FindEntries(IEnumerable<string> migrationNames)
{
var uow = UowProvider.GetUnitOfWork();
using (var repo = RepositoryFactory.CreateMigrationEntryRepository(uow))
{
return repo.FindEntries(migrationNames);
}
}
public IEnumerable<IMigrationEntry> FindEntries(SemVersion version, IEnumerable<string> migrationNames)
{
var uow = UowProvider.GetUnitOfWork();
using (var repo = RepositoryFactory.CreateMigrationEntryRepository(uow))
{
return repo.FindEntries(version, migrationNames);
}
}
/// <summary>
/// Gets all entries for a given migration name
/// </summary>
@@ -7,7 +7,7 @@ namespace Umbraco.Core.Strings.Css
{
internal class StylesheetHelper
{
private const string RuleRegexFormat = @"/\*\*\s*umb_name:\s*(?<Name>{0}?)\s*\*/\s*(?<Selector>[^\s,{{]*?)\s*{{\s*(?<Styles>.*?)\s*}}";
private const string RuleRegexFormat = @"/\*\*\s*umb_name:\s*(?<Name>{0}?)\s*\*/\s*(?<Selector>[^,{{]*?)\s*{{\s*(?<Styles>.*?)\s*}}";
public static IEnumerable<StylesheetRule> ParseRules(string input)
{
+5 -1
View File
@@ -404,6 +404,7 @@
<Compile Include="Models\UmbracoDomain.cs" />
<Compile Include="Models\DoNotCloneAttribute.cs" />
<Compile Include="Models\IDomain.cs" />
<Compile Include="Packaging\PackageMigrationsContext.cs" />
<Compile Include="Persistence\DatabaseNodeLockExtensions.cs" />
<Compile Include="Persistence\Factories\ExternalLoginFactory.cs" />
<Compile Include="Persistence\Factories\MigrationEntryFactory.cs" />
@@ -415,6 +416,8 @@
<Compile Include="Persistence\Mappers\AccessMapper.cs" />
<Compile Include="Persistence\Mappers\DomainMapper.cs" />
<Compile Include="Persistence\Mappers\MigrationEntryMapper.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionFourOneZero\AddPreviewXmlTable.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenFiveZero\EnsureServersLockObject.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenFourZero\FixListViewMediaSortOrder.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenFourZero\AddDataDecimalColumn.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenFourZero\AddUmbracoDeployTables.cs" />
@@ -476,6 +479,7 @@
<Compile Include="Persistence\Repositories\TaskRepository.cs" />
<Compile Include="Persistence\Repositories\TaskTypeRepository.cs" />
<Compile Include="PropertyEditors\DecimalValidator.cs" />
<Compile Include="PropertyEditors\PropertyEditorValueTypes.cs" />
<Compile Include="PropertyEditors\ValueConverters\GridValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\DecimalValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\LabelValueConverter.cs" />
@@ -490,7 +494,7 @@
<Compile Include="Security\BackOfficeUserStore.cs" />
<Compile Include="Security\IBackOfficeUserPasswordChecker.cs" />
<Compile Include="Security\MembershipPasswordHasher.cs" />
<Compile Include="SemVersionExtensions.cs" />
<Compile Include="Security\EmailService.cs" />
<Compile Include="Serialization\NoTypeConverterJsonConverter.cs" />
<Compile Include="ServiceProviderExtensions.cs" />
<Compile Include="IO\ResizedImage.cs" />
+19 -3
View File
@@ -5,9 +5,25 @@ using Semver;
namespace Umbraco.Core
{
internal static class VersionExtensions
public static class VersionExtensions
{
public static Version GetVersion(this SemVersion semVersion, int maxParts = 4)
public static string ToSemanticString(this SemVersion semVersion)
{
return semVersion.ToString().Replace("--", "-").Replace("-+", "+");
}
internal static SemVersion GetSemanticVersion(this Version version)
{
return new SemVersion(
version.Major,
version.Minor,
version.Build,
null,
version.Revision > 0 ? version.Revision.ToInvariantString() : null);
}
internal static Version GetVersion(this SemVersion semVersion, int maxParts = 4)
{
int build = 0;
int.TryParse(semVersion.Build, out build);
@@ -24,7 +40,7 @@ namespace Umbraco.Core
return new Version(semVersion.Major, semVersion.Minor);
}
public static Version SubtractRevision(this Version version)
internal static Version SubtractRevision(this Version version)
{
var parts = new List<int>(new[] {version.Major, version.Minor, version.Build, version.Revision});
+7 -3
View File
@@ -210,6 +210,9 @@ namespace Umbraco.Core
var childNodesAndOrder = parentNode.SelectNodes(childNodesXPath).Cast<XmlNode>()
.Select(x => Tuple.Create(x, orderBy(x))).ToArray();
// only one node = node is in the right place already, obviously
if (childNodesAndOrder.Length == 1) return false;
// find the first node with a sortOrder > node.sortOrder
var i = 0;
while (i < childNodesAndOrder.Length && childNodesAndOrder[i].Item2 <= nodeSortOrder)
@@ -220,17 +223,18 @@ namespace Umbraco.Core
{
// and node is just before, we're done already
// else we need to move it right before the node that was found
if (i > 0 && childNodesAndOrder[i - 1].Item1 != node)
if (i == 0 || childNodesAndOrder[i - 1].Item1 != node)
{
parentNode.InsertBefore(node, childNodesAndOrder[i].Item1);
return true;
}
}
else
else // i == childNodesAndOrder.Length && childNodesAndOrder.Length > 1
{
// and node is the last one, we're done already
// else we need to append it as the last one
if (i > 0 && childNodesAndOrder[i - 1].Item1 != node)
// (and i > 1, see above)
if (childNodesAndOrder[i - 1].Item1 != node)
{
parentNode.AppendChild(node);
return true;
@@ -11,16 +11,25 @@ namespace Umbraco.Tests.Configurations.UmbracoSettings
{
Assert.IsTrue(SettingsSection.Security.KeepUserLoggedIn == true);
}
[Test]
public void HideDisabledUsersInBackoffice()
{
Assert.IsTrue(SettingsSection.Security.HideDisabledUsersInBackoffice == false);
}
[Test]
public void AllowPasswordReset()
{
Assert.IsTrue(SettingsSection.Security.AllowPasswordReset == true);
}
[Test]
public void AuthCookieDomain()
{
Assert.IsTrue(SettingsSection.Security.AuthCookieDomain == null);
}
[Test]
public void AuthCookieName()
{
@@ -110,7 +110,10 @@
<!-- change in 4.8: Disabled users are now showed dimmed and last in the tree. If you prefer not to display them set this to true -->
<hideDisabledUsersInBackoffice>false</hideDisabledUsersInBackoffice>
<!-- set to true to enable the UI and API to allow back-office users to reset their passwords -->
<allowPasswordReset>true</allowPasswordReset>
</security>
<requestHandler>
@@ -26,7 +26,7 @@ namespace Umbraco.Tests.Migrations
() => new List<Type>
{
typeof (AlterUserTableMigrationStub),
typeof(Dummy),
typeof (Dummy),
typeof (SixZeroMigration1),
typeof (SixZeroMigration2),
typeof (FourElevenMigration),
@@ -51,7 +51,6 @@ namespace Umbraco.Tests.Migrations
};
Resolution.Freeze();
}
[Test]
@@ -0,0 +1,94 @@
using System;
using System.Linq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven;
using Umbraco.Tests.TestHelpers;
namespace Umbraco.Tests.Migrations
{
[TestFixture]
[DatabaseTestBehavior(DatabaseBehavior.NewDbFileAndSchemaPerTest)]
public class MigrationIssuesTests : BaseDatabaseFactoryTest
{
[Test]
public void Issue8370Test()
{
// fixme maybe we need to create some content?
// yes otherwise cannot get it to fail!
var n = new NodeDto
{
Text = "text",
CreateDate = DateTime.Now,
Path = "-1",
ParentId = -1,
UniqueId = Guid.NewGuid()
};
DatabaseContext.Database.Insert(n);
var ct = new ContentTypeDto
{
Alias = "alias",
NodeId = n.NodeId,
Thumbnail = "thumb"
};
DatabaseContext.Database.Insert(ct);
n = new NodeDto
{
Text = "text",
CreateDate = DateTime.Now,
Path = "-1",
ParentId = -1,
UniqueId = Guid.NewGuid()
};
DatabaseContext.Database.Insert(n);
var dt = new DataTypeDto
{
PropertyEditorAlias = Constants.PropertyEditors.RelatedLinksAlias,
DbType = "x",
DataTypeId = n.NodeId
};
DatabaseContext.Database.Insert(dt);
var pt = new PropertyTypeDto
{
Alias = "alias",
ContentTypeId = ct.NodeId,
DataTypeId = dt.DataTypeId
};
DatabaseContext.Database.Insert(pt);
n = new NodeDto
{
Text = "text",
CreateDate = DateTime.Now,
Path = "-1",
ParentId = -1,
UniqueId = Guid.NewGuid()
};
DatabaseContext.Database.Insert(n);
var data = new PropertyDataDto
{
NodeId = n.NodeId,
PropertyTypeId = pt.Id,
Text = "text"
};
DatabaseContext.Database.Insert(data);
data = new PropertyDataDto
{
NodeId = n.NodeId,
PropertyTypeId = pt.Id,
Text = "<root><node title=\"\" type=\"\" newwindow=\"\" link=\"\" /></root>"
};
DatabaseContext.Database.Insert(data);
var migration = new UpdateRelatedLinksData(SqlSyntax, Logger);
migration.UpdateRelatedLinksDataDo(DatabaseContext.Database);
data = DatabaseContext.Database.Fetch<PropertyDataDto>("SELECT * FROM cmsPropertyData WHERE id=" + data.Id).FirstOrDefault();
Assert.IsNotNull(data);
Console.WriteLine(data.Text);
Assert.AreEqual("[{\"title\":\"\",\"caption\":\"\",\"link\":\"\",\"newWindow\":false,\"type\":\"external\",\"internal\":null,\"edit\":false,\"isInternal\":false}]",
data.Text);
}
}
}
@@ -0,0 +1,134 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Moq;
using NUnit.Framework;
using Semver;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Packaging;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Migrations;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Profiling;
using Umbraco.Core.Services;
using Umbraco.Tests.Migrations.Stubs;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web.Install.MigrationSteps;
using GlobalSettings = Umbraco.Core.Configuration.GlobalSettings;
namespace Umbraco.Tests.Migrations
{
[DatabaseTestBehavior(DatabaseBehavior.EmptyDbFilePerTest)]
[TestFixture]
public class PackageMigrationsTests : BaseDatabaseFactoryTest
{
private DatabaseContext _databaseContext;
private ILogger _logger;
private IMigrationEntryService _migrationEntryService;
/// <summary>
/// sets up resolvers before resolution is frozen
/// </summary>
protected override void FreezeResolution()
{
MigrationResolver.Current = new MigrationResolver(
Mock.Of<ILogger>(),
() => new List<Type>
{
typeof (PackageMigration1),
typeof (PackageMigration2)
});
//This is needed because the Migration resolver is creating the migration instances with their full ctors
_logger = Mock.Of<ILogger>();
LoggerResolver.Current = new LoggerResolver(_logger)
{
CanResolveBeforeFrozen = true
};
base.FreezeResolution();
}
protected override ApplicationContext CreateApplicationContext()
{
var sqlSyntax = new SqlCeSyntaxProvider();
var db = GetConfiguredDatabase();
var databaseContext = new Mock<DatabaseContext>(Mock.Of<IDatabaseFactory>(), Mock.Of<ILogger>(), sqlSyntax, "test");
databaseContext.SetupGet(x => x.CanConnect).Returns(true);
databaseContext.SetupGet(x => x.IsDatabaseConfigured).Returns(true);
databaseContext.Setup(x => x.Database).Returns(db);
_databaseContext = databaseContext.Object;
var umbracoMigrationEntry = new MigrationEntry(1, DateTime.UtcNow, GlobalSettings.UmbracoMigrationName,
UmbracoVersion.GetSemanticVersion());
var migrationEntryService = new Mock<IMigrationEntryService>();
migrationEntryService.Setup(x => x.FindEntry(It.IsAny<string>(), It.IsAny<SemVersion>()))
.Returns(umbracoMigrationEntry);
migrationEntryService.Setup(x => x.FindEntries(It.IsAny<string>())).Returns(Enumerable.Empty<IMigrationEntry>());
migrationEntryService.Setup(x => x.FindEntries(It.IsAny<string[]>())).Returns(Enumerable.Empty<IMigrationEntry>());
_migrationEntryService = migrationEntryService.Object;
//This is needed because the Migration resolver is creating migration instances with their full ctors
var applicationContext = new ApplicationContext(
//assign the db context
_databaseContext,
//assign the service context
new ServiceContext(migrationEntryService: _migrationEntryService),
CacheHelper.CreateDisabledCacheHelper(),
ProfilingLogger)
{
IsReady = true
};
return applicationContext;
}
[Test]
public void PackageMigrationsContext_HasPendingPackageMigrations()
{
var packageMigrationsContext = new PackageMigrationsContext(_databaseContext,
_migrationEntryService, _logger);
var hasPackageMigrations = packageMigrationsContext.HasPendingPackageMigrations;
Assert.True(hasPackageMigrations);
var result = packageMigrationsContext.GetPendingPackageMigrations();
Assert.AreEqual(1, result.Count);
Assert.True(result.ContainsKey("com.company.package"));
Assert.AreEqual(new SemVersion(2, 0, 0), result.First().Value);
var names = packageMigrationsContext.GetPendingPackageMigrationFriendlyNames();
var friendlyName = names.First();
Assert.AreEqual("com.company.package (2.0.0)", friendlyName);
}
[Test]
public void ExecutionMigrationStep_Can_Execute()
{
var packageMigrationsContext = new PackageMigrationsContext(_databaseContext,
_migrationEntryService, _logger);
var migrationStep = new ExecutionMigrationStep(_migrationEntryService, packageMigrationsContext,
_databaseContext.Database, _databaseContext.DatabaseProvider, _logger);
//Note: model isn't used here, so we just pass in an empty string
var executed = migrationStep.Execute(string.Empty);
Assert.Null(executed);
}
public UmbracoDatabase GetConfiguredDatabase()
{
return new UmbracoDatabase(GetDbConnectionString(), GetDbProviderName(), Mock.Of<ILogger>());
}
[TearDown]
public override void TearDown()
{
base.TearDown();
LoggerResolver.Reset();
MigrationResolver.Reset();
}
}
}
@@ -0,0 +1,29 @@
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.Migrations;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Tests.Migrations.Stubs
{
[Migration("1.0.0", 0, "com.company.package")]
public class PackageMigration1 : MigrationBase
{
private const string TableName = "RandomTableTest";
public PackageMigration1(ISqlSyntaxProvider sqlSyntax, ILogger logger) : base(sqlSyntax, logger)
{
}
public override void Up()
{
Create.Table(TableName)
.WithColumn("Id").AsGuid().Unique().NotNullable().PrimaryKey("awesome_id")
.WithColumn("Content").AsString(500).NotNullable()
.WithColumn("TimeStamp").AsDateTime().NotNullable();
}
public override void Down()
{
Delete.Table(TableName);
}
}
}
@@ -0,0 +1,27 @@
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.Migrations;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Tests.Migrations.Stubs
{
[Migration("2.0.0", 0, "com.company.package")]
public class PackageMigration2 : MigrationBase
{
private const string TableName = "RandomTableTest";
private const string ColumnName = "MoreContent";
public PackageMigration2(ISqlSyntaxProvider sqlSyntax, ILogger logger) : base(sqlSyntax, logger)
{
}
public override void Up()
{
Alter.Table(TableName).AddColumn(ColumnName).AsString(200).Nullable();
}
public override void Down()
{
Delete.Column(ColumnName).FromTable(TableName);
}
}
}
@@ -1,19 +1,14 @@
using System;
using System.Collections.Generic;
using System.Data.SqlServerCe;
using System.Linq;
using System.Text.RegularExpressions;
using Moq;
using NUnit.Framework;
using Semver;
using SQLCE4Umbraco;
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.ObjectResolution;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Migrations;
using Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Services;
using Umbraco.Tests.TestHelpers;
using GlobalSettings = Umbraco.Core.Configuration.GlobalSettings;
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using Moq;
using NUnit.Framework;
@@ -20,6 +21,7 @@ using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
using umbraco.editorControls.tinyMCE3;
using umbraco.interfaces;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
namespace Umbraco.Tests.Persistence.Repositories
@@ -72,7 +74,7 @@ namespace Umbraco.Tests.Persistence.Repositories
//create 100 non published
for (var i = 0; i < 100; i++)
{
{
var c1 = MockedContent.CreateSimpleContent(contentType1);
repository.AddOrUpdate(c1);
allCreated.Add(c1);
@@ -176,7 +178,7 @@ namespace Umbraco.Tests.Persistence.Repositories
for (var i = 0; i < 30; i++)
{
//These will be non-published so shouldn't show up
var c1 = MockedContent.CreateSimpleContent(contentType1);
var c1 = MockedContent.CreateSimpleContent(contentType1);
repository.AddOrUpdate(c1);
allCreated.Add(c1);
}
@@ -265,16 +267,17 @@ namespace Umbraco.Tests.Persistence.Repositories
using (var repository = CreateRepository(unitOfWork, out contentTypeRepository))
{
ContentType contentType = MockedContentTypes.CreateSimpleContentType("umbTextpage2", "Textpage");
Content textpage = MockedContent.CreateSimpleContent(contentType);
IContent textpage = MockedContent.CreateSimpleContent(contentType);
// Act
contentTypeRepository.AddOrUpdate(contentType);
repository.AddOrUpdate(textpage);
unitOfWork.Commit();
// Assert
Assert.That(contentType.HasIdentity, Is.True);
Assert.That(textpage.HasIdentity, Is.True);
}
}
@@ -299,14 +302,18 @@ namespace Umbraco.Tests.Persistence.Repositories
Content textpage = MockedContent.CreateSimpleContent(contentType);
// Act
contentTypeRepository.AddOrUpdate(contentType);
repository.AddOrUpdate(textpage);
unitOfWork.Commit();
var fetched = repository.Get(textpage.Id);
// Assert
Assert.That(textpage.Template, Is.Not.Null);
Assert.That(textpage.Template, Is.EqualTo(contentType.DefaultTemplate));
TestHelper.AssertAllPropertyValuesAreEquals(textpage, fetched, "yyyy-MM-dd HH:mm:ss");
}
}
@@ -520,7 +527,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var unitOfWork = provider.GetUnitOfWork();
ContentTypeRepository contentTypeRepository;
using (var repository = CreateRepository(unitOfWork, out contentTypeRepository))
{
{
var result = repository.GetAll().ToArray();
foreach (var content in result)
{
@@ -543,6 +550,41 @@ namespace Umbraco.Tests.Persistence.Repositories
}
}
[Test]
public void Can_Perform_GetPagedResultsByQuery_Sorting_On_Custom_Property()
{
// Arrange
var provider = new PetaPocoUnitOfWorkProvider(Logger);
var unitOfWork = provider.GetUnitOfWork();
ContentTypeRepository contentTypeRepository;
using (var repository = CreateRepository(unitOfWork, out contentTypeRepository))
{
// Act
var query = Query<IContent>.Builder.Where(x => x.Name.Contains("Text"));
long totalRecords;
try
{
DatabaseContext.Database.EnableSqlTrace = true;
DatabaseContext.Database.EnableSqlCount();
var result = repository.GetPagedResultsByQuery(query, 0, 2, out totalRecords, "title", Direction.Ascending, false);
Assert.AreEqual(3, totalRecords);
Assert.AreEqual(2, result.Count());
result = repository.GetPagedResultsByQuery(query, 1, 2, out totalRecords, "title", Direction.Ascending, false);
Assert.AreEqual(1, result.Count());
}
finally
{
DatabaseContext.Database.EnableSqlTrace = false;
DatabaseContext.Database.DisableSqlCount();
}
}
}
[Test]
public void Can_Perform_GetPagedResultsByQuery_ForFirstPage_On_ContentRepository()
{
@@ -555,12 +597,23 @@ namespace Umbraco.Tests.Persistence.Repositories
// Act
var query = Query<IContent>.Builder.Where(x => x.Level == 2);
long totalRecords;
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "Name", Direction.Ascending);
// Assert
Assert.That(totalRecords, Is.GreaterThanOrEqualTo(2));
Assert.That(result.Count(), Is.EqualTo(1));
Assert.That(result.First().Name, Is.EqualTo("Text Page 1"));
try
{
DatabaseContext.Database.EnableSqlTrace = true;
DatabaseContext.Database.EnableSqlCount();
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "Name", Direction.Ascending, true);
// Assert
Assert.That(totalRecords, Is.GreaterThanOrEqualTo(2));
Assert.That(result.Count(), Is.EqualTo(1));
Assert.That(result.First().Name, Is.EqualTo("Text Page 1"));
}
finally
{
DatabaseContext.Database.EnableSqlTrace = false;
DatabaseContext.Database.DisableSqlCount();
}
}
}
@@ -576,7 +629,7 @@ namespace Umbraco.Tests.Persistence.Repositories
// Act
var query = Query<IContent>.Builder.Where(x => x.Level == 2);
long totalRecords;
var result = repository.GetPagedResultsByQuery(query, 1, 1, out totalRecords, "Name", Direction.Ascending);
var result = repository.GetPagedResultsByQuery(query, 1, 1, out totalRecords, "Name", Direction.Ascending, true);
// Assert
Assert.That(totalRecords, Is.GreaterThanOrEqualTo(2));
@@ -597,7 +650,7 @@ namespace Umbraco.Tests.Persistence.Repositories
// Act
var query = Query<IContent>.Builder.Where(x => x.Level == 2);
long totalRecords;
var result = repository.GetPagedResultsByQuery(query, 0, 2, out totalRecords, "Name", Direction.Ascending);
var result = repository.GetPagedResultsByQuery(query, 0, 2, out totalRecords, "Name", Direction.Ascending, true);
// Assert
Assert.That(totalRecords, Is.GreaterThanOrEqualTo(2));
@@ -618,7 +671,7 @@ namespace Umbraco.Tests.Persistence.Repositories
// Act
var query = Query<IContent>.Builder.Where(x => x.Level == 2);
long totalRecords;
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "Name", Direction.Descending);
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "Name", Direction.Descending, true);
// Assert
Assert.That(totalRecords, Is.GreaterThanOrEqualTo(2));
@@ -639,7 +692,7 @@ namespace Umbraco.Tests.Persistence.Repositories
// Act
var query = Query<IContent>.Builder.Where(x => x.Level == 2);
long totalRecords;
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "Name", Direction.Ascending, "Page 2");
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "Name", Direction.Ascending, true, "Page 2");
// Assert
Assert.That(totalRecords, Is.EqualTo(1));
@@ -660,7 +713,7 @@ namespace Umbraco.Tests.Persistence.Repositories
// Act
var query = Query<IContent>.Builder.Where(x => x.Level == 2);
long totalRecords;
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "Name", Direction.Ascending, "Page");
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "Name", Direction.Ascending, true, "Page");
// Assert
Assert.That(totalRecords, Is.EqualTo(2));
@@ -266,6 +266,8 @@ namespace Umbraco.Tests.Persistence.Repositories
repository.AddOrUpdate(contentType);
unitOfWork.Commit();
var fetched = repository.Get(contentType.Id);
// Assert
Assert.That(contentType.HasIdentity, Is.True);
Assert.That(contentType.PropertyGroups.All(x => x.HasIdentity), Is.True);
@@ -281,6 +283,8 @@ namespace Umbraco.Tests.Persistence.Repositories
{
Assert.AreNotEqual(propertyType.Key, Guid.Empty);
}
TestHelper.AssertAllPropertyValuesAreEquals(contentType, fetched, "yyyy-MM-dd HH:mm:ss", ignoreProperties: new [] { "DefaultTemplate", "AllowedTemplates", "UpdateDate" });
}
}
@@ -355,9 +355,13 @@ namespace Umbraco.Tests.Persistence.Repositories
unitOfWork.Commit();
var exists = repository.Exists(dataTypeDefinition.Id);
var fetched = repository.Get(dataTypeDefinition.Id);
// Assert
Assert.That(dataTypeDefinition.HasIdentity, Is.True);
Assert.That(exists, Is.True);
TestHelper.AssertAllPropertyValuesAreEquals(dataTypeDefinition, fetched, "yyyy-MM-dd HH:mm:ss");
}
}
@@ -27,7 +27,7 @@ namespace Umbraco.Tests.Persistence.Repositories
[SetUp]
public override void Initialize()
{
{
base.Initialize();
CreateTestData();
@@ -51,12 +51,12 @@ namespace Umbraco.Tests.Persistence.Repositories
{
var mediaType = mediaTypeRepository.Get(1032);
for (var i = 0; i < 100; i++)
{
var image = MockedMedia.CreateMediaImage(mediaType, -1);
repository.AddOrUpdate(image);
}
}
unitOfWork.Commit();
//delete all xml
@@ -81,7 +81,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var imageMediaType = mediaTypeRepository.Get(1032);
var fileMediaType = mediaTypeRepository.Get(1033);
var folderMediaType = mediaTypeRepository.Get(1031);
for (var i = 0; i < 30; i++)
{
var image = MockedMedia.CreateMediaImage(imageMediaType, -1);
@@ -103,12 +103,12 @@ namespace Umbraco.Tests.Persistence.Repositories
unitOfWork.Database.Execute("DELETE FROM cmsContentXml");
Assert.AreEqual(0, unitOfWork.Database.ExecuteScalar<int>("SELECT COUNT(*) FROM cmsContentXml"));
repository.RebuildXmlStructures(media => new XElement("test"), 10, contentTypeIds: new[] {1032, 1033});
repository.RebuildXmlStructures(media => new XElement("test"), 10, contentTypeIds: new[] { 1032, 1033 });
Assert.AreEqual(62, unitOfWork.Database.ExecuteScalar<int>("SELECT COUNT(*) FROM cmsContentXml"));
}
}
[Test]
public void Can_Perform_Add_On_MediaRepository()
{
@@ -127,9 +127,13 @@ namespace Umbraco.Tests.Persistence.Repositories
repository.AddOrUpdate(image);
unitOfWork.Commit();
var fetched = repository.Get(image.Id);
// Assert
Assert.That(mediaType.HasIdentity, Is.True);
Assert.That(image.HasIdentity, Is.True);
TestHelper.AssertAllPropertyValuesAreEquals(image, fetched, "yyyy-MM-dd HH:mm:ss");
}
}
@@ -207,7 +211,7 @@ namespace Umbraco.Tests.Persistence.Repositories
// Act
var media = repository.Get(NodeDto.NodeIdSeed + 1);
bool dirty = ((ICanBeDirty) media).IsDirty();
bool dirty = ((ICanBeDirty)media).IsDirty();
// Assert
Assert.That(dirty, Is.False);
@@ -319,7 +323,7 @@ namespace Umbraco.Tests.Persistence.Repositories
// Act
var query = Query<IMedia>.Builder.Where(x => x.Level == 2);
long totalRecords;
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "SortOrder", Direction.Ascending);
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "SortOrder", Direction.Ascending, true);
// Assert
Assert.That(totalRecords, Is.GreaterThanOrEqualTo(2));
@@ -340,7 +344,7 @@ namespace Umbraco.Tests.Persistence.Repositories
// Act
var query = Query<IMedia>.Builder.Where(x => x.Level == 2);
long totalRecords;
var result = repository.GetPagedResultsByQuery(query, 1, 1, out totalRecords, "SortOrder", Direction.Ascending);
var result = repository.GetPagedResultsByQuery(query, 1, 1, out totalRecords, "SortOrder", Direction.Ascending, true);
// Assert
Assert.That(totalRecords, Is.GreaterThanOrEqualTo(2));
@@ -361,7 +365,7 @@ namespace Umbraco.Tests.Persistence.Repositories
// Act
var query = Query<IMedia>.Builder.Where(x => x.Level == 2);
long totalRecords;
var result = repository.GetPagedResultsByQuery(query, 0, 2, out totalRecords, "SortOrder", Direction.Ascending);
var result = repository.GetPagedResultsByQuery(query, 0, 2, out totalRecords, "SortOrder", Direction.Ascending, true);
// Assert
Assert.That(totalRecords, Is.GreaterThanOrEqualTo(2));
@@ -382,7 +386,7 @@ namespace Umbraco.Tests.Persistence.Repositories
// Act
var query = Query<IMedia>.Builder.Where(x => x.Level == 2);
long totalRecords;
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "SortOrder", Direction.Descending);
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "SortOrder", Direction.Descending, true);
// Assert
Assert.That(totalRecords, Is.GreaterThanOrEqualTo(2));
@@ -403,7 +407,7 @@ namespace Umbraco.Tests.Persistence.Repositories
// Act
var query = Query<IMedia>.Builder.Where(x => x.Level == 2);
long totalRecords;
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "Name", Direction.Ascending);
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "Name", Direction.Ascending, true);
// Assert
Assert.That(totalRecords, Is.GreaterThanOrEqualTo(2));
@@ -424,7 +428,7 @@ namespace Umbraco.Tests.Persistence.Repositories
// Act
var query = Query<IMedia>.Builder.Where(x => x.Level == 2);
long totalRecords;
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "SortOrder", Direction.Ascending, "File");
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "SortOrder", Direction.Ascending, true, "File");
// Assert
Assert.That(totalRecords, Is.EqualTo(1));
@@ -445,7 +449,7 @@ namespace Umbraco.Tests.Persistence.Repositories
// Act
var query = Query<IMedia>.Builder.Where(x => x.Level == 2);
long totalRecords;
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "SortOrder", Direction.Ascending, "Test");
var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "SortOrder", Direction.Ascending, true, "Test");
// Assert
Assert.That(totalRecords, Is.EqualTo(2));
@@ -197,11 +197,15 @@ namespace Umbraco.Tests.Persistence.Repositories
repository.AddOrUpdate(contentType);
unitOfWork.Commit();
var fetched = repository.Get(contentType.Id);
// Assert
Assert.That(contentType.HasIdentity, Is.True);
Assert.That(contentType.PropertyGroups.All(x => x.HasIdentity), Is.True);
Assert.That(contentType.Path.Contains(","), Is.True);
Assert.That(contentType.SortOrder, Is.GreaterThan(0));
Assert.That(contentType.SortOrder, Is.GreaterThan(0));
TestHelper.AssertAllPropertyValuesAreEquals(contentType, fetched, "yyyy-MM-dd HH:mm:ss", ignoreProperties: new[] { "UpdateDate" });
}
@@ -220,7 +220,9 @@ namespace Umbraco.Tests.Persistence.Repositories
Assert.That(sut.Name, Is.EqualTo("Johnny Hefty"));
Assert.That(sut.Email, Is.EqualTo("johnny@example.com"));
Assert.That(sut.RawPasswordValue, Is.EqualTo("123"));
Assert.That(sut.Username, Is.EqualTo("hefty"));
Assert.That(sut.Username, Is.EqualTo("hefty"));
TestHelper.AssertAllPropertyValuesAreEquals(sut, member, "yyyy-MM-dd HH:mm:ss");
}
}
@@ -42,7 +42,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var unitOfWork = provider.GetUnitOfWork();
using (var repository = CreateRepository(unitOfWork))
{
var memberType = MockedContentTypes.CreateSimpleMemberType();
var memberType = (IMemberType)MockedContentTypes.CreateSimpleMemberType();
repository.AddOrUpdate(memberType);
unitOfWork.Commit();
@@ -56,6 +56,33 @@ namespace Umbraco.Tests.Persistence.Repositories
Assert.That(sut.PropertyGroups.Any(x => x.HasIdentity == false || x.Id == 0), Is.False);
Assert.That(sut.PropertyTypes.Any(x => x.HasIdentity == false || x.Id == 0), Is.False);
TestHelper.AssertAllPropertyValuesAreEquals(sut, memberType, "yyyy-MM-dd HH:mm:ss");
}
}
[Test]
public void Can_Persist_Member_Type_Same_Property_Keys()
{
var provider = new PetaPocoUnitOfWorkProvider(Logger);
var unitOfWork = provider.GetUnitOfWork();
using (var repository = CreateRepository(unitOfWork))
{
var memberType = (IMemberType)MockedContentTypes.CreateSimpleMemberType();
repository.AddOrUpdate(memberType);
unitOfWork.Commit();
var propertyKeys = memberType.PropertyTypes.Select(x => x.Key).OrderBy(x => x).ToArray();
var groupKeys = memberType.PropertyGroups.Select(x => x.Key).OrderBy(x => x).ToArray();
memberType = repository.Get(memberType.Id);
var propertyKeys2 = memberType.PropertyTypes.Select(x => x.Key).OrderBy(x => x).ToArray();
var groupKeys2 = memberType.PropertyGroups.Select(x => x.Key).OrderBy(x => x).ToArray();
Assert.IsTrue(propertyKeys.SequenceEqual(propertyKeys2));
Assert.IsTrue(groupKeys.SequenceEqual(groupKeys2));
}
}
@@ -41,8 +41,8 @@ namespace Umbraco.Tests.PropertyEditors
var valueEditor = new PropertyValueEditor
{
ValueType = "STRING"
};
ValueType = PropertyEditorValueTypes.String
};
var result = valueEditor.ConvertDbToEditor(prop, prop.PropertyType, new Mock<IDataTypeService>().Object);
Assert.AreEqual(isOk, !(result is string));
@@ -73,7 +73,7 @@ namespace Umbraco.Tests.PropertyEditors
{
var valueEditor = new PropertyValueEditor
{
ValueType = "DECIMAL"
ValueType = PropertyEditorValueTypes.Decimal
};
var result = valueEditor.TryConvertValueToCrlType("12.34");
@@ -86,7 +86,7 @@ namespace Umbraco.Tests.PropertyEditors
{
var valueEditor = new PropertyValueEditor
{
ValueType = "DECIMAL"
ValueType = PropertyEditorValueTypes.Decimal
};
var result = valueEditor.TryConvertValueToCrlType("12,34");
@@ -99,7 +99,7 @@ namespace Umbraco.Tests.PropertyEditors
{
var valueEditor = new PropertyValueEditor
{
ValueType = "DECIMAL"
ValueType = PropertyEditorValueTypes.Decimal
};
var result = valueEditor.TryConvertValueToCrlType(string.Empty);
@@ -112,20 +112,20 @@ namespace Umbraco.Tests.PropertyEditors
{
var valueEditor = new PropertyValueEditor
{
ValueType = "DATE"
};
ValueType = PropertyEditorValueTypes.Date
};
var result = valueEditor.TryConvertValueToCrlType("2010-02-05");
Assert.IsTrue(result.Success);
Assert.AreEqual(new DateTime(2010, 2, 5), result.Result);
}
[TestCase("STRING", "hello", "hello")]
[TestCase("TEXT", "hello", "hello")]
[TestCase("INT", 123, "123")]
[TestCase("INTEGER", 123, "123")]
[TestCase("INTEGER", "", "")] //test empty string for int
[TestCase("DATETIME", "", "")] //test empty string for date
[TestCase(PropertyEditorValueTypes.String, "hello", "hello")]
[TestCase(PropertyEditorValueTypes.Text, "hello", "hello")]
[TestCase(PropertyEditorValueTypes.Integer, 123, "123")]
[TestCase(PropertyEditorValueTypes.IntegerAlternative, 123, "123")]
[TestCase(PropertyEditorValueTypes.Integer, "", "")] //test empty string for int
[TestCase(PropertyEditorValueTypes.DateTime, "", "")] //test empty string for date
public void Value_Editor_Can_Serialize_Value(string valueType, object val, string expected)
{
var prop = new Property(1, Guid.NewGuid(), new PropertyType("test", DataTypeDatabaseType.Nvarchar), val);
@@ -145,8 +145,8 @@ namespace Umbraco.Tests.PropertyEditors
var value = 12.34M;
var valueEditor = new PropertyValueEditor
{
ValueType = "DECIMAL"
};
ValueType = PropertyEditorValueTypes.Decimal
};
var prop = new Property(1, Guid.NewGuid(), new PropertyType("test", DataTypeDatabaseType.Decimal), value);
@@ -159,8 +159,8 @@ namespace Umbraco.Tests.PropertyEditors
{
var valueEditor = new PropertyValueEditor
{
ValueType = "DECIMAL"
};
ValueType = PropertyEditorValueTypes.Decimal
};
var prop = new Property(1, Guid.NewGuid(), new PropertyType("test", DataTypeDatabaseType.Decimal), string.Empty);
@@ -174,8 +174,8 @@ namespace Umbraco.Tests.PropertyEditors
var now = DateTime.Now;
var valueEditor = new PropertyValueEditor
{
ValueType = "DATE"
};
ValueType = PropertyEditorValueTypes.Date
};
var prop = new Property(1, Guid.NewGuid(), new PropertyType("test", DataTypeDatabaseType.Date), now);
@@ -57,10 +57,10 @@ namespace Umbraco.Tests.Routing
public const int LangNlId = 337;
public const int LangDkId = 338;
protected override void SetupApplicationContext()
protected override ApplicationContext CreateApplicationContext()
{
var settings = SettingsForTests.GetDefault();
ApplicationContext.Current = new ApplicationContext(
return new ApplicationContext(
new DatabaseContext(Mock.Of<IDatabaseFactory>(), Logger, Mock.Of<ISqlSyntaxProvider>(), "test"),
GetServiceContext(settings, Logger),
CacheHelper,
@@ -57,6 +57,7 @@ namespace Umbraco.Tests.TestHelpers
private string _dbPath;
//used to store (globally) the pre-built db with schema and initial data
private static Byte[] _dbBytes;
private DefaultDatabaseFactory _dbFactory;
[SetUp]
public override void Initialize()
@@ -66,27 +67,11 @@ namespace Umbraco.Tests.TestHelpers
var path = TestHelper.CurrentAssemblyDirectory;
AppDomain.CurrentDomain.SetData("DataDirectory", path);
//disable cache
var cacheHelper = CacheHelper.CreateDisabledCacheHelper();
var dbFactory = new DefaultDatabaseFactory(
_dbFactory = new DefaultDatabaseFactory(
GetDbConnectionString(),
GetDbProviderName(),
Logger);
var repositoryFactory = new RepositoryFactory(cacheHelper, Logger, SqlSyntax, SettingsForTests.GenerateMockSettings());
var evtMsgs = new TransientMessagesFactory();
_appContext = new ApplicationContext(
//assign the db context
new DatabaseContext(dbFactory, Logger, SqlSyntax, "System.Data.SqlServerCe.4.0"),
//assign the service context
new ServiceContext(repositoryFactory, new PetaPocoUnitOfWorkProvider(dbFactory), new FileUnitOfWorkProvider(), new PublishingStrategy(evtMsgs, Logger), cacheHelper, Logger, evtMsgs),
cacheHelper,
ProfilingLogger)
{
IsReady = true
};
base.Initialize();
@@ -94,7 +79,7 @@ namespace Umbraco.Tests.TestHelpers
{
//TODO: Somehow make this faster - takes 5s +
DatabaseContext.Initialize(dbFactory.ProviderName, dbFactory.ConnectionString);
DatabaseContext.Initialize(_dbFactory.ProviderName, _dbFactory.ConnectionString);
CreateSqlCeDatabase();
InitializeDatabase();
@@ -103,16 +88,32 @@ namespace Umbraco.Tests.TestHelpers
}
}
protected override ApplicationContext CreateApplicationContext()
{
//disable cache
var cacheHelper = CacheHelper.CreateDisabledCacheHelper();
var repositoryFactory = new RepositoryFactory(cacheHelper, Logger, SqlSyntax, SettingsForTests.GenerateMockSettings());
var evtMsgs = new TransientMessagesFactory();
_appContext = new ApplicationContext(
//assign the db context
new DatabaseContext(_dbFactory, Logger, SqlSyntax, "System.Data.SqlServerCe.4.0"),
//assign the service context
new ServiceContext(repositoryFactory, new PetaPocoUnitOfWorkProvider(_dbFactory), new FileUnitOfWorkProvider(), new PublishingStrategy(evtMsgs, Logger), cacheHelper, Logger, evtMsgs),
cacheHelper,
ProfilingLogger)
{
IsReady = true
};
return _appContext;
}
protected virtual ISqlSyntaxProvider SqlSyntax
{
get { return new SqlCeSyntaxProvider(); }
}
protected override void SetupApplicationContext()
{
ApplicationContext.Current = _appContext;
}
/// <summary>
/// The database behavior to use for the test/fixture
/// </summary>
@@ -192,9 +193,7 @@ namespace Umbraco.Tests.TestHelpers
engine.CreateDatabase();
}
}
}
}
/// <summary>

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