Compare commits

...

119 Commits

Author SHA1 Message Date
mikkelhm 69775c369a Bump version to 7.5.14 2017-05-16 08:33:19 +02:00
mikkelhm 3f25d3637a Bump version to 7.5.14 2017-05-16 08:32:33 +02:00
Claus 5dc3e0a3fc Merge pull request #1880 from marcemarc/temp-U4-9765
debug logging when there is a distributed calls config issue
2017-05-15 10:28:26 +02:00
Claus d146df43e6 Merge pull request #1903 from HarveyWilliams/dev-v7
U4-9806 Media Picker media hover should show full title
2017-05-15 10:19:04 +02:00
Mikkel Holck Madsen 080150baa3 Merge pull request #1924 from wanddy/dev-v7
Fix missing translation for some menu tree item
2017-05-10 21:18:58 +02:00
wanddy c6bc5ae6aa Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2017-05-10 22:37:47 +08:00
Shannon Deminick f84d3b435b Merge pull request #1898 from DaveLong/U4-9799
Fixed Serialization issue in ValidatePasswordResetCodeModel
2017-05-10 14:59:04 +10:00
Shannon Deminick 99855bce11 Adds AppVeyor build badge 2017-05-10 14:51:40 +10:00
Shannon d0b2f10a8c U4-9836 CreatorId on a media is overwritten on save 2017-05-10 14:32:09 +10:00
Shannon Deminick bbfd570b8a Merge pull request #1938 from suedeapple/U4-9886
U4 9886 - automaticly - > automatically (typo fix up)
2017-05-10 14:24:36 +10:00
suedeapple 7b4912b1e7 automaticly - > automatically 2017-05-09 16:47:36 +01:00
suedeapple 8c6362d947 automaticly - > automatically 2017-05-09 16:40:59 +01:00
Shannon Deminick d012d8e8b6 Merge pull request #1925 from SaDa1337/dev-v7
fixed console error on media picker
2017-05-08 17:11:28 +10:00
Shannon Deminick 9792d8df25 Merge pull request #1930 from TomSteer/U4-9852
Change Context to be public on MigrationBase
2017-05-08 13:39:06 +10:00
Sebastiaan Janssen 85d10014c2 Make new build work when there's spaces in the current path 2017-05-05 16:14:59 +02:00
Sebastiaan Janssen fcf5ecc166 Uses vswhere to figure out where VS17 is installed (if needed)
Removes targets file that was almost unused, moved the relevant bits to the main csproj
Updates BuildBelle.bat to be completely independent of installed version of node & npm on the machine
2017-05-05 14:14:37 +02:00
Claus 3b236ba724 Merge pull request #1794 from TheBekker/fix-U4-9038
[fix-U4-9038] get and set media start node for mediaPickerOverlay in …
2017-05-05 10:47:52 +02:00
Tom Steer 3e294e290b Change Context to be public on MigrationBase 2017-05-04 09:10:35 +01:00
Maciej Sadowski 0eafa14246 fixed console error on media picker 2017-05-02 15:36:39 +02:00
wanddy b807b84466 Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2017-05-02 14:23:36 +08:00
wanddy ab551b2c96 Fix some menu tree header won't be translated.
This may be caused by the explicit definition of tree node name.

Signed-off-by: wanddy <wanddy@163.com>
2017-05-02 14:20:44 +08:00
wanddy 1520fa77d5 Add missing translation item for en.xml and zh.xml
Signed-off-by: wanddy <wanddy@163.com>
2017-05-02 14:12:58 +08:00
Shannon Deminick d91fc6ce60 Merge pull request #1887 from umbraco/temp-U4-9775
U4-9775 AlreadyClosedException is thrown when retrieving media if the…
2017-05-02 13:40:28 +10:00
Shannon Deminick 8461aea7d8 Merge pull request #1907 from wanddy/dev-v7
Improve Chinese translation.
2017-04-30 17:10:58 +10:00
Sebastiaan Janssen 9fa76a0133 Merge pull request #1911 from umbraco/temp-U4-9812
U4-9812 FailedLoginAttempts should be reset to 0 after a successfull …
2017-04-29 10:19:26 +02:00
Sebastiaan Janssen 3242b31a8a U4-9812 FailedLoginAttempts should be reset to 0 after a successfull login attempt 2017-04-28 12:46:58 +02:00
Shannon 2be330d237 adds notes, changes to protected 2017-04-28 07:45:01 +10:00
Shannon 4381a700ba Updates UmbracoVirtualNodeRouteHandler to have a new protected GetUmbracoContext method used to get the umb context used in the rest of the code 2017-04-28 07:38:03 +10:00
Shannon 99821954f1 adds notes 2017-04-28 07:31:44 +10:00
Shannon Deminick 10a15be8ad Merge pull request #1901 from tompipe/U4-9384-StaleVariableFix
Quick/simple fix for the stale variable
2017-04-28 07:28:00 +10:00
wanddy 0a2830aece Improve Chinese translation.
Signed-off-by: wanddy <wanddy@163.com>
2017-04-27 22:59:17 +08:00
Shannon bed5f8a03b backports updates from 7.6 so that the packages.umbraco.org endpoint is not used for fetching package files any longer 2017-04-27 13:21:07 +10:00
Shannon 7cd385dd6b disables ssl by default 2017-04-26 14:17:24 +10:00
Shannon 5d4a97591a Cherry picks changes for package fetching for Our to use the new endpoint and passes in the current version 2017-04-26 14:08:37 +10:00
Harvey Williams 81354cea3c U4-9806 Media Picker media hover should show full title
Added title to all media items in the media picker rather than just SVG and normal images.

Solving an issue where whole titles could not be visible if the title was too long.
2017-04-24 16:29:35 +01:00
Tom Pipe 67e3ec2ae0 Quick/simple fix for the stale variable
The umbracoContext variable can hold a null reference to UmbracoContext.Current. 

If a request containing a file extension is passed through an UmbracoVirtualNodeRouteHandler, the UmbracoContext will be null, because a context is never created for urls containing extensions due to https://github.com/umbraco/Umbraco-CMS/blob/5397f2c53acbdeb0805e1fe39fda938f571d295a/src/Umbraco.Core/UriExtensions.cs#L143

A call can be made to EnsureContext in the overridden FindContent method, but the fresh context would never get picked up, instead the variable always contains a null reference, and an exception is then thrown on line 23
2017-04-24 13:23:12 +01:00
Dave Long b88e714050 Fixed Serialization issue in Password Reset Validate Model 2017-04-21 08:33:21 +02:00
Shannon Deminick da8c46e426 Merge pull request #1859 from alexxn/dev-v7
Add basic xss prevention logic
2017-04-21 13:05:40 +10:00
Shannon Deminick 62af834176 Merge pull request #1876 from jwoods1/patch-1
The form closing tag
2017-04-18 13:17:12 +10:00
Shannon 2dac1b3cf5 Merge branch 'normalize-stream-seek' of https://github.com/JimBobSquarePants/Umbraco-CMS into JimBobSquarePants-normalize-stream-seek
# Conflicts:
#	src/Umbraco.Core/Media/ImageHelper.cs
2017-04-18 13:11:44 +10:00
Shannon Deminick 68fb951283 Merge pull request #1885 from JimBobSquarePants/fix-image-memoryleak
EncodingParameters implements IDisposable
2017-04-18 13:08:04 +10:00
Shannon Deminick 1ca825de62 Merge pull request #1886 from JimBobSquarePants/filesystem-docs
Document the IFileSystem interface
2017-04-18 13:05:35 +10:00
Shannon 13ccd86192 Adds another check for not being able to read the index 2017-04-18 12:35:21 +10:00
Shannon 336266c0eb U4-9775 AlreadyClosedException is thrown when retrieving media if the app domain is currently in a shutdown state and the site is under heavy load 2017-04-18 12:32:44 +10:00
James Jackson-South 54b57f7d51 Document the IFileSystem interface 2017-04-15 17:21:48 +10:00
James Jackson-South 2f6e161120 EncodingParameters implements IDisposable 2017-04-15 16:41:24 +10:00
Marc Goodson 58f9ff4b79 Add some debug logging when there is a distributed calls configuration issue 2017-04-11 20:37:59 +01:00
Shannon f2c7c1e2c6 bumps version 2017-04-10 16:42:31 +10:00
Shannon 9f2c428a7c updates to latest Models Builder 2017-04-10 16:12:23 +10:00
Shannon a958f946ef bumps version (beta) so i can post the patch release 2017-04-08 13:57:43 +10:00
Shannon 688652fb91 U4-9752 Very slow indexing after 7.5.12 update 2017-04-08 13:53:10 +10:00
Jason Woods 4ef1eeb8bc The form closing tag
The form was closing tag was </div> should be </form>
2017-04-07 11:09:21 -06:00
Claus d6bc0934ff u4-6233: backporting preview fix. 2017-04-07 11:05:37 +02:00
Stephan 759c6dfef2 Add a few SiteDomainHelper tests 2017-04-05 12:49:10 +02:00
Alex Novgorodov de9739118e Add basic xss prevention logic 2017-04-04 18:11:48 +03:00
Shannon Deminick 218f523022 Merge pull request #1843 from umbraco/temp-U4-9691
Fixes the Examine mgmt dashboard to look better and to detect if an i…
2017-04-03 16:28:36 +10:00
Shannon Deminick 50c6fb036a Merge pull request #1839 from umbraco/temp-uaasscrum-827
uaasscrum-827 - more robust umbraco.config
2017-04-03 16:19:27 +10:00
Shannon Deminick bc2115ff0a Merge pull request #1847 from umbraco/temp-u4-9683
Upgrade to ModelsBuilder 3.0.6
2017-04-03 16:03:13 +10:00
Shannon Deminick 9eee5c2bc0 Merge pull request #1840 from umbraco/temp-U4-9689
U4-9689 Content type description isn't always saved the same way
2017-04-03 15:53:30 +10:00
Mads Rasmussen ed3096642d Merge pull request #1844 from ryanology/temp-U4-9697
U4-9697 - Listview create new node ordering
2017-03-30 10:31:51 +02:00
Stephan 95508c4fb7 Upgrade nuspec accordingly 2017-03-30 09:32:22 +02:00
Stephan 4677faff38 Upgrade to ModelsBuilder 3.0.6 2017-03-30 08:54:01 +02:00
Shannon 725b3c5eca Merge branch 'dev-v7' into temp-U4-9691 2017-03-30 16:37:24 +11:00
Shannon 25f5179b29 updates nuspec 2017-03-30 16:36:54 +11:00
Shannon bf6d084f82 Merge branch 'dev-v7' into temp-U4-9691 2017-03-30 15:50:16 +11:00
Shannon 1a03bd9624 Logs an error if the index is rebuilding due to being corrupt 2017-03-30 15:49:45 +11:00
Shannon 6a1d60c5a7 U4-9692 Update to Examine 0.1.82 2017-03-30 15:43:06 +11:00
Shannon 4fef17190f adds notes 2017-03-30 11:03:07 +11:00
rrueckl 08ca75bb35 U4-9697 - Listview create new node ordering 2017-03-29 13:59:23 -04:00
Shannon 0512eaa7fd Fixes the Examine mgmt dashboard to look better and to detect if an index is unreadable in which case it allows you to rebuild it. 2017-03-29 21:43:00 +11:00
Claus e8df5f9eb4 U4-9689 Content type description isn't always saved the same way
also fixed for member types (and added test for media types also using the ContentTypeService)
2017-03-29 11:08:57 +02:00
Stephan c46678c766 uaasscrum-827 - more robust umbraco.config 2017-03-29 10:03:02 +02:00
Shannon 7cdb48b6c9 bumps version 2017-03-29 16:35:37 +11:00
Shannon Deminick 4ffa6bb41b Merge pull request #1824 from umbraco/temp-u4-9617
U4-9617 - perf for published date
2017-03-29 16:29:31 +11:00
Shannon 77af16db55 Merge branch 'dev-v7' into temp-u4-9617
# Conflicts:
#	src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs
2017-03-29 16:29:18 +11:00
Stephan 85d85fa587 Merge pull request #1819 from umbraco/temp-u4-9623
U4-9323 - fix DataTypeDefinitionRepository prevalues cache
2017-03-28 17:37:04 +02:00
Claus 7ade64f855 Merge pull request #1802 from umbraco/temp-U4-9637
U4-9637 addDashboardSection package action shouldn't add the dashboar…
2017-03-28 13:12:26 +02:00
Shannon Deminick 346e8dcaf0 Merge pull request #1820 from umbraco/temp-u4-9615
U4-9615 - implement way to find listviews in path fast
2017-03-28 16:05:25 +11:00
Shannon ddfd07bf4a Fixes count query 2017-03-28 16:04:06 +11:00
Shannon a9fe46da0c makes HasContainerInPath public 2017-03-28 15:55:45 +11:00
Shannon aca1f0d186 Adds comments 2017-03-28 15:46:33 +11:00
Shannon 9eb415d398 U4-9682 Repository's have a double nested DeepCloneRuntimeCacheProvider set which means all entities are double deep cloned in and out of the cache and ensures that PreValueCollections are not also manually deep cloned. 2017-03-28 15:41:55 +11:00
Shannon 8f6b728534 Moves paging value to a constant 2017-03-28 13:37:10 +11:00
Shannon Deminick 2e0c09ab39 Merge pull request #1827 from umbraco/temp-u4-9598
U4-9598 - fix paging in UmbracoContentIndexer
2017-03-28 13:31:37 +11:00
Shannon Deminick f211344786 Merge pull request #1825 from umbraco/temp-u4-9604
U4-9604 - fix current HttpContext in ManyObjectsResolverBase
2017-03-28 13:11:09 +11:00
Stephan 68702b98f5 U4-9604 - add nullcheck 2017-03-27 08:52:10 +02:00
Stephan f93caf277b Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into temp-u4-9604 2017-03-27 08:47:40 +02:00
Shannon Deminick e0a7698780 Merge pull request #1821 from andyneil/dev-v7-lang-fixes
Dev v7 lang fixes
2017-03-27 14:20:41 +11:00
Shannon Deminick 783c74d3ba Merge pull request #1829 from abryukhov/patch-6
Adding missing keys before v7.6
2017-03-27 14:12:08 +11:00
Alexander Bryukhov 21963c03a2 Adding missing keys before v7.6 2017-03-24 21:59:02 +07:00
Stephan 879a132077 U4-9598 - fix paging in UmbracoContentIndexer 2017-03-24 13:05:06 +01:00
Stephan 606ebcae92 U4-9604 - fix current HttpContext in ManyObjectsResolverBase 2017-03-24 11:07:15 +01:00
Stephan af10ae9e34 U4-9617 - fix 2017-03-23 18:00:58 +01:00
Stephan a23c150738 U4-9617 - fix 2017-03-23 17:51:30 +01:00
Stephan 085a678266 U4-9617 - perf for published date 2017-03-23 17:44:07 +01:00
andyneil cf7cafeb4c Update wording to be more grammatically correct 2017-03-23 13:41:48 +00:00
andyneil 870657affa Update wording to be more grammatically correct 2017-03-23 13:41:23 +00:00
Stephan fe11d4770d U4-9615 - implement way to find listviews in path fast 2017-03-23 14:07:45 +01:00
Stephan c8fe9030c7 U4-9323 - fix DataTypeDefinitionRepository prevalues cache 2017-03-23 10:39:28 +01:00
Shannon Deminick 3d81c73495 Merge pull request #1814 from umbraco/temp-u4-9658
U4-9658 - detect umbraco.config rogue content types, and fix
2017-03-23 12:16:10 +11:00
Shannon e7a540e717 Proper Exception handling 2017-03-23 12:15:14 +11:00
Shannon Deminick bb886c237e Merge pull request #1815 from umbraco/temp-u4-9610
U4-9610 - fix nullref in BulkPublishController
2017-03-23 11:28:03 +11:00
Shannon 6c1e271fa8 Fixes styling and fixing error message quotes to make it more clear 2017-03-23 11:27:46 +11:00
Shannon Deminick 4c1b807e4f Merge pull request #1812 from umbraco/temp-u4-6811
U4-6811 - fix preview set deletion
2017-03-23 11:06:33 +11:00
Shannon 3b22c0cdd7 Catches correct expected exception type, we'll log for other non expected errors. 2017-03-23 11:06:06 +11:00
Stephan 631404743f U4-9610 - fix nullref in BulkPublishController 2017-03-22 14:44:39 +01:00
Stephan d5c9639170 U4-9658 - detect umbraco.config rogue content types, and fix 2017-03-22 13:58:40 +01:00
Stephan 94b7c36d62 U4-6811 - fix preview set deletion 2017-03-22 12:16:33 +01:00
Claus 532b177d2e Merge pull request #1793 from Phosworks/U4-8418
Fixes jquery selector bug, http://issues.umbraco.org/issue/U4-8418
2017-03-20 14:43:43 +01:00
Shannon 4093fd9b79 U4-9637 addDashboardSection package action shouldn't add the dashboard if it already exists 2017-03-18 16:52:30 +11:00
Shannon 3d6f91cbef Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2017-03-18 15:47:56 +11:00
Shannon fffd508bb2 missing null check 2017-03-18 15:44:57 +11:00
Stephan 333b35d8b9 U4-9606 - hard cap of 8 minidump files 2017-03-16 15:51:19 +01:00
Claus 890673a197 Merge pull request #1797 from umbraco/temp-u4-9606
U4-9606 - New DumpOnTimeoutThreadAbort debug option
2017-03-16 15:38:01 +01:00
Stephan 27539d4aad U4-9606 - always minidump on Monitor.ReliableEnter exceptions 2017-03-16 14:04:28 +01:00
Stephan f7f23015d0 U4-9606 - missing file 2017-03-15 09:39:35 +01:00
Stephan e432b7061d U4-9606 - New DumpOnTimeoutThreadAbort debug option 2017-03-14 19:02:33 +01:00
TheBekker ab14b65078 [fix-U4-9038] get and set media start node for mediaPickerOverlay in grid 2017-03-13 22:54:20 +01:00
Wincent fc92d40b3a Fixes jquery selector bug, http://issues.umbraco.org/issue/U4-8418 2017-03-13 11:25:02 +01:00
111 changed files with 2308 additions and 980 deletions
+2
View File
@@ -142,3 +142,5 @@ build/ui-docs.zip
build/csharp-docs.zip
build/msbuild.log
.vs/
build/tools/
+2
View File
@@ -1,3 +1,5 @@
[![Build status](https://ci.appveyor.com/api/projects/status/ikpgqxiw9v8opltv/branch/dev-v7?svg=true)](https://ci.appveyor.com/project/Umbraco/umbraco-cms-hs8dx/branch/dev-v7)
Umbraco CMS
===========
The friendliest, most flexible and fastest growing ASP.NET CMS used by more than 390,000 websites worldwide: [https://umbraco.com](https://umbraco.com)
+43 -1
View File
@@ -49,10 +49,52 @@ REM This is necessary because SETLOCAL is on in InstallGit.cmd so that one might
REM but the path setting is lost due to SETLOCAL
path=C:\Program Files (x86)\Git\cmd;C:\Program Files\Git\cmd;%PATH%
SET toolsFolder=%CD%\tools\
IF NOT EXIST "%toolsFolder%" (
MD tools
)
SET nuGetExecutable=%CD%\tools\nuget.exe
IF NOT EXIST "%nuGetExecutable%" (
ECHO Getting NuGet so we can fetch some tools
ECHO Downloading https://dist.nuget.org/win-x86-commandline/latest/nuget.exe to %nuGetExecutable%
powershell -Command "(New-Object Net.WebClient).DownloadFile('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', '%nuGetExecutable%')"
)
:: We need 7za.exe for BuildBelle.bat
IF NOT EXIST "%toolsFolder%7za.exe" (
ECHO 7zip not found - fetching now
"%nuGetExecutable%" install 7-Zip.CommandLine -OutputDirectory tools -Verbosity quiet
)
:: We need vswhere.exe for VS2017+
IF NOT EXIST "%toolsFolder%vswhere.exe" (
ECHO vswhere not found - fetching now
"%nuGetExecutable%" install vswhere -OutputDirectory tools -Verbosity quiet
)
:: Put 7za.exe and vswhere.exe in a predictable path (not version specific)
FOR /f "delims=" %%A in ('dir "%toolsFolder%7-Zip.CommandLine.*" /b') DO SET "sevenZipExePath=%toolsFolder%%%A\"
MOVE "%sevenZipExePath%tools\7za.exe" "%toolsFolder%7za.exe"
FOR /f "delims=" %%A in ('dir "%toolsFolder%vswhere.*" /b') DO SET "vswhereExePath=%toolsFolder%%%A\"
MOVE "%vswhereExePath%tools\vswhere.exe" "%toolsFolder%vswhere.exe"
ECHO.
ECHO Making sure we have a web.config
IF NOT EXIST %CD%\..\src\Umbraco.Web.UI\web.config COPY %CD%\..\src\Umbraco.Web.UI\web.Template.config %CD%\..\src\Umbraco.Web.UI\web.config
for /f "usebackq tokens=1* delims=: " %%i in (`"%CD%\tools\vswhere.exe" -latest -requires Microsoft.Component.MSBuild`) do (
if /i "%%i"=="installationPath" set InstallDir=%%j
)
SET VSWherePath="%InstallDir%\MSBuild"
ECHO.
ECHO Visual Studio is installed in: %InstallDir%
SET MSBUILDPATH=C:\Program Files (x86)\MSBuild\14.0\Bin
SET MSBUILD="%MSBUILDPATH%\MsBuild.exe"
ECHO.
ECHO.
ECHO Performing MSBuild and producing Umbraco binaries zip files
@@ -60,7 +102,7 @@ ECHO This takes a few minutes and logging is set to report warnings
ECHO and errors only so it might seems like nothing is happening for a while.
ECHO You can check the msbuild.log file for progress.
ECHO.
%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe "Build.proj" /p:BUILD_RELEASE=%release% /p:BUILD_COMMENT=%comment% /p:NugetPackagesDirectory=%nuGetFolder% /consoleloggerparameters:Summary;ErrorsOnly;WarningsOnly /fileLogger
%MSBUILD% "Build.proj" /p:BUILD_RELEASE=%release% /p:BUILD_COMMENT=%comment% /p:NugetPackagesDirectory=%nuGetFolder% /p:VSWherePath=%VSWherePath%
IF ERRORLEVEL 1 GOTO :error
ECHO.
+48 -22
View File
@@ -1,33 +1,59 @@
@ECHO OFF
SETLOCAL
:: SETLOCAL is on, so changes to the path not persist to the actual user's path
SET release=%1
ECHO Installing Npm NuGet Package
SET nuGetFolder=%CD%\..\src\packages\
ECHO Configured packages folder: %nuGetFolder%
SET toolsFolder=%CD%\tools\
ECHO Current folder: %CD%
%CD%\..\src\.nuget\NuGet.exe install Npm.js -OutputDirectory %nuGetFolder% -Verbosity quiet
SET nodeFileName=node-v6.9.1-win-x86.7z
SET nodeExtractFolder=%toolsFolder%node.js.691
for /f "delims=" %%A in ('dir %nuGetFolder%node.js.* /b') do set "nodePath=%nuGetFolder%%%A\"
for /f "delims=" %%A in ('dir %nuGetFolder%npm.js.* /b') do set "npmPath=%nuGetFolder%%%A\tools\"
IF NOT EXIST "%nodeExtractFolder%" (
ECHO Downloading http://nodejs.org/dist/v6.9.1/%nodeFileName% to %toolsFolder%%nodeFileName%
powershell -Command "(New-Object Net.WebClient).DownloadFile('http://nodejs.org/dist/v6.9.1/%nodeFileName%', '%toolsFolder%%nodeFileName%')"
ECHO Extracting %nodeFileName% to %nodeExtractFolder%
"%toolsFolder%\7za.exe" x "%toolsFolder%\%nodeFileName%" -o"%nodeExtractFolder%" -aos > nul
)
FOR /f "delims=" %%A in ('dir "%nodeExtractFolder%\node*" /b') DO SET "nodePath=%nodeExtractFolder%\%%A"
ECHO Adding Npm and Node to path
REM SETLOCAL is on, so changes to the path not persist to the actual user's path
PATH=%npmPath%;%nodePath%;%PATH%
SET buildFolder=%CD%
SET nuGetExecutable=%CD%\tools\nuget.exe
IF NOT EXIST "%nuGetExecutable%" (
ECHO Downloading https://dist.nuget.org/win-x86-commandline/latest/nuget.exe to %nuGetExecutable%
powershell -Command "(New-Object Net.WebClient).DownloadFile('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', '%nuGetExecutable%')"
)
ECHO Change directory to %CD%\..\src\Umbraco.Web.UI.Client\
CD %CD%\..\src\Umbraco.Web.UI.Client\
SET drive=%CD:~0,2%
SET nuGetFolder=%drive%\packages\
FOR /f "delims=" %%A in ('dir "%nuGetFolder%npm.*" /b') DO SET "npmPath=%nuGetFolder%%%A\"
ECHO Do npm install and the grunt build of Belle
call npm cache clean --quiet
call npm install --quiet
call npm install -g grunt-cli --quiet
call npm install -g bower --quiet
call grunt build --buildversion=%release%
IF [%npmPath%] == [] GOTO :installnpm
IF NOT [%npmPath%] == [] GOTO :build
ECHO Move back to the build folder
CD %buildFolder%
:installnpm
ECHO Downloading npm
ECHO Configured packages folder: %nuGetFolder%
ECHO Installing Npm NuGet Package
"%nuGetExecutable%" install Npm -OutputDirectory %nuGetFolder% -Verbosity detailed
REM Ensures that we look for the just downloaded NPM, not whatever the user has installed on their machine
FOR /f "delims=" %%A in ('dir %nuGetFolder%npm.* /b') DO SET "npmPath=%nuGetFolder%%%A\"
GOTO :build
:build
ECHO Adding Npm and Node to path
REM SETLOCAL is on, so changes to the path not persist to the actual user's path
PATH="%npmPath%";"%nodePath%";%PATH%
SET buildFolder=%CD%
ECHO Change directory to %CD%\..\src\Umbraco.Web.UI.Client\
CD %CD%\..\src\Umbraco.Web.UI.Client\
ECHO Do npm install and the grunt build of Belle
call npm cache clean --quiet
call npm install --quiet
call npm install -g grunt-cli --quiet
call npm install -g bower --quiet
call grunt build --buildversion=%release%
ECHO Move back to the build folder
CD "%buildFolder%"
+1 -1
View File
@@ -32,7 +32,7 @@
<!-- AutoMapper can not be updated due to: https://github.com/AutoMapper/AutoMapper/issues/373#issuecomment-127644405 -->
<dependency id="AutoMapper" version="[3.3.1, 4.0.0)" />
<dependency id="Newtonsoft.Json" version="[6.0.8, 10.0.0)" />
<dependency id="Examine" version="[0.1.81, 1.0.0)" />
<dependency id="Examine" version="[0.1.82, 1.0.0)" />
<dependency id="ImageProcessor" version="[2.5.2, 3.0.0)" />
<dependency id="ImageProcessor.Web" version="[4.8.2, 5.0.0)" />
<dependency id="semver" version="[1.1.2, 2.0.0)" />
+2 -2
View File
@@ -17,8 +17,8 @@
<dependencies>
<dependency id="UmbracoCms.Core" version="[$version$]" />
<dependency id="Newtonsoft.Json" version="[6.0.8, 10.0.0)" />
<dependency id="Umbraco.ModelsBuilder" version="[3.0.5, 4.0.0)" />
<dependency id="ImageProcessor.Web.Config" version="[2.3.0, 3.0.0)" />
<dependency id="Umbraco.ModelsBuilder" version="[3.0.7, 4.0.0)" />
<dependency id="ImageProcessor.Web.Config" version="[2.3.0, 3.0.0)" />
</dependencies>
</metadata>
<files>
+1 -1
View File
@@ -1,2 +1,2 @@
# Usage: on line 2 put the release version, on line 3 put the version comment (example: beta)
7.5.11
7.5.14
+2 -2
View File
@@ -11,5 +11,5 @@ using System.Resources;
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("7.5.11")]
[assembly: AssemblyInformationalVersion("7.5.11")]
[assembly: AssemblyFileVersion("7.5.14")]
[assembly: AssemblyInformationalVersion("7.5.14")]
@@ -26,6 +26,9 @@ namespace Umbraco.Core.Cache
public DeepCloneRuntimeCacheProvider(IRuntimeCacheProvider innerProvider)
{
if (innerProvider.GetType() == typeof(DeepCloneRuntimeCacheProvider))
throw new InvalidOperationException("A " + typeof(DeepCloneRuntimeCacheProvider) + " cannot wrap another instance of " + typeof(DeepCloneRuntimeCacheProvider));
InnerProvider = innerProvider;
}
@@ -105,9 +108,11 @@ namespace Umbraco.Core.Cache
var value = result.Value; // force evaluation now - this may throw if cacheItem throws, and then nothing goes into cache
if (value == null) return null; // do not store null values (backward compat)
//Clone/reset to go into the cache
return CheckCloneableAndTracksChanges(value);
}, timeout, isSliding, priority, removedCallback, dependentFiles);
//Clone/reset to go out of the cache
return CheckCloneableAndTracksChanges(cached);
}
@@ -0,0 +1,27 @@
using System;
namespace Umbraco.Core.Configuration
{
internal static class CoreDebugExtensions
{
private static CoreDebug _coreDebug;
public static CoreDebug CoreDebug(this UmbracoConfig config)
{
return _coreDebug ?? (_coreDebug = new CoreDebug());
}
}
internal class CoreDebug
{
public CoreDebug()
{
var appSettings = System.Configuration.ConfigurationManager.AppSettings;
DumpOnTimeoutThreadAbort = string.Equals("true", appSettings["Umbraco.CoreDebug.DumpOnTimeoutThreadAbort"], StringComparison.OrdinalIgnoreCase);
}
// when true, the Logger creates a minidump of w3wp in ~/App_Data/MiniDump whenever it logs
// an error due to a ThreadAbortException that is due to a timeout.
public bool DumpOnTimeoutThreadAbort { get; private set; }
}
}
@@ -8,6 +8,7 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
Guid Id { get; }
string RepositoryUrl { get; }
string WebServiceUrl { get; }
bool HasCustomWebServiceUrl { get; }
bool HasCustomWebServiceUrl { get; }
string RestApiUrl { get; }
}
}
@@ -0,0 +1,19 @@
using System;
using System.Linq;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
public static class RepositoryConfigExtensions
{
//Our package repo
private static readonly Guid RepoGuid = new Guid("65194810-1f85-11dd-bd0b-0800200c9a66");
public static IRepository GetDefault(this IRepositoriesSection repos)
{
var found = repos.Repositories.FirstOrDefault(x => x.Id == RepoGuid);
if (found == null)
throw new InvalidOperationException("No default package repository found with id " + RepoGuid);
return found;
}
}
}
@@ -38,9 +38,16 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
get
{
var prop = Properties["webserviceurl"];
var repoUrl = this[prop] as ConfigurationElement;
return (repoUrl != null && repoUrl.ElementInformation.IsPresent);
return (string) prop.DefaultValue != (string) this[prop];
}
}
[ConfigurationProperty("restapiurl", DefaultValue = "https://our.umbraco.org/webapi/packages/v1")]
public string RestApiUrl
{
get { return (string)base["restapiurl"]; }
set { base["restapiurl"] = value; }
}
}
}
@@ -6,7 +6,7 @@ namespace Umbraco.Core.Configuration
{
public class UmbracoVersion
{
private static readonly Version Version = new Version("7.5.11");
private static readonly Version Version = new Version("7.5.14");
/// <summary>
/// Gets the current version of Umbraco.
+135
View File
@@ -0,0 +1,135 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using Umbraco.Core.IO;
namespace Umbraco.Core.Diagnostics
{
// taken from https://blogs.msdn.microsoft.com/dondu/2010/10/24/writing-minidumps-in-c/
// and https://blogs.msdn.microsoft.com/dondu/2010/10/31/writing-minidumps-from-exceptions-in-c/
// which itself got it from http://blog.kalmbach-software.de/2008/12/13/writing-minidumps-in-c/
internal static class MiniDump
{
private static readonly object LockO = new object();
[Flags]
public enum Option : uint
{
// From dbghelp.h:
Normal = 0x00000000,
WithDataSegs = 0x00000001,
WithFullMemory = 0x00000002,
WithHandleData = 0x00000004,
FilterMemory = 0x00000008,
ScanMemory = 0x00000010,
WithUnloadedModules = 0x00000020,
WithIndirectlyReferencedMemory = 0x00000040,
FilterModulePaths = 0x00000080,
WithProcessThreadData = 0x00000100,
WithPrivateReadWriteMemory = 0x00000200,
WithoutOptionalData = 0x00000400,
WithFullMemoryInfo = 0x00000800,
WithThreadInfo = 0x00001000,
WithCodeSegs = 0x00002000,
WithoutAuxiliaryState = 0x00004000,
WithFullAuxiliaryState = 0x00008000,
WithPrivateWriteCopyMemory = 0x00010000,
IgnoreInaccessibleMemory = 0x00020000,
ValidTypeFlags = 0x0003ffff,
}
//typedef struct _MINIDUMP_EXCEPTION_INFORMATION {
// DWORD ThreadId;
// PEXCEPTION_POINTERS ExceptionPointers;
// BOOL ClientPointers;
//} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION;
[StructLayout(LayoutKind.Sequential, Pack = 4)] // Pack=4 is important! So it works also for x64!
public struct MiniDumpExceptionInformation
{
public uint ThreadId;
public IntPtr ExceptionPointers;
[MarshalAs(UnmanagedType.Bool)]
public bool ClientPointers;
}
//BOOL
//WINAPI
//MiniDumpWriteDump(
// __in HANDLE hProcess,
// __in DWORD ProcessId,
// __in HANDLE hFile,
// __in MINIDUMP_TYPE DumpType,
// __in_opt PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
// __in_opt PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
// __in_opt PMINIDUMP_CALLBACK_INFORMATION CallbackParam
// );
// Overload requiring MiniDumpExceptionInformation
[DllImport("dbghelp.dll", EntryPoint = "MiniDumpWriteDump", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
private static extern bool MiniDumpWriteDump(IntPtr hProcess, uint processId, SafeHandle hFile, uint dumpType, ref MiniDumpExceptionInformation expParam, IntPtr userStreamParam, IntPtr callbackParam);
// Overload supporting MiniDumpExceptionInformation == NULL
[DllImport("dbghelp.dll", EntryPoint = "MiniDumpWriteDump", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
private static extern bool MiniDumpWriteDump(IntPtr hProcess, uint processId, SafeHandle hFile, uint dumpType, IntPtr expParam, IntPtr userStreamParam, IntPtr callbackParam);
[DllImport("kernel32.dll", EntryPoint = "GetCurrentThreadId", ExactSpelling = true)]
private static extern uint GetCurrentThreadId();
private static bool Write(SafeHandle fileHandle, Option options, bool withException = false)
{
var currentProcess = Process.GetCurrentProcess();
var currentProcessHandle = currentProcess.Handle;
var currentProcessId = (uint)currentProcess.Id;
MiniDumpExceptionInformation exp;
exp.ThreadId = GetCurrentThreadId();
exp.ClientPointers = false;
exp.ExceptionPointers = IntPtr.Zero;
if (withException)
exp.ExceptionPointers = Marshal.GetExceptionPointers();
var bRet = exp.ExceptionPointers == IntPtr.Zero
? MiniDumpWriteDump(currentProcessHandle, currentProcessId, fileHandle, (uint) options, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero)
: MiniDumpWriteDump(currentProcessHandle, currentProcessId, fileHandle, (uint) options, ref exp, IntPtr.Zero, IntPtr.Zero);
return bRet;
}
public static bool Dump(Option options = Option.WithFullMemory, bool withException = false)
{
lock (LockO)
{
// work around "stack trace is not available while minidump debugging",
// by making sure a local var (that we can inspect) contains the stack trace.
// getting the call stack before it is unwound would require a special exception
// filter everywhere in our code = not!
var stacktrace = withException ? Environment.StackTrace : string.Empty;
var filepath = IOHelper.MapPath("~/App_Data/MiniDump");
if (Directory.Exists(filepath) == false)
Directory.CreateDirectory(filepath);
var filename = Path.Combine(filepath, string.Format("{0:yyyyMMddTHHmmss}.{1}.dmp", DateTime.UtcNow, Guid.NewGuid().ToString("N").Substring(0, 4)));
using (var stream = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite, FileShare.Write))
{
return Write(stream.SafeFileHandle, options, withException);
}
}
}
public static bool OkToDump()
{
lock (LockO)
{
var filepath = IOHelper.MapPath("~/App_Data/MiniDump");
if (Directory.Exists(filepath) == false) return true;
var count = Directory.GetFiles(filepath, "*.dmp").Length;
return count < 8;
}
}
}
}
@@ -0,0 +1,12 @@
using System;
namespace Umbraco.Core.Exceptions
{
internal class ConnectionException : Exception
{
public ConnectionException(string message, Exception innerException) : base(message, innerException)
{
}
}
}
+108 -3
View File
@@ -7,39 +7,144 @@ namespace Umbraco.Core.IO
//TODO: There is no way to create a directory here without creating a file in a directory and then deleting it
//TODO: Should probably implement a rename?
public interface IFileSystem
/// <summary>
/// Provides methods allowing the manipulation of files within an Umbraco application.
/// </summary>
public interface IFileSystem
{
/// <summary>
/// Gets all directories matching the given path.
/// </summary>
/// <param name="path">The path to the directories.</param>
/// <returns>
/// The <see cref="IEnumerable{String}"/> representing the matched directories.
/// </returns>
IEnumerable<string> GetDirectories(string path);
/// <summary>
/// Deletes the specified directory.
/// </summary>
/// <param name="path">The name of the directory to remove.</param>
void DeleteDirectory(string path);
/// <summary>
/// Deletes the specified directory and, if indicated, any subdirectories and files in the directory.
/// </summary>
/// <remarks>Azure blob storage has no real concept of directories so deletion is always recursive.</remarks>
/// <param name="path">The name of the directory to remove.</param>
/// <param name="recursive">Whether to remove directories, subdirectories, and files in path.</param>
void DeleteDirectory(string path, bool recursive);
/// <summary>
/// Determines whether the specified directory exists.
/// </summary>
/// <param name="path">The directory to check.</param>
/// <returns>
/// <c>True</c> if the directory exists and the user has permission to view it; otherwise <c>false</c>.
/// </returns>
bool DirectoryExists(string path);
/// <summary>
/// Adds a file to the file system.
/// </summary>
/// <param name="path">The path to the given file.</param>
/// <param name="stream">The <see cref="Stream"/> containing the file contents.</param>
void AddFile(string path, Stream stream);
/// <summary>
/// Adds a file to the file system.
/// </summary>
/// <param name="path">The path to the given file.</param>
/// <param name="stream">The <see cref="Stream"/> containing the file contents.</param>
/// <param name="overrideIfExists">Whether to override the file if it already exists.</param>
void AddFile(string path, Stream stream, bool overrideIfExists);
/// <summary>
/// Gets all files matching the given path.
/// </summary>
/// <param name="path">The path to the files.</param>
/// <returns>
/// The <see cref="IEnumerable{String}"/> representing the matched files.
/// </returns>
IEnumerable<string> GetFiles(string path);
/// <summary>
/// Gets all files matching the given path and filter.
/// </summary>
/// <param name="path">The path to the files.</param>
/// <param name="filter">A filter that allows the querying of file extension. <example>*.jpg</example></param>
/// <returns>
/// The <see cref="IEnumerable{String}"/> representing the matched files.
/// </returns>
IEnumerable<string> GetFiles(string path, string filter);
/// <summary>
/// Gets a <see cref="Stream"/> representing the file at the gieven path.
/// </summary>
/// <param name="path">The path to the file.</param>
/// <returns>
/// <see cref="Stream"/>.
/// </returns>
Stream OpenFile(string path);
/// <summary>
/// Deletes the specified file.
/// </summary>
/// <param name="path">The name of the file to remove.</param>
void DeleteFile(string path);
/// <summary>
/// Determines whether the specified file exists.
/// </summary>
/// <param name="path">The file to check.</param>
/// <returns>
/// <c>True</c> if the file exists and the user has permission to view it; otherwise <c>false</c>.
/// </returns>
bool FileExists(string path);
/// <summary>
/// Returns the application relative path to the file.
/// </summary>
/// <param name="fullPathOrUrl">The full path or url.</param>
/// <returns>
/// The <see cref="string"/> representing the relative path.
/// </returns>
string GetRelativePath(string fullPathOrUrl);
/// <summary>
/// Gets the full qualified path to the file.
/// </summary>
/// <param name="path">The file to return the full path for.</param>
/// <returns>
/// The <see cref="string"/> representing the full path.
/// </returns>
string GetFullPath(string path);
/// <summary>
/// Returns the application relative url to the file.
/// </summary>
/// <param name="path">The path to return the url for.</param>
/// <returns>
/// <see cref="string"/> representing the relative url.
/// </returns>
string GetUrl(string path);
/// <summary>
/// Gets the last modified date/time of the file, expressed as a UTC value.
/// </summary>
/// <param name="path">The path to the file.</param>
/// <returns>
/// <see cref="DateTimeOffset"/>.
/// </returns>
DateTimeOffset GetLastModified(string path);
/// <summary>
/// Gets the created date/time of the file, expressed as a UTC value.
/// </summary>
/// <param name="path">The path to the file.</param>
/// <returns>
/// <see cref="DateTimeOffset"/>.
/// </returns>
DateTimeOffset GetCreated(string path);
}
}
+1 -1
View File
@@ -122,7 +122,7 @@ namespace Umbraco.Core.IO
Directory.CreateDirectory(Path.GetDirectoryName(fullPath)); // ensure it exists
if (stream.CanSeek)
stream.Seek(0, 0);
stream.Seek(0, SeekOrigin.Begin);
using (var destination = (Stream)File.Create(fullPath))
stream.CopyTo(destination);
+39 -5
View File
@@ -7,6 +7,8 @@ using System.Threading;
using System.Web;
using log4net;
using log4net.Config;
using Umbraco.Core.Configuration;
using Umbraco.Core.Diagnostics;
namespace Umbraco.Core.Logging
{
@@ -57,23 +59,55 @@ namespace Umbraco.Core.Logging
internal ILog LoggerFor(object getTypeFromInstance)
{
if (getTypeFromInstance == null) throw new ArgumentNullException("getTypeFromInstance");
return LogManager.GetLogger(getTypeFromInstance.GetType());
}
public void Error(Type callingType, string message, Exception exception)
{
var logger = LogManager.GetLogger(callingType);
if (logger == null) return;
var dump = false;
if (IsTimeoutThreadAbortException(exception))
{
message += "\r\nThe thread has been aborted, because the request has timed out.";
// dump if configured, or if stacktrace contains Monitor.ReliableEnter
dump = UmbracoConfig.For.CoreDebug().DumpOnTimeoutThreadAbort || IsMonitorEnterThreadAbortException(exception);
// dump if it is ok to dump (might have a cap on number of dump...)
dump &= MiniDump.OkToDump();
}
logger.Error(message, exception);
if (dump)
{
try
{
var dumped = MiniDump.Dump(withException: true);
message += dumped
? "\r\nA minidump was created in App_Data/MiniDump"
: "\r\nFailed to create a minidump";
}
catch (Exception e)
{
message += string.Format("\r\nFailed to create a minidump ({0}: {1})", e.GetType().FullName, e.Message);
}
}
logger.Error(message, exception);
}
private static bool IsMonitorEnterThreadAbortException(Exception exception)
{
var abort = exception as ThreadAbortException;
if (abort == null) return false;
var stacktrace = abort.StackTrace;
return stacktrace.Contains("System.Threading.Monitor.ReliableEnter");
}
private static bool IsTimeoutThreadAbortException(Exception exception)
{
var abort = exception as ThreadAbortException;
@@ -105,7 +139,7 @@ namespace Umbraco.Core.Logging
if (showHttpTrace && HttpContext.Current != null)
{
HttpContext.Current.Trace.Warn(callingType.Name, string.Format(message, formatItems.Select(x => x.Invoke()).ToArray()));
}
}
var logger = LogManager.GetLogger(callingType);
if (logger == null || logger.IsWarnEnabled == false) return;
@@ -122,7 +156,7 @@ namespace Umbraco.Core.Logging
var logger = LogManager.GetLogger(callingType);
if (logger == null || logger.IsWarnEnabled == false) return;
var executedParams = formatItems.Select(x => x.Invoke()).ToArray();
logger.WarnFormat((message) + ". Exception: " + e, executedParams);
logger.WarnFormat((message) + ". Exception: " + e, executedParams);
}
/// <summary>
+22 -20
View File
@@ -227,35 +227,37 @@ namespace Umbraco.Core.Media
}
// Set compresion ratio to 90%
var ep = new EncoderParameters();
ep.Param[0] = new EncoderParameter(Encoder.Quality, 90L);
// Save the new image using the dimensions of the image
var predictableThumbnailName = thumbnailFileName.Replace("UMBRACOSYSTHUMBNAIL", maxWidthHeight.ToString(CultureInfo.InvariantCulture));
var predictableThumbnailNameJpg = predictableThumbnailName.Substring(0, predictableThumbnailName.LastIndexOf(".", StringComparison.Ordinal)) + ".jpg";
using (var ms = new MemoryStream())
string newFileName;
using (var ep = new EncoderParameters())
{
bp.Save(ms, codec, ep);
ms.Seek(0, 0);
ep.Param[0] = new EncoderParameter(Encoder.Quality, 90L);
fs.AddFile(predictableThumbnailName, ms);
fs.AddFile(predictableThumbnailNameJpg, ms);
}
// Save the new image using the dimensions of the image
var predictableThumbnailName = thumbnailFileName.Replace("UMBRACOSYSTHUMBNAIL", maxWidthHeight.ToString(CultureInfo.InvariantCulture));
var predictableThumbnailNameJpg = predictableThumbnailName.Substring(0, predictableThumbnailName.LastIndexOf(".", StringComparison.Ordinal)) + ".jpg";
using (var ms = new MemoryStream())
{
bp.Save(ms, codec, ep);
ms.Seek(0, SeekOrigin.Begin);
// TODO: Remove this, this is ONLY here for backwards compatibility but it is essentially completely unusable see U4-5385
var newFileName = thumbnailFileName.Replace("UMBRACOSYSTHUMBNAIL", string.Format("{0}x{1}", widthTh, heightTh));
using (var ms = new MemoryStream())
{
bp.Save(ms, codec, ep);
ms.Seek(0, 0);
fs.AddFile(predictableThumbnailName, ms);
fs.AddFile(predictableThumbnailNameJpg, ms);
}
fs.AddFile(newFileName, ms);
// TODO: Remove this, this is ONLY here for backwards compatibility but it is essentially completely unusable see U4-5385
newFileName = thumbnailFileName.Replace("UMBRACOSYSTHUMBNAIL", string.Format("{0}x{1}", widthTh, heightTh));
using (var ms = new MemoryStream())
{
bp.Save(ms, codec, ep);
ms.Seek(0, SeekOrigin.Begin);
fs.AddFile(newFileName, ms);
}
}
return new ResizedImage(widthTh, heightTh, newFileName);
}
}
}
}
}
+3
View File
@@ -274,6 +274,9 @@ namespace Umbraco.Core.Models
/// </summary>
public bool HasPublishedVersion { get { return PublishedVersionGuid != default(Guid); } }
[IgnoreDataMember]
internal DateTime PublishedDate { get; set; }
/// <summary>
/// Changes the Trashed state of the content object
/// </summary>
+1 -1
View File
@@ -545,7 +545,7 @@ namespace Umbraco.Core.Models
if (supportsResizing)
{
//get the original image from the original stream
if (fileStream.CanSeek) fileStream.Seek(0, 0);
if (fileStream.CanSeek) fileStream.Seek(0, SeekOrigin.Begin);
using (var originalImage = Image.FromStream(fileStream))
{
var additionalSizes = new List<int>();
@@ -179,7 +179,7 @@ namespace Umbraco.Core.Models.PublishedContent
}
if (contentType == null)
throw new Exception(string.Format("ContentTypeService failed to find a {0} type with alias \"{1}\".",
throw new InvalidOperationException(string.Format("ContentTypeService failed to find a {0} type with alias \"{1}\".",
itemType.ToString().ToLower(), alias));
return new PublishedContentType(contentType);
@@ -19,5 +19,8 @@ namespace Umbraco.Core.Models.Rdbms
[Column("newest")]
public bool Newest { get; set; }
[Column("updateDate")]
public DateTime VersionDate { get; set; }
}
}
@@ -22,6 +22,7 @@ namespace Umbraco.Core.ObjectResolution
private readonly string _httpContextKey;
private readonly List<Type> _instanceTypes = new List<Type>();
private IEnumerable<TResolved> _sortedValues;
private readonly Func<HttpContextBase> _httpContextGetter;
private int _defaultPluginWeight = 100;
@@ -42,12 +43,7 @@ namespace Umbraco.Core.ObjectResolution
if (logger == null) throw new ArgumentNullException("logger");
CanResolveBeforeFrozen = false;
if (scope == ObjectLifetimeScope.HttpRequest)
{
if (HttpContext.Current == null)
throw new InvalidOperationException("Use alternative constructor accepting a HttpContextBase object in order to set the lifetime scope to HttpRequest when HttpContext.Current is null");
CurrentHttpContext = new HttpContextWrapper(HttpContext.Current);
}
_httpContextGetter = () => new HttpContextWrapper(HttpContext.Current);
ServiceProvider = serviceProvider;
Logger = logger;
@@ -84,7 +80,7 @@ namespace Umbraco.Core.ObjectResolution
LifetimeScope = ObjectLifetimeScope.HttpRequest;
_httpContextKey = GetType().FullName;
ServiceProvider = serviceProvider;
CurrentHttpContext = httpContext;
_httpContextGetter = () => httpContext;
_instanceTypes = new List<Type>();
InitializeAppInstances();
@@ -160,7 +156,16 @@ namespace Umbraco.Core.ObjectResolution
/// Gets or sets the <see cref="HttpContextBase"/> used to initialize this object, if any.
/// </summary>
/// <remarks>If not null, then <c>LifetimeScope</c> will be <c>ObjectLifetimeScope.HttpRequest</c>.</remarks>
protected HttpContextBase CurrentHttpContext { get; private set; }
protected HttpContextBase CurrentHttpContext
{
get
{
var context = _httpContextGetter == null ? null : _httpContextGetter();
if (context == null)
throw new InvalidOperationException("Cannot use this resolver with lifetime 'HttpRequest' when there is no current HttpContext. Either use the ctor accepting an HttpContextBase, or use the resolver from within a request exclusively.");
return context;
}
}
/// <summary>
/// Returns the service provider used to instantiate objects
@@ -196,7 +201,7 @@ namespace Umbraco.Core.ObjectResolution
/// <summary>
/// Gets or sets the default type weight.
/// </summary>
/// <remarks>Determines the weight of types that do not have a <c>WeightAttribute</c> set on
/// <remarks>Determines the weight of types that do not have a <c>WeightAttribute</c> set on
/// them, when calling <c>GetSortedValues</c>.</remarks>
protected virtual int DefaultPluginWeight
{
@@ -276,7 +281,7 @@ namespace Umbraco.Core.ObjectResolution
/// Removes a type.
/// </summary>
/// <param name="value">The type to remove.</param>
/// <exception cref="InvalidOperationException">the resolver does not support removing types, or
/// <exception cref="InvalidOperationException">the resolver does not support removing types, or
/// the type is not a valid type for the resolver.</exception>
public virtual void RemoveType(Type value)
{
@@ -296,7 +301,7 @@ namespace Umbraco.Core.ObjectResolution
/// Removes a type.
/// </summary>
/// <typeparam name="T">The type to remove.</typeparam>
/// <exception cref="InvalidOperationException">the resolver does not support removing types, or
/// <exception cref="InvalidOperationException">the resolver does not support removing types, or
/// the type is not a valid type for the resolver.</exception>
public void RemoveType<T>()
where T : TResolved
@@ -309,7 +314,7 @@ namespace Umbraco.Core.ObjectResolution
/// </summary>
/// <param name="types">The types to add.</param>
/// <remarks>The types are appended at the end of the list.</remarks>
/// <exception cref="InvalidOperationException">the resolver does not support adding types, or
/// <exception cref="InvalidOperationException">the resolver does not support adding types, or
/// a type is not a valid type for the resolver, or a type is already in the collection of types.</exception>
protected void AddTypes(IEnumerable<Type> types)
{
@@ -336,7 +341,7 @@ namespace Umbraco.Core.ObjectResolution
/// </summary>
/// <param name="value">The type to add.</param>
/// <remarks>The type is appended at the end of the list.</remarks>
/// <exception cref="InvalidOperationException">the resolver does not support adding types, or
/// <exception cref="InvalidOperationException">the resolver does not support adding types, or
/// the type is not a valid type for the resolver, or the type is already in the collection of types.</exception>
public virtual void AddType(Type value)
{
@@ -362,7 +367,7 @@ namespace Umbraco.Core.ObjectResolution
/// </summary>
/// <typeparam name="T">The type to add.</typeparam>
/// <remarks>The type is appended at the end of the list.</remarks>
/// <exception cref="InvalidOperationException">the resolver does not support adding types, or
/// <exception cref="InvalidOperationException">the resolver does not support adding types, or
/// the type is not a valid type for the resolver, or the type is already in the collection of types.</exception>
public void AddType<T>()
where T : TResolved
@@ -404,7 +409,7 @@ namespace Umbraco.Core.ObjectResolution
/// </summary>
/// <param name="index">The zero-based index at which the type should be inserted.</param>
/// <param name="value">The type to insert.</param>
/// <exception cref="InvalidOperationException">the resolver does not support inserting types, or
/// <exception cref="InvalidOperationException">the resolver does not support inserting types, or
/// the type is not a valid type for the resolver, or the type is already in the collection of types.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> is out of range.</exception>
public virtual void InsertType(int index, Type value)
@@ -430,7 +435,7 @@ namespace Umbraco.Core.ObjectResolution
/// Inserts a type at the beginning of the list.
/// </summary>
/// <param name="value">The type to insert.</param>
/// <exception cref="InvalidOperationException">the resolver does not support inserting types, or
/// <exception cref="InvalidOperationException">the resolver does not support inserting types, or
/// the type is not a valid type for the resolver, or the type is already in the collection of types.</exception>
public virtual void InsertType(Type value)
{
@@ -464,7 +469,7 @@ namespace Umbraco.Core.ObjectResolution
/// </summary>
/// <param name="existingType">The existing type before which to insert.</param>
/// <param name="value">The type to insert.</param>
/// <exception cref="InvalidOperationException">the resolver does not support inserting types, or
/// <exception cref="InvalidOperationException">the resolver does not support inserting types, or
/// one of the types is not a valid type for the resolver, or the existing type is not in the collection,
/// or the new type is already in the collection of types.</exception>
public virtual void InsertTypeBefore(Type existingType, Type value)
@@ -498,7 +503,7 @@ namespace Umbraco.Core.ObjectResolution
/// </summary>
/// <typeparam name="TExisting">The existing type before which to insert.</typeparam>
/// <typeparam name="T">The type to insert.</typeparam>
/// <exception cref="InvalidOperationException">the resolver does not support inserting types, or
/// <exception cref="InvalidOperationException">the resolver does not support inserting types, or
/// one of the types is not a valid type for the resolver, or the existing type is not in the collection,
/// or the new type is already in the collection of types.</exception>
public void InsertTypeBefore<TExisting, T>()
@@ -72,6 +72,9 @@ namespace Umbraco.Core.Persistence.Factories
content.PublishedVersionGuid = publishedDto == null
? (dto.DocumentPublishedReadOnlyDto == null ? default(Guid) : dto.DocumentPublishedReadOnlyDto.VersionId)
: publishedDto.VersionId;
content.PublishedDate = publishedDto == null
? (dto.DocumentPublishedReadOnlyDto == null ? default(DateTime) : dto.DocumentPublishedReadOnlyDto.VersionDate)
: publishedDto.VersionDate;
//on initial construction we don't want to have dirty properties tracked
// http://issues.umbraco.org/issue/U4-1946
@@ -23,7 +23,7 @@ namespace Umbraco.Core.Persistence.Migrations
Logger = logger;
}
internal IMigrationContext Context;
public IMigrationContext Context;
public abstract void Up();
public abstract void Down();
@@ -513,11 +513,13 @@ namespace Umbraco.Core.Persistence.Repositories
dto.DocumentPublishedReadOnlyDto = new DocumentPublishedReadOnlyDto
{
VersionId = dto.VersionId,
VersionDate = dto.UpdateDate,
Newest = true,
NodeId = dto.NodeId,
Published = true
Published = true
};
((Content)entity).PublishedVersionGuid = dto.VersionId;
((Content) entity).PublishedVersionGuid = dto.VersionId;
((Content) entity).PublishedDate = dto.UpdateDate;
}
entity.ResetDirtyProperties();
@@ -687,22 +689,26 @@ namespace Umbraco.Core.Persistence.Repositories
dto.DocumentPublishedReadOnlyDto = new DocumentPublishedReadOnlyDto
{
VersionId = dto.VersionId,
VersionDate = dto.UpdateDate,
Newest = true,
NodeId = dto.NodeId,
Published = true
};
((Content)entity).PublishedVersionGuid = dto.VersionId;
((Content) entity).PublishedVersionGuid = dto.VersionId;
((Content) entity).PublishedDate = dto.UpdateDate;
}
else if (publishedStateChanged)
{
dto.DocumentPublishedReadOnlyDto = new DocumentPublishedReadOnlyDto
{
VersionId = default(Guid),
VersionId = default (Guid),
VersionDate = default (DateTime),
Newest = false,
NodeId = dto.NodeId,
Published = false
};
((Content)entity).PublishedVersionGuid = default(Guid);
((Content) entity).PublishedVersionGuid = default(Guid);
((Content) entity).PublishedDate = default (DateTime);
}
entity.ResetDirtyProperties();
@@ -974,7 +980,7 @@ order by umbracoNode.{2}, umbracoNode.parentID, umbracoNode.sortOrder",
}
//order by update date DESC, if there is corrupted published flags we only want the latest!
var publishedSql = new Sql(@"SELECT cmsDocument.nodeId, cmsDocument.published, cmsDocument.versionId, cmsDocument.newest
var publishedSql = new Sql(@"SELECT cmsDocument.nodeId, cmsDocument.published, cmsDocument.versionId, cmsDocument.updateDate, cmsDocument.newest
FROM cmsDocument INNER JOIN cmsContentVersion ON cmsContentVersion.VersionId = cmsDocument.versionId
WHERE cmsDocument.published = 1 AND cmsDocument.nodeId IN
(" + parsedOriginalSql + @")
@@ -1250,5 +1250,19 @@ WHERE cmsContentType." + aliasColumn + @" LIKE @pattern",
while (aliases.Contains(test = alias + i)) i++;
return test;
}
/// <summary>
/// Given the path of a content item, this will return true if the content item exists underneath a list view content item
/// </summary>
/// <param name="contentPath"></param>
/// <returns></returns>
public bool HasContainerInPath(string contentPath)
{
var ids = contentPath.Split(',').Select(int.Parse);
var sql = new Sql(@"SELECT COUNT(*) FROM cmsContentType
INNER JOIN cmsContent ON cmsContentType.nodeId=cmsContent.contentType
WHERE cmsContent.nodeId IN (@ids) AND cmsContentType.isContainer=@isContainer", new { ids, isContainer = true });
return Database.ExecuteScalar<int>(sql) > 0;
}
}
}
@@ -34,7 +34,7 @@ namespace Umbraco.Core.Persistence.Repositories
: base(work, cache, logger, sqlSyntax)
{
_contentTypeRepository = contentTypeRepository;
_preValRepository = new DataTypePreValueRepository(work, CacheHelper.CreateDisabledCacheHelper(), logger, sqlSyntax);
_preValRepository = new DataTypePreValueRepository(work, CacheHelper.CreateDisabledCacheHelper(), logger, sqlSyntax);
}
#region Overrides of RepositoryBase<int,DataTypeDefinition>
@@ -276,47 +276,33 @@ AND umbracoNode.id <> @id",
public PreValueCollection GetPreValuesCollectionByDataTypeId(int dataTypeId)
{
var cached = RuntimeCache.GetCacheItemsByKeySearch<PreValueCollection>(GetPrefixedCacheKey(dataTypeId));
if (cached != null && cached.Any())
{
//return from the cache, ensure it's a cloned result
return (PreValueCollection)cached.First().DeepClone();
}
return GetAndCachePreValueCollection(dataTypeId);
}
internal static string GetCacheKeyRegex(int preValueId)
{
return CacheKeys.DataTypePreValuesCacheKey + @"[-\d]+-([\d]*,)*" + preValueId + @"(?!\d)[,\d$]*";
var collection = GetCachedPreValueCollection(dataTypeId);
return collection;
}
/// <summary>
/// Gets a specific PreValue by its Id
/// </summary>
/// <param name="preValueId">Id of the PreValue to retrieve the value from</param>
/// <returns>PreValue as a string</returns>
public string GetPreValueAsString(int preValueId)
{
//We need to see if we can find the cached PreValueCollection based on the cache key above
var collections = RuntimeCache.GetCacheItemsByKeySearch<PreValueCollection>(CacheKeys.DataTypePreValuesCacheKey + "_");
var cached = RuntimeCache.GetCacheItemsByKeyExpression<PreValueCollection>(GetCacheKeyRegex(preValueId));
if (cached != null && cached.Any())
{
//return from the cache
var collection = cached.First();
var preVal = collection.FormatAsDictionary().Single(x => x.Value.Id == preValueId);
return preVal.Value.Value;
}
var preValue = collections.SelectMany(x => x.FormatAsDictionary().Values).FirstOrDefault(x => x.Id == preValueId);
if (preValue != null)
return preValue.Value;
//go and find the data type id for the pre val id passed in
var dto = Database.FirstOrDefault<DataTypePreValueDto>("WHERE id = @preValueId", new { preValueId = preValueId });
var dto = Database.FirstOrDefault<DataTypePreValueDto>("WHERE id = @preValueId", new { preValueId });
if (dto == null)
{
return string.Empty;
}
// go cache the collection
var preVals = GetAndCachePreValueCollection(dto.DataTypeNodeId);
//return the single value for this id
var pv = preVals.FormatAsDictionary().Single(x => x.Value.Id == preValueId);
return pv.Value.Value;
var collection = GetCachedPreValueCollection(dto.DataTypeNodeId);
if (collection == null)
return string.Empty;
preValue = collection.FormatAsDictionary().Values.FirstOrDefault(x => x.Id == preValueId);
return preValue == null ? string.Empty : preValue.Value;
}
public void AddOrUpdatePreValues(int dataTypeId, IDictionary<string, PreValue> values)
@@ -441,40 +427,28 @@ AND umbracoNode.id <> @id",
sortOrder++;
}
}
private string GetPrefixedCacheKey(int dataTypeId)
private static string GetPrefixedCacheKey(int dataTypeId)
{
return CacheKeys.DataTypePreValuesCacheKey + dataTypeId + "-";
return CacheKeys.DataTypePreValuesCacheKey + "_" + dataTypeId;
}
private PreValueCollection GetAndCachePreValueCollection(int dataTypeId)
private PreValueCollection GetCachedPreValueCollection(int datetypeId)
{
//go get the data
var dtos = Database.Fetch<DataTypePreValueDto>("WHERE datatypeNodeId = @Id", new { Id = dataTypeId });
var list = dtos.Select(x => new Tuple<PreValue, string, int>(new PreValue(x.Id, x.Value, x.SortOrder), x.Alias, x.SortOrder)).ToList();
var collection = PreValueConverter.ConvertToPreValuesCollection(list);
//now create the cache key, this needs to include all pre-value ids so that we can use this cached item in the GetPreValuesAsString method
//the key will be: "UmbracoPreValDATATYPEID-CSVOFPREVALIDS
var key = GetPrefixedCacheKey(dataTypeId)
+ string.Join(",", collection.FormatAsDictionary().Select(x => x.Value.Id).ToArray());
//store into cache
RuntimeCache.InsertCacheItem(key, () => collection,
//30 mins
new TimeSpan(0, 0, 30),
//sliding is true
true);
return collection;
var key = GetPrefixedCacheKey(datetypeId);
return RuntimeCache.GetCacheItem<PreValueCollection>(key, () =>
{
var dtos = Database.Fetch<DataTypePreValueDto>("WHERE datatypeNodeId = @Id", new { Id = datetypeId });
var list = dtos.Select(x => new Tuple<PreValue, string, int>(new PreValue(x.Id, x.Value, x.SortOrder), x.Alias, x.SortOrder)).ToList();
var collection = PreValueConverter.ConvertToPreValuesCollection(list);
return collection;
}, TimeSpan.FromMinutes(20), isSliding: true);
}
private string EnsureUniqueNodeName(string nodeName, int id = 0)
{
var sql = new Sql();
sql.Select("*")
@@ -576,7 +550,7 @@ AND umbracoNode.id <> @id",
}
//NOTE: We used to check that the Alias was unique for the given DataTypeNodeId prevalues list, BUT
// in reality there is no need to check the uniqueness of this alias because the only way that this code executes is
// in reality there is no need to check the uniqueness of this alias because the only way that this code executes is
// based on an IDictionary<string, PreValue> dictionary being passed to this repository and a dictionary
// must have unique aliases by definition, so there is no need for this additional check
@@ -596,10 +570,10 @@ AND umbracoNode.id <> @id",
{
throw new InvalidOperationException("Cannot update a pre value for a data type that has no identity");
}
//NOTE: We used to check that the Alias was unique for the given DataTypeNodeId prevalues list, BUT
// this causes issues when sorting the pre-values (http://issues.umbraco.org/issue/U4-5670) but in reality
// there is no need to check the uniqueness of this alias because the only way that this code executes is
// there is no need to check the uniqueness of this alias because the only way that this code executes is
// based on an IDictionary<string, PreValue> dictionary being passed to this repository and a dictionary
// must have unique aliases by definition, so there is no need for this additional check
@@ -614,7 +588,7 @@ AND umbracoNode.id <> @id",
Database.Update(dto);
}
}
internal static class PreValueConverter
@@ -8,6 +8,13 @@ namespace Umbraco.Core.Persistence.Repositories
{
public interface IContentTypeRepository : IContentTypeCompositionRepository<IContentType>
{
/// <summary>
/// Given the path of a content item, this will return true if the content item exists underneath a list view content item
/// </summary>
/// <param name="contentPath"></param>
/// <returns></returns>
bool HasContainerInPath(string contentPath);
/// <summary>
/// Gets all entities of the specified <see cref="PropertyType"/> query
/// </summary>
@@ -48,7 +48,12 @@ namespace Umbraco.Core.Persistence
_cacheHelper.IsolatedRuntimeCache.CacheFactory = type =>
{
var cache = origFactory(type);
return new DeepCloneRuntimeCacheProvider(cache);
//if the result is already a DeepCloneRuntimeCacheProvider then return it, otherwise
//wrap the result with a DeepCloneRuntimeCacheProvider
return cache is DeepCloneRuntimeCacheProvider
? cache
: new DeepCloneRuntimeCacheProvider(cache);
};
}
+4 -3
View File
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Events;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
@@ -12,7 +13,8 @@ namespace Umbraco.Core.Publishing
{
public PublishStatus(IContent content, PublishStatusType statusType, EventMessages eventMessages)
: base(content, statusType, eventMessages)
{
{
InvalidProperties = Enumerable.Empty<Property>();
}
/// <summary>
@@ -20,8 +22,7 @@ namespace Umbraco.Core.Publishing
/// </summary>
public PublishStatus(IContent content, EventMessages eventMessages)
: this(content, PublishStatusType.Success, eventMessages)
{
}
{ }
public IContent ContentItem
{
@@ -30,7 +30,7 @@ namespace Umbraco.Core.Publishing
/// Publishes a single piece of Content
/// </summary>
/// <param name="content"><see cref="IContent"/> to publish</param>
/// <param name="userId">Id of the User issueing the publish operation</param>
/// <param name="userId">Id of the User issueing the publish operation</param>
internal Attempt<PublishStatus> PublishInternal(IContent content, int userId)
{
var evtMsgs = _eventMessagesFactory.Get();
@@ -99,26 +99,26 @@ namespace Umbraco.Core.Publishing
/// By default this is set to true which means that it will publish any content item in the list that is completely unpublished and
/// not visible on the front-end. If set to false, this will only publish content that is live on the front-end but has new versions
/// that have yet to be published.
/// </param>
/// </param>
/// <returns></returns>
/// <remarks>
///
///
/// This method becomes complex once we start to be able to cancel events or stop publishing a content item in any way because if a
/// content item is not published then it's children shouldn't be published either. This rule will apply for the following conditions:
/// * If a document fails to be published, do not proceed to publish it's children if:
/// ** The document does not have a publish version
/// ** The document does have a published version but the includeUnpublishedDocuments = false
///
///
/// In order to do this, we will order the content by level and begin by publishing each item at that level, then proceed to the next
/// level and so on. If we detect that the above rule applies when the document publishing is cancelled we'll add it to the list of
/// level and so on. If we detect that the above rule applies when the document publishing is cancelled we'll add it to the list of
/// parentsIdsCancelled so that it's children don't get published.
///
///
/// Its important to note that all 'root' documents included in the list *will* be published regardless of the rules mentioned
/// above (unless it is invalid)!! By 'root' documents we are referring to documents in the list with the minimum value for their 'level'.
/// In most cases the 'root' documents will only be one document since under normal circumstance we only publish one document and
/// above (unless it is invalid)!! By 'root' documents we are referring to documents in the list with the minimum value for their 'level'.
/// In most cases the 'root' documents will only be one document since under normal circumstance we only publish one document and
/// its children. The reason we have to do this is because if a user is publishing a document and it's children, it is implied that
/// the user definitely wants to publish it even if it has never been published before.
///
///
/// </remarks>
internal IEnumerable<Attempt<PublishStatus>> PublishWithChildrenInternal(
IEnumerable<IContent> content, int userId, bool includeUnpublishedDocuments = true)
@@ -132,7 +132,7 @@ namespace Umbraco.Core.Publishing
//group by levels and iterate over the sorted ascending level.
//TODO: This will cause all queries to execute, they will not be lazy but I'm not really sure being lazy actually made
// much difference because we iterate over them all anyways?? Morten?
// much difference because we iterate over them all anyways?? Morten?
// Because we're grouping I think this will execute all the queries anyways so need to fetch it all first.
var fetchedContent = content.ToArray();
@@ -149,7 +149,7 @@ namespace Umbraco.Core.Publishing
var levelGroups = fetchedContent.GroupBy(x => x.Level);
foreach (var level in levelGroups.OrderBy(x => x.Key))
{
//set the first level flag, used to ensure that all documents at the first level will
//set the first level flag, used to ensure that all documents at the first level will
//be published regardless of the rules mentioned in the remarks.
if (!firstLevel.HasValue)
{
@@ -200,7 +200,10 @@ namespace Umbraco.Core.Publishing
_logger.Info<PublishingStrategy>(
string.Format("Content '{0}' with Id '{1}' will not be published because some of it's content is not passing validation rules.",
item.Name, item.Id));
statuses.Add(Attempt.Fail(new PublishStatus(item, PublishStatusType.FailedContentInvalid, evtMsgs)));
statuses.Add(Attempt.Fail(new PublishStatus(item, PublishStatusType.FailedContentInvalid, evtMsgs)
{
InvalidProperties = ((ContentBase)item).LastInvalidProperties
}));
//Does this document apply to our rule to cancel it's children being published?
CheckCancellingOfChildPublishing(item, parentsIdsCancelled, includeUnpublishedDocuments);
@@ -272,11 +275,11 @@ namespace Umbraco.Core.Publishing
/// <param name="includeUnpublishedDocuments"></param>
/// <remarks>
/// See remarks on method: PublishWithChildrenInternal
/// </remarks>
/// </remarks>
private void CheckCancellingOfChildPublishing(IContent content, List<int> parentsIdsCancelled, bool includeUnpublishedDocuments)
{
//Does this document apply to our rule to cancel it's children being published?
//TODO: We're going back to the service layer here... not sure how to avoid this? And this will add extra overhead to
//TODO: We're going back to the service layer here... not sure how to avoid this? And this will add extra overhead to
// any document that fails to publish...
var hasPublishedVersion = ApplicationContext.Current.Services.ContentService.HasPublishedVersion(content.Id);
@@ -306,8 +309,8 @@ namespace Umbraco.Core.Publishing
//NOTE: This previously always returned true so I've left it that way. It returned true because (from Morten)...
// ... if one item couldn't be published it wouldn't be correct to return false.
// in retrospect it should have returned a list of with Ids and Publish Status
// come to think of it ... the cache would still be updated for a failed item or at least tried updated.
// It would call the Published event for the entire list, but if the Published property isn't set to True it
// come to think of it ... the cache would still be updated for a failed item or at least tried updated.
// It would call the Published event for the entire list, but if the Published property isn't set to True it
// wouldn't actually update the cache for that item. But not really ideal nevertheless...
return true;
}
@@ -345,7 +348,7 @@ namespace Umbraco.Core.Publishing
var evtMsgs = _eventMessagesFactory.Get();
//Fire UnPublishing event
if (UnPublishing.IsRaisedEventCancelled(
if (UnPublishing.IsRaisedEventCancelled(
new PublishEventArgs<IContent>(content, evtMsgs), this))
{
_logger.Info<PublishingStrategy>(
@@ -388,8 +391,8 @@ namespace Umbraco.Core.Publishing
//NOTE: This previously always returned true so I've left it that way. It returned true because (from Morten)...
// ... if one item couldn't be published it wouldn't be correct to return false.
// in retrospect it should have returned a list of with Ids and Publish Status
// come to think of it ... the cache would still be updated for a failed item or at least tried updated.
// It would call the Published event for the entire list, but if the Published property isn't set to True it
// come to think of it ... the cache would still be updated for a failed item or at least tried updated.
// It would call the Published event for the entire list, but if the Published property isn't set to True it
// wouldn't actually update the cache for that item. But not really ideal nevertheless...
return true;
}
@@ -405,7 +408,7 @@ namespace Umbraco.Core.Publishing
public override void PublishingFinalized(IContent content)
{
var evtMsgs = _eventMessagesFactory.Get();
Published.RaiseEvent(
Published.RaiseEvent(
new PublishEventArgs<IContent>(content, false, false, evtMsgs), this);
}
@@ -129,6 +129,7 @@ namespace Umbraco.Core.Security
//track the last login date
user.LastLoginDateUtc = DateTime.UtcNow;
user.AccessFailedCount = 0;
await UserManager.UpdateAsync(user);
_logger.WriteCore(TraceEventType.Information, 0,
@@ -138,4 +139,4 @@ namespace Umbraco.Core.Security
_request.RemoteIpAddress), null, null);
}
}
}
}
+60 -58
View File
@@ -1,22 +1,15 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Threading;
using AutoMapper;
using Umbraco.Core.Auditing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Events;
using Umbraco.Core.Exceptions;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Services
@@ -26,14 +19,15 @@ namespace Umbraco.Core.Services
/// </summary>
public class ContentTypeService : ContentTypeServiceBase, IContentTypeService
{
private readonly IContentService _contentService;
private readonly IContentService _contentService;
private readonly IMediaService _mediaService;
//Support recursive locks because some of the methods that require locking call other methods that require locking.
//for example, the Move method needs to be locked but this calls the Save method which also needs to be locked.
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
public ContentTypeService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory, IContentService contentService, IMediaService mediaService)
public ContentTypeService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory, IContentService contentService,
IMediaService mediaService)
: base(provider, repositoryFactory, logger, eventMessagesFactory)
{
if (contentService == null) throw new ArgumentNullException("contentService");
@@ -154,8 +148,8 @@ namespace Umbraco.Core.Services
}
if (savingEvent.IsRaisedEventCancelled(
new SaveEventArgs<EntityContainer>(container, evtMsgs),
this))
new SaveEventArgs<EntityContainer>(container, evtMsgs),
this))
{
return OperationStatus.Cancelled(evtMsgs);
}
@@ -214,7 +208,7 @@ namespace Umbraco.Core.Services
public IEnumerable<EntityContainer> GetMediaTypeContainers(IMediaType mediaType)
{
var ancestorIds = mediaType.Path.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
var ancestorIds = mediaType.Path.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries)
.Select(x =>
{
var asInt = x.TryConvertTo<int>();
@@ -290,8 +284,8 @@ namespace Umbraco.Core.Services
if (container == null) return OperationStatus.NoOperation(evtMsgs);
if (DeletingContentTypeContainer.IsRaisedEventCancelled(
new DeleteEventArgs<EntityContainer>(container, evtMsgs),
this))
new DeleteEventArgs<EntityContainer>(container, evtMsgs),
this))
{
return Attempt.Fail(new OperationStatus(OperationStatusType.FailedCancelledByEvent, evtMsgs));
}
@@ -316,8 +310,8 @@ namespace Umbraco.Core.Services
if (container == null) return OperationStatus.NoOperation(evtMsgs);
if (DeletingMediaTypeContainer.IsRaisedEventCancelled(
new DeleteEventArgs<EntityContainer>(container, evtMsgs),
this))
new DeleteEventArgs<EntityContainer>(container, evtMsgs),
this))
{
return Attempt.Fail(new OperationStatus(OperationStatusType.FailedCancelledByEvent, evtMsgs));
}
@@ -421,7 +415,7 @@ namespace Umbraco.Core.Services
clone.Name = name;
var compositionAliases = clone.CompositionAliases().Except(new[] { alias }).ToList();
var compositionAliases = clone.CompositionAliases().Except(new[] {alias}).ToList();
//remove all composition that is not it's current alias
foreach (var a in compositionAliases)
{
@@ -680,7 +674,7 @@ namespace Umbraco.Core.Services
var comparer = new DelegateEqualityComparer<IContentTypeComposition>((x, y) => x.Id == y.Id, x => x.Id);
var dependencies = new HashSet<IContentTypeComposition>(compositions, comparer);
var stack = new Stack<IContentTypeComposition>();
indirectReferences.ForEach(stack.Push);//Push indirect references to a stack, so we can add recursively
indirectReferences.ForEach(stack.Push); //Push indirect references to a stack, so we can add recursively
while (stack.Count > 0)
{
var indirectReference = stack.Pop();
@@ -734,6 +728,8 @@ namespace Umbraco.Core.Services
{
ValidateLocked(contentType); // throws if invalid
contentType.CreatorId = userId;
if (contentType.Description == string.Empty)
contentType.Description = null;
repository.AddOrUpdate(contentType);
uow.Commit();
@@ -742,7 +738,7 @@ namespace Umbraco.Core.Services
UpdateContentXmlStructure(contentType);
}
SavedContentType.RaiseEvent(new SaveEventArgs<IContentType>(contentType, false), this);
Audit(AuditType.Save, string.Format("Save ContentType performed by user"), userId, contentType.Id);
Audit(AuditType.Save, string.Format("Save ContentType performed by user"), userId, contentType.Id);
}
/// <summary>
@@ -755,7 +751,7 @@ namespace Umbraco.Core.Services
var asArray = contentTypes.ToArray();
if (SavingContentType.IsRaisedEventCancelled(new SaveEventArgs<IContentType>(asArray), this))
return;
return;
using (new WriteLock(Locker))
{
@@ -770,6 +766,8 @@ namespace Umbraco.Core.Services
foreach (var contentType in asArray)
{
contentType.CreatorId = userId;
if (contentType.Description == string.Empty)
contentType.Description = null;
repository.AddOrUpdate(contentType);
}
@@ -780,7 +778,7 @@ namespace Umbraco.Core.Services
UpdateContentXmlStructure(asArray.Cast<IContentTypeBase>().ToArray());
}
SavedContentType.RaiseEvent(new SaveEventArgs<IContentType>(asArray, false), this);
Audit(AuditType.Save, string.Format("Save ContentTypes performed by user"), userId, -1);
Audit(AuditType.Save, string.Format("Save ContentTypes performed by user"), userId, -1);
}
/// <summary>
@@ -791,8 +789,8 @@ namespace Umbraco.Core.Services
/// <remarks>Deleting a <see cref="IContentType"/> will delete all the <see cref="IContent"/> objects based on this <see cref="IContentType"/></remarks>
public void Delete(IContentType contentType, int userId = 0)
{
if (DeletingContentType.IsRaisedEventCancelled(new DeleteEventArgs<IContentType>(contentType), this))
return;
if (DeletingContentType.IsRaisedEventCancelled(new DeleteEventArgs<IContentType>(contentType), this))
return;
using (new WriteLock(Locker))
{
@@ -836,7 +834,7 @@ namespace Umbraco.Core.Services
var asArray = contentTypes.ToArray();
if (DeletingContentType.IsRaisedEventCancelled(new DeleteEventArgs<IContentType>(asArray), this))
return;
return;
using (new WriteLock(Locker))
{
@@ -1004,8 +1002,8 @@ namespace Umbraco.Core.Services
var evtMsgs = EventMessagesFactory.Get();
if (MovingMediaType.IsRaisedEventCancelled(
new MoveEventArgs<IMediaType>(evtMsgs, new MoveEventInfo<IMediaType>(toMove, toMove.Path, containerId)),
this))
new MoveEventArgs<IMediaType>(evtMsgs, new MoveEventInfo<IMediaType>(toMove, toMove.Path, containerId)),
this))
{
return Attempt.Fail(
new OperationStatus<MoveOperationStatusType>(
@@ -1047,8 +1045,8 @@ namespace Umbraco.Core.Services
var evtMsgs = EventMessagesFactory.Get();
if (MovingContentType.IsRaisedEventCancelled(
new MoveEventArgs<IContentType>(evtMsgs, new MoveEventInfo<IContentType>(toMove, toMove.Path, containerId)),
this))
new MoveEventArgs<IContentType>(evtMsgs, new MoveEventInfo<IContentType>(toMove, toMove.Path, containerId)),
this))
{
return Attempt.Fail(
new OperationStatus<MoveOperationStatusType>(
@@ -1178,8 +1176,8 @@ namespace Umbraco.Core.Services
/// <param name="userId">Optional Id of the user saving the MediaType</param>
public void Save(IMediaType mediaType, int userId = 0)
{
if (SavingMediaType.IsRaisedEventCancelled(new SaveEventArgs<IMediaType>(mediaType), this))
return;
if (SavingMediaType.IsRaisedEventCancelled(new SaveEventArgs<IMediaType>(mediaType), this))
return;
using (new WriteLock(Locker))
{
@@ -1188,6 +1186,8 @@ namespace Umbraco.Core.Services
{
ValidateLocked(mediaType); // throws if invalid
mediaType.CreatorId = userId;
if (mediaType.Description == string.Empty)
mediaType.Description = null;
repository.AddOrUpdate(mediaType);
uow.Commit();
@@ -1197,7 +1197,7 @@ namespace Umbraco.Core.Services
}
SavedMediaType.RaiseEvent(new SaveEventArgs<IMediaType>(mediaType, false), this);
Audit(AuditType.Save, string.Format("Save MediaType performed by user"), userId, mediaType.Id);
Audit(AuditType.Save, string.Format("Save MediaType performed by user"), userId, mediaType.Id);
}
/// <summary>
@@ -1210,7 +1210,7 @@ namespace Umbraco.Core.Services
var asArray = mediaTypes.ToArray();
if (SavingMediaType.IsRaisedEventCancelled(new SaveEventArgs<IMediaType>(asArray), this))
return;
return;
using (new WriteLock(Locker))
{
@@ -1225,6 +1225,8 @@ namespace Umbraco.Core.Services
foreach (var mediaType in asArray)
{
mediaType.CreatorId = userId;
if (mediaType.Description == string.Empty)
mediaType.Description = null;
repository.AddOrUpdate(mediaType);
}
@@ -1236,7 +1238,7 @@ namespace Umbraco.Core.Services
}
SavedMediaType.RaiseEvent(new SaveEventArgs<IMediaType>(asArray, false), this);
Audit(AuditType.Save, string.Format("Save MediaTypes performed by user"), userId, -1);
Audit(AuditType.Save, string.Format("Save MediaTypes performed by user"), userId, -1);
}
/// <summary>
@@ -1247,8 +1249,8 @@ namespace Umbraco.Core.Services
/// <remarks>Deleting a <see cref="IMediaType"/> will delete all the <see cref="IMedia"/> objects based on this <see cref="IMediaType"/></remarks>
public void Delete(IMediaType mediaType, int userId = 0)
{
if (DeletingMediaType.IsRaisedEventCancelled(new DeleteEventArgs<IMediaType>(mediaType), this))
return;
if (DeletingMediaType.IsRaisedEventCancelled(new DeleteEventArgs<IMediaType>(mediaType), this))
return;
using (new WriteLock(Locker))
{
_mediaService.DeleteMediaOfType(mediaType.Id, userId);
@@ -1280,7 +1282,7 @@ namespace Umbraco.Core.Services
var asArray = mediaTypes.ToArray();
if (DeletingMediaType.IsRaisedEventCancelled(new DeleteEventArgs<IMediaType>(asArray), this))
return;
return;
using (new WriteLock(Locker))
{
foreach (var mediaType in asArray)
@@ -1390,40 +1392,40 @@ namespace Umbraco.Core.Services
/// </summary>
public static event TypedEventHandler<IContentTypeService, DeleteEventArgs<IContentType>> DeletingContentType;
/// <summary>
/// Occurs after Delete
/// </summary>
public static event TypedEventHandler<IContentTypeService, DeleteEventArgs<IContentType>> DeletedContentType;
/// <summary>
/// Occurs after Delete
/// </summary>
public static event TypedEventHandler<IContentTypeService, DeleteEventArgs<IContentType>> DeletedContentType;
/// <summary>
/// Occurs before Delete
/// </summary>
public static event TypedEventHandler<IContentTypeService, DeleteEventArgs<IMediaType>> DeletingMediaType;
/// <summary>
/// Occurs before Delete
/// </summary>
public static event TypedEventHandler<IContentTypeService, DeleteEventArgs<IMediaType>> DeletingMediaType;
/// <summary>
/// Occurs after Delete
/// </summary>
public static event TypedEventHandler<IContentTypeService, DeleteEventArgs<IMediaType>> DeletedMediaType;
/// <summary>
/// Occurs after Delete
/// </summary>
public static event TypedEventHandler<IContentTypeService, DeleteEventArgs<IMediaType>> DeletedMediaType;
/// <summary>
/// Occurs before Save
/// </summary>
public static event TypedEventHandler<IContentTypeService, SaveEventArgs<IContentType>> SavingContentType;
public static event TypedEventHandler<IContentTypeService, SaveEventArgs<IContentType>> SavingContentType;
/// <summary>
/// Occurs after Save
/// </summary>
public static event TypedEventHandler<IContentTypeService, SaveEventArgs<IContentType>> SavedContentType;
public static event TypedEventHandler<IContentTypeService, SaveEventArgs<IContentType>> SavedContentType;
/// <summary>
/// Occurs before Save
/// </summary>
public static event TypedEventHandler<IContentTypeService, SaveEventArgs<IMediaType>> SavingMediaType;
/// <summary>
/// Occurs before Save
/// </summary>
public static event TypedEventHandler<IContentTypeService, SaveEventArgs<IMediaType>> SavingMediaType;
/// <summary>
/// Occurs after Save
/// </summary>
public static event TypedEventHandler<IContentTypeService, SaveEventArgs<IMediaType>> SavedMediaType;
/// <summary>
/// Occurs after Save
/// </summary>
public static event TypedEventHandler<IContentTypeService, SaveEventArgs<IMediaType>> SavedMediaType;
/// <summary>
/// Occurs before Move
@@ -5,6 +5,7 @@ using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Services
@@ -70,5 +71,20 @@ namespace Umbraco.Core.Services
return toUpdate;
}
/// <summary>
/// Given the path of a content item, this will return true if the content item exists underneath a list view content item
/// </summary>
/// <param name="contentPath"></param>
/// <returns></returns>
public bool HasContainerInPath(string contentPath)
{
using (var uow = UowProvider.GetUnitOfWork())
{
// can use same repo for both content and media
var repository = RepositoryFactory.CreateContentTypeRepository(uow);
return repository.HasContainerInPath(contentPath);
}
}
}
}
@@ -11,6 +11,13 @@ namespace Umbraco.Core.Services
/// </summary>
public interface IContentTypeService : IService
{
/// <summary>
/// Given the path of a content item, this will return true if the content item exists underneath a list view content item
/// </summary>
/// <param name="contentPath"></param>
/// <returns></returns>
bool HasContainerInPath(string contentPath);
int CountContentTypes();
int CountMediaTypes();
+11 -1
View File
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Xml.Linq;
using Umbraco.Core.Models;
@@ -6,6 +7,15 @@ namespace Umbraco.Core.Services
{
public interface IPackagingService : IService
{
/// <summary>
/// This will fetch an Umbraco package file from the package repository and return the relative file path to the downloaded package file
/// </summary>
/// <param name="packageId"></param>
/// <param name="umbracoVersion"></param>
/// <param name="userId">The current user id performing the operation</param>
/// <returns></returns>
string FetchPackageFile(Guid packageId, Version umbracoVersion, int userId);
/// <summary>
/// Imports and saves package xml as <see cref="IContent"/>
/// </summary>
+6 -1
View File
@@ -891,7 +891,12 @@ namespace Umbraco.Core.Services
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateMediaRepository(uow))
{
media.CreatorId = userId;
//set the creator id if it's new
if (media.HasIdentity == false)
{
media.CreatorId = userId;
}
repository.AddOrUpdate(media);
repository.AddOrUpdateContentXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, _userService, m));
// generate preview for blame history?
@@ -2,12 +2,10 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Umbraco.Core.Auditing;
using Umbraco.Core.Events;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Services
@@ -89,6 +87,8 @@ namespace Umbraco.Core.Services
using (var repository = RepositoryFactory.CreateMemberTypeRepository(uow))
{
memberType.CreatorId = userId;
if (memberType.Description == string.Empty)
memberType.Description = null;
repository.AddOrUpdate(memberType);
uow.Commit();
@@ -114,6 +114,8 @@ namespace Umbraco.Core.Services
foreach (var memberType in asArray)
{
memberType.CreatorId = userId;
if (memberType.Description == string.Empty)
memberType.Description = null;
repository.AddOrUpdate(memberType);
}
+60 -1
View File
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI.WebControls;
@@ -9,7 +11,9 @@ using System.Xml.Linq;
using System.Xml.XPath;
using Newtonsoft.Json;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Events;
using Umbraco.Core.Exceptions;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
@@ -58,7 +62,7 @@ namespace Umbraco.Core.Services
IEntityService entityService,
IUserService userService,
RepositoryFactory repositoryFactory,
IDatabaseUnitOfWorkProvider uowProvider)
IDatabaseUnitOfWorkProvider uowProvider)
{
_logger = logger;
_contentService = contentService;
@@ -75,6 +79,61 @@ namespace Umbraco.Core.Services
_importedContentTypes = new Dictionary<string, IContentType>();
}
/// <summary>
/// This will fetch an Umbraco package file from the package repository and return the relative file path to the downloaded package file
/// </summary>
/// <param name="packageId"></param>
/// <param name="umbracoVersion"></param>
/// /// <param name="userId">The current user id performing the operation</param>
/// <returns></returns>
public string FetchPackageFile(Guid packageId, Version umbracoVersion, int userId)
{
var packageRepo = UmbracoConfig.For.UmbracoSettings().PackageRepositories.GetDefault();
using (var httpClient = new HttpClient())
using (var uow = _uowProvider.GetUnitOfWork())
{
//includeHidden = true because we don't care if it's hidden we want to get the file regardless
var url = string.Format("{0}/{1}?version={2}&includeHidden=true&asFile=true", packageRepo.RestApiUrl, packageId, umbracoVersion.ToString(3));
byte[] bytes;
try
{
bytes = httpClient.GetByteArrayAsync(url).GetAwaiter().GetResult();
}
catch (HttpRequestException ex)
{
throw new ConnectionException("An error occuring downloading the package from " + url, ex);
}
//successfull
if (bytes.Length > 0)
{
var packagePath = IOHelper.MapPath(SystemDirectories.Packages);
// Check for package directory
if (Directory.Exists(packagePath) == false)
Directory.CreateDirectory(packagePath);
var packageFilePath = Path.Combine(packagePath, packageId + ".umb");
using (var fs1 = new FileStream(packageFilePath, FileMode.Create))
{
fs1.Write(bytes, 0, bytes.Length);
return "packages\\" + packageId + ".umb";
}
}
Audit(uow, AuditType.PackagerInstall, string.Format("Package {0} fetched from {1}", packageId, packageRepo.Id), userId, -1);
return null;
}
}
private void Audit(IDatabaseUnitOfWork uow, AuditType type, string message, int userId, int objectId)
{
var auditRepo = _repositoryFactory.CreateAuditRepository(uow);
auditRepo.AddOrUpdate(new AuditItem(objectId, message, type, userId));
}
#region Content
/// <summary>
@@ -4,6 +4,7 @@ using System.Web;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
namespace Umbraco.Core.Sync
{
@@ -40,8 +41,9 @@ namespace Umbraco.Core.Sync
.ToList();
if (serversA.Length == 0)
{
{
_serverRole = ServerRole.Unknown; // config error, actually
LogHelper.Debug<ConfigServerRegistrar>(string.Format("Server Role Unknown: DistributedCalls are enabled but no servers are listed"));
}
else
{
@@ -50,7 +52,10 @@ namespace Umbraco.Core.Sync
var serverName = master.ServerName;
if (appId.IsNullOrWhiteSpace() && serverName.IsNullOrWhiteSpace())
{
_serverRole = ServerRole.Unknown; // config error, actually
LogHelper.Debug<ConfigServerRegistrar>(string.Format("Server Role Unknown: Server Name or AppId missing from Server configuration in DistributedCalls settings"));
}
else
_serverRole = IsCurrentServer(appId, serverName)
? ServerRole.Master
+4
View File
@@ -180,6 +180,7 @@
<Compile Include="Configuration\BaseRest\ExtensionElementCollection.cs" />
<Compile Include="Configuration\BaseRest\MethodElement.cs" />
<Compile Include="Configuration\ContentXmlStorage.cs" />
<Compile Include="Configuration\CoreDebug.cs" />
<Compile Include="Configuration\Dashboard\AccessElement.cs" />
<Compile Include="Configuration\Dashboard\AccessItem.cs" />
<Compile Include="Configuration\Dashboard\AccessType.cs" />
@@ -273,6 +274,7 @@
<Compile Include="Configuration\UmbracoSettings\RazorStaticMappingElement.cs" />
<Compile Include="Configuration\UmbracoSettings\RepositoriesCollection.cs" />
<Compile Include="Configuration\UmbracoSettings\RepositoriesElement.cs" />
<Compile Include="Configuration\UmbracoSettings\RepositoryConfigExtensions.cs" />
<Compile Include="Configuration\UmbracoSettings\RepositoryElement.cs" />
<Compile Include="Configuration\UmbracoSettings\RequestHandlerElement.cs" />
<Compile Include="Configuration\UmbracoSettings\ScheduledTaskElement.cs" />
@@ -300,6 +302,7 @@
<Compile Include="DateTimeExtensions.cs" />
<Compile Include="DecimalExtensions.cs" />
<Compile Include="DelegateExtensions.cs" />
<Compile Include="Diagnostics\MiniDump.cs" />
<Compile Include="DictionaryExtensions.cs" />
<Compile Include="Dictionary\CultureDictionaryFactoryResolver.cs" />
<Compile Include="Dictionary\ICultureDictionaryFactory.cs" />
@@ -333,6 +336,7 @@
<Compile Include="Events\RollbackEventArgs.cs" />
<Compile Include="Events\SaveEventArgs.cs" />
<Compile Include="Events\SendToPublishEventArgs.cs" />
<Compile Include="Exceptions\ConnectionException.cs" />
<Compile Include="Exceptions\DataOperationException.cs" />
<Compile Include="Exceptions\InvalidCompositionException.cs" />
<Compile Include="Exceptions\UmbracoStartupFailedException.cs" />
@@ -46,23 +46,6 @@ namespace Umbraco.Tests.Persistence.Repositories
return new EntityContainerRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), SqlSyntax, Constants.ObjectTypes.DataTypeContainerGuid);
}
[TestCase("UmbracoPreVal87-21,3,48", 3, true)]
[TestCase("UmbracoPreVal87-21,33,48", 3, false)]
[TestCase("UmbracoPreVal87-21,33,48", 33, true)]
[TestCase("UmbracoPreVal87-21,3,48", 33, false)]
[TestCase("UmbracoPreVal87-21,3,48", 21, true)]
[TestCase("UmbracoPreVal87-21,3,48", 48, true)]
[TestCase("UmbracoPreVal87-22,33,48", 2, false)]
[TestCase("UmbracoPreVal87-22,33,48", 22, true)]
[TestCase("UmbracoPreVal87-22,33,44", 4, false)]
[TestCase("UmbracoPreVal87-22,33,44", 44, true)]
[TestCase("UmbracoPreVal87-22,333,44", 33, false)]
[TestCase("UmbracoPreVal87-22,333,44", 333, true)]
public void Pre_Value_Cache_Key_Tests(string cacheKey, int preValueId, bool outcome)
{
Assert.AreEqual(outcome, Regex.IsMatch(cacheKey, DataTypeDefinitionRepository.GetCacheKeyRegex(preValueId)));
}
[Test]
public void Can_Move()
{
@@ -537,7 +520,7 @@ namespace Umbraco.Tests.Persistence.Repositories
}
var cached = cache.IsolatedRuntimeCache.GetCache<IDataTypeDefinition>().Result
.GetCacheItemsByKeySearch<PreValueCollection>(CacheKeys.DataTypePreValuesCacheKey + dtd.Id + "-");
.GetCacheItemsByKeySearch<PreValueCollection>(CacheKeys.DataTypePreValuesCacheKey + "_" + dtd.Id);
Assert.IsNotNull(cached);
Assert.AreEqual(1, cached.Count());
@@ -581,7 +564,7 @@ namespace Umbraco.Tests.Persistence.Repositories
}
var cached = cache.IsolatedRuntimeCache.GetCache<IDataTypeDefinition>().Result
.GetCacheItemsByKeySearch<PreValueCollection>(CacheKeys.DataTypePreValuesCacheKey + dtd.Id + "-");
.GetCacheItemsByKeySearch<PreValueCollection>(CacheKeys.DataTypePreValuesCacheKey + "_" + dtd.Id);
Assert.IsNotNull(cached);
Assert.AreEqual(1, cached.Count());
@@ -25,14 +25,14 @@ namespace Umbraco.Tests.Routing
{
SiteDomainHelper.AddSite("site1", "domain1.com", "domain1.net", "domain1.org");
SiteDomainHelper.AddSite("site2", "domain2.com", "domain2.net", "domain2.org");
var sites = SiteDomainHelper.Sites;
Assert.AreEqual(2, sites.Count);
Assert.Contains("site1", sites.Keys);
Assert.Contains("site2", sites.Keys);
var domains = sites["site1"];
Assert.AreEqual(3, domains.Count());
Assert.Contains("domain1.com", domains);
@@ -84,7 +84,7 @@ namespace Umbraco.Tests.Routing
Assert.Contains("site2", sites.Keys);
}
[Test]
public void AddSiteAgain()
{
@@ -175,15 +175,15 @@ namespace Umbraco.Tests.Routing
// map methods are not static because we can override them
var helper = new SiteDomainHelper();
// current is a site1 uri, domains contain current
// so we'll get current
//
var current = new Uri("http://domain1.com/foo/bar");
var output = helper.MapDomain(current, new[]
{
new DomainAndUri(new UmbracoDomain("domain1.com"), Uri.UriSchemeHttp),
new DomainAndUri(new UmbracoDomain("domain2.com"), Uri.UriSchemeHttp),
new DomainAndUri(new UmbracoDomain("domain1.com"), Uri.UriSchemeHttp),
new DomainAndUri(new UmbracoDomain("domain2.com"), Uri.UriSchemeHttp),
}).Uri.ToString();
Assert.AreEqual("http://domain1.com/", output);
@@ -193,7 +193,7 @@ namespace Umbraco.Tests.Routing
current = new Uri("http://domain1.com/foo/bar");
output = helper.MapDomain(current, new[]
{
new DomainAndUri(new UmbracoDomain("domain1.net"), Uri.UriSchemeHttp),
new DomainAndUri(new UmbracoDomain("domain1.net"), Uri.UriSchemeHttp),
new DomainAndUri(new UmbracoDomain("domain2.net"), Uri.UriSchemeHttp)
}).Uri.ToString();
Assert.AreEqual("http://domain1.net/", output);
@@ -205,12 +205,73 @@ namespace Umbraco.Tests.Routing
current = new Uri("http://domain1.com/foo/bar");
output = helper.MapDomain(current, new[]
{
new DomainAndUri(new UmbracoDomain("domain2.net"), Uri.UriSchemeHttp),
new DomainAndUri(new UmbracoDomain("domain2.net"), Uri.UriSchemeHttp),
new DomainAndUri(new UmbracoDomain("domain1.net"), Uri.UriSchemeHttp)
}).Uri.ToString();
Assert.AreEqual("http://domain1.net/", output);
}
private DomainAndUri[] DomainAndUris(Uri current, IDomain[] domains)
{
var scheme = current == null ? Uri.UriSchemeHttp : current.Scheme;
return domains
.Where(d => d.IsWildcard == false)
.Select(d => new DomainAndUri(d, scheme))
.OrderByDescending(d => d.Uri.ToString())
.ToArray();
}
[Test]
public void MapDomainWithScheme()
{
SiteDomainHelper.AddSite("site1", "domain1.com", "domain1.net", "domain1.org");
SiteDomainHelper.AddSite("site2", "domain2.com", "domain2.net", "domain2.org");
SiteDomainHelper.AddSite("site3", "domain3.com", "domain3.net", "domain3.org");
SiteDomainHelper.AddSite("site4", "https://domain4.com", "https://domain4.net", "https://domain4.org");
// map methods are not static because we can override them
var helper = new SiteDomainHelper();
// this works, but it's purely by chance / arbitrary
// don't use the www in tests here!
var current = new Uri("https://www.domain1.com/foo/bar");
var domainAndUris = DomainAndUris(current, new []
{
new UmbracoDomain("domain2.com"),
new UmbracoDomain("domain1.com"),
});
var output = helper.MapDomain(current, domainAndUris).Uri.ToString();
Assert.AreEqual("https://domain1.com/", output);
// will pick it all right
current = new Uri("https://domain1.com/foo/bar");
domainAndUris = DomainAndUris(current, new[]
{
new UmbracoDomain("https://domain1.com"),
new UmbracoDomain("https://domain2.com")
});
output = helper.MapDomain(current, domainAndUris).Uri.ToString();
Assert.AreEqual("https://domain1.com/", output);
current = new Uri("https://domain1.com/foo/bar");
domainAndUris = DomainAndUris(current, new[]
{
new UmbracoDomain("https://domain1.com"),
new UmbracoDomain("https://domain4.com")
});
output = helper.MapDomain(current, domainAndUris).Uri.ToString();
Assert.AreEqual("https://domain1.com/", output);
current = new Uri("https://domain4.com/foo/bar");
domainAndUris = DomainAndUris(current, new[]
{
new UmbracoDomain("https://domain1.com"),
new UmbracoDomain("https://domain4.com")
});
output = helper.MapDomain(current, domainAndUris).Uri.ToString();
Assert.AreEqual("https://domain4.com/", output);
}
[Test]
public void MapDomains()
{
@@ -1,4 +1,3 @@
using System.Runtime.Remoting;
using NUnit.Framework;
using System;
using System.Collections.Generic;
@@ -8,7 +7,6 @@ using Umbraco.Core.Exceptions;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Services;
using Umbraco.Tests.CodeFirst.TestModels.Composition;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
@@ -1420,6 +1418,38 @@ namespace Umbraco.Tests.Services
Assert.That(descriptionPropertyTypeReloaded.PropertyGroupId.IsValueCreated, Is.False);
}
[Test]
public void Empty_Description_Is_Always_Null_After_Saving_Content_Type()
{
var service = ServiceContext.ContentTypeService;
var contentType = MockedContentTypes.CreateBasicContentType();
contentType.Description = null;
service.Save(contentType);
var contentType2 = MockedContentTypes.CreateBasicContentType("basePage2", "Base Page 2");
contentType2.Description = string.Empty;
service.Save(contentType2);
Assert.IsNull(contentType.Description);
Assert.IsNull(contentType2.Description);
}
[Test]
public void Empty_Description_Is_Always_Null_After_Saving_Media_Type()
{
var service = ServiceContext.ContentTypeService;
var mediaType = MockedContentTypes.CreateSimpleMediaType("mediaType", "Media Type");
mediaType.Description = null;
service.Save(mediaType);
var mediaType2 = MockedContentTypes.CreateSimpleMediaType("mediaType2", "Media Type 2");
mediaType2.Description = string.Empty;
service.Save(mediaType2);
Assert.IsNull(mediaType.Description);
Assert.IsNull(mediaType2.Description);
}
private ContentType CreateComponent()
{
var component = new ContentType(-1)
@@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using umbraco.cms.presentation.create.controls;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
@@ -183,6 +181,22 @@ namespace Umbraco.Tests.Services
Assert.Throws<ArgumentException>(() => ServiceContext.MemberTypeService.Save(memberType));
}
[Test]
public void Empty_Description_Is_Always_Null_After_Saving_Member_Type()
{
var service = ServiceContext.MemberTypeService;
var memberType = MockedContentTypes.CreateSimpleMemberType();
memberType.Description = null;
service.Save(memberType);
var memberType2 = MockedContentTypes.CreateSimpleMemberType("memberType2", "Member Type 2");
memberType2.Description = string.Empty;
service.Save(memberType2);
Assert.IsNull(memberType.Description);
Assert.IsNull(memberType2.Description);
}
//[Test]
//public void Can_Save_MemberType_Structure_And_Create_A_Member_Based_On_It()
//{
@@ -1,5 +1,4 @@
using System;
using System.Linq;
using Umbraco.Core;
using Umbraco.Core.Models;
+2 -2
View File
@@ -57,8 +57,8 @@
<Reference Include="AutoMapper.Net4, Version=3.3.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.Net4.dll</HintPath>
</Reference>
<Reference Include="Examine, Version=0.1.81.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Examine.0.1.81\lib\net45\Examine.dll</HintPath>
<Reference Include="Examine, Version=0.1.82.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Examine.0.1.82\lib\net45\Examine.dll</HintPath>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
+1 -1
View File
@@ -2,7 +2,7 @@
<packages>
<package id="AspNetWebApi.SelfHost" version="4.0.20710.0" targetFramework="net45" />
<package id="AutoMapper" version="3.3.1" targetFramework="net45" />
<package id="Examine" version="0.1.81" targetFramework="net45" />
<package id="Examine" version="0.1.82" targetFramework="net45" />
<package id="log4net-mediumtrust" version="2.0.0" targetFramework="net45" />
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net45" />
@@ -163,13 +163,13 @@ angular.module('umbraco.directives')
}
// ignore clicks on dialog from old dialog service
var oldDialog = $(el).parents("#old-dialog-service");
var oldDialog = $(event.target).parents("#old-dialog-service");
if (oldDialog.length === 1) {
return;
}
// ignore clicks in tinyMCE dropdown(floatpanel)
var floatpanel = $(el).parents(".mce-floatpanel");
var floatpanel = $(event.target).closest(".mce-floatpanel");
if (floatpanel.length === 1) {
return;
}
@@ -105,12 +105,14 @@ angular.module("umbraco.directives")
});
//// INIT /////
$image.load(function(){
$timeout(function(){
setDimensions();
scope.loaded = true;
scope.onImageLoaded();
});
$image.load(function() {
$timeout(function() {
setDimensions();
scope.loaded = true;
if (angular.isFunction(scope.onImageLoaded)) {
scope.onImageLoaded();
}
});
});
$(window).on('resize.umbImageGravity', function(){
@@ -5,15 +5,14 @@
**/
function ourPackageRepositoryResource($q, $http, umbDataFormatter, umbRequestHelper) {
//var baseurl = "http://localhost:24292/webapi/packages/v1";
var baseurl = "https://our.umbraco.org/webapi/packages/v1";
var baseurl = Umbraco.Sys.ServerVariables.umbracoUrls.packagesRestApiBaseUrl;
return {
getDetails: function (packageId) {
return umbRequestHelper.resourcePromise(
$http.get(baseurl + "/" + packageId),
$http.get(baseurl + "/" + packageId + "?version=" + Umbraco.Sys.ServerVariables.application.version),
'Failed to get package details');
},
@@ -14,6 +14,7 @@ body {
overflow: hidden;
height: 100%;
width: 100%;
width: ~"(calc(~'100%' - ~'80px'))"; // 80px is the fixed left menu for toggling the different browser sizes
position: absolute;
padding: 0;
margin: 0;
@@ -158,4 +158,4 @@
</div>
</div>
</form>
@@ -1,5 +1,5 @@
<div class="umb-media-grid">
<div class="umb-media-grid__item" ng-click="clickItem(item, $event, $index)" ng-repeat="item in items | filter:filterBy" ng-style="item.flexStyle" ng-class="{'-selected': item.selected, '-file': !item.thumbnail, '-svg': item.extension == 'svg'}">
<div class="umb-media-grid__item" title="{{item.name}}" ng-click="clickItem(item, $event, $index)" ng-repeat="item in items | filter:filterBy" ng-style="item.flexStyle" ng-class="{'-selected': item.selected, '-file': !item.thumbnail, '-svg': item.extension == 'svg'}">
<div>
<i ng-show="item.selected" class="icon-check umb-media-grid__checkmark"></i>
@@ -12,10 +12,10 @@
<div class="umb-media-grid__image-background" ng-if="item.thumbnail || item.extension == 'svg'"></div>
<!-- Image thumbnail -->
<img class="umb-media-grid__item-image" width="{{item.width}}" height="{{item.height}}" ng-if="item.thumbnail" ng-src="{{item.thumbnail}}" alt="{{item.name}}" title="{{item.name}}" draggable="false" />
<img class="umb-media-grid__item-image" width="{{item.width}}" height="{{item.height}}" ng-if="item.thumbnail" ng-src="{{item.thumbnail}}" alt="{{item.name}}" draggable="false" />
<!-- SVG -->
<img class="umb-media-grid__item-image" width="{{item.width}}" height="{{item.height}}" ng-if="!item.thumbnail && item.extension == 'svg'" ng-src="{{item.file}}" alt="{{item.name}}" title="{{item.name}}" draggable="false" />
<img class="umb-media-grid__item-image" width="{{item.width}}" height="{{item.height}}" ng-if="!item.thumbnail && item.extension == 'svg'" ng-src="{{item.file}}" alt="{{item.name}}" draggable="false" />
<!-- Transparent image - fallback - used to keep image proportions on wrapper-->
<img class="umb-media-grid__item-image-placeholder" ng-if="!item.thumbnail && item.extension != 'svg'" src="assets/img/transparent.png" alt="{{item.name}}" draggable="false" />
@@ -3,232 +3,285 @@
<h3>Examine Management</h3>
<div ng-show="loading">
Loading...
<div class="umb-healthcheck-group__details-status-overlay"></div>
<umb-load-indicator></umb-load-indicator>
</div>
<h4>Indexers</h4>
<div ng-hide="loading" class="umb-healthcheck-group__details">
<ul ng-hide="loading">
<li class="provider" ng-repeat="indexer in indexerDetails">
<div class="umb-healthcheck-group__details-group-title">
<div class="umb-healthcheck-group__details-group-name">Indexers</div>
</div>
<a class="btn-link -underline" href="" ng-click="toggle(indexer, 'showProperties')">
{{indexer.name}}
</a>
<div class="umb-healthcheck-group__details-checks">
<div class="umb-healthcheck-group__details-check">
<div class="umb-healthcheck-group__details-check-title">
<div class="umb-healthcheck-group__details-check-name">Manage Examine's indexes</div>
<div class="umb-healthcheck-group__details-check-description">Allows you to view the details of each index and provides some tools for managing the indexes</div>
</div>
<ul ng-show="indexer.showProperties">
<div class="umb-healthcheck-group__details-status" ng-repeat="indexer in indexerDetails">
<li>
<div class="umb-healthcheck-group__details-status-icon-container">
<i class="umb-healthcheck-status-icon" ng-class="{'icon-check color-green' : indexer.isHealthy, 'icon-delete color-red' : !indexer.isHealthy}"></i>
</div>
<a href="" ng-click="toggle(indexer, 'showTools')">Index info & tools</a>
<div ng-show="indexer.showTools && indexer.isLuceneIndex">
<div>
<br />
<div ng-show="!indexer.isProcessing && (!indexer.processingAttempts || indexer.processingAttempts < 100)" class="btn-group">
<button type="button" class="btn btn-warning" ng-click="rebuildIndex(indexer)">Rebuild index</button>
<button type="button" class="btn btn-warning" ng-click="optimizeIndex(indexer)" ng-show="indexer.documentCount > 0">Optimize index</button>
<div class="umb-healthcheck-group__details-status-content">
<div class="umb-healthcheck-group__details-status-text">
<div ng-show="!indexer.isHealthy">
{{indexer.name}}
</div>
<div ng-show="indexer.isProcessing" class="umb-loader-wrapper" ng-show="actionInProgress">
<div class="umb-loader"></div>
</div>
<div class="error" ng-show="indexer.processingAttempts >= 100">
The process is taking longer than expected, check the umbraco log to see if there have been any errors during this operation
<a class="btn-link -underline" href="" ng-click="toggle(indexer, 'showProperties')" ng-show="indexer.isHealthy">
{{indexer.name}}
</a>
<div ng-if="!indexer.isHealthy" class="text-error">
The index cannot be read and will need to be rebuilt
</div>
</div>
<table class="table table-bordered table-condensed">
<caption>&nbsp;</caption>
<tr>
<th>Documents in index</th>
<td>{{indexer.documentCount}}</td>
</tr>
<tr>
<th>Fields in index</th>
<td>{{indexer.fieldCount}}</td>
</tr>
<tr>
<th>Has deletions?</th>
<td>
<span>{{indexer.deletionCount > 0}}</span>
(<span>{{indexer.deletionCount}}</span>)
</td>
</tr>
<tr>
<th>Optimized?</th>
<td>
<span>{{indexer.isOptimized}}</span>
</td>
</tr>
</table>
</div>
</li>
<li ng-show="indexer.indexCriteria.IncludeNodeTypes.length > 0 || indexer.indexCriteria.ExcludeNodeTypes.length > 0 || indexer.indexCriteria.ParentNodeId">
<a href="" ng-click="toggle(indexer, 'showNodeTypes')">Node types</a>
<table ng-show="indexer.showNodeTypes" class="table table-bordered table-condensed">
<tr ng-show="indexer.indexCriteria.IncludeNodeTypes.length > 0">
<th>Include node types</th>
<td>{{indexer.indexCriteria.IncludeNodeTypes | json}}</td>
</tr>
<tr ng-show="indexer.indexCriteria.ExcludeNodeTypes.length > 0">
<th>Exclude node types</th>
<td>{{indexer.indexCriteria.ExcludeNodeTypes | json}}</td>
</tr>
<tr ng-show="indexer.indexCriteria.ParentNodeId">
<th>Parent node id</th>
<td>{{indexer.indexCriteria.ParentNodeId}}</td>
</tr>
</table>
</li>
<li ng-show="indexer.indexCriteria.StandardFields.length > 0">
<a href="" ng-click="toggle(indexer, 'showSystemFields')">System fields</a>
<table ng-show="indexer.showSystemFields" class="table table-bordered table-condensed">
<caption>&nbsp;</caption>
<thead>
<tr>
<th>Name</th>
<th>Enable sorting</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="field in indexer.indexCriteria.StandardFields">
<th>{{field.Name}}</th>
<td>{{field.EnableSorting}}</td>
<td>{{field.Type}}</td>
</tr>
</tbody>
</table>
</li>
<li ng-show="indexer.indexCriteria.UserFields.length > 0">
<a href="" ng-click="toggle(indexer, 'showUserFields')">User fields</a>
<table ng-show="indexer.showUserFields" class="table table-bordered table-condensed">
<caption>&nbsp;</caption>
<thead>
<tr>
<th>Name</th>
<th>Enable sorting</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="field in indexer.indexCriteria.UserFields">
<th>{{field.Name}}</th>
<td>{{field.EnableSorting}}</td>
<td>{{field.Type}}</td>
</tr>
</tbody>
</table>
</li>
<li>
<a href="" ng-click="toggle(indexer, 'showProviderProperties')">Provider properties</a>
<table ng-show="indexer.showProviderProperties" class="table table-bordered table-condensed">
<caption>&nbsp;</caption>
<tr ng-repeat="(key, val) in indexer.providerProperties track by $index">
<th>{{key}}</th>
<td>{{val}}</td>
</tr>
</table>
</li>
</ul>
</li>
</ul>
<h4>Searchers</h4>
<ul ng-hide="loading">
<li class="provider" ng-repeat="searcher in searcherDetails">
<a class="btn-link -underline" href="" ng-click="toggle(searcher, 'showProperties')">
{{searcher.name}}
</a>
<ul ng-show="searcher.showProperties">
<li class="search-tools">
<a href="" ng-click="toggle(searcher, 'showTools')">Search tools</a>
<div ng-show="searcher.showTools">
<a class="hide" href="" ng-click="closeSearch(searcher)" ng-show="searcher.isSearching">Hide search results</a>
<br />
<form>
<div class="row form-search">
<div class="span8 input-append">
<input type="text" class="search-query" ng-model="searcher.searchText" no-dirty-check />
<button type="button" class="btn btn-info" ng-click="search(searcher)" ng-disabled="searcher.isProcessing">Search</button>
</div>
</div>
<div class="row">
<label for="{{searcher.name}}-textSearch" class="radio inline">
<input type="radio" name="searchType" id="{{searcher.name}}-textSearch" value="text" ng-model="searcher.searchType" no-dirty-check />
Text Search
</label>
<label for="{{searcher.name}}-luceneSearch" class="radio inline">
<input type="radio" name="searchType" id="{{searcher.name}}-luceneSearch" value="lucene" ng-model="searcher.searchType" no-dirty-check />
Lucene Search
</label>
<div class="umb-healthcheck-group__details-status-actions" ng-if="!indexer.isHealthy">
<div class="umb-healthcheck-group__details-status-action">
<button type="button" class="umb-era-button -blue"
ng-show="!indexer.isProcessing && (!indexer.processingAttempts || indexer.processingAttempts < 100)"
ng-click="rebuildIndex(indexer)">
Rebuild index
</button>
</div>
</div>
<div class="umb-healthcheck-group__details-status-actions" ng-show="indexer.isHealthy && indexer.showProperties">
<ul>
<li>
<a href="" ng-click="toggle(indexer, 'showTools')">Index info & tools</a>
</form>
<div ng-show="indexer.showTools && indexer.isLuceneIndex">
<div>
<br />
<div class="search-results" ng-show="searcher.isSearching">
<div ng-show="!indexer.isProcessing && (!indexer.processingAttempts || indexer.processingAttempts < 100)"
class="umb-healthcheck-group__details-status-action">
<button type="button" class="umb-era-button -blue" ng-click="rebuildIndex(indexer)">Rebuild index</button>
</div>
<div ng-show="indexer.isProcessing" class="umb-loader-wrapper" ng-show="indexer.isProcessing">
<div class="umb-loader"></div>
</div>
<div ng-show="indexer.processingAttempts >= 100">
The process is taking longer than expected, check the umbraco log to see if there have been any errors during this operation
</div>
</div>
<table class="table table-bordered table-condensed">
<caption>&nbsp;</caption>
<tr>
<th>Documents in index</th>
<td>{{indexer.documentCount}}</td>
</tr>
<tr>
<th>Fields in index</th>
<td>{{indexer.fieldCount}}</td>
</tr>
<tr>
<th>Has deletions?</th>
<td>
<span>{{indexer.deletionCount > 0}}</span>
(<span>{{indexer.deletionCount}}</span>)
</td>
</tr>
<tr>
<th>Optimized?</th>
<td>
<span>{{indexer.isOptimized}}</span>
</td>
</tr>
<table ng-hide="searcher.isProcessing" class="table table-bordered table-condensed">
<thead>
<tr>
<th class="score">Score</th>
<th class="id">Id</th>
<th>Values</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="result in searcher.searchResults">
<td>{{result.Score}}</td>
<td>{{result.Id}}</td>
<td>
<span ng-repeat="(key,val) in result.Fields track by $index">
<span class=""><em>{{key}}</em>:</span>
<span class="text-info">{{val}}</span>
</span>
</td>
</tr>
</tbody>
</table>
</table>
</div>
</li>
<li ng-show="indexer.indexCriteria.IncludeNodeTypes.length > 0 || indexer.indexCriteria.ExcludeNodeTypes.length > 0 || indexer.indexCriteria.ParentNodeId">
<a href="" ng-click="toggle(indexer, 'showNodeTypes')">Node types</a>
<table ng-show="indexer.showNodeTypes" class="table table-bordered table-condensed">
<tr ng-show="indexer.indexCriteria.IncludeNodeTypes.length > 0">
<th>Include node types</th>
<td>{{indexer.indexCriteria.IncludeNodeTypes | json}}</td>
</tr>
<tr ng-show="indexer.indexCriteria.ExcludeNodeTypes.length > 0">
<th>Exclude node types</th>
<td>{{indexer.indexCriteria.ExcludeNodeTypes | json}}</td>
</tr>
<tr ng-show="indexer.indexCriteria.ParentNodeId">
<th>Parent node id</th>
<td>{{indexer.indexCriteria.ParentNodeId}}</td>
</tr>
</table>
</li>
<li ng-show="indexer.indexCriteria.StandardFields.length > 0">
<a href="" ng-click="toggle(indexer, 'showSystemFields')">System fields</a>
<table ng-show="indexer.showSystemFields" class="table table-bordered table-condensed">
<caption>&nbsp;</caption>
<thead>
<tr>
<th>Name</th>
<th>Enable sorting</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="field in indexer.indexCriteria.StandardFields">
<th>{{field.Name}}</th>
<td>{{field.EnableSorting}}</td>
<td>{{field.Type}}</td>
</tr>
</tbody>
</table>
</li>
<li ng-show="indexer.indexCriteria.UserFields.length > 0">
<a href="" ng-click="toggle(indexer, 'showUserFields')">User fields</a>
<table ng-show="indexer.showUserFields" class="table table-bordered table-condensed">
<caption>&nbsp;</caption>
<thead>
<tr>
<th>Name</th>
<th>Enable sorting</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="field in indexer.indexCriteria.UserFields">
<th>{{field.Name}}</th>
<td>{{field.EnableSorting}}</td>
<td>{{field.Type}}</td>
</tr>
</tbody>
</table>
</li>
<li>
<a href="" ng-click="toggle(indexer, 'showProviderProperties')">Provider properties</a>
<table ng-show="indexer.showProviderProperties" class="table table-bordered table-condensed">
<caption>&nbsp;</caption>
<tr ng-repeat="(key, val) in indexer.providerProperties track by $index">
<th>{{key}}</th>
<td>{{val}}</td>
</tr>
</table>
</li>
</ul>
</div>
</div>
</li>
<li>
<a href="" ng-click="toggle(searcher, 'showProviderProperties')">Provider properties</a>
<table ng-show="searcher.showProviderProperties" class="table table-bordered table-condensed">
<caption>&nbsp;</caption>
<tr ng-repeat="(key, val) in searcher.providerProperties track by $index">
<th>{{key}}</th>
<td>{{val}}</td>
</tr>
</table>
</li>
<div ng-show="indexer.isProcessing">
<div class="umb-healthcheck-group__details-status-overlay"></div>
<umb-load-indicator></umb-load-indicator>
</div>
</div>
</div>
</div>
<br />
<div class="umb-healthcheck-group__details-group-title">
<div class="umb-healthcheck-group__details-group-name">Searchers</div>
</div>
<div class="umb-healthcheck-group__details-checks">
<div class="umb-healthcheck-group__details-check">
<div class="umb-healthcheck-group__details-check-title">
<div class="umb-healthcheck-group__details-check-name">Search indexes</div>
<div class="umb-healthcheck-group__details-check-description">Allows you to search the indexes and view the searcher properties</div>
</div>
<div class="umb-healthcheck-group__details-status" ng-repeat="searcher in searcherDetails">
<div class="umb-healthcheck-group__details-status-icon-container">
<i class="umb-healthcheck-status-icon icon-info"></i>
</div>
<div class="umb-healthcheck-group__details-status-content">
<div class="umb-healthcheck-group__details-status-text">
<a class="btn-link -underline" href="" ng-click="toggle(searcher, 'showProperties')">
{{searcher.name}}
</a>
</div>
<div class="umb-healthcheck-group__details-status-actions" ng-show="searcher.showProperties">
<ul>
<li class="search-tools">
<a href="" ng-click="toggle(searcher, 'showTools')">Search tools</a>
<div ng-show="searcher.showTools">
<a class="hide" href="" ng-click="closeSearch(searcher)" ng-show="searcher.isSearching">Hide search results</a>
<br />
<form>
<div class="row form-search">
<div class="span8 input-append">
<input type="text" class="search-query" ng-model="searcher.searchText" no-dirty-check />
<button type="button" class="btn btn-info" ng-click="search(searcher)" ng-disabled="searcher.isProcessing">Search</button>
</div>
</div>
<div class="row">
<label for="{{searcher.name}}-textSearch" class="radio inline">
<input type="radio" name="searchType" id="{{searcher.name}}-textSearch" value="text" ng-model="searcher.searchType" no-dirty-check />
Text Search
</label>
<label for="{{searcher.name}}-luceneSearch" class="radio inline">
<input type="radio" name="searchType" id="{{searcher.name}}-luceneSearch" value="lucene" ng-model="searcher.searchType" no-dirty-check />
Lucene Search
</label>
</div>
</form>
<div class="search-results" ng-show="searcher.isSearching">
<div ng-show="indexer.isProcessing" class="umb-loader-wrapper" ng-show="indexer.isProcessing">
<div class="umb-loader"></div>
</div>
<table ng-hide="searcher.isProcessing" class="table table-bordered table-condensed">
<thead>
<tr>
<th class="score">Score</th>
<th class="id">Id</th>
<th>Values</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="result in searcher.searchResults">
<td>{{result.Score}}</td>
<td>{{result.Id}}</td>
<td>
<span ng-repeat="(key,val) in result.Fields track by $index">
<span class=""><em>{{key}}</em>:</span>
<span class="text-info">{{val}}</span>
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</li>
<li>
<a href="" ng-click="toggle(searcher, 'showProviderProperties')">Provider properties</a>
<table ng-show="searcher.showProviderProperties" class="table table-bordered table-condensed">
<caption>&nbsp;</caption>
<tr ng-repeat="(key, val) in searcher.providerProperties track by $index">
<th>{{key}}</th>
<td>{{val}}</td>
</tr>
</table>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</ul>
</li>
</ul>
</div>
@@ -1,10 +1,17 @@
angular.module("umbraco")
.controller("Umbraco.PropertyEditors.Grid.MediaController",
function ($scope, $rootScope, $timeout) {
function ($scope, $rootScope, $timeout, userService) {
if (!$scope.model.config.startNodeId) {
userService.getCurrentUser().then(function (userData) {
$scope.model.config.startNodeId = userData.startMediaId;
});
}
$scope.setImage = function(){
$scope.mediaPickerOverlay = {};
$scope.mediaPickerOverlay.view = "mediapicker";
$scope.mediaPickerOverlay.startNodeId = $scope.model.config && $scope.model.config.startNodeId ? $scope.model.config.startNodeId : undefined;
$scope.mediaPickerOverlay.cropSize = $scope.control.editor.config && $scope.control.editor.config.size ? $scope.control.editor.config.size : undefined;
$scope.mediaPickerOverlay.showDetails = true;
$scope.mediaPickerOverlay.disableFolderSelect = true;
@@ -17,7 +17,7 @@
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li ng-repeat="contentType in listViewAllowedTypes">
<li ng-repeat="contentType in listViewAllowedTypes | orderBy:'name':false">
<a href="#/{{entityType}}/{{entityType}}/edit/{{contentId}}?doctype={{contentType.alias}}&create=true">
<i class="icon-{{contentType.cssClass}}"></i>
{{contentType.name}}
+27 -10
View File
@@ -40,7 +40,8 @@
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
<UseIISExpress>true</UseIISExpress>
<IISExpressSSLPort>44319</IISExpressSSLPort>
<IISExpressSSLPort>
</IISExpressSSLPort>
<IISExpressAnonymousAuthentication>enabled</IISExpressAnonymousAuthentication>
<IISExpressWindowsAuthentication>disabled</IISExpressWindowsAuthentication>
<IISExpressUseClassicPipelineMode>false</IISExpressUseClassicPipelineMode>
@@ -127,8 +128,8 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\dotless.1.4.1.0\lib\dotless.Core.dll</HintPath>
</Reference>
<Reference Include="Examine, Version=0.1.81.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Examine.0.1.81\lib\net45\Examine.dll</HintPath>
<Reference Include="Examine, Version=0.1.82.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Examine.0.1.82\lib\net45\Examine.dll</HintPath>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@@ -350,9 +351,8 @@
<Name>umbraco.providers</Name>
</ProjectReference>
<Reference Include="System.Xml.Linq" />
<Reference Include="Umbraco.ModelsBuilder, Version=3.0.5.96, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Umbraco.ModelsBuilder.3.0.5\lib\Umbraco.ModelsBuilder.dll</HintPath>
<Private>True</Private>
<Reference Include="Umbraco.ModelsBuilder, Version=3.0.7.99, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Umbraco.ModelsBuilder.3.0.7\lib\Umbraco.ModelsBuilder.dll</HintPath>
</Reference>
<Reference Include="UrlRewritingNet.UrlRewriter, Version=2.0.7.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\UrlRewritingNet.UrlRewriter.2.0.7\lib\UrlRewritingNet.UrlRewriter.dll</HintPath>
@@ -2423,9 +2423,9 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\"
<WebProjectProperties>
<UseIIS>True</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>7511</DevelopmentServerPort>
<DevelopmentServerPort>7514</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:7511</IISUrl>
<IISUrl>http://localhost:7514</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
@@ -2435,14 +2435,31 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\"
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
<Import Project="$(MSBuildProjectDirectory)\..\umbraco.presentation.targets" Condition="$(BuildingInsideVisualStudio) != true" />
<Import Project="$(SolutionDir)umbraco.presentation.targets" Condition="$(BuildingInsideVisualStudio) == true" />
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll')">
<WebPublishingTasks>$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll</WebPublishingTasks>
</PropertyGroup>
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v11.0\Web\Microsoft.Web.Publishing.Tasks.dll')">
<WebPublishingTasks>$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v11.0\Web\Microsoft.Web.Publishing.Tasks.dll</WebPublishingTasks>
</PropertyGroup>
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v12.0\Web\Microsoft.Web.Publishing.Tasks.dll')">
<WebPublishingTasks>$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v12.0\Web\Microsoft.Web.Publishing.Tasks.dll</WebPublishingTasks>
</PropertyGroup>
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v14.0\Web\Microsoft.Web.Publishing.Tasks.dll')">
<WebPublishingTasks>$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v14.0\Web\Microsoft.Web.Publishing.Tasks.dll</WebPublishingTasks>
</PropertyGroup>
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v15.0\Web\Microsoft.Web.Publishing.Tasks.dll')">
<WebPublishingTasks>$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v15.0\Web\Microsoft.Web.Publishing.Tasks.dll</WebPublishingTasks>
</PropertyGroup>
<UsingTask TaskName="TransformXml" AssemblyFile="$(WebPublishingTasks)" Condition="'$(WebPublishingTasks)' != ''" />
<UsingTask TaskName="TransformXml" AssemblyFile="$(VSWherePath)\Microsoft\VisualStudio\v15.0\Web\Microsoft.Web.Publishing.Tasks.dll" Condition="'$(VSWherePath)' != ''" />
<Target Name="BeforeBuild">
<Message Text="WebPublishingTasks: $(WebPublishingTasks)" Importance="high" />
<Message Text="VSWherePath: $(VSWherePath)" Importance="high" />
<!-- Create web.config file from Template if it doesn't exist -->
<Copy SourceFiles="$(ProjectDir)web.Template.config" DestinationFiles="$(ProjectDir)Web.config" OverwriteReadOnlyFiles="true" SkipUnchangedFiles="false" Condition="!Exists('$(ProjectDir)Web.config')" />
<!-- Transform the local Web.config file in Visual Studio -->
+2 -2
View File
@@ -4,7 +4,7 @@
<package id="ClientDependency" version="1.9.2" targetFramework="net45" />
<package id="ClientDependency-Mvc5" version="1.8.0.0" targetFramework="net45" />
<package id="dotless" version="1.4.1.0" targetFramework="net45" />
<package id="Examine" version="0.1.81" targetFramework="net45" />
<package id="Examine" version="0.1.82" targetFramework="net45" />
<package id="ImageProcessor" version="2.5.2" targetFramework="net45" />
<package id="ImageProcessor.Web" version="4.8.2" targetFramework="net45" />
<package id="ImageProcessor.Web.Config" version="2.3.0" targetFramework="net45" />
@@ -37,6 +37,6 @@
<package id="SqlServerCE" version="4.0.0.1" targetFramework="net45" />
<package id="System.Collections.Immutable" version="1.1.36" targetFramework="net45" />
<package id="System.Reflection.Metadata" version="1.0.21" targetFramework="net45" />
<package id="Umbraco.ModelsBuilder" version="3.0.5" targetFramework="net45" />
<package id="Umbraco.ModelsBuilder" version="3.0.7" targetFramework="net45" />
<package id="UrlRewritingNet.UrlRewriter" version="2.0.7" targetFramework="net45" />
</packages>
@@ -972,7 +972,7 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="dictionaryItemSaved">Dictionary item saved</key>
<key alias="editContentPublishedFailedByParent">Publishing failed because the parent page isn't published</key>
<key alias="editContentPublishedHeader">Content published</key>
<key alias="editContentPublishedText">and visible at the website</key>
<key alias="editContentPublishedText">and visible on the website</key>
<key alias="editContentSavedHeader">Content saved</key>
<key alias="editContentSavedText">Remember to publish to make changes visible</key>
<key alias="editContentSendToPublish">Sent For Approval</key>
@@ -1252,6 +1252,8 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="templates">Templates</key>
<key alias="xslt">XSLT Files</key>
<key alias="analytics">Analytics</key>
<key alias="partialViews">Partial Views</key>
<key alias="partialViewMacros">Partial View Macro Files</key>
</area>
<area alias="update">
<key alias="updateAvailable">New update ready</key>
@@ -972,7 +972,7 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="dictionaryItemSaved">Dictionary item saved</key>
<key alias="editContentPublishedFailedByParent">Publishing failed because the parent page isn't published</key>
<key alias="editContentPublishedHeader">Content published</key>
<key alias="editContentPublishedText">and visible at the website</key>
<key alias="editContentPublishedText">and visible on the website</key>
<key alias="editContentSavedHeader">Content saved</key>
<key alias="editContentSavedText">Remember to publish to make changes visible</key>
<key alias="editContentSendToPublish">Sent For Approval</key>
+15 -2
View File
@@ -123,7 +123,6 @@
<key alias="saveListView">Сохранить список</key>
<key alias="select">Выбрать</key>
<key alias="selectCurrentFolder">Выбрать текущую папку</key>
<key alias="selected">выбранные</key>
<key alias="showPage">Предварительный просмотр</key>
<key alias="showPageDisabled">Предварительный просмотр запрещен, так как документу не сопоставлен шаблон</key>
<key alias="somethingElse">Другие действия</key>
@@ -993,6 +992,7 @@
<key alias="installStateInstalling">Установка...</key>
<key alias="installStateRestarting">Перезапуск, подождите, пожалуйста...</key>
<key alias="installStateComplete">Все готово, сейчас браузер перезагрузит страницу, подождите, пожалуйста...</key>
<key alias="installStateCompleted">Пожалуйста, нажмите кнопку 'finish' для завершения установки и перезагрузки страницы.</key>
</area>
<area alias="paste">
<key alias="doNothing">Вставить, полностью сохранив форматирование (не рекомендуется)</key>
@@ -1119,9 +1119,9 @@
<key alias="statistics">Статистика</key>
<key alias="translation">Перевод</key>
<key alias="users">Пользователи</key>
<key alias="addIcon">Добавить значок</key>
</area>
<area alias="settings">
<key alias="addIcon">Добавить значок</key>
<key alias="asAContentMasterType">в качестве родительского типа. Вкладки родительского типа не показаны и могут быть изменены непосредственно в родительском типе</key>
<key alias="contentTypeEnabled">Родительский тип контента разрешен</key>
<key alias="contentTypeUses">Данный тип контента использует</key>
@@ -1178,6 +1178,7 @@
<key alias="contentTypeTabDeletedText">Вкладка с идентификатором (id): %0% удалена</key>
<key alias="contentUnpublished">Документ скрыт (публикация отменена)</key>
<key alias="cssErrorHeader">Стиль CSS не сохранен</key>
<key alias="cssErrorText">При сохранении файла произошла ошибка.</key>
<key alias="cssSavedHeader">Стиль CSS сохранен</key>
<key alias="cssSavedText">Стиль CSS сохранен без ошибок</key>
<key alias="dataTypeSaved">Тип данных сохранен</key>
@@ -1202,9 +1203,13 @@
<key alias="fileErrorText">Файл не может быть сохранен. Пожалуйста, проверьте установки файловых разрешений</key>
<key alias="fileSavedHeader">Файл сохранен</key>
<key alias="fileSavedText">Файл сохранен без ошибок</key>
<key alias="invalidUserPermissionsText">У текущего пользователя недостаточно прав, невозможно завершить операцию</key>
<key alias="languageSaved">Язык сохранен</key>
<key alias="mediaTypeSavedHeader">Тип медиа сохранен</key>
<key alias="memberTypeSavedHeader">Тип участника сохранен</key>
<key alias="operationCancelledHeader">Отменено</key>
<key alias="operationCancelledText">Операция отменена установленным сторонним расширением или блоком кода</key>
<key alias="operationFailedHeader">Ошибка</key>
<key alias="partialViewErrorHeader">Представление не сохранено</key>
<key alias="partialViewErrorText">Произошла ошибка при сохранении файла</key>
<key alias="partialViewSavedHeader">Представление сохранено</key>
@@ -1213,10 +1218,16 @@
<key alias="pythonErrorText">Cкрипт Python не может быть сохранен в связи с ошибками</key>
<key alias="pythonSavedHeader">Cкрипт Python сохранен</key>
<key alias="pythonSavedText">Cкрипт Python сохранен без ошибок</key>
<key alias="scriptErrorHeader">Скрипт не сохранен</key>
<key alias="scriptErrorText">При сохранении файла скрипта произошла ошибка</key>
<key alias="scriptSavedHeader">Скрипт сохранен</key>
<key alias="scriptSavedText">Файл скрипта сохранен без ошибок</key>
<key alias="templateErrorHeader">Шаблон не сохранен</key>
<key alias="templateErrorText">Пожалуйста, проверьте, что нет двух шаблонов с одним и тем же алиасом (названием)</key>
<key alias="templateSavedHeader">Шаблон сохранен</key>
<key alias="templateSavedText">Шаблон сохранен без ошибок</key>
<key alias="validationFailedHeader">Проверка значений</key>
<key alias="validationFailedMessage">Ошибки, найденные при проверке значений, должны быть исправлены, чтобы было возможно сохранить документ</key>
<key alias="xsltErrorHeader">XSLT-документ не сохранен</key>
<key alias="xsltErrorText">XSLT-документ содержит одну или несколько ошибок</key>
<key alias="xsltPermissionErrorText">XSLT-документ не может быть сохранен, проверьте установки файловых разрешений</key>
@@ -1343,6 +1354,7 @@
<key alias="packager">Пакеты дополнений</key>
<key alias="packages">Пакеты дополнений</key>
<key alias="python">Скрипты Python</key>
<key alias="relationTypes">Типы связей</key>
<key alias="repositories">Установить из репозитория</key>
<key alias="runway">Установить Runway</key>
<key alias="runwayModules">Модули Runway </key>
@@ -1361,6 +1373,7 @@
<area alias="user">
<key alias="administrators">Администратор</key>
<key alias="categoryField">Поле категории</key>
<key alias="change">Изменить</key>
<key alias="changePassword">Изменить пароль</key>
<key alias="changePasswordDescription">Вы можете сменить свой пароль для доступа к административной панели Umbraco, заполнив нижеследующие поля и нажав на кнопку 'Изменить пароль'</key>
<key alias="confirmNewPassword">Подтверждение нового пароля</key>
File diff suppressed because it is too large Load Diff
@@ -80,7 +80,7 @@
<div id="feedbackMsg" data-bind="visible: processStatus() == 'complete'">
<div data-bind="css: { success: isSuccessful(), error: !isSuccessful() }">
<div data-bind="css: { 'text-success': isSuccessful(), 'text-error': !isSuccessful() }">
<span data-bind="text: resultMessage, visible: resultMessages().length == 0"></span>
<ul data-bind="foreach: resultMessages, visible: resultMessages().length > 1">
<li data-bind="text: message"></li>
@@ -16,7 +16,7 @@
<cc1:Pane ID="pane_uploadFile" runat="server" Text="Upload translation file">
<p>
When you have completed the translation. Upload the edited XML file here. The related translation tasks will automaticly be closed when a file is uploaded.
When you have completed the translation. Upload the edited XML file here. The related translation tasks will automatically be closed when a file is uploaded.
</p>
<cc1:PropertyPanel runat="server">
@@ -27,7 +27,7 @@
<script type="text/javascript" language="javascript">
jQuery(document).ready(function() {
jQuery("#<%=JTree.ClientID%>").PermissionsEditor({
userId: <%=Request.QueryString["id"] %>,
userId: <%=Request.CleanForXss("id") %>,
pPanelSelector: "#permissionsPanel",
replacePChkBoxSelector: "#chkChildPermissions"});
});
@@ -101,13 +101,13 @@ namespace Umbraco.Web.Cache
ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheByKeySearch(CacheKeys.IdToKeyCacheKey);
ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheByKeySearch(CacheKeys.KeyToIdCacheKey);
var dataTypeCache = ApplicationContext.Current.ApplicationCache.IsolatedRuntimeCache.GetCache<IDataTypeDefinition>();
payloads.ForEach(payload =>
{
//clears the prevalue cache
var dataTypeCache = ApplicationContext.Current.ApplicationCache.IsolatedRuntimeCache.GetCache<IDataTypeDefinition>();
if (dataTypeCache)
dataTypeCache.Result.ClearCacheByKeySearch(string.Format("{0}{1}", CacheKeys.DataTypePreValuesCacheKey, payload.Id));
dataTypeCache.Result.ClearCacheByKeySearch(string.Format("{0}_{1}", CacheKeys.DataTypePreValuesCacheKey, payload.Id));
PublishedContentType.ClearDataType(payload.Id);
});
@@ -22,6 +22,7 @@ using Newtonsoft.Json.Linq;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Manifest;
@@ -224,6 +225,9 @@ namespace Umbraco.Web.Editors
{"gridConfig", Url.Action("GetGridConfig", "BackOffice")},
{"serverVarsJs", Url.Action("Application", "BackOffice")},
//API URLs
{
"packagesRestApiBaseUrl", UmbracoConfig.For.UmbracoSettings().PackageRepositories.GetDefault().RestApiUrl
},
{
"redirectUrlManagementApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl<RedirectUrlManagementController>(
controller => controller.GetEnableState())
@@ -444,11 +444,7 @@ namespace Umbraco.Web.Editors
string path = Path.Combine("packages", packageGuid + ".umb");
if (File.Exists(IOHelper.MapPath(Path.Combine(SystemDirectories.Data, path))) == false)
{
//our repo guid
using (var our = Repository.getByGuid("65194810-1f85-11dd-bd0b-0800200c9a66"))
{
path = our.fetch(packageGuid, Security.CurrentUser.Id);
}
path = Services.PackagingService.FetchPackageFile(Guid.Parse(packageGuid), UmbracoVersion.Current, Security.GetUserId());
}
var model = new LocalPackageInstallModel
@@ -64,7 +64,8 @@ namespace Umbraco.Web.HealthCheck.Checks.Security
var url = HealthCheckContext.HttpContext.Request.Url;
// Access the site home page and check for the click-jack protection header or meta tag
var useSsl = GlobalSettings.UseSSL || HealthCheckContext.HttpContext.Request.ServerVariables["SERVER_PORT"] == "443";
var serverVariables = HealthCheckContext.HttpContext.Request.ServerVariables;
var useSsl = GlobalSettings.UseSSL || serverVariables["SERVER_PORT"] == "443";
var address = string.Format("http{0}://{1}:{2}", useSsl ? "s" : "", url.Host.ToLower(), url.Port);
var request = WebRequest.Create(address);
request.Method = "GET";
@@ -49,7 +49,8 @@ namespace Umbraco.Web.HealthCheck.Checks.Security
var url = HealthCheckContext.HttpContext.Request.Url;
// Access the site home page and check for the headers
var useSsl = GlobalSettings.UseSSL || HealthCheckContext.HttpContext.Request.ServerVariables["SERVER_PORT"] == "443";
var serverVariables = HealthCheckContext.HttpContext.Request.ServerVariables;
var useSsl = GlobalSettings.UseSSL || serverVariables["SERVER_PORT"] == "443";
var address = string.Format("http{0}://{1}:{2}", useSsl ? "s" : "", url.Host.ToLower(), url.Port);
var request = WebRequest.Create(address);
request.Method = "HEAD";
@@ -48,12 +48,22 @@ namespace Umbraco.Web.HealthCheck
return healthCheckGroups;
}
[HttpGet]
public object GetStatus(Guid id)
{
var check = _healthCheckResolver.HealthChecks.FirstOrDefault(x => x.Id == id);
if (check == null) throw new InvalidOperationException("No health check found with ID " + id);
return check.GetStatus();
try
{
//Core.Logging.LogHelper.Debug<HealthCheckController>("Running health check: " + check.Name);
return check.GetStatus();
}
catch (Exception e)
{
Core.Logging.LogHelper.Error<HealthCheckController>("Exception in health check: " + check.Name, e);
throw;
}
}
[HttpPost]
@@ -19,7 +19,7 @@ namespace Umbraco.Web.HealthCheck
/// </remarks>
internal class HealthCheckResolver : LazyManyObjectsResolverBase<HealthCheckResolver, HealthCheck>, IHealthCheckResolver
{
public HealthCheckResolver(ILogger logger, Func<IEnumerable<Type>> lazyTypeList)
public HealthCheckResolver(ILogger logger, Func<IEnumerable<Type>> lazyTypeList)
: base(new HealthCheckServiceProvider(), logger, lazyTypeList, ObjectLifetimeScope.HttpRequest)
{
}
@@ -51,7 +51,7 @@ namespace Umbraco.Web.HealthCheck
new HealthCheckContext(new HttpContextWrapper(HttpContext.Current), UmbracoContext.Current)
});
}
//use normal ctor
return Activator.CreateInstance(serviceType);
}
@@ -36,7 +36,7 @@ namespace Umbraco.Web.Models.Mapping
.ForMember(display => display.IsContainer, expression => expression.MapFrom(content => content.ContentType.IsContainer))
.ForMember(display => display.IsChildOfListView, expression => expression.Ignore())
.ForMember(display => display.Trashed, expression => expression.MapFrom(content => content.Trashed))
.ForMember(display => display.PublishDate, expression => expression.MapFrom(content => GetPublishedDate(content, applicationContext)))
.ForMember(display => display.PublishDate, expression => expression.MapFrom(content => GetPublishedDate(content)))
.ForMember(display => display.TemplateAlias, expression => expression.MapFrom(content => content.Template.Alias))
.ForMember(display => display.HasPublishedVersion, expression => expression.MapFrom(content => content.HasPublishedVersion))
.ForMember(display => display.Urls,
@@ -75,6 +75,12 @@ namespace Umbraco.Web.Models.Mapping
.ForMember(dto => dto.Alias, expression => expression.Ignore());
}
private static DateTime? GetPublishedDate(IContent content)
{
var date = ((Content) content).PublishedDate;
return date == default (DateTime) ? (DateTime?) null : date;
}
/// <summary>
/// Maps the generic tab with custom properties for content
/// </summary>
@@ -86,31 +92,9 @@ namespace Umbraco.Web.Models.Mapping
private static void AfterMap(IContent content, ContentItemDisplay display, IDataTypeService dataTypeService,
ILocalizedTextService localizedText, IContentTypeService contentTypeService)
{
//map the IsChildOfListView (this is actually if it is a descendant of a list view!)
//TODO: Fix this shorthand .Ancestors() lookup, at least have an overload to use the current
if (content.HasIdentity)
{
var ancesctorListView = content.Ancestors().FirstOrDefault(x => x.ContentType.IsContainer);
display.IsChildOfListView = ancesctorListView != null;
}
else
{
//it's new so it doesn't have a path, so we need to look this up by it's parent + ancestors
var parent = content.Parent();
if (parent == null)
{
display.IsChildOfListView = false;
}
else if (parent.ContentType.IsContainer)
{
display.IsChildOfListView = true;
}
else
{
var ancesctorListView = parent.Ancestors().FirstOrDefault(x => x.ContentType.IsContainer);
display.IsChildOfListView = ancesctorListView != null;
}
}
// map the IsChildOfListView (this is actually if it is a descendant of a list view!)
var parent = content.Parent();
display.IsChildOfListView = parent != null && (parent.ContentType.IsContainer || contentTypeService.HasContainerInPath(parent.Path));
//map the tree node url
if (HttpContext.Current != null)
@@ -223,26 +207,7 @@ namespace Umbraco.Web.Models.Mapping
}
/// <summary>
/// Gets the published date value for the IContent object
/// </summary>
/// <param name="content"></param>
/// <param name="applicationContext"></param>
/// <returns></returns>
private static DateTime? GetPublishedDate(IContent content, ApplicationContext applicationContext)
{
if (content.Published)
{
return content.UpdateDate;
}
if (content.HasPublishedVersion)
{
var published = applicationContext.Services.ContentService.GetPublishedVersion(content.Id);
return published.UpdateDate;
}
return null;
}
/// <summary>
//TODO: This is horribly inneficient
/// Creates the list of action buttons allowed for this user - Publish, Send to publish, save, unpublish returned as the button's 'letter'
/// </summary>
private class ActionButtonsResolver : ValueResolver<IContent, IEnumerable<char>>
@@ -41,7 +41,7 @@ namespace Umbraco.Web.Models.Mapping
.ForMember(display => display.IsContainer, expression => expression.Ignore())
.ForMember(display => display.HasPublishedVersion, expression => expression.Ignore())
.ForMember(display => display.Tabs, expression => expression.ResolveUsing(new TabsAndPropertiesResolver(applicationContext.Services.TextService)))
.AfterMap((media, display) => AfterMap(media, display, applicationContext.Services.DataTypeService, applicationContext.Services.TextService, applicationContext.ProfilingLogger.Logger));
.AfterMap((media, display) => AfterMap(media, display, applicationContext.Services.DataTypeService, applicationContext.Services.TextService, applicationContext.Services.ContentTypeService, applicationContext.ProfilingLogger.Logger));
//FROM IMedia TO ContentItemBasic<ContentPropertyBasic, IMedia>
config.CreateMap<IMedia, ContentItemBasic<ContentPropertyBasic, IMedia>>()
@@ -64,34 +64,12 @@ namespace Umbraco.Web.Models.Mapping
.ForMember(dto => dto.HasPublishedVersion, expression => expression.Ignore());
}
private static void AfterMap(IMedia media, MediaItemDisplay display, IDataTypeService dataTypeService, ILocalizedTextService localizedText, ILogger logger)
private static void AfterMap(IMedia media, MediaItemDisplay display, IDataTypeService dataTypeService, ILocalizedTextService localizedText, IContentTypeService contentTypeService, ILogger logger)
{
// Adapted from ContentModelMapper
//map the IsChildOfListView (this is actually if it is a descendant of a list view!)
//TODO: Fix this shorthand .Ancestors() lookup, at least have an overload to use the current
if (media.HasIdentity)
{
var ancesctorListView = media.Ancestors().FirstOrDefault(x => x.ContentType.IsContainer);
display.IsChildOfListView = ancesctorListView != null;
}
else
{
//it's new so it doesn't have a path, so we need to look this up by it's parent + ancestors
var parent = media.Parent();
if (parent == null)
{
display.IsChildOfListView = false;
}
else if (parent.ContentType.IsContainer)
{
display.IsChildOfListView = true;
}
else
{
var ancesctorListView = parent.Ancestors().FirstOrDefault(x => x.ContentType.IsContainer);
display.IsChildOfListView = ancesctorListView != null;
}
}
// Adapted from ContentModelMapper
//map the IsChildOfListView (this is actually if it is a descendant of a list view!)
var parent = media.Parent();
display.IsChildOfListView = parent != null && (parent.ContentType.IsContainer || contentTypeService.HasContainerInPath(parent.Path));
//map the tree node url
if (HttpContext.Current != null)
@@ -1,8 +1,10 @@
using System.ComponentModel.DataAnnotations;
using System;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
namespace Umbraco.Web.Models
{
[Serializable]
[DataContract(Name = "validatePasswordReset", Namespace = "")]
public class ValidatePasswordResetCodeModel
{
+1
View File
@@ -175,6 +175,7 @@ namespace Umbraco.Web.Mvc
public IModelBinder GetBinder(Type modelType)
{
// can bind to RenderModel (exact type match)
// You might be tempted to change this to IRenderModel but do not change this: http://issues.umbraco.org/issue/U4-8216
if (modelType == typeof(RenderModel)) return this;
// can bind to RenderModel<TContent> (exact generic type match)
@@ -13,10 +13,39 @@ namespace Umbraco.Web.Mvc
{
public abstract class UmbracoVirtualNodeRouteHandler : IRouteHandler
{
/// <summary>
/// Returns the UmbracoContext for this route handler
/// </summary>
/// <remarks>
/// By default this uses the UmbracoContext singleton, this could be overridden to check for null in the case
/// that this handler is used for a request where an UmbracoContext is not created by default see http://issues.umbraco.org/issue/U4-9384
/// <example>
/// <![CDATA[
/// protected override UmbracoContext GetUmbracoContext(RequestContext requestContext)
/// {
/// var ctx = base.GetUmbracoContext(requestContext);
/// //check if context is null, we know it will be null if we are dealing with a request that
/// //has an extension and by default no Umb ctx is created for the request
/// if (ctx == null) {
/// //TODO: Here you can EnsureContext , please note that the requestContext is passed in
/// //therefore your should refrain from using other singletons like HttpContext.Current since
/// //you will already have a reference to it. Also if you need an ApplicationContext you should
/// //pass this in via a ctor instead of using the ApplicationContext.Current singleton.
/// }
/// return ctx;
/// }
/// ]]>
/// </example>
/// </remarks>
protected virtual UmbracoContext GetUmbracoContext(RequestContext requestContext)
{
return UmbracoContext.Current;
}
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
var umbracoContext = UmbracoContext.Current;
var umbracoContext = GetUmbracoContext(requestContext);
var found = FindContent(requestContext, umbracoContext);
if (found == null) return new NotFoundHandler();
@@ -10,6 +10,7 @@ using Examine;
using Examine.LuceneEngine.SearchCriteria;
using Examine.Providers;
using Lucene.Net.Documents;
using Lucene.Net.Store;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Dynamics;
@@ -173,6 +174,11 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
// the manager will return the singleton without throwing initialization errors, however if examine isn't configured correctly a null
// reference error will occur because the examine settings are null.
}
catch (AlreadyClosedException)
{
//If the app domain is shutting down and the site is under heavy load the index reader will be closed and it really cannot
//be re-opened since the app domain is shutting down. In this case we have no option but to try to load the data from the db.
}
}
return null;
}
@@ -211,13 +217,23 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
var result = searchProvider.Search(filter.Compile()).FirstOrDefault();
if (result != null) return ConvertFromSearchResult(result);
}
catch (FileNotFoundException ex)
catch (Exception ex)
{
//Currently examine is throwing FileNotFound exceptions when we have a loadbalanced filestore and a node is published in umbraco
//See this thread: http://examine.cdodeplex.com/discussions/264341
//Catch the exception here for the time being, and just fallback to GetMedia
//TODO: Need to fix examine in LB scenarios!
LogHelper.Error<PublishedMediaCache>("Could not load data from Examine index for media", ex);
if (ex is FileNotFoundException)
{
//Currently examine is throwing FileNotFound exceptions when we have a loadbalanced filestore and a node is published in umbraco
//See this thread: http://examine.cdodeplex.com/discussions/264341
//Catch the exception here for the time being, and just fallback to GetMedia
//TODO: Need to fix examine in LB scenarios!
LogHelper.Error<PublishedMediaCache>("Could not load data from Examine index for media", ex);
}
else if (ex is AlreadyClosedException)
{
//If the app domain is shutting down and the site is under heavy load the index reader will be closed and it really cannot
//be re-opened since the app domain is shutting down. In this case we have no option but to try to load the data from the db.
LogHelper.Error<PublishedMediaCache>("Could not load data from Examine index for media, the app domain is most likely in a shutdown state", ex);
}
else throw;
}
}
@@ -4,6 +4,7 @@ using System.Linq;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.XPath;
using umbraco;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models;
@@ -315,9 +316,9 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
private void InitializeNode()
{
InitializeNode(_xmlNode, UmbracoConfig.For.UmbracoSettings().Content.UseLegacyXmlSchema, _isPreviewing,
out _id, out _key, out _template, out _sortOrder, out _name, out _writerName,
out _urlName, out _creatorName, out _creatorId, out _writerId, out _docTypeAlias, out _docTypeId, out _path,
InitializeNode(_xmlNode, UmbracoConfig.For.UmbracoSettings().Content.UseLegacyXmlSchema, _isPreviewing,
out _id, out _key, out _template, out _sortOrder, out _name, out _writerName,
out _urlName, out _creatorName, out _creatorId, out _writerId, out _docTypeAlias, out _docTypeId, out _path,
out _version, out _createDate, out _updateDate, out _level, out _isDraft, out _contentType, out _properties,
PublishedContentType.Get);
@@ -345,7 +346,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
//return if this is null
if (xmlNode == null)
{
{
return;
}
@@ -407,8 +408,8 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
}
//dictionary to store the property node data
var propertyNodes = new Dictionary<string, XmlNode>();
var propertyNodes = new Dictionary<string, XmlNode>();
foreach (XmlNode n in xmlNode.ChildNodes)
{
var e = n as XmlElement;
@@ -432,7 +433,22 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
}
//lookup the content type and create the properties collection
contentType = getPublishedContentType(PublishedItemType.Content, docTypeAlias);
try
{
contentType = getPublishedContentType(PublishedItemType.Content, docTypeAlias);
}
catch (InvalidOperationException e)
{
content.Instance.RefreshContentFromDatabase();
throw new InvalidOperationException(
string.Format("{0}. This usually indicates that the content cache is corrupt; the content cache has been rebuilt in an attempt to self-fix the issue.",
//keep the original message but don't use this as an inner exception because we want the above message to be displayed, if we use the inner exception
//we can keep the stack trace but the header message will be the original message and the one we really want to display will be hidden below the fold.
e.Message));
}
properties = new Dictionary<string, IPublishedProperty>(StringComparer.OrdinalIgnoreCase);
//fill in the property collection
@@ -8,6 +8,7 @@ namespace Umbraco.Web.Search
[DataContract(Name = "indexer", Namespace = "")]
public class ExamineIndexerModel : ExamineSearcherModel
{
[DataMember(Name = "indexCriteria")]
public IIndexCriteria IndexCriteria { get; set; }
@@ -14,6 +14,18 @@ namespace Umbraco.Web.Search
ProviderProperties = new Dictionary<string, string>();
}
/// <summary>
/// If the index is not healthy this represents the index error state
/// </summary>
[DataMember(Name = "error")]
public string Error { get; set; }
/// <summary>
/// If the index can be open/read
/// </summary>
[DataMember(Name = "isHealthy")]
public bool IsHealthy { get; set; }
[DataMember(Name = "name")]
public string Name { get; set; }
@@ -15,6 +15,28 @@ namespace Umbraco.Web.Search
/// </summary>
internal static class ExamineExtensions
{
/// <summary>
/// Checks if the index can be read/opened
/// </summary>
/// <param name="indexer"></param>
/// <param name="ex">The exception returned if there was an error</param>
/// <returns></returns>
public static bool IsHealthy(this LuceneIndexer indexer, out Exception ex)
{
try
{
using (indexer.GetIndexWriter().GetReader())
{
ex = null;
return true;
}
}
catch (Exception e)
{
ex = e;
return false;
}
}
/// <summary>
/// Return the number of indexed documents in Lucene
@@ -9,7 +9,7 @@ namespace Umbraco.Web.Trees
/// <summary>
/// Tree for displaying partial view macros in the developer app
/// </summary>
[Tree(Constants.Applications.Developer, "partialViewMacros", "Partial View Macro Files", sortOrder: 6)]
[Tree(Constants.Applications.Developer, "partialViewMacros", null, sortOrder: 6)]
public class PartialViewMacrosTree : PartialViewsTree
{
public PartialViewMacrosTree(string application) : base(application)
+1 -1
View File
@@ -18,7 +18,7 @@ namespace Umbraco.Web.Trees
/// <summary>
/// Tree for displaying partial views in the settings app
/// </summary>
[Tree(Constants.Applications.Settings, "partialViews", "Partial Views", sortOrder: 2)]
[Tree(Constants.Applications.Settings, "partialViews", null, sortOrder: 2)]
public class PartialViewsTree : FileSystemTree
{
public PartialViewsTree(string application) : base(application) { }
@@ -21,7 +21,7 @@ namespace Umbraco.Web.Trees
{
[UmbracoTreeAuthorize(Constants.Trees.Templates)]
[LegacyBaseTree(typeof (loadTemplates))]
[Tree(Constants.Applications.Settings, Constants.Trees.Templates, "Templates", sortOrder:1)]
[Tree(Constants.Applications.Settings, Constants.Trees.Templates, null, sortOrder:1)]
[PluginController("UmbracoTrees")]
[CoreTree]
public class TemplatesTreeController : TreeController
+2 -2
View File
@@ -112,8 +112,8 @@
<Reference Include="dotless.Core, Version=1.4.1.0, Culture=neutral, PublicKeyToken=96b446c9e63eae34, processorArchitecture=MSIL">
<HintPath>..\packages\dotless.1.4.1.0\lib\dotless.Core.dll</HintPath>
</Reference>
<Reference Include="Examine, Version=0.1.81.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Examine.0.1.81\lib\net45\Examine.dll</HintPath>
<Reference Include="Examine, Version=0.1.82.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Examine.0.1.82\lib\net45\Examine.dll</HintPath>
</Reference>
<Reference Include="HtmlAgilityPack, Version=1.4.9.0, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
<HintPath>..\packages\HtmlAgilityPack.1.4.9\lib\Net45\HtmlAgilityPack.dll</HintPath>
+6 -1
View File
@@ -1389,10 +1389,15 @@ namespace Umbraco.Web
return test ? new HtmlString(valueIfTrue) : new HtmlString(string.Empty);
}
#endregion
#endregion
#region Prevalues
/// <summary>
/// Gets a specific PreValue by its Id
/// </summary>
/// <param name="id">Id of the PreValue to retrieve the value from</param>
/// <returns>PreValue as a string</returns>
public string GetPreValueAsString(int id)
{
return DataTypeService.GetPreValueAsString(id);
+9
View File
@@ -579,6 +579,15 @@ namespace Umbraco.Web
// is complete and cancel this current event so the rebuild process doesn't start right now.
args.Cancel = true;
IndexesToRebuild.Add((BaseIndexProvider)args.Indexer);
//check if the index is rebuilding due to an error and log it
if (args.IsHealthy == false)
{
var baseIndex = args.Indexer as BaseIndexProvider;
var name = baseIndex != null ? baseIndex.Name : "[UKNOWN]";
ProfilingLogger.Logger.Error<WebBootManager>(string.Format("The index {0} is rebuilding due to being unreadable/corrupt", name), args.UnhealthyException);
}
}
}
}
@@ -46,16 +46,16 @@ namespace Umbraco.Web.WebServices
/*var result = ((ContentService) Services.ContentService)
.PublishWithChildrenInternal(content, UmbracoUser.Id, includeUnpublished)
.ToArray();*/
var result = doc.PublishWithSubs(UmbracoUser.Id, includeUnpublished);
var result = doc.PublishWithSubs(UmbracoUser.Id, includeUnpublished).ToArray();
return Json(new
{
success = result.All(x => x.Success),
message = GetMessageForStatuses(result.Select(x => x.Result), content)
message = GetMessageForStatuses(result.Select(x => x.Result).ToArray(), content)
});
}
}
private string GetMessageForStatuses(IEnumerable<PublishStatus> statuses, IContent doc)
private string GetMessageForStatuses(PublishStatus[] statuses, IContent doc)
{
//if all are successful then just say it was successful
if (statuses.All(x => ((int) x.StatusType) < 10))
@@ -91,12 +91,12 @@ namespace Umbraco.Web.WebServices
return "Cannot publish document with a status of " + status.StatusType;
case PublishStatusType.FailedCancelledByEvent:
return ui.Text("publish", "contentPublishedFailedByEvent",
string.Format("{0} ({1})", status.ContentItem.Name, status.ContentItem.Id), UmbracoUser);
string.Format("'{0}' ({1})", status.ContentItem.Name, status.ContentItem.Id), UmbracoUser);
case PublishStatusType.FailedContentInvalid:
return ui.Text("publish", "contentPublishedFailedInvalid",
new []{
string.Format("{0} ({1})", status.ContentItem.Name, status.ContentItem.Id),
string.Join(",", status.InvalidProperties.Select(x => x.Alias))
string.Format("'{0}' ({1})", status.ContentItem.Name, status.ContentItem.Id),
string.Format("'{0}'", string.Join(", ", status.InvalidProperties.Select(x => x.Alias)))
},
UmbracoUser);
default:
@@ -86,7 +86,7 @@ namespace Umbraco.Web.WebServices
var model = new List<ExamineSearcherModel>(
ExamineManager.Instance.SearchProviderCollection.Cast<BaseSearchProvider>().Select(searcher =>
{
var indexerModel = new ExamineIndexerModel()
var indexerModel = new ExamineSearcherModel()
{
Name = searcher.Name
};
@@ -260,6 +260,7 @@ namespace Umbraco.Web.WebServices
IndexCriteria = indexer.IndexerData,
Name = indexer.Name
};
var props = TypeHelper.CachedDiscoverableProperties(indexer.GetType(), mustWrite: false)
//ignore these properties
.Where(x => new[] {"IndexerData", "Description", "WorkingFolder"}.InvariantContains(x.Name) == false)
@@ -281,11 +282,21 @@ namespace Umbraco.Web.WebServices
var luceneIndexer = indexer as LuceneIndexer;
if (luceneIndexer != null)
{
{
indexerModel.IsLuceneIndex = true;
if (luceneIndexer.IndexExists())
{
Exception indexError;
indexerModel.IsHealthy = luceneIndexer.IsHealthy(out indexError);
if (indexerModel.IsHealthy == false)
{
//we cannot continue at this point
indexerModel.Error = indexError.ToString();
return indexerModel;
}
indexerModel.DocumentCount = luceneIndexer.GetIndexDocumentCount();
indexerModel.FieldCount = luceneIndexer.GetIndexFieldCount();
indexerModel.IsOptimized = luceneIndexer.IsIndexOptimized();
+1 -1
View File
@@ -3,7 +3,7 @@
<package id="AutoMapper" version="3.3.1" targetFramework="net45" />
<package id="ClientDependency" version="1.9.2" targetFramework="net45" />
<package id="dotless" version="1.4.1.0" targetFramework="net45" />
<package id="Examine" version="0.1.81" targetFramework="net45" />
<package id="Examine" version="0.1.82" targetFramework="net45" />
<package id="HtmlAgilityPack" version="1.4.9" targetFramework="net45" />
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net45" />
<package id="Markdown" version="1.14.7" targetFramework="net45" />
@@ -431,7 +431,7 @@ namespace umbraco
{
XmlNode x;
//Hack: this is here purely for backwards compat if someone for some reason is using the
//Hack: this is here purely for backwards compat if someone for some reason is using the
// ClearDocumentCache(int documentId) method and expecting it to remove the xml
if (removeDbXmlEntry)
{
@@ -870,8 +870,15 @@ namespace umbraco
catch (Exception e)
{
// if something goes wrong remove the file
DeleteXmlFile();
try
{
DeleteXmlFile();
}
catch
{
// don't make it worse: could be that we failed to write because we cannot
// access the file, in which case we won't be able to delete it either
}
LogHelper.Error<content>("Failed to save Xml to file.", e);
}
}
@@ -933,7 +940,15 @@ namespace umbraco
catch (Exception e)
{
LogHelper.Error<content>("Failed to load Xml from file.", e);
DeleteXmlFile();
try
{
DeleteXmlFile();
}
catch
{
// don't make it worse: could be that we failed to read because we cannot
// access the file, in which case we won't be able to delete it either
}
return null;
}
}
@@ -89,7 +89,7 @@ namespace umbraco
/// <param name="rootNode">the 'Relation Types' root node</param>
protected override void CreateRootNode(ref XmlTreeNode rootNode)
{
rootNode.Text = "Relation Types";
//rootNode.Text = "Relation Types";
rootNode.Icon = BaseTree.FolderIcon;
rootNode.OpenIcon = BaseTree.FolderIconOpen;
rootNode.NodeType = this.TreeAlias; // (Was prefixed with init)
@@ -118,7 +118,7 @@
<tr>
<td>
<strong style="color: Red;">Remember:</strong> .xslt and .ascx files for your macros
will be added automaticly, but you will still need to add <strong>assemblies</strong>,
will be added automatically, but you will still need to add <strong>assemblies</strong>,
<strong>images</strong> and <strong>script files</strong> manually to the list below.
</td>
</tr>
@@ -99,7 +99,7 @@ namespace umbraco.presentation.preview
//Inject preview xml
parentId = document.Level == 1 ? -1 : document.ParentId;
var previewXml = document.ToPreviewXml(XmlContent);
if (document.ContentEntity.Published == false
if (document.ContentEntity.Published == false
&& ApplicationContext.Current.Services.ContentService.HasPublishedVersion(document.Id))
previewXml.Attributes.Append(XmlContent.CreateAttribute("isDraft"));
XmlContent = content.GetAddOrUpdateXmlNode(XmlContent, document.Id, document.Level, parentId, previewXml);
@@ -187,13 +187,9 @@ namespace umbraco.presentation.preview
private static void CleanPreviewDirectory(int userId, DirectoryInfo dir)
{
foreach (FileInfo file in dir.GetFiles(userId + "_*.config"))
{
DeletePreviewFile(userId, file);
}
// also delete any files accessed more than 10 minutes ago
var now = DateTime.Now;
foreach (FileInfo file in dir.GetFiles("*.config"))
foreach (var file in dir.GetFiles("*.config"))
{
if ((now - file.LastAccessTime).TotalMinutes > 10)
DeletePreviewFile(userId, file);
@@ -206,6 +202,12 @@ namespace umbraco.presentation.preview
{
file.Delete();
}
catch (IOException)
{
// for *some* reason deleting the file can fail,
// and it will work later on (long-lasting locks, etc),
// so just ignore the exception
}
catch (Exception ex)
{
LogHelper.Error<PreviewContent>(string.Format("Couldn't delete preview set: {0} - User {1}", file.Name, userId), ex);
+27 -27
View File
@@ -36,6 +36,7 @@ namespace UmbracoExamine
private readonly IUserService _userService;
private readonly IContentTypeService _contentTypeService;
private readonly EntityXmlSerializer _serializer = new EntityXmlSerializer();
private const int PageSize = 10000;
#region Constructors
@@ -407,8 +408,7 @@ namespace UmbracoExamine
{
if (SupportedTypes.Contains(type) == false)
return;
const int pageSize = 10000;
var pageIndex = 0;
DataService.LogService.AddInfoLog(-1, string.Format("PerformIndexAll - Start data queries - {0}", type));
@@ -444,6 +444,7 @@ namespace UmbracoExamine
//sorted by: umbracoNode.level, umbracoNode.parentID, umbracoNode.sortOrder
var result = _contentService.GetPagedXmlEntries(path, pIndex, pSize, out totalContent).ToArray();
var more = result.Length == pSize;
//then like we do in the ContentRepository.BuildXmlCache we need to track what Parents have been processed
// already so that we can then exclude implicitly unpublished content items
@@ -479,7 +480,7 @@ namespace UmbracoExamine
filtered.Add(xml);
}
return new Tuple<long, XElement[]>(totalContent, filtered.ToArray());
return Tuple.Create(filtered.ToArray(), more);
},
i => _contentService.GetById(i));
}
@@ -497,13 +498,13 @@ namespace UmbracoExamine
IContent[] descendants;
if (SupportUnpublishedContent)
{
descendants = _contentService.GetPagedDescendants(contentParentId, pageIndex, pageSize, out total, "umbracoNode.id").ToArray();
descendants = _contentService.GetPagedDescendants(contentParentId, pageIndex, PageSize, out total, "umbracoNode.id").ToArray();
}
else
{
//get all paged records but order by level ascending, we need to do this because we need to track which nodes are not published so that we can determine
// which descendent nodes are implicitly not published
descendants = _contentService.GetPagedDescendants(contentParentId, pageIndex, pageSize, out total, "level", Direction.Ascending, true, (string)null).ToArray();
descendants = _contentService.GetPagedDescendants(contentParentId, pageIndex, PageSize, out total, "level", Direction.Ascending, true, (string)null).ToArray();
}
// need to store decendants count before filtering, in order for loop to work correctly
@@ -527,7 +528,7 @@ namespace UmbracoExamine
content, notPublished).WhereNotNull(), type);
pageIndex++;
} while (currentPageSize == pageSize);
} while (currentPageSize == PageSize);
}
break;
@@ -545,7 +546,8 @@ namespace UmbracoExamine
{
long totalMedia;
var result = _mediaService.GetPagedXmlEntries(path, pIndex, pSize, out totalMedia).ToArray();
return new Tuple<long, XElement[]>(totalMedia, result);
var more = result.Length == pSize;
return Tuple.Create(result, more);
},
i => _mediaService.GetById(i));
@@ -573,39 +575,37 @@ namespace UmbracoExamine
string type,
int parentId,
Func<TContentType[]> getContentTypes,
Func<string, int, int, Tuple<long, XElement[]>> getPagedXmlEntries,
Func<string, int, int, Tuple<XElement[], bool>> getPagedXmlEntries,
Func<int, IContentBase> getContent)
where TContentType: IContentTypeComposition
{
const int pageSize = 10000;
var pageIndex = 0;
XElement[] xElements;
var pageIndex = 0;
var contentTypes = getContentTypes();
var icons = contentTypes.ToDictionary(x => x.Id, y => y.Icon);
var parent = parentId == -1 ? null : getContent(parentId);
bool more;
do
{
long total;
XElement[] xElements;
if (parentId == -1)
{
var pagedElements = getPagedXmlEntries("-1", pageIndex, pageSize);
total = pagedElements.Item1;
xElements = pagedElements.Item2;
var pagedElements = getPagedXmlEntries("-1", pageIndex, PageSize);
xElements = pagedElements.Item1;
more = pagedElements.Item2;
}
else if (parent == null)
{
xElements = new XElement[0];
more = false;
}
else
{
//Get the parent
var parent = getContent(parentId);
if (parent == null)
xElements = new XElement[0];
else
{
var pagedElements = getPagedXmlEntries(parent.Path, pageIndex, pageSize);
total = pagedElements.Item1;
xElements = pagedElements.Item2;
}
var pagedElements = getPagedXmlEntries(parent.Path, pageIndex, PageSize);
xElements = pagedElements.Item1;
more = pagedElements.Item2;
}
//if specific types are declared we need to post filter them
@@ -626,7 +626,7 @@ namespace UmbracoExamine
AddNodesToIndex(xElements, type);
pageIndex++;
} while (xElements.Length == pageSize);
} while (more);
}
internal static IEnumerable<XElement> GetSerializedContent(

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