Compare commits

...

156 Commits

Author SHA1 Message Date
Sebastiaan Janssen 267cd46ea0 Another additional fix to make the reloading of trees work after package install 2012-11-28 13:34:35 -01:00
Sebastiaan Janssen 96f6a0161f Merge with 4.11.1 2012-11-28 13:08:13 -01:00
Sebastiaan Janssen 7bc53adc67 Closing 4.11.1 branch 2012-11-28 13:06:01 -01:00
Sebastiaan Janssen 8ecff73c18 Added tag Release-4.11.1 for changeset 7f827760cb49 2012-11-28 13:05:21 -01:00
Stephan 35e65ad18c add support for "/foo" hostnames ONLY for backward compat.
fix invalid hostname message
2012-11-28 12:43:19 -01:00
Sebastiaan Janssen 8def8eaa86 Bumping the version to 4.11.1 2012-11-28 09:44:03 -01:00
Sebastiaan Janssen c0774ad9b9 Merge 2012-11-28 09:24:54 -01:00
Sebastiaan Janssen f306cbe457 Move invalidDomain entry to the correct area. 2012-11-28 09:24:40 -01:00
Sebastiaan Janssen 577b989c4c Aha, string needs to start all the way to the left to appear nicely in the editor 2012-11-28 08:41:54 -01:00
Sebastiaan Janssen e6b162f4f6 Add translation for invalid hostname 2012-11-28 08:37:08 -01:00
Stephan b40cc1879f missing entry in language file 2012-11-28 07:36:08 -01:00
Shannon Deminick 8a7c7bf77d Merge 2012-11-27 21:47:20 +05:00
Shannon Deminick 38a1179de5 applied patch from rev 189f37a1dd63 which reverts the last minute changes before 4.11
release, namely changes to the ApplicationTreeRegistrar, TreeDefinitionCollection, theend installer step.
2012-11-27 21:45:57 +05:00
Sebastiaan Janssen f263b4d92b Fixes U4-1162 - In MVC mode, creating a child template doesn't set the layout
correctly (it's missing the .cshtml extension)
2012-11-27 15:36:54 -01:00
Sebastiaan Janssen c612727116 Add translations that got lost in merge, fixes U4-1254 2012-11-27 14:07:13 -01:00
Sebastiaan Janssen ab9c9df7d6 Reverting last minute hacks around the pluginmanager and adding Shannon's fixes
from changeset 85f9e5879e60
2012-11-27 13:27:33 -01:00
Stephan c607e50433 U4-1245, U4-1186... fix the mess I created with hostnames 2012-11-27 12:43:57 -01:00
Stephan df5555bdf1 Opened branch 4.11.1 2012-11-27 12:40:42 -01:00
Sebastiaan Janssen 9506339e6f Merge with 4.11.0 2012-11-23 13:37:17 -01:00
Sebastiaan Janssen 68605a7560 Closed branch 4.11.0 2012-11-23 13:36:14 -01:00
Sebastiaan Janssen 839dd7315a Added tag Release-4.11.0 for changeset 20e4dff821d8 2012-11-23 13:33:15 -01:00
Sebastiaan Janssen f1314628d7 One last hack to get the the macroengines to show up after install. 2012-11-23 12:01:43 -01:00
Sebastiaan Janssen e23ed30b0c Took out the temporary tree fixes and put another temp fix in (reverts to the 4.10.x code)
Also removed dependency on ClientDependency.Mvc for now to make upgrades easier (no requirement to do assembly redirects in web.config)
2012-11-23 11:45:51 -01:00
PerPloug 55cb46927e Changes to template and masterpages helper 2012-11-23 09:37:35 -01:00
Sebastiaan Janssen 654c3b7403 Another temporary fix for trees being unavailable after install, the context is null during upgrades in the installer, so would cause a YSOD 2012-11-23 08:02:23 -01:00
Sebastiaan Janssen 4195754b0c Pull in new translations before release 2012-11-23 07:36:58 -01:00
Sebastiaan Janssen 96a6f17bd7 Update for the WebPI build, should now automatically be good
Fixes U4-132
2012-11-22 16:06:06 -01:00
Sebastiaan Janssen 61d99c4061 Of course we also need the assembly redirect for MVC2 -> 3 in the template config to start with (so the build.bat picks it up as well) 2012-11-22 15:45:14 -01:00
Sebastiaan Janssen 0a6e91a2f9 Fixed U4-1235 Changing document type alias YSOD's on SQL CE 2012-11-22 15:04:27 -01:00
jeavonleopold cf9e786e45 U4-1241 Fix - BaseTreePicker GetItemBreadcrumbs causes YSOD for Property Editors that do not store numeric ID's 2012-11-22 15:17:12 +00:00
Sebastiaan Janssen ba1d3fd3e6 Fix Library.Search not giving back an list of DynamicNodes any more, breaking accessibility to custom properties 2012-11-22 13:23:20 -01:00
Sebastiaan Janssen ac01fd48fa Some refactoring of the Umbraco:image implementation after code review 2012-11-22 12:30:58 -01:00
Sebastiaan Janssen f53fb694be Tightened up and renamed the ReadPublished method (relating to pull request for U4-606) 2012-11-22 09:53:11 -01:00
Sebastiaan Janssen 1ecd8fa87d Temporary fix for trees being unavailable after install 2012-11-22 09:34:05 -01:00
Sebastiaan Janssen ce1c9d697b Add assemblyredirect for System.Web.Mvc because ClientDependency.Core.Mvc relies on Mvc v2 while we're using 3. 2012-11-22 09:30:07 -01:00
Sebastiaan Janssen c67a76fb03 json2.js was not included in VS, so not in the build 2012-11-22 08:06:39 -01:00
Shannon Deminick 3d72a4497c Merge 2012-11-22 02:56:53 +05:00
Sebastiaan Janssen 30cc8e0861 Merge 2012-11-21 11:05:38 -01:00
Sebastiaan Janssen 30ca3f6df9 Bump the version to 4.11.0 2012-11-21 11:05:30 -01:00
Stephan cccfed6efe U4-1222 - improve alternate template consistency 2012-11-21 10:12:04 -01:00
Sebastiaan Janssen 82c148e997 Fixed U4-596 with thanks to firepol! 2012-11-21 09:50:47 -01:00
Sebastiaan Janssen c50a3e7a27 I broke the build, oh noes! Sorry. :-) 2012-11-21 09:46:04 -01:00
callicj@M2UA1450WRW.us.maritz.net 811cbe2339 Added new method to the Document Service named readPublished() which returns the published version of the document.
Added new method to the Document class named GetPublishedVersion() which returns the published version of the document.
2012-11-21 08:03:53 -01:00
ksykora@ksykora-Win7 a8bf881ae1 * Fixed an umbraco bug where the macro editor, if it tried to enumerate over a
property whose value was null, would throw a null reference exception instead
 of just ignoring the property.
2012-11-21 07:53:29 -01:00
ksykora@ksykora-Win7 c446be734c Moved ParseMacros from Init into Load in ItemRenderer to fix an issue where the
NodeId property on the Item control was being set after the ItemRenderer had
already loaded it into memory.
2012-11-21 07:54:17 -01:00
Morten Bock f0f7f6af55 Include some missing files 2012-11-21 07:23:15 -01:00
Shannon Deminick 19bd8ae193 Fixes overloads for TypedMedia, TypedContent, Content, Media calls on UmbracoHelper now that
GetPropertyValue returns 'object'
2012-11-21 09:09:37 +05:00
Shannon Deminick 81d8f74e0d Small update to hashcodecombiner and pluginmanager 2012-11-21 08:39:10 +05:00
Shannon Deminick 0011d568c6 Fixes up HashCodeCombiner with correct long field intead of int with correct initialization.
Adds App_Code and global.asax to be monitored for changes to create the hash code.
2012-11-21 08:28:11 +05:00
Shannon Deminick 159718bf4f Updated sln to use Nuget for ClientDependency references, ensures that all config changes
are backward compatible. Have updated the new ClientDependency.config file with the new
features, though these are not required for existing installs but we should advise to merge
the new changes in.
Added ClientDependency.Core.Mvc to the UI project so that it will now ship with this library.
2012-11-21 08:01:23 +05:00
Shannon Deminick b9ff3ca729 updated proj references, was getting warnings in build that they could not be referenced. Might be a VS 2012 thing. 2012-11-20 07:41:12 +05:00
Shannon Deminick 4f3ac36d7f Merge 2012-11-19 19:57:23 +05:00
Shannon Deminick a9257ad366 Fixes #U4-1213, much better support for ignoring routes in route table. Fixes issue with LogHelper. Adds unit tests
for ignoring routes.
2012-11-19 19:56:52 +05:00
Sebastiaan Janssen 2218459877 Correcting the path for the targets file, should work now even if there are spaces in the path 2012-11-19 08:59:23 -01:00
Sebastiaan Janssen 8f5e2946d6 Merge 2012-11-19 08:10:16 -01:00
Sebastiaan Janssen 19c3b251a0 Include the VS targets file so that the build server can find it as well 2012-11-19 08:09:43 -01:00
Shannon Deminick ce4c855f00 Fixes up the resulting casts when invoking extension methods dynamically in our dynamic objects. 2012-11-19 05:47:34 +05:00
Shannon Deminick 48c45447e4 Fixes: #U4-1207, Enhancements to DynamicXml (legacy and new), now implements proper IEnumerable<T> interfaces.
Added DynamicInstanceHelper for any dynamic object that should find matches on methods, properties and
extension methods. Fixed ExtensionMethodFinder to find the Enumerable extensions (was previously set to IEnumerable which would
find nothing).
2012-11-18 10:28:53 +05:00
Shannon Deminick 4683144987 Changed CacheHelper to be public so it can be exposed publicly by the app context. 2012-11-18 03:34:31 +05:00
Shannon Deminick 238a237cb5 Merge 2012-11-18 03:31:15 +05:00
Shannon Deminick cde1ca9f83 updated some logging on content class. 2012-11-18 03:31:02 +05:00
Shannon Deminick 93e2d8d822 added missing file for tests. 2012-11-18 02:49:55 +05:00
Stephan 8609389bdb U4-1198 - publish dialog does not detect that a parent is not published 2012-11-17 14:55:58 -01:00
Stephan 48f985b70a U4-1212 - can publish grand-child of unpublished node
fixed by introducing Document PathPublished property
2012-11-17 14:37:41 -01:00
Stephan b02afb3af8 u4-1186 - Manage hostnames UI bug with validators 2012-11-17 13:45:53 -01:00
Stephan b9d814c3fb (michielvoo pull request) Consitent new lines in templates 2012-11-17 13:28:38 -01:00
Stephan 1b54ce1d48 U4-1210 - ysod on rollback 2012-11-17 12:29:05 -01:00
Stephan e3efc0d19b U4-1194 - Mvc templates do not work when running in a virtual directory 2012-11-16 15:52:14 -01:00
Sebastiaan Janssen 3ba9e09164 Update obsolete messages to point to the correct classes (instead of being misleading) :-) 2012-11-16 14:41:30 -01:00
NielsHartvig@UMBRACORATI.localdomain d148c10c66 Update to sanitizer 2012-11-16 14:24:24 -01:00
NielsHartvig@UMBRACORATI.localdomain 2b573b9070 The BOSS is fixing U4-367 2012-11-16 14:08:28 -01:00
Shannon Deminick 4cb03ab36c Fixes issue with ChildActions when inherting from UmbracoViewPage<T> and using the @Umbraco helper. 2012-11-16 10:08:12 +05:00
Shannon Deminick 3ebbcc77e9 Merge 2012-11-16 00:45:29 +05:00
Shannon Deminick 8be97295dc Added new method to RenderMvcController for easier return of the current template when hijacking routes.
Added better error checking for media handling in MVC.
2012-11-16 00:38:03 +05:00
Shannon Deminick 3dd411f159 Working on #U4-1174, lots of updates/fixes to media in MVC regarding loading data from the examine cache to return media + lots of unit tests. 2012-11-15 21:46:54 +05:00
Shannon Deminick 8b141dc51a Working on #U4-1174, lots of updates/fixes to media in MVC + unit tests. 2012-11-15 20:11:10 +05:00
Stephan 278aa3f820 U4-1203 - UmbracoHelper.RenderMacro displays trace output at the wrong place 2012-11-15 13:41:44 -01:00
Shannon Deminick a7a38478db Working on #U4-1174 - issue with TypedMedia in MVC, fixes a few things and ensures Children() works
as expected, adds unit tests.
2012-11-15 04:18:23 +05:00
Shannon Deminick b2e004b825 renamed namespace in test proj 2012-11-15 02:04:46 +05:00
Shannon Deminick 10df6e878c updated config 2012-11-14 22:05:58 +05:00
Shannon Deminick eac11c1b80 cleaned up some of the install auth attribute 2012-11-14 21:22:30 +05:00
Shannon Deminick 0ad5da67ea Merge with 4.10.1 2012-11-14 21:18:34 +05:00
Shannon Deminick 3fb9ffca5b Update for installer rest service, updates version 2012-11-14 19:50:39 +05:00
Stephan 8e7fe5ee55 fix f3a3bdaf6329 2012-11-14 06:40:09 -01:00
Shannon Deminick 9554c6a1c6 Fixes #U4-1174 - allows MVC views to render when using RenderTemplate. Added new UmbracoHelper method RenderTemplate. Cleaned up some code and
ensuring that the string writers are disposed. Moved TemplateRenderer to a better namespace.
2012-11-14 10:47:40 +05:00
Shannon Deminick 8597876c92 Fixed up the library calls to RenderTemplate, no longer a ton of duplicated code and removed
the requirement to build up query strings as this is completley not required since we use 'preserveForm'
in the Server.Execute.
2012-11-14 09:31:20 +05:00
Shannon Deminick 3df7d81bde Fixed up the webforms url gen 2012-11-14 09:19:39 +05:00
Shannon Deminick f82ae4fdda Fixes: #U4-1174, this now works for all webforms related templates, however RenderTemplate will currently not work for
MVC templates... this will come soon. If you try to it will just throw a NotImplementedException.
2012-11-14 09:13:53 +05:00
Shannon Deminick 4a981225b3 Merge 2012-11-14 03:52:34 +05:00
Shannon Deminick 0cd115c268 Fixees: #U4-1166, automatically adds parsable routes in the route table to the reserved paths
so you don't have to explicitly add reserved paths to Umbraco config that you are creating routes for.
2012-11-14 03:32:50 +05:00
Sebastiaan Janssen 291b0582e4 Merge 2012-11-12 07:41:40 -01:00
Sebastiaan Janssen f4e48872a2 Imported pull request by Michiel van Oosterhout (consistent line endings)
Removed some commented out code
Pull: http://umbraco.codeplex.com/SourceControl/network/forks/michielvoo/UmbracoU4451/contribution/3482
2012-11-12 07:40:58 -01:00
Shannon Deminick 9e320700e2 Fixes: #U4-1178, adds another strongly typed overload to GetPropertyValue<T> and adds more unit tests. 2012-11-12 10:50:23 +05:00
Shannon Deminick 7f0ff70ca9 Fixes: #U4-1132, this is a bit of a hack fix because the Media should include creatorName/id but it doesn't. 2012-11-12 09:20:54 +05:00
Shannon Deminick 65e3b7f951 Merge 2012-11-12 08:24:36 +05:00
Shannon Deminick 156f145c69 Updated the build manager to find instances based on persisted cache of previous lookups but uses BuildManager to do so, after
some benchmark unit tests against loading a type from an assembly this is about 100% faster. Updated the UmbracoModule to write more diagnostics
for benchmark debugging. Have basically reduced the startup time to approx 50% of what it used to be based on the current
benchmarks run. Previously app startup on my machine was about 5 seconds, now after the first startup it is about 2.5 seconds.
2012-11-12 08:10:12 +05:00
clausjensen a0c941dac2 Fixes U4-1092 - TinyMce breaks script tags by double wrapping in CDATA on save 2012-11-11 09:50:42 -01:00
Bitmapped 33eb9d40f3 Catches exception thrown by native ActiveDirectoryMembershipProvider when there
is no current user.
Fixes U4-709
2012-11-11 09:40:48 -01:00
Sebastiaan Janssen cf8186653c Merge 2012-11-11 09:19:02 -01:00
Sebastiaan Janssen 75403d3b94 Fix by Tom Witherington - U4-1167 tags not saving or deleting in Tags data type
Also cleaned up the usage of obsolete method calls
2012-11-11 09:17:20 -01:00
Shannon Deminick 083bab0528 Added HashCodeCombiner and unit tests to support. Added ability to create a hashed file based on scanned assemblies in the
PluginManager and added a cached plugin xml file to the PluginManager. Now we don't actually scan any assemblies on app startup
during plugin finding if none of the DLLs have changed. Added trace statements to the UmbracoModule for better benchmarking for
how long a full request takes to load from start to finish.
2012-11-11 09:09:06 +05:00
leekelleher ee3e3787a8 PropertyEditorConverters - reusing TryConvertTo<T>, removing duplicate code. 2012-11-10 21:41:40 +00:00
leekelleher a3895ab149 Added unit tests for PropertyEditorValueConverters. 2012-11-10 21:40:37 +00:00
Matt@MBP13-PC c590c6a265 Fixes issue #U4-1169 wherby Umbraco.Field always runs in the context of the current page regardless of whether a custom IPublishedContent is passed in 2012-11-10 16:40:00 +00:00
leekelleher 6c1bf4b85f Added unit test for ObjectExtensions TryConvertTo<DateTime>.
Modified CustomBooleanTypeConverter to accept an empty string as a FALSE.
2012-11-10 14:09:27 +00:00
Sebastiaan Janssen 3632d6b0c6 Opened branch 4.11.0 2012-11-08 15:31:41 -01:00
Sebastiaan Janssen bf95792524 Merge with 4.10.0 2012-11-08 15:00:52 -01:00
Sebastiaan Janssen 885b421201 Closed branch 4.10.0 2012-11-08 14:48:26 -01:00
Sebastiaan Janssen b11143e2c4 Added tag Release-4.10.0 for changeset f6da531fbb4c 2012-11-08 14:46:56 -01:00
Sebastiaan Janssen 0df1ebb83e Merge 4.9.1 into default 2012-11-01 07:12:47 -01:00
Sebastiaan Janssen 204d7a79aa Closed branch 4.9.1 2012-11-01 07:10:42 -01:00
Sebastiaan Janssen e68629b8bc Added tag Release-4.9.1 for changeset 8d7d8609e2e4 2012-11-01 07:10:31 -01:00
Sebastiaan Janssen 84858bea65 Move the Umbraco.Web.UI project up to the first position in the .sln file so
that when you first clone the project and hit F5 it will actually start the
correct project (and not the class library)
2012-10-30 15:27:59 -01:00
Sebastiaan Janssen 243633365e Re-include ItemEditing javascripts 2012-10-23 10:46:26 -02:00
Sebastiaan Janssen dc7e18b97b Re-include splitbutton.js 2012-10-12 11:41:29 -02:00
Shannon Deminick d3c553c945 Fixes issue with wrapping the UmbEditor init in doc ready causing template editing not to work. 2012-10-12 09:15:33 +05:00
Casey Neehouse 05fc15d164 Wraps Code Editor initialization in a document ready call to correct an IE7
sizing bug.
2012-10-11 13:02:36 +04:00
Morten Bock a71961c35b Indenting 2012-10-08 13:33:18 -02:00
tg@umbraco.com da8af696c5 Fixes U4-680: insert Macro split buttons not working 2012-10-08 08:42:47 -02:00
Sebastiaan Janssen 12f5df33da Add z-index too treePickerToolTip to get it on top when media picker preview is on 2012-10-23 08:24:33 -02:00
Sebastiaan Janssen f184276ef8 Moved tree picker tooltip style to default.css so it also works in editMacro (and elsewhere) 2012-10-07 11:45:22 -02:00
funka@WETWIRED c72ab927a6 Resolves redundant BaseTreePicker script initialization (U4-192) 2012-10-17 05:36:22 +07:00
Sebastiaan Janssen 7bc2375a77 Adds a nice tooltip when hovering over the content/media picker
#U4-192 Fixed
2012-10-06 11:46:37 -02:00
funka@WETWIRED 392fbb836f Resolves feature request U4-192 Add more meta data to Content and Media pickers 2012-10-06 01:26:56 +07:00
Sebastiaan Janssen 0cb8603c80 Updating version number to 4.9.1 2012-10-23 07:14:48 -02:00
Sebastiaan Janssen 20fc02053a Made CodeMirror 100% height again 2012-10-09 12:25:36 -02:00
Sebastiaan Janssen e389dc39a7 Upgrade to CodeMirror 2.34 2012-10-10 11:02:59 -02:00
Sebastiaan Janssen fbd4669da8 Unpublished icon in tree with published node
#U4-387 Fixed
2012-10-15 07:16:32 -02:00
Morten Bock c138c6643a Ignore casing, and avoid null http contexts 2012-10-04 14:48:14 -02:00
Morten Bock a2b876608f Refactoring to use object resolver, instead of ProviderBase 2012-11-21 07:14:40 -01:00
Morten Bock c95c1a7038 Add support for thumbs and crops from standard datatypes. 2012-09-30 20:37:05 -02:00
Morten Bock 9e1c5e71e4 Adding the umbraco:image control, and the ImageUrl feature with a some generic ProviderFeature classes, to make it easier to implement future provider based features. 2012-11-21 07:13:31 -01:00
Sebastiaan Janssen aba68720bb Localized the create window for new Scrips (js) 2012-11-21 06:54:52 -01:00
Sebastiaan Janssen 1b1722c875 Renamed method to remove characters that are illegal in XML and made the method internal for now 2012-11-21 06:23:31 -01:00
Michiel van Oosterhout 248af2eaa2 Correct code that validates the user name when the session times out by serializing
user name and password.

Adds a minified 4KB JSON library to umbraco.aspx to support older browsers, namely
https://github.com/douglascrockford/JSON-js (public domain)
2012-10-07 20:54:34 -02:00
Casey Neehouse 0709174560 Merge 2012-11-20 21:11:11 +05:00
Casey Neehouse b0c0ed050d Adds SQL to validate that a node is published before loading the xml.
U4-759, u4-590, U4-589
2012-11-20 21:09:19 +05:00
Sebastiaan Janssen e3a085774c Revert 5c828605ef65 / 8b3a266b2d00 because that would have nasty side effects,
see http://issues.umbraco.org/issue/U4-1061
2012-11-20 14:49:30 -01:00
Sebastiaan Janssen 6f0ddc37a0 Include System.Data.SqlServerCe* should do a copy local 2012-11-20 14:13:47 -01:00
Sebastiaan Janssen d3eb5ceabe Merge 2012-11-20 12:55:17 -01:00
Stephan 1bffb7395c U4-1192 - uQuery.GetNodeIdByUrl should not follow redirects etc 2012-11-20 09:12:45 -01:00
Stephan e636a42744 .hgignore ~/scripts and ~/images 2012-11-20 08:52:56 -01:00
Stephan d3927a1265 code annotation attributes TLC 2012-11-20 08:49:06 -01:00
Stephan d6fc106588 fix DisposableTimer so args can be evaluated _after_ completion 2012-11-20 08:34:32 -01:00
Stephan 68fc833280 U4-1186 - bugfix previous commit 2012-11-19 16:09:43 -01:00
David@David-PC 5a8443fe72 committed wrong version 2012-11-18 18:48:56 -01:00
David@David-PC 153fb4a248 Do a recursive unpublish (fixes U4-462, U4-594, U4-1061) 2012-11-17 14:25:04 -01:00
Michael Wulff Nielsen 72ef5b01d2 Fixes bug 383, inserting macro parameters with quotes fails in macrocontainer 2012-11-20 09:29:38 -01:00
NielsHartvig@UMBRACORATI.localdomain 0854fee4ee Update to sanitizer 2012-11-16 14:24:24 -01:00
NielsHartvig@UMBRACORATI.localdomain e122d40fb9 The BOSS is fixing U4-367 2012-11-16 14:08:28 -01:00
Sebastiaan Janssen b696aa4340 ApplicationContext.Current.ApplicationCache wasn't public due to an oversight, it is now. 2012-11-19 15:31:58 -01:00
Sebastiaan Janssen e32dd303e3 Have to revert Microsoft.WebApplication.target file change as we got weird
results (umbraco.presentation folder and a XmlSerializers dll in the root).
Copied the targets file to the appropriate Program Files folder on the build
server. :-(
2012-11-19 15:02:43 -01:00
Stephan 7c524abb84 U4-1186 - support wildcard domains to change the culture 2012-11-19 14:11:34 -01:00
Stephan 993bac8a29 bugfix LogHelper 2012-11-19 14:09:52 -01:00
dseefeld 51769847ad Error: Delete media item with upload property - empty recycle bin fails
Fixed #U4-771
2012-09-17 04:06:53 -02:00
Sebastiaan Janssen 918e7ad682 Fixed "inception" media tree bug due to recycle bin auto initializing when it shouldn't 2012-10-23 07:06:50 -02:00
181 changed files with 15173 additions and 8111 deletions
+2
View File
@@ -36,6 +36,8 @@ src\Umbraco.Web.UI\media\*
src\Umbraco.Web.UI\masterpages\*
src\Umbraco.Web.UI\macroScripts\*
src\Umbraco.Web.UI\xslt\*
src\Umbraco.Web.UI\images\*
src\Umbraco.Web.UI\scripts\*
umbraco\presentation\umbraco\plugins\uComponents\uComponentsInstaller.ascx
umbraco\presentation\packages\uComponents\MultiNodePicker\CustomTreeService.asmx
+4 -4
View File
@@ -10,7 +10,7 @@ d03fcffb8834a9583a56813bb44b6abbd9f042cc Release-4.6.0
096f20bb0575d6199f20fcb3147b63554e765a74 Release-4.8.0
8f8a203857886b373148af29edd57460a42940be Release-4.8.1
de73e687ddf6086ed52b6554676c1632865d07f2 Release-4.9.0
de73e687ddf6086ed52b6554676c1632865d07f2 Release-4.9.0
0000000000000000000000000000000000000000 Release-4.9.0
0000000000000000000000000000000000000000 Release-4.9.0
09f5a69cf19ebf7ddd9501e5258bee1e6a125391 Release-4.9.0
8d7d8609e2e4b971da99cd97f72132ce85ce3333 Release-4.9.1
f6da531fbb4c251ff61d314e2a7effb13c71e74a Release-4.10.0
20e4dff821d8ac2527a5353618fa1a23ea1d8b34 Release-4.11.0
7f827760cb49d749616859f528d19dde64807947 Release-4.11.1
+1 -1
View File
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>UmbracoCms.Core</id>
<version>4.10.0</version>
<version>4.11.1</version>
<title>Umbraco Cms Core Binaries</title>
<authors>Morten Christensen</authors>
<owners>Umbraco HQ</owners>
+2 -2
View File
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>UmbracoCms</id>
<version>4.10.0</version>
<version>4.11.1</version>
<title>Umbraco Cms</title>
<authors>Morten Christensen</authors>
<owners>Umbraco HQ</owners>
@@ -15,7 +15,7 @@
<language>en-US</language>
<tags>umbraco</tags>
<dependencies>
<dependency id="UmbracoCms.Core" version="4.9.0" />
<dependency id="UmbracoCms.Core" version="4.11.1" />
</dependencies>
</metadata>
<files>
+2 -1
View File
@@ -43,7 +43,7 @@ namespace Umbraco.Core
/// <remarks>
/// Any caching that is done in the application (app wide) should be done through this property
/// </remarks>
internal CacheHelper ApplicationCache { get; private set; }
public CacheHelper ApplicationCache { get; private set; }
// IsReady is set to true by the boot manager once it has successfully booted
// note - the original umbraco module checks on content.Instance in umbraco.dll
@@ -111,6 +111,7 @@ namespace Umbraco.Core
}
}
}
private string ConfigurationStatus
{
get
+1 -1
View File
@@ -16,7 +16,7 @@ namespace Umbraco.Core
/// <remarks>
/// This class may be opened publicly at some point but needs a review of what is absoletely necessary.
/// </remarks>
internal class CacheHelper
public class CacheHelper
{
private readonly Cache _cache;
@@ -1,28 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Umbraco.Core.CodeAnnotations
{
/// <summary>
/// An attribute used to decorate classes or methods that have been marked to be obsoleted
/// </summary>
/// <remarks>
/// This attribute exists because sometimes we may not want to explicitly [Obsolete] a class or method because we
/// know it is still in use and we don't want warning messages showing up in developers output windows when they compile, however
/// we will be able to produce reports declaring which classes/methods/etc... have been marked for being obsoleted in the near future
/// </remarks>
internal class UmbracoDeprecateAttribute : Attribute
{
/// <summary>
/// Constructor requries a description
/// </summary>
/// <param name="description"></param>
public UmbracoDeprecateAttribute(string description)
{
}
}
}
@@ -3,16 +3,30 @@ using System;
namespace Umbraco.Core.CodeAnnotations
{
/// <summary>
/// An attribute used to decorate classes or methods that have been marked to become public but require more testing and review
/// before this is possible.
/// Marks the program elements that Umbraco is experimenting with and could become public.
/// </summary>
internal class UmbracoExperimentalFeatureAttribute : Attribute
/// <remarks>
/// <para>Indicates that Umbraco is experimenting with code that potentially could become
/// public, but we're not sure, and the code is not stable and can be refactored at any time.</para>
/// <para>The issue tracker should contain more details, discussion, and planning.</para>
/// </remarks>
[AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = false)]
internal sealed class UmbracoExperimentalFeatureAttribute : Attribute
{
/// <summary>
/// constructor requires a tracker url and a description
/// Initializes a new instance of the <see cref="UmbracoExperimentalFeatureAttribute"/> class with a description.
/// </summary>
/// <param name="trackerUrl"></param>
/// <param name="description"></param>
/// <param name="description">The text string that describes what is intended.</param>
public UmbracoExperimentalFeatureAttribute(string description)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="UmbracoExperimentalFeatureAttribute"/> class with a tracker url and a description.
/// </summary>
/// <param name="trackerUrl">The url of a tracker issue containing more details, discussion, and planning.</param>
/// <param name="description">The text string that describes what is intended.</param>
public UmbracoExperimentalFeatureAttribute(string trackerUrl, string description)
{
@@ -3,20 +3,31 @@ using System;
namespace Umbraco.Core.CodeAnnotations
{
/// <summary>
/// An attribute used to decorate classes or methods that have potential to become part of the public API
/// Marks the program elements that Umbraco is considering making public.
/// </summary>
/// <remarks>
/// Classes, properties or methods marked with this attribute will have a tracker URL assigned where discussions may take place
/// regarding whether or not this should become part of the public APIs and if/when. Please note that any objects marked with this
/// attribute may not ever become public, this attribute exists to tag code that has potential to become public pending reviews.
/// <para>Indicates that Umbraco considers making the (currently internal) program element public
/// at some point in the future, but the decision is not fully made yet and is still pending reviews.</para>
/// <para>Note that it is not a commitment to make the program element public. It may not ever become public.</para>
/// <para>The issue tracker should contain more details, discussion, and planning.</para>
/// </remarks>
internal class UmbracoProposedPublicAttribute : Attribute
[AttributeUsage(AttributeTargets.All, AllowMultiple=false, Inherited=false)]
internal sealed class UmbracoProposedPublicAttribute : Attribute
{
/// <summary>
/// constructor requires a tracker url and a description
/// Initializes a new instance of the <see cref="UmbracoProposedPublicAttribute"/> class with a description.
/// </summary>
/// <param name="trackerUrl"></param>
/// <param name="description"></param>
/// <param name="description">The text string that describes what is intended.</param>
public UmbracoProposedPublicAttribute(string description)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="UmbracoProposedPublicAttribute"/> class with a tracker url and a description.
/// </summary>
/// <param name="trackerUrl">The url of a tracker issue containing more details, discussion, and planning.</param>
/// <param name="description">The text string that describes what is intended.</param>
public UmbracoProposedPublicAttribute(string trackerUrl, string description)
{
@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Umbraco.Core.CodeAnnotations
{
/// <summary>
/// Marks the program elements that Umbraco will obsolete.
/// </summary>
/// <remarks>
/// Indicates that Umbraco will obsolete the program element at some point in the future, but we do not want to
/// explicitely mark it [Obsolete] yet to avoid warning messages showing when developers compile Umbraco.
/// </remarks>
[AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = false)]
internal sealed class UmbracoWillObsoleteAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="UmbracoWillObsoleteAttribute"/> class with a description.
/// </summary>
/// <param name="description">The text string that describes what is intended.</param>
public UmbracoWillObsoleteAttribute(string description)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="UmbracoWillObsoleteAttribute"/> class with a tracker url and a description.
/// </summary>
/// <param name="trackerUrl">The url of a tracker issue containing more details, discussion, and planning.</param>
/// <param name="description">The text string that describes what is intended.</param>
public UmbracoWillObsoleteAttribute(string trackerUrl, string description)
{
}
}
}
@@ -4,6 +4,7 @@ using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Configuration;
using System.Web.Routing;
using System.Xml;
using System.Xml.Linq;
using Umbraco.Core.IO;
@@ -27,7 +28,7 @@ namespace Umbraco.Core.Configuration
#region Private static fields
// CURRENT UMBRACO VERSION ID
private const string CurrentUmbracoVersion = "4.10.0";
private const string CurrentUmbracoVersion = "4.11.1";
private static string _reservedUrlsCache;
private static string _reservedPathsCache;
@@ -57,9 +58,9 @@ namespace Umbraco.Core.Configuration
{
get
{
return ConfigurationManager.AppSettings.ContainsKey("umbracoReservedPaths")
? ConfigurationManager.AppSettings["umbracoReservedPaths"]
: string.Empty;
return ConfigurationManager.AppSettings.ContainsKey("umbracoReservedPaths")
? ConfigurationManager.AppSettings["umbracoReservedPaths"]
: string.Empty;
}
}
@@ -549,7 +550,29 @@ namespace Umbraco.Core.Configuration
}
}
/// <summary>
/// <summary>
/// Determines whether the current request is reserved based on the route table and
/// whether the specified URL is reserved or is inside a reserved path.
/// </summary>
/// <param name="url"></param>
/// <param name="httpContext"></param>
/// <param name="routes">The route collection to lookup the request in</param>
/// <returns></returns>
public static bool IsReservedPathOrUrl(string url, HttpContextBase httpContext, RouteCollection routes)
{
if (httpContext == null) throw new ArgumentNullException("httpContext");
if (routes == null) throw new ArgumentNullException("routes");
//check if the current request matches a route, if so then it is reserved.
var route = routes.GetRouteData(httpContext);
if (route != null)
return true;
//continue with the standard ignore routine
return IsReservedPathOrUrl(url);
}
/// <summary>
/// Determines whether the specified URL is reserved or is inside a reserved path.
/// </summary>
/// <param name="url">The URL to check.</param>
@@ -557,7 +580,7 @@ namespace Umbraco.Core.Configuration
/// <c>true</c> if the specified URL is reserved; otherwise, <c>false</c>.
/// </returns>
public static bool IsReservedPathOrUrl(string url)
{
{
// check if GlobalSettings.ReservedPaths and GlobalSettings.ReservedUrls are unchanged
if (!object.ReferenceEquals(_reservedPathsCache, GlobalSettings.ReservedPaths)
|| !object.ReferenceEquals(_reservedUrlsCache, GlobalSettings.ReservedUrls))
@@ -25,6 +25,18 @@ namespace Umbraco.Core.Configuration
/// </summary>
internal class UmbracoSettings
{
/// <summary>
/// Used in unit testing to reset all config items that were set with property setters (i.e. did not come from config)
/// </summary>
internal static void ResetSetters()
{
_addTrailingSlash = null;
_forceSafeAliases = null;
_useLegacySchema = null;
_useDomainPrefixes = null;
_umbracoLibraryCacheDuration = null;
}
internal const string TempFriendlyXmlChildContainerNodename = ""; // "children";
/// <summary>
@@ -601,6 +613,8 @@ namespace Umbraco.Core.Configuration
}
}
private static bool? _forceSafeAliases;
/// <summary>
/// Whether to force safe aliases (no spaces, no special characters) at businesslogic level on contenttypes and propertytypes
/// </summary>
@@ -608,6 +622,9 @@ namespace Umbraco.Core.Configuration
{
get
{
if (_forceSafeAliases.HasValue)
return _forceSafeAliases.Value;
string forceSafeAlias = GetKey("/settings/content/ForceSafeAliases");
if (String.IsNullOrEmpty(forceSafeAlias))
return true;
@@ -622,7 +639,11 @@ namespace Umbraco.Core.Configuration
return true;
}
}
}
internal set
{
//used for unit testing
_forceSafeAliases = value;
}
}
@@ -645,6 +666,8 @@ namespace Umbraco.Core.Configuration
get { return GetKey("/settings/content/scripteditor/scriptFileTypes"); }
}
private static int? _umbracoLibraryCacheDuration;
/// <summary>
/// Gets the duration in seconds to cache queries to umbraco library member and media methods
/// Default is 1800 seconds (30 minutes)
@@ -653,6 +676,9 @@ namespace Umbraco.Core.Configuration
{
get
{
if (_umbracoLibraryCacheDuration.HasValue)
return _umbracoLibraryCacheDuration.Value;
string libraryCacheDuration = GetKey("/settings/content/UmbracoLibraryCacheDuration");
if (String.IsNullOrEmpty(libraryCacheDuration))
return 1800;
@@ -669,6 +695,7 @@ namespace Umbraco.Core.Configuration
}
}
internal set { _umbracoLibraryCacheDuration = value; }
}
/// <summary>
@@ -23,7 +23,7 @@ namespace Umbraco.Core
{
var str = (string)value;
if (str == "1") return true;
if (str == "0") return false;
if (str == "0" || str == "") return false;
}
return base.ConvertFrom(context, culture, value);
+123 -87
View File
@@ -4,99 +4,135 @@ using Umbraco.Core.Logging;
namespace Umbraco.Core
{
/// <summary>
/// Starts the timer and invokes a callback upon disposal. Provides a simple way of timing an operation by wrapping it in a <code>using</code> (C#) statement.
/// </summary>
/// <example>
/// <code>
/// Console.WriteLine("Testing Stopwatchdisposable, should be 567:");
// using (var timer = new DisposableTimer(result => Console.WriteLine("Took {0}ms", result)))
// {
// Thread.Sleep(567);
// }
/// </code>
/// </example>
public class DisposableTimer : DisposableObject
{
private readonly Stopwatch _stopwatch = Stopwatch.StartNew();
private readonly Action<long> _callback;
/// <summary>
/// Starts the timer and invokes a callback upon disposal. Provides a simple way of timing an operation by wrapping it in a <code>using</code> (C#) statement.
/// </summary>
/// <example>
/// <code>
/// Console.WriteLine("Testing Stopwatchdisposable, should be 567:");
// using (var timer = new DisposableTimer(result => Console.WriteLine("Took {0}ms", result)))
// {
// Thread.Sleep(567);
// }
/// </code>
/// </example>
public class DisposableTimer : DisposableObject
{
private readonly Stopwatch _stopwatch = Stopwatch.StartNew();
private readonly Action<long> _callback;
protected DisposableTimer(Action<long> callback)
{
_callback = callback;
}
protected DisposableTimer(Action<long> callback)
{
_callback = callback;
}
public Stopwatch Stopwatch
{
get { return _stopwatch; }
}
public Stopwatch Stopwatch
{
get { return _stopwatch; }
}
/// <summary>
/// Starts the timer and invokes the specified callback upon disposal.
/// </summary>
/// <param name="callback">The callback.</param>
/// <returns></returns>
public static DisposableTimer Start(Action<long> callback)
{
return new DisposableTimer(callback);
}
/// <summary>
/// Starts the timer and invokes the specified callback upon disposal.
/// </summary>
/// <param name="callback">The callback.</param>
/// <returns></returns>
public static DisposableTimer Start(Action<long> callback)
{
return new DisposableTimer(callback);
}
/// <summary>
/// Adds a start and end log entry as Info and tracks how long it takes until disposed.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="startMessage"></param>
/// <param name="completeMessage"></param>
/// <returns></returns>
public static DisposableTimer TraceDuration<T>(string startMessage, string completeMessage)
{
return TraceDuration(typeof(T), startMessage, completeMessage);
}
public static DisposableTimer TraceDuration<T>(Func<string> startMessage, Func<string> completeMessage)
{
return TraceDuration(typeof(T), startMessage, completeMessage);
}
/// <summary>
/// Adds a start and end log entry as Info and tracks how long it takes until disposed.
/// </summary>
/// <param name="loggerType"></param>
/// <param name="startMessage"></param>
/// <param name="completeMessage"></param>
/// <returns></returns>
public static DisposableTimer TraceDuration(Type loggerType, string startMessage, string completeMessage)
{
LogHelper.Info(loggerType, () => startMessage);
return new DisposableTimer(x => LogHelper.Info(loggerType, () => completeMessage + " (took " + x + "ms)"));
}
public static DisposableTimer TraceDuration(Type loggerType, Func<string> startMessage, Func<string> completeMessage)
{
LogHelper.Debug(loggerType, startMessage);
return new DisposableTimer(x => LogHelper.Info(loggerType, () => completeMessage() + " (took " + x + "ms)"));
}
/// <summary>
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="startMessage"></param>
/// <param name="completeMessage"></param>
/// <returns></returns>
public static DisposableTimer DebugDuration<T>(string startMessage, string completeMessage)
{
return DebugDuration(typeof(T), startMessage, completeMessage);
}
/// <summary>
/// Adds a start and end log entry as Info and tracks how long it takes until disposed.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="startMessage"></param>
/// <param name="completeMessage"></param>
/// <returns></returns>
public static DisposableTimer TraceDuration<T>(string startMessage, string completeMessage)
{
return TraceDuration(typeof(T), startMessage, completeMessage);
}
/// <summary>
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
/// </summary>
/// <param name="loggerType"></param>
/// <param name="startMessage"></param>
/// <param name="completeMessage"></param>
/// <returns></returns>
public static DisposableTimer DebugDuration(Type loggerType, string startMessage, string completeMessage)
{
LogHelper.Debug(loggerType, () => startMessage);
return new DisposableTimer(x => LogHelper.Debug(loggerType, () => completeMessage + " (took " + x + "ms)"));
}
/// <summary>
/// Adds a start and end log entry as Info and tracks how long it takes until disposed.
/// </summary>
/// <param name="loggerType"></param>
/// <param name="startMessage"></param>
/// <param name="completeMessage"></param>
/// <returns></returns>
public static DisposableTimer TraceDuration(Type loggerType, string startMessage, string completeMessage)
{
LogHelper.Info(loggerType, () => startMessage);
return new DisposableTimer(x => LogHelper.Info(loggerType, () => completeMessage + " (took " + x + "ms)"));
}
/// <summary>
/// Handles the disposal of resources. Derived from abstract class <see cref="DisposableObject"/> which handles common required locking logic.
/// </summary>
protected override void DisposeResources()
{
_callback.Invoke(Stopwatch.ElapsedMilliseconds);
}
}
/// <summary>
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="startMessage"></param>
/// <param name="completeMessage"></param>
/// <returns></returns>
public static DisposableTimer DebugDuration<T>(string startMessage, string completeMessage)
{
return DebugDuration(typeof(T), startMessage, completeMessage);
}
/// <summary>
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="startMessage"></param>
/// <param name="completeMessage"></param>
/// <returns></returns>
public static DisposableTimer DebugDuration<T>(Func<string> startMessage, Func<string> completeMessage)
{
return DebugDuration(typeof(T), startMessage, completeMessage);
}
/// <summary>
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
/// </summary>
/// <param name="loggerType"></param>
/// <param name="startMessage"></param>
/// <param name="completeMessage"></param>
/// <returns></returns>
public static DisposableTimer DebugDuration(Type loggerType, string startMessage, string completeMessage)
{
LogHelper.Debug(loggerType, () => startMessage);
return new DisposableTimer(x => LogHelper.Debug(loggerType, () => completeMessage + " (took " + x + "ms)"));
}
/// <summary>
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
/// </summary>
/// <param name="loggerType"></param>
/// <param name="startMessage"></param>
/// <param name="completeMessage"></param>
/// <returns></returns>
public static DisposableTimer DebugDuration(Type loggerType, Func<string> startMessage, Func<string> completeMessage)
{
LogHelper.Debug(loggerType, startMessage);
return new DisposableTimer(x => LogHelper.Debug(loggerType, () => completeMessage() + " (took " + x + "ms)"));
}
/// <summary>
/// Handles the disposal of resources. Derived from abstract class <see cref="DisposableObject"/> which handles common required locking logic.
/// </summary>
protected override void DisposeResources()
{
_callback.Invoke(Stopwatch.ElapsedMilliseconds);
}
}
}
@@ -0,0 +1,178 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Reflection;
using System.Text;
using Umbraco.Core.Logging;
namespace Umbraco.Core.Dynamics
{
/// <summary>
/// A helper class to try invoke members, find properties, etc...
/// </summary>
internal class DynamicInstanceHelper
{
internal class TryInvokeMemberResult
{
public object ObjectResult { get; private set; }
public TryInvokeMemberSuccessReason Reason { get; private set; }
public TryInvokeMemberResult(object result, TryInvokeMemberSuccessReason reason)
{
ObjectResult = result;
Reason = reason;
}
}
internal enum TryInvokeMemberSuccessReason
{
FoundProperty,
FoundMethod,
FoundExtensionMethod
}
/// <summary>
/// Attempts to invoke a member based on the dynamic instance
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="thisObject">The object instance to invoke the extension method for</param>
/// <param name="binder"></param>
/// <param name="args"></param>
/// <returns></returns>
/// <remarks>
/// First tries to find a property with the binder name, if that fails it will try to find a static or instance method
/// on the object that matches the binder name
/// </remarks>
public static Attempt<TryInvokeMemberResult> TryInvokeMember<T>(T thisObject, InvokeMemberBinder binder, object[] args)
{
return TryInvokeMember<T>(thisObject, binder, args, null);
}
/// <summary>
/// Attempts to invoke a member based on the dynamic instance
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="thisObject">The object instance to invoke the extension method for</param>
/// <param name="binder"></param>
/// <param name="args"></param>
/// <param name="findExtensionMethodsOnTypes">The types to scan for extension methods </param>
/// <returns></returns>
/// <remarks>
/// First tries to find a property with the binder name, if that fails it will try to find a static or instance method
/// on the object that matches the binder name, if that fails it will then attempt to invoke an extension method
/// based on the binder name and the extension method types to scan.
/// </remarks>
public static Attempt<TryInvokeMemberResult> TryInvokeMember<T>(T thisObject,
InvokeMemberBinder binder,
object[] args,
IEnumerable<Type> findExtensionMethodsOnTypes)
{
//TODO: We MUST cache the result here, it is very expensive to keep finding extension methods!
object result;
try
{
//Property?
result = typeof(T).InvokeMember(binder.Name,
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.GetProperty,
null,
thisObject,
args);
return new Attempt<TryInvokeMemberResult>(true, new TryInvokeMemberResult(result, TryInvokeMemberSuccessReason.FoundProperty));
}
catch (MissingMethodException)
{
try
{
//Static or Instance Method?
result = typeof(T).InvokeMember(binder.Name,
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.Static |
System.Reflection.BindingFlags.InvokeMethod,
null,
thisObject,
args);
return new Attempt<TryInvokeMemberResult>(true, new TryInvokeMemberResult(result, TryInvokeMemberSuccessReason.FoundMethod));
}
catch (MissingMethodException)
{
if (findExtensionMethodsOnTypes != null)
{
try
{
result = FindAndExecuteExtensionMethod(thisObject, args, binder.Name, findExtensionMethodsOnTypes);
return new Attempt<TryInvokeMemberResult>(true, new TryInvokeMemberResult(result, TryInvokeMemberSuccessReason.FoundExtensionMethod));
}
catch (TargetInvocationException ext)
{
//don't log here, we return this exception because the caller may need to do something specific when
//this exception occurs.
return new Attempt<TryInvokeMemberResult>(ext);
}
catch (Exception ex)
{
var sb = new StringBuilder("An error occurred finding an executing an extension method for type ");
sb.Append(typeof (T));
sb.Append("Types searched for extension methods were ");
foreach(var t in findExtensionMethodsOnTypes)
{
sb.Append(t + ",");
}
LogHelper.Error<DynamicInstanceHelper>(sb.ToString(), ex);
return new Attempt<TryInvokeMemberResult>(ex);
}
}
return Attempt<TryInvokeMemberResult>.False;
}
}
catch (Exception ex)
{
LogHelper.Error<DynamicInstanceHelper>("An unhandled exception occurred in method TryInvokeMember", ex);
return new Attempt<TryInvokeMemberResult>(ex);
}
}
/// <summary>
/// Attempts to find an extension method that matches the name and arguments based on scanning the Type's passed in
/// to the findMethodsOnTypes parameter
/// </summary>
/// <param name="thisObject">The instance object to execute the extension method for</param>
/// <param name="args"></param>
/// <param name="name"></param>
/// <param name="findMethodsOnTypes"></param>
/// <returns></returns>
internal static object FindAndExecuteExtensionMethod<T>(T thisObject,
object[] args,
string name,
IEnumerable<Type> findMethodsOnTypes)
{
object result = null;
//find known extension methods that match the first type in the list
MethodInfo toExecute = null;
foreach (var t in findMethodsOnTypes)
{
toExecute = ExtensionMethodFinder.FindExtensionMethod(t, args, name, false);
if (toExecute != null)
break;
}
if (toExecute != null)
{
var genericArgs = (new[] { (object)thisObject }).Concat(args);
result = toExecute.Invoke(null, genericArgs.ToArray());
}
else
{
throw new MissingMethodException();
}
return result;
}
}
}
+79 -9
View File
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Dynamic;
using System.Reflection;
using System.Xml.Linq;
using System.Xml.XPath;
using System.Collections;
@@ -10,7 +11,7 @@ using System.Web;
namespace Umbraco.Core.Dynamics
{
public class DynamicXml : DynamicObject, IEnumerable
public class DynamicXml : DynamicObject, IEnumerable<DynamicXml>, IEnumerable<XElement>
{
public XElement BaseElement { get; set; }
@@ -70,7 +71,53 @@ namespace Umbraco.Core.Dynamics
HandleIEnumerableXElement(elements, out result);
return true; //anyway
}
return base.TryInvokeMember(binder, args, out result);
//ok, now lets try to match by member, property, extensino method
var attempt = DynamicInstanceHelper.TryInvokeMember(this, binder, args, new[]
{
typeof (IEnumerable<DynamicXml>),
typeof (IEnumerable<XElement>),
typeof (DynamicXml)
});
if (attempt.Success)
{
result = attempt.Result.ObjectResult;
//need to check the return type and possibly cast if result is from an extension method found
if (attempt.Result.Reason == DynamicInstanceHelper.TryInvokeMemberSuccessReason.FoundExtensionMethod)
{
//if the result is already a DynamicXml instance, then we do not need to cast
if (attempt.Result.ObjectResult != null && !(attempt.Result.ObjectResult is DynamicXml))
{
if (attempt.Result.ObjectResult is XElement)
{
result = new DynamicXml((XElement)attempt.Result.ObjectResult);
}
else if (attempt.Result.ObjectResult is IEnumerable<XElement>)
{
result = ((IEnumerable<XElement>)attempt.Result.ObjectResult).Select(x => new DynamicXml(x));
}
else if (attempt.Result.ObjectResult is IEnumerable<DynamicXml>)
{
result = ((IEnumerable<DynamicXml>)attempt.Result.ObjectResult).Select(x => new DynamicXml(x.BaseElement));
}
}
}
return true;
}
//this is the result of an extension method execution gone wrong so we return dynamic null
if (attempt.Result.Reason == DynamicInstanceHelper.TryInvokeMemberSuccessReason.FoundExtensionMethod
&& attempt.Error != null && attempt.Error is TargetInvocationException)
{
result = new DynamicNull();
return true;
}
result = null;
return false;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
@@ -181,20 +228,41 @@ namespace Umbraco.Core.Dynamics
return new DynamicXml(this.BaseElement.XPathSelectElements(expression).FirstOrDefault());
}
public IEnumerator GetEnumerator()
{
return this.BaseElement.Elements().Select(e => new DynamicXml(e)).GetEnumerator();
}
IEnumerator<XElement> IEnumerable<XElement>.GetEnumerator()
{
return this.BaseElement.Elements().GetEnumerator();
}
public IEnumerator<DynamicXml> GetEnumerator()
{
return this.BaseElement.Elements().Select(e => new DynamicXml(e)).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public int Count()
{
return this.BaseElement.Elements().Count();
return ((IEnumerable<XElement>)this).Count();
}
public bool Any()
{
return this.BaseElement.Elements().Any();
return ((IEnumerable<XElement>)this).Any();
}
public IEnumerable<DynamicXml> Take(int count)
{
return ((IEnumerable<DynamicXml>)this).Take(count);
}
public IEnumerable<DynamicXml> Skip(int count)
{
return ((IEnumerable<DynamicXml>)this).Skip(count);
}
public bool IsNull()
{
return false;
@@ -514,7 +582,7 @@ namespace Umbraco.Core.Dynamics
}
public IEnumerable<DynamicXml> Ancestors(Func<XElement, bool> func)
{
List<XElement> ancestorList = new List<XElement>();
var ancestorList = new List<XElement>();
var node = this.BaseElement;
while (node != null)
{
@@ -661,5 +729,7 @@ namespace Umbraco.Core.Dynamics
}
}
}
}
}
@@ -44,7 +44,7 @@ namespace Umbraco.Core.Dynamics
);
//add the extension methods defined in IEnumerable
candidates = candidates.Concat(typeof(IEnumerable).GetMethods(BindingFlags.Static | BindingFlags.Public));
candidates = candidates.Concat(typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public));
//filter by name
var methodsByName = candidates.Where(m => m.Name == name);
+94
View File
@@ -0,0 +1,94 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
namespace Umbraco.Core
{
/// <summary>
/// Used to create a hash code from multiple objects.
/// </summary>
/// <remarks>
/// .Net has a class the same as this: System.Web.Util.HashCodeCombiner and of course it works for all sorts of things
/// which we've not included here as we just need a quick easy class for this in order to create a unique
/// hash of directories/files to see if they have changed.
/// </remarks>
internal class HashCodeCombiner
{
private long _combinedHash = 5381L;
internal void AddInt(int i)
{
_combinedHash = ((_combinedHash << 5) + _combinedHash) ^ i;
}
internal void AddObject(object o)
{
AddInt(o.GetHashCode());
}
internal void AddDateTime(DateTime d)
{
AddInt(d.GetHashCode());
}
internal void AddCaseInsensitiveString(string s)
{
if (s != null)
AddInt((StringComparer.InvariantCultureIgnoreCase).GetHashCode(s));
}
internal void AddFileSystemItem(FileSystemInfo f)
{
//if it doesn't exist, don't proceed.
if (!f.Exists)
return;
AddCaseInsensitiveString(f.FullName);
AddDateTime(f.CreationTimeUtc);
AddDateTime(f.LastWriteTimeUtc);
//check if it is a file or folder
var fileInfo = f as FileInfo;
if (fileInfo != null)
{
AddInt(fileInfo.Length.GetHashCode());
}
var dirInfo = f as DirectoryInfo;
if (dirInfo != null)
{
foreach (var d in dirInfo.GetFiles())
{
AddFile(d);
}
foreach (var s in dirInfo.GetDirectories())
{
AddFolder(s);
}
}
}
internal void AddFile(FileInfo f)
{
AddFileSystemItem(f);
}
internal void AddFolder(DirectoryInfo d)
{
AddFileSystemItem(d);
}
/// <summary>
/// Returns the hex code of the combined hash code
/// </summary>
/// <returns></returns>
internal string GetCombinedHashCode()
{
return _combinedHash.ToString("x", CultureInfo.InvariantCulture);
}
}
}
+1
View File
@@ -12,6 +12,7 @@ namespace Umbraco.Core.IO
//all paths has a starting but no trailing /
public class SystemDirectories
{
//TODO: Why on earth is this even configurable? You cannot change the /Bin folder in ASP.Net
public static string Bin
{
get
+2 -1
View File
@@ -220,7 +220,8 @@ namespace Umbraco.Core.Logging
{
if (trace != null)
{
trace.Write(string.Format(generateMessageFormat, formatItems.Select(x => x())));
// must .ToArray() here else string.Format sees only one parameter
trace.Write(string.Format(generateMessageFormat, formatItems.Select(x => x()).ToArray()));
}
Debug(typeof(T), generateMessageFormat, formatItems);
}
@@ -0,0 +1,11 @@
using System.Collections.Generic;
namespace Umbraco.Core.Media
{
public interface IImageUrlProvider
{
string Name { get; }
string GetImageUrlFromMedia(int mediaId, IDictionary<string, string> parameters);
string GetImageUrlFromFileName(string specifiedSrc, IDictionary<string, string> parameters);
}
}
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using Umbraco.Core.Macros;
using umbraco.interfaces;
@@ -47,7 +48,7 @@ namespace Umbraco.Core.ObjectResolution
/// </remarks>
internal string GetValueFromMacroControl(Control macroControl)
{
return ((IMacroGuiRendering)macroControl).Value;
return HttpUtility.HtmlDecode(((IMacroGuiRendering)macroControl).Value);
}
/// <remarks>
@@ -74,7 +75,7 @@ namespace Umbraco.Core.ObjectResolution
{
if (!string.IsNullOrEmpty(prop.Value))
{
instance.Value = prop.Value;
instance.Value = HttpUtility.HtmlDecode(prop.Value);
}
var macroControl = instance as Control;
if (macroControl != null)
File diff suppressed because it is too large Load Diff
@@ -21,16 +21,7 @@ namespace Umbraco.Core.PropertyEditors
/// <returns></returns>
public Attempt<object> ConvertPropertyValue(object value)
{
if (value == null) return new Attempt<object>(false, null);
//if its already a DateTime
if (TypeHelper.IsTypeAssignableFrom<DateTime>(value))
return new Attempt<object>(true, value);
//convert to string
var asString = Convert.ToString(value);
DateTime dt;
return DateTime.TryParse(asString, out dt)
? new Attempt<object>(true, dt)
: new Attempt<object>(false, null);
return value.TryConvertTo(typeof(DateTime));
}
}
}
@@ -16,18 +16,7 @@ namespace Umbraco.Core.PropertyEditors
/// <returns></returns>
public Attempt<object> ConvertPropertyValue(object value)
{
if (value == null) return new Attempt<object>(false, null);
//if its already a bool
if (TypeHelper.IsTypeAssignableFrom<bool>(value))
return new Attempt<object>(true, value);
//convert to string
var asString = Convert.ToString(value);
bool asBool;
return bool.TryParse(asString, out asBool)
? new Attempt<object>(true, asBool)
: bool.TryParse(asString.Replace("1", "true").Replace("0", "false"), out asBool) //convert 0 or 1 to true or false
? new Attempt<object>(true, asBool)
: new Attempt<object>(false, null);
return value.TryConvertTo(typeof(bool));
}
}
}
+56 -19
View File
@@ -1,9 +1,8 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net.Mime;
using System.Web;
using Umbraco.Core.Dynamics;
using Umbraco.Core.Models;
using umbraco.interfaces;
@@ -14,6 +13,7 @@ namespace Umbraco.Core
/// </summary>
public static class PublishedContentExtensions
{
#region GetProperty
@@ -41,24 +41,33 @@ namespace Umbraco.Core
#endregion
#region GetPropertyValue
public static string GetPropertyValue(this IPublishedContent doc, string alias)
public static object GetPropertyValue(this IPublishedContent doc, string alias)
{
return doc.GetPropertyValue(alias, false);
}
public static string GetPropertyValue(this IPublishedContent doc, string alias, string fallback)
public static object GetPropertyValue(this IPublishedContent doc, string alias, string fallback)
{
var prop = doc.GetPropertyValue(alias);
return !prop.IsNullOrWhiteSpace() ? prop : fallback;
return (prop != null && !Convert.ToString(prop).IsNullOrWhiteSpace()) ? prop : fallback;
}
public static string GetPropertyValue(this IPublishedContent doc, string alias, bool recursive)
public static object GetPropertyValue(this IPublishedContent doc, string alias, bool recursive)
{
var p = doc.GetProperty(alias, recursive);
return p == null ? null : Convert.ToString(p.Value);
if (p == null) return null;
//Here we need to put the value through the IPropertyEditorValueConverter's
//get the data type id for the current property
var dataType = PublishedContentHelper.GetDataType(doc.DocumentTypeAlias, alias);
//convert the string value to a known type
var converted = PublishedContentHelper.ConvertPropertyValue(p.Value, dataType, doc.DocumentTypeAlias, alias);
return converted.Success
? converted.Result
: p.Value;
}
public static string GetPropertyValue(this IPublishedContent doc, string alias, bool recursive, string fallback)
public static object GetPropertyValue(this IPublishedContent doc, string alias, bool recursive, string fallback)
{
var prop = doc.GetPropertyValue(alias, recursive);
return !prop.IsNullOrWhiteSpace() ? prop : fallback;
return (prop != null && !Convert.ToString(prop).IsNullOrWhiteSpace()) ? prop : fallback;
}
#endregion
@@ -125,23 +134,51 @@ namespace Umbraco.Core
/// then the default value of type T is returned.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="prop"></param>
/// <param name="doc"></param>
/// <param name="alias"></param>
/// <returns></returns>
public static T GetPropertyValue<T>(this IPublishedContent prop, string alias)
public static T GetPropertyValue<T>(this IPublishedContent doc, string alias)
{
return prop.GetPropertyValue<T>(alias, default(T));
return doc.GetPropertyValue<T>(alias, default(T));
}
public static T GetPropertyValue<T>(this IPublishedContent prop, string alias, bool recursive, T ifCannotConvert)
{
var p = prop.GetProperty(alias, recursive);
if (p == null)
return ifCannotConvert;
//before we try to convert it manually, lets see if the PropertyEditorValueConverter does this for us
//Here we need to put the value through the IPropertyEditorValueConverter's
//get the data type id for the current property
var dataType = PublishedContentHelper.GetDataType(prop.DocumentTypeAlias, alias);
//convert the value to a known type
var converted = PublishedContentHelper.ConvertPropertyValue(p.Value, dataType, prop.DocumentTypeAlias, alias);
if (converted.Success)
{
//if its successful, check if its the correct type and return it
if (converted.Result is T)
{
return (T)converted.Result;
}
//if that's not correct, try converting the converted type
var reConverted = converted.Result.TryConvertTo<T>();
if (reConverted.Success)
{
return reConverted.Result;
}
}
//last, if all the above has failed, we'll just try converting the raw value straight to 'T'
var manualConverted = p.Value.TryConvertTo<T>();
if (manualConverted.Success)
return manualConverted.Result;
return ifCannotConvert;
}
public static T GetPropertyValue<T>(this IPublishedContent prop, string alias, T ifCannotConvert)
{
var p = prop.GetProperty(alias);
if (p == null)
return default(T);
var converted = p.Value.TryConvertTo<T>();
if (converted.Success)
return converted.Result;
return ifCannotConvert;
return prop.GetPropertyValue<T>(alias, false, ifCannotConvert);
}
}
+103
View File
@@ -0,0 +1,103 @@
using System;
using System.Linq;
using System.Xml.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Dynamics;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Core
{
internal class PublishedContentHelper
{
/// <summary>
/// This callback is used only so we can set it dynamically because in the "Core" project currently we don't have
/// access to the business logic layer.
/// TODO: Once 6.0 is released we need to change this to use the new business logic layer that we can access from
/// this proejct. Until then this will return a Guid.Empty but the callback will need to be set in the WebBootManager
/// to work in the website. if people use this in a non-web aspect without the WebBootManager, the the IPropertyEditorValueConverters
/// will not be executed.
/// </summary>
internal static Func<string, string, Guid> GetDataTypeCallback = (docTypeAlias, propertyAlias) => Guid.Empty;
internal static Guid GetDataType(string docTypeAlias, string propertyAlias)
{
return GetDataTypeCallback(docTypeAlias, propertyAlias);
}
/// <summary>
/// Converts the currentValue to a correctly typed value based on known registered converters, then based on known standards.
/// </summary>
/// <param name="currentValue"></param>
/// <param name="dataType"></param>
/// <param name="docTypeAlias"></param>
/// <param name="propertyTypeAlias"></param>
/// <returns></returns>
internal static Attempt<object> ConvertPropertyValue(object currentValue, Guid dataType, string docTypeAlias, string propertyTypeAlias)
{
if (currentValue == null) return Attempt<object>.False;
//First lets check all registered converters for this data type.
var converters = PropertyEditorValueConvertersResolver.Current.Converters
.Where(x => x.IsConverterFor(dataType, docTypeAlias, propertyTypeAlias))
.ToArray();
//try to convert the value with any of the converters:
foreach (var converted in converters
.Select(p => p.ConvertPropertyValue(currentValue))
.Where(converted => converted.Success))
{
return new Attempt<object>(true, converted.Result);
}
//if none of the converters worked, then we'll process this from what we know
var sResult = Convert.ToString(currentValue).Trim();
//this will eat csv strings, so only do it if the decimal also includes a decimal seperator (according to the current culture)
if (sResult.Contains(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator))
{
decimal dResult;
if (decimal.TryParse(sResult, System.Globalization.NumberStyles.Number, System.Globalization.CultureInfo.CurrentCulture, out dResult))
{
return new Attempt<object>(true, dResult);
}
}
//process string booleans as booleans
if (sResult.InvariantEquals("true"))
{
return new Attempt<object>(true, true);
}
if (sResult.InvariantEquals("false"))
{
return new Attempt<object>(true, false);
}
//a really rough check to see if this may be valid xml
//TODO: This is legacy code, I'm sure there's a better and nicer way
if (sResult.StartsWith("<") && sResult.EndsWith(">") && sResult.Contains("/"))
{
try
{
var e = XElement.Parse(DynamicXml.StripDashesInElementOrAttributeNames(sResult), LoadOptions.None);
//check that the document element is not one of the disallowed elements
//allows RTE to still return as html if it's valid xhtml
var documentElement = e.Name.LocalName;
//TODO: See note against this setting, pretty sure we don't need this
if (!UmbracoSettings.NotDynamicXmlDocumentElements.Any(
tag => string.Equals(tag, documentElement, StringComparison.CurrentCultureIgnoreCase)))
{
return new Attempt<object>(true, new DynamicXml(e));
}
return Attempt<object>.False;
}
catch (Exception)
{
return Attempt<object>.False;
}
}
return Attempt<object>.False;
}
}
}
+5 -1
View File
@@ -54,7 +54,7 @@
<Compile Include="AssemblyExtensions.cs" />
<Compile Include="Attempt.cs" />
<Compile Include="CacheHelper.cs" />
<Compile Include="CodeAnnotations\UmbracoDeprecateAttribute.cs" />
<Compile Include="CodeAnnotations\UmbracoWillObsoleteAttribute.cs" />
<Compile Include="CodeAnnotations\UmbracoExperimentalFeatureAttribute.cs" />
<Compile Include="CodeAnnotations\UmbracoProposedPublicAttribute.cs" />
<Compile Include="Configuration\FileSystemProviderElement.cs" />
@@ -65,8 +65,11 @@
<Compile Include="DictionaryExtensions.cs" />
<Compile Include="Dictionary\CultureDictionaryFactoryResolver.cs" />
<Compile Include="Dictionary\ICultureDictionaryFactory.cs" />
<Compile Include="Dynamics\DynamicInstanceHelper.cs" />
<Compile Include="Enum.cs" />
<Compile Include="HashCodeCombiner.cs" />
<Compile Include="IO\FileSystemWrapper.cs" />
<Compile Include="Media\IImageUrlProvider.cs" />
<Compile Include="PublishedContentExtensions.cs" />
<Compile Include="Dictionary\ICultureDictionary.cs" />
<Compile Include="Dynamics\ClassFactory.cs" />
@@ -124,6 +127,7 @@
<Compile Include="ObjectResolution\Resolution.cs" />
<Compile Include="ObjectResolution\ResolverBase.cs" />
<Compile Include="ObjectResolution\SingleObjectResolverBase.cs" />
<Compile Include="PublishedContentHelper.cs" />
<Compile Include="RenderingEngine.cs" />
<Compile Include="TypeExtensions.cs" />
<Compile Include="ReadLock.cs" />
@@ -17,7 +17,7 @@ namespace Umbraco.Tests
TestHelper.SetupLog4NetForTests();
//this ensures its reset
PluginManager.Current = new PluginManager();
PluginManager.Current = new PluginManager(false);
//for testing, we'll specify which assemblies are scanned for the PluginTypeResolver
PluginManager.Current.AssembliesToScan = new[]
@@ -6,13 +6,69 @@ using Examine;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Tests.PublishedContent;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web;
using umbraco.BusinessLogic;
namespace Umbraco.Tests
namespace Umbraco.Tests.ContentStores
{
[TestFixture]
public class PublishMediaStoreTests
public class PublishMediaStoreTests : BaseWebTest
{
public override void Initialize()
{
base.Initialize();
//we're going to use the same initialization as the PublishedMediaTests
PublishedMediaTests.DoInitialization(GetUmbracoContext("/test", 1234));
}
public override void TearDown()
{
base.TearDown();
PublishedMediaTests.DoTearDown();
}
[Test]
public void Get_Root_Docs()
{
var user = new User(0);
var mType = global::umbraco.cms.businesslogic.media.MediaType.MakeNew(user, "TestMediaType");
var mRoot1 = global::umbraco.cms.businesslogic.media.Media.MakeNew("MediaRoot1", mType, user, -1);
var mRoot2 = global::umbraco.cms.businesslogic.media.Media.MakeNew("MediaRoot2", mType, user, -1);
var mChild1 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child1", mType, user, mRoot1.Id);
var mChild2 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child2", mType, user, mRoot2.Id);
var ctx = GetUmbracoContext("/test", 1234);
var mediaStore = new DefaultPublishedMediaStore();
var roots = mediaStore.GetRootDocuments(ctx);
Assert.AreEqual(2, roots.Count());
Assert.IsTrue(roots.Select(x => x.Id).ContainsAll(new[] {mRoot1.Id, mRoot2.Id}));
}
[Test]
public void Get_Item_Without_Examine()
{
var user = new User(0);
var mType = global::umbraco.cms.businesslogic.media.MediaType.MakeNew(user, "TestMediaType");
var mRoot = global::umbraco.cms.businesslogic.media.Media.MakeNew("MediaRoot", mType, user, -1);
var mChild1 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child1", mType, user, mRoot.Id);
var publishedMedia = PublishedMediaTests.GetNode(mRoot.Id, GetUmbracoContext("/test", 1234));
Assert.AreEqual(mRoot.Id, publishedMedia.Id);
Assert.AreEqual(mRoot.CreateDateTime.ToString("dd/MM/yyyy HH:mm:ss"), publishedMedia.CreateDate.ToString("dd/MM/yyyy HH:mm:ss"));
Assert.AreEqual(mRoot.User.Id, publishedMedia.CreatorId);
Assert.AreEqual(mRoot.User.Name, publishedMedia.CreatorName);
Assert.AreEqual(mRoot.ContentType.Alias, publishedMedia.DocumentTypeAlias);
Assert.AreEqual(mRoot.ContentType.Id, publishedMedia.DocumentTypeId);
Assert.AreEqual(mRoot.Level, publishedMedia.Level);
Assert.AreEqual(mRoot.Text, publishedMedia.Name);
Assert.AreEqual(mRoot.Path, publishedMedia.Path);
Assert.AreEqual(mRoot.sortOrder, publishedMedia.SortOrder);
Assert.IsNull(publishedMedia.Parent);
}
[TestCase("id")]
[TestCase("nodeId")]
[TestCase("__NodeId")]
@@ -191,10 +247,12 @@ namespace Umbraco.Tests
a => null,
//we're not going to test this so ignore
a => new List<IPublishedContent>(),
(dd, a) => dd.Properties.FirstOrDefault(x => x.Alias.InvariantEquals(a))),
(dd, a) => dd.Properties.FirstOrDefault(x => x.Alias.InvariantEquals(a)),
false),
//callback to get the children
d => children,
(dd, a) => dd.Properties.FirstOrDefault(x => x.Alias.InvariantEquals(a)));
(dd, a) => dd.Properties.FirstOrDefault(x => x.Alias.InvariantEquals(a)),
false);
return dicDoc;
}
+1 -1
View File
@@ -19,7 +19,7 @@ namespace Umbraco.Tests
TestHelper.SetupLog4NetForTests();
//this ensures its reset
PluginManager.Current = new PluginManager();
PluginManager.Current = new PluginManager(false);
//for testing, we'll specify which assemblies are scanned for the PluginTypeResolver
PluginManager.Current.AssembliesToScan = new[]
@@ -1,87 +0,0 @@
using System;
using System.Diagnostics;
using System.Xml;
using System.Xml.Linq;
using Microsoft.CSharp.RuntimeBinder;
using NUnit.Framework;
using Umbraco.Core.Dynamics;
namespace Umbraco.Tests.DynamicDocument
{
[TestFixture]
public class DynamicXmlTests
{
[Test]
public void Ensure_Legacy_Objects_Are_Returned()
{
var xml = "<DAMP fullMedia=\"\"><mediaItem><Image id=\"1057\" version=\"d58d5c16-153e-4896-892f-a722e45a69af\" parentID=\"-1\" level=\"1\" writerID=\"0\" nodeType=\"1032\" template=\"0\" sortOrder=\"1\" createDate=\"2012-11-05T16:55:29\" updateDate=\"2012-11-05T16:55:44\" nodeName=\"test12\" urlName=\"test12\" writerName=\"admin\" nodeTypeAlias=\"Image\" path=\"-1,1057\"><umbracoFile>/media/54/tulips.jpg</umbracoFile><umbracoWidth>1024</umbracoWidth><umbracoHeight>768</umbracoHeight><umbracoBytes>620888</umbracoBytes><umbracoExtension>jpg</umbracoExtension><newsCrops><crops date=\"2012-11-05T16:55:34\"><crop name=\"thumbCrop\" x=\"154\" y=\"1\" x2=\"922\" y2=\"768\" url=\"/media/54/tulips_thumbCrop.jpg\" /></crops></newsCrops></Image></mediaItem><mediaItem><Image id=\"1055\" version=\"4df1f08a-3552-45f2-b4bf-fa980c762f4a\" parentID=\"-1\" level=\"1\" writerID=\"0\" nodeType=\"1032\" template=\"0\" sortOrder=\"1\" createDate=\"2012-11-05T16:29:58\" updateDate=\"2012-11-05T16:30:27\" nodeName=\"Test\" urlName=\"test\" writerName=\"admin\" nodeTypeAlias=\"Image\" path=\"-1,1055\"><umbracoFile>/media/41/hydrangeas.jpg</umbracoFile><umbracoWidth>1024</umbracoWidth><umbracoHeight>768</umbracoHeight><umbracoBytes>595284</umbracoBytes><umbracoExtension>jpg</umbracoExtension><newsCrops><crops date=\"2012-11-05T16:30:18\"><crop name=\"thumbCrop\" x=\"133\" y=\"0\" x2=\"902\" y2=\"768\" url=\"/media/41/hydrangeas_thumbCrop.jpg\" /></crops></newsCrops></Image></mediaItem></DAMP>";
var mediaItems = new global::umbraco.MacroEngines.DynamicXml(xml);
//Debug.WriteLine("full xml = {0}", mediaItems.ToXml());
if (mediaItems.Count() != 0)
{
foreach (dynamic item in mediaItems)
{
Type itemType = item.GetType();
Debug.WriteLine("item type = {0}", itemType);
dynamic image = item.Image;
Type imageType = image.GetType();
Debug.WriteLine("image type = {0}", imageType);
//ensure they are the same
Assert.AreEqual(itemType, imageType);
//ensure they are legacy
Assert.AreEqual(typeof(global::umbraco.MacroEngines.DynamicXml), itemType);
Assert.AreEqual(typeof(global::umbraco.MacroEngines.DynamicXml), imageType);
}
}
}
/// <summary>
/// Test the current Core class
/// </summary>
[Test]
public void Find_Test_Core_Class()
{
RunFindTest(x => new DynamicXml(x));
}
/// <summary>
/// Tests the macroEngines legacy class
/// </summary>
[Test]
public void Find_Test_Legacy_Class()
{
RunFindTest(x => new global::umbraco.MacroEngines.DynamicXml(x));
}
private void RunFindTest(Func<string, dynamic> getDynamicXml)
{
var xmlstring = @"<test>
<item id='1' name='test 1' value='found 1'/>
<item id='2' name='test 2' value='found 2'/>
<item id='3' name='test 3' value='found 3'/>
</test>";
dynamic dXml = getDynamicXml(xmlstring);
var result1 = dXml.Find("@name", "test 1");
var result2 = dXml.Find("@name", "test 2");
var result3 = dXml.Find("@name", "test 3");
var result4 = dXml.Find("@name", "dont find");
Assert.AreEqual("found 1", result1.value);
Assert.AreEqual("found 2", result2.value);
Assert.AreEqual("found 3", result3.value);
Assert.Throws<RuntimeBinderException>(() =>
{
//this will throw because result4 is not found
var temp = result4.value;
});
}
}
}
+39
View File
@@ -1,6 +1,8 @@
using System.Configuration;
using System.Web.Routing;
using NUnit.Framework;
using Umbraco.Tests.TestHelpers;
using System.Web.Mvc;
namespace Umbraco.Tests
{
@@ -53,5 +55,42 @@ namespace Umbraco.Tests
{
Assert.IsFalse(Umbraco.Core.Configuration.GlobalSettings.IsReservedPathOrUrl(url));
}
[TestCase("/Do/Not/match", false)]
[TestCase("/Umbraco/RenderMvcs", false)]
[TestCase("/Umbraco/RenderMvc", true)]
[TestCase("/Umbraco/RenderMvc/Index", true)]
[TestCase("/Umbraco/RenderMvc/Index/1234", true)]
[TestCase("/Umbraco/RenderMvc/Index/1234/9876", false)]
[TestCase("/api", true)]
[TestCase("/api/WebApiTest", true)]
[TestCase("/api/WebApiTest/1234", true)]
[TestCase("/api/WebApiTest/Index/1234", false)]
public void Is_Reserved_By_Route(string url, bool shouldMatch)
{
//reset the app config, we only want to test routes not the hard coded paths
ConfigurationManager.AppSettings.Set("umbracoReservedPaths", "");
ConfigurationManager.AppSettings.Set("umbracoReservedUrls", "");
var routes = new RouteCollection();
routes.MapRoute(
"Umbraco_default",
"Umbraco/RenderMvc/{action}/{id}",
new { controller = "RenderMvc", action = "Index", id = UrlParameter.Optional });
routes.MapRoute(
"WebAPI",
"api/{controller}/{id}",
new { controller = "WebApiTestController", action = "Index", id = UrlParameter.Optional });
var context = new FakeHttpContextFactory(url);
Assert.AreEqual(
shouldMatch,
Umbraco.Core.Configuration.GlobalSettings.IsReservedPathOrUrl(url, context.HttpContext, routes));
}
}
}
+154
View File
@@ -0,0 +1,154 @@
using System;
using System.IO;
using System.Reflection;
using NUnit.Framework;
using Umbraco.Core;
namespace Umbraco.Tests
{
[TestFixture]
public class HashCodeCombinerTests : PartialTrust.AbstractPartialTrustFixture<HashCodeCombinerTests>
{
private DirectoryInfo PrepareFolder()
{
var assDir = new FileInfo(Assembly.GetExecutingAssembly().Location).Directory;
var dir = Directory.CreateDirectory(Path.Combine(assDir.FullName, "HashCombiner", Guid.NewGuid().ToString("N")));
foreach (var f in dir.GetFiles())
{
f.Delete();
}
return dir;
}
[Test]
public void HashCombiner_Test_String()
{
var combiner1 = new HashCodeCombiner();
combiner1.AddCaseInsensitiveString("Hello");
var combiner2 = new HashCodeCombiner();
combiner2.AddCaseInsensitiveString("hello");
Assert.AreEqual(combiner1.GetCombinedHashCode(), combiner2.GetCombinedHashCode());
combiner2.AddCaseInsensitiveString("world");
Assert.AreNotEqual(combiner1.GetCombinedHashCode(), combiner2.GetCombinedHashCode());
}
[Test]
public void HashCombiner_Test_Int()
{
var combiner1 = new HashCodeCombiner();
combiner1.AddInt(1234);
var combiner2 = new HashCodeCombiner();
combiner2.AddInt(1234);
Assert.AreEqual(combiner1.GetCombinedHashCode(), combiner2.GetCombinedHashCode());
combiner2.AddInt(1);
Assert.AreNotEqual(combiner1.GetCombinedHashCode(), combiner2.GetCombinedHashCode());
}
[Test]
public void HashCombiner_Test_DateTime()
{
var dt = DateTime.Now;
var combiner1 = new HashCodeCombiner();
combiner1.AddDateTime(dt);
var combiner2 = new HashCodeCombiner();
combiner2.AddDateTime(dt);
Assert.AreEqual(combiner1.GetCombinedHashCode(), combiner2.GetCombinedHashCode());
combiner2.AddDateTime(DateTime.Now);
Assert.AreNotEqual(combiner1.GetCombinedHashCode(), combiner2.GetCombinedHashCode());
}
[Test]
public void HashCombiner_Test_File()
{
var dir = PrepareFolder();
var file1Path = Path.Combine(dir.FullName, "hastest1.txt");
File.Delete(file1Path);
using (var file1 = File.CreateText(Path.Combine(dir.FullName, "hastest1.txt")))
{
file1.WriteLine("hello");
}
var file2Path = Path.Combine(dir.FullName, "hastest2.txt");
File.Delete(file2Path);
using (var file2 = File.CreateText(Path.Combine(dir.FullName, "hastest2.txt")))
{
//even though files are the same, the dates are different
file2.WriteLine("hello");
}
var combiner1 = new HashCodeCombiner();
combiner1.AddFile(new FileInfo(file1Path));
var combiner2 = new HashCodeCombiner();
combiner2.AddFile(new FileInfo(file1Path));
var combiner3 = new HashCodeCombiner();
combiner3.AddFile(new FileInfo(file2Path));
Assert.AreEqual(combiner1.GetCombinedHashCode(), combiner2.GetCombinedHashCode());
Assert.AreNotEqual(combiner1.GetCombinedHashCode(), combiner3.GetCombinedHashCode());
combiner2.AddFile(new FileInfo(file2Path));
Assert.AreNotEqual(combiner1.GetCombinedHashCode(), combiner2.GetCombinedHashCode());
}
[Test]
public void HashCombiner_Test_Folder()
{
var dir = PrepareFolder();
var file1Path = Path.Combine(dir.FullName, "hastest1.txt");
File.Delete(file1Path);
using (var file1 = File.CreateText(Path.Combine(dir.FullName, "hastest1.txt")))
{
file1.WriteLine("hello");
}
//first test the whole folder
var combiner1 = new HashCodeCombiner();
combiner1.AddFolder(dir);
var combiner2 = new HashCodeCombiner();
combiner2.AddFolder(dir);
Assert.AreEqual(combiner1.GetCombinedHashCode(), combiner2.GetCombinedHashCode());
//now add a file to the folder
var file2Path = Path.Combine(dir.FullName, "hastest2.txt");
File.Delete(file2Path);
using (var file2 = File.CreateText(Path.Combine(dir.FullName, "hastest2.txt")))
{
//even though files are the same, the dates are different
file2.WriteLine("hello");
}
var combiner3 = new HashCodeCombiner();
combiner3.AddFolder(dir);
Assert.AreNotEqual(combiner1.GetCombinedHashCode(), combiner3.GetCombinedHashCode());
}
public override void TestSetup()
{
}
public override void TestTearDown()
{
}
}
}
+1 -1
View File
@@ -18,7 +18,7 @@ namespace Umbraco.Tests
TestHelper.SetupLog4NetForTests();
//this ensures its reset
PluginManager.Current = new PluginManager();
PluginManager.Current = new PluginManager(false);
//for testing, we'll specify which assemblies are scanned for the PluginTypeResolver
PluginManager.Current.AssembliesToScan = new[]
+1 -1
View File
@@ -18,7 +18,7 @@ namespace Umbraco.Tests
TestHelper.SetupLog4NetForTests();
//this ensures its reset
PluginManager.Current = new PluginManager();
PluginManager.Current = new PluginManager(false);
//for testing, we'll specify which assemblies are scanned for the PluginTypeResolver
PluginManager.Current.AssembliesToScan = new[]
+31 -1
View File
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using NUnit.Framework;
using Umbraco.Core;
@@ -67,7 +68,8 @@ namespace Umbraco.Tests
{"FALSE", false},
{"False", false},
{"false", false},
{"0", false}
{"0", false},
{"", false}
};
foreach (var testCase in testCases)
@@ -79,6 +81,34 @@ namespace Umbraco.Tests
}
}
[Test]
[TestOnlyInFullTrust]
public virtual void CanConvertStringToDateTime()
{
var dateTime = new DateTime(2012, 11, 10, 13, 14, 15);
var testCases = new Dictionary<string, bool>
{
{"2012-11-10", true},
{"2012/11/10", true},
{"10/11/2012", true},
{"11/10/2012", false},
{"Sat 10, Nov 2012", true},
{"Saturday 10, Nov 2012", true},
{"Sat 10, November 2012", true},
{"Saturday 10, November 2012", true},
{"2012-11-10 13:14:15", true},
{"", false}
};
foreach (var testCase in testCases)
{
var result = testCase.Key.TryConvertTo<DateTime>();
Assert.IsTrue(result.Success);
Assert.AreEqual(DateTime.Equals(dateTime.Date, result.Result.Date), testCase.Value);
}
}
/// <summary>
/// Run once before each test in derived test fixtures.
/// </summary>
+307 -114
View File
@@ -1,37 +1,44 @@
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Web.Compilation;
using NUnit.Framework;
using SqlCE4Umbraco;
using Umbraco.Core;
using Umbraco.Core.IO;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web;
using umbraco;
using umbraco.DataLayer;
using umbraco.MacroEngines;
using umbraco.MacroEngines.Iron;
using umbraco.businesslogic;
using umbraco.cms.businesslogic;
using umbraco.editorControls;
using umbraco.interfaces;
using umbraco.uicontrols;
using umbraco.cms;
namespace Umbraco.Tests
{
[TestFixture]
public class PluginManagerTests
{
[TestFixture]
public class PluginManagerTests
{
[SetUp]
public void Initialize()
{
TestHelper.SetupLog4NetForTests();
[SetUp]
public void Initialize()
{
TestHelper.SetupLog4NetForTests();
//this ensures its reset
PluginManager.Current = new PluginManager();
//this ensures its reset
PluginManager.Current = new PluginManager(false);
//for testing, we'll specify which assemblies are scanned for the PluginTypeResolver
//TODO: Should probably update this so it only searches this assembly and add custom types to be found
PluginManager.Current.AssembliesToScan = new[]
//for testing, we'll specify which assemblies are scanned for the PluginTypeResolver
//TODO: Should probably update this so it only searches this assembly and add custom types to be found
PluginManager.Current.AssembliesToScan = new[]
{
this.GetType().Assembly,
typeof(ApplicationStartupHandler).Assembly,
@@ -47,132 +54,318 @@ namespace Umbraco.Tests
typeof(System.Web.Mvc.ActionResult).Assembly,
typeof(TypeFinder).Assembly,
typeof(ISqlHelper).Assembly,
typeof(DLRScriptingEngine).Assembly,
typeof(ICultureDictionary).Assembly,
typeof(UmbracoContext).Assembly,
typeof(BaseDataType).Assembly
};
}
}
[Test]
public void Ensure_Only_One_Type_List_Created()
{
var foundTypes1 = PluginManager.Current.ResolveFindMeTypes();
var foundTypes2 = PluginManager.Current.ResolveFindMeTypes();
Assert.AreEqual(1,
PluginManager.Current.GetTypeLists()
.Count(x => x.IsTypeList<IFindMe>(PluginManager.TypeResolutionKind.FindAllTypes)));
}
private DirectoryInfo PrepareFolder()
{
var assDir = new FileInfo(Assembly.GetExecutingAssembly().Location).Directory;
var dir = Directory.CreateDirectory(Path.Combine(assDir.FullName, "PluginManager", Guid.NewGuid().ToString("N")));
foreach (var f in dir.GetFiles())
{
f.Delete();
}
return dir;
}
[Test]
public void Resolves_Types()
{
var foundTypes1 = PluginManager.Current.ResolveFindMeTypes();
Assert.AreEqual(2, foundTypes1.Count());
}
//[Test]
//public void Scan_Vs_Load_Benchmark()
//{
// var pluginManager = new PluginManager(false);
// var watch = new Stopwatch();
// watch.Start();
// for (var i = 0; i < 1000; i++)
// {
// var type2 = Type.GetType("umbraco.macroCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null");
// var type3 = Type.GetType("umbraco.templateCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null");
// var type4 = Type.GetType("umbraco.presentation.cache.MediaLibraryRefreshers, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null");
// var type5 = Type.GetType("umbraco.presentation.cache.pageRefresher, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null");
// }
// watch.Stop();
// Debug.WriteLine("TOTAL TIME (1st round): " + watch.ElapsedMilliseconds);
// watch.Start();
// for (var i = 0; i < 1000; i++)
// {
// var type2 = BuildManager.GetType("umbraco.macroCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true);
// var type3 = BuildManager.GetType("umbraco.templateCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true);
// var type4 = BuildManager.GetType("umbraco.presentation.cache.MediaLibraryRefreshers, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true);
// var type5 = BuildManager.GetType("umbraco.presentation.cache.pageRefresher, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true);
// }
// watch.Stop();
// Debug.WriteLine("TOTAL TIME (1st round): " + watch.ElapsedMilliseconds);
// watch.Reset();
// watch.Start();
// for (var i = 0; i < 1000; i++)
// {
// var refreshers = pluginManager.ResolveTypes<ICacheRefresher>(false);
// }
// watch.Stop();
// Debug.WriteLine("TOTAL TIME (2nd round): " + watch.ElapsedMilliseconds);
//}
[Test]
public void Resolves_Attributed_Trees()
{
var trees = PluginManager.Current.ResolveAttributedTrees();
Assert.AreEqual(27, trees.Count());
}
////NOTE: This test shows that Type.GetType is 100% faster than Assembly.Load(..).GetType(...) so we'll use that :)
//[Test]
//public void Load_Type_Benchmark()
//{
// var watch = new Stopwatch();
// watch.Start();
// for (var i = 0; i < 1000; i++)
// {
// var type2 = Type.GetType("umbraco.macroCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null");
// var type3 = Type.GetType("umbraco.templateCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null");
// var type4 = Type.GetType("umbraco.presentation.cache.MediaLibraryRefreshers, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null");
// var type5 = Type.GetType("umbraco.presentation.cache.pageRefresher, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null");
// }
// watch.Stop();
// Debug.WriteLine("TOTAL TIME (1st round): " + watch.ElapsedMilliseconds);
// watch.Reset();
// watch.Start();
// for (var i = 0; i < 1000; i++)
// {
// var type2 = Assembly.Load("umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null")
// .GetType("umbraco.macroCacheRefresh");
// var type3 = Assembly.Load("umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null")
// .GetType("umbraco.templateCacheRefresh");
// var type4 = Assembly.Load("umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null")
// .GetType("umbraco.presentation.cache.MediaLibraryRefreshers");
// var type5 = Assembly.Load("umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null")
// .GetType("umbraco.presentation.cache.pageRefresher");
// }
// watch.Stop();
// Debug.WriteLine("TOTAL TIME (2nd round): " + watch.ElapsedMilliseconds);
// watch.Reset();
// watch.Start();
// for (var i = 0; i < 1000; i++)
// {
// var type2 = BuildManager.GetType("umbraco.macroCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true);
// var type3 = BuildManager.GetType("umbraco.templateCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true);
// var type4 = BuildManager.GetType("umbraco.presentation.cache.MediaLibraryRefreshers, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true);
// var type5 = BuildManager.GetType("umbraco.presentation.cache.pageRefresher, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true);
// }
// watch.Stop();
// Debug.WriteLine("TOTAL TIME (1st round): " + watch.ElapsedMilliseconds);
//}
[Test]
public void Resolves_Actions()
{
var actions = PluginManager.Current.ResolveActions();
Assert.AreEqual(37, actions.Count());
}
[Test]
public void Detect_Legacy_Plugin_File_List()
{
var tempFolder = IOHelper.MapPath("~/App_Data/TEMP/PluginCache");
var manager = new PluginManager(false);
var filePath = Path.Combine(tempFolder, "umbraco-plugins.list");
File.WriteAllText(filePath, @"<?xml version=""1.0"" encoding=""utf-8""?>
<plugins>
<baseType type=""umbraco.interfaces.ICacheRefresher"">
<add type=""umbraco.macroCacheRefresh, umbraco, Version=6.0.0.0, Culture=neutral, PublicKeyToken=null"" />
</baseType>
</plugins>");
[Test]
public void Resolves_Trees()
{
var trees = PluginManager.Current.ResolveTrees();
Assert.AreEqual(36, trees.Count());
}
Assert.IsTrue(manager.DetectLegacyPluginListFile());
[Test]
public void Resolves_Applications()
{
var apps = PluginManager.Current.ResolveApplications();
Assert.AreEqual(7, apps.Count());
}
File.Delete(filePath);
[Test]
public void Resolves_Action_Handlers()
{
var types = PluginManager.Current.ResolveActionHandlers();
Assert.AreEqual(1, types.Count());
}
//now create a valid one
File.WriteAllText(filePath, @"<?xml version=""1.0"" encoding=""utf-8""?>
<plugins>
<baseType type=""umbraco.interfaces.ICacheRefresher"" resolutionType=""FindAllTypes"">
<add type=""umbraco.macroCacheRefresh, umbraco, Version=6.0.0.0, Culture=neutral, PublicKeyToken=null"" />
</baseType>
</plugins>");
[Test]
public void Resolves_DataTypes()
{
var types = PluginManager.Current.ResolveDataTypes();
Assert.AreEqual(37, types.Count());
}
Assert.IsFalse(manager.DetectLegacyPluginListFile());
}
[Test]
public void Resolves_RazorDataTypeModels()
{
var types = PluginManager.Current.ResolveRazorDataTypeModels();
Assert.AreEqual(2, types.Count());
}
[Test]
public void Create_Cached_Plugin_File()
{
var types = new[] { typeof(PluginManager), typeof(PluginManagerTests), typeof(UmbracoContext) };
[Test]
public void Resolves_RestExtensions()
{
var types = PluginManager.Current.ResolveRestExtensions();
Assert.AreEqual(2, types.Count());
}
var manager = new PluginManager(false);
//yes this is silly, none of these types inherit from string, but this is just to test the xml file format
manager.UpdateCachedPluginsFile<string>(types, PluginManager.TypeResolutionKind.FindAllTypes);
[Test]
public void Resolves_LegacyRestExtensions()
{
var types = PluginManager.Current.ResolveLegacyRestExtensions();
Assert.AreEqual(1, types.Count());
}
var plugins = manager.TryGetCachedPluginsFromFile<string>(PluginManager.TypeResolutionKind.FindAllTypes);
var diffType = manager.TryGetCachedPluginsFromFile<string>(PluginManager.TypeResolutionKind.FindAttributedTypes);
[Test]
public void Resolves_XsltExtensions()
{
var types = PluginManager.Current.ResolveXsltExtensions();
Assert.AreEqual(1, types.Count());
}
Assert.IsTrue(plugins.Success);
//this will be false since there is no cache of that type resolution kind
Assert.IsFalse(diffType.Success);
[XsltExtension("Blah.Blah")]
public class MyXsltExtension
{
Assert.AreEqual(3, plugins.Result.Count());
var shouldContain = types.Select(x => x.AssemblyQualifiedName);
//ensure they are all found
Assert.IsTrue(plugins.Result.ContainsAll(shouldContain));
}
}
[Test]
public void PluginHash_From_String()
{
var s = "hello my name is someone".GetHashCode().ToString("x", CultureInfo.InvariantCulture);
var output = PluginManager.ConvertPluginsHashFromHex(s);
Assert.AreNotEqual(0, output);
}
[umbraco.presentation.umbracobase.RestExtension("Blah")]
public class MyLegacyRestExtension
{
}
[Test]
public void Get_Plugins_Hash()
{
//Arrange
var dir = PrepareFolder();
var d1 = dir.CreateSubdirectory("1");
var d2 = dir.CreateSubdirectory("2");
var d3 = dir.CreateSubdirectory("3");
var d4 = dir.CreateSubdirectory("4");
var f1 = new FileInfo(Path.Combine(d1.FullName, "test1.dll"));
var f2 = new FileInfo(Path.Combine(d1.FullName, "test2.dll"));
var f3 = new FileInfo(Path.Combine(d2.FullName, "test1.dll"));
var f4 = new FileInfo(Path.Combine(d2.FullName, "test2.dll"));
var f5 = new FileInfo(Path.Combine(d3.FullName, "test1.dll"));
var f6 = new FileInfo(Path.Combine(d3.FullName, "test2.dll"));
var f7 = new FileInfo(Path.Combine(d4.FullName, "test1.dll"));
f1.CreateText().Close();
f2.CreateText().Close();
f3.CreateText().Close();
f4.CreateText().Close();
f5.CreateText().Close();
f6.CreateText().Close();
f7.CreateText().Close();
var list1 = new[] { f1, f2, f3, f4, f5, f6 };
var list2 = new[] { f1, f3, f5 };
var list3 = new[] { f1, f3, f5, f7 };
[Umbraco.Web.BaseRest.RestExtension("Blah")]
public class MyRestExtesion
{
}
//Act
var hash1 = PluginManager.GetAssembliesHash(list1);
var hash2 = PluginManager.GetAssembliesHash(list2);
var hash3 = PluginManager.GetAssembliesHash(list3);
public interface IFindMe
{
//Assert
Assert.AreNotEqual(hash1, hash2);
Assert.AreNotEqual(hash1, hash3);
Assert.AreNotEqual(hash2, hash3);
}
Assert.AreEqual(hash1, PluginManager.GetAssembliesHash(list1));
}
public class FindMe1 : IFindMe
{
[Test]
public void Ensure_Only_One_Type_List_Created()
{
var foundTypes1 = PluginManager.Current.ResolveFindMeTypes();
var foundTypes2 = PluginManager.Current.ResolveFindMeTypes();
Assert.AreEqual(1,
PluginManager.Current.GetTypeLists()
.Count(x => x.IsTypeList<IFindMe>(PluginManager.TypeResolutionKind.FindAllTypes)));
}
}
[Test]
public void Resolves_Types()
{
var foundTypes1 = PluginManager.Current.ResolveFindMeTypes();
Assert.AreEqual(2, foundTypes1.Count());
}
public class FindMe2 : IFindMe
{
[Test]
public void Resolves_Attributed_Trees()
{
var trees = PluginManager.Current.ResolveAttributedTrees();
Assert.AreEqual(27, trees.Count());
}
}
[Test]
public void Resolves_Actions()
{
var actions = PluginManager.Current.ResolveActions();
Assert.AreEqual(37, actions.Count());
}
}
[Test]
public void Resolves_Trees()
{
var trees = PluginManager.Current.ResolveTrees();
Assert.AreEqual(36, trees.Count());
}
[Test]
public void Resolves_Applications()
{
var apps = PluginManager.Current.ResolveApplications();
Assert.AreEqual(7, apps.Count());
}
[Test]
public void Resolves_Action_Handlers()
{
var types = PluginManager.Current.ResolveActionHandlers();
Assert.AreEqual(1, types.Count());
}
[Test]
public void Resolves_DataTypes()
{
var types = PluginManager.Current.ResolveDataTypes();
Assert.AreEqual(37, types.Count());
}
[Test]
public void Resolves_RazorDataTypeModels()
{
var types = PluginManager.Current.ResolveRazorDataTypeModels();
Assert.AreEqual(2, types.Count());
}
[Test]
public void Resolves_RestExtensions()
{
var types = PluginManager.Current.ResolveRestExtensions();
Assert.AreEqual(2, types.Count());
}
[Test]
public void Resolves_LegacyRestExtensions()
{
var types = PluginManager.Current.ResolveLegacyRestExtensions();
Assert.AreEqual(1, types.Count());
}
[Test]
public void Resolves_XsltExtensions()
{
var types = PluginManager.Current.ResolveXsltExtensions();
Assert.AreEqual(1, types.Count());
}
[XsltExtension("Blah.Blah")]
public class MyXsltExtension
{
}
[umbraco.presentation.umbracobase.RestExtension("Blah")]
public class MyLegacyRestExtension
{
}
[Umbraco.Web.BaseRest.RestExtension("Blah")]
public class MyRestExtesion
{
}
public interface IFindMe
{
}
public class FindMe1 : IFindMe
{
}
public class FindMe2 : IFindMe
{
}
}
}
@@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.PropertyEditors;
using Umbraco.Tests.TestHelpers;
namespace Umbraco.Tests.PropertyEditors
{
[TestFixture]
public class PropertyEditorValueConverterTests
{
[Test]
public void CanConvertDatePickerPropertyEditor()
{
var converter = new DatePickerPropertyEditorValueConverter();
var dateTime = new DateTime(2012, 11, 10, 13, 14, 15);
var testCases = new Dictionary<string, bool>
{
{"2012-11-10", true},
{"2012/11/10", true},
{"10/11/2012", true},
{"11/10/2012", false},
{"Sat 10, Nov 2012", true},
{"Saturday 10, Nov 2012", true},
{"Sat 10, November 2012", true},
{"Saturday 10, November 2012", true},
{"2012-11-10 13:14:15", true},
{"", false}
};
foreach (var testCase in testCases)
{
var result = converter.ConvertPropertyValue(testCase.Key);
Assert.IsTrue(result.Success);
Assert.AreEqual(DateTime.Equals(dateTime.Date, ((DateTime)result.Result).Date), testCase.Value);
}
}
[Test]
public void CanConvertYesNoPropertyEditor()
{
var converter = new YesNoPropertyEditorValueConverter();
var testCases = new Dictionary<string, bool>
{
{"TRUE", true},
{"True", true},
{"true", true},
{"1", true},
{"FALSE", false},
{"False", false},
{"false", false},
{"0", false},
{"", false}
};
foreach (var testCase in testCases)
{
var result = converter.ConvertPropertyValue(testCase.Key);
Assert.IsTrue(result.Success);
Assert.AreEqual(testCase.Value, result.Result);
}
}
}
}
@@ -6,10 +6,9 @@ using System.Web;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Dynamics;
using Umbraco.Core.Models;
using Umbraco.Tests.TestHelpers;
namespace Umbraco.Tests.DynamicDocument
namespace Umbraco.Tests.PublishedContent
{
[TestFixture]
public abstract class DynamicDocumentTestsBase<TDocument, TDocumentList> : BaseRoutingTest
@@ -5,17 +5,12 @@ using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web;
using Umbraco.Web.Models;
using umbraco.BusinessLogic;
using umbraco.IO;
using umbraco.MacroEngines;
using umbraco.NodeFactory;
using umbraco.cms.businesslogic;
using umbraco.cms.businesslogic.template;
using System.Linq;
using umbraco.cms.businesslogic.web;
namespace Umbraco.Tests.DynamicDocument
namespace Umbraco.Tests.PublishedContent
{
[TestFixture]
public class DynamicNodeTests : DynamicDocumentTestsBase<DynamicNode, DynamicNodeList>
@@ -1,9 +1,7 @@
using System.Collections.Generic;
using Umbraco.Core.Dynamics;
using Umbraco.Core.Models;
using Umbraco.Web.Models;
namespace Umbraco.Tests.DynamicDocument
namespace Umbraco.Tests.PublishedContent
{
public static class DynamicPublishedContentCustomExtensionMethods
{
@@ -1,22 +1,13 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using NUnit.Framework;
using Umbraco.Core.Dynamics;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.PropertyEditors;
using Umbraco.Tests.Routing;
using Umbraco.Web;
using Umbraco.Web.Models;
using Umbraco.Web.Routing;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic;
using umbraco.cms.businesslogic.template;
using umbraco.cms.businesslogic.web;
namespace Umbraco.Tests.DynamicDocument
namespace Umbraco.Tests.PublishedContent
{
[TestFixture]
public class DynamicPublishedContentTests : DynamicDocumentTestsBase<DynamicPublishedContent, DynamicPublishedContentList>
@@ -34,7 +25,7 @@ namespace Umbraco.Tests.DynamicDocument
});
//need to specify a custom callback for unit tests
DynamicPublishedContent.GetDataTypeCallback = (docTypeAlias, propertyAlias) =>
PublishedContentHelper.GetDataTypeCallback = (docTypeAlias, propertyAlias) =>
{
if (propertyAlias == "content")
{
@@ -86,6 +77,7 @@ namespace Umbraco.Tests.DynamicDocument
Assert.AreEqual("Hello world!" + 123 + false, asDynamic.DynamicDocumentMultiParam("Hello world!", 123, false));
Assert.AreEqual("Hello world!" + 123 + false, asDynamic.Children.DynamicDocumentListMultiParam("Hello world!", 123, false));
Assert.AreEqual("Hello world!" + 123 + false, asDynamic.Children.DynamicDocumentEnumerableMultiParam("Hello world!", 123, false));
}
[Test]
@@ -0,0 +1,145 @@
using System;
using System.Diagnostics;
using Microsoft.CSharp.RuntimeBinder;
using NUnit.Framework;
using Umbraco.Core.Dynamics;
using System.Linq;
namespace Umbraco.Tests.PublishedContent
{
[TestFixture]
public class DynamicXmlTests
{
[Test]
public void Custom_Extension_Method_Legacy()
{
var xml = "<DAMP fullMedia=\"\"><mediaItem><Image id=\"1057\" version=\"d58d5c16-153e-4896-892f-a722e45a69af\" parentID=\"-1\" level=\"1\" writerID=\"0\" nodeType=\"1032\" template=\"0\" sortOrder=\"1\" createDate=\"2012-11-05T16:55:29\" updateDate=\"2012-11-05T16:55:44\" nodeName=\"test12\" urlName=\"test12\" writerName=\"admin\" nodeTypeAlias=\"Image\" path=\"-1,1057\"><umbracoFile>/media/54/tulips.jpg</umbracoFile><umbracoWidth>1024</umbracoWidth><umbracoHeight>768</umbracoHeight><umbracoBytes>620888</umbracoBytes><umbracoExtension>jpg</umbracoExtension><newsCrops><crops date=\"2012-11-05T16:55:34\"><crop name=\"thumbCrop\" x=\"154\" y=\"1\" x2=\"922\" y2=\"768\" url=\"/media/54/tulips_thumbCrop.jpg\" /></crops></newsCrops></Image></mediaItem><mediaItem><Image id=\"1055\" version=\"4df1f08a-3552-45f2-b4bf-fa980c762f4a\" parentID=\"-1\" level=\"1\" writerID=\"0\" nodeType=\"1032\" template=\"0\" sortOrder=\"1\" createDate=\"2012-11-05T16:29:58\" updateDate=\"2012-11-05T16:30:27\" nodeName=\"Test\" urlName=\"test\" writerName=\"admin\" nodeTypeAlias=\"Image\" path=\"-1,1055\"><umbracoFile>/media/41/hydrangeas.jpg</umbracoFile><umbracoWidth>1024</umbracoWidth><umbracoHeight>768</umbracoHeight><umbracoBytes>595284</umbracoBytes><umbracoExtension>jpg</umbracoExtension><newsCrops><crops date=\"2012-11-05T16:30:18\"><crop name=\"thumbCrop\" x=\"133\" y=\"0\" x2=\"902\" y2=\"768\" url=\"/media/41/hydrangeas_thumbCrop.jpg\" /></crops></newsCrops></Image></mediaItem></DAMP>";
var typedXml = new global::umbraco.MacroEngines.DynamicXml(xml);
dynamic dynamicXml = typedXml;
//we haven't explicitly defined ElementAt so this will dynamically invoke this method
var element = dynamicXml.ElementAt(0);
Assert.AreEqual("1057", Enumerable.First(element.BaseElement.Elements()).Attribute("id").Value);
}
[Test]
public void Custom_Extension_Method()
{
var xml = "<DAMP fullMedia=\"\"><mediaItem><Image id=\"1057\" version=\"d58d5c16-153e-4896-892f-a722e45a69af\" parentID=\"-1\" level=\"1\" writerID=\"0\" nodeType=\"1032\" template=\"0\" sortOrder=\"1\" createDate=\"2012-11-05T16:55:29\" updateDate=\"2012-11-05T16:55:44\" nodeName=\"test12\" urlName=\"test12\" writerName=\"admin\" nodeTypeAlias=\"Image\" path=\"-1,1057\"><umbracoFile>/media/54/tulips.jpg</umbracoFile><umbracoWidth>1024</umbracoWidth><umbracoHeight>768</umbracoHeight><umbracoBytes>620888</umbracoBytes><umbracoExtension>jpg</umbracoExtension><newsCrops><crops date=\"2012-11-05T16:55:34\"><crop name=\"thumbCrop\" x=\"154\" y=\"1\" x2=\"922\" y2=\"768\" url=\"/media/54/tulips_thumbCrop.jpg\" /></crops></newsCrops></Image></mediaItem><mediaItem><Image id=\"1055\" version=\"4df1f08a-3552-45f2-b4bf-fa980c762f4a\" parentID=\"-1\" level=\"1\" writerID=\"0\" nodeType=\"1032\" template=\"0\" sortOrder=\"1\" createDate=\"2012-11-05T16:29:58\" updateDate=\"2012-11-05T16:30:27\" nodeName=\"Test\" urlName=\"test\" writerName=\"admin\" nodeTypeAlias=\"Image\" path=\"-1,1055\"><umbracoFile>/media/41/hydrangeas.jpg</umbracoFile><umbracoWidth>1024</umbracoWidth><umbracoHeight>768</umbracoHeight><umbracoBytes>595284</umbracoBytes><umbracoExtension>jpg</umbracoExtension><newsCrops><crops date=\"2012-11-05T16:30:18\"><crop name=\"thumbCrop\" x=\"133\" y=\"0\" x2=\"902\" y2=\"768\" url=\"/media/41/hydrangeas_thumbCrop.jpg\" /></crops></newsCrops></Image></mediaItem></DAMP>";
var typedXml = new DynamicXml(xml);
dynamic dynamicXml = typedXml;
//we haven't explicitly defined ElementAt so this will dynamically invoke this method
var element = dynamicXml.ElementAt(0);
Assert.AreEqual("1057", Enumerable.First(element.BaseElement.Elements()).Attribute("id").Value);
}
[Test]
public void Take_Legacy()
{
var xml = "<DAMP fullMedia=\"\"><mediaItem><Image id=\"1057\" version=\"d58d5c16-153e-4896-892f-a722e45a69af\" parentID=\"-1\" level=\"1\" writerID=\"0\" nodeType=\"1032\" template=\"0\" sortOrder=\"1\" createDate=\"2012-11-05T16:55:29\" updateDate=\"2012-11-05T16:55:44\" nodeName=\"test12\" urlName=\"test12\" writerName=\"admin\" nodeTypeAlias=\"Image\" path=\"-1,1057\"><umbracoFile>/media/54/tulips.jpg</umbracoFile><umbracoWidth>1024</umbracoWidth><umbracoHeight>768</umbracoHeight><umbracoBytes>620888</umbracoBytes><umbracoExtension>jpg</umbracoExtension><newsCrops><crops date=\"2012-11-05T16:55:34\"><crop name=\"thumbCrop\" x=\"154\" y=\"1\" x2=\"922\" y2=\"768\" url=\"/media/54/tulips_thumbCrop.jpg\" /></crops></newsCrops></Image></mediaItem><mediaItem><Image id=\"1055\" version=\"4df1f08a-3552-45f2-b4bf-fa980c762f4a\" parentID=\"-1\" level=\"1\" writerID=\"0\" nodeType=\"1032\" template=\"0\" sortOrder=\"1\" createDate=\"2012-11-05T16:29:58\" updateDate=\"2012-11-05T16:30:27\" nodeName=\"Test\" urlName=\"test\" writerName=\"admin\" nodeTypeAlias=\"Image\" path=\"-1,1055\"><umbracoFile>/media/41/hydrangeas.jpg</umbracoFile><umbracoWidth>1024</umbracoWidth><umbracoHeight>768</umbracoHeight><umbracoBytes>595284</umbracoBytes><umbracoExtension>jpg</umbracoExtension><newsCrops><crops date=\"2012-11-05T16:30:18\"><crop name=\"thumbCrop\" x=\"133\" y=\"0\" x2=\"902\" y2=\"768\" url=\"/media/41/hydrangeas_thumbCrop.jpg\" /></crops></newsCrops></Image></mediaItem></DAMP>";
var typedXml = new global::umbraco.MacroEngines.DynamicXml(xml);
dynamic dynamicXml = typedXml;
var typedTaken = typedXml.Take(1);
var dynamicTaken = dynamicXml.Take(1);
Assert.AreEqual(1, typedTaken.Count());
Assert.AreEqual(1, Enumerable.Count(dynamicTaken));
Assert.AreEqual("1057", typedTaken.ElementAt(0).BaseElement.Elements().First().Attribute("id").Value);
Assert.AreEqual("1057", Enumerable.First(Enumerable.ElementAt(dynamicTaken, 0).BaseElement.Elements()).Attribute("id").Value);
}
[Test]
public void Take()
{
var xml = "<DAMP fullMedia=\"\"><mediaItem><Image id=\"1057\" version=\"d58d5c16-153e-4896-892f-a722e45a69af\" parentID=\"-1\" level=\"1\" writerID=\"0\" nodeType=\"1032\" template=\"0\" sortOrder=\"1\" createDate=\"2012-11-05T16:55:29\" updateDate=\"2012-11-05T16:55:44\" nodeName=\"test12\" urlName=\"test12\" writerName=\"admin\" nodeTypeAlias=\"Image\" path=\"-1,1057\"><umbracoFile>/media/54/tulips.jpg</umbracoFile><umbracoWidth>1024</umbracoWidth><umbracoHeight>768</umbracoHeight><umbracoBytes>620888</umbracoBytes><umbracoExtension>jpg</umbracoExtension><newsCrops><crops date=\"2012-11-05T16:55:34\"><crop name=\"thumbCrop\" x=\"154\" y=\"1\" x2=\"922\" y2=\"768\" url=\"/media/54/tulips_thumbCrop.jpg\" /></crops></newsCrops></Image></mediaItem><mediaItem><Image id=\"1055\" version=\"4df1f08a-3552-45f2-b4bf-fa980c762f4a\" parentID=\"-1\" level=\"1\" writerID=\"0\" nodeType=\"1032\" template=\"0\" sortOrder=\"1\" createDate=\"2012-11-05T16:29:58\" updateDate=\"2012-11-05T16:30:27\" nodeName=\"Test\" urlName=\"test\" writerName=\"admin\" nodeTypeAlias=\"Image\" path=\"-1,1055\"><umbracoFile>/media/41/hydrangeas.jpg</umbracoFile><umbracoWidth>1024</umbracoWidth><umbracoHeight>768</umbracoHeight><umbracoBytes>595284</umbracoBytes><umbracoExtension>jpg</umbracoExtension><newsCrops><crops date=\"2012-11-05T16:30:18\"><crop name=\"thumbCrop\" x=\"133\" y=\"0\" x2=\"902\" y2=\"768\" url=\"/media/41/hydrangeas_thumbCrop.jpg\" /></crops></newsCrops></Image></mediaItem></DAMP>";
var typedXml = new DynamicXml(xml);
dynamic dynamicXml = typedXml;
var typedTaken = typedXml.Take(1);
var dynamicTaken = dynamicXml.Take(1);
Assert.AreEqual(1, typedTaken.Count());
Assert.AreEqual(1, Enumerable.Count(dynamicTaken));
Assert.AreEqual("1057", typedTaken.ElementAt(0).BaseElement.Elements().First().Attribute("id").Value);
Assert.AreEqual("1057", Enumerable.First(Enumerable.ElementAt(dynamicTaken, 0).BaseElement.Elements()).Attribute("id").Value);
}
[Test]
public void Ensure_Legacy_Objects_Are_Returned()
{
var xml = "<DAMP fullMedia=\"\"><mediaItem><Image id=\"1057\" version=\"d58d5c16-153e-4896-892f-a722e45a69af\" parentID=\"-1\" level=\"1\" writerID=\"0\" nodeType=\"1032\" template=\"0\" sortOrder=\"1\" createDate=\"2012-11-05T16:55:29\" updateDate=\"2012-11-05T16:55:44\" nodeName=\"test12\" urlName=\"test12\" writerName=\"admin\" nodeTypeAlias=\"Image\" path=\"-1,1057\"><umbracoFile>/media/54/tulips.jpg</umbracoFile><umbracoWidth>1024</umbracoWidth><umbracoHeight>768</umbracoHeight><umbracoBytes>620888</umbracoBytes><umbracoExtension>jpg</umbracoExtension><newsCrops><crops date=\"2012-11-05T16:55:34\"><crop name=\"thumbCrop\" x=\"154\" y=\"1\" x2=\"922\" y2=\"768\" url=\"/media/54/tulips_thumbCrop.jpg\" /></crops></newsCrops></Image></mediaItem><mediaItem><Image id=\"1055\" version=\"4df1f08a-3552-45f2-b4bf-fa980c762f4a\" parentID=\"-1\" level=\"1\" writerID=\"0\" nodeType=\"1032\" template=\"0\" sortOrder=\"1\" createDate=\"2012-11-05T16:29:58\" updateDate=\"2012-11-05T16:30:27\" nodeName=\"Test\" urlName=\"test\" writerName=\"admin\" nodeTypeAlias=\"Image\" path=\"-1,1055\"><umbracoFile>/media/41/hydrangeas.jpg</umbracoFile><umbracoWidth>1024</umbracoWidth><umbracoHeight>768</umbracoHeight><umbracoBytes>595284</umbracoBytes><umbracoExtension>jpg</umbracoExtension><newsCrops><crops date=\"2012-11-05T16:30:18\"><crop name=\"thumbCrop\" x=\"133\" y=\"0\" x2=\"902\" y2=\"768\" url=\"/media/41/hydrangeas_thumbCrop.jpg\" /></crops></newsCrops></Image></mediaItem></DAMP>";
var mediaItems = new global::umbraco.MacroEngines.DynamicXml(xml);
//Debug.WriteLine("full xml = {0}", mediaItems.ToXml());
if (mediaItems.Count() != 0)
{
foreach (dynamic item in mediaItems)
{
Type itemType = item.GetType();
Debug.WriteLine("item type = {0}", itemType);
dynamic image = item.Image;
Type imageType = image.GetType();
Debug.WriteLine("image type = {0}", imageType);
//ensure they are the same
Assert.AreEqual(itemType, imageType);
//ensure they are legacy
Assert.AreEqual(typeof(global::umbraco.MacroEngines.DynamicXml), itemType);
Assert.AreEqual(typeof(global::umbraco.MacroEngines.DynamicXml), imageType);
}
}
}
/// <summary>
/// Test the current Core class
/// </summary>
[Test]
public void Find_Test_Core_Class()
{
RunFindTest(x => new DynamicXml(x));
}
/// <summary>
/// Tests the macroEngines legacy class
/// </summary>
[Test]
public void Find_Test_Legacy_Class()
{
RunFindTest(x => new global::umbraco.MacroEngines.DynamicXml(x));
}
private void RunFindTest(Func<string, dynamic> getDynamicXml)
{
var xmlstring = @"<test>
<item id='1' name='test 1' value='found 1'/>
<item id='2' name='test 2' value='found 2'/>
<item id='3' name='test 3' value='found 3'/>
</test>";
dynamic dXml = getDynamicXml(xmlstring);
var result1 = dXml.Find("@name", "test 1");
var result2 = dXml.Find("@name", "test 2");
var result3 = dXml.Find("@name", "test 3");
var result4 = dXml.Find("@name", "dont find");
Assert.AreEqual("found 1", result1.value);
Assert.AreEqual("found 2", result2.value);
Assert.AreEqual("found 3", result3.value);
Assert.Throws<RuntimeBinderException>(() =>
{
//this will throw because result4 is not found
var temp = result4.value;
});
}
}
}
@@ -9,7 +9,7 @@ using Umbraco.Core.Models;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web;
namespace Umbraco.Tests.DynamicDocument
namespace Umbraco.Tests.PublishedContent
{
/// <summary>
/// Unit tests for IPublishedContent and extensions
@@ -1,17 +1,17 @@
using System;
using System.Linq;
using System.Web;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.PropertyEditors;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web;
using Umbraco.Web.Models;
namespace Umbraco.Tests.DynamicDocument
namespace Umbraco.Tests.PublishedContent
{
/// <summary>
/// Tests the typed extension methods on IPublishedContent the same way we test the dynamic ones
/// Tests the methods on IPublishedContent using the DefaultPublishedContentStore
/// </summary>
[TestFixture]
public class PublishedContentTests : BaseWebTest
@@ -72,7 +72,7 @@ namespace Umbraco.Tests.DynamicDocument
});
//need to specify a custom callback for unit tests
DynamicPublishedContent.GetDataTypeCallback = (docTypeAlias, propertyAlias) =>
PublishedContentHelper.GetDataTypeCallback = (docTypeAlias, propertyAlias) =>
{
if (propertyAlias == "content")
{
@@ -105,6 +105,20 @@ namespace Umbraco.Tests.DynamicDocument
return doc;
}
[Test]
public void Get_Property_Value_Uses_Converter()
{
var doc = GetNode(1173);
var propVal = doc.GetPropertyValue("content");
Assert.IsTrue(TypeHelper.IsTypeAssignableFrom<IHtmlString>(propVal.GetType()));
Assert.AreEqual("<div>This is some content</div>", propVal.ToString());
var propVal2 = doc.GetPropertyValue<IHtmlString>("content");
Assert.IsTrue(TypeHelper.IsTypeAssignableFrom<IHtmlString>(propVal2.GetType()));
Assert.AreEqual("<div>This is some content</div>", propVal2.ToString());
}
[Test]
public void Complex_Linq()
{
@@ -113,7 +127,7 @@ namespace Umbraco.Tests.DynamicDocument
var result = doc.Ancestors().OrderBy(x => x.Level)
.Single()
.Descendants()
.FirstOrDefault(x => x.GetPropertyValue("selectedNodes", "").Split(',').Contains("1173"));
.FirstOrDefault(x => x.GetPropertyValue<string>("selectedNodes", "").Split(',').Contains("1173"));
Assert.IsNotNull(result);
}
@@ -255,17 +269,7 @@ namespace Umbraco.Tests.DynamicDocument
Assert.IsTrue(visible.IsVisible());
}
[Test]
public void Ensure_TinyMCE_Converted_Type_User_Property()
{
var doc = GetNode(1173);
throw new NotImplementedException("We currently don't have an extension method to return the formatted value using IPropertyValueConverter! This currently only works in the dynamic implementation");
//Assert.IsTrue(TypeHelper.IsTypeAssignableFrom<IHtmlString>(doc.GetPropertyValue().Content.GetType()));
//Assert.AreEqual("<div>This is some content</div>", doc.Content.ToString());
}
[Test]
public void Ancestor_Or_Self()
{
@@ -326,8 +330,8 @@ namespace Umbraco.Tests.DynamicDocument
Assert.IsNotNull(result);
Assert.AreEqual(6, result.Count());
Assert.IsTrue(result.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[] { 1173, 1174, 1176, 1175 }));
Assert.AreEqual(7, result.Count());
Assert.IsTrue(result.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[] { 1173, 1174, 1176, 1175, 4444 }));
}
[Test]
@@ -0,0 +1,343 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using System.Xml.XPath;
using Examine;
using Examine.LuceneEngine;
using Examine.LuceneEngine.Providers;
using Lucene.Net.Analysis.Standard;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models;
using Umbraco.Core.PropertyEditors;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.ExamineHelpers;
using Umbraco.Web;
using UmbracoExamine;
using UmbracoExamine.DataServices;
using umbraco.BusinessLogic;
using System.Linq;
namespace Umbraco.Tests.PublishedContent
{
/// <summary>
/// Tests the typed extension methods on IPublishedContent using the DefaultPublishedMediaStore
/// </summary>
[TestFixture]
public class PublishedMediaTests : BaseWebTest
{
public override void Initialize()
{
base.Initialize();
DoInitialization(GetUmbracoContext("/test", 1234));
}
/// <summary>
/// Shared with PublishMediaStoreTests
/// </summary>
/// <param name="umbContext"></param>
internal static void DoInitialization(UmbracoContext umbContext)
{
PropertyEditorValueConvertersResolver.Current = new PropertyEditorValueConvertersResolver(
new[]
{
typeof(DatePickerPropertyEditorValueConverter),
typeof(TinyMcePropertyEditorValueConverter),
typeof(YesNoPropertyEditorValueConverter)
});
//need to specify a custom callback for unit tests
PublishedContentHelper.GetDataTypeCallback = (docTypeAlias, propertyAlias) =>
{
if (propertyAlias == "content")
{
//return the rte type id
return Guid.Parse("5e9b75ae-face-41c8-b47e-5f4b0fd82f83");
}
return Guid.Empty;
};
UmbracoSettings.ForceSafeAliases = true;
UmbracoSettings.UmbracoLibraryCacheDuration = 1800;
UmbracoContext.Current = umbContext;
PublishedMediaStoreResolver.Current = new PublishedMediaStoreResolver(new DefaultPublishedMediaStore());
UmbracoSettings.ForceSafeAliases = true;
}
public override void TearDown()
{
base.TearDown();
DoTearDown();
}
/// <summary>
/// Shared with PublishMediaStoreTests
/// </summary>
internal static void DoTearDown()
{
PropertyEditorValueConvertersResolver.Reset();
UmbracoContext.Current = null;
PublishedMediaStoreResolver.Reset();
}
/// <summary>
/// Shared with PublishMediaStoreTests
/// </summary>
/// <param name="id"></param>
/// <param name="umbracoContext"></param>
/// <returns></returns>
internal static IPublishedContent GetNode(int id, UmbracoContext umbracoContext)
{
var ctx = umbracoContext;
var mediaStore = new DefaultPublishedMediaStore();
var doc = mediaStore.GetDocumentById(ctx, id);
Assert.IsNotNull(doc);
return doc;
}
private IPublishedContent GetNode(int id)
{
return GetNode(id, GetUmbracoContext("/test", 1234));
}
[Test]
public void Children_With_Examine()
{
var newIndexFolder = new DirectoryInfo(Path.Combine("App_Data\\CWSIndexSetTest", Guid.NewGuid().ToString()));
var indexInit = new IndexInitializer();
var indexer = indexInit.GetUmbracoIndexer(newIndexFolder);
indexer.RebuildIndex();
var store = new DefaultPublishedMediaStore(indexInit.GetUmbracoSearcher(newIndexFolder));
//we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace
var publishedMedia = store.GetDocumentById(GetUmbracoContext("/test", 1234), 1111);
var rootChildren = publishedMedia.Children();
Assert.IsTrue(rootChildren.Select(x => x.Id).ContainsAll(new[] { 2222, 1113, 1114, 1115, 1116 }));
var publishedChild1 = store.GetDocumentById(GetUmbracoContext("/test", 1234), 2222);
var subChildren = publishedChild1.Children();
Assert.IsTrue(subChildren.Select(x => x.Id).ContainsAll(new[] { 2112 }));
}
[Test]
public void Descendants_With_Examine()
{
var newIndexFolder = new DirectoryInfo(Path.Combine("App_Data\\CWSIndexSetTest", Guid.NewGuid().ToString()));
var indexInit = new IndexInitializer();
var indexer = indexInit.GetUmbracoIndexer(newIndexFolder);
indexer.RebuildIndex();
var store = new DefaultPublishedMediaStore(indexInit.GetUmbracoSearcher(newIndexFolder));
//we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace
var publishedMedia = store.GetDocumentById(GetUmbracoContext("/test", 1234), 1111);
var rootDescendants = publishedMedia.Descendants();
Assert.IsTrue(rootDescendants.Select(x => x.Id).ContainsAll(new[] { 2112, 2222, 1113, 1114, 1115, 1116 }));
var publishedChild1 = store.GetDocumentById(GetUmbracoContext("/test", 1234), 2222);
var subDescendants = publishedChild1.Descendants();
Assert.IsTrue(subDescendants.Select(x => x.Id).ContainsAll(new[] { 2112, 3113 }));
}
[Test]
public void DescendantsOrSelf_With_Examine()
{
var newIndexFolder = new DirectoryInfo(Path.Combine("App_Data\\CWSIndexSetTest", Guid.NewGuid().ToString()));
var indexInit = new IndexInitializer();
var indexer = indexInit.GetUmbracoIndexer(newIndexFolder);
indexer.RebuildIndex();
var store = new DefaultPublishedMediaStore(indexInit.GetUmbracoSearcher(newIndexFolder));
//we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace
var publishedMedia = store.GetDocumentById(GetUmbracoContext("/test", 1234), 1111);
var rootDescendants = publishedMedia.DescendantsOrSelf();
Assert.IsTrue(rootDescendants.Select(x => x.Id).ContainsAll(new[] { 1111, 2112, 2222, 1113, 1114, 1115, 1116 }));
var publishedChild1 = store.GetDocumentById(GetUmbracoContext("/test", 1234), 2222);
var subDescendants = publishedChild1.DescendantsOrSelf();
Assert.IsTrue(subDescendants.Select(x => x.Id).ContainsAll(new[] { 2222, 2112, 3113 }));
}
[Test]
public void Ancestors_With_Examine()
{
var newIndexFolder = new DirectoryInfo(Path.Combine("App_Data\\CWSIndexSetTest", Guid.NewGuid().ToString()));
var indexInit = new IndexInitializer();
var indexer = indexInit.GetUmbracoIndexer(newIndexFolder);
indexer.RebuildIndex();
var store = new DefaultPublishedMediaStore(indexInit.GetUmbracoSearcher(newIndexFolder));
//we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace
var publishedMedia = store.GetDocumentById(GetUmbracoContext("/test", 1234), 3113);
var ancestors = publishedMedia.Ancestors();
Assert.IsTrue(ancestors.Select(x => x.Id).ContainsAll(new[] { 2112, 2222, 1111 }));
}
[Test]
public void AncestorsOrSelf_With_Examine()
{
var newIndexFolder = new DirectoryInfo(Path.Combine("App_Data\\CWSIndexSetTest", Guid.NewGuid().ToString()));
var indexInit = new IndexInitializer();
var indexer = indexInit.GetUmbracoIndexer(newIndexFolder);
indexer.RebuildIndex();
var store = new DefaultPublishedMediaStore(indexInit.GetUmbracoSearcher(newIndexFolder));
//we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace
var publishedMedia = store.GetDocumentById(GetUmbracoContext("/test", 1234), 3113);
var ancestors = publishedMedia.AncestorsOrSelf();
Assert.IsTrue(ancestors.Select(x => x.Id).ContainsAll(new[] { 3113, 2112, 2222, 1111 }));
}
[Test]
public void Children_Without_Examine()
{
var user = new User(0);
var mType = global::umbraco.cms.businesslogic.media.MediaType.MakeNew(user, "TestMediaType");
var mRoot = global::umbraco.cms.businesslogic.media.Media.MakeNew("MediaRoot", mType, user, -1);
var mChild1 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child1", mType, user, mRoot.Id);
var mChild2 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child2", mType, user, mRoot.Id);
var mChild3 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child3", mType, user, mRoot.Id);
var mSubChild1 = global::umbraco.cms.businesslogic.media.Media.MakeNew("SubChild1", mType, user, mChild1.Id);
var mSubChild2 = global::umbraco.cms.businesslogic.media.Media.MakeNew("SubChild2", mType, user, mChild1.Id);
var mSubChild3 = global::umbraco.cms.businesslogic.media.Media.MakeNew("SubChild3", mType, user, mChild1.Id);
var publishedMedia = GetNode(mRoot.Id);
var rootChildren = publishedMedia.Children();
Assert.IsTrue(rootChildren.Select(x => x.Id).ContainsAll(new[] {mChild1.Id, mChild2.Id, mChild3.Id}));
var publishedChild1 = GetNode(mChild1.Id);
var subChildren = publishedChild1.Children();
Assert.IsTrue(subChildren.Select(x => x.Id).ContainsAll(new[] { mSubChild1.Id, mSubChild2.Id, mSubChild3.Id }));
}
[Test]
public void Descendants_Without_Examine()
{
var user = new User(0);
var mType = global::umbraco.cms.businesslogic.media.MediaType.MakeNew(user, "TestMediaType");
var mRoot = global::umbraco.cms.businesslogic.media.Media.MakeNew("MediaRoot", mType, user, -1);
var mChild1 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child1", mType, user, mRoot.Id);
var mChild2 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child2", mType, user, mRoot.Id);
var mChild3 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child3", mType, user, mRoot.Id);
var mSubChild1 = global::umbraco.cms.businesslogic.media.Media.MakeNew("SubChild1", mType, user, mChild1.Id);
var mSubChild2 = global::umbraco.cms.businesslogic.media.Media.MakeNew("SubChild2", mType, user, mChild1.Id);
var mSubChild3 = global::umbraco.cms.businesslogic.media.Media.MakeNew("SubChild3", mType, user, mChild1.Id);
var publishedMedia = GetNode(mRoot.Id);
var rootDescendants = publishedMedia.Descendants();
Assert.IsTrue(rootDescendants.Select(x => x.Id).ContainsAll(new[] { mChild1.Id, mChild2.Id, mChild3.Id, mSubChild1.Id, mSubChild2.Id, mSubChild3.Id }));
var publishedChild1 = GetNode(mChild1.Id);
var subDescendants = publishedChild1.Descendants();
Assert.IsTrue(subDescendants.Select(x => x.Id).ContainsAll(new[] { mSubChild1.Id, mSubChild2.Id, mSubChild3.Id }));
}
[Test]
public void DescendantsOrSelf_Without_Examine()
{
var user = new User(0);
var mType = global::umbraco.cms.businesslogic.media.MediaType.MakeNew(user, "TestMediaType");
var mRoot = global::umbraco.cms.businesslogic.media.Media.MakeNew("MediaRoot", mType, user, -1);
var mChild1 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child1", mType, user, mRoot.Id);
var mChild2 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child2", mType, user, mRoot.Id);
var mChild3 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child3", mType, user, mRoot.Id);
var mSubChild1 = global::umbraco.cms.businesslogic.media.Media.MakeNew("SubChild1", mType, user, mChild1.Id);
var mSubChild2 = global::umbraco.cms.businesslogic.media.Media.MakeNew("SubChild2", mType, user, mChild1.Id);
var mSubChild3 = global::umbraco.cms.businesslogic.media.Media.MakeNew("SubChild3", mType, user, mChild1.Id);
var publishedMedia = GetNode(mRoot.Id);
var rootDescendantsOrSelf = publishedMedia.DescendantsOrSelf();
Assert.IsTrue(rootDescendantsOrSelf.Select(x => x.Id).ContainsAll(
new[] { mRoot.Id, mChild1.Id, mChild2.Id, mChild3.Id, mSubChild1.Id, mSubChild2.Id, mSubChild3.Id }));
var publishedChild1 = GetNode(mChild1.Id);
var subDescendantsOrSelf = publishedChild1.DescendantsOrSelf();
Assert.IsTrue(subDescendantsOrSelf.Select(x => x.Id).ContainsAll(
new[] { mChild1.Id, mSubChild1.Id, mSubChild2.Id, mSubChild3.Id }));
}
[Test]
public void Parent_Without_Examine()
{
var user = new User(0);
var mType = global::umbraco.cms.businesslogic.media.MediaType.MakeNew(user, "TestMediaType");
var mRoot = global::umbraco.cms.businesslogic.media.Media.MakeNew("MediaRoot", mType, user, -1);
var mChild1 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child1", mType, user, mRoot.Id);
var mChild2 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child2", mType, user, mRoot.Id);
var mChild3 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child3", mType, user, mRoot.Id);
var mSubChild1 = global::umbraco.cms.businesslogic.media.Media.MakeNew("SubChild1", mType, user, mChild1.Id);
var mSubChild2 = global::umbraco.cms.businesslogic.media.Media.MakeNew("SubChild2", mType, user, mChild1.Id);
var mSubChild3 = global::umbraco.cms.businesslogic.media.Media.MakeNew("SubChild3", mType, user, mChild1.Id);
var publishedRoot = GetNode(mRoot.Id);
Assert.AreEqual(null, publishedRoot.Parent);
var publishedChild1 = GetNode(mChild1.Id);
Assert.AreEqual(mRoot.Id, publishedChild1.Parent.Id);
var publishedSubChild1 = GetNode(mSubChild1.Id);
Assert.AreEqual(mChild1.Id, publishedSubChild1.Parent.Id);
}
[Test]
public void Ancestors_Without_Examine()
{
var user = new User(0);
var mType = global::umbraco.cms.businesslogic.media.MediaType.MakeNew(user, "TestMediaType");
var mRoot = global::umbraco.cms.businesslogic.media.Media.MakeNew("MediaRoot", mType, user, -1);
var mChild1 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child1", mType, user, mRoot.Id);
var mChild2 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child2", mType, user, mRoot.Id);
var mChild3 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child3", mType, user, mRoot.Id);
var mSubChild1 = global::umbraco.cms.businesslogic.media.Media.MakeNew("SubChild1", mType, user, mChild1.Id);
var mSubChild2 = global::umbraco.cms.businesslogic.media.Media.MakeNew("SubChild2", mType, user, mChild1.Id);
var mSubChild3 = global::umbraco.cms.businesslogic.media.Media.MakeNew("SubChild3", mType, user, mChild1.Id);
var publishedSubChild1 = GetNode(mSubChild1.Id);
Assert.IsTrue(publishedSubChild1.Ancestors().Select(x => x.Id).ContainsAll(new[] {mChild1.Id, mRoot.Id}));
}
[Test]
public void AncestorsOrSelf_Without_Examine()
{
var user = new User(0);
var mType = global::umbraco.cms.businesslogic.media.MediaType.MakeNew(user, "TestMediaType");
var mRoot = global::umbraco.cms.businesslogic.media.Media.MakeNew("MediaRoot", mType, user, -1);
var mChild1 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child1", mType, user, mRoot.Id);
var mChild2 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child2", mType, user, mRoot.Id);
var mChild3 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child3", mType, user, mRoot.Id);
var mSubChild1 = global::umbraco.cms.businesslogic.media.Media.MakeNew("SubChild1", mType, user, mChild1.Id);
var mSubChild2 = global::umbraco.cms.businesslogic.media.Media.MakeNew("SubChild2", mType, user, mChild1.Id);
var mSubChild3 = global::umbraco.cms.businesslogic.media.Media.MakeNew("SubChild3", mType, user, mChild1.Id);
var publishedSubChild1 = GetNode(mSubChild1.Id);
Assert.IsTrue(publishedSubChild1.AncestorsOrSelf().Select(x => x.Id).ContainsAll(
new[] { mSubChild1.Id, mChild1.Id, mRoot.Id }));
}
}
}
@@ -1,5 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
@@ -9,7 +8,7 @@ using Umbraco.Core.Models;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web;
namespace Umbraco.Tests.DynamicDocument
namespace Umbraco.Tests.PublishedContent
{
[TestFixture]
public class StronglyTypedQueryTests : BaseWebTest
@@ -18,7 +18,7 @@ namespace Umbraco.Tests.Resolvers
TestHelper.SetupLog4NetForTests();
//this ensures its reset
PluginManager.Current = new PluginManager();
PluginManager.Current = new PluginManager(false);
//for testing, we'll specify which assemblies are scanned for the PluginTypeResolver
PluginManager.Current.AssembliesToScan = new[]
@@ -18,7 +18,7 @@ namespace Umbraco.Tests.Resolvers
TestHelper.SetupLog4NetForTests();
//this ensures its reset
PluginManager.Current = new PluginManager();
PluginManager.Current = new PluginManager(false);
//for testing, we'll specify which assemblies are scanned for the PluginTypeResolver
PluginManager.Current.AssembliesToScan = new[]
@@ -18,7 +18,7 @@ namespace Umbraco.Tests.Resolvers
TestHelper.SetupLog4NetForTests();
//this ensures its reset
PluginManager.Current = new PluginManager();
PluginManager.Current = new PluginManager(false);
//for testing, we'll specify which assemblies are scanned for the PluginTypeResolver
PluginManager.Current.AssembliesToScan = new[]
@@ -4,6 +4,7 @@ using System.Web.Routing;
using System.Xml;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
using Umbraco.Core.ObjectResolution;
using Umbraco.Tests.Stubs;
@@ -41,6 +42,7 @@ namespace Umbraco.Tests.TestHelpers
public virtual void TearDown()
{
//reset the app context
ApplicationContext.ApplicationCache.ClearAllCache();
ApplicationContext.Current = null;
Resolution.IsFrozen = false;
if (RequiresDbSetup)
@@ -49,6 +51,8 @@ namespace Umbraco.Tests.TestHelpers
AppDomain.CurrentDomain.SetData("DataDirectory", null);
Cache.ClearAllCache();
UmbracoSettings.ResetSetters();
}
/// <summary>
@@ -0,0 +1,99 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.17929
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Umbraco.Tests.TestHelpers.ExamineHelpers {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class ExamineResources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal ExamineResources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Umbraco.Tests.TestHelpers.ExamineHelpers.ExamineResources", typeof(ExamineResources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
///&lt;media&gt;
/// &lt;node id=&quot;1111&quot; version=&quot;902e13f7-5793-482a-9e06-cd94eebd1de0&quot; parentID=&quot;-1&quot; level=&quot;1&quot; writerID=&quot;0&quot; nodeType=&quot;1031&quot; template=&quot;0&quot; sortOrder=&quot;2&quot; createDate=&quot;2010-05-19T15:26:08&quot; updateDate=&quot;2010-05-19T15:26:09&quot; nodeName=&quot;Product Images&quot; urlName=&quot;productimages&quot; writerName=&quot;Administrator&quot; nodeTypeAlias=&quot;Folder&quot; path=&quot;-1,1111&quot;&gt;
/// &lt;data alias=&quot;contents&quot;&gt;&lt;/data&gt;
/// &lt;node id=&quot;2222&quot; version=&quot;902e13f7-5793-482a-9e06-cd94eebd1de0&quot; parentID=&quot;-1&quot; level=&quot;1&quot; writerID=&quot;0&quot; [rest of string was truncated]&quot;;.
/// </summary>
internal static string media {
get {
return ResourceManager.GetString("media", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
///&lt;!DOCTYPE root[
/// &lt;!ELEMENT CWS_Contact ANY&gt;
/// &lt;!ATTLIST CWS_Contact id ID #REQUIRED&gt;
/// &lt;!ELEMENT CWS_EmailAFriend ANY&gt;
/// &lt;!ATTLIST CWS_EmailAFriend id ID #REQUIRED&gt;
/// &lt;!ELEMENT CWS_EventItem ANY&gt;
/// &lt;!ATTLIST CWS_EventItem id ID #REQUIRED&gt;
/// &lt;!ELEMENT CWS_Galleries ANY&gt;
/// &lt;!ATTLIST CWS_Galleries id ID #REQUIRED&gt;
/// &lt;!ELEMENT CWS_Gallery ANY&gt;
/// &lt;!ATTLIST CWS_Gallery id ID #REQUIRED&gt;
/// &lt;!ELEMENT CWS_Home ANY&gt;
/// &lt;!ATTLIST CWS_Home id ID #REQUIRED&gt;
/// &lt;!ELEMENT CWS_NewsEven [rest of string was truncated]&quot;;.
/// </summary>
internal static string umbraco {
get {
return ResourceManager.GetString("umbraco", resourceCulture);
}
}
}
}
@@ -0,0 +1,127 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="media" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>media.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="umbraco" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>umbraco.config;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
</root>
@@ -0,0 +1,360 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using System.Xml.XPath;
using Examine;
using Examine.LuceneEngine;
using Examine.LuceneEngine.Providers;
using Lucene.Net.Analysis.Standard;
using UmbracoExamine;
using UmbracoExamine.DataServices;
namespace Umbraco.Tests.TestHelpers.ExamineHelpers
{
/// <summary>
/// Used internally by test classes to initialize a new index from the template
/// </summary>
internal class IndexInitializer
{
public IndexInitializer()
{
//ensure the umbraco.config and media.xml files exist at the location where we need to load them
var appData = Path.Combine(TestHelper.CurrentAssemblyDirectory, "App_Data");
Directory.CreateDirectory(appData);
var umbConfig = Path.Combine(appData, "umbraco.config");
File.Delete(umbConfig);
using (var s = File.CreateText(umbConfig))
{
s.Write(ExamineResources.umbraco);
}
var umbMedia = Path.Combine(appData, "media.xml");
File.Delete(umbMedia);
using (var s = File.CreateText(umbMedia))
{
s.Write(ExamineResources.media);
}
}
public UmbracoContentIndexer GetUmbracoIndexer(DirectoryInfo d)
{
var i = new UmbracoContentIndexer(new IndexCriteria(
new[]
{
new TestIndexField { Name = "id", EnableSorting = true, Type = "Number" },
new TestIndexField { Name = "nodeName", EnableSorting = true },
new TestIndexField { Name = "updateDate", EnableSorting = true, Type = "DateTime" },
new TestIndexField { Name = "writerName" },
new TestIndexField { Name = "path" },
new TestIndexField { Name = "nodeTypeAlias" },
new TestIndexField { Name = "parentID" }
},
Enumerable.Empty<IIndexField>(),
//new[]
// {
// new TestIndexField { Name = "headerText" },
// new TestIndexField { Name = "bodyText" },
// new TestIndexField { Name = "metaDescription" },
// new TestIndexField { Name = "metaKeywords" },
// new TestIndexField { Name = "bodyTextColOne" },
// new TestIndexField { Name = "bodyTextColTwo" },
// new TestIndexField { Name = "xmlStorageTest" }
// },
Enumerable.Empty<string>(),
//new[]
// {
// "CWS_Home",
// "CWS_Textpage",
// "CWS_TextpageTwoCol",
// "CWS_NewsEventsList",
// "CWS_NewsItem",
// "CWS_Gallery",
// "CWS_EventItem",
// "Image",
// },
new string[] { },
-1),
d,
new TestDataService(),
new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29),
false);
//i.IndexSecondsInterval = 1;
i.IndexingError += IndexingError;
return i;
}
public UmbracoExamineSearcher GetUmbracoSearcher(DirectoryInfo d)
{
return new UmbracoExamineSearcher(d, new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29));
}
//public SimpleDataIndexer GetSimpleIndexer(DirectoryInfo d)
//{
// var i = new SimpleDataIndexer(new IndexCriteria(
// new IIndexField[] { },
// new[]
// {
// new TestIndexField { Name = "Author" },
// new TestIndexField { Name = "DateCreated", EnableSorting = true, Type = "DateTime" },
// new TestIndexField { Name = "Title" },
// new TestIndexField { Name = "Photographer" },
// new TestIndexField { Name = "YearCreated", Type = "Date.Year" },
// new TestIndexField { Name = "MonthCreated", Type = "Date.Month" },
// new TestIndexField { Name = "DayCreated", Type = "Date.Day" },
// new TestIndexField { Name = "HourCreated", Type = "Date.Hour" },
// new TestIndexField { Name = "MinuteCreated", Type = "Date.Minute" },
// new TestIndexField { Name = "SomeNumber", Type = "Number" },
// new TestIndexField { Name = "SomeFloat", Type = "Float" },
// new TestIndexField { Name = "SomeDouble", Type = "Double" },
// new TestIndexField { Name = "SomeLong", Type = "Long" }
// },
// new string[] { },
// new string[] { },
// -1),
// d,
// new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29),
// new TestSimpleDataProvider(),
// new[] { "Documents", "Pictures" },
// false);
// i.IndexingError += IndexingError;
// return i;
//}
public LuceneSearcher GetLuceneSearcher(DirectoryInfo d)
{
return new LuceneSearcher(d, new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29));
}
//public PDFIndexer GetPdfIndexer(DirectoryInfo d)
//{
// var i = new PDFIndexer(d,
// new TestDataService(),
// new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29),
// false);
// i.IndexingError += IndexingError;
// return i;
//}
public MultiIndexSearcher GetMultiSearcher(DirectoryInfo pdfDir, DirectoryInfo simpleDir, DirectoryInfo conventionDir, DirectoryInfo cwsDir)
{
var i = new MultiIndexSearcher(new[] { pdfDir, simpleDir, conventionDir, cwsDir }, new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29));
return i;
}
internal void IndexingError(object sender, IndexingErrorEventArgs e)
{
throw new ApplicationException(e.Message, e.InnerException);
}
internal class TestIndexField : IIndexField
{
public string Name { get; set; }
public bool EnableSorting { get; set; }
public string Type { get; set; }
}
internal class TestDataService : IDataService
{
public TestDataService()
{
ContentService = new TestContentService();
LogService = new TestLogService();
MediaService = new TestMediaService();
}
#region IDataService Members
public IContentService ContentService { get; private set; }
public ILogService LogService { get; private set; }
public IMediaService MediaService { get; private set; }
public string MapPath(string virtualPath)
{
return new DirectoryInfo(TestHelper.CurrentAssemblyDirectory) + "\\" + virtualPath.Replace("/", "\\");
}
#endregion
}
/// <summary>
/// A mock data service used to return content from the XML data file created with CWS
/// </summary>
internal class TestContentService : IContentService
{
public const int ProtectedNode = 1142;
public TestContentService()
{
var xmlFile = new DirectoryInfo(TestHelper.CurrentAssemblyDirectory).GetDirectories("App_Data")
.Single()
.GetFiles("umbraco.config")
.Single();
_xDoc = XDocument.Load(xmlFile.FullName);
}
#region IContentService Members
/// <summary>
/// Return the XDocument containing the xml from the umbraco.config xml file
/// </summary>
/// <param name="xpath"></param>
/// <returns></returns>
/// <remarks>
/// This is no different in the test suite as published content
/// </remarks>
public XDocument GetLatestContentByXPath(string xpath)
{
var xdoc = XDocument.Parse("<content></content>");
xdoc.Root.Add(_xDoc.XPathSelectElements(xpath));
return xdoc;
}
/// <summary>
/// Return the XDocument containing the xml from the umbraco.config xml file
/// </summary>
/// <param name="xpath"></param>
/// <returns></returns>
public XDocument GetPublishedContentByXPath(string xpath)
{
var xdoc = XDocument.Parse("<content></content>");
xdoc.Root.Add(_xDoc.XPathSelectElements(xpath));
return xdoc;
}
public string StripHtml(string value)
{
const string pattern = @"<(.|\n)*?>";
return Regex.Replace(value, pattern, string.Empty);
}
public bool IsProtected(int nodeId, string path)
{
// single node is marked as protected for test indexer
// hierarchy is not important for this test
return nodeId == ProtectedNode;
}
public IEnumerable<string> GetAllUserPropertyNames()
{
return GetPublishedContentByXPath("//*[count(@id)>0]")
.Root
.Elements()
.Select(x => x.Name.LocalName)
.ToList();
}
public IEnumerable<string> GetAllSystemPropertyNames()
{
return new Dictionary<string, FieldIndexTypes>()
{
{"id", FieldIndexTypes.NOT_ANALYZED},
{"version", FieldIndexTypes.NOT_ANALYZED},
{"parentID", FieldIndexTypes.NOT_ANALYZED},
{"level", FieldIndexTypes.NOT_ANALYZED},
{"writerID", FieldIndexTypes.NOT_ANALYZED},
{"creatorID", FieldIndexTypes.NOT_ANALYZED},
{"nodeType", FieldIndexTypes.NOT_ANALYZED},
{"template", FieldIndexTypes.NOT_ANALYZED},
{"sortOrder", FieldIndexTypes.NOT_ANALYZED},
{"createDate", FieldIndexTypes.NOT_ANALYZED},
{"updateDate", FieldIndexTypes.NOT_ANALYZED},
{"nodeName", FieldIndexTypes.ANALYZED},
{"urlName", FieldIndexTypes.NOT_ANALYZED},
{"writerName", FieldIndexTypes.ANALYZED},
{"creatorName", FieldIndexTypes.ANALYZED},
{"nodeTypeAlias", FieldIndexTypes.ANALYZED},
{"path", FieldIndexTypes.NOT_ANALYZED}
}.Select(x => x.Key);
}
#endregion
private readonly XDocument _xDoc;
}
internal class TestLogService : ILogService
{
#region ILogService Members
public string ProviderName { get; set; }
public void AddErrorLog(int nodeId, string msg)
{
Trace.WriteLine("ERROR: (" + nodeId.ToString() + ") " + msg);
}
public void AddInfoLog(int nodeId, string msg)
{
Trace.WriteLine("INFO: (" + nodeId.ToString() + ") " + msg);
}
public void AddVerboseLog(int nodeId, string msg)
{
if (LogLevel == LoggingLevel.Verbose)
Trace.WriteLine("VERBOSE: (" + nodeId.ToString() + ") " + msg);
}
public LoggingLevel LogLevel
{
get
{
return LoggingLevel.Verbose;
}
set
{
//do nothing
}
}
#endregion
}
internal class TestMediaService : IMediaService
{
public TestMediaService()
{
var xmlFile = new DirectoryInfo(TestHelper.CurrentAssemblyDirectory).GetDirectories("App_Data")
.Single()
.GetFiles("media.xml")
.Single();
m_Doc = XDocument.Load(xmlFile.FullName);
}
#region IMediaService Members
public System.Xml.Linq.XDocument GetLatestMediaByXpath(string xpath)
{
var xdoc = XDocument.Parse("<media></media>");
xdoc.Root.Add(m_Doc.XPathSelectElements(xpath));
return xdoc;
}
#endregion
private XDocument m_Doc;
}
}
}
@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<media>
<node id="1111" version="902e13f7-5793-482a-9e06-cd94eebd1de0" parentID="-1" level="1" writerID="0" nodeType="1031" template="0" sortOrder="2" createDate="2010-05-19T15:26:08" updateDate="2010-05-19T15:26:09" nodeName="Product Images" urlName="productimages" writerName="Administrator" nodeTypeAlias="Folder" path="-1,1111">
<data alias="contents"></data>
<node id="2222" version="902e13f7-5793-482a-9e06-cd94eebd1de0" parentID="1111" level="1" writerID="0" nodeType="1031" template="0" sortOrder="2" createDate="2010-05-19T15:26:08" updateDate="2010-05-19T15:26:09" nodeName="Product Images" urlName="productimages" writerName="Administrator" nodeTypeAlias="Folder" path="-1,1111,2222">
<data alias="contents"></data>
<node id="2112" version="5b3e46ab-3e37-4cfa-ab70-014234b5bd39" parentID="2222" level="2" writerID="0" nodeType="1032" template="0" sortOrder="1" createDate="2010-05-19T17:32:46" updateDate="2010-05-19T17:32:46" nodeName="Sam's Umbraco Image" urlName="acnestressscrub" writerName="Administrator" nodeTypeAlias="Image" path="-1,1111,2222,2112">
<data alias="umbracoFile"><![CDATA[/media/1234/blah.pdf]]></data>
<data alias="umbracoWidth">115</data>
<data alias="umbracoHeight">268</data>
<data alias="umbracoBytes">10726</data>
<data alias="umbracoExtension">jpg</data>
<node id="3113" version="5b3e46ab-3e37-4cfa-ab70-014234b5bd33" parentID="2112" level="3" writerID="0" nodeType="1032" template="0" sortOrder="2" createDate="2010-05-19T17:32:46" updateDate="2010-05-19T17:32:46" nodeName="Another Umbraco Image" urlName="acnestressscrub" writerName="Administrator" nodeTypeAlias="Image" path="-1,1111,2222,2112,3113">
<data alias="umbracoFile"><![CDATA[/media/1234/blah.pdf]]></data>
<data alias="umbracoWidth">115</data>
<data alias="umbracoHeight">268</data>
<data alias="umbracoBytes">10726</data>
<data alias="umbracoExtension">jpg</data>
</node>
</node>
</node>
<node id="1113" version="5b3e46ab-3e37-4cfa-ab70-014234b5bd39" parentID="1111" level="2" writerID="0" nodeType="1032" template="0" sortOrder="1" createDate="2010-05-19T17:32:46" updateDate="2010-05-19T17:32:46" nodeName="Acne Stress Scrub" urlName="acnestressscrub" writerName="Administrator" nodeTypeAlias="File" path="-1,1111,1113">
<data alias="umbracoFile"><![CDATA[/App_Data/VS2010CSharp.pdf]]></data>
<data alias="umbracoWidth">115</data>
<data alias="umbracoHeight">268</data>
<data alias="umbracoBytes">10726</data>
<data alias="umbracoExtension">jpg</data>
</node>
<node id="1114" version="5b3e46ab-3e37-4cfa-ab70-014234b5bd39" parentID="1111" level="2" writerID="0" nodeType="1032" template="0" sortOrder="1" createDate="2010-05-19T17:32:46" updateDate="2010-05-19T17:32:46" nodeName="String thoery" urlName="stringtheory" writerName="Administrator" nodeTypeAlias="File" path="-1,1111,1114">
<data alias="umbracoFile"><![CDATA[/App_Data/StringTheory.pdf]]></data>
<data alias="umbracoWidth">115</data>
<data alias="umbracoHeight">268</data>
<data alias="umbracoBytes">10726</data>
<data alias="umbracoExtension">jpg</data>
</node>
<node id="1115" version="5b3e46ab-3e37-4cfa-ab70-014234b5bd39" parentID="1111" level="2" writerID="0" nodeType="1032" template="0" sortOrder="1" createDate="2010-05-19T17:32:46" updateDate="2010-05-19T17:32:46" nodeName="Umbraco Contour" urlName="umbracocontour" writerName="Administrator" nodeTypeAlias="File" path="-1,1111,1115">
<data alias="umbracoFile"><![CDATA[/App_Data/UmbracoContour.pdf]]></data>
<data alias="umbracoWidth">115</data>
<data alias="umbracoHeight">268</data>
<data alias="umbracoBytes">10726</data>
<data alias="umbracoExtension">jpg</data>
</node>
<node id="1116" version="5b3e46ab-3e37-4cfa-ab70-014234b5bd39" parentID="1111" level="2" writerID="0" nodeType="1032" template="0" sortOrder="1" createDate="2010-05-19T17:32:46" updateDate="2010-05-19T17:32:46" nodeName="PDF Standards" urlName="pdfstandards" writerName="Administrator" nodeTypeAlias="File" path="-1,1111,1116">
<data alias="umbracoFile"><![CDATA[/App_Data/PDFStandards.pdf]]></data>
<data alias="umbracoWidth">115</data>
<data alias="umbracoHeight">268</data>
<data alias="umbracoBytes">10726</data>
<data alias="umbracoExtension">jpg</data>
</node>
</node>
</media>
@@ -0,0 +1,656 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root[
<!ELEMENT CWS_Contact ANY>
<!ATTLIST CWS_Contact id ID #REQUIRED>
<!ELEMENT CWS_EmailAFriend ANY>
<!ATTLIST CWS_EmailAFriend id ID #REQUIRED>
<!ELEMENT CWS_EventItem ANY>
<!ATTLIST CWS_EventItem id ID #REQUIRED>
<!ELEMENT CWS_Galleries ANY>
<!ATTLIST CWS_Galleries id ID #REQUIRED>
<!ELEMENT CWS_Gallery ANY>
<!ATTLIST CWS_Gallery id ID #REQUIRED>
<!ELEMENT CWS_Home ANY>
<!ATTLIST CWS_Home id ID #REQUIRED>
<!ELEMENT CWS_NewsEventsList ANY>
<!ATTLIST CWS_NewsEventsList id ID #REQUIRED>
<!ELEMENT CWS_NewsItem ANY>
<!ATTLIST CWS_NewsItem id ID #REQUIRED>
<!ELEMENT CWS_Photo ANY>
<!ATTLIST CWS_Photo id ID #REQUIRED>
<!ELEMENT CWS_Textpage ANY>
<!ATTLIST CWS_Textpage id ID #REQUIRED>
<!ELEMENT CWS_TextpageTwoCol ANY>
<!ATTLIST CWS_TextpageTwoCol id ID #REQUIRED>
]>
<root id="-1">
<CWS_Home id="1139" parentID="-1" level="1" writerID="0" creatorID="0" nodeType="1125" template="1110" sortOrder="2" createDate="2009-02-26T18:39:39" updateDate="2010-05-03T20:34:27" nodeName="Home" urlName="home" writerName="Administrator" creatorName="Administrator" path="-1,1139" isDoc="">
<CWS_Textpage id="1140" parentID="1139" level="2" writerID="0" creatorID="0" nodeType="1129" template="1117" sortOrder="1" createDate="2009-02-26T18:47:46" updateDate="2010-04-22T02:19:21" nodeName="About" urlName="about" writerName="Administrator" creatorName="Administrator" path="-1,1139,1140" isDoc="">
<CWS_Textpage id="1141" parentID="1140" level="3" writerID="0" creatorID="0" nodeType="1129" template="1117" sortOrder="1" createDate="2009-02-26T18:51:52" updateDate="2010-04-22T02:18:30" nodeName="About Umbraco" urlName="about-umbraco" writerName="Administrator" creatorName="Administrator" path="-1,1139,1140,1141" isDoc="">
<umbracoUrlName>
</umbracoUrlName>
<umbracoUrlAlias>
</umbracoUrlAlias>
<metaDescription><![CDATA[]]></metaDescription>
<metaKeywords><![CDATA[]]></metaKeywords>
<umbracoRedirect>
</umbracoRedirect>
<umbracoNaviHide>0</umbracoNaviHide>
<headerText>
<![CDATA[
<p>It's the <strong>KING</strong> of all CMS's, what more do you
need to know about it?</p>
]]>
</headerText>
<articlePhoto>/media/171/umbraco_tshirt.jpg</articlePhoto>
<bodyText>
<![CDATA[
<h3>Umbraco CMS is free</h3>
<p>It means that you are not bound and locked to the licensing
rules about the number of content items / processors / web /
domains, etc. Many products are very expensive as the license cost
escalates with the number of websites. In many cases, one is soon
up in the 500' before one can even start to implement the
solution.</p>
<h3>Umbraco is Open Source</h3>
<p>In an Open Source product one has at any time full access to
source code. This provides insight and leads to better quality, as
"shortcuts" and bad code can easily be penetrated. Moreover, one
has the ability to influence and further develop the product.</p>
<p>Umbraco is based on open source and is therefore not
lisence-plated or subject to an enterprise's ownership. The Umbraco
publishing tool places great emphasis on simplicity, standards,
flexibility and integration. Umbraco was launched in 2005 and has
had a tremendous growth since that time. Umbraco is today among the
most popular systems based on open source for Microsoft. NET
platform.</p>
<h3>100% Microsoft .NET</h3>
<p>Umbraco is built 100% on the Microsoft. NET 2.0. This means that
you can use 3rd party .NET components directly in Umbraco.
Moreover, integration with other .NET-based solutions is well
adapted from Umbracos part. Umbraco won an award for the
Integration possibilities on BNP Awards 2006.</p>
<h3>Fast results</h3>
<p>Umbraco is a powerful tool with a focus on core functionality
and openness. This efficiently allows you to achieve exactly what
you want - rather than be restricted to a "finished" module, which
makes only half of what you really wanted.</p>
<h3>Easy-to-use</h3>
<p>Umbraco has a focus on content and facilitate rapid and
intuitive content management. The system strives to be elegant,
usable and effective.</p>
<h3>Based on standards</h3>
<p>Umbraco is based on standards from the W3C as XHTML, CSS, XML
and XSLT. This gives a greater flexibility and independence, which
in turn provides more value for the money.</p>
<h3>Integration</h3>
<p>Umbraco is known to be among the best CMS on integration. Much
of the reason for this is the way to expose Microsoft ASP.NET
components as elements of, or so-called "macro's" for use in
templates, as well as in the WYSIWYG editor that writers and
editors use. Elements is also possible to "cache" on several levels
and is based on standard Microsoft .NET technology. Below are some
examples:</p>
<ul>
<li>External XML sources (ex RSS) can be directly implemented via
XSLT elements (macros).</li>
<li>ASP.NET controls that retrieve data from external or internal
posterior systems via standard Web Services.</li>
</ul>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]>
</bodyText>
</CWS_Textpage>
<CWS_TextpageTwoCol id="1142" parentID="1140" level="3" writerID="0" creatorID="0" nodeType="1130" template="1118" sortOrder="2" createDate="2009-02-26T18:56:06" updateDate="2010-04-22T02:18:30" nodeName="About this project" urlName="about-this-project" writerName="Administrator" creatorName="Administrator" path="-1,1139,1140,1142" isDoc="">
<articlePhotoColOne>/media/227/warren-buckley.jpg</articlePhotoColOne>
<articlePhotoColTwo>/media/228/sam-grady.jpg</articlePhotoColTwo>
<bodyTextColTwo>
<![CDATA[
<h3>Sam Grady</h3>
<p>Sam Grady, me, is a graphic designer. I loves graphic design.
Great graphic design and simple solutions makes this man very
happy. Photography is also very close to my heart and I'd like to
be better, so I practice a lot and annoy people with my
requests.<br />
<br />
I haven't got a blog, yet, don't Twitter and cancelled my Facebook
account as I felt uncomfortable with people knowing my business.
Anyone else feel that way? I do, however, have a Flickr account, so
go check it out: <a
href="http://www.flickr.com/photos/mrgrady">www.flickr.com/photos/mrgrady</a><br />
<br />
I also have my own business, G72, which has a website that
desperately needs updating. Also, as of today (03/03/09), it's
currently down due to inept web hosts. Hopefully it won't be if you
want to take a look: <a
href="http://www.g-72.co.uk">www.g-72.co.uk</a><br />
<br />
Regarding this project, Warren asked me if I wanted to design his
website starter package for the fantastic Umbraco CMS, which I
jumped at the chance to do. Hopefully you'll find the design
appropriate and the package very useful, as that's what we really
want from this project.<br />
<br />
Finally, Warren says the layout is work in progress and I have a,
typically fussy, list of designer layout requests that I've asked
Warren to do, but time being what it is, these changes won't be
made on version 2.0, so if you spot anything, do mail the man as
we'll be compiling a list of tweaks to be made.<br />
<br />
Enjoy.</p>
]]>
</bodyTextColTwo>
<bodyTextColOne>
<![CDATA[
<h3>Warren Buckley</h3>
<p>Warren Buckley is a web developer who specialises in using the
Umbraco CMS platform to build content managed websites for Xeed in
Norway. I run a blog called <a
href="http://www.creativewebspecialist.co.uk">Creative Web
Specialist</a>, where I mainly write tips and tutorial articles
around Umbraco.</p>
<p>I have teamed up with ex-collegue Sam Grady to help me design
the new version of CWS as he produces wonderfully sexy designs for
the web. If you have seen my previous version/s of CWS you will
know that my design skills are far from stunning.</p>
<p>I decided to create this website starter site nicknamed CWS
(Creative Website Starter site) as a learning tool to help you
understand how all the elements of a site work together in
Umbraco.</p>
<p>From this <strong>NEW</strong> CWS package comes the
following:</p>
<ul>
<li>Obviously a <strong>BRAND NEW</strong> spanking design from
ex-collegue Sam Grady of G-72</li>
<li>A focus for this site to be used to help teach new users to the
Umbraco CMS platform.</li>
<li>.NET usercontrols written in C#</li>
<li>XSLT &amp; .NET code heavily commented to help understand what
is going on.</li>
<li>With supporting documentation coming in the near future.</li>
</ul>
<p>Want to see where else you can find me on the net?<br />
Blog - <a
href="http://www.creativewebspecialist.co.uk">www.creativewebspecialist.co.uk</a><br />
Flickr - <a
href="http://www.flickr.com/photos/warrenbuckley">www.flickr.com/photos/warrenbuckley</a><br />
Last.FM - <a
href="http://www.last.fm/user/warrenbuckley">www.last.fm/user/warrenbuckley</a><br />
Twitter - <a
href="http://twitter.com/warrenbuckley">twitter.com/warrenbuckley</a></p>
]]>
</bodyTextColOne>
<umbracoUrlName>
</umbracoUrlName>
<umbracoUrlAlias>
</umbracoUrlAlias>
<metaDescription><![CDATA[]]></metaDescription>
<metaKeywords><![CDATA[]]></metaKeywords>
<xmlStorageTest>
<XmlStorage>
<Nodes>
<Node>1</Node>
<Node>2</Node>
<Node>3</Node>
<Node>4</Node>
<Node>5</Node>
</Nodes>
</XmlStorage>
</xmlStorageTest>
<umbracoRedirect>
</umbracoRedirect>
<umbracoNaviHide>0</umbracoNaviHide>
<headerText>
<![CDATA[
<p>This website has been produced to help you understand
Umbraco.</p>
]]>
</headerText>
</CWS_TextpageTwoCol>
<umbracoUrlName />
<umbracoUrlAlias />
<metaDescription><![CDATA[This is the META description for the about page.]]></metaDescription>
<metaKeywords><![CDATA[about, creative web specialist, umbraco, warren buckley, sam grady]]></metaKeywords>
<umbracoRedirect />
<umbracoNaviHide>0</umbracoNaviHide>
<headerText><![CDATA[<p>This is a good place to put a service message or something to help define your site or company.</p>]]></headerText>
<articlePhoto />
<bodyText>
<![CDATA[<p><strong>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam ullamcorper condimentum lorem. Curabitur placerat nunc ut leo. Integer eros ligula, vestibulum at, eleifend id, dignissim vel, est.</strong></p>
<p>Fusce tristique. Cras faucibus porta nunc. Aliquam ultrices, arcu quis ornare sagittis, lectus augue ornare nulla, eu lobortis velit lectus id nibh. Aliquam condimentum aliquet purus. Quisque blandit ante non sapien. Sed justo libero, sollicitudin ac, pretium et, luctus nec, nisl. Nulla semper neque nec magna. Cras ut nibh ut urna bibendum sodales. Quisque venenatis euismod lacus. Pellentesque dapibus turpis at urna.</p>
<h3>Sub Header</h3>
<p>Sed scelerisque adipiscing mauris. Mauris egestas dapibus quam. Integer in libero eget eros dignissim pretium. Proin luctus sem nec lorem. Praesent lorem. Vivamus eget nunc quis sapien condimentum egestas. Maecenas facilisis, nunc at sodales facilisis, quam magna pretium nibh, vel ultrices lectus lorem quis neque. Nam sit amet leo ac lectus gravida convallis. Phasellus at enim vel dui porta porttitor. Morbi id dolor adipiscing erat egestas consequat.</p>
<p><a href="http://www.google.co.uk">Phasellus diam. Morbi dolor.</a> Donec consequat sodales nunc. Nam dapibus lectus id lectus. Sed ultrices metus sit amet est. Morbi porttitor. Proin vel risus. Phasellus sodales convallis justo. <em>Sed luctus hendrerit risus. Sed est lorem, feugiat et, rutrum quis, condimentum non, nunc.</em> Aenean urna leo, sagittis a, commodo eget, lobortis nec, eros. Vivamus pharetra, lectus eu ultrices pulvinar, nunc quam consectetur nibh, sed pulvinar leo dolor ut felis.</p>
<ol>
<li>Item one</li>
<li>Item two</li>
<li>Item three</li>
</ol>
<p>Nullam lobortis, mi nec feugiat congue, dolor diam cursus lacus, a elementum ligula dolor vitae sem. Suspendisse at quam. Praesent neque. Vestibulum at justo. Nulla rutrum velit et eros.</p>
<ul>
<li>Integer convallis augue in tellus</li>
<li>Magna quam sollicitudin mauris</li>
</ul>
<p>Nullam lobortis, mi nec feugiat congue, dolor diam cursus lacus, a elementum ligula dolor vitae sem. Suspendisse at quam.</p>]]>
</bodyText>
</CWS_Textpage>
<CWS_Galleries id="1143" parentID="1139" level="2" writerID="0" creatorID="0" nodeType="1123" template="1108" sortOrder="2" createDate="2009-02-27T09:39:54" updateDate="2010-04-22T02:34:59" nodeName="Gallery" urlName="gallery" writerName="Administrator" creatorName="Administrator" path="-1,1139,1143" isDoc="">
<CWS_Gallery id="1144" parentID="1143" level="3" writerID="0" creatorID="0" nodeType="1124" template="1109" sortOrder="1" createDate="2009-03-02T17:58:22" updateDate="2010-04-22T02:18:30" nodeName="The Bookhouse Boys" urlName="the-bookhouse-boys" writerName="Administrator" creatorName="Administrator" path="-1,1139,1143,1144" isDoc="">
<umbracoUrlName>
</umbracoUrlName>
<umbracoUrlAlias>
</umbracoUrlAlias>
<metaDescription><![CDATA[I am the description]]></metaDescription>
<metaKeywords><![CDATA[keywords, here]]></metaKeywords>
<umbracoRedirect>
</umbracoRedirect>
<umbracoNaviHide>0</umbracoNaviHide>
<headerText>
<![CDATA[
<p>The Bookhouse Boys. Live at the ICA, London.</p>
]]>
</headerText>
<sortBy><![CDATA[sortOrder]]></sortBy>
<sortOrder><![CDATA[ascending]]></sortOrder>
<galleryThumbnail>/media/1239/bookhouse-boys_gallery.jpg</galleryThumbnail>
<CWS_Photo id="1145" parentID="1144" level="4" writerID="0" creatorID="0" nodeType="1128" template="1114" sortOrder="1" createDate="2009-03-03T18:08:55" updateDate="2010-04-22T02:18:30" nodeName="Catherine Turner and Paul Van Oestren" urlName="catherine-turner-and-paul-van-oestren" writerName="Administrator" creatorName="Administrator" path="-1,1139,1143,1144,1145" isDoc="">
<photoText>Credit: Sam Grady</photoText>
<photo>/media/1277/bookhouse-boys_3.jpg</photo>
<photoThumbnail>/media/1314/bookhouse-boys_3_thumb.jpg</photoThumbnail>
<umbracoUrlName>
</umbracoUrlName>
<umbracoUrlAlias>
</umbracoUrlAlias>
<metaDescription><![CDATA[]]></metaDescription>
<metaKeywords><![CDATA[]]></metaKeywords>
<umbracoRedirect>
</umbracoRedirect>
<umbracoNaviHide>0</umbracoNaviHide>
</CWS_Photo>
<CWS_Photo id="1146" parentID="1144" level="4" writerID="0" creatorID="0" nodeType="1128" template="1114" sortOrder="2" createDate="2009-03-03T18:08:19" updateDate="2010-04-22T02:18:30" nodeName="J.P.Fellows" urlName="jpfellows" writerName="Administrator" creatorName="Administrator" path="-1,1139,1143,1144,1146" isDoc="">
<photoText>Credit: Sam Grady</photoText>
<photo>/media/1250/bookhouse-boys_1.jpg</photo>
<photoThumbnail>/media/1296/bookhouse-boys_1_thumb.jpg</photoThumbnail>
<umbracoUrlName>
</umbracoUrlName>
<umbracoUrlAlias>
</umbracoUrlAlias>
<metaDescription><![CDATA[]]></metaDescription>
<metaKeywords><![CDATA[]]></metaKeywords>
<umbracoRedirect>
</umbracoRedirect>
<umbracoNaviHide>0</umbracoNaviHide>
</CWS_Photo>
<CWS_Photo id="1147" parentID="1144" level="4" writerID="0" creatorID="0" nodeType="1128" template="1114" sortOrder="3" createDate="2009-03-03T18:08:48" updateDate="2010-04-22T02:18:30" nodeName="Catherine Turner" urlName="catherine-turner" writerName="Administrator" creatorName="Administrator" path="-1,1139,1143,1144,1147" isDoc="">
<photoText>Credit: Sam Grady</photoText>
<photo>/media/1331/bookhouse-boys_2.jpg</photo>
<photoThumbnail>/media/1350/bookhouse-boys_2_thumb.jpg</photoThumbnail>
<umbracoUrlName>
</umbracoUrlName>
<umbracoUrlAlias>
</umbracoUrlAlias>
<metaDescription><![CDATA[]]></metaDescription>
<metaKeywords><![CDATA[]]></metaKeywords>
<umbracoRedirect>
</umbracoRedirect>
<umbracoNaviHide>0</umbracoNaviHide>
</CWS_Photo>
</CWS_Gallery>
<CWS_Gallery id="1148" parentID="1143" level="3" writerID="0" creatorID="0" nodeType="1124" template="1109" sortOrder="2" createDate="2009-02-27T09:48:12" updateDate="2010-04-22T02:18:30" nodeName="Codegarden 08" urlName="codegarden-08" writerName="Administrator" creatorName="Administrator" path="-1,1139,1143,1148" isDoc="">
<umbracoUrlName>
</umbracoUrlName>
<umbracoUrlAlias>
</umbracoUrlAlias>
<metaDescription><![CDATA[]]></metaDescription>
<metaKeywords><![CDATA[]]></metaKeywords>
<umbracoRedirect>
</umbracoRedirect>
<umbracoNaviHide>0</umbracoNaviHide>
<headerText>
<![CDATA[
<p>Where all the great minds of umbraco meet!</p>
]]>
</headerText>
<sortBy><![CDATA[sortOrder]]></sortBy>
<sortOrder><![CDATA[ascending]]></sortOrder>
<galleryThumbnail>/media/993/codegarden-08_gallery.jpg</galleryThumbnail>
<CWS_Photo id="1149" parentID="1148" level="4" writerID="0" creatorID="0" nodeType="1128" template="1114" sortOrder="1" createDate="2009-03-02T15:40:01" updateDate="2010-04-22T02:18:30" nodeName="Darren and David have a chat" urlName="darren-and-david-have-a-chat" writerName="Administrator" creatorName="Administrator" path="-1,1139,1143,1148,1149" isDoc="">
<photoText>Credit: Douglas Robar</photoText>
<photo>/media/825/darren-ferguson_david-conlisk.jpg</photo>
<photoThumbnail>/media/835/darren-ferguson_david-conlisk_thumb.jpg</photoThumbnail>
<umbracoUrlName>
</umbracoUrlName>
<umbracoUrlAlias>
</umbracoUrlAlias>
<metaDescription><![CDATA[]]></metaDescription>
<metaKeywords><![CDATA[]]></metaKeywords>
<umbracoRedirect>
</umbracoRedirect>
<umbracoNaviHide>0</umbracoNaviHide>
</CWS_Photo>
<CWS_Photo id="1150" parentID="1148" level="4" writerID="0" creatorID="0" nodeType="1128" template="1114" sortOrder="2" createDate="2009-02-27T09:54:07" updateDate="2010-04-22T02:18:31" nodeName="Codegarden 08 T-Shirt" urlName="codegarden-08-t-shirt" writerName="Administrator" creatorName="Administrator" path="-1,1139,1143,1148,1150" isDoc="">
<photoText>Credit: Warren Buckley</photoText>
<photo>/media/394/codegarden08-t-shirt.jpg</photo>
<photoThumbnail>/media/799/codegarden08-t-shirt_thumb.jpg</photoThumbnail>
<umbracoUrlName>
</umbracoUrlName>
<umbracoUrlAlias>
</umbracoUrlAlias>
<metaDescription><![CDATA[]]></metaDescription>
<metaKeywords><![CDATA[]]></metaKeywords>
<umbracoRedirect>
</umbracoRedirect>
<umbracoNaviHide>0</umbracoNaviHide>
</CWS_Photo>
<CWS_Photo id="1151" parentID="1148" level="4" writerID="0" creatorID="0" nodeType="1128" template="1114" sortOrder="3" createDate="2009-03-02T15:43:43" updateDate="2010-04-22T02:18:31" nodeName="The Umbraco BINGO callers" urlName="the-umbraco-bingo-callers" writerName="Administrator" creatorName="Administrator" path="-1,1139,1143,1148,1151" isDoc="">
<photoText>Credit: Douglas Robar</photoText>
<photo>/media/852/bingo-callers.jpg</photo>
<photoThumbnail>/media/871/bingo-callers_thumb.jpg</photoThumbnail>
<umbracoUrlName>
</umbracoUrlName>
<umbracoUrlAlias>
</umbracoUrlAlias>
<metaDescription><![CDATA[]]></metaDescription>
<metaKeywords><![CDATA[]]></metaKeywords>
<umbracoRedirect>
</umbracoRedirect>
<umbracoNaviHide>0</umbracoNaviHide>
</CWS_Photo>
<CWS_Photo id="1152" parentID="1148" level="4" writerID="0" creatorID="0" nodeType="1128" template="1114" sortOrder="4" createDate="2009-03-02T15:59:24" updateDate="2010-04-22T02:18:31" nodeName="Christian Palm chatting" urlName="christian-palm-chatting" writerName="Administrator" creatorName="Administrator" path="-1,1139,1143,1148,1152" isDoc="">
<photoText>Credit: Douglas Robar</photoText>
<photo>/media/879/christian-palm.jpg</photo>
<photoThumbnail>/media/889/christian-palm_thumb.jpg</photoThumbnail>
<umbracoUrlName>
</umbracoUrlName>
<umbracoUrlAlias>
</umbracoUrlAlias>
<metaDescription><![CDATA[]]></metaDescription>
<metaKeywords><![CDATA[]]></metaKeywords>
<umbracoRedirect>
</umbracoRedirect>
<umbracoNaviHide>0</umbracoNaviHide>
</CWS_Photo>
</CWS_Gallery>
<CWS_Gallery id="1153" parentID="1143" level="3" writerID="0" creatorID="0" nodeType="1124" template="1109" sortOrder="3" createDate="2009-03-02T16:02:14" updateDate="2010-04-22T02:18:31" nodeName="Bath, UK" urlName="bath,-uk" writerName="Administrator" creatorName="Administrator" path="-1,1139,1143,1153" isDoc="">
<umbracoUrlName>
</umbracoUrlName>
<umbracoUrlAlias>
</umbracoUrlAlias>
<metaDescription><![CDATA[]]></metaDescription>
<metaKeywords><![CDATA[]]></metaKeywords>
<umbracoRedirect>
</umbracoRedirect>
<umbracoNaviHide>0</umbracoNaviHide>
<headerText>
<![CDATA[
<p>Photos from a trip to Bath in November 2008</p>
]]>
</headerText>
<sortBy><![CDATA[updateDate]]></sortBy>
<sortOrder><![CDATA[ascending]]></sortOrder>
<galleryThumbnail>/media/935/bath_gallery.jpg</galleryThumbnail>
<CWS_Photo id="1154" parentID="1153" level="4" writerID="0" creatorID="0" nodeType="1128" template="1114" sortOrder="1" createDate="2009-03-02T16:27:17" updateDate="2010-04-22T02:18:31" nodeName="Royal Crescent" urlName="royal-crescent" writerName="Administrator" creatorName="Administrator" path="-1,1139,1143,1153,1154" isDoc="">
<photoText>Credit: Warren Buckley</photoText>
<photo>/media/995/royal-crescent.jpg</photo>
<photoThumbnail>/media/1014/royal-crescent_thumb.jpg</photoThumbnail>
<umbracoUrlName>
</umbracoUrlName>
<umbracoUrlAlias>
</umbracoUrlAlias>
<metaDescription><![CDATA[]]></metaDescription>
<metaKeywords><![CDATA[]]></metaKeywords>
<umbracoRedirect>
</umbracoRedirect>
<umbracoNaviHide>0</umbracoNaviHide>
</CWS_Photo>
</CWS_Gallery>
<umbracoUrlName />
<umbracoUrlAlias />
<metaDescription><![CDATA[dfg]]></metaDescription>
<metaKeywords><![CDATA[dsfg]]></metaKeywords>
<umbracoRedirect />
<umbracoNaviHide>0</umbracoNaviHide>
<headerText><![CDATA[<p>This first page displays all the albums featured within your site.<br /> Please have a browse through.</p>]]></headerText>
<sortBy><![CDATA[sortOrder]]></sortBy>
<sortOrder><![CDATA[ascending]]></sortOrder>
</CWS_Galleries>
<CWS_NewsEventsList id="1155" parentID="1139" level="2" writerID="0" creatorID="0" nodeType="1126" template="1112" sortOrder="3" createDate="2009-02-27T09:57:30" updateDate="2010-04-22T02:18:31" nodeName="News and Events" urlName="news-and-events" writerName="Administrator" creatorName="Administrator" path="-1,1139,1155" isDoc="">
<CWS_EventItem id="1156" parentID="1155" level="3" writerID="0" creatorID="0" nodeType="1122" template="1107" sortOrder="1" createDate="2009-02-27T10:00:53" updateDate="2010-04-22T02:18:31" nodeName="Codegarden 09" urlName="codegarden-09" writerName="Administrator" creatorName="Administrator" path="-1,1139,1155,1156" isDoc="">
<eventDate>2009-06-22T00:00:00</eventDate>
<bodyText>
<![CDATA[
<h3>Come join the annual umbraco developer conference in Wonderful
Copenhagen on June 22nd - 23rd. Two days for insights, eye-openers,
great conversations and friendly people.</h3>
<p>The who's who of umbraco will be gathered and share their
knowledge through talks, tutorials and via un-conference formats
like open space or hacking sessions. We have booked a cool, old and
huge industrial venue in central Copenhagen where we'll have one
huge room, three rooms for breakout sessions and a Caf&eacute; that
serves your taste of espresso.</p>
<p>Come join the annual umbraco developer conference in Wonderful
Copenhagen on June 22nd - 23rd. Two days for insights, eye-openers,
great conversations and friendly people.</p>
<p>We've planned a program that fits both experienced umbraco users
as well as new comers. The conference is kicked off with a Keynote
and after that we'll have two or three tracks of sessions and the
first day is rounded with an open Q/A session with the umbraco core
team.</p>
<p>The second day features an un-conference format called open
space, which we also used with great success at last year's
conference. It's a format where everybody can suggest a topic and
as we have plenty of break-out rooms rest assured that there'll be
room for your topic as well. Last year's more than 20 topics
covered Silverlight, High performance websites with umbraco,
building custom data types and much more.</p>
<p>But it doesn't ends there. We've ensured that we can stay at the
venue until midnight both days which means that when the first day
ends, the fun begins. With more than hundred people gathered at a
place with loads of umbraco knowledge, wifi, great food and plenty
of space, who knows what could happen. A BBQ, new packages,
improvised demos and talks, or...?</p>
<p>&nbsp;</p>
]]>
</bodyText>
<articlePhoto>/media/445/umbraco_tshirt.jpg</articlePhoto>
<umbracoUrlName>
</umbracoUrlName>
<umbracoUrlAlias>
</umbracoUrlAlias>
<metaDescription><![CDATA[]]></metaDescription>
<metaKeywords><![CDATA[]]></metaKeywords>
<umbracoRedirect>
</umbracoRedirect>
<umbracoNaviHide>0</umbracoNaviHide>
</CWS_EventItem>
<CWS_NewsItem id="1157" parentID="1155" level="3" writerID="0" creatorID="0" nodeType="1127" template="1113" sortOrder="2" createDate="2009-03-02T16:32:06" updateDate="2010-04-22T02:18:31" nodeName="CWS2 is released" urlName="cws2-is-released" writerName="Administrator" creatorName="Administrator" path="-1,1139,1155,1157" isDoc="">
<bodyText>
<![CDATA[
<h3>After Warren Buckley's success of the first Creative Website
Starter site package, with over 20K downloads he has decided to
work on CWS2.</h3>
<p>As of today Wednesday the 4th March 2009, the CWS2 package is
now available to download from the built in package repository
inside Umbraco.</p>
<p>With this new version comes the following:</p>
<ul>
<li>A <strong>BRAND NEW</strong> spanking design from ex-collegue
<a href="http://www.g-72.co.uk"
title="Designer Sam Grady of G72">Sam Grady of G-72</a></li>
<li>A focus for this site to be used to help teach new users to the
Umbraco CMS platform.</li>
<li>.NET usercontrols written in C#</li>
<li>XSLT &amp; .NET code heavily commented to help understand what
is going on.</li>
<li>With supporting documentation coming in the near future.</li>
</ul>
]]>
</bodyText>
<articlePhoto>
</articlePhoto>
<umbracoUrlName>
</umbracoUrlName>
<umbracoUrlAlias>
</umbracoUrlAlias>
<metaDescription><![CDATA[]]></metaDescription>
<metaKeywords><![CDATA[]]></metaKeywords>
<umbracoRedirect>
</umbracoRedirect>
<umbracoNaviHide>0</umbracoNaviHide>
</CWS_NewsItem>
<umbracoUrlName />
<umbracoUrlAlias />
<metaDescription><![CDATA[]]></metaDescription>
<metaKeywords><![CDATA[]]></metaKeywords>
<umbracoRedirect />
<umbracoNaviHide>0</umbracoNaviHide>
<sortBy><![CDATA[sortOrder]]></sortBy>
<sortOrder><![CDATA[ascending]]></sortOrder>
<headerText>
<![CDATA[
<p>Please browse through our news archive and event listings
below.</p>
]]>
</headerText>
</CWS_NewsEventsList>
<CWS_Contact id="1158" parentID="1139" level="2" writerID="0" creatorID="0" nodeType="1120" template="1105" sortOrder="4" createDate="2009-02-27T10:03:12" updateDate="2010-04-22T02:18:31" nodeName="Contact" urlName="contact" writerName="Administrator" creatorName="Administrator" path="-1,1139,1158" isDoc="">
<emailTo>you@yourcompany.co.uk</emailTo>
<emailSubject>Email from Contact form on website</emailSubject>
<emailBody>
<![CDATA[Hello a user of your site has filled in your contact form on [Date] @ [Time]
Name: [Name]
Address: [AddressLine1], [AddressLine2]
Email: [Email]
Message: [Message]]]>
</emailBody>
<emailReplyFrom>you@yourcompany.co.uk</emailReplyFrom>
<emailReplySubject>Thank you for your message</emailReplySubject>
<emailReplyBody>
<![CDATA[Hello [Name]
Thanks for contacting us, we will reply shortly.
Your Company Name
www.yourcompany.co.uk]]>
</emailReplyBody>
<enableSSL>0</enableSSL>
<umbracoUrlName />
<umbracoUrlAlias />
<metaDescription><![CDATA[]]></metaDescription>
<metaKeywords><![CDATA[]]></metaKeywords>
<umbracoRedirect />
<umbracoNaviHide>0</umbracoNaviHide>
<headerText>
<![CDATA[
<p>Everything you need to<br />
get in touch.</p>
]]>
</headerText>
<formText>
<![CDATA[
<h3>Enquiry Form</h3>
<p>If you have a particular enquiry, please fill out the form below
and provide as much information as you can, so that one of our
representatives can deal with your enquiry as effciently as
possible.</p>
]]>
</formText>
<thankYouHeaderText>
<![CDATA[
<p><strong>Thank you.</strong> We will be in touch shortly.</p>
]]>
</thankYouHeaderText>
<thankYouMessageText>
<![CDATA[
<p>Thanks for filling out our contact form we will get back to you
shortly.</p>
<p>Regards,<br />
My Company</p>
]]>
</thankYouMessageText>
</CWS_Contact>
<CWS_EmailAFriend id="1159" parentID="1139" level="2" writerID="0" creatorID="0" nodeType="1121" template="1106" sortOrder="5" createDate="2009-02-27T10:05:57" updateDate="2010-04-22T02:18:31" nodeName="Email a Friend" urlName="email-a-friend" writerName="Administrator" creatorName="Administrator" path="-1,1139,1159" isDoc="">
<emailFrom>you@yourcompany.co.uk</emailFrom>
<emailSubjectToFriend>[YourName] has sent you a link to read</emailSubjectToFriend>
<emailMessageToFriend>
<![CDATA[Hello [FriendName], [YourName] has sent you this link to read.
URL: [URL]
Message: [Message]
--------------------------------------------------------
Your Company Name
www.yourcompany.co.uk]]>
</emailMessageToFriend>
<enableSSL>0</enableSSL>
<umbracoUrlName />
<umbracoUrlAlias />
<metaDescription><![CDATA[]]></metaDescription>
<metaKeywords><![CDATA[]]></metaKeywords>
<umbracoRedirect />
<umbracoNaviHide>1</umbracoNaviHide>
<headerText><![CDATA[<p>Send a page onto your friend.</p>]]></headerText>
<thankYouHeaderText><![CDATA[<p><strong>Thank you.</strong> We appreciate the love you are giving our site.</p>]]></thankYouHeaderText>
<thankYouMessageText><![CDATA[<p>Thanks for sending that link onto your friend, we really appreciate it here at My Company.</p>]]></thankYouMessageText>
</CWS_EmailAFriend>
<metaDescription><![CDATA[]]></metaDescription>
<metaKeywords><![CDATA[]]></metaKeywords>
<umbracoNaviHide>0</umbracoNaviHide>
<siteName>Your logo/name</siteName>
<headerText><![CDATA[<p><strong>Sam Grady designed this for Warren Buckley.</strong> "This" idea was first created by the incredible Robert Brownjohn and has been copied many times since.</p>]]></headerText>
<homepagePhoto><![CDATA[]]></homepagePhoto>
<bodyText>
<![CDATA[<p>Thank you for installing the umbraco website package created and developed by Warren Buckley. This should website package be used to help you understand how all the components of an Umbraco site works.</p>
<p><img src="/media/1670/clientdependencylogo.png" width="89" height="89" alt="test1"/></p>]]>
</bodyText>
<MediaPickerTest />
<umbracoUrlName />
<umbracoUrlAlias />
<umbracoRedirect>0</umbracoRedirect>
</CWS_Home>
</root>
+1 -1
View File
@@ -51,7 +51,7 @@ namespace Umbraco.Tests.TestHelpers
{
get
{
var codeBase = Assembly.GetCallingAssembly().CodeBase;
var codeBase = typeof(TestHelper).Assembly.CodeBase;
var uri = new Uri(codeBase);
var path = uri.LocalPath;
return Path.GetDirectoryName(path);
+33 -9
View File
@@ -35,6 +35,10 @@
<Reference Include="log4net, Version=1.2.11.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\log4net.2.0.0\lib\net40-full\log4net.dll</HintPath>
</Reference>
<Reference Include="Lucene.Net, Version=2.9.4.1, Culture=neutral, PublicKeyToken=85089178b9ac3181, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Umbraco.Web.UI\bin\Lucene.Net.dll</HintPath>
</Reference>
<Reference Include="nunit.framework">
<HintPath>..\packages\NUnit.2.6.0.12054\lib\nunit.framework.dll</HintPath>
</Reference>
@@ -51,27 +55,34 @@
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="UmbracoExamine, Version=0.1.42.2941, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Umbraco.Web.UI\bin\UmbracoExamine.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="BusinessLogic\DictionaryTest.cs" />
<Compile Include="ContentStores\PublishMediaStoreTests.cs" />
<Compile Include="DynamicDocument\DynamicXmlTests.cs" />
<Compile Include="DynamicDocument\PublishedContentDataTableTests.cs" />
<Compile Include="DynamicDocument\PublishedContentTests.cs" />
<Compile Include="DynamicDocument\StronglyTypedQueryTests.cs" />
<Compile Include="PublishedContent\DynamicXmlTests.cs" />
<Compile Include="PublishedContent\PublishedContentDataTableTests.cs" />
<Compile Include="PublishedContent\PublishedContentTests.cs" />
<Compile Include="PublishedContent\PublishedMediaTests.cs" />
<Compile Include="PublishedContent\StronglyTypedQueryTests.cs" />
<Compile Include="HashCodeCombinerTests.cs" />
<Compile Include="HtmlHelperExtensionMethodsTests.cs" />
<Compile Include="IO\IOHelperTest.cs" />
<Compile Include="LibraryTests.cs" />
<Compile Include="PropertyEditors\PropertyEditorValueConverterTests.cs" />
<Compile Include="Resolvers\ActionsResolverTests.cs" />
<Compile Include="AsynchronousRollingFileAppenderTests.cs" />
<Compile Include="BusinessLogic\ApplicationTest.cs" />
<Compile Include="BusinessLogic\ApplicationTreeTest.cs" />
<Compile Include="BusinessLogic\BaseTest.cs" />
<Compile Include="CacheRefresherFactoryTests.cs" />
<Compile Include="DynamicDocument\DynamicPublishedContentCustomExtensionMethods.cs" />
<Compile Include="DynamicDocument\DynamicPublishedContentTests.cs" />
<Compile Include="DynamicDocument\DynamicDocumentTestsBase.cs" />
<Compile Include="DynamicDocument\DynamicNodeTests.cs" />
<Compile Include="PublishedContent\DynamicPublishedContentCustomExtensionMethods.cs" />
<Compile Include="PublishedContent\DynamicPublishedContentTests.cs" />
<Compile Include="PublishedContent\DynamicDocumentTestsBase.cs" />
<Compile Include="PublishedContent\DynamicNodeTests.cs" />
<Compile Include="ObjectExtensionsTests.cs" />
<Compile Include="ContentStores\PublishContentStoreTests.cs" />
<Compile Include="DataTypeFactoryTests.cs" />
@@ -93,6 +104,12 @@
<Compile Include="Routing\RouteTestExtensions.cs" />
<Compile Include="Stubs\TestControllerFactory.cs" />
<Compile Include="TestHelpers\BaseWebTest.cs" />
<Compile Include="TestHelpers\ExamineHelpers\ExamineResources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>ExamineResources.resx</DependentUpon>
</Compile>
<Compile Include="TestHelpers\ExamineHelpers\IndexInitializer.cs" />
<Compile Include="UriUtilityTests.cs" />
<Compile Include="Resolvers\MacroFieldEditorsResolverTests.cs" />
<Compile Include="MacroEngineFactoryTests.cs" />
@@ -124,6 +141,7 @@
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
<None Include="TestHelpers\ExamineHelpers\umbraco.config" />
<None Include="unit-test-log4net.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
@@ -174,9 +192,15 @@
<Name>Umbraco.Web</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<ItemGroup>
<EmbeddedResource Include="TestHelpers\ExamineHelpers\ExamineResources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>ExamineResources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Content Include="Masterpages\dummy.txt" />
<Content Include="TestHelpers\ExamineHelpers\media.xml" />
<Content Include="Views\dummy.txt" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+8
View File
@@ -1,6 +1,7 @@
using System;
using System.Configuration;
using NUnit.Framework;
using Umbraco.Core.Configuration;
using Umbraco.Web;
namespace Umbraco.Tests
@@ -10,6 +11,13 @@ namespace Umbraco.Tests
[TestFixture]
public class UriUtilityTests
{
[TearDown]
public void TearDown()
{
UmbracoSettings.ResetSetters();
}
// test normal urls
[TestCase("http://LocalHost/", "http://localhost/")]
[TestCase("http://LocalHost/?x=y", "http://localhost/?x=y")]
+9 -2
View File
@@ -93,9 +93,9 @@
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="ClientDependency.Core, Version=1.5.0.0, Culture=neutral, PublicKeyToken=7a99a55a05d191a8, processorArchitecture=MSIL">
<Reference Include="ClientDependency.Core, Version=1.5.1.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\ClientDependency.Core.dll</HintPath>
<HintPath>..\packages\ClientDependency.1.5.1.0\lib\ClientDependency.Core.dll</HintPath>
</Reference>
<Reference Include="CookComputing.XmlRpcV2, Version=2.5.0.0, Culture=neutral, PublicKeyToken=a7d6e17aa302004d, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@@ -147,10 +147,12 @@
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\SQLCE4\System.Data.SqlServerCe.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\SQLCE4\System.Data.SqlServerCe.Entity.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Design" />
<Reference Include="System.Drawing">
@@ -1440,6 +1442,7 @@
<Content Include="umbraco_client\ui\base2.js" />
<Content Include="umbraco_client\ui\jquery.alphanumeric.js" />
<Content Include="umbraco_client\ui\jquery.tooltip.min.js" />
<Content Include="umbraco_client\ui\json2.js" />
<Content Include="umbraco_client\ui\knockout.js" />
<Content Include="umbraco_client\ui\knockout.mapping.js" />
<Content Include="umbraco_client\ui\ui-lightness\images\ui-bg_diagonals-thick_18_b81900_40x40.png" />
@@ -2320,6 +2323,10 @@
<None Include="web.Template.NILSJO.Debug.config">
<DependentUpon>web.Template.config</DependentUpon>
</None>
<None Include="web.Template.wulff-Pc.Debug.config">
<DependentUpon>web.Template.config</DependentUpon>
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<Folder Include="App_Code\" />
@@ -10,19 +10,28 @@ NOTES:
* Compression/Combination/Minification is not enabled unless debug="false" is specified on the 'compiliation' element in the web.config
* A new version will invalidate both client and server cache and create new persisted files
-->
<clientDependency version="37">
<fileRegistration defaultProvider="LoaderControlProvider" fileDependencyExtensions=".js,.css">
<providers>
<add name="PageHeaderProvider" type="ClientDependency.Core.FileRegistration.Providers.PageHeaderProvider, ClientDependency.Core"/>
<add name="LazyLoadProvider" type="ClientDependency.Core.FileRegistration.Providers.LazyLoadProvider, ClientDependency.Core"/>
<add name="LoaderControlProvider" type="ClientDependency.Core.FileRegistration.Providers.LoaderControlProvider, ClientDependency.Core"/>
<!-- Used for loading dependencies in Canvas mode -->
<add name="CanvasProvider" type="umbraco.presentation.LiveEditing.CanvasClientDependencyProvider, umbraco" />
</providers>
</fileRegistration>
<clientDependency version="40" fileDependencyExtensions=".js,.css">
<!--
<fileRegistration defaultProvider="LoaderControlProvider">
<providers>
<add name="PageHeaderProvider" type="ClientDependency.Core.FileRegistration.Providers.PageHeaderProvider, ClientDependency.Core"/>
<add name="LazyLoadProvider" type="ClientDependency.Core.FileRegistration.Providers.LazyLoadProvider, ClientDependency.Core"/>
<add name="LoaderControlProvider" type="ClientDependency.Core.FileRegistration.Providers.LoaderControlProvider, ClientDependency.Core"/>
<add name="PlaceHolderProvider" type="ClientDependency.Core.FileRegistration.Providers.PlaceHolderProvider, ClientDependency.Core" enableCompositeFiles="true" javascriptPlaceHolderId="JavaScriptPlaceHolder" cssPlaceHolderId="CssPlaceHolder"/>
<!-- Used for loading dependencies in Canvas mode -->
<add name="CanvasProvider" type="umbraco.presentation.LiveEditing.CanvasClientDependencyProvider, umbraco" />
</providers>
</fileRegistration>
<!-- This section is used for MVC only -->
<mvc defaultRenderer="StandardRenderer">
<renderers>
<add name="StandardRenderer" type="ClientDependency.Core.FileRegistration.Providers.StandardRenderer, ClientDependency.Core"/>
<add name="LazyLoadRenderer" type="ClientDependency.Core.FileRegistration.Providers.LazyLoadRenderer, ClientDependency.Core"/>
</renderers>
</mvc>
<!--
The composite file section configures the compression/combination/minification of files.
You can enable/disable minification of either JS/CSS files and you can enable/disable the
persistence of composite files. By default, minification and persistence is enabled. Persisting files
@@ -30,39 +39,35 @@ NOTES:
to disk so that on any subsequent request (when output cache expires) that these files don't have
to be recreated again and will be based on the persisted file on disk. This saves on processing time.
-->
<compositeFiles defaultProvider="CompositeFileProcessor" compositeFileHandlerPath="DependencyHandler.axd">
<providers>
<add name="CompositeFileProcessor"
<compositeFiles defaultProvider="defaultFileProcessingProvider" compositeFileHandlerPath="~/DependencyHandler.axd">
<fileProcessingProviders>
<add name="CompositeFileProcessor"
type="ClientDependency.Core.CompositeFiles.Providers.CompositeFileProcessingProvider, ClientDependency.Core"
enableCssMinify="true"
enableJsMinify="true"
persistFiles="true"
compositeFilePath="~/App_Data/TEMP/ClientDependency" />
</providers>
<!--
compositeFilePath="~/App_Data/TEMP/ClientDependency"
urlType="Base64QueryStrings" />
</fileProcessingProviders>
<!-- A file map provider stores references to dependency files by an id to be used in the handler URL when using the MappedId Url type -->
<fileMapProviders>
<add name="XmlFileMap"
type="ClientDependency.Core.CompositeFiles.Providers.XmlFileMapper, ClientDependency.Core"
mapPath="~/App_Data/TEMP/ClientDependency"/>
</fileMapProviders>
<!--
Defines the mime types to compress when requested by the client.
Path is a regex selector, or a * can be used as in place of 'any'.
Generally mime types are only set by client browsers in the request for things
such as JSON or XML ajax requests.
-->
<mimeTypeCompression>
<!-- Compress all json requests for the tree -->
<add type="application/json" path="^.*?/webservices/Tree.*" />
</mimeTypeCompression>
<mimeTypeCompression>
<!-- Compress all json requests for the tree -->
<add type="application/json" path="^.*?/webservices/Tree.*" />
</mimeTypeCompression>
</compositeFiles>
</compositeFiles>
<!-- ClientDependency also supports the ASP.Net MVC framework, see codeplex URL for full details -->
<!--
<mvc defaultRenderer="StandardRenderer">
<renderers>
<add name="StandardRenderer" type="ClientDependency.Core.Mvc.Providers.StandardRenderer, ClientDependency.Core"/>
<add name="LazyLoadRenderer" type="ClientDependency.Core.Mvc.Providers.LazyLoadRenderer, ClientDependency.Core"/>
</renderers>
</mvc>
-->
</clientDependency>
+2
View File
@@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<!--<package id="ClientDependency" version="1.5.1.0" targetFramework="net40" />
<package id="ClientDependency-Mvc" version="1.5.1.0" targetFramework="net40" />-->
<package id="log4net" version="2.0.0" targetFramework="net40" />
<package id="Microsoft.AspNet.Mvc" version="3.0.20105.1" targetFramework="net40" />
<package id="Microsoft.AspNet.Razor" version="1.0.20105.408" targetFramework="net40" />
+9
View File
@@ -11,5 +11,14 @@ namespace Umbraco.Web.UI.Umbraco {
public partial class Umbraco {
/// <summary>
/// JSON2 control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::ClientDependency.Core.Controls.JsInclude JSON2;
}
}
@@ -71,7 +71,6 @@
<key alias="saveAndPublish">Gem og udgiv</key>
<key alias="saveToPublish">Gem og send til udgivelse</key>
<key alias="showPage">Se siden</key>
<key alias="showPageDisabled">Se siden (du kan ikke se siden, da der ikke er valgt nogen skabelon)</key>
<key alias="styleChoose">Vælg formattering</key>
<key alias="styleShow">Vis koder</key>
<key alias="tableInsert">Indsæt tabel</key>
+151 -75
View File
@@ -36,11 +36,16 @@
</area>
<area alias="assignDomain">
<key alias="addNew">Add new Domain</key>
<key alias="invalidDomain">Invalid hostname</key>
<key alias="domain">Domain</key>
<key alias="domainCreated">New domain '%0%' has been created</key>
<key alias="domainDeleted">Domain '%0%' is deleted</key>
<key alias="domainExists">Domain '%0%' has already been assigned</key>
<key alias="domainHelp">ei: yourdomain.com, www.yourdomain.com</key>
<key alias="domainHelp">
<![CDATA[eg: example.com, www.example.com, example.com:8080,<br/>
https://www.example.com/, example.com/en, etc. Use * to match<br/>
any domain and just set the culture.]]>
</key>
<key alias="domainUpdated">Domain '%0%' has been updated</key>
<key alias="orEdit">Edit Current Domains</key>
</area>
@@ -89,7 +94,7 @@
<key alias="itemNotPublished">This item is not published</key>
<key alias="lastPublished">Last published</key>
<key alias="mediatype">Media Type</key>
<key alias="mediaLinks">Link to media item(s)</key>
<key alias="mediaLinks">Link to media item(s)</key>
<key alias="membergroup">Member Group</key>
<key alias="memberrole">Role</key>
<key alias="membertype">Member Type</key>
@@ -165,18 +170,24 @@
<key alias="siterepublishHelp">The website cache will be refreshed. All published content will be updated, while unpublished content will stay unpublished.</key>
<key alias="tableColumns">Number of columns</key>
<key alias="tableRows">Number of rows</key>
<key alias="templateContentAreaHelp"><![CDATA[<strong>Set a placeholder id</strong> by setting an ID on your placeholder you can inject content into this template from child templates,
by refering this ID using a <code>&lt;asp:content /&gt;</code> element.]]></key>
<key alias="templateContentPlaceHolderHelp"><![CDATA[<strong>Select a placeholder id</strong> from the list below. You can only
choose Id's from the current template's master.]]></key>
<key alias="templateContentAreaHelp">
<![CDATA[<strong>Set a placeholder id</strong> by setting an ID on your placeholder you can inject content into this template from child templates,
by refering this ID using a <code>&lt;asp:content /&gt;</code> element.]]>
</key>
<key alias="templateContentPlaceHolderHelp">
<![CDATA[<strong>Select a placeholder id</strong> from the list below. You can only
choose Id's from the current template's master.]]>
</key>
<key alias="thumbnailimageclickfororiginal">Click on the image to see full size</key>
<key alias="treepicker">Pick item</key>
<key alias="viewCacheItem">View Cache Item</key>
</area>
<area alias="dictionaryItem">
<key alias="description"><![CDATA[
<key alias="description">
<![CDATA[
Edit the different language versions for the dictionary item '<em>%0%</em>' below<br/>You can add additional languages under the 'languages' in the menu on the left
]]></key>
]]>
</key>
<key alias="displayName">Culture Name</key>
</area>
<area alias="editcontenttype">
@@ -324,6 +335,7 @@
<key alias="welcome">Welcome...</key>
<key alias="width">Width</key>
<key alias="yes">Yes</key>
<key alias="folder">Folder</key>
</area>
<area alias="graphicheadline">
<key alias="backgroundcolor">Background color</key>
@@ -340,34 +352,45 @@
<key alias="databaseErrorWebConfig">Could not save the web.config file. Please modify the connection string manually.</key>
<key alias="databaseFound">Your database has been found and is identified as</key>
<key alias="databaseHeader">Database configuration</key>
<key alias="databaseInstall"><![CDATA[
<key alias="databaseInstall">
<![CDATA[
Press the <strong>install</strong> button to install the Umbraco %0% database
]]></key>
]]>
</key>
<key alias="databaseInstallDone"><![CDATA[Umbraco %0% has now been copied to your database. Press <strong>Next</strong> to proceed.]]></key>
<key alias="databaseNotFound"><![CDATA[<p>Database not found! Please check that the information in the "connection string" of the “web.config” file is correct.</p>
<key alias="databaseNotFound">
<![CDATA[<p>Database not found! Please check that the information in the "connection string" of the “web.config” file is correct.</p>
<p>To proceed, please edit the "web.config" file (using Visual Studio or your favourite text editor), scroll to the bottom, add the connection string for your database in the key named "umbracoDbDSN" and save the file. </p>
<p>
Click the <strong>retry</strong> button when
done.<br /><a href="http://umbraco.org/redir/installWebConfig" target="_blank">
More information on editing web.config here.</a></p>]]></key>
<key alias="databaseText"><![CDATA[To complete this step, you must know some information regarding your database server ("connection string").<br />
More information on editing web.config here.</a></p>]]>
</key>
<key alias="databaseText">
<![CDATA[To complete this step, you must know some information regarding your database server ("connection string").<br />
Please contact your ISP if necessary.
If you're installing on a local machine or server you might need information from your system administrator.]]></key>
<key alias="databaseUpgrade"><![CDATA[
If you're installing on a local machine or server you might need information from your system administrator.]]>
</key>
<key alias="databaseUpgrade">
<![CDATA[
<p>
Press the <strong>upgrade</strong> button to upgrade your database to Umbraco %0%</p>
<p>
Don't worry - no content will be deleted and everything will continue working afterwards!
</p>
]]></key>
<key alias="databaseUpgradeDone"><![CDATA[Your database has been upgraded to the final version %0%.<br />Press <strong>Next</strong> to
proceed. ]]></key>
]]>
</key>
<key alias="databaseUpgradeDone">
<![CDATA[Your database has been upgraded to the final version %0%.<br />Press <strong>Next</strong> to
proceed. ]]>
</key>
<key alias="databaseUpToDate"><![CDATA[Your current database is up-to-date!. Click <strong>next</strong> to continue the configuration wizard]]></key>
<key alias="defaultUserChangePass"><![CDATA[<strong>The Default users password needs to be changed!</strong>]]></key>
<key alias="defaultUserDisabled"><![CDATA[<strong>The Default user has been disabled or has no access to umbraco!</strong></p><p>No further actions needs to be taken. Click <b>Next</b> to proceed.]]></key>
<key alias="defaultUserPassChanged"><![CDATA[<strong>The Default user's password has been successfully changed since the installation!</strong></p><p>No further actions needs to be taken. Click <strong>Next</strong> to proceed.]]></key>
<key alias="defaultUserPasswordChanged">The password is changed!</key>
<key alias="defaultUserText"><![CDATA[
<key alias="defaultUserText">
<![CDATA[
<p>
umbraco creates a default user with a login <strong>('admin')</strong> and password <strong>('default')</strong>. It's <strong>important</strong> that the password is
changed to something unique.
@@ -375,48 +398,64 @@
<p>
This step will check the default user's password and suggest if it needs to be changed.
</p>
]]></key>
]]>
</key>
<key alias="greatStart">Get a great start, watch our introduction videos</key>
<key alias="licenseText">By clicking the next button (or modifying the umbracoConfigurationStatus in web.config), you accept the license for this software as specified in the box below. Notice that this umbraco distribution consists of two different licenses, the open source MIT license for the framework and the umbraco freeware license that covers the UI.</key>
<key alias="None">Not installed yet.</key>
<key alias="permissionsAffectedFolders">Affected files and folders</key>
<key alias="permissionsAffectedFoldersMoreInfo">More information on setting up permissions for umbraco here</key>
<key alias="permissionsAffectedFoldersText">You need to grant ASP.NET modify permissions to the following files/folders</key>
<key alias="permissionsAlmostPerfect"><![CDATA[<strong>Your permission settings are almost perfect!</strong><br /><br />
You can run umbraco without problems, but you will not be able to install packages which are recommended to take full advantage of umbraco.]]></key>
<key alias="permissionsAlmostPerfect">
<![CDATA[<strong>Your permission settings are almost perfect!</strong><br /><br />
You can run umbraco without problems, but you will not be able to install packages which are recommended to take full advantage of umbraco.]]>
</key>
<key alias="permissionsHowtoResolve">How to Resolve</key>
<key alias="permissionsHowtoResolveLink">Click here to read the text version</key>
<key alias="permissionsHowtoResolveText"><![CDATA[Watch our <strong>video tutorial</strong> on setting up folder permissions for umbraco or read the text version.]]></key>
<key alias="permissionsMaybeAnIssue"><![CDATA[<strong>Your permission settings might be an issue!</strong>
<key alias="permissionsMaybeAnIssue">
<![CDATA[<strong>Your permission settings might be an issue!</strong>
<br/><br />
You can run umbraco without problems, but you will not be able to create folders or install packages which are recommended to take full advantage of umbraco.]]></key>
<key alias="permissionsNotReady"><![CDATA[<strong>Your permission settings are not ready for umbraco!</strong>
You can run umbraco without problems, but you will not be able to create folders or install packages which are recommended to take full advantage of umbraco.]]>
</key>
<key alias="permissionsNotReady">
<![CDATA[<strong>Your permission settings are not ready for umbraco!</strong>
<br /><br />
In order to run umbraco, you'll need to update your permission settings.]]></key>
<key alias="permissionsPerfect"><![CDATA[<strong>Your permission settings are perfect!</strong><br /><br />
You are ready to run umbraco and install packages!]]></key>
In order to run umbraco, you'll need to update your permission settings.]]>
</key>
<key alias="permissionsPerfect">
<![CDATA[<strong>Your permission settings are perfect!</strong><br /><br />
You are ready to run umbraco and install packages!]]>
</key>
<key alias="permissionsResolveFolderIssues">Resolving folder issue</key>
<key alias="permissionsResolveFolderIssuesLink">Follow this link for more information on problems with ASP.NET and creating folders</key>
<key alias="permissionsSettingUpPermissions">Setting up folder permissions</key>
<key alias="permissionsText"><![CDATA[
<key alias="permissionsText">
<![CDATA[
umbraco needs write/modify access to certain directories in order to store files like pictures and PDF's.
It also stores temporary data (aka: cache) for enhancing the performance of your website.
]]></key>
]]>
</key>
<key alias="runwayFromScratch">I want to start from scratch</key>
<key alias="runwayFromScratchText"><![CDATA[
<key alias="runwayFromScratchText">
<![CDATA[
Your website is completely empty at the moment, so thats perfect if you want to start from scratch and create your own document types and templates.
(<a href="http://umbraco.tv/documentation/videos/for-site-builders/foundation/document-types">learn how</a>)
You can still choose to install Runway later on. Please go to the Developer section and choose Packages.
]]></key>
]]>
</key>
<key alias="runwayHeader">Youve just set up a clean Umbraco platform. What do you want to do next?</key>
<key alias="runwayInstalled">Runway is installed</key>
<key alias="runwayInstalledText"><![CDATA[
<key alias="runwayInstalledText">
<![CDATA[
You have the foundation in place. Select what modules you wish to install on top of it.<br />
This is our list of recommended modules, check off the ones you would like to install, or view the <a href="#" onclick="toggleModules(); return false;" id="toggleModuleList">full list of modules</a>
]]></key>
]]>
</key>
<key alias="runwayOnlyProUsers">Only recommended for experienced users</key>
<key alias="runwaySimpleSite">I want to start with a simple website</key>
<key alias="runwaySimpleSiteText"><![CDATA[
<key alias="runwaySimpleSiteText">
<![CDATA[
<p>
"Runway" is a simple website providing some basic document types and templates. The installer can set up Runway for you automatically,
but you can easily edit, extend or remove it. Its not necessary and you can perfectly use Umbraco without it. However,
@@ -427,7 +466,8 @@
<em>Included with Runway:</em> Home page, Getting Started page, Installing Modules page.<br />
<em>Optional Modules:</em> Top Navigation, Sitemap, Contact, Gallery.
</small>
]]></key>
]]>
</key>
<key alias="runwayWhatIsRunway">What is Runway</key>
<key alias="step1">Step 1/5 Accept license</key>
<key alias="step2">Step 2/5: Database configuration</key>
@@ -435,24 +475,36 @@
<key alias="step4">Step 4/5: Check umbraco security</key>
<key alias="step5">Step 5/5: Umbraco is ready to get you started</key>
<key alias="thankYou">Thank you for choosing umbraco</key>
<key alias="theEndBrowseSite"><![CDATA[<h3>Browse your new site</h3>
You installed Runway, so why not see how your new website looks.]]></key>
<key alias="theEndFurtherHelp"><![CDATA[<h3>Further help and information</h3>
Get help from our award winning community, browse the documentation or watch some free videos on how to build a simple site, how to use packages and a quick guide to the umbraco terminology]]></key>
<key alias="theEndBrowseSite">
<![CDATA[<h3>Browse your new site</h3>
You installed Runway, so why not see how your new website looks.]]>
</key>
<key alias="theEndFurtherHelp">
<![CDATA[<h3>Further help and information</h3>
Get help from our award winning community, browse the documentation or watch some free videos on how to build a simple site, how to use packages and a quick guide to the umbraco terminology]]>
</key>
<key alias="theEndHeader">Umbraco %0% is installed and ready for use</key>
<key alias="theEndInstallFailed"><![CDATA[To finish the installation, you'll need to
manually edit the <strong>/web.config file</strong> and update the AppSetting key <strong>umbracoConfigurationStatus</strong> in the bottom to the value of <strong>'%0%'</strong>.]]></key>
<key alias="theEndInstallSuccess"><![CDATA[You can get <strong>started instantly</strong> by clicking the "Launch Umbraco" button below. <br />If you are <strong>new to umbraco</strong>,
you can find plenty of resources on our getting started pages.]]></key>
<key alias="theEndOpenUmbraco"><![CDATA[<h3>Launch Umbraco</h3>
To manage your website, simply open the umbraco back office and start adding content, updating the templates and stylesheets or add new functionality]]></key>
<key alias="theEndInstallFailed">
<![CDATA[To finish the installation, you'll need to
manually edit the <strong>/web.config file</strong> and update the AppSetting key <strong>umbracoConfigurationStatus</strong> in the bottom to the value of <strong>'%0%'</strong>.]]>
</key>
<key alias="theEndInstallSuccess">
<![CDATA[You can get <strong>started instantly</strong> by clicking the "Launch Umbraco" button below. <br />If you are <strong>new to umbraco</strong>,
you can find plenty of resources on our getting started pages.]]>
</key>
<key alias="theEndOpenUmbraco">
<![CDATA[<h3>Launch Umbraco</h3>
To manage your website, simply open the umbraco back office and start adding content, updating the templates and stylesheets or add new functionality]]>
</key>
<key alias="Unavailable">Connection to database failed.</key>
<key alias="Version3">Umbraco Version 3</key>
<key alias="Version4">Umbraco Version 4</key>
<key alias="watch">Watch</key>
<key alias="welcomeIntro"><![CDATA[This wizard will guide you through the process of configuring <strong>umbraco %0%</strong> for a fresh install or upgrading from version 3.0.
<key alias="welcomeIntro">
<![CDATA[This wizard will guide you through the process of configuring <strong>umbraco %0%</strong> for a fresh install or upgrading from version 3.0.
<br /><br />
Press <strong>"next"</strong> to start the wizard.]]></key>
Press <strong>"next"</strong> to start the wizard.]]>
</key>
</area>
<area alias="language">
<key alias="cultureCode">Culture Code</key>
@@ -486,7 +538,8 @@ To manage your website, simply open the umbraco back office and start adding con
</area>
<area alias="notifications">
<key alias="editNotifications">Edit your notification for %0%</key>
<key alias="mailBody"><![CDATA[
<key alias="mailBody">
<![CDATA[
Hi %0%
This is an automated mail to inform you that the task '%1%'
@@ -498,8 +551,10 @@ To manage your website, simply open the umbraco back office and start adding con
Have a nice day!
Cheers from the umbraco robot
]]></key>
<key alias="mailBodyHtml"><![CDATA[<p>Hi %0%</p>
]]>
</key>
<key alias="mailBodyHtml">
<![CDATA[<p>Hi %0%</p>
<p>This is an automated mail to inform you that the task <strong>'%1%'</strong>
has been performed on the page <a href="%7%"><strong>'%2%'</strong></a>
@@ -529,23 +584,28 @@ To manage your website, simply open the umbraco back office and start adding con
<p>Have a nice day!<br /><br />
Cheers from the umbraco robot
</p>]]></key>
</p>]]>
</key>
<key alias="mailSubject">[%0%] Notification about %1% performed on %2%</key>
<key alias="notifications">Notifications</key>
</area>
<area alias="packager">
<key alias="chooseLocalPackageText"><![CDATA[
<key alias="chooseLocalPackageText">
<![CDATA[
Choose Package from your machine, by clicking the Browse<br />
button and locating the package. umbraco packages usually have a ".umb" or ".zip" extension.
]]></key>
]]>
</key>
<key alias="packageAuthor">Author</key>
<key alias="packageDemonstration">Demonstration</key>
<key alias="packageDocumentation">Documentation</key>
<key alias="packageMetaData">Package meta data</key>
<key alias="packageName">Package name</key>
<key alias="packageNoItemsHeader">Package doesn't contain any items</key>
<key alias="packageNoItemsText"><![CDATA[This package file doesn't contain any items to uninstall.<br/><br/>
You can safely remove this from the system by clicking "uninstall package" below.]]></key>
<key alias="packageNoItemsText">
<![CDATA[This package file doesn't contain any items to uninstall.<br/><br/>
You can safely remove this from the system by clicking "uninstall package" below.]]>
</key>
<key alias="packageNoUpgrades">No upgrades available</key>
<key alias="packageOptions">Package options</key>
<key alias="packageReadme">Package readme</key>
@@ -554,9 +614,11 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="packageUninstalledHeader">Package was uninstalled</key>
<key alias="packageUninstalledText">The package was successfully uninstalled</key>
<key alias="packageUninstallHeader">Uninstall package</key>
<key alias="packageUninstallText"><![CDATA[You can unselect items you do not wish to remove, at this time, below. When you click "confirm uninstall" all checked-off items will be removed.<br />
<key alias="packageUninstallText">
<![CDATA[You can unselect items you do not wish to remove, at this time, below. When you click "confirm uninstall" all checked-off items will be removed.<br />
<span style="color: Red; font-weight: bold;">Notice:</span> any documents, media etc depending on the items you remove, will stop working, and could lead to system instability,
so uninstall with caution. If in doubt, contact the package author.]]></key>
so uninstall with caution. If in doubt, contact the package author.]]>
</key>
<key alias="packageUpgradeDownload">Download update from the repository</key>
<key alias="packageUpgradeHeader">Upgrade package</key>
<key alias="packageUpgradeInstructions">Upgrade instructions</key>
@@ -589,18 +651,27 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="paSimpleHelp">If you just want to setup simple protection using a single login and password</key>
</area>
<area alias="publish">
<key alias="contentPublishedFailedByEvent"><![CDATA[
<key alias="contentPublishedFailedByEvent">
<![CDATA[
%0% could not be published, due to a 3rd party extension cancelling the action.
]]></key>
]]>
</key>
<key alias="contentPublishedFailedByParent">
<![CDATA[
%0% can not be published, because a parent page is not published.
]]>
</key>
<key alias="includeUnpublished">Include unpublished child pages</key>
<key alias="inProgress">Publishing in progress - please wait...</key>
<key alias="inProgressCounter">%0% out of %1% pages have been published...</key>
<key alias="nodePublish">%0% has been published</key>
<key alias="nodePublishAll">%0% and subpages have been published</key>
<key alias="publishAll">Publish %0% and all its subpages</key>
<key alias="publishHelp"><![CDATA[Click <em>ok</em> to publish <strong>%0%</strong> and thereby making it's content publicly available.<br/><br />
<key alias="publishHelp">
<![CDATA[Click <em>ok</em> to publish <strong>%0%</strong> and thereby making it's content publicly available.<br/><br />
You can publish this page and all it's sub-pages by checking <em>publish all children</em> below.
]]></key>
]]>
</key>
</area>
<area alias="relatedlinks">
<key alias="addExternal">Add external link</key>
@@ -655,7 +726,6 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="contentTypeEnabled">Master Content Type enabled</key>
<key alias="contentTypeUses">This Content Type uses</key>
<key alias="asAContentMasterType">as a Master Content Type. Tabs from Master Content Types are not shown and can only be edited on the Master Content Type itself</key>
</area>
<area alias="sort">
<key alias="sortDone">Sorting complete.</key>
@@ -736,7 +806,7 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="chooseField">Choose field</key>
<key alias="convertLineBreaks">Convert Linebreaks</key>
<key alias="convertLineBreaksHelp">Replaces linebreaks with html-tag &amp;lt;br&amp;gt;</key>
<key alias="customFields">Custom Fields</key>
<key alias="customFields">Custom Fields</key>
<key alias="dateOnly">Yes, Date only</key>
<key alias="formatAsDate">Format as date</key>
<key alias="htmlEncode">HTML encode</key>
@@ -750,7 +820,7 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="recursive">Recursive</key>
<key alias="removeParagraph">Remove Paragraph tags</key>
<key alias="removeParagraphHelp">Will remove any &amp;lt;P&amp;gt; in the beginning and end of the text</key>
<key alias="standardFields">Standard Fields</key>
<key alias="standardFields">Standard Fields</key>
<key alias="uppercase">Uppercase</key>
<key alias="urlEncode">URL encode</key>
<key alias="urlEncodeHelp">Will format special characters in URLs</key>
@@ -760,10 +830,12 @@ To manage your website, simply open the umbraco back office and start adding con
</area>
<area alias="translation">
<key alias="assignedTasks">Tasks assigned to you</key>
<key alias="assignedTasksHelp"><![CDATA[ The list below shows translation tasks <strong>assigned to you</strong>. To see a detailed view including comments, click on "Details" or just the page name.
<key alias="assignedTasksHelp">
<![CDATA[ The list below shows translation tasks <strong>assigned to you</strong>. To see a detailed view including comments, click on "Details" or just the page name.
You can also download the page as XML directly by clicking the "Download Xml" link. <br/>
To close a translation task, please go to the Details view and click the "Close" button.
]]></key>
]]>
</key>
<key alias="closeTask">close task</key>
<key alias="details">Translation details</key>
<key alias="downloadAllAsXml">Download all translation tasks as xml</key>
@@ -771,7 +843,8 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="DownloadXmlDTD">Download xml DTD</key>
<key alias="fields">Fields</key>
<key alias="includeSubpages">Include subpages</key>
<key alias="mailBody"><![CDATA[
<key alias="mailBody">
<![CDATA[
Hi %0%
This is an automated mail to inform you that the document '%1%'
@@ -785,14 +858,17 @@ To manage your website, simply open the umbraco back office and start adding con
Have a nice day!
Cheers from the umbraco robot
]]></key>
]]>
</key>
<key alias="mailSubject">[%0%] Translation task for %1%</key>
<key alias="noTranslators">No translator users found. Please create a translator user before you start sending content to translation</key>
<key alias="ownedTasks">Tasks created by you</key>
<key alias="ownedTasksHelp"><![CDATA[ The list below shows pages <strong>created by you</strong>. To see a detailed view including comments,
<key alias="ownedTasksHelp">
<![CDATA[ The list below shows pages <strong>created by you</strong>. To see a detailed view including comments,
click on "Details" or just the page name. You can also download the page as XML directly by clicking the "Download Xml" link.
To close a translation task, please go to the Details view and click the "Close" button.
]]></key>
]]>
</key>
<key alias="pageHasBeenSendToTranslation">The page '%0%' has been send to translation</key>
<key alias="sendToTranslate">Send the page '%0%' to translation</key>
<key alias="taskAssignedBy">Assigned by</key>
@@ -825,7 +901,7 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="memberType">Member Types</key>
<key alias="nodeTypes">Document Types</key>
<key alias="packager">Packages</key>
<key alias="packages">Packages</key>
<key alias="packages">Packages</key>
<key alias="python">Python Files</key>
<key alias="repositories">Install from repository</key>
<key alias="runway">Install Runway</key>
@@ -865,9 +941,9 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="passwordChanged">Your password has been changed!</key>
<key alias="passwordConfirm">Please confirm the new password</key>
<key alias="passwordEnterNew">Enter your new password</key>
<key alias="passwordIsBlank">Your new password cannot be blank!</key>
<key alias="passwordCurrent">Current password</key>
<key alias="passwordInvalid">Invalid current password</key>
<key alias="passwordIsBlank">Your new password cannot be blank!</key>
<key alias="passwordCurrent">Current password</key>
<key alias="passwordInvalid">Invalid current password</key>
<key alias="passwordIsDifferent">There was a difference between the new password and the confirmed password. Please try again!</key>
<key alias="passwordMismatch">The confirmed password doesn't match the new password!</key>
<key alias="permissionReplaceChildren">Replace child node permssions</key>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -75,7 +75,7 @@
</area>
<area alias="content">
<key alias="about">Об этой странице</key>
<key alias="alias">Альтернативная ссылка</key>
<key alias="alias">Алиас</key>
<key alias="alternativeTextHelp">(как бы Вы описали изображение по телефону)</key>
<key alias="alternativeUrls">Альтернативные ссылки</key>
<key alias="clickToEdit">Нажмите для правки этого элемента</key>
@@ -261,6 +261,7 @@
<key alias="email">邮箱</key>
<key alias="error">错误</key>
<key alias="findDocument">查找文档</key>
<key alias="folder">文件夹</key>
<key alias="height"></key>
<key alias="help">帮助</key>
<key alias="icon">图标</key>
@@ -2,13 +2,12 @@
<input type="hidden" name="nodeType" value="-1"/>
Name: <asp:RequiredFieldValidator id="RequiredFieldValidator1" ErrorMessage="*" ControlToValidate="rename" runat="server">*</asp:RequiredFieldValidator><br />
<%=umbraco.ui.Text("name")%>: <asp:RequiredFieldValidator id="RequiredFieldValidator1" ErrorMessage="*" ControlToValidate="rename" runat="server">*</asp:RequiredFieldValidator><br />
<asp:TextBox id="rename" Runat="server" Width="350" CssClass="bigInput"></asp:TextBox>
<div style="MARGIN-TOP: 10px">
Type:<br />
<%=umbraco.ui.Text("type")%>:<br />
<asp:ListBox id="scriptType" Runat="server" Width="350" CssClass="bigInput" Rows="1" SelectionMode="Single">
<asp:ListItem Selected="True" Value="">Folder</asp:ListItem>
</asp:ListBox>
</div>
@@ -17,6 +16,6 @@ Type:<br />
<div style="MARGIN-TOP: 15px;">
<asp:Button id="sbmt" Runat="server" style="MARGIN-TOP: 14px" Width="90"></asp:Button>
<em> or </em>
<em> <%=umbraco.ui.Text("or")%> </em>
<a href="#" style="color: Blue; margin-left: 6px;" onclick="UmbClientMgr.closeModalWindow()"><%=umbraco.ui.Text("cancel")%></a>
</div>
@@ -21,14 +21,14 @@
<cc1:Pane runat="server" ID="pane_addnew">
<cc1:PropertyPanel runat="server" ID="prop_domain" Text="Domain">
<asp:TextBox ID="DomainName" runat="server" Width="252px"></asp:TextBox>
<asp:RequiredFieldValidator ControlToValidate="Languages" ErrorMessage="*" ID="DomainValidator" runat="server" Display="Dynamic" />
<br /><small><%= umbraco.ui.Text("assignDomain", "domainHelp") %></small>
<asp:RequiredFieldValidator ControlToValidate="DomainName" ErrorMessage="*" ID="DomainValidator" runat="server" Display="Dynamic" />
<asp:RegularExpressionValidator ControlToValidate="DomainName" ErrorMessage="*" ID="DomainValidator2" runat="server" Display="Dynamic" />
<br /><small><%= umbraco.ui.Text("assignDomain", "domainHelp") %></small>
</cc1:PropertyPanel>
<cc1:PropertyPanel ID="prop_lang" runat="server" Text="language">
<asp:RequiredFieldValidator ControlToValidate="Languages" ErrorMessage="*" ID="LanguageValidator"
runat="server" Display="Dynamic" />
<asp:DropDownList ID="Languages" runat="server" />
<asp:DropDownList ID="Languages" runat="server" />
<asp:RequiredFieldValidator ControlToValidate="Languages" ErrorMessage="*" ID="LanguageValidator" runat="server" Display="Dynamic" />
</cc1:PropertyPanel>
<cc1:PropertyPanel runat="server" Text=" ">
@@ -3,6 +3,7 @@
<%@ Register TagPrefix="ui" Namespace="umbraco.uicontrols" Assembly="controls" %>
<%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %>
<%@ Register TagPrefix="asp" Namespace="System.Web.UI" Assembly="System.Web" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
@@ -100,6 +101,7 @@
<form id="Form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<input type="hidden" name="macroMode" value="<%=Request["mode"]%>" />
<%if (Request["umb_macroID"] != null || Request["umb_macroAlias"] != null)
{%>
+12 -2
View File
@@ -1,6 +1,8 @@
<%@ Page Trace="false" Language="c#" CodeBehind="umbraco.aspx.cs" AutoEventWireup="True"
Inherits="Umbraco.Web.UI.Umbraco.Umbraco" %>
<%@ Import Namespace="System.Web.Script.Serialization" %>
<%@ Register Src="controls/Tree/TreeControl.ascx" TagName="TreeControl" TagPrefix="umbraco" %>
<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %>
<%@ Register TagPrefix="uc1" TagName="quickSearch" Src="Search/QuickSearch.ascx" %>
@@ -16,6 +18,8 @@
<umb:CssInclude ID="CssInclude2" runat="server" FilePath="modal/style.css" PathNameAlias="UmbracoClient" />
<umb:JsInclude ID="JsInclude1" runat="server" FilePath="Application/NamespaceManager.js"
PathNameAlias="UmbracoClient" Priority="0" />
<umb:JsInclude ID="JSON2" runat="server" FilePath="ui/json2.js" PathNameAlias="UmbracoClient"
Priority="0" />
<umb:JsInclude ID="JsInclude2" runat="server" FilePath="ui/jquery.js" PathNameAlias="UmbracoClient"
Priority="0" />
<umb:JsInclude ID="JsInclude3" runat="server" FilePath="ui/jqueryui.js" PathNameAlias="UmbracoClient"
@@ -289,14 +293,20 @@
}
function umbracoSessionRenewCheckPassword() {
var password = jQuery("#sessionrefreshpassword input").val();
if (password != "") {
var data = {
username: <%= new JavaScriptSerializer().Serialize(this.getUser().LoginName) %>,
password: password
};
if (jQuery("#sessionrefreshpassword input").val() != "") {
jQuery.ajax({
type: "POST",
url: "<%=umbraco.IO.IOHelper.ResolveUrl(umbraco.IO.SystemDirectories.Umbraco) %>/webservices/legacyAjaxCalls.asmx/ValidateUser",
data: "{'username': '<%=this.getUser().LoginName%>', 'password': '" + jQuery("#sessionrefreshpassword input").val() + "'}",
data: JSON.stringify(data),
processData: false,
success: function (result) {
if (result.d == true) {
@@ -0,0 +1 @@
var JSON; if (!JSON) { JSON = {} } (function () { function f(n) { return n < 10 ? "0" + n : n } if (typeof Date.prototype.toJSON !== "function") { Date.prototype.toJSON = function (key) { return isFinite(this.valueOf()) ? this.getUTCFullYear() + "-" + f(this.getUTCMonth() + 1) + "-" + f(this.getUTCDate()) + "T" + f(this.getUTCHours()) + ":" + f(this.getUTCMinutes()) + ":" + f(this.getUTCSeconds()) + "Z" : null }; String.prototype.toJSON = Number.prototype.toJSON = Boolean.prototype.toJSON = function (key) { return this.valueOf() } } var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, gap, indent, meta = { "\b": "\\b", "\t": "\\t", "\n": "\\n", "\f": "\\f", "\r": "\\r", '"': '\\"', "\\": "\\\\" }, rep; function quote(string) { escapable.lastIndex = 0; return escapable.test(string) ? '"' + string.replace(escapable, function (a) { var c = meta[a]; return typeof c === "string" ? c : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4) }) + '"' : '"' + string + '"' } function str(key, holder) { var i, k, v, length, mind = gap, partial, value = holder[key]; if (value && typeof value === "object" && typeof value.toJSON === "function") { value = value.toJSON(key) } if (typeof rep === "function") { value = rep.call(holder, key, value) } switch (typeof value) { case "string": return quote(value); case "number": return isFinite(value) ? String(value) : "null"; case "boolean": case "null": return String(value); case "object": if (!value) { return "null" } gap += indent; partial = []; if (Object.prototype.toString.apply(value) === "[object Array]") { length = value.length; for (i = 0; i < length; i += 1) { partial[i] = str(i, value) || "null" } v = partial.length === 0 ? "[]" : gap ? "[\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "]" : "[" + partial.join(",") + "]"; gap = mind; return v } if (rep && typeof rep === "object") { length = rep.length; for (i = 0; i < length; i += 1) { if (typeof rep[i] === "string") { k = rep[i]; v = str(k, value); if (v) { partial.push(quote(k) + (gap ? ": " : ":") + v) } } } } else { for (k in value) { if (Object.prototype.hasOwnProperty.call(value, k)) { v = str(k, value); if (v) { partial.push(quote(k) + (gap ? ": " : ":") + v) } } } } v = partial.length === 0 ? "{}" : gap ? "{\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "}" : "{" + partial.join(",") + "}"; gap = mind; return v } } if (typeof JSON.stringify !== "function") { JSON.stringify = function (value, replacer, space) { var i; gap = ""; indent = ""; if (typeof space === "number") { for (i = 0; i < space; i += 1) { indent += " " } } else { if (typeof space === "string") { indent = space } } rep = replacer; if (replacer && typeof replacer !== "function" && (typeof replacer !== "object" || typeof replacer.length !== "number")) { throw new Error("JSON.stringify") } return str("", { "": value }) } } if (typeof JSON.parse !== "function") { JSON.parse = function (text, reviver) { var j; function walk(holder, key) { var k, v, value = holder[key]; if (value && typeof value === "object") { for (k in value) { if (Object.prototype.hasOwnProperty.call(value, k)) { v = walk(value, k); if (v !== undefined) { value[k] = v } else { delete value[k] } } } } return reviver.call(holder, key, value) } text = String(text); cx.lastIndex = 0; if (cx.test(text)) { text = text.replace(cx, function (a) { return "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4) }) } if (/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]").replace(/(?:^|:|,)(?:\s*\[)+/g, ""))) { j = eval("(" + text + ")"); return typeof reviver === "function" ? walk({ "": j }, "") : j } throw new SyntaxError("JSON.parse") } } }());
+32 -21
View File
@@ -1,33 +1,44 @@
<?xml version="1.0"?>
<!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<!--
In the example below, the "SetAttributes" transform will change the value of
"connectionString" to use "ReleaseSQLServer" only when the "Match" locator
finds an atrribute "name" that has a value of "MyDB".
CAREFUL!
========
<connectionStrings>
<add name="MyDB"
connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
ONLY edit this if a certain change NEEDS to go into the config file of EVERYBODY contributing to the project.
After first build you will get your own web.config, which is no included in source control.
In the web.config you can edit all you want, it won't be overwritten, but it WILL be altered by this transform file.
The transforms in this file only apply to debugging, not to the web.config that will be released, see web.Template.Release.config for that
2012-11-08 SJ - Add Medium trust for everybody so we'll see errors early on
2012-11-22 SJ - Added MVC v2 redirect to v3 because ClientDependency.Mvc is built against MVC2
(not sure if this is the right thing to do but at least the project runs again)
-->
<system.web>
<compilation debug="true" xdt:Transform="SetAttributes(debug)" />
<trust level="Medium" xdt:Transform="Remove" />
<trust level="Medium" originUrl=".*" xdt:Transform="Insert" />
<!--
In the example below, the "Replace" transform will replace the entire
<customErrors> section of your web.config file.
Note that because there is only one customErrors section under the
<system.web> node, there is no need to use the "xdt:Locator" attribute.
<customErrors defaultRedirect="GenericError.htm"
mode="RemoteOnly" xdt:Transform="Replace">
<error statusCode="500" redirect="InternalError.htm"/>
</customErrors>
-->
</system.web>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly xdt:Transform="RemoveAll" />
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
@@ -19,7 +19,7 @@
<add xdt:Transform="Replace" xdt:Locator="Match(key)" key="umbracoDbDSN"
value="server=.\sqlexpress;database=v4;user id=sa;password=test;Application Name=Umbraco41"/>
<add xdt:Transform="Replace" xdt:Locator="Match(key)" key="umbracoConfigurationStatus"
value="4.10.0"/>
value="4.10.1"/>
<add xdt:Transform="Replace" xdt:Locator="Match(key)" key="umbracoContentXML"
value="~/App_Data/umbraco.config"/>
<add xdt:Transform="Replace" xdt:Locator="Match(key)" key="umbracoStorageDirectory"
@@ -27,7 +27,8 @@
</appSettings>
<system.web>
<trust level="Medium"/>
<trust level="Medium" xdt:Transform="Remove" />
<trust level="Medium" originUrl=".*" xdt:Transform="Insert" />
<compilation debug="true" xdt:Transform="SetAttributes(debug)" />
<!--
In the example below, the "Replace" transform will replace the entire
+1 -1
View File
@@ -241,7 +241,7 @@
<dependentAssembly>
<assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
</dependentAssembly>
</assemblyBinding>
</runtime>
@@ -0,0 +1,44 @@
<?xml version="1.0"?>
<!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<!--
In the example below, the "SetAttributes" transform will change the value of
"connectionString" to use "ReleaseSQLServer" only when the "Match" locator
finds an atrribute "name" that has a value of "MyDB".
<connectionStrings>
<add name="MyDB"
connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
-->
<appSettings>
<add xdt:Transform="Replace" xdt:Locator="Match(key)" key="umbracoDbDSN"
value="datalayer=SQLCE4Umbraco.SqlCEHelper,SQLCE4Umbraco;data source=|DataDirectory|\Umbraco.sdf"/>
<add xdt:Transform="Replace" xdt:Locator="Match(key)" key="umbracoConfigurationStatus" value="4.9.1"/>
<add xdt:Transform="Replace" xdt:Locator="Match(key)" key="umbracoContentXML" value="~/App_Data/umbraco.config"/>
<add xdt:Transform="Replace" xdt:Locator="Match(key)" key="umbracoStorageDirectory" value="~/App_Data"/>
</appSettings>
<system.web>
<compilation debug="true" xdt:Transform="SetAttributes(debug)">
<assemblies>
</assemblies>
</compilation>
<!--
In the example below, the "Replace" transform will replace the entire
<customErrors> section of your web.config file.
Note that because there is only one customErrors section under the
<system.web> node, there is no need to use the "xdt:Locator" attribute.
<customErrors defaultRedirect="GenericError.htm"
mode="RemoteOnly" xdt:Transform="Replace">
<error statusCode="500" redirect="InternalError.htm"/>
</customErrors>
-->
</system.web>
</configuration>
+157 -75
View File
@@ -5,6 +5,8 @@ using System.IO;
using System.Linq;
using System.Xml.XPath;
using Examine;
using Examine.Providers;
using Lucene.Net.Documents;
using Umbraco.Core;
using Umbraco.Core.Dynamics;
using Umbraco.Core.Models;
@@ -21,6 +23,22 @@ namespace Umbraco.Web
/// </remarks>
internal class DefaultPublishedMediaStore : IPublishedMediaStore
{
public DefaultPublishedMediaStore()
{
}
/// <summary>
/// Generally used for unit testing to use an explicit examine searcher
/// </summary>
/// <param name="searchProvider"></param>
internal DefaultPublishedMediaStore(BaseSearchProvider searchProvider)
{
_searchProvider = searchProvider;
}
private readonly BaseSearchProvider _searchProvider;
public virtual IPublishedContent GetDocumentById(UmbracoContext umbracoContext, int nodeId)
{
return GetUmbracoMedia(nodeId);
@@ -41,46 +59,87 @@ namespace Umbraco.Web
return result;
}
private IPublishedContent GetUmbracoMedia(int id)
private ExamineManager GetExamineManagerSafe()
{
try
{
//first check in Examine as this is WAY faster
var criteria = ExamineManager.Instance
.SearchProviderCollection["InternalSearcher"]
.CreateSearchCriteria("media");
var filter = criteria.Id(id);
var results = ExamineManager
.Instance.SearchProviderCollection["InternalSearcher"]
.Search(filter.Compile());
if (results.Any())
return ExamineManager.Instance;
}
catch (TypeInitializationException)
{
return null;
}
}
private BaseSearchProvider GetSearchProviderSafe()
{
if (_searchProvider != null)
return _searchProvider;
var eMgr = GetExamineManagerSafe();
if (eMgr != null)
{
try
{
return ConvertFromSearchResult(results.First());
//by default use the InternalSearcher
return eMgr.SearchProviderCollection["InternalSearcher"];
}
catch (FileNotFoundException)
{
//Currently examine is throwing FileNotFound exceptions when we have a loadbalanced filestore and a node is published in umbraco
//See this thread: http://examine.cdodeplex.com/discussions/264341
//Catch the exception here for the time being, and just fallback to GetMedia
//TODO: Need to fix examine in LB scenarios!
}
}
catch (FileNotFoundException)
return null;
}
private IPublishedContent GetUmbracoMedia(int id)
{
var searchProvider = GetSearchProviderSafe();
if (searchProvider != null)
{
//Currently examine is throwing FileNotFound exceptions when we have a loadbalanced filestore and a node is published in umbraco
//See this thread: http://examine.cdodeplex.com/discussions/264341
//Catch the exception here for the time being, and just fallback to GetMedia
//TODO: Need to fix examine in LB scenarios!
try
{
//first check in Examine as this is WAY faster
var criteria = searchProvider.CreateSearchCriteria("media");
var filter = criteria.Id(id);
var results = searchProvider.Search(filter.Compile());
if (results.Any())
{
return ConvertFromSearchResult(results.First());
}
}
catch (FileNotFoundException)
{
//Currently examine is throwing FileNotFound exceptions when we have a loadbalanced filestore and a node is published in umbraco
//See this thread: http://examine.cdodeplex.com/discussions/264341
//Catch the exception here for the time being, and just fallback to GetMedia
//TODO: Need to fix examine in LB scenarios!
}
}
var media = global::umbraco.library.GetMedia(id, true);
if (media != null && media.Current != null)
{
if (media.MoveNext())
media.MoveNext();
var moved = media.Current.MoveToFirstChild();
//first check if we have an error
if (moved)
{
var current = media.Current;
//error check
if (media.Current.MoveToFirstChild() && media.Current.Name.InvariantEquals("error"))
if (media.Current.Name.InvariantEquals("error"))
{
return null;
}
return ConvertFromXPathNavigator(current);
}
}
}
if (moved)
{
//move back to the parent and return
media.Current.MoveToParent();
}
return ConvertFromXPathNavigator(media.Current);
}
return null;
@@ -116,15 +175,13 @@ namespace Umbraco.Web
return new DictionaryPublishedContent(values,
d => d.ParentId != -1 //parent should be null if -1
? GetUmbracoMedia(d.ParentId)
: null,
//callback to return the children of the current node
d => GetChildrenMedia(d.ParentId),
GetProperty)
{
LoadedFromExamine = true
};
d => d.ParentId != -1 //parent should be null if -1
? GetUmbracoMedia(d.ParentId)
: null,
//callback to return the children of the current node
d => GetChildrenMedia(d.Id),
GetProperty,
true);
}
internal IPublishedContent ConvertFromXPathNavigator(XPathNavigator xpath)
@@ -180,8 +237,9 @@ namespace Umbraco.Web
? GetUmbracoMedia(d.ParentId)
: null,
//callback to return the children of the current node based on the xml structure already found
d => GetChildrenMedia(d.ParentId, xpath),
GetProperty);
d => GetChildrenMedia(d.Id, xpath),
GetProperty,
false);
}
/// <summary>
@@ -240,57 +298,62 @@ namespace Umbraco.Web
//if there is no navigator, try examine first, then re-look it up
if (xpath == null)
{
try
var searchProvider = GetSearchProviderSafe();
if (searchProvider != null)
{
//first check in Examine as this is WAY faster
var criteria = ExamineManager.Instance
.SearchProviderCollection["InternalSearcher"]
.CreateSearchCriteria("media");
var filter = criteria.ParentId(parentId);
var results = ExamineManager
.Instance.SearchProviderCollection["InternalSearcher"]
.Search(filter.Compile());
if (results.Any())
try
{
return results.Select(ConvertFromSearchResult);
//first check in Examine as this is WAY faster
var criteria = searchProvider.CreateSearchCriteria("media");
var filter = criteria.ParentId(parentId);
var results = searchProvider.Search(filter.Compile());
if (results.Any())
{
return results.Select(ConvertFromSearchResult);
}
}
}
catch (FileNotFoundException)
{
//Currently examine is throwing FileNotFound exceptions when we have a loadbalanced filestore and a node is published in umbraco
//See this thread: http://examine.cdodeplex.com/discussions/264341
//Catch the exception here for the time being, and just fallback to GetMedia
}
catch (FileNotFoundException)
{
//Currently examine is throwing FileNotFound exceptions when we have a loadbalanced filestore and a node is published in umbraco
//See this thread: http://examine.cdodeplex.com/discussions/264341
//Catch the exception here for the time being, and just fallback to GetMedia
}
}
var media = library.GetMedia(parentId, true);
if (media != null && media.Current != null)
{
if (!media.MoveNext())
return null;
xpath = media.Current;
}
else
{
return null;
}
}
var children = xpath.SelectChildren(XPathNodeType.Element);
var mediaList = new List<IPublishedContent>();
while (children.Current != null)
//The xpath might be the whole xpath including the current ones ancestors so we need to select the current node
var item = xpath.Select("//*[@id='" + parentId + "']");
if (item.Current == null)
{
if (!children.MoveNext())
{
break;
}
return null;
}
var children = item.Current.SelectChildren(XPathNodeType.Element);
var mediaList = new List<IPublishedContent>();
foreach(XPathNavigator x in children)
{
//NOTE: I'm not sure why this is here, it is from legacy code of ExamineBackedMedia, but
// will leave it here as it must have done something!
if (children.Current.Name != "contents")
if (x.Name != "contents")
{
//make sure it's actually a node, not a property
if (!string.IsNullOrEmpty(children.Current.GetAttribute("path", "")) &&
!string.IsNullOrEmpty(children.Current.GetAttribute("id", "")))
if (!string.IsNullOrEmpty(x.GetAttribute("path", "")) &&
!string.IsNullOrEmpty(x.GetAttribute("id", "")))
{
mediaList.Add(ConvertFromXPathNavigator(children.Current));
mediaList.Add(ConvertFromXPathNavigator(x));
}
}
}
}
return mediaList;
}
@@ -309,7 +372,8 @@ namespace Umbraco.Web
IDictionary<string, string> valueDictionary,
Func<DictionaryPublishedContent, IPublishedContent> getParent,
Func<DictionaryPublishedContent, IEnumerable<IPublishedContent>> getChildren,
Func<DictionaryPublishedContent, string, IPublishedContentProperty> getProperty)
Func<DictionaryPublishedContent, string, IPublishedContentProperty> getProperty,
bool fromExamine)
{
if (valueDictionary == null) throw new ArgumentNullException("valueDictionary");
if (getParent == null) throw new ArgumentNullException("getParent");
@@ -319,7 +383,7 @@ namespace Umbraco.Web
_getChildren = getChildren;
_getProperty = getProperty;
LoadedFromExamine = false; //default to false
LoadedFromExamine = fromExamine;
ValidateAndSetProperty(valueDictionary, val => Id = int.Parse(val), "id", "nodeId", "__NodeId"); //should validate the int!
ValidateAndSetProperty(valueDictionary, val => TemplateId = int.Parse(val), "template", "templateId");
@@ -329,12 +393,12 @@ namespace Umbraco.Web
ValidateAndSetProperty(valueDictionary, val => DocumentTypeAlias = val, "nodeTypeAlias", "__NodeTypeAlias");
ValidateAndSetProperty(valueDictionary, val => DocumentTypeId = int.Parse(val), "nodeType");
ValidateAndSetProperty(valueDictionary, val => WriterName = val, "writerName");
ValidateAndSetProperty(valueDictionary, val => CreatorName = val, "creatorName");
ValidateAndSetProperty(valueDictionary, val => CreatorName = val, "creatorName", "writerName"); //this is a bit of a hack fix for: U4-1132
ValidateAndSetProperty(valueDictionary, val => WriterId = int.Parse(val), "writerID");
ValidateAndSetProperty(valueDictionary, val => CreatorId = int.Parse(val), "creatorID");
ValidateAndSetProperty(valueDictionary, val => CreatorId = int.Parse(val), "creatorID", "writerID"); //this is a bit of a hack fix for: U4-1132
ValidateAndSetProperty(valueDictionary, val => Path = val, "path", "__Path");
ValidateAndSetProperty(valueDictionary, val => CreateDate = DateTime.Parse(val), "createDate");
ValidateAndSetProperty(valueDictionary, val => UpdateDate = DateTime.Parse(val), "updateDate");
ValidateAndSetProperty(valueDictionary, val => CreateDate = ParseDateTimeValue(val), "createDate");
ValidateAndSetProperty(valueDictionary, val => UpdateDate = ParseDateTimeValue(val), "updateDate");
ValidateAndSetProperty(valueDictionary, val => Level = int.Parse(val), "level");
ValidateAndSetProperty(valueDictionary, val =>
{
@@ -358,10 +422,28 @@ namespace Umbraco.Web
}
}
private DateTime ParseDateTimeValue(string val)
{
if (LoadedFromExamine)
{
try
{
//we might need to parse the date time using Lucene converters
return DateTools.StringToDate(val);
}
catch (FormatException)
{
//swallow exception, its not formatted correctly so revert to just trying to parse
}
}
return DateTime.Parse(val);
}
/// <summary>
/// Flag to get/set if this was laoded from examine cache
/// </summary>
internal bool LoadedFromExamine { get; set; }
internal bool LoadedFromExamine { get; private set; }
private readonly Func<DictionaryPublishedContent, IPublishedContent> _getParent;
private readonly Func<DictionaryPublishedContent, IEnumerable<IPublishedContent>> _getChildren;
+1 -1
View File
@@ -6,7 +6,7 @@ namespace Umbraco.Web
/// <summary>
/// Defines the methods to access published content
/// </summary>
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1153", "This should become public one day but we need to create something like the IPublishListener interface to have proper published content storage. We'll also need to publicize the resolveres so people can set a resolver at app startup.")]
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1153", "We need to create something like the IPublishListener interface to have proper published content storage. We'll also need to publicize the resolvers so people can set a resolver at app startup.")]
internal interface IPublishedContentStore : IPublishedStore
{
IPublishedContent GetDocumentByRoute(UmbracoContext umbracoContext, string route, bool? hideTopLevelNode = null);
+1 -1
View File
@@ -5,7 +5,7 @@ namespace Umbraco.Web
/// <summary>
/// Defines the methods to access published media
/// </summary>
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1153", "This should become public one day but we need to create something like the IPublishListener interface to have proper published content storage. We'll also need to publicize the resolveres so people can set a resolver at app startup.")]
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1153", "We need to create something like the IPublishListener interface to have proper published content storage. We'll also need to publicize the resolvers so people can set a resolver at app startup.")]
internal interface IPublishedMediaStore : IPublishedStore
{
}
+1 -1
View File
@@ -7,7 +7,7 @@ namespace Umbraco.Web
/// <summary>
/// Defines the methods for published documents
/// </summary>
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1153", "This should become public one day but we need to create something like the IPublishListener interface to have proper published content storage. We'll also need to publicize the resolveres so people can set a resolver at app startup.")]
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1153", "We need to create something like the IPublishListener interface to have proper published content storage. We'll also need to publicize the resolvers so people can set a resolver at app startup.")]
internal interface IPublishedStore
{
IPublishedContent GetDocumentById(UmbracoContext umbracoContext, int nodeId);
@@ -16,6 +16,7 @@ namespace Umbraco.Web.Install
/// Currently this is used for web services however we should/could eventually migrate the whole installer to MVC as it
/// is a bit of a mess currently.
/// </remarks>
[UmbracoInstallAuthorize]
public class InstallPackageController : Controller
{
private readonly ApplicationContext _applicationContext;
@@ -173,6 +174,6 @@ namespace Umbraco.Web.Install
message = "Starter kit has been installed"
});
}
}
}
@@ -0,0 +1,89 @@
using System;
using System.Web;
using System.Web.Mvc;
using Umbraco.Core;
using umbraco.BasePages;
namespace Umbraco.Web.Install
{
/// <summary>
/// Ensures authorization occurs for the installer if it has already completed. If install has not yet occured
/// then the authorization is successful
/// </summary>
internal class UmbracoInstallAuthorizeAttribute : AuthorizeAttribute
{
private readonly ApplicationContext _applicationContext;
public UmbracoInstallAuthorizeAttribute(ApplicationContext appContext)
{
if (appContext == null) throw new ArgumentNullException("appContext");
_applicationContext = appContext;
}
public UmbracoInstallAuthorizeAttribute()
: this(ApplicationContext.Current)
{
}
/// <summary>
/// Ensures that the user must be in the Administrator or the Install role
/// </summary>
/// <param name="httpContext"></param>
/// <returns></returns>
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext == null)
{
throw new ArgumentNullException("httpContext");
}
try
{
//if its not configured then we can continue
if (!_applicationContext.IsConfigured)
{
return true;
}
//otherwise we need to ensure that a user is logged in
var isLoggedIn = BasePage.ValidateUserContextID(BasePage.umbracoUserContextID);
if (isLoggedIn)
{
return true;
}
return false;
}
catch (Exception)
{
return false;
}
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
Mandate.ParameterNotNull(filterContext, "filterContext");
if (OutputCacheAttribute.IsChildActionCacheActive(filterContext))
throw new InvalidOperationException("Cannot use UmbracoInstallAuthorizeAttribute on a child action");
if (AuthorizeCore(filterContext.HttpContext))
{
//with a little help from dotPeek... this is what it normally would do
var cache = filterContext.HttpContext.Response.Cache;
cache.SetProxyMaxAge(new TimeSpan(0L));
cache.AddValidationCallback(CacheValidateHandler, null);
}
else
{
//they aren't authorized but the app has installed
throw new HttpException((int)global::System.Net.HttpStatusCode.Unauthorized,
"You must login to view this resource.");
}
}
private void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus)
{
validationStatus = OnCacheAuthorization(new HttpContextWrapper(context));
}
}
}
+84
View File
@@ -0,0 +1,84 @@
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Globalization;
using System.Linq;
using System.Web;
using Umbraco.Core.Media;
using umbraco;
namespace Umbraco.Web.Media
{
public class ImageUrl
{
public static string GetImageUrl(string specifiedSrc, string field, string provider, string parameters, int? nodeId = null)
{
string url;
var imageUrlProvider = GetProvider(provider);
var parsedParameters = string.IsNullOrEmpty(parameters) ? new NameValueCollection() : HttpUtility.ParseQueryString(parameters);
var queryValues = parsedParameters.Keys.Cast<string>().ToDictionary(key => key, key => parsedParameters[key]);
if (string.IsNullOrEmpty(field))
{
url = imageUrlProvider.GetImageUrlFromFileName(specifiedSrc, queryValues);
}
else
{
var fieldValue = string.Empty;
if (nodeId.HasValue)
{
var contentFromCache = GetContentFromCache(nodeId.GetValueOrDefault(), field);
if (contentFromCache != null)
{
fieldValue = contentFromCache.ToString();
}
else
{
var itemPage = new page(content.Instance.XmlContent.GetElementById(nodeId.GetValueOrDefault().ToString(CultureInfo.InvariantCulture)));
var value = itemPage.Elements[field];
fieldValue = value != null ? value.ToString() : string.Empty;
}
}
else
{
var context = HttpContext.Current;
if (context != null)
{
var elements = context.Items["pageElements"] as Hashtable;
if (elements != null)
{
var value = elements[field];
fieldValue = value != null ? value.ToString() : string.Empty;
}
}
}
int mediaId;
url = int.TryParse(fieldValue, out mediaId)
? imageUrlProvider.GetImageUrlFromMedia(mediaId, queryValues)
: imageUrlProvider.GetImageUrlFromFileName(fieldValue, queryValues);
}
return url;
}
private static IImageUrlProvider GetProvider(string provider)
{
return ImageUrlProviderResolver.Current.GetProvider(provider);
}
private static object GetContentFromCache(int nodeIdInt, string field)
{
var context = HttpContext.Current;
if (context == null)
return string.Empty;
var content = context.Cache[String.Format("contentItem{0}_{1}", nodeIdInt.ToString(CultureInfo.InvariantCulture), field)];
return content;
}
}
}
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Media;
using Umbraco.Core.ObjectResolution;
using Umbraco.Web.Media.ImageUrlProviders;
namespace Umbraco.Web.Media
{
internal sealed class ImageUrlProviderResolver : ManyObjectsResolverBase<ImageUrlProviderResolver, IImageUrlProvider>
{
internal ImageUrlProviderResolver(IEnumerable<Type> value) : base(value) { }
public IImageUrlProvider GetProvider(string provider)
{
return string.IsNullOrEmpty(provider) ?
Values.First(v => v.Name.Equals(ImageUrlProvider.DefaultName, StringComparison.InvariantCultureIgnoreCase)) :
Values.First(v => v.Name.Equals(provider, StringComparison.InvariantCultureIgnoreCase));
}
}
}
@@ -0,0 +1,91 @@
using System.Collections.Generic;
using System.Xml.XPath;
using Umbraco.Core.Media;
using umbraco;
namespace Umbraco.Web.Media.ImageUrlProviders
{
public class ImageUrlProvider : IImageUrlProvider
{
public const string DefaultName = "umbracoUpload";
public string Name
{
get { return DefaultName; }
}
public string GetImageUrlFromMedia(int mediaId, IDictionary<string, string> parameters)
{
var url = string.Empty;
var nodeIterator = library.GetMedia(mediaId, false);
if (nodeIterator.Current != null)
{
var filename = GetProperty(nodeIterator, "umbracoFile");
var withThumb = AddThumbInfo(filename, parameters);
url = AddCropInfo(withThumb, parameters);
}
return url;
}
public string GetImageUrlFromFileName(string specifiedSrc, IDictionary<string, string> parameters)
{
var withThumb = AddThumbInfo(specifiedSrc, parameters);
return AddCropInfo(withThumb, parameters);
}
private static string AddThumbInfo(string filename, IDictionary<string, string> parameters)
{
var thumb = string.Empty;
if (parameters.ContainsKey("thumb"))
thumb = parameters["thumb"];
if (!string.IsNullOrEmpty(thumb))
{
var lastIndexOf = filename.LastIndexOf('.');
var name = filename.Substring(0, lastIndexOf);
var extension = filename.Substring(lastIndexOf, filename.Length - lastIndexOf);
return string.Format("{0}_thumb_{1}{2}", name, thumb, extension);
}
return filename;
}
private static string AddCropInfo(string filename, IDictionary<string, string> parameters)
{
var crop = string.Empty;
if (parameters.ContainsKey("crop"))
crop = parameters["crop"];
if (!string.IsNullOrEmpty(crop))
{
var lastIndexOf = filename.LastIndexOf('.');
var name = filename.Substring(0, lastIndexOf);
//var extension = filename.Substring(lastIndexOf, filename.Length - lastIndexOf);
//Built in cropper currently always uses jpg as an extension
const string extension = ".jpg";
return string.Format("{0}_{1}{2}", name, crop, extension);
}
return filename;
}
private static string GetProperty(XPathNodeIterator nodeIterator, string fileProp)
{
var xpath = UmbracoSettings.UseLegacyXmlSchema
? string.Format(".//data[@alias = '{0}']", fileProp)
: string.Format(".//{0}", fileProp);
var file = string.Empty;
var selectSingleNode = nodeIterator.Current.SelectSingleNode(xpath);
if (selectSingleNode != null)
file = selectSingleNode.InnerXml;
return file;
}
}
}
+38 -187
View File
@@ -21,12 +21,6 @@ namespace Umbraco.Web.Models
/// </summary>
public class DynamicPublishedContent : DynamicObject, IPublishedContent
{
/// <summary>
/// This callback is used only so we can set it dynamically for use in unit tests
/// </summary>
internal static Func<string, string, Guid> GetDataTypeCallback = (docTypeAlias, propertyAlias) =>
ContentType.GetDataType(docTypeAlias, propertyAlias);
protected IPublishedContent PublishedContent { get; private set; }
private DynamicPublishedContentList _cachedChildren;
private readonly ConcurrentDictionary<string, object> _cachedMemberOutput = new ConcurrentDictionary<string, object>();
@@ -60,111 +54,48 @@ namespace Umbraco.Web.Models
/// <returns></returns>
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
//TODO: We MUST cache the result here, it is very expensive to keep finding extension methods!
try
{
//Property?
result = typeof(DynamicPublishedContent).InvokeMember(binder.Name,
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.GetProperty,
null,
this,
args);
return true;
}
catch (MissingMethodException)
{
try
{
//Static or Instance Method?
result = typeof(DynamicPublishedContent).InvokeMember(binder.Name,
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.Static |
System.Reflection.BindingFlags.InvokeMethod,
null,
this,
args);
return true;
}
catch (MissingMethodException)
{
try
{
result = ExecuteExtensionMethod(args, binder.Name);
return true;
}
catch (TargetInvocationException)
{
result = new DynamicNull();
return true;
}
catch
{
//TODO: LOg this!
result = null;
return false;
}
}
}
catch
{
result = null;
return false;
}
}
private object ExecuteExtensionMethod(object[] args, string name)
{
object result = null;
var methodTypesToFind = new[]
var attempt = DynamicInstanceHelper.TryInvokeMember(this, binder, args, new[]
{
typeof(DynamicPublishedContent)
};
});
//find known extension methods that match the first type in the list
MethodInfo toExecute = null;
foreach (var t in methodTypesToFind)
if (attempt.Success)
{
toExecute = ExtensionMethodFinder.FindExtensionMethod(t, args, name, false);
if (toExecute != null)
break;
}
result = attempt.Result.ObjectResult;
if (toExecute != null)
{
var genericArgs = (new[] { this }).Concat(args);
result = toExecute.Invoke(null, genericArgs.ToArray());
}
else
{
throw new MissingMethodException();
}
if (result != null)
{
if (result is IPublishedContent)
{
result = new DynamicPublishedContent((IPublishedContent)result);
}
if (result is IEnumerable<IPublishedContent>)
{
result = new DynamicPublishedContentList((IEnumerable<IPublishedContent>)result);
//need to check the return type and possibly cast if result is from an extension method found
if (attempt.Result.Reason == DynamicInstanceHelper.TryInvokeMemberSuccessReason.FoundExtensionMethod)
{
//we don't need to cast if it is already DynamicPublishedContent
if (attempt.Result.ObjectResult != null && (!(attempt.Result.ObjectResult is DynamicPublishedContent)))
{
if (attempt.Result.ObjectResult is IPublishedContent)
{
result = new DynamicPublishedContent((IPublishedContent)attempt.Result.ObjectResult);
}
else if (attempt.Result.ObjectResult is IEnumerable<DynamicPublishedContent>)
{
result = new DynamicPublishedContentList((IEnumerable<DynamicPublishedContent>)attempt.Result.ObjectResult);
}
else if (attempt.Result.ObjectResult is IEnumerable<IPublishedContent>)
{
result = new DynamicPublishedContentList((IEnumerable<IPublishedContent>)attempt.Result.ObjectResult);
}
}
}
if (result is IEnumerable<DynamicPublishedContent>)
{
result = new DynamicPublishedContentList((IEnumerable<DynamicPublishedContent>)result);
}
return true;
}
return result;
//this is the result of an extension method execution gone wrong so we return dynamic null
if (attempt.Result.Reason == DynamicInstanceHelper.TryInvokeMemberSuccessReason.FoundExtensionMethod
&& attempt.Error != null && attempt.Error is TargetInvocationException)
{
result = new DynamicNull();
return true;
}
result = null;
return false;
}
/// <summary>
@@ -262,10 +193,10 @@ namespace Umbraco.Web.Models
}
//get the data type id for the current property
var dataType = GetDataType(userProperty.DocumentTypeAlias, userProperty.Alias);
var dataType = Umbraco.Core.PublishedContentHelper.GetDataType(userProperty.DocumentTypeAlias, userProperty.Alias);
//convert the string value to a known type
var converted = ConvertPropertyValue(result, dataType, userProperty.DocumentTypeAlias, userProperty.Alias);
var converted = Umbraco.Core.PublishedContentHelper.ConvertPropertyValue(result, dataType, userProperty.DocumentTypeAlias, userProperty.Alias);
if (converted.Success)
{
result = converted.Result;
@@ -823,87 +754,7 @@ namespace Umbraco.Web.Models
}
#endregion
private static Guid GetDataType(string docTypeAlias, string propertyAlias)
{
return GetDataTypeCallback(docTypeAlias, propertyAlias);
}
/// <summary>
/// Converts the currentValue to a correctly typed value based on known registered converters, then based on known standards.
/// </summary>
/// <param name="currentValue"></param>
/// <param name="dataType"></param>
/// <param name="docTypeAlias"></param>
/// <param name="propertyTypeAlias"></param>
/// <returns></returns>
private Attempt<object> ConvertPropertyValue(object currentValue, Guid dataType, string docTypeAlias, string propertyTypeAlias)
{
if (currentValue == null) return Attempt<object>.False;
//First lets check all registered converters for this data type.
var converters = PropertyEditorValueConvertersResolver.Current.Converters
.Where(x => x.IsConverterFor(dataType, docTypeAlias, propertyTypeAlias))
.ToArray();
//try to convert the value with any of the converters:
foreach (var converted in converters
.Select(p => p.ConvertPropertyValue(currentValue))
.Where(converted => converted.Success))
{
return new Attempt<object>(true, converted.Result);
}
//if none of the converters worked, then we'll process this from what we know
var sResult = Convert.ToString(currentValue).Trim();
//this will eat csv strings, so only do it if the decimal also includes a decimal seperator (according to the current culture)
if (sResult.Contains(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator))
{
decimal dResult;
if (decimal.TryParse(sResult, System.Globalization.NumberStyles.Number, System.Globalization.CultureInfo.CurrentCulture, out dResult))
{
return new Attempt<object>(true, dResult);
}
}
//process string booleans as booleans
if (sResult.InvariantEquals("true"))
{
return new Attempt<object>(true, true);
}
if (sResult.InvariantEquals("false"))
{
return new Attempt<object>(true, false);
}
//a really rough check to see if this may be valid xml
//TODO: This is legacy code, I'm sure there's a better and nicer way
if (sResult.StartsWith("<") && sResult.EndsWith(">") && sResult.Contains("/"))
{
try
{
var e = XElement.Parse(DynamicXml.StripDashesInElementOrAttributeNames(sResult), LoadOptions.None);
//check that the document element is not one of the disallowed elements
//allows RTE to still return as html if it's valid xhtml
var documentElement = e.Name.LocalName;
//TODO: See note against this setting, pretty sure we don't need this
if (!UmbracoSettings.NotDynamicXmlDocumentElements.Any(
tag => string.Equals(tag, documentElement, StringComparison.CurrentCultureIgnoreCase)))
{
return new Attempt<object>(true, new DynamicXml(e));
}
return Attempt<object>.False;
}
catch (Exception)
{
return Attempt<object>.False;
}
}
return Attempt<object>.False;
}
#region Index/Position
public int Position()
{
@@ -46,9 +46,6 @@ namespace Umbraco.Web.Models
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
//TODO: We MUST cache the result here, it is very expensive to keep finding extension methods and processing this stuff!
//TODO: Nowhere here are we checking if args is the correct length!
//NOTE: For many of these we could actually leave them out since we are executing custom extension methods and because
@@ -196,11 +193,6 @@ namespace Umbraco.Web.Models
{
result = new DynamicPublishedContentList(this.Items.Except(firstArg as IEnumerable<DynamicPublishedContent>, new DynamicPublishedContentIdEqualityComparer()));
return true;
}
if ((firstArg as DynamicPublishedContentList) != null)
{
result = new DynamicPublishedContentList(this.Items.Except((firstArg as DynamicPublishedContentList).Items, new DynamicPublishedContentIdEqualityComparer()));
return true;
}
}
if (name == "Intersect")
@@ -209,11 +201,6 @@ namespace Umbraco.Web.Models
{
result = new DynamicPublishedContentList(this.Items.Intersect(firstArg as IEnumerable<DynamicPublishedContent>, new DynamicPublishedContentIdEqualityComparer()));
return true;
}
if ((firstArg as DynamicPublishedContentList) != null)
{
result = new DynamicPublishedContentList(this.Items.Intersect((firstArg as DynamicPublishedContentList).Items, new DynamicPublishedContentIdEqualityComparer()));
return true;
}
}
if (name == "Distinct")
@@ -226,65 +213,51 @@ namespace Umbraco.Web.Models
result = Pluck(args);
return true;
}
try
{
//Property?
result = Items.GetType().InvokeMember(binder.Name,
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.GetProperty,
null,
Items,
args);
return true;
}
catch (MissingMethodException)
{
try
{
//Static or Instance Method?
result = Items.GetType().InvokeMember(binder.Name,
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.Static |
System.Reflection.BindingFlags.InvokeMethod,
null,
Items,
args);
return true;
}
catch (MissingMethodException)
{
try
{
result = ExecuteExtensionMethod(args, name);
return true;
}
catch (TargetInvocationException)
{
//We do this to enable error checking of Razor Syntax when a method e.g. ElementAt(2) is used.
//When the Script is tested, there's no Children which means ElementAt(2) is invalid (IndexOutOfRange)
//Instead, we are going to return DynamicNull;
result = new DynamicNull();
return true;
}
//ok, now lets try to match by member, property, extensino method
var attempt = DynamicInstanceHelper.TryInvokeMember(this, binder, args, new[]
{
typeof (IEnumerable<DynamicPublishedContent>),
typeof (DynamicPublishedContentList)
});
catch
{
result = null;
return false;
}
if (attempt.Success)
{
result = attempt.Result.ObjectResult;
}
//need to check the return type and possibly cast if result is from an extension method found
if (attempt.Result.Reason == DynamicInstanceHelper.TryInvokeMemberSuccessReason.FoundExtensionMethod)
{
//we don't need to cast if the result is already DynamicPublishedContentList
if (attempt.Result.ObjectResult != null && (!(attempt.Result.ObjectResult is DynamicPublishedContentList)))
{
if (attempt.Result.ObjectResult is IPublishedContent)
{
result = new DynamicPublishedContent((IPublishedContent)attempt.Result.ObjectResult);
}
else if (attempt.Result.ObjectResult is IEnumerable<DynamicPublishedContent>)
{
result = new DynamicPublishedContentList((IEnumerable<DynamicPublishedContent>)attempt.Result.ObjectResult);
}
else if (attempt.Result.ObjectResult is IEnumerable<IPublishedContent>)
{
result = new DynamicPublishedContentList((IEnumerable<IPublishedContent>)attempt.Result.ObjectResult);
}
}
}
return true;
}
//this is the result of an extension method execution gone wrong so we return dynamic null
if (attempt.Result.Reason == DynamicInstanceHelper.TryInvokeMemberSuccessReason.FoundExtensionMethod
&& attempt.Error != null && attempt.Error is TargetInvocationException)
{
result = new DynamicNull();
return true;
}
}
catch
{
result = null;
return false;
}
result = null;
return false;
}
private T Aggregate<T>(IEnumerable<T> data, string name) where T : struct
@@ -425,67 +398,7 @@ namespace Umbraco.Web.Models
}
return result;
}
private object ExecuteExtensionMethod(object[] args, string name)
{
object result = null;
var methodTypesToFind = new[]
{
typeof(IEnumerable<DynamicPublishedContent>),
typeof(DynamicPublishedContentList)
};
//find known extension methods that match the first type in the list
MethodInfo toExecute = null;
foreach(var t in methodTypesToFind)
{
toExecute = ExtensionMethodFinder.FindExtensionMethod(t, args, name, false);
if (toExecute != null)
break;
}
if (toExecute != null)
{
if (toExecute.GetParameters().First().ParameterType == typeof(DynamicPublishedContentList))
{
var genericArgs = (new[] { this }).Concat(args);
result = toExecute.Invoke(null, genericArgs.ToArray());
}
else if (TypeHelper.IsTypeAssignableFrom<IQueryable>(toExecute.GetParameters().First().ParameterType))
{
//if it is IQueryable, we'll need to cast Items AsQueryable
var genericArgs = (new[] { Items.AsQueryable() }).Concat(args);
result = toExecute.Invoke(null, genericArgs.ToArray());
}
else
{
var genericArgs = (new[] { Items }).Concat(args);
result = toExecute.Invoke(null, genericArgs.ToArray());
}
}
else
{
throw new MissingMethodException();
}
if (result != null)
{
if (result is IPublishedContent)
{
result = new DynamicPublishedContent((IPublishedContent)result);
}
if (result is IEnumerable<IPublishedContent>)
{
result = new DynamicPublishedContentList((IEnumerable<IPublishedContent>)result);
}
if (result is IEnumerable<DynamicPublishedContent>)
{
result = new DynamicPublishedContentList((IEnumerable<DynamicPublishedContent>)result);
}
}
return result;
}
public T Single<T>(string predicate, params object[] values)
{
return predicate.IsNullOrWhiteSpace()
+10 -5
View File
@@ -69,23 +69,28 @@ namespace Umbraco.Web.Mvc
return sw.ToString().Trim();
}
}
/// <summary>
/// Renders the partial view to string.
/// </summary>
/// <param name="controller">The controller context.</param>
/// <param name="viewName">Name of the view.</param>
/// <param name="model">The model.</param>
/// <param name="isPartial">true if it is a Partial view, otherwise false for a normal view </param>
/// <returns></returns>
internal static string RenderPartialViewToString(this ControllerBase controller, string viewName, object model)
internal static string RenderViewToString(this ControllerBase controller, string viewName, object model, bool isPartial = false)
{
if (controller.ControllerContext == null)
throw new ArgumentException("The controller must have an assigned ControllerContext to execute this method.");
controller.ViewData.Model = model;
using (StringWriter sw = new StringWriter())
using (var sw = new StringWriter())
{
ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
ViewContext viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
var viewResult = !isPartial
? ViewEngines.Engines.FindView(controller.ControllerContext, viewName, null)
: ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
viewResult.View.Render(viewContext, sw);
return sw.GetStringBuilder().ToString();
+16 -3
View File
@@ -61,20 +61,33 @@ namespace Umbraco.Web.Mvc
}
/// <summary>
/// The default action to render the front-end view
/// Returns an ActionResult based on the template name found in the route values and the given model.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="model"></param>
/// <returns></returns>
public virtual ActionResult Index(RenderModel model)
/// <remarks>
/// If the template found in the route values doesn't physically exist, then an empty ContentResult will be returned.
/// </remarks>
protected ActionResult CurrentTemplate<T>(T model)
{
var template = ControllerContext.RouteData.Values["action"].ToString();
if (!EnsurePhsyicalViewExists(template))
{
return Content("");
}
return View(template, model);
}
/// <summary>
/// The default action to render the front-end view
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public virtual ActionResult Index(RenderModel model)
{
return CurrentTemplate(model);
}
}
}

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