Compare commits

...

333 Commits

Author SHA1 Message Date
Sebastiaan Janssen 8fae55e44e Correct path to Courier 2013-04-25 09:02:58 -02:00
Sebastiaan Janssen a8ca3a89bd Forgot to uncomment some items 2013-04-25 08:51:31 -02:00
Sebastiaan Janssen 765f959f20 Reverting includes removal of courier/contour files 2013-04-25 08:44:37 -02:00
Sebastiaan Janssen 2cf90477ed Make Selenium Contour install work 2013-04-25 08:44:01 -02:00
Sebastiaan Janssen 6ca6a08233 Add RevertToEmptyInstall which installs an empty DB with credentials admin/test
Also deletes all dlls from /bin and rebuilds the project (to remove packages
that have installed dlls).
2013-04-25 07:15:54 -02:00
Sebastiaan Janssen 0119f1eb1b Merge 2013-04-25 06:11:28 -02:00
Sebastiaan Janssen cd4f66e7c5 Making a start on adding Selenium integration/UI tests for the backoffice 2013-04-25 06:10:57 -02:00
Morten Christensen 3fdc0e5361 Fixes #U4-2137 Ensuring that existing templates are updated instead of duplicated when installing packages.
Adds test for installing templates and then updating the same templates through another package install.
2013-04-24 07:41:37 -02:00
Shannon Deminick 4bfb8569c8 Fixed up merge issues 2013-04-23 21:37:03 -10:00
Shannon Deminick df9a887032 Merge with 4.11.7 2013-04-23 20:50:30 -10:00
Shannon Deminick 1e0a4690fc Added an error log if timed out 2013-04-23 20:31:32 -10:00
Shannon Deminick 52163494db changed the async state object to be a custom class to hold the original values of alias/text 2013-04-23 20:19:48 -10:00
Shannon Deminick 8416764a83 removed the trace from the page 2013-04-23 20:01:26 -10:00
Shannon Deminick 2d3eb8c208 Working on #U4-493, updated ContentTypeControlNew and EditNodeTypeNew to use correct webforms class structures.
Changed the saving logic in ContentTypeControlNew to use the page's async execution and changed the page to support async.
Changed the page's async timeout to be 5 minutes.
2013-04-23 20:00:48 -10:00
Sebastiaan Janssen aa84a3f7f2 Fixes U4-2138 Copying a node reverses sort order in target 2013-04-23 12:49:33 -02:00
agrath 3594693f4b Backported fix for u4-335 from Commit b15d0ab0b879 into 4.11.7 2013-04-22 11:12:03 -12:00
Morten Christensen c573459626 Fixing nuget related issue #U4-2067 and updating version 2013-04-22 06:01:31 -02:00
Sebastiaan Janssen b99de245bf Fixes U4-2052 for new mediatypes as well 2013-04-21 09:44:08 -02:00
Morten Christensen 222723b8fe Fixes #U4-2004 so GetPublishedDescendants retrieves the published version and not the latest version. 2013-04-21 09:06:22 -02:00
Morten Christensen f758b33da5 Properly fixes #U4-2112 and adds option to determine whether or not to import doc type structues. 2013-04-21 07:25:38 -02:00
Morten Christensen eeb0e0026a Making PropertyCollection, PropertyGroupCollection and PropertyTypeCollection return a proper null when FirstOrDefault should return null. 2013-04-20 19:47:30 -02:00
Morten Christensen 082dacf737 Fixes #U4-2029 Finding scripts and stylesheets recursively. 2013-04-20 12:56:43 -02:00
Morten Christensen afc2fd9420 Ensures that CreateDate and UpdateDate is set on both PropertyTypes and Properties for Content and Media.
Fixes #U4-2028
2013-04-20 12:23:14 -02:00
Morten Christensen ff6715d42a Fixes #U4-2013 Localization lost in packaging for DocumentTypes 2013-04-20 11:23:04 -02:00
Morten Christensen b776675ac8 Fixes #U4-2065 Document.AfterMove legacy event handler returns wrong parent. 2013-04-20 11:19:27 -02:00
Morten Christensen 1e21671b62 Fixes #U4-2008 Umbraco.Core.Models.PropertyType -> change ValidationRegExp from internal to public 2013-04-20 11:10:28 -02:00
Morten Christensen 59184981cb Fixes #U4-2009 Delete of media doesnt delete relations 2013-04-20 11:05:48 -02:00
Morten Christensen 0632ffb93d Fixes #U4-2069 2013-04-20 11:03:57 -02:00
Shannon Deminick 034aa6d8f9 Fixes merge issue 2013-04-20 03:58:15 +06:00
Shannon Deminick 1484fba1ad Merge with 4.11.7 2013-04-20 03:51:22 +06:00
Shannon Deminick 82fc1a5304 updated proj file 2013-04-20 03:47:57 +06:00
Shannon Deminick f0aab6ae81 Fixes: U4-2089 - sort dialog behavior when clicking on column headers. Updated to latest version of table sorting, had to create a custom sort parser
upgraded the sort.aspx to have the proper code behind structure and updated the page to have proper css and js files instead of inline. Fixes missing images.
2013-04-20 03:42:47 +06:00
Shannon Deminick 9ac325c1a4 Fixes: #U4-2130 - regression bug for handling image uploads 2013-04-20 00:04:39 +06:00
Sebastiaan Janssen 8c257d39f9 Fix merge issue 2013-04-19 06:43:58 -02:00
Sebastiaan Janssen 76f040aef4 Merge with 4.11.7 2013-04-19 06:42:33 -02:00
Sebastiaan Janssen 721f813d1e U4-1604 Fix latest edits dashboard control so that it doesn't make a zillion queries - Limit the latestedits query to specified amount of rows 2013-04-19 06:10:58 -02:00
Morten Christensen 7ed5a6f706 Fixes #U4-2068 and #U4-2125
Creating test for verifying path is correctly updated when moving items to the recycle bin.
2013-04-19 06:07:25 -02:00
Shannon Deminick 35a698cdc9 Merge with 4.11.7 2013-04-19 04:40:13 +06:00
Shannon Deminick 6c9e82e735 fixed typo 2013-04-19 04:31:55 +06:00
Shannon Deminick f7ddb1ed49 fixed typo 2013-04-19 04:30:15 +06:00
Shannon Deminick c0fd974cc1 fixes typo on word disallow 2013-04-19 04:20:24 +06:00
Shannon Deminick e9c4a031c9 Fixes up directory browser and removes legacy request params which are prone to xss 2013-04-19 04:10:35 +06:00
Shannon Deminick 123e65c55f Fixes: #U4-2118 - BOM encoding issue 2013-04-18 23:00:57 +06:00
Shannon Deminick e5e4e7b685 Fixes another merge issue and improves performance slightly for sorting so that we are not double saving the entity if it is published already. 2013-04-18 21:44:38 +06:00
Shannon Deminick 88795b86fd Updated merge issue, and removed the call to refreshXmlSortOrder since we are already republishing which already writes the updated xml 2013-04-18 21:16:00 +06:00
Shannon Deminick 378a544c1a Merge with 4.11.7 2013-04-18 20:59:42 +06:00
Shannon Deminick a159b50c05 Fixed a couple threading issues. Improved the performance of the nodeSorter but this should be better improved in 6.x 2013-04-18 20:52:49 +06:00
Shannon Deminick 3891e46549 Fixed a couple threading issues. Improved the performance of the nodeSorter but this should be better improved in 6.x 2013-04-18 20:52:30 +06:00
Shannon Deminick e7bcc642a9 fix build error on build server 2013-04-18 19:50:01 +06:00
Shannon Deminick 4983990d39 Big optimization for content.SortNodes - 92% performance increase for this method which is a big
contributor to CPU time during publishing.
2013-04-18 05:43:05 +06:00
Shannon Deminick e9a496df4f Merge with 4.11.7 2013-04-17 23:31:52 +06:00
Shannon Deminick 2f6dada481 Fixes issue with ctor not setting default property 2013-04-17 23:20:20 +06:00
Shannon Deminick 580123cb87 fixed merge issues 2013-04-17 23:03:51 +06:00
Shannon Deminick de0e47d7ef Merge with 4.11.7 2013-04-17 22:50:31 +06:00
Shannon Deminick ff5dc324fe Fixes: #U4-227 - ensures data is not persisted to the db for members/media if validation fails.
Fixes up (enables) validation summary for members too.
2013-04-17 22:41:43 +06:00
Shannon Deminick 096c5ad69f Fixes: #U4-485, changes name field from saving to the db if it is empty. cleans up some code. 2013-04-17 22:05:10 +06:00
Sebastiaan Janssen eba7582a97 Eh, yeah, maybe I should start with making a copy of the element first.. d'oh! 2013-04-17 11:16:15 -02:00
Sebastiaan Janssen 0cf2a1fc2a Possible fix for U4-2097 Package import causes template tree to break - modified
closure problem
2013-04-17 10:57:24 -02:00
Sebastiaan Janssen 77ee87178e Merge 2013-04-17 07:04:04 -02:00
Sebastiaan Janssen a6997a5cb7 Revert U4-1922 to resume expected sorting behavior. 2013-04-17 07:03:18 -02:00
Shannon Deminick ff3fc5d825 Merge with 4.11.7 2013-04-17 01:56:20 +06:00
Stephan 3b9bf7b0f9 U4-2117 - fix Ancestor- vs AncestorsOrSelf inconsistencies 2013-04-16 12:58:03 -02:00
Stephan 3882e1984d U4-2117 - fix Ancestor- vs AncestorsOrSelf inconsistencies 2013-04-16 12:29:58 -02:00
Sebastiaan Janssen b32ea68fd0 Merge with 4.11.7 2013-04-15 07:36:58 -02:00
Sebastiaan Janssen eb2db791b8 Additional fix for U4-2105 Saving a document will make it look like it is unpublished 2013-04-15 07:33:26 -02:00
Sebastiaan Janssen 158f4d0614 Merge 2013-04-15 07:32:00 -02:00
Sebastiaan Janssen 7a38970cf4 U4-2109 Regex text-field in DocTypes > (a type) > Properties (a property) >
Validation + Description lack Trimming
2013-04-15 07:31:24 -02:00
Sebastiaan Janssen 7f6d8b6bdd Fixes U4-2105 Saving a document will make it look like it is unpublished 2013-04-12 06:49:06 -02:00
Shannon Deminick 22fb7e1706 Merge 2013-04-12 03:07:53 +06:00
Shannon Deminick 12b1168de9 Fixes merge issues 2013-04-12 02:59:03 +06:00
Shannon Deminick 01290f8174 Merge with 4.11.7 2013-04-12 02:14:59 +06:00
Shannon Deminick 26a7bf8187 Fixes: #U4-2087 2013-04-12 02:11:01 +06:00
Sebastiaan Janssen ba1d0fa193 Improve code for previous fix so we don't need the try/catch any more. 2013-04-11 16:36:26 -02:00
Sebastiaan Janssen 97355bde6f Fixes U4-2091 Inserting image in RTE with mediatype "File" causes YSOD 2013-04-11 13:15:08 -02:00
Sebastiaan Janssen ed35f234de Fixes U4-2100 Media Doesn't Overwrite in 6.0.3 2013-04-11 12:27:11 -02:00
Sebastiaan Janssen c874fa6507 Fixes U4-2097 Package import causes template tree to break 2013-04-11 10:20:17 -02:00
Sebastiaan Janssen ba387598ed Merge with 4.11.7 2013-04-11 07:17:23 -02:00
Sebastiaan Janssen 3ff1b01e46 Add DotSettings file for custom code inspections. In this case: Replace
!someBool with an explicit false check (someBool == false) for readability.
2013-04-11 07:15:06 -02:00
Shannon Deminick 36e803713c Fixed up some code in UmbracoEnsuredPage and moveOrCopy 2013-04-11 02:15:48 +06:00
Shannon Deminick a3e7f644de merges changes for UmbracoHelper from 6.0.x to deal with null objects when using Content method (dynamic) 2013-04-10 22:51:19 +06:00
Sebastiaan Janssen 1586f1679a Merge with 4.11.7 2013-04-10 11:54:24 -02:00
Sebastiaan Janssen 809badd1cf Update version to 4.11.7 2013-04-10 08:54:31 -02:00
Sebastiaan Janssen da92ece774 Update version to 4.11.7 2013-04-10 07:57:56 -02:00
Sebastiaan Janssen a531afb819 Don't need IronPython license any more either. 2013-04-10 07:46:05 -02:00
Sebastiaan Janssen 1d6009e3c7 Merge with 4.11.7 2013-04-10 07:42:21 -02:00
Sebastiaan Janssen 8dfeb1e616 Cleanup solution and folders, removes Linq2Umbraco and IronPython engine from
the project as we don't ship with them any more. Updated readme and docs.
2013-04-10 07:30:14 -02:00
Shannon Deminick 1b086e2267 fixes merge issue 2013-04-10 04:04:33 +06:00
Shannon Deminick 1f86d8c562 fixes merge issues 2013-04-10 03:56:10 +06:00
Shannon Deminick 25b9262cf1 Merge with 4.11.7 2013-04-10 03:51:53 +06:00
Shannon Deminick 1012a4814d updates #U4-2070 for tiny mce plugins 2013-04-10 03:22:11 +06:00
Shannon Deminick bae41cde14 updates #U4-2070 for skin module files in live editing 2013-04-10 03:16:26 +06:00
Shannon Deminick b3260f05c0 updates #U4-2070 for templateskinning.aspx 2013-04-10 03:05:57 +06:00
Shannon Deminick e33a79ac65 updates #U4-2070 for insertMasterpageContent.aspx 2013-04-10 03:02:10 +06:00
Shannon Deminick c4dbabf654 updates #U4-2070 for translation/xml.aspx and translation/preview.aspx 2013-04-10 02:59:47 +06:00
Shannon Deminick 423643d66c updates #U4-2070 for tinymce3/insertmacro.aspx 2013-04-10 02:46:11 +06:00
Shannon Deminick 4ccb655f73 updates #U4-2070 for members/search.aspx 2013-04-10 02:43:03 +06:00
Shannon Deminick c8330d60f9 updates #U4-2070 for sendToTranslation.aspx 2013-04-10 02:41:22 +06:00
Shannon Deminick a9aa3a04b5 updates #U4-2070 for search.aspx 2013-04-10 02:39:32 +06:00
Shannon Deminick 0bffa8e3f4 updates #U4-2070 for preview.aspx 2013-04-10 02:35:31 +06:00
Shannon Deminick 436322f58c updates #U4-2070 for directoryBrowser.aspx 2013-04-10 02:34:44 +06:00
Shannon Deminick e90c46dd78 updates #U4-2070 for canvas.aspx 2013-04-10 02:33:08 +06:00
Shannon Deminick deda2534f8 updates #U4-2070 for SendPublish.aspx 2013-04-10 02:30:53 +06:00
Shannon Deminick 8112c13857 updates #U4-2070 for insertMacro.aspx 2013-04-10 02:28:50 +06:00
Shannon Deminick 57792de185 updates #U4-2070 for imageViewer.aspx 2013-04-10 02:21:59 +06:00
Shannon Deminick e1f93029a5 updates #U4-2070 for assigndomain.aspx 2013-04-10 02:19:29 +06:00
Shannon Deminick f64e0c7eb7 updates #U4-2070 for autodoc.aspx 2013-04-10 02:17:02 +06:00
Shannon Deminick bf024e9011 updates #U4-2070 for assemblyBrowser.aspx 2013-04-10 02:14:13 +06:00
Shannon Deminick 036b888d30 updates #U4-2070 for ShowUmbracoTags.aspx 2013-04-10 02:08:56 +06:00
Shannon Deminick 1838a8dac5 updates #U4-2070 for NewRelationType.aspx 2013-04-10 02:07:16 +06:00
Shannon Deminick 205bf5fe4e updates #U4-2070 for EditRelationType.aspx 2013-04-10 02:05:52 +06:00
Shannon Deminick a50e192ab7 updates #U4-2070 for sort.aspx 2013-04-10 02:03:04 +06:00
Shannon Deminick 9684255e6e ensures validation is correct in editContent, cleans up some code. 2013-04-10 01:58:22 +06:00
Shannon Deminick 72790d74f5 Fixes: #U4-2072 and cleans up some code. 2013-04-10 01:47:17 +06:00
Shannon Deminick bb70bee6ae Fixes: #U4-2071 and cleans up some code. 2013-04-10 01:42:15 +06:00
Shannon Deminick 0430e7966c Fixes: #U4-2074 and cleans up a bit of code 2013-04-10 01:24:06 +06:00
Shannon Deminick 2e9a52b1f8 Fixes: #U4-2075 2013-04-10 00:56:43 +06:00
Sebastiaan Janssen db4ed70d70 Merge with 4.11.7 2013-04-09 11:37:37 -02:00
Sebastiaan Janssen e6ccd8a5b5 Fix for U4-2081 tinymce Image picker does not work in 6.03 2013-04-09 11:33:35 -02:00
Sebastiaan Janssen a9781d79e2 Merge with 4.11.7 2013-04-09 10:22:11 -02:00
Sebastiaan Janssen 7ae8b28466 Fix the medium trust error in the about box 2013-04-09 10:20:34 -02:00
Sebastiaan Janssen 29a4cb8b71 Fixes merge issues 2013-04-09 08:34:03 -02:00
Sebastiaan Janssen ffb39de003 Merge with 4.11.7 2013-04-09 07:55:54 -02:00
Sebastiaan Janssen 527375b238 Fixes U4-2052 Creating a new document type has a bin icon by default
Also deals better with pre-existing selected id's before switching the behaviour
2013-04-09 07:49:22 -02:00
Sebastiaan Janssen a4ed0e266c Merge with 4.11.7 2013-04-09 07:11:54 -02:00
Sebastiaan Janssen 1929f60ea8 Update the webservices version 2013-04-09 07:10:24 -02:00
Sebastiaan Janssen b9cc2efc8c Add authentication to creating templates in webservices 2013-04-09 07:07:13 -02:00
Shannon Deminick eadb1bb194 Fixes merge issues 2013-04-09 07:54:32 +06:00
Shannon Deminick 30be665a40 Merge with 4.11.7 2013-04-09 07:41:55 +06:00
Shannon Deminick bad284515c Fixes: #U4-2076 2013-04-09 07:32:13 +06:00
Shannon Deminick 5b660d95f1 Fixes: #U4-2077 2013-04-09 07:26:21 +06:00
Shannon Deminick 106ac44e64 Fixes: #U4-2073 2013-04-09 07:23:33 +06:00
Shannon Deminick 64bb7e1db0 Fixes up an app check 2013-04-09 07:14:58 +06:00
Shannon Deminick 25b9ca3b0e Works on #U4-2078 - adds new base classes for HttpHandlers just like for web services. 2013-04-09 07:01:43 +06:00
Shannon Deminick b928170103 Works on #U4-2078 2013-04-09 06:40:02 +06:00
Shannon Deminick e25ee246fb Works on #U4-2078 2013-04-09 06:31:26 +06:00
Shannon Deminick 8e8ec41dae Works on #U4-2078 2013-04-09 06:25:47 +06:00
Shannon Deminick fb34c4716a Works on #U4-2078 2013-04-09 06:18:15 +06:00
Shannon Deminick 29bf61b1f2 Starts on #U4-2078, mostly just some initial code cleanup 2013-04-09 06:07:25 +06:00
Shannon Deminick 9803309e34 imports patch from 846d845a5a87 since it belongs in the main dev branch. 2013-04-09 05:04:57 +06:00
Shannon Deminick 3a539629dc imports patch from ed6939e5927f since that fix belongs in the main dev branch 2013-04-09 05:04:21 +06:00
Shannon Deminick 74b970d586 Fixes: #U4-529 - Created 2 base classes for web services - UmbracoWebService and UmbracoAuthorizedWebService for use in
creating asmx classes. This makes it easier to authenticate/authorize per app and also exposes Umbraco standard
objects like UmbracoContext, ApplicationCOntext, etc...
2013-04-09 05:00:22 +06:00
Shannon Deminick 518898b04b Merge 2013-04-09 01:09:27 +06:00
Sebastiaan Janssen a773e0a018 Merge with 4.11.7 2013-04-08 06:56:43 -02:00
Sebastiaan Janssen 99fe89addc Fix U4-1864 the same way as in 6.0.x 2013-04-08 06:55:48 -02:00
Sebastiaan Janssen 668d4f9f91 Fixes U4-1864 Publishing document type with Upload field and related
umbracoWidth, umbracoHeight, etc fields added
2013-04-08 05:59:02 -02:00
Shannon Deminick 90e73cb89f cleans up some code in codeEditorSave 2013-04-06 01:59:28 +06:00
Shannon Deminick dcd6477030 Removes un-needed ShowUmbracoTags files from legacy files. 2013-04-06 01:54:41 +06:00
Shannon Deminick 13b73231de Merge with 4.11.7 2013-04-06 01:45:45 +06:00
Shannon Deminick 50a70c28df Merge 2013-04-06 01:45:30 +06:00
Shannon Deminick 7d5589118f Merge 2013-04-06 01:43:41 +06:00
Shannon Deminick c39b698d4c Merge with 4.11.7 2013-04-06 00:31:10 +06:00
Shannon Deminick 103efbdc27 removes config check on p.aspx since we need it to show the feeds when installer is done. 2013-04-06 00:30:37 +06:00
Shannon Deminick 3d51dd767b Fixed merge issues. 2013-04-06 00:27:44 +06:00
Shannon Deminick e22988e435 Merged with 4.11.7 2013-04-06 00:21:06 +06:00
Shannon Deminick 9736aaafaa Fixes authorize issue with insertchar.aspx 2013-04-06 00:09:43 +06:00
Shannon Deminick bf3fa20a53 Cleaned up the code fro rsd and wlwmanifest and ensures wlwmanifest actually returns the results in xml format. 2013-04-06 00:04:23 +06:00
Shannon Deminick f936f8b0dd updates install utility to throw exception if the app is configured already. 2013-04-05 23:40:02 +06:00
Shannon Deminick 1bd20c9b06 Fixes: #U4-2059 and removes un-needed ping.aspx files, cleans up some code 2013-04-05 23:28:43 +06:00
Shannon Deminick 099b713947 Fixed ValidateProxyUrl to check for invalid Urls. 2013-04-05 22:29:45 +06:00
Shannon Deminick 165d9c7dff Fixed nonodes to now show version information and updated it so that it redirects to root if there
is actually content so the page is actually not accessible unless you actually have no nodes.
2013-04-05 21:58:13 +06:00
Stephan 09400be6e0 U4-2030 - failed to update UmbracoContext on some devt webservers 2013-04-05 10:28:19 -02:00
Stephan 7934ba7ec4 U4-2030 - failed to update UmbracoContext on some devt webservers 2013-04-05 10:28:19 -02:00
Shannon Deminick 7edbc34e6c Merge with 4.11.7 2013-04-05 06:46:13 +06:00
Shannon Deminick 60b6608289 patch for fix #U4-2027 2013-04-05 06:42:52 +06:00
Morten Christensen 792599a42f Minor correct to the doc.SaveAndPublish method. 2013-04-04 12:20:50 -02:00
Morten Christensen 7610ee5f8b Adding event proxies to the ContentService for publishing events for easier discoverability.
Fixes U4-2046
2013-04-04 07:16:33 -02:00
Morten Christensen eab9be4ef7 Fixing issue with reimporting document types and the structure of allowed doc types.
Removing old code from Installer.
2013-04-04 06:02:08 -02:00
Shannon Deminick e48a030aab Merge 2013-04-04 05:46:01 +06:00
Morten Christensen e207b1f1e1 Adds new test case for single doc type imports.
Corrects issue with installing/importing single or multiple doc types, which is not part of the usual complete package xml.
2013-04-03 18:26:54 -02:00
Shannon Deminick fd3540f92d Removes unused private method 2013-04-03 20:40:06 +06:00
Shannon Deminick b9d7f0c5a5 Fixes merge issues, merge ensures that js error is fixed and that thread-safe caching is in place
in the ContentType.cs class.
2013-04-02 22:06:15 +06:00
Shannon Deminick 3d76614a78 Merge with 4.11.7 2013-04-02 21:31:21 +06:00
Sebastiaan Janssen de0e6f3179 Merge 2013-04-02 08:08:31 -02:00
Sebastiaan Janssen 39edb9b7e2 Fixes U4-2032 Preview for an RTE field shows published content instead of actual
preview
2013-04-02 08:07:18 -02:00
Shannon Deminick a638488eb7 Fixes unit tests which require the ApplicationContext.Current singleton to be setup 2013-04-01 23:30:19 +06:00
Shannon Deminick a2a539f7db Merge 2013-04-01 23:12:47 +06:00
Shannon Deminick 6768bb4793 Fixes: #U4-1874 - merges in thread-safe fixes for static object caching from 6.1 and cleans up
a bunch of the code in ContentType.cs. Back ports fixes for Languages.cs from 6.1 and cleans up code.
2013-04-01 23:12:17 +06:00
Sebastiaan Janssen 19c2841576 Fixes U4-535 Stylesheet content gets deleted if you change case 2013-04-01 14:27:20 -02:00
Sebastiaan Janssen 71aa248a4e Fixes U4-535 Stylesheet content gets deleted if you change case 2013-04-01 14:27:20 -02:00
Sebastiaan Janssen eeaef5ac5c Merge 2013-04-01 11:51:48 -02:00
Sebastiaan Janssen bea50f4562 Fixes: U4-662 Most icon for document type can't be shown in 4.8.1. 2013-04-01 11:50:27 -02:00
Sebastiaan Janssen ff337457f8 Fixes: U4-662 Most icon for document type can't be shown in 4.8.1. 2013-04-01 11:31:03 -02:00
Morten Christensen 49b5ddf850 Refactor of fix for U4-2014 2013-03-31 18:17:01 -02:00
Shannon Deminick b449b8762b Merge 2013-03-29 23:53:08 +06:00
Shannon Deminick 13e555f50b Fixed merge issue based on overlap with class + namespace name. 2013-03-29 23:52:40 +06:00
Shannon Deminick 48c809a797 Merge with 4.11.7 2013-03-29 23:22:18 +06:00
Shannon Deminick 55c7f72d8e Converts create.aspx to have the correct webforms file/class structure, fixed logging for userTask,
fixed issue with last regex fix for xss
2013-03-29 23:14:42 +06:00
Sebastiaan Janssen 8612113fc0 Merge 2013-03-29 15:02:43 -01:00
Sebastiaan Janssen 69b0c7cf09 Fixes: U4-2024 Umbraco 6.0.3 : Error while importing Document Type 2013-03-29 15:01:04 -01:00
Shannon Deminick 37a97a2e7c Merge with 4.11.7 2013-03-29 21:34:56 +06:00
Shannon Deminick 5f4eaef4a2 Fixes: #U4-2022 2013-03-29 21:31:27 +06:00
Sebastiaan Janssen 44f5c3a34f Fixes U4-2019 Create new Document Type dialog displays poorly in Chrome 2013-03-29 09:13:44 -01:00
Sebastiaan Janssen a33ae696a2 Fixes U4-2014 Can't install XSLTSearch 3.0.4 with Umbraco 6.0.3
Updated the topological sorter to only add items that exist in the indexes
2013-03-29 08:46:09 -01:00
Sebastiaan Janssen 2705efb809 Updated file for WebPI builds 2013-03-29 08:34:34 -01:00
Sebastiaan Janssen 648d631151 Opening new branch 2013-03-27 14:48:13 -01:00
Sebastiaan Janssen 27c0c4d64e Opening new branch 2013-03-27 14:47:35 -01:00
Sebastiaan Janssen 52cf559536 Closing 4.11.6 branch 2013-03-27 12:00:18 -01:00
Sebastiaan Janssen c9b0362c62 Closed 6.0.3 branch 2013-03-27 11:54:12 -01:00
Sebastiaan Janssen 11e5bdf556 Added tag release-6.0.3 for changeset aed55cba2900 2013-03-27 11:14:18 -01:00
Sebastiaan Janssen 3d0be3836c Added tag release-4.11.6 for changeset 14338b0ab173 2013-03-27 11:13:56 -01:00
Sebastiaan Janssen 2bc33e0115 Merge 2013-03-27 08:58:34 -01:00
Sebastiaan Janssen 8576d9c67e Bump version to 4.11.6 2013-03-27 08:56:30 -01:00
Shannon Deminick a0651f4383 Merge with 4.11.6 2013-03-27 03:09:36 +06:00
Shannon Deminick 9452d5fd09 adds patch for #U4-1754 and updates 2013-03-27 03:08:37 +06:00
Shannon Deminick 1f40d726de adds patch for #U4-1754 2013-03-27 02:59:42 +06:00
Shannon Deminick 2699611ba3 adds patch for #U4-1754 2013-03-27 02:58:59 +06:00
Shannon Deminick 43795f0007 Merge with 4.11.6 2013-03-26 22:03:23 +06:00
Shannon Deminick b1fa06bfe8 Removes unused code. 2013-03-26 22:02:49 +06:00
Shannon Deminick 4dc22b6ce4 Applies patch for #U4-497 for getting exceptions for xslt 2013-03-26 22:02:08 +06:00
Sebastiaan Janssen d4ab60f8af Merge with 4.11.6 2013-03-26 13:29:45 -01:00
Sebastiaan Janssen 883277125a Can't use parameters here as the query gets butchered. 2013-03-26 13:27:46 -01:00
Sebastiaan Janssen 8edfc0ffdd Merge with 4.11.6 2013-03-26 09:53:59 -01:00
Sebastiaan Janssen ff961abaab Actual fix for U4-1987 Error when attempting to save document type 2013-03-26 09:50:48 -01:00
Sebastiaan Janssen b2414c1ab8 Fixes U4-1987 Error when attempting to save document type 2013-03-26 09:33:08 -01:00
Sebastiaan Janssen 9dde86d591 Fixes U4-1999 When copying content with subcontent, the new subcontent data is a
direct reference to the old.
2013-03-26 08:39:50 -01:00
Sebastiaan Janssen b4ce4fbdef Logging warning when package installer can't create a property due to a missing
datatype for that property
2013-03-26 07:55:43 -01:00
Sebastiaan Janssen 4285484c1b Update code comment 2013-03-26 07:19:39 -01:00
Sebastiaan Janssen 2fd299ebfc Change TinyMCE to use the mediaservice to get the original image + some updates
to the new mediaservice method.
2013-03-26 07:15:22 -01:00
Morten Christensen f545f293b1 Adding GetMediaByUrl method to MediaService cause Sebastiaan needs it for less hacky code. 2013-03-26 05:46:20 -01:00
Sebastiaan Janssen b745c0ae90 If the image is not resized, there's probably not going to be an underscore,
just query for the whole image source then.
2013-03-25 18:18:14 -01:00
Sebastiaan Janssen f2efff5411 Temporary fix until we can fix this properly for U4-1812 - Changing Width or
Height in Insert Picture popup results in NaN in other dimension
2013-03-25 18:09:31 -01:00
Sebastiaan Janssen 9ef5890636 Changing sortorder on tabs now also re-orders the tabs in the contenttype editor 2013-03-25 13:33:32 -01:00
Sebastiaan Janssen bc9fd04a36 Related to U4-1847 - Tabs weren't imported with the correct sort order and when
a datatype can't be found we should silently fail and not create the property
that wants that datatype (that's how v4 did it).
2013-03-25 12:49:43 -01:00
Sebastiaan Janssen 185c5d78f1 Query changed due to fix fe02cef72d87 that uses 1/0 instead of True/False 2013-03-25 11:27:54 -01:00
Brian Powell 3ea9963166 Fixes U4-1904 / U4-1905 2013-03-25 10:39:35 -01:00
Sebastiaan Janssen ab40822a98 Fix merge issue by re-applying Stephen Roberts' patch 2013-03-25 10:30:55 -01:00
Sebastiaan Janssen dffce76e29 Merge with 4.11.6 2013-03-25 10:24:36 -01:00
Sebastiaan Janssen d1e02f506c PropertyGroupId can be null 2013-03-25 07:51:44 -01:00
Morten Christensen 5e18d13178 Fixing parsing issue with saving boolean values in the Integer column for Members.
Related to issue U4-1989
2013-03-23 07:22:43 -01:00
Shannon Deminick 1dfca6836d Merge with 4.11.6 2013-03-23 02:34:59 +06:00
Shannon Deminick dbbdd16bb9 Fixes: #U4-497 2013-03-23 02:34:34 +06:00
Shannon Deminick 74362fba23 Merge 2013-03-22 22:11:26 +06:00
Morten Christensen 112502cf18 Fixes U4-547 2013-03-22 15:09:36 -01:00
Shannon Deminick 1db7f808c9 Merge with 4.11.6 2013-03-22 21:59:52 +06:00
Shannon Deminick 762cca145f Fixes: #U4-1931 - allow empty string in dictionary item. 2013-03-22 21:59:21 +06:00
Morten Christensen 65dc5eaeee Corrects incorrect sql query in the ContentTypeBaseRepository and looping through property types in the DataTypeService.
Adds initial test fixture for the DataTypeService.
Fixes U4-1939
2013-03-22 14:54:44 -01:00
Morten Christensen 4f81e06d3d Fixes U4-1894 by ensuring that all overloads of SetValue uses the IOHelper.SafeFileName 2013-03-22 14:18:45 -01:00
Morten Christensen 6b74b75b6f Adding a few checks to ensure that we don't try to bulk save an empty list 2013-03-22 14:08:20 -01:00
Morten Christensen 98e53b3d74 Correcting a few checks for multiple or single item imports in the PackagingService 2013-03-22 13:58:21 -01:00
Morten Christensen a1f01f9d5c re-inverting the check for existing datatypedefinitions in the packaging service 2013-03-22 13:48:51 -01:00
Sebastiaan Janssen f5d8cb0275 Merge 2013-03-22 13:36:26 -01:00
Sebastiaan Janssen 0d8b65caea Merge 2013-03-22 13:36:04 -01:00
Sebastiaan Janssen 70285991bb I think this was an oversight, if a definition is NOT null, then fill it 2013-03-22 13:35:47 -01:00
Sebastiaan Janssen a336eaa4a1 Check all of the elements for null, apparently any kind of installable thing can
be missing from the install xml file
2013-03-22 13:35:19 -01:00
Morten Christensen fdefe993b7 Fixes U4-1990 2013-03-22 12:54:46 -01:00
Morten Christensen ba0e72a1c1 Fixes U4-1937 by calling save when media is updated with new properties. Also uses the incremented folder count instead of the property id. 2013-03-22 12:30:20 -01:00
Morten Christensen c5710277a5 Redoing the fix for U4-1875 2013-03-22 12:13:06 -01:00
Morten Christensen 5cd2d568e3 Fixes U4-1938 by actually calling and checking the Before/AfterDelete events for DataTypeDefinitions.
Backported from 32fb51f603a3
2013-03-22 11:12:32 -01:00
Morten Christensen 9c89a56d8d Fixes U4-1938 by actually calling and checking the Before/AfterDelete events for DataTypeDefinitions. 2013-03-22 10:53:07 -01:00
Morten Christensen 9ba7664f78 Updating repositories to handle sort order upon updating in a consistent manner.
Related to U4-1828
2013-03-22 10:34:05 -01:00
Morten Christensen 4b87a5c2d3 Adding safe alias cast to Templates.
Updating doc type create dialog to verify alias before saving.
Updating ContentTypeRepository to Mandate that the alias is not empty.
Fixes the cause for U4-1976
2013-03-22 09:56:21 -01:00
Morten Christensen f0699afb6e Fixes U4-1974 2013-03-21 18:45:06 -01:00
Morten Christensen b4d5658d45 Fixes U4-1828 by correctly incrementing the sortorder ... doh! 2013-03-21 17:34:08 -01:00
Morten Christensen d485c3da97 Fixes U4-1875 by correcting the Creating events in the ContentService and MediaService, so null is returned if the creation of an object is cancelled.
In the legacy Document and Media classes we check if the created object is null to determine if the event has been cancelled through the new api.
2013-03-21 16:09:45 -01:00
Morten Christensen 1214082997 Fixes U4-1883 by setting the Document/Media UpdateDate property in the Save/SaveAndPublish methods 2013-03-21 14:56:50 -01:00
Morten Christensen 1a56e6693a Removing dictionary from DataTypeDefinition as it wasn't used.
Updating package xml to include DatabaseType for testing.
2013-03-21 14:50:39 -01:00
Morten Christensen c6b7f20dab Fixes U4-1849 by introducing a new attribute for packaged DataTypes, so it stores information about the database type.
Will still default to Ntext, but seeing as the database type has never been used before it always defaulted to Ntext.
2013-03-21 14:40:17 -01:00
Morten Christensen 5cc55ad6e2 Fixing U4-1948 by setting the Published property when using document.Publish so updating the cache won't be skipped. 2013-03-21 13:51:45 -01:00
Morten Christensen a55fedab0a Adding a few checks to ensure package installation doesn't fail when properties are not present in the xml. 2013-03-21 13:40:54 -01:00
Morten Christensen 0e12f14a4a Making the export method internal until its been properly implemented 2013-03-21 13:10:31 -01:00
Morten Christensen 3e25b71d9e Updating test for adding PropertyType outside a group to use the proper method for doing so. 2013-03-21 12:58:55 -01:00
Morten Christensen 63de9e6691 Refactoring package installer to use the new PackagingService.
Refactoring ImportDocumentType dialog to import through the PackagingService.
Making a few corrections to the ProppertyGroup and PropertyType classes to support bulk saving.
2013-03-21 12:34:10 -01:00
Morten Christensen b9ea85d29d Updating Template to have a lazy master template id.
Adding a few new methods to the DataTypeService, which were needed for the import of DataTypes.
Adding bulk saving of templates.
Adding TopologicalSorter for sorting dependencies.
Implementing import of DataTypes and Templates.
Renaming the import test fixture for consistency after having creating the PackagingService.
2013-03-20 20:31:44 -01:00
Morten Christensen d0787e92fe Implementing PackagingService and moving Import Export methods to this service to have it specialized and centralized around packaging operations. 2013-03-20 13:51:46 -01:00
Morten Christensen ffe9953c43 Merge 2013-03-19 20:08:40 -01:00
Morten Christensen 99a9f1ab87 Adding note to mediaService regarding issue U4-1937 2013-03-19 20:06:33 -01:00
Morten Christensen 7def26a489 Implementing import methods in the Content- and ContentType services.
Adding tests to verify import is correct.
2013-03-19 20:05:55 -01:00
Shannon Deminick a76ffe8daf Backported changes from 6.1 to fix how RePublishAll behaves in the content service to ensure its the same as what was done with
Document.RePublishAll
2013-03-20 00:19:36 +06:00
Sebastiaan Janssen 259fbcb8f0 Fixed U4-1934 Error in comments of config files 2013-03-18 08:50:24 -01:00
Shannon Deminick ee9f91b5cf Merge with 4.11.6 2013-03-15 11:31:34 +06:00
Shannon Deminick db3f21429e Fixes infinite loop bug with string trimming. 2013-03-15 11:31:11 +06:00
Shannon Deminick 033692d7ee had some strange issues with unit tests, added error checks. 2013-03-15 08:26:49 +04:00
Shannon Deminick 23146cb12a Merge with 4.11.6 2013-03-15 08:06:26 +04:00
Shannon Deminick 04b9607741 Fixes: #U4-1916 and another issue for vdirs, added unit tests, changed UI web project to always
launch in a VDIR.
2013-03-15 08:03:19 +04:00
Stephen Roberts 0e392b398c Fixed Property order for document types with Master document types. 2013-03-14 11:08:02 +00:00
Sebastiaan Janssen 5914690ad8 Allow leading sign in number field so that negative numbers are supported 2013-03-25 10:09:02 -01:00
Morten Christensen c4aa9095f2 Fixes U4-1858 by ensuring that the text field is reset before setting or removing a value 2013-03-13 20:24:21 -01:00
Morten Christensen 79ce586c8b Fixes U4-1808 by removing the database lookup from an id that was resolved from the media url 2013-03-13 19:26:22 -01:00
Morten Christensen 8fba03c05d Fixes U4-1863 and U4-1908 by ensuring that content and media are loaded in the same manner through the new api 2013-03-13 18:55:25 -01:00
Shannon Deminick 2fdcb9164a Fix merge issues 2013-03-12 00:19:06 +04:00
Shannon Deminick 7404a1f93d Merge with 4.11.6 2013-03-12 00:14:50 +04:00
Shannon Deminick c8b8b28e9b applies patch for #U4-1890 2013-03-12 00:10:59 +04:00
Shannon Deminick 5bd2571395 Merge 2013-03-12 00:01:14 +04:00
Shannon Deminick c0cd157e60 applies patch for #U4-1890 2013-03-12 00:00:55 +04:00
Sebastiaan Janssen ac2f9b172c .transformed files are auto-generated and shouldn't be under source control 2013-03-11 17:15:30 -01:00
Sebastiaan Janssen b8e4a73c3b Revert Casey's mistakenly added files 2013-03-11 15:55:35 -01:00
Shannon Deminick 63192f3a65 Merge 2013-03-11 22:04:06 +06:00
Shannon Deminick 727f62d418 Merge with 4.11.6 2013-03-11 21:49:27 +06:00
Shannon Deminick 68c4255a51 updates proper error handling for razor script macros 2013-03-11 21:49:04 +06:00
Shannon Deminick 187af3e361 Fixed merge issue 2013-03-11 21:23:35 +06:00
Shannon Deminick c6f29a50d6 Merge with 4.11.6 2013-03-11 21:17:57 +06:00
Shannon Deminick d07212c89b Fixed changes with new MacroErrors config and how macros are rendered so it supports all macro types and also fixes up a bit of code
in the umbraco.macro class.
2013-03-11 21:06:02 +06:00
Shannon Deminick 28c55320a1 Updates the pull request for handling macro errors.
Backports fixes for partial view macros from 6.x - U4-1488, U4-1844, U4-1730, U4-1843
2013-03-11 20:11:11 +06:00
Morten Christensen cb0dd70434 Minor change to the SqlSyntaxProvidersResolver in the CoreBootManager as per Shannons review. 2013-03-11 12:44:12 -01:00
Shannon Deminick fd58017e97 imported patches for pull request spudstuff/u4497 2013-03-11 18:49:45 +06:00
Morten Christensen 928d92fce4 Making the Sql Syntax Providers public and changing a few names and bits for consistency.
Adding resolver for the syntax providers and wiring it up in the boot manager.
2013-03-09 10:43:34 -01:00
Casey Neehouse 09408b898e Merge 2013-03-08 19:38:33 +05:00
Morten Christensen d1b05332c5 Manually adds fix for U4-1869 from 6.0.3 branch 2013-03-07 20:28:13 -01:00
Morten Christensen 836b0f39c2 Additional correction of the implementation for U4-1869 2013-03-07 20:19:39 -01:00
Morten Christensen 1b01386673 Changing the initial fix of U4-1869 to use UrlReplacingCharacters 2013-03-07 19:56:59 -01:00
Morten Christensen 2a09f02afb Fixing incorrect sql syntax when the query contains two expressions. 2013-03-07 19:56:10 -01:00
Morten Christensen ee95434cea Implements U4-1869 by adding the 3 characters to the list of reserved characters. 2013-03-07 19:04:25 -01:00
Casey Neehouse caad0afed8 Corrects u4-1870 - Refactor Load Content SQL to check if ID is in published list
versus using a join that can cause duplicate entries.
2013-03-07 21:00:31 +05:00
Morten Christensen fe08e7fc2f Fixes U4-1865 by excluding trashed items from GetByLevel method for both Content and Media 2013-03-07 13:42:14 -01:00
Morten Christensen 4ad96b49e7 Fixes U4-1862 2013-03-07 13:35:17 -01:00
Morten Christensen 9a1bb4a2dd Adding unit test to assert issue with issue with creation of property types outside a property type group.
Fixes U4-1861.
2013-03-07 13:33:22 -01:00
Sebastiaan Janssen c39f902ed5 And one more fix for U4-1845 to make upgrades succeed as well 2013-03-06 14:30:09 -01:00
Sebastiaan Janssen b7dc052cb2 Additional fixes for U4-1845 to maintain compatibility for people using the
wrong connection string
2013-03-06 14:09:01 -01:00
Morten Christensen 0c77114cd5 Fixes U4-1845 by correcting the sql ce connectionstring 2013-03-06 13:36:03 -01:00
Morten Christensen 222a5237b0 Version updated to 6.0.3 2013-03-06 12:03:01 -01:00
Morten Christensen de55cb8392 Correcting fix for U4-1835 2013-03-06 08:32:05 -01:00
Morten Christensen df164ee618 Fixes U4-1835 by checking if the value is null before running the regex validation against the value. 2013-03-06 08:02:09 -01:00
Morten Christensen 21b0687a57 Fixes U4-1837 by syncing tree after saveing DataTypeDefinition 2013-03-06 07:57:00 -01:00
Morten Christensen 9310efa280 Fixes U4-1831 by catching exception if there is no current logged in user. 2013-03-06 07:54:09 -01:00
Morten Christensen a41b55a9e6 Fixes U4-1846 2013-03-06 07:50:20 -01:00
Morten Christensen af2d8a4755 Fix related to U4-1407 but for Media. We already committed this fix for Content. 2013-03-06 07:49:29 -01:00
Shannon Deminick d48e339b81 Fixes: #U4-1844, #U4-1730, #U4-1843 2013-03-06 04:12:28 +06:00
Shannon Deminick 9b6d498cf7 Merge with 4.11.6 2013-03-06 03:17:47 +06:00
Shannon Deminick 62d365573f Back ports fixes for: #U4-1614, #U4-793 - preview working properly in mvc 2013-03-06 03:17:18 +06:00
Shannon Deminick 04bf011fcd Merge with 4.11.6 2013-03-05 23:55:09 +06:00
Shannon Deminick f3b7a8a581 Fixes: #U4-1471 - issue with having NewRelic installed and some sort of conflict with shutting down
our logger.
2013-03-05 23:49:45 +06:00
Shannon Deminick 5d62902684 Fixes up the double event for MakeNew on document (#U4-1737) 2013-03-05 22:34:31 +06:00
Shannon Deminick 82d645a0f7 Merge with 4.11.6 2013-03-05 22:18:53 +06:00
Shannon Deminick a8936de638 Fixes: #U4-1834 2013-03-05 21:52:22 +06:00
Shannon Deminick a765f36d24 Adds unit tests for DynamicNode and DynamicPublishedContent, fixes both when querying for recursive properties.
Fixes: #U4-1839
2013-03-05 21:00:16 +06:00
Shannon Deminick 6b691eb461 Merge with 4.11.6 2013-03-05 08:34:14 +06:00
Shannon Deminick 046da1a8ce Fixes: #U4-1824 - issue with razor dynamic node property access performance enhancements. 2013-03-05 07:06:41 +06:00
Shannon Deminick ca7abd6c78 Merge 2013-03-05 06:08:59 +06:00
Shannon Deminick 452688b2bb Merge with 4.11.6 2013-03-05 05:57:35 +06:00
Shannon Deminick 7cc0f2a514 Fixes: #U4-1819 2013-03-05 05:56:53 +06:00
Sebastiaan Janssen a2251fe062 Created branch 6.0.3 2013-03-04 10:19:22 -01:00
Sebastiaan Janssen 3d0684eac0 Closing branch 6.0.2 2013-03-04 10:18:18 -01:00
Sebastiaan Janssen a8fafaa194 Added tag Release-6.0.2 for changeset b247b35d8211 2013-03-04 10:18:08 -01:00
371 changed files with 18967 additions and 8114 deletions
+1
View File
@@ -44,6 +44,7 @@ src\Umbraco.Web.UI\[Mm]acro[Ss]cripts\*
src\Umbraco.Web.UI\[Xx]slt\*
src\Umbraco.Web.UI\[Ii]mages\*
src\Umbraco.Web.UI\[Ss]cripts\*
src\Umbraco.Web.UI\Web.*.config.transformed
umbraco\presentation\umbraco\plugins\uComponents\uComponentsInstaller.ascx
umbraco\presentation\packages\uComponents\MultiNodePicker\CustomTreeService.asmx
+3
View File
@@ -26,3 +26,6 @@ ff3bb24ea0c915878396a6ae27f1ff164e8ac150 Release-6.0.0-beta
56015ac26f5ab60e3c61b1d09075297b660afa07 Release-6.0.0-RC
1719fbd857f28b376639ac2aa0abada0ef2e7560 Release-6.0.0
e02f5aebb87e3f07d27376647756caa9762931d8 Release-4.11.4
14338b0ab1738fbd8987677ecdb9a73d79fc229d release-4.11.6
b247b35d821144849f551e02da8ba719f91d5fb0 Release-6.0.2
aed55cba29009ad3db48880a7cfb66407ce9805f release-6.0.3
+1 -1
View File
@@ -1,5 +1,5 @@
@ECHO OFF
SET release=6.0.2
SET release=6.0.4
SET comment=
SET version=%release%
+161
View File
@@ -0,0 +1,161 @@
@ECHO OFF
:choice
set /P c=WARNING! Are you sure you want to continue, this will remove all package files, view files, sqlce database, etc... Press 'Y' to auto-remove all files/folders, 'N' to cancel or 'C' to prompt for each folder removal?
if /I "%c%" EQU "C" goto :prompt
if /I "%c%" EQU "Y" goto :auto
if /I "%c%" EQU "N" goto :exit
goto :choice
:prompt
echo Current folder: %CD%
echo Regenerating SQL CE database
SET buildfolder=%CD%
CD ..\tools\RegenerateUmbracoSQLCEDatabase\
RegenerateUmbracoSQLCEDatabase.exe %CD%\..\..\src\Umbraco.Web.UI
CD %buildfolder%
echo Removing bin files
del ..\src\Umbraco.Web.UI\bin\*.*
echo Building solution
%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe ..\src\umbraco.sln /t:Clean,Build
echo Resetting installedPackages.config
echo ^<?xml version="1.0" encoding="utf-8"?^>^<packages^>^</packages^> >..\src\Umbraco.Web.UI\App_Data\packages\installed\installedPackages.config
echo Removing plugin cache files
del ..\src\Umbraco.Web.UI\App_Data\TEMP\PluginCache\*.*
echo Removing cache files and examine index
del ..\src\Umbraco.Web.UI\App_Data\TEMP\*.*
echo Removing log files
del ..\src\Umbraco.Web.UI\App_Data\Logs\*.*
echo Removing packages
del ..\src\Umbraco.Web.UI\App_Data\packages\*.*
echo Removing previews
del ..\src\Umbraco.Web.UI\App_Data\preview\*.*
echo Removing app code files (typically added by starterkits)
del ..\src\Umbraco.Web.UI\App_Code\*.*
echo Removing xslt files
del ..\src\Umbraco.Web.UI\xslt\*.*
echo Removing user control files
del ..\src\Umbraco.Web.UI\UserControls\*.*
echo Removing masterpage files
del ..\src\Umbraco.Web.UI\masterpages\*.*
echo Removing view files
del ..\src\Umbraco.Web.UI\Views\*.*
echo Removing razor files
del ..\src\Umbraco.Web.UI\macroScripts\*.*
echo Removing media files
del ..\src\Umbraco.Web.UI\media\*.*
echo Removing script files
del ..\src\Umbraco.Web.UI\scripts\*.*
echo Removing css files
del ..\src\Umbraco.Web.UI\css\*.*
echo "Umbraco install reverted to clean install"
pause
exit
:auto
echo Current folder: %CD%
echo Regenerating SQL CE database
SET buildfolder=%CD%
CD ..\tools\RegenerateUmbracoSQLCEDatabase\
RegenerateUmbracoSQLCEDatabase.exe %CD%\..\..\src\Umbraco.Web.UI
CD %buildfolder%
echo Removing bin files
FOR %%A IN (..\src\Umbraco.Web.UI\bin\*.*) DO DEL %%A
echo Building solution
%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe ..\src\umbraco.sln /t:Clean,Build
echo Resetting installedPackages.config
echo ^<?xml version="1.0" encoding="utf-8"?^>^<packages^>^</packages^> >..\src\Umbraco.Web.UI\App_Data\packages\installed\installedPackages.config
echo Removing plugin cache files
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\TEMP\PluginCache\*.*) DO DEL %%A
echo Removing cache files and examine index
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\TEMP\*.*) DO DEL %%A
echo Removing log files
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\Logs\*.*) DO DEL %%A
echo Removing packages
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\packages\*.*) DO DEL %%A
echo Removing previews
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\preview\*.*) DO DEL %%A
echo Removing app code files (typically added by starterkits)
FOR %%A IN (..\src\Umbraco.Web.UI\App_Code\*.*) DO DEL %%A
echo Removing xslt files
FOR %%A IN (..\src\Umbraco.Web.UI\xslt\*.*) DO DEL %%A
echo Removing masterpage files
FOR %%A IN (..\src\Umbraco.Web.UI\masterpages\*.*) DO DEL %%A
echo Removing user control files
FOR %%A IN (..\src\Umbraco.Web.UI\usercontrols\*.*) DO DEL %%A
echo Removing view files
FOR %%A IN (..\src\Umbraco.Web.UI\Views\*.*) DO DEL %%A
echo Removing razor files
FOR %%A IN (..\src\Umbraco.Web.UI\macroScripts\*.*) DO DEL %%A
echo Removing media files
FOR %%A IN (..\src\Umbraco.Web.UI\media\*.*) DO DEL %%A
echo Removing script files
FOR %%A IN (..\src\Umbraco.Web.UI\scripts\*.*) DO DEL %%A
echo Removing css files
FOR %%A IN (..\src\Umbraco.Web.UI\css\*.*) DO DEL %%A
echo Removing Courier files
del ..\src\Umbraco.Web.UI\config\courier.config
del ..\src\Umbraco.Web.UI\umbraco\images\tray\courier.jpg
rmdir "..\src\Umbraco.Web.UI\umbraco\plugins\courier\" /S /Q
echo Removing Contour files
del ..\src\Umbraco.Web.UI\umbraco\images\tray\contour.png
FOR %%A IN (..\src\Umbraco.Web.UI\umbraco\images\umbraco\icon_*.*) DO DEL %%A
rmdir "..\src\Umbraco.Web.UI\umbraco\plugins\umbracoContour\" /S /Q
del ..\src\Umbraco.Web.UI\umbraco\xslt\templates\UmbracoContour*.* /S /Q
rmdir "..\src\Umbraco.Web.UI\usercontrols\umbracoContour\" /S /Q
echo Start with a clean web.config
copy ..\src\Umbraco.Web.UI\web.Template.config ..\src\Umbraco.Web.UI\web.config /Y
echo "Umbraco install reverted to clean install"
pause
exit
:exit
exit
Binary file not shown.
-24
View File
@@ -1,24 +0,0 @@
Hi! Thanks for grabbing the Umbraco sourcecode.
===========================================
NOTE - DEFAULT BRANCH EMPTY - December 2010
===========================================
- With the help of CodePlex we have migrated much of our previous changesets (as of Dec 13th 2010) from TFS to Mercurial.
- However, not everything could be migrated to our new branching workflow. So for each nominal group of 4.x changes, we've created named branches. For upcoming 5.x changesets, we'll adhere to our new workflow which we'll describe on the Wiki for contributors.
- FOR THE MOMENT, the 'default' branch is empty - pending the addition of the 5.0 changesets
- To switch to the codebase on which you want to work, 'hg update' to the named branch (e.g. "4.6.0") or tag (e.g. "Release-4.5.2") and browse or work from that point.
Thanks to Matt Hawley at CodePlex for his help in our migration!
Cheers,
The Umbraco Team
http://umbraco.org
http://our.umbraco.org
http://umbraco.codeplex.com
-82
View File
@@ -1,82 +0,0 @@
{\rtf1\ansi\ansicpg1252\uc1\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f36\fswiss\fcharset0\fprq2{\*\panose 020b0604030504040204}Tahoma;}
{\f39\froman\fcharset238\fprq2 Times New Roman CE;}{\f40\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f42\froman\fcharset161\fprq2 Times New Roman Greek;}{\f43\froman\fcharset162\fprq2 Times New Roman Tur;}
{\f44\froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f45\froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f46\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f47\froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
{\f399\fswiss\fcharset238\fprq2 Tahoma CE;}{\f400\fswiss\fcharset204\fprq2 Tahoma Cyr;}{\f402\fswiss\fcharset161\fprq2 Tahoma Greek;}{\f403\fswiss\fcharset162\fprq2 Tahoma Tur;}{\f404\fswiss\fcharset177\fprq2 Tahoma (Hebrew);}
{\f405\fswiss\fcharset178\fprq2 Tahoma (Arabic);}{\f406\fswiss\fcharset186\fprq2 Tahoma Baltic;}{\f407\fswiss\fcharset163\fprq2 Tahoma (Vietnamese);}{\f408\fswiss\fcharset222\fprq2 Tahoma (Thai);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;
\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;
\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 Normal;}{\*\cs10 \additive
\ssemihidden Default Paragraph Font;}{\*\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv
\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1024\langfe1024\cgrid\langnp1024\langfenp1024 \snext11 \ssemihidden Normal Table;}{\s15\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0
\f36\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext15 \ssemihidden \styrsid668380 Balloon Text;}}{\*\latentstyles\lsdstimax156\lsdlockeddef0}{\*\listtable{\list\listtemplateid130696116{\listlevel\levelnfc0\levelnfcn0\leveljc0
\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00.;}{\levelnumbers\'01;}\fi-360\li720\jclisttab\tx720\lin720 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0
{\leveltext\'02\'01.;}{\levelnumbers\'01;}\fi-360\li1440\jclisttab\tx1440\lin1440 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'02.;}{\levelnumbers\'01;}\fi-360\li2160
\jclisttab\tx2160\lin2160 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'03.;}{\levelnumbers\'01;}\fi-360\li2880\jclisttab\tx2880\lin2880 }{\listlevel\levelnfc0\levelnfcn0\leveljc0
\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'04.;}{\levelnumbers\'01;}\fi-360\li3600\jclisttab\tx3600\lin3600 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0
{\leveltext\'02\'05.;}{\levelnumbers\'01;}\fi-360\li4320\jclisttab\tx4320\lin4320 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'06.;}{\levelnumbers\'01;}\fi-360\li5040
\jclisttab\tx5040\lin5040 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'07.;}{\levelnumbers\'01;}\fi-360\li5760\jclisttab\tx5760\lin5760 }{\listlevel\levelnfc0\levelnfcn0\leveljc0
\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'08.;}{\levelnumbers\'01;}\fi-360\li6480\jclisttab\tx6480\lin6480 }{\listname ;}\listid723138990}}{\*\listoverridetable{\listoverride\listid723138990\listoverridecount0\ls1}}
{\*\pgptbl {\pgp\ipgp2\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp4\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}}{\*\rsidtbl \rsid288726\rsid668380\rsid1077358\rsid1250157\rsid1778664
\rsid2232581\rsid3018318\rsid3766585\rsid4417501\rsid4531485\rsid4807452\rsid5341002\rsid7018004\rsid7880391\rsid10749719\rsid12150908\rsid12939982\rsid13596669\rsid15149892\rsid15551579\rsid16128754\rsid16674677}{\*\generator Microsoft Word 11.0.6359;}
{\info{\title Shared Source License for Software included in Workspaces}{\author suev}{\operator Martin Maly}{\creatim\yr2005\mo3\dy22\hr10\min45}{\revtim\yr2005\mo3\dy22\hr15\min54}{\printim\yr2002\mo9\dy20\hr15\min39}{\version3}{\edmins1}{\nofpages1}
{\nofwords672}{\nofchars3837}{\*\company Microsoft}{\nofcharsws4501}{\vern24703}}\widowctrl\ftnbj\aenddoc\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\hyphcaps0\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1701\dgvorigin1984
\dghshow1\dgvshow1\jexpand\viewkind5\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct
\asianbrkrule\nojkernpunct\rsidroot15149892 \fet0\sectd \linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3
\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}
{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain
\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\b\fs28\insrsid1250157\charrsid1250157 Shared Source License for }{\b\fs28\insrsid16674677 IronPython}{
\b\fs28\insrsid1250157
\par }{\b\fs28\insrsid5341002
\par }{\b\insrsid5341002\charrsid5341002 This license governs use of the accompanying software}{\b\insrsid5341002 (\'93Software\'94)}{\b\insrsid5341002\charrsid5341002 , and your use of the }{\b\insrsid5341002 S}{\b\insrsid5341002\charrsid5341002
oftware constitutes acceptance of this license.
\par }{\insrsid1250157\charrsid5341002
\par }{\b\insrsid1250157\charrsid1250157 You }{\b\insrsid5341002 may}{\b\insrsid1250157\charrsid1250157 use }{\b\insrsid5341002 the}{\b\insrsid1250157\charrsid1250157 Software for any }{\b\insrsid1250157 commercial or }{\b\insrsid1250157\charrsid1250157
noncommercial purpose, including distributing derivative}{\b\insrsid4417501 work}{\b\insrsid1250157\charrsid1250157 s}{\b\insrsid1250157 .
\par }{\insrsid1250157
\par }\pard \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid1250157 {\insrsid1250157\charrsid1250157 In return, we simply require that you agree:
\par {\listtext\pard\plain\insrsid1250157\charrsid1250157 \hich\af0\dbch\af0\loch\f0 1.\tab}}\pard \ql \fi-360\li720\ri0\widctlpar\jclisttab\tx720\aspalpha\aspnum\faauto\ls1\adjustright\rin0\lin720\itap0\pararsid1250157 {\insrsid1250157\charrsid1250157
Not to remove any copyright}{\insrsid5341002 or other}{\insrsid1250157\charrsid1250157 notices from the Software.
\par {\listtext\pard\plain\insrsid1250157\charrsid1250157 \hich\af0\dbch\af0\loch\f0 2.\tab}That if you distribute the Software in source code form you do so only under this }{\insrsid5341002 l}{\insrsid1250157\charrsid1250157
icense (i.e. you must include a complete copy of this }{\insrsid5341002 l}{\insrsid1250157\charrsid1250157 icense with your distribution), and if you distribute the Software solely in object form you only do so under a license that complies with this }{
\insrsid5341002 l}{\insrsid1250157\charrsid1250157 icense.
\par {\listtext\pard\plain\b\insrsid1250157\charrsid1250157 \hich\af0\dbch\af0\loch\f0 3.\tab}}{\b\insrsid1250157\charrsid1250157
That the Software comes "as is", with no warranties. None whatsoever. This means no express, implied or statutory warranty, including without limitation, warranties of merchantability or fitness for a particular purpose or any warranty of }{
\b\insrsid5341002 title or }{\b\insrsid1250157\charrsid1250157 non}{\b\insrsid5341002 -}{\b\insrsid1250157\charrsid1250157 infringement. Also, you must pass this disclaimer on whenever you distribute the Software}{\b\insrsid5341002 or derivative works}{
\b\insrsid1250157\charrsid1250157 .}{\insrsid1250157\charrsid1250157
\par {\listtext\pard\plain\b\insrsid1250157\charrsid1250157 \hich\af0\dbch\af0\loch\f0 4.\tab}}{\b\insrsid1250157\charrsid1250157 That neither Microsoft nor }{\b\insrsid1250157 any contributor to the Software}{\b\insrsid1250157\charrsid1250157
will be liable for any of those types of damages known as}{\b\insrsid5341002 }{\b\insrsid1250157\charrsid1250157 indirect, special, consequential, or incidental related to the Software or this }{\b\insrsid5341002 l}{\b\insrsid1250157\charrsid1250157
icense, to the maximum extent the law permits, no matter what legal theory it\rquote s based on. Also, you must pass this limitation of liability on whenever you distribute the Software}{\b\insrsid5341002 or derivative works}{
\b\insrsid1250157\charrsid1250157 .}{\insrsid1250157\charrsid1250157
\par {\listtext\pard\plain\insrsid1250157\charrsid1250157 \hich\af0\dbch\af0\loch\f0 5.\tab}That if you sue anyone over patents that you think may apply to the Software for a person's use of the Software, your license to the Software ends automatically.
\par {\listtext\pard\plain\insrsid1250157 \hich\af0\dbch\af0\loch\f0 6.\tab}}{\insrsid1250157 That the patent rights, if any, }{\insrsid288726 granted in this license}{\insrsid1250157\charrsid1250157 only apply to the Software, not to any derivative}{
\insrsid4417501 work}{\insrsid1250157\charrsid1250157 s you make.}{\insrsid3018318
\par {\listtext\pard\plain\insrsid3018318\charrsid3018318 \hich\af0\dbch\af0\loch\f0 7.\tab}}{\insrsid3018318\charrsid3018318 That if you are an agency of the U.S. Government, (i) Software provided pursuant to a solicitation issued on or after Dece
mber 1, 1995, is provided with the commercial license rights set forth in this license, and (ii) Software provided pursuant to a solicitation issued prior to December 1, 1995, is provided with \'93Restricted Rights\'94
as set forth in FAR, 48 C.F.R. 52.227-14 (June 1987) or DFAR, 48 C.F.R. 252.227-7013 (Oct 1988), as applicable.}{\insrsid1250157
\par {\listtext\pard\plain\insrsid1250157 \hich\af0\dbch\af0\loch\f0 8.\tab}That your rights under this License end automatically if you breach it in any way.
\par {\listtext\pard\plain\insrsid5341002 \hich\af0\dbch\af0\loch\f0 9.\tab}}{\insrsid5341002 That all rights not expressly granted to you in this license are reserved.
\par }\pard \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid1778664 {\insrsid1778664
\par }{\insrsid12150908 Read below}{\insrsid1778664 for answers to frequently asked questions about this license.
\par }{\insrsid12150908
\par }\pard \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid12150908 {\b\insrsid12150908\charrsid12150908 Q: Is this license OSI compliant?
\par }{\insrsid12150908
A: This license has not been submitted to OSI, but it allows developers to take full advantage of a dynamic language on the CLR and to have the freedom to distribute their works for the benefit of the community at large. The license is half of a
page long and very straight forward. We believe it stands up to what developers demand of an "open" license.
\par
\par }{\b\insrsid12150908\charrsid12150908 Q: What copyright rights does the license grant me?
\par }{\insrsid12150908 A: The license grants you a copyright license to make unlimited copies of the Software in sour
ce or object code form, as well as to create Derivative Works (as that term is defined under US copyright law). This means that in addition to making unlimited copies of the Software, you have a copyright license to modify the Software and to use all or p
art of the Software to create a Derivative Work.
\par
\par }{\b\insrsid12150908\charrsid12150908 Q: What patent rights does the license grant me?
\par }{\insrsid12150908 A: This license grants you a patent license to use and distribute the Software under any Microsoft patent claims that read on the Software itself. In other wo
rds, if you create a modified version of the Software, you still retain the patent license to use and distribute the original portions of the Software under the specific Microsoft patent claims that read on the Software, but you do not have a patent licen
s
e as to the new functionality you may have added by modifying the Software. This result is typical of many common open source licenses, including the Common Public License (CPL) and the Mozilla Public License (MPL). In addition, this license grants no rig
h
ts to any Microsoft patents that read on other components or files not included in the Software. This means that no patent license is granted to use or distribute any other software or technology that may be needed to use the Software or was created from
t
he Software (for example, any compiled output of the Software, the combination of the Software with other hardware or other software, or any additional enabling technologies that may be necessary to make or use the Software or any final product that inclu
des the Software).}{\insrsid12150908
\par }{\insrsid12150908\charrsid1250157
\par }}
+30 -6
View File
@@ -1,9 +1,33 @@
!! Umbraco - the simple, flexible and friendly ASP.NET CMS
Umbraco - the simple, flexible and friendly ASP.NET CMS
=======================================================
For the first time on the Microsoft platform a free user and developer friendly cms that makes it quick and easy to create websites - or a breeze to build complex web applications. umbraco got award-winning integration capabilities and supports your ASP.NET User and Custom Controls out of the box. It's a developers dream and your users will love it too. Used by more than 57.000 active websites including Heinz.com, Peugeot.com, NAIAS.com and Microsofts documentinteropinitiative.org website you can be sure that the technology is proven, stable and scales.
[url:More info at http://umbraco.org|http://umbraco.org]
!! Forums
We have a forum running on [url:http://our.umbraco.org]. The discussions area on CodePlex will be for discussions on developing the core, and not on Umbraco-implementations or extensions in general. For those topics, please use [url:http://our.umbraco.org].
More info at http://umbraco.com
!! Submitting Issues
Another way you can contribute to Umbraco is by providing issue reports, for information on how to submit an issue report refer to our [url:online guide|http://our.umbraco.org/wiki/how-tos/submitting-bug-reports].
Exploring the repository
========================
Most contributors will work on their own fork and should pick the branch in which they need their fix. For more information see:
http://our.umbraco.org/contribute/guidelines-for-core-contribution
Exploring the source
====================
The Umbraco source code is never required for you to start building sites. If you are not using the source code for debugging purposes or to contribute to the source then please download the binaries listed at http://umbraco.codeplex.com
With that said, the Umbraco solution can be opened in Visual Studio 2010 with SP1 installed or Visual Studio 2012.
Contributing
============
Umbraco is Open Source which means you can contribute to make it great!
Read all about it at http://our.umbraco.org/contribute
Forums
======
We have a forum running on http://our.umbraco.org for friendly community support.
Documentation
=============
Our documentation section provides help on installing and using Umbraco including API reference documentation: http://our.umbraco.org/documentation
Submitting Issues
=================
Another way you can contribute to Umbraco is by providing issue reports, for information on how to submit an issue report refer to our online guide at http://our.umbraco.org/contribute/report-an-issue-or-request-a-feature
+3 -1
View File
@@ -149,7 +149,9 @@ namespace SqlCE4Umbraco
var dataDirectory = AppDomain.CurrentDomain.GetData("DataDirectory") as string;
if (!string.IsNullOrEmpty(dataDirectory))
{
path = path.Replace("|DataDirectory|", dataDirectory + System.IO.Path.DirectorySeparatorChar);
path = path.Contains(@"|\")
? path.Replace("|DataDirectory|", dataDirectory)
: path.Replace("|DataDirectory|", dataDirectory + System.IO.Path.DirectorySeparatorChar);
}
}
+12 -1
View File
@@ -100,6 +100,18 @@ namespace Umbraco.Core
}
}
/// <summary>
/// The original/first url that the web application executes
/// </summary>
/// <remarks>
/// we need to set the initial url in our ApplicationContext, this is so our keep alive service works and this must
/// exist on a global context because the keep alive service doesn't run in a web context.
/// we are NOT going to put a lock on this because locking will slow down the application and we don't really care
/// if two threads write to this at the exact same time during first page hit.
/// see: http://issues.umbraco.org/issue/U4-2059
/// </remarks>
internal string OriginalRequestUrl { get; set; }
private bool Configured
{
get
@@ -140,7 +152,6 @@ namespace Umbraco.Core
}
}
private void AssertIsReady()
{
if (!this.IsReady)
@@ -154,6 +154,9 @@ namespace Umbraco.Core.Configuration
/// This will return the MVC area that we will route all custom routes through like surface controllers, etc...
/// We will use the 'Path' (default ~/umbraco) to create it but since it cannot contain '/' and people may specify a path of ~/asdf/asdf/admin
/// we will convert the '/' to '-' and use that as the path. its a bit lame but will work.
///
/// We also make sure that the virtual directory (SystemDirectories.Root) is stripped off first, otherwise we'd end up with something
/// like "MyVirtualDirectory-Umbraco" instead of just "Umbraco".
/// </remarks>
internal static string UmbracoMvcArea
{
@@ -163,7 +166,7 @@ namespace Umbraco.Core.Configuration
{
throw new InvalidOperationException("Cannot create an MVC Area path without the umbracoPath specified");
}
return Path.TrimStart('~').TrimStart('/').Replace('/', '-').Trim();
return Path.TrimStart(SystemDirectories.Root).TrimStart('~').TrimStart('/').Replace('/', '-').Trim().ToLower();
}
}
@@ -671,6 +671,18 @@ namespace Umbraco.Core.Configuration
}
}
/// <summary>
/// File types that will not be allowed to be uploaded via the content/media upload control
/// </summary>
public static IEnumerable<string> DisallowedUploadFiles
{
get
{
var val = GetKey("/settings/content/disallowedUploadFiles");
return val.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries);
}
}
/// <summary>
/// Gets the allowed image file types.
/// </summary>
@@ -1216,6 +1228,75 @@ namespace Umbraco.Core.Configuration
}
}
private static MacroErrorBehaviour? _macroErrorBehaviour;
/// <summary>
/// This configuration setting defines how to handle macro errors:
/// - Inline - Show error within macro as text (default and current Umbraco 'normal' behavior)
/// - Silent - Suppress error and hide macro
/// - Throw - Throw an exception and invoke the global error handler (if one is defined, if not you'll get a YSOD)
/// </summary>
/// <value>MacroErrorBehaviour enum defining how to handle macro errors.</value>
public static MacroErrorBehaviour MacroErrorBehaviour
{
get
{
if (_macroErrorBehaviour == null)
{
try
{
var behaviour = MacroErrorBehaviour.Inline;
var value = GetKey("/settings/content/MacroErrors");
if (value != null)
{
Enum<MacroErrorBehaviour>.TryParse(value, true, out behaviour);
}
_macroErrorBehaviour = behaviour;
}
catch (Exception ex)
{
LogHelper.Error<UmbracoSettings>("Could not load /settings/content/MacroErrors from umbracosettings.config", ex);
_macroErrorBehaviour = MacroErrorBehaviour.Inline;
}
}
return _macroErrorBehaviour.Value;
}
}
private static IconPickerBehaviour? _iconPickerBehaviour;
/// <summary>
/// This configuration setting defines how to show icons in the document type editor.
/// - ShowDuplicates - Show duplicates in files and sprites. (default and current Umbraco 'normal' behaviour)
/// - HideSpriteDuplicates - Show files on disk and hide duplicates from the sprite
/// - HideFileDuplicates - Show files in the sprite and hide duplicates on disk
/// </summary>
/// <value>MacroErrorBehaviour enum defining how to show icons in the document type editor.</value>
public static IconPickerBehaviour IconPickerBehaviour
{
get
{
if (_iconPickerBehaviour == null)
{
try
{
var behaviour = IconPickerBehaviour.ShowDuplicates;
var value = GetKey("/settings/content/DocumentTypeIconList");
if (value != null)
{
Enum<IconPickerBehaviour>.TryParse(value, true, out behaviour);
}
_iconPickerBehaviour = behaviour;
}
catch (Exception ex)
{
LogHelper.Error<UmbracoSettings>("Could not load /settings/content/DocumentTypeIconList from umbracosettings.config", ex);
_iconPickerBehaviour = IconPickerBehaviour.ShowDuplicates;
}
}
return _iconPickerBehaviour.Value;
}
}
/// <summary>
/// Configuration regarding webservices
@@ -5,7 +5,7 @@ namespace Umbraco.Core.Configuration
{
public class UmbracoVersion
{
private static readonly Version Version = new Version("6.0.2");
private static readonly Version Version = new Version("6.0.4");
/// <summary>
/// Gets the current version of Umbraco.
+32 -11
View File
@@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.ObjectResolution;
@@ -10,6 +8,7 @@ using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.Migrations;
using Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix;
using Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixZeroOne;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Publishing;
@@ -61,27 +60,36 @@ namespace Umbraco.Core
new PetaPocoUnitOfWorkProvider(dbFactory),
new FileUnitOfWorkProvider(),
new PublishingStrategy());
//create the ApplicationContext
ApplicationContext = ApplicationContext.Current = new ApplicationContext(dbContext, serviceContext);
//initialize the DatabaseContext
dbContext.Initialize();
CreateApplicationContext(dbContext, serviceContext);
InitializeApplicationEventsResolver();
InitializeResolvers();
//initialize the DatabaseContext
dbContext.Initialize();
//now we need to call the initialize methods
ApplicationEventsResolver.Current.ApplicationEventHandlers
.ForEach(x => x.OnApplicationInitialized(UmbracoApplication, ApplicationContext));
_isInitialized = true;
return this;
}
/// <summary>
/// Creates and assigns the application context singleton
/// </summary>
/// <param name="dbContext"></param>
/// <param name="serviceContext"></param>
protected virtual void CreateApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext)
{
//create the ApplicationContext
ApplicationContext = ApplicationContext.Current = new ApplicationContext(dbContext, serviceContext);
}
/// <summary>
/// Special method to initialize the ApplicationEventsResolver and any modifications required for it such
/// as adding custom types to the resolver.
@@ -135,8 +143,7 @@ namespace Umbraco.Core
if (_isComplete)
throw new InvalidOperationException("The boot manager has already been completed");
//freeze resolution to not allow Resolvers to be modified
Resolution.Freeze();
FreezeResolution();
//stop the timer and log the output
_timer.Dispose();
@@ -161,6 +168,14 @@ namespace Umbraco.Core
return this;
}
/// <summary>
/// Freeze resolution to not allow Resolvers to be modified
/// </summary>
protected virtual void FreezeResolution()
{
Resolution.Freeze();
}
/// <summary>
/// Create the resolvers
/// </summary>
@@ -169,6 +184,12 @@ namespace Umbraco.Core
RepositoryResolver.Current = new RepositoryResolver(
new RepositoryFactory());
SqlSyntaxProvidersResolver.Current = new SqlSyntaxProvidersResolver(
new[] { typeof(MySqlSyntaxProvider), typeof(SqlCeSyntaxProvider), typeof(SqlServerSyntaxProvider) })
{
CanResolveBeforeFrozen = true
};
CacheRefreshersResolver.Current = new CacheRefreshersResolver(
() => PluginManager.Current.ResolveCacheRefreshers());
+18 -17
View File
@@ -112,7 +112,7 @@ namespace Umbraco.Core
public void ConfigureEmbeddedDatabaseConnection()
{
const string providerName = "System.Data.SqlServerCe.4.0";
const string connectionString = "Datasource=|DataDirectory|Umbraco.sdf";
const string connectionString = @"Data Source=|DataDirectory|\Umbraco.sdf";
SaveConnectionString(connectionString, providerName);
@@ -337,21 +337,22 @@ namespace Umbraco.Core
internal void Initialize(string providerName)
{
if (providerName.StartsWith("MySql"))
{
SyntaxConfig.SqlSyntaxProvider = MySqlSyntax.Provider;
}
else if (providerName.Contains("SqlServerCe"))
{
SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider;
}
else
{
SyntaxConfig.SqlSyntaxProvider = SqlServerSyntax.Provider;
}
_providerName = providerName;
_configured = true;
try
{
SqlSyntaxContext.SqlSyntaxProvider =
SqlSyntaxProvidersResolver.Current.GetByProviderNameOrDefault(providerName);
_configured = true;
}
catch (Exception e)
{
_configured = false;
LogHelper.Info<DatabaseContext>("Initialization of the DatabaseContext failed with following error: " + e.Message);
LogHelper.Info<DatabaseContext>(e.StackTrace);
}
}
internal DatabaseSchemaResult ValidateDatabaseSchema()
@@ -388,7 +389,7 @@ namespace Umbraco.Core
var message = string.Empty;
var database = new UmbracoDatabase(_connectionString, ProviderName);
var supportsCaseInsensitiveQueries = SyntaxConfig.SqlSyntaxProvider.SupportsCaseInsensitiveQueries(database);
var supportsCaseInsensitiveQueries = SqlSyntaxContext.SqlSyntaxProvider.SupportsCaseInsensitiveQueries(database);
if (supportsCaseInsensitiveQueries == false)
{
message = "<p>&nbsp;</p><p>The database you're trying to use does not support case insensitive queries. <br />We currently do not support these types of databases.</p>" +
@@ -411,7 +412,7 @@ namespace Umbraco.Core
}
else
{
if (SyntaxConfig.SqlSyntaxProvider == MySqlSyntaxProvider.Instance)
if (SqlSyntaxContext.SqlSyntaxProvider.GetType() == typeof(MySqlSyntaxProvider))
{
message = "<p>&nbsp;</p><p>Congratulations, the database step ran successfully!</p>" +
"<p>Note: You're using MySQL and the database instance you're connecting to seems to support case insensitive queries.</p>" +
@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Umbraco.Core.Events
{
// Provides information on the macro that caused an error
public class MacroErrorEventArgs : System.EventArgs
{
/// <summary>
/// Name of the faulting macro.
/// </summary>
public string Name { get; set; }
/// <summary>
/// Alias of the faulting macro.
/// </summary>
public string Alias { get; set; }
/// <summary>
/// Filename, file path, fully qualified class name, or other key used by the macro engine to do it's processing of the faulting macro.
/// </summary>
public string ItemKey { get; set; }
/// <summary>
/// Exception raised.
/// </summary>
public Exception Exception { get; set; }
/// <summary>
/// Gets or sets the desired behaviour when a matching macro causes an error. See
/// <see cref="MacroErrorBehaviour"/> for definitions. By setting this in your event
/// you can override the default behaviour defined in UmbracoSettings.config.
/// </summary>
/// <value>Macro error behaviour enum.</value>
public MacroErrorBehaviour Behaviour { get; set; }
}
}
+15
View File
@@ -8,6 +8,7 @@ using System.IO;
using System.Configuration;
using System.Web;
using System.Text.RegularExpressions;
using System.Xml;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
@@ -230,6 +231,20 @@ namespace Umbraco.Core.IO
filePath = String.Empty;
}
//Break up the file in name and extension before applying the UrlReplaceCharacters
var fileNamePart = filePath.Substring(0, filePath.LastIndexOf('.'));
var ext = filePath.Substring(filePath.LastIndexOf('.'));
//Because the file usually is downloadable as well we check characters against 'UmbracoSettings.UrlReplaceCharacters'
XmlNode replaceChars = UmbracoSettings.UrlReplaceCharacters;
foreach (XmlNode n in replaceChars.SelectNodes("char"))
{
if (n.Attributes.GetNamedItem("org") != null && n.Attributes.GetNamedItem("org").Value != "")
fileNamePart = fileNamePart.Replace(n.Attributes.GetNamedItem("org").Value, XmlHelper.GetNodeValue(n));
}
filePath = string.Concat(fileNamePart, ext);
// Adapted from: http://stackoverflow.com/a/4827510/5018
// Combined both Reserved Characters and Character Data
// from http://en.wikipedia.org/wiki/Percent-encoding
+14 -4
View File
@@ -183,16 +183,26 @@ namespace Umbraco.Core.IO
}
}
private static string _root;
/// <summary>
/// Gets the root path of the application
/// </summary>
public static string Root
{
get
{
string appPath = HttpRuntime.AppDomainAppVirtualPath ?? string.Empty;
if (appPath == "/")
appPath = string.Empty;
if (_root == null)
{
string appPath = HttpRuntime.AppDomainAppVirtualPath ?? string.Empty;
if (appPath == "/")
appPath = string.Empty;
return appPath;
_root = appPath;
}
return _root;
}
//Only required for unit tests
internal set { _root = value; }
}
}
+24
View File
@@ -0,0 +1,24 @@
namespace Umbraco.Core
{
public enum IconPickerBehaviour
{
/// <summary>
/// Default umbraco behavior - show duplicates in files and sprites
/// </summary>
ShowDuplicates,
/// <summary>
/// If a file exists on disk with the same name as one in the sprite
/// then the file on disk overrules the one in the sprite, the
/// sprite icon will not be shown
/// </summary>
HideSpriteDuplicates,
/// <summary>
/// If a file exists on disk with the same name as one in the sprite
/// then the file in the sprite overrules the one on disk, the file
/// on disk will be shown
/// </summary>
HideFileDuplicates
}
}
@@ -64,23 +64,28 @@ namespace Umbraco.Core.Logging
{
_forceStop = true;
var windowsIdentity = WindowsIdentity.GetCurrent();
base.Append(new LoggingEvent(new LoggingEventData
{
Level = Level.Error,
Message =
"Unable to clear out the AsynchronousRollingFileAppender buffer in the allotted time, forcing a shutdown",
TimeStamp = DateTime.UtcNow,
Identity = "",
ExceptionString = "",
UserName = windowsIdentity != null ? windowsIdentity.Name : "",
Domain = AppDomain.CurrentDomain.FriendlyName,
ThreadName = Thread.CurrentThread.ManagedThreadId.ToString(),
LocationInfo =
new LocationInfo(this.GetType().Name, "OnClose", "AsynchronousRollingFileAppender.cs", "59"),
LoggerName = this.GetType().FullName,
Properties = new PropertiesDictionary(),
})
);
var logEvent = new LoggingEvent(new LoggingEventData
{
Level = global::log4net.Core.Level.Error,
Message =
"Unable to clear out the AsynchronousRollingFileAppender buffer in the allotted time, forcing a shutdown",
TimeStamp = DateTime.UtcNow,
Identity = "",
ExceptionString = "",
UserName = windowsIdentity != null ? windowsIdentity.Name : "",
Domain = AppDomain.CurrentDomain.FriendlyName,
ThreadName = Thread.CurrentThread.ManagedThreadId.ToString(),
LocationInfo =
new LocationInfo(this.GetType().Name, "OnClose", "AsynchronousRollingFileAppender.cs", "59"),
LoggerName = this.GetType().FullName,
Properties = new PropertiesDictionary(),
});
if (this.DateTimeStrategy != null)
{
base.Append(logEvent);
}
}
base.OnClose();
+23
View File
@@ -0,0 +1,23 @@
namespace Umbraco.Core
{
public enum MacroErrorBehaviour
{
/// <summary>
/// Default umbraco behavior - show an inline error within the
/// macro but allow the page to continue rendering.
/// </summary>
Inline,
/// <summary>
/// Silently eat the error and do not display the offending macro.
/// </summary>
Silent,
/// <summary>
/// Throw an exception which can be caught by the global error handler
/// defined in Application_OnError. If no such error handler is defined
/// then you'll see the Yellow Screen Of Death (YSOD) error page.
/// </summary>
Throw
}
}
+8 -4
View File
@@ -117,8 +117,10 @@ namespace Umbraco.Core.Models
if (fileName.LastIndexOf(@"\") > 0)
fileName = fileName.Substring(fileName.LastIndexOf(@"\") + 1);
if (string.IsNullOrEmpty(fileName) == false)
SetFileOnContent(content, propertyTypeAlias, fileName, value.InputStream);
var name = IOHelper.SafeFileName(fileName);
if (string.IsNullOrEmpty(name) == false)
SetFileOnContent(content, propertyTypeAlias, name, value.InputStream);
}
/// <summary>
@@ -131,8 +133,10 @@ namespace Umbraco.Core.Models
public static void SetValue(this IContentBase content, string propertyTypeAlias, string fileName,
Stream fileStream)
{
if (string.IsNullOrEmpty(fileName) == false && fileStream != null)
SetFileOnContent(content, propertyTypeAlias, fileName, fileStream);
var name = IOHelper.SafeFileName(fileName);
if (string.IsNullOrEmpty(name) == false && fileStream != null)
SetFileOnContent(content, propertyTypeAlias, name, fileStream);
}
private static void SetFileOnContent(IContentBase content, string propertyTypeAlias, string name, Stream fileStream)
+1 -1
View File
@@ -381,7 +381,7 @@ namespace Umbraco.Core.Models
oldPropertyGroup.PropertyTypes.RemoveItem(propertyTypeAlias);
}
propertyType.PropertyGroupId = default(int);
propertyType.PropertyGroupId = new Lazy<int>(() => default(int));
propertyType.ResetDirtyProperties();
var propertyGroup = PropertyGroups.First(x => x.Name == propertyGroupName);
@@ -140,8 +140,8 @@ namespace Umbraco.Core.Models
if (CompositionPropertyGroups.Any(x => x.Name == groupName))
{
var first = CompositionPropertyGroups.First(x => x.Name == groupName && x.ParentId.HasValue == false);
propertyGroup.ParentId = first.Id;
var firstGroup = CompositionPropertyGroups.First(x => x.Name == groupName && x.ParentId.HasValue == false);
propertyGroup.SetLazyParentId(new Lazy<int?>(() => firstGroup.Id));
}
if (PropertyGroups.Any())
@@ -166,7 +166,7 @@ namespace Umbraco.Core.Models
{
if (PropertyGroups.Contains(propertyGroupName))
{
propertyType.PropertyGroupId = PropertyGroups[propertyGroupName].Id;
propertyType.PropertyGroupId = new Lazy<int>(() => PropertyGroups[propertyGroupName].Id);
PropertyGroups[propertyGroupName].PropertyTypes.Add(propertyType);
}
else
@@ -179,7 +179,8 @@ namespace Umbraco.Core.Models
{
var parentPropertyGroup = CompositionPropertyGroups.First(x => x.Name == propertyGroupName && x.ParentId.HasValue == false);
propertyGroup.SortOrder = parentPropertyGroup.SortOrder;
propertyGroup.ParentId = parentPropertyGroup.Id;
//propertyGroup.ParentId = parentPropertyGroup.Id;
propertyGroup.SetLazyParentId(new Lazy<int?>(() => parentPropertyGroup.Id));
}
PropertyGroups.Add(propertyGroup);
@@ -8,6 +8,17 @@ namespace Umbraco.Core.Models
/// </summary>
public class ContentTypeSort : IValueObject
{
public ContentTypeSort()
{
}
public ContentTypeSort(Lazy<int> id, int sortOrder, string @alias)
{
Id = id;
SortOrder = sortOrder;
Alias = alias;
}
/// <summary>
/// Gets or sets the Id of the ContentType
/// </summary>
@@ -15,12 +15,12 @@ namespace Umbraco.Core.Models
public enum DataTypeDatabaseType
{
[EnumMember]
Integer,
[EnumMember]
Date,
Ntext,
[EnumMember]
Nvarchar,
[EnumMember]
Ntext /*, Object*/
Integer,
[EnumMember]
Date
}
}
@@ -172,7 +172,9 @@ namespace Umbraco.Core.Models
internal override void AddingEntity()
{
base.AddingEntity();
Key = Guid.NewGuid();
if(Key == default(Guid))
Key = Guid.NewGuid();
}
}
}
+9 -13
View File
@@ -66,6 +66,15 @@ namespace Umbraco.Core.Models.EntityBase
[DataMember]
public DateTime UpdateDate { get; set; }
/// <summary>
/// Gets or sets the WasCancelled flag, which is used to track
/// whether some action against an entity was cancelled through some event.
/// This only exists so we have a way to check if an event was cancelled through
/// the new api, which also needs to take effect in the legacy api.
/// </summary>
[IgnoreDataMember]
internal bool WasCancelled { get; set; }
/// <summary>
/// Property changed event
/// </summary>
@@ -159,19 +168,6 @@ namespace Umbraco.Core.Models.EntityBase
}
}
public static bool operator ==(Entity left, Entity right)
{
if (ReferenceEquals(null, left))
return false;
return left.Equals(right);
}
public static bool operator !=(Entity left, Entity right)
{
return !(left == right);
}
public virtual bool SameIdentityAs(IEntity other)
{
if (ReferenceEquals(null, other))
+17 -3
View File
@@ -14,7 +14,7 @@ namespace Umbraco.Core.Models
public class PropertyGroup : Entity, IEquatable<PropertyGroup>
{
private string _name;
private int? _parentId;
private Lazy<int?> _parentId;
private int _sortOrder;
private PropertyTypeCollection _propertyTypes;
@@ -60,10 +60,15 @@ namespace Umbraco.Core.Models
[DataMember]
public int? ParentId
{
get { return _parentId; }
get
{
if (_parentId == null)
return default(int?);
return _parentId.Value;
}
set
{
_parentId = value;
_parentId = new Lazy<int?>(() => value);
OnPropertyChanged(ParentIdSelector);
}
}
@@ -96,6 +101,15 @@ namespace Umbraco.Core.Models
}
}
/// <summary>
/// Sets the ParentId from the lazy integer id
/// </summary>
/// <param name="id">Id of the Parent</param>
internal void SetLazyParentId(Lazy<int?> id)
{
_parentId = id;
}
public bool Equals(PropertyGroup other)
{
//Check whether the compared object is null.
+7 -18
View File
@@ -13,12 +13,11 @@ namespace Umbraco.Core.Models
[DataContract(IsReference = true)]
public class PropertyType : Entity, IEquatable<PropertyType>
{
//private SerializationService _service;
private string _name;
private string _alias;
private string _description;
private int _dataTypeDefinitionId;
private int _propertyGroupId;
private Lazy<int> _propertyGroupId;
private Guid _dataTypeId;
private DataTypeDatabaseType _dataTypeDatabaseType;
private bool _mandatory;
@@ -33,22 +32,12 @@ namespace Umbraco.Core.Models
DataTypeId = dataTypeDefinition.ControlId;
DataTypeDatabaseType = dataTypeDefinition.DatabaseType;
EnsureSerializationService();
}
internal PropertyType(Guid dataTypeControlId, DataTypeDatabaseType dataTypeDatabaseType)
{
DataTypeId = dataTypeControlId;
DataTypeDatabaseType = dataTypeDatabaseType;
EnsureSerializationService();
}
private void EnsureSerializationService()
{
/*var serviceStackSerializer = new ServiceStackXmlSerializer();
_service = new SerializationService(serviceStackSerializer);*/
}
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<PropertyType, string>(x => x.Name);
@@ -61,7 +50,7 @@ namespace Umbraco.Core.Models
private static readonly PropertyInfo HelpTextSelector = ExpressionHelper.GetPropertyInfo<PropertyType, string>(x => x.HelpText);
private static readonly PropertyInfo SortOrderSelector = ExpressionHelper.GetPropertyInfo<PropertyType, int>(x => x.SortOrder);
private static readonly PropertyInfo ValidationRegExpSelector = ExpressionHelper.GetPropertyInfo<PropertyType, string>(x => x.ValidationRegExp);
private static readonly PropertyInfo PropertyGroupIdSelector = ExpressionHelper.GetPropertyInfo<PropertyType, int>(x => x.PropertyGroupId);
private static readonly PropertyInfo PropertyGroupIdSelector = ExpressionHelper.GetPropertyInfo<PropertyType, Lazy<int>>(x => x.PropertyGroupId);
/// <summary>
/// Gets of Sets the Name of the PropertyType
@@ -153,7 +142,7 @@ namespace Umbraco.Core.Models
/// Gets or Sets the PropertyGroup's Id for which this PropertyType belongs
/// </summary>
[DataMember]
internal int PropertyGroupId
internal Lazy<int> PropertyGroupId
{
get { return _propertyGroupId; }
set
@@ -181,6 +170,7 @@ namespace Umbraco.Core.Models
/// Gets of Sets the Help text for the current PropertyType
/// </summary>
[DataMember]
[Obsolete("Not used anywhere in the UI")]
public string HelpText
{
get { return _helpText; }
@@ -209,7 +199,7 @@ namespace Umbraco.Core.Models
/// Gets or Sets the RegEx for validation of legacy DataTypes
/// </summary>
[DataMember]
internal string ValidationRegExp
public string ValidationRegExp
{
get { return _validationRegExp; }
set
@@ -218,7 +208,6 @@ namespace Umbraco.Core.Models
OnPropertyChanged(ValidationRegExpSelector);
}
}
//Note that Validation should eventually come from PropertyEditors like in v5
/// <summary>
/// Create a new Property object from a "raw" database value.
@@ -335,8 +324,8 @@ namespace Umbraco.Core.Models
if (Mandatory && (value == null || string.IsNullOrEmpty(value.ToString())))
return false;
//Check against Regular Expression for Legacy DataTypes
if(!string.IsNullOrEmpty(ValidationRegExp))
//Check against Regular Expression for Legacy DataTypes - Validation exists and value is not null:
if(string.IsNullOrEmpty(ValidationRegExp) == false && (value != null && string.IsNullOrEmpty(value.ToString()) == false))
{
var regexPattern = new Regex(ValidationRegExp);
return regexPattern.IsMatch(value.ToString());
+15 -7
View File
@@ -28,12 +28,8 @@ namespace Umbraco.Core.Models
{
base.Path = path;
ParentId = -1;
Key = name.EncodeAsGuid();
_name = name;
_alias = alias;
CreateDate = DateTime.Now;
UpdateDate = DateTime.Now;
_name = name.Replace("/", ".").Replace("\\", "");
_alias = alias.ToSafeAlias();
}
[DataMember]
@@ -52,7 +48,7 @@ namespace Umbraco.Core.Models
internal string NodePath { get; set; }
[DataMember]
internal int MasterTemplateId { get; set; }
internal Lazy<int> MasterTemplateId { get; set; }
[DataMember]
internal string MasterTemplateAlias { get; set; }
@@ -116,5 +112,17 @@ namespace Umbraco.Core.Models
return validFile && validExtension;
}
/// <summary>
/// Method to call when Entity is being saved
/// </summary>
/// <remarks>Created date is set and a Unique key is assigned</remarks>
internal override void AddingEntity()
{
base.AddingEntity();
if (Key == Guid.Empty)
Key = Guid.NewGuid();
}
}
}
@@ -51,7 +51,8 @@ namespace Umbraco.Core.Persistence.Factories
UpdateDate = dto.ContentVersionDto.VersionDate,
ExpireDate = dto.ExpiresDate.HasValue ? dto.ExpiresDate.Value : (DateTime?)null,
ReleaseDate = dto.ReleaseDate.HasValue ? dto.ReleaseDate.Value : (DateTime?)null,
Version = dto.ContentVersionDto.VersionId
Version = dto.ContentVersionDto.VersionId,
PublishedState = dto.Published ? PublishedState.Published : PublishedState.Unpublished
};
}
@@ -8,23 +8,26 @@ namespace Umbraco.Core.Persistence.Factories
{
internal class PropertyFactory : IEntityFactory<IEnumerable<Property>, IEnumerable<PropertyDataDto>>
{
private readonly IContentType _contentType;
private readonly IMediaType _mediaType;
private readonly IContentTypeComposition _contentType;
private readonly Guid _version;
private readonly int _id;
private readonly DateTime _createDate;
private readonly DateTime _updateDate;
public PropertyFactory(IContentType contentType, Guid version, int id)
public PropertyFactory(IContentTypeComposition contentType, Guid version, int id)
{
_contentType = contentType;
_version = version;
_id = id;
}
public PropertyFactory(IMediaType mediaType, Guid version, int id)
public PropertyFactory(IContentTypeComposition contentType, Guid version, int id, DateTime createDate, DateTime updateDate)
{
_mediaType = mediaType;
_contentType = contentType;
_version = version;
_id = id;
_createDate = createDate;
_updateDate = updateDate;
}
#region Implementation of IEntityFactory<IContent,PropertyDataDto>
@@ -42,6 +45,8 @@ namespace Umbraco.Core.Persistence.Factories
propertyDataDto.VersionId.Value,
propertyDataDto.Id);
property.CreateDate = _createDate;
property.UpdateDate = _updateDate;
property.ResetDirtyProperties();
properties.Add(property);
}
@@ -98,22 +103,5 @@ namespace Umbraco.Core.Persistence.Factories
}
#endregion
public IEnumerable<Property> BuildMediaEntity(IEnumerable<PropertyDataDto> dtos)
{
var properties = new List<Property>();
foreach (var dto in dtos)
{
if (_mediaType.CompositionPropertyTypes.Any(x => x.Id == dto.PropertyTypeId))
{
var propertyType = _mediaType.CompositionPropertyTypes.First(x => x.Id == dto.PropertyTypeId);
var property = propertyType.CreatePropertyFromRawValue(dto.GetValue, dto.VersionId.Value, dto.Id);
property.ResetDirtyProperties();
properties.Add(property);
}
}
return properties;
}
}
}
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
@@ -8,12 +9,21 @@ namespace Umbraco.Core.Persistence.Factories
internal class PropertyGroupFactory : IEntityFactory<IEnumerable<PropertyGroup>, IEnumerable<PropertyTypeGroupDto>>
{
private readonly int _id;
private readonly DateTime _createDate;
private readonly DateTime _updateDate;
public PropertyGroupFactory(int id)
{
_id = id;
}
public PropertyGroupFactory(int id, DateTime createDate, DateTime updateDate)
{
_id = id;
_createDate = createDate;
_updateDate = updateDate;
}
#region Implementation of IEntityFactory<IEnumerable<PropertyGroup>,IEnumerable<TabDto>>
public IEnumerable<PropertyGroup> BuildEntity(IEnumerable<PropertyTypeGroupDto> dto)
@@ -44,6 +54,7 @@ namespace Umbraco.Core.Persistence.Factories
var typeDtos = groupDto.PropertyTypeDtos.Where(x => x.Id > 0);
foreach (var typeDto in typeDtos)
{
var tempGroupDto = groupDto;
var propertyType = new PropertyType(typeDto.DataTypeDto.ControlId,
typeDto.DataTypeDto.DbType.EnumParse<DataTypeDatabaseType>(true))
{
@@ -56,7 +67,9 @@ namespace Umbraco.Core.Persistence.Factories
Mandatory = typeDto.Mandatory,
SortOrder = typeDto.SortOrder,
ValidationRegExp = typeDto.ValidationRegExp,
PropertyGroupId = groupDto.Id
PropertyGroupId = new Lazy<int>(() => tempGroupDto.Id),
CreateDate = _createDate,
UpdateDate = _updateDate
};
propertyType.ResetDirtyProperties();
@@ -28,17 +28,22 @@ namespace Umbraco.Core.Persistence.Factories
public Template BuildEntity(TemplateDto dto)
{
return new Template(string.Empty, dto.NodeDto.Text, dto.Alias)
{
CreateDate = dto.NodeDto.CreateDate,
Id = dto.NodeId,
Key = dto.NodeDto.UniqueId.Value,
CreatorId = dto.NodeDto.UserId.Value,
Level = dto.NodeDto.Level,
ParentId = dto.NodeDto.ParentId,
SortOrder = dto.NodeDto.SortOrder,
NodePath = dto.NodeDto.Path
};
var template = new Template(string.Empty, dto.NodeDto.Text, dto.Alias)
{
CreateDate = dto.NodeDto.CreateDate,
Id = dto.NodeId,
Key = dto.NodeDto.UniqueId.Value,
CreatorId = dto.NodeDto.UserId.Value,
Level = dto.NodeDto.Level,
ParentId = dto.NodeDto.ParentId,
SortOrder = dto.NodeDto.SortOrder,
NodePath = dto.NodeDto.Path
};
if(dto.Master.HasValue)
template.MasterTemplateId = new Lazy<int>(() => dto.Master.Value);
return template;
}
public TemplateDto BuildDto(Template entity)
@@ -50,6 +55,11 @@ namespace Umbraco.Core.Persistence.Factories
NodeDto = BuildNodeDto(entity)
};
if (entity.MasterTemplateId != null && entity.MasterTemplateId.Value != default(int))
{
dto.Master = entity.MasterTemplateId.Value;
}
if (entity.HasIdentity)
{
dto.NodeId = entity.Id;
@@ -30,8 +30,8 @@ namespace Umbraco.Core.Persistence.Mappers
string columnName = columnAttribute.Name;
string columnMap = string.Format("{0}.{1}",
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName),
SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(columnName));
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName),
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(columnName));
return columnMap;
}
}
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Events;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.SqlSyntax;
@@ -54,15 +55,39 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
{34, typeof (TaskTypeDto)},
{35, typeof (TaskDto)},
{36, typeof (ContentType2ContentTypeDto)},
{
37,
typeof (ContentTypeAllowedContentTypeDto)
},
{37, typeof (ContentTypeAllowedContentTypeDto)},
{38, typeof (User2AppDto)},
{39, typeof (User2NodeNotifyDto)},
{40, typeof (User2NodePermissionDto)}
};
#endregion
/// <summary>
/// Drops all Umbraco tables in the db
/// </summary>
internal void UninstallDatabaseSchema()
{
LogHelper.Info<DatabaseSchemaCreation>("Start UninstallDatabaseSchema");
foreach (var item in OrderedTables.OrderByDescending(x => x.Key))
{
var tableNameAttribute = item.Value.FirstAttribute<TableNameAttribute>();
string tableName = tableNameAttribute == null ? item.Value.Name : tableNameAttribute.Value;
LogHelper.Info<DatabaseSchemaCreation>("Uninstall" + tableName);
try
{
_database.DropTable(tableName);
}
catch (Exception ex)
{
//swallow this for now, not sure how best to handle this with diff databases... though this is internal
// and only used for unit tests. If this fails its because the table doesn't exist... generally!
LogHelper.Error<DatabaseSchemaCreation>("Could not drop table " + tableName, ex);
}
}
}
public DatabaseSchemaCreation(Database database)
{
@@ -102,7 +127,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
}
//Check tables in configured database against tables in schema
var tablesInDatabase = SyntaxConfig.SqlSyntaxProvider.GetTablesInSchema(_database).ToList();
var tablesInDatabase = SqlSyntaxContext.SqlSyntaxProvider.GetTablesInSchema(_database).ToList();
var tablesInSchema = result.TableDefinitions.Select(x => x.Name).ToList();
//Add valid and invalid table differences to the result object
var validTableDifferences = tablesInDatabase.Intersect(tablesInSchema);
@@ -117,7 +142,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
}
//Check columns in configured database against columns in schema
var columnsInDatabase = SyntaxConfig.SqlSyntaxProvider.GetColumnsInSchema(_database);
var columnsInDatabase = SqlSyntaxContext.SqlSyntaxProvider.GetColumnsInSchema(_database);
var columnsPerTableInDatabase = columnsInDatabase.Select(x => string.Concat(x.TableName, ",", x.ColumnName)).ToList();
var columnsPerTableInSchema = result.TableDefinitions.SelectMany(x => x.Columns.Select(y => string.Concat(y.TableName, ",", y.Name))).ToList();
//Add valid and invalid column differences to the result object
@@ -134,11 +159,11 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
//MySql doesn't conform to the "normal" naming of constraints, so there is currently no point in doing these checks.
//NOTE: At a later point we do other checks for MySql, but ideally it should be necessary to do special checks for different providers.
if (SyntaxConfig.SqlSyntaxProvider is MySqlSyntaxProvider)
if (SqlSyntaxContext.SqlSyntaxProvider is MySqlSyntaxProvider)
return result;
//Check constraints in configured database against constraints in schema
var constraintsInDatabase = SyntaxConfig.SqlSyntaxProvider.GetConstraintsPerColumn(_database).DistinctBy(x => x.Item3).ToList();
var constraintsInDatabase = SqlSyntaxContext.SqlSyntaxProvider.GetConstraintsPerColumn(_database).DistinctBy(x => x.Item3).ToList();
var foreignKeysInDatabase = constraintsInDatabase.Where(x => x.Item3.StartsWith("FK_")).Select(x => x.Item3).ToList();
var primaryKeysInDatabase = constraintsInDatabase.Where(x => x.Item3.StartsWith("PK_")).Select(x => x.Item3).ToList();
var indexesInDatabase = constraintsInDatabase.Where(x => x.Item3.StartsWith("IX_")).Select(x => x.Item3).ToList();
@@ -111,7 +111,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
sb.AppendLine(" ");
}
if (SyntaxConfig.SqlSyntaxProvider is MySqlSyntaxProvider)
if (SqlSyntaxContext.SqlSyntaxProvider is MySqlSyntaxProvider)
{
sb.AppendLine("Please note that the constraints could not be validated because the current dataprovider is MySql.");
}
@@ -21,9 +21,9 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Expressions
public override string ToString()
{
return string.Format(SyntaxConfig.SqlSyntaxProvider.AlterColumn,
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(TableName),
SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(Column.Name));
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.AlterColumn,
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(TableName),
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(Column.Name));
}
}
}
@@ -22,9 +22,9 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Expressions
{
//NOTE Should probably investigate if Deleting a Default Constraint is different from deleting a 'regular' constraint
return string.Format(SyntaxConfig.SqlSyntaxProvider.DeleteConstraint,
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(TableName),
SyntaxConfig.SqlSyntaxProvider.GetQuotedName(ConstraintName));
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteConstraint,
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(TableName),
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedName(ConstraintName));
}
}
}
@@ -17,7 +17,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Create.Expressions
{
var constraintType = (Constraint.IsPrimaryKeyConstraint) ? "PRIMARY KEY" : "UNIQUE";
if (Constraint.IsPrimaryKeyConstraint && SyntaxConfig.SqlSyntaxProvider.SupportsClustered())
if (Constraint.IsPrimaryKeyConstraint && SqlSyntaxContext.SqlSyntaxProvider.SupportsClustered())
constraintType += " CLUSTERED";
if (Constraint.IsNonUniqueConstraint)
@@ -27,12 +27,12 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Create.Expressions
for (int i = 0; i < Constraint.Columns.Count; i++)
{
columns[i] = SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(Constraint.Columns.ElementAt(i));
columns[i] = SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(Constraint.Columns.ElementAt(i));
}
return string.Format(SyntaxConfig.SqlSyntaxProvider.CreateConstraint,
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(Constraint.TableName),
SyntaxConfig.SqlSyntaxProvider.GetQuotedName(Constraint.ConstraintName),
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.CreateConstraint,
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(Constraint.TableName),
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedName(Constraint.ConstraintName),
constraintType,
string.Join(", ", columns));
}
@@ -24,7 +24,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Create.Expressions
{
var table = new TableDefinition{Name = TableName, SchemaName = SchemaName, Columns = Columns};
return string.Format(SyntaxConfig.SqlSyntaxProvider.Format(table));
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.Format(table));
}
}
}
@@ -31,9 +31,9 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions
foreach (string columnName in ColumnNames)
{
if (ColumnNames.First() != columnName) sb.AppendLine(";");
sb.AppendFormat(SyntaxConfig.SqlSyntaxProvider.DropColumn,
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(TableName),
SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(columnName));
sb.AppendFormat(SqlSyntaxContext.SqlSyntaxProvider.DropColumn,
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(TableName),
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(columnName));
}
return sb.ToString();
@@ -14,9 +14,9 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions
public override string ToString()
{
return string.Format(SyntaxConfig.SqlSyntaxProvider.DeleteConstraint,
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(Constraint.TableName),
SyntaxConfig.SqlSyntaxProvider.GetQuotedName(Constraint.ConstraintName));
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteConstraint,
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(Constraint.TableName),
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedName(Constraint.ConstraintName));
}
}
}
@@ -32,7 +32,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions
if (IsAllRows)
{
deleteItems.Add(string.Format(SyntaxConfig.SqlSyntaxProvider.DeleteData, SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(TableName), "1 = 1"));
deleteItems.Add(string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteData, SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(TableName), "1 = 1"));
}
else
{
@@ -42,13 +42,13 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions
foreach (KeyValuePair<string, object> item in row)
{
whereClauses.Add(string.Format("{0} {1} {2}",
SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(item.Key),
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(item.Key),
item.Value == null ? "IS" : "=",
SyntaxConfig.SqlSyntaxProvider.GetQuotedValue(item.Value.ToString())));
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedValue(item.Value.ToString())));
}
deleteItems.Add(string.Format(SyntaxConfig.SqlSyntaxProvider.DeleteData,
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(TableName),
deleteItems.Add(string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteData,
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(TableName),
String.Join(" AND ", whereClauses.ToArray())));
}
}
@@ -22,7 +22,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions
if (IsExpressionSupported() == false)
return string.Empty;
return string.Format(SyntaxConfig.SqlSyntaxProvider.DeleteDefaultConstraint,
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteDefaultConstraint,
TableName,
ColumnName);
}
@@ -33,10 +33,10 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions
if (string.IsNullOrEmpty(ForeignKey.Name))
ForeignKey.Name = string.Format("{0}_ibfk_1", ForeignKey.ForeignTable.ToLower());
return string.Format(SyntaxConfig.SqlSyntaxProvider.DeleteConstraint,
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(ForeignKey.ForeignTable),
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteConstraint,
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(ForeignKey.ForeignTable),
"FOREIGN KEY ",
SyntaxConfig.SqlSyntaxProvider.GetQuotedName(ForeignKey.Name));
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedName(ForeignKey.Name));
}
if (string.IsNullOrEmpty(ForeignKey.Name))
@@ -44,9 +44,9 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions
ForeignKey.Name = string.Format("FK_{0}_{1}", ForeignKey.ForeignTable, ForeignKey.PrimaryTable);
}
return string.Format(SyntaxConfig.SqlSyntaxProvider.DeleteConstraint,
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(ForeignKey.ForeignTable),
SyntaxConfig.SqlSyntaxProvider.GetQuotedName(ForeignKey.Name));
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteConstraint,
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(ForeignKey.ForeignTable),
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedName(ForeignKey.Name));
}
}
}
@@ -19,9 +19,9 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions
public override string ToString()
{
return string.Format(SyntaxConfig.SqlSyntaxProvider.DropIndex,
SyntaxConfig.SqlSyntaxProvider.GetQuotedName(Index.Name),
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(Index.TableName));
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DropIndex,
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedName(Index.Name),
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(Index.TableName));
}
}
}
@@ -17,8 +17,8 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions
public override string ToString()
{
return string.Format(SyntaxConfig.SqlSyntaxProvider.DropTable,
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(TableName));
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DropTable,
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(TableName));
}
}
}
@@ -28,9 +28,9 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Expressions
if (string.IsNullOrEmpty(Column.TableName))
Column.TableName = TableName;
return string.Format(SyntaxConfig.SqlSyntaxProvider.AddColumn,
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(Column.TableName),
SyntaxConfig.SqlSyntaxProvider.Format(Column));
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.AddColumn,
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(Column.TableName),
SqlSyntaxContext.SqlSyntaxProvider.Format(Column));
}
}
}
@@ -23,7 +23,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Expressions
if (IsExpressionSupported() == false)
return string.Empty;
return SyntaxConfig.SqlSyntaxProvider.Format(ForeignKey);
return SqlSyntaxContext.SqlSyntaxProvider.Format(ForeignKey);
}
}
}
@@ -19,7 +19,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Expressions
public override string ToString()
{
return SyntaxConfig.SqlSyntaxProvider.Format(Index);
return SqlSyntaxContext.SqlSyntaxProvider.Format(Index);
}
}
}
@@ -52,7 +52,7 @@ SELECT CONCAT(
if (IsExpressionSupported() == false)
return string.Empty;
return SyntaxConfig.SqlSyntaxProvider.FormatColumnRename(TableName, OldName, NewName);
return SqlSyntaxContext.SqlSyntaxProvider.FormatColumnRename(TableName, OldName, NewName);
}
}
}
@@ -22,7 +22,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Rename.Expressions
if (IsExpressionSupported() == false)
return string.Empty;
return SyntaxConfig.SqlSyntaxProvider.FormatTableRename(OldName, NewName);
return SqlSyntaxContext.SqlSyntaxProvider.FormatTableRename(OldName, NewName);
}
}
}
@@ -31,8 +31,8 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Update.Expressions
foreach (var item in Set)
{
updateItems.Add(string.Format("{0} = {1}",
SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(item.Key),
SyntaxConfig.SqlSyntaxProvider.GetQuotedValue(item.Value.ToString())));
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(item.Key),
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedValue(item.Value.ToString())));
}
if (IsAllRows)
@@ -44,13 +44,13 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Update.Expressions
foreach (var item in Where)
{
whereClauses.Add(string.Format("{0} {1} {2}",
SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(item.Key),
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(item.Key),
item.Value == null ? "IS" : "=",
SyntaxConfig.SqlSyntaxProvider.GetQuotedValue(item.Value.ToString())));
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedValue(item.Value.ToString())));
}
}
return string.Format(SyntaxConfig.SqlSyntaxProvider.UpdateData,
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(TableName),
return string.Format(SqlSyntaxContext.SqlSyntaxProvider.UpdateData,
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(TableName),
string.Join(", ", updateItems.ToArray()),
string.Join(" AND ", whereClauses.ToArray()));
}
@@ -33,10 +33,10 @@ namespace Umbraco.Core.Persistence
var tableDefinition = DefinitionFactory.GetTableDefinition(modelType);
var tableName = tableDefinition.Name;
string createSql = SyntaxConfig.SqlSyntaxProvider.Format(tableDefinition);
string createPrimaryKeySql = SyntaxConfig.SqlSyntaxProvider.FormatPrimaryKey(tableDefinition);
var foreignSql = SyntaxConfig.SqlSyntaxProvider.Format(tableDefinition.ForeignKeys);
var indexSql = SyntaxConfig.SqlSyntaxProvider.Format(tableDefinition.Indexes);
string createSql = SqlSyntaxContext.SqlSyntaxProvider.Format(tableDefinition);
string createPrimaryKeySql = SqlSyntaxContext.SqlSyntaxProvider.FormatPrimaryKey(tableDefinition);
var foreignSql = SqlSyntaxContext.SqlSyntaxProvider.Format(tableDefinition.ForeignKeys);
var indexSql = SqlSyntaxContext.SqlSyntaxProvider.Format(tableDefinition.Indexes);
var tableExist = db.TableExist(tableName);
if (overwrite && tableExist)
@@ -65,18 +65,18 @@ namespace Umbraco.Core.Persistence
var e = new TableCreationEventArgs();
//Turn on identity insert if db provider is not mysql
if (SyntaxConfig.SqlSyntaxProvider.SupportsIdentityInsert() && tableDefinition.Columns.Any(x => x.IsIdentity))
db.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName))));
if (SqlSyntaxContext.SqlSyntaxProvider.SupportsIdentityInsert() && tableDefinition.Columns.Any(x => x.IsIdentity))
db.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName))));
//Call the NewTable-event to trigger the insert of base/default data
NewTable(tableName, db, e);
//Turn off identity insert if db provider is not mysql
if (SyntaxConfig.SqlSyntaxProvider.SupportsIdentityInsert() && tableDefinition.Columns.Any(x => x.IsIdentity))
db.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF;", SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName))));
if (SqlSyntaxContext.SqlSyntaxProvider.SupportsIdentityInsert() && tableDefinition.Columns.Any(x => x.IsIdentity))
db.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF;", SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName))));
//Special case for MySql
if (SyntaxConfig.SqlSyntaxProvider is MySqlSyntaxProvider && tableName.Equals("umbracoUser"))
if (SqlSyntaxContext.SqlSyntaxProvider is MySqlSyntaxProvider && tableName.Equals("umbracoUser"))
{
db.Update<UserDto>("SET id = @IdAfter WHERE id = @IdBefore AND userLogin = @Login", new { IdAfter = 0, IdBefore = 1, Login = "admin" });
}
@@ -120,18 +120,28 @@ namespace Umbraco.Core.Persistence
public static void DropTable(this Database db, string tableName)
{
var sql = new Sql(string.Format("DROP TABLE {0}", SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName)));
var sql = new Sql(string.Format(
SqlSyntaxContext.SqlSyntaxProvider.DropTable,
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName)));
db.Execute(sql);
}
public static void TruncateTable(this Database db, string tableName)
{
var sql = new Sql(string.Format(
SqlSyntaxContext.SqlSyntaxProvider.TruncateTable,
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName)));
db.Execute(sql);
}
public static bool TableExist(this Database db, string tableName)
{
return SyntaxConfig.SqlSyntaxProvider.DoesTableExist(db, tableName);
return SqlSyntaxContext.SqlSyntaxProvider.DoesTableExist(db, tableName);
}
public static bool TableExist(this UmbracoDatabase db, string tableName)
{
return SyntaxConfig.SqlSyntaxProvider.DoesTableExist(db, tableName);
return SqlSyntaxContext.SqlSyntaxProvider.DoesTableExist(db, tableName);
}
public static void CreateDatabaseSchema(this Database db)
@@ -17,7 +17,7 @@ namespace Umbraco.Core.Persistence
var tableNameAttribute = type.FirstAttribute<TableNameAttribute>();
string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value;
return sql.From(SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName));
return sql.From(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName));
}
public static Sql Where<T>(this Sql sql, Expression<Func<T, bool>> predicate)
@@ -38,8 +38,8 @@ namespace Umbraco.Core.Persistence
string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value;
var syntax = string.Format("{0}.{1}",
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName),
SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(columnName));
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName),
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(columnName));
return sql.OrderBy(syntax);
}
@@ -54,8 +54,8 @@ namespace Umbraco.Core.Persistence
string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value;
var syntax = string.Format("{0}.{1} DESC",
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName),
SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(columnName));
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName),
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(columnName));
return sql.OrderBy(syntax);
}
@@ -65,7 +65,7 @@ namespace Umbraco.Core.Persistence
var column = ExpressionHelper.FindProperty(columnMember) as PropertyInfo;
var columnName = column.FirstAttribute<ColumnAttribute>().Name;
return sql.GroupBy(SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(columnName));
return sql.GroupBy(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(columnName));
}
public static Sql.SqlJoinClause InnerJoin<T>(this Sql sql)
@@ -74,7 +74,7 @@ namespace Umbraco.Core.Persistence
var tableNameAttribute = type.FirstAttribute<TableNameAttribute>();
string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value;
return sql.InnerJoin(SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName));
return sql.InnerJoin(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName));
}
public static Sql.SqlJoinClause LeftJoin<T>(this Sql sql)
@@ -83,7 +83,7 @@ namespace Umbraco.Core.Persistence
var tableNameAttribute = type.FirstAttribute<TableNameAttribute>();
string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value;
return sql.LeftJoin(SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName));
return sql.LeftJoin(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName));
}
public static Sql.SqlJoinClause LeftOuterJoin<T>(this Sql sql)
@@ -92,7 +92,7 @@ namespace Umbraco.Core.Persistence
var tableNameAttribute = type.FirstAttribute<TableNameAttribute>();
string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value;
return sql.LeftOuterJoin(SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName));
return sql.LeftOuterJoin(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName));
}
public static Sql.SqlJoinClause RightJoin<T>(this Sql sql)
@@ -101,7 +101,7 @@ namespace Umbraco.Core.Persistence
var tableNameAttribute = type.FirstAttribute<TableNameAttribute>();
string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value;
return sql.RightJoin(SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName));
return sql.RightJoin(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName));
}
public static Sql On<TLeft, TRight>(this Sql.SqlJoinClause sql, Expression<Func<TLeft, object>> leftMember,
@@ -118,10 +118,10 @@ namespace Umbraco.Core.Persistence
var rightColumnName = right.FirstAttribute<ColumnAttribute>().Name;
string onClause = string.Format("{0}.{1} = {2}.{3}",
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(leftTableName),
SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(leftColumnName),
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(rightTableName),
SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(rightColumnName));
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(leftTableName),
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(leftColumnName),
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(rightTableName),
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(rightColumnName));
return sql.On(onClause);
}
}
@@ -523,7 +523,8 @@ namespace Umbraco.Core.Persistence.Querying
protected bool IsFieldName(string quotedExp)
{
return true;
//Not entirely sure this is reliable, but its better then simply returning true
return quotedExp.LastIndexOf("'", StringComparison.InvariantCultureIgnoreCase) + 1 != quotedExp.Length;
}
}
}
@@ -468,6 +468,9 @@ namespace Umbraco.Core.Persistence.Querying
if(fieldType == typeof(DateTime))
return "'" + EscapeParam(((DateTime)value).ToString(CultureInfo.InvariantCulture)) + "'";
if (fieldType == typeof(bool))
return ((bool)value) ? Convert.ToString(1, CultureInfo.InvariantCulture) : Convert.ToString(0, CultureInfo.InvariantCulture);
return ShouldQuoteValue(fieldType)
? "'" + EscapeParam(value) + "'"
: value.ToString();
@@ -487,8 +490,8 @@ namespace Umbraco.Core.Persistence.Querying
{
var column = pocoData.Columns.FirstOrDefault(x => x.Value.PropertyInfo.Name == name);
return string.Format("{0}.{1}",
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(pocoData.TableInfo.TableName),
SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(column.Value.ColumnName));
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(pocoData.TableInfo.TableName),
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(column.Value.ColumnName));
}
protected string RemoveQuote(string exp)
@@ -266,8 +266,11 @@ namespace Umbraco.Core.Persistence.Repositories
var parent = Database.First<NodeDto>("WHERE id = @ParentId", new { ParentId = entity.ParentId });
entity.Path = string.Concat(parent.Path, ",", entity.Id);
entity.Level = parent.Level + 1;
var maxSortOrder = Database.ExecuteScalar<int>("SELECT coalesce(max(sortOrder),0) FROM umbracoNode WHERE parentid = @ParentId", new { ParentId = entity.ParentId });
entity.SortOrder = maxSortOrder;
var maxSortOrder =
Database.ExecuteScalar<int>(
"SELECT coalesce(max(sortOrder),0) FROM umbracoNode WHERE parentid = @ParentId AND nodeObjectType = @NodeObjectType",
new {ParentId = entity.ParentId, NodeObjectType = NodeObjectTypeId});
entity.SortOrder = maxSortOrder + 1;
}
var factory = new ContentFactory(NodeObjectTypeId, entity.Id);
@@ -398,6 +401,24 @@ namespace Umbraco.Core.Persistence.Repositories
#region Implementation of IContentRepository
public IEnumerable<IContent> GetByPublishedVersion(IQuery<IContent> query)
{
var sqlClause = GetBaseQuery(false);
var translator = new SqlTranslator<IContent>(sqlClause, query);
var sql = translator.Translate()
.Where<DocumentDto>(x => x.Published)
.OrderByDescending<ContentVersionDto>(x => x.VersionDate)
.OrderBy<NodeDto>(x => x.SortOrder);
//NOTE: This doesn't allow properties to be part of the query
var dtos = Database.Fetch<DocumentDto, ContentVersionDto, ContentDto, NodeDto>(sql);
foreach (var dto in dtos)
{
yield return CreateContentFromDto(dto, dto.VersionId);
}
}
public IContent GetByLanguage(int id, string language)
{
var sql = GetBaseQuery(false);
@@ -434,13 +455,13 @@ namespace Umbraco.Core.Persistence.Repositories
content.Template = _templateRepository.Get(dto.TemplateId.Value);
}
content.Properties = GetPropertyCollection(dto.NodeId, versionId, contentType);
content.Properties = GetPropertyCollection(dto.NodeId, versionId, contentType, content.CreateDate, content.UpdateDate);
((ICanBeDirty)content).ResetDirtyProperties();
return content;
}
private PropertyCollection GetPropertyCollection(int id, Guid versionId, IContentType contentType)
private PropertyCollection GetPropertyCollection(int id, Guid versionId, IContentType contentType, DateTime createDate, DateTime updateDate)
{
var sql = new Sql();
sql.Select("*")
@@ -451,7 +472,7 @@ namespace Umbraco.Core.Persistence.Repositories
.Where<PropertyDataDto>(x => x.VersionId == versionId);
var propertyDataDtos = Database.Fetch<PropertyDataDto, PropertyTypeDto>(sql);
var propertyFactory = new PropertyFactory(contentType, versionId, id);
var propertyFactory = new PropertyFactory(contentType, versionId, id, createDate, updateDate);
var properties = propertyFactory.BuildEntity(propertyDataDtos);
var newProperties = properties.Where(x => x.HasIdentity == false);
@@ -41,11 +41,11 @@ namespace Umbraco.Core.Persistence.Repositories
.RightJoin<PropertyTypeDto>()
.On<PropertyTypeGroupDto, PropertyTypeDto>(left => left.Id, right => right.PropertyTypeGroupId)
.InnerJoin<DataTypeDto>()
.On<PropertyTypeDto, DataTypeDto>(left => left.DataTypeId, right => right.DataTypeId)
.OrderBy<PropertyTypeDto>(x => x.PropertyTypeGroupId);
.On<PropertyTypeDto, DataTypeDto>(left => left.DataTypeId, right => right.DataTypeId);
var translator = new SqlTranslator<PropertyType>(sqlClause, query);
var sql = translator.Translate();
var sql = translator.Translate()
.OrderBy<PropertyTypeDto>(x => x.PropertyTypeGroupId);
var dtos = Database.Fetch<PropertyTypeGroupDto, PropertyTypeDto, DataTypeDto, PropertyTypeGroupDto>(new GroupPropertyTypeRelator().Map, sql);
@@ -108,7 +108,12 @@ namespace Umbraco.Core.Persistence.Repositories
//Insert collection of allowed content types
foreach (var allowedContentType in entity.AllowedContentTypes)
{
Database.Insert(new ContentTypeAllowedContentTypeDto { Id = entity.Id, AllowedId = allowedContentType.Id.Value, SortOrder = allowedContentType.SortOrder });
Database.Insert(new ContentTypeAllowedContentTypeDto
{
Id = entity.Id,
AllowedId = allowedContentType.Id.Value,
SortOrder = allowedContentType.SortOrder
});
}
var propertyFactory = new PropertyGroupFactory(nodeDto.NodeId);
@@ -119,22 +124,31 @@ namespace Umbraco.Core.Persistence.Repositories
var tabDto = propertyFactory.BuildGroupDto(propertyGroup);
var primaryKey = Convert.ToInt32(Database.Insert(tabDto));
propertyGroup.Id = primaryKey;//Set Id on PropertyGroup
//Ensure that the PropertyGroup's Id is set on the PropertyTypes within a group
//unless the PropertyGroupId has already been changed.
foreach (var propertyType in propertyGroup.PropertyTypes)
{
if (propertyType.IsPropertyDirty("PropertyGroupId") == false)
{
var tempGroup = propertyGroup;
propertyType.PropertyGroupId = new Lazy<int>(() => tempGroup.Id);
}
}
}
//Insert PropertyTypes
foreach (var propertyGroup in entity.PropertyGroups)
foreach (var propertyType in entity.PropertyTypes)
{
foreach (var propertyType in propertyGroup.PropertyTypes)
{
var propertyTypeDto = propertyFactory.BuildPropertyTypeDto(propertyGroup.Id, propertyType);
var primaryKey = Convert.ToInt32(Database.Insert(propertyTypeDto));
propertyType.Id = primaryKey;//Set Id on PropertyType
var tabId = propertyType.PropertyGroupId != null ? propertyType.PropertyGroupId.Value : default(int);
var propertyTypeDto = propertyFactory.BuildPropertyTypeDto(tabId, propertyType);
int typePrimaryKey = Convert.ToInt32(Database.Insert(propertyTypeDto));
propertyType.Id = typePrimaryKey; //Set Id on new PropertyType
//Update the current PropertyType with correct ControlId and DatabaseType
var dataTypeDto = Database.FirstOrDefault<DataTypeDto>("WHERE nodeId = @Id", new { Id = propertyTypeDto.DataTypeId });
propertyType.DataTypeId = dataTypeDto.ControlId;
propertyType.DataTypeDatabaseType = dataTypeDto.DbType.EnumParse<DataTypeDatabaseType>(true);
}
//Update the current PropertyType with correct ControlId and DatabaseType
var dataTypeDto = Database.FirstOrDefault<DataTypeDto>("WHERE nodeId = @Id", new { Id = propertyTypeDto.DataTypeId });
propertyType.DataTypeId = dataTypeDto.ControlId;
propertyType.DataTypeDatabaseType = dataTypeDto.DbType.EnumParse<DataTypeDatabaseType>(true);
}
}
@@ -267,15 +281,18 @@ namespace Umbraco.Core.Persistence.Repositories
foreach (var propertyType in propertyGroup.PropertyTypes)
{
if (propertyType.IsPropertyDirty("PropertyGroupId") == false)
propertyType.PropertyGroupId = propertyGroup.Id;
{
var tempGroup = propertyGroup;
propertyType.PropertyGroupId = new Lazy<int>(() => tempGroup.Id);
}
}
}
//Run through all PropertyTypes to insert or update entries
foreach (var propertyType in entity.PropertyTypes)
{
var propertyTypeDto = propertyGroupFactory.BuildPropertyTypeDto(propertyType.PropertyGroupId,
propertyType);
var tabId = propertyType.PropertyGroupId != null ? propertyType.PropertyGroupId.Value : default(int);
var propertyTypeDto = propertyGroupFactory.BuildPropertyTypeDto(tabId, propertyType);
int typePrimaryKey = propertyType.HasIdentity
? Database.Update(propertyTypeDto)
: Convert.ToInt32(Database.Insert(propertyTypeDto));
@@ -295,7 +312,7 @@ namespace Umbraco.Core.Persistence.Repositories
return allowedContentTypeDtos.Select(x => new ContentTypeSort { Id = new Lazy<int>(() => x.AllowedId), SortOrder = x.SortOrder }).ToList();
}
protected PropertyGroupCollection GetPropertyGroupCollection(int id)
protected PropertyGroupCollection GetPropertyGroupCollection(int id, DateTime createDate, DateTime updateDate)
{
var sql = new Sql();
sql.Select("*")
@@ -309,12 +326,12 @@ namespace Umbraco.Core.Persistence.Repositories
var dtos = Database.Fetch<PropertyTypeGroupDto, PropertyTypeDto, DataTypeDto, PropertyTypeGroupDto>(new GroupPropertyTypeRelator().Map, sql);
var propertyGroupFactory = new PropertyGroupFactory(id);
var propertyGroupFactory = new PropertyGroupFactory(id, createDate, updateDate);
var propertyGroups = propertyGroupFactory.BuildEntity(dtos);
return new PropertyGroupCollection(propertyGroups);
}
protected PropertyTypeCollection GetPropertyTypeCollection(int id)
protected PropertyTypeCollection GetPropertyTypeCollection(int id, DateTime createDate, DateTime updateDate)
{
var sql = new Sql();
sql.Select("*")
@@ -340,7 +357,9 @@ namespace Umbraco.Core.Persistence.Repositories
HelpText = dto.HelpText,
Mandatory = dto.Mandatory,
SortOrder = dto.SortOrder,
ValidationRegExp = dto.ValidationRegExp
ValidationRegExp = dto.ValidationRegExp,
CreateDate = createDate,
UpdateDate = updateDate
}).ToList();
//Reset dirty properties
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Rdbms;
@@ -50,8 +51,8 @@ namespace Umbraco.Core.Persistence.Repositories
var contentType = factory.BuildEntity(dto);
contentType.AllowedContentTypes = GetAllowedContentTypeIds(id);
contentType.PropertyGroups = GetPropertyGroupCollection(id);
((ContentType)contentType).PropertyTypes = GetPropertyTypeCollection(id);
contentType.PropertyGroups = GetPropertyGroupCollection(id, contentType.CreateDate, contentType.UpdateDate);
((ContentType)contentType).PropertyTypes = GetPropertyTypeCollection(id, contentType.CreateDate, contentType.UpdateDate);
var templates = Database.Fetch<DocumentTypeDto>("WHERE contentTypeNodeId = @Id", new { Id = id });
if(templates.Any())
@@ -167,6 +168,19 @@ namespace Umbraco.Core.Persistence.Repositories
protected override void PersistNewItem(IContentType entity)
{
Mandate.That<Exception>(string.IsNullOrEmpty(entity.Alias) == false,
() =>
{
var message =
string.Format(
"ContentType '{0}' cannot have an empty Alias. This is most likely due to invalid characters stripped from the Alias.",
entity.Name);
var exception = new Exception(message);
LogHelper.Error<ContentTypeRepository>(message, exception);
throw exception;
});
((ContentType)entity).AddingEntity();
var factory = new ContentTypeFactory(NodeObjectTypeId);
@@ -192,6 +206,19 @@ namespace Umbraco.Core.Persistence.Repositories
protected override void PersistUpdatedItem(IContentType entity)
{
Mandate.That<Exception>(string.IsNullOrEmpty(entity.Alias) == false,
() =>
{
var message =
string.Format(
"ContentType '{0}' cannot have an empty Alias. This is most likely due to invalid characters stripped from the Alias.",
entity.Name);
var exception = new Exception(message);
LogHelper.Error<ContentTypeRepository>(message, exception);
throw exception;
});
//Updates Modified date
((ContentType)entity).UpdatingEntity();
@@ -200,6 +227,12 @@ namespace Umbraco.Core.Persistence.Repositories
{
var parent = Database.First<NodeDto>("WHERE id = @ParentId", new { ParentId = entity.ParentId });
entity.Path = string.Concat(parent.Path, ",", entity.Id);
entity.Level = parent.Level + 1;
var maxSortOrder =
Database.ExecuteScalar<int>(
"SELECT coalesce(max(sortOrder),0) FROM umbracoNode WHERE parentid = @ParentId AND nodeObjectType = @NodeObjectType",
new { ParentId = entity.ParentId, NodeObjectType = NodeObjectTypeId });
entity.SortOrder = maxSortOrder + 1;
}
var factory = new ContentTypeFactory(NodeObjectTypeId);
@@ -159,6 +159,12 @@ namespace Umbraco.Core.Persistence.Repositories
{
var parent = Database.First<NodeDto>("WHERE id = @ParentId", new { ParentId = entity.ParentId });
entity.Path = string.Concat(parent.Path, ",", entity.Id);
entity.Level = parent.Level + 1;
var maxSortOrder =
Database.ExecuteScalar<int>(
"SELECT coalesce(max(sortOrder),0) FROM umbracoNode WHERE parentid = @ParentId AND nodeObjectType = @NodeObjectType",
new { ParentId = entity.ParentId, NodeObjectType = NodeObjectTypeId });
entity.SortOrder = maxSortOrder + 1;
}
var factory = new DataTypeDefinitionFactory(NodeObjectTypeId);
@@ -111,6 +111,20 @@ namespace Umbraco.Core.Persistence.Repositories
#endregion
protected IEnumerable<string> FindAllFiles(string path)
{
var list = new List<string>();
list.AddRange(FileSystem.GetFiles(path, "*"));
var directories = FileSystem.GetDirectories(path);
foreach (var directory in directories)
{
list.AddRange(FindAllFiles(directory));
}
return list;
}
/// <summary>
/// Dispose any disposable properties
/// </summary>
@@ -1,4 +1,6 @@
using Umbraco.Core.Models;
using System.Collections.Generic;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence.Querying;
namespace Umbraco.Core.Persistence.Repositories
{
@@ -11,5 +13,12 @@ namespace Umbraco.Core.Persistence.Repositories
/// <param name="language">Culture code for the language to retrieve</param>
/// <returns>An <see cref="IContent"/> item</returns>
IContent GetByLanguage(int id, string language);
/// <summary>
/// Gets all published Content byh the specified query
/// </summary>
/// <param name="query">Query to execute against published versions</param>
/// <returns>An enumerable list of <see cref="IContent"/></returns>
IEnumerable<IContent> GetByPublishedVersion(IQuery<IContent> query);
}
}
@@ -51,7 +51,7 @@ namespace Umbraco.Core.Persistence.Repositories
var factory = new MediaFactory(mediaType, NodeObjectTypeId, id);
var media = factory.BuildEntity(dto);
media.Properties = GetPropertyCollection(id, dto.VersionId, mediaType);
media.Properties = GetPropertyCollection(id, dto.VersionId, mediaType, media.CreateDate, media.UpdateDate);
((ICanBeDirty)media).ResetDirtyProperties();
return media;
@@ -118,6 +118,8 @@ namespace Umbraco.Core.Persistence.Repositories
{
"DELETE FROM umbracoUser2NodeNotify WHERE nodeId = @Id",
"DELETE FROM umbracoUser2NodePermission WHERE nodeId = @Id",
"DELETE FROM umbracoRelation WHERE parentId = @Id",
"DELETE FROM umbracoRelation WHERE childId = @Id",
"DELETE FROM cmsTagRelationship WHERE nodeId = @Id",
"DELETE FROM cmsDocument WHERE NodeId = @Id",
"DELETE FROM cmsPropertyData WHERE contentNodeId = @Id",
@@ -155,7 +157,7 @@ namespace Umbraco.Core.Persistence.Repositories
var factory = new MediaFactory(mediaType, NodeObjectTypeId, dto.NodeId);
var media = factory.BuildEntity(dto);
media.Properties = GetPropertyCollection(dto.NodeId, dto.VersionId, mediaType);
media.Properties = GetPropertyCollection(dto.NodeId, dto.VersionId, mediaType, media.CreateDate, media.UpdateDate);
((ICanBeDirty)media).ResetDirtyProperties();
return media;
@@ -246,8 +248,11 @@ namespace Umbraco.Core.Persistence.Repositories
var parent = Database.First<NodeDto>("WHERE id = @ParentId", new { ParentId = entity.ParentId });
entity.Path = string.Concat(parent.Path, ",", entity.Id);
entity.Level = parent.Level + 1;
var maxSortOrder = Database.ExecuteScalar<int>("SELECT coalesce(max(sortOrder),0) FROM umbracoNode WHERE parentid = @ParentId", new { ParentId = entity.ParentId });
entity.SortOrder = maxSortOrder;
var maxSortOrder =
Database.ExecuteScalar<int>(
"SELECT coalesce(max(sortOrder),0) FROM umbracoNode WHERE parentid = @ParentId AND nodeObjectType = @NodeObjectType",
new { ParentId = entity.ParentId, NodeObjectType = NodeObjectTypeId });
entity.SortOrder = maxSortOrder + 1;
}
var factory = new MediaFactory(NodeObjectTypeId, entity.Id);
@@ -335,7 +340,7 @@ namespace Umbraco.Core.Persistence.Repositories
#endregion
private PropertyCollection GetPropertyCollection(int id, Guid versionId, IMediaType contentType)
private PropertyCollection GetPropertyCollection(int id, Guid versionId, IMediaType contentType, DateTime createDate, DateTime updateDate)
{
var sql = new Sql();
sql.Select("*")
@@ -346,8 +351,19 @@ namespace Umbraco.Core.Persistence.Repositories
.Where<PropertyDataDto>(x => x.VersionId == versionId);
var propertyDataDtos = Database.Fetch<PropertyDataDto, PropertyTypeDto>(sql);
var propertyFactory = new PropertyFactory(contentType, versionId, id);
var properties = propertyFactory.BuildMediaEntity(propertyDataDtos);
var propertyFactory = new PropertyFactory(contentType, versionId, id, createDate, updateDate);
var properties = propertyFactory.BuildEntity(propertyDataDtos);
var newProperties = properties.Where(x => x.HasIdentity == false);
foreach (var property in newProperties)
{
var propertyDataDto = new PropertyDataDto { NodeId = id, PropertyTypeId = property.PropertyTypeId, VersionId = versionId };
int primaryKey = Convert.ToInt32(Database.Insert(propertyDataDto));
property.Version = versionId;
property.Id = primaryKey;
}
return new PropertyCollection(properties);
}
}
@@ -42,8 +42,8 @@ namespace Umbraco.Core.Persistence.Repositories
var contentType = factory.BuildEntity(dto);
contentType.AllowedContentTypes = GetAllowedContentTypeIds(id);
contentType.PropertyGroups = GetPropertyGroupCollection(id);
((MediaType)contentType).PropertyTypes = GetPropertyTypeCollection(id);
contentType.PropertyGroups = GetPropertyGroupCollection(id, contentType.CreateDate, contentType.UpdateDate);
((MediaType)contentType).PropertyTypes = GetPropertyTypeCollection(id, contentType.CreateDate, contentType.UpdateDate);
var list = Database.Fetch<ContentType2ContentTypeDto>("WHERE childContentTypeId = @Id", new{ Id = id});
foreach (var contentTypeDto in list)
@@ -168,6 +168,12 @@ namespace Umbraco.Core.Persistence.Repositories
{
var parent = Database.First<NodeDto>("WHERE id = @ParentId", new { ParentId = entity.ParentId });
entity.Path = string.Concat(parent.Path, ",", entity.Id);
entity.Level = parent.Level + 1;
var maxSortOrder =
Database.ExecuteScalar<int>(
"SELECT coalesce(max(sortOrder),0) FROM umbracoNode WHERE parentid = @ParentId AND nodeObjectType = @NodeObjectType",
new { ParentId = entity.ParentId, NodeObjectType = NodeObjectTypeId });
entity.SortOrder = maxSortOrder + 1;
}
var factory = new MediaTypeFactory(NodeObjectTypeId);
@@ -45,12 +45,11 @@ namespace Umbraco.Core.Persistence.Repositories
var path = FileSystem.GetRelativePath(id);
var created = FileSystem.GetCreated(path).UtcDateTime;
var updated = FileSystem.GetLastModified(path).UtcDateTime;
var name = new FileInfo(path).Name;
var script = new Script(path)
{
Content = content,
Key = name.EncodeAsGuid(),
Key = path.EncodeAsGuid(),
CreateDate = created,
UpdateDate = updated
};
@@ -71,7 +70,7 @@ namespace Umbraco.Core.Persistence.Repositories
}
else
{
var files = FileSystem.GetFiles("", "*");
var files = FindAllFiles("");
foreach (var file in files)
{
yield return Get(file);
@@ -47,12 +47,11 @@ namespace Umbraco.Core.Persistence.Repositories
var path = FileSystem.GetRelativePath(id);
var created = FileSystem.GetCreated(path).UtcDateTime;
var updated = FileSystem.GetLastModified(path).UtcDateTime;
var name = new FileInfo(path).Name;
var stylesheet = new Stylesheet(path)
{
Content = content,
Key = name.EncodeAsGuid(),
Key = path.EncodeAsGuid(),
CreateDate = created,
UpdateDate = updated
};
@@ -73,7 +72,7 @@ namespace Umbraco.Core.Persistence.Repositories
}
else
{
var files = FileSystem.GetFiles("", "*");
var files = FindAllFiles("");
foreach (var file in files)
{
yield return Get(file);
@@ -71,7 +71,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
var masterTemplate = Get(dto.Master.Value);
template.MasterTemplateAlias = masterTemplate.Alias;
template.MasterTemplateId = dto.Master.Value;
template.MasterTemplateId = new Lazy<int>(() => dto.Master.Value);
}
if (_viewsFileSystem.FileExists(csViewName))
@@ -172,16 +172,22 @@ namespace Umbraco.Core.Persistence.Repositories
{
if (entity.GetTypeOfRenderingEngine() == RenderingEngine.Mvc)
{
_viewsFileSystem.AddFile(entity.Name, stream, true);
string viewName = string.Concat(entity.Alias, ".cshtml");
_viewsFileSystem.AddFile(viewName, stream, true);
}
else
{
_masterpagesFileSystem.AddFile(entity.Name, stream, true);
string masterpageName = string.Concat(entity.Alias, ".master");
_masterpagesFileSystem.AddFile(masterpageName, stream, true);
}
}
//TODO Possibly ensure unique alias here (as is done in the legacy Template class)?
//Save to db
var template = entity as Template;
template.AddingEntity();
var factory = new TemplateFactory(NodeObjectTypeId);
var dto = factory.BuildDto(template);
@@ -223,11 +229,13 @@ namespace Umbraco.Core.Persistence.Repositories
{
if (entity.GetTypeOfRenderingEngine() == RenderingEngine.Mvc)
{
_viewsFileSystem.AddFile(entity.Name, stream, true);
string viewName = string.Concat(entity.Alias, ".cshtml");
_viewsFileSystem.AddFile(viewName, stream, true);
}
else
{
_masterpagesFileSystem.AddFile(entity.Name, stream, true);
string masterpageName = string.Concat(entity.Alias, ".master");
_masterpagesFileSystem.AddFile(masterpageName, stream, true);
}
}
@@ -236,12 +244,19 @@ namespace Umbraco.Core.Persistence.Repositories
{
var parent = Database.First<NodeDto>("WHERE id = @ParentId", new { ParentId = ((Template)entity).ParentId });
entity.Path = string.Concat(parent.Path, ",", entity.Id);
((Template)entity).Level = parent.Level + 1;
var maxSortOrder =
Database.ExecuteScalar<int>(
"SELECT coalesce(max(sortOrder),0) FROM umbracoNode WHERE parentid = @ParentId AND nodeObjectType = @NodeObjectType",
new { ParentId = ((Template)entity).ParentId, NodeObjectType = NodeObjectTypeId });
((Template)entity).SortOrder = maxSortOrder + 1;
}
//Get TemplateDto from db to get the Primary key of the entity
var templateDto = Database.SingleOrDefault<TemplateDto>("WHERE nodeId = @Id", new { Id = entity.Id });
//Save updated entity to db
var template = entity as Template;
template.UpdateDate = DateTime.Now;
var factory = new TemplateFactory(templateDto.PrimaryKey, NodeObjectTypeId);
var dto = factory.BuildDto(template);
@@ -328,8 +343,8 @@ namespace Umbraco.Core.Persistence.Repositories
public ITemplate Get(string alias)
{
var sql = GetBaseQuery(false);
sql.Where("cmsTemplate.alias = @Alias", new { Alias = alias });
var sql = GetBaseQuery(false)
.Where<TemplateDto>(x => x.Alias == alias);
var dto = Database.Fetch<TemplateDto, NodeDto>(sql).FirstOrDefault();
@@ -1,11 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Caching;
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
@@ -4,7 +4,7 @@ using System.Data;
namespace Umbraco.Core.Persistence.SqlSyntax
{
internal class DbTypes<TSyntax>
public class DbTypes<TSyntax>
where TSyntax : ISqlSyntaxProvider
{
public DbType DbType;
@@ -31,6 +31,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
string InsertData { get; }
string UpdateData { get; }
string DeleteData { get; }
string TruncateTable { get; }
string CreateConstraint { get; }
string DeleteConstraint { get; }
string CreateForeignKeyConstraint { get; }
@@ -7,21 +7,20 @@ using Umbraco.Core.Persistence.DatabaseModelDefinitions;
namespace Umbraco.Core.Persistence.SqlSyntax
{
/// <summary>
/// Static class that provides simple access to the MySql SqlSyntax Providers singleton
/// Static class that provides simple access to the MySql SqlSyntax Provider
/// </summary>
internal static class MySqlSyntax
{
public static ISqlSyntaxProvider Provider { get { return MySqlSyntaxProvider.Instance; } }
public static ISqlSyntaxProvider Provider { get { return new MySqlSyntaxProvider(); } }
}
/// <summary>
/// Represents an SqlSyntaxProvider for MySql
/// </summary>
internal class MySqlSyntaxProvider : SqlSyntaxProviderBase<MySqlSyntaxProvider>
[SqlSyntaxProviderAttribute("MySql.Data.MySqlClient")]
public class MySqlSyntaxProvider : SqlSyntaxProviderBase<MySqlSyntaxProvider>
{
public static MySqlSyntaxProvider Instance = new MySqlSyntaxProvider();
private MySqlSyntaxProvider()
public MySqlSyntaxProvider()
{
DefaultStringLength = 255;
StringLengthColumnDefinitionFormat = StringLengthUnicodeColumnDefinitionFormat;
@@ -1,28 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Umbraco.Core.Persistence.DatabaseAnnotations;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
namespace Umbraco.Core.Persistence.SqlSyntax
{
/// <summary>
/// Static class that provides simple access to the Sql CE SqlSyntax Providers singleton
/// Static class that provides simple access to the Sql CE SqlSyntax Provider
/// </summary>
internal static class SqlCeSyntax
{
public static ISqlSyntaxProvider Provider { get { return SqlCeSyntaxProvider.Instance; } }
public static ISqlSyntaxProvider Provider { get { return new SqlCeSyntaxProvider(); } }
}
/// <summary>
/// Represents an SqlSyntaxProvider for Sql Ce
/// </summary>
internal class SqlCeSyntaxProvider : SqlSyntaxProviderBase<SqlCeSyntaxProvider>
[SqlSyntaxProviderAttribute("System.Data.SqlServerCe.4.0")]
public class SqlCeSyntaxProvider : SqlSyntaxProviderBase<SqlCeSyntaxProvider>
{
public static SqlCeSyntaxProvider Instance = new SqlCeSyntaxProvider();
private SqlCeSyntaxProvider()
public SqlCeSyntaxProvider()
{
StringLengthColumnDefinitionFormat = StringLengthUnicodeColumnDefinitionFormat;
StringColumnDefinition = string.Format(StringLengthColumnDefinitionFormat, DefaultStringLength);
@@ -44,6 +42,14 @@ namespace Umbraco.Core.Persistence.SqlSyntax
return false;
}
/// <summary>
/// SqlCe doesn't support the Truncate Table syntax, so we just have to do a DELETE FROM which is slower but we have no choice.
/// </summary>
public override string TruncateTable
{
get { return "DELETE FROM {0}"; }
}
public override string GetIndexType(IndexTypes indexTypes)
{
string indexType;
@@ -6,21 +6,20 @@ using Umbraco.Core.Persistence.DatabaseModelDefinitions;
namespace Umbraco.Core.Persistence.SqlSyntax
{
/// <summary>
/// Static class that provides simple access to the Sql Server SqlSyntax Providers singleton
/// Static class that provides simple access to the Sql Server SqlSyntax Provider
/// </summary>
internal static class SqlServerSyntax
{
public static ISqlSyntaxProvider Provider { get { return SqlServerSyntaxProvider.Instance; } }
public static ISqlSyntaxProvider Provider { get { return new SqlServerSyntaxProvider(); } }
}
/// <summary>
/// Represents an SqlSyntaxProvider for Sql Server
/// </summary>
internal class SqlServerSyntaxProvider : SqlSyntaxProviderBase<SqlServerSyntaxProvider>
[SqlSyntaxProviderAttribute("System.Data.SqlClient")]
public class SqlServerSyntaxProvider : SqlSyntaxProviderBase<SqlServerSyntaxProvider>
{
public static SqlServerSyntaxProvider Instance = new SqlServerSyntaxProvider();
private SqlServerSyntaxProvider()
public SqlServerSyntaxProvider()
{
StringLengthColumnDefinitionFormat = StringLengthUnicodeColumnDefinitionFormat;
StringColumnDefinition = string.Format(StringLengthColumnDefinitionFormat, DefaultStringLength);
@@ -3,9 +3,9 @@
namespace Umbraco.Core.Persistence.SqlSyntax
{
/// <summary>
/// Singleton to handle the configuration of an SqlSyntaxProvider
/// Singleton to handle the configuration of a SqlSyntaxProvider
/// </summary>
internal static class SyntaxConfig
public static class SqlSyntaxContext
{
private static ISqlSyntaxProvider _sqlSyntaxProvider;
@@ -16,7 +16,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
if(_sqlSyntaxProvider == null)
{
throw new ArgumentNullException("SqlSyntaxProvider",
"You must set the singleton 'Umbraco.Core.Persistence.SqlSyntax.SyntaxConfig' to use an sql syntax provider");
"You must set the singleton 'Umbraco.Core.Persistence.SqlSyntax.SqlSyntaxContext' to use an sql syntax provider");
}
return _sqlSyntaxProvider;
}
@@ -0,0 +1,21 @@
using System;
namespace Umbraco.Core.Persistence.SqlSyntax
{
/// <summary>
/// Attribute for implementations of an ISqlSyntaxProvider
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class SqlSyntaxProviderAttribute : Attribute
{
public SqlSyntaxProviderAttribute(string providerName)
{
ProviderName = providerName;
}
/// <summary>
/// Gets or sets the ProviderName that corresponds to the sql syntax in a provider.
/// </summary>
public string ProviderName { get; set; }
}
}
@@ -15,7 +15,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
/// All Sql Syntax provider implementations should derive from this abstract class.
/// </remarks>
/// <typeparam name="TSyntax"></typeparam>
internal abstract class SqlSyntaxProviderBase<TSyntax> : ISqlSyntaxProvider
public abstract class SqlSyntaxProviderBase<TSyntax> : ISqlSyntaxProvider
where TSyntax : ISqlSyntaxProvider
{
protected SqlSyntaxProviderBase()
@@ -436,6 +436,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
public virtual string InsertData { get { return "INSERT INTO {0} ({1}) VALUES ({2})"; } }
public virtual string UpdateData { get { return "UPDATE {0} SET {1} WHERE {2}"; } }
public virtual string DeleteData { get { return "DELETE FROM {0} WHERE {1}"; } }
public virtual string TruncateTable { get { return "TRUNCATE TABLE {0}"; } }
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}"; } }
@@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.ObjectResolution;
namespace Umbraco.Core.Persistence.SqlSyntax
{
/// <summary>
/// A resolver to return all ISqlSyntaxProvider objects
/// </summary>
internal sealed class SqlSyntaxProvidersResolver : ManyObjectsResolverBase<SqlSyntaxProvidersResolver, ISqlSyntaxProvider>
{
/// <summary>
/// Constructor
/// </summary>
/// <param name="syntaxProviders"></param>
internal SqlSyntaxProvidersResolver(IEnumerable<Type> syntaxProviders)
: base(syntaxProviders)
{
}
/// <summary>
/// Gets the <see cref="ISqlSyntaxProvider"/> implementations.
/// </summary>
public IEnumerable<ISqlSyntaxProvider> SqlSyntaxProviders
{
get
{
return Values;
}
}
/// <summary>
/// Gets a <see cref="ISqlSyntaxProvider"/> by its attributed provider.
/// </summary>
/// <param name="providerName">ProviderName from the ConnectionString settings</param>
/// <returns><see cref="ISqlSyntaxProvider"/> that corresponds to the attributed provider or the default Sql Server Syntax Provider.</returns>
public ISqlSyntaxProvider GetByProviderNameOrDefault(string providerName)
{
var provider =
Values.FirstOrDefault(
x =>
x.GetType()
.FirstAttribute<SqlSyntaxProviderAttribute>()
.ProviderName.ToLowerInvariant()
.Equals(providerName.ToLowerInvariant()));
if (provider != null)
return provider;
return Values.First(x => x.GetType() == typeof (SqlServerSyntaxProvider));
}
}
}
+10
View File
@@ -12,6 +12,7 @@ using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence.Migrations;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.PropertyEditors;
using umbraco.interfaces;
using File = System.IO.File;
@@ -477,6 +478,15 @@ namespace Umbraco.Core
return ResolveTypes<IMigration>();
}
/// <summary>
/// Returns all SqlSyntaxProviders with the SqlSyntaxProviderAttribute
/// </summary>
/// <returns></returns>
internal IEnumerable<Type> ResolveSqlSyntaxProviders()
{
return ResolveTypesWithAttribute<ISqlSyntaxProvider, SqlSyntaxProviderAttribute>();
}
/// <summary>
/// Gets/sets which assemblies to scan when type finding, generally used for unit testing, if not explicitly set
/// this will search all assemblies known to have plugins and exclude ones known to not have them.
File diff suppressed because it is too large Load Diff
+71 -55
View File
@@ -1,7 +1,10 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Threading;
using Umbraco.Core.Auditing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Events;
@@ -22,6 +25,9 @@ namespace Umbraco.Core.Services
private readonly IContentService _contentService;
private readonly IMediaService _mediaService;
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
//Support recursive locks because some of the methods that require locking call other methods that require locking.
//for example, the Move method needs to be locked but this calls the Save method which also needs to be locked.
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
public ContentTypeService(IContentService contentService, IMediaService mediaService)
: this(new PetaPocoUnitOfWorkProvider(), new RepositoryFactory(), contentService, mediaService)
@@ -173,19 +179,22 @@ namespace Umbraco.Core.Services
{
if (DeletingContentType.IsRaisedEventCancelled(new DeleteEventArgs<IContentType>(contentType), this))
return;
_contentService.DeleteContentOfType(contentType.Id);
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateContentTypeRepository(uow))
{
repository.Delete(contentType);
uow.Commit();
using (new WriteLock(Locker))
{
_contentService.DeleteContentOfType(contentType.Id);
DeletedContentType.RaiseEvent(new DeleteEventArgs<IContentType>(contentType, false), this);
}
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateContentTypeRepository(uow))
{
repository.Delete(contentType);
uow.Commit();
Audit.Add(AuditTypes.Delete, string.Format("Delete ContentType performed by user"), userId, contentType.Id);
DeletedContentType.RaiseEvent(new DeleteEventArgs<IContentType>(contentType, false), this);
}
Audit.Add(AuditTypes.Delete, string.Format("Delete ContentType performed by user"), userId, contentType.Id);
}
}
/// <summary>
@@ -200,27 +209,30 @@ namespace Umbraco.Core.Services
{
if (DeletingContentType.IsRaisedEventCancelled(new DeleteEventArgs<IContentType>(contentTypes), this))
return;
var contentTypeList = contentTypes.ToList();
foreach (var contentType in contentTypeList)
{
_contentService.DeleteContentOfType(contentType.Id);
}
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateContentTypeRepository(uow))
{
foreach (var contentType in contentTypeList)
{
repository.Delete(contentType);
}
using (new WriteLock(Locker))
{
var contentTypeList = contentTypes.ToList();
foreach (var contentType in contentTypeList)
{
_contentService.DeleteContentOfType(contentType.Id);
}
uow.Commit();
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateContentTypeRepository(uow))
{
foreach (var contentType in contentTypeList)
{
repository.Delete(contentType);
}
DeletedContentType.RaiseEvent(new DeleteEventArgs<IContentType>(contentTypes, false), this);
}
uow.Commit();
Audit.Add(AuditTypes.Delete, string.Format("Delete ContentTypes performed by user"), userId, -1);
DeletedContentType.RaiseEvent(new DeleteEventArgs<IContentType>(contentTypes, false), this);
}
Audit.Add(AuditTypes.Delete, string.Format("Delete ContentTypes performed by user"), userId, -1);
}
}
/// <summary>
@@ -357,20 +369,22 @@ namespace Umbraco.Core.Services
{
if (DeletingMediaType.IsRaisedEventCancelled(new DeleteEventArgs<IMediaType>(mediaType), this))
return;
_mediaService.DeleteMediaOfType(mediaType.Id, userId);
using (new WriteLock(Locker))
{
_mediaService.DeleteMediaOfType(mediaType.Id, userId);
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
{
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
{
repository.Delete(mediaType);
uow.Commit();
repository.Delete(mediaType);
uow.Commit();
DeletedMediaType.RaiseEvent(new DeleteEventArgs<IMediaType>(mediaType, false), this);
}
DeletedMediaType.RaiseEvent(new DeleteEventArgs<IMediaType>(mediaType, false), this);
}
Audit.Add(AuditTypes.Delete, string.Format("Delete MediaType performed by user"), userId, mediaType.Id);
Audit.Add(AuditTypes.Delete, string.Format("Delete MediaType performed by user"), userId, mediaType.Id);
}
}
/// <summary>
@@ -383,26 +397,28 @@ namespace Umbraco.Core.Services
{
if (DeletingMediaType.IsRaisedEventCancelled(new DeleteEventArgs<IMediaType>(mediaTypes), this))
return;
var mediaTypeList = mediaTypes.ToList();
foreach (var mediaType in mediaTypeList)
{
_mediaService.DeleteMediaOfType(mediaType.Id);
}
using (new WriteLock(Locker))
{
var mediaTypeList = mediaTypes.ToList();
foreach (var mediaType in mediaTypeList)
{
_mediaService.DeleteMediaOfType(mediaType.Id);
}
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
{
foreach (var mediaType in mediaTypeList)
{
repository.Delete(mediaType);
}
uow.Commit();
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
{
foreach (var mediaType in mediaTypeList)
{
repository.Delete(mediaType);
}
uow.Commit();
DeletedMediaType.RaiseEvent(new DeleteEventArgs<IMediaType>(mediaTypes, false), this);
}
DeletedMediaType.RaiseEvent(new DeleteEventArgs<IMediaType>(mediaTypes, false), this);
}
Audit.Add(AuditTypes.Delete, string.Format("Delete MediaTypes performed by user"), userId, -1);
Audit.Add(AuditTypes.Delete, string.Format("Delete MediaTypes performed by user"), userId, -1);
}
}
/// <summary>
@@ -459,7 +475,7 @@ namespace Umbraco.Core.Services
}
return dtd.ToString();
}
#region Event Handlers
/// <summary>
+99 -16
View File
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Umbraco.Core.Auditing;
using Umbraco.Core.Events;
using Umbraco.Core.Models;
@@ -19,6 +20,7 @@ namespace Umbraco.Core.Services
{
private readonly RepositoryFactory _repositoryFactory;
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
public DataTypeService()
: this(new RepositoryFactory())
@@ -105,11 +107,26 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of string values</returns>
public IEnumerable<string> GetPreValuesByDataTypeId(int id)
{
var uow = _uowProvider.GetUnitOfWork();
var dtos = uow.Database.Fetch<DataTypePreValueDto>("WHERE datatypeNodeId = @Id", new {Id = id});
var list = dtos.Select(x => x.Value).ToList();
uow.Dispose();
return list;
using (var uow = _uowProvider.GetUnitOfWork())
{
var dtos = uow.Database.Fetch<DataTypePreValueDto>("WHERE datatypeNodeId = @Id", new {Id = id});
var list = dtos.Select(x => x.Value).ToList();
return list;
}
}
/// <summary>
/// Gets a specific PreValue by its Id
/// </summary>
/// <param name="id">Id of the PreValue to retrieve the value from</param>
/// <returns>PreValue as a string</returns>
public string GetPreValueAsString(int id)
{
using (var uow = _uowProvider.GetUnitOfWork())
{
var dto = uow.Database.FirstOrDefault<DataTypePreValueDto>("WHERE id = @Id", new { Id = id });
return dto != null ? dto.Value : string.Empty;
}
}
/// <summary>
@@ -121,18 +138,84 @@ namespace Umbraco.Core.Services
{
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IDataTypeDefinition>(dataTypeDefinition), this))
return;
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateDataTypeDefinitionRepository(uow))
{
dataTypeDefinition.CreatorId = userId;
repository.AddOrUpdate(dataTypeDefinition);
uow.Commit();
Saved.RaiseEvent(new SaveEventArgs<IDataTypeDefinition>(dataTypeDefinition, false), this);
}
using (new WriteLock(Locker))
{
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateDataTypeDefinitionRepository(uow))
{
dataTypeDefinition.CreatorId = userId;
repository.AddOrUpdate(dataTypeDefinition);
uow.Commit();
Audit.Add(AuditTypes.Save, string.Format("Save DataTypeDefinition performed by user"), userId, dataTypeDefinition.Id);
Saved.RaiseEvent(new SaveEventArgs<IDataTypeDefinition>(dataTypeDefinition, false), this);
}
}
Audit.Add(AuditTypes.Save, string.Format("Save DataTypeDefinition performed by user"), userId, dataTypeDefinition.Id);
}
/// <summary>
/// Saves a collection of <see cref="IDataTypeDefinition"/>
/// </summary>
/// <param name="dataTypeDefinitions"><see cref="IDataTypeDefinition"/> to save</param>
/// <param name="userId">Id of the user issueing the save</param>
public void Save(IEnumerable<IDataTypeDefinition> dataTypeDefinitions, int userId = 0)
{
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IDataTypeDefinition>(dataTypeDefinitions), this))
return;
using (new WriteLock(Locker))
{
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateDataTypeDefinitionRepository(uow))
{
foreach (var dataTypeDefinition in dataTypeDefinitions)
{
dataTypeDefinition.CreatorId = userId;
repository.AddOrUpdate(dataTypeDefinition);
}
uow.Commit();
Saved.RaiseEvent(new SaveEventArgs<IDataTypeDefinition>(dataTypeDefinitions, false), this);
}
}
Audit.Add(AuditTypes.Save, string.Format("Save DataTypeDefinition performed by user"), userId, -1);
}
/// <summary>
/// Saves a list of PreValues for a given DataTypeDefinition
/// </summary>
/// <param name="id">Id of the DataTypeDefinition to save PreValues for</param>
/// <param name="values">List of string values to save</param>
public void SavePreValues(int id, IEnumerable<string> values)
{
using (new WriteLock(Locker))
{
using (var uow = _uowProvider.GetUnitOfWork())
{
var sortOrderObj =
uow.Database.ExecuteScalar<object>(
"SELECT max(sortorder) FROM cmsDataTypePreValues WHERE datatypeNodeId = @DataTypeId", new { DataTypeId = id });
int sortOrder;
if (sortOrderObj == null || int.TryParse(sortOrderObj.ToString(), out sortOrder) == false)
{
sortOrder = 1;
}
using (var transaction = uow.Database.GetTransaction())
{
foreach (var value in values)
{
var dto = new DataTypePreValueDto { DataTypeNodeId = id, Value = value, SortOrder = sortOrder };
uow.Database.Insert(dto);
sortOrder++;
}
transaction.Complete();
}
}
}
}
/// <summary>
@@ -163,7 +246,7 @@ namespace Umbraco.Core.Services
foreach (var group in contentType.PropertyGroups)
{
var types = @group.PropertyTypes.Where(x => x.DataTypeDefinitionId == dataTypeDefinition.Id);
var types = @group.PropertyTypes.Where(x => x.DataTypeDefinitionId == dataTypeDefinition.Id).ToList();
foreach (var propertyType in types)
{
@group.PropertyTypes.Remove(propertyType);
+25
View File
@@ -255,6 +255,31 @@ namespace Umbraco.Core.Services
Audit.Add(AuditTypes.Save, string.Format("Save Template performed by user"), userId, template.Id);
}
/// <summary>
/// Saves a collection of <see cref="Template"/> objects
/// </summary>
/// <param name="templates">List of <see cref="Template"/> to save</param>
/// <param name="userId">Optional id of the user</param>
public void SaveTemplate(IEnumerable<ITemplate> templates, int userId = 0)
{
if (SavingTemplate.IsRaisedEventCancelled(new SaveEventArgs<ITemplate>(templates), this))
return;
var uow = _dataUowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateTemplateRepository(uow))
{
foreach (var template in templates)
{
repository.AddOrUpdate(template);
}
uow.Commit();
SavedTemplate.RaiseEvent(new SaveEventArgs<ITemplate>(templates, false), this);
}
Audit.Add(AuditTypes.Save, string.Format("Save Template performed by user"), userId, -1);
}
/// <summary>
/// Deletes a template by its alias
/// </summary>
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Xml.Linq;
using Umbraco.Core.Models;
namespace Umbraco.Core.Services
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Xml.Linq;
using Umbraco.Core.Models;
namespace Umbraco.Core.Services
@@ -38,6 +38,13 @@ namespace Umbraco.Core.Services
/// <param name="userId">Id of the user issueing the save</param>
void Save(IDataTypeDefinition dataTypeDefinition, int userId = 0);
/// <summary>
/// Saves a collection of <see cref="IDataTypeDefinition"/>
/// </summary>
/// <param name="dataTypeDefinitions"><see cref="IDataTypeDefinition"/> to save</param>
/// <param name="userId">Id of the user issueing the save</param>
void Save(IEnumerable<IDataTypeDefinition> dataTypeDefinitions, int userId = 0);
/// <summary>
/// Deletes an <see cref="IDataTypeDefinition"/>
/// </summary>
@@ -75,5 +82,19 @@ namespace Umbraco.Core.Services
/// <param name="id">Id of the <see cref="IDataTypeDefinition"/> to retrieve prevalues from</param>
/// <returns>An enumerable list of string values</returns>
IEnumerable<string> GetPreValuesByDataTypeId(int id);
/// <summary>
/// Saves a list of PreValues for a given DataTypeDefinition
/// </summary>
/// <param name="id">Id of the DataTypeDefinition to save PreValues for</param>
/// <param name="values">List of string values to save</param>
void SavePreValues(int id, IEnumerable<string> values);
/// <summary>
/// Gets a specific PreValue by its Id
/// </summary>
/// <param name="id">Id of the PreValue to retrieve the value from</param>
/// <returns>PreValue as a string</returns>
string GetPreValueAsString(int id);
}
}
@@ -116,5 +116,12 @@ namespace Umbraco.Core.Services
/// <param name="template"><see cref="ITemplate"/> to validate</param>
/// <returns>True if Script is valid, otherwise false</returns>
bool ValidateTemplate(ITemplate template);
/// <summary>
/// Saves a collection of <see cref="Template"/> objects
/// </summary>
/// <param name="templates">List of <see cref="Template"/> to save</param>
/// <param name="userId">Optional id of the user</param>
void SaveTemplate(IEnumerable<ITemplate> templates, int userId = 0);
}
}
@@ -177,5 +177,12 @@ namespace Umbraco.Core.Services
/// <param name="deletePriorVersions">Boolean indicating whether to delete versions prior to the versionId</param>
/// <param name="userId">Optional Id of the User deleting versions of a Content object</param>
void DeleteVersion(int id, Guid versionId, bool deletePriorVersions, int userId = 0);
/// <summary>
/// Gets an <see cref="IMedia"/> object from the path stored in the 'umbracoFile' property.
/// </summary>
/// <param name="mediaPath">Path of the media item to retreive (for example: /media/1024/koala_403x328.jpg)</param>
/// <returns><see cref="IMedia"/></returns>
IMedia GetMediaByPath(string mediaPath);
}
}
+136 -68
View File
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Xml.Linq;
using Umbraco.Core.Auditing;
using Umbraco.Core.Events;
@@ -19,6 +20,9 @@ namespace Umbraco.Core.Services
{
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
private readonly RepositoryFactory _repositoryFactory;
//Support recursive locks because some of the methods that require locking call other methods that require locking.
//for example, the Move method needs to be locked but this calls the Save method which also needs to be locked.
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
public MediaService(RepositoryFactory repositoryFactory)
: this(new PetaPocoUnitOfWorkProvider(), repositoryFactory)
@@ -42,7 +46,8 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IMedia"/></returns>
public IMedia CreateMedia(string name, int parentId, string mediaTypeAlias, int userId = 0)
{
IMediaType mediaType = null;
IMediaType mediaType;
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
{
@@ -62,8 +67,11 @@ namespace Umbraco.Core.Services
var media = new Models.Media(name, parentId, mediaType);
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IMedia>(media, mediaTypeAlias, parentId), this))
return media;
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IMedia>(media, mediaTypeAlias, parentId), this))
{
media.WasCancelled = true;
return media;
}
media.CreatorId = userId;
@@ -85,7 +93,8 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IMedia"/></returns>
public IMedia CreateMedia(string name, IMedia parent, string mediaTypeAlias, int userId = 0)
{
IMediaType mediaType = null;
IMediaType mediaType;
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
{
@@ -104,9 +113,11 @@ namespace Umbraco.Core.Services
}
var media = new Models.Media(name, parent, mediaType);
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IMedia>(media, mediaTypeAlias, parent), this))
{
media.WasCancelled = true;
return media;
}
media.CreatorId = userId;
@@ -155,7 +166,7 @@ namespace Umbraco.Core.Services
{
using (var repository = _repositoryFactory.CreateMediaRepository(_uowProvider.GetUnitOfWork()))
{
var query = Query<IMedia>.Builder.Where(x => x.Level == level);
var query = Query<IMedia>.Builder.Where(x => x.Level == level && !x.Path.StartsWith("-21"));
var contents = repository.GetByQuery(query);
return contents;
@@ -283,6 +294,40 @@ namespace Umbraco.Core.Services
}
}
/// <summary>
/// Gets an <see cref="IMedia"/> object from the path stored in the 'umbracoFile' property.
/// </summary>
/// <param name="mediaPath">Path of the media item to retreive (for example: /media/1024/koala_403x328.jpg)</param>
/// <returns><see cref="IMedia"/></returns>
public IMedia GetMediaByPath(string mediaPath)
{
var umbracoFileValue = mediaPath;
var isResized = mediaPath.Contains("_") && mediaPath.Contains("x");
// If the image has been resized we strip the "_403x328" of the original "/media/1024/koala_403x328.jpg" url.
if (isResized)
{
var underscoreIndex = mediaPath.LastIndexOf('_');
var dotIndex = mediaPath.LastIndexOf('.');
umbracoFileValue = string.Concat(mediaPath.Substring(0, underscoreIndex), mediaPath.Substring(dotIndex));
}
var sql = new Sql()
.Select("*")
.From<PropertyDataDto>()
.InnerJoin<PropertyTypeDto>()
.On<PropertyDataDto, PropertyTypeDto>(left => left.PropertyTypeId, right => right.Id)
.Where<PropertyTypeDto>(x => x.Alias == "umbracoFile")
.Where<PropertyDataDto>(x => x.VarChar == umbracoFileValue);
using (var uow = _uowProvider.GetUnitOfWork())
{
var propertyDataDto = uow.Database.Fetch<PropertyDataDto, PropertyTypeDto>(sql).FirstOrDefault();
return propertyDataDto == null ? null : GetById(propertyDataDto.NodeId);
}
}
/// <summary>
/// Checks whether an <see cref="IMedia"/> item has any children
/// </summary>
@@ -306,32 +351,35 @@ namespace Umbraco.Core.Services
/// <param name="userId">Id of the User moving the Media</param>
public void Move(IMedia media, int parentId, int userId = 0)
{
//This ensures that the correct method is called if this method is used to Move to recycle bin.
if (parentId == -21)
{
MoveToRecycleBin(media, userId);
return;
}
using (new WriteLock(Locker))
{
//This ensures that the correct method is called if this method is used to Move to recycle bin.
if (parentId == -21)
{
MoveToRecycleBin(media, userId);
return;
}
if (Moving.IsRaisedEventCancelled(new MoveEventArgs<IMedia>(media, parentId), this))
return;
if (Moving.IsRaisedEventCancelled(new MoveEventArgs<IMedia>(media, parentId), this))
return;
media.ParentId = parentId;
Save(media, userId);
media.ParentId = parentId;
Save(media, userId);
//Ensure that Path and Level is updated on children
var children = GetChildren(media.Id);
if (children.Any())
{
var parentPath = media.Path;
var parentLevel = media.Level;
var updatedDescendents = UpdatePathAndLevelOnChildren(children, parentPath, parentLevel);
Save(updatedDescendents, userId);
}
//Ensure that Path and Level is updated on children
var children = GetChildren(media.Id);
if (children.Any())
{
var parentPath = media.Path;
var parentLevel = media.Level;
var updatedDescendents = UpdatePathAndLevelOnChildren(children, parentPath, parentLevel);
Save(updatedDescendents, userId);
}
Moved.RaiseEvent(new MoveEventArgs<IMedia>(media, false, parentId), this);
Moved.RaiseEvent(new MoveEventArgs<IMedia>(media, false, parentId), this);
Audit.Add(AuditTypes.Move, "Move Media performed by user", userId, media.Id);
Audit.Add(AuditTypes.Move, "Move Media performed by user", userId, media.Id);
}
}
/// <summary>
@@ -345,7 +393,7 @@ namespace Umbraco.Core.Services
return;
//Find Descendants, which will be moved to the recycle bin along with the parent/grandparent.
var descendants = GetDescendants(media).ToList();
var descendants = GetDescendants(media).OrderBy(x => x.Level).ToList();
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
@@ -378,8 +426,8 @@ namespace Umbraco.Core.Services
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
{
var query = Query<IMedia>.Builder.Where(x => x.Path.Contains("-21"));
var contents = repository.GetByQuery(query).OrderByDescending(x => x.ParentId);
var query = Query<IMedia>.Builder.Where(x => x.Trashed == true);
var contents = repository.GetByQuery(query).OrderByDescending(x => x.Level);
foreach (var content in contents)
{
@@ -403,39 +451,49 @@ namespace Umbraco.Core.Services
/// <param name="mediaTypeId">Id of the <see cref="IMediaType"/></param>
/// <param name="userId">Optional id of the user deleting the media</param>
public void DeleteMediaOfType(int mediaTypeId, int userId = 0)
{
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
{
using (new WriteLock(Locker))
{
//NOTE What about media that has the contenttype as part of its composition?
//The ContentType has to be removed from the composition somehow as it would otherwise break
//Dbl.check+test that the ContentType's Id is removed from the ContentType2ContentType table
var query = Query<IMedia>.Builder.Where(x => x.ContentTypeId == mediaTypeId);
var contents = repository.GetByQuery(query);
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
{
//NOTE What about media that has the contenttype as part of its composition?
//The ContentType has to be removed from the composition somehow as it would otherwise break
//Dbl.check+test that the ContentType's Id is removed from the ContentType2ContentType table
var query = Query<IMedia>.Builder.Where(x => x.ContentTypeId == mediaTypeId);
var contents = repository.GetByQuery(query);
if (Deleting.IsRaisedEventCancelled(new DeleteEventArgs<IMedia>(contents), this))
return;
if (Deleting.IsRaisedEventCancelled(new DeleteEventArgs<IMedia>(contents), this))
return;
foreach (var content in contents)
{
((Core.Models.Media)content).ChangeTrashedState(true);
repository.AddOrUpdate(content);
}
foreach (var content in contents.OrderByDescending(x => x.ParentId))
{
//Look for children of current content and move that to trash before the current content is deleted
var c = content;
var childQuery = Query<IMedia>.Builder.Where(x => x.Path.StartsWith(c.Path));
var children = repository.GetByQuery(childQuery);
uow.Commit();
foreach (var child in children)
{
if (child.ContentType.Id != mediaTypeId)
MoveToRecycleBin(child, userId);
}
Deleted.RaiseEvent(new DeleteEventArgs<IMedia>(contents, false), this);
}
//Permantly delete the content
Delete(content, userId);
}
}
Audit.Add(AuditTypes.Delete, "Delete Media items by Type performed by user", userId, -1);
}
Audit.Add(AuditTypes.Delete, "Delete Media items by Type performed by user", userId, -1);
}
}
/// <summary>
/// Permanently deletes an <see cref="IMedia"/> object
/// Permanently deletes an <see cref="IMedia"/> object as well as all of its Children.
/// </summary>
/// <remarks>
/// Please note that this method will completely remove the Media from the database,
/// but current not from the file system.
/// as well as associated media files from the file system.
/// </remarks>
/// <param name="media">The <see cref="IMedia"/> to delete</param>
/// <param name="userId">Id of the User deleting the Media</param>
@@ -444,6 +502,13 @@ namespace Umbraco.Core.Services
if (Deleting.IsRaisedEventCancelled(new DeleteEventArgs<IMedia>(media), this))
return;
//Delete children before deleting the 'possible parent'
var children = GetChildren(media.Id);
foreach (var child in children)
{
Delete(child, userId);
}
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
{
@@ -523,25 +588,28 @@ namespace Umbraco.Core.Services
return;
}
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
{
media.CreatorId = userId;
repository.AddOrUpdate(media);
uow.Commit();
using (new WriteLock(Locker))
{
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateMediaRepository(uow))
{
media.CreatorId = userId;
repository.AddOrUpdate(media);
uow.Commit();
var xml = media.ToXml();
var poco = new ContentXmlDto { NodeId = media.Id, Xml = xml.ToString(SaveOptions.None) };
var exists = uow.Database.FirstOrDefault<ContentXmlDto>("WHERE nodeId = @Id", new { Id = media.Id }) != null;
int result = exists
? uow.Database.Update(poco)
: Convert.ToInt32(uow.Database.Insert(poco));
}
var xml = media.ToXml();
var poco = new ContentXmlDto {NodeId = media.Id, Xml = xml.ToString(SaveOptions.None)};
var exists = uow.Database.FirstOrDefault<ContentXmlDto>("WHERE nodeId = @Id", new {Id = media.Id}) != null;
int result = exists
? uow.Database.Update(poco)
: Convert.ToInt32(uow.Database.Insert(poco));
}
if(raiseEvents)
Saved.RaiseEvent(new SaveEventArgs<IMedia>(media, false), this);
if (raiseEvents)
Saved.RaiseEvent(new SaveEventArgs<IMedia>(media, false), this);
Audit.Add(AuditTypes.Save, "Save Media performed by user", media.CreatorId, media.Id);
Audit.Add(AuditTypes.Save, "Save Media performed by user", media.CreatorId, media.Id);
}
}
/// <summary>
@@ -0,0 +1,674 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Xml.Linq;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Services
{
/// <summary>
/// Represents the Packaging Service, which provides import/export functionality for the Core models of the API
/// using xml representation. This is primarily used by the Package functionality.
/// </summary>
public class PackagingService : IService
{
private readonly IContentService _contentService;
private readonly IContentTypeService _contentTypeService;
private readonly IMediaService _mediaService;
private readonly IDataTypeService _dataTypeService;
private readonly IFileService _fileService;
private readonly RepositoryFactory _repositoryFactory;
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
private Dictionary<string, IContentType> _importedContentTypes;
//Support recursive locks because some of the methods that require locking call other methods that require locking.
//for example, the Move method needs to be locked but this calls the Save method which also needs to be locked.
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
public PackagingService(IContentService contentService, IContentTypeService contentTypeService, IMediaService mediaService, IDataTypeService dataTypeService, IFileService fileService, RepositoryFactory repositoryFactory, IDatabaseUnitOfWorkProvider uowProvider)
{
_contentService = contentService;
_contentTypeService = contentTypeService;
_mediaService = mediaService;
_dataTypeService = dataTypeService;
_fileService = fileService;
_repositoryFactory = repositoryFactory;
_uowProvider = uowProvider;
_importedContentTypes = new Dictionary<string, IContentType>();
}
#region Content
/// <summary>
/// Imports and saves package xml as <see cref="IContent"/>
/// </summary>
/// <param name="element">Xml to import</param>
/// <param name="parentId">Optional parent Id for the content being imported</param>
/// <param name="userId">Optional Id of the user performing the import</param>
/// <returns>An enumrable list of generated content</returns>
public IEnumerable<IContent> ImportContent(XElement element, int parentId = -1, int userId = 0)
{
var name = element.Name.LocalName;
if (name.Equals("DocumentSet"))
{
//This is a regular deep-structured import
var roots = from doc in element.Elements()
where (string)doc.Attribute("isDoc") == ""
select doc;
var contents = ParseDocumentRootXml(roots, parentId);
if(contents.Any())
_contentService.Save(contents, userId);
return contents;
}
var attribute = element.Attribute("isDoc");
if (attribute != null)
{
//This is a single doc import
var elements = new List<XElement> { element };
var contents = ParseDocumentRootXml(elements, parentId);
if (contents.Any())
_contentService.Save(contents, userId);
return contents;
}
throw new ArgumentException(
"The passed in XElement is not valid! It does not contain a root element called " +
"'DocumentSet' (for structured imports) nor is the first element a Document (for single document import).");
}
private IEnumerable<IContent> ParseDocumentRootXml(IEnumerable<XElement> roots, int parentId)
{
var contents = new List<IContent>();
foreach (var root in roots)
{
bool isLegacySchema = root.Name.LocalName.ToLowerInvariant().Equals("node");
string contentTypeAlias = isLegacySchema
? root.Attribute("nodeTypeAlias").Value
: root.Name.LocalName;
if (_importedContentTypes.ContainsKey(contentTypeAlias) == false)
{
var contentType = FindContentTypeByAlias(contentTypeAlias);
_importedContentTypes.Add(contentTypeAlias, contentType);
}
var content = CreateContentFromXml(root, _importedContentTypes[contentTypeAlias], null, parentId, isLegacySchema);
contents.Add(content);
var children = from child in root.Elements()
where (string)child.Attribute("isDoc") == ""
select child;
if (children.Any())
contents.AddRange(CreateContentFromXml(children, content, isLegacySchema));
}
return contents;
}
private IEnumerable<IContent> CreateContentFromXml(IEnumerable<XElement> children, IContent parent, bool isLegacySchema)
{
var list = new List<IContent>();
foreach (var child in children)
{
string contentTypeAlias = isLegacySchema
? child.Attribute("nodeTypeAlias").Value
: child.Name.LocalName;
if (_importedContentTypes.ContainsKey(contentTypeAlias) == false)
{
var contentType = FindContentTypeByAlias(contentTypeAlias);
_importedContentTypes.Add(contentTypeAlias, contentType);
}
//Create and add the child to the list
var content = CreateContentFromXml(child, _importedContentTypes[contentTypeAlias], parent, default(int), isLegacySchema);
list.Add(content);
//Recursive call
XElement child1 = child;
var grandChildren = from grand in child1.Elements()
where (string)grand.Attribute("isDoc") == ""
select grand;
if (grandChildren.Any())
list.AddRange(CreateContentFromXml(grandChildren, content, isLegacySchema));
}
return list;
}
private IContent CreateContentFromXml(XElement element, IContentType contentType, IContent parent, int parentId, bool isLegacySchema)
{
var id = element.Attribute("id").Value;
var level = element.Attribute("level").Value;
var sortOrder = element.Attribute("sortOrder").Value;
var nodeName = element.Attribute("nodeName").Value;
var path = element.Attribute("path").Value;
var template = element.Attribute("template").Value;
var properties = from property in element.Elements()
where property.Attribute("isDoc") == null
select property;
IContent content = parent == null
? new Content(nodeName, parentId, contentType)
{
Level = int.Parse(level),
SortOrder = int.Parse(sortOrder)
}
: new Content(nodeName, parent, contentType)
{
Level = int.Parse(level),
SortOrder = int.Parse(sortOrder)
};
foreach (var property in properties)
{
string propertyTypeAlias = isLegacySchema ? property.Attribute("alias").Value : property.Name.LocalName;
if (content.HasProperty(propertyTypeAlias))
content.SetValue(propertyTypeAlias, property.Value);
}
return content;
}
internal XElement Export(IContent content, bool deep = false)
{
throw new NotImplementedException();
}
#endregion
#region ContentTypes
/// <summary>
/// Imports and saves package xml as <see cref="IContentType"/>
/// </summary>
/// <param name="element">Xml to import</param>
/// <param name="userId">Optional id of the User performing the operation. Default is zero (admin).</param>
/// <returns>An enumrable list of generated ContentTypes</returns>
public IEnumerable<IContentType> ImportContentTypes(XElement element, int userId = 0)
{
return ImportContentTypes(element, true, userId);
}
/// <summary>
/// Imports and saves package xml as <see cref="IContentType"/>
/// </summary>
/// <param name="element">Xml to import</param>
/// <param name="importStructure">Boolean indicating whether or not to import the </param>
/// <param name="userId">Optional id of the User performing the operation. Default is zero (admin).</param>
/// <returns>An enumrable list of generated ContentTypes</returns>
public IEnumerable<IContentType> ImportContentTypes(XElement element, bool importStructure, int userId = 0)
{
var name = element.Name.LocalName;
if (name.Equals("DocumentTypes") == false && name.Equals("DocumentType") == false)
{
throw new ArgumentException("The passed in XElement is not valid! It does not contain a root element called 'DocumentTypes' for multiple imports or 'DocumentType' for a single import.");
}
_importedContentTypes = new Dictionary<string, IContentType>();
var documentTypes = name.Equals("DocumentTypes")
? (from doc in element.Elements("DocumentType") select doc).ToList()
: new List<XElement> {element};
//NOTE it might be an idea to sort the doctype XElements based on dependencies
//before creating the doc types - should also allow for a better structure/inheritance support.
foreach (var documentType in documentTypes)
{
var alias = documentType.Element("Info").Element("Alias").Value;
if (_importedContentTypes.ContainsKey(alias) == false)
{
var contentType = _contentTypeService.GetContentType(alias);
_importedContentTypes.Add(alias, contentType == null
? CreateContentTypeFromXml(documentType)
: UpdateContentTypeFromXml(documentType, contentType));
}
}
var list = _importedContentTypes.Select(x => x.Value).ToList();
_contentTypeService.Save(list, userId);
if (importStructure)
{
var updatedContentTypes = new List<IContentType>();
//Update the structure here - we can't do it untill all DocTypes have been created
foreach (var documentType in documentTypes)
{
var alias = documentType.Element("Info").Element("Alias").Value;
var structureElement = documentType.Element("Structure");
//Ensure that we only update ContentTypes which has actual structure-elements
if (structureElement == null || structureElement.Elements("DocumentType").Any() == false) continue;
var updated = UpdateContentTypesStructure(_importedContentTypes[alias], structureElement);
updatedContentTypes.Add(updated);
}
//Update ContentTypes with a newly added structure/list of allowed children
if (updatedContentTypes.Any())
_contentTypeService.Save(updatedContentTypes, userId);
}
return list;
}
private IContentType CreateContentTypeFromXml(XElement documentType)
{
var infoElement = documentType.Element("Info");
//Name of the master corresponds to the parent
var masterElement = infoElement.Element("Master");
IContentType parent = null;
if (masterElement != null)
{
var masterAlias = masterElement.Value;
parent = _importedContentTypes.ContainsKey(masterAlias)
? _importedContentTypes[masterAlias]
: _contentTypeService.GetContentType(masterAlias);
}
var contentType = parent == null
? new ContentType(-1)
{
Alias = infoElement.Element("Alias").Value
}
: new ContentType(parent)
{
Alias = infoElement.Element("Alias").Value
};
if (parent != null)
contentType.AddContentType(parent);
return UpdateContentTypeFromXml(documentType, contentType);
}
private IContentType UpdateContentTypeFromXml(XElement documentType, IContentType contentType)
{
var infoElement = documentType.Element("Info");
var defaultTemplateElement = infoElement.Element("DefaultTemplate");
contentType.Name = infoElement.Element("Name").Value;
contentType.Icon = infoElement.Element("Icon").Value;
contentType.Thumbnail = infoElement.Element("Thumbnail").Value;
contentType.Description = infoElement.Element("Description").Value;
//NOTE AllowAtRoot is a new property in the package xml so we need to verify it exists before using it.
if (infoElement.Element("AllowAtRoot") != null)
contentType.AllowedAsRoot = infoElement.Element("AllowAtRoot").Value.ToLowerInvariant().Equals("true");
UpdateContentTypesAllowedTemplates(contentType, infoElement.Element("AllowedTemplates"), defaultTemplateElement);
UpdateContentTypesTabs(contentType, documentType.Element("Tabs"));
UpdateContentTypesProperties(contentType, documentType.Element("GenericProperties"));
return contentType;
}
private void UpdateContentTypesAllowedTemplates(IContentType contentType,
XElement allowedTemplatesElement, XElement defaultTemplateElement)
{
if (allowedTemplatesElement != null && allowedTemplatesElement.Elements("Template").Any())
{
var allowedTemplates = contentType.AllowedTemplates.ToList();
foreach (var templateElement in allowedTemplatesElement.Elements("Template"))
{
var alias = templateElement.Value;
var template = _fileService.GetTemplate(alias);
if (template != null)
{
allowedTemplates.Add(template);
}
else
{
LogHelper.Warn<PackagingService>(
string.Format(
"Packager: Error handling allowed templates. Template with alias '{0}' could not be found.",
alias));
}
}
contentType.AllowedTemplates = allowedTemplates;
}
if (string.IsNullOrEmpty(defaultTemplateElement.Value) == false)
{
var defaultTemplate = _fileService.GetTemplate(defaultTemplateElement.Value);
if (defaultTemplate != null)
{
contentType.SetDefaultTemplate(defaultTemplate);
}
else
{
LogHelper.Warn<PackagingService>(
string.Format(
"Packager: Error handling default template. Default template with alias '{0}' could not be found.",
defaultTemplateElement.Value));
}
}
}
private void UpdateContentTypesTabs(IContentType contentType, XElement tabElement)
{
if(tabElement == null)
return;
var tabs = tabElement.Elements("Tab");
foreach (var tab in tabs)
{
var id = tab.Element("Id").Value;//Do we need to use this for tracking?
var caption = tab.Element("Caption").Value;
if (contentType.PropertyGroups.Contains(caption) == false)
{
contentType.AddPropertyGroup(caption);
}
}
}
private void UpdateContentTypesProperties(IContentType contentType, XElement genericPropertiesElement)
{
var properties = genericPropertiesElement.Elements("GenericProperty");
foreach (var property in properties)
{
var dataTypeId = new Guid(property.Element("Type").Value);//The DataType's Control Id
var dataTypeDefinitionId = new Guid(property.Element("Definition").Value);//Unique Id for a DataTypeDefinition
var dataTypeDefinition = _dataTypeService.GetDataTypeDefinitionById(dataTypeDefinitionId);
//If no DataTypeDefinition with the guid from the xml wasn't found OR the ControlId on the DataTypeDefinition didn't match the DataType Id
//We look up a DataTypeDefinition that matches
if (dataTypeDefinition == null || dataTypeDefinition.ControlId != dataTypeId)
{
var dataTypeDefinitions = _dataTypeService.GetDataTypeDefinitionByControlId(dataTypeId);
if (dataTypeDefinitions != null && dataTypeDefinitions.Any())
{
dataTypeDefinition = dataTypeDefinitions.First();
}
}
// For backwards compatibility, if no datatype with that ID can be found, we're letting this fail silently.
// This means that the property will not be created.
if(dataTypeDefinition == null)
{
LogHelper.Warn<PackagingService>(string.Format("Packager: Error handling creation of PropertyType '{0}'. Could not find DataTypeDefintion with unique id '{1}' nor one referencing the DataType with control id '{2}'. Did the package creator forget to package up custom datatypes?",
property.Element("Name").Value, dataTypeDefinitionId, dataTypeId));
continue;
}
var propertyType = new PropertyType(dataTypeDefinition)
{
Alias = property.Element("Alias").Value,
Name = property.Element("Name").Value,
Description = property.Element("Description").Value,
Mandatory = property.Element("Mandatory").Value.ToLowerInvariant().Equals("true"),
ValidationRegExp = property.Element("Validation").Value
};
var helpTextElement = property.Element("HelpText");
if (helpTextElement != null)
{
propertyType.HelpText = helpTextElement.Value;
}
var tab = property.Element("Tab").Value;
if (string.IsNullOrEmpty(tab))
{
contentType.AddPropertyType(propertyType);
}
else
{
contentType.AddPropertyType(propertyType, tab);
}
}
}
private IContentType UpdateContentTypesStructure(IContentType contentType, XElement structureElement)
{
var allowedChildren = contentType.AllowedContentTypes.ToList();
int sortOrder = allowedChildren.Any() ? allowedChildren.Last().SortOrder : 0;
foreach (var element in structureElement.Elements("DocumentType"))
{
var alias = element.Value;
if (_importedContentTypes.ContainsKey(alias))
{
var allowedChild = _importedContentTypes[alias];
if (allowedChild == null || allowedChildren.Any(x => x.Id.IsValueCreated && x.Id.Value == allowedChild.Id)) continue;
allowedChildren.Add(new ContentTypeSort(new Lazy<int>(() => allowedChild.Id), sortOrder, allowedChild.Alias));
sortOrder++;
}
else
{
LogHelper.Warn<PackagingService>(
string.Format(
"Packager: Error handling DocumentType structure. DocumentType with alias '{0}' could not be found and was not added to the structure for '{1}'.",
alias, contentType.Alias));
}
}
contentType.AllowedContentTypes = allowedChildren;
return contentType;
}
private IContentType FindContentTypeByAlias(string contentTypeAlias)
{
using (var repository = _repositoryFactory.CreateContentTypeRepository(_uowProvider.GetUnitOfWork()))
{
var query = Query<IContentType>.Builder.Where(x => x.Alias == contentTypeAlias);
var types = repository.GetByQuery(query);
if (!types.Any())
throw new Exception(
string.Format("No ContentType matching the passed in Alias: '{0}' was found",
contentTypeAlias));
var contentType = types.First();
if (contentType == null)
throw new Exception(string.Format("ContentType matching the passed in Alias: '{0}' was null",
contentTypeAlias));
return contentType;
}
}
#endregion
#region DataTypes
/// <summary>
/// Imports and saves package xml as <see cref="IDataTypeDefinition"/>
/// </summary>
/// <param name="element">Xml to import</param>
/// <param name="userId"></param>
/// <returns>An enumrable list of generated DataTypeDefinitions</returns>
public IEnumerable<IDataTypeDefinition> ImportDataTypeDefinitions(XElement element, int userId = 0)
{
var name = element.Name.LocalName;
if (name.Equals("DataTypes") == false && name.Equals("DataType") == false)
{
throw new ArgumentException("The passed in XElement is not valid! It does not contain a root element called 'DataTypes' for multiple imports or 'DataType' for a single import.");
}
var dataTypes = new Dictionary<string, IDataTypeDefinition>();
var dataTypeElements = name.Equals("DataTypes")
? (from doc in element.Elements("DataType") select doc).ToList()
: new List<XElement> {element.Element("DataType")};
foreach (var dataTypeElement in dataTypeElements)
{
var dataTypeDefinitionName = dataTypeElement.Attribute("Name").Value;
var dataTypeId = new Guid(dataTypeElement.Attribute("Id").Value);
var dataTypeDefinitionId = new Guid(dataTypeElement.Attribute("Definition").Value);
var databaseTypeAttribute = dataTypeElement.Attribute("DatabaseType");
var definition = _dataTypeService.GetDataTypeDefinitionById(dataTypeDefinitionId);
//If the datatypedefinition doesn't already exist we create a new new according to the one in the package xml
if (definition == null)
{
var databaseType = databaseTypeAttribute != null
? databaseTypeAttribute.Value.EnumParse<DataTypeDatabaseType>(true)
: DataTypeDatabaseType.Ntext;
var dataTypeDefinition = new DataTypeDefinition(-1, dataTypeId)
{
Key = dataTypeDefinitionId,
Name = dataTypeDefinitionName,
DatabaseType = databaseType
};
dataTypes.Add(dataTypeDefinitionName, dataTypeDefinition);
}
}
var list = dataTypes.Select(x => x.Value).ToList();
if (list.Any())
{
_dataTypeService.Save(list, userId);
SavePrevaluesFromXml(list, dataTypeElements);
}
return list;
}
private void SavePrevaluesFromXml(List<IDataTypeDefinition> dataTypes, IEnumerable<XElement> dataTypeElements)
{
foreach (var dataTypeElement in dataTypeElements)
{
var prevaluesElement = dataTypeElement.Element("PreValues");
if (prevaluesElement == null) continue;
var dataTypeDefinitionName = dataTypeElement.Attribute("Name").Value;
var dataTypeDefinition = dataTypes.First(x => x.Name == dataTypeDefinitionName);
var values = prevaluesElement.Elements("PreValue").Select(prevalue => prevalue.Attribute("Value").Value).ToList();
_dataTypeService.SavePreValues(dataTypeDefinition.Id, values);
}
}
#endregion
#region Dictionary Items
#endregion
#region Files
#endregion
#region Languages
#endregion
#region Macros
#endregion
#region Media
#endregion
#region MediaTypes
#endregion
#region Package Manifest
#endregion
#region Templates
/// <summary>
/// Imports and saves package xml as <see cref="ITemplate"/>
/// </summary>
/// <param name="element">Xml to import</param>
/// <param name="userId">Optional user id</param>
/// <returns>An enumrable list of generated Templates</returns>
public IEnumerable<ITemplate> ImportTemplates(XElement element, int userId = 0)
{
var name = element.Name.LocalName;
if (name.Equals("Templates") == false && name.Equals("Template") == false)
{
throw new ArgumentException("The passed in XElement is not valid! It does not contain a root element called 'Templates' for multiple imports or 'Template' for a single import.");
}
var templates = new List<ITemplate>();
var templateElements = name.Equals("Templates")
? (from doc in element.Elements("Template") select doc).ToList()
: new List<XElement> { element.Element("Template") };
var fields = new List<TopologicalSorter.DependencyField<XElement>>();
foreach (XElement tempElement in templateElements)
{
var dependencies = new List<string>();
var elementCopy = tempElement;
//Ensure that the Master of the current template is part of the import, otherwise we ignore this dependency as part of the dependency sorting.
if (elementCopy.Element("Master") != null &&
string.IsNullOrEmpty(elementCopy.Element("Master").Value) == false &&
templateElements.Any(x => x.Element("Alias").Value == elementCopy.Element("Master").Value))
{
dependencies.Add(elementCopy.Element("Master").Value);
}
else if (elementCopy.Element("Master") != null &&
string.IsNullOrEmpty(elementCopy.Element("Master").Value) == false &&
templateElements.Any(x => x.Element("Alias").Value == elementCopy.Element("Master").Value) ==
false)
{
LogHelper.Info<PackagingService>(string.Format("Template '{0}' has an invalid Master '{1}', so the reference has been ignored.", elementCopy.Element("Alias").Value, elementCopy.Element("Master").Value));
}
var field = new TopologicalSorter.DependencyField<XElement>
{
Alias = elementCopy.Element("Alias").Value,
Item = new Lazy<XElement>(() => elementCopy),
DependsOn = dependencies.ToArray()
};
fields.Add(field);
}
//Sort templates by dependencies to a potential master template
var sortedElements = TopologicalSorter.GetSortedItems(fields);
foreach (var templateElement in sortedElements)
{
var templateName = templateElement.Element("Name").Value;
var alias = templateElement.Element("Alias").Value;
var design = templateElement.Element("Design").Value;
var masterElement = templateElement.Element("Master");
var isMasterPage = IsMasterPageSyntax(design);
var path = isMasterPage ? MasterpagePath(alias) : ViewPath(alias);
var existingTemplate = _fileService.GetTemplate(alias) as Template;
var template = existingTemplate ?? new Template(path, templateName, alias);
template.Content = design;
if (masterElement != null && string.IsNullOrEmpty(masterElement.Value) == false)
{
template.MasterTemplateAlias = masterElement.Value;
var masterTemplate = templates.FirstOrDefault(x => x.Alias == masterElement.Value);
if(masterTemplate != null)
template.MasterTemplateId = new Lazy<int>(() => masterTemplate.Id);
}
templates.Add(template);
}
if(templates.Any())
_fileService.SaveTemplate(templates, userId);
return templates;
}
private bool IsMasterPageSyntax(string code)
{
return Regex.IsMatch(code, @"<%@\s*Master", RegexOptions.IgnoreCase) ||
code.InvariantContains("<umbraco:Item") || code.InvariantContains("<asp:") || code.InvariantContains("<umbraco:Macro");
}
private string ViewPath(string alias)
{
return SystemDirectories.MvcViews + "/" + alias.Replace(" ", "") + ".cshtml";
}
private string MasterpagePath(string alias)
{
return IOHelper.MapPath(SystemDirectories.Masterpages + "/" + alias.Replace(" ", "") + ".master");
}
#endregion
}
}
@@ -20,6 +20,7 @@ namespace Umbraco.Core.Services
private Lazy<DataTypeService> _dataTypeService;
private Lazy<FileService> _fileService;
private Lazy<LocalizationService> _localizationService;
private Lazy<PackagingService> _packagingService;
/// <summary>
/// Constructor
@@ -70,6 +71,9 @@ namespace Umbraco.Core.Services
if(_localizationService == null)
_localizationService = new Lazy<LocalizationService>(() => new LocalizationService(provider, repositoryFactory.Value));
if(_packagingService == null)
_packagingService = new Lazy<PackagingService>(() => new PackagingService(_contentService.Value, _contentTypeService.Value, _mediaService.Value, _dataTypeService.Value, _fileService.Value, repositoryFactory.Value, provider));
}
/// <summary>
@@ -120,6 +124,14 @@ namespace Umbraco.Core.Services
get { return _mediaService.Value; }
}
/// <summary>
/// Gets the <see cref="PackagingService"/>
/// </summary>
public PackagingService PackagingService
{
get { return _packagingService.Value; }
}
/// <summary>
/// Gets the <see cref="IMacroService"/>
/// </summary>
+5 -1
View File
@@ -179,6 +179,8 @@ namespace Umbraco.Core
public static string TrimEnd(this string value, string forRemoving)
{
if (string.IsNullOrEmpty(value)) return value;
if (string.IsNullOrEmpty(forRemoving)) return value;
while (value.EndsWith(forRemoving, StringComparison.InvariantCultureIgnoreCase))
{
value = value.Remove(value.LastIndexOf(forRemoving, StringComparison.InvariantCultureIgnoreCase));
@@ -189,6 +191,8 @@ namespace Umbraco.Core
public static string TrimStart(this string value, string forRemoving)
{
if (string.IsNullOrEmpty(value)) return value;
if (string.IsNullOrEmpty(forRemoving)) return value;
while (value.StartsWith(forRemoving, StringComparison.InvariantCultureIgnoreCase))
{
value = value.Substring(forRemoving.Length);
@@ -831,7 +835,7 @@ namespace Umbraco.Core
public static string ToSafeAlias(this string alias)
{
const string validAliasCharacters = "_-abcdefghijklmnopqrstuvwxyz1234567890";
const string invalidFirstCharacters = "01234567890";
const string invalidFirstCharacters = "0123456789";
var safeString = new StringBuilder();
int aliasLength = alias.Length;
for (int i = 0; i < aliasLength; i++)
+178
View File
@@ -0,0 +1,178 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Umbraco.Core
{
internal class TopologicalSorter
{
private readonly int[] _vertices; // list of vertices
private readonly int[,] _matrix; // adjacency matrix
private int _numVerts; // current number of vertices
private readonly int[] _sortedArray;
public TopologicalSorter(int size)
{
_vertices = new int[size];
_matrix = new int[size, size];
_numVerts = 0;
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++)
_matrix[i, j] = 0;
_sortedArray = new int[size]; // sorted vert labels
}
#region Public Methods
public int AddVertex(int vertex)
{
_vertices[_numVerts++] = vertex;
return _numVerts - 1;
}
public void AddEdge(int start, int end)
{
_matrix[start, end] = 1;
}
public int[] Sort() // toplogical sort
{
while (_numVerts > 0) // while vertices remain,
{
// get a vertex with no successors, or -1
int currentVertex = NoSuccessors();
if (currentVertex == -1) // must be a cycle
throw new Exception("Graph has cycles");
// insert vertex label in sorted array (start at end)
_sortedArray[_numVerts - 1] = _vertices[currentVertex];
DeleteVertex(currentVertex); // delete vertex
}
// vertices all gone; return sortedArray
return _sortedArray;
}
#endregion
#region Private Helper Methods
// returns vert with no successors (or -1 if no such verts)
private int NoSuccessors()
{
for (int row = 0; row < _numVerts; row++)
{
bool isEdge = false; // edge from row to column in adjMat
for (int col = 0; col < _numVerts; col++)
{
if (_matrix[row, col] > 0) // if edge to another,
{
isEdge = true;
break; // this vertex has a successor try another
}
}
if (!isEdge) // if no edges, has no successors
return row;
}
return -1; // no
}
private void DeleteVertex(int delVert)
{
// if not last vertex, delete from vertexList
if (delVert != _numVerts - 1)
{
for (int j = delVert; j < _numVerts - 1; j++)
_vertices[j] = _vertices[j + 1];
for (int row = delVert; row < _numVerts - 1; row++)
MoveRowUp(row, _numVerts);
for (int col = delVert; col < _numVerts - 1; col++)
MoveColLeft(col, _numVerts - 1);
}
_numVerts--; // one less vertex
}
private void MoveRowUp(int row, int length)
{
for (int col = 0; col < length; col++)
_matrix[row, col] = _matrix[row + 1, col];
}
private void MoveColLeft(int col, int length)
{
for (int row = 0; row < length; row++)
_matrix[row, col] = _matrix[row, col + 1];
}
#endregion
#region Internal Staic methods
internal static IEnumerable<T> GetSortedItems<T>(List<DependencyField<T>> fields) where T : class
{
int[] sortOrder = GetTopologicalSortOrder(fields);
var list = new List<T>();
for (int i = 0; i < sortOrder.Length; i++)
{
var field = fields[sortOrder[i]];
list.Add(field.Item.Value);
}
list.Reverse();
return list;
}
internal static int[] GetTopologicalSortOrder<T>(List<DependencyField<T>> fields) where T : class
{
var g = new TopologicalSorter(fields.Count());
var indexes = new Dictionary<string, int>();
//add vertices
for (int i = 0; i < fields.Count(); i++)
{
indexes[fields[i].Alias.ToLowerInvariant()] = g.AddVertex(i);
}
//add edges
for (int i = 0; i < fields.Count; i++)
{
if (fields[i].DependsOn != null)
{
for (int j = 0; j < fields[i].DependsOn.Length; j++)
{
if (indexes.ContainsKey(fields[i].DependsOn[j].ToLowerInvariant()) == false)
throw new IndexOutOfRangeException(
string.Format(
"The alias '{0}' has an invalid dependency. The dependency '{1}' does not exist in the list of aliases",
fields[i], fields[i].DependsOn[j]));
g.AddEdge(i, indexes[fields[i].DependsOn[j].ToLowerInvariant()]);
}
}
}
int[] result = g.Sort();
return result;
}
#endregion
internal class DependencyField<T> where T : class
{
public DependencyField()
{
}
public DependencyField(string @alias, string[] dependsOn, Lazy<T> item)
{
Alias = alias;
DependsOn = dependsOn;
Item = item;
}
public string Alias { get; set; }
public string[] DependsOn { get; set; }
public Lazy<T> Item { get; set; }
}
}
}
-1
View File
@@ -232,7 +232,6 @@ namespace Umbraco.Core
"NuGet.",
"RouteDebugger,",
"SqlCE4Umbraco,",
"Umbraco.Core,",
"umbraco.datalayer,",
"umbraco.interfaces,",
"umbraco.providers,",
+8 -2
View File
@@ -143,8 +143,11 @@
<Compile Include="Models\ContentBase.cs" />
<Compile Include="Models\ContentExtensions.cs" />
<Compile Include="Enum.cs" />
<Compile Include="Events\MacroErrorEventArgs.cs" />
<Compile Include="HashCodeCombiner.cs" />
<Compile Include="IconPickerBehaviour.cs" />
<Compile Include="IO\FileSystemWrapper.cs" />
<Compile Include="MacroErrorBehaviour.cs" />
<Compile Include="Media\IImageUrlProvider.cs" />
<Compile Include="Models\ContentTypeBase.cs" />
<Compile Include="Models\ContentTypeCompositionBase.cs" />
@@ -451,8 +454,10 @@
<Compile Include="Persistence\SqlSyntax\MySqlSyntaxProvider.cs" />
<Compile Include="Persistence\SqlSyntax\SqlCeSyntaxProvider.cs" />
<Compile Include="Persistence\SqlSyntax\SqlServerSyntaxProvider.cs" />
<Compile Include="Persistence\SqlSyntax\SqlSyntaxProviderAttribute.cs" />
<Compile Include="Persistence\SqlSyntax\SqlSyntaxProviderBase.cs" />
<Compile Include="Persistence\SqlSyntax\SyntaxConfig.cs" />
<Compile Include="Persistence\SqlSyntax\SqlSyntaxContext.cs" />
<Compile Include="Persistence\SqlSyntax\SqlSyntaxProvidersResolver.cs" />
<Compile Include="Persistence\TransactionType.cs" />
<Compile Include="Persistence\UmbracoDatabase.cs" />
<Compile Include="Persistence\UnitOfWork\FileUnitOfWork.cs" />
@@ -650,8 +655,10 @@
<Compile Include="Services\LocalizationService.cs" />
<Compile Include="Services\MacroService.cs" />
<Compile Include="Services\MediaService.cs" />
<Compile Include="Services\PackagingService.cs" />
<Compile Include="Services\ServiceContext.cs" />
<Compile Include="Services\UserService.cs" />
<Compile Include="TopologicalSorter.cs" />
<Compile Include="TypeExtensions.cs" />
<Compile Include="ReadLock.cs" />
<Compile Include="TypeFinder.cs" />
@@ -701,7 +708,6 @@
<Name>umbraco.interfaces</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+73
View File
@@ -9,6 +9,79 @@ namespace Umbraco.Core
/// </summary>
internal static class XmlExtensions
{
/// <summary>
/// Converts from an XDocument to an XmlDocument
/// </summary>
/// <param name="xDocument"></param>
/// <returns></returns>
public static XmlDocument ToXmlDocument(this XDocument xDocument)
{
var xmlDocument = new XmlDocument();
using (var xmlReader = xDocument.CreateReader())
{
xmlDocument.Load(xmlReader);
}
return xmlDocument;
}
/// <summary>
/// Converts from an XmlDocument to an XDocument
/// </summary>
/// <param name="xmlDocument"></param>
/// <returns></returns>
public static XDocument ToXDocument(this XmlDocument xmlDocument)
{
using (var nodeReader = new XmlNodeReader(xmlDocument))
{
nodeReader.MoveToContent();
return XDocument.Load(nodeReader);
}
}
/// <summary>
/// Converts from an XElement to an XmlElement
/// </summary>
/// <param name="xElement"></param>
/// <returns></returns>
public static XmlNode ToXmlElement(this XElement xElement)
{
var xmlDocument = new XmlDocument();
using (var xmlReader = xElement.CreateReader())
{
xmlDocument.Load(xmlReader);
}
return xmlDocument.DocumentElement;
}
/// <summary>
/// Converts from an XmlElement to an XElement
/// </summary>
/// <param name="xmlElement"></param>
/// <returns></returns>
public static XElement ToXElement(this XmlNode xmlElement)
{
using (var nodeReader = new XmlNodeReader(xmlElement))
{
nodeReader.MoveToContent();
return XElement.Load(nodeReader);
}
}
public static T AttributeValue<T>(this XElement xml, string attributeName)
{
if (xml == null) throw new ArgumentNullException("xml");
if (xml.HasAttributes == false) return default(T);
if (xml.Attribute(attributeName) == null)
return default(T);
var val = xml.Attribute(attributeName).Value;
var result = val.TryConvertTo<T>();
if (result.Success)
return result.Result;
return default(T);
}
public static T AttributeValue<T>(this XmlNode xml, string attributeName)
{
if (xml == null) throw new ArgumentNullException("xml");
+58
View File
@@ -5,6 +5,9 @@ using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
namespace Umbraco.Core
@@ -14,6 +17,61 @@ namespace Umbraco.Core
/// </summary>
public class XmlHelper
{
/// <summary>
/// Sorts the children of the parentNode that match the xpath selector
/// </summary>
/// <param name="parentNode"></param>
/// <param name="childXPathSelector">An xpath expression used to select child nodes of the XmlElement</param>
/// <param name="childSelector">An expression that returns true if the XElement passed in is a valid child node to be sorted</param>
/// <param name="orderByValue">The value to order the results by</param>
internal static void SortNodes(
XmlNode parentNode,
string childXPathSelector,
Func<XElement, bool> childSelector,
Func<XElement, object> orderByValue)
{
var xElement = parentNode.ToXElement();
var children = xElement.Elements().Where(x => childSelector(x)).ToArray(); //(DONT conver to method group, the build server doesn't like it)
var data = children
.OrderByDescending(orderByValue) //order by the sort order desc
.Select(x => children.IndexOf(x)) //store the current item's index (DONT conver to method group, the build server doesn't like it)
.ToList();
//get the minimum index that a content node exists in the parent
var minElementIndex = xElement.Elements()
.TakeWhile(x => childSelector(x) == false)
.Count();
//if the minimum index is zero, then it is the very first node inside the parent,
// if it is not, we need to store the child property node that exists just before the
// first content node found so we can insert elements after it when we're sorting.
var insertAfter = minElementIndex == 0 ? null : parentNode.ChildNodes[minElementIndex - 1];
var selectedChildren = parentNode.SelectNodes(childXPathSelector);
if (selectedChildren == null)
{
throw new InvalidOperationException(string.Format("The childXPathSelector value did not return any results {0}", childXPathSelector));
}
var childElements = selectedChildren.Cast<XmlElement>().ToArray();
//iterate over the ndoes starting with the node with the highest sort order.
//then we insert this node at the begginning of the parent so that by the end
//of the iteration the node with the least sort order will be at the top.
foreach (var node in data.Select(index => childElements[index]))
{
if (insertAfter == null)
{
parentNode.PrependChild(node);
}
else
{
parentNode.InsertAfter(node, insertAfter);
}
}
}
public static string StripDashesInElementOrAttributeNames(string xml)
{
@@ -6,6 +6,7 @@ using System.Web;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.ObjectResolution;
using Umbraco.Core.Persistence.SqlSyntax;
using umbraco.interfaces;
namespace Umbraco.Tests.BootManagers
@@ -27,6 +28,7 @@ namespace Umbraco.Tests.BootManagers
{
_testApp = null;
ApplicationEventsResolver.Reset();
SqlSyntaxProvidersResolver.Reset();
Resolution.IsFrozen = false;
}
@@ -67,6 +69,12 @@ namespace Umbraco.Tests.BootManagers
protected override void InitializeResolvers()
{
//Do nothing as we don't want to initialize all resolvers in this test
//We only include this resolver to not cause trouble for the database context
SqlSyntaxProvidersResolver.Current = new SqlSyntaxProvidersResolver(
PluginManager.Current.ResolveSqlSyntaxProviders())
{
CanResolveBeforeFrozen = true
};
}
}

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