Compare commits

...

420 Commits

Author SHA1 Message Date
Sebastiaan Janssen a43e0eb5b8 Display version comment in installer steps ("beta 2" in this case) 2013-05-10 10:55:55 -02:00
Sebastiaan Janssen 3b05663597 Add MiniProfiler as a requirement for the NuGet package 2013-05-10 10:55:28 -02:00
NielsHartvig@UMBRACORATI.localdomain 191d744ec6 Adds profiling support to MVC views 2013-05-10 10:38:59 -02:00
NielsHartvig@UMBRACORATI.localdomain 980cd20e4c Adjustments to profiling 2013-05-10 10:24:25 -02:00
NielsHartvig@UMBRACORATI.localdomain f04916c9a9 Adds MiniProfiler support 2013-05-10 10:15:30 -02:00
Sebastiaan Janssen 8fde65d417 Merge with 6.0.6 2013-05-10 08:50:28 -02:00
Sebastiaan Janssen 8cca1b77b3 Merge with 4.11.9 2013-05-10 08:47:24 -02:00
Sebastiaan Janssen 53e4308c29 Fixes U4-2205 Log.GetLogItems(LogTypes, DateTime) fails with 'Conversion failed
when converting the nvarchar value 'Custom' to data type int'
2013-05-10 08:44:47 -02:00
Sebastiaan Janssen d10eff04a7 Update version 2013-05-10 07:09:43 -02:00
Sebastiaan Janssen 59c36ad70e Fixed U4-2090 Content not published after installing starterkit on fresh site
(Umbraco 6.1 beta)
Reverts previous "fix" as the actual cause was in Document.cs
2013-05-10 06:59:51 -02:00
Shannon Deminick 7b8d526a8a Fixed up some merge issues. 2013-05-08 18:16:58 -10:00
Shannon Deminick f69a017078 Merge with 6.0.6 2013-05-08 18:11:52 -10:00
Shannon Deminick 6f26f7b57c Patching from 6.1 2013-05-08 18:08:55 -10:00
Shannon Deminick bda2614290 Patching from 6.1 2013-05-08 17:49:48 -10:00
Shannon Deminick efc482511e Patching from 6.1 2013-05-08 17:48:17 -10:00
Shannon Deminick 40b90b8a58 Patching from 6.1 2013-05-08 17:45:53 -10:00
Shannon Deminick a009dfe2a1 Patching from 6.1 2013-05-08 17:39:03 -10:00
Shannon Deminick bc0b419288 Merge 2013-05-08 17:12:09 -10:00
Shannon Deminick 806715594e Fixes up created package tree sync. 2013-05-08 17:11:50 -10:00
Shannon Deminick 41e87fca98 Fixes macro tree syncing 2013-05-08 17:04:51 -10:00
Shannon Deminick f23c6c53cc Fixes up created package tree sync. 2013-05-08 17:11:50 -10:00
Shannon Deminick f2a97326fa Fixes macro tree syncing 2013-05-08 17:04:51 -10:00
Shannon Deminick dd1983dc55 Fixes macro script editor and syncing, changes over editPython to use correct webforms file format. 2013-05-08 17:01:48 -10:00
Shannon Deminick 78cd51d333 Fixed xslt editing and syncing. 2013-05-08 16:33:09 -10:00
Shannon Deminick 28b6c5897f Fixes up script editor and tree syncing. 2013-05-08 16:13:18 -10:00
Shannon Deminick baed852767 Re-fixed up stylesheet editing and syncing, starting fixup for script editor/syncing 2013-05-08 15:15:56 -10:00
Shannon Deminick 0762decd92 Fixes up tree syncing for views, stylesheets and partial views. Now ensures we can actually
sync a tree for a file based node that doesn't have a static id. Also ensures that when we change a
Partial view name that we don't end up duplicating some files when we change it twice in the
same session.
2013-05-08 14:18:18 -10:00
Shannon Deminick 0b58c1c03c Patching from 6.1 2013-05-08 17:34:40 -10:00
Shannon Deminick 38c6a21896 Patching from 6.1 2013-05-08 17:33:48 -10:00
Shannon Deminick 15bff44ec1 Patching from 6.1 2013-05-08 17:24:00 -10:00
Shannon Deminick a626efa9b6 Merge with 4.11.9 2013-05-08 17:15:09 -10:00
Shannon Deminick 1f87470f89 Fixes up tree syncing for views, stylesheets and partial views. Now ensures we can actually
sync a tree for a file based node that doesn't have a static id. Also ensures that when we change a
Partial view name that we don't end up duplicating some files when we change it twice in the
same session.
2013-05-08 14:18:18 -10:00
Hendy 54d2258634 added null checks into the uQuery .ToNameIds() methods 2013-05-08 16:29:29 -01:00
Sebastiaan Janssen 25be0621b2 Whoops, connection string doesn't contain the datalayer here 2013-05-08 13:14:02 -02:00
Sebastiaan Janssen 6fe3507099 Merge with 6.0.6 2013-05-08 08:13:57 -02:00
Sebastiaan Janssen cba09ed817 Merge with 4.11.9 2013-05-08 08:10:48 -02:00
Sebastiaan Janssen d5d00553b4 Fixed U4-2176 MySql Dashboard error for 4.11 as well 2013-05-08 08:09:13 -02:00
Shannon Deminick 55750b534b Fixed the template editor to ensure that the tree syncs and updated much of it to use correct JavaScript, however
id didn't have time to update the whole thing.
2013-05-07 22:19:42 -10:00
Shannon Deminick a31cb3b1df Fixed stylesheet property tree syncing, updated the stylesheet property page to use
correct web forms structure.
2013-05-07 21:13:30 -10:00
Shannon Deminick fc44138d9e Fixes Stylesheet tree-syncing. Converts editStylesheets over to correct web forms structure and
implements the correct Javascript.
2013-05-07 20:49:58 -10:00
Shannon Deminick 0cda994538 Fixes DataTypeCacheRefresher to be a Json cache refresher since it needs to refresh both by GUID and by Int Ids 2013-05-07 19:37:57 -10:00
Shannon Deminick 4b199a9166 Manually applies fix for #U4-2094 since the class structure has changed in 6.1 2013-05-07 19:02:36 -10:00
Shannon Deminick cfe6ac0486 Merge with 6.0.6 2013-05-07 18:57:39 -10:00
Shannon Deminick c52669fb05 Fixes: #U4-2094 - issue with duplicates in getting Descendants for media in mvc. 2013-05-07 18:56:24 -10:00
Sebastiaan Janssen 753fe411c5 Fixes U4-2090 Content not published after installing starterkit on fresh site
(Umbraco 6.1 beta)
2013-05-07 13:01:18 -02:00
Shannon Deminick f05c77dc78 Fixed med trust issue with SecuritySafeCritical attributes 2013-05-06 17:23:53 -10:00
Shannon Deminick d1677d9d59 Updates: #U4-2192 - moves method call to be inside of the lock. 2013-05-06 15:54:55 -10:00
Shannon Deminick 137685d883 Updates: #U4-2192 - moves method call to be inside of the lock. 2013-05-06 15:49:51 -10:00
Shannon Deminick 266d8ba69a Merge with 6.0.6 2013-05-06 15:20:26 -10:00
Shannon Deminick c4a071523e Merge with 4.11.9 2013-05-06 15:12:10 -10:00
Shannon Deminick ca99319ead Fixes: #U4-644 - DynamicNode and MVC don't output RTE values for media 2013-05-06 15:09:24 -10:00
Shannon Deminick f808aac4cd Fixes: #U4-644 - DynamicNode and MVC don't output RTE values for media 2013-05-06 14:36:47 -10:00
Shannon Deminick 0553bd1f9f Merge with 6.0.6 2013-05-06 12:54:43 -10:00
Shannon Deminick 81360f629e Merge with 4.11.9 2013-05-06 12:54:28 -10:00
Sebastiaan Janssen 1b3669787b Merge with 6.0.6 2013-05-06 12:27:56 -02:00
Sebastiaan Janssen aa36c66f39 Fixes U4-2176 6.0.5 Dashboard error 2013-05-06 12:27:15 -02:00
Sebastiaan Janssen 950cb1436a Merge with 6.0.6 2013-05-06 12:07:22 -02:00
Sebastiaan Janssen 09e31d6595 Fixes U4-2179 Error with GetChildNodes after upgrade to Umbraco 6.0.5 from
Umbraco 6.0.0
2013-05-06 12:06:45 -02:00
Sebastiaan Janssen f9fc2619fa Fixes U4-2179 Error with GetChildNodes after upgrade to Umbraco 6.0.5 from
Umbraco 6.0.0
2013-05-06 12:06:45 -02:00
Sebastiaan Janssen 004d9ab3e6 Merge with 6.0.6 2013-05-06 11:12:31 -02:00
Sebastiaan Janssen 5d8cfa5efb Merge 2013-05-06 11:06:54 -02:00
Sebastiaan Janssen 297f8e2a0b Remove reference to v4 in text. 2013-05-06 11:06:28 -02:00
Shannon Deminick 83584375c1 Merge with 6.0.6 2013-05-06 02:10:26 -10:00
Shannon Deminick 8ddfb5f6ad Merge 2013-05-06 02:09:44 -10:00
Shannon Deminick 9387544865 Fixes test outcome 2013-05-06 02:08:38 -10:00
Shannon Deminick 66ddb21ef8 Fixes null check 2013-05-06 02:03:24 -10:00
Sebastiaan Janssen d746ec6409 Merge with 6.0.6 2013-05-06 09:34:11 -02:00
Shannon Deminick e08322f6fe Fixes merge issues 2013-05-05 23:45:47 -10:00
Shannon Deminick de52f3ee93 Merge with 6.0.6 2013-05-05 23:39:52 -10:00
Shannon Deminick 9d19ed9463 Fix merge issues 2013-05-05 23:35:51 -10:00
Shannon Deminick df62697477 Merge with 4.11.9 2013-05-05 23:23:24 -10:00
Shannon Deminick f0cacf0d52 Fixed app_code assembly check. 2013-05-05 23:03:31 -10:00
Shannon Deminick d501fcb679 Fixes TypeFinder issue but retains the improved performance. Adds TypeHelper tests. 2013-05-05 22:57:41 -10:00
Stephan 3c15f9b57c Web.Standalone - refactor 2013-05-05 09:07:51 -02:00
Shannon Deminick f5994d8442 Fixes up async methods in ContentTypeControlNew to ensure that the UmbracoContext is current since
the actions might run on different threads and therefore some event handlers might need access to the context.
2013-05-04 19:33:49 -10:00
Shannon Deminick bfe5250138 Fixes issue with async delete webforms method not re-setting the umbraco context. 2013-05-04 18:29:24 -10:00
Shannon Deminick 3fa9219c27 Merge 2013-05-04 18:13:03 -10:00
Shannon Deminick 4295cba915 Updated unit tests for TypeFinder - this shows the issue with the new refactored performance changes. 2013-05-04 18:12:02 -10:00
Robert Stocks 6d66fc6cb8 Remove extra space in name of http module in web.config 2013-05-03 07:24:28 -01:00
Robert Stocks 4484f83caa Remove extra space in name of http module in web.config 2013-05-03 07:24:28 -01:00
Sebastiaan Janssen 3ada1770eb Merge with 4.11.9 2013-05-06 09:32:23 -02:00
Shannon Deminick cbf84566e2 updated casing in proj file to be correct for a couple elements. 2013-05-02 15:57:02 -10:00
Shannon Deminick 294c2f4fba Fixes: #U4-2183 - null check on UmbracoContext and fixes bad merge issue, the UserTypeCacheRefresher got removed from the proj file. 2013-05-02 14:24:27 -10:00
Shannon Deminick 0b6f05e630 Fixes: #U4-2172 - better single threaded supported for the database instance outside http context 2013-05-02 03:48:14 -10:00
Sebastiaan Janssen 2170380f7b Opening new branch 2013-05-01 13:07:53 -02:00
Sebastiaan Janssen a8ab7e4c35 Open new branch 2013-05-01 13:05:12 -02:00
Sebastiaan Janssen c20c9c638f Merge with 4.11.8 2013-05-01 13:04:06 -02:00
Sebastiaan Janssen 43b2a2185e Fix unit test 2013-05-01 13:02:09 -02:00
Sebastiaan Janssen 2423bdd623 Merge with 4.11.8 2013-05-01 05:33:19 -02:00
Sebastiaan Janssen bcb90d64a5 Fixes U4-1136 Class in MediaPickerDataType.cs wrongly named MemberPickerDataType
+ a bit of code cleanup
2013-05-01 05:32:29 -02:00
Shannon Deminick eca01b845c publicized some ObjectExtensions, added Umbraco.Belle to internals, updated the names in which plugin routes are created,
added HttpUrlHelper extensions for web api
2013-04-30 16:43:59 -10:00
Morten Christensen dc5cf5ef6e Adding strongly typed query POC to test project 2013-04-30 17:41:59 -02:00
Sebastiaan Janssen 7d448d0959 Merge 2013-04-30 05:22:43 -02:00
Sebastiaan Janssen 53fe02db7e And another update for WebPI... 2013-04-30 05:22:21 -02:00
Shannon Deminick b2929ea50a Merge with 6.0.5 2013-04-29 19:56:41 -10:00
Shannon Deminick a03dd7b11e Merge with 4.11.8 2013-04-29 19:56:18 -10:00
Shannon Deminick 6d994f48ac merged in patch for TypeFinder changes 2013-04-29 19:55:44 -10:00
Shannon Deminick 8e1f7170c7 Merged in TypeFinder changes from U4-1187 and wrote benchmark unit tests and other general
tests to confirm it is still finding types.
2013-04-29 19:48:11 -10:00
Shannon Deminick 3fd1c49da7 Merge with 6.0.5 2013-04-29 12:09:36 -10:00
Shannon Deminick f0e8252e38 Merge with 4.11.8 2013-04-29 12:09:12 -10:00
Shannon Deminick ad06aded1b Removed strange old legacy config section that never did anything 2013-04-29 12:08:36 -10:00
Sebastiaan Janssen be049f9093 Fix merge issue 2013-04-29 12:36:03 -02:00
Sebastiaan Janssen 64bbfb8cbc Merge with 6.0.5 2013-04-29 12:31:13 -02:00
Sebastiaan Janssen 0ca52fcc60 Fix merge issues, update version number 2013-04-29 12:29:15 -02:00
Sebastiaan Janssen c53342ba4c Merge with 4.11.8 2013-04-29 12:13:00 -02:00
Sebastiaan Janssen 25eea8d599 Re-add internals visible to umbraco.webservices in case people install the
seperate project.
2013-04-29 11:17:32 -02:00
Sebastiaan Janssen 22498649b1 Merge 2013-04-29 10:36:30 -02:00
Sebastiaan Janssen 25ce7baa7d Removing the umbraco.webservices project 2013-04-29 10:36:11 -02:00
Morten Christensen b4fd2f6d46 Fixing oversight in SaveAndPublish method - content might not have an Id yet, so take that into account. 2013-04-29 07:09:23 -02:00
Shannon Deminick aba4a9b07c oops, removed test code 2013-04-28 16:15:19 -10:00
Shannon Deminick 577d77cfab Fixes: #U4-1760 - allows a developer to set the default RenderMvcController on startup. 2013-04-28 16:09:24 -10:00
Shannon Deminick 7ff50e2652 Merge with 6.0.5 2013-04-28 13:43:38 -10:00
Shannon Deminick e885384678 Merge with 4.11.8 2013-04-28 13:40:06 -10:00
Shannon Deminick 528209f8da instantly improve performance by 45% for regenerating xml structures for documents when a doc type alias changes
or when a doc type property alias is changed or a doc type property is removed.
2013-04-28 13:37:36 -10:00
Shannon Deminick 056696d36f Fixes up more issues with cmsContentXml - got media updating properly now, nearly the same as content and all done with
the new API.
2013-04-25 22:13:05 -10:00
Shannon Deminick 6cffa67518 Fixes merge issues and WebSecurity with the correct encryption (from failed merge along time ago).
Fixes ContentType to ensure that ALL property type values get reset, not just ones assigned to a group.
Fixes logic in ContentTypeService to ensure that xml is re-generated when a property type alias is changed too.
2013-04-25 21:09:07 -10:00
Shannon Deminick d2a285c120 Merge with 6.0.5 2013-04-25 19:43:03 -10:00
Shannon Deminick 153fe248a7 Fixes ContentService fix for issue U4-1772, we don't want to truncate! Plus the truncate term doesn't work in SQLCE anyways. 2013-04-25 19:33:53 -10:00
Shannon Deminick 7fc4822bbe Fixes merge issues. Fixes Fixes for cmsContentXml table since the Content type heirarchy tables are different in v6. 2013-04-25 19:26:06 -10:00
Shannon Deminick d65bee76b2 Merge with 4.11.8 2013-04-25 14:15:09 -10:00
Shannon Deminick 385d6396b0 disables auto-complete on the login page. 2013-04-25 13:28:47 -10:00
Shannon Deminick 46858af1ed Ensures user cookie is encrypted, removes ASP.Net headers from being returned in our response. Ensures
that our auth cookie is httponly.
2013-04-25 13:25:25 -10:00
Shannon Deminick 34163625fe Merge with 4.11.7 - cmsContentXml fixes 2013-04-25 12:20:06 -10:00
Sebastiaan Janssen e53b388a5e Opening new branch 2013-04-25 11:19:06 -02:00
Sebastiaan Janssen 4fb4af0b4f Added tag release-6.0.4 for changeset 0dee9964687e 2013-04-25 11:18:36 -02:00
Sebastiaan Janssen 461f032777 Added tag release-4.11.7 for changeset ce47176bc6b9 2013-04-25 11:17:07 -02:00
Sebastiaan Janssen ab37f9ae35 Closing 6.0.4 2013-04-25 11:16:29 -02:00
Sebastiaan Janssen a3347c0037 Opening new branch 2013-04-25 11:14:46 -02:00
Sebastiaan Janssen f3835d1ca3 Closing branch 4.11.7 2013-04-25 11:14:09 -02:00
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
Shannon Deminick d30c4791fe fixed a documentation error 2013-04-24 15:46:38 -10:00
Shannon Deminick 7ee9b9ebcc Fixes: #U4-2144 - ensures that the xml is re-gen'd when a content type alias is changed or a content type property is removed.
Also had to change the property type deletion to be async as well since it might be long running to re-gen the xml.
2013-04-24 15:31:36 -10:00
Shannon Deminick b4caf109f7 Working on #U4-2144 - ensures that xml is re-gen'd when a property alias is changed. 2013-04-24 15:17:20 -10:00
Shannon Deminick 0e8ffe528a Fixes: #U4-2149 - updates the logic for changing aliases for any content type. Now if an alias changes for any content type, the
xml is regenerated for any entity that is of that content type. For DocumentType's this is slightly different because we regenerate
the xml for the doc type and any document of the doc type's descendant types.
2013-04-24 14:57:20 -10:00
Shannon Deminick a8029d1dc5 Fixes: #U4-1772 - ensures that when changing a doc type alias that we only rebuild the data in the cmsContentXml table for Document types, not media types or member types, now we need
to fix all of the other bugs assocated with cmsContentXml table and alias changes.
2013-04-24 13:19:30 -10:00
Stephan a1d5b61ae5 PublishedContent - create tests to illustrate issues 2013-04-24 11:56:32 -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 6818ac4e50 Fixes merge issues, ensures that the UmbracoContext is set for the async operation since
it is required, previous versions didn't require it to be set. Added the WebSecurity property
to UmbracoUserControl, made ContentTypeControlNew inherit from UmbracoUserControl
2013-04-23 22:39:35 -10:00
Shannon Deminick 710c8aa6ea Merge with 6.0.4 2013-04-23 21:52:07 -10: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 f8652d98fe Merge with 6.0.4 2013-04-20 04:01:22 +06: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 174ff44e3b proj file update 2013-04-20 00:50:02 +06:00
Shannon Deminick b3c3e114ad missing images 2013-04-20 00:49:39 +06:00
Shannon Deminick 60481e7e02 Fixes: #U4-2093 stylehsheet property cache refresher had wrong id assigned. 2013-04-20 00:18:45 +06:00
Shannon Deminick 12de5d6ed3 Merge with 6.0.4 2013-04-20 00:12:52 +06:00
Shannon Deminick 9ac325c1a4 Fixes: #U4-2130 - regression bug for handling image uploads 2013-04-20 00:04:39 +06:00
Shannon Deminick 7f5457316a Fixed: #U4-2129 - using new api didn't use the CompositionPropertyTypes instead of just PropertyTypes and fixed up cache invalidation for PublishedContentHelper 2013-04-19 23:47:51 +06:00
Sebastiaan Janssen 671c8715b0 Fix merge issue 2013-04-19 10:18:46 -02: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 d6d630cb2c Merge with 6.0.4 2013-04-19 04:40:49 +06: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 988940095c Merge with 6.0.4 2013-04-18 23:03:52 +06:00
Shannon Deminick 123e65c55f Fixes: #U4-2118 - BOM encoding issue 2013-04-18 23:00:57 +06:00
Shannon Deminick 08a049594c Merge 2013-04-18 22:01:53 +06:00
Shannon Deminick a895a2a20a Fixes merge issues, ensures that the tree node is reloaded when publishing. 2013-04-18 22:01:28 +06:00
Shannon Deminick a5e33e1e02 Merge with 6.0.4 2013-04-18 21:45:04 +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 a721f06ac8 Merge with 6.0.4 2013-04-18 21:22:32 +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
Morten Christensen 39095b524c Updating test - Inheritance between parent/child ContentType has been updated so the parent doesn't have to be added to the composition afterwards. 2013-04-18 10:46:15 -02: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 3b1bfe04f2 updates method name 2013-04-18 01:15:25 +06:00
Shannon Deminick 979fe46e9b Updated CDF to 1.6.0.0 2013-04-18 00:55:40 +06:00
Shannon Deminick 0107a10145 Manually merge in changes for previous commits due to the codebase differences in 6.1 2013-04-18 00:06:42 +06:00
Shannon Deminick a38f0af49b Merge with 6.0.4 2013-04-17 23:47:33 +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
Morten Christensen 83d1e9c76f Merge 2013-04-17 11:25:53 -02: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
Sebastiaan Janssen b40619634d Fix bad merge 2013-04-17 06:36:40 -02:00
Morten Christensen fc84a21f06 Adding a few methods to relate two entities both based on the IUmbracoEntity. 2013-04-17 06:26:59 -02:00
Shannon Deminick 9137ce7cf4 Merge with 6.0.4 2013-04-17 01:57:50 +06:00
Shannon Deminick ff3fc5d825 Merge with 4.11.7 2013-04-17 01:56:20 +06:00
Morten Christensen 9621403f79 Fixes U4-2053 2013-04-16 17:19:46 -02: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
Stephan 2245c88396 U4-2117 - fix Ancestor- vs AncestorsOrSelf inconsistencies 2013-04-16 12:29:58 -02:00
Sebastiaan Janssen 2e39c55d56 Merge 2013-04-16 04:27:44 -02:00
Sebastiaan Janssen e4e0bcf642 Correct spelling error 2013-04-16 04:27:03 -02:00
Shannon Deminick 7537e4c6d6 updated DefaultServerMessenger with more ctor options for testing 2013-04-16 04:05:31 +06:00
Shannon Deminick c410b6dc20 Changed UmbracoSettings back to internal, it should not be exposed atm 2013-04-16 02:49:14 +06:00
Shannon Deminick 1e7e670df3 Fixes #U4-2104 - namespace issue with UmbracoApiControllers 2013-04-15 21:44:26 +06:00
Shannon Deminick da53ffe9f2 Merge 2013-04-15 21:36:35 +06:00
Shannon Deminick 47f6401fcd updates unit test to ensure UmbracoContext.Current is nulled, updates dispose on application context to
not dispose the database if it is not configured.
2013-04-15 21:36:24 +06:00
Sebastiaan Janssen 33190ea5e1 Merge 2013-04-15 12:19:11 -02:00
Sebastiaan Janssen a06951afbd Fix MemberAuthorizeAttribute for UmbracoApiControllers 2013-04-15 12:18:40 -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
Stephan 43d6c9a46d Core.Strings - bugfix DefaultShortStringHelper 2013-04-12 11:32:37 -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
Stephan 0b3eaf9c77 Core.Strings - refactor DefaultShortStringHelper for better backward compat. 2013-04-12 05:33:39 -02:00
Shannon Deminick 0fe8ff57a1 changes a method to be protected instead of private 2013-04-12 05:04:20 +06:00
Shannon Deminick 2642d74450 adds some logging and fixes sequence of events for distributed cache sending 2013-04-12 04:06:24 +06:00
Shannon Deminick 761b749f37 Merge with 6.0.4 2013-04-12 03:08:11 +06:00
Shannon Deminick 22fb7e1706 Merge 2013-04-12 03:07:53 +06:00
Shannon Deminick 4ef9dbb9b4 Merge 2013-04-12 03:07:30 +06:00
Shannon Deminick f716ba380c Merge with 6.0.4 2013-04-12 03:02:40 +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 439445aae4 Merge with 6.0.4 2013-04-11 16:39:28 -02: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
Shannon Deminick 0d79eaf3c5 Merge with 6.0.4 2013-04-12 00:32:19 +06:00
Shannon Deminick e747438a4b Merge 2013-04-12 00:31:28 +06:00
Shannon Deminick 14f71c9059 Fixes #U4-2058 2013-04-12 00:30:45 +06: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
Stephan 5154bcd2e9 Web.Routing - template setter on PublishedContentRequest 2013-04-11 11:55:32 -02:00
Stephan e3af8b4e5f Web.Routing - public, though readonly, UmbracoContext.PublishedContentRequest 2013-04-11 11:44:15 -02:00
Morten Christensen 3e8c1a426c Merge 2013-04-12 03:50:36 -02:00
Morten Christensen d7081dbc6b Implementing new RelationService.
Making EntityService public as it will be used within the RelationService.
2013-04-11 17:12:14 -02:00
Sebastiaan Janssen 1d89702c2c Merge with 6.0.4 2013-04-11 10:21:37 -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 df26090d63 Fix merge issue 2013-04-11 07:23:13 -02:00
Sebastiaan Janssen 3050258fdc Merge with 6.0.4 2013-04-11 07:20:00 -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
Stephan 84e990c239 Core.Configuration - fix setting that accidentally became public 2013-04-10 14:19:26 -02:00
Stephan 911a1cf80b merge 6.1.0-public into 6.1.0 2013-04-10 14:03:47 -02:00
Stephan ef493ef9af fix merge + public 2013-04-10 14:02:16 -02:00
Stephan 76a12f3f33 merge with 6.1.0 2013-04-10 13:56:39 -02:00
Stephan 344a4cc485 merge with 6.1.0 2013-04-10 12:51:49 -02:00
Stephan 5e1115218c Web.Standalone - import initial version
* * *
FOLD 003
2013-04-10 12:50:08 -02:00
Stephan 71a28cbeaa Core.Strings - bugfix error in DefaultShortStringHelper 2013-05-04 14:53:33 -02:00
Stephan 4aa750694a Core - add methods to XmlHelper 2013-05-03 13:56:34 -02:00
Stephan 5d89ab1e2a Web.UI - fix nasty preview bug introduced in 9a92dea49ede 2013-05-03 20:09:15 -02:00
Stephan 262aa3b8fe Web.Routing, Web.Mvc - fix issues with content with no template 2013-05-03 20:09:14 -02:00
Stephan 106d733d08 Web.PublishedCache - support XPathExpression 2013-04-10 12:49:45 -02:00
Sebastiaan Janssen a010448ad1 Merge with 6.0.4 2013-04-10 11:55:36 -02: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 111df761aa Merge with 6.0.4 2013-04-10 07:43:10 -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 5f9c7bb49c changed DefaultServerMessenger to expose login 2013-04-10 09:41:53 +06:00
Shannon Deminick 0c3b7c27a7 fix merge issues 2013-04-10 04:24:42 +06:00
Shannon Deminick f2293e01fa Merge with 6.0.4 2013-04-10 04:15:26 +06: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
Shannon Deminick 506d32f353 Merge 2013-04-09 22:11:54 +06:00
Shannon Deminick 16746c8548 Updates authorized web services/http handlers to use WebSecurity and implements the new base class
properties available in 6.1. Updates WebSecurity with a few more helpful methods.
2013-04-09 22:11:12 +06:00
Sebastiaan Janssen fb994bdc11 Merge with 6.0.4 2013-04-09 11:45:04 -02: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 abee79ca69 Fixes merge issues 2013-04-09 08:08:22 -02:00
Sebastiaan Janssen d8ccf20840 Merge with 6.0.4 2013-04-09 08:04:55 -02:00
Sebastiaan Janssen 9e10694ebb Fixes merge issue, no idea why it's expecting an ApiController.. weird! 2013-04-09 08:03:17 -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 1c5cd4e245 Merge with 6.0.4 2013-04-09 07:19:47 -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 63cae70ec3 Fixes merge issue 2013-04-09 08:05:31 +06:00
Shannon Deminick dd990b5df4 Merge with 6.0.4 2013-04-09 08:00:10 +06: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
Morten Christensen efbc461da9 Code cleanup - removing all internal code related to Macros, which was created for v6 but left out for backwards compatibility. 2013-04-07 17:47:10 -02:00
Morten Christensen 97d41f8998 Merge 2013-04-07 16:35:20 -02:00
Morten Christensen 8ef88dc955 Making the topological sorter public 2013-04-07 16:35: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 e50bac7c9f Merge with 6.0.4 2013-04-06 01:46:13 +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 01bf0bcfa5 Fixes merge issues 2013-04-06 01:41:06 +06:00
Shannon Deminick 7dcfcaf339 Merge with 6.0.4 2013-04-06 01:23:29 +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
Shannon Deminick 6badfae849 Merge 2013-04-05 20:44:44 +06:00
Shannon Deminick 9d0dbda3bd Fixed merge issue 2013-04-05 20:44:16 +06:00
Shannon Deminick df986c8254 Merge with 6.0.4 2013-04-05 20:43:24 +06:00
Stephan cd823db766 merge with 6.1.0 2013-04-05 10:28:50 -02: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
Stephan 2f9de56968 U4-2030 - failed to update UmbracoContext on some devt webservers 2013-04-05 10:28:19 -02:00
Stephan 49a61c5820 merge with 6.1.0 2013-04-05 06:22:35 -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
Shannon Deminick 2dfdc1050b Updates solution to use latest examine 1.5.1 from official Nuget source. 2013-04-05 06:19:52 +06:00
Shannon Deminick 9e239f135d Fixes: #U4-2027, changes DirectoryBrowser over to use correct webforms file structure, cleans up (a teeny bit)
how this page is structured, at least its not all inline c# code with inline styles.
2013-04-05 06:06:10 +06:00
Sebastiaan Janssen 480b84a223 Added tag release-6.1.0-beta for changeset 87cf618a39e3 2013-04-04 16:59:27 -02:00
Stephan e1c810c033 merge with 6.1.0 2013-04-04 14:27:11 -02:00
Stephan 7a1e3b96b8 Web.PublishedCache - IPublishedCaches doesn't return !contextual caches anymore 2013-04-04 05:10:53 -02:00
Stephan 4abb9fff3e merge with 6.1.0 2013-04-03 11:19:41 -02:00
Stephan 2490908401 merge with 6.1.0 2013-04-03 08:41:53 -02:00
Stephan 4217949719 merge with 6.1.0 2013-04-02 11:35:06 -02:00
Stephan fc68ba69e2 merge with 6.1.0 2013-04-02 09:24:36 -02:00
Stephan 28892a7bb2 merge with 6.1.0 2013-04-01 16:35:52 -02:00
Stephan 65cb6fbaff merge with 6.1.0 2013-03-31 19:19:24 -02:00
Stephan 4b49f9779f merge with 6.1.0 2013-03-31 19:05:24 -02:00
Stephan c5b6bb52e0 Web.PublishedCache - refactor how caches manage preview 2013-03-31 18:47:25 -02:00
Stephan efee4d0c0c Web.PublishedCache - IPublishedCaches creates contextual caches 2013-04-04 05:09:26 -02:00
Stephan b89951dd11 Web.PublishedCache - refactor contextual caches & inner caches management 2013-03-31 18:44:29 -02:00
Stephan 70ad3edc1f Web.UmbracoContext - refactor constructor to use IPublishedCaches 2013-04-03 08:40:35 -02:00
Stephan 9982a09826 Web.PublishedCache - merge resolvers so caches can be related 2013-03-31 18:40:55 -02:00
Stephan 83308c3d5f Core.Xml - support XPathExpression 2013-04-10 12:47:11 -02:00
Stephan 495b661263 Core.Xml - refactor 2013-04-10 12:47:09 -02:00
Stephan f2d7e3549d XmlPublishedCache - fix casting exception messages 2013-04-04 15:24:29 -02:00
Stephan 4201d678fa XmlPublishedCache - GetXml() can be private, no need for internal 2013-04-04 15:24:29 -02:00
Stephan ff6ee360da ItemRenderer - cleanup access to Xml cache 2013-04-04 15:24:29 -02:00
Stephan 1f999d7e22 Macros - bugfix & refactor access to Xml cache 2013-04-04 05:02:55 -02:00
Stephan be24075850 presentation.library - get Xml navigator via Web.UmbracoContext 2013-04-04 05:03:01 -02:00
Stephan 6148d63b02 merge with 6.1.0 2013-03-26 11:37:52 -01:00
Stephan 3ed4da19c2 merge with 6.1.0 2013-03-25 09:46:25 -01:00
Stephan a9df92b7a3 merge with 6.1.0 2013-03-22 17:45:42 -01:00
Stephan 6e4d8b638e merge 2013-03-22 17:40:29 -01:00
Stephan 97f3f13aaa Core. and Web.Configuration - go public
UmbracoSettings now public, only static For<> method is not internal, though
2013-03-01 13:56:12 -01:00
Stephan 5110e0ec0e Web.Routing - go public 2013-01-24 08:51:27 -01:00
Stephan edb84b3c97 Core.Strings - go public 2013-02-19 06:37:24 -01:00
506 changed files with 17934 additions and 12310 deletions
+3
View File
@@ -27,5 +27,8 @@ ff3bb24ea0c915878396a6ae27f1ff164e8ac150 Release-6.0.0-beta
1719fbd857f28b376639ac2aa0abada0ef2e7560 Release-6.0.0
e02f5aebb87e3f07d27376647756caa9762931d8 Release-4.11.4
14338b0ab1738fbd8987677ecdb9a73d79fc229d release-4.11.6
ce47176bc6b9298741783e20f1fe2672c811f744 release-4.11.7
b247b35d821144849f551e02da8ba719f91d5fb0 Release-6.0.2
aed55cba29009ad3db48880a7cfb66407ce9805f release-6.0.3
87cf618a39e38ec58df916d10e6a924de62ae37d release-6.1.0-beta
0dee9964687ea51ea797984cf7cce3655d6a6558 release-6.0.4
+1 -1
View File
@@ -1,6 +1,6 @@
@ECHO OFF
SET release=6.1.0
SET comment=beta
SET comment=beta-2
SET version=%release%
IF [%comment%] EQU [] (SET version=%release%) ELSE (SET version=%release%-%comment%)
+1 -2
View File
@@ -18,6 +18,7 @@
<dependency id="Microsoft.AspNet.Mvc" version="[4.0.20710.0]" />
<dependency id="Microsoft.AspNet.WebApi" version="4.0.20710.0" />
<dependency id="Microsoft.AspNet.Mvc.FixedDisplayModes" version="1.0.0" />
<dependency id="MiniProfiler" version="2.1.0" />
</dependencies>
</metadata>
<files>
@@ -63,8 +64,6 @@
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.dll" target="lib\umbraco.providers.dll" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.xml" target="lib\umbraco.providers.xml" />
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Web.UI.dll" target="lib\Umbraco.Web.UI.dll" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.webservices.dll" target="lib\umbraco.webservices.dll" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.webservices.xml" target="lib\umbraco.webservices.xml" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.XmlSerializers.dll" target="lib\umbraco.XmlSerializers.dll" />
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.dll" target="lib\UmbracoExamine.dll" />
<file src="..\_BuildOutput\WebApp\bin\UrlRewritingNet.UrlRewriter.dll" target="lib\UrlRewritingNet.UrlRewriter.dll" />
+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
+13 -2
View File
@@ -123,6 +123,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
@@ -163,7 +175,6 @@ namespace Umbraco.Core
}
}
private void AssertIsReady()
{
if (!this.IsReady)
@@ -245,7 +256,7 @@ namespace Umbraco.Core
this.ApplicationCache = null;
if (_databaseContext != null) //need to check the internal field here
{
if (DatabaseContext.Database != null)
if (DatabaseContext.IsDatabaseConfigured)
{
DatabaseContext.Database.Dispose();
}
+35 -1
View File
@@ -19,7 +19,41 @@ namespace Umbraco.Core
return new FileInfo(path);
}
/// <summary>
/// <summary>
/// Returns true if the assembly is the App_Code assembly
/// </summary>
/// <param name="assembly"></param>
/// <returns></returns>
public static bool IsAppCodeAssembly(this Assembly assembly)
{
if (assembly.FullName.StartsWith("App_Code"))
{
try
{
Assembly.Load("App_Code");
return true;
}
catch (FileNotFoundException)
{
//this will occur if it cannot load the assembly
return false;
}
}
return false;
}
/// <summary>
/// Returns true if the assembly is the compiled global asax.
/// </summary>
/// <param name="assembly"></param>
/// <returns></returns>
public static bool IsGlobalAsaxAssembly(this Assembly assembly)
{
//only way I can figure out how to test is by the name
return assembly.FullName.StartsWith("App_global.asax");
}
/// <summary>
/// Returns the file used to load the assembly
/// </summary>
/// <param name="assemblyName"></param>
@@ -10,7 +10,7 @@ namespace Umbraco.Core.Configuration
/// A case-insensitive configuration converter for enumerations.
/// </summary>
/// <typeparam name="T">The type of the enumeration.</typeparam>
internal class CaseInsensitiveEnumConfigConverter<T> : ConfigurationConverterBase
public class CaseInsensitiveEnumConfigConverter<T> : ConfigurationConverterBase
where T : struct
{
public override object ConvertFrom(ITypeDescriptorContext ctx, CultureInfo ci, object data)
@@ -9,7 +9,7 @@ namespace Umbraco.Core.Configuration
/// Indicates the configuration key for a section or a group.
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
internal sealed class ConfigurationKeyAttribute : Attribute
public sealed class ConfigurationKeyAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="ConfigurationKeyAttribute"/> class with a configuration key.
@@ -16,7 +16,7 @@ namespace Umbraco.Core.Configuration
/// <para>The <c>UmbracoSettings.For{T}</c> method will return a section, either one that
/// is in the configuration file, or a section that was created with default values.</para>
/// </remarks>
internal abstract class UmbracoConfigurationSection : ConfigurationSection
public abstract class UmbracoConfigurationSection : ConfigurationSection
{
/// <summary>
/// Gets a value indicating whether the section actually is in the configuration file.
@@ -135,7 +135,7 @@ namespace Umbraco.Core.Configuration
/// </summary>
/// <param name="key">The xpath query to the specific node.</param>
/// <returns>If found, it returns the specific configuration xml node.</returns>
public static XmlNode GetKeyAsNode(string key)
internal static XmlNode GetKeyAsNode(string key)
{
if (key == null)
throw new ArgumentException("Key cannot be null");
@@ -150,7 +150,7 @@ namespace Umbraco.Core.Configuration
/// </summary>
/// <param name="key">The key.</param>
/// <returns></returns>
public static string GetKey(string key)
internal static string GetKey(string key)
{
EnsureSettingsDocument();
@@ -187,7 +187,7 @@ namespace Umbraco.Core.Configuration
/// <value>
/// <c>true</c> if new directories are allowed otherwise, <c>false</c>.
/// </value>
public static bool UploadAllowDirectories
internal static bool UploadAllowDirectories
{
get { return bool.Parse(GetKey("/settings/content/UploadAllowDirectories")); }
}
@@ -214,7 +214,7 @@ namespace Umbraco.Core.Configuration
/// Gets a value indicating whether logging is enabled in umbracoSettings.config (/settings/logging/enableLogging).
/// </summary>
/// <value><c>true</c> if logging is enabled; otherwise, <c>false</c>.</value>
public static bool EnableLogging
internal static bool EnableLogging
{
get
{
@@ -229,7 +229,7 @@ namespace Umbraco.Core.Configuration
/// Gets a value indicating whether logging happens async.
/// </summary>
/// <value><c>true</c> if async logging is enabled; otherwise, <c>false</c>.</value>
public static bool EnableAsyncLogging
internal static bool EnableAsyncLogging
{
get
{
@@ -244,7 +244,7 @@ namespace Umbraco.Core.Configuration
/// <summary>
/// Gets the assembly of an external logger that can be used to store log items in 3rd party systems
/// </summary>
public static string ExternalLoggerAssembly
internal static string ExternalLoggerAssembly
{
get
{
@@ -256,7 +256,7 @@ namespace Umbraco.Core.Configuration
/// <summary>
/// Gets the type of an external logger that can be used to store log items in 3rd party systems
/// </summary>
public static string ExternalLoggerType
internal static string ExternalLoggerType
{
get
{
@@ -268,7 +268,7 @@ namespace Umbraco.Core.Configuration
/// <summary>
/// Long Audit Trail to external log too
/// </summary>
public static bool ExternalLoggerLogAuditTrail
internal static bool ExternalLoggerLogAuditTrail
{
get
{
@@ -287,7 +287,7 @@ namespace Umbraco.Core.Configuration
/// <summary>
/// Keep user alive as long as they have their browser open? Default is true
/// </summary>
public static bool KeepUserLoggedIn
internal static bool KeepUserLoggedIn
{
get
{
@@ -302,7 +302,7 @@ namespace Umbraco.Core.Configuration
/// <summary>
/// Enables the experimental canvas (live) editing on the frontend of the website
/// </summary>
public static bool EnableCanvasEditing
internal static bool EnableCanvasEditing
{
get
{
@@ -317,7 +317,7 @@ namespace Umbraco.Core.Configuration
/// <summary>
/// Show disabled users in the tree in the Users section in the backoffice
/// </summary>
public static bool HideDisabledUsersInBackoffice
internal static bool HideDisabledUsersInBackoffice
{
get
{
@@ -333,7 +333,7 @@ namespace Umbraco.Core.Configuration
/// Gets a value indicating whether the logs will be auto cleaned
/// </summary>
/// <value><c>true</c> if logs are to be automatically cleaned; otherwise, <c>false</c></value>
public static bool AutoCleanLogs
internal static bool AutoCleanLogs
{
get
{
@@ -348,7 +348,7 @@ namespace Umbraco.Core.Configuration
/// <summary>
/// Gets the value indicating the log cleaning frequency (in miliseconds)
/// </summary>
public static int CleaningMiliseconds
internal static int CleaningMiliseconds
{
get
{
@@ -360,7 +360,7 @@ namespace Umbraco.Core.Configuration
}
}
public static int MaxLogAge
internal static int MaxLogAge
{
get
{
@@ -376,7 +376,7 @@ namespace Umbraco.Core.Configuration
/// Gets the disabled log types.
/// </summary>
/// <value>The disabled log types.</value>
public static XmlNode DisabledLogTypes
internal static XmlNode DisabledLogTypes
{
get { return GetKeyAsNode("/settings/logging/disabledLogTypes"); }
}
@@ -385,7 +385,7 @@ namespace Umbraco.Core.Configuration
/// Gets the package server url.
/// </summary>
/// <value>The package server url.</value>
public static string PackageServer
internal static string PackageServer
{
get { return "packages.umbraco.org"; }
}
@@ -396,15 +396,14 @@ namespace Umbraco.Core.Configuration
/// Gets a value indicating whether umbraco will use domain prefixes.
/// </summary>
/// <value><c>true</c> if umbraco will use domain prefixes; otherwise, <c>false</c>.</value>
// TODO rename as EnforceAbsoluteUrls
public static bool UseDomainPrefixes
internal static bool UseDomainPrefixes
{
get
{
// default: false
return _useDomainPrefixes ?? GetKeyValue("/settings/requestHandler/useDomainPrefixes", false);
}
internal set
/*internal*/ set
{
// for unit tests only
_useDomainPrefixes = value;
@@ -417,7 +416,7 @@ namespace Umbraco.Core.Configuration
/// This will add a trailing slash (/) to urls when in directory url mode
/// NOTICE: This will always return false if Directory Urls in not active
/// </summary>
public static bool AddTrailingSlash
internal static bool AddTrailingSlash
{
get
{
@@ -425,7 +424,7 @@ namespace Umbraco.Core.Configuration
return GlobalSettings.UseDirectoryUrls
&& (_addTrailingSlash ?? GetKeyValue("/settings/requestHandler/addTrailingSlash", false));
}
internal set
/*internal*/ set
{
// for unit tests only
_addTrailingSlash = value;
@@ -436,7 +435,7 @@ namespace Umbraco.Core.Configuration
/// Gets a value indicating whether umbraco will use ASP.NET MasterPages for rendering instead of its propriatary templating system.
/// </summary>
/// <value><c>true</c> if umbraco will use ASP.NET MasterPages; otherwise, <c>false</c>.</value>
public static bool UseAspNetMasterPages
internal static bool UseAspNetMasterPages
{
get
{
@@ -458,7 +457,7 @@ namespace Umbraco.Core.Configuration
/// Gets a value indicating whether umbraco will attempt to load any skins to override default template files
/// </summary>
/// <value><c>true</c> if umbraco will override templates with skins if present and configured <c>false</c>.</value>
public static bool EnableTemplateFolders
internal static bool EnableTemplateFolders
{
get
{
@@ -482,7 +481,7 @@ namespace Umbraco.Core.Configuration
/// <summary>
/// razor DynamicNode typecasting detects XML and returns DynamicXml - Root elements that won't convert to DynamicXml
/// </summary>
public static IEnumerable<string> NotDynamicXmlDocumentElements
internal static IEnumerable<string> NotDynamicXmlDocumentElements
{
get
{
@@ -571,7 +570,7 @@ namespace Umbraco.Core.Configuration
/// <value>
/// <c>true</c> if umbraco will clone XML cache on publish; otherwise, <c>false</c>.
/// </value>
public static bool CloneXmlCacheOnPublish
internal static bool CloneXmlCacheOnPublish
{
get
{
@@ -593,7 +592,7 @@ namespace Umbraco.Core.Configuration
/// Gets a value indicating whether rich text editor content should be parsed by tidy.
/// </summary>
/// <value><c>true</c> if content is parsed; otherwise, <c>false</c>.</value>
public static bool TidyEditorContent
internal static bool TidyEditorContent
{
get { return bool.Parse(GetKey("/settings/content/TidyEditorContent")); }
}
@@ -602,7 +601,7 @@ namespace Umbraco.Core.Configuration
/// Gets the encoding type for the tidyied content.
/// </summary>
/// <value>The encoding type as string.</value>
public static string TidyCharEncoding
internal static string TidyCharEncoding
{
get
{
@@ -619,12 +618,12 @@ namespace Umbraco.Core.Configuration
/// Gets the property context help option, this can either be 'text', 'icon' or 'none'
/// </summary>
/// <value>The property context help option.</value>
public static string PropertyContextHelpOption
internal static string PropertyContextHelpOption
{
get { return GetKey("/settings/content/PropertyContextHelpOption").ToLower(); }
}
public static string DefaultBackofficeProvider
internal static string DefaultBackofficeProvider
{
get
{
@@ -641,14 +640,14 @@ namespace Umbraco.Core.Configuration
/// <summary>
/// Whether to force safe aliases (no spaces, no special characters) at businesslogic level on contenttypes and propertytypes
/// </summary>
public static bool ForceSafeAliases
internal static bool ForceSafeAliases
{
get
{
// default: true
return _forceSafeAliases ?? GetKeyValue("/settings/content/ForceSafeAliases", true);
}
internal set
/*internal*/ set
{
// used for unit testing
_forceSafeAliases = value;
@@ -673,11 +672,23 @@ namespace Umbraco.Core.Configuration
get { return GetKeyValue("/settings/web.routing/@internalRedirectPreservesTemplate", false); }
}
/// <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>
/// <value>The allowed image file types.</value>
public static string ImageFileTypes
internal static string ImageFileTypes
{
get { return GetKey("/settings/content/imaging/imageFileTypes").ToLowerInvariant(); }
}
@@ -686,7 +697,7 @@ namespace Umbraco.Core.Configuration
/// Gets the allowed script file types.
/// </summary>
/// <value>The allowed script file types.</value>
public static string ScriptFileTypes
internal static string ScriptFileTypes
{
get { return GetKey("/settings/content/scripteditor/scriptFileTypes"); }
}
@@ -697,14 +708,14 @@ namespace Umbraco.Core.Configuration
/// Gets the duration in seconds to cache queries to umbraco library member and media methods
/// Default is 1800 seconds (30 minutes)
/// </summary>
public static int UmbracoLibraryCacheDuration
internal static int UmbracoLibraryCacheDuration
{
get
{
// default: 1800
return _umbracoLibraryCacheDuration ?? GetKeyValue("/settings/content/UmbracoLibraryCacheDuration", 1800);
}
internal set
/*internal*/ set
{
// for unit tests only
_umbracoLibraryCacheDuration = value;
@@ -715,7 +726,7 @@ namespace Umbraco.Core.Configuration
/// Gets the path to the scripts folder used by the script editor.
/// </summary>
/// <value>The script folder path.</value>
public static string ScriptFolderPath
internal static string ScriptFolderPath
{
get { return GetKey("/settings/content/scripteditor/scriptFolderPath"); }
}
@@ -723,7 +734,7 @@ namespace Umbraco.Core.Configuration
/// <summary>
/// Enabled or disable the script/code editor
/// </summary>
public static bool ScriptDisableEditor
internal static bool ScriptDisableEditor
{
get
{
@@ -741,7 +752,7 @@ namespace Umbraco.Core.Configuration
/// ex: existingnodename.aspx would become existingnodename(1).aspx if a node with the same name is found
/// </summary>
/// <value><c>true</c> if umbraco ensures unique node naming; otherwise, <c>false</c>.</value>
public static bool EnsureUniqueNaming
internal static bool EnsureUniqueNaming
{
get
{
@@ -760,7 +771,7 @@ namespace Umbraco.Core.Configuration
/// Gets the notification email sender.
/// </summary>
/// <value>The notification email sender.</value>
public static string NotificationEmailSender
internal static string NotificationEmailSender
{
get { return GetKey("/settings/content/notifications/email"); }
}
@@ -771,7 +782,7 @@ namespace Umbraco.Core.Configuration
/// <value>
/// <c>true</c> if html notification-emails are disabled; otherwise, <c>false</c>.
/// </value>
public static bool NotificationDisableHtmlEmail
internal static bool NotificationDisableHtmlEmail
{
get
{
@@ -784,12 +795,12 @@ namespace Umbraco.Core.Configuration
/// Gets the allowed attributes on images.
/// </summary>
/// <value>The allowed attributes on images.</value>
public static string ImageAllowedAttributes
internal static string ImageAllowedAttributes
{
get { return GetKey("/settings/content/imaging/allowedAttributes"); }
}
public static XmlNode ImageAutoFillImageProperties
internal static XmlNode ImageAutoFillImageProperties
{
get { return GetKeyAsNode("/settings/content/imaging/autoFillImageProperties"); }
}
@@ -798,7 +809,7 @@ namespace Umbraco.Core.Configuration
/// Gets the scheduled tasks as XML
/// </summary>
/// <value>The scheduled tasks.</value>
public static XmlNode ScheduledTasks
internal static XmlNode ScheduledTasks
{
get { return GetKeyAsNode("/settings/scheduledTasks"); }
}
@@ -807,7 +818,7 @@ namespace Umbraco.Core.Configuration
/// Gets a list of characters that will be replaced when generating urls
/// </summary>
/// <value>The URL replacement characters.</value>
public static XmlNode UrlReplaceCharacters
internal static XmlNode UrlReplaceCharacters
{
get { return GetKeyAsNode("/settings/requestHandler/urlReplacing"); }
}
@@ -815,7 +826,7 @@ namespace Umbraco.Core.Configuration
/// <summary>
/// Whether to replace double dashes from url (ie my--story----from--dash.aspx caused by multiple url replacement chars
/// </summary>
public static bool RemoveDoubleDashesFromUrlReplacing
internal static bool RemoveDoubleDashesFromUrlReplacing
{
get
{
@@ -836,7 +847,7 @@ namespace Umbraco.Core.Configuration
/// Used for load-balancing high-traffic sites.
/// </summary>
/// <value><c>true</c> if umbraco uses distributed calls; otherwise, <c>false</c>.</value>
public static bool UseDistributedCalls
internal static bool UseDistributedCalls
{
get
{
@@ -856,7 +867,7 @@ namespace Umbraco.Core.Configuration
/// Gets the ID of the user with access rights to perform the distributed calls.
/// </summary>
/// <value>The distributed call user.</value>
public static int DistributedCallUser
internal static int DistributedCallUser
{
get
{
@@ -874,7 +885,7 @@ namespace Umbraco.Core.Configuration
/// <summary>
/// Gets the html injected into a (x)html page if Umbraco is running in preview mode
/// </summary>
public static string PreviewBadge
internal static string PreviewBadge
{
get
{
@@ -895,7 +906,7 @@ namespace Umbraco.Core.Configuration
/// and update their content cache accordingly, ensuring a consistent cache on all servers
/// </summary>
/// <value>The distribution servers.</value>
public static XmlNode DistributionServers
internal static XmlNode DistributionServers
{
get
{
@@ -915,7 +926,7 @@ namespace Umbraco.Core.Configuration
/// A help page configuration specify language, user type, application, application url and
/// the target help page url.
/// </summary>
public static XmlNode HelpPages
internal static XmlNode HelpPages
{
get
{
@@ -937,7 +948,7 @@ namespace Umbraco.Core.Configuration
/// All packages installed from a repository gets the repository alias included in the install information
/// </summary>
/// <value>The repository servers.</value>
public static XmlNode Repositories
internal static XmlNode Repositories
{
get
{
@@ -960,7 +971,7 @@ namespace Umbraco.Core.Configuration
/// <value>
/// <c>true</c> if umbraco will use the viewstate mover module; otherwise, <c>false</c>.
/// </value>
public static bool UseViewstateMoverModule
internal static bool UseViewstateMoverModule
{
get
{
@@ -982,7 +993,7 @@ namespace Umbraco.Core.Configuration
/// Tells us whether the Xml Content cache is disabled or not
/// Default is enabled
/// </summary>
public static bool IsXmlContentCacheDisabled
internal static bool IsXmlContentCacheDisabled
{
get
{
@@ -1007,7 +1018,7 @@ namespace Umbraco.Core.Configuration
/// Makes it possible to updates environments by syncing the umbraco.config file across instances
/// Relates to http://umbraco.codeplex.com/workitem/30722
/// </summary>
public static bool XmlContentCheckForDiskChanges
internal static bool XmlContentCheckForDiskChanges
{
get
{
@@ -1032,7 +1043,7 @@ namespace Umbraco.Core.Configuration
/// If disabled, only documents will generate data.
/// This feature is useful if anyone would like to see how data looked at a given time
/// </summary>
public static bool EnableGlobalPreviewStorage
internal static bool EnableGlobalPreviewStorage
{
get
{
@@ -1060,14 +1071,14 @@ namespace Umbraco.Core.Configuration
/// <value>
/// <c>true</c> if yes, use the old node/data model; otherwise, <c>false</c>.
/// </value>
public static bool UseLegacyXmlSchema
internal static bool UseLegacyXmlSchema
{
get
{
// default: true
return _useLegacySchema ?? GetKeyValue("/settings/content/UseLegacyXmlSchema", false);
}
internal set
/*internal*/ set
{
// used for unit testing
_useLegacySchema = value;
@@ -1075,7 +1086,7 @@ namespace Umbraco.Core.Configuration
}
[Obsolete("This setting is not used anymore, the only file extensions that are supported are .cs and .vb files")]
public static IEnumerable<string> AppCodeFileExtensionsList
internal static IEnumerable<string> AppCodeFileExtensionsList
{
get
{
@@ -1086,7 +1097,7 @@ namespace Umbraco.Core.Configuration
}
[Obsolete("This setting is not used anymore, the only file extensions that are supported are .cs and .vb files")]
public static XmlNode AppCodeFileExtensions
internal static XmlNode AppCodeFileExtensions
{
get
{
@@ -1108,7 +1119,7 @@ namespace Umbraco.Core.Configuration
/// Tells us whether the Xml to always update disk cache, when changes are made to content
/// Default is enabled
/// </summary>
public static bool ContinouslyUpdateXmlDiskCache
internal static bool ContinouslyUpdateXmlDiskCache
{
get
{
@@ -1134,7 +1145,7 @@ namespace Umbraco.Core.Configuration
/// have a splash page
/// Default is disabled
/// </summary>
public static bool EnableSplashWhileLoading
internal static bool EnableSplashWhileLoading
{
get
{
@@ -1155,7 +1166,7 @@ namespace Umbraco.Core.Configuration
}
private static bool? _resolveUrlsFromTextString;
public static bool ResolveUrlsFromTextString
internal static bool ResolveUrlsFromTextString
{
get
{
@@ -1192,7 +1203,7 @@ namespace Umbraco.Core.Configuration
/// is used instead of the masterpages editor
/// </summary>
/// <value><c>true</c> if umbraco defaults to using MVC views for templating, otherwise <c>false</c>.</value>
public static RenderingEngine DefaultRenderingEngine
internal static RenderingEngine DefaultRenderingEngine
{
get
{
@@ -1233,7 +1244,7 @@ namespace Umbraco.Core.Configuration
/// - 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
internal static MacroErrorBehaviour MacroErrorBehaviour
{
get
{
@@ -1268,7 +1279,7 @@ namespace Umbraco.Core.Configuration
/// - 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
internal static IconPickerBehaviour IconPickerBehaviour
{
get
{
@@ -1504,7 +1515,7 @@ namespace Umbraco.Core.Configuration
/// </summary>
/// <typeparam name="T">The type of the UmbracoConfigurationSectiont.</typeparam>
/// <returns>The UmbracoConfigurationSection of the specified type.</returns>
internal static T For<T>()
public static T For<T>()
where T : UmbracoConfigurationSection, new()
{
var sectionType = typeof (T);
@@ -23,7 +23,7 @@ namespace Umbraco.Core.Configuration
/// Gets the version comment (like beta or RC).
/// </summary>
/// <value>The version comment.</value>
public static string CurrentComment { get { return "beta"; } }
public static string CurrentComment { get { return "beta-2"; } }
// Get the version of the umbraco.dll by looking at a class in that dll
// Had to do it like this due to medium trust issues, see: http://haacked.com/archive/2010/11/04/assembly-location-and-medium-trust.aspx
+1 -4
View File
@@ -158,7 +158,7 @@ namespace Umbraco.Core
.ForEach(x => x.OnApplicationStarted(UmbracoApplication, ApplicationContext));
//Now, startup all of our legacy startup handler
ApplicationEventsResolver.Current.InstantiateLegacyStartupHanlders();
ApplicationEventsResolver.Current.InstantiateLegacyStartupHandlers();
if (afterComplete != null)
{
@@ -223,9 +223,6 @@ namespace Umbraco.Core
ActionsResolver.Current = new ActionsResolver(
() => PluginManager.Current.ResolveActions());
MacroPropertyTypeResolver.Current = new MacroPropertyTypeResolver(
PluginManager.Current.ResolveMacroPropertyTypes());
//the database migration objects
MigrationResolver.Current = new MigrationResolver(
() => PluginManager.Current.ResolveMigrationTypes());
@@ -1,34 +0,0 @@
using System;
using System.Collections.Generic;
using Umbraco.Core.Models;
using Umbraco.Core.ObjectResolution;
namespace Umbraco.Core
{
/// <summary>
/// A resolver to return all <see cref="IMacroPropertyType"/> objects
/// </summary>
internal sealed class MacroPropertyTypeResolver : ManyObjectsResolverBase<MacroPropertyTypeResolver, IMacroPropertyType>
{
/// <summary>
/// Constructor
/// </summary>
/// <param name="macroPropertyTypes"></param>
internal MacroPropertyTypeResolver(IEnumerable<Type> macroPropertyTypes)
: base(macroPropertyTypes)
{
}
/// <summary>
/// Gets the <see cref="IMacroPropertyType"/> implementations.
/// </summary>
public IEnumerable<IMacroPropertyType> MacroPropertyTypes
{
get
{
return Values;
}
}
}
}
@@ -1,27 +0,0 @@
using Umbraco.Core.Models;
namespace Umbraco.Core.Macros.PropertyTypes
{
internal class ContentAll : IMacroPropertyType
{
public string Alias
{
get { return "contentAll"; }
}
public string RenderingAssembly
{
get { return "umbraco.macroRenderings"; }
}
public string RenderingType
{
get { return "content"; }
}
public MacroPropertyTypeBaseTypes BaseType
{
get { return MacroPropertyTypeBaseTypes.Int32; }
}
}
}
@@ -1,27 +0,0 @@
using Umbraco.Core.Models;
namespace Umbraco.Core.Macros.PropertyTypes
{
internal class ContentPicker : IMacroPropertyType
{
public string Alias
{
get { return "contentPicker"; }
}
public string RenderingAssembly
{
get { return "umbraco.macroRenderings"; }
}
public string RenderingType
{
get { return "content"; }
}
public MacroPropertyTypeBaseTypes BaseType
{
get { return MacroPropertyTypeBaseTypes.Int32; }
}
}
}
@@ -1,27 +0,0 @@
using Umbraco.Core.Models;
namespace Umbraco.Core.Macros.PropertyTypes
{
internal class ContentRandom : IMacroPropertyType
{
public string Alias
{
get { return "contentRandom"; }
}
public string RenderingAssembly
{
get { return "umbraco.macroRenderings"; }
}
public string RenderingType
{
get { return "content"; }
}
public MacroPropertyTypeBaseTypes BaseType
{
get { return MacroPropertyTypeBaseTypes.Int32; }
}
}
}
@@ -1,27 +0,0 @@
using Umbraco.Core.Models;
namespace Umbraco.Core.Macros.PropertyTypes
{
internal class ContentStubs : IMacroPropertyType
{
public string Alias
{
get { return "contentStubs"; }
}
public string RenderingAssembly
{
get { return "umbraco.macroRenderings"; }
}
public string RenderingType
{
get { return "content"; }
}
public MacroPropertyTypeBaseTypes BaseType
{
get { return MacroPropertyTypeBaseTypes.Int32; }
}
}
}
@@ -1,27 +0,0 @@
using Umbraco.Core.Models;
namespace Umbraco.Core.Macros.PropertyTypes
{
internal class ContentTree : IMacroPropertyType
{
public string Alias
{
get { return "contentTree"; }
}
public string RenderingAssembly
{
get { return "umbraco.macroRenderings"; }
}
public string RenderingType
{
get { return "content"; }
}
public MacroPropertyTypeBaseTypes BaseType
{
get { return MacroPropertyTypeBaseTypes.Int32; }
}
}
}
@@ -1,27 +0,0 @@
using Umbraco.Core.Models;
namespace Umbraco.Core.Macros.PropertyTypes
{
internal class ContentType : IMacroPropertyType
{
public string Alias
{
get { return "contentType"; }
}
public string RenderingAssembly
{
get { return "umbraco.macroRenderings"; }
}
public string RenderingType
{
get { return "contentTypeSingle"; }
}
public MacroPropertyTypeBaseTypes BaseType
{
get { return MacroPropertyTypeBaseTypes.Int32; }
}
}
}
@@ -1,27 +0,0 @@
using Umbraco.Core.Models;
namespace Umbraco.Core.Macros.PropertyTypes
{
internal class ContentTypeMultiple : IMacroPropertyType
{
public string Alias
{
get { return "contentTypeMultiple"; }
}
public string RenderingAssembly
{
get { return "umbraco.macroRenderings"; }
}
public string RenderingType
{
get { return "contentTypeMultiple"; }
}
public MacroPropertyTypeBaseTypes BaseType
{
get { return MacroPropertyTypeBaseTypes.Int32; }
}
}
}
@@ -1,27 +0,0 @@
using Umbraco.Core.Models;
namespace Umbraco.Core.Macros.PropertyTypes
{
internal class MediaCurrent : IMacroPropertyType
{
public string Alias
{
get { return "mediaCurrent"; }
}
public string RenderingAssembly
{
get { return "umbraco.macroRenderings"; }
}
public string RenderingType
{
get { return "media"; }
}
public MacroPropertyTypeBaseTypes BaseType
{
get { return MacroPropertyTypeBaseTypes.Int32; }
}
}
}
@@ -1,27 +0,0 @@
using Umbraco.Core.Models;
namespace Umbraco.Core.Macros.PropertyTypes
{
internal class Number : IMacroPropertyType
{
public string Alias
{
get { return "number"; }
}
public string RenderingAssembly
{
get { return "umbraco.macroRenderings"; }
}
public string RenderingType
{
get { return "numeric"; }
}
public MacroPropertyTypeBaseTypes BaseType
{
get { return MacroPropertyTypeBaseTypes.Int32; }
}
}
}
@@ -1,27 +0,0 @@
using Umbraco.Core.Models;
namespace Umbraco.Core.Macros.PropertyTypes
{
internal class PropertyTypePicker : IMacroPropertyType
{
public string Alias
{
get { return "propertyTypePicker"; }
}
public string RenderingAssembly
{
get { return "umbraco.macroRenderings"; }
}
public string RenderingType
{
get { return "propertyTypePicker"; }
}
public MacroPropertyTypeBaseTypes BaseType
{
get { return MacroPropertyTypeBaseTypes.String; }
}
}
}
@@ -1,27 +0,0 @@
using Umbraco.Core.Models;
namespace Umbraco.Core.Macros.PropertyTypes
{
internal class PropertyTypePickerMultiple : IMacroPropertyType
{
public string Alias
{
get { return "propertyTypePickerMultiple"; }
}
public string RenderingAssembly
{
get { return "umbraco.macroRenderings"; }
}
public string RenderingType
{
get { return "propertyTypePickerMultiple"; }
}
public MacroPropertyTypeBaseTypes BaseType
{
get { return MacroPropertyTypeBaseTypes.String; }
}
}
}
@@ -1,27 +0,0 @@
using Umbraco.Core.Models;
namespace Umbraco.Core.Macros.PropertyTypes
{
internal class TabPicker : IMacroPropertyType
{
public string Alias
{
get { return "tabPicker"; }
}
public string RenderingAssembly
{
get { return "umbraco.macroRenderings"; }
}
public string RenderingType
{
get { return "tabPicker"; }
}
public MacroPropertyTypeBaseTypes BaseType
{
get { return MacroPropertyTypeBaseTypes.String; }
}
}
}
@@ -1,27 +0,0 @@
using Umbraco.Core.Models;
namespace Umbraco.Core.Macros.PropertyTypes
{
internal class TabPickerMultiple : IMacroPropertyType
{
public string Alias
{
get { return "tabPickerMultiple"; }
}
public string RenderingAssembly
{
get { return "umbraco.macroRenderings"; }
}
public string RenderingType
{
get { return "tabPickerMultiple"; }
}
public MacroPropertyTypeBaseTypes BaseType
{
get { return MacroPropertyTypeBaseTypes.String; }
}
}
}
@@ -1,27 +0,0 @@
using Umbraco.Core.Models;
namespace Umbraco.Core.Macros.PropertyTypes
{
internal class Text : IMacroPropertyType
{
public string Alias
{
get { return "text"; }
}
public string RenderingAssembly
{
get { return "umbraco.macroRenderings"; }
}
public string RenderingType
{
get { return "text"; }
}
public MacroPropertyTypeBaseTypes BaseType
{
get { return MacroPropertyTypeBaseTypes.String; }
}
}
}
@@ -1,27 +0,0 @@
using Umbraco.Core.Models;
namespace Umbraco.Core.Macros.PropertyTypes
{
internal class TextMultiLine : IMacroPropertyType
{
public string Alias
{
get { return "textMultiLine"; }
}
public string RenderingAssembly
{
get { return "umbraco.macroRenderings"; }
}
public string RenderingType
{
get { return "textMultiple"; }
}
public MacroPropertyTypeBaseTypes BaseType
{
get { return MacroPropertyTypeBaseTypes.String; }
}
}
}
@@ -1,27 +0,0 @@
using Umbraco.Core.Models;
namespace Umbraco.Core.Macros.PropertyTypes
{
internal class YesNoBool : IMacroPropertyType
{
public string Alias
{
get { return "bool"; }
}
public string RenderingAssembly
{
get { return "umbraco.macroRenderings"; }
}
public string RenderingType
{
get { return "yesNo"; }
}
public MacroPropertyTypeBaseTypes BaseType
{
get { return MacroPropertyTypeBaseTypes.Boolean; }
}
}
}
+22 -3
View File
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models
{
@@ -16,12 +15,22 @@ namespace Umbraco.Core.Models
{
private int _defaultTemplate;
private IEnumerable<ITemplate> _allowedTemplates;
/// <summary>
/// Constuctor for creating a ContentType with the parent's id.
/// </summary>
/// <remarks>You usually only want to use this for creating ContentTypes at the root.</remarks>
/// <param name="parentId"></param>
public ContentType(int parentId) : base(parentId)
{
_allowedTemplates = new List<ITemplate>();
}
/// <summary>
/// Constuctor for creating a ContentType with the parent as an inherited type.
/// </summary>
/// <remarks>Use this to ensure inheritance from parent.</remarks>
/// <param name="parent"></param>
public ContentType(IContentType parent) : base(parent)
{
_allowedTemplates = new List<ITemplate>();
@@ -152,14 +161,24 @@ namespace Umbraco.Core.Models
{
base.ResetDirtyProperties();
//loop through each property group to reset the property types
var propertiesReset = new List<int>();
foreach (var propertyGroup in PropertyGroups)
{
propertyGroup.ResetDirtyProperties();
foreach (var propertyType in propertyGroup.PropertyTypes)
{
{
propertyType.ResetDirtyProperties();
propertiesReset.Add(propertyType.Id);
}
}
//then loop through our property type collection since some might not exist on a property group
//but don't re-reset ones we've already done.
foreach (var propertyType in PropertyTypes.Where(x => propertiesReset.Contains(x.Id) == false))
{
propertyType.ResetDirtyProperties();
}
}
/// <summary>
@@ -20,8 +20,10 @@ namespace Umbraco.Core.Models
{
}
protected ContentTypeCompositionBase(IContentTypeBase parent) : base(parent)
protected ContentTypeCompositionBase(IContentTypeComposition parent)
: base(parent)
{
AddContentType(parent);
}
private static readonly PropertyInfo ContentTypeCompositionSelector =
@@ -171,19 +171,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))
-94
View File
@@ -1,94 +0,0 @@
using System.Collections.Generic;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Models
{
/// <summary>
/// Defines a Macro
/// </summary>
internal interface IMacro : IAggregateRoot
{
/// <summary>
/// Gets or sets the alias of the Macro
/// </summary>
[DataMember]
string Alias { get; set; }
/// <summary>
/// Gets or sets the name of the Macro
/// </summary>
[DataMember]
string Name { get; set; }
/// <summary>
/// Gets or sets a boolean indicating whether the Macro can be used in an Editor
/// </summary>
[DataMember]
bool UseInEditor { get; set; }
/// <summary>
/// Gets or sets the Cache Duration for the Macro
/// </summary>
[DataMember]
int CacheDuration { get; set; }
/// <summary>
/// Gets or sets a boolean indicating whether the Macro should be Cached by Page
/// </summary>
[DataMember]
bool CacheByPage { get; set; }
/// <summary>
/// Gets or sets a boolean indicating whether the Macro should be Cached Personally
/// </summary>
[DataMember]
bool CacheByMember { get; set; }
/// <summary>
/// Gets or sets a boolean indicating whether the Macro should be rendered in an Editor
/// </summary>
[DataMember]
bool DontRender { get; set; }
/// <summary>
/// Gets or sets the path to the script file in use
/// </summary>
/// <remarks>Optional: Can only be one of three Script, Python or Xslt</remarks>
[DataMember]
string ScriptFile { get; set; }
/// <summary>
/// Gets or sets the name of the assembly, which should be used by the Macro
/// </summary>
/// <remarks>Will usually only be filled if the ScriptFile is a Usercontrol</remarks>
[DataMember]
string ScriptAssembly { get; set; }
/// <summary>
/// Gets or set the path to the Python file in use
/// </summary>
/// <remarks>Optional: Can only be one of three Script, Python or Xslt</remarks>
[DataMember]
string Python { get; set; }
/// <summary>
/// Gets or sets the path to the Xslt file in use
/// </summary>
/// <remarks>Optional: Can only be one of three Script, Python or Xslt</remarks>
[DataMember]
string Xslt { get; set; }
/// <summary>
/// Gets or sets a list of Macro Properties
/// </summary>
[DataMember]
List<IMacroProperty> Properties { get; set; }
/// <summary>
/// Returns an enum <see cref="MacroTypes"/> based on the properties on the Macro
/// </summary>
/// <returns><see cref="MacroTypes"/></returns>
MacroTypes MacroType();
}
}
-39
View File
@@ -1,39 +0,0 @@
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Models
{
/// <summary>
/// Defines a Property for a Macro
/// </summary>
internal interface IMacroProperty : IValueObject
{
/// <summary>
/// Gets or sets the Alias of the Property
/// </summary>
[DataMember]
string Alias { get; set; }
/// <summary>
/// Gets or sets the Name of the Property
/// </summary>
[DataMember]
string Name { get; set; }
/// <summary>
/// Gets or sets the Sort Order of the Property
/// </summary>
[DataMember]
int SortOrder { get; set; }
/// <summary>
/// Gets or sets the Type for this Property
/// </summary>
/// <remarks>
/// The MacroPropertyTypes acts as a plugin for Macros.
/// All types was previously contained in the database, but has been ported to code.
/// </remarks>
[DataMember]
IMacroPropertyType PropertyType { get; set; }
}
}
@@ -1,28 +0,0 @@
namespace Umbraco.Core.Models
{
/// <summary>
/// Defines a PropertyType (plugin) for a Macro
/// </summary>
internal interface IMacroPropertyType
{
/// <summary>
/// Gets the unique Alias of the Property Type
/// </summary>
string Alias { get; }
/// <summary>
/// Gets the name of the Assembly used to render the Property Type
/// </summary>
string RenderingAssembly { get; }
/// <summary>
/// Gets the name of the Type used to render the Property Type
/// </summary>
string RenderingType { get; }
/// <summary>
/// Gets the Base Type for storing the PropertyType (Int32, String, Boolean)
/// </summary>
MacroPropertyTypeBaseTypes BaseType { get; }
}
}
+2 -1
View File
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
namespace Umbraco.Core.Models
{
@@ -10,7 +11,7 @@ namespace Umbraco.Core.Models
/// <remarks>
/// A replacement for INode which needs to occur since INode doesn't contain the document type alias
/// and INode is poorly formatted with mutable properties (i.e. Lists instead of IEnumerable)
/// </remarks>
/// </remarks>
public interface IPublishedContent
{
int Id { get; }
-290
View File
@@ -1,290 +0,0 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Models
{
/// <summary>
/// Represents a Macro
/// </summary>
[Serializable]
[DataContract(IsReference = true)]
internal class Macro : Entity, IMacro
{
private string _alias;
private string _name;
private bool _useInEditor;
private int _cacheDuration;
private bool _cacheByPage;
private bool _cacheByMember;
private bool _dontRender;
private string _scriptFile;
private string _scriptAssembly;
private string _python;
private string _xslt;
private List<IMacroProperty> _properties;
private static readonly PropertyInfo AliasSelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.Alias);
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.Name);
private static readonly PropertyInfo UseInEditorSelector = ExpressionHelper.GetPropertyInfo<Macro, bool>(x => x.UseInEditor);
private static readonly PropertyInfo CacheDurationSelector = ExpressionHelper.GetPropertyInfo<Macro, int>(x => x.CacheDuration);
private static readonly PropertyInfo CacheByPageSelector = ExpressionHelper.GetPropertyInfo<Macro, bool>(x => x.CacheByPage);
private static readonly PropertyInfo CacheByMemberSelector = ExpressionHelper.GetPropertyInfo<Macro, bool>(x => x.CacheByMember);
private static readonly PropertyInfo DontRenderSelector = ExpressionHelper.GetPropertyInfo<Macro, bool>(x => x.DontRender);
private static readonly PropertyInfo ScriptFileSelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.ScriptFile);
private static readonly PropertyInfo ScriptAssemblySelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.ScriptAssembly);
private static readonly PropertyInfo PythonSelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.Python);
private static readonly PropertyInfo XsltSelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.Xslt);
private static readonly PropertyInfo PropertiesSelector = ExpressionHelper.GetPropertyInfo<Macro, List<IMacroProperty>>(x => x.Properties);
/// <summary>
/// Gets or sets the alias of the Macro
/// </summary>
[DataMember]
public string Alias
{
get { return _alias; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_alias = value;
return _alias;
}, _alias, AliasSelector);
}
}
/// <summary>
/// Gets or sets the name of the Macro
/// </summary>
[DataMember]
public string Name
{
get { return _name; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_name = value;
return _name;
}, _name, NameSelector);
}
}
/// <summary>
/// Gets or sets a boolean indicating whether the Macro can be used in an Editor
/// </summary>
[DataMember]
public bool UseInEditor
{
get { return _useInEditor; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_useInEditor = value;
return _useInEditor;
}, _useInEditor, UseInEditorSelector);
}
}
/// <summary>
/// Gets or sets the Cache Duration for the Macro
/// </summary>
[DataMember]
public int CacheDuration
{
get { return _cacheDuration; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_cacheDuration = value;
return _cacheDuration;
}, _cacheDuration, CacheDurationSelector);
}
}
/// <summary>
/// Gets or sets a boolean indicating whether the Macro should be Cached by Page
/// </summary>
[DataMember]
public bool CacheByPage
{
get { return _cacheByPage; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_cacheByPage = value;
return _cacheByPage;
}, _cacheByPage, CacheByPageSelector);
}
}
/// <summary>
/// Gets or sets a boolean indicating whether the Macro should be Cached Personally
/// </summary>
[DataMember]
public bool CacheByMember
{
get { return _cacheByMember; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_cacheByMember = value;
return _cacheByMember;
}, _cacheByMember, CacheByMemberSelector);
}
}
/// <summary>
/// Gets or sets a boolean indicating whether the Macro should be rendered in an Editor
/// </summary>
[DataMember]
public bool DontRender
{
get { return _dontRender; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_dontRender = value;
return _dontRender;
}, _dontRender, DontRenderSelector);
}
}
/// <summary>
/// Gets or sets the path to the script file in use
/// </summary>
/// <remarks>Optional: Can only be one of three Script, Python or Xslt</remarks>
[DataMember]
public string ScriptFile
{
get { return _scriptFile; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_scriptFile = value;
return _scriptFile;
}, _scriptFile, ScriptFileSelector);
}
}
/// <summary>
/// Gets or sets the name of the assembly, which should be used by the Macro
/// </summary>
/// <remarks>Will usually only be filled if the ScriptFile is a Usercontrol</remarks>
[DataMember]
public string ScriptAssembly
{
get { return _scriptAssembly; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_scriptAssembly = value;
return _scriptAssembly;
}, _scriptAssembly, ScriptAssemblySelector);
}
}
/// <summary>
/// Gets or set the path to the Python file in use
/// </summary>
/// <remarks>Optional: Can only be one of three Script, Python or Xslt</remarks>
[DataMember]
public string Python
{
get { return _python; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_python = value;
return _python;
}, _python, PythonSelector);
}
}
/// <summary>
/// Gets or sets the path to the Xslt file in use
/// </summary>
/// <remarks>Optional: Can only be one of three Script, Python or Xslt</remarks>
[DataMember]
public string Xslt
{
get { return _xslt; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_xslt = value;
return _xslt;
}, _xslt, XsltSelector);
}
}
//TODO: This needs to be changed to a custom collection class so we can track the dirtyness of each property!
/// <summary>
/// Gets or sets a list of Macro Properties
/// </summary>
[DataMember]
public List<IMacroProperty> Properties
{
get { return _properties; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_properties = value;
return _properties;
}, _properties, PropertiesSelector);
}
}
/// <summary>
/// Overridden this method in order to set a random Id
/// </summary>
internal override void AddingEntity()
{
base.AddingEntity();
var random = new Random();
Id = random.Next(10000, int.MaxValue);
Key = Alias.EncodeAsGuid();
}
/// <summary>
/// Returns an enum <see cref="MacroTypes"/> based on the properties on the Macro
/// </summary>
/// <returns><see cref="MacroTypes"/></returns>
public MacroTypes MacroType()
{
if (!string.IsNullOrEmpty(Xslt))
return MacroTypes.Xslt;
if (!string.IsNullOrEmpty(Python))
return MacroTypes.Python;
if (!string.IsNullOrEmpty(ScriptFile))
return MacroTypes.Script;
if (!string.IsNullOrEmpty(ScriptFile) && ScriptFile.ToLower().IndexOf(".ascx", StringComparison.InvariantCultureIgnoreCase) > -1)
{
return MacroTypes.UserControl;
}
if (!string.IsNullOrEmpty(ScriptFile) && !string.IsNullOrEmpty(ScriptAssembly))
return MacroTypes.CustomControl;
return MacroTypes.Unknown;
}
}
}
-98
View File
@@ -1,98 +0,0 @@
using System;
using System.Reflection;
using System.Runtime.Serialization;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Models
{
/// <summary>
/// Represents a Macro Property
/// </summary>
[Serializable]
[DataContract(IsReference = true)]
internal class MacroProperty : TracksChangesEntityBase, IMacroProperty, IRememberBeingDirty
{
private string _alias;
private string _name;
private int _sortOrder;
private IMacroPropertyType _propertyType;
private static readonly PropertyInfo AliasSelector = ExpressionHelper.GetPropertyInfo<MacroProperty, string>(x => x.Alias);
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<MacroProperty, string>(x => x.Name);
private static readonly PropertyInfo SortOrderSelector = ExpressionHelper.GetPropertyInfo<MacroProperty, int>(x => x.SortOrder);
private static readonly PropertyInfo PropertyTypeSelector = ExpressionHelper.GetPropertyInfo<MacroProperty, IMacroPropertyType>(x => x.PropertyType);
/// <summary>
/// Gets or sets the Alias of the Property
/// </summary>
[DataMember]
public string Alias
{
get { return _alias; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_alias = value;
return _alias;
}, _alias, AliasSelector);
}
}
/// <summary>
/// Gets or sets the Name of the Property
/// </summary>
[DataMember]
public string Name
{
get { return _name; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_name = value;
return _name;
}, _name, NameSelector);
}
}
/// <summary>
/// Gets or sets the Sort Order of the Property
/// </summary>
[DataMember]
public int SortOrder
{
get { return _sortOrder; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_sortOrder = value;
return _sortOrder;
}, _sortOrder, SortOrderSelector);
}
}
/// <summary>
/// Gets or sets the Type for this Property
/// </summary>
/// <remarks>
/// The MacroPropertyTypes acts as a plugin for Macros.
/// All types was previously contained in the database, but has been ported to code.
/// </remarks>
[DataMember]
public IMacroPropertyType PropertyType
{
get { return _propertyType; }
set
{
SetPropertyValueAndDetectChanges(o =>
{
_propertyType = value;
return _propertyType;
}, _propertyType, PropertyTypeSelector);
}
}
}
}
@@ -1,20 +0,0 @@
using System;
using System.Runtime.Serialization;
namespace Umbraco.Core.Models
{
/// <summary>
/// Enum for the three allowed BaseTypes
/// </summary>
[Serializable]
[DataContract(IsReference = true)]
internal enum MacroPropertyTypeBaseTypes
{
[EnumMember]
Int32,
[EnumMember]
Boolean,
[EnumMember]
String
}
}
-26
View File
@@ -1,26 +0,0 @@
using System;
using System.Runtime.Serialization;
namespace Umbraco.Core.Models
{
/// <summary>
/// Enum for the various types of Macros
/// </summary>
[Serializable]
[DataContract(IsReference = true)]
internal enum MacroTypes
{
[EnumMember]
Xslt = 1,
[EnumMember]
CustomControl = 2,
[EnumMember]
UserControl = 3,
[EnumMember]
Unknown = 4,
[EnumMember]
Python = 5,
[EnumMember]
Script = 6
}
}
+10 -1
View File
@@ -1,6 +1,5 @@
using System;
using System.Runtime.Serialization;
using Umbraco.Core.Persistence.Mappers;
namespace Umbraco.Core.Models
{
@@ -11,10 +10,20 @@ namespace Umbraco.Core.Models
[DataContract(IsReference = true)]
public class MediaType : ContentTypeCompositionBase, IMediaType
{
/// <summary>
/// Constuctor for creating a MediaType with the parent's id.
/// </summary>
/// <remarks>You usually only want to use this for creating MediaTypes at the root.</remarks>
/// <param name="parentId"></param>
public MediaType(int parentId) : base(parentId)
{
}
/// <summary>
/// Constuctor for creating a MediaType with the parent as an inherited type.
/// </summary>
/// <remarks>Use this to ensure inheritance from parent.</remarks>
/// <param name="parent"></param>
public MediaType(IMediaType parent) : base(parent)
{
}
+2 -13
View File
@@ -14,7 +14,6 @@ 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;
@@ -34,22 +33,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);
@@ -206,6 +195,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; }
@@ -240,7 +230,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
@@ -252,7 +242,6 @@ namespace Umbraco.Core.Models
}, _validationRegExp, ValidationRegExpSelector);
}
}
//Note that Validation should eventually come from PropertyEditors like in v5
/// <summary>
/// Create a new Property object from a "raw" database value.
@@ -94,5 +94,10 @@ namespace Umbraco.Core.Models
}, _isActive, IsActiveSelector);
}
}
public override string ToString()
{
return "(" + ServerAddress + ", " + ComputerName + ", IsActive = " + IsActive + ")";
}
}
}
+12 -4
View File
@@ -45,12 +45,8 @@ namespace Umbraco.Core.Models
{
base.Path = path;
ParentId = -1;
Key = name.EncodeAsGuid();
_name = name.Replace("/", ".").Replace("\\", "");
_alias = alias.ToSafeAlias();
CreateDate = DateTime.Now;
UpdateDate = DateTime.Now;
}
[DataMember]
@@ -199,5 +195,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();
}
}
}
+8 -8
View File
@@ -14,7 +14,7 @@ using System.Xml;
namespace Umbraco.Core
{
internal static class ObjectExtensions
public static class ObjectExtensions
{
//private static readonly ConcurrentDictionary<Type, Func<object>> ObjectFactoryCache = new ConcurrentDictionary<Type, Func<object>>();
@@ -36,7 +36,7 @@ namespace Umbraco.Core
/// <typeparam name="T"></typeparam>
/// <param name="input">The input.</param>
/// <returns></returns>
public static T SafeCast<T>(this object input)
internal static T SafeCast<T>(this object input)
{
if (ReferenceEquals(null, input) || ReferenceEquals(default(T), input)) return default(T);
if (input is T) return (T)input;
@@ -165,7 +165,7 @@ namespace Umbraco.Core
return Attempt<object>.False;
}
public static void CheckThrowObjectDisposed(this IDisposable disposable, bool isDisposed, string objectname)
internal static void CheckThrowObjectDisposed(this IDisposable disposable, bool isDisposed, string objectname)
{
//TODO: Localise this exception
if (isDisposed)
@@ -246,7 +246,7 @@ namespace Umbraco.Core
/// <param name="o"></param>
/// <param name="ignoreProperties"></param>
/// <returns></returns>
public static IDictionary<string, TVal> ToDictionary<T, TProperty, TVal>(this T o,
internal static IDictionary<string, TVal> ToDictionary<T, TProperty, TVal>(this T o,
params Expression<Func<T, TProperty>>[] ignoreProperties)
{
return o.ToDictionary<TVal>(ignoreProperties.Select(e => o.GetPropertyInfo(e)).Select(propInfo => propInfo.Name).ToArray());
@@ -258,7 +258,7 @@ namespace Umbraco.Core
/// <param name="o"></param>
/// <param name="ignoreProperties">Properties to ignore</param>
/// <returns></returns>
public static IDictionary<string, TVal> ToDictionary<TVal>(this object o, params string[] ignoreProperties)
internal static IDictionary<string, TVal> ToDictionary<TVal>(this object o, params string[] ignoreProperties)
{
if (o != null)
{
@@ -277,7 +277,7 @@ namespace Umbraco.Core
return new Dictionary<string, TVal>();
}
public static string ToDebugString(this object obj, int levels = 0)
internal static string ToDebugString(this object obj, int levels = 0)
{
if (obj == null) return "{null}";
try
@@ -346,7 +346,7 @@ namespace Umbraco.Core
/// <param name="value"></param>
/// <param name="type"></param>
/// <returns></returns>
public static Attempt<string> TryConvertToXmlString(this object value, Type type)
internal static Attempt<string> TryConvertToXmlString(this object value, Type type)
{
try
{
@@ -365,7 +365,7 @@ namespace Umbraco.Core
/// <param name="value"></param>
/// <param name="type">The Type can only be a primitive type or Guid and byte[] otherwise an exception is thrown</param>
/// <returns></returns>
public static string ToXmlString(this object value, Type type)
internal static string ToXmlString(this object value, Type type)
{
if (type == typeof(string)) return ((string)value).IsNullOrWhiteSpace() ? "" : (string)value;
if (type == typeof(bool)) return XmlConvert.ToString((bool)value);
@@ -45,7 +45,7 @@ namespace Umbraco.Core.ObjectResolution
/// <summary>
/// Create instances of all of the legacy startup handlers
/// </summary>
public void InstantiateLegacyStartupHanlders()
public void InstantiateLegacyStartupHandlers()
{
//this will instantiate them all
var handlers = _legacyResolver.LegacyStartupHandlers;
@@ -1,3 +1,4 @@
using System;
using System.Web;
using Umbraco.Core.Configuration;
@@ -16,7 +17,12 @@ namespace Umbraco.Core.Persistence
private readonly string _connectionStringName;
private readonly string _connectionString;
private readonly string _providerName;
private static volatile UmbracoDatabase _globalInstance = null;
//very important to have ThreadStatic:
// see: http://issues.umbraco.org/issue/U4-2172
[ThreadStatic]
private static volatile UmbracoDatabase _nonHttpInstance;
private static readonly object Locker = new object();
/// <summary>
@@ -55,29 +61,27 @@ namespace Umbraco.Core.Persistence
//no http context, create the singleton global object
if (HttpContext.Current == null)
{
if (_globalInstance == null)
if (_nonHttpInstance == null)
{
lock (Locker)
{
//double check
if (_globalInstance == null)
if (_nonHttpInstance == null)
{
_globalInstance = string.IsNullOrEmpty(_connectionString) == false &&
string.IsNullOrEmpty(_providerName) == false
_nonHttpInstance = string.IsNullOrEmpty(_connectionString) == false && string.IsNullOrEmpty(_providerName) == false
? new UmbracoDatabase(_connectionString, _providerName)
: new UmbracoDatabase(_connectionStringName);
}
}
}
return _globalInstance;
return _nonHttpInstance;
}
//we have an http context, so only create one per request
if (!HttpContext.Current.Items.Contains(typeof(DefaultDatabaseFactory)))
if (HttpContext.Current.Items.Contains(typeof(DefaultDatabaseFactory)) == false)
{
HttpContext.Current.Items.Add(typeof (DefaultDatabaseFactory),
string.IsNullOrEmpty(_connectionString) == false &&
string.IsNullOrEmpty(_providerName) == false
string.IsNullOrEmpty(_connectionString) == false && string.IsNullOrEmpty(_providerName) == false
? new UmbracoDatabase(_connectionString, _providerName)
: new UmbracoDatabase(_connectionStringName));
}
@@ -88,7 +92,7 @@ namespace Umbraco.Core.Persistence
{
if (HttpContext.Current == null)
{
_globalInstance.Dispose();
_nonHttpInstance.Dispose();
}
else
{
@@ -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
};
//on initial construction we don't want to have dirty properties tracked
// http://issues.umbraco.org/issue/U4-1946
@@ -11,6 +11,8 @@ namespace Umbraco.Core.Persistence.Factories
private readonly IContentTypeComposition _contentType;
private readonly Guid _version;
private readonly int _id;
private readonly DateTime _createDate;
private readonly DateTime _updateDate;
public PropertyFactory(IContentTypeComposition contentType, Guid version, int id)
{
@@ -19,6 +21,15 @@ namespace Umbraco.Core.Persistence.Factories
_id = id;
}
public PropertyFactory(IContentTypeComposition contentType, Guid version, int id, DateTime createDate, DateTime updateDate)
{
_contentType = contentType;
_version = version;
_id = id;
_createDate = createDate;
_updateDate = updateDate;
}
#region Implementation of IEntityFactory<IContent,PropertyDataDto>
public IEnumerable<Property> BuildEntity(IEnumerable<PropertyDataDto> dtos)
@@ -34,6 +45,8 @@ namespace Umbraco.Core.Persistence.Factories
propertyDataDto.VersionId.Value,
propertyDataDto.Id);
//on initial construction we don't want to have dirty properties tracked
property.CreateDate = _createDate;
property.UpdateDate = _updateDate;
// http://issues.umbraco.org/issue/U4-1946
property.ResetDirtyProperties(false);
properties.Add(property);
@@ -9,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)
@@ -58,7 +67,9 @@ namespace Umbraco.Core.Persistence.Factories
Mandatory = typeDto.Mandatory,
SortOrder = typeDto.SortOrder,
ValidationRegExp = typeDto.ValidationRegExp,
PropertyGroupId = new Lazy<int>(() => tempGroupDto.Id)
PropertyGroupId = new Lazy<int>(() => tempGroupDto.Id),
CreateDate = _createDate,
UpdateDate = _updateDate
};
//on initial construction we don't want to have dirty properties tracked
// http://issues.umbraco.org/issue/U4-1946
@@ -55,27 +55,29 @@ 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)},
{41, typeof (ServerRegistrationDto)}
};
#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);
@@ -401,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);
@@ -437,7 +455,7 @@ 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);
//on initial construction we don't want to have dirty properties tracked
// http://issues.umbraco.org/issue/U4-1946
@@ -445,7 +463,7 @@ namespace Umbraco.Core.Persistence.Repositories
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("*")
@@ -456,7 +474,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);
@@ -326,7 +326,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("*")
@@ -340,12 +340,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("*")
@@ -371,7 +371,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
@@ -51,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())
@@ -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);
}
}
@@ -1,13 +0,0 @@
using Umbraco.Core.Models;
namespace Umbraco.Core.Persistence.Repositories
{
/// <summary>
/// Defines the Macro Repository, which exposes CRUD operations for <see cref="IMacro"/>
/// </summary>
/// <remarks>Uses string Alias as the Id type</remarks>
internal interface IMacroRepository : IRepositoryQueryable<string, IMacro>
{
}
}
@@ -1,132 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Umbraco.Core.IO;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.Caching;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.UnitOfWork;
using Umbraco.Core.Serialization;
namespace Umbraco.Core.Persistence.Repositories
{
/// <summary>
/// Represents the Macro Repository
/// </summary>
internal class MacroRepository : RepositoryBase<string, IMacro>, IMacroRepository
{
private IFileSystem _fileSystem;
private SerializationService _serializationService;
public MacroRepository(IUnitOfWork work)
: base(work)
{
EnsureDependencies();
}
public MacroRepository(IUnitOfWork work, IRepositoryCacheProvider cache)
: base(work, cache)
{
EnsureDependencies();
}
private void EnsureDependencies()
{
_fileSystem = new PhysicalFileSystem("~/App_Data/Macros");
var jsonSerializer = new JsonNetSerializer();
_serializationService = new SerializationService(jsonSerializer);
}
#region Overrides of RepositoryBase<string,IMacro>
protected override IMacro PerformGet(string id)
{
var name = string.Concat(id, ".macro");
Stream file = _fileSystem.OpenFile(name);
var o = _serializationService.FromStream(file, typeof(Macro));
var macro = o as IMacro;
//on initial construction we don't want to have dirty properties tracked
// http://issues.umbraco.org/issue/U4-1946
if(macro != null)
((Entity)macro).ResetDirtyProperties(false);
return macro;
}
protected override IEnumerable<IMacro> PerformGetAll(params string[] ids)
{
if (ids.Any())
{
foreach (var id in ids)
{
yield return Get(id);
}
}
else
{
var files = _fileSystem.GetFiles("", "*.macro");
foreach (var file in files)
{
yield return Get(file.Replace(".macro", ""));
}
}
}
protected override IEnumerable<IMacro> PerformGetByQuery(IQuery<IMacro> query)
{
throw new NotImplementedException();
}
protected override bool PerformExists(string id)
{
var name = string.Concat(id, ".macro");
return _fileSystem.FileExists(name);
}
protected override int PerformCount(IQuery<IMacro> query)
{
var files = _fileSystem.GetFiles("", "*.macro");
return files.Count();
}
#endregion
#region Overrides of IUnitOfWorkRepository
protected override void PersistNewItem(IMacro entity)
{
((Macro)entity).AddingEntity();
var name = string.Concat(entity.Alias, ".macro");
var json = _serializationService.ToStream(entity);
_fileSystem.AddFile(name, json.ResultStream, true);
((ICanBeDirty)entity).ResetDirtyProperties();
}
protected override void PersistUpdatedItem(IMacro entity)
{
((Macro)entity).UpdatingEntity();
var name = string.Concat(entity.Alias, ".macro");
var json = _serializationService.ToStream(entity);
_fileSystem.AddFile(name, json.ResultStream, true);
((ICanBeDirty)entity).ResetDirtyProperties();
}
protected override void PersistDeletedItem(IMacro entity)
{
var name = string.Concat(entity.Alias, ".macro");
if (_fileSystem.FileExists(name))
{
_fileSystem.DeleteFile(name);
}
}
#endregion
}
}
@@ -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);
//on initial construction we don't want to have dirty properties tracked
// http://issues.umbraco.org/issue/U4-1946
@@ -120,6 +120,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",
@@ -157,7 +159,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);
//on initial construction we don't want to have dirty properties tracked
// http://issues.umbraco.org/issue/U4-1946
@@ -342,7 +344,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("*")
@@ -353,7 +355,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);
@@ -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)
@@ -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
};
@@ -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);
@@ -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
};
@@ -75,7 +74,7 @@ namespace Umbraco.Core.Persistence.Repositories
}
else
{
var files = FileSystem.GetFiles("", "*");
var files = FindAllFiles("");
foreach (var file in files)
{
yield return Get(file);
@@ -191,6 +191,8 @@ namespace Umbraco.Core.Persistence.Repositories
//Save to db
var template = entity as Template;
template.AddingEntity();
var factory = new TemplateFactory(NodeObjectTypeId);
var dto = factory.BuildDto(template);
@@ -259,6 +261,7 @@ namespace Umbraco.Core.Persistence.Repositories
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);
@@ -76,13 +76,6 @@ namespace Umbraco.Core.Persistence
InMemoryCacheProvider.Current);
}
internal virtual IMacroRepository CreateMacroRepository(IUnitOfWork uow)
{
return new MacroRepository(
uow,
InMemoryCacheProvider.Current);
}
public virtual IMediaRepository CreateMediaRepository(IDatabaseUnitOfWork uow)
{
return new MediaRepository(
@@ -1,6 +1,7 @@
using System;
using System.Data;
using System.Data.Common;
using StackExchange.Profiling;
using Umbraco.Core.Logging;
namespace Umbraco.Core.Persistence
@@ -40,6 +41,13 @@ namespace Umbraco.Core.Persistence
{
}
public override IDbConnection OnConnectionOpened(IDbConnection connection)
{
// wrap the connection with a profiling connection that tracks timings
return new StackExchange.Profiling.Data.ProfiledDbConnection(connection as DbConnection, MiniProfiler.Current);
}
public override void OnException(Exception x)
{
LogHelper.Info<UmbracoDatabase>(x.StackTrace);
-9
View File
@@ -487,15 +487,6 @@ namespace Umbraco.Core
return ResolveTypes<IAction>();
}
/// <summary>
/// Returns all available IMacroPropertyTypes in application
/// </summary>
/// <returns></returns>
internal IEnumerable<Type> ResolveMacroPropertyTypes()
{
return ResolveTypes<IMacroPropertyType>();
}
/// <summary>
/// Returns all mapper types that have a MapperFor attribute defined
/// </summary>
+52
View File
@@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using StackExchange.Profiling;
namespace Umbraco.Core.Profiling
{
public class Profiler
{
private static Profiler _instance;
private Profiler()
{
}
public string Render()
{
return MiniProfiler.RenderIncludes().ToString();
}
public IDisposable Step(string name)
{
return MiniProfiler.Current.Step(name);
}
public void Start()
{
MiniProfiler.Start();
}
public void Stop()
{
MiniProfiler.Stop();
}
public static Profiler Instance
{
get
{
if (_instance == null)
{
_instance = new Profiler();
}
return _instance;
}
}
}
}
+3 -2
View File
@@ -29,11 +29,11 @@ using System.Security.Permissions;
[assembly: InternalsVisibleTo("businesslogic")]
[assembly: InternalsVisibleTo("cms")]
[assembly: InternalsVisibleTo("umbraco.editorControls")]
[assembly: InternalsVisibleTo("umbraco.webservices")]
[assembly: InternalsVisibleTo("umbraco.datalayer")]
[assembly: InternalsVisibleTo("umbraco.MacroEngines")]
[assembly: InternalsVisibleTo("umbraco.editorControls")]
[assembly: InternalsVisibleTo("umbraco.webservices")]
[assembly: InternalsVisibleTo("Umbraco.Tests")]
[assembly: InternalsVisibleTo("Umbraco.Core")]
[assembly: InternalsVisibleTo("Umbraco.Web")]
@@ -41,4 +41,5 @@ using System.Security.Permissions;
[assembly: InternalsVisibleTo("UmbracoExamine")]
[assembly: InternalsVisibleTo("Umbraco.Courier.Persistence")]
[assembly: InternalsVisibleTo("Concorde.Sync")]
[assembly: InternalsVisibleTo("Concorde.Sync")]
[assembly: InternalsVisibleTo("Umbraco.Belle")]
+11 -29
View File
@@ -22,37 +22,14 @@ namespace Umbraco.Core
/// </remarks>
internal class PublishedContentHelper : ApplicationEventHandler
{
#region event handlers to ensure that the cache is cleared when content types change
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
ContentTypeService.SavedContentType += ContentTypeServiceSavedContentType;
ContentTypeService.SavedMediaType += ContentTypeServiceSavedMediaType;
ContentTypeService.DeletedContentType += ContentTypeServiceDeletedContentType;
ContentTypeService.DeletedMediaType += ContentTypeServiceDeletedMediaType;
}
static void ContentTypeServiceDeletedMediaType(IContentTypeService sender, Events.DeleteEventArgs<Models.IMediaType> e)
/// <summary>
/// Used to invalidate the cache from the ICacherefresher
/// </summary>
internal static void ClearPropertyTypeCache()
{
PropertyTypeCache.Clear();
}
static void ContentTypeServiceDeletedContentType(IContentTypeService sender, Events.DeleteEventArgs<Models.IContentType> e)
{
PropertyTypeCache.Clear();
}
static void ContentTypeServiceSavedMediaType(IContentTypeService sender, Events.SaveEventArgs<Models.IMediaType> e)
{
PropertyTypeCache.Clear();
}
static void ContentTypeServiceSavedContentType(IContentTypeService sender, Events.SaveEventArgs<Models.IContentType> e)
{
PropertyTypeCache.Clear();
}
#endregion
/// <summary>
/// This callback is used only for unit tests which enables us to return any data we want and not rely on having the data in a database
/// </summary>
@@ -77,11 +54,16 @@ namespace Umbraco.Core
{
var result = applicationContext.Services.ContentTypeService.GetContentType(docTypeAlias);
if (result == null) return Guid.Empty;
if (!result.PropertyTypes.Any(x => x.Alias.InvariantEquals(propertyAlias)))
//SD: we need to check for 'any' here because the collection is backed by KeyValuePair which is a struct
// and can never be null so FirstOrDefault doesn't actually work. Have told Seb and Morten about thsi
// issue.
if (!result.CompositionPropertyTypes.Any(x => x.Alias.InvariantEquals(propertyAlias)))
{
return Guid.Empty;
}
var property = result.PropertyTypes.FirstOrDefault(x => x.Alias.InvariantEquals(propertyAlias));
var property = result.CompositionPropertyTypes.FirstOrDefault(x => x.Alias.InvariantEquals(propertyAlias));
//as per above, this will never be null but we'll keep the check here anyways.
if (property == null) return Guid.Empty;
return property.DataTypeId;
});
File diff suppressed because it is too large Load Diff
+81 -44
View File
@@ -144,7 +144,7 @@ namespace Umbraco.Core.Services
/// if they are required to be updated.
/// </summary>
/// <param name="contentTypes">A tuple of a content type and a boolean indicating if it is new (HasIdentity was false before committing)</param>
private void UpdateContentXmlStructure(params IContentType[] contentTypes)
private void UpdateContentXmlStructure(params IContentTypeBase[] contentTypes)
{
var toUpdate = new List<IContentTypeBase>();
@@ -152,43 +152,71 @@ namespace Umbraco.Core.Services
foreach (var contentType in contentTypes)
{
//we need to determine if we need to refresh the xml content in the database. This is to be done when:
// - the item is not new (already existed in the db)
// - a content type changes it's alias
// - if a content type has it's property removed
// - the item is not new (already existed in the db) AND
// - a content type changes it's alias OR
// - if a content type has it's property removed OR
// - if a content type has a property whose alias has changed
//here we need to check if the alias of the content type changed or if one of the properties was removed.
var dirty = contentType as IRememberBeingDirty;
if (dirty != null
&& !dirty.WasPropertyDirty("HasIdentity") //ensure it's now 'new'
&& (dirty.WasPropertyDirty("Alias") || dirty.WasPropertyDirty("HasPropertyTypeBeenRemoved")))
if (dirty == null) continue;
//check if any property types have changed their aliases (and not new property types)
var hasAnyPropertiesChangedAlias = contentType.PropertyTypes.Any(propType =>
{
var dirtyProperty = propType as IRememberBeingDirty;
if (dirtyProperty == null) return false;
return dirtyProperty.WasPropertyDirty("HasIdentity") == false //ensure it's not 'new'
&& dirtyProperty.WasPropertyDirty("Alias"); //alias has changed
});
if (dirty.WasPropertyDirty("HasIdentity") == false //ensure it's not 'new'
&& (dirty.WasPropertyDirty("Alias") || dirty.WasPropertyDirty("HasPropertyTypeBeenRemoved") || hasAnyPropertiesChangedAlias))
{
//if the alias was changed then we only need to update the xml structures for content of the current content type.
//if a property was deleted then we need to update the xml structures for any content of the current content type
// and any of the content type's child content types.
if (dirty.WasPropertyDirty("Alias") && !dirty.WasPropertyDirty("HasPropertyTypeBeenRemoved"))
//If the alias was changed then we only need to update the xml structures for content of the current content type.
//If a property was deleted or a property alias was changed then we need to update the xml structures for any
// content of the current content type and any of the content type's child content types.
if (dirty.WasPropertyDirty("Alias")
&& dirty.WasPropertyDirty("HasPropertyTypeBeenRemoved") == false && hasAnyPropertiesChangedAlias == false)
{
//if only the alias changed then only update the current content type
toUpdate.Add(contentType);
}
else
{
//if a property was deleted (and maybe the alias changed too), then update all content of the current content type
//if a property was deleted or alias changed, then update all content of the current content type
// and all of it's desscendant doc types.
toUpdate.AddRange(contentType.DescendantsAndSelf());
}
}
}
}
var typedContentService = _contentService as ContentService;
if (typedContentService != null && toUpdate.Any())
if (toUpdate.Any())
{
typedContentService.RePublishAll(toUpdate.Select(x => x.Id).ToArray());
var firstType = toUpdate.First();
//if it is a content type then call the rebuilding methods or content
if (firstType is IContentType)
{
var typedContentService = _contentService as ContentService;
if (typedContentService != null)
{
typedContentService.RePublishAll(toUpdate.Select(x => x.Id).ToArray());
}
else
{
//this should never occur, the content service should always be typed but we'll check anyways.
_contentService.RePublishAll();
}
}
else if (firstType is IMediaType)
{
//if it is a media type then call the rebuilding methods for media
var typedContentService = _mediaService as MediaService;
if (typedContentService != null)
{
typedContentService.RebuildXmlStructures(toUpdate.Select(x => x.Id).ToArray());
}
}
}
else if (toUpdate.Any())
{
//this should never occur, the content service should always be typed but we'll check anyways.
_contentService.RePublishAll();
}
}
@@ -246,7 +274,7 @@ namespace Umbraco.Core.Services
uow.Commit();
}
UpdateContentXmlStructure(asArray);
UpdateContentXmlStructure(asArray.Cast<IContentTypeBase>().ToArray());
}
SavedContentType.RaiseEvent(new SaveEventArgs<IContentType>(asArray, false), this);
Audit.Add(AuditTypes.Save, string.Format("Save ContentTypes performed by user"), userId, -1);
@@ -400,17 +428,22 @@ namespace Umbraco.Core.Services
{
if (SavingMediaType.IsRaisedEventCancelled(new SaveEventArgs<IMediaType>(mediaType), this))
return;
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
{
mediaType.CreatorId = userId;
repository.AddOrUpdate(mediaType);
uow.Commit();
SavedMediaType.RaiseEvent(new SaveEventArgs<IMediaType>(mediaType, false), this);
}
using (new WriteLock(Locker))
{
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
{
mediaType.CreatorId = userId;
repository.AddOrUpdate(mediaType);
uow.Commit();
}
UpdateContentXmlStructure(mediaType);
}
SavedMediaType.RaiseEvent(new SaveEventArgs<IMediaType>(mediaType, false), this);
Audit.Add(AuditTypes.Save, string.Format("Save MediaType performed by user"), userId, mediaType.Id);
}
@@ -426,22 +459,26 @@ namespace Umbraco.Core.Services
if (SavingMediaType.IsRaisedEventCancelled(new SaveEventArgs<IMediaType>(asArray), this))
return;
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
{
using (new WriteLock(Locker))
{
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateMediaTypeRepository(uow))
{
foreach (var mediaType in asArray)
{
mediaType.CreatorId = userId;
repository.AddOrUpdate(mediaType);
}
foreach (var mediaType in asArray)
{
mediaType.CreatorId = userId;
repository.AddOrUpdate(mediaType);
}
//save it all in one go
uow.Commit();
//save it all in one go
uow.Commit();
}
SavedMediaType.RaiseEvent(new SaveEventArgs<IMediaType>(asArray, false), this);
}
UpdateContentXmlStructure(asArray.Cast<IContentTypeBase>().ToArray());
}
SavedMediaType.RaiseEvent(new SaveEventArgs<IMediaType>(asArray, false), this);
Audit.Add(AuditTypes.Save, string.Format("Save MediaTypes performed by user"), userId, -1);
}
+1 -1
View File
@@ -10,7 +10,7 @@ using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Services
{
internal class EntityService : IService
public class EntityService : IService
{
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
private readonly RepositoryFactory _repositoryFactory;
@@ -1,54 +0,0 @@
using System.Collections.Generic;
using Umbraco.Core.Models;
namespace Umbraco.Core.Services
{
/// <summary>
/// Defines the ContentService, which is an easy access to operations involving <see cref="IMacro"/>
/// </summary>
internal interface IMacroService : IService
{
//TODO Possibly create import macro method and ToXml?
/// <summary>
/// Gets an <see cref="IMacro"/> object by its alias
/// </summary>
/// <param name="alias">Alias to retrieve an <see cref="IMacro"/> for</param>
/// <returns>An <see cref="IMacro"/> object</returns>
IMacro GetByAlias(string alias);
/// <summary>
/// Gets a list all available <see cref="IMacro"/> objects
/// </summary>
/// <param name="aliases">Optional array of aliases to limit the results</param>
/// <returns>An enumerable list of <see cref="IMacro"/> objects</returns>
IEnumerable<IMacro> GetAll(params string[] aliases);
/// <summary>
/// Deletes an <see cref="IMacro"/>
/// </summary>
/// <param name="macro"><see cref="IMacro"/> to delete</param>
/// <param name="userId">Optional id of the user deleting the macro</param>
void Delete(IMacro macro, int userId = 0);
/// <summary>
/// Saves an <see cref="IMacro"/>
/// </summary>
/// <param name="macro"><see cref="IMacro"/> to save</param>
/// <param name="userId">Optional id of the user saving the macro</param>
void Save(IMacro macro, int userId = 0);
/// <summary>
/// Gets a list all available <see cref="IMacroPropertyType"/> plugins
/// </summary>
/// <returns>An enumerable list of <see cref="IMacroPropertyType"/> objects</returns>
IEnumerable<IMacroPropertyType> GetMacroPropertyTypes();
/// <summary>
/// Gets an <see cref="IMacroPropertyType"/> by its alias
/// </summary>
/// <param name="alias">Alias to retrieve an <see cref="IMacroPropertyType"/> for</param>
/// <returns>An <see cref="IMacroPropertyType"/> object</returns>
IMacroPropertyType GetMacroPropertyTypeByAlias(string alias);
}
}
-168
View File
@@ -1,168 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Auditing;
using Umbraco.Core.Events;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Services
{
/// <summary>
/// Represents the Macro Service, which is an easy access to operations involving <see cref="IMacro"/>
/// </summary>
internal class MacroService : IMacroService
{
private readonly RepositoryFactory _repositoryFactory;
private readonly IUnitOfWorkProvider _uowProvider;
public MacroService()
: this(new RepositoryFactory())
{
}
public MacroService(RepositoryFactory repositoryFactory)
: this(new FileUnitOfWorkProvider(), repositoryFactory)
{
}
public MacroService(IUnitOfWorkProvider provider)
: this(provider, new RepositoryFactory())
{
}
public MacroService(IUnitOfWorkProvider provider, RepositoryFactory repositoryFactory) : this(provider, repositoryFactory, false)
{
}
public MacroService(IUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, bool ensureCachedMacros)
{
_uowProvider = provider;
_repositoryFactory = repositoryFactory;
if(ensureCachedMacros)
EnsureMacroCache();
}
/// <summary>
/// Ensures the macro cache by getting all macros
/// from the repository and thus caching them.
/// </summary>
private void EnsureMacroCache()
{
IEnumerable<IMacro> macros = GetAll();
}
/// <summary>
/// Gets an <see cref="IMacro"/> object by its alias
/// </summary>
/// <param name="alias">Alias to retrieve an <see cref="IMacro"/> for</param>
/// <returns>An <see cref="IMacro"/> object</returns>
public IMacro GetByAlias(string alias)
{
using (var repository = _repositoryFactory.CreateMacroRepository(_uowProvider.GetUnitOfWork()))
{
return repository.Get(alias);
}
}
/// <summary>
/// Gets a list all available <see cref="IMacro"/> objects
/// </summary>
/// <param name="aliases">Optional array of aliases to limit the results</param>
/// <returns>An enumerable list of <see cref="IMacro"/> objects</returns>
public IEnumerable<IMacro> GetAll(params string[] aliases)
{
using (var repository = _repositoryFactory.CreateMacroRepository(_uowProvider.GetUnitOfWork()))
{
return repository.GetAll(aliases);
}
}
/// <summary>
/// Deletes an <see cref="IMacro"/>
/// </summary>
/// <param name="macro"><see cref="IMacro"/> to delete</param>
/// <param name="userId">Optional id of the user deleting the macro</param>
public void Delete(IMacro macro, int userId = 0)
{
if (Deleting.IsRaisedEventCancelled(new DeleteEventArgs<IMacro>(macro), this))
return;
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateMacroRepository(uow))
{
repository.Delete(macro);
uow.Commit();
Deleted.RaiseEvent(new DeleteEventArgs<IMacro>(macro, false), this);
}
Audit.Add(AuditTypes.Delete, "Delete Macro performed by user", userId, -1);
}
/// <summary>
/// Saves an <see cref="IMacro"/>
/// </summary>
/// <param name="macro"><see cref="IMacro"/> to save</param>
/// <param name="userId">Optional Id of the user deleting the macro</param>
public void Save(IMacro macro, int userId = 0)
{
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMacro>(macro), this))
return;
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateMacroRepository(uow))
{
repository.AddOrUpdate(macro);
uow.Commit();
Saved.RaiseEvent(new SaveEventArgs<IMacro>(macro, false), this);
}
Audit.Add(AuditTypes.Save, "Save Macro performed by user", userId, -1);
}
/// <summary>
/// Gets a list all available <see cref="IMacroPropertyType"/> plugins
/// </summary>
/// <returns>An enumerable list of <see cref="IMacroPropertyType"/> objects</returns>
public IEnumerable<IMacroPropertyType> GetMacroPropertyTypes()
{
return MacroPropertyTypeResolver.Current.MacroPropertyTypes;
}
/// <summary>
/// Gets an <see cref="IMacroPropertyType"/> by its alias
/// </summary>
/// <param name="alias">Alias to retrieve an <see cref="IMacroPropertyType"/> for</param>
/// <returns>An <see cref="IMacroPropertyType"/> object</returns>
public IMacroPropertyType GetMacroPropertyTypeByAlias(string alias)
{
return MacroPropertyTypeResolver.Current.MacroPropertyTypes.FirstOrDefault(x => x.Alias == alias);
}
#region Event Handlers
/// <summary>
/// Occurs before Delete
/// </summary>
public static event TypedEventHandler<IMacroService, DeleteEventArgs<IMacro>> Deleting;
/// <summary>
/// Occurs after Delete
/// </summary>
public static event TypedEventHandler<IMacroService, DeleteEventArgs<IMacro>> Deleted;
/// <summary>
/// Occurs before Save
/// </summary>
public static event TypedEventHandler<IMacroService, SaveEventArgs<IMacro>> Saving;
/// <summary>
/// Occurs after Save
/// </summary>
public static event TypedEventHandler<IMacroService, SaveEventArgs<IMacro>> Saved;
#endregion
}
}
+78 -5
View File
@@ -446,7 +446,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))
@@ -479,8 +479,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)
{
@@ -542,11 +542,11 @@ namespace Umbraco.Core.Services
}
/// <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>
@@ -555,6 +555,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))
{
@@ -691,6 +698,72 @@ namespace Umbraco.Core.Services
Audit.Add(AuditTypes.Save, "Save Media items performed by user", userId, -1);
}
/// <summary>
/// Rebuilds all xml content in the cmsContentXml table for all media
/// </summary>
/// <param name="contentTypeIds">
/// Only rebuild the xml structures for the content type ids passed in, if none then rebuilds the structures
/// for all media
/// </param>
/// <returns>True if publishing succeeded, otherwise False</returns>
internal void RebuildXmlStructures(params int[] contentTypeIds)
{
using (new WriteLock(Locker))
{
var list = new List<IMedia>();
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateContentRepository(uow))
{
if (contentTypeIds.Any() == false)
{
//Remove all media records from the cmsContentXml table (DO NOT REMOVE Content/Members!)
uow.Database.Execute(@"DELETE FROM cmsContentXml WHERE nodeId IN
(SELECT DISTINCT cmsContentXml.nodeId FROM cmsContentXml
INNER JOIN umbracoNode ON cmsContentXml.nodeId = umbracoNode.id
WHERE nodeObjectType = @nodeObjectType)",
new {nodeObjectType = Constants.ObjectTypes.Media});
// Consider creating a Path query instead of recursive method:
// var query = Query<IContent>.Builder.Where(x => x.Path.StartsWith("-1"));
var rootMedia = GetRootMedia();
foreach (var media in rootMedia)
{
list.Add(media);
list.AddRange(GetDescendants(media));
}
}
else
{
foreach (var id in contentTypeIds)
{
//first we'll clear out the data from the cmsContentXml table for this type
uow.Database.Execute(@"delete from cmsContentXml where nodeId in
(SELECT DISTINCT cmsContentXml.nodeId FROM cmsContentXml
INNER JOIN umbracoNode ON cmsContentXml.nodeId = umbracoNode.id
INNER JOIN cmsContent ON cmsContent.nodeId = umbracoNode.id
WHERE nodeObjectType = @nodeObjectType AND cmsContent.contentType = @contentTypeId)",
new {contentTypeId = id, nodeObjectType = Constants.ObjectTypes.Media});
//now get all media objects of this type and add to the list
list.AddRange(GetMediaOfMediaType(id));
}
}
foreach (var c in list)
{
//generate the xml
var xml = c.ToXml();
//create the dto to insert
var poco = new ContentXmlDto { NodeId = c.Id, Xml = xml.ToString(SaveOptions.None) };
//insert it into the database
uow.Database.Insert(poco);
}
}
Audit.Add(AuditTypes.Publish, "RebuildXmlStructures completed, the xml has been regenerated in the database", 0, -1);
}
}
/// <summary>
/// Updates the Path and Level on a collection of <see cref="IMedia"/> objects
/// based on the Parent's Path and Level.
+54 -35
View File
@@ -65,7 +65,7 @@ namespace Umbraco.Core.Services
select doc;
var contents = ParseDocumentRootXml(roots, parentId);
if(contents.Any())
if (contents.Any())
_contentService.Save(contents, userId);
return contents;
@@ -196,9 +196,21 @@ namespace Umbraco.Core.Services
/// Imports and saves package xml as <see cref="IContentType"/>
/// </summary>
/// <param name="element">Xml to import</param>
/// <param name="userId"></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)
@@ -209,7 +221,7 @@ namespace Umbraco.Core.Services
_importedContentTypes = new Dictionary<string, IContentType>();
var documentTypes = name.Equals("DocumentTypes")
? (from doc in element.Elements("DocumentType") select doc).ToList()
: new List<XElement> {element};
: 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)
@@ -227,22 +239,25 @@ namespace Umbraco.Core.Services
var list = _importedContentTypes.Select(x => x.Value).ToList();
_contentTypeService.Save(list, userId);
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)
if (importStructure)
{
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 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);
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);
}
//Update ContentTypes with a newly added structure/list of allowed children
if(updatedContentTypes.Any())
_contentTypeService.Save(updatedContentTypes, userId);
return list;
}
@@ -342,7 +357,7 @@ namespace Umbraco.Core.Services
private void UpdateContentTypesTabs(IContentType contentType, XElement tabElement)
{
if(tabElement == null)
if (tabElement == null)
return;
var tabs = tabElement.Elements("Tab");
@@ -376,10 +391,10 @@ namespace Umbraco.Core.Services
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)
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));
@@ -388,7 +403,7 @@ namespace Umbraco.Core.Services
var propertyType = new PropertyType(dataTypeDefinition)
{
Alias = property.Element("Alias").Value,
Alias = property.Element("Alias").Value,
Name = property.Element("Name").Value,
Description = property.Element("Description").Value,
Mandatory = property.Element("Mandatory").Value.ToLowerInvariant().Equals("true"),
@@ -423,7 +438,7 @@ namespace Umbraco.Core.Services
if (_importedContentTypes.ContainsKey(alias))
{
var allowedChild = _importedContentTypes[alias];
if(allowedChild == null || allowedChildren.Any(x => x.Alias == alias)) continue;
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++;
@@ -484,7 +499,7 @@ namespace Umbraco.Core.Services
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")};
: new List<XElement> { element.Element("DataType") };
foreach (var dataTypeElement in dataTypeElements)
{
@@ -582,24 +597,26 @@ namespace Umbraco.Core.Services
foreach (XElement tempElement in templateElements)
{
var dependencies = new List<string>();
if (tempElement.Element("Master") != null &&
string.IsNullOrEmpty(tempElement.Element("Master").Value) == false &&
templateElements.Any(x => x.Element("Alias").Value == tempElement.Element("Master").Value))
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(tempElement.Element("Master").Value);
dependencies.Add(elementCopy.Element("Master").Value);
}
else if (tempElement.Element("Master") != null &&
string.IsNullOrEmpty(tempElement.Element("Master").Value) == false &&
templateElements.Any(x => x.Element("Alias").Value == tempElement.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.", tempElement.Element("Alias").Value, tempElement.Element("Master").Value));
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 = tempElement.Element("Alias").Value,
Item = new Lazy<XElement>(() => tempElement),
Alias = elementCopy.Element("Alias").Value,
Item = new Lazy<XElement>(() => elementCopy),
DependsOn = dependencies.ToArray()
};
@@ -617,18 +634,20 @@ namespace Umbraco.Core.Services
var isMasterPage = IsMasterPageSyntax(design);
var path = isMasterPage ? MasterpagePath(alias) : ViewPath(alias);
var template = new Template(path, templateName, alias) { Content = design };
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)
if (masterTemplate != null)
template.MasterTemplateId = new Lazy<int>(() => masterTemplate.Id);
}
templates.Add(template);
}
if(templates.Any())
if (templates.Any())
_fileService.SaveTemplate(templates, userId);
return templates;
@@ -0,0 +1,469 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Services
{
public class RelationService
{
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
private readonly RepositoryFactory _repositoryFactory;
private readonly EntityService _entityService;
public RelationService(IDatabaseUnitOfWorkProvider uowProvider, RepositoryFactory repositoryFactory,
EntityService entityService)
{
_uowProvider = uowProvider;
_repositoryFactory = repositoryFactory;
_entityService = entityService;
}
/// <summary>
/// Gets a <see cref="Relation"/> by its Id
/// </summary>
/// <param name="id">Id of the <see cref="Relation"/></param>
/// <returns>A <see cref="Relation"/> object</returns>
public Relation GetById(int id)
{
using (var repository = _repositoryFactory.CreateRelationRepository(_uowProvider.GetUnitOfWork()))
{
return repository.Get(id);
}
}
/// <summary>
/// Gets a <see cref="RelationType"/> by its Id
/// </summary>
/// <param name="id">Id of the <see cref="RelationType"/></param>
/// <returns>A <see cref="RelationType"/> object</returns>
public RelationType GetRelationTypeById(int id)
{
using (var repository = _repositoryFactory.CreateRelationTypeRepository(_uowProvider.GetUnitOfWork()))
{
return repository.Get(id);
}
}
/// <summary>
/// Gets a <see cref="RelationType"/> by its Alias
/// </summary>
/// <param name="alias">Alias of the <see cref="RelationType"/></param>
/// <returns>A <see cref="RelationType"/> object</returns>
public RelationType GetRelationTypeByAlias(string alias)
{
using (var repository = _repositoryFactory.CreateRelationTypeRepository(_uowProvider.GetUnitOfWork()))
{
var query = new Query<RelationType>().Where(x => x.Alias == alias);
return repository.GetByQuery(query).FirstOrDefault();
}
}
/// <summary>
/// Gets all <see cref="Relation"/> objects
/// </summary>
/// <param name="ids">Optional array of integer ids to return relations for</param>
/// <returns>An enumerable list of <see cref="Relation"/> objects</returns>
public IEnumerable<Relation> GetAllRelations(params int[] ids)
{
using (var repository = _repositoryFactory.CreateRelationRepository(_uowProvider.GetUnitOfWork()))
{
return repository.GetAll(ids);
}
}
/// <summary>
/// Gets all <see cref="Relation"/> objects by their <see cref="RelationType"/>
/// </summary>
/// <param name="relationType"><see cref="RelationType"/> to retrieve Relations for</param>
/// <returns>An enumerable list of <see cref="Relation"/> objects</returns>
public IEnumerable<Relation> GetAllRelationsByRelationType(RelationType relationType)
{
return GetAllRelationsByRelationType(relationType.Id);
}
/// <summary>
/// Gets all <see cref="Relation"/> objects by their <see cref="RelationType"/>'s Id
/// </summary>
/// <param name="relationTypeId">Id of the <see cref="RelationType"/> to retrieve Relations for</param>
/// <returns>An enumerable list of <see cref="Relation"/> objects</returns>
public IEnumerable<Relation> GetAllRelationsByRelationType(int relationTypeId)
{
using (var repository = _repositoryFactory.CreateRelationRepository(_uowProvider.GetUnitOfWork()))
{
var query = new Query<Relation>().Where(x => x.RelationTypeId == relationTypeId);
return repository.GetByQuery(query);
}
}
/// <summary>
/// Gets all <see cref="Relation"/> objects
/// </summary>
/// <param name="ids">Optional array of integer ids to return relationtypes for</param>
/// <returns>An enumerable list of <see cref="RelationType"/> objects</returns>
public IEnumerable<RelationType> GetAllRelationTypes(params int[] ids)
{
using (var repository = _repositoryFactory.CreateRelationTypeRepository(_uowProvider.GetUnitOfWork()))
{
return repository.GetAll(ids);
}
}
/// <summary>
/// Gets a list of <see cref="Relation"/> objects by their parent Id
/// </summary>
/// <param name="id">Id of the parent to retrieve relations for</param>
/// <returns>An enumerable list of <see cref="Relation"/> objects</returns>
public IEnumerable<Relation> GetByParentId(int id)
{
using (var repository = _repositoryFactory.CreateRelationRepository(_uowProvider.GetUnitOfWork()))
{
var query = new Query<Relation>().Where(x => x.ParentId == id);
return repository.GetByQuery(query);
}
}
/// <summary>
/// Gets a list of <see cref="Relation"/> objects by their child Id
/// </summary>
/// <param name="id">Id of the child to retrieve relations for</param>
/// <returns>An enumerable list of <see cref="Relation"/> objects</returns>
public IEnumerable<Relation> GetByChildId(int id)
{
using (var repository = _repositoryFactory.CreateRelationRepository(_uowProvider.GetUnitOfWork()))
{
var query = new Query<Relation>().Where(x => x.ChildId == id);
return repository.GetByQuery(query);
}
}
/// <summary>
/// Gets a list of <see cref="Relation"/> objects by the Name of the <see cref="RelationType"/>
/// </summary>
/// <param name="relationTypeName">Name of the <see cref="RelationType"/> to retrieve Relations for</param>
/// <returns>An enumerable list of <see cref="Relation"/> objects</returns>
public IEnumerable<Relation> GetByRelationTypeName(string relationTypeName)
{
List<int> relationTypeIds = null;
using (var repository = _repositoryFactory.CreateRelationTypeRepository(_uowProvider.GetUnitOfWork()))
{
var query = new Query<RelationType>().Where(x => x.Name == relationTypeName);
var relationTypes = repository.GetByQuery(query);
if (relationTypes.Any())
{
relationTypeIds = relationTypes.Select(x => x.Id).ToList();
}
}
if (relationTypeIds == null)
return Enumerable.Empty<Relation>();
return GetRelationsByListOfTypeIds(relationTypeIds);
}
/// <summary>
/// Gets a list of <see cref="Relation"/> objects by the Alias of the <see cref="RelationType"/>
/// </summary>
/// <param name="relationTypeAlias">Alias of the <see cref="RelationType"/> to retrieve Relations for</param>
/// <returns>An enumerable list of <see cref="Relation"/> objects</returns>
public IEnumerable<Relation> GetByRelationTypeAlias(string relationTypeAlias)
{
List<int> relationTypeIds = null;
using (var repository = _repositoryFactory.CreateRelationTypeRepository(_uowProvider.GetUnitOfWork()))
{
var query = new Query<RelationType>().Where(x => x.Alias == relationTypeAlias);
var relationTypes = repository.GetByQuery(query);
if (relationTypes.Any())
{
relationTypeIds = relationTypes.Select(x => x.Id).ToList();
}
}
if (relationTypeIds == null)
return Enumerable.Empty<Relation>();
return GetRelationsByListOfTypeIds(relationTypeIds);
}
/// <summary>
/// Gets a list of <see cref="Relation"/> objects by the Id of the <see cref="RelationType"/>
/// </summary>
/// <param name="relationTypeId">Id of the <see cref="RelationType"/> to retrieve Relations for</param>
/// <returns>An enumerable list of <see cref="Relation"/> objects</returns>
public IEnumerable<Relation> GetByRelationTypeId(int relationTypeId)
{
using (var repository = _repositoryFactory.CreateRelationRepository(_uowProvider.GetUnitOfWork()))
{
var query = new Query<Relation>().Where(x => x.RelationTypeId == relationTypeId);
return repository.GetByQuery(query);
}
}
/// <summary>
/// Gets the Child object from a Relation as an <see cref="IUmbracoEntity"/>
/// </summary>
/// <param name="relation">Relation to retrieve child object from</param>
/// <param name="loadBaseType">Optional bool to load the complete object graph when set to <c>False</c></param>
/// <returns>An <see cref="IUmbracoEntity"/></returns>
public IUmbracoEntity GetChildEntityFromRelation(Relation relation, bool loadBaseType = false)
{
var objectType = UmbracoObjectTypesExtensions.GetUmbracoObjectType(relation.RelationType.ChildObjectType);
return _entityService.Get(relation.ChildId, objectType, loadBaseType);
}
/// <summary>
/// Gets the Parent object from a Relation as an <see cref="IUmbracoEntity"/>
/// </summary>
/// <param name="relation">Relation to retrieve parent object from</param>
/// <param name="loadBaseType">Optional bool to load the complete object graph when set to <c>False</c></param>
/// <returns>An <see cref="IUmbracoEntity"/></returns>
public IUmbracoEntity GetParentEntityFromRelation(Relation relation, bool loadBaseType = false)
{
var objectType = UmbracoObjectTypesExtensions.GetUmbracoObjectType(relation.RelationType.ParentObjectType);
return _entityService.Get(relation.ParentId, objectType, loadBaseType);
}
/// <summary>
/// Gets the Parent and Child objects from a Relation as a <see cref="Tuple"/>"/> with <see cref="IUmbracoEntity"/>.
/// </summary>
/// <param name="relation">Relation to retrieve parent and child object from</param>
/// <param name="loadBaseType">Optional bool to load the complete object graph when set to <c>False</c></param>
/// <returns>Returns a Tuple with Parent (item1) and Child (item2)</returns>
public Tuple<IUmbracoEntity, IUmbracoEntity> GetEntitiesFromRelation(Relation relation, bool loadBaseType = false)
{
var childObjectType = UmbracoObjectTypesExtensions.GetUmbracoObjectType(relation.RelationType.ChildObjectType);
var parentObjectType = UmbracoObjectTypesExtensions.GetUmbracoObjectType(relation.RelationType.ParentObjectType);
var child = _entityService.Get(relation.ChildId, childObjectType, loadBaseType);
var parent = _entityService.Get(relation.ParentId, parentObjectType, loadBaseType);
return new Tuple<IUmbracoEntity, IUmbracoEntity>(parent, child);
}
/// <summary>
/// Gets the Child objects from a list of Relations as a list of <see cref="IUmbracoEntity"/> objects.
/// </summary>
/// <param name="relations">List of relations to retrieve child objects from</param>
/// <param name="loadBaseType">Optional bool to load the complete object graph when set to <c>False</c></param>
/// <returns>An enumerable list of <see cref="IUmbracoEntity"/></returns>
public IEnumerable<IUmbracoEntity> GetChildEntitiesFromRelations(IEnumerable<Relation> relations, bool loadBaseType = false)
{
foreach (var relation in relations)
{
var objectType = UmbracoObjectTypesExtensions.GetUmbracoObjectType(relation.RelationType.ChildObjectType);
yield return _entityService.Get(relation.ChildId, objectType, loadBaseType);
}
}
/// <summary>
/// Gets the Parent objects from a list of Relations as a list of <see cref="IUmbracoEntity"/> objects.
/// </summary>
/// <param name="relations">List of relations to retrieve parent objects from</param>
/// <param name="loadBaseType">Optional bool to load the complete object graph when set to <c>False</c></param>
/// <returns>An enumerable list of <see cref="IUmbracoEntity"/></returns>
public IEnumerable<IUmbracoEntity> GetParentEntitiesFromRelations(IEnumerable<Relation> relations,
bool loadBaseType = false)
{
foreach (var relation in relations)
{
var objectType = UmbracoObjectTypesExtensions.GetUmbracoObjectType(relation.RelationType.ParentObjectType);
yield return _entityService.Get(relation.ParentId, objectType, loadBaseType);
}
}
/// <summary>
/// Gets the Parent and Child objects from a list of Relations as a list of <see cref="IUmbracoEntity"/> objects.
/// </summary>
/// <param name="relations">List of relations to retrieve parent and child objects from</param>
/// <param name="loadBaseType">Optional bool to load the complete object graph when set to <c>False</c></param>
/// <returns>An enumerable list of <see cref="Tuple"/> with <see cref="IUmbracoEntity"/></returns>
public IEnumerable<Tuple<IUmbracoEntity, IUmbracoEntity>> GetEntitiesFromRelations(
IEnumerable<Relation> relations,
bool loadBaseType = false)
{
foreach (var relation in relations)
{
var childObjectType = UmbracoObjectTypesExtensions.GetUmbracoObjectType(relation.RelationType.ChildObjectType);
var parentObjectType = UmbracoObjectTypesExtensions.GetUmbracoObjectType(relation.RelationType.ParentObjectType);
var child = _entityService.Get(relation.ChildId, childObjectType, loadBaseType);
var parent = _entityService.Get(relation.ParentId, parentObjectType, loadBaseType);
yield return new Tuple<IUmbracoEntity, IUmbracoEntity>(parent, child);
}
}
/// <summary>
/// Relates two objects that are based on the <see cref="IUmbracoEntity"/> interface.
/// </summary>
/// <param name="parent">Parent entity</param>
/// <param name="child">Child entity</param>
/// <param name="relationType">The type of relation to create</param>
/// <returns>The created <see cref="Relation"/></returns>
public Relation Relate(IUmbracoEntity parent, IUmbracoEntity child, RelationType relationType)
{
//Ensure that the RelationType has an indentity before using it to relate two entities
if(relationType.HasIdentity == false)
Save(relationType);
var relation = new Relation(parent.Id, child.Id, relationType);
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateRelationRepository(uow))
{
repository.AddOrUpdate(relation);
uow.Commit();
return relation;
}
}
/// <summary>
/// Relates two objects that are based on the <see cref="IUmbracoEntity"/> interface.
/// </summary>
/// <param name="parent">Parent entity</param>
/// <param name="child">Child entity</param>
/// <param name="relationTypeAlias">Alias of the type of relation to create</param>
/// <returns>The created <see cref="Relation"/></returns>
public Relation Relate(IUmbracoEntity parent, IUmbracoEntity child, string relationTypeAlias)
{
var relationType = GetRelationTypeByAlias(relationTypeAlias);
if(relationType == null || string.IsNullOrEmpty(relationType.Alias))
throw new ArgumentNullException(string.Format("No RelationType with Alias '{0}' exists.", relationTypeAlias));
var relation = new Relation(parent.Id, child.Id, relationType);
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateRelationRepository(uow))
{
repository.AddOrUpdate(relation);
uow.Commit();
return relation;
}
}
/// <summary>
/// Checks whether any relations exists for the passed in <see cref="RelationType"/>.
/// </summary>
/// <param name="relationType"><see cref="RelationType"/> to check for relations</param>
/// <returns>Returns <c>True</c> if any relations exists for the given <see cref="RelationType"/>, otherwise <c>False</c></returns>
public bool HasRelations(RelationType relationType)
{
using (var repository = _repositoryFactory.CreateRelationRepository(_uowProvider.GetUnitOfWork()))
{
var query = new Query<Relation>().Where(x => x.RelationTypeId == relationType.Id);
return repository.GetByQuery(query).Any();
}
}
/// <summary>
/// Checks whether any relations exists for the passed in Id.
/// </summary>
/// <param name="id">Id of an object to check relations for</param>
/// <returns>Returns <c>True</c> if any relations exists with the given Id, otherwise <c>False</c></returns>
public bool IsRelated(int id)
{
using (var repository = _repositoryFactory.CreateRelationRepository(_uowProvider.GetUnitOfWork()))
{
var query = new Query<Relation>().Where(x => x.ParentId == id || x.ChildId == id);
return repository.GetByQuery(query).Any();
}
}
/// <summary>
/// Saves a <see cref="Relation"/>
/// </summary>
/// <param name="relation">Relation to save</param>
public void Save(Relation relation)
{
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateRelationRepository(uow))
{
repository.AddOrUpdate(relation);
uow.Commit();
}
}
/// <summary>
/// Saves a <see cref="RelationType"/>
/// </summary>
/// <param name="relationType">RelationType to Save</param>
public void Save(RelationType relationType)
{
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateRelationTypeRepository(uow))
{
repository.AddOrUpdate(relationType);
uow.Commit();
}
}
/// <summary>
/// Deletes a <see cref="Relation"/>
/// </summary>
/// <param name="relation">Relation to Delete</param>
public void Delete(Relation relation)
{
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateRelationRepository(uow))
{
repository.Delete(relation);
uow.Commit();
}
}
/// <summary>
/// Deletes a <see cref="RelationType"/>
/// </summary>
/// <param name="relationType">RelationType to Delete</param>
public void Delete(RelationType relationType)
{
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateRelationTypeRepository(uow))
{
repository.Delete(relationType);
uow.Commit();
}
}
/// <summary>
/// Deletes all <see cref="Relation"/> objects based on the passed in <see cref="RelationType"/>
/// </summary>
/// <param name="relationType"><see cref="RelationType"/> to Delete Relations for</param>
public void DeleteRelationsOfType(RelationType relationType)
{
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateRelationRepository(uow))
{
var query = new Query<Relation>().Where(x => x.RelationTypeId == relationType.Id);
var list = repository.GetByQuery(query).ToList();
foreach (var relation in list)
{
repository.Delete(relation);
}
uow.Commit();
}
}
#region Private Methods
private IEnumerable<Relation> GetRelationsByListOfTypeIds(IEnumerable<int> relationTypeIds)
{
var relations = new List<Relation>();
using (var repository = _repositoryFactory.CreateRelationRepository(_uowProvider.GetUnitOfWork()))
{
foreach (var relationTypeId in relationTypeIds)
{
int id = relationTypeId;
var query = new Query<Relation>().Where(x => x.RelationTypeId == id);
relations.AddRange(repository.GetByQuery(query).ToList());
}
}
return relations;
}
#endregion
}
}
+13 -13
View File
@@ -15,7 +15,6 @@ namespace Umbraco.Core.Services
private Lazy<ContentService> _contentService;
private Lazy<UserService> _userService;
private Lazy<MediaService> _mediaService;
private Lazy<MacroService> _macroService;
private Lazy<ContentTypeService> _contentTypeService;
private Lazy<DataTypeService> _dataTypeService;
private Lazy<FileService> _fileService;
@@ -23,6 +22,7 @@ namespace Umbraco.Core.Services
private Lazy<PackagingService> _packagingService;
private Lazy<ServerRegistrationService> _serverRegistrationService;
private Lazy<EntityService> _entityService;
private Lazy<RelationService> _relationService;
/// <summary>
/// Constructor
@@ -62,9 +62,6 @@ namespace Umbraco.Core.Services
if(_mediaService == null)
_mediaService = new Lazy<MediaService>(() => new MediaService(provider, repositoryFactory.Value));
if(_macroService == null)
_macroService = new Lazy<MacroService>(() => new MacroService(fileProvider, repositoryFactory.Value));
if(_contentTypeService == null)
_contentTypeService = new Lazy<ContentTypeService>(() => new ContentTypeService(provider, repositoryFactory.Value, _contentService.Value, _mediaService.Value));
@@ -82,6 +79,9 @@ namespace Umbraco.Core.Services
if (_entityService == null)
_entityService = new Lazy<EntityService>(() => new EntityService(provider, repositoryFactory.Value, _contentService.Value, _contentTypeService.Value, _mediaService.Value, _dataTypeService.Value));
if(_relationService == null)
_relationService = new Lazy<RelationService>(() => new RelationService(provider, repositoryFactory.Value, _entityService.Value));
}
/// <summary>
@@ -95,11 +95,19 @@ namespace Umbraco.Core.Services
/// <summary>
/// Gets the <see cref="EntityService"/>
/// </summary>
internal EntityService EntityService
public EntityService EntityService
{
get { return _entityService.Value; }
}
/// <summary>
/// Gets the <see cref="RelationService"/>
/// </summary>
public RelationService RelationService
{
get { return _relationService.Value; }
}
/// <summary>
/// Gets the <see cref="IContentService"/>
/// </summary>
@@ -156,14 +164,6 @@ namespace Umbraco.Core.Services
get { return _packagingService.Value; }
}
/// <summary>
/// Gets the <see cref="IMacroService"/>
/// </summary>
internal IMacroService MacroService
{
get { return _macroService.Value; }
}
/// <summary>
/// Gets the <see cref="IMacroService"/>
/// </summary>
+3
View File
@@ -1,5 +1,8 @@
using Umbraco.Core.CodeAnnotations;
namespace Umbraco.Core
{
[UmbracoWillObsolete("This enumeration should be removed. Use Umbraco.Core.Strings.CleanStringType instead.")]
public enum StringAliasCaseType
{
PascalCase,
+8 -1
View File
@@ -17,7 +17,7 @@ namespace Umbraco.Core.Strings
/// <summary>
/// Flag mask for casing.
/// </summary>
CaseMask = 0x1f, // 0xff - 8 possible values
CaseMask = 0x3f, // 0xff - 8 possible values
/// <summary>
/// Flag mask for encoding.
@@ -59,6 +59,13 @@ namespace Umbraco.Core.Strings
/// </summary>
UpperCase = 0x10,
/// <summary>
/// Umbraco "safe alias" case.
/// </summary>
/// <remarks>This is for backward compatibility. Casing is unchanged within terms,
/// and is pascal otherwise.</remarks>
UmbracoCase = 0x20,
/// <summary>
/// Unicode encoding.
/// </summary>
@@ -16,7 +16,7 @@ namespace Umbraco.Core.Strings
/// <para>Full-unicode support is probably not so good.</para>
/// <para>NOTE: pre-filters run _before_ the string is re-encoded.</para>
/// </remarks>
internal class DefaultShortStringHelper : IShortStringHelper
public class DefaultShortStringHelper : IShortStringHelper
{
#region Ctor and vars
@@ -119,7 +119,7 @@ namespace Umbraco.Core.Strings
bool breakTermsOnUpper = true, bool allowLeadingDigits = false, bool allowUnderscoreInTerm = false)
{
EnsureNotFrozen();
if (!_configs.ContainsKey(culture))
if (_configs.ContainsKey(culture) == false)
_configs[culture] = new Dictionary<CleanStringType, HelperConfig>();
_configs[culture][stringRole] = new HelperConfig(preFilter, breakTermsOnUpper, allowLeadingDigits, allowUnderscoreInTerm);
return this;
@@ -144,10 +144,23 @@ namespace Umbraco.Core.Strings
}
public Func<string, string> PreFilter { get; private set; }
// indicate whether an uppercase within a term eg "fooBar" is to break
// into a new term, or to be considered as part of the current term
public bool BreakTermsOnUpper { get; private set; }
// indicates whether it is legal to have leading digits, or whether they
// should be stripped as any other illegal character
public bool AllowLeadingDigits { get; private set; }
// indicates whether underscore is a valid character in a term or is
// to be considered as a separator
public bool AllowUnderscoreInTerm { get; private set; }
// indicates whether acronyms parsing is greedy ie whether "FOObar" is
// "FOO" + "bar" (greedy) or "FO" + "Obar" (non-greedy)
public bool GreedyAcronyms { get { return false; } }
public static readonly HelperConfig Empty = new HelperConfig();
}
@@ -237,9 +250,9 @@ function validateSafeAlias(id, value, immediate, callback) {{
/// <para>The string will be cleaned in the context of the default culture.</para>
/// <para>Safe aliases are Ascii only.</para>
/// </remarks>
public string CleanStringForSafeAlias(string text)
public virtual string CleanStringForSafeAlias(string text)
{
return CleanString(text, CleanStringType.Ascii | CleanStringType.CamelCase | CleanStringType.Alias);
return CleanString(text, CleanStringType.Ascii | CleanStringType.UmbracoCase | CleanStringType.Alias);
}
/// <summary>
@@ -251,9 +264,9 @@ function validateSafeAlias(id, value, immediate, callback) {{
/// <remarks>
/// <para>Safe aliases are Ascii only.</para>
/// </remarks>
public string CleanStringForSafeAlias(string text, CultureInfo culture)
public virtual string CleanStringForSafeAlias(string text, CultureInfo culture)
{
return CleanString(text, CleanStringType.Ascii | CleanStringType.CamelCase | CleanStringType.Alias, culture);
return CleanString(text, CleanStringType.Ascii | CleanStringType.UmbracoCase | CleanStringType.Alias, culture);
}
/// <summary>
@@ -265,7 +278,7 @@ function validateSafeAlias(id, value, immediate, callback) {{
/// <para>The string will be cleaned in the context of the default culture.</para>
/// <para>Url segments are Ascii only (no accents...).</para>
/// </remarks>
public string CleanStringForUrlSegment(string text)
public virtual string CleanStringForUrlSegment(string text)
{
return CleanString(text, CleanStringType.Ascii | CleanStringType.LowerCase | CleanStringType.Url, '-');
}
@@ -279,7 +292,7 @@ function validateSafeAlias(id, value, immediate, callback) {{
/// <remarks>
/// <para>Url segments are Ascii only (no accents...).</para>
/// </remarks>
public string CleanStringForUrlSegment(string text, CultureInfo culture)
public virtual string CleanStringForUrlSegment(string text, CultureInfo culture)
{
return CleanString(text, CleanStringType.Ascii | CleanStringType.LowerCase | CleanStringType.Url, '-', culture);
}
@@ -402,7 +415,7 @@ function validateSafeAlias(id, value, immediate, callback) {{
/// <param name="separator">The separator.</param>
/// <param name="culture">The culture.</param>
/// <returns>The clean string.</returns>
public string CleanString(string text, CleanStringType stringType, char separator, CultureInfo culture)
public virtual string CleanString(string text, CleanStringType stringType, char separator, CultureInfo culture)
{
var config = GetConfig(stringType & CleanStringType.RoleMask, culture);
return CleanString(text, stringType, separator, culture, config);
@@ -678,10 +691,9 @@ function validateSafeAlias(id, value, immediate, callback) {{
// then we cannot break words on uppercase chars
var input = text;
// because we shouldn't be adding any extra char
// it's faster to use an array than a StringBuilder
var ilen = input.Length;
var output = new char[ilen];
var output = new char[ilen * 2]; // twice the length should be OK in all cases
//var termFilter = config.TermFilter;
@@ -697,7 +709,7 @@ function validateSafeAlias(id, value, immediate, callback) {{
switch (state)
{
case StateBreak:
if (isTerm && (opos > 0 || (!isUnder && (config.AllowLeadingDigits || !isDigit))))
if (isTerm && (opos > 0 || (isUnder == false && (config.AllowLeadingDigits || isDigit == false))))
{
ipos = i;
if (opos > 0 && separator != char.MinValue)
@@ -707,7 +719,7 @@ function validateSafeAlias(id, value, immediate, callback) {{
break;
case StateWord:
if (!isTerm || (config.BreakTermsOnUpper && isUpper))
if (isTerm == false || (config.BreakTermsOnUpper && isUpper))
{
CopyUtf8Term(input, ipos, output, ref opos, i - ipos, caseType, culture, /*termFilter,*/ false);
ipos = i;
@@ -718,8 +730,10 @@ function validateSafeAlias(id, value, immediate, callback) {{
break;
case StateAcronym:
if (!isTerm || isLower || isDigit)
if (isTerm == false || isLower || isDigit)
{
if (isLower && config.GreedyAcronyms == false)
i -= 1;
CopyUtf8Term(input, ipos, output, ref opos, i - ipos, caseType, culture, /*termFilter,*/ true);
ipos = i;
state = isTerm ? StateWord : StateBreak;
@@ -780,9 +794,9 @@ function validateSafeAlias(id, value, immediate, callback) {{
if (isAcronym)
{
if (caseType == CleanStringType.CamelCase && len <= 2 && opos > 0)
caseType = CleanStringType.Unchanged;
else if (caseType == CleanStringType.PascalCase && len <= 2)
if ((caseType == CleanStringType.CamelCase && len <= 2 && opos > 0) ||
(caseType == CleanStringType.PascalCase && len <= 2) ||
(caseType == CleanStringType.UmbracoCase))
caseType = CleanStringType.Unchanged;
}
@@ -822,6 +836,14 @@ function validateSafeAlias(id, value, immediate, callback) {{
opos += len - 1;
break;
case CleanStringType.UmbracoCase:
c = term[ipos++];
output[opos] = opos++ == 0 ? c : char.ToUpper(c, culture);
if (len > 1)
term.CopyTo(ipos, output, opos, len - 1);
opos += len - 1;
break;
default:
throw new ArgumentOutOfRangeException("caseType");
}
@@ -838,7 +860,7 @@ function validateSafeAlias(id, value, immediate, callback) {{
/// <param name="separator">The separator, which defaults to a whitespace.</param>
/// <returns>The splitted text.</returns>
/// <remarks>Supports Utf8 and Ascii strings, not Unicode strings.</remarks>
public string SplitPascalCasing(string text, char separator)
public virtual string SplitPascalCasing(string text, char separator)
{
// be safe
if (text == null)
@@ -892,7 +914,7 @@ function validateSafeAlias(id, value, immediate, callback) {{
/// <returns>The filtered string.</returns>
/// <remarks>If <paramref name="stringType"/> is not <c>Unicode</c> then non-utf8 characters are
/// removed. If it is <c>Ascii</c> we try to do some intelligent replacement of accents, etc.</remarks>
public string Recode(string text, CleanStringType stringType)
public virtual string Recode(string text, CleanStringType stringType)
{
// be safe
if (text == null)
@@ -939,7 +961,7 @@ function validateSafeAlias(id, value, immediate, callback) {{
/// <param name="text">The string to filter.</param>
/// <param name="replacements">The replacements definition.</param>
/// <returns>The filtered string.</returns>
public string ReplaceMany(string text, IDictionary<string, string> replacements)
public virtual string ReplaceMany(string text, IDictionary<string, string> replacements)
{
// be safe
if (text == null)
@@ -6,7 +6,7 @@ namespace Umbraco.Core.Strings
/// <summary>
/// Default implementation of IUrlSegmentProvider.
/// </summary>
internal class DefaultUrlSegmentProvider : IUrlSegmentProvider
public class DefaultUrlSegmentProvider : IUrlSegmentProvider
{
/// <summary>
/// Gets the default url segment for a specified content.
@@ -7,7 +7,7 @@ namespace Umbraco.Core.Strings
/// Provides string functions for short strings such as aliases or url segments.
/// </summary>
/// <remarks>Not necessarily optimized to work on large bodies of text.</remarks>
internal interface IShortStringHelper
public interface IShortStringHelper
{
/// <summary>
/// Freezes the helper so it can prevents its configuration from being modified.
@@ -7,7 +7,7 @@ namespace Umbraco.Core.Strings
/// Provides url segments for content.
/// </summary>
/// <remarks>Url segments should comply with IETF RFCs regarding content, encoding, etc.</remarks>
internal interface IUrlSegmentProvider
public interface IUrlSegmentProvider
{
/// <summary>
/// Gets the default url segment for a specified content.
@@ -5,7 +5,7 @@ namespace Umbraco.Core.Strings
/// <summary>
/// Resolves the IShortStringHelper object
/// </summary>
internal sealed class ShortStringHelperResolver : SingleObjectResolverBase<ShortStringHelperResolver, IShortStringHelper>
public sealed class ShortStringHelperResolver : SingleObjectResolverBase<ShortStringHelperResolver, IShortStringHelper>
{
/// <summary>
/// Initializes a new instance of the <see cref="ShortStringHelperResolver"/> class with an instance of a helper.
@@ -3,7 +3,7 @@
/// <summary>
/// Provides extension methods to StringAliasCaseType to facilitate migration to CleanStringType.
/// </summary>
internal static class StringAliasCaseTypeExtensions
public static class StringAliasCaseTypeExtensions
{
/// <summary>
/// Gets the CleanStringType value corresponding to the StringAliasCaseType value.
@@ -7,7 +7,7 @@ namespace Umbraco.Core.Strings
/// <summary>
/// Resolves IUrlSegmentProvider objects.
/// </summary>
internal sealed class UrlSegmentProviderResolver : ManyObjectsResolverBase<UrlSegmentProviderResolver, IUrlSegmentProvider>
public sealed class UrlSegmentProviderResolver : ManyObjectsResolverBase<UrlSegmentProviderResolver, IUrlSegmentProvider>
{
/// <summary>
/// Initializes a new instance of the <see cref="UrlSegmentProviderResolver"/> class with an initial list of provider types.
@@ -24,6 +24,11 @@ namespace Umbraco.Core.Sync
}
public string ServerAddress { get; private set; }
public override string ToString()
{
return ServerAddress;
}
}
}
+50 -20
View File
@@ -19,11 +19,12 @@ namespace Umbraco.Core.Sync
{
private readonly Func<Tuple<string, string>> _getUserNamePasswordDelegate;
private volatile bool _hasResolvedDelegate = false;
private readonly object _locker = new object();
private string _login;
private string _password;
private readonly object _locker = new object();
private bool _useDistributedCalls;
protected string Login { get; private set; }
protected string Password{ get; private set; }
/// <summary>
/// Without a username/password all distribuion will be disabled
/// </summary>
@@ -38,13 +39,24 @@ namespace Umbraco.Core.Sync
/// <param name="login"></param>
/// <param name="password"></param>
internal DefaultServerMessenger(string login, string password)
: this(login, password, UmbracoSettings.UseDistributedCalls)
{
}
/// <summary>
/// Specifies the username/password and whether or not to use distributed calls
/// </summary>
/// <param name="login"></param>
/// <param name="password"></param>
/// <param name="useDistributedCalls"></param>
internal DefaultServerMessenger(string login, string password, bool useDistributedCalls)
{
if (login == null) throw new ArgumentNullException("login");
if (password == null) throw new ArgumentNullException("password");
_useDistributedCalls = UmbracoSettings.UseDistributedCalls;
_login = login;
_password = password;
_useDistributedCalls = useDistributedCalls;
Login = login;
Password = password;
}
/// <summary>
@@ -137,6 +149,10 @@ namespace Umbraco.Core.Sync
{
if (refresher == null) throw new ArgumentNullException("refresher");
LogHelper.Debug<DefaultServerMessenger>("Invoking refresher {0} on single server instance, message type {1}",
() => refresher.GetType(),
() => dispatchType);
var stronglyTypedRefresher = refresher as ICacheRefresher<T>;
foreach (var instance in instances)
@@ -202,22 +218,22 @@ namespace Umbraco.Core.Sync
var result = _getUserNamePasswordDelegate();
if (result == null)
{
_login = null;
_password = null;
Login = null;
Password = null;
_useDistributedCalls = false;
}
else
{
_login = result.Item1;
_password = result.Item2;
Login = result.Item1;
Password = result.Item2;
_useDistributedCalls = UmbracoSettings.UseDistributedCalls;
}
}
catch (Exception ex)
{
LogHelper.Error<DefaultServerMessenger>("Could not resolve username/password delegate, server distribution will be disabled", ex);
_login = null;
_password = null;
Login = null;
Password = null;
_useDistributedCalls = false;
}
}
@@ -225,10 +241,14 @@ namespace Umbraco.Core.Sync
}
}
private void InvokeMethodOnRefresherInstance(ICacheRefresher refresher, MessageType dispatchType, IEnumerable<object> ids = null, string jsonPayload = null)
protected void InvokeMethodOnRefresherInstance(ICacheRefresher refresher, MessageType dispatchType, IEnumerable<object> ids = null, string jsonPayload = null)
{
if (refresher == null) throw new ArgumentNullException("refresher");
LogHelper.Debug<DefaultServerMessenger>("Invoking refresher {0} on single server instance, message type {1}",
() => refresher.GetType(),
() => dispatchType);
//if it is a refresh all we'll do it here since ids will be null or empty
if (dispatchType == MessageType.RefreshAll)
{
@@ -289,6 +309,8 @@ namespace Umbraco.Core.Sync
if (servers == null) throw new ArgumentNullException("servers");
if (refresher == null) throw new ArgumentNullException("refresher");
EnsureLazyUsernamePasswordDelegateResolved();
//Now, check if we are using Distrubuted calls. If there are no servers in the list then we
// can definitely not distribute.
if (!_useDistributedCalls || !servers.Any())
@@ -317,7 +339,9 @@ namespace Umbraco.Core.Sync
{
throw new ArgumentException("The id must be either an int or a Guid");
}
EnsureLazyUsernamePasswordDelegateResolved();
//Now, check if we are using Distrubuted calls. If there are no servers in the list then we
// can definitely not distribute.
if (!_useDistributedCalls || !servers.Any())
@@ -327,7 +351,13 @@ namespace Umbraco.Core.Sync
return;
}
EnsureLazyUsernamePasswordDelegateResolved();
LogHelper.Debug<DefaultServerMessenger>(
"Performing distributed call for refresher {0}, message type: {1}, servers: {2}, ids: {3}, json: {4}",
refresher.GetType,
() => dispatchType,
() => string.Join(";", servers.Select(x => x.ToString())),
() => ids == null ? "" : string.Join(";", ids.Select(x => x.ToString())),
() => jsonPayload ?? "");
PerformDistributedCall(servers, refresher, dispatchType, ids, arrayType, jsonPayload);
}
@@ -385,12 +415,12 @@ namespace Umbraco.Core.Sync
case MessageType.RefreshByJson:
asyncResultsList.Add(
cacheRefresher.BeginRefreshByJson(
refresher.UniqueIdentifier, jsonPayload, _login, _password, null, null));
refresher.UniqueIdentifier, jsonPayload, Login, Password, null, null));
break;
case MessageType.RefreshAll:
asyncResultsList.Add(
cacheRefresher.BeginRefreshAll(
refresher.UniqueIdentifier, _login, _password, null, null));
refresher.UniqueIdentifier, Login, Password, null, null));
break;
case MessageType.RefreshById:
if (idArrayType == null)
@@ -403,7 +433,7 @@ namespace Umbraco.Core.Sync
var serializer = new JavaScriptSerializer();
var jsonIds = serializer.Serialize(ids.Cast<int>().ToArray());
//we support bulk loading of Integers
var result = cacheRefresher.BeginRefreshByIds(refresher.UniqueIdentifier, jsonIds, _login, _password, null, null);
var result = cacheRefresher.BeginRefreshByIds(refresher.UniqueIdentifier, jsonIds, Login, Password, null, null);
asyncResultsList.Add(result);
}
else
@@ -412,7 +442,7 @@ namespace Umbraco.Core.Sync
//so we'll just iterate
asyncResultsList.AddRange(
ids.Select(i => cacheRefresher.BeginRefreshByGuid(
refresher.UniqueIdentifier, (Guid)i, _login, _password, null, null)));
refresher.UniqueIdentifier, (Guid)i, Login, Password, null, null)));
}
break;
@@ -420,7 +450,7 @@ namespace Umbraco.Core.Sync
//we don't currently support bulk removing so we'll iterate
asyncResultsList.AddRange(
ids.Select(i => cacheRefresher.BeginRemoveById(
refresher.UniqueIdentifier, (int)i, _login, _password, null, null)));
refresher.UniqueIdentifier, (int)i, Login, Password, null, null)));
break;
}
}
+11 -4
View File
@@ -4,7 +4,12 @@ using System.Linq;
namespace Umbraco.Core
{
internal class TopologicalSorter
/// <summary>
/// Topological Sort algorithm for sorting items based on dependencies.
/// Use the static method TopologicalSorter.GetSortedItems for a convenient
/// way of sorting a list of items with dependencies between them.
/// </summary>
public class TopologicalSorter
{
private readonly int[] _vertices; // list of vertices
private readonly int[,] _matrix; // adjacency matrix
@@ -109,8 +114,9 @@ namespace Umbraco.Core
#endregion
#region Internal Staic methods
internal static IEnumerable<T> GetSortedItems<T>(List<DependencyField<T>> fields) where T : class
#region Static methods
public static IEnumerable<T> GetSortedItems<T>(List<DependencyField<T>> fields) where T : class
{
int[] sortOrder = GetTopologicalSortOrder(fields);
var list = new List<T>();
@@ -155,9 +161,10 @@ namespace Umbraco.Core
int[] result = g.Sort();
return result;
}
#endregion
internal class DependencyField<T> where T : class
public class DependencyField<T> where T : class
{
public DependencyField()
{
+179 -65
View File
@@ -19,8 +19,6 @@ using Umbraco.Core.IO;
namespace Umbraco.Core
{
//TODO: Get the App_Code stuff in here from the old one
/// <summary>
/// A utility class to find all classes of a certain type by reflection in the current bin folder
/// of the web application.
@@ -175,7 +173,8 @@ namespace Umbraco.Core
{
try
{
var foundAssembly = safeDomainAssemblies.FirstOrDefault(a => a.GetAssemblyFile() == assemblyName.GetAssemblyFile());
var foundAssembly =
safeDomainAssemblies.FirstOrDefault(a => a.GetAssemblyFile() == assemblyName.GetAssemblyFile());
if (foundAssembly != null)
{
binFolderAssemblies.Add(foundAssembly);
@@ -268,7 +267,7 @@ namespace Umbraco.Core
"umbraco.interfaces,",
"umbraco.providers,",
"Umbraco.Web.UI,",
"umbraco.webservices",
"umbraco.webservices",
"Lucene.",
"Examine,",
"Examine.",
@@ -280,36 +279,66 @@ namespace Umbraco.Core
"CookComputing."
};
/// <summary>
/// Finds any classes derived from the type T that contain the attribute TAttribute
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TAttribute"></typeparam>
/// <returns></returns>
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>()
where TAttribute : Attribute
{
return FindClassesOfTypeWithAttribute<T, TAttribute>(GetAssembliesWithKnownExclusions(), true);
}
/// <summary>
/// Finds any classes derived from the type T that contain the attribute TAttribute
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TAttribute"></typeparam>
/// <param name="assemblies"></param>
/// <returns></returns>
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>(IEnumerable<Assembly> assemblies)
where TAttribute : Attribute
{
return FindClassesOfTypeWithAttribute<T, TAttribute>(assemblies, true);
}
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>(IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
where TAttribute : Attribute
/// <summary>
/// Finds any classes derived from the type T that contain the attribute TAttribute
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TAttribute"></typeparam>
/// <param name="assemblies"></param>
/// <param name="onlyConcreteClasses"></param>
/// <returns></returns>
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>(
IEnumerable<Assembly> assemblies,
bool onlyConcreteClasses)
where TAttribute : Attribute
{
return FindClassesOfTypeWithAttribute<TAttribute>(typeof (T), assemblies, onlyConcreteClasses);
}
/// <summary>
/// Finds any classes derived from the assignTypeFrom Type that contain the attribute TAttribute
/// </summary>
/// <typeparam name="TAttribute"></typeparam>
/// <param name="assignTypeFrom"></param>
/// <param name="assemblies"></param>
/// <param name="onlyConcreteClasses"></param>
/// <returns></returns>
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<TAttribute>(
Type assignTypeFrom,
IEnumerable<Assembly> assemblies,
bool onlyConcreteClasses)
where TAttribute : Attribute
{
if (assemblies == null) throw new ArgumentNullException("assemblies");
var l = new List<Type>();
foreach(var a in assemblies)
{
var types = from t in GetTypesWithFormattedException(a)
where !t.IsInterface
&& typeof (T).IsAssignableFrom(t)
&& t.GetCustomAttributes<TAttribute>(false).Any()
&& (!onlyConcreteClasses || (t.IsClass && !t.IsAbstract))
select t;
l.AddRange(types);
}
return l;
return GetClasses(assignTypeFrom, assemblies, onlyConcreteClasses,
//the additional filter will ensure that any found types also have the attribute applied.
t => t.GetCustomAttributes<TAttribute>(false).Any());
}
/// <summary>
@@ -333,7 +362,7 @@ namespace Umbraco.Core
{
if (assemblies == null) throw new ArgumentNullException("assemblies");
return GetAssignablesFromType<T>(assemblies, onlyConcreteClasses);
return GetClasses(typeof(T), assemblies, onlyConcreteClasses);
}
/// <summary>
@@ -360,32 +389,50 @@ namespace Umbraco.Core
return FindClassesWithAttribute(typeof(T), assemblies, onlyConcreteClasses);
}
/// <summary>
/// Finds the classes with attribute.
/// </summary>
/// <param name="type">The attribute type </param>
/// <param name="assemblies">The assemblies.</param>
/// <param name="onlyConcreteClasses">if set to <c>true</c> only concrete classes.</param>
/// <returns></returns>
public static IEnumerable<Type> FindClassesWithAttribute(Type type, IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
{
if (assemblies == null) throw new ArgumentNullException("assemblies");
if (!TypeHelper.IsTypeAssignableFrom<Attribute>(type))
throw new ArgumentException("The type specified: " + type + " is not an Attribute type");
/// <summary>
/// Finds any classes with the attribute.
/// </summary>
/// <param name="attributeType">The attribute type </param>
/// <param name="assemblies">The assemblies.</param>
/// <param name="onlyConcreteClasses">if set to <c>true</c> only concrete classes.</param>
/// <returns></returns>
public static IEnumerable<Type> FindClassesWithAttribute(
Type attributeType,
IEnumerable<Assembly> assemblies,
bool onlyConcreteClasses)
{
if (assemblies == null) throw new ArgumentNullException("assemblies");
var l = new List<Type>();
foreach (var a in assemblies)
{
var types = from t in GetTypesWithFormattedException(a)
where !t.IsInterface && t.GetCustomAttributes(type, false).Any() && (!onlyConcreteClasses || (t.IsClass && !t.IsAbstract))
select t;
l.AddRange(types);
}
if (TypeHelper.IsTypeAssignableFrom<Attribute>(attributeType) == false)
throw new ArgumentException("The type specified: " + attributeType + " is not an Attribute type");
return l;
}
var foundAssignableTypes = new List<Type>();
/// <summary>
var assemblyList = assemblies.ToArray();
//find all assembly references that are referencing the attribute type's assembly since we
//should only be scanning those assemblies because any other assembly will definitely not
//contain a class that has this attribute.
var referencedAssemblies = TypeHelper.GetReferencedAssemblies(attributeType, assemblyList);
foreach (var a in referencedAssemblies)
{
//get all types in the assembly that are sub types of the current type
var allTypes = GetTypesWithFormattedException(a).ToArray();
var types = allTypes.Where(t => TypeHelper.IsNonStaticClass(t)
&& (onlyConcreteClasses == false || t.IsAbstract == false)
//the type must have this attribute
&& t.GetCustomAttributes(attributeType, false).Any());
foundAssignableTypes.AddRange(types);
}
return foundAssignableTypes;
}
/// <summary>
/// Finds the classes with attribute.
/// </summary>
/// <typeparam name="T"></typeparam>
@@ -411,29 +458,96 @@ namespace Umbraco.Core
#region Private methods
/// <summary>
/// Gets a collection of assignables of type T from a collection of assemblies
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="assemblies"></param>
/// <param name="onlyConcreteClasses"></param>
/// <returns></returns>
private static IEnumerable<Type> GetAssignablesFromType<T>(IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
/// <summary>
/// Finds types that are assignable from the assignTypeFrom parameter and will scan for these types in the assembly
/// list passed in, however we will only scan assemblies that have a reference to the assignTypeFrom Type or any type
/// deriving from the base type.
/// </summary>
/// <param name="assignTypeFrom"></param>
/// <param name="assemblies"></param>
/// <param name="onlyConcreteClasses"></param>
/// <param name="additionalFilter">An additional filter to apply for what types will actually be included in the return value</param>
/// <returns></returns>
private static IEnumerable<Type> GetClasses(
Type assignTypeFrom,
IEnumerable<Assembly> assemblies,
bool onlyConcreteClasses,
Func<Type, bool> additionalFilter = null)
{
return GetTypes(typeof(T), assemblies, onlyConcreteClasses);
}
//the default filter will always return true.
if (additionalFilter == null)
{
additionalFilter = type => true;
}
var foundAssignableTypes = new List<Type>();
var assemblyList = assemblies.ToArray();
//find all assembly references that are referencing the current type's assembly since we
//should only be scanning those assemblies because any other assembly will definitely not
//contain sub type's of the one we're currently looking for
var referencedAssemblies = TypeHelper.GetReferencedAssemblies(assignTypeFrom, assemblyList);
//get a list of non-referenced assemblies (we'll use this when we recurse below)
var otherAssemblies = assemblyList.Where(x => referencedAssemblies.Contains(x) == false).ToArray();
//loop through the referenced assemblies
foreach (var a in referencedAssemblies)
{
//get all types in the assembly that are sub types of the current type
var allSubTypes = GetTypesWithFormattedException(a)
.Where(assignTypeFrom.IsAssignableFrom)
.ToArray();
//now filter the types based on the onlyConcreteClasses flag, not interfaces, not static classes
var filteredTypes = allSubTypes
.Where(t => (TypeHelper.IsNonStaticClass(t)
&& (onlyConcreteClasses == false || t.IsAbstract == false)
&& additionalFilter(t)))
.ToArray();
//add the types to our list to return
foundAssignableTypes.AddRange(filteredTypes);
//now we need to include types that may be inheriting from sub classes of the type being searched for
//so we will search in assemblies that reference those types too.
foreach (var subTypesInAssembly in allSubTypes.GroupBy(x => x.Assembly))
{
//So that we are not scanning too much, we need to group the sub types:
// * if there is more than 1 sub type in the same assembly then we should only search on the 'lowest base' type.
// * We should also not search for sub types if the type is sealed since you cannot inherit from a sealed class
// * We should not search for sub types if the type is static since you cannot inherit from them.
var subTypeList = subTypesInAssembly
.Where(t => t.IsSealed == false && TypeHelper.IsStaticClass(t) == false)
.ToArray();
var baseClassAttempt = TypeHelper.GetLowestBaseType(subTypeList);
//if there's a base class amongst the types then we'll only search for that type.
//otherwise we'll have to search for all of them.
var subTypesToSearch = new List<Type>();
if (baseClassAttempt.Success)
{
subTypesToSearch.Add(baseClassAttempt.Result);
}
else
{
subTypesToSearch.AddRange(subTypeList);
}
foreach (var typeToSearch in subTypesToSearch)
{
//recursively find the types inheriting from this sub type in the other non-scanned assemblies.
var foundTypes = GetClasses(typeToSearch, otherAssemblies, onlyConcreteClasses);
foundAssignableTypes.AddRange(foundTypes);
}
}
private static IEnumerable<Type> GetTypes(Type assignTypeFrom, IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
{
var l = new List<Type>();
foreach (var a in assemblies)
{
var types = from t in GetTypesWithFormattedException(a)
where !t.IsInterface && assignTypeFrom.IsAssignableFrom(t) && (!onlyConcreteClasses || (t.IsClass && !t.IsAbstract))
select t;
l.AddRange(types);
}
return l;
return foundAssignableTypes;
}
private static IEnumerable<Type> GetTypesWithFormattedException(Assembly a)
@@ -452,7 +566,7 @@ namespace Umbraco.Core
sb.AppendLine("Could not load types from assembly " + a.FullName + ", errors:");
foreach (var loaderException in ex.LoaderExceptions.WhereNotNull())
{
sb.AppendLine("Exception: " + loaderException.ToString());
sb.AppendLine("Exception: " + loaderException);
}
throw new ReflectionTypeLoadException(ex.Types, ex.LoaderExceptions, sb.ToString());
}
+104
View File
@@ -1,5 +1,6 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
@@ -15,6 +16,109 @@ namespace Umbraco.Core
private static readonly ConcurrentDictionary<Type, FieldInfo[]> GetFieldsCache = new ConcurrentDictionary<Type, FieldInfo[]>();
private static readonly ConcurrentDictionary<Tuple<Type, bool, bool, bool>, PropertyInfo[]> GetPropertiesCache = new ConcurrentDictionary<Tuple<Type, bool, bool, bool>, PropertyInfo[]>();
/// <summary>
/// Find all assembly references that are referencing the assignTypeFrom Type's assembly found in the assemblyList
/// </summary>
/// <param name="assignTypeFrom"></param>
/// <param name="assemblies"></param>
/// <returns></returns>
/// <remarks>
/// If the assembly of the assignTypeFrom Type is in the App_Code assembly, then we return nothing since things cannot
/// reference that assembly, same with the global.asax assembly.
/// </remarks>
public static Assembly[] GetReferencedAssemblies(Type assignTypeFrom, IEnumerable<Assembly> assemblies)
{
//check if it is the app_code assembly.
//check if it is App_global.asax assembly
if (assignTypeFrom.Assembly.IsAppCodeAssembly() || assignTypeFrom.Assembly.IsGlobalAsaxAssembly())
{
return Enumerable.Empty<Assembly>().ToArray();
}
//find all assembly references that are referencing the current type's assembly since we
//should only be scanning those assemblies because any other assembly will definitely not
//contain sub type's of the one we're currently looking for
return assemblies
.Where(assembly =>
assembly == assignTypeFrom.Assembly || HasReferenceToAssemblyWithName(assembly, assignTypeFrom.Assembly.GetName().Name))
.ToArray();
}
/// <summary>
/// checks if the assembly has a reference with the same name as the expected assembly name.
/// </summary>
/// <param name="assembly"></param>
/// <param name="expectedAssemblyName"></param>
/// <returns></returns>
private static bool HasReferenceToAssemblyWithName(Assembly assembly, string expectedAssemblyName)
{
return assembly
.GetReferencedAssemblies()
.Select(a => a.Name)
.Contains(expectedAssemblyName, StringComparer.Ordinal);
}
/// <summary>
/// Returns true if the type is a class and is not static
/// </summary>
/// <param name="t"></param>
/// <returns></returns>
public static bool IsNonStaticClass(Type t)
{
return t.IsClass && IsStaticClass(t) == false;
}
/// <summary>
/// Returns true if the type is a static class
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
/// <remarks>
/// In IL a static class is abstract and sealed
/// see: http://stackoverflow.com/questions/1175888/determine-if-a-type-is-static
/// </remarks>
public static bool IsStaticClass(Type type)
{
return type.IsAbstract && type.IsSealed;
}
/// <summary>
/// Finds a lowest base class amongst a collection of types
/// </summary>
/// <param name="types"></param>
/// <returns></returns>
/// <remarks>
/// The term 'lowest' refers to the most base class of the type collection.
/// If a base type is not found amongst the type collection then an invalid attempt is returned.
/// </remarks>
public static Attempt<Type> GetLowestBaseType(params Type[] types)
{
if (types.Length == 0)
{
return Attempt<Type>.False;
}
if (types.Length == 1)
{
return new Attempt<Type>(true, types[0]);
}
foreach (var curr in types)
{
var others = types.Except(new[] {curr});
//is the curr type a common denominator for all others ?
var isBase = others.All(curr.IsAssignableFrom);
//if this type is the base for all others
if (isBase)
{
return new Attempt<Type>(true, curr);
}
}
return Attempt<Type>.False;
}
/// <summary>
/// Determines whether the type <paramref name="implementation"/> is assignable from the specified implementation <typeparamref name="TContract"/>,
/// and caches the result across the application using a <see cref="ConcurrentDictionary{TKey,TValue}"/>.
+6 -28
View File
@@ -42,6 +42,9 @@
<Private>True</Private>
<HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
</Reference>
<Reference Include="MiniProfiler">
<HintPath>..\packages\MiniProfiler.2.1.0\lib\net40\MiniProfiler.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll</HintPath>
</Reference>
@@ -157,7 +160,6 @@
<Compile Include="Events\SaveEventArgs.cs" />
<Compile Include="Events\SendToPublishEventArgs.cs" />
<Compile Include="IApplicationEventHandler.cs" />
<Compile Include="MacroPropertyTypeResolver.cs" />
<Compile Include="Media\MediaSubfolderCounter.cs" />
<Compile Include="Models\ContentBase.cs" />
<Compile Include="Models\ContentExtensions.cs" />
@@ -468,7 +470,6 @@
<Compile Include="Persistence\Repositories\Interfaces\IDataTypeDefinitionRepository.cs" />
<Compile Include="Persistence\Repositories\Interfaces\IDictionaryRepository.cs" />
<Compile Include="Persistence\Repositories\Interfaces\ILanguageRepository.cs" />
<Compile Include="Persistence\Repositories\Interfaces\IMacroRepository.cs" />
<Compile Include="Persistence\Repositories\Interfaces\IMediaRepository.cs" />
<Compile Include="Persistence\Repositories\Interfaces\IMediaTypeRepository.cs" />
<Compile Include="Persistence\Repositories\Interfaces\IRelationRepository.cs" />
@@ -483,7 +484,6 @@
<Compile Include="Persistence\Repositories\Interfaces\IUserRepository.cs" />
<Compile Include="Persistence\Repositories\Interfaces\IUserTypeRepository.cs" />
<Compile Include="Persistence\Repositories\LanguageRepository.cs" />
<Compile Include="Persistence\Repositories\MacroRepository.cs" />
<Compile Include="Persistence\Repositories\MediaRepository.cs" />
<Compile Include="Persistence\Repositories\MediaTypeRepository.cs" />
<Compile Include="Persistence\Repositories\PetaPocoRepositoryBase.cs" />
@@ -521,6 +521,7 @@
<Compile Include="Persistence\UnitOfWork\IUnitOfWorkRepository.cs" />
<Compile Include="Persistence\UnitOfWork\PetaPocoUnitOfWork.cs" />
<Compile Include="Persistence\UnitOfWork\PetaPocoUnitOfWorkProvider.cs" />
<Compile Include="Profiling\Profiler.cs" />
<Compile Include="PropertyEditors\Attributes\PropertyEditorAttribute.cs" />
<Compile Include="PropertyEditors\Attributes\ShowLabelAttribute.cs" />
<Compile Include="PropertyEditors\BlankPreValueModel.cs" />
@@ -547,23 +548,7 @@
<Compile Include="IO\FileSystemProviderAttribute.cs" />
<Compile Include="IO\FileSystemExtensions.cs" />
<Compile Include="IO\MediaFileSystem.cs" />
<Compile Include="Macros\PropertyTypes\ContentAll.cs" />
<Compile Include="Macros\PropertyTypes\ContentPicker.cs" />
<Compile Include="Macros\PropertyTypes\ContentRandom.cs" />
<Compile Include="Macros\PropertyTypes\ContentStubs.cs" />
<Compile Include="Macros\PropertyTypes\ContentTree.cs" />
<Compile Include="Macros\PropertyTypes\ContentType.cs" />
<Compile Include="Macros\PropertyTypes\ContentTypeMultiple.cs" />
<Compile Include="Macros\PropertyTypes\MediaCurrent.cs" />
<Compile Include="Macros\PropertyTypes\Number.cs" />
<Compile Include="Macros\PropertyTypes\PropertyTypePicker.cs" />
<Compile Include="Macros\PropertyTypes\PropertyTypePickerMultiple.cs" />
<Compile Include="Macros\PropertyTypes\TabPicker.cs" />
<Compile Include="Macros\PropertyTypes\TabPickerMultiple.cs" />
<Compile Include="Macros\PropertyTypes\Text.cs" />
<Compile Include="Macros\PropertyTypes\TextMultiLine.cs" />
<Compile Include="Macros\MacroTagParser.cs" />
<Compile Include="Macros\PropertyTypes\YesNoBool.cs" />
<Compile Include="Mandate.cs" />
<Compile Include="Models\Content.cs" />
<Compile Include="Models\ContentStatus.cs" />
@@ -580,15 +565,8 @@
<Compile Include="Models\IContentType.cs" />
<Compile Include="Models\IContentTypeBase.cs" />
<Compile Include="Models\IContentTypeComposition.cs" />
<Compile Include="Models\IMacro.cs" />
<Compile Include="Models\IMacroProperty.cs" />
<Compile Include="Models\IMacroPropertyType.cs" />
<Compile Include="Models\IMedia.cs" />
<Compile Include="Models\IMediaType.cs" />
<Compile Include="Models\Macro.cs" />
<Compile Include="Models\MacroProperty.cs" />
<Compile Include="Models\MacroPropertyTypeBaseTypes.cs" />
<Compile Include="Models\MacroTypes.cs" />
<Compile Include="Models\Property.cs" />
<Compile Include="Models\PropertyCollection.cs" />
<Compile Include="Models\PropertyGroup.cs" />
@@ -702,13 +680,12 @@
<Compile Include="Services\IDataTypeService.cs" />
<Compile Include="Services\IFileService.cs" />
<Compile Include="Services\ILocalizationService.cs" />
<Compile Include="Services\IMacroService.cs" />
<Compile Include="Services\IMediaService.cs" />
<Compile Include="Services\IService.cs" />
<Compile Include="Services\IUserService.cs" />
<Compile Include="Services\LocalizationService.cs" />
<Compile Include="Services\MacroService.cs" />
<Compile Include="Services\MediaService.cs" />
<Compile Include="Services\RelationService.cs" />
<Compile Include="Services\ServerRegistrationService.cs" />
<Compile Include="Services\PackagingService.cs" />
<Compile Include="Services\ServiceContext.cs" />
@@ -793,6 +770,7 @@
<Compile Include="Xml\XmlNamespaces.cs" />
<Compile Include="Xml\XmlNodeListFactory.cs" />
<Compile Include="Xml\XmlNodeExtensions.cs" />
<Compile Include="Xml\XPathNavigatorExtensions.cs" />
<Compile Include="Xml\XPathVariable.cs" />
</ItemGroup>
<ItemGroup>
@@ -4,6 +4,9 @@ using System.Linq;
using System.Text;
using System.Web;
using System.Web.Hosting;
using System.Web.Mvc;
using StackExchange.Profiling;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
namespace Umbraco.Core
@@ -27,6 +30,9 @@ namespace Umbraco.Core
/// </summary>
internal void StartApplication(object sender, EventArgs e)
{
//don't output the MVC version header (security)
MvcHandler.DisableMvcResponseHeader = true;
//boot up the application
GetBootManager()
.Initialize()
@@ -44,6 +50,24 @@ namespace Umbraco.Core
StartApplication(sender, e);
}
protected void Application_BeginRequest()
{
if (GlobalSettings.DebugMode)
{
if (!String.IsNullOrEmpty(Request["umbDebug"]))
Umbraco.Core.Profiling.Profiler.Instance.Start();
}
}
protected void Application_EndRequest()
{
if (GlobalSettings.DebugMode)
{
if (!String.IsNullOrEmpty(Request["umbDebug"]))
Umbraco.Core.Profiling.Profiler.Instance.Stop();
}
}
/// <summary>
/// Developers can override this method to modify objects on startup
/// </summary>
@@ -0,0 +1,57 @@
using System.Xml.XPath;
namespace Umbraco.Core.Xml
{
/// <summary>
/// Provides extensions to XPathNavigator.
/// </summary>
internal static class XPathNavigatorExtensions
{
/// <summary>
/// Selects a node set, using the specified XPath expression.
/// </summary>
/// <param name="navigator">A source XPathNavigator.</param>
/// <param name="expression">An XPath expression.</param>
/// <param name="variables">A set of XPathVariables.</param>
/// <returns>An iterator over the nodes matching the specified expression.</returns>
public static XPathNodeIterator Select(this XPathNavigator navigator, string expression, params XPathVariable[] variables)
{
if (variables == null || variables.Length == 0 || variables[0] == null)
return navigator.Select(expression);
// Reflector shows that the standard XPathNavigator.Compile method just does
// return XPathExpression.Compile(xpath);
// only difference is, XPathNavigator.Compile is virtual so it could be overriden
// by a class inheriting from XPathNavigator... there does not seem to be any
// doing it in the Framework, though... so we'll assume it's much cleaner to use
// the static compile:
var compiled = XPathExpression.Compile(expression);
var context = new DynamicContext();
foreach (var variable in variables)
context.AddVariable(variable.Name, variable.Value);
compiled.SetContext(context);
return navigator.Select(compiled);
}
/// <summary>
/// Selects a node set, using the specified XPath expression.
/// </summary>
/// <param name="navigator">A source XPathNavigator.</param>
/// <param name="expression">An XPath expression.</param>
/// <param name="variables">A set of XPathVariables.</param>
/// <returns>An iterator over the nodes matching the specified expression.</returns>
public static XPathNodeIterator Select(this XPathNavigator navigator, XPathExpression expression, params XPathVariable[] variables)
{
if (variables == null || variables.Length == 0 || variables[0] == null)
return navigator.Select(expression);
var compiled = expression.Clone(); // clone for thread-safety
var context = new DynamicContext();
foreach (var variable in variables)
context.AddVariable(variable.Name, variable.Value);
compiled.SetContext(context);
return navigator.Select(compiled);
}
}
}
+83 -13
View File
@@ -7,18 +7,11 @@ using System.Xml.XPath;
namespace Umbraco.Core.Xml
{
/// <summary>
/// Provides extensions to XmlNode.
/// </summary>
internal static class XmlNodeExtensions
{
static XPathNodeIterator Select(string expression, XPathNavigator source, params XPathVariable[] variables)
{
var expr = source.Compile(expression);
var context = new DynamicContext();
foreach (var variable in variables)
context.AddVariable(variable.Name, variable.Value);
expr.SetContext(context);
return source.Select(expr);
}
/// <summary>
/// Selects a list of XmlNode matching an XPath expression.
/// </summary>
@@ -37,6 +30,24 @@ namespace Umbraco.Core.Xml
return SelectNodes(source, expression, av);
}
/// <summary>
/// Selects a list of XmlNode matching an XPath expression.
/// </summary>
/// <param name="source">A source XmlNode.</param>
/// <param name="expression">An XPath expression.</param>
/// <param name="variables">A set of XPathVariables.</param>
/// <returns>The list of XmlNode matching the XPath expression.</returns>
/// <remarks>
/// <para>If <param name="variables" /> is <c>null</c>, or is empty, or contains only one single
/// value which itself is <c>null</c>, then variables are ignored.</para>
/// <para>The XPath expression should reference variables as <c>$var</c>.</para>
/// </remarks>
public static XmlNodeList SelectNodes(this XmlNode source, XPathExpression expression, IEnumerable<XPathVariable> variables)
{
var av = variables == null ? null : variables.ToArray();
return SelectNodes(source, expression, av);
}
/// <summary>
/// Selects a list of XmlNode matching an XPath expression.
/// </summary>
@@ -54,10 +65,31 @@ namespace Umbraco.Core.Xml
if (variables == null || variables.Length == 0 || variables[0] == null)
return source.SelectNodes(expression);
var iterator = Select(expression, source.CreateNavigator(), variables);
var iterator = source.CreateNavigator().Select(expression, variables);
return XmlNodeListFactory.CreateNodeList(iterator);
}
/// <summary>
/// Selects a list of XmlNode matching an XPath expression.
/// </summary>
/// <param name="source">A source XmlNode.</param>
/// <param name="expression">An XPath expression.</param>
/// <param name="variables">A set of XPathVariables.</param>
/// <returns>The list of XmlNode matching the XPath expression.</returns>
/// <remarks>
/// <para>If <param name="variables" /> is <c>null</c>, or is empty, or contains only one single
/// value which itself is <c>null</c>, then variables are ignored.</para>
/// <para>The XPath expression should reference variables as <c>$var</c>.</para>
/// </remarks>
public static XmlNodeList SelectNodes(this XmlNode source, XPathExpression expression, params XPathVariable[] variables)
{
if (variables == null || variables.Length == 0 || variables[0] == null)
return source.SelectNodes(expression);
var iterator = source.CreateNavigator().Select(expression, variables);
return XmlNodeListFactory.CreateNodeList(iterator);
}
/// <summary>
/// Selects the first XmlNode that matches an XPath expression.
/// </summary>
@@ -75,7 +107,25 @@ namespace Umbraco.Core.Xml
var av = variables == null ? null : variables.ToArray();
return SelectSingleNode(source, expression, av);
}
/// <summary>
/// Selects the first XmlNode that matches an XPath expression.
/// </summary>
/// <param name="source">A source XmlNode.</param>
/// <param name="expression">An XPath expression.</param>
/// <param name="variables">A set of XPathVariables.</param>
/// <returns>The first XmlNode that matches the XPath expression.</returns>
/// <remarks>
/// <para>If <param name="variables" /> is <c>null</c>, or is empty, or contains only one single
/// value which itself is <c>null</c>, then variables are ignored.</para>
/// <para>The XPath expression should reference variables as <c>$var</c>.</para>
/// </remarks>
public static XmlNode SelectSingleNode(this XmlNode source, XPathExpression expression, IEnumerable<XPathVariable> variables)
{
var av = variables == null ? null : variables.ToArray();
return SelectSingleNode(source, expression, av);
}
/// <summary>
/// Selects the first XmlNode that matches an XPath expression.
/// </summary>
@@ -95,5 +145,25 @@ namespace Umbraco.Core.Xml
return SelectNodes(source, expression, variables).Cast<XmlNode>().FirstOrDefault();
}
}
/// <summary>
/// Selects the first XmlNode that matches an XPath expression.
/// </summary>
/// <param name="source">A source XmlNode.</param>
/// <param name="expression">An XPath expression.</param>
/// <param name="variables">A set of XPathVariables.</param>
/// <returns>The first XmlNode that matches the XPath expression.</returns>
/// <remarks>
/// <para>If <param name="variables" /> is <c>null</c>, or is empty, or contains only one single
/// value which itself is <c>null</c>, then variables are ignored.</para>
/// <para>The XPath expression should reference variables as <c>$var</c>.</para>
/// </remarks>
public static XmlNode SelectSingleNode(this XmlNode source, XPathExpression expression, params XPathVariable[] variables)
{
if (variables == null || variables.Length == 0 || variables[0] == null)
return source.SelectSingleNode(expression);
return SelectNodes(source, expression, variables).Cast<XmlNode>().FirstOrDefault();
}
}
}

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