Compare commits

...

55 Commits

Author SHA1 Message Date
Sebastiaan Janssen 25c68a5a36 Merge pull request #567 from readingdancer/Fix_issue_U4-4585
Fix so Login screen now works correctly with Umbraco UI Localization settings.
2014-11-26 12:03:46 +01:00
Sebastiaan Janssen 82d433d291 Ignore VS15 generated files 2014-11-26 11:31:22 +01:00
Sebastiaan Janssen 69ae715998 Revert to using MVC 4.0.0.0 OOB so that people who have only 4.0.0.0 in the GAC can actually install Umbraco. If 4.0.0.1 is in the GAC that version will be taken.
Leaves the additional reference to System.Web.Http in web.config so that you don't get the System.Web.Http.ApiController when 4.0.0.1 is indeed in the GAC.
2014-11-26 10:31:13 +01:00
Shannon 1930022f19 Fixes: U4-5714 Calling Index() on IPublishedContent level 1 media fails 2014-11-26 10:52:30 +11:00
Shannon bece953fa3 fixes a null check 2014-11-26 10:20:19 +11:00
Shannon a41d37b1cf Fixes assembly error msg. 2014-11-26 09:44:31 +11:00
Shannon 31603f7063 Fixes assembly error msg. 2014-11-26 09:43:44 +11:00
Chris Houston 87ae16b89a Fix for issue http://issues.umbraco.org/issue/U4-4585
"I cant change UI language for the login screen in Umbraco 7.1.6"

Also added a couple more Spanish translations to the Language file.
2014-11-25 19:14:35 +00:00
Sebastiaan Janssen 4520c06454 Fixes missing filename in the log 2014-11-25 19:21:10 +01:00
Sebastiaan Janssen 9f0c00827d Fixes build, still had some wrong paths preventing build.bat from working 2014-11-25 18:54:25 +01:00
Sebastiaan Janssen 0df0b78b90 #U4-5453 Fixed
Enabling IIS Compression gives ERR_CONTENT_DECODING_FAILED in backoffice
2014-11-25 16:56:44 +01:00
Sebastiaan Janssen c6b6685dc7 Fixes the build for VS15 2014-11-25 16:55:59 +01:00
Stephan 7c3c477f18 Merge remote-tracking branch 'origin/7.1.9' into 7.1.9
Conflicts:
	src/Umbraco.Web/umbraco.presentation/umbraco/create/nodeType.ascx.cs
2014-11-25 11:28:48 +01:00
Stephan d7cc626396 U4-1083 - proper error message on content type alias duplicate 2014-11-25 11:25:04 +01:00
Shannon 9d50a4d2a5 Re Fixes: U4-5220 XSLT Extensions in App_Code or /bin not working in 7.1.4 - this is just a work-around fix, the real problem is the dll's in the user's bin folder. 2014-11-25 09:50:16 +11:00
Shannon Deminick 321e2f9de0 Merge pull request #546 from readingdancer/UmbUkFest-U4-3979
Updated the language files to fix issue #U4-3979
2014-11-24 13:12:56 +11:00
Chris Houston 9834352de2 - Added all the missing Key's to the Spanish file
- Updated the help documentation URL's
- Updated the Community Contributor URL's
2014-11-23 03:30:18 +00:00
Shannon Deminick 2341622243 Merge pull request #558 from LottePitcher/7.1.9
U4-5851
2014-11-21 09:31:02 +11:00
Shannon Deminick 956a51ab67 Merge pull request #557 from AnthonyCogworks/umbUKFest-u4-5307
Issue U4-5307 - Added umb-editor css class to allow text box stretching.
2014-11-21 09:30:14 +11:00
Shannon Deminick e358d3b170 Merge pull request #555 from ismailmayat/umbUKFest-906
fix for u4-906
2014-11-21 09:20:08 +11:00
Shannon Deminick 752ce55cfa Merge pull request #551 from kristianschneider/UmbUkFest-5737
Fix for U4-5737 Create package: ContentType Tab index not saved
2014-11-21 08:55:30 +11:00
Shannon Deminick e6d6d3dd69 Merge pull request #545 from kristianschneider/UmbUKFest-5657
Fix for U4-5657 List view typo: "There are no items show in the list."
2014-11-21 08:19:43 +11:00
Lotte Pitcher dca14f3eb4 U4-5851 - Typo of 'seperate' when creating new MNTP data type : changed to 'separate' 2014-11-20 15:41:06 +00:00
Anthony Dang 1abdca2432 Issue U4-5307 - Added umb-editor css class to allow text box stretching. 2014-11-20 15:22:13 +00:00
Ismail Mayat 6db4fedcad some reason there is double quote escape which is not needed as peta poco handles any encoding 2014-11-20 15:12:34 +00:00
Kristian Schneider 3e66235932 amendment to U4-5737 Create package: ContentType Tab index not saved to ensure that the sortorder gets updated when importing doctypes 2014-11-20 14:23:47 +00:00
Kristian Schneider 1ab321c7b1 Fix for U4-5737 Create package: ContentType Tab index not saved 2014-11-20 14:04:13 +00:00
Chris Houston dffcf10032 Fixed ticket U4-4840 invalid Italian words in the Italian language file. 2014-11-20 12:44:41 +00:00
Chris Houston 054033c73f Updated the language files to fix issue #U4-3979 and also corrected invalid URL's across all the language files. 2014-11-20 12:24:49 +00:00
Kristian Schneider 4fcd23d8dc Fix for U4-5657 List view typo: "There are no items show in the list." 2014-11-20 12:04:54 +00:00
Shannon 209ccb9ae7 removes a MoveNext() call since we're no longer dealing with xdocuments and instead xelements 2014-11-19 11:49:13 +11:00
Shannon 2850c8aa05 Fixes build and fixes how published media cache gets root nodes - if people have done this in the past it would have been horrible for site performance 2014-11-19 11:35:37 +11:00
Shannon 87a9a57e6d Fixes media tests and updates how the IPublishedContent is created from the xpath iterator 2014-11-19 11:11:14 +11:00
Shannon f3f6504398 Working on: U4-5711 Media cache valueDictionary exception 2014-11-18 12:23:32 +11:00
Shannon c47d59a257 Fixes: U4-5820 List View showing content of complete site after deleting last page of data 2014-11-18 10:50:56 +11:00
Shannon d61d6008da Adds internal event for when a package is installed which gives access to the InstalledPackage instance which contains a PackageInstance reference that contains all of the files installed in the package 2014-11-17 18:00:51 +11:00
Sebastiaan Janssen 403f64eeed Only set comment to blank if there's command line arguments 2014-11-15 14:19:26 +01:00
Sebastiaan Janssen 5aa29cc150 Adds version comment to UmbracoVersion.txt and makes it possible to overrule by adding arguments to build.bat 2014-11-15 14:04:19 +01:00
Sebastiaan Janssen 9be3bdb8a5 Makes sure that the very first build on a fresh machine works immediately (previously you'd get an error saying that some NuGet packages were restored and you need to run the build again). 2014-11-15 13:14:40 +01:00
Sebastiaan Janssen c0baac2b38 Should fix the build for real now. Sets GenerateSerializationAssemblies to Off which then doesn't produce umbraco.XmlSerializers.dll any more.
Should be safe as this is only used for updatechecker and packageinstaller. From:  http://hashtagfail.com/post/5255977780/sgen-loaderexceptions-error - "Visual Studio attempts to generate a serialization assembly containing the types in your solution, to improve XmlSerializer serialization performance, should you choose to serialize your types."

Conflicts:
	build/NuSpecs/tools/install.core.ps1
2014-11-15 12:38:28 +01:00
Sebastiaan Janssen b20fc22577 U4-5814 Apply MVC 4.0.0.1 security update 2014-11-14 16:51:51 +01:00
Shannon 74ebf67aef updates the local storage sync, simplifies options and does more error checking in case sync cannot occur - which will default to normal storage. 2014-11-13 15:49:34 +11:00
Shannon 33036f80fe Fixes: U4-5789 Add native option to UmbracoExamine library to run the indexes locally 2014-11-13 14:01:13 +11:00
Shannon 0688550143 start integrating the local templ storage option for examine 2014-11-13 13:09:29 +11:00
Shannon d43b673092 Merge branch '7.1.9' of https://github.com/umbraco/Umbraco-CMS into 7.1.9 2014-11-13 13:06:53 +11:00
Shannon 4ec37b9d3a Fixes: U4-5391 Create config to explicitly set the 'base url' for a website that is not running as a load balanced site - used for scheduled tasks/publishing/keepalive 2014-11-13 13:05:27 +11:00
Sebastiaan Janssen 4eb0981552 Bump version 2014-11-12 14:28:13 +01:00
Sebastiaan Janssen ed8cc2ad0d Also fixes U4-5592 and U4-5746 for 7.1.9 2014-11-12 12:40:24 +01:00
Shannon 10bc7d0c1e Makes the section scanning and loading from the xml lazy so this no longer happens on startup but instead when sections are required, this ensures during startup there is no IO or scanning for sections, this should assist with U4-5126 config files get cleared out with zero size and of course also help a bunch with startup time. 2014-11-12 18:32:51 +11:00
Shannon aa11d3504d Makes the tree scanning and loading from the xml lazy so this no longer happens on startup but instead when trees are required, this ensures during startup there is no IO or scanning for trees, this should assist with U4-5126 config files get cleared out with zero size and of course also help a bunch with startup time. 2014-11-12 18:06:10 +11:00
Shannon 6903ebda1f even slightly better locking 2014-11-12 16:45:36 +11:00
Shannon 6c6e398c53 Fixes locking check on tree collection, will speed things up a little 2014-11-12 16:36:08 +11:00
Shannon bccb9655d0 Fixes: U4-5715 On startup when detecting if the db is configured we need to ensure it can also be connected to 2014-11-12 16:30:01 +11:00
Shannon dd143681f1 By default, changes all log output for NH to be Warn 2014-11-12 16:02:02 +11:00
Shannon b1d4a99510 U4-5728 - Do not run KeepAlive, ScheduledPublishing, without an url
Updates the scheduler and the scheduled tasks to use a background task runner (ported from new courier codebase with tests) so that they are web aware and wind down properly.
2014-11-12 16:00:17 +11:00
113 changed files with 5023 additions and 2962 deletions
+1
View File
@@ -110,3 +110,4 @@ src/Umbraco.Web.UI/umbraco/js/init.js
build/ApiDocs/*
build/ApiDocs/Output/*
src/Umbraco.Web.UI.Client/bower_components/*
src/umbraco.sln.ide
+29 -16
View File
@@ -2,9 +2,18 @@
IF NOT EXIST UmbracoVersion.txt (
ECHO UmbracoVersion.txt missing!
GOTO :showerror
)
SET /p release=<UmbracoVersion.txt
SET comment=
)
REM Get the version and comment from UmbracoVersion.txt lines 2 and 3
SET "release="
SET "comment="
FOR /F "skip=1 delims=" %%i IN (UmbracoVersion.txt) DO IF NOT DEFINED release SET "release=%%i"
FOR /F "skip=2 delims=" %%i IN (UmbracoVersion.txt) DO IF NOT DEFINED comment SET "comment=%%i"
REM If there's arguments on the command line overrule UmbracoVersion.txt and use that as the version
IF [%1] NEQ [] (SET release=%1)
IF [%2] NEQ [] (SET comment=%2) ELSE (IF [%1] NEQ [] (SET "comment="))
SET version=%release%
IF [%comment%] EQU [] (SET version=%release%) ELSE (SET version=%release%-%comment%)
@@ -14,8 +23,11 @@ ReplaceIISExpressPortNumber.exe ..\src\Umbraco.Web.UI\Umbraco.Web.UI.csproj %rel
ECHO Installing the Microsoft.Bcl.Build package before anything else, otherwise you'd have to run build.cmd twice
SET nuGetFolder=%CD%\..\src\packages\
..\src\.nuget\NuGet.exe sources Remove -Name MyGetUmbracoCore
..\src\.nuget\NuGet.exe sources Add -Name MyGetUmbracoCore -Source https://www.myget.org/F/umbracocore/api/v2/
..\src\.nuget\NuGet.exe install ..\src\Umbraco.Web.UI\packages.config -OutputDirectory %nuGetFolder%
..\src\.nuget\NuGet.exe install ..\src\umbraco.businesslogic\packages.config -OutputDirectory %nuGetFolder%
..\src\.nuget\NuGet.exe install ..\src\Umbraco.Core\packages.config -OutputDirectory %nuGetFolder%
ECHO Removing the belle build folder to make sure everything is clean as a whistle
RD ..\src\Umbraco.Web.UI.Client\build /Q /S
@@ -30,21 +42,22 @@ ECHO Performing MSBuild and producing Umbraco binaries zip files
%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe "Build.proj" /p:BUILD_RELEASE=%release% /p:BUILD_COMMENT=%comment%
ECHO Adding dummy files to include in the NuGet package so that empty folders actually get created
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\App_Code\dummy.txt
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\App_Data\dummy.txt
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\App_Plugins\dummy.txt
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\css\dummy.txt
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\masterpages\dummy.txt
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\media\dummy.txt
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\scripts\dummy.txt
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\usercontrols\dummy.txt
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\Views\Partials\dummy.txt
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\Views\MacroPartials\dummy.txt
SET dummytext=This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete.
ECHO %dummytext% > .\_BuildOutput\WebApp\App_Code\dummy.txt
ECHO %dummytext% > .\_BuildOutput\WebApp\App_Data\dummy.txt
ECHO %dummytext% > .\_BuildOutput\WebApp\App_Plugins\dummy.txt
ECHO %dummytext% > .\_BuildOutput\WebApp\css\dummy.txt
ECHO %dummytext% > .\_BuildOutput\WebApp\masterpages\dummy.txt
ECHO %dummytext% > .\_BuildOutput\WebApp\media\dummy.txt
ECHO %dummytext% > .\_BuildOutput\WebApp\scripts\dummy.txt
ECHO %dummytext% > .\_BuildOutput\WebApp\usercontrols\dummy.txt
ECHO %dummytext% > .\_BuildOutput\WebApp\Views\Partials\dummy.txt
ECHO %dummytext% > .\_BuildOutput\WebApp\Views\MacroPartials\dummy.txt
ECHO Adding Web.config transform files to the NuGet package
ren .\_BuildOutput\WebApp\MacroScripts\Web.config Web.config.transform
ren .\_BuildOutput\WebApp\Views\Web.config Web.config.transform
ren .\_BuildOutput\WebApp\Xslt\Web.config Web.config.transform
REN .\_BuildOutput\WebApp\MacroScripts\Web.config Web.config.transform
REN .\_BuildOutput\WebApp\Views\Web.config Web.config.transform
REN .\_BuildOutput\WebApp\Xslt\Web.config Web.config.transform
ECHO Packing the NuGet release files
..\src\.nuget\NuGet.exe Pack NuSpecs\UmbracoCms.Core.nuspec -Version %version%
-3
View File
@@ -252,14 +252,11 @@
</Target>
<!-- Unlike 2010, the VS2012 build targets file doesn't clean up the umbraco.presentation dir, do it manually -->
<!-- Also, it places umbraco.XmlSerializers.dll in the root, even though it's also in the bin folder. Kill! -->
<Target Name="CleanupPresentation" DependsOnTargets="CompileProjects">
<ItemGroup>
<PresentationFolderToDelete Include="$(WebAppFolder)umbraco.presentation" />
<XmlSerializersDll Include="$(WebAppFolder)umbraco.XmlSerializers.dll" />
</ItemGroup>
<RemoveDir Directories="@(PresentationFolderToDelete)" />
<Delete Files="@(XmlSerializersDll)" />
</Target>
<Target Name="CompileProjects" DependsOnTargets="CompileExternalExamineProjects">
+2 -3
View File
@@ -33,8 +33,8 @@
<dependency id="AutoMapper" version="[3.0.0, 4.0.0)" />
<dependency id="Newtonsoft.Json" version="[6.0.4, 7.0.0)" />
<dependency id="Examine" version="[0.1.57, 1.0.0)" />
<dependency id="ImageProcessor" version="[1.9.5, 2.0.0)" />
<dependency id="ImageProcessor.Web" version="[3.3.0, 4.0.0)" />
<dependency id="ImageProcessor" version="[1.9.5, 3.0.0)" />
<dependency id="ImageProcessor.Web" version="[3.3.1, 5.0.0)" />
</dependencies>
</metadata>
<files>
@@ -66,7 +66,6 @@
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.dll" target="lib\umbraco.providers.dll" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.xml" target="lib\umbraco.providers.xml" />
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Web.UI.dll" target="lib\Umbraco.Web.UI.dll" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.XmlSerializers.dll" target="lib\umbraco.XmlSerializers.dll" />
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.dll" target="lib\UmbracoExamine.dll" />
<file src="..\_BuildOutput\WebApp\bin\UrlRewritingNet.UrlRewriter.dll" target="lib\UrlRewritingNet.UrlRewriter.dll" />
<file src="tools\install.core.ps1" target="tools\install.ps1" />
+54 -2
View File
@@ -10,7 +10,7 @@ if ($project) {
New-Item -ItemType Directory -Force -Path $backupPath
New-Item -ItemType Directory -Force -Path $copyLogsPath
# After backing up, remove all dlls from bin folder in case dll files are included in the VS project
# After backing up, remove all umbraco dlls from bin folder in case dll files are included in the VS project
# See: http://issues.umbraco.org/issue/U4-4930
$umbracoBinFolder = Join-Path $projectDestinationPath "bin"
if(Test-Path $umbracoBinFolder) {
@@ -19,6 +19,58 @@ if ($project) {
New-Item -ItemType Directory -Force -Path $umbracoBinBackupPath
robocopy $umbracoBinFolder $umbracoBinBackupPath /e /LOG:$copyLogsPath\UmbracoBinBackup.log
Remove-Item $umbracoBinFolder\*.dll -Force -Confirm:$false
# Delete files Umbraco brings in
if(Test-Path $umbracoBinFolder\businesslogic.dll) { Remove-Item $umbracoBinFolder\businesslogic.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\cms.dll) { Remove-Item $umbracoBinFolder\cms.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\controls.dll) { Remove-Item $umbracoBinFolder\controls.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\interfaces.dll) { Remove-Item $umbracoBinFolder\interfaces.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\log4net.dll) { Remove-Item $umbracoBinFolder\log4net.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Microsoft.ApplicationBlocks.Data.dll) { Remove-Item $umbracoBinFolder\Microsoft.ApplicationBlocks.Data.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Microsoft.Web.Helpers.dll) { Remove-Item $umbracoBinFolder\Microsoft.Web.Helpers.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\SQLCE4Umbraco.dll) { Remove-Item $umbracoBinFolder\SQLCE4Umbraco.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\System.Data.SqlServerCe.dll) { Remove-Item $umbracoBinFolder\System.Data.SqlServerCe.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\System.Data.SqlServerCe.Entity.dll) { Remove-Item $umbracoBinFolder\System.Data.SqlServerCe.Entity.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\TidyNet.dll) { Remove-Item $umbracoBinFolder\TidyNet.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\umbraco.dll) { Remove-Item $umbracoBinFolder\umbraco.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Umbraco.Core.dll) { Remove-Item $umbracoBinFolder\Umbraco.Core.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\umbraco.DataLayer.dll) { Remove-Item $umbracoBinFolder\umbraco.DataLayer.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\umbraco.editorControls.dll) { Remove-Item $umbracoBinFolder\umbraco.editorControls.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\umbraco.MacroEngines.dll) { Remove-Item $umbracoBinFolder\umbraco.MacroEngines.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\umbraco.providers.dll) { Remove-Item $umbracoBinFolder\umbraco.providers.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Umbraco.Web.UI.dll) { Remove-Item $umbracoBinFolder\Umbraco.Web.UI.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\UmbracoExamine.dll) { Remove-Item $umbracoBinFolder\UmbracoExamine.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\UrlRewritingNet.UrlRewriter.dll) { Remove-Item $umbracoBinFolder\UrlRewritingNet.UrlRewriter.dll -Force -Confirm:$false }
# Delete files Umbraco depends upon
$amd64Folder = Join-Path $projectDestinationPath "bin\amd64"
if(Test-Path $amd64Folder) { Remove-Item $amd64Folder -Force -Recurse -Confirm:$false }
$x86Folder = Join-Path $projectDestinationPath "bin\x86"
if(Test-Path $x86Folder) { Remove-Item $x86Folder -Force -Recurse -Confirm:$false }
if(Test-Path $umbracoBinFolder\AutoMapper.dll) { Remove-Item $umbracoBinFolder\AutoMapper.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\AutoMapper.Net4.dll) { Remove-Item $umbracoBinFolder\AutoMapper.Net4.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\ClientDependency.Core.dll) { Remove-Item $umbracoBinFolder\ClientDependency.Core.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\ClientDependency.Core.Mvc.dll) { Remove-Item $umbracoBinFolder\ClientDependency.Core.Mvc.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\CookComputing.XmlRpcV2.dll) { Remove-Item $umbracoBinFolder\CookComputing.XmlRpcV2.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Examine.dll) { Remove-Item $umbracoBinFolder\Examine.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\HtmlAgilityPack.dll) { Remove-Item $umbracoBinFolder\HtmlAgilityPack.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\ICSharpCode.SharpZipLib.dll) { Remove-Item $umbracoBinFolder\ICSharpCode.SharpZipLib.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\ImageProcessor.dll) { Remove-Item $umbracoBinFolder\ImageProcessor.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\ImageProcessor.Web.dll) { Remove-Item $umbracoBinFolder\ImageProcessor.Web.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Lucene.Net.dll) { Remove-Item $umbracoBinFolder\Lucene.Net.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Microsoft.Web.Infrastructure.dll) { Remove-Item $umbracoBinFolder\Microsoft.Web.Infrastructure.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Microsoft.Web.Mvc.FixedDisplayModes.dll) { Remove-Item $umbracoBinFolder\Microsoft.Web.Mvc.FixedDisplayModes.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\MiniProfiler.dll) { Remove-Item $umbracoBinFolder\MiniProfiler.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\MySql.Data.dll) { Remove-Item $umbracoBinFolder\MySql.Data.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Newtonsoft.Json.dll) { Remove-Item $umbracoBinFolder\Newtonsoft.Json.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\System.Net.Http.Formatting.dll) { Remove-Item $umbracoBinFolder\System.Net.Http.Formatting.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\System.Web.Helpers.dll) { Remove-Item $umbracoBinFolder\System.Web.Helpers.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\System.Web.Http.dll) { Remove-Item $umbracoBinFolder\System.Web.Http.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\System.Web.Http.WebHost.dll) { Remove-Item $umbracoBinFolder\System.Web.Http.WebHost.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\System.Web.Mvc.dll) { Remove-Item $umbracoBinFolder\System.Web.Mvc.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\System.Web.Razor.dll) { Remove-Item $umbracoBinFolder\System.Web.Razor.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\System.Web.WebPages.dll) { Remove-Item $umbracoBinFolder\System.Web.WebPages.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\System.Web.WebPages.Deployment.dll) { Remove-Item $umbracoBinFolder\System.Web.WebPages.Deployment.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\System.Web.WebPages.Razor.dll) { Remove-Item $umbracoBinFolder\System.Web.WebPages.Razor.dll -Force -Confirm:$false }
}
}
+2 -1
View File
@@ -1 +1,2 @@
7.1.8
# Usage: on line 2 put the release version, on line 3 put the version comment (example: beta)
7.1.9
+10
View File
@@ -229,5 +229,15 @@ namespace SqlCE4Umbraco
return new SqlCeDataReaderHelper(SqlCeApplicationBlock.ExecuteReader(ConnectionString, CommandType.Text,
commandText, parameters));
}
internal IRecordsReader ExecuteReader(string commandText)
{
return ExecuteReader(commandText, new SqlCEParameter(string.Empty, string.Empty));
}
internal int ExecuteNonQuery(string commandText)
{
return ExecuteNonQuery(commandText, new SqlCEParameter(string.Empty, string.Empty));
}
}
}
+2 -2
View File
@@ -74,7 +74,7 @@ namespace Umbraco.Core
/// <returns></returns>
private bool ShouldExecute(ApplicationContext applicationContext)
{
if (applicationContext.IsConfigured && applicationContext.DatabaseContext.IsDatabaseConfigured)
if (applicationContext.IsConfigured && applicationContext.DatabaseContext.CanConnect)
{
return true;
}
@@ -84,7 +84,7 @@ namespace Umbraco.Core
return true;
}
if (!applicationContext.DatabaseContext.IsDatabaseConfigured && ExecuteWhenDatabaseNotConfigured)
if (!applicationContext.DatabaseContext.CanConnect && ExecuteWhenDatabaseNotConfigured)
{
return true;
}
@@ -5,5 +5,7 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
public interface IScheduledTasksSection : IUmbracoConfigurationSection
{
IEnumerable<IScheduledTask> Tasks { get; }
string BaseUrl { get; }
}
}
@@ -16,5 +16,11 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
{
get { return Tasks; }
}
[ConfigurationProperty("baseUrl", IsRequired = false, DefaultValue = null)]
public string BaseUrl
{
get { return (string)base["baseUrl"]; }
}
}
}
@@ -5,7 +5,7 @@ namespace Umbraco.Core.Configuration
{
public class UmbracoVersion
{
private static readonly Version Version = new Version("7.1.8");
private static readonly Version Version = new Version("7.1.9");
/// <summary>
/// Gets the current version of Umbraco.
+29
View File
@@ -26,6 +26,9 @@ namespace Umbraco.Core
{
private readonly IDatabaseFactory _factory;
private bool _configured;
private bool _canConnect;
private volatile bool _connectCheck = false;
private readonly object _locker = new object();
private string _connectionString;
private string _providerName;
private DatabaseSchemaResult _result;
@@ -56,6 +59,32 @@ namespace Umbraco.Core
get { return _configured; }
}
/// <summary>
/// Determines if the db can be connected to
/// </summary>
public bool CanConnect
{
get
{
if (IsDatabaseConfigured == false) return false;
//double check lock so that it is only checked once and is fast
if (_connectCheck == false)
{
lock (_locker)
{
if (_canConnect == false)
{
_canConnect = DbConnectionExtensions.IsConnectionAvailable(ConnectionString, DatabaseProvider);
_connectCheck = true;
}
}
}
return _canConnect;
}
}
/// <summary>
/// Gets the configured umbraco db connection string.
/// </summary>
@@ -75,7 +75,7 @@ namespace Umbraco.Core.Persistence
connection.Open();
connection.Close();
}
catch (SqlException)
catch (DbException)
{
return false;
}
@@ -694,7 +694,10 @@ namespace Umbraco.Core.Persistence.Repositories
IEnumerable<IContent> result;
var pagedResult = Database.Page<DocumentDto>(pageNumber, pageSize, modifiedSQL, sql.Arguments);
totalRecords = Convert.ToInt32(pagedResult.TotalItems);
if (totalRecords > 0)
//NOTE: We need to check the actual items returned, not the 'totalRecords', that is because if you request a page number
// that doesn't actually have any data on it, the totalRecords will still indicate there are records but there are none in
// the pageResult, then the GetAll will actually return ALL records in the db.
if (pagedResult.Items.Any())
{
// Parse out node Ids and load content (we need the cast here in order to be able to call the IQueryable extension
// methods OrderBy or OrderByDescending)
@@ -8,6 +8,7 @@ using Umbraco.Core.Events;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Cache;
using File = System.IO.File;
namespace Umbraco.Core.Services
@@ -15,15 +16,18 @@ namespace Umbraco.Core.Services
internal class ApplicationTreeService : IApplicationTreeService
{
private readonly CacheHelper _cache;
private IEnumerable<ApplicationTree> _allAvailableTrees;
private volatile bool _isInitialized = false;
internal const string TreeConfigFileName = "trees.config";
private static string _treeConfig;
private static readonly object Locker = new object();
public ApplicationTreeService(CacheHelper cache)
{
_cache = cache;
}
internal const string TreeConfigFileName = "trees.config";
private static string _treeConfig;
private static readonly object Locker = new object();
/// <summary>
/// gets/sets the trees.config file path
@@ -45,74 +49,101 @@ namespace Umbraco.Core.Services
}
/// <summary>
/// The cache storage for all application trees
/// The main entry point to get application trees
/// </summary>
/// <remarks>
/// This lazily on first access will scan for plugin trees and ensure the trees.config is up-to-date with the plugins. If plugins
/// haven't changed on disk then the file will not be saved. The trees are all then loaded from this config file into cache and returned.
/// </remarks>
private List<ApplicationTree> GetAppTrees()
{
return _cache.GetCacheItem(
return _cache.RuntimeCache.GetCacheItem<List<ApplicationTree>>(
CacheKeys.ApplicationTreeCacheKey,
() =>
{
var list = ReadFromXmlAndSort();
//On first access we need to do some initialization
if (_isInitialized == false)
{
var list = new List<ApplicationTree>();
LoadXml(doc =>
lock (Locker)
{
if (_isInitialized == false)
{
foreach (var addElement in doc.Root.Elements("add").OrderBy(x =>
{
var sortOrderAttr = x.Attribute("sortOrder");
return sortOrderAttr != null ? Convert.ToInt32(sortOrderAttr.Value) : 0;
}))
//now we can check the non-volatile flag
if (_allAvailableTrees != null)
{
var applicationAlias = (string) addElement.Attribute("application");
var type = (string) addElement.Attribute("type");
var assembly = (string) addElement.Attribute("assembly");
var hasChanges = false;
var clrType = Type.GetType(type);
if (clrType == null)
LoadXml(doc =>
{
LogHelper.Warn<ApplicationTreeService>("The tree definition: " + addElement.ToString() + " could not be resolved to a .Net object type");
continue;
}
//Now, load in the xml structure and update it with anything that is not declared there and save the file.
//check if the tree definition (applicationAlias + type + assembly) is already in the list
//NOTE: On the first iteration here, it will lazily scan all trees, etc... this is because this ienumerable is lazy
// based on the ApplicationTreeRegistrar - and as noted there this is not an ideal way to do things but were stuck like this
// currently because of the legacy assemblies and types not in the Core.
if (list.Any(tree => tree.ApplicationAlias.InvariantEquals(applicationAlias) && tree.GetRuntimeType() == clrType) == false)
//Get all the trees not registered in the config
var unregistered = _allAvailableTrees
.Where(x => list.Any(l => l.Alias == x.Alias) == false)
.ToArray();
hasChanges = unregistered.Any();
if (hasChanges == false) return false;
//add the unregistered ones to the list and re-save the file if any changes were found
var count = 0;
foreach (var tree in unregistered)
{
doc.Root.Add(new XElement("add",
new XAttribute("initialize", tree.Initialize),
new XAttribute("sortOrder", tree.SortOrder),
new XAttribute("alias", tree.Alias),
new XAttribute("application", tree.ApplicationAlias),
new XAttribute("title", tree.Title),
new XAttribute("iconClosed", tree.IconClosed),
new XAttribute("iconOpen", tree.IconOpened),
new XAttribute("type", tree.Type)));
count++;
}
//don't save if there's no changes
return count > 0;
}, true);
if (hasChanges)
{
list.Add(new ApplicationTree(
addElement.Attribute("initialize") == null || Convert.ToBoolean(addElement.Attribute("initialize").Value),
addElement.Attribute("sortOrder") != null ? Convert.ToByte(addElement.Attribute("sortOrder").Value) : (byte) 0,
addElement.Attribute("application").Value,
addElement.Attribute("alias").Value,
addElement.Attribute("title").Value,
addElement.Attribute("iconClosed").Value,
addElement.Attribute("iconOpen").Value,
addElement.Attribute("type").Value));
//If there were changes, we need to re-read the structures from the XML
list = ReadFromXmlAndSort();
}
}
}, false);
return list;
});
_isInitialized = true;
}
}
}
return list;
});
}
public void Intitialize(IEnumerable<ApplicationTree> existingTrees)
/// <summary>
/// Initializes the service with any trees found in plugins
/// </summary>
/// <param name="allAvailableTrees">
/// A collection of all available tree found in assemblies in the application
/// </param>
/// <remarks>
/// This will update the trees.config with the found tree plugins that are not currently listed in the file when the first
/// access is made to resolve the tree collection
/// </remarks>
public void Intitialize(IEnumerable<ApplicationTree> allAvailableTrees)
{
LoadXml(doc =>
{
foreach (var tree in existingTrees)
{
doc.Root.Add(new XElement("add",
new XAttribute("initialize", tree.Initialize),
new XAttribute("sortOrder", tree.SortOrder),
new XAttribute("alias", tree.Alias),
new XAttribute("application", tree.ApplicationAlias),
new XAttribute("title", tree.Title),
new XAttribute("iconClosed", tree.IconClosed),
new XAttribute("iconOpen", tree.IconOpened),
new XAttribute("type", tree.Type)));
}
}, true);
_allAvailableTrees = allAvailableTrees;
}
/// <summary>
@@ -134,16 +165,19 @@ namespace Umbraco.Core.Services
if (el == null)
{
doc.Root.Add(new XElement("add",
new XAttribute("initialize", initialize),
new XAttribute("sortOrder", sortOrder),
new XAttribute("alias", alias),
new XAttribute("application", applicationAlias),
new XAttribute("title", title),
new XAttribute("iconClosed", iconClosed),
new XAttribute("iconOpen", iconOpened),
new XAttribute("type", type)));
doc.Root.Add(new XElement("add",
new XAttribute("initialize", initialize),
new XAttribute("sortOrder", sortOrder),
new XAttribute("alias", alias),
new XAttribute("application", applicationAlias),
new XAttribute("title", title),
new XAttribute("iconClosed", iconClosed),
new XAttribute("iconOpen", iconOpened),
new XAttribute("type", type)));
}
return true;
}, true);
OnNew(new ApplicationTree(initialize, sortOrder, applicationAlias, alias, title, iconClosed, iconOpened, type), new EventArgs());
@@ -161,7 +195,7 @@ namespace Umbraco.Core.Services
if (el != null)
{
el.RemoveAttributes();
el.Add(new XAttribute("initialize", tree.Initialize));
el.Add(new XAttribute("sortOrder", tree.SortOrder));
el.Add(new XAttribute("alias", tree.Alias));
@@ -172,6 +206,8 @@ namespace Umbraco.Core.Services
el.Add(new XAttribute("type", tree.Type));
}
return true;
}, true);
OnUpdated(tree, new EventArgs());
@@ -181,11 +217,16 @@ namespace Umbraco.Core.Services
/// Deletes this instance.
/// </summary>
public void DeleteTree(ApplicationTree tree)
{
{
LoadXml(doc =>
{
doc.Root.Elements("add").Where(x => x.Attribute("application") != null && x.Attribute("application").Value == tree.ApplicationAlias &&
x.Attribute("alias") != null && x.Attribute("alias").Value == tree.Alias).Remove();
doc.Root.Elements("add")
.Where(x => x.Attribute("application") != null
&& x.Attribute("application").Value == tree.ApplicationAlias
&& x.Attribute("alias") != null && x.Attribute("alias").Value == tree.Alias).Remove();
return true;
}, true);
OnDeleted(tree, new EventArgs());
@@ -231,31 +272,44 @@ namespace Umbraco.Core.Services
{
var list = GetAppTrees().FindAll(
t =>
{
if (onlyInitialized)
return (t.ApplicationAlias == applicationAlias && t.Initialize);
return (t.ApplicationAlias == applicationAlias);
}
{
if (onlyInitialized)
return (t.ApplicationAlias == applicationAlias && t.Initialize);
return (t.ApplicationAlias == applicationAlias);
}
);
return list.OrderBy(x => x.SortOrder).ToArray();
}
internal void LoadXml(Action<XDocument> callback, bool saveAfterCallback)
/// <summary>
/// Loads in the xml structure from disk if one is found, otherwise loads in an empty xml structure, calls the
/// callback with the xml document and saves the structure back to disk if saveAfterCallback is true.
/// </summary>
/// <param name="callback"></param>
/// <param name="saveAfterCallbackIfChanges"></param>
internal void LoadXml(Func<XDocument, bool> callback, bool saveAfterCallbackIfChanges)
{
lock (Locker)
{
var doc = File.Exists(TreeConfigFilePath)
? XDocument.Load(TreeConfigFilePath)
: XDocument.Parse("<?xml version=\"1.0\"?><trees />");
if (doc.Root != null)
{
callback.Invoke(doc);
var hasChanges = callback.Invoke(doc);
if (saveAfterCallback)
if (saveAfterCallbackIfChanges && hasChanges
//Don't save it if it is empty, in some very rare cases if the app domain get's killed in the middle of this process
// in some insane way the file saved will be empty. I'm pretty sure it's not actually anything to do with the xml doc and
// more about the IO trying to save the XML doc, but it doesn't hurt to check.
&& doc.Root != null && doc.Root.Elements().Any())
{
//ensures the folder exists
Directory.CreateDirectory(Path.GetDirectoryName(TreeConfigFilePath));
//saves it
doc.Save(TreeConfigFilePath);
//remove the cache now that it has changed SD: I'm leaving this here even though it
@@ -266,6 +320,54 @@ namespace Umbraco.Core.Services
}
}
private List<ApplicationTree> ReadFromXmlAndSort()
{
var list = new List<ApplicationTree>();
//read in the xml file containing trees and convert them all to ApplicationTree instances
LoadXml(doc =>
{
foreach (var addElement in doc.Root.Elements("add").OrderBy(x =>
{
var sortOrderAttr = x.Attribute("sortOrder");
return sortOrderAttr != null ? Convert.ToInt32(sortOrderAttr.Value) : 0;
}))
{
var applicationAlias = (string)addElement.Attribute("application");
var type = (string)addElement.Attribute("type");
var assembly = (string)addElement.Attribute("assembly");
var clrType = Type.GetType(type);
if (clrType == null)
{
LogHelper.Warn<ApplicationTreeService>("The tree definition: " + addElement.ToString() + " could not be resolved to a .Net object type");
continue;
}
//check if the tree definition (applicationAlias + type + assembly) is already in the list
if (list.Any(tree => tree.ApplicationAlias.InvariantEquals(applicationAlias) && tree.GetRuntimeType() == clrType) == false)
{
list.Add(new ApplicationTree(
addElement.Attribute("initialize") == null || Convert.ToBoolean(addElement.Attribute("initialize").Value),
addElement.Attribute("sortOrder") != null ? Convert.ToByte(addElement.Attribute("sortOrder").Value) : (byte)0,
addElement.Attribute("application").Value,
addElement.Attribute("alias").Value,
addElement.Attribute("title").Value,
addElement.Attribute("iconClosed").Value,
addElement.Attribute("iconOpen").Value,
addElement.Attribute("type").Value));
}
}
return false;
}, false);
return list;
}
internal static event TypedEventHandler<ApplicationTree, EventArgs> Deleted;
private static void OnDeleted(ApplicationTree app, EventArgs args)
{
@@ -248,7 +248,9 @@ namespace Umbraco.Core.Services
{
var tab = new XElement("Tab",
new XElement("Id", propertyGroup.Id.ToString(CultureInfo.InvariantCulture)),
new XElement("Caption", propertyGroup.Name));
new XElement("Caption", propertyGroup.Name),
new XElement("SortOrder", propertyGroup.SortOrder));
tabs.Add(tab);
}
@@ -354,7 +356,8 @@ namespace Umbraco.Core.Services
{
var tab = new XElement("Tab",
new XElement("Id", propertyGroup.Id.ToString(CultureInfo.InvariantCulture)),
new XElement("Caption", propertyGroup.Name));
new XElement("Caption", propertyGroup.Name),
new XElement("SortOrder", propertyGroup.SortOrder));
tabs.Add(tab);
}
@@ -5,7 +5,17 @@ namespace Umbraco.Core.Services
{
public interface IApplicationTreeService
{
void Intitialize(IEnumerable<ApplicationTree> existingTrees);
/// <summary>
/// Initializes the service with any trees found in plugins
/// </summary>
/// <param name="allAvailableTrees">
/// A collection of all available tree found in assemblies in the application
/// </param>
/// <remarks>
/// This will update the trees.config with the found tree plugins that are not currently listed in the file when the first
/// access is made to resolve the tree collection
/// </remarks>
void Intitialize(IEnumerable<ApplicationTree> allAvailableTrees);
/// <summary>
/// Creates a new application tree.
+8 -3
View File
@@ -6,10 +6,15 @@ namespace Umbraco.Core.Services
public interface ISectionService
{
/// <summary>
/// Ensures all available sections exist in the storage medium
/// Initializes the service with all available application plugins
/// </summary>
/// <param name="existingSections"></param>
void Initialize(IEnumerable<Section> existingSections);
/// <param name="allAvailableSections">
/// All application plugins found in assemblies
/// </param>
/// <remarks>
/// This is used to populate the app.config file with any applications declared in plugins that don't exist in the file
/// </remarks>
void Initialize(IEnumerable<Section> allAvailableSections);
/// <summary>
/// The cache storage for all applications
+31 -31
View File
@@ -74,7 +74,7 @@ namespace Umbraco.Core.Services
public XElement Export(IContent content, bool deep = false, bool raiseEvents = true)
{
var nodeName = UmbracoConfig.For.UmbracoSettings().Content.UseLegacyXmlSchema ? "node" : content.ContentType.Alias.ToSafeAliasWithForcingCheck();
if (raiseEvents)
{
if (ExportingContent.IsRaisedEventCancelled(new ExportEventArgs<IContent>(content, nodeName), this))
@@ -84,13 +84,13 @@ namespace Umbraco.Core.Services
var exporter = new EntityXmlSerializer();
var xml = exporter.Serialize(_contentService, _dataTypeService, content, deep);
if(raiseEvents)
if (raiseEvents)
ExportedContent.RaiseEvent(new ExportEventArgs<IContent>(content, xml, false), this);
return xml;
}
/// <summary>
/// Imports and saves package xml as <see cref="IContent"/>
@@ -107,7 +107,7 @@ namespace Umbraco.Core.Services
if (ImportingContent.IsRaisedEventCancelled(new ImportEventArgs<IContent>(element), this))
return Enumerable.Empty<IContent>();
}
var name = element.Name.LocalName;
if (name.Equals("DocumentSet"))
{
@@ -120,7 +120,7 @@ namespace Umbraco.Core.Services
if (contents.Any())
_contentService.Save(contents, userId);
if(raiseEvents)
if (raiseEvents)
ImportedContent.RaiseEvent(new ImportEventArgs<IContent>(contents, element, false), this);
return contents;
}
@@ -134,7 +134,7 @@ namespace Umbraco.Core.Services
if (contents.Any())
_contentService.Save(contents, userId);
if(raiseEvents)
if (raiseEvents)
ImportedContent.RaiseEvent(new ImportEventArgs<IContent>(contents, element, false), this);
return contents;
}
@@ -248,7 +248,7 @@ namespace Umbraco.Core.Services
//TODO: We need to refactor this so the packager isn't making direct db calls for an 'edge' case
var database = ApplicationContext.Current.DatabaseContext.Database;
var dtos = database.Fetch<DataTypePreValueDto>("WHERE datatypeNodeId = @Id", new {Id = propertyType.DataTypeDefinitionId});
var dtos = database.Fetch<DataTypePreValueDto>("WHERE datatypeNodeId = @Id", new { Id = propertyType.DataTypeDefinitionId });
var propertyValueList = new List<string>();
foreach (var preValue in propertyValue.Split(','))
@@ -261,7 +261,7 @@ namespace Umbraco.Core.Services
}
//set property value
content.SetValue(propertyTypeAlias, propertyValue);
content.SetValue(propertyTypeAlias, propertyValue);
}
}
}
@@ -491,13 +491,13 @@ namespace Umbraco.Core.Services
{
contentType.AddPropertyGroup(caption);
int sortOrder;
if(tab.Element("SortOrder") != null &&
int.TryParse(tab.Element("SortOrder").Value, out sortOrder))
{
// Override the sort order with the imported value
contentType.PropertyGroups[caption].SortOrder = sortOrder;
}
}
int sortOrder;
if (tab.Element("SortOrder") != null && int.TryParse(tab.Element("SortOrder").Value, out sortOrder))
{
// Override the sort order with the imported value
contentType.PropertyGroups[caption].SortOrder = sortOrder;
}
}
}
@@ -549,7 +549,7 @@ namespace Umbraco.Core.Services
dataTypeDefinition = dataTypeDefinitions.First();
}
}
// For backwards compatibility, if no datatype with that ID can be found, we're letting this fail silently.
// This means that the property will not be created.
if (dataTypeDefinition == null)
@@ -786,15 +786,15 @@ namespace Umbraco.Core.Services
var dataTypeDefinition = dataTypes.First(x => x.Name == dataTypeDefinitionName);
var valuesWithoutKeys = prevaluesElement.Elements("PreValue")
.Where(x => ((string) x.Attribute("Alias")).IsNullOrWhiteSpace())
.Where(x => ((string)x.Attribute("Alias")).IsNullOrWhiteSpace())
.Select(x => x.Attribute("Value").Value);
var valuesWithKeys = prevaluesElement.Elements("PreValue")
.Where(x => ((string) x.Attribute("Alias")).IsNullOrWhiteSpace() == false)
.Where(x => ((string)x.Attribute("Alias")).IsNullOrWhiteSpace() == false)
.ToDictionary(
key => (string) key.Attribute("Alias"),
val => new PreValue((string) val.Attribute("Value")));
key => (string)key.Attribute("Alias"),
val => new PreValue((string)val.Attribute("Value")));
//save the values with keys
_dataTypeService.SavePreValues(dataTypeDefinition, valuesWithKeys);
@@ -841,7 +841,7 @@ namespace Umbraco.Core.Services
var exporter = new EntityXmlSerializer();
var xml = exporter.Serialize(dictionaryItem);
if (includeChildren)
{
var children = _localizationService.GetDictionaryItemChildren(dictionaryItem.Key);
@@ -1115,7 +1115,7 @@ namespace Umbraco.Core.Services
dontRender = bool.Parse(dontRenderElement.Value);
}
var existingMacro = _macroService.GetByAlias(macroAlias) as Macro;
var existingMacro = _macroService.GetByAlias(macroAlias) as Macro;
var macro = existingMacro ?? new Macro(macroAlias, macroName, controlType, controlAssembly, xsltPath, scriptPath,
cacheByPage, cacheByMember, dontRender, useInEditor, cacheDuration);
@@ -1210,7 +1210,7 @@ namespace Umbraco.Core.Services
public XElement Export(IMedia media, bool deep = false, bool raiseEvents = true)
{
var nodeName = UmbracoConfig.For.UmbracoSettings().Content.UseLegacyXmlSchema ? "node" : media.ContentType.Alias.ToSafeAliasWithForcingCheck();
if (raiseEvents)
{
if (ExportingMedia.IsRaisedEventCancelled(new ExportEventArgs<IMedia>(media, nodeName), this))
@@ -1220,7 +1220,7 @@ namespace Umbraco.Core.Services
var exporter = new EntityXmlSerializer();
var xml = exporter.Serialize(_mediaService, _dataTypeService, media, deep);
if(raiseEvents)
if (raiseEvents)
ExportedMedia.RaiseEvent(new ExportEventArgs<IMedia>(media, xml, false), this);
return xml;
@@ -1334,7 +1334,7 @@ namespace Umbraco.Core.Services
if (templates.Any())
_fileService.SaveTemplate(templates, userId);
if(raiseEvents)
if (raiseEvents)
ImportedTemplate.RaiseEvent(new ImportEventArgs<ITemplate>(templates, element, false), this);
return templates;
@@ -1352,10 +1352,10 @@ namespace Umbraco.Core.Services
IEnumerable<IFile> styleSheets = Enumerable.Empty<IFile>();
if(element.Elements().Any())
if (element.Elements().Any())
throw new NotImplementedException("This needs to be implimentet");
if (raiseEvents)
ImportingStylesheets.RaiseEvent(new ImportEventArgs<IFile>(styleSheets, element, false), this);
@@ -1480,7 +1480,7 @@ namespace Umbraco.Core.Services
/// </summary>
public static event TypedEventHandler<IPackagingService, ImportEventArgs<IContent>> ImportedContent;
public static event TypedEventHandler<IPackagingService, ExportEventArgs<IContent>> ExportingContent;
/// <summary>
@@ -1607,7 +1607,7 @@ namespace Umbraco.Core.Services
/// Occurs before Importing Stylesheets
/// </summary>
public static event TypedEventHandler<IPackagingService, ImportEventArgs<IFile>> ImportingStylesheets;
/// <summary>
/// Occurs after Template is Imported and Saved
/// </summary>
@@ -1622,7 +1622,7 @@ namespace Umbraco.Core.Services
/// Occurs after Template is Exported to Xml
/// </summary>
public static event TypedEventHandler<IPackagingService, ExportEventArgs<ITemplate>> ExportedTemplate;
/// <summary>
/// Occurs before Importing umbraco package
/// </summary>
+105 -38
View File
@@ -17,12 +17,19 @@ namespace Umbraco.Core.Services
internal class SectionService : ISectionService
{
private readonly IUserService _userService;
private IEnumerable<Section> _allAvailableSections;
private readonly IApplicationTreeService _applicationTreeService;
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
private readonly CacheHelper _cache;
internal const string AppConfigFileName = "applications.config";
private static string _appConfig;
private volatile bool _isInitialized = false;
private static readonly object Locker = new object();
public SectionService(
IUserService userService,
IApplicationTreeService applicationTreeService,
IApplicationTreeService applicationTreeService,
IDatabaseUnitOfWorkProvider uowProvider,
CacheHelper cache)
{
if (applicationTreeService == null) throw new ArgumentNullException("applicationTreeService");
@@ -30,12 +37,11 @@ namespace Umbraco.Core.Services
_userService = userService;
_applicationTreeService = applicationTreeService;
_uowProvider = uowProvider;
_cache = cache;
}
internal const string AppConfigFileName = "applications.config";
private static string _appConfig;
private static readonly object Locker = new object();
/// <summary>
/// gets/sets the application.config file path
@@ -57,22 +63,17 @@ namespace Umbraco.Core.Services
}
/// <summary>
/// Ensures all available sections exist in the storage medium
/// Initializes the service with all available application plugins
/// </summary>
/// <param name="existingSections"></param>
public void Initialize(IEnumerable<Section> existingSections)
/// <param name="allAvailableSections">
/// All application plugins found in assemblies
/// </param>
/// <remarks>
/// This is used to populate the app.config file with any applications declared in plugins that don't exist in the file
/// </remarks>
public void Initialize(IEnumerable<Section> allAvailableSections)
{
LoadXml(doc =>
{
foreach (var attr in existingSections)
{
doc.Root.Add(new XElement("add",
new XAttribute("alias", attr.Alias),
new XAttribute("name", attr.Name),
new XAttribute("icon", attr.Icon),
new XAttribute("sortOrder", attr.SortOrder)));
}
}, true);
_allAvailableSections = allAvailableSections;
}
/// <summary>
@@ -80,7 +81,7 @@ namespace Umbraco.Core.Services
/// </summary>
public IEnumerable<Section> GetSections()
{
return _cache.GetCacheItem(
return _cache.RuntimeCache.GetCacheItem<IEnumerable<Section>>(
CacheKeys.ApplicationsCacheKey,
() =>
{
@@ -88,28 +89,66 @@ namespace Umbraco.Core.Services
//if (_testApps != null)
// return _testApps;
var tmp = new List<Section>();
var list = ReadFromXmlAndSort();
LoadXml(doc =>
//On first access we need to do some initialization
if (_isInitialized == false)
{
lock (Locker)
{
foreach (var addElement in doc.Root.Elements("add").OrderBy(x =>
{
var sortOrderAttr = x.Attribute("sortOrder");
return sortOrderAttr != null ? Convert.ToInt32(sortOrderAttr.Value) : 0;
}))
if (_isInitialized == false)
{
var sortOrderAttr = addElement.Attribute("sortOrder");
tmp.Add(new Section(addElement.Attribute("name").Value,
addElement.Attribute("alias").Value,
addElement.Attribute("icon").Value,
sortOrderAttr != null ? Convert.ToInt32(sortOrderAttr.Value) : 0));
//now we can check the non-volatile flag
if (_allAvailableSections != null)
{
var hasChanges = false;
LoadXml(doc =>
{
//Now, load in the xml structure and update it with anything that is not declared there and save the file.
//NOTE: On the first iteration here, it will lazily scan all apps, etc... this is because this ienumerable is lazy
// based on the ApplicationRegistrar - and as noted there this is not an ideal way to do things but were stuck like this
// currently because of the legacy assemblies and types not in the Core.
//Get all the trees not registered in the config
var unregistered = _allAvailableSections
.Where(x => list.Any(l => l.Alias == x.Alias) == false)
.ToArray();
hasChanges = unregistered.Any();
var count = 0;
foreach (var attr in unregistered)
{
doc.Root.Add(new XElement("add",
new XAttribute("alias", attr.Alias),
new XAttribute("name", attr.Name),
new XAttribute("icon", attr.Icon),
new XAttribute("sortOrder", attr.SortOrder)));
count++;
}
//don't save if there's no changes
return count > 0;
}, true);
if (hasChanges)
{
//If there were changes, we need to re-read the structures from the XML
list = ReadFromXmlAndSort();
}
}
}
}, false);
return tmp;
}
}
return list;
});
}
internal void LoadXml(Action<XDocument> callback, bool saveAfterCallback)
internal void LoadXml(Func<XDocument, bool> callback, bool saveAfterCallbackIfChanged)
{
lock (Locker)
{
@@ -119,9 +158,9 @@ namespace Umbraco.Core.Services
if (doc.Root != null)
{
callback.Invoke(doc);
var changed = callback.Invoke(doc);
if (saveAfterCallback)
if (saveAfterCallbackIfChanged && changed)
{
//ensure the folder is created!
Directory.CreateDirectory(Path.GetDirectoryName(AppConfigFilePath));
@@ -194,6 +233,7 @@ namespace Umbraco.Core.Services
new XAttribute("name", name),
new XAttribute("icon", icon),
new XAttribute("sortOrder", sortOrder)));
return true;
}, true);
//raise event
@@ -209,7 +249,7 @@ namespace Umbraco.Core.Services
lock (Locker)
{
//delete the assigned applications
ApplicationContext.Current.DatabaseContext.Database.Execute(
_uowProvider.GetUnitOfWork().Database.Execute(
"delete from umbracoUser2App where app = @appAlias",
new { appAlias = section.Alias });
@@ -222,7 +262,10 @@ namespace Umbraco.Core.Services
LoadXml(doc =>
{
doc.Root.Elements("add").Where(x => x.Attribute("alias") != null && x.Attribute("alias").Value == section.Alias).Remove();
doc.Root.Elements("add").Where(x => x.Attribute("alias") != null && x.Attribute("alias").Value == section.Alias)
.Remove();
return true;
}, true);
//raise event
@@ -230,6 +273,30 @@ namespace Umbraco.Core.Services
}
}
private List<Section> ReadFromXmlAndSort()
{
var tmp = new List<Section>();
LoadXml(doc =>
{
foreach (var addElement in doc.Root.Elements("add").OrderBy(x =>
{
var sortOrderAttr = x.Attribute("sortOrder");
return sortOrderAttr != null ? Convert.ToInt32(sortOrderAttr.Value) : 0;
}))
{
var sortOrderAttr = addElement.Attribute("sortOrder");
tmp.Add(new Section(addElement.Attribute("name").Value,
addElement.Attribute("alias").Value,
addElement.Attribute("icon").Value,
sortOrderAttr != null ? Convert.ToInt32(sortOrderAttr.Value) : 0));
}
return false;
}, false);
return tmp;
}
internal static event TypedEventHandler<Section, EventArgs> Deleted;
private static void OnDeleted(Section app, EventArgs args)
{
+1 -1
View File
@@ -162,7 +162,7 @@ namespace Umbraco.Core.Services
_treeService = new Lazy<IApplicationTreeService>(() => new ApplicationTreeService(cache));
if (_sectionService == null)
_sectionService = new Lazy<ISectionService>(() => new SectionService(_userService.Value, _treeService.Value, cache));
_sectionService = new Lazy<ISectionService>(() => new SectionService(_userService.Value, _treeService.Value, provider, cache));
if (_macroService == null)
_macroService = new Lazy<IMacroService>(() => new MacroService(provider, repositoryFactory.Value));
@@ -3,6 +3,7 @@ using System.Linq;
using System.Web;
using System.Xml;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.IO;
namespace Umbraco.Core.Sync
@@ -17,23 +18,26 @@ namespace Umbraco.Core.Sync
/// status. This will attempt to determine the internal umbraco base url that can be used by the current
/// server to send a request to itself if it is in a load balanced environment.
/// </summary>
/// <returns>The full base url including schema (i.e. http://myserver:80/umbraco )</returns>
public static string GetCurrentServerUmbracoBaseUrl()
/// <returns>The full base url including schema (i.e. http://myserver:80/umbraco ) - or <c>null</c> if the url
/// cannot be determined at the moment (usually because the first request has not properly completed yet).</returns>
public static string GetCurrentServerUmbracoBaseUrl(ApplicationContext appContext, IUmbracoSettingsSection settings)
{
var status = GetStatus();
var status = GetStatus(settings);
if (status == CurrentServerEnvironmentStatus.Single)
{
//if it's a single install, then the base url has to be the first url registered
return string.Format("http://{0}", ApplicationContext.Current.OriginalRequestUrl);
// single install, return null if no config/original url, else use config/original url as base
// use http or https as appropriate
return GetBaseUrl(appContext, settings);
}
var servers = UmbracoConfig.For.UmbracoSettings().DistributedCall.Servers.ToArray();
var servers = settings.DistributedCall.Servers.ToArray();
if (servers.Any() == false)
{
//cannot be determined, then the base url has to be the first url registered
return string.Format("http://{0}", ApplicationContext.Current.OriginalRequestUrl);
// cannot be determined, return null if no config/original url, else use config/original url as base
// use http or https as appropriate
return GetBaseUrl(appContext, settings);
}
foreach (var server in servers)
@@ -58,22 +62,23 @@ namespace Umbraco.Core.Sync
}
}
//cannot be determined, then the base url has to be the first url registered
return string.Format("http://{0}", ApplicationContext.Current.OriginalRequestUrl);
// cannot be determined, return null if no config/original url, else use config/original url as base
// use http or https as appropriate
return GetBaseUrl(appContext, settings);
}
/// <summary>
/// Returns the current environment status for the current server
/// </summary>
/// <returns></returns>
public static CurrentServerEnvironmentStatus GetStatus()
public static CurrentServerEnvironmentStatus GetStatus(IUmbracoSettingsSection settings)
{
if (UmbracoConfig.For.UmbracoSettings().DistributedCall.Enabled == false)
if (settings.DistributedCall.Enabled == false)
{
return CurrentServerEnvironmentStatus.Single;
}
var servers = UmbracoConfig.For.UmbracoSettings().DistributedCall.Servers.ToArray();
var servers = settings.DistributedCall.Servers.ToArray();
if (servers.Any() == false)
{
@@ -108,5 +113,21 @@ namespace Umbraco.Core.Sync
return CurrentServerEnvironmentStatus.Slave;
}
private static string GetBaseUrl(ApplicationContext appContext, IUmbracoSettingsSection settings)
{
return (
// is config empty?
settings.ScheduledTasks.BaseUrl.IsNullOrWhiteSpace()
// is the orig req empty?
? appContext.OriginalRequestUrl.IsNullOrWhiteSpace()
// we've got nothing
? null
//the orig req url is not null, use that
: string.Format("http{0}://{1}", GlobalSettings.UseSSL ? "s" : "", appContext.OriginalRequestUrl)
// the config has been specified, use that
: string.Format("http{0}://{1}", GlobalSettings.UseSSL ? "s" : "", settings.ScheduledTasks.BaseUrl))
.EnsureEndsWith('/');
}
}
}
+37 -18
View File
@@ -15,6 +15,7 @@ using System.Web.Compilation;
using System.Web.Hosting;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
namespace Umbraco.Core
{
@@ -450,14 +451,23 @@ namespace Umbraco.Core
var allTypes = GetTypesWithFormattedException(a)
.ToArray();
//now filter the types based on the onlyConcreteClasses flag, not interfaces, not static classes but have
//the specified attribute
var attributedTypes = allTypes
.Where(t => (TypeHelper.IsNonStaticClass(t)
&& (onlyConcreteClasses == false || t.IsAbstract == false))
//the type must have this attribute
&& t.GetCustomAttributes(attributeType, false).Any())
.ToArray();
var attributedTypes = new Type[] {};
try
{
//now filter the types based on the onlyConcreteClasses flag, not interfaces, not static classes but have
//the specified attribute
attributedTypes = allTypes
.Where(t => (TypeHelper.IsNonStaticClass(t)
&& (onlyConcreteClasses == false || t.IsAbstract == false))
//the type must have this attribute
&& t.GetCustomAttributes(attributeType, false).Any())
.ToArray();
}
catch (TypeLoadException ex)
{
LogHelper.Error(typeof(TypeFinder), string.Format("Could not query types on {0} assembly, this is most likely due to this assembly not being compatible with the current Umbraco version", a), ex);
continue;
}
//add the types to our list to return
foreach (var t in attributedTypes)
@@ -583,16 +593,25 @@ namespace Umbraco.Core
.Where(assignTypeFrom.IsAssignableFrom)
.ToArray();
//now filter the types based on the onlyConcreteClasses flag, not interfaces, not static classes
var filteredTypes = allSubTypes
.Where(t => (TypeHelper.IsNonStaticClass(t)
//Do not include nested private classes - since we are in full trust now this will find those too!
&& t.IsNestedPrivate == false
&& (onlyConcreteClasses == false || t.IsAbstract == false)
//Do not include classes that are flagged to hide from the type finder
&& t.GetCustomAttribute<HideFromTypeFinderAttribute>() == null
&& additionalFilter(t)))
.ToArray();
var filteredTypes = new Type[] { };
try
{
//now filter the types based on the onlyConcreteClasses flag, not interfaces, not static classes
filteredTypes = allSubTypes
.Where(t => (TypeHelper.IsNonStaticClass(t)
//Do not include nested private classes - since we are in full trust now this will find those too!
&& t.IsNestedPrivate == false
&& (onlyConcreteClasses == false || t.IsAbstract == false)
//Do not include classes that are flagged to hide from the type finder
&& t.GetCustomAttribute<HideFromTypeFinderAttribute>() == null
&& additionalFilter(t)))
.ToArray();
}
catch (TypeLoadException ex)
{
LogHelper.Error(typeof(TypeFinder), string.Format("Could not query types on {0} assembly, this is most likely due to this assembly not being compatible with the current Umbraco version", a), ex);
continue;
}
//add the types to our list to return
foreach (var t in filteredTypes)
@@ -1,120 +1,119 @@
using System.Configuration;
using System.Web.Routing;
using NUnit.Framework;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
using Umbraco.Tests.TestHelpers;
using System.Web.Mvc;
namespace Umbraco.Tests
{
[TestFixture]
public class GlobalSettingsTests : BaseWebTest
{
public override void Initialize()
{
base.Initialize();
SettingsForTests.UmbracoPath = "~/umbraco";
}
public override void TearDown()
{
//ensure this is reset
SystemDirectories.Root = null;
SettingsForTests.UmbracoPath = "~/umbraco";
//reset the app config
base.TearDown();
}
[Test]
public void Is_Debug_Mode()
{
Assert.That(Umbraco.Core.Configuration.GlobalSettings.DebugMode, Is.EqualTo(true));
}
[Ignore]
[Test]
public void Is_Version_From_Assembly_Correct()
{
Assert.That(UmbracoVersion.Current.ToString(3), Is.EqualTo("6.0.0"));
}
[TestCase("~/umbraco", "/", "umbraco")]
[TestCase("~/umbraco", "/MyVirtualDir", "umbraco")]
[TestCase("~/customPath", "/MyVirtualDir/", "custompath")]
[TestCase("~/some-wacky/nestedPath", "/MyVirtualDir", "some-wacky-nestedpath")]
[TestCase("~/some-wacky/nestedPath", "/MyVirtualDir/NestedVDir/", "some-wacky-nestedpath")]
public void Umbraco_Mvc_Area(string path, string rootPath, string outcome)
{
SettingsForTests.UmbracoPath = path;
SystemDirectories.Root = rootPath;
Assert.AreEqual(outcome, Umbraco.Core.Configuration.GlobalSettings.UmbracoMvcArea);
}
[TestCase("/umbraco/umbraco.aspx")]
[TestCase("/umbraco/editContent.aspx")]
[TestCase("/install/default.aspx")]
[TestCase("/install/")]
[TestCase("/install")]
[TestCase("/install/?installStep=asdf")]
[TestCase("/install/test.aspx")]
[TestCase("/config/splashes/booting.aspx")]
public void Is_Reserved_Path_Or_Url(string url)
{
Assert.IsTrue(Umbraco.Core.Configuration.GlobalSettings.IsReservedPathOrUrl(url));
}
[TestCase("/umbraco_client/Tree/treeIcons.css")]
[TestCase("/umbraco_client/Tree/Themes/umbraco/style.css")]
[TestCase("/umbraco_client/scrollingmenu/style.css")]
[TestCase("/base/somebasehandler")]
[TestCase("/")]
[TestCase("/home.aspx")]
[TestCase("/umbraco-test")]
[TestCase("/install-test")]
[TestCase("/install.aspx")]
public void Is_Not_Reserved_Path_Or_Url(string url)
{
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
Umbraco.Core.Configuration.GlobalSettings.ReservedPaths = "";
Umbraco.Core.Configuration.GlobalSettings.ReservedUrls = "";
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));
}
}
using System.Web.Mvc;
using System.Web.Routing;
using NUnit.Framework;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
using Umbraco.Tests.TestHelpers;
namespace Umbraco.Tests.Configurations
{
[TestFixture]
public class GlobalSettingsTests : BaseWebTest
{
public override void Initialize()
{
base.Initialize();
SettingsForTests.UmbracoPath = "~/umbraco";
}
public override void TearDown()
{
//ensure this is reset
SystemDirectories.Root = null;
SettingsForTests.UmbracoPath = "~/umbraco";
//reset the app config
base.TearDown();
}
[Test]
public void Is_Debug_Mode()
{
Assert.That(Umbraco.Core.Configuration.GlobalSettings.DebugMode, Is.EqualTo(true));
}
[Ignore]
[Test]
public void Is_Version_From_Assembly_Correct()
{
Assert.That(UmbracoVersion.Current.ToString(3), Is.EqualTo("6.0.0"));
}
[TestCase("~/umbraco", "/", "umbraco")]
[TestCase("~/umbraco", "/MyVirtualDir", "umbraco")]
[TestCase("~/customPath", "/MyVirtualDir/", "custompath")]
[TestCase("~/some-wacky/nestedPath", "/MyVirtualDir", "some-wacky-nestedpath")]
[TestCase("~/some-wacky/nestedPath", "/MyVirtualDir/NestedVDir/", "some-wacky-nestedpath")]
public void Umbraco_Mvc_Area(string path, string rootPath, string outcome)
{
SettingsForTests.UmbracoPath = path;
SystemDirectories.Root = rootPath;
Assert.AreEqual(outcome, Umbraco.Core.Configuration.GlobalSettings.UmbracoMvcArea);
}
[TestCase("/umbraco/umbraco.aspx")]
[TestCase("/umbraco/editContent.aspx")]
[TestCase("/install/default.aspx")]
[TestCase("/install/")]
[TestCase("/install")]
[TestCase("/install/?installStep=asdf")]
[TestCase("/install/test.aspx")]
[TestCase("/config/splashes/booting.aspx")]
public void Is_Reserved_Path_Or_Url(string url)
{
Assert.IsTrue(Umbraco.Core.Configuration.GlobalSettings.IsReservedPathOrUrl(url));
}
[TestCase("/umbraco_client/Tree/treeIcons.css")]
[TestCase("/umbraco_client/Tree/Themes/umbraco/style.css")]
[TestCase("/umbraco_client/scrollingmenu/style.css")]
[TestCase("/base/somebasehandler")]
[TestCase("/")]
[TestCase("/home.aspx")]
[TestCase("/umbraco-test")]
[TestCase("/install-test")]
[TestCase("/install.aspx")]
public void Is_Not_Reserved_Path_Or_Url(string url)
{
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
Umbraco.Core.Configuration.GlobalSettings.ReservedPaths = "";
Umbraco.Core.Configuration.GlobalSettings.ReservedUrls = "";
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));
}
}
}
@@ -1,90 +1,87 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web;
using Umbraco.Web.Mvc;
namespace Umbraco.Tests.Surface
{
[TestFixture]
public class PluginControllerAreaTests : BaseWebTest
{
[Test]
public void Ensure_Same_Area1()
{
Assert.Throws<InvalidOperationException>(() =>
new PluginControllerArea(new PluginControllerMetadata[]
{
PluginController.GetMetadata(typeof(Plugin1Controller)),
PluginController.GetMetadata(typeof(Plugin2Controller)),
PluginController.GetMetadata(typeof(Plugin3Controller)) //not same area
}));
}
[Test]
public void Ensure_Same_Area3()
{
Assert.Throws<InvalidOperationException>(() =>
new PluginControllerArea(new PluginControllerMetadata[]
{
PluginController.GetMetadata(typeof(Plugin1Controller)),
PluginController.GetMetadata(typeof(Plugin2Controller)),
PluginController.GetMetadata(typeof(Plugin4Controller)) //no area assigned
}));
}
[Test]
public void Ensure_Same_Area2()
{
var area = new PluginControllerArea(new PluginControllerMetadata[]
{
PluginController.GetMetadata(typeof(Plugin1Controller)),
PluginController.GetMetadata(typeof(Plugin2Controller))
});
Assert.Pass();
}
#region Test classes
[PluginController("Area1")]
public class Plugin1Controller : PluginController
{
public Plugin1Controller(UmbracoContext umbracoContext) : base(umbracoContext)
{
}
}
[PluginController("Area1")]
public class Plugin2Controller : PluginController
{
public Plugin2Controller(UmbracoContext umbracoContext)
: base(umbracoContext)
{
}
}
[PluginController("Area2")]
public class Plugin3Controller : PluginController
{
public Plugin3Controller(UmbracoContext umbracoContext)
: base(umbracoContext)
{
}
}
public class Plugin4Controller : PluginController
{
public Plugin4Controller(UmbracoContext umbracoContext)
: base(umbracoContext)
{
}
}
#endregion
}
}
using System;
using NUnit.Framework;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web;
using Umbraco.Web.Mvc;
namespace Umbraco.Tests.Controllers
{
[TestFixture]
public class PluginControllerAreaTests : BaseWebTest
{
[Test]
public void Ensure_Same_Area1()
{
Assert.Throws<InvalidOperationException>(() =>
new PluginControllerArea(new PluginControllerMetadata[]
{
PluginController.GetMetadata(typeof(Plugin1Controller)),
PluginController.GetMetadata(typeof(Plugin2Controller)),
PluginController.GetMetadata(typeof(Plugin3Controller)) //not same area
}));
}
[Test]
public void Ensure_Same_Area3()
{
Assert.Throws<InvalidOperationException>(() =>
new PluginControllerArea(new PluginControllerMetadata[]
{
PluginController.GetMetadata(typeof(Plugin1Controller)),
PluginController.GetMetadata(typeof(Plugin2Controller)),
PluginController.GetMetadata(typeof(Plugin4Controller)) //no area assigned
}));
}
[Test]
public void Ensure_Same_Area2()
{
var area = new PluginControllerArea(new PluginControllerMetadata[]
{
PluginController.GetMetadata(typeof(Plugin1Controller)),
PluginController.GetMetadata(typeof(Plugin2Controller))
});
Assert.Pass();
}
#region Test classes
[PluginController("Area1")]
public class Plugin1Controller : PluginController
{
public Plugin1Controller(UmbracoContext umbracoContext) : base(umbracoContext)
{
}
}
[PluginController("Area1")]
public class Plugin2Controller : PluginController
{
public Plugin2Controller(UmbracoContext umbracoContext)
: base(umbracoContext)
{
}
}
[PluginController("Area2")]
public class Plugin3Controller : PluginController
{
public Plugin3Controller(UmbracoContext umbracoContext)
: base(umbracoContext)
{
}
}
public class Plugin4Controller : PluginController
{
public Plugin4Controller(UmbracoContext umbracoContext)
: base(umbracoContext)
{
}
}
#endregion
}
}
@@ -1,211 +1,210 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.ObjectResolution;
using Umbraco.Core.Sync;
using Umbraco.Web.Cache;
using umbraco.interfaces;
namespace Umbraco.Tests.Sync
{
/// <summary>
/// Ensures that calls to DistributedCache methods carry through to the IServerMessenger correctly
/// </summary>
[TestFixture]
public class DistributedCacheTests
{
[SetUp]
public void Setup()
{
ServerRegistrarResolver.Current = new ServerRegistrarResolver(
new TestServerRegistrar());
ServerMessengerResolver.Current = new ServerMessengerResolver(
new TestServerMessenger());
CacheRefreshersResolver.Current = new CacheRefreshersResolver(() => new[] { typeof(TestCacheRefresher) });
Resolution.Freeze();
}
[TearDown]
public void Teardown()
{
ServerRegistrarResolver.Reset();
ServerMessengerResolver.Reset();
CacheRefreshersResolver.Reset();
}
[Test]
public void RefreshIntId()
{
for (var i = 1; i < 11; i++)
{
DistributedCache.Instance.Refresh(Guid.Parse("E0F452CB-DCB2-4E84-B5A5-4F01744C5C73"), i);
}
Assert.AreEqual(10, ((TestServerMessenger)ServerMessengerResolver.Current.Messenger).IntIdsRefreshed.Count);
}
[Test]
public void RefreshIntIdFromObject()
{
for (var i = 0; i < 10; i++)
{
DistributedCache.Instance.Refresh(
Guid.Parse("E0F452CB-DCB2-4E84-B5A5-4F01744C5C73"),
x => x.Id,
new TestObjectWithId{Id = i});
}
Assert.AreEqual(10, ((TestServerMessenger)ServerMessengerResolver.Current.Messenger).IntIdsRefreshed.Count);
}
[Test]
public void RefreshGuidId()
{
for (var i = 0; i < 11; i++)
{
DistributedCache.Instance.Refresh(Guid.Parse("E0F452CB-DCB2-4E84-B5A5-4F01744C5C73"), Guid.NewGuid());
}
Assert.AreEqual(11, ((TestServerMessenger)ServerMessengerResolver.Current.Messenger).GuidIdsRefreshed.Count);
}
[Test]
public void RemoveIds()
{
for (var i = 1; i < 13; i++)
{
DistributedCache.Instance.Remove(Guid.Parse("E0F452CB-DCB2-4E84-B5A5-4F01744C5C73"), i);
}
Assert.AreEqual(12, ((TestServerMessenger)ServerMessengerResolver.Current.Messenger).IntIdsRemoved.Count);
}
[Test]
public void FullRefreshes()
{
for (var i = 0; i < 13; i++)
{
DistributedCache.Instance.RefreshAll(Guid.Parse("E0F452CB-DCB2-4E84-B5A5-4F01744C5C73"));
}
Assert.AreEqual(13, ((TestServerMessenger)ServerMessengerResolver.Current.Messenger).CountOfFullRefreshes);
}
#region internal test classes
internal class TestObjectWithId
{
public int Id { get; set; }
}
internal class TestCacheRefresher : ICacheRefresher
{
public Guid UniqueIdentifier
{
get { return Guid.Parse("E0F452CB-DCB2-4E84-B5A5-4F01744C5C73"); }
}
public string Name
{
get { return "Test"; }
}
public void RefreshAll()
{
}
public void Refresh(int id)
{
}
public void Remove(int id)
{
}
public void Refresh(Guid id)
{
}
}
internal class TestServerMessenger : IServerMessenger
{
//used for tests
public List<int> IntIdsRefreshed = new List<int>();
public List<Guid> GuidIdsRefreshed = new List<Guid>();
public List<int> IntIdsRemoved = new List<int>();
public List<string> PayloadsRemoved = new List<string>();
public List<string> PayloadsRefreshed = new List<string>();
public int CountOfFullRefreshes = 0;
public void PerformRefresh(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, string jsonPayload)
{
PayloadsRefreshed.Add(jsonPayload);
}
public void PerformRefresh<T>(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, Func<T, int> getNumericId, params T[] instances)
{
IntIdsRefreshed.AddRange(instances.Select(getNumericId));
}
public void PerformRefresh<T>(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, Func<T, Guid> getGuidId, params T[] instances)
{
GuidIdsRefreshed.AddRange(instances.Select(getGuidId));
}
public void PerformRemove(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, string jsonPayload)
{
PayloadsRemoved.Add(jsonPayload);
}
public void PerformRemove<T>(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, Func<T, int> getNumericId, params T[] instances)
{
IntIdsRemoved.AddRange(instances.Select(getNumericId));
}
public void PerformRemove(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, params int[] numericIds)
{
IntIdsRemoved.AddRange(numericIds);
}
public void PerformRefresh(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, params int[] numericIds)
{
IntIdsRefreshed.AddRange(numericIds);
}
public void PerformRefresh(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, params Guid[] guidIds)
{
GuidIdsRefreshed.AddRange(guidIds);
}
public void PerformRefreshAll(IEnumerable<IServerAddress> servers, ICacheRefresher refresher)
{
CountOfFullRefreshes++;
}
}
internal class TestServerRegistrar : IServerRegistrar
{
public IEnumerable<IServerAddress> Registrations
{
get
{
return new List<IServerAddress>()
{
new TestServerAddress("localhost")
};
}
}
}
public class TestServerAddress : IServerAddress
{
public TestServerAddress(string address)
{
ServerAddress = address;
}
public string ServerAddress { get; private set; }
}
#endregion
}
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.ObjectResolution;
using Umbraco.Core.Sync;
using umbraco.interfaces;
namespace Umbraco.Tests.DistributedCache
{
/// <summary>
/// Ensures that calls to DistributedCache methods carry through to the IServerMessenger correctly
/// </summary>
[TestFixture]
public class DistributedCacheTests
{
[SetUp]
public void Setup()
{
ServerRegistrarResolver.Current = new ServerRegistrarResolver(
new TestServerRegistrar());
ServerMessengerResolver.Current = new ServerMessengerResolver(
new TestServerMessenger());
CacheRefreshersResolver.Current = new CacheRefreshersResolver(() => new[] { typeof(TestCacheRefresher) });
Resolution.Freeze();
}
[TearDown]
public void Teardown()
{
ServerRegistrarResolver.Reset();
ServerMessengerResolver.Reset();
CacheRefreshersResolver.Reset();
}
[Test]
public void RefreshIntId()
{
for (var i = 1; i < 11; i++)
{
Web.Cache.DistributedCache.Instance.Refresh(Guid.Parse("E0F452CB-DCB2-4E84-B5A5-4F01744C5C73"), i);
}
Assert.AreEqual(10, ((TestServerMessenger)ServerMessengerResolver.Current.Messenger).IntIdsRefreshed.Count);
}
[Test]
public void RefreshIntIdFromObject()
{
for (var i = 0; i < 10; i++)
{
Web.Cache.DistributedCache.Instance.Refresh(
Guid.Parse("E0F452CB-DCB2-4E84-B5A5-4F01744C5C73"),
x => x.Id,
new TestObjectWithId{Id = i});
}
Assert.AreEqual(10, ((TestServerMessenger)ServerMessengerResolver.Current.Messenger).IntIdsRefreshed.Count);
}
[Test]
public void RefreshGuidId()
{
for (var i = 0; i < 11; i++)
{
Web.Cache.DistributedCache.Instance.Refresh(Guid.Parse("E0F452CB-DCB2-4E84-B5A5-4F01744C5C73"), Guid.NewGuid());
}
Assert.AreEqual(11, ((TestServerMessenger)ServerMessengerResolver.Current.Messenger).GuidIdsRefreshed.Count);
}
[Test]
public void RemoveIds()
{
for (var i = 1; i < 13; i++)
{
Web.Cache.DistributedCache.Instance.Remove(Guid.Parse("E0F452CB-DCB2-4E84-B5A5-4F01744C5C73"), i);
}
Assert.AreEqual(12, ((TestServerMessenger)ServerMessengerResolver.Current.Messenger).IntIdsRemoved.Count);
}
[Test]
public void FullRefreshes()
{
for (var i = 0; i < 13; i++)
{
Web.Cache.DistributedCache.Instance.RefreshAll(Guid.Parse("E0F452CB-DCB2-4E84-B5A5-4F01744C5C73"));
}
Assert.AreEqual(13, ((TestServerMessenger)ServerMessengerResolver.Current.Messenger).CountOfFullRefreshes);
}
#region internal test classes
internal class TestObjectWithId
{
public int Id { get; set; }
}
internal class TestCacheRefresher : ICacheRefresher
{
public Guid UniqueIdentifier
{
get { return Guid.Parse("E0F452CB-DCB2-4E84-B5A5-4F01744C5C73"); }
}
public string Name
{
get { return "Test"; }
}
public void RefreshAll()
{
}
public void Refresh(int id)
{
}
public void Remove(int id)
{
}
public void Refresh(Guid id)
{
}
}
internal class TestServerMessenger : IServerMessenger
{
//used for tests
public List<int> IntIdsRefreshed = new List<int>();
public List<Guid> GuidIdsRefreshed = new List<Guid>();
public List<int> IntIdsRemoved = new List<int>();
public List<string> PayloadsRemoved = new List<string>();
public List<string> PayloadsRefreshed = new List<string>();
public int CountOfFullRefreshes = 0;
public void PerformRefresh(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, string jsonPayload)
{
PayloadsRefreshed.Add(jsonPayload);
}
public void PerformRefresh<T>(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, Func<T, int> getNumericId, params T[] instances)
{
IntIdsRefreshed.AddRange(instances.Select(getNumericId));
}
public void PerformRefresh<T>(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, Func<T, Guid> getGuidId, params T[] instances)
{
GuidIdsRefreshed.AddRange(instances.Select(getGuidId));
}
public void PerformRemove(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, string jsonPayload)
{
PayloadsRemoved.Add(jsonPayload);
}
public void PerformRemove<T>(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, Func<T, int> getNumericId, params T[] instances)
{
IntIdsRemoved.AddRange(instances.Select(getNumericId));
}
public void PerformRemove(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, params int[] numericIds)
{
IntIdsRemoved.AddRange(numericIds);
}
public void PerformRefresh(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, params int[] numericIds)
{
IntIdsRefreshed.AddRange(numericIds);
}
public void PerformRefresh(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, params Guid[] guidIds)
{
GuidIdsRefreshed.AddRange(guidIds);
}
public void PerformRefreshAll(IEnumerable<IServerAddress> servers, ICacheRefresher refresher)
{
CountOfFullRefreshes++;
}
}
internal class TestServerRegistrar : IServerRegistrar
{
public IEnumerable<IServerAddress> Registrations
{
get
{
return new List<IServerAddress>()
{
new TestServerAddress("localhost")
};
}
}
}
public class TestServerAddress : IServerAddress
{
public TestServerAddress(string address)
{
ServerAddress = address;
}
public string ServerAddress { get; private set; }
}
#endregion
}
}
@@ -1,162 +1,158 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;
using Umbraco.Core.Dynamics;
using Umbraco.Web.Dynamics;
using Umbraco.Core.Models;
namespace Umbraco.Tests.Dynamics
{
//NOTE: there's libraries in both Umbraco.Core.Dynamics and Umbraco.Web.Dynamics - the reason for this is that the Web.Dynamics
// started with the razor macro implementation and is modified with hard coded references to dynamic node and dynamic null, though it seems
// to still work for other regular classes I don't want to move it to the core without removing these references but that would require a lot of work.
[TestFixture]
public class QueryableExtensionTests
{
[Test]
public void Order_By_Test_Int()
{
var items = new List<TestModel>
{
new TestModel {Age = 10, Name = "test1", Female = false},
new TestModel {Age = 31, Name = "someguy", Female = true},
new TestModel {Age = 11, Name = "test2", Female = true},
new TestModel {Age = 20, Name = "anothertest", Female = false},
new TestModel {Age = 55, Name = "blah", Female = false},
new TestModel {Age = 12, Name = "test3", Female = false}
};
var result = items.AsQueryable().OrderBy("Age").ToArray();
Assert.AreEqual(10, result.ElementAt(0).Age);
Assert.AreEqual(11, result.ElementAt(1).Age);
Assert.AreEqual(12, result.ElementAt(2).Age);
Assert.AreEqual(20, result.ElementAt(3).Age);
Assert.AreEqual(31, result.ElementAt(4).Age);
Assert.AreEqual(55, result.ElementAt(5).Age);
}
[Test]
public void Order_By_Test_String()
{
var items = new List<TestModel>
{
new TestModel {Age = 10, Name = "test1", Female = false},
new TestModel {Age = 31, Name = "someguy", Female = true},
new TestModel {Age = 11, Name = "test2", Female = true},
new TestModel {Age = 20, Name = "anothertest", Female = false},
new TestModel {Age = 55, Name = "blah", Female = false},
new TestModel {Age = 12, Name = "test3", Female = false}
};
var result = items.AsQueryable().OrderBy("Name").ToArray();
Assert.AreEqual("anothertest", result.ElementAt(0).Name);
Assert.AreEqual("blah", result.ElementAt(1).Name);
Assert.AreEqual("someguy", result.ElementAt(2).Name);
Assert.AreEqual("test1", result.ElementAt(3).Name);
Assert.AreEqual("test2", result.ElementAt(4).Name);
Assert.AreEqual("test3", result.ElementAt(5).Name);
}
[Test]
public void Where_Test_String()
{
var items = new List<TestModel>
{
new TestModel {Age = 10, Name = "test1", Female = false},
new TestModel {Age = 31, Name = "someguy", Female = true},
new TestModel {Age = 11, Name = "test2", Female = true},
new TestModel {Age = 20, Name = "anothertest", Female = false},
new TestModel {Age = 55, Name = "blah", Female = false},
new TestModel {Age = 12, Name = "test3", Female = false}
};
var result = items.AsQueryable().Where("Name = \"test1\"").ToArray();
Assert.AreEqual(1, result.Count());
Assert.AreEqual("test1", result.ElementAt(0).Name);
}
[Test]
public void Where_Test_String_With_Params()
{
var items = new List<TestModel>
{
new TestModel {Age = 10, Name = "test1", Female = false},
new TestModel {Age = 31, Name = "someguy", Female = true},
new TestModel {Age = 11, Name = "test2", Female = true},
new TestModel {Age = 20, Name = "anothertest", Female = false},
new TestModel {Age = 55, Name = "blah", Female = false},
new TestModel {Age = 12, Name = "test3", Female = false}
};
//NOTE: Currently the object query structure is not supported
//var result = items.AsQueryable().Where("Name = @name", new {name = "test1"}).ToArray();
var result = items.AsQueryable().Where("Name = @Name", new Dictionary<string, object> { { "Name", "test1" } }).ToArray();
Assert.AreEqual(1, result.Count());
Assert.AreEqual("test1", result.ElementAt(0).Name);
}
[Test]
public void Where_Test_Int_With_Params()
{
var items = new List<TestModel>
{
new TestModel {Age = 10, Name = "test1", Female = false},
new TestModel {Age = 31, Name = "someguy", Female = true},
new TestModel {Age = 11, Name = "test2", Female = true},
new TestModel {Age = 20, Name = "anothertest", Female = false},
new TestModel {Age = 55, Name = "blah", Female = false},
new TestModel {Age = 12, Name = "test3", Female = false}
};
var result = items.AsQueryable().Where("Age = @Age", new Dictionary<string, object> { { "Age", 10 } }).ToArray();
Assert.AreEqual(1, result.Count());
Assert.AreEqual("test1", result.ElementAt(0).Name);
}
[Test]
public void Where_Test_Bool_With_Params()
{
var items = new List<TestModel>
{
new TestModel {Age = 10, Name = "test1", Female = false},
new TestModel {Age = 31, Name = "someguy", Female = true},
new TestModel {Age = 11, Name = "test2", Female = true},
new TestModel {Age = 20, Name = "anothertest", Female = false},
new TestModel {Age = 55, Name = "blah", Female = false},
new TestModel {Age = 12, Name = "test3", Female = false}
};
var result = items.AsQueryable().Where("Female = @Female", new Dictionary<string, object> { { "Female", true } }).ToArray();
Assert.AreEqual(2, result.Count());
}
private class TestModel
{
public string Name { get; set; }
public int Age { get; set; }
public bool Female { get; set; }
}
}
}
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using Umbraco.Core.Dynamics;
using Umbraco.Web.Dynamics;
namespace Umbraco.Tests.DynamicsAndReflection
{
//NOTE: there's libraries in both Umbraco.Core.Dynamics and Umbraco.Web.Dynamics - the reason for this is that the Web.Dynamics
// started with the razor macro implementation and is modified with hard coded references to dynamic node and dynamic null, though it seems
// to still work for other regular classes I don't want to move it to the core without removing these references but that would require a lot of work.
[TestFixture]
public class QueryableExtensionTests
{
[Test]
public void Order_By_Test_Int()
{
var items = new List<TestModel>
{
new TestModel {Age = 10, Name = "test1", Female = false},
new TestModel {Age = 31, Name = "someguy", Female = true},
new TestModel {Age = 11, Name = "test2", Female = true},
new TestModel {Age = 20, Name = "anothertest", Female = false},
new TestModel {Age = 55, Name = "blah", Female = false},
new TestModel {Age = 12, Name = "test3", Female = false}
};
var result = items.AsQueryable().OrderBy("Age").ToArray();
Assert.AreEqual(10, result.ElementAt(0).Age);
Assert.AreEqual(11, result.ElementAt(1).Age);
Assert.AreEqual(12, result.ElementAt(2).Age);
Assert.AreEqual(20, result.ElementAt(3).Age);
Assert.AreEqual(31, result.ElementAt(4).Age);
Assert.AreEqual(55, result.ElementAt(5).Age);
}
[Test]
public void Order_By_Test_String()
{
var items = new List<TestModel>
{
new TestModel {Age = 10, Name = "test1", Female = false},
new TestModel {Age = 31, Name = "someguy", Female = true},
new TestModel {Age = 11, Name = "test2", Female = true},
new TestModel {Age = 20, Name = "anothertest", Female = false},
new TestModel {Age = 55, Name = "blah", Female = false},
new TestModel {Age = 12, Name = "test3", Female = false}
};
var result = items.AsQueryable().OrderBy("Name").ToArray();
Assert.AreEqual("anothertest", result.ElementAt(0).Name);
Assert.AreEqual("blah", result.ElementAt(1).Name);
Assert.AreEqual("someguy", result.ElementAt(2).Name);
Assert.AreEqual("test1", result.ElementAt(3).Name);
Assert.AreEqual("test2", result.ElementAt(4).Name);
Assert.AreEqual("test3", result.ElementAt(5).Name);
}
[Test]
public void Where_Test_String()
{
var items = new List<TestModel>
{
new TestModel {Age = 10, Name = "test1", Female = false},
new TestModel {Age = 31, Name = "someguy", Female = true},
new TestModel {Age = 11, Name = "test2", Female = true},
new TestModel {Age = 20, Name = "anothertest", Female = false},
new TestModel {Age = 55, Name = "blah", Female = false},
new TestModel {Age = 12, Name = "test3", Female = false}
};
var result = items.AsQueryable().Where("Name = \"test1\"").ToArray();
Assert.AreEqual(1, result.Count());
Assert.AreEqual("test1", result.ElementAt(0).Name);
}
[Test]
public void Where_Test_String_With_Params()
{
var items = new List<TestModel>
{
new TestModel {Age = 10, Name = "test1", Female = false},
new TestModel {Age = 31, Name = "someguy", Female = true},
new TestModel {Age = 11, Name = "test2", Female = true},
new TestModel {Age = 20, Name = "anothertest", Female = false},
new TestModel {Age = 55, Name = "blah", Female = false},
new TestModel {Age = 12, Name = "test3", Female = false}
};
//NOTE: Currently the object query structure is not supported
//var result = items.AsQueryable().Where("Name = @name", new {name = "test1"}).ToArray();
var result = items.AsQueryable().Where("Name = @Name", new Dictionary<string, object> { { "Name", "test1" } }).ToArray();
Assert.AreEqual(1, result.Count());
Assert.AreEqual("test1", result.ElementAt(0).Name);
}
[Test]
public void Where_Test_Int_With_Params()
{
var items = new List<TestModel>
{
new TestModel {Age = 10, Name = "test1", Female = false},
new TestModel {Age = 31, Name = "someguy", Female = true},
new TestModel {Age = 11, Name = "test2", Female = true},
new TestModel {Age = 20, Name = "anothertest", Female = false},
new TestModel {Age = 55, Name = "blah", Female = false},
new TestModel {Age = 12, Name = "test3", Female = false}
};
var result = items.AsQueryable().Where("Age = @Age", new Dictionary<string, object> { { "Age", 10 } }).ToArray();
Assert.AreEqual(1, result.Count());
Assert.AreEqual("test1", result.ElementAt(0).Name);
}
[Test]
public void Where_Test_Bool_With_Params()
{
var items = new List<TestModel>
{
new TestModel {Age = 10, Name = "test1", Female = false},
new TestModel {Age = 31, Name = "someguy", Female = true},
new TestModel {Age = 11, Name = "test2", Female = true},
new TestModel {Age = 20, Name = "anothertest", Female = false},
new TestModel {Age = 55, Name = "blah", Female = false},
new TestModel {Age = 12, Name = "test3", Female = false}
};
var result = items.AsQueryable().Where("Female = @Female", new Dictionary<string, object> { { "Female", true } }).ToArray();
Assert.AreEqual(2, result.Count());
}
private class TestModel
{
public string Name { get; set; }
public int Age { get; set; }
public bool Female { get; set; }
}
}
}
@@ -1,139 +1,139 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Tests.TestHelpers;
using umbraco.cms.businesslogic.macro;
using umbraco.interfaces;
namespace Umbraco.Tests
{
[TestFixture]
public class MacroEngineFactoryTests
{
[SetUp]
public void Initialize()
{
TestHelper.SetupLog4NetForTests();
//this ensures its reset
PluginManager.Current = new PluginManager(false);
//for testing, we'll specify which assemblies are scanned for the PluginTypeResolver
PluginManager.Current.AssembliesToScan = new[]
{
this.GetType().Assembly
};
}
[TearDown]
public void TearDown()
{
PluginManager.Current = null;
}
[Test]
public void Get_All()
{
var engines = MacroEngineFactory.GetAll();
Assert.AreEqual(2, engines.Count());
}
[Test]
public void Get_Engine()
{
var engine1 = MacroEngineFactory.GetEngine("MacroEngine1");
Assert.IsNotNull(engine1);
}
[Test]
public void Get_By_Filename()
{
var engine1 = MacroEngineFactory.GetByFilename("test.me1");
var engine2 = MacroEngineFactory.GetByFilename("test.me2");
Assert.IsNotNull(engine1);
Assert.IsNotNull(engine2);
Assert.Throws<MacroEngineException>(() => MacroEngineFactory.GetByFilename("test.blah"));
}
[Test]
public void Get_By_Extension()
{
var engine1 = MacroEngineFactory.GetByExtension("me1");
var engine2 = MacroEngineFactory.GetByExtension("me2");
Assert.IsNotNull(engine1);
Assert.IsNotNull(engine2);
Assert.Throws<MacroEngineException>(() => MacroEngineFactory.GetByExtension("blah"));
}
#region Classes for tests
public class MacroEngine1 : IMacroEngine
{
public string Name
{
get { return "MacroEngine1"; }
}
public IEnumerable<string> SupportedExtensions
{
get { return new[] {"me1"}; }
}
public IEnumerable<string> SupportedUIExtensions
{
get { throw new NotImplementedException(); }
}
public Dictionary<string, IMacroGuiRendering> SupportedProperties
{
get { throw new NotImplementedException(); }
}
public bool Validate(string code, string tempFileName, INode currentPage, out string errorMessage)
{
throw new NotImplementedException();
}
public string Execute(MacroModel macro, INode currentPage)
{
throw new NotImplementedException();
}
}
public class MacroEngine2 : IMacroEngine
{
public string Name
{
get { return "MacroEngine2"; }
}
public IEnumerable<string> SupportedExtensions
{
get { return new[] { "me2" }; }
}
public IEnumerable<string> SupportedUIExtensions
{
get { throw new NotImplementedException(); }
}
public Dictionary<string, IMacroGuiRendering> SupportedProperties
{
get { throw new NotImplementedException(); }
}
public bool Validate(string code, string tempFileName, INode currentPage, out string errorMessage)
{
throw new NotImplementedException();
}
public string Execute(MacroModel macro, INode currentPage)
{
throw new NotImplementedException();
}
}
#endregion
}
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using umbraco.cms.businesslogic.macro;
using Umbraco.Core;
using umbraco.interfaces;
using Umbraco.Tests.TestHelpers;
namespace Umbraco.Tests.Macros
{
[TestFixture]
public class MacroEngineFactoryTests
{
[SetUp]
public void Initialize()
{
TestHelper.SetupLog4NetForTests();
//this ensures its reset
PluginManager.Current = new PluginManager(false);
//for testing, we'll specify which assemblies are scanned for the PluginTypeResolver
PluginManager.Current.AssembliesToScan = new[]
{
this.GetType().Assembly
};
}
[TearDown]
public void TearDown()
{
PluginManager.Current = null;
}
[Test]
public void Get_All()
{
var engines = MacroEngineFactory.GetAll();
Assert.AreEqual(2, engines.Count());
}
[Test]
public void Get_Engine()
{
var engine1 = MacroEngineFactory.GetEngine("MacroEngine1");
Assert.IsNotNull(engine1);
}
[Test]
public void Get_By_Filename()
{
var engine1 = MacroEngineFactory.GetByFilename("test.me1");
var engine2 = MacroEngineFactory.GetByFilename("test.me2");
Assert.IsNotNull(engine1);
Assert.IsNotNull(engine2);
Assert.Throws<MacroEngineException>(() => MacroEngineFactory.GetByFilename("test.blah"));
}
[Test]
public void Get_By_Extension()
{
var engine1 = MacroEngineFactory.GetByExtension("me1");
var engine2 = MacroEngineFactory.GetByExtension("me2");
Assert.IsNotNull(engine1);
Assert.IsNotNull(engine2);
Assert.Throws<MacroEngineException>(() => MacroEngineFactory.GetByExtension("blah"));
}
#region Classes for tests
public class MacroEngine1 : IMacroEngine
{
public string Name
{
get { return "MacroEngine1"; }
}
public IEnumerable<string> SupportedExtensions
{
get { return new[] {"me1"}; }
}
public IEnumerable<string> SupportedUIExtensions
{
get { throw new NotImplementedException(); }
}
public Dictionary<string, IMacroGuiRendering> SupportedProperties
{
get { throw new NotImplementedException(); }
}
public bool Validate(string code, string tempFileName, INode currentPage, out string errorMessage)
{
throw new NotImplementedException();
}
public string Execute(MacroModel macro, INode currentPage)
{
throw new NotImplementedException();
}
}
public class MacroEngine2 : IMacroEngine
{
public string Name
{
get { return "MacroEngine2"; }
}
public IEnumerable<string> SupportedExtensions
{
get { return new[] { "me2" }; }
}
public IEnumerable<string> SupportedUIExtensions
{
get { throw new NotImplementedException(); }
}
public Dictionary<string, IMacroGuiRendering> SupportedProperties
{
get { throw new NotImplementedException(); }
}
public bool Validate(string code, string tempFileName, INode currentPage, out string errorMessage)
{
throw new NotImplementedException();
}
public string Execute(MacroModel macro, INode currentPage)
{
throw new NotImplementedException();
}
}
#endregion
}
}
@@ -1,33 +1,33 @@
using System.Web.Mvc;
using NUnit.Framework;
using Umbraco.Web;
namespace Umbraco.Tests
{
[TestFixture]
public class HtmlHelperExtensionMethodsTests
{
[SetUp]
public virtual void Initialize()
{
//create an empty htmlHelper
_htmlHelper = new HtmlHelper(new ViewContext(), new ViewPage());
}
private HtmlHelper _htmlHelper;
[Test]
public void Wrap_Simple()
{
var output = _htmlHelper.Wrap("div", "hello world");
Assert.AreEqual("<div>hello world</div>", output.ToHtmlString());
}
[Test]
public void Wrap_Object_Attributes()
{
var output = _htmlHelper.Wrap("div", "hello world", new {style = "color:red;", onclick = "void();"});
Assert.AreEqual("<div style=\"color:red;\" onclick=\"void();\">hello world</div>", output.ToHtmlString());
}
}
using System.Web.Mvc;
using NUnit.Framework;
using Umbraco.Web;
namespace Umbraco.Tests.Mvc
{
[TestFixture]
public class HtmlHelperExtensionMethodsTests
{
[SetUp]
public virtual void Initialize()
{
//create an empty htmlHelper
_htmlHelper = new HtmlHelper(new ViewContext(), new ViewPage());
}
private HtmlHelper _htmlHelper;
[Test]
public void Wrap_Simple()
{
var output = _htmlHelper.Wrap("div", "hello world");
Assert.AreEqual("<div>hello world</div>", output.ToHtmlString());
}
[Test]
public void Wrap_Object_Attributes()
{
var output = _htmlHelper.Wrap("div", "hello world", new {style = "color:red;", onclick = "void();"});
Assert.AreEqual("<div style=\"color:red;\" onclick=\"void();\">hello world</div>", output.ToHtmlString());
}
}
}
@@ -408,7 +408,7 @@ namespace Umbraco.Tests.Mvc
var ctx = new UmbracoContext(
GetHttpContextFactory(url, routeData).HttpContext,
appCtx,
new PublishedCaches(cache, new PublishedMediaCache()),
new PublishedCaches(cache, new PublishedMediaCache(appCtx)),
new WebSecurity(http, appCtx));
//if (setSingleton)
@@ -1,17 +1,17 @@
using System;
using System.Collections.Generic;
using Umbraco.Core;
namespace Umbraco.Tests
{
/// <summary>
/// Used for PluginTypeResolverTests
/// </summary>
internal static class PluginManagerExtensions
{
public static IEnumerable<Type> ResolveFindMeTypes(this PluginManager resolver)
{
return resolver.ResolveTypes<PluginManagerTests.IFindMe>();
}
}
using System;
using System.Collections.Generic;
using Umbraco.Core;
namespace Umbraco.Tests.Plugins
{
/// <summary>
/// Used for PluginTypeResolverTests
/// </summary>
internal static class PluginManagerExtensions
{
public static IEnumerable<Type> ResolveFindMeTypes(this PluginManager resolver)
{
return resolver.ResolveTypes<PluginManagerTests.IFindMe>();
}
}
}
@@ -1,392 +1,388 @@
using System;
using System.Collections.Generic;
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.Core.PropertyEditors;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web;
using Umbraco.Web.PropertyEditors;
using umbraco;
using umbraco.DataLayer;
using umbraco.MacroEngines;
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
{
[SetUp]
public void Initialize()
{
TestHelper.SetupLog4NetForTests();
//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[]
{
this.GetType().Assembly,
typeof(ApplicationStartupHandler).Assembly,
typeof(SqlCEHelper).Assembly,
typeof(CMSNode).Assembly,
typeof(System.Guid).Assembly,
typeof(NUnit.Framework.Assert).Assembly,
typeof(Microsoft.CSharp.CSharpCodeProvider).Assembly,
typeof(System.Xml.NameTable).Assembly,
typeof(System.Configuration.GenericEnumConverter).Assembly,
typeof(System.Web.SiteMap).Assembly,
typeof(TabPage).Assembly,
typeof(System.Web.Mvc.ActionResult).Assembly,
typeof(TypeFinder).Assembly,
typeof(ISqlHelper).Assembly,
typeof(ICultureDictionary).Assembly,
typeof(UmbracoContext).Assembly,
typeof(BaseDataType).Assembly
};
}
[TearDown]
public void TearDown()
{
PluginManager.Current = null;
}
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 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);
//}
////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 Detect_Legacy_Plugin_File_List()
{
var tempFolder = IOHelper.MapPath("~/App_Data/TEMP/PluginCache");
var manager = new PluginManager(false);
var filePath= Path.Combine(tempFolder, string.Format("umbraco-plugins.{0}.list", NetworkHelper.FileSafeMachineName));
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>");
Assert.IsTrue(manager.DetectLegacyPluginListFile());
File.Delete(filePath);
//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>");
Assert.IsFalse(manager.DetectLegacyPluginListFile());
}
[Test]
public void Create_Cached_Plugin_File()
{
var types = new[] { typeof(PluginManager), typeof(PluginManagerTests), typeof(UmbracoContext) };
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);
var plugins = manager.TryGetCachedPluginsFromFile<string>(PluginManager.TypeResolutionKind.FindAllTypes);
var diffType = manager.TryGetCachedPluginsFromFile<string>(PluginManager.TypeResolutionKind.FindAttributedTypes);
Assert.IsTrue(plugins.Success);
//this will be false since there is no cache of that type resolution kind
Assert.IsFalse(diffType.Success);
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);
}
[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 };
//Act
var hash1 = PluginManager.GetFileHash(list1);
var hash2 = PluginManager.GetFileHash(list2);
var hash3 = PluginManager.GetFileHash(list3);
//Assert
Assert.AreNotEqual(hash1, hash2);
Assert.AreNotEqual(hash1, hash3);
Assert.AreNotEqual(hash2, hash3);
Assert.AreEqual(hash1, PluginManager.GetFileHash(list1));
}
[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_Assigned_Mappers()
{
var foundTypes1 = PluginManager.Current.ResolveAssignedMapperTypes();
Assert.AreEqual(22, foundTypes1.Count());
}
[Test]
public void Resolves_Types()
{
var foundTypes1 = PluginManager.Current.ResolveFindMeTypes();
Assert.AreEqual(2, foundTypes1.Count());
}
[Test]
public void Resolves_Attributed_Trees()
{
var trees = PluginManager.Current.ResolveAttributedTrees();
Assert.AreEqual(19, trees.Count());
}
[Test]
public void Resolves_Actions()
{
var actions = PluginManager.Current.ResolveActions();
Assert.AreEqual(36, actions.Count());
}
[Test]
public void Resolves_Trees()
{
var trees = PluginManager.Current.ResolveTrees();
Assert.AreEqual(39, trees.Count());
}
[Test]
public void Resolves_Applications()
{
var apps = PluginManager.Current.ResolveApplications();
Assert.AreEqual(7, apps.Count());
}
[Test]
public void Resolves_DataTypes()
{
var types = PluginManager.Current.ResolveDataTypes();
Assert.AreEqual(35, 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(3, types.Count());
}
[Test]
public void Resolves_XsltExtensions()
{
var types = PluginManager.Current.ResolveXsltExtensions();
Assert.AreEqual(3, types.Count());
}
/// <summary>
/// This demonstrates this issue: http://issues.umbraco.org/issue/U4-3505 - the TypeList was returning a list of assignable types
/// not explicit types which is sort of ideal but is confusing so we'll do it the less confusing way.
/// </summary>
[Test]
public void TypeList_Resolves_Explicit_Types()
{
var types = new HashSet<PluginManager.TypeList>();
var propEditors = new PluginManager.TypeList<PropertyEditor>(PluginManager.TypeResolutionKind.FindAllTypes);
propEditors.AddType(typeof(LabelPropertyEditor));
types.Add(propEditors);
var found = types.SingleOrDefault(x => x.IsTypeList<PropertyEditor>(PluginManager.TypeResolutionKind.FindAllTypes));
Assert.IsNotNull(found);
//This should not find a type list of this type
var shouldNotFind = types.SingleOrDefault(x => x.IsTypeList<IParameterEditor>(PluginManager.TypeResolutionKind.FindAllTypes));
Assert.IsNull(shouldNotFind);
}
[XsltExtension("Blah.Blah")]
public class MyXsltExtension
{
}
[Umbraco.Web.BaseRest.RestExtension("Blah")]
public class MyRestExtesion
{
}
public interface IFindMe
{
}
public class FindMe1 : IFindMe
{
}
public class FindMe2 : IFindMe
{
}
}
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using NUnit.Framework;
using SqlCE4Umbraco;
using umbraco;
using umbraco.businesslogic;
using umbraco.cms.businesslogic;
using Umbraco.Core;
using Umbraco.Core.IO;
using Umbraco.Core.PropertyEditors;
using umbraco.DataLayer;
using umbraco.editorControls;
using umbraco.MacroEngines;
using Umbraco.Tests.TestHelpers;
using umbraco.uicontrols;
using Umbraco.Web;
using Umbraco.Web.PropertyEditors;
namespace Umbraco.Tests.Plugins
{
[TestFixture]
public class PluginManagerTests
{
[SetUp]
public void Initialize()
{
TestHelper.SetupLog4NetForTests();
//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[]
{
this.GetType().Assembly,
typeof(ApplicationStartupHandler).Assembly,
typeof(SqlCEHelper).Assembly,
typeof(CMSNode).Assembly,
typeof(System.Guid).Assembly,
typeof(NUnit.Framework.Assert).Assembly,
typeof(Microsoft.CSharp.CSharpCodeProvider).Assembly,
typeof(System.Xml.NameTable).Assembly,
typeof(System.Configuration.GenericEnumConverter).Assembly,
typeof(System.Web.SiteMap).Assembly,
typeof(TabPage).Assembly,
typeof(System.Web.Mvc.ActionResult).Assembly,
typeof(TypeFinder).Assembly,
typeof(ISqlHelper).Assembly,
typeof(ICultureDictionary).Assembly,
typeof(UmbracoContext).Assembly,
typeof(BaseDataType).Assembly
};
}
[TearDown]
public void TearDown()
{
PluginManager.Current = null;
}
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 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);
//}
////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 Detect_Legacy_Plugin_File_List()
{
var tempFolder = IOHelper.MapPath("~/App_Data/TEMP/PluginCache");
var manager = new PluginManager(false);
var filePath= Path.Combine(tempFolder, string.Format("umbraco-plugins.{0}.list", NetworkHelper.FileSafeMachineName));
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>");
Assert.IsTrue(manager.DetectLegacyPluginListFile());
File.Delete(filePath);
//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>");
Assert.IsFalse(manager.DetectLegacyPluginListFile());
}
[Test]
public void Create_Cached_Plugin_File()
{
var types = new[] { typeof(PluginManager), typeof(PluginManagerTests), typeof(UmbracoContext) };
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);
var plugins = manager.TryGetCachedPluginsFromFile<string>(PluginManager.TypeResolutionKind.FindAllTypes);
var diffType = manager.TryGetCachedPluginsFromFile<string>(PluginManager.TypeResolutionKind.FindAttributedTypes);
Assert.IsTrue(plugins.Success);
//this will be false since there is no cache of that type resolution kind
Assert.IsFalse(diffType.Success);
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);
}
[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 };
//Act
var hash1 = PluginManager.GetFileHash(list1);
var hash2 = PluginManager.GetFileHash(list2);
var hash3 = PluginManager.GetFileHash(list3);
//Assert
Assert.AreNotEqual(hash1, hash2);
Assert.AreNotEqual(hash1, hash3);
Assert.AreNotEqual(hash2, hash3);
Assert.AreEqual(hash1, PluginManager.GetFileHash(list1));
}
[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_Assigned_Mappers()
{
var foundTypes1 = PluginManager.Current.ResolveAssignedMapperTypes();
Assert.AreEqual(22, foundTypes1.Count());
}
[Test]
public void Resolves_Types()
{
var foundTypes1 = PluginManager.Current.ResolveFindMeTypes();
Assert.AreEqual(2, foundTypes1.Count());
}
[Test]
public void Resolves_Attributed_Trees()
{
var trees = PluginManager.Current.ResolveAttributedTrees();
Assert.AreEqual(19, trees.Count());
}
[Test]
public void Resolves_Actions()
{
var actions = PluginManager.Current.ResolveActions();
Assert.AreEqual(36, actions.Count());
}
[Test]
public void Resolves_Trees()
{
var trees = PluginManager.Current.ResolveTrees();
Assert.AreEqual(39, trees.Count());
}
[Test]
public void Resolves_Applications()
{
var apps = PluginManager.Current.ResolveApplications();
Assert.AreEqual(7, apps.Count());
}
[Test]
public void Resolves_DataTypes()
{
var types = PluginManager.Current.ResolveDataTypes();
Assert.AreEqual(35, 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(3, types.Count());
}
[Test]
public void Resolves_XsltExtensions()
{
var types = PluginManager.Current.ResolveXsltExtensions();
Assert.AreEqual(3, types.Count());
}
/// <summary>
/// This demonstrates this issue: http://issues.umbraco.org/issue/U4-3505 - the TypeList was returning a list of assignable types
/// not explicit types which is sort of ideal but is confusing so we'll do it the less confusing way.
/// </summary>
[Test]
public void TypeList_Resolves_Explicit_Types()
{
var types = new HashSet<PluginManager.TypeList>();
var propEditors = new PluginManager.TypeList<PropertyEditor>(PluginManager.TypeResolutionKind.FindAllTypes);
propEditors.AddType(typeof(LabelPropertyEditor));
types.Add(propEditors);
var found = types.SingleOrDefault(x => x.IsTypeList<PropertyEditor>(PluginManager.TypeResolutionKind.FindAllTypes));
Assert.IsNotNull(found);
//This should not find a type list of this type
var shouldNotFind = types.SingleOrDefault(x => x.IsTypeList<IParameterEditor>(PluginManager.TypeResolutionKind.FindAllTypes));
Assert.IsNull(shouldNotFind);
}
[XsltExtension("Blah.Blah")]
public class MyXsltExtension
{
}
[Umbraco.Web.BaseRest.RestExtension("Blah")]
public class MyRestExtesion
{
}
public interface IFindMe
{
}
public class FindMe1 : IFindMe
{
}
public class FindMe2 : IFindMe
{
}
}
}
File diff suppressed because it is too large Load Diff
@@ -1,79 +1,72 @@
using System;
using System.ComponentModel;
using System.Data.Common;
using System.Data.Odbc;
using System.Data.OleDb;
using System.Data.SqlClient;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Web;
using Umbraco.Web.Cache;
using Umbraco.Web.Scheduling;
using UmbracoExamine;
using UmbracoExamine.DataServices;
using umbraco;
using umbraco.presentation;
using umbraco.presentation.nodeFactory;
using umbraco.presentation.umbraco.Search;
namespace Umbraco.Tests
{
/// <summary>
/// Tests for TypeHelper
/// </summary>
[TestFixture]
public class TypeHelperTests
{
[Test]
public void Is_Static_Class()
{
Assert.IsTrue(TypeHelper.IsStaticClass(typeof(TypeHelper)));
Assert.IsFalse(TypeHelper.IsStaticClass(typeof(TypeHelperTests)));
}
[Test]
public void Find_Common_Base_Class()
{
var t1 = TypeHelper.GetLowestBaseType(typeof (OleDbCommand),
typeof (OdbcCommand),
typeof (SqlCommand));
Assert.IsFalse(t1.Success);
var t2 = TypeHelper.GetLowestBaseType(typeof (OleDbCommand),
typeof (OdbcCommand),
typeof (SqlCommand),
typeof (Component));
Assert.IsTrue(t2.Success);
Assert.AreEqual(typeof(Component), t2.Result);
var t3 = TypeHelper.GetLowestBaseType(typeof (OleDbCommand),
typeof (OdbcCommand),
typeof (SqlCommand),
typeof (Component),
typeof (Component).BaseType);
Assert.IsTrue(t3.Success);
Assert.AreEqual(typeof(MarshalByRefObject), t3.Result);
var t4 = TypeHelper.GetLowestBaseType(typeof(OleDbCommand),
typeof(OdbcCommand),
typeof(SqlCommand),
typeof(Component),
typeof(Component).BaseType,
typeof(int));
Assert.IsFalse(t4.Success);
var t5 = TypeHelper.GetLowestBaseType(typeof(PropertyAliasDto));
Assert.IsTrue(t5.Success);
Assert.AreEqual(typeof(PropertyAliasDto), t5.Result);
var t6 = TypeHelper.GetLowestBaseType(typeof (IApplicationEventHandler),
typeof (Scheduler),
typeof(CacheRefresherEventHandler));
Assert.IsTrue(t6.Success);
Assert.AreEqual(typeof(IApplicationEventHandler), t6.Result);
}
}
using System;
using System.ComponentModel;
using System.Data.Odbc;
using System.Data.OleDb;
using System.Data.SqlClient;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Web.Cache;
using Umbraco.Web.Scheduling;
using UmbracoExamine.DataServices;
namespace Umbraco.Tests.Plugins
{
/// <summary>
/// Tests for TypeHelper
/// </summary>
[TestFixture]
public class TypeHelperTests
{
[Test]
public void Is_Static_Class()
{
Assert.IsTrue(TypeHelper.IsStaticClass(typeof(TypeHelper)));
Assert.IsFalse(TypeHelper.IsStaticClass(typeof(TypeHelperTests)));
}
[Test]
public void Find_Common_Base_Class()
{
var t1 = TypeHelper.GetLowestBaseType(typeof (OleDbCommand),
typeof (OdbcCommand),
typeof (SqlCommand));
Assert.IsFalse(t1.Success);
var t2 = TypeHelper.GetLowestBaseType(typeof (OleDbCommand),
typeof (OdbcCommand),
typeof (SqlCommand),
typeof (Component));
Assert.IsTrue(t2.Success);
Assert.AreEqual(typeof(Component), t2.Result);
var t3 = TypeHelper.GetLowestBaseType(typeof (OleDbCommand),
typeof (OdbcCommand),
typeof (SqlCommand),
typeof (Component),
typeof (Component).BaseType);
Assert.IsTrue(t3.Success);
Assert.AreEqual(typeof(MarshalByRefObject), t3.Result);
var t4 = TypeHelper.GetLowestBaseType(typeof(OleDbCommand),
typeof(OdbcCommand),
typeof(SqlCommand),
typeof(Component),
typeof(Component).BaseType,
typeof(int));
Assert.IsFalse(t4.Success);
var t5 = TypeHelper.GetLowestBaseType(typeof(PropertyAliasDto));
Assert.IsTrue(t5.Success);
Assert.AreEqual(typeof(PropertyAliasDto), t5.Result);
var t6 = TypeHelper.GetLowestBaseType(typeof (IApplicationEventHandler),
typeof (Scheduler),
typeof(CacheRefresherEventHandler));
Assert.IsTrue(t6.Success);
Assert.AreEqual(typeof(IApplicationEventHandler), t6.Result);
}
}
}
@@ -92,9 +92,9 @@ namespace Umbraco.Tests.PublishedCache
_umbracoContext = new UmbracoContext(
_httpContextFactory.HttpContext,
ApplicationContext.Current,
new PublishedCaches(cache, new PublishedMediaCache()),
new WebSecurity(_httpContextFactory.HttpContext, ApplicationContext.Current));
ApplicationContext,
new PublishedCaches(cache, new PublishedMediaCache(ApplicationContext)),
new WebSecurity(_httpContextFactory.HttpContext, ApplicationContext));
_cache = _umbracoContext.ContentCache;
}
@@ -37,7 +37,7 @@ namespace Umbraco.Tests.PublishedCache
var mChild2 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child2", mType, user, mRoot2.Id);
var ctx = GetUmbracoContext("/test", 1234);
var cache = new ContextualPublishedMediaCache(new PublishedMediaCache(), ctx);
var cache = new ContextualPublishedMediaCache(new PublishedMediaCache(ctx.Application), ctx);
var roots = cache.GetAtRoot();
Assert.AreEqual(2, roots.Count());
Assert.IsTrue(roots.Select(x => x.Id).ContainsAll(new[] {mRoot1.Id, mRoot2.Id}));
@@ -126,6 +126,8 @@ namespace Umbraco.Tests.PublishedCache
[Test]
public void Convert_From_Search_Result()
{
var ctx = GetUmbracoContext("/test", 1234);
var result = new SearchResult()
{
Id = 1234,
@@ -144,7 +146,7 @@ namespace Umbraco.Tests.PublishedCache
result.Fields.Add("updateDate", "2012-07-16T10:34:09");
result.Fields.Add("writerName", "Shannon");
var store = new PublishedMediaCache();
var store = new PublishedMediaCache(ctx.Application);
var doc = store.ConvertFromSearchResult(result);
DoAssert(doc, 1234, 0, 0, "", "Image", 0, "Shannon", "", 0, 0, "-1,1234", default(DateTime), DateTime.Parse("2012-07-16T10:34:09"), 2);
@@ -154,9 +156,11 @@ namespace Umbraco.Tests.PublishedCache
[Test]
public void Convert_From_XPath_Navigator()
{
var ctx = GetUmbracoContext("/test", 1234);
var xmlDoc = GetMediaXml();
var navigator = xmlDoc.SelectSingleNode("/root/Image").CreateNavigator();
var cache = new PublishedMediaCache();
var cache = new PublishedMediaCache(ctx.Application);
var doc = cache.ConvertFromXPathNavigator(navigator);
DoAssert(doc, 2000, 0, 2, "image1", "Image", 2044, "Shannon", "Shannon2", 22, 33, "-1,2000", DateTime.Parse("2012-06-12T14:13:17"), DateTime.Parse("2012-07-20T18:50:43"), 1);
@@ -49,7 +49,7 @@ namespace Umbraco.Tests.PublishedContent
});
PublishedCachesResolver.Current = new PublishedCachesResolver(new PublishedCaches(
new PublishedContentCache(), new PublishedMediaCache()));
new PublishedContentCache(), new PublishedMediaCache(ApplicationContext)));
if (PublishedContentModelFactoryResolver.HasCurrent == false)
PublishedContentModelFactoryResolver.Current = new PublishedContentModelFactoryResolver();
@@ -11,6 +11,7 @@ using Examine.LuceneEngine;
using Examine.LuceneEngine.Providers;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.Store;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Configuration;
@@ -60,7 +61,7 @@ namespace Umbraco.Tests.PublishedContent
internal static IPublishedContent GetNode(int id, UmbracoContext umbracoContext)
{
var ctx = umbracoContext;
var cache = new ContextualPublishedMediaCache(new PublishedMediaCache(), ctx);
var cache = new ContextualPublishedMediaCache(new PublishedMediaCache(ctx.Application), ctx);
var doc = cache.GetById(id);
Assert.IsNotNull(doc);
return doc;
@@ -112,7 +113,7 @@ namespace Umbraco.Tests.PublishedContent
indexer.RebuildIndex();
var searcher = IndexInitializer.GetUmbracoSearcher(luceneDir);
var ctx = GetUmbracoContext("/test", 1234);
var cache = new ContextualPublishedMediaCache(new PublishedMediaCache(searcher, indexer), ctx);
var cache = new ContextualPublishedMediaCache(new PublishedMediaCache(ctx.Application, searcher, indexer), ctx);
//we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace
var publishedMedia = cache.GetById(1111);
@@ -141,7 +142,7 @@ namespace Umbraco.Tests.PublishedContent
indexer.RebuildIndex();
var searcher = IndexInitializer.GetUmbracoSearcher(luceneDir);
var ctx = GetUmbracoContext("/test", 1234);
var cache = new ContextualPublishedMediaCache(new PublishedMediaCache(searcher, indexer), ctx);
var cache = new ContextualPublishedMediaCache(new PublishedMediaCache(ctx.Application, searcher, indexer), ctx);
//ensure it is found
var publishedMedia = cache.GetById(3113);
@@ -181,7 +182,7 @@ namespace Umbraco.Tests.PublishedContent
indexer.RebuildIndex();
var searcher = IndexInitializer.GetUmbracoSearcher(luceneDir);
var ctx = GetUmbracoContext("/test", 1234);
var cache = new ContextualPublishedMediaCache(new PublishedMediaCache(searcher, indexer), ctx);
var cache = new ContextualPublishedMediaCache(new PublishedMediaCache(ctx.Application, searcher, indexer), ctx);
//we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace
var publishedMedia = cache.GetById(1111);
@@ -203,7 +204,7 @@ namespace Umbraco.Tests.PublishedContent
indexer.RebuildIndex();
var searcher = IndexInitializer.GetUmbracoSearcher(luceneDir);
var ctx = GetUmbracoContext("/test", 1234);
var cache = new ContextualPublishedMediaCache(new PublishedMediaCache(searcher, indexer), ctx);
var cache = new ContextualPublishedMediaCache(new PublishedMediaCache(ctx.Application, searcher, indexer), ctx);
//we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace
var publishedMedia = cache.GetById(1111);
@@ -225,7 +226,7 @@ namespace Umbraco.Tests.PublishedContent
indexer.RebuildIndex();
var searcher = IndexInitializer.GetUmbracoSearcher(luceneDir);
var ctx = GetUmbracoContext("/test", 1234);
var cache = new ContextualPublishedMediaCache(new PublishedMediaCache(searcher, indexer), ctx);
var cache = new ContextualPublishedMediaCache(new PublishedMediaCache(ctx.Application, searcher, indexer), ctx);
//we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace
var publishedMedia = cache.GetById(1111);
@@ -247,7 +248,7 @@ namespace Umbraco.Tests.PublishedContent
indexer.RebuildIndex();
var ctx = GetUmbracoContext("/test", 1234);
var searcher = IndexInitializer.GetUmbracoSearcher(luceneDir);
var cache = new ContextualPublishedMediaCache(new PublishedMediaCache(searcher, indexer), ctx);
var cache = new ContextualPublishedMediaCache(new PublishedMediaCache(ctx.Application, searcher, indexer), ctx);
//we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace
var publishedMedia = cache.GetById(3113);
@@ -266,7 +267,7 @@ namespace Umbraco.Tests.PublishedContent
indexer.RebuildIndex();
var ctx = GetUmbracoContext("/test", 1234);
var searcher = IndexInitializer.GetUmbracoSearcher(luceneDir);
var cache = new ContextualPublishedMediaCache(new PublishedMediaCache(searcher, indexer), ctx);
var cache = new ContextualPublishedMediaCache(new PublishedMediaCache(ctx.Application, searcher, indexer), ctx);
//we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace
var publishedMedia = cache.GetById(3113);
@@ -412,6 +413,100 @@ namespace Umbraco.Tests.PublishedContent
Assert.IsTrue(publishedSubChild1.AncestorsOrSelf().Select(x => x.Id).ContainsAll(
new[] { mSubChild1.Id, mChild1.Id, mRoot.Id }));
}
[Test]
public void Convert_From_Legacy_Xml()
{
var config = SettingsForTests.GenerateMockSettings();
var contentMock = Mock.Get(config.Content);
contentMock.Setup(x => x.UseLegacyXmlSchema).Returns(true);
SettingsForTests.ConfigureSettings(config);
var nodeId = 2112;
var xml = XElement.Parse(@"<node id=""2112"" version=""5b3e46ab-3e37-4cfa-ab70-014234b5bd39"" parentID=""2222"" level=""3"" 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=""4"" 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>");
var node = xml.DescendantsAndSelf("node").Single(x => (int) x.Attribute("id") == nodeId);
var publishedMedia = new PublishedMediaCache(ApplicationContext);
var nav = node.CreateNavigator();
var converted = publishedMedia.ConvertFromXPathNodeIterator(nav.Select("/node"), nodeId);
Assert.AreEqual(nodeId, converted.Id);
Assert.AreEqual(3, converted.Level);
Assert.AreEqual(1, converted.SortOrder);
Assert.AreEqual("Sam's Umbraco Image", converted.Name);
Assert.AreEqual("-1,1111,2222,2112", converted.Path);
}
[Test]
public void Convert_From_Standard_Xml()
{
var config = SettingsForTests.GenerateMockSettings();
var contentMock = Mock.Get(config.Content);
contentMock.Setup(x => x.UseLegacyXmlSchema).Returns(true);
SettingsForTests.ConfigureSettings(config);
var nodeId = 2112;
var xml = XElement.Parse(@"<Image id=""2112"" version=""5b3e46ab-3e37-4cfa-ab70-014234b5bd39"" parentID=""2222"" level=""3"" 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"" isDoc="""">
<umbracoFile><![CDATA[/media/1234/blah.pdf]]></umbracoFile>
<umbracoWidth>115</umbracoWidth>
<umbracoHeight>268</umbracoHeight>
<umbracoBytes>10726</umbracoBytes>
<umbracoExtension>jpg</umbracoExtension>
<Image id=""3113"" version=""5b3e46ab-3e37-4cfa-ab70-014234b5bd33"" parentID=""2112"" level=""4"" 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"" isDoc="""">
<umbracoFile><![CDATA[/media/1234/blah.pdf]]></umbracoFile>
<umbracoWidth>115</umbracoWidth>
<umbracoHeight>268</umbracoHeight>
<umbracoBytes>10726</umbracoBytes>
<umbracoExtension>jpg</umbracoExtension>
</Image>
</Image>");
var node = xml.DescendantsAndSelf("Image").Single(x => (int)x.Attribute("id") == nodeId);
var publishedMedia = new PublishedMediaCache(ApplicationContext);
var nav = node.CreateNavigator();
var converted = publishedMedia.ConvertFromXPathNodeIterator(nav.Select("/Image"), nodeId);
Assert.AreEqual(nodeId, converted.Id);
Assert.AreEqual(3, converted.Level);
Assert.AreEqual(1, converted.SortOrder);
Assert.AreEqual("Sam's Umbraco Image", converted.Name);
Assert.AreEqual("-1,1111,2222,2112", converted.Path);
}
[Test]
public void Detects_Error_In_Xml()
{
var errorXml = new XElement("error", string.Format("No media is maching '{0}'", 1234));
var nav = errorXml.CreateNavigator();
var publishedMedia = new PublishedMediaCache(ApplicationContext);
var converted = publishedMedia.ConvertFromXPathNodeIterator(nav.Select("/"), 1234);
Assert.IsNull(converted);
}
}
@@ -0,0 +1,280 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Web.Scheduling;
namespace Umbraco.Tests.Scheduling
{
[TestFixture]
public class BackgroundTaskRunnerTests
{
[Test]
public void Startup_And_Shutdown()
{
BackgroundTaskRunner<IBackgroundTask> tManager;
using (tManager = new BackgroundTaskRunner<IBackgroundTask>(true, true))
{
tManager.StartUp();
}
NUnit.Framework.Assert.IsFalse(tManager.IsRunning);
}
[Test]
public void Startup_Starts_Automatically()
{
BackgroundTaskRunner<BaseTask> tManager;
using (tManager = new BackgroundTaskRunner<BaseTask>(true, true))
{
tManager.Add(new MyTask());
NUnit.Framework.Assert.IsTrue(tManager.IsRunning);
}
}
[Test]
public void Task_Runs()
{
var myTask = new MyTask();
var waitHandle = new ManualResetEvent(false);
BackgroundTaskRunner<BaseTask> tManager;
using (tManager = new BackgroundTaskRunner<BaseTask>(true, true))
{
tManager.TaskCompleted += (sender, task) => waitHandle.Set();
tManager.Add(myTask);
//wait for ITasks to complete
waitHandle.WaitOne();
NUnit.Framework.Assert.IsTrue(myTask.Ended != default(DateTime));
}
}
[Test]
public void Many_Tasks_Run()
{
var tasks = new Dictionary<BaseTask, ManualResetEvent>();
for (var i = 0; i < 10; i++)
{
tasks.Add(new MyTask(), new ManualResetEvent(false));
}
BackgroundTaskRunner<BaseTask> tManager;
using (tManager = new BackgroundTaskRunner<BaseTask>(true, true))
{
tManager.TaskCompleted += (sender, task) => tasks[task.Task].Set();
tasks.ForEach(t => tManager.Add(t.Key));
//wait for all ITasks to complete
WaitHandle.WaitAll(tasks.Values.Select(x => (WaitHandle)x).ToArray());
foreach (var task in tasks)
{
NUnit.Framework.Assert.IsTrue(task.Key.Ended != default(DateTime));
}
}
}
[Test]
public void Tasks_Can_Keep_Being_Added_And_Will_Execute()
{
Func<Dictionary<BaseTask, ManualResetEvent>> getTasks = () =>
{
var newTasks = new Dictionary<BaseTask, ManualResetEvent>();
for (var i = 0; i < 10; i++)
{
newTasks.Add(new MyTask(), new ManualResetEvent(false));
}
return newTasks;
};
IDictionary<BaseTask, ManualResetEvent> tasks = getTasks();
BackgroundTaskRunner<BaseTask> tManager;
using (tManager = new BackgroundTaskRunner<BaseTask>(true, true))
{
tManager.TaskCompleted += (sender, task) => tasks[task.Task].Set();
//execute first batch
tasks.ForEach(t => tManager.Add(t.Key));
//wait for all ITasks to complete
WaitHandle.WaitAll(tasks.Values.Select(x => (WaitHandle)x).ToArray());
foreach (var task in tasks)
{
NUnit.Framework.Assert.IsTrue(task.Key.Ended != default(DateTime));
}
//execute another batch after a bit
Thread.Sleep(2000);
tasks = getTasks();
tasks.ForEach(t => tManager.Add(t.Key));
//wait for all ITasks to complete
WaitHandle.WaitAll(tasks.Values.Select(x => (WaitHandle)x).ToArray());
foreach (var task in tasks)
{
NUnit.Framework.Assert.IsTrue(task.Key.Ended != default(DateTime));
}
}
}
[Test]
public void Task_Queue_Will_Be_Completed_Before_Shutdown()
{
var tasks = new Dictionary<BaseTask, ManualResetEvent>();
for (var i = 0; i < 10; i++)
{
tasks.Add(new MyTask(), new ManualResetEvent(false));
}
BackgroundTaskRunner<BaseTask> tManager;
using (tManager = new BackgroundTaskRunner<BaseTask>(true, true))
{
tManager.TaskCompleted += (sender, task) => tasks[task.Task].Set();
tasks.ForEach(t => tManager.Add(t.Key));
////wait for all ITasks to complete
//WaitHandle.WaitAll(tasks.Values.Select(x => (WaitHandle)x).ToArray());
tManager.Stop(false);
//immediate stop will block until complete - but since we are running on
// a single thread this doesn't really matter as the above will just process
// until complete.
tManager.Stop(true);
NUnit.Framework.Assert.AreEqual(0, tManager.TaskCount);
}
}
//NOTE: These tests work in .Net 4.5 but in this current version we don't have the correct
// async/await signatures with GetAwaiter, so am just commenting these out in this version
[Test]
public async void Non_Persistent_Runner_Will_End_After_Queue_Empty()
{
var tasks = new List<BaseTask>();
for (var i = 0; i < 10; i++)
{
tasks.Add(new MyTask());
}
BackgroundTaskRunner<BaseTask> tManager;
using (tManager = new BackgroundTaskRunner<BaseTask>(persistentThread: false, dedicatedThread:true))
{
tasks.ForEach(t => tManager.Add(t));
//wait till the thread is done
await tManager;
foreach (var task in tasks)
{
Assert.IsTrue(task.Ended != default(DateTime));
}
Assert.AreEqual(TaskStatus.RanToCompletion, tManager.TaskStatus);
Assert.IsFalse(tManager.IsRunning);
Assert.IsFalse(tManager.IsDisposed);
}
}
[Test]
public async void Non_Persistent_Runner_Will_Start_New_Threads_When_Required()
{
Func<List<BaseTask>> getTasks = () =>
{
var newTasks = new List<BaseTask>();
for (var i = 0; i < 10; i++)
{
newTasks.Add(new MyTask());
}
return newTasks;
};
List<BaseTask> tasks = getTasks();
BackgroundTaskRunner<BaseTask> tManager;
using (tManager = new BackgroundTaskRunner<BaseTask>(persistentThread: false, dedicatedThread: true))
{
tasks.ForEach(t => tManager.Add(t));
//wait till the thread is done
await tManager;
Assert.AreEqual(TaskStatus.RanToCompletion, tManager.TaskStatus);
Assert.IsFalse(tManager.IsRunning);
Assert.IsFalse(tManager.IsDisposed);
foreach (var task in tasks)
{
Assert.IsTrue(task.Ended != default(DateTime));
}
//create more tasks
tasks = getTasks();
//add more tasks
tasks.ForEach(t => tManager.Add(t));
//wait till the thread is done
await tManager;
foreach (var task in tasks)
{
Assert.IsTrue(task.Ended != default(DateTime));
}
Assert.AreEqual(TaskStatus.RanToCompletion, tManager.TaskStatus);
Assert.IsFalse(tManager.IsRunning);
Assert.IsFalse(tManager.IsDisposed);
}
}
private class MyTask : BaseTask
{
public MyTask()
{
}
public override void Run()
{
Thread.Sleep(500);
}
public override void Cancel()
{
}
}
public abstract class BaseTask : IBackgroundTask
{
public Guid UniqueId { get; protected set; }
public abstract void Run();
public abstract void Cancel();
public DateTime Queued { get; set; }
public DateTime Started { get; set; }
public DateTime Ended { get; set; }
public virtual void Dispose()
{
Ended = DateTime.Now;
}
}
}
}
@@ -0,0 +1,92 @@
using System.Configuration;
using System.Linq;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Sync;
namespace Umbraco.Tests
{
[TestFixture]
public class ServerEnvironmentHelperTests
{
[Test]
public void Get_Base_Url_Single_Server_Orig_Request_Url_No_SSL()
{
var appContext = new ApplicationContext(null)
{
OriginalRequestUrl = "test.com"
};
ConfigurationManager.AppSettings.Set("umbracoUseSSL", "false");
var result = ServerEnvironmentHelper.GetCurrentServerUmbracoBaseUrl(
appContext,
Mock.Of<IUmbracoSettingsSection>(
section =>
section.DistributedCall == Mock.Of<IDistributedCallSection>(callSection => callSection.Servers == Enumerable.Empty<IServer>())
&& section.ScheduledTasks == Mock.Of<IScheduledTasksSection>()));
Assert.AreEqual("http://test.com/", result);
}
[Test]
public void Get_Base_Url_Single_Server_Orig_Request_Url_With_SSL()
{
var appContext = new ApplicationContext(null)
{
OriginalRequestUrl = "test.com"
};
ConfigurationManager.AppSettings.Set("umbracoUseSSL", "true");
var result = ServerEnvironmentHelper.GetCurrentServerUmbracoBaseUrl(
appContext,
Mock.Of<IUmbracoSettingsSection>(
section =>
section.DistributedCall == Mock.Of<IDistributedCallSection>(callSection => callSection.Servers == Enumerable.Empty<IServer>())
&& section.ScheduledTasks == Mock.Of<IScheduledTasksSection>()));
Assert.AreEqual("https://test.com/", result);
}
[Test]
public void Get_Base_Url_Single_Server_Via_Config_Url_No_SSL()
{
var appContext = new ApplicationContext(null);
ConfigurationManager.AppSettings.Set("umbracoUseSSL", "false");
var result = ServerEnvironmentHelper.GetCurrentServerUmbracoBaseUrl(
appContext,
Mock.Of<IUmbracoSettingsSection>(
section =>
section.DistributedCall == Mock.Of<IDistributedCallSection>(callSection => callSection.Servers == Enumerable.Empty<IServer>())
&& section.ScheduledTasks == Mock.Of<IScheduledTasksSection>(tasksSection => tasksSection.BaseUrl == "mycoolhost.com/hello/world")));
Assert.AreEqual("http://mycoolhost.com/hello/world/", result);
}
[Test]
public void Get_Base_Url_Single_Server_Via_Config_Url_With_SSL()
{
var appContext = new ApplicationContext(null);
ConfigurationManager.AppSettings.Set("umbracoUseSSL", "true");
var result = ServerEnvironmentHelper.GetCurrentServerUmbracoBaseUrl(
appContext,
Mock.Of<IUmbracoSettingsSection>(
section =>
section.DistributedCall == Mock.Of<IDistributedCallSection>(callSection => callSection.Servers == Enumerable.Empty<IServer>())
&& section.ScheduledTasks == Mock.Of<IScheduledTasksSection>(tasksSection => tasksSection.BaseUrl == "mycoolhost.com/hello/world")));
Assert.AreEqual("https://mycoolhost.com/hello/world/", result);
}
}
}
@@ -356,7 +356,7 @@ namespace Umbraco.Tests.TestHelpers
var ctx = new UmbracoContext(
httpContext,
ApplicationContext,
new PublishedCaches(cache, new PublishedMediaCache()),
new PublishedCaches(cache, new PublishedMediaCache(ApplicationContext)),
new WebSecurity(httpContext, ApplicationContext));
if (setSingleton)
@@ -19,10 +19,7 @@ namespace Umbraco.Tests.TestHelpers
[SetUp]
public virtual void Initialize()
{
using (DisposableTimer.TraceDuration<BaseUmbracoConfigurationTest>("init"))
{
SettingsForTests.Reset();
}
SettingsForTests.Reset();
}
@@ -30,10 +27,7 @@ namespace Umbraco.Tests.TestHelpers
public virtual void TearDown()
{
//reset settings
using (DisposableTimer.TraceDuration<BaseUmbracoConfigurationTest>("teardown"))
{
SettingsForTests.Reset();
}
SettingsForTests.Reset();
}
}
@@ -1,127 +1,123 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using umbraco.cms.presentation.Trees;
namespace Umbraco.Tests.Trees
{
[TestFixture]
public class BaseContentTreeTests
{
[TearDown]
public void TestTearDown()
{
BaseTree.AfterTreeRender -= EventHandler;
BaseTree.BeforeTreeRender -= EventHandler;
}
[Test]
public void Run_Optimized()
{
var tree1 = new MyOptimizedContentTree1("content");
var tree2 = new MyOptimizedContentTree2("content");
Assert.IsTrue(tree1.UseOptimizedRendering);
Assert.IsTrue(tree2.UseOptimizedRendering);
}
[Test]
public void Not_Optimized_Events_AfterRender()
{
var tree = new MyOptimizedContentTree1("content");
BaseTree.AfterTreeRender += EventHandler;
Assert.IsFalse(tree.UseOptimizedRendering);
}
[Test]
public void Not_Optimized_Events_BeforeRender()
{
var tree = new MyOptimizedContentTree1("content");
BaseTree.BeforeTreeRender += EventHandler;
Assert.IsFalse(tree.UseOptimizedRendering);
}
[Test]
public void Not_Optimized_Overriden_Method()
{
var tree = new MyNotOptimizedContentTree("content");
Assert.IsFalse(tree.UseOptimizedRendering);
}
private void EventHandler(object sender, TreeEventArgs treeEventArgs)
{
}
//optimized because we are not overriding OnRenderNode
public class MyOptimizedContentTree1 : BaseContentTree
{
public MyOptimizedContentTree1(string application)
: base(application)
{
}
protected override void CreateRootNode(ref XmlTreeNode rootNode)
{
}
}
public class MyOptimizedContentTree2 : BaseContentTree
{
public MyOptimizedContentTree2(string application)
: base(application)
{
}
protected override bool LoadMinimalDocument
{
get { return true; }
}
protected override void CreateRootNode(ref XmlTreeNode rootNode)
{
}
//even if we override it will still be optimized because of the LoadMinimalDocument flag
protected override void OnRenderNode(ref XmlTreeNode xNode, umbraco.cms.businesslogic.web.Document doc)
{
base.OnRenderNode(ref xNode, doc);
}
}
public class MyNotOptimizedContentTree : BaseContentTree
{
public MyNotOptimizedContentTree(string application)
: base(application)
{
}
protected override void CreateRootNode(ref XmlTreeNode rootNode)
{
}
protected override bool LoadMinimalDocument
{
get { return false; }
}
protected override void OnRenderNode(ref XmlTreeNode xNode, umbraco.cms.businesslogic.web.Document doc)
{
base.OnRenderNode(ref xNode, doc);
}
}
}
}
using NUnit.Framework;
using umbraco.cms.presentation.Trees;
namespace Umbraco.Tests.TreesAndSections
{
[TestFixture]
public class BaseContentTreeTests
{
[TearDown]
public void TestTearDown()
{
BaseTree.AfterTreeRender -= EventHandler;
BaseTree.BeforeTreeRender -= EventHandler;
}
[Test]
public void Run_Optimized()
{
var tree1 = new MyOptimizedContentTree1("content");
var tree2 = new MyOptimizedContentTree2("content");
Assert.IsTrue(tree1.UseOptimizedRendering);
Assert.IsTrue(tree2.UseOptimizedRendering);
}
[Test]
public void Not_Optimized_Events_AfterRender()
{
var tree = new MyOptimizedContentTree1("content");
BaseTree.AfterTreeRender += EventHandler;
Assert.IsFalse(tree.UseOptimizedRendering);
}
[Test]
public void Not_Optimized_Events_BeforeRender()
{
var tree = new MyOptimizedContentTree1("content");
BaseTree.BeforeTreeRender += EventHandler;
Assert.IsFalse(tree.UseOptimizedRendering);
}
[Test]
public void Not_Optimized_Overriden_Method()
{
var tree = new MyNotOptimizedContentTree("content");
Assert.IsFalse(tree.UseOptimizedRendering);
}
private void EventHandler(object sender, TreeEventArgs treeEventArgs)
{
}
//optimized because we are not overriding OnRenderNode
public class MyOptimizedContentTree1 : BaseContentTree
{
public MyOptimizedContentTree1(string application)
: base(application)
{
}
protected override void CreateRootNode(ref XmlTreeNode rootNode)
{
}
}
public class MyOptimizedContentTree2 : BaseContentTree
{
public MyOptimizedContentTree2(string application)
: base(application)
{
}
protected override bool LoadMinimalDocument
{
get { return true; }
}
protected override void CreateRootNode(ref XmlTreeNode rootNode)
{
}
//even if we override it will still be optimized because of the LoadMinimalDocument flag
protected override void OnRenderNode(ref XmlTreeNode xNode, umbraco.cms.businesslogic.web.Document doc)
{
base.OnRenderNode(ref xNode, doc);
}
}
public class MyNotOptimizedContentTree : BaseContentTree
{
public MyNotOptimizedContentTree(string application)
: base(application)
{
}
protected override void CreateRootNode(ref XmlTreeNode rootNode)
{
}
protected override bool LoadMinimalDocument
{
get { return false; }
}
protected override void OnRenderNode(ref XmlTreeNode xNode, umbraco.cms.businesslogic.web.Document doc)
{
base.OnRenderNode(ref xNode, doc);
}
}
}
}
@@ -1,65 +1,65 @@
using NUnit.Framework;
using umbraco.cms.presentation.Trees;
namespace Umbraco.Tests.Trees
{
[TestFixture]
public class BaseMediaTreeTests
{
[TearDown]
public void TestTearDown()
{
BaseTree.AfterTreeRender -= EventHandler;
BaseTree.BeforeTreeRender -= EventHandler;
}
[Test]
public void Run_Optimized()
{
var tree = new MyOptimizedMediaTree("media");
Assert.IsTrue(tree.UseOptimizedRendering);
}
[Test]
public void Not_Optimized_Events_AfterRender()
{
var tree = new MyOptimizedMediaTree("media");
BaseTree.AfterTreeRender += EventHandler;
Assert.IsFalse(tree.UseOptimizedRendering);
}
[Test]
public void Not_Optimized_Events_BeforeRender()
{
var tree = new MyOptimizedMediaTree("media");
BaseTree.BeforeTreeRender += EventHandler;
Assert.IsFalse(tree.UseOptimizedRendering);
}
private void EventHandler(object sender, TreeEventArgs treeEventArgs)
{
}
public class MyOptimizedMediaTree : BaseMediaTree
{
public MyOptimizedMediaTree(string application)
: base(application)
{
}
protected override void CreateRootNode(ref XmlTreeNode rootNode)
{
}
}
}
using NUnit.Framework;
using umbraco.cms.presentation.Trees;
namespace Umbraco.Tests.TreesAndSections
{
[TestFixture]
public class BaseMediaTreeTests
{
[TearDown]
public void TestTearDown()
{
BaseTree.AfterTreeRender -= EventHandler;
BaseTree.BeforeTreeRender -= EventHandler;
}
[Test]
public void Run_Optimized()
{
var tree = new MyOptimizedMediaTree("media");
Assert.IsTrue(tree.UseOptimizedRendering);
}
[Test]
public void Not_Optimized_Events_AfterRender()
{
var tree = new MyOptimizedMediaTree("media");
BaseTree.AfterTreeRender += EventHandler;
Assert.IsFalse(tree.UseOptimizedRendering);
}
[Test]
public void Not_Optimized_Events_BeforeRender()
{
var tree = new MyOptimizedMediaTree("media");
BaseTree.BeforeTreeRender += EventHandler;
Assert.IsFalse(tree.UseOptimizedRendering);
}
private void EventHandler(object sender, TreeEventArgs treeEventArgs)
{
}
public class MyOptimizedMediaTree : BaseMediaTree
{
public MyOptimizedMediaTree(string application)
: base(application)
{
}
protected override void CreateRootNode(ref XmlTreeNode rootNode)
{
}
}
}
}
+15 -15
View File
@@ -276,7 +276,7 @@
<Compile Include="Controllers\WebApiEditors\FilterAllowedOutgoingContentAttributeTests.cs" />
<Compile Include="Controllers\WebApiEditors\MediaControllerUnitTests.cs" />
<Compile Include="CoreXml\FrameworkXmlTests.cs" />
<Compile Include="Dynamics\QueryableExtensionTests.cs" />
<Compile Include="DynamicsAndReflection\QueryableExtensionTests.cs" />
<Compile Include="DynamicsAndReflection\ExtensionMethodFinderTests.cs" />
<Compile Include="DynamicsAndReflection\ReflectionTests.cs" />
<Compile Include="Integration\CreateContent.cs" />
@@ -311,6 +311,8 @@
<Compile Include="PublishedContent\StronglyTypedModels\Textpage.cs" />
<Compile Include="PublishedContent\StronglyTypedModels\TypedModelBase.cs" />
<Compile Include="PublishedContent\StronglyTypedModels\UmbracoTemplatePage`T.cs" />
<Compile Include="Scheduling\BackgroundTaskRunnerTests.cs" />
<Compile Include="ServerEnvironmentHelperTests.cs" />
<Compile Include="Services\TagServiceTests.cs" />
<Compile Include="Services\LocalizationServiceTests.cs" />
<Compile Include="Resolvers\XsltExtensionsResolverTests.cs" />
@@ -375,7 +377,7 @@
<Compile Include="PublishedContent\PublishedContentTests.cs" />
<Compile Include="PublishedContent\PublishedMediaTests.cs" />
<Compile Include="HashCodeCombinerTests.cs" />
<Compile Include="HtmlHelperExtensionMethodsTests.cs" />
<Compile Include="Mvc\HtmlHelperExtensionMethodsTests.cs" />
<Compile Include="IO\IOHelperTest.cs" />
<Compile Include="LibraryTests.cs" />
<Compile Include="PropertyEditors\PropertyEditorValueConverterTests.cs" />
@@ -462,15 +464,15 @@
<DependentUpon>ImportResources.resx</DependentUpon>
</Compile>
<Compile Include="Services\ThreadSafetyServiceTest.cs" />
<Compile Include="Surface\PluginControllerAreaTests.cs" />
<Compile Include="Sync\DistributedCacheTests.cs" />
<Compile Include="Controllers\PluginControllerAreaTests.cs" />
<Compile Include="DistributedCache\DistributedCacheTests.cs" />
<Compile Include="Templates\MasterPageHelperTests.cs" />
<Compile Include="TestHelpers\BaseDatabaseFactoryTest.cs" />
<Compile Include="TestHelpers\BaseRoutingTest.cs" />
<Compile Include="TestHelpers\BaseUmbracoApplicationTest.cs" />
<Compile Include="TestHelpers\DatabaseBehavior.cs" />
<Compile Include="TestHelpers\SettingsForTests.cs" />
<Compile Include="GlobalSettingsTests.cs" />
<Compile Include="Configurations\GlobalSettingsTests.cs" />
<Compile Include="Routing\ContentFinderByAliasTests.cs" />
<Compile Include="Routing\ContentFinderByIdTests.cs" />
<Compile Include="Routing\ContentFinderByNiceUrlAndTemplateTests.cs" />
@@ -488,11 +490,11 @@
<Compile Include="TestHelpers\Entities\MockedEntity.cs" />
<Compile Include="TestHelpers\Entities\MockedMedia.cs" />
<Compile Include="TestHelpers\DisposableUmbracoTest.cs" />
<Compile Include="Trees\BaseContentTreeTests.cs" />
<Compile Include="Trees\BaseMediaTreeTests.cs" />
<Compile Include="TreesAndSections\BaseContentTreeTests.cs" />
<Compile Include="TreesAndSections\BaseMediaTreeTests.cs" />
<Compile Include="UmbracoExamine\ContentServiceTest.cs" />
<Compile Include="UmbracoExamine\EventsTest.cs" />
<Compile Include="TypeHelperTests.cs" />
<Compile Include="Plugins\TypeHelperTests.cs" />
<Compile Include="UmbracoExamine\ExamineBaseTest.cs" />
<Compile Include="UmbracoExamine\IndexInitializer.cs" />
<Compile Include="UmbracoExamine\IndexTest.cs" />
@@ -512,11 +514,11 @@
<Compile Include="UriExtensionsTests.cs" />
<Compile Include="UriUtilityTests.cs" />
<Compile Include="Resolvers\MacroFieldEditorsResolverTests.cs" />
<Compile Include="MacroEngineFactoryTests.cs" />
<Compile Include="Macros\MacroEngineFactoryTests.cs" />
<Compile Include="MediaFactoryTests.cs" />
<Compile Include="Resolvers\PackageActionsResolverTests.cs" />
<Compile Include="PluginManagerExtensions.cs" />
<Compile Include="PluginManagerTests.cs" />
<Compile Include="Plugins\PluginManagerExtensions.cs" />
<Compile Include="Plugins\PluginManagerTests.cs" />
<Compile Include="TestHelpers\Stubs\FakeLastChanceFinder.cs" />
<Compile Include="TestHelpers\TestHelper.cs" />
<Compile Include="EnumerableExtensionsTests.cs" />
@@ -526,7 +528,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="CoreStrings\StringExtensionsTests.cs" />
<Compile Include="TestHelpers\FakeHttpContextFactory.cs" />
<Compile Include="TypeFinderTests.cs" />
<Compile Include="Plugins\TypeFinderTests.cs" />
<Compile Include="Routing\UmbracoModuleTests.cs" />
<Compile Include="XmlExtensionsTests.cs" />
<Compile Include="XmlHelperTests.cs" />
@@ -696,9 +698,7 @@
<Content Include="Services\Importing\uBlogsy-Package.xml" />
<Content Include="Services\Importing\XsltSearch-Package.xml" />
</ItemGroup>
<ItemGroup>
<Folder Include="Install\" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
@@ -86,8 +86,14 @@ function listViewController($rootScope, $scope, $routeParams, $injector, notific
$scope.pagination[i] = { index: i, name: i + 1 };
}
//NOTE: This might occur if we are requesting a higher page number than what is actually available, for example
// if you have more than one page and you delete all items on the last page. In this case, we need to reset to the last
// available page and then re-load again
if ($scope.options.pageNumber > $scope.listViewResultSet.totalPages) {
$scope.options.pageNumber = $scope.listViewResultSet.totalPages;
//reload!
$scope.reloadView(id);
}
});
@@ -1,7 +1,7 @@
<div class="umb-editor umb-multiple-textbox" ng-controller="Umbraco.PropertyEditors.MultipleTextBoxController">
<div class="control-group" ng-repeat="item in model.value">
<input type="text" name="item_{{$index}}" ng-model="item.value" />
<input type="text" name="item_{{$index}}" ng-model="item.value" class="umb-editor" />
<a prevent-default href="" title="Remove this text box"
ng-show="model.value.length > model.config.min"
ng-click="remove($index)">
+11 -6
View File
@@ -132,9 +132,9 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ImageProcessor.1.9.5.0\lib\ImageProcessor.dll</HintPath>
</Reference>
<Reference Include="ImageProcessor.Web, Version=3.2.2.0, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="ImageProcessor.Web, Version=3.3.1.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ImageProcessor.Web.3.3.0.0\lib\net45\ImageProcessor.Web.dll</HintPath>
<HintPath>..\packages\ImageProcessor.Web.3.3.1.0\lib\net45\ImageProcessor.Web.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="log4net, Version=1.2.11.0, Culture=neutral, processorArchitecture=MSIL">
@@ -199,6 +199,7 @@
</Reference>
<Reference Include="System.Net.Http.Formatting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.4.0.30506.0\lib\net40\System.Net.Http.Formatting.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.WebRequest, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@@ -223,9 +224,11 @@
</Reference>
<Reference Include="System.Web.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.4.0.30506.0\lib\net40\System.Web.Http.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Http.WebHost, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.4.0.30506.0\lib\net40\System.Web.Http.WebHost.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
@@ -2512,8 +2515,10 @@
<Folder Include="Views\Partials\" />
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">11.0</VisualStudioVersion>
<VSToolsPath Condition="exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v11.0')">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v11.0</VSToolsPath>
<VSToolsPath Condition="exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v12.0')">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v12.0</VSToolsPath>
<VSToolsPath Condition="exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v14.0')">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v14.0</VSToolsPath>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
@@ -2530,9 +2535,9 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.0\x86\*.* "$(TargetDir)x86\"
<WebProjectProperties>
<UseIIS>True</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>7180</DevelopmentServerPort>
<DevelopmentServerPort>7190</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:7180</IISUrl>
<IISUrl>http://localhost:7190</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
@@ -1,17 +1,11 @@
<?xml version="1.0"?>
<log4net>
<root>
<priority value="Info"/>
<appender-ref ref="AsynchronousLog4NetAppender" />
</root>
<!--To Change the way logging works for certain namespaces, insert a new logger like: -->
<!--
<logger name="Umbraco.Core">
<level value="WARN" />
</logger>-->
<appender name="AsynchronousLog4NetAppender" type="Umbraco.Core.Logging.AsynchronousRollingFileAppender, Umbraco.Core">
<file value="App_Data\Logs\UmbracoTraceLog.txt" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
@@ -23,4 +17,12 @@
</layout>
<encoding value="utf-8" />
</appender>
<!--Here you can change the way logging works for certain namespaces -->
<logger name="NHibernate">
<level value="WARN" />
</logger>
</log4net>
+10 -7
View File
@@ -1,17 +1,12 @@
<?xml version="1.0"?>
<log4net>
<root>
<priority value="Debug"/>
<appender-ref ref="AsynchronousLog4NetAppender" />
</root>
<!--To Change the way logging works for certain namespaces, insert a new logger like: -->
<!--
<logger name="Umbraco.Core">
<level value="WARN" />
</logger>-->
<appender name="AsynchronousLog4NetAppender" type="Umbraco.Core.Logging.AsynchronousRollingFileAppender, Umbraco.Core">
<file value="App_Data\Logs\UmbracoTraceLog.txt" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
@@ -23,4 +18,12 @@
</layout>
<encoding value="utf-8" />
</appender>
<!--Here you can change the way logging works for certain namespaces -->
<logger name="NHibernate">
<level value="WARN" />
</logger>
</log4net>
+1 -1
View File
@@ -5,7 +5,7 @@
<package id="ClientDependency-Mvc" version="1.7.0.4" targetFramework="net40" />
<package id="Examine" version="0.1.57.2941" targetFramework="net40" />
<package id="ImageProcessor" version="1.9.5.0" targetFramework="net45" />
<package id="ImageProcessor.Web" version="3.3.0.0" targetFramework="net45" />
<package id="ImageProcessor.Web" version="3.3.1.0" targetFramework="net45" />
<package id="log4net-mediumtrust" version="2.0.0" targetFramework="net40" />
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net40" />
<package id="Microsoft.AspNet.Mvc" version="4.0.30506.0" targetFramework="net40" />
+12 -6
View File
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<language alias="da" intName="Danish" localName="dansk" lcid="6" culture="da-DK">
<creator>
<name>The umbraco community</name>
<link>http://umbraco.org/documentation/language-files</link>
<name>The Umbraco community</name>
<link>http://our.umbraco.org/documentation/Extending-Umbraco/Language-Files</link>
</creator>
<area alias="actions">
<key alias="assignDomain">Tilføj domæne</key>
@@ -368,7 +368,7 @@
<key alias="databaseInstall"><![CDATA[Tryk på <strong>installér</strong> knappen for at installere Umbraco %0% databasen]]></key>
<key alias="databaseInstallDone"><![CDATA[Umbraco %0% er nu blevet kopieret til din database. Tryk på <string>Næste</strong> for at fortsætte.]]></key>
<key alias="databaseNotFound"><![CDATA[<p>Databasen er ikke fundet. Kontrollér venligst at informationen i database forbindelsesstrengen i "web.config" filen er korrekt.</p>
<p>For at fortsætte bedes du venligst rette "web.config" filen (ved at bruge Visual Studio eller dit favoritprogram), scroll til bunden, tilføj forbindelsesstrengen til din database i feltet som hedder "umbracoDbDSN" og gem filen.</p><p>Klik på <strong>Forsøg igen</strong> knappen når du er færdig.<br/><a href="http://umbraco.org/redir/installWebConfig" target="_blank">Mere information om at redigere web.config her.</a></p>]]></key>
<p>For at fortsætte bedes du venligst rette "web.config" filen (ved at bruge Visual Studio eller dit favoritprogram), scroll til bunden, tilføj forbindelsesstrengen til din database i feltet som hedder "umbracoDbDSN" og gem filen.</p><p>Klik på <strong>Forsøg igen</strong> knappen når du er færdig.<br/><a href="http://our.umbraco.org/documentation/Using-Umbraco/Config-files/webconfig7" target="_blank">Mere information om at redigere web.config her.</a></p>]]></key>
<key alias="databaseText"><![CDATA[For at afslutte dette skridt er du nødt til at have nogle informationer om din database parat ("database forbindelsesstrengen").<br/>Kontakt venligst din ISP hvis det er nødvendigt. Hvis du installerer på en lokal maskine eller server kan du muligvis få informationerne fra din systemadministrator.]]></key>
<key alias="databaseUpgrade"><![CDATA[<p>Tryk på <strong>Opgradér</strong> knappen for at opgradere din database til Umbraco %0%</p><p>Bare rolig - intet indhold vil blive slettet og alt vil stadig fungere bagefter!</p>]]></key>
<key alias="databaseUpgradeDone"><![CDATA[Din database er blevet opgraderet til den endelige version %0%.<br/>Tryk på <strong>Næste</strong> for at fortsætte.]]></key>
@@ -446,7 +446,7 @@
<key alias="timeout">Din session er udløbet</key>
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href="http://umbraco.org" style="text-decoration: none" target="_blank">umbraco.org</a></p> ]]></key>
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href="http://umbraco.com" style="text-decoration: none" target="_blank">umbraco.com</a></p> ]]></key>
</area>
<area alias="main">
<key alias="dashboard">Skrivebord</key>
@@ -481,7 +481,11 @@ Ha' en dejlig dag!
Mange hilsner fra umbraco robotten
]]></key>
<key alias="mailBodyHtml"><![CDATA[<p>Hej %0%</p> <p>Dette er en automatisk mail for at informere dig om at opgaven <strong>'%1%'</strong> er blevet udførtpå siden <a href="http://%4%/#/content/content/edit/%5%"><strong>'%2%'</strong></a> af brugeren <strong>'%3%'</strong> </p> <div style="margin: 8px 0; padding: 8px; display: block;"> <br /> <a style="color: white; font-weight: bold; background-color: #5372c3; text-decoration : none; margin-right: 20px; border: 8px solid #5372c3; width: 150px;" href="http://%4%/#/content/content/edit/%5%">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RET&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</a> &nbsp; <br /> </div> <p> <h3>Opdateringssammendrag:</h3> <table style="width: 100%;"> %6% </table> </p> <div style="margin: 8px 0; padding: 8px; display: block;"> <br /> <a style="color: white; font-weight: bold; background-color: #66cc66; text-decoration : none; margin-right: 20px; border: 8px solid #66cc66; width: 150px;" href="http://%4%/actions/publish.aspx?id=%5%">&nbsp;&nbsp;PUBLISÉR&nbsp;&nbsp;</a> &nbsp; <a style="color: white; font-weight: bold; background-color: #5372c3; text-decoration : none; margin-right: 20px; border: 8px solid #5372c3; width: 150px;" href="http://%4%/#/content/content/edit/%5%">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RET&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</a> &nbsp; <a style="color: white; font-weight: bold; background-color: #ca4a4a; text-decoration : none; margin-right: 20px; border: 8px solid #ca4a4a; width: 150px;" href="http://%4%/actions/delete.aspx?id=%5%">&nbsp;&nbsp;&nbsp;&nbsp;SLET&nbsp;&nbsp;&nbsp;&nbsp;</a> <br /> </div> <p>Hav en fortsat god dag!<br /><br /> De bedste hilsner fra umbraco robotten </p>]]></key>
<key alias="mailBodyHtml"><![CDATA[<p>Hej %0%</p>
<p>Dette er en automatisk mail for at informere dig om at opgaven <strong>'%1%'</strong>
er blevet udførtpå siden <a href="http://%4%/#/content/content/edit/%5%"><strong>'%2%'</strong></a> af brugeren <strong>'%3%'</strong> </p>
<div style="margin: 8px 0; padding: 8px; display: block;"> <br />
<a style="color: white; font-weight: bold; background-color: #5372c3; text-decoration : none; margin-right: 20px; border: 8px solid #5372c3; width: 150px;" href="http://%4%/#/content/content/edit/%5%">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RET&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</a> &nbsp; <br /> </div> <p> <h3>Opdateringssammendrag:</h3> <table style="width: 100%;"> %6% </table> </p> <div style="margin: 8px 0; padding: 8px; display: block;"> <br /> <a style="color: white; font-weight: bold; background-color: #66cc66; text-decoration : none; margin-right: 20px; border: 8px solid #66cc66; width: 150px;" href="http://%4%/actions/publish.aspx?id=%5%">&nbsp;&nbsp;PUBLISÉR&nbsp;&nbsp;</a> &nbsp; <a style="color: white; font-weight: bold; background-color: #5372c3; text-decoration : none; margin-right: 20px; border: 8px solid #5372c3; width: 150px;" href="http://%4%/#/content/content/edit/%5%">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RET&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</a> &nbsp; <a style="color: white; font-weight: bold; background-color: #ca4a4a; text-decoration : none; margin-right: 20px; border: 8px solid #ca4a4a; width: 150px;" href="http://%4%/actions/delete.aspx?id=%5%">&nbsp;&nbsp;&nbsp;&nbsp;SLET&nbsp;&nbsp;&nbsp;&nbsp;</a> <br /> </div> <p>Hav en fortsat god dag!<br /><br /> De bedste hilsner fra umbraco robotten </p>]]></key>
<key alias="mailSubject">[%0%] Notificering om %1% udført på %2%</key>
<key alias="notifications">Notificeringer</key>
</area>
@@ -542,7 +546,7 @@ Mange hilsner fra umbraco robotten
<key alias="inProgressCounter">%0% ud af %1% sider er blevet udgivet...</key>
<key alias="nodePublish">%0% er nu publiceret</key>
<key alias="nodePublishAll">%0% og alle undersider er nu publiceret</key>
<key alias="publishAll">Publisér alle undersider</key>
<key alias="publishAll">Publicér alle undersider</key>
<key alias="publishHelp"><![CDATA[Klik <em>ok</em> for at udgive <strong>%0%</strong> og derved gøre indholdet offentligt tilgængeligt..<br/><br /> Du kan udgive denne side og dens undersider ved at klikke <em>Udgiv alle undersider</em> forneden]]></key>
</area>
<area alias="relatedlinks">
@@ -596,6 +600,8 @@ Mange hilsner fra umbraco robotten
<key alias="tab">Faneblad</key>
<key alias="tabname">Titel på faneblad</key>
<key alias="tabs">Faneblade</key>
<key alias="masterDocumentType">Master Dokument Type</key>
<key alias="createMatchingTemplate">Opret matchende skabelon</key>
</area>
<area alias="sort">
<key alias="sortDone">Sortering udført</key>
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<language alias="de" intName="German" localName="Deutsch" lcid="7" culture="de-DE">
<creator>
<name>The German Umbraco Community</name>
<link>http://umbraco.org</link>
<name>The Umbraco community</name>
<link>http://our.umbraco.org/documentation/Extending-Umbraco/Language-Files</link>
</creator>
<area alias="actions">
<key alias="assignDomain">Hostnamen verwalten</key>
@@ -465,7 +465,7 @@ Wenn Sie sich für Runway entscheiden, können Sie optional Blöcke nutzen, die
<key alias="renewSession">Erneuern Sie, um Ihre Arbeit zu speichern ...</key>
</area>
<area alias="login">
<key alias="bottomText">&lt;p style="text-align:right;"&gt;&amp;copy; 2001 - %0% &lt;br /&gt;&lt;a href="http://umbraco.org" style="text-decoration: none" target="_blank"&gt;umbraco.org&lt;/a&gt;&lt;/p&gt; </key>
<key alias="bottomText">&lt;p style="text-align:right;"&gt;&amp;copy; 2001 - %0% &lt;br /&gt;&lt;a href="http://umbraco.com" style="text-decoration: none" target="_blank"&gt;umbraco.org&lt;/a&gt;&lt;/p&gt; </key>
<key alias="greeting1">Einen wunderbaren Sonntag</key>
<key alias="greeting6">Frohen freundlichen Freitag</key>
<key alias="greeting5">Donnerwetter Donnerstag</key>
+14 -12
View File
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<language alias="en" intName="English (UK)" localName="English (UK)" lcid="" culture="en-GB">
<creator>
<name>umbraco</name>
<link>http://umbraco.org</link>
<name>The Umbraco community</name>
<link>http://our.umbraco.org/documentation/Extending-Umbraco/Language-Files</link>
</creator>
<area alias="actions">
<key alias="assignDomain">Culture and Hostnames</key>
@@ -44,16 +44,16 @@
<key alias="invalidNode">Invalid node.</key>
<key alias="invalidDomain">Invalid domain format.</key>
<key alias="duplicateDomain">Domain has already been assigned.</key>
<key alias="domain">Domain</key>
<key alias="language">Language</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="domainUpdated">Domain '%0%' has been updated</key>
<key alias="orEdit">Edit Current Domains</key>
<key alias="domainHelp"><![CDATA[Valid domain names are: "example.com", "www.example.com", "example.com:8080" or
"https://www.example.com/".<br /><br />One-level paths in domains are supported, eg. "example.com/en". However, they
should be avoided. Better use the culture setting above.]]></key>
<key alias="domainUpdated">Domain '%0%' has been updated</key>
<key alias="orEdit">Edit Current Domains</key>
<key alias="inherit">Inherit</key>
<key alias="setLanguage">Culture</key>
<key alias="setLanguageHelp"><![CDATA[Set the culture for nodes below the current node,<br /> or inherit culture from parent nodes. Will also apply<br />
@@ -130,7 +130,7 @@
<key alias="itemChanged">This item has been changed after publication</key>
<key alias="itemNotPublished">This item is not published</key>
<key alias="lastPublished">Last published</key>
<key alias="listViewNoItems" version="7.1.5">There are no items show in the list.</key>
<key alias="listViewNoItems" version="7.1.5">There are no items to show in the list.</key>
<key alias="mediatype">Media Type</key>
<key alias="mediaLinks">Link to media item(s)</key>
<key alias="membergroup">Member Group</key>
@@ -418,11 +418,11 @@
Press the <strong>install</strong> button to install the Umbraco %0% database
]]></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">
done.<br /><a href="http://our.umbraco.org/documentation/Using-Umbraco/Config-files/webconfig7" 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 />
Please contact your ISP if necessary.
@@ -437,7 +437,7 @@
<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="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>
@@ -478,11 +478,11 @@
]]></key>
<key alias="runwayFromScratch">I want to start from scratch</key>
<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.
Your website is completely empty at the moment, so that's 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 alias="runwayHeader">Youve just set up a clean Umbraco platform. What do you want to do next?</key>
<key alias="runwayHeader">You've 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[
You have the foundation in place. Select what modules you wish to install on top of it.<br />
@@ -493,7 +493,7 @@
<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,
but you can easily edit, extend or remove it. It's not necessary and you can perfectly use Umbraco without it. However,
Runway offers an easy foundation based on best practices to get you started faster than ever.
If you choose to install Runway, you can optionally select basic building blocks called Runway Modules to enhance your Runway pages.
</p>
@@ -751,6 +751,8 @@ To manage your website, simply open the Umbraco back office and start adding con
<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>
<key alias="noPropertiesDefinedOnTab">No properties defined on this tab. Click on the "add a new property" link at the top to create a new property.</key>
<key alias="masterDocumentType">Master Document Type</key>
<key alias="createMatchingTemplate">Create matching template</key>
</area>
<area alias="sort">
<key alias="sortDone">Sorting complete.</key>
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<language alias="en_us" intName="English (US)" localName="English (US)" lcid="" culture="en-US">
<creator>
<name>umbraco</name>
<link>http://umbraco.org</link>
<name>The Umbraco community</name>
<link>http://our.umbraco.org/documentation/Extending-Umbraco/Language-Files</link>
</creator>
<area alias="actions">
<key alias="assignDomain">Culture and Hostnames</key>
@@ -133,6 +133,7 @@
<key alias="itemChanged">This item has been changed after publication</key>
<key alias="itemNotPublished">This item is not published</key>
<key alias="lastPublished">Last published</key>
<key alias="listViewNoItems" version="7.1.5">There are no items show in the list.</key>
<key alias="mediatype">Media Type</key>
<key alias="mediaLinks">Link to media item(s)</key>
<key alias="membergroup">Member Group</key>
@@ -152,6 +153,7 @@
<key alias="sortHelp">To sort the nodes, simply drag the nodes or click one of the column headers. You can select multiple nodes by holding the "shift" or "control" key while selecting</key>
<key alias="statistics">Statistics</key>
<key alias="titleOptional">Title (optional)</key>
<key alias="altTextOptional">Alternative text (optional)</key>
<key alias="type">Type</key>
<key alias="unPublish">Unpublish</key>
<key alias="updateDate">Last edited</key>
@@ -180,7 +182,7 @@
<area alias="dashboard">
<key alias="browser">Browse your website</key>
<key alias="dontShowAgain">- Hide</key>
<key alias="nothinghappens">If umbraco isn't opening, you might need to allow popups from this site</key>
<key alias="nothinghappens">If Umbraco isn't opening, you might need to allow popups from this site</key>
<key alias="openinnew">has opened in a new window</key>
<key alias="restart">Restart</key>
<key alias="visit">Visit</key>
@@ -208,7 +210,7 @@
<key alias="lastEdited">Last Edited</key>
<key alias="link">Link</key>
<key alias="linkinternal">Internal link:</key>
<key alias="linklocaltip">When using local links, insert "#" infront of link</key>
<key alias="linklocaltip">When using local links, insert "#" in front of link</key>
<key alias="linknewwindow">Open in new window?</key>
<key alias="macroContainerSettings">Macro Settings</key>
<key alias="macroDoesNotHaveProperties">This macro does not contain any properties you can edit</key>
@@ -222,7 +224,7 @@
<key alias="removeMacro">Remove Macro</key>
<key alias="requiredField">Required Field</key>
<key alias="sitereindexed">Site is reindexed</key>
<key alias="siterepublished">The website cache has been refreshed. All publish content is now uptodate. While all unpublished content is still unpublished</key>
<key alias="siterepublished">The website cache has been refreshed. All publish content is now up to date. While all unpublished content is still unpublished</key>
<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>
@@ -250,7 +252,8 @@
</area>
<area alias="editcontenttype">
<key alias="allowedchildnodetypes">Allowed child nodetypes</key>
<key alias="allowedchildnodetypes">Allowed child node types</key>
<key alias="contenttypecompositions">Document Type Compositions</key>
<key alias="create">Create</key>
<key alias="deletetab">Delete tab</key>
<key alias="description">Description</key>
@@ -274,7 +277,7 @@
</area>
<area alias="errorHandling">
<key alias="errorButDataWasSaved">Your data has been saved, but before you can publish this page there are some errors you need to fix first:</key>
<key alias="errorChangingProviderPassword">The current MemberShip Provider does not support changing password (EnablePasswordRetrieval need to be true)</key>
<key alias="errorChangingProviderPassword">The current membership provider does not support changing password (EnablePasswordRetrieval need to be true)</key>
<key alias="errorExistsWithoutTab">%0% already exists</key>
<key alias="errorHeader">There were errors:</key>
<key alias="errorHeaderWithoutTab">There were errors:</key>
@@ -288,7 +291,7 @@
<area alias="errors">
<key alias="dissallowedMediaType">The specified file type has been disallowed by the administrator</key>
<key alias="codemirroriewarning">NOTE! Even though CodeMirror is enabled by configuration, it is disabled in Internet Explorer because it's not stable enough.</key>
<key alias="contentTypeAliasAndNameNotNull">Please fill both alias and name on the new propertytype!</key>
<key alias="contentTypeAliasAndNameNotNull">Please fill both alias and name on the new property type!</key>
<key alias="filePermissionsError">There is a problem with read/write access to a specific file or folder</key>
<key alias="missingTitle">Please enter a title</key>
<key alias="missingType">Please choose a type</key>
@@ -423,11 +426,11 @@
Press the <strong>install</strong> button to install the Umbraco %0% database
]]></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">
done.<br /><a href="http://our.umbraco.org/documentation/Using-Umbraco/Config-files/webconfig7" 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 />
Please contact your ISP if necessary.
@@ -442,13 +445,13 @@
<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="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[
<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
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.
</p>
<p>
@@ -456,38 +459,38 @@
</p>
]]></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="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="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>
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="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>
<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>
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>
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[
umbraco needs write/modify access to certain directories in order to store files like pictures and PDF's.
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 alias="runwayFromScratch">I want to start from scratch</key>
<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.
Your website is completely empty at the moment, so that's 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 alias="runwayHeader">Youve just set up a clean Umbraco platform. What do you want to do next?</key>
<key alias="runwayHeader">You've 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[
You have the foundation in place. Select what modules you wish to install on top of it.<br />
@@ -498,7 +501,7 @@
<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,
but you can easily edit, extend or remove it. It's not necessary and you can perfectly use Umbraco without it. However,
Runway offers an easy foundation based on best practices to get you started faster than ever.
If you choose to install Runway, you can optionally select basic building blocks called Runway Modules to enhance your Runway pages.
</p>
@@ -511,25 +514,25 @@
<key alias="step1">Step 1/5 Accept license</key>
<key alias="step2">Step 2/5: Database configuration</key>
<key alias="step3">Step 3/5: Validating File Permissions</key>
<key alias="step4">Step 4/5: Check umbraco security</key>
<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="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>
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>,
<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>
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>
</area>
@@ -552,8 +555,7 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="instruction">log in below</key>
<key alias="timeout">Session timed out</key>
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href="http://umbraco.org" style="text-decoration: none" target="_blank">umbraco.org</a></p> ]]></key>
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href="http://umbraco.com" style="text-decoration: none" target="_blank">Umbraco.com</a></p> ]]></key>
</area>
<area alias="main">
@@ -588,7 +590,7 @@ To manage your website, simply open the umbraco back office and start adding con
Have a nice day!
Cheers from the umbraco robot
Cheers from the Umbraco robot
]]></key>
<key alias="mailBodyHtml"><![CDATA[<p>Hi %0%</p>
@@ -615,7 +617,7 @@ To manage your website, simply open the umbraco back office and start adding con
</div>
<p>Have a nice day!<br /><br />
Cheers from the umbraco robot
Cheers from the Umbraco robot
</p>]]></key>
<key alias="mailSubject">[%0%] Notification about %1% performed on %2%</key>
<key alias="notifications">Notifications</key>
@@ -623,7 +625,7 @@ To manage your website, simply open the umbraco back office and start adding con
<area alias="packager">
<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.
button and locating the package. Umbraco packages usually have a ".umb" or ".zip" extension.
]]></key>
<key alias="packageAuthor">Author</key>
<key alias="packageDemonstration">Demonstration</key>
@@ -647,20 +649,20 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="packageUpgradeDownload">Download update from the repository</key>
<key alias="packageUpgradeHeader">Upgrade package</key>
<key alias="packageUpgradeInstructions">Upgrade instructions</key>
<key alias="packageUpgradeText"> There's an upgrade available for this package. You can download it directly from the umbraco package repository.</key>
<key alias="packageUpgradeText"> There's an upgrade available for this package. You can download it directly from the Umbraco package repository.</key>
<key alias="packageVersion">Package version</key>
<key alias="packageVersionHistory">Package version history</key>
<key alias="viewPackageWebsite">View package website</key>
</area>
<area alias="paste">
<key alias="doNothing">Paste with full formatting (Not recommended)</key>
<key alias="errorMessage">The text you're trying to paste contains special characters or formatting. This could be caused by copying text from Microsoft Word. umbraco can remove special characters or formatting automatically, so the pasted content will be more suitable for the web.</key>
<key alias="errorMessage">The text you're trying to paste contains special characters or formatting. This could be caused by copying text from Microsoft Word. Umbraco can remove special characters or formatting automatically, so the pasted content will be more suitable for the web.</key>
<key alias="removeAll">Paste as raw text without any formatting at all</key>
<key alias="removeSpecialFormattering">Paste, but remove formatting (Recommended)</key>
</area>
<area alias="publicAccess">
<key alias="paAdvanced">Role based protection</key>
<key alias="paAdvancedHelp"><![CDATA[If you wish to control access to the page using role-based authentication,<br /> using umbraco's member groups.]]></key>
<key alias="paAdvancedHelp"><![CDATA[If you wish to control access to the page using role-based authentication,<br /> using Umbraco's member groups.]]></key>
<key alias="paAdvancedNoGroups"><![CDATA[You need to create a membergroup before you can use <br />role-based authentication.]]></key>
<key alias="paErrorPage">Error Page</key>
<key alias="paErrorPageHelp">Used when people are logged on, but do not have access</key>
@@ -668,7 +670,7 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="paIsProtected">%0% is now protected</key>
<key alias="paIsRemoved">Protection removed from %0%</key>
<key alias="paLoginPage">Login Page</key>
<key alias="paLoginPageHelp">Choose the page that has the login formular</key>
<key alias="paLoginPageHelp">Choose the page that contains the login form</key>
<key alias="paRemoveProtection">Remove Protection</key>
<key alias="paSelectPages">Select the pages that contain login form and error messages</key>
<key alias="paSelectRoles">Pick the roles who have access to this page</key>
@@ -686,7 +688,7 @@ To manage your website, simply open the umbraco back office and start adding con
%0% could not be published because these properties: %1% did not pass validation rules.
]]></key>
<key alias="contentPublishedFailedByEvent"><![CDATA[
%0% could not be published, due to a 3rd party extension cancelling the action.
%0% could not be published, a 3rd party add-in cancelled the action.
]]></key>
<key alias="contentPublishedFailedByParent"><![CDATA[
%0% can not be published, because a parent page is not published.
@@ -698,7 +700,7 @@ To manage your website, simply open the umbraco back office and start adding con
<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 its content publicly available.<br/><br />
You can publish this page and all its sub-pages by checking <em>publish all children</em> below.
You can publish this page and all it's sub-pages by checking <em>publish all children</em> below.
]]></key>
</area>
<area alias="colorpicker">
@@ -720,7 +722,7 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="currentVersion">Current version</key>
<key alias="diffHelp"><![CDATA[This shows the differences between the current version and the selected version<br /><del>Red</del> text will not be shown in the selected version. , <ins>green means added</ins>]]></key>
<key alias="documentRolledBack">Document has been rolled back</key>
<key alias="htmlHelp">This displays the selected version as html, if you wish to see the difference between 2 versions at the same time, use the diff view</key>
<key alias="htmlHelp">This displays the selected version as HTML, if you wish to see the difference between 2 versions at the same time, use the diff view</key>
<key alias="rollbackTo">Rollback to</key>
<key alias="selectVersion">Select version</key>
<key alias="view">View</key>
@@ -743,13 +745,14 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="users">Users</key>
<key alias="help" version="7.0">Help</key>
<key alias="analytics">Analytics</key>
</area>
<area alias="settings">
<key alias="defaulttemplate">Default template</key>
<key alias="dictionary editor egenskab">Dictionary Key</key>
<key alias="importDocumentTypeHelp">To import a document type, find the ".udt" file on your computer by clicking the "Browse" button and click "Import" (you'll be asked for confirmation on the next screen)</key>
<key alias="newtabname">New Tab Title</key>
<key alias="nodetype">Nodetype</key>
<key alias="nodetype">Node type</key>
<key alias="objecttype">Type</key>
<key alias="stylesheet">Stylesheet</key>
<key alias="script">Script</key>
@@ -761,6 +764,8 @@ To manage your website, simply open the umbraco back office and start adding con
<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>
<key alias="noPropertiesDefinedOnTab">No properties defined on this tab. Click on the "add a new property" link at the top to create a new property.</key>
<key alias="masterDocumentType">Master Document Type</key>
<key alias="createMatchingTemplate">Create matching template</key>
</area>
<area alias="sort">
<key alias="sortDone">Sorting complete.</key>
@@ -836,9 +841,9 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="insertContentAreaPlaceHolder">Insert content area placeholder</key>
<key alias="insertDictionaryItem">Insert dictionary item</key>
<key alias="insertMacro">Insert Macro</key>
<key alias="insertPageField">Insert umbraco page field</key>
<key alias="insertPageField">Insert Umbraco page field</key>
<key alias="mastertemplate">Master template</key>
<key alias="quickGuide">Quick Guide to umbraco template tags</key>
<key alias="quickGuide">Quick Guide to Umbraco template tags</key>
<key alias="template">Template</key>
</area>
<area alias="templateEditor">
@@ -847,8 +852,8 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="casing">Casing</key>
<key alias="encoding">Encoding</key>
<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="convertLineBreaks">Convert line breaks</key>
<key alias="convertLineBreaksHelp">Replaces line breaks with html-tag &amp;lt;br&amp;gt;</key>
<key alias="customFields">Custom Fields</key>
<key alias="dateOnly">Yes, Date only</key>
<key alias="formatAsDate">Format as date</key>
@@ -879,9 +884,9 @@ To manage your website, simply open the umbraco back office and start adding con
]]></key>
<key alias="closeTask">close task</key>
<key alias="details">Translation details</key>
<key alias="downloadAllAsXml">Download all translation tasks as xml</key>
<key alias="downloadTaskAsXml">Download xml</key>
<key alias="DownloadXmlDTD">Download xml DTD</key>
<key alias="downloadAllAsXml">Download all translation tasks as XML</key>
<key alias="downloadTaskAsXml">Download XML</key>
<key alias="DownloadXmlDTD">Download XML DTD</key>
<key alias="fields">Fields</key>
<key alias="includeSubpages">Include subpages</key>
<key alias="mailBody"><![CDATA[
@@ -892,12 +897,12 @@ To manage your website, simply open the umbraco back office and start adding con
Go to http://%3%/translation/details.aspx?id=%4% to edit.
Or log into umbraco to get an overview of your translation tasks
Or log into Umbraco to get an overview of your translation tasks
http://%3%
Have a nice day!
Cheers from the umbraco robot
Cheers from the Umbraco robot
]]></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>
@@ -914,10 +919,10 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="translateTo">Translate to</key>
<key alias="translationDone">Translation completed.</key>
<key alias="translationDoneHelp">You can preview the pages, you've just translated, by clicking below. If the original page is found, you will get a comparison of the 2 pages.</key>
<key alias="translationFailed">Translation failed, the xml file might be corrupt</key>
<key alias="translationFailed">Translation failed, the XML file might be corrupt</key>
<key alias="translationOptions">Translation options</key>
<key alias="translator">Translator</key>
<key alias="uploadTranslationXml">Upload translation xml</key>
<key alias="uploadTranslationXml">Upload translation XML</key>
</area>
<area alias="treeHeaders">
<key alias="cacheBrowser">Cache Browser</key>
@@ -948,6 +953,7 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="stylesheets">Stylesheets</key>
<key alias="templates">Templates</key>
<key alias="xslt">XSLT Files</key>
<key alias="analytics">Analytics</key>
</area>
<area alias="update">
<key alias="updateAvailable">New update ready</key>
+136 -45
View File
@@ -1,13 +1,14 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<language alias="es" intName="Spanish" localName="español" lcid="10" culture="es-ES">
<creator>
<name>The umbraco community</name>
<link>http://umbraco.org/documentation/language-files</link>
<name>The Umbraco community</name>
<link>http://our.umbraco.org/documentation/Extending-Umbraco/Language-Files</link>
</creator>
<area alias="actions">
<key alias="assignDomain">Administrar hostnames</key>
<key alias="auditTrail">Auditoría</key>
<key alias="browse">Nodo de Exploración</key>
<key alias="changeDocType">Cambiar tipo de documento</key>
<key alias="copy">Copiar</key>
<key alias="create">Crear</key>
<key alias="createPackage">Crear Paquete</key>
@@ -15,8 +16,6 @@
<key alias="disable">Deshabilitar</key>
<key alias="emptyTrashcan">Vaciar Papelera</key>
<key alias="exportDocumentType">Exportar Documento (tipo)</key>
<key alias="exportDocumentTypeAsCode">TRANSLATE ME: 'Export to .NET'</key>
<key alias="exportDocumentTypeAsCode-Full">TRANSLATE ME: 'Export to .NET'</key>
<key alias="importDocumentType">Importar Documento (tipo)</key>
<key alias="importPackage">Importar Paquete</key>
<key alias="liveEdit">Editar en lienzo</key>
@@ -25,6 +24,7 @@
<key alias="notify">Notificaciones</key>
<key alias="protect">Acceso Público</key>
<key alias="publish">Publicar</key>
<key alias="unpublish">Unpublish</key>
<key alias="refreshNode">Recargar Nodos</key>
<key alias="republish">Republicar sitio completo</key>
<key alias="rights">Permisos</key>
@@ -35,21 +35,42 @@
<key alias="toPublish">Enviar a publicación</key>
<key alias="translate">Traducir</key>
<key alias="update">Actualizar</key>
<key alias="defaultValue">Default value</key>
</area>
<area alias="assignDomain">
<key alias="permissionDenied">Permission denied.</key>
<key alias="addNew">Añadir nuevo dominio</key>
<key alias="remove">remove</key>
<key alias="invalidNode">Invalid node.</key>
<key alias="invalidDomain">Invalid domain format.</key>
<key alias="duplicateDomain">Domain has already been assigned.</key>
<key alias="language">Language</key>
<key alias="domain">Dominio</key>
<key alias="domainCreated">El nuevo dominio %0% ha sido creado</key>
<key alias="domainDeleted">El dominio %0% ha sido borrado</key>
<key alias="domainExists">El dominio'%0%' ya ha sido asignado</key>
<key alias="domainHelp">p.ej.: tudominio.com, www.tudominio.com</key>
<key alias="domainUpdated">El dominio %0% ha sido actualizado</key>
<key alias="orEdit">Editar dominios actuales</key>
<key alias="domainHelp">
<![CDATA[Valid domain names are: "example.com", "www.example.com", "example.com:8080" or
"https://www.example.com/".<br /><br />One-level paths in domains are supported, eg. "example.com/en". However, they
should be avoided. Better use the culture setting above.]]>
</key>
<key alias="inherit">Inherit</key>
<key alias="setLanguage">Culture</key>
<key alias="setLanguageHelp">
<![CDATA[Set the culture for nodes below the current node,<br /> or inherit culture from parent nodes. Will also apply<br />
to the current node, unless a domain below applies too.]]>
</key>
<key alias="setDomains">Domains</key>
</area>
<area alias="auditTrails">
<key alias="atViewingFor">Visualización de</key>
</area>
<area alias="buttons">
<key alias="select">Select</key>
<key alias="selectCurrentFolder">Select current folder</key>
<key alias="somethingElse">Do something else</key>
<key alias="bold">Negrita</key>
<key alias="deindent">Cancelar Sangría del Párrafo </key>
<key alias="formFieldInsert">Insertar campo de formulario</key>
@@ -71,10 +92,31 @@
<key alias="saveAndPublish">Guardar y publicar</key>
<key alias="saveToPublish">Guardar y enviar para aprobación</key>
<key alias="showPage">Previsualizar</key>
<key alias="showPageDisabled">Preview is disabled because there's no template assigned</key>
<key alias="styleChoose">Elegir estilo</key>
<key alias="styleShow">Mostrar estilos</key>
<key alias="tableInsert">Insertar tabla</key>
</area>
<area alias="changeDocType">
<key alias="changeDocTypeInstruction">To change the document type for the selected content, first select from the list of valid types for this location.</key>
<key alias="changeDocTypeInstruction2">Then confirm and/or amend the mapping of properties from the current type to the new, and click Save.</key>
<key alias="contentRepublished">The content has been re-published.</key>
<key alias="currentProperty">Current Property</key>
<key alias="currentType">Current type</key>
<key alias="docTypeCannotBeChanged">The document type cannot be changed, as there are no alternatives valid for this location.</key>
<key alias="docTypeChanged">Document Type Changed</key>
<key alias="mapProperties">Map Properties</key>
<key alias="mapToProperty">Map to Property</key>
<key alias="newTemplate">New Template</key>
<key alias="newType">New Type</key>
<key alias="none">none</key>
<key alias="selectedContent">Content</key>
<key alias="selectNewDocType">Select New Document Type</key>
<key alias="successMessage">The document type of the selected content has been successfully changed to [new type] and the following properties mapped:</key>
<key alias="to">to</key>
<key alias="validationErrorPropertyWithMoreThanOneMapping">Could not complete property mapping as one or more properties have more than one mapping defined.</key>
<key alias="validDocTypesNote">Only alternate types valid for the current location are displayed.</key>
</area>
<area alias="content">
<key alias="about">Acerca de</key>
<key alias="alias">Link alternativo</key>
@@ -82,7 +124,10 @@
<key alias="alternativeUrls">Vinculos Alternativos</key>
<key alias="clickToEdit">Click para editar esta entrada</key>
<key alias="createBy">Creado por</key>
<key alias="createByDesc" version="7.0">Autor original</key>
<key alias="updatedBy" version="7.0">Actualizado por</key>
<key alias="createDate">Creado</key>
<key alias="createDateDesc" version="7.0">Fecha/hora de creación del documento</key>
<key alias="documentType">Tipo de Documento</key>
<key alias="editing">Editando</key>
<key alias="expireDate">Remover el</key>
@@ -97,9 +142,11 @@
<key alias="nodeName">Título de la página</key>
<key alias="otherElements">Propiedades</key>
<key alias="parentNotPublished">Este documento ha sido publicado pero no es visible porque el padre '%0%' no esta publicado</key>
<key alias="parentNotPublishedAnomaly">Oops: this document is published but is not in the cache (internal error)</key>
<key alias="publish">Publicar</key>
<key alias="publishStatus">Estado de la Publicación</key>
<key alias="releaseDate">Publicar el</key>
<key alias="unpublishDate">Despublicar el</key>
<key alias="removeDate">Fecha de Eliminación</key>
<key alias="sortDone">El Orden esta actualizado</key>
<key alias="sortHelp">Para organizar los nodos, simplemente arrastre los nodos o realice un clic en uno de los encabezados de columna. Puede seleccionar multiple nodos manteniendo presionados "Shift" o "Control" mientras selecciona</key>
@@ -108,17 +155,28 @@
<key alias="type">Tipo</key>
<key alias="unPublish">No Publicar</key>
<key alias="updateDate">Última actualización</key>
<key alias="updateDateDesc" version="7.0">Fecha/hora este documento fue modificado</key>
<key alias="uploadClear">Eliminar archivo</key>
<key alias="urls">Vínculo al documento</key>
<key alias="memberof">Member of group(s)</key>
<key alias="notmemberof">Not a member of group(s)</key>
<key alias="childItems" version="7.0">Child items</key>
<key alias="target" version="7.0">Target</key>
</area>
<area alias="media">
<key alias="clickToUpload">Click to upload</key>
<key alias="dropFilesHere">Drop your files here...</key>
</area>
<area alias="create">
<key alias="chooseNode">¿Dónde quieres crear el nuevo %0%</key>
<key alias="createUnder">Crear debajo de</key>
<key alias="updateData">Elije un tipo y un título</key>
<key alias="noDocumentTypes" version="7.0"><![CDATA[There are no allowed document types available. You must enable these in the settings section under <strong>"document types"</strong>.]]></key>
<key alias="noMediaTypes" version="7.0"><![CDATA[There are no allowed media types available. You must enable these in the settings section under <strong>"media types"</strong>.]]></key>
</area>
<area alias="dashboard">
<key alias="browser">Navega en tu sitio Web</key>
<key alias="dontShowAgain">TRANSLATE ME: '- Hide'</key>
<key alias="dontShowAgain">No volver a mostrar</key>
<key alias="nothinghappens">Si Umbraco no se ha abierto tendrás que permitir ventanas emergentes para este sitio Web</key>
<key alias="openinnew">se ha abierto en una nueva ventana</key>
<key alias="restart">Reinicio</key>
@@ -134,11 +192,11 @@
<key alias="confirmEmptyTrashcan">Por favor seleccione esta casilla para confirmar la eliminación de %0% entrada(s)</key>
<key alias="confirmlogout">Esta usted seguro?</key>
<key alias="confirmSure">Esta usted Seguro?</key>
<key alias="cut">TRANSLATE ME: 'Cut'</key>
<key alias="cut">Cortar</key>
<key alias="editdictionary">Editar entrada del Diccionario</key>
<key alias="editlanguage">Editar idioma</key>
<key alias="insertAnchor">Agregar enlace interno</key>
<key alias="insertCharacter">TRANSLATE ME: 'Insert character'</key>
<key alias="insertCharacter">Insertar caracter</key>
<key alias="insertgraphicheadline">Insertar titular gráfico</key>
<key alias="insertimage">Insertar imagen</key>
<key alias="insertlink">Insertar enlace</key>
@@ -149,7 +207,7 @@
<key alias="linkinternal">Enlace interno</key>
<key alias="linklocaltip">Al usar enlaces locales, insertar "#" delante del enlace</key>
<key alias="linknewwindow">¿Abrir en nueva ventana?</key>
<key alias="macroContainerSettings">TRANSLATE ME: 'Macro Settings'</key>
<key alias="macroContainerSettings">Ajustes para la Macro</key>
<key alias="macroDoesNotHaveProperties">Esta macro no contiene ninguna propiedad que pueda editar</key>
<key alias="paste">Pegar</key>
<key alias="permissionsEdit">Editar permisos para</key>
@@ -158,7 +216,7 @@
<key alias="recycleBinWarning">No podrá recuperar los items una vez sean borrados de la papelera</key>
<key alias="regexSearchError"><![CDATA[El servicio web <a target='_blank' href='http://regexlib.com'>regexlib.com</a> está experimentando algunos problemas en estos momentos, de los cuales no somos responsables. Pedimos disculpas por las molestias.]]></key>
<key alias="regexSearchHelp">Buscar una expresión regular para agregar validación a un campo de formulario. Ejemplo: 'correo electrónico', código postal "," url "</key>
<key alias="removeMacro">TRANSLATE ME: 'Remove Macro'</key>
<key alias="removeMacro">Eliminar macro</key>
<key alias="requiredField">Campo obligatorio</key>
<key alias="sitereindexed">El sitio ha sido reindexado</key>
<key alias="siterepublished">Se ha actualizado la caché y se ha publicado el contenido del sitio web.</key>
@@ -176,14 +234,24 @@
<key alias="displayName"><![CDATA[nombre de la cultura
]]></key>
</area>
<area alias="placeholders">
<key alias="username">Introduzca su nombre de usuario</key>
<key alias="password">Introduzca su contraseña</key>
<key alias="nameentity">Nombre de %0%...</key>
<key alias="entername">Introduzca un nombre ...</key>
<key alias="search">Buscar ...</key>
<key alias="filter">Filtrar ...</key>
</area>
<area alias="editcontenttype">
<key alias="allowedchildnodetypes">Tipos de nodos hijos permitidos</key>
<key alias="contenttypecompositions">Document Type Compositions</key>
<key alias="create">Crear</key>
<key alias="deletetab">Borrar pestaña</key>
<key alias="description">TRANSLATE ME: 'Description'</key>
<key alias="description">Descripción</key>
<key alias="newtab">Nueva pestaña</key>
<key alias="tab">Pestaña</key>
<key alias="thumbnail">TRANSLATE ME: 'Thumbnail'</key>
<key alias="thumbnail">Miniatura</key>
<key alias="hasListView">Enable list view</key>
</area>
<area alias="editdatatype">
<key alias="addPrevalue">añadir prevalor</key>
@@ -215,7 +283,7 @@
<key alias="errorRegExpWithoutTab">Debe poner un formato correcto en %0%</key>
</area>
<area alias="errors">
<key alias="codemirroriewarning">TRANSLATE ME: 'NOTE! Even though CodeMirror is enabled by configuration, it is disabled in Internet Explorer because it's not stable enough.'</key>
<key alias="codemirroriewarning">NOTA: Aunque CodeMirror esté activado en los ajustes de configuracion, no se muestra en Internet Explorer debido a que no es lo suficientemente estable.'</key>
<key alias="contentTypeAliasAndNameNotNull">Debe llenar el alias y el nombre en el propertytype</key>
<key alias="filePermissionsError">Hay un problema de lectura y escritura al acceder a un archivo o carpeta</key>
<key alias="missingTitle"><![CDATA[Por favor, introduzca un título
@@ -239,6 +307,7 @@
<area alias="general">
<key alias="about">Acerca de</key>
<key alias="action">Acción</key>
<key alias="actions">Acciones</key>
<key alias="add">Añadir</key>
<key alias="alias">Alias</key>
<key alias="areyousure">¿Está seguro?</key>
@@ -268,7 +337,7 @@
<key alias="edit">Editar</key>
<key alias="edited">Editado</key>
<key alias="elements">Elementos</key>
<key alias="email">Email</key>
<key alias="email">Mail</key>
<key alias="error">Error</key>
<key alias="findDocument">Buscar</key>
<key alias="height">Altura</key>
@@ -282,7 +351,7 @@
<key alias="language">Idioma</key>
<key alias="layout">Diseño</key>
<key alias="loading">Cargando</key>
<key alias="locked">TRANSLATE ME: 'Locked'</key>
<key alias="locked">Bloqueado</key>
<key alias="login">Iniciar sesión</key>
<key alias="logoff">Cerrar sesión</key>
<key alias="logout">Cerrar sesión</key>
@@ -302,11 +371,11 @@
<key alias="pleasewait">Un momento por favor...</key>
<key alias="previous">Anterior</key>
<key alias="properties">Propiedades</key>
<key alias="reciept">Email para recibir los datos del formulario</key>
<key alias="reciept">Mail para recibir los datos del formulario</key>
<key alias="recycleBin">Papelera</key>
<key alias="remaining">Restantes</key>
<key alias="rename">Renombrar</key>
<key alias="renew">TRANSLATE ME: 'Renew'</key>
<key alias="renew">Renovar</key>
<key alias="retry">Reintentar</key>
<key alias="rights">Permisos</key>
<key alias="search">Buscar</key>
@@ -347,7 +416,7 @@
<key alias="databaseHeader">Configuración de la base de datos</key>
<key alias="databaseInstall"><![CDATA[Pulse el botón <strong> instalar </ strong> para instalar %0% la base de datos de Umbraco]]></key>
<key alias="databaseInstallDone"><![CDATA[Se ha copiado Umbraco %0% a la base de datos. Pulse <strong>Próximo</strong> para continuar]]></key>
<key alias="databaseNotFound"><![CDATA[<p>¡No se ha encontrado ninguna base de datos! Mira si la información en la "connection string" del “web.config” es correcta.</p> <p>Para continuar, edite el "web.config" (bien sea usando Visual Studio o su editor de texto preferido), vaya al final del archivo y añada la cadena de conexión para la base de datos con el nombre (key) "umbracoDbDSN" y guarde el archivo. </p> <p>Pinche en <strong>reintentar</strong> cuando haya terminado.<br /><a href="http://umbraco.org/redir/installWebConfig" target="_blank">Pinche aquí para mayor información de como editar el web.config (en inglés)</a></p>]]></key>
<key alias="databaseNotFound"><![CDATA[<p>¡No se ha encontrado ninguna base de datos! Mira si la información en la "connection string" del “web.config” es correcta.</p> <p>Para continuar, edite el "web.config" (bien sea usando Visual Studio o su editor de texto preferido), vaya al final del archivo y añada la cadena de conexión para la base de datos con el nombre (key) "umbracoDbDSN" y guarde el archivo. </p> <p>Pinche en <strong>reintentar</strong> cuando haya terminado.<br /><a href="http://our.umbraco.org/documentation/Using-Umbraco/Config-files/webconfig7" target="_blank">Pinche aquí para mayor información de como editar el web.config (en inglés)</a></p>]]></key>
<key alias="databaseText"><![CDATA[Para completar este paso, debes conocer la información correspondiente a tu servidor de base de datos ("cadena de conexión").<br /> Por favor, contacta con tu ISP si es necesario. Si estás realizando la instalación en una máquina o servidor local, quizás necesites información de tu administrador de sistemas.]]></key>
<key alias="databaseUpgrade"><![CDATA[<p> Pinche en <strong>actualizar</strong> para actualizar la base de datos a Umbraco %0%</p> <p> Ningún contenido será borrado de la base de datos y seguirá funcionando después de la actualización </p> ]]></key>
<key alias="databaseUpgradeDone"><![CDATA[La base de datos ha sido actualizada a la versión 0%.<br />Pinche en <strong>Próximo</strong> para continuar. ]]></key>
@@ -407,13 +476,23 @@ However, Runway offers an easy foundation based on best practices to get you sta
<key alias="displayName">Nombre de cultura</key>
</area>
<area alias="lockout">
<key alias="lockoutWillOccur">TRANSLATE ME: 'You've been idle and logout will automatically occur in'</key>
<key alias="renewSession">TRANSLATE ME: 'Renew now to save your work'</key>
<key alias="lockoutWillOccur">No ha habido ninguna actividad y su sessión se cerrará en </key>
<key alias="renewSession">Renovar su sessión para guardar sus cambios</key>
</area>
<area alias="login">
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href="http://umbraco.org" style="text-decoration: none" target="_blank">umbraco.org</a></p> ]]></key>
<key alias="greeting0">Feliz Domingo</key>
<key alias="greeting1">Feliz Lunes</key>
<key alias="greeting2">Feliz Martes</key>
<key alias="greeting3">Feliz Miércoles</key>
<key alias="greeting4">Feliz Jueves</key>
<key alias="greeting5">Feliz Viernes</key>
<key alias="greeting6">Feliz Sábado</key>
<key alias="instruction">Introduce abajo</key>
<key alias="timeout">Session timed out</key>
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href="http://umbraco.com" style="text-decoration: none" target="_blank">umbraco.com</a></p> ]]></key>
<key alias="topText">Bienvenido a umbraco, escribe tu nombre de usuario y clave en los campos de debajo:</key>
</area>
<area alias="main">
<key alias="dashboard">Panel de Administración</key>
<key alias="sections">Secciones</key>
@@ -429,7 +508,7 @@ However, Runway offers an easy foundation based on best practices to get you sta
<key alias="noNodeSelected">No ha seleccionado ningún nodo. Seleccione un nodo en la lista mostrada arriba antes the pinchar en 'continuar' (continue)</key>
<key alias="notAllowedByContentType">No se puede colgar el nodo actual bajo el nodo elegido debido a su tipo</key>
<key alias="notAllowedByPath">El nodo actual no puede moverse a ninguna de sus subpáginas</key>
<key alias="notValid">TRANSLATE ME: 'The action isn't allowed since you have insufficient permissions on 1 or more child documents.'</key>
<key alias="notValid">Acción no permitida. No tiene permisos suficientes para uno o más subnodos.'</key>
</area>
<area alias="notifications">
<key alias="editNotifications">Edite su notificación para %0%</key>
@@ -499,16 +578,16 @@ However, Runway offers an easy foundation based on best practices to get you sta
<key alias="publishHelp"><![CDATA[Pulsa en <em>aceptar</em> para publicar <strong>%0%</strong> y por lo tanto, hacer que su contenido esté disponible al público.<br/><br /> Puedes publicar esta página y todas sus subpáginas marcando <em>publicar todos los hijos</em> debajo. ]]></key>
</area>
<area alias="relatedlinks">
<key alias="addExternal">TRANSLATE ME: 'Add external link'</key>
<key alias="addInternal">TRANSLATE ME: 'Add internal link'</key>
<key alias="addlink">TRANSLATE ME: 'Add'</key>
<key alias="caption">TRANSLATE ME: 'Caption'</key>
<key alias="internalPage">TRANSLATE ME: 'Internal page'</key>
<key alias="linkurl">TRANSLATE ME: 'URL'</key>
<key alias="modeDown">TRANSLATE ME: 'Move Down'</key>
<key alias="modeUp">TRANSLATE ME: 'Move Up'</key>
<key alias="newWindow">TRANSLATE ME: 'Open in new window'</key>
<key alias="removeLink">TRANSLATE ME: 'Remove link'</key>
<key alias="addExternal">Añadir un enlace externo</key>
<key alias="addInternal">Añadir un enlace interno</key>
<key alias="addlink">Añadir</key>
<key alias="caption">Título</key>
<key alias="internalPage">Página interna</key>
<key alias="linkurl">Enlace</key>
<key alias="modeDown">Bajar</key>
<key alias="modeUp">Subir</key>
<key alias="newWindow">Abrir en una nueva ventana</key>
<key alias="removeLink">Quitar el enlace</key>
</area>
<area alias="rollback">
<key alias="currentVersion">Versión actual</key>
@@ -535,6 +614,8 @@ However, Runway offers an easy foundation based on best practices to get you sta
<key alias="statistics">Estadísticas</key>
<key alias="translation">Traducción</key>
<key alias="users">Usuarios</key>
<key alias="help" version="7.0">Ayuda</key>
<key alias="analytics">Analytics</key>
</area>
<area alias="settings">
<key alias="defaulttemplate">Plantilla por defecto</key>
@@ -548,6 +629,8 @@ However, Runway offers an easy foundation based on best practices to get you sta
<key alias="tab">Pestaña</key>
<key alias="tabname">Nombre de la pestaña</key>
<key alias="tabs">Pestañas</key>
<key alias="masterDocumentType">Tipo de documento Maestro</key>
<key alias="createMatchingTemplate">Crear template correspondiente</key>
</area>
<area alias="sort">
<key alias="sortDone">Ordenación completa.</key>
@@ -661,7 +744,7 @@ However, Runway offers an easy foundation based on best practices to get you sta
<key alias="mailBody"><![CDATA[
Hola %0%.
Este email se ha generado automáticamente para informale que %2% ha solicitado que el documento '%1%' sea traducido en '%5%'.
Este mail se ha generado automáticamente para informale que %2% ha solicitado que el documento '%1%' sea traducido en '%5%'.
Para editarlo, vaya a la dirección http://%3%/translation/details.aspx?id=%4% o inicie la sesión en umbraco y vaya a http://%3% para ver las tareas pendientes de traducir.
@@ -693,8 +776,8 @@ However, Runway offers an easy foundation based on best practices to get you sta
<key alias="datatype">Tipos de datos</key>
<key alias="dictionary">Diccionario</key>
<key alias="installedPackages">Paquetes instalados</key>
<key alias="installSkin">TRANSLATE ME: 'Install skin'</key>
<key alias="installStarterKit">TRANSLATE ME: 'Install starter kit'</key>
<key alias="installSkin">Instalar skin</key>
<key alias="installStarterKit">Instalar starter kit</key>
<key alias="languages">Idiomas</key>
<key alias="localPackage">Instalar paquete local</key>
<key alias="macros">Macros</key>
@@ -710,7 +793,7 @@ However, Runway offers an easy foundation based on best practices to get you sta
<key alias="repositories">Instalar desde repositorio</key>
<key alias="runway">Instalar pasarela</key>
<key alias="runwayModules">Módulos pasarela</key>
<key alias="scripting">TRANSLATE ME: 'Scripting Files'</key>
<key alias="scripting">Ficheros de script</key>
<key alias="scripts">Scripts</key>
<key alias="stylesheets">Hojas de estilo</key>
<key alias="templates">Plantillas</key>
@@ -725,8 +808,10 @@ However, Runway offers an easy foundation based on best practices to get you sta
<area alias="user">
<key alias="administrators">Administrador</key>
<key alias="categoryField">Campo de categoria</key>
<key alias="changePassword">TRANSLATE ME: 'Change Your Password'</key>
<key alias="changePasswordDescription">TRANSLATE ME: 'You can change your password for accessing the Umbraco Back Office by filling out the form below and click the 'Change Password' button'</key>
<key alias="changePassword">Cambiar contraseña</key>
<key alias="newPassword">Change Your Password</key>
<key alias="confirmNewPassword">Confirm new password</key>
<key alias="changePasswordDescription">Puede cambiar su contraseña para acceder al 'back office' de Umbraco rellenando el siguiente formulario y haciendo clic en el botón 'Cambiar contraseña'</key>
<key alias="contentChannel">Canal de contenido</key>
<key alias="descriptionField">Campo descriptivo</key>
<key alias="disabled">Deshabilitar usuario</key>
@@ -738,13 +823,16 @@ However, Runway offers an easy foundation based on best practices to get you sta
<key alias="mediastartnode">Nodo de comienzo en la libreria de medios</key>
<key alias="modules">Secciones</key>
<key alias="noConsole">Deshabilitar acceso a Umbraco</key>
<key alias="password">Password</key>
<key alias="passwordChanged">TRANSLATE ME: 'Your password has been changed!'</key>
<key alias="passwordConfirm">TRANSLATE ME: 'Please confirm the new password'</key>
<key alias="passwordEnterNew">TRANSLATE ME: 'Enter your new password'</key>
<key alias="passwordIsBlank">TRANSLATE ME: 'Your new password cannot be blank!'</key>
<key alias="passwordIsDifferent">TRANSLATE ME: 'There was a difference between the new password and the confirmed password. Please try again!'</key>
<key alias="passwordMismatch">TRANSLATE ME: 'The confirmed password doesn't match the new password!'</key>
<key alias="password">Contraseña</key>
<key alias="resetPassword">Reset password</key>
<key alias="passwordChanged">Su contraseña ha sido cambiada</key>
<key alias="passwordConfirm">Por favor confirme su nueva contraseña</key>
<key alias="passwordEnterNew">Introduzca su nueva contraseña</key>
<key alias="passwordIsBlank">La nueva contraseña no puede estar vacía</key>
<key alias="passwordCurrent">Current password</key>
<key alias="passwordInvalid">Invalid current password</key>
<key alias="passwordIsDifferent">La nueva contraseña no coincide con la contraseña de confirmación. Por favor, vuela a intentarlo!'</key>
<key alias="passwordMismatch">La contraseña de confirmación no coincide con la nueva contraseña!'</key>
<key alias="permissionReplaceChildren">Reemplazar los permisos de los nodos hijo</key>
<key alias="permissionSelectedPages">Estas modificando los permisos para las páginas:</key>
<key alias="permissionSelectPages">Selecciona las páginas para modificar sus permisos</key>
@@ -755,5 +843,8 @@ However, Runway offers an easy foundation based on best practices to get you sta
<key alias="usertype">Tipo de usuario</key>
<key alias="userTypes">Tipos de usuarios</key>
<key alias="writer">Redactor</key>
<key alias="yourProfile" version="7.0">Your profile</key>
<key alias="yourHistory" version="7.0">Your recent history</key>
<key alias="sessionExpires" version="7.0">Session expires in</key>
</area>
</language>
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<language alias="fr" intName="French" localName="français" lcid="12" culture="fr-FR">
<creator>
<name>The umbraco community</name>
<link>http://umbraco.org/documentation/language-files</link>
<name>The Umbraco community</name>
<link>http://our.umbraco.org/documentation/Extending-Umbraco/Language-Files</link>
</creator>
<area alias="actions">
<key alias="assignDomain">Gérer les noms d'hôtes</key>
@@ -420,7 +420,7 @@
<p>Pour poursuivre, éditez le fichier "web.config" (avec Visual Studio ou votre éditeur de texte favori), scrollez jusqu'en bas, ajoutez une "connection string" dans la ligne "umbracoDbDSN" et sauvegardez votre fichier.</p>
<p>
Cliquez sur le bouton <strong>Réessayer</strong> lorsque cela est fait.
<br /><a href="http://umbraco.org/redir/installWebConfig" target="_blank">
<br /><a href="http://our.umbraco.org/documentation/Using-Umbraco/Config-files/webconfig7" target="_blank">
Plus d'informations sur l'édition du fichier web.config ici.</a></p>]]></key>
<key alias="databaseText"><![CDATA[Pour effectuer cette étape, vous devez d'abord connaître des informations de votre serveur de base de données ("connection string").<br />
Contactez votre administrateur système si nécessaire.
@@ -545,7 +545,7 @@ Pour gérer votre site, ouvrez simplement le backoffice Umbraco et commencez à
<key alias="greeting6">Joyeux samedi</key>
<key alias="instruction">Connectez-vous ci-dessous</key>
<key alias="timeout">La session a expiré</key>
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href="http://umbraco.org" style="text-decoration: none" target="_blank">umbraco.org</a></p> ]]></key>
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href="http://umbraco.com" style="text-decoration: none" target="_blank">umbraco.com</a></p> ]]></key>
</area>
<area alias="main">
<key alias="dashboard">Tableau de bord</key>
@@ -751,6 +751,8 @@ Pour gérer votre site, ouvrez simplement le backoffice Umbraco et commencez à
<key alias="contentTypeUses">Ce type de contenu utilise</key>
<key alias="asAContentMasterType">en tant que type de contenu master, les onglets du type de contenu master ne sont pas affichés et peuvent seulement être modifiés dans le type de contenu master lui-même.</key>
<key alias="noPropertiesDefinedOnTab">Aucune propriétés définies dans cet onglet. Cliquez sur le lien "Ajouter une nouvelle propriété" en haut pour créer une nouvelle propriété.</key>
<key alias="masterDocumentType">Type de contenu parent</key>
<key alias="createMatchingTemplate">Créer le template correspondant</key>
</area>
<area alias="sort">
<key alias="sortDone">Tri achevé.</key>
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<language alias="he" intName="Hebrew (Israel)" localName="Hebrew" lcid="" culture="he-IL">
<creator>
<name>Umbraco Hebrew 2011</name>
<link>http://umbraco.org</link>
<name>The Umbraco community</name>
<link>http://our.umbraco.org/documentation/Extending-Umbraco/Language-Files</link>
</creator>
<area alias="actions">
<key alias="assignDomain">נהל שמות מתחם</key>
@@ -354,7 +354,7 @@
<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">
done.<br /><a href="http://our.umbraco.org/documentation/Using-Umbraco/Config-files/webconfig7" 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 />
Please contact your ISP if necessary.
@@ -469,7 +469,7 @@ To manage your website, simply open the umbraco back office and start adding con
<key alias="renewSession">יש לבצע חידוש פעילות על מנת לשמור על התוכן</key>
</area>
<area alias="login">
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href="http://umbraco.org" style="text-decoration: none" target="_blank">umbraco.org</a></p> ]]></key>
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href="http://umbraco.com" style="text-decoration: none" target="_blank">umbraco.com</a></p> ]]></key>
<key alias="topText">ברוכים הבאים לאומברקו, יש להזין שם משתמש וסיסמה בשדות למטה:</key>
</area>
<area alias="main">
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<language alias="it" intName="Italian" localName="italiano" lcid="16" culture="it-IT">
<creator>
<name>The umbraco community</name>
<link>http://umbraco.org/documentation/language-files</link>
<name>The Umbraco community</name>
<link>http://our.umbraco.org/documentation/Extending-Umbraco/Language-Files</link>
</creator>
<area alias="actions">
<key alias="assignDomain">Gestisci hostnames</key>
@@ -266,7 +266,7 @@
<key alias="findDocument">Trova</key>
<key alias="folder">Cartella</key>
<key alias="height">Altezza</key>
<key alias="help">Aiuto</key>
<key alias="help">Guida</key>
<key alias="icon">Icona</key>
<key alias="import">Importa</key>
<key alias="innerMargin"><![CDATA[Margine interno (inner margin)]]></key>
@@ -343,7 +343,7 @@
<key alias="databaseInstallDone"><![CDATA[Umbraco %0% è stato copiato nel tuo database. Premi <strong>Avanti</strong> per proseguire.]]></key>
<key alias="databaseNotFound">
<![CDATA[<p>Database non trovato! Perfavore, controlla che le informazioni della stringa di connessione nel file "web.config" siano corrette.</p>
<p>Per procedere, edita il file "web.config" (utilizzando Visual Studio o l'editor di testo che preferisci), scorri in basso, aggiungi la stringa di connessione per il database chiamato "umbracoDbDSN" e salva il file.</p><p>Clicca il tasto <strong>riprova</strong> quando hai finito.<br /><a href="http://umbraco.org/redir/installWebConfig" target="_blank"> Maggiori dettagli per la modifica del file web.config qui.</a></p>]]>
<p>Per procedere, edita il file "web.config" (utilizzando Visual Studio o l'editor di testo che preferisci), scorri in basso, aggiungi la stringa di connessione per il database chiamato "umbracoDbDSN" e salva il file.</p><p>Clicca il tasto <strong>riprova</strong> quando hai finito.<br /><a href="http://our.umbraco.org/documentation/Using-Umbraco/Config-files/webconfig7" target="_blank"> Maggiori dettagli per la modifica del file web.config qui.</a></p>]]>
</key>
<key alias="databaseText"><![CDATA[Per completare questo passaggio, devi conoscere alcune informazioni riguardanti il tuo database server ("connection string"). Se è necessario contatta il tuo ISP per reperire le informazioni necessarie. Se stai effettuando l'installazione in locale o su un server, puoi richiederle al tuo amministratore di sistema]]></key>
<key alias="databaseUpgrade"><![CDATA[<p>Premi il tasto <strong>aggiorna</strong> per aggiornare il database ad Umbraco %0%</p><p>Non preoccuparti, il contenuto non verrà perso e tutto continuerà a funzionare dopo l'aggiornamento!</p>]]></key>
@@ -428,7 +428,7 @@ Per gestire il tuo sito web, è sufficiente aprire il back office di Umbraco e i
<key alias="renewSession">Riconnetti adesso per salvare il tuo lavoro</key>
</area>
<area alias="login">
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href="http://umbraco.org" style="text-decoration: none" target="_blank">umbraco.org</a></p> ]]></key>
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href="http://umbraco.com" style="text-decoration: none" target="_blank">umbraco.com</a></p> ]]></key>
<key alias="topText">Benvenuti in Umbraco, digita il tuo username e la tua password nelle caselle seguenti:</key>
</area>
<area alias="main">
@@ -630,7 +630,7 @@ Per gestire il tuo sito web, è sufficiente aprire il back office di Umbraco e i
<key alias="contentTypeTabCreated">Tab creata</key>
<key alias="contentTypeTabDeleted">Tab eliminata</key>
<key alias="contentTypeTabDeletedText">Tab con id: %0% eliminata</key>
<key alias="contentUnpublished">Contenuto non pubblicato</key>
<key alias="contentUnpublished">Contenuto non pubblicare</key>
<key alias="cssErrorHeader"><![CDATA[Foglio di stile non salvato]]></key>
<key alias="cssSavedHeader"><![CDATA[Foglio di stile salvato]]></key>
<key alias="cssSavedText"><![CDATA[Foglio di stile salvato correttamente]]></key>
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<language alias="ja" intName="Japanese" localName="日本語" lcid="17" culture="ja-JP">
<creator>
<name>umbraco</name>
<link>http://umbraco.org</link>
<name>The Umbraco community</name>
<link>http://our.umbraco.org/documentation/Extending-Umbraco/Language-Files</link>
</creator>
<area alias="actions">
<key alias="assignDomain">ドメインの割り当て</key>
@@ -351,7 +351,7 @@
<p>続行するには"web.config"ファイルを編集(Visual Studioないし使い慣れたテキストエディタで)し、下の方にスクロールし、"umbracoDbDSN"という名前のキーでデータベースの接続文字列を追加して保存します。</p>
<p>
<strong>再施行</strong>ボタンをクリックして
続けます。<br /><a href="http://umbraco.org/redir/installWebConfig" target="_blank">
続けます。<br /><a href="http://our.umbraco.org/documentation/Using-Umbraco/Config-files/webconfig7" target="_blank">
より詳細にはこちらの web.config を編集します。</a></p>]]></key>
<key alias="databaseText"><![CDATA[このステップを完了するには、データベースサーバー(の"接続文字列")について把握していなければなりません。<br />
必要ならISPに連絡するなどしてみてください。
@@ -466,7 +466,7 @@ Runwayをインストールして作られた新しいウェブサイトがど
<key alias="renewSession">作業を保存して今すぐ更新</key>
</area>
<area alias="login">
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href="http://umbraco.org" style="text-decoration: none" target="_blank">umbraco.org</a></p> ]]></key>
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href="http://umbraco.com" style="text-decoration: none" target="_blank">umbraco.com</a></p> ]]></key>
<key alias="topText">Umbraco にようこそ。ユーザー名とパスワードを入力してください:</key>
</area>
<area alias="main">
@@ -2,7 +2,7 @@
<language alias="ko" intName="Korean" localName="한국어" lcid="18" culture="ko-KR">
<creator>
<name>The Umbraco community</name>
<link>http://umbraco.org/documentation/language-files</link>
<link>http://our.umbraco.org/documentation/Extending-Umbraco/Language-Files</link>
</creator>
<area alias="actions">
<key alias="assignDomain">호스트명 관리</key>
@@ -344,7 +344,7 @@
<key alias="databaseNotFound"><![CDATA[<p>데이터베이스를 찾을 수 없습니다. “web.config”파일의 "connection string"이 바르게 설정되었는지 확인하세요.</p>
<p>"web.config" 파일에 맨아래에 ,키네임을 "umbracoDbDSN"로 하여 사용하시는 데이터베이스의 connection string 정보를 입력하시고 파일을 저장하세요. </p>
<p>
완료 후<strong>재시도</strong>버튼을 누르세요.<br /><a href="http://umbraco.org/redir/installWebConfig" target="_blank">
완료 후<strong>재시도</strong>버튼을 누르세요.<br /><a href="http://our.umbraco.org/documentation/Using-Umbraco/Config-files/webconfig7" target="_blank">
web.config의 더많은 정보는 여기에 있습니다.</a></p>]]></key>
<key alias="databaseText"><![CDATA[이과정을 위해선, 당신의 DB서버 정보에 대해서 알고 계셔야합니다.("connection string").<br />
필요하시다면 사용하시는 ISP쪽에 문의하시기 바랍니다..
@@ -447,7 +447,7 @@
<key alias="renewSession">TRANSLATE ME: 'Renew now to save your work'</key>
</area>
<area alias="login">
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href="http://umbraco.org" style="text-decoration: none" target="_blank">umbraco.org</a></p> ]]></key>
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href="http://umbraco.com" style="text-decoration: none" target="_blank">umbraco.com</a></p> ]]></key>
<key alias="topText">umbraco 에 오신것을 환영합니다. 사용자명과 비밀번호를 입력하십시오:</key>
</area>
<area alias="main">
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<language alias="nl" intName="Dutch" localName="Nederlands" lcid="19" culture="nl-NL">
<creator>
<name>The umbraco community</name>
<link>http://umbraco.org/documentation/language-files</link>
<name>The Umbraco community</name>
<link>http://our.umbraco.org/documentation/Extending-Umbraco/Language-Files</link>
</creator>
<area alias="actions">
<key alias="assignDomain">Beheer domeinnamen</key>
@@ -421,7 +421,7 @@
<key alias="databaseHeader">Database configuratie </key>
<key alias="databaseInstall"><![CDATA[Druk op de knop <strong>installeren</strong> om de Umbraco %0% database te installeren]]></key>
<key alias="databaseInstallDone"><![CDATA[Umbraco %0% is nu gekopieerd naar je database. Druk op <strong>Volgende</strong> om door te gaan.]]></key>
<key alias="databaseNotFound"><![CDATA[<p>De database kon niet gevonden worden! Gelieve na te kijken of de informatie in de "connection string" van het "web.config" bestand correct is.</p><p> Om door te gaan, gelieve het "web.config" bestand aan te passen (met behulp van Visual Studio of je favoriete tekstverwerker), scroll in het bestand naar beneden, voeg de connection string voor je database toe in de key met naam "umbracoDbDSN" en sla het bestand op.</p><p>Klik op de knop <strong>opnieuw proberen</strong> als je hiermee klaar bent. <br/> <a href="http://umbraco.org/redir/installWebConfig" target="_blank">Meer informatie over het aanpassen van de web.config vind je hier.</a></p>]]></key>
<key alias="databaseNotFound"><![CDATA[<p>De database kon niet gevonden worden! Gelieve na te kijken of de informatie in de "connection string" van het "web.config" bestand correct is.</p><p> Om door te gaan, gelieve het "web.config" bestand aan te passen (met behulp van Visual Studio of je favoriete tekstverwerker), scroll in het bestand naar beneden, voeg de connection string voor je database toe in de key met naam "umbracoDbDSN" en sla het bestand op.</p><p>Klik op de knop <strong>opnieuw proberen</strong> als je hiermee klaar bent. <br/> <a href="http://our.umbraco.org/documentation/Using-Umbraco/Config-files/webconfig7" target="_blank">Meer informatie over het aanpassen van de web.config vind je hier.</a></p>]]></key>
<key alias="databaseText"><![CDATA[Om deze stap te voltooien moet je enkele gegevens weten over je database server ("connection string").<br/> Gelieve contact op te nemen met je ISP indien nodig. Wanneer je installeert op een lokale computer of server, dan heb je waarschijnlijk informatie nodig van je systeembeheerder.]]></key>
<key alias="databaseUpgrade"><![CDATA[<p> Klik de <strong>upgrade</strong> knop om je database te upgraden naar Umbraco %0%</p> <p> Maak je geen zorgen - er zal geen inhoud worden gewist en alles blijft gewoon werken! </p>]]></key>
<key alias="databaseUpgradeDone"><![CDATA[Je database is geupgrade naar de definitieve versie %0%.<br />Klik <strong>Volgende</strong> om verder te gaan.]]></key>
@@ -500,7 +500,7 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je
<key alias="instruction">log hieronder in</key>
<key alias="timeout">Sessie is verlopen</key>
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href="http://umbraco.org" style="text-decoration: none" target="_blank">umbraco.org</a></p>]]></key>
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href="http://umbraco.com" style="text-decoration: none" target="_blank">umbraco.com</a></p>]]></key>
<key alias="topText">Welkom bij umbraco, geef je gebruikersnaam en wachtwoord op in de onderstaande velden:</key>
</area>
<area alias="main">
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<language alias="no" intName="Norwegian" localName="norsk" lcid="20" culture="nb-NO">
<creator>
<name>The umbraco community</name>
<link>http://umbraco.org/documentation/language-files</link>
<name>The Umbraco community</name>
<link>http://our.umbraco.org/documentation/Extending-Umbraco/Language-Files</link>
</creator>
<area alias="actions">
<key alias="assignDomain">Angi domene</key>
@@ -352,7 +352,7 @@
<key alias="databaseHeader">Databasekonfigurasjon</key>
<key alias="databaseInstall">Klikk &lt;strong&gt;installer&lt;/strong&gt;-knappen for å installere Umbraco %0% databasen</key>
<key alias="databaseInstallDone">Umbraco %0% har nå blitt kopiert til din database. Trykk &lt;strong&gt;Neste&lt;/strong&gt; for å fortsette.</key>
<key alias="databaseNotFound">&lt;p&gt;Databasen ble ikke funnet! Vennligst sjekk at informasjonen i "connection string" i "web.config"-filen er korrekt.&lt;/p&gt;&lt;p&gt;For å fortsette, vennligst rediger "web.config"-filen (bruk Visual Studio eller din favoritteditor), rull ned til bunnen, og legg til tilkoblingsstrengen for din database i nøkkelen "umbracoDbDSN" og lagre filen.&lt;/p&gt;&lt;p&gt;Klikk &lt;strong&gt;prøv på nytt&lt;/strong&gt; når du er ferdig.&lt;br /&gt; &lt;a href="http://umbraco.org/redir/installWebConfig" target="_blank"&gt;Mer informasjon om redigering av web.config her.&lt;/a&gt;&lt;/p&gt;</key>
<key alias="databaseNotFound">&lt;p&gt;Databasen ble ikke funnet! Vennligst sjekk at informasjonen i "connection string" i "web.config"-filen er korrekt.&lt;/p&gt;&lt;p&gt;For å fortsette, vennligst rediger "web.config"-filen (bruk Visual Studio eller din favoritteditor), rull ned til bunnen, og legg til tilkoblingsstrengen for din database i nøkkelen "umbracoDbDSN" og lagre filen.&lt;/p&gt;&lt;p&gt;Klikk &lt;strong&gt;prøv på nytt&lt;/strong&gt; når du er ferdig.&lt;br /&gt; &lt;a href="http://our.umbraco.org/documentation/Using-Umbraco/Config-files/webconfig7" target="_blank"&gt;Mer informasjon om redigering av web.config her.&lt;/a&gt;&lt;/p&gt;</key>
<key alias="databaseText">For å fullføre dette steget, må du vite en del informasjon om din database server ("tilkoblingsstreng").&lt;br/&gt; Vennligst kontakt din ISP om nødvendig. Hvis du installerer på en lokal maskin eller server, må du kanskje skaffe informasjonen fra din systemadministrator.</key>
<key alias="databaseUpgrade">&lt;p&gt; Trykk på knappen &lt;strong&gt;oppgrader&lt;/strong&gt; for å oppgradere databasen din til Umbraco %0%&lt;/p&gt; &lt;p&gt; Ikke vær urolig - intet innhold vil bli slettet og alt vil fortsette å virke etterpå! &lt;/p&gt;</key>
<key alias="databaseUpgradeDone">Databasen din har blitt oppgradert til den siste utgaven, %0%.&lt;br/&gt;Trykk &lt;strong&gt;Neste&lt;/strong&gt; for å fortsette.</key>
@@ -415,7 +415,7 @@
<key alias="renewSession">Forny innlogging for å lagre</key>
</area>
<area alias="login">
<key alias="bottomText">&lt;p style="text-align:right;"&gt;&amp;copy; 2001 - %0% &lt;br /&gt;&lt;a href="http://umbraco.org" style="text-decoration: none" target="_blank"&gt;umbraco.org&lt;/a&gt;&lt;/p&gt; </key>
<key alias="bottomText">&lt;p style="text-align:right;"&gt;&amp;copy; 2001 - %0% &lt;br /&gt;&lt;a href="http://umbraco.com" style="text-decoration: none" target="_blank"&gt;umbraco.org&lt;/a&gt;&lt;/p&gt; </key>
<key alias="topText">Velkommen til Umbraco, skriv inn ditt brukernavn og passord i feltene under:</key>
</area>
<area alias="main">
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<language alias="pl" intName="Polish" localName="polski" lcid="21" culture="pl-PL">
<creator>
<name>The umbraco community</name>
<link>http://umbraco.org/documentation/language-files</link>
<name>The Umbraco community</name>
<link>http://our.umbraco.org/documentation/Extending-Umbraco/Language-Files</link>
</creator>
<area alias="actions">
<key alias="assignDomain">Zarządzanie hostami</key>
@@ -339,7 +339,7 @@ Możesz dodać dodatkowe języki w menu "Języki" po lewej stronie.]]></key>
<key alias="databaseHeader">Konfiguracja bazy danych</key>
<key alias="databaseInstall"><![CDATA[Naciśnij przycisk <strong>instaluj</strong> aby zainstalować bazę danych Umbraco %0%]]></key>
<key alias="databaseInstallDone"><![CDATA[Umbraco %0% zostało skopiowane do Twojej bazy danych. Naciśnij <strong>Dalej</strong> aby kontynuować.]]></key>
<key alias="databaseNotFound"><![CDATA[<p>Nie odnaleziono bazy danych! Sprawdź czy informacje w sekcji "connection string" w pliku "web.config" są prawidłowe.</p> <p>Aby kontynuować, dokonaj edycji pliku "web.config" (używając Visual Studio lub dowolnego edytora tekstu), przemieść kursor na koniec pliku, dodaj parametry połączenia do Twojej bazy danych w kluczu o nazwie "umbracoDbDSN" i zapisz plik.</p> <p>Kliknij <strong>ponów próbę</strong> kiedy skończysz.<br /><a href="http://umbraco.org/redir/installWebConfig" target="_blank">Tu znajdziesz więcej informacji na temat edycji pliku "web.config".</a></p>]]></key>
<key alias="databaseNotFound"><![CDATA[<p>Nie odnaleziono bazy danych! Sprawdź czy informacje w sekcji "connection string" w pliku "web.config" są prawidłowe.</p> <p>Aby kontynuować, dokonaj edycji pliku "web.config" (używając Visual Studio lub dowolnego edytora tekstu), przemieść kursor na koniec pliku, dodaj parametry połączenia do Twojej bazy danych w kluczu o nazwie "umbracoDbDSN" i zapisz plik.</p> <p>Kliknij <strong>ponów próbę</strong> kiedy skończysz.<br /><a href="http://our.umbraco.org/documentation/Using-Umbraco/Config-files/webconfig7" target="_blank">Tu znajdziesz więcej informacji na temat edycji pliku "web.config".</a></p>]]></key>
<key alias="databaseText"><![CDATA[Aby zakończyć ten etap instalacji, będziesz musiał podać parametry połączenia do Twojego serwera baz danych ("connection string").<br />Skontaktuj się z Twoim dostawą usług internetowych jeśli zajdzie taka potrzeba. W przypadku instalacji na lokalnej maszynie lub serwerze możesz potrzebować pomocy administratora.]]></key>
<key alias="databaseUpgrade"><![CDATA[<p>Naciśnij przycisk <strong>aktualizuj</strong> by zaktualizować swoją bazę danych do Umbraco %0%</p> <p>Bez obaw - żadne dane nie zostaną usunięte i wszystko będzie działać jak należy!</p>]]></key>
<key alias="databaseUpgradeDone"><![CDATA[Twoja baza danych została zaktualizowana do wersji %0%.<br />Naciśnij przycisk <strong>Dalej</strong> aby kontynuować.]]></key>
@@ -402,7 +402,7 @@ Możesz dodać dodatkowe języki w menu "Języki" po lewej stronie.]]></key>
<key alias="renewSession">TRANSLATE ME: 'Renew now to save your work'</key>
</area>
<area alias="login">
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href="http://umbraco.org" style="text-decoration: none" target="_blank">umbraco.org</a></p> ]]></key>
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href="http://umbraco.com" style="text-decoration: none" target="_blank">umbraco.com</a></p> ]]></key>
<key alias="topText">Witamy w umbraco. Wprowadź swój login oraz hasło w polach poniżej:</key>
</area>
<area alias="main">
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<language alias="pt" intName="Portuguese Brazil" localName="Portuguese Brazil" lcid="" culture="pt-BR">
<creator>
<name>Carlos Casalicchio</name>
<link>http://www.zueuz.net</link>
<name>The Umbraco community</name>
<link>http://our.umbraco.org/documentation/Extending-Umbraco/Language-Files</link>
</creator>
<area alias="actions">
<key alias="assignDomain">Gerenciar hostnames</key>
@@ -340,7 +340,7 @@
<key alias="databaseInstallDone"><![CDATA[Umbraco %0% agora foi copiado para seu banco de dados. Pressione <strong>Próximo</strong> para prosseguir.]]></key>
<key alias="databaseNotFound"><![CDATA[<p>Banco de dados não encontrado! Favor checar se a informação no "connection string" do "web.config" esteja correta. </p>
<p>Para prosseguir, favor editar o arquivo "web.config" (usando Visual Studio ou seu editor de texto favorito), role até embaixo, adicione a connection string para seu banco de dados com a chave de nome "umbracoDbDSN" e salve o arquivo </p>
<p>Clique o botão <strong>tentar novamente</strong> quando terminar. <br /><a href="http://umbraco.org/redir/installWebConfig" target="_blank">
<p>Clique o botão <strong>tentar novamente</strong> quando terminar. <br /><a href="http://our.umbraco.org/documentation/Using-Umbraco/Config-files/webconfig7" target="_blank">
Mais informações em como editar o web.config aqui.</a></p>]]></key>
<key alias="databaseText"><![CDATA[Para completar este passo, você deve saber algumas informações relativas ao seu servidor de banco de dados ("connection string"). <br /> Favor contatar seu provedor de internet ou hospedagem web se necessário. Se você estiver instalando em uma máquina ou servidor local é possível que você precise dessas informações por um administrador de sistema.]]></key>
<key alias="databaseUpgrade"><![CDATA[<p>
@@ -440,7 +440,7 @@ Pressione <strong>"próximo"</strong> para iniciar o assistente.]]></key>
<key alias="renewSession">Renovar agora para salvar seu trabalho</key>
</area>
<area alias="login">
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href="http://umbraco.org" style="text-decoration: none" target="_blank">umbraco.org</a></p> ]]></key>
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href="http://umbraco.com" style="text-decoration: none" target="_blank">umbraco.com</a></p> ]]></key>
<key alias="topText">Bem vindo(a) à Umbraco, digite seu nome de usuário e senha nas caixas abaixo:</key>
</area>
<area alias="main">
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<language alias="ru" intName="Russian" localName="русский" lcid="" culture="ru-RU">
<creator>
<name>Alexander Bryukhov (Unico Design company)</name>
<link>http://unicodsgn.com</link>
<name>The Umbraco community</name>
<link>http://our.umbraco.org/documentation/Extending-Umbraco/Language-Files</link>
</creator>
<area alias="actions">
<key alias="assignDomain">Языки и домены</key>
@@ -369,7 +369,7 @@
<p>Для настройки откройте файл "web.config" с помошью любого текстового редактора и добавьте нужную информацию в строку подключения (параметр "umbracoDbDSN"),
затем сохраните файл.</p>
<p>Нажмите кнопку "Повторить" когда все будет готово<br />
<a href="http://umbraco.org/redir/installWebConfig"
<a href="http://our.umbraco.org/documentation/Using-Umbraco/Config-files/webconfig7"
target="_blank">Более подробно о внесении изменений в файл "web.config" расскзано здесь.</a></p>]]></key>
<key alias="databaseText"><![CDATA[Для завершения данного шага Вам нужно распологать некоторой информацией о Вашем сервере базы данных
(строка подключения "connection string")<br />
@@ -484,7 +484,7 @@
<key alias="renewSession">Обновите сейчас, чтобы сохранить сделанные изменения</key>
</area>
<area alias="login">
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href="http://umbraco.org" style="text-decoration: none" target="_blank">umbraco.org</a></p>]]></key>
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href="http://umbraco.com" style="text-decoration: none" target="_blank">umbraco.com</a></p>]]></key>
<key alias="topText">Рады приветствовать Вас в umbraco, укажите Ваши логин и пароль для входа в систему:</key>
</area>
<area alias="main">
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<language alias="sv" intName="Swedish" localName="Svenska" lcid="29" culture="sv-SE">
<creator>
<name>Kalle Ekstrand, Toxic Interactive Solutions AB</name>
<link>http://www.toxic.se</link>
<name>The Umbraco community</name>
<link>http://our.umbraco.org/documentation/Extending-Umbraco/Language-Files</link>
</creator>
<area alias="actions">
<key alias="assignDomain">Hantera domännamn</key>
@@ -400,7 +400,7 @@
<key alias="databaseHeader">Databaskonfiguration</key>
<key alias="databaseInstall"><![CDATA[För att installera Umbraco {0} databasen, tryck på knappen <strong>installera</strong>]]></key>
<key alias="databaseInstallDone"><![CDATA[Nu har Umbraco {0} kopierats till din databas. Tryck <strong>Nästa</strong> för att fortsätta.]]></key>
<key alias="databaseNotFound"><![CDATA[<p>Databasen kunde inte hittas! Kontrollera att informationen i databasanslutnings-inställningarna i filen "web.config" är rätt.</p> <p>För att fortsätta måste du redigera filen "web.config" (du kan använda Visual Studio eller din favorit text-redigerare), bläddra till slutet, lägg till databasanslutnings-inställningarna för din databas i fältet som heter "umbracoDbDSN" och spara filen. </p> <p> Klicka på <strong>Försök igen</strong> knappen när du är klar.<br />><a href="http://umbraco.org/redir/installWebConfig" target="_blank"> Mer information om att redigera web.config hittar du här.</a></p>]]></key>
<key alias="databaseNotFound"><![CDATA[<p>Databasen kunde inte hittas! Kontrollera att informationen i databasanslutnings-inställningarna i filen "web.config" är rätt.</p> <p>För att fortsätta måste du redigera filen "web.config" (du kan använda Visual Studio eller din favorit text-redigerare), bläddra till slutet, lägg till databasanslutnings-inställningarna för din databas i fältet som heter "umbracoDbDSN" och spara filen. </p> <p> Klicka på <strong>Försök igen</strong> knappen när du är klar.<br />><a href="http://our.umbraco.org/documentation/Using-Umbraco/Config-files/webconfig7" target="_blank"> Mer information om att redigera web.config hittar du här.</a></p>]]></key>
<key alias="databaseText"><![CDATA[För att avsluta det här steget måste du veta lite information om din databasserver ("connection string").<br /> Eventuellt kan du behöva kontakta ditt webb-hotell. Om du installerar på en lokal maskin eller server kan du få informationen från din systemadministratör.]]></key>
<key alias="databaseUpgrade"><![CDATA[<p> Tryck <strong>Uppgradera</strong> knappen för att uppgradera din databas till Umbraco {0}</p> <p> Du behöver inte vara orolig. Inget innehåll kommer att raderas och efteråt kommer allt att fungera som vanligt! </p>]]></key>
<key alias="databaseUpgradeDone"><![CDATA[Din databas har nu uppgraderats till den senaste versionen {0}.<br />Tryck <strong>Nästa</strong> för att fortsätta.]]></key>
@@ -466,7 +466,7 @@
<key alias="renewSession">Förnya nu för att spara ditt arbete</key>
</area>
<area alias="login">
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - {0} <br /><a href="http://umbraco.org" style="text-decoration: none" target="_blank">umbraco.org</a></p> ]]></key>
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - {0} <br /><a href="http://umbraco.com" style="text-decoration: none" target="_blank">umbraco.com</a></p> ]]></key>
<key alias="greeting0">Happy super Sunday</key>
<key alias="greeting1">Happy manic Monday</key>
<key alias="greeting2">Happy tremendous Tuesday</key>
@@ -2,7 +2,7 @@
<language alias="zh" intName="Chinese (Simple)" localName="中文(简体,中国)" lcid="0804" culture="zh-CN">
<creator>
<name>孙柱梁</name>
<link></link>
<link>http://our.umbraco.org/documentation/Extending-Umbraco/Language-Files</link>
</creator>
<area alias="actions">
<key alias="assignDomain">管理主机名</key>
@@ -384,7 +384,7 @@
<key alias="databaseNotFound"><![CDATA[<p>数据库未找到!请检查数据库连接串设置。</p>
<p>您可以自行编辑“web.config”文件,键名为 “umbracoDbDSN”</p>
<p>
当自行编辑后,单击<strong>重试</strong>按钮<br /><a href="http://umbraco.org/redir/installWebConfig" target="_blank">。
当自行编辑后,单击<strong>重试</strong>按钮<br /><a href="http://our.umbraco.org/documentation/Using-Umbraco/Config-files/webconfig7" target="_blank">。
如何编辑web.config</a></p>
]]></key>
<key alias="databaseText"><![CDATA[完成本步,需要配置一个正确的连接字符串(“connection string”)。<br />
@@ -2,7 +2,7 @@
<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %>
<cc1:Pane runat="server">
<cc1:PropertyPanel runat="server" text="Master Document Type">
<cc1:PropertyPanel runat="server" text="Master Document Type" id="pp_MasterDocumentType">
<asp:ListBox id="masterType" Runat="server" cssClass="bigInput input-large-type input-block-level" Rows="1" SelectionMode="Single"></asp:ListBox>
<asp:Literal ID="masterTypePreDefined" runat="server" Visible="false"></asp:Literal>
</cc1:PropertyPanel>
@@ -11,5 +11,23 @@ namespace Umbraco.Web.UI.Umbraco.Settings {
public partial class EditNodeTypeNew {
/// <summary>
/// allowedTemplates control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::umbraco.uicontrols.PropertyPanel allowedTemplates;
/// <summary>
/// defaultTemplate control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::umbraco.uicontrols.PropertyPanel defaultTemplate;
}
}
+13 -1
View File
@@ -118,6 +118,7 @@
<compilation defaultLanguage="c#" debug="false" batch="false" targetFramework="4.5">
<assemblies>
<add assembly="System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<add assembly="System.Web.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</assemblies>
<buildProviders>
<add extension=".cshtml" type="umbraco.MacroEngines.RazorBuildProvider, umbraco.MacroEngines" />
@@ -256,5 +257,16 @@
</dependentAssembly>
</assemblyBinding>
</runtime>
<location path="umbraco">
<system.webServer>
<urlCompression doStaticCompression="false" doDynamicCompression="false" dynamicCompressionBeforeCache="false" />
</system.webServer>
</location>
<location path="App_Plugins">
<system.webServer>
<urlCompression doStaticCompression="false" doDynamicCompression="false" dynamicCompressionBeforeCache="false" />
</system.webServer>
</location>
</configuration>
@@ -117,7 +117,8 @@ namespace Umbraco.Web.Models.Mapping
//fill in the template config to be passed to the template drop down.
var templateItemConfig = new Dictionary<string, string> { { "", "Choose..." } };
foreach (var t in content.ContentType.AllowedTemplates)
foreach (var t in content.ContentType.AllowedTemplates
.Where(t => t.Alias.IsNullOrWhiteSpace() == false && t.Name.IsNullOrWhiteSpace() == false))
{
templateItemConfig.Add(t.Alias, t.Name);
}
@@ -37,7 +37,7 @@ namespace Umbraco.Web.PropertyEditors
[PreValueField("startNode", "Node type", "treesource")]
public string StartNode { get; set; }
[PreValueField("filter", "Allow items of type", "textstring", Description = "Seperate with comma")]
[PreValueField("filter", "Allow items of type", "textstring", Description = "Separate with comma")]
public string Filter { get; set; }
[PreValueField("minNumber", "Minimum number of items", "number")]
@@ -18,8 +18,6 @@ using Umbraco.Core.Xml;
using Umbraco.Web.Models;
using UmbracoExamine;
using umbraco;
using umbraco.cms.businesslogic;
using ContentType = umbraco.cms.businesslogic.ContentType;
namespace Umbraco.Web.PublishedCache.XmlPublishedCache
{
@@ -31,21 +29,30 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
/// </remarks>
internal class PublishedMediaCache : IPublishedMediaCache
{
public PublishedMediaCache()
{
}
public PublishedMediaCache(ApplicationContext applicationContext)
{
if (applicationContext == null) throw new ArgumentNullException("applicationContext");
_applicationContext = applicationContext;
}
/// <summary>
/// Generally used for unit testing to use an explicit examine searcher
/// </summary>
/// <param name="applicationContext"></param>
/// <param name="searchProvider"></param>
/// <param name="indexProvider"></param>
internal PublishedMediaCache(BaseSearchProvider searchProvider, BaseIndexProvider indexProvider)
internal PublishedMediaCache(ApplicationContext applicationContext, BaseSearchProvider searchProvider, BaseIndexProvider indexProvider)
{
_searchProvider = searchProvider;
if (applicationContext == null) throw new ArgumentNullException("applicationContext");
if (searchProvider == null) throw new ArgumentNullException("searchProvider");
if (indexProvider == null) throw new ArgumentNullException("indexProvider");
_applicationContext = applicationContext;
_searchProvider = searchProvider;
_indexProvider = indexProvider;
}
private readonly ApplicationContext _applicationContext;
private readonly BaseSearchProvider _searchProvider;
private readonly BaseIndexProvider _indexProvider;
@@ -56,17 +63,10 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
public virtual IEnumerable<IPublishedContent> GetAtRoot(UmbracoContext umbracoContext, bool preview)
{
var rootMedia = global::umbraco.cms.businesslogic.media.Media.GetRootMedias();
var result = new List<IPublishedContent>();
//TODO: need to get a ConvertFromMedia method but we'll just use this for now.
foreach (var media in rootMedia
.Select(m => global::umbraco.library.GetMedia(m.Id, true))
.Where(media => media != null && media.Current != null))
{
media.MoveNext();
result.Add(ConvertFromXPathNavigator(media.Current));
}
return result;
//TODO: We should be able to look these ids first in Examine!
var rootMedia = _applicationContext.Services.MediaService.GetRootMedia();
return rootMedia.Select(m => GetUmbracoMedia(m.Id));
}
public virtual IPublishedContent GetSingleByXPath(UmbracoContext umbracoContext, bool preview, string xpath, XPathVariable[] vars)
@@ -96,7 +96,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
public bool XPathNavigatorIsNavigable { get { return false; } }
public virtual bool HasContent(UmbracoContext context, bool preview) { throw new NotImplementedException(); }
public virtual bool HasContent(UmbracoContext context, bool preview) { throw new NotImplementedException(); }
private ExamineManager GetExamineManagerSafe()
{
@@ -192,30 +192,31 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
}
}
var media = global::umbraco.library.GetMedia(id, true);
if (media != null && media.Current != null)
{
media.MoveNext();
var moved = media.Current.MoveToFirstChild();
//first check if we have an error
if (moved)
{
if (media.Current.Name.InvariantEquals("error"))
{
return null;
}
}
if (moved)
{
//move back to the parent and return
media.Current.MoveToParent();
}
return ConvertFromXPathNavigator(media.Current);
}
LogHelper.Debug<PublishedMediaCache>(
"Could not retrieve media {0} from Examine index, reverting to looking up media via legacy library.GetMedia method",
() => id);
return null;
var media = global::umbraco.library.GetMedia(id, true);
return ConvertFromXPathNodeIterator(media, id);
}
internal IPublishedContent ConvertFromXPathNodeIterator(XPathNodeIterator media, int id)
{
if (media != null && media.Current != null)
{
return media.Current.Name.InvariantEquals("error")
? null
: ConvertFromXPathNavigator(media.Current);
}
LogHelper.Debug<PublishedMediaCache>(
"Could not retrieve media {0} from Examine index or from legacy library.GetMedia method",
() => id);
return null;
}
internal IPublishedContent ConvertFromSearchResult(SearchResult searchResult)
{
//NOTE: Some fields will not be included if the config section for the internal index has been
@@ -417,7 +418,6 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
var media = library.GetMedia(parentId, true);
if (media != null && media.Current != null)
{
media.MoveNext();
xpath = media.Current;
}
else
@@ -1562,9 +1562,11 @@ namespace Umbraco.Web
// what else? would need root content to have a special, non-null but hidden,
// parent...
var siblings = content.Parent == null
? UmbracoContext.Current.ContentCache.GetAtRoot()
: content.Parent.Children;
? content.ItemType == PublishedItemType.Media ? UmbracoContext.Current.MediaCache.GetAtRoot() : UmbracoContext.Current.ContentCache.GetAtRoot()
: content.Parent.Children;
// make sure we run it once
return siblings.ToArray();
+3 -3
View File
@@ -38,7 +38,7 @@ namespace Umbraco.Web
public IEnumerable<IPublishedContent> TypedContent(IEnumerable<int> ids)
{
return TypedDocumentsbyIds(_contentCache, ids);
return TypedDocumentsByIds(_contentCache, ids);
}
public IEnumerable<IPublishedContent> TypedContentAtXPath(string xpath, params XPathVariable[] vars)
@@ -102,7 +102,7 @@ namespace Umbraco.Web
public IEnumerable<IPublishedContent> TypedMedia(IEnumerable<int> ids)
{
return TypedDocumentsbyIds(_mediaCache, ids);
return TypedDocumentsByIds(_mediaCache, ids);
}
public IEnumerable<IPublishedContent> TypedMediaAtRoot()
@@ -148,7 +148,7 @@ namespace Umbraco.Web
// return doc;
//}
private IEnumerable<IPublishedContent> TypedDocumentsbyIds(ContextualPublishedCache cache, IEnumerable<int> ids)
private IEnumerable<IPublishedContent> TypedDocumentsByIds(ContextualPublishedCache cache, IEnumerable<int> ids)
{
return ids.Select(eachId => TypedDocumentById(eachId, cache));
}
@@ -0,0 +1,381 @@
using System;
using System.Collections.Concurrent;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Hosting;
using Umbraco.Core.Logging;
namespace Umbraco.Web.Scheduling
{
/// <summary>
/// This is used to create a background task runner which will stay alive in the background of and complete
/// any tasks that are queued. It is web aware and will ensure that it is shutdown correctly when the app domain
/// is shutdown.
/// </summary>
/// <typeparam name="T"></typeparam>
internal class BackgroundTaskRunner<T> : IDisposable, IRegisteredObject
where T : IBackgroundTask
{
private readonly bool _dedicatedThread;
private readonly bool _persistentThread;
private readonly BlockingCollection<T> _tasks = new BlockingCollection<T>();
private Task _consumer;
private volatile bool _isRunning = false;
private static readonly object Locker = new object();
private CancellationTokenSource _tokenSource;
internal event EventHandler<TaskEventArgs<T>> TaskError;
internal event EventHandler<TaskEventArgs<T>> TaskStarting;
internal event EventHandler<TaskEventArgs<T>> TaskCompleted;
internal event EventHandler<TaskEventArgs<T>> TaskCancelled;
public BackgroundTaskRunner(bool dedicatedThread = false, bool persistentThread = false)
{
_dedicatedThread = dedicatedThread;
_persistentThread = persistentThread;
HostingEnvironment.RegisterObject(this);
}
public int TaskCount
{
get { return _tasks.Count; }
}
public bool IsRunning
{
get { return _isRunning; }
}
public TaskStatus TaskStatus
{
get { return _consumer.Status; }
}
/// <summary>
/// Returns the task awaiter so that consumers of the BackgroundTaskManager can await
/// the threading operation.
/// </summary>
/// <returns></returns>
/// <remarks>
/// This is just the coolest thing ever, check this article out:
/// http://blogs.msdn.com/b/pfxteam/archive/2011/01/13/10115642.aspx
///
/// So long as we have a method called GetAwaiter() that returns an instance of INotifyCompletion
/// we can await anything! :)
/// </remarks>
public TaskAwaiter GetAwaiter()
{
return _consumer.GetAwaiter();
}
public void Add(T task)
{
//add any tasks first
LogHelper.Debug<BackgroundTaskRunner<T>>(" Task added {0}", () => task.GetType());
_tasks.Add(task);
//ensure's everything is started
StartUp();
}
public void StartUp()
{
if (!_isRunning)
{
lock (Locker)
{
//double check
if (!_isRunning)
{
_isRunning = true;
//Create a new token source since this is a new proces
_tokenSource = new CancellationTokenSource();
StartConsumer();
LogHelper.Debug<BackgroundTaskRunner<T>>("Starting");
}
}
}
}
public void ShutDown()
{
lock (Locker)
{
_isRunning = false;
try
{
if (_consumer != null)
{
//cancel all operations
_tokenSource.Cancel();
try
{
_consumer.Wait();
}
catch (AggregateException e)
{
//NOTE: We are logging Debug because we are expecting these errors
LogHelper.Debug<BackgroundTaskRunner<T>>("AggregateException thrown with the following inner exceptions:");
// Display information about each exception.
foreach (var v in e.InnerExceptions)
{
var exception = v as TaskCanceledException;
if (exception != null)
{
LogHelper.Debug<BackgroundTaskRunner<T>>(" .Net TaskCanceledException: .Net Task ID {0}", () => exception.Task.Id);
}
else
{
LogHelper.Debug<BackgroundTaskRunner<T>>(" Exception: {0}", () => v.GetType().Name);
}
}
}
}
if (_tasks.Count > 0)
{
LogHelper.Debug<BackgroundTaskRunner<T>>("Processing remaining tasks before shutdown: {0}", () => _tasks.Count);
//now we need to ensure the remaining queue is processed if there's any remaining,
// this will all be processed on the current/main thread.
T remainingTask;
while (_tasks.TryTake(out remainingTask))
{
ConsumeTaskInternal(remainingTask);
}
}
LogHelper.Debug<BackgroundTaskRunner<T>>("Shutdown");
//disposing these is really optional since they'll be disposed immediately since they are no longer running
//but we'll put this here anyways.
if (_consumer != null && (_consumer.IsCompleted || _consumer.IsCanceled))
{
_consumer.Dispose();
}
}
catch (Exception ex)
{
LogHelper.Error<BackgroundTaskRunner<T>>("Error occurred shutting down task runner", ex);
}
finally
{
HostingEnvironment.UnregisterObject(this);
}
}
}
/// <summary>
/// Starts the consumer task
/// </summary>
private void StartConsumer()
{
var token = _tokenSource.Token;
_consumer = Task.Factory.StartNew(() =>
StartThread(token),
token,
_dedicatedThread ? TaskCreationOptions.LongRunning : TaskCreationOptions.None,
TaskScheduler.Default);
//if this is not a persistent thread, wait till it's done and shut ourselves down
// thus ending the thread or giving back to the thread pool. If another task is added
// another thread will spawn or be taken from the pool to process.
if (!_persistentThread)
{
_consumer.ContinueWith(task => ShutDown());
}
}
/// <summary>
/// Invokes a new worker thread to consume tasks
/// </summary>
/// <param name="token"></param>
private void StartThread(CancellationToken token)
{
// Was cancellation already requested?
if (token.IsCancellationRequested)
{
LogHelper.Info<BackgroundTaskRunner<T>>("Thread {0} was cancelled before it got started.", () => Thread.CurrentThread.ManagedThreadId);
token.ThrowIfCancellationRequested();
}
TakeAndConsumeTask(token);
}
/// <summary>
/// Trys to get a task from the queue, if there isn't one it will wait a second and try again
/// </summary>
/// <param name="token"></param>
private void TakeAndConsumeTask(CancellationToken token)
{
if (token.IsCancellationRequested)
{
LogHelper.Info<BackgroundTaskRunner<T>>("Thread {0} was cancelled.", () => Thread.CurrentThread.ManagedThreadId);
token.ThrowIfCancellationRequested();
}
//If this is true, the thread will stay alive and just wait until there is anything in the queue
// and process it. When there is nothing in the queue, the thread will just block until there is
// something to process.
//When this is false, the thread will process what is currently in the queue and once that is
// done, the thread will end and we will shutdown the process
if (_persistentThread)
{
//This will iterate over the collection, if there is nothing to take
// the thread will block until there is something available.
//We need to pass our cancellation token so that the thread will
// cancel when we shutdown
foreach (var t in _tasks.GetConsumingEnumerable(token))
{
ConsumeTaskCancellable(t, token);
}
//recurse and keep going
TakeAndConsumeTask(token);
}
else
{
T repositoryTask;
while (_tasks.TryTake(out repositoryTask))
{
ConsumeTaskCancellable(repositoryTask, token);
}
//the task will end here
}
}
internal void ConsumeTaskCancellable(T task, CancellationToken token)
{
if (token.IsCancellationRequested)
{
OnTaskCancelled(new TaskEventArgs<T>(task));
//NOTE: Since the task hasn't started this is pretty pointless so leaving it out.
LogHelper.Info<BackgroundTaskRunner<T>>("Task {0}) was cancelled.",
() => task.GetType());
token.ThrowIfCancellationRequested();
}
ConsumeTaskInternal(task);
}
private void ConsumeTaskInternal(T task)
{
try
{
OnTaskStarting(new TaskEventArgs<T>(task));
try
{
using (task)
{
task.Run();
}
}
catch (Exception e)
{
OnTaskError(new TaskEventArgs<T>(task, e));
throw;
}
OnTaskCompleted(new TaskEventArgs<T>(task));
}
catch (Exception ex)
{
LogHelper.Error<BackgroundTaskRunner<T>>("An error occurred consuming task", ex);
}
}
protected virtual void OnTaskError(TaskEventArgs<T> e)
{
var handler = TaskError;
if (handler != null) handler(this, e);
}
protected virtual void OnTaskStarting(TaskEventArgs<T> e)
{
var handler = TaskStarting;
if (handler != null) handler(this, e);
}
protected virtual void OnTaskCompleted(TaskEventArgs<T> e)
{
var handler = TaskCompleted;
if (handler != null) handler(this, e);
}
protected virtual void OnTaskCancelled(TaskEventArgs<T> e)
{
var handler = TaskCancelled;
if (handler != null) handler(this, e);
}
#region Disposal
private readonly object _disposalLocker = new object();
public bool IsDisposed { get; private set; }
~BackgroundTaskRunner()
{
this.Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (this.IsDisposed || !disposing)
return;
lock (_disposalLocker)
{
if (IsDisposed)
return;
DisposeResources();
IsDisposed = true;
}
}
protected virtual void DisposeResources()
{
ShutDown();
}
#endregion
public void Stop(bool immediate)
{
if (immediate == false)
{
LogHelper.Debug<BackgroundTaskRunner<T>>("Application is shutting down, waiting for tasks to complete");
Dispose();
}
else
{
//NOTE: this will thread block the current operation if the manager
// is still shutting down because the Shutdown operation is also locked
// by this same lock instance. This would only matter if Stop is called by ASP.Net
// on two different threads though, otherwise the current thread will just block normally
// until the app is shutdown
lock (Locker)
{
LogHelper.Info<BackgroundTaskRunner<T>>("Application is shutting down immediately");
}
}
}
}
}
@@ -0,0 +1,9 @@
using System;
namespace Umbraco.Web.Scheduling
{
internal interface IBackgroundTask : IDisposable
{
void Run();
}
}
+22 -11
View File
@@ -1,6 +1,8 @@
using System;
using System.Net;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
using Umbraco.Core.Sync;
@@ -8,24 +10,33 @@ namespace Umbraco.Web.Scheduling
{
internal class KeepAlive
{
public static void Start(object sender)
public static void Start(ApplicationContext appContext, IUmbracoSettingsSection settings)
{
using (DisposableTimer.DebugDuration<KeepAlive>(() => "Keep alive executing", () => "Keep alive complete"))
{
var umbracoBaseUrl = ServerEnvironmentHelper.GetCurrentServerUmbracoBaseUrl();
var umbracoBaseUrl = ServerEnvironmentHelper.GetCurrentServerUmbracoBaseUrl(
appContext,
settings);
var url = string.Format("{0}/ping.aspx", umbracoBaseUrl);
try
if (string.IsNullOrWhiteSpace(umbracoBaseUrl))
{
using (var wc = new WebClient())
{
wc.DownloadString(url);
}
LogHelper.Warn<KeepAlive>("No url for service (yet), skip.");
}
catch (Exception ee)
else
{
LogHelper.Error<KeepAlive>("Error in ping", ee);
var url = string.Format("{0}ping.aspx", umbracoBaseUrl.EnsureEndsWith('/'));
try
{
using (var wc = new WebClient())
{
wc.DownloadString(url);
}
}
catch (Exception ee)
{
LogHelper.Error<KeepAlive>("Error in ping", ee);
}
}
}
+19 -42
View File
@@ -2,47 +2,31 @@ using System;
using System.Web;
using System.Web.Caching;
using umbraco.BusinessLogic;
using Umbraco.Core;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
namespace Umbraco.Web.Scheduling
{
//TODO: Refactor this to use a normal scheduling processor!
internal class LogScrubber
internal class LogScrubber : DisposableObject, IBackgroundTask
{
// this is a raw copy of the legacy code in all its uglyness
private readonly ApplicationContext _appContext;
private readonly IUmbracoSettingsSection _settings;
CacheItemRemovedCallback _onCacheRemove;
const string LogScrubberTaskName = "ScrubLogs";
public void Start()
public LogScrubber(ApplicationContext appContext, IUmbracoSettingsSection settings)
{
// log scrubbing
AddTask(LogScrubberTaskName, GetLogScrubbingInterval());
_appContext = appContext;
_settings = settings;
}
private static int GetLogScrubbingInterval()
{
int interval = 24 * 60 * 60; //24 hours
try
{
if (global::umbraco.UmbracoSettings.CleaningMiliseconds > -1)
interval = global::umbraco.UmbracoSettings.CleaningMiliseconds;
}
catch (Exception e)
{
LogHelper.Error<Scheduler>("Unable to locate a log scrubbing interval. Defaulting to 24 horus", e);
}
return interval;
}
private static int GetLogScrubbingMaximumAge()
private int GetLogScrubbingMaximumAge(IUmbracoSettingsSection settings)
{
int maximumAge = 24 * 60 * 60;
try
{
if (global::umbraco.UmbracoSettings.MaxLogAge > -1)
maximumAge = global::umbraco.UmbracoSettings.MaxLogAge;
if (settings.Logging.MaxLogAge > -1)
maximumAge = settings.Logging.MaxLogAge;
}
catch (Exception e)
{
@@ -52,26 +36,19 @@ namespace Umbraco.Web.Scheduling
}
private void AddTask(string name, int seconds)
{
_onCacheRemove = new CacheItemRemovedCallback(CacheItemRemoved);
HttpRuntime.Cache.Insert(name, seconds, null,
DateTime.Now.AddSeconds(seconds), System.Web.Caching.Cache.NoSlidingExpiration,
CacheItemPriority.NotRemovable, _onCacheRemove);
/// <summary>
/// Handles the disposal of resources. Derived from abstract class <see cref="DisposableObject"/> which handles common required locking logic.
/// </summary>
protected override void DisposeResources()
{
}
public void CacheItemRemoved(string k, object v, CacheItemRemovedReason r)
public void Run()
{
if (k.Equals(LogScrubberTaskName))
using (DisposableTimer.DebugDuration<LogScrubber>(() => "Log scrubbing executing", () => "Log scrubbing complete"))
{
ScrubLogs();
Log.CleanLogs(GetLogScrubbingMaximumAge(_settings));
}
AddTask(k, Convert.ToInt32(v));
}
private static void ScrubLogs()
{
Log.CleanLogs(GetLogScrubbingMaximumAge());
}
}
}
@@ -3,6 +3,7 @@ using System.Diagnostics;
using System.Net;
using System.Text;
using Umbraco.Core;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
using Umbraco.Core.Publishing;
using Umbraco.Core.Sync;
@@ -10,30 +11,55 @@ using Umbraco.Web.Mvc;
namespace Umbraco.Web.Scheduling
{
internal class ScheduledPublishing
internal class ScheduledPublishing : DisposableObject, IBackgroundTask
{
private readonly ApplicationContext _appContext;
private readonly IUmbracoSettingsSection _settings;
private static bool _isPublishingRunning = false;
public void Start(ApplicationContext appContext)
public ScheduledPublishing(ApplicationContext appContext, IUmbracoSettingsSection settings)
{
if (appContext == null) return;
_appContext = appContext;
_settings = settings;
}
/// <summary>
/// Handles the disposal of resources. Derived from abstract class <see cref="DisposableObject"/> which handles common required locking logic.
/// </summary>
protected override void DisposeResources()
{
}
public void Run()
{
if (_appContext == null) return;
using (DisposableTimer.DebugDuration<ScheduledPublishing>(() => "Scheduled publishing executing", () => "Scheduled publishing complete"))
{
{
if (_isPublishingRunning) return;
_isPublishingRunning = true;
try
{
var umbracoBaseUrl = ServerEnvironmentHelper.GetCurrentServerUmbracoBaseUrl();
var url = string.Format("{0}/RestServices/ScheduledPublish/Index", umbracoBaseUrl);
using (var wc = new WebClient())
{
//pass custom the authorization header
wc.Headers.Set("Authorization", AdminTokenAuthorizeAttribute.GetAuthHeaderTokenVal(appContext));
var umbracoBaseUrl = ServerEnvironmentHelper.GetCurrentServerUmbracoBaseUrl(_appContext, _settings);
var result = wc.UploadString(url, "");
if (string.IsNullOrWhiteSpace(umbracoBaseUrl))
{
LogHelper.Warn<ScheduledPublishing>("No url for service (yet), skip.");
}
else
{
var url = string.Format("{0}RestServices/ScheduledPublish/Index", umbracoBaseUrl.EnsureEndsWith('/'));
using (var wc = new WebClient())
{
//pass custom the authorization header
wc.Headers.Set("Authorization", AdminTokenAuthorizeAttribute.GetAuthHeaderTokenVal(_appContext));
var result = wc.UploadString(url, "");
}
}
}
catch (Exception ee)
@@ -46,7 +72,5 @@ namespace Umbraco.Web.Scheduling
}
}
}
}
}
+41 -25
View File
@@ -4,6 +4,7 @@ using System.Linq;
using System.Net;
using System.Xml;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
using Umbraco.Core.Publishing;
using Umbraco.Core.Sync;
@@ -15,40 +16,25 @@ namespace Umbraco.Web.Scheduling
// would need to be a publicly available task (URL) which isn't really very good :(
// We should really be using the AdminTokenAuthorizeAttribute for this stuff
internal class ScheduledTasks
internal class ScheduledTasks : DisposableObject, IBackgroundTask
{
private readonly ApplicationContext _appContext;
private readonly IUmbracoSettingsSection _settings;
private static readonly Hashtable ScheduledTaskTimes = new Hashtable();
private static bool _isPublishingRunning = false;
public void Start(ApplicationContext appContext)
public ScheduledTasks(ApplicationContext appContext, IUmbracoSettingsSection settings)
{
using (DisposableTimer.DebugDuration<ScheduledTasks>(() => "Scheduled tasks executing", () => "Scheduled tasks complete"))
{
if (_isPublishingRunning) return;
_isPublishingRunning = true;
try
{
ProcessTasks();
}
catch (Exception ee)
{
LogHelper.Error<ScheduledTasks>("Error executing scheduled task", ee);
}
finally
{
_isPublishingRunning = false;
}
}
_appContext = appContext;
_settings = settings;
}
private static void ProcessTasks()
private void ProcessTasks()
{
var scheduledTasks = UmbracoConfig.For.UmbracoSettings().ScheduledTasks.Tasks;
var scheduledTasks = _settings.ScheduledTasks.Tasks;
foreach (var t in scheduledTasks)
{
var runTask = false;
@@ -75,7 +61,7 @@ namespace Umbraco.Web.Scheduling
}
}
private static bool GetTaskByHttp(string url)
private bool GetTaskByHttp(string url)
{
var myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url);
@@ -93,5 +79,35 @@ namespace Umbraco.Web.Scheduling
return false;
}
/// <summary>
/// Handles the disposal of resources. Derived from abstract class <see cref="DisposableObject"/> which handles common required locking logic.
/// </summary>
protected override void DisposeResources()
{
}
public void Run()
{
using (DisposableTimer.DebugDuration<ScheduledTasks>(() => "Scheduled tasks executing", () => "Scheduled tasks complete"))
{
if (_isPublishingRunning) return;
_isPublishingRunning = true;
try
{
ProcessTasks();
}
catch (Exception ee)
{
LogHelper.Error<ScheduledTasks>("Error executing scheduled task", ee);
}
finally
{
_isPublishingRunning = false;
}
}
}
}
}
+82 -37
View File
@@ -1,5 +1,9 @@
using System.Threading;
using System;
using System.Threading;
using System.Web;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
using Umbraco.Core.Sync;
@@ -9,65 +13,107 @@ namespace Umbraco.Web.Scheduling
/// Used to do the scheduling for tasks, publishing, etc...
/// </summary>
/// <remarks>
///
/// TODO: Much of this code is legacy and needs to be updated, there are a few new/better ways to do scheduling
/// in a web project nowadays.
///
/// //TODO: We need a much more robust way of handing scheduled tasks and also need to take into account app shutdowns during
/// a scheduled tasks operation
/// http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx/
///
/// All tasks are run in a background task runner which is web aware and will wind down the task correctly instead of killing it completely when
/// the app domain shuts down.
/// </remarks>
internal sealed class Scheduler : ApplicationEventHandler
{
private static Timer _pingTimer;
private static Timer _schedulingTimer;
private static LogScrubber _scrubber;
private static BackgroundTaskRunner<ScheduledPublishing> _publishingRunner;
private static BackgroundTaskRunner<ScheduledTasks> _tasksRunner;
private static BackgroundTaskRunner<LogScrubber> _scrubberRunner;
private static Timer _logScrubberTimer;
private static volatile bool _started = false;
private static readonly object Locker = new object();
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
if (umbracoApplication.Context == null)
return;
LogHelper.Debug<Scheduler>(() => "Initializing the scheduler");
//subscribe to app init so we can subsribe to the application events
UmbracoApplicationBase.ApplicationInit += (sender, args) =>
{
var app = (HttpApplication)sender;
// time to setup the tasks
//subscribe to the end of a successful request (a handler actually executed)
app.PostRequestHandlerExecute += (o, eventArgs) =>
{
if (_started == false)
{
lock (Locker)
{
if (_started == false)
{
_started = true;
LogHelper.Debug<Scheduler>(() => "Initializing the scheduler");
// these are the legacy tasks
// just copied over here for backward compatibility
// of course we should have a proper scheduler, see #U4-809
// time to setup the tasks
//NOTE: It is important to note that we need to use the ctor for a timer without the 'state' object specified, this is in order
// to ensure that the timer itself is not GC'd since internally .net will pass itself in as the state object and that will keep it alive.
// There's references to this here: http://stackoverflow.com/questions/4962172/why-does-a-system-timers-timer-survive-gc-but-not-system-threading-timer
// we also make these timers static to ensure further GC safety.
//We have 3 background runners that are web aware, if the app domain dies, these tasks will wind down correctly
_publishingRunner = new BackgroundTaskRunner<ScheduledPublishing>();
_tasksRunner = new BackgroundTaskRunner<ScheduledTasks>();
_scrubberRunner = new BackgroundTaskRunner<LogScrubber>();
// ping/keepalive
_pingTimer = new Timer(KeepAlive.Start);
_pingTimer.Change(60000, 300000);
//NOTE: It is important to note that we need to use the ctor for a timer without the 'state' object specified, this is in order
// to ensure that the timer itself is not GC'd since internally .net will pass itself in as the state object and that will keep it alive.
// There's references to this here: http://stackoverflow.com/questions/4962172/why-does-a-system-timers-timer-survive-gc-but-not-system-threading-timer
// we also make these timers static to ensure further GC safety.
// scheduled publishing/unpublishing
_schedulingTimer = new Timer(PerformScheduling);
_schedulingTimer.Change(30000, 60000);
// ping/keepalive - NOTE: we don't use a background runner for this because it does not need to be web aware, if the app domain dies, no problem
_pingTimer = new Timer(state => KeepAlive.Start(applicationContext, UmbracoConfig.For.UmbracoSettings()));
_pingTimer.Change(60000, 300000);
//log scrubbing
_scrubber = new LogScrubber();
_scrubber.Start();
// scheduled publishing/unpublishing
_schedulingTimer = new Timer(state => PerformScheduling(applicationContext, UmbracoConfig.For.UmbracoSettings()));
_schedulingTimer.Change(60000, 60000);
//log scrubbing
_logScrubberTimer = new Timer(state => PerformLogScrub(applicationContext, UmbracoConfig.For.UmbracoSettings()));
_logScrubberTimer.Change(60000, GetLogScrubbingInterval(UmbracoConfig.For.UmbracoSettings()));
}
}
}
};
};
}
private int GetLogScrubbingInterval(IUmbracoSettingsSection settings)
{
int interval = 24 * 60 * 60; //24 hours
try
{
if (settings.Logging.CleaningMiliseconds > -1)
interval = settings.Logging.CleaningMiliseconds;
}
catch (Exception e)
{
LogHelper.Error<Scheduler>("Unable to locate a log scrubbing interval. Defaulting to 24 horus", e);
}
return interval;
}
private static void PerformLogScrub(ApplicationContext appContext, IUmbracoSettingsSection settings)
{
_scrubberRunner.Add(new LogScrubber(appContext, settings));
}
/// <summary>
/// This performs all of the scheduling on the one timer
/// </summary>
/// <param name="sender"></param>
/// <param name="appContext"></param>
/// <param name="settings"></param>
/// <remarks>
/// No processing will be done if this server is a slave
/// </remarks>
private static void PerformScheduling(object sender)
private static void PerformScheduling(ApplicationContext appContext, IUmbracoSettingsSection settings)
{
using (DisposableTimer.DebugDuration<Scheduler>(() => "Scheduling interval executing", () => "Scheduling interval complete"))
{
//get the current server status to see if this server should execute the scheduled publishing
var serverStatus = ServerEnvironmentHelper.GetStatus();
var serverStatus = ServerEnvironmentHelper.GetStatus(settings);
switch (serverStatus)
{
@@ -78,13 +124,11 @@ namespace Umbraco.Web.Scheduling
// then we will process the scheduling
//do the scheduled publishing
var scheduledPublishing = new ScheduledPublishing();
scheduledPublishing.Start(ApplicationContext.Current);
_publishingRunner.Add(new ScheduledPublishing(appContext, settings));
//do the scheduled tasks
var scheduledTasks = new ScheduledTasks();
scheduledTasks.Start(ApplicationContext.Current);
_tasksRunner.Add(new ScheduledTasks(appContext, settings));
break;
case CurrentServerEnvironmentStatus.Slave:
//do not process
@@ -97,5 +141,6 @@ namespace Umbraco.Web.Scheduling
}
}
}
}
@@ -0,0 +1,22 @@
using System;
namespace Umbraco.Web.Scheduling
{
internal class TaskEventArgs<T> : EventArgs
where T : IBackgroundTask
{
public T Task { get; private set; }
public Exception Exception { get; private set; }
public TaskEventArgs(T task)
{
Task = task;
}
public TaskEventArgs(T task, Exception exception)
{
Task = task;
Exception = exception;
}
}
}
@@ -57,7 +57,7 @@ namespace Umbraco.Web.Standalone
var caches = new PublishedCaches(
new PublishedCache.XmlPublishedCache.PublishedContentCache(),
new PublishedCache.XmlPublishedCache.PublishedMediaCache());
new PublishedCache.XmlPublishedCache.PublishedMediaCache(ApplicationContext.Current));
PublishedCachesResolver.Current = new PublishedCachesResolver(caches);
@@ -1,64 +1,93 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Umbraco.Core;
using Umbraco.Core.Models;
using umbraco.businesslogic;
using Umbraco.Core.Services;
namespace Umbraco.Web.Trees
{
//TODO: Is there any way to get this to execute lazily when needed?
// i.e. When the back office loads so that this doesn't execute on startup for a content request.
/// <summary>
/// A startup handler for putting the tree config in the config file based on attributes found
/// </summary>
/// <remarks>
/// TODO: This is really not a very ideal process but the code is found here because tree plugins are in the Web project or the legacy business logic project.
/// Moving forward we can put the base tree plugin classes in the core and then this can all just be taken care of normally within the service.
/// </remarks>
public sealed class ApplicationTreeRegistrar : ApplicationEventHandler
{
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
ScanTrees(applicationContext);
//Call initialize on the tree service with the lazy enumerable class below, when the tree service needs to resolve,
// it will lazily do the scanning and comparing so it's not actually done on app start.
applicationContext.Services.ApplicationTreeService.Intitialize(new LazyEnumerableTrees());
}
/// <summary>
/// Scans for all attributed trees and ensures they exist in the tree xml
/// This class is here so that we can provide lazy access to tree scanning for when it is needed
/// </summary>
private static void ScanTrees(ApplicationContext applicationContext)
private class LazyEnumerableTrees : IEnumerable<ApplicationTree>
{
var added = new List<string>();
public LazyEnumerableTrees()
{
_lazyTrees = new Lazy<IEnumerable<ApplicationTree>>(() =>
{
var added = new List<string>();
// Load all Controller Trees by attribute and add them to the XML config
// we also need to make sure that any alias added with the new trees is not also added
// with the legacy trees.
var types = PluginManager.Current.ResolveAttributedTreeControllers();
// Load all Controller Trees by attribute
var types = PluginManager.Current.ResolveAttributedTreeControllers();
//convert them to ApplicationTree instances
var items = types
.Select(x =>
new Tuple<Type, TreeAttribute>(x, x.GetCustomAttributes<TreeAttribute>(false).Single()))
.Select(x => new ApplicationTree(x.Item2.Initialize, x.Item2.SortOrder, x.Item2.ApplicationAlias, x.Item2.Alias, x.Item2.Title, x.Item2.IconClosed, x.Item2.IconOpen, x.Item1.GetFullNameWithAssembly()))
.ToArray();
//get all non-legacy application tree's
var items = types
.Select(x =>
new Tuple<Type, TreeAttribute>(x, x.GetCustomAttributes<TreeAttribute>(false).Single()))
.Where(x => applicationContext.Services.ApplicationTreeService.GetByAlias(x.Item2.Alias) == null)
.Select(x => new ApplicationTree(x.Item2.Initialize, x.Item2.SortOrder, x.Item2.ApplicationAlias, x.Item2.Alias, x.Item2.Title, x.Item2.IconClosed, x.Item2.IconOpen, x.Item1.GetFullNameWithAssembly()))
.ToArray();
added.AddRange(items.Select(x => x.Alias));
added.AddRange(items.Select(x => x.Alias));
//find the legacy trees
var legacyTreeTypes = PluginManager.Current.ResolveAttributedTrees();
//find the legacy trees
var legacyTreeTypes = PluginManager.Current.ResolveAttributedTrees();
//convert them to ApplicationTree instances
var legacyItems = legacyTreeTypes
.Select(x =>
new Tuple<Type, global::umbraco.businesslogic.TreeAttribute>(
x,
x.GetCustomAttributes<global::umbraco.businesslogic.TreeAttribute>(false).SingleOrDefault()))
.Where(x => x.Item2 != null)
//make sure the legacy tree isn't added on top of the controller tree!
.Where(x => added.InvariantContains(x.Item2.Alias) == false)
.Select(x => new ApplicationTree(x.Item2.Initialize, x.Item2.SortOrder, x.Item2.ApplicationAlias, x.Item2.Alias, x.Item2.Title, x.Item2.IconClosed, x.Item2.IconOpen, x.Item1.GetFullNameWithAssembly()));
var legacyItems = legacyTreeTypes
.Select(x =>
new Tuple<Type, global::umbraco.businesslogic.TreeAttribute>(
x,
x.GetCustomAttributes<global::umbraco.businesslogic.TreeAttribute>(false).SingleOrDefault()))
.Where(x => x.Item2 != null)
.Where(x => applicationContext.Services.ApplicationTreeService.GetByAlias(x.Item2.Alias) == null
//make sure the legacy tree isn't added on top of the controller tree!
&& added.InvariantContains(x.Item2.Alias) == false)
.Select(x => new ApplicationTree(x.Item2.Initialize, x.Item2.SortOrder, x.Item2.ApplicationAlias, x.Item2.Alias, x.Item2.Title, x.Item2.IconClosed, x.Item2.IconOpen, x.Item1.GetFullNameWithAssembly()));
return items.Concat(legacyItems).ToArray();
});
}
applicationContext.Services.ApplicationTreeService.Intitialize(items.Concat(legacyItems));
private readonly Lazy<IEnumerable<ApplicationTree>> _lazyTrees;
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>
/// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
/// </returns>
public IEnumerator<ApplicationTree> GetEnumerator()
{
return _lazyTrees.Value.GetEnumerator();
}
/// <summary>
/// Returns an enumerator that iterates through a collection.
/// </summary>
/// <returns>
/// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection.
/// </returns>
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
}
+8 -1
View File
@@ -65,6 +65,7 @@
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<OutputPath>bin\Release\</OutputPath>
@@ -89,6 +90,7 @@
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\UmbracoExamine\UmbracoExamine.csproj">
@@ -262,6 +264,7 @@
</Compile>
<Compile Include="ApplicationContextExtensions.cs" />
<Compile Include="AreaRegistrationContextExtensions.cs" />
<Compile Include="Scheduling\BackgroundTaskRunner.cs" />
<Compile Include="BatchedServerMessenger.cs" />
<Compile Include="CacheHelperExtensions.cs" />
<Compile Include="Cache\ApplicationCacheRefresher.cs" />
@@ -464,6 +467,8 @@
<Compile Include="ImageCropperTemplateExtensions.cs" />
<Compile Include="Mvc\UmbracoVirtualNodeRouteHandler.cs" />
<Compile Include="Routing\UrlProviderExtensions.cs" />
<Compile Include="Scheduling\IBackgroundTask.cs" />
<Compile Include="Scheduling\TaskEventArgs.cs" />
<Compile Include="Strategies\Migrations\ClearCsrfCookiesAfterUpgrade.cs" />
<Compile Include="Strategies\Migrations\ClearMediaXmlCacheForDeletedItemsAfterUpgrade.cs" />
<Compile Include="Strategies\NotificationsHandler.cs" />
@@ -2116,7 +2121,9 @@
<ItemGroup />
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">11.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<VSToolsPath Condition="exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v11.0')">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v11.0</VSToolsPath>
<VSToolsPath Condition="exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v12.0')">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v12.0</VSToolsPath>
<VSToolsPath Condition="exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v14.0')">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v14.0</VSToolsPath>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
+1 -1
View File
@@ -338,7 +338,7 @@ namespace Umbraco.Web
PublishedCachesResolver.Current = new PublishedCachesResolver(new PublishedCaches(
new PublishedCache.XmlPublishedCache.PublishedContentCache(),
new PublishedCache.XmlPublishedCache.PublishedMediaCache()));
new PublishedCache.XmlPublishedCache.PublishedMediaCache(ApplicationContext)));
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector),
new NamespaceHttpControllerSelector(GlobalConfiguration.Configuration));
+61 -41
View File
@@ -9,6 +9,7 @@ using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;
using Newtonsoft.Json;
using Umbraco.Core;
@@ -16,21 +17,23 @@ using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
using Umbraco.Web;
using Umbraco.Web.Cache;
using Umbraco.Web.Templates;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic;
using umbraco.cms.businesslogic.media;
using umbraco.cms.businesslogic.member;
using umbraco.cms.businesslogic.propertytype;
using umbraco.cms.businesslogic.relation;
using umbraco.cms.businesslogic.web;
using umbraco.cms.helpers;
using umbraco.scripting;
using umbraco.DataLayer;
using umbraco.cms.businesslogic.language;
using Umbraco.Core.IO;
using Language = umbraco.cms.businesslogic.language.Language;
using Media = umbraco.cms.businesslogic.media.Media;
using Member = umbraco.cms.businesslogic.member.Member;
using PropertyType = umbraco.cms.businesslogic.propertytype.PropertyType;
using Relation = umbraco.cms.businesslogic.relation.Relation;
using UmbracoContext = umbraco.presentation.UmbracoContext;
namespace umbraco
@@ -490,46 +493,55 @@ namespace umbraco
{
if (UmbracoConfig.For.UmbracoSettings().Content.UmbracoLibraryCacheDuration > 0)
{
XPathNodeIterator retVal = ApplicationContext.Current.ApplicationCache.GetCacheItem(
var xml = ApplicationContext.Current.ApplicationCache.GetCacheItem(
string.Format(
"{0}_{1}_{2}", CacheKeys.MediaCacheKey, MediaId, Deep),
TimeSpan.FromSeconds(UmbracoConfig.For.UmbracoSettings().Content.UmbracoLibraryCacheDuration),
() => GetMediaDo(MediaId, Deep));
if (retVal != null)
return retVal;
if (xml != null)
{
return FromXElement(xml, xml.Attribute("nodeTypeAlias").Value);
}
}
else
{
return GetMediaDo(MediaId, Deep);
var xml = GetMediaDo(MediaId, Deep);
return FromXElement(xml, xml.Attribute("nodeTypeAlias").Value);
}
}
catch
catch(Exception ex)
{
LogHelper.Error<library>("An error occurred looking up media", ex);
}
XmlDocument xd = new XmlDocument();
xd.LoadXml(string.Format("<error>No media is maching '{0}'</error>", MediaId));
return xd.CreateNavigator().Select("/");
LogHelper.Debug<library>("No media result for id {0}", () => MediaId);
var errorXml = new XElement("error", string.Format("No media is maching '{0}'", MediaId));
return errorXml.CreateNavigator().Select("/");
}
private static XPathNodeIterator GetMediaDo(int mediaId, bool deep)
private static XElement GetMediaDo(int mediaId, bool deep)
{
var m = new Media(mediaId);
if (m.nodeObjectType == Media._objectType)
{
var mXml = new XmlDocument();
var xml = m.ToXml(mXml, deep);
//This will be null if the media isn't public (meaning it is in the trash)
if (xml == null) return null;
//TODO: This is an aweful way of loading in XML - it is very slow.
mXml.LoadXml(xml.OuterXml);
var xp = mXml.CreateNavigator();
var xpath = UmbracoConfig.For.UmbracoSettings().Content.UseLegacyXmlSchema ? "/node" : String.Format("/{0}", Casing.SafeAliasWithForcingCheck(m.ContentType.Alias));
return xp.Select(xpath);
}
return null;
var media = ApplicationContext.Current.Services.MediaService.GetById(mediaId);
if (media == null) return null;
var serializer = new EntityXmlSerializer();
var serialized = serializer.Serialize(
ApplicationContext.Current.Services.MediaService,
ApplicationContext.Current.Services.DataTypeService,
media,
deep);
return serialized;
}
private static XPathNodeIterator FromXElement(XNode xml, string mediaContentType)
{
var xp = xml.CreateNavigator();
var xpath = UmbracoConfig.For.UmbracoSettings().Content.UseLegacyXmlSchema
? "/node"
: String.Format("/{0}", Casing.SafeAliasWithForcingCheck(mediaContentType));
return xp.Select(xpath);
}
/// <summary>
@@ -545,35 +557,42 @@ namespace umbraco
{
if (UmbracoConfig.For.UmbracoSettings().Content.UmbracoLibraryCacheDuration > 0)
{
var retVal = ApplicationContext.Current.ApplicationCache.GetCacheItem(
var xml = ApplicationContext.Current.ApplicationCache.GetCacheItem(
string.Format(
"{0}_{1}", CacheKeys.MemberLibraryCacheKey, MemberId),
TimeSpan.FromSeconds(UmbracoConfig.For.UmbracoSettings().Content.UmbracoLibraryCacheDuration),
() => GetMemberDo(MemberId));
if (retVal != null)
return retVal.CreateNavigator().Select("/");
if (xml != null)
{
return xml.CreateNavigator().Select("/");
}
}
else
{
return GetMemberDo(MemberId).CreateNavigator().Select("/");
}
}
catch
catch (Exception ex)
{
LogHelper.Error<library>("An error occurred looking up member", ex);
}
XmlDocument xd = new XmlDocument();
LogHelper.Debug<library>("No member result for id {0}", () => MemberId);
var xd = new XmlDocument();
xd.LoadXml(string.Format("<error>No member is maching '{0}'</error>", MemberId));
return xd.CreateNavigator().Select("/");
}
private static XmlDocument GetMemberDo(int MemberId)
private static XElement GetMemberDo(int MemberId)
{
Member m = new Member(MemberId);
XmlDocument mXml = new XmlDocument();
mXml.LoadXml(m.ToXml(mXml, false).OuterXml);
return mXml;
var member = ApplicationContext.Current.Services.MemberService.GetById(MemberId);
if (member == null) return null;
var serializer = new EntityXmlSerializer();
var serialized = serializer.Serialize(
ApplicationContext.Current.Services.DataTypeService, member);
return serialized;
}
/// <summary>
@@ -1365,8 +1384,9 @@ namespace umbraco
nav.MoveToId(HttpContext.Current.Items["pageID"].ToString());
return nav.Select(".");
}
catch
catch (Exception ex)
{
LogHelper.Error<library>("Could not retrieve current xml node", ex);
}
XmlDocument xd = new XmlDocument();
@@ -28,8 +28,9 @@ namespace umbraco.cms.presentation.Trees
//create singleton
private static readonly TreeDefinitionCollection instance = new TreeDefinitionCollection();
private static readonly ReaderWriterLockSlim Lock = new ReaderWriterLockSlim();
private static readonly object Locker = new object();
private static volatile bool _ensureTrees = false;
public static TreeDefinitionCollection Instance
{
get
@@ -128,7 +129,12 @@ namespace umbraco.cms.presentation.Trees
public void ReRegisterTrees()
{
EnsureTreesRegistered(true);
//clears the trees/flag so that they are lazily refreshed on next access
lock (Locker)
{
this.Clear();
_ensureTrees = false;
}
}
/// <summary>
@@ -137,70 +143,68 @@ namespace umbraco.cms.presentation.Trees
/// This will also store an instance of each tree object in the TreeDefinition class which should be
/// used when referencing all tree classes.
/// </summary>
private void EnsureTreesRegistered(bool clearFirst = false)
private void EnsureTreesRegistered()
{
using (var l = new UpgradeableReadLock(Lock))
{
if (clearFirst)
{
this.Clear();
}
if (_ensureTrees == false)
{
lock (Locker)
{
if (_ensureTrees == false)
{
//if we already have tree, exit
if (this.Count > 0)
return;
var foundITrees = PluginManager.Current.ResolveTrees();
l.UpgradeToWriteLock();
var objTrees = ApplicationTree.getAll();
var appTrees = new List<ApplicationTree>();
appTrees.AddRange(objTrees);
var apps = Application.getAll();
foreach (var type in foundITrees)
{
//find the Application tree's who's combination of assembly name and tree type is equal to
//the Type that was found's full name.
//Since a tree can exist in multiple applications we'll need to register them all.
//The logic of this has changed in 6.0: http://issues.umbraco.org/issue/U4-1360
// we will support the old legacy way but the normal way is to match on assembly qualified names
var appTreesForType = appTrees.FindAll(
tree =>
{
//match the type on assembly qualified name if the assembly attribute is empty or if the
// tree type contains a comma (meaning it is assembly qualified)
if (tree.AssemblyName.IsNullOrWhiteSpace() || tree.Type.Contains(","))
{
return tree.GetRuntimeType() == type;
}
//otherwise match using legacy match rules
return (string.Format("{0}.{1}", tree.AssemblyName, tree.Type).InvariantEquals(type.FullName));
}
);
foreach (var appTree in appTreesForType)
{
//find the Application object whos name is the same as our appTree ApplicationAlias
var app = apps.Find(
a => (a.alias == appTree.ApplicationAlias)
);
var def = new TreeDefinition(type, appTree, app);
this.Add(def);
}
}
//sort our trees with the sort order definition
this.Sort((t1, t2) => t1.Tree.SortOrder.CompareTo(t2.Tree.SortOrder));
_ensureTrees = true;
}
}
}
var foundITrees = PluginManager.Current.ResolveTrees();
var objTrees = ApplicationTree.getAll();
var appTrees = new List<ApplicationTree>();
appTrees.AddRange(objTrees);
var apps = Application.getAll();
foreach (var type in foundITrees)
{
//find the Application tree's who's combination of assembly name and tree type is equal to
//the Type that was found's full name.
//Since a tree can exist in multiple applications we'll need to register them all.
//The logic of this has changed in 6.0: http://issues.umbraco.org/issue/U4-1360
// we will support the old legacy way but the normal way is to match on assembly qualified names
var appTreesForType = appTrees.FindAll(
tree =>
{
//match the type on assembly qualified name if the assembly attribute is empty or if the
// tree type contains a comma (meaning it is assembly qualified)
if (tree.AssemblyName.IsNullOrWhiteSpace() || tree.Type.Contains(","))
{
return tree.GetRuntimeType() == type;
}
//otherwise match using legacy match rules
return (string.Format("{0}.{1}", tree.AssemblyName, tree.Type).InvariantEquals(type.FullName));
}
);
foreach (var appTree in appTreesForType)
{
//find the Application object whos name is the same as our appTree ApplicationAlias
var app = apps.Find(
a => (a.alias == appTree.ApplicationAlias)
);
var def = new TreeDefinition(type, appTree, app);
this.Add(def);
}
}
//sort our trees with the sort order definition
this.Sort((t1, t2) => t1.Tree.SortOrder.CompareTo(t2.Tree.SortOrder));
}
}
}
@@ -1090,7 +1090,7 @@ jQuery(document).ready(function() {{ refreshDropDowns(); }});
foreach (DataGridItem dgi in dgTabs.Items)
{
int tabid = int.Parse(dgi.Cells[0].Text);
string tabName = ((TextBox)dgi.FindControl("txtTab")).Text.Replace("'", "''");
string tabName = ((TextBox) dgi.FindControl("txtTab")).Text;
int tabSortOrder;
if (Int32.TryParse(((TextBox)dgi.FindControl("txtSortOrder")).Text, out tabSortOrder))
{
@@ -2,7 +2,7 @@
<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %>
<cc1:Pane runat="server">
<cc1:PropertyPanel runat="server" text="Master Document Type">
<cc1:PropertyPanel runat="server" text="Master Document Type" id="pp_MasterDocumentType">
<asp:ListBox id="masterType" Runat="server" cssClass="bigInput input-large-type input-block-level" Rows="1" SelectionMode="Single"></asp:ListBox>
<asp:Literal ID="masterTypePreDefined" runat="server" Visible="false"></asp:Literal>
</cc1:PropertyPanel>
@@ -1,31 +1,38 @@
using System.Globalization;
using Umbraco.Core;
using Umbraco.Web.UI;
using Umbraco.Web;
namespace umbraco.cms.presentation.create.controls
{
using System;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using umbraco.cms.helpers;
using umbraco.BasePages;
using System;
using System.Globalization;
using System.Web;
using System.Web.UI.WebControls;
using umbraco.BasePages;
using umbraco.cms.businesslogic.web;
/// <summary>
using Umbraco.Core;
using Umbraco.Core.Strings;
using Umbraco.Web;
using Umbraco.Web.UI;
/// <summary>
/// Summary description for nodeType.
/// </summary>
public partial class nodeType : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
sbmt.Text = ui.Text("create");
pp_name.Text = ui.Text("name");
/// <summary>
/// The page_load.
/// </summary>
/// <param name="sender">
/// The sender.
/// </param>
/// <param name="e">
/// The e.
/// </param>
protected void Page_Load(object sender, EventArgs e)
{
this.sbmt.Text = ui.Text("create");
this.pp_name.Text = ui.Text("name");
this.pp_MasterDocumentType.Text = ui.Text("masterDocumentType");
this.createTemplate.Text = ui.Text("createMatchingTemplate");
if (!IsPostBack)
{
@@ -60,10 +67,34 @@ namespace umbraco.cms.presentation.create.controls
e.IsValid = false;
}
private bool ValidateAlias(string text)
{
// get the alias - same way we do it in nodetypeTasks.PerformSave()
// ensure it's not empty
var alias = text.ToCleanString(CleanStringType.Alias | CleanStringType.PascalCase, ' ');
if (string.IsNullOrWhiteSpace(alias))
return false;
// ensure no content with that alias exists
var existing = ApplicationContext.Current.Services.ContentTypeService.GetContentType(alias);
if (existing != null)
return false;
// all is ok
return true;
}
protected void sbmt_Click(object sender, EventArgs e)
{
if (Page.IsValid)
{
if (ValidateAlias(rename.Text) == false)
{
BasePage.Current.ClientTools.ShowSpeechBubble(BasePage.speechBubbleIcon.error, "Error",
"Name is empty, invalid, or causing an invalid or duplicate alias.");
return;
}
var createTemplateVal = 0;
if (createTemplate.Checked)
createTemplateVal = 1;
@@ -71,15 +102,27 @@ namespace umbraco.cms.presentation.create.controls
// check master type
string masterTypeVal = String.IsNullOrEmpty(Request.GetItemAsString("nodeId")) || Request.GetItemAsString("nodeId") == "init" ? masterType.SelectedValue : Request.GetItemAsString("nodeId");
var returnUrl = LegacyDialogHandler.Create(
new HttpContextWrapper(Context),
BasePage.Current.getUser(),
Request.GetItemAsString("nodeType"),
createTemplateVal,
rename.Text,
int.Parse(masterTypeVal));
string returnUrl;
try
{
// this *may* throw even if Page.IsValid because of race conditions
returnUrl = LegacyDialogHandler.Create(
new HttpContextWrapper(Context),
BasePage.Current.getUser(),
Request.GetItemAsString("nodeType"),
createTemplateVal,
rename.Text,
int.Parse(masterTypeVal));
}
catch (Exception ex)
{
// because it's always nicer to show a message to user vs YSOD
BasePage.Current.ClientTools.ShowSpeechBubble(BasePage.speechBubbleIcon.error, "Error",
ex.GetType().FullName + ": " + ex.Message);
return;
}
BasePage.Current.ClientTools
BasePage.Current.ClientTools
.ChangeContentFrameUrl(returnUrl)
.ChildNodeCreated()
.CloseModalWindow();
@@ -12,6 +12,15 @@ namespace umbraco.cms.presentation.create.controls {
public partial class nodeType {
/// <summary>
/// pp_MasterDocumentType control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::umbraco.uicontrols.PropertyPanel pp_MasterDocumentType;
/// <summary>
/// masterType control.
/// </summary>
@@ -12,10 +12,19 @@ namespace umbraco.js
{
Response.ContentType = "application/json";
string lang = "en";
if(ValidateCurrentUser()){
var language = GlobalSettings.DefaultUILanguage;
if (language != string.Empty)
{
lang = language;
}
if (ValidateCurrentUser())
{
lang = UmbracoUser.Language;
}
XmlDocument all = ui.getLanguageFile(lang);
if(all == null)
+5 -8
View File
@@ -42,14 +42,12 @@ namespace UmbracoExamine
/// <param name="indexPath"></param>
/// <param name="dataService"></param>
/// <param name="analyzer"></param>
[SecuritySafeCritical]
protected BaseUmbracoIndexer(IIndexCriteria indexerData, DirectoryInfo indexPath, IDataService dataService, Analyzer analyzer, bool async)
: base(indexerData, indexPath, analyzer, async)
{
DataService = dataService;
}
[SecuritySafeCritical]
protected BaseUmbracoIndexer(IIndexCriteria indexerData, Lucene.Net.Store.Directory luceneDirectory, IDataService dataService, Analyzer analyzer, bool async)
: base(indexerData, luceneDirectory, analyzer, async)
{
@@ -96,7 +94,6 @@ namespace UmbracoExamine
/// </summary>
/// <param name="name"></param>
/// <param name="config"></param>
[SecuritySafeCritical]
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
if (config["dataService"] != null && !string.IsNullOrEmpty(config["dataService"]))
@@ -217,7 +214,6 @@ namespace UmbracoExamine
/// Returns true if the Umbraco application is in a state that we can initialize the examine indexes
/// </summary>
/// <returns></returns>
[SecuritySafeCritical]
protected bool CanInitialize()
{
//check the DisableInitializationCheck and ensure that it is not set to true
@@ -268,6 +264,9 @@ namespace UmbracoExamine
/// <param name="type"></param>
protected override void PerformIndexAll(string type)
{
//TODO: Fix all of this up, the whole xpath thing is horrible and was made sooooooooo long ago to only work with published content
// but not it's being used for all content types and is really bad for performance.
if (!SupportedTypes.Contains(type))
return;
@@ -360,11 +359,9 @@ namespace UmbracoExamine
XDocument xDoc = GetXDocument(xPath, type);
if (xDoc != null)
{
XElement rootNode = xDoc.Root;
var rootNode = xDoc.Root;
IEnumerable<XElement> children = rootNode.Elements();
AddNodesToIndex(children, type);
AddNodesToIndex(rootNode.Elements(), type);
}
}
-2
View File
@@ -28,7 +28,6 @@ namespace UmbracoExamine
/// If the type of node is not a Document, the cacheOnly has no effect, it will use the API to return
/// the xml.
/// </remarks>
[SecuritySafeCritical]
[Obsolete("This method is no longer used and will be removed in future versions")]
public static XDocument ToXDocument(this Content node, bool cacheOnly)
{
@@ -52,7 +51,6 @@ namespace UmbracoExamine
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
[SecuritySafeCritical]
[Obsolete("This method is no longer used and will be removed in future versions")]
private static XDocument ToXDocument(this Content node)
{
@@ -29,14 +29,12 @@ namespace UmbracoExamine.DataServices
private readonly ApplicationContext _applicationContext;
[SecuritySafeCritical]
public UmbracoContentService()
: this(ApplicationContext.Current)
{
}
[SecuritySafeCritical]
public UmbracoContentService(ApplicationContext applicationContext)
{
_applicationContext = applicationContext;
@@ -47,7 +45,6 @@ namespace UmbracoExamine.DataServices
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
[SecuritySafeCritical]
public string StripHtml(string value)
{
return value.StripHtml();
@@ -58,7 +55,6 @@ namespace UmbracoExamine.DataServices
/// </summary>
/// <param name="xpath"></param>
/// <returns></returns>
[SecuritySafeCritical]
public XDocument GetPublishedContentByXPath(string xpath)
{
//TODO: Remove the need for this, the best way would be to remove all requirements of examine based on Xml but that
@@ -74,7 +70,7 @@ namespace UmbracoExamine.DataServices
/// </summary>
/// <param name="xpath"></param>
/// <returns></returns>
[SecuritySafeCritical]
public XDocument GetLatestContentByXPath(string xpath)
{
var xmlContent = XDocument.Parse("<content></content>");
@@ -93,7 +89,7 @@ namespace UmbracoExamine.DataServices
/// </summary>
/// <param name="documentId"></param>
/// <returns></returns>
[SecuritySafeCritical]
private static XmlNode GetPage(int documentId)
{
var xDoc = Access.GetXmlDocumentCopy();
@@ -118,7 +114,7 @@ namespace UmbracoExamine.DataServices
/// Returns a list of all of the user defined property names in Umbraco
/// </summary>
/// <returns></returns>
[SecuritySafeCritical]
public IEnumerable<string> GetAllUserPropertyNames()
{
try
@@ -12,13 +12,13 @@ namespace UmbracoExamine.DataServices
{
public string ProviderName { get; set; }
[SecuritySafeCritical]
public void AddInfoLog(int nodeId, string msg)
{
LogHelper.Info<UmbracoLogService>("{0}, Provider={1}, NodeId={2}", () => msg, () => ProviderName, () => nodeId);
}
[SecuritySafeCritical]
public void AddErrorLog(int nodeId, string msg)
{
//NOTE: not really the prettiest but since AddErrorLog is legacy code, we cannot change it now to accept a real Exception obj for
@@ -28,7 +28,7 @@ namespace UmbracoExamine.DataServices
new Exception(msg));
}
[SecuritySafeCritical]
public void AddVerboseLog(int nodeId, string msg)
{
LogHelper.Debug<UmbracoLogService>("{0}, Provider={1}, NodeId={2}", () => msg, () => ProviderName, () => nodeId);
@@ -19,14 +19,14 @@ namespace UmbracoExamine.DataServices
{
private readonly ServiceContext _services;
[SecuritySafeCritical]
public UmbracoMediaService()
: this(ApplicationContext.Current.Services)
{
}
[SecuritySafeCritical]
public UmbracoMediaService(ServiceContext services)
{
_services = services;
@@ -39,7 +39,7 @@ namespace UmbracoExamine.DataServices
/// </summary>
/// <param name="xpath"></param>
/// <returns></returns>
[SecuritySafeCritical]
public XDocument GetLatestMediaByXpath(string xpath)
{
var xmlMedia = XDocument.Parse("<media></media>");

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