Compare commits
62 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8db18bf82e | |||
| 31b293aa4d | |||
| f1d1c95709 | |||
| eace918258 | |||
| 8961e8b4be | |||
| b526b8f246 | |||
| ed6d54e64a | |||
| 57290c4180 | |||
| 84b60f8b9f | |||
| cfc04a9df0 | |||
| 3e4ff05d37 | |||
| 28034d664e | |||
| edf3fd5d31 | |||
| f7705ef134 | |||
| f0caa6be4b | |||
| 5aa38c1f43 | |||
| b809f9f03a | |||
| eabc05d6f8 | |||
| d3fb614d25 | |||
| 0eb7d404a1 | |||
| 093b57505a | |||
| 2a7cd4d94a | |||
| 4503967778 | |||
| f227f2ed61 | |||
| 553bf6d304 | |||
| 45dfef78bd | |||
| b172a5f847 | |||
| 41f80b942a | |||
| 055f983cbf | |||
| 3e9556fead | |||
| b403272389 | |||
| b5bda772af | |||
| 02ccd45bf6 | |||
| b86e7dc0e8 | |||
| 578eb8b32c | |||
| f2d7ed69ca | |||
| 746573d28b | |||
| 09dc908332 | |||
| 35bf75bc82 | |||
| cb0268dfdd | |||
| 9186b392c9 | |||
| 4f30dd32f1 | |||
| bac2b1cb71 | |||
| 57af355d85 | |||
| 9bcce48df3 | |||
| c83630b376 | |||
| e1856bf851 | |||
| fe3525bc54 | |||
| 452dcbd016 | |||
| 4b489b52ef | |||
| aa86dfa956 | |||
| 04e916b41c | |||
| e167388e74 | |||
| 8f17d6fcd2 | |||
| 1300389ce6 | |||
| ea8d8ba771 | |||
| 1eb6ae10c9 | |||
| 5d3e1fb95f | |||
| 19aae9ffdc | |||
| 218995f9e0 | |||
| 0d167c4f2d | |||
| d44e0d8664 |
@@ -1,4 +1,4 @@
|
||||
_Looking for Umbraco version 8? [Click here](https://github.com/umbraco/Umbraco-CMS/blob/temp8/.github/V8_GETTING_STARTED.md) to go to the v8 branch_
|
||||
_Looking for Umbraco version 8? [Click here](https://github.com/umbraco/Umbraco-CMS/blob/dev-v8/.github/V8_GETTING_STARTED.md) to go to the v8 branch_
|
||||
# Contributing to Umbraco CMS
|
||||
|
||||
👍🎉 First off, thanks for taking the time to contribute! 🎉👍
|
||||
|
||||
+5
-3
@@ -1,7 +1,9 @@
|
||||
_You are browsing the Umbraco v8 branch. Umbraco 8 is currently under development._
|
||||
[](https://pullreminders.com?ref=badge)
|
||||
[](https://umbraco.visualstudio.com/Umbraco%20Cms/_build?definitionId=75) [](https://pullreminders.com?ref=badge)
|
||||
|
||||
_Looking for Umbraco version 7? [Click here](https://github.com/umbraco/Umbraco-CMS) to go to the v7 branch._
|
||||
|
||||
_You are browsing the Umbraco v8 branch. Umbraco 8 is currently under development._
|
||||
|
||||
_Looking for Umbraco version 7? [Click here](https://github.com/umbraco/Umbraco-CMS/tree/dev-v7) to go to the v7 branch._
|
||||
|
||||
_Ready to try out Version 8? [See the quick start guide](V8_GETTING_STARTED.md)._
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* [Visual Studio 2017 Community (Free)](https://www.visualstudio.com/vs/community/), or Professional, Enterprise, etc... _(**Minimum of Version 15.7** or higher, this is important, you WILL get issues with lesser versions)_
|
||||
* .NET Framework 4.7.2 installed, get it here: https://www.microsoft.com/net/download/thank-you/net472?survey=false
|
||||
* .NET Framework 4.7.2 developer pack, get it here: https://www.microsoft.com/net/download/thank-you/net472-developer-pack _(be sure this is the ENU file which will be named `NDP472-DevPack-ENU.exe`)_
|
||||
* Clone the Umbraco repository using the `temp8` branch. If your git client doesn't support specifying the branch as you clone then use the command `git clone --single-branch -b temp8 <your fork url>`. _(If you clone the repo using the default v7 branch and then checkout the `temp8` branch you **might** get problems)_
|
||||
* Clone the Umbraco repository using the `dev-v8` branch. If your git client doesn't support specifying the branch as you clone then use the command `git clone --single-branch -b dev-v8 <your fork url>`. _(If you clone the repo using the default v7 branch and then checkout the `dev-v8` branch you **might** get problems)_
|
||||
|
||||
### Start the solution
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata minClientVersion="4.1.0">
|
||||
<metadata minClientVersion="3.4.4">
|
||||
<id>UmbracoCms.Core</id>
|
||||
<version>8.0.0</version>
|
||||
<title>Umbraco Cms Core Binaries</title>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata minClientVersion="4.1.0">
|
||||
<metadata minClientVersion="3.4.4">
|
||||
<id>UmbracoCms.Web</id>
|
||||
<version>8.0.0</version>
|
||||
<title>Umbraco Cms Core Binaries</title>
|
||||
@@ -27,7 +27,7 @@
|
||||
<dependency id="ClientDependency" version="[1.9.7,1.999999)" />
|
||||
<dependency id="ClientDependency-Mvc5" version="[1.8.0,1.999999)" />
|
||||
<dependency id="CSharpTest.Net.Collections" version="[14.906.1403.1082,14.999999)" />
|
||||
<dependency id="Examine" version="[1.0.0,1.999999)" />
|
||||
<dependency id="Examine" version="[1.0.1,1.999999)" />
|
||||
<dependency id="HtmlAgilityPack" version="[1.8.14,1.999999)" />
|
||||
<dependency id="ImageProcessor" version="[2.7.0.100,2.999999)" />
|
||||
<dependency id="LightInject.Mvc" version="[2.0.0,2.999999)" />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata minClientVersion="4.1.0">
|
||||
<metadata minClientVersion="3.4.4">
|
||||
<id>UmbracoCms</id>
|
||||
<version>8.0.0</version>
|
||||
<title>Umbraco Cms</title>
|
||||
@@ -25,7 +25,7 @@
|
||||
not want this to happen as the alpha of the next major is, really, the next major already.
|
||||
-->
|
||||
<dependency id="Microsoft.AspNet.SignalR.Core" version="[2.4.0, 2.999999)" />
|
||||
<dependency id="Umbraco.ModelsBuilder.Ui" version="[8.0.4]" />
|
||||
<dependency id="Umbraco.ModelsBuilder.Ui" version="[8.0.1]" />
|
||||
<dependency id="ImageProcessor.Web" version="[4.10.0.100,4.999999)" />
|
||||
<dependency id="ImageProcessor.Web.Config" version="[2.5.0.100,2.999999)" />
|
||||
<dependency id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="[2.0.1,2.999999)" />
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
param($installPath, $toolsPath, $package, $project)
|
||||
|
||||
Write-Host "installPath:" "${installPath}"
|
||||
Write-Host "toolsPath:" "${toolsPath}"
|
||||
|
||||
Write-Host " "
|
||||
|
||||
if ($project) {
|
||||
$dateTime = Get-Date -Format yyyyMMdd-HHmmss
|
||||
|
||||
# Create paths and list them
|
||||
$projectPath = (Get-Item $project.Properties.Item("FullPath").Value).FullName
|
||||
Write-Host "projectPath:" "${projectPath}"
|
||||
$backupPath = Join-Path $projectPath "App_Data\NuGetBackup\$dateTime"
|
||||
Write-Host "backupPath:" "${backupPath}"
|
||||
$copyLogsPath = Join-Path $backupPath "CopyLogs"
|
||||
Write-Host "copyLogsPath:" "${copyLogsPath}"
|
||||
$umbracoBinFolder = Join-Path $projectPath "bin"
|
||||
Write-Host "umbracoBinFolder:" "${umbracoBinFolder}"
|
||||
|
||||
# Create backup folder and logs folder if it doesn't exist yet
|
||||
New-Item -ItemType Directory -Force -Path $backupPath
|
||||
New-Item -ItemType Directory -Force -Path $copyLogsPath
|
||||
|
||||
# After backing up, remove all umbraco dlls from bin folder in case dll files are included in the VS project
|
||||
# See: http://issues.umbraco.org/issue/U4-4930
|
||||
|
||||
if(Test-Path $umbracoBinFolder) {
|
||||
$umbracoBinBackupPath = Join-Path $backupPath "bin"
|
||||
|
||||
New-Item -ItemType Directory -Force -Path $umbracoBinBackupPath
|
||||
|
||||
robocopy $umbracoBinFolder $umbracoBinBackupPath /e /LOG:$copyLogsPath\UmbracoBinBackup.log
|
||||
|
||||
# Delete files Umbraco ships with
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.ApplicationBlocks.Data.dll) { Remove-Item $umbracoBinFolder\Microsoft.ApplicationBlocks.Data.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Data.SqlServerCe.dll) { Remove-Item $umbracoBinFolder\System.Data.SqlServerCe.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Data.SqlServerCe.Entity.dll) { Remove-Item $umbracoBinFolder\System.Data.SqlServerCe.Entity.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Umbraco.Web.dll) { Remove-Item $umbracoBinFolder\Umbraco.Web.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Umbraco.Core.dll) { Remove-Item $umbracoBinFolder\Umbraco.Core.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Umbraco.ModelsBuilder.dll) { Remove-Item $umbracoBinFolder\Umbraco.ModelsBuilder.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Umbraco.ModelsBuilder.AspNet.dll) { Remove-Item $umbracoBinFolder\Umbraco.ModelsBuilder.AspNet.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Umbraco.Web.UI.dll) { Remove-Item $umbracoBinFolder\Umbraco.Web.UI.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Umbraco.Examine.dll) { Remove-Item $umbracoBinFolder\Umbraco.Examine.dll -Force -Confirm:$false }
|
||||
|
||||
# Delete files Umbraco depends upon
|
||||
$amd64Folder = Join-Path $umbracoBinFolder "amd64"
|
||||
if(Test-Path $amd64Folder) { Remove-Item $amd64Folder -Force -Recurse -Confirm:$false }
|
||||
$x86Folder = Join-Path $umbracoBinFolder "x86"
|
||||
if(Test-Path $x86Folder) { Remove-Item $x86Folder -Force -Recurse -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\AutoMapper.dll) { Remove-Item $umbracoBinFolder\AutoMapper.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\AutoMapper.Net4.dll) { Remove-Item $umbracoBinFolder\AutoMapper.Net4.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\ClientDependency.Core.dll) { Remove-Item $umbracoBinFolder\ClientDependency.Core.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\ClientDependency.Core.Mvc.dll) { Remove-Item $umbracoBinFolder\ClientDependency.Core.Mvc.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\CookComputing.XmlRpcV2.dll) { Remove-Item $umbracoBinFolder\CookComputing.XmlRpcV2.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Examine.dll) { Remove-Item $umbracoBinFolder\Examine.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\HtmlAgilityPack.dll) { Remove-Item $umbracoBinFolder\HtmlAgilityPack.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\ICSharpCode.SharpZipLib.dll) { Remove-Item $umbracoBinFolder\ICSharpCode.SharpZipLib.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\ImageProcessor.dll) { Remove-Item $umbracoBinFolder\ImageProcessor.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\ImageProcessor.Web.dll) { Remove-Item $umbracoBinFolder\ImageProcessor.Web.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Lucene.Net.dll) { Remove-Item $umbracoBinFolder\Lucene.Net.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.IO.RecyclableMemoryStream.dll) { Remove-Item $umbracoBinFolder\Microsoft.IO.RecyclableMemoryStream.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.AspNet.Identity.Core.dll) { Remove-Item $umbracoBinFolder\Microsoft.AspNet.Identity.Core.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.AspNet.Identity.Owin.dll) { Remove-Item $umbracoBinFolder\Microsoft.AspNet.Identity.Owin.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.CodeAnalysis.CSharp.dll) { Remove-Item $umbracoBinFolder\Microsoft.CodeAnalysis.CSharp.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.CodeAnalysis.dll) { Remove-Item $umbracoBinFolder\Microsoft.CodeAnalysis.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.Owin.dll) { Remove-Item $umbracoBinFolder\Microsoft.Owin.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.Owin.Host.SystemWeb.dll) { Remove-Item $umbracoBinFolder\Microsoft.Owin.Host.SystemWeb.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.Owin.Security.dll) { Remove-Item $umbracoBinFolder\Microsoft.Owin.Security.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.Owin.Security.Cookies.dll) { Remove-Item $umbracoBinFolder\Microsoft.Owin.Security.Cookies.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.Owin.Security.OAuth.dll) { Remove-Item $umbracoBinFolder\Microsoft.Owin.Security.OAuth.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.Web.Infrastructure.dll) { Remove-Item $umbracoBinFolder\Microsoft.Web.Infrastructure.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.Web.Helpers.dll) { Remove-Item $umbracoBinFolder\Microsoft.Web.Helpers.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.Web.Mvc.FixedDisplayModes.dll) { Remove-Item $umbracoBinFolder\Microsoft.Web.Mvc.FixedDisplayModes.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\MiniProfiler.dll) { Remove-Item $umbracoBinFolder\MiniProfiler.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Newtonsoft.Json.dll) { Remove-Item $umbracoBinFolder\Newtonsoft.Json.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Owin.dll) { Remove-Item $umbracoBinFolder\Owin.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Semver.dll) { Remove-Item $umbracoBinFolder\Semver.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Collections.Immutable.dll) { Remove-Item $umbracoBinFolder\System.Collections.Immutable.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Reflection.Metadata.dll) { Remove-Item $umbracoBinFolder\System.Reflection.Metadata.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Net.Http.Extensions.dll) { Remove-Item $umbracoBinFolder\System.Net.Http.Extensions.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Net.Http.Formatting.dll) { Remove-Item $umbracoBinFolder\System.Net.Http.Formatting.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Net.Http.Primitives.dll) { Remove-Item $umbracoBinFolder\System.Net.Http.Primitives.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.Helpers.dll) { Remove-Item $umbracoBinFolder\System.Web.Helpers.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.Http.dll) { Remove-Item $umbracoBinFolder\System.Web.Http.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.Http.WebHost.dll) { Remove-Item $umbracoBinFolder\System.Web.Http.WebHost.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.Mvc.dll) { Remove-Item $umbracoBinFolder\System.Web.Mvc.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.Razor.dll) { Remove-Item $umbracoBinFolder\System.Web.Razor.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.WebPages.dll) { Remove-Item $umbracoBinFolder\System.Web.WebPages.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.WebPages.Deployment.dll) { Remove-Item $umbracoBinFolder\System.Web.WebPages.Deployment.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.WebPages.Razor.dll) { Remove-Item $umbracoBinFolder\System.Web.WebPages.Razor.dll -Force -Confirm:$false }
|
||||
}
|
||||
}
|
||||
@@ -11,15 +11,37 @@ if ($project) {
|
||||
# Create paths and list them
|
||||
$projectPath = (Get-Item $project.Properties.Item("FullPath").Value).FullName
|
||||
Write-Host "projectPath:" "${projectPath}"
|
||||
$backupPath = Join-Path $projectPath "App_Data\NuGetBackup\$dateTime"
|
||||
Write-Host "backupPath:" "${backupPath}"
|
||||
$copyLogsPath = Join-Path $backupPath "CopyLogs"
|
||||
Write-Host "copyLogsPath:" "${copyLogsPath}"
|
||||
$webConfigSource = Join-Path $projectPath "Web.config"
|
||||
Write-Host "webConfigSource:" "${webConfigSource}"
|
||||
$configFolder = Join-Path $projectPath "Config"
|
||||
Write-Host "configFolder:" "${configFolder}"
|
||||
|
||||
# Create backup folder and logs folder if it doesn't exist yet
|
||||
New-Item -ItemType Directory -Force -Path $backupPath
|
||||
New-Item -ItemType Directory -Force -Path $copyLogsPath
|
||||
|
||||
# Create a backup of original web.config
|
||||
Copy-Item $webConfigSource $backupPath -Force
|
||||
|
||||
# Backup config files folder
|
||||
if(Test-Path $configFolder) {
|
||||
$umbracoBackupPath = Join-Path $backupPath "Config"
|
||||
New-Item -ItemType Directory -Force -Path $umbracoBackupPath
|
||||
|
||||
robocopy $configFolder $umbracoBackupPath /e /LOG:$copyLogsPath\ConfigBackup.log
|
||||
}
|
||||
|
||||
# Copy umbraco and umbraco_files from package to project folder
|
||||
$umbracoFolder = Join-Path $projectPath "Umbraco"
|
||||
New-Item -ItemType Directory -Force -Path $umbracoFolder
|
||||
$umbracoFolderSource = Join-Path $installPath "UmbracoFiles\Umbraco"
|
||||
$umbracoBackupPath = Join-Path $backupPath "Umbraco"
|
||||
New-Item -ItemType Directory -Force -Path $umbracoBackupPath
|
||||
robocopy $umbracoFolder $umbracoBackupPath /e /LOG:$copyLogsPath\UmbracoBackup.log
|
||||
robocopy $umbracoFolderSource $umbracoFolder /is /it /e /xf UI.xml /LOG:$copyLogsPath\UmbracoCopy.log
|
||||
|
||||
$copyWebconfig = $true
|
||||
@@ -78,6 +100,11 @@ if ($project) {
|
||||
}
|
||||
}
|
||||
|
||||
$installFolder = Join-Path $projectPath "Install"
|
||||
if(Test-Path $installFolder) {
|
||||
Remove-Item $installFolder -Force -Recurse -Confirm:$false
|
||||
}
|
||||
|
||||
# Open appropriate readme
|
||||
if($copyWebconfig -eq $true)
|
||||
{
|
||||
|
||||
+2
-2
@@ -18,5 +18,5 @@ using System.Resources;
|
||||
[assembly: AssemblyVersion("8.0.0")]
|
||||
|
||||
// these are FYI and changed automatically
|
||||
[assembly: AssemblyFileVersion("8.0.1")]
|
||||
[assembly: AssemblyInformationalVersion("8.0.1")]
|
||||
[assembly: AssemblyFileVersion("8.1.0")]
|
||||
[assembly: AssemblyInformationalVersion("8.1.0")]
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
/// <summary>
|
||||
/// Compose.
|
||||
/// </summary>
|
||||
/// <param name="composition"></param>
|
||||
void Compose(Composition composition);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,10 @@
|
||||
/// Represents a core <see cref="IComposer"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Core composers compose after the initial composer, and before user composers.</para>
|
||||
/// <para>All core composers are required by (compose before) all user composers,
|
||||
/// and require (compose after) all runtime composers.</para>
|
||||
/// </remarks>
|
||||
[ComposeAfter(typeof(IRuntimeComposer))]
|
||||
public interface ICoreComposer : IComposer
|
||||
{ }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a runtime <see cref="IComposer"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>All runtime composers are required by (compose before) all core composers</para>
|
||||
/// </remarks>
|
||||
public interface IRuntimeComposer : IComposer
|
||||
{ }
|
||||
}
|
||||
@@ -4,9 +4,9 @@
|
||||
/// Represents a user <see cref="IComposer"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>User composers compose after core composers, and before the final composer.</para>
|
||||
/// <para>All user composers require (compose after) all core composers.</para>
|
||||
/// </remarks>
|
||||
[ComposeAfter(typeof(ICoreComposer))]
|
||||
public interface IUserComposer : IComposer
|
||||
{ }
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a base class for collections of types.
|
||||
/// </summary>
|
||||
public abstract class TypeCollectionBuilderBase<TCollection, TConstraint> : ICollectionBuilder<TCollection, Type>
|
||||
where TCollection : class, IBuilderCollection<Type>
|
||||
{
|
||||
private readonly HashSet<Type> _types = new HashSet<Type>();
|
||||
|
||||
private Type Validate(Type type, string action)
|
||||
{
|
||||
if (!typeof(TConstraint).IsAssignableFrom(type))
|
||||
throw new InvalidOperationException($"Cannot {action} type {type.FullName} as it does not inherit from/implement {typeof(TConstraint).FullName}.");
|
||||
return type;
|
||||
}
|
||||
|
||||
public void Add(Type type) => _types.Add(Validate(type, "add"));
|
||||
|
||||
public void Add<T>() => Add(typeof(T));
|
||||
|
||||
public void Add(IEnumerable<Type> types)
|
||||
{
|
||||
foreach (var type in types) Add(type);
|
||||
}
|
||||
|
||||
public void Remove(Type type) => _types.Remove(Validate(type, "remove"));
|
||||
|
||||
public void Remove<T>() => Remove(typeof(T));
|
||||
|
||||
public TCollection CreateCollection(IFactory factory)
|
||||
{
|
||||
return factory.CreateInstance<TCollection>(_types);
|
||||
}
|
||||
|
||||
public void RegisterWith(IRegister register)
|
||||
{
|
||||
register.Register(CreateCollection, Lifetime.Singleton);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,12 +8,9 @@ namespace Umbraco.Core.IO.MediaPathSchemes
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Path is "{combinedGuid}/{filename}" where combinedGuid is a combination of itemGuid and propertyGuid.</para>
|
||||
/// <para>This scheme is dangerous, as it does not prevent potential collisions.</para>
|
||||
/// </remarks>
|
||||
public class CombinedGuidsMediaPathScheme : IMediaPathScheme
|
||||
{
|
||||
private const int DirectoryLength = 8;
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetFilePath(IMediaFileSystem fileSystem, Guid itemGuid, Guid propertyGuid, string filename, string previous = null)
|
||||
{
|
||||
@@ -21,7 +18,7 @@ namespace Umbraco.Core.IO.MediaPathSchemes
|
||||
// for a single content cannot store two different files with the same name
|
||||
|
||||
var combinedGuid = GuidUtils.Combine(itemGuid, propertyGuid);
|
||||
var directory = GuidUtils.ToBase32String(combinedGuid, DirectoryLength); // see also HexEncoder, we may want to fragment path eg 12/e4/f3...
|
||||
var directory = HexEncoder.Encode(combinedGuid.ToByteArray()/*'/', 2, 4*/); // could use ext to fragment path eg 12/e4/f2/...
|
||||
return Path.Combine(directory, filename).Replace('\\', '/');
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Umbraco.Core.IO.MediaPathSchemes
|
||||
/// Implements a unique directory media path scheme.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>This scheme provides short paths, yet handle potential collisions.</para>
|
||||
/// <para>This scheme provides deterministic short paths, with potential collisions.</para>
|
||||
/// </remarks>
|
||||
public class UniqueMediaPathScheme : IMediaPathScheme
|
||||
{
|
||||
@@ -16,23 +16,22 @@ namespace Umbraco.Core.IO.MediaPathSchemes
|
||||
/// <inheritdoc />
|
||||
public string GetFilePath(IMediaFileSystem fileSystem, Guid itemGuid, Guid propertyGuid, string filename, string previous = null)
|
||||
{
|
||||
string directory;
|
||||
|
||||
// no point "combining" guids if all we want is some random guid - just get a new one
|
||||
// and then, because we don't want collisions, ensure that the directory does not already exist
|
||||
// (should be quite rare, but eh...)
|
||||
|
||||
do
|
||||
{
|
||||
var combinedGuid = Guid.NewGuid();
|
||||
directory = GuidUtils.ToBase32String(combinedGuid, DirectoryLength); // see also HexEncoder, we may want to fragment path eg 12/e4/f3...
|
||||
|
||||
} while (fileSystem.DirectoryExists(directory));
|
||||
var combinedGuid = GuidUtils.Combine(itemGuid, propertyGuid);
|
||||
var directory = GuidUtils.ToBase32String(combinedGuid, DirectoryLength);
|
||||
|
||||
return Path.Combine(directory, filename).Replace('\\', '/');
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetDeleteDirectory(IMediaFileSystem fileSystem, string filepath) => Path.GetDirectoryName(filepath);
|
||||
/// <remarks>
|
||||
/// <para>Returning null so that <see cref="MediaFileSystem.DeleteMediaFiles"/> does *not*
|
||||
/// delete any directory. This is because the above shortening of the Guid to 8 chars
|
||||
/// means we're increasing the risk of collision, and we don't want to delete files
|
||||
/// belonging to other media items.</para>
|
||||
/// <para>And, at the moment, we cannot delete directory "only if it is empty" because of
|
||||
/// race conditions. We'd need to implement locks in <see cref="MediaFileSystem"/> for
|
||||
/// this.</para>
|
||||
/// </remarks>
|
||||
public string GetDeleteDirectory(IMediaFileSystem fileSystem, string filepath) => null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_7_12_0;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_7_14_0;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_8_0_0;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_8_0_1;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade
|
||||
{
|
||||
@@ -138,8 +137,6 @@ namespace Umbraco.Core.Migrations.Upgrade
|
||||
|
||||
To<RenameLabelAndRichTextPropertyEditorAliases>("{E0CBE54D-A84F-4A8F-9B13-900945FD7ED9}");
|
||||
To<MergeDateAndDateTimePropertyEditor>("{78BAF571-90D0-4D28-8175-EF96316DA789}");
|
||||
To<ChangeNuCacheJsonFormat>("{80C0A0CB-0DD5-4573-B000-C4B7C313C70D}");
|
||||
|
||||
//FINAL
|
||||
|
||||
|
||||
@@ -170,7 +167,7 @@ namespace Umbraco.Core.Migrations.Upgrade
|
||||
From("{init-7.12.4}").To("{init-7.10.0}"); // same as 7.12.0
|
||||
From("{init-7.13.0}").To("{init-7.10.0}"); // same as 7.12.0
|
||||
From("{init-7.13.1}").To("{init-7.10.0}"); // same as 7.12.0
|
||||
|
||||
|
||||
// 7.14.0 has migrations, handle it...
|
||||
// clone going from 7.10 to 1350617A (the last one before we started to merge 7.12 migrations), then
|
||||
// clone going from CF51B39B (after 7.12 migrations) to 0009109C (the last one before we started to merge 7.12 migrations),
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
using Umbraco.Core.Migrations.PostMigrations;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_1
|
||||
{
|
||||
public class ChangeNuCacheJsonFormat : MigrationBase
|
||||
{
|
||||
public ChangeNuCacheJsonFormat(IMigrationContext context) : base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
// nothing - just adding the post-migration
|
||||
Context.AddPostMigration<RebuildPublishedSnapshot>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,14 +11,14 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PublishedCultureInfo"/> class.
|
||||
/// </summary>
|
||||
public PublishedCultureInfo(string culture, string name, string urlSegment, DateTime date)
|
||||
public PublishedCultureInfo(string culture, string name, DateTime date)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(culture)) throw new ArgumentNullOrEmptyException(nameof(culture));
|
||||
if (string.IsNullOrWhiteSpace(name)) throw new ArgumentNullOrEmptyException(nameof(name));
|
||||
|
||||
Culture = culture;
|
||||
Name = name;
|
||||
UrlSegment = urlSegment;
|
||||
UrlSegment = name.ToUrlSegment(culture);
|
||||
Date = date;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,10 +36,6 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
if (source is int)
|
||||
return (int)source == 1;
|
||||
|
||||
// this is required for correct true/false handling in nested content elements
|
||||
if (source is long)
|
||||
return (long)source == 1;
|
||||
|
||||
if (source is bool)
|
||||
return (bool)source;
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ namespace Umbraco.Core.Runtime
|
||||
_state.BootFailedException = bfe;
|
||||
}
|
||||
|
||||
timer?.Fail(exception: bfe); // be sure to log the exception - even if we repeat ourselves
|
||||
timer.Fail(exception: bfe); // be sure to log the exception - even if we repeat ourselves
|
||||
|
||||
// if something goes wrong above, we may end up with no factory
|
||||
// meaning nothing can get the runtime state, etc - so let's try
|
||||
@@ -242,7 +242,7 @@ namespace Umbraco.Core.Runtime
|
||||
}
|
||||
catch
|
||||
{
|
||||
timer?.Fail();
|
||||
timer.Fail();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -5,11 +5,11 @@ using Umbraco.Core.IO;
|
||||
|
||||
namespace Umbraco.Core.Runtime
|
||||
{
|
||||
public class CoreInitialComponent : IComponent
|
||||
public class CoreRuntimeComponent : IComponent
|
||||
{
|
||||
private readonly IEnumerable<Profile> _mapperProfiles;
|
||||
|
||||
public CoreInitialComponent(IEnumerable<Profile> mapperProfiles)
|
||||
public CoreRuntimeComponent(IEnumerable<Profile> mapperProfiles)
|
||||
{
|
||||
_mapperProfiles = mapperProfiles;
|
||||
}
|
||||
+1
-3
@@ -24,9 +24,7 @@ using IntegerValidator = Umbraco.Core.PropertyEditors.Validators.IntegerValidato
|
||||
|
||||
namespace Umbraco.Core.Runtime
|
||||
{
|
||||
// core's initial composer composes before all core composers
|
||||
[ComposeBefore(typeof(ICoreComposer))]
|
||||
public class CoreInitialComposer : ComponentComposer<CoreInitialComponent>
|
||||
public class CoreRuntimeComposer : ComponentComposer<CoreRuntimeComponent>, IRuntimeComposer
|
||||
{
|
||||
public override void Compose(Composition composition)
|
||||
{
|
||||
@@ -2862,7 +2862,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
{
|
||||
if (blueprint == null) throw new ArgumentNullException(nameof(blueprint));
|
||||
|
||||
var contentType = _contentTypeRepository.Get(blueprint.ContentType.Id);
|
||||
var contentType = GetContentType(blueprint.ContentType.Alias);
|
||||
var content = new Content(name, -1, contentType);
|
||||
content.Path = string.Concat(content.ParentId.ToString(), ",", content.Id);
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Umbraco.Core.Strings
|
||||
/// Converts an Utf8 string into an Ascii string.
|
||||
/// </summary>
|
||||
/// <param name="text">The text to convert.</param>
|
||||
/// <param name="fail">The character to used to replace characters that cannot properly be converted.</param>
|
||||
/// <param name="fail">The character to use to replace characters that cannot properly be converted.</param>
|
||||
/// <returns>The converted text.</returns>
|
||||
public static string ToAsciiString(string text, char fail = '?')
|
||||
{
|
||||
@@ -39,7 +39,7 @@ namespace Umbraco.Core.Strings
|
||||
/// Converts an Utf8 string into an array of Ascii characters.
|
||||
/// </summary>
|
||||
/// <param name="text">The text to convert.</param>
|
||||
/// <param name="fail">The character to used to replace characters that cannot properly be converted.</param>
|
||||
/// <param name="fail">The character to use to replace characters that cannot properly be converted.</param>
|
||||
/// <returns>The converted text.</returns>
|
||||
public static char[] ToAsciiCharArray(string text, char fail = '?')
|
||||
{
|
||||
@@ -66,7 +66,7 @@ namespace Umbraco.Core.Strings
|
||||
/// </summary>
|
||||
/// <param name="input">The input array.</param>
|
||||
/// <param name="output">The output array.</param>
|
||||
/// <param name="fail">The character to used to replace characters that cannot properly be converted.</param>
|
||||
/// <param name="fail">The character to use to replace characters that cannot properly be converted.</param>
|
||||
/// <returns>The number of characters in the output array.</returns>
|
||||
/// <remarks>The caller must ensure that the output array is big enough.</remarks>
|
||||
/// <exception cref="OverflowException">The output array is not big enough.</exception>
|
||||
@@ -112,7 +112,7 @@ namespace Umbraco.Core.Strings
|
||||
/// <param name="ipos">The input position.</param>
|
||||
/// <param name="output">The output array.</param>
|
||||
/// <param name="opos">The output position.</param>
|
||||
/// <param name="fail">The character to used to replace characters that cannot properly be converted.</param>
|
||||
/// <param name="fail">The character to use to replace characters that cannot properly be converted.</param>
|
||||
/// <remarks>
|
||||
/// <para>Adapted from various sources on the 'net including <c>Lucene.Net.Analysis.ASCIIFoldingFilter</c>.</para>
|
||||
/// <para>Input should contain Utf8 characters exclusively and NOT Unicode.</para>
|
||||
|
||||
@@ -168,6 +168,7 @@
|
||||
<Compile Include="Composing\EnableComposerAttribute.cs" />
|
||||
<Compile Include="Composing\IComposer.cs" />
|
||||
<Compile Include="Composing\ICoreComposer.cs" />
|
||||
<Compile Include="Composing\IRuntimeComposer.cs" />
|
||||
<Compile Include="Composing\IComponent.cs" />
|
||||
<Compile Include="Composing\IUserComposer.cs" />
|
||||
<Compile Include="Compose\ManifestWatcherComposer.cs" />
|
||||
@@ -208,13 +209,11 @@
|
||||
<Compile Include="Composing\TypeLoader.cs" />
|
||||
<Compile Include="IO\MediaPathSchemes\UniqueMediaPathScheme.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\MergeDateAndDateTimePropertyEditor.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_1\ChangeNuCacheJsonFormat.cs" />
|
||||
<Compile Include="Models\PublishedContent\ILivePublishedModelFactory.cs" />
|
||||
<Compile Include="PropertyEditors\DateTimeConfiguration.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\RenameLabelAndRichTextPropertyEditorAliases.cs" />
|
||||
<Compile Include="PublishedModelFactoryExtensions.cs" />
|
||||
<Compile Include="Services\PropertyValidationService.cs" />
|
||||
<Compile Include="Composing\TypeCollectionBuilderBase.cs" />
|
||||
<Compile Include="TypeLoaderExtensions.cs" />
|
||||
<Compile Include="Composing\WeightAttribute.cs" />
|
||||
<Compile Include="Composing\WeightedCollectionBuilderBase.cs" />
|
||||
@@ -531,7 +530,7 @@
|
||||
<Compile Include="RuntimeLevelReason.cs" />
|
||||
<Compile Include="RuntimeOptions.cs" />
|
||||
<Compile Include="Runtime\CoreRuntime.cs" />
|
||||
<Compile Include="Runtime\CoreInitialComponent.cs" />
|
||||
<Compile Include="Runtime\CoreRuntimeComponent.cs" />
|
||||
<Compile Include="CustomBooleanTypeConverter.cs" />
|
||||
<Compile Include="Migrations\Expressions\Common\ExecutableBuilder.cs" />
|
||||
<Compile Include="Migrations\Expressions\Common\IExecutableBuilder.cs" />
|
||||
@@ -1312,7 +1311,7 @@
|
||||
<Compile Include="ReflectionUtilities.cs" />
|
||||
<Compile Include="RuntimeLevel.cs" />
|
||||
<Compile Include="RuntimeState.cs" />
|
||||
<Compile Include="Runtime\CoreInitialComposer.cs" />
|
||||
<Compile Include="Runtime\CoreRuntimeComposer.cs" />
|
||||
<Compile Include="SafeCallContext.cs" />
|
||||
<Compile Include="Scoping\IInstanceIdentifiable.cs" />
|
||||
<Compile Include="Scoping\IScope.cs" />
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<!-- note: NuGet deals with transitive references now -->
|
||||
<PackageReference Include="Examine" Version="1.0.0" />
|
||||
<PackageReference Include="Examine" Version="1.0.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
|
||||
<PackageReference Include="NPoco" Version="3.9.4" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -158,7 +158,7 @@ namespace Umbraco.Tests.Cache
|
||||
new TestDefaultCultureAccessor(),
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
TestObjects.GetGlobalSettings(),
|
||||
new UrlProviderCollection(Enumerable.Empty<IUrlProvider>()),
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
// just assert it does not throw
|
||||
|
||||
@@ -112,9 +112,19 @@ namespace Umbraco.Tests.IO
|
||||
fs.DeleteMediaFiles(new[] { virtPath });
|
||||
Assert.IsFalse(File.Exists(physPath));
|
||||
|
||||
// ~/media/1234 is gone
|
||||
physPath = Path.GetDirectoryName(physPath);
|
||||
Assert.IsFalse(Directory.Exists(physPath));
|
||||
var scheme = Current.Factory.GetInstance<IMediaPathScheme>();
|
||||
if (scheme is UniqueMediaPathScheme)
|
||||
{
|
||||
// ~/media/1234 is *not* gone
|
||||
physPath = Path.GetDirectoryName(physPath);
|
||||
Assert.IsTrue(Directory.Exists(physPath));
|
||||
}
|
||||
else
|
||||
{
|
||||
// ~/media/1234 is gone
|
||||
physPath = Path.GetDirectoryName(physPath);
|
||||
Assert.IsFalse(Directory.Exists(physPath));
|
||||
}
|
||||
|
||||
// ~/media exists
|
||||
physPath = Path.GetDirectoryName(physPath);
|
||||
|
||||
@@ -15,7 +15,6 @@ using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Scoping;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Services.Changes;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Tests.Testing.Objects;
|
||||
using Umbraco.Tests.Testing.Objects.Accessors;
|
||||
@@ -182,8 +181,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
globalSettings,
|
||||
new SiteDomainHelper(),
|
||||
Mock.Of<IEntityXmlSerializer>(),
|
||||
Mock.Of<IPublishedModelFactory>(),
|
||||
new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }));
|
||||
Mock.Of<IPublishedModelFactory>());
|
||||
|
||||
// invariant is the current default
|
||||
_variationAccesor.VariationContext = new VariationContext();
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace Umbraco.Tests.Routing
|
||||
{
|
||||
base.SetUp();
|
||||
|
||||
WebFinalComponent.CreateRoutes(
|
||||
WebRuntimeComponent.CreateRoutes(
|
||||
new TestUmbracoContextAccessor(),
|
||||
TestObjects.GetGlobalSettings(),
|
||||
new SurfaceControllerTypeCollection(Enumerable.Empty<Type>()),
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace Umbraco.Tests.Runtimes
|
||||
|
||||
var composerTypes = typeLoader.GetTypes<IComposer>() // all of them
|
||||
.Where(x => !x.FullName.StartsWith("Umbraco.Tests.")) // exclude test components
|
||||
.Where(x => x != typeof(WebInitialComposer)); // exclude web runtime
|
||||
.Where(x => x != typeof(WebRuntimeComposer)); // exclude web runtime
|
||||
var composers = new Composers(composition, composerTypes, profilingLogger);
|
||||
composers.Compose();
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Umbraco.Tests.Runtimes
|
||||
new PluginViewEngine()
|
||||
};
|
||||
|
||||
WebInitialComponent.WrapViewEngines(engines);
|
||||
WebRuntimeComponent.WrapViewEngines(engines);
|
||||
|
||||
Assert.That(engines.Count, Is.EqualTo(2));
|
||||
Assert.That(engines[0], Is.InstanceOf<ProfilingViewEngine>());
|
||||
@@ -34,7 +34,7 @@ namespace Umbraco.Tests.Runtimes
|
||||
new PluginViewEngine()
|
||||
};
|
||||
|
||||
WebInitialComponent.WrapViewEngines(engines);
|
||||
WebRuntimeComponent.WrapViewEngines(engines);
|
||||
|
||||
Assert.That(engines.Count, Is.EqualTo(2));
|
||||
Assert.That(((ProfilingViewEngine)engines[0]).Inner, Is.InstanceOf<RenderViewEngine>());
|
||||
@@ -50,7 +50,7 @@ namespace Umbraco.Tests.Runtimes
|
||||
profiledEngine
|
||||
};
|
||||
|
||||
WebInitialComponent.WrapViewEngines(engines);
|
||||
WebRuntimeComponent.WrapViewEngines(engines);
|
||||
|
||||
Assert.That(engines[0], Is.SameAs(profiledEngine));
|
||||
}
|
||||
@@ -58,7 +58,7 @@ namespace Umbraco.Tests.Runtimes
|
||||
[Test]
|
||||
public void WrapViewEngines_CollectionIsNull_DoesNotThrow()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WebInitialComponent.WrapViewEngines(null));
|
||||
Assert.DoesNotThrow(() => WebRuntimeComponent.WrapViewEngines(null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ using Umbraco.Core.Persistence.Repositories;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Services.Implement;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Core.Sync;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Tests.Testing;
|
||||
@@ -100,8 +99,7 @@ namespace Umbraco.Tests.Scoping
|
||||
new DatabaseDataSource(),
|
||||
Factory.GetInstance<IGlobalSettings>(), new SiteDomainHelper(),
|
||||
Factory.GetInstance<IEntityXmlSerializer>(),
|
||||
Mock.Of<IPublishedModelFactory>(),
|
||||
new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }));
|
||||
Mock.Of<IPublishedModelFactory>());
|
||||
}
|
||||
|
||||
protected UmbracoContext GetUmbracoContextNu(string url, int templateId = 1234, RouteData routeData = null, bool setSingleton = false, IUmbracoSettingsSection umbracoSettings = null, IEnumerable<IUrlProvider> urlProviders = null)
|
||||
|
||||
@@ -15,7 +15,6 @@ using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Core.Persistence.Repositories;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Core.Sync;
|
||||
using Umbraco.Tests.Testing;
|
||||
using Umbraco.Web;
|
||||
@@ -73,8 +72,7 @@ namespace Umbraco.Tests.Services
|
||||
new DatabaseDataSource(),
|
||||
Factory.GetInstance<IGlobalSettings>(), new SiteDomainHelper(),
|
||||
Factory.GetInstance<IEntityXmlSerializer>(),
|
||||
Mock.Of<IPublishedModelFactory>(),
|
||||
new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }));
|
||||
Mock.Of<IPublishedModelFactory>());
|
||||
}
|
||||
|
||||
public class LocalServerMessenger : ServerMessengerBase
|
||||
|
||||
@@ -116,7 +116,7 @@ namespace Umbraco.Tests.TestHelpers
|
||||
|
||||
var umbracoSettings = GetUmbracoSettings();
|
||||
var globalSettings = GetGlobalSettings();
|
||||
var urlProviders = new UrlProviderCollection(Enumerable.Empty<IUrlProvider>());
|
||||
var urlProviders = Enumerable.Empty<IUrlProvider>();
|
||||
|
||||
if (accessor == null) accessor = new TestUmbracoContextAccessor();
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoMapper" Version="8.0.0" />
|
||||
<PackageReference Include="Castle.Core" Version="4.3.1" />
|
||||
<PackageReference Include="Examine" Version="1.0.0" />
|
||||
<PackageReference Include="Examine" Version="1.0.1" />
|
||||
<PackageReference Include="HtmlAgilityPack">
|
||||
<Version>1.8.14</Version>
|
||||
</PackageReference>
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace Umbraco.Tests.Web.Mvc
|
||||
new TestDefaultCultureAccessor(),
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
globalSettings,
|
||||
new UrlProviderCollection(Enumerable.Empty<IUrlProvider>()),
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>());
|
||||
@@ -100,7 +100,7 @@ namespace Umbraco.Tests.Web.Mvc
|
||||
new TestDefaultCultureAccessor(),
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
globalSettings,
|
||||
new UrlProviderCollection(Enumerable.Empty<IUrlProvider>()),
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>());
|
||||
@@ -129,7 +129,7 @@ namespace Umbraco.Tests.Web.Mvc
|
||||
new TestDefaultCultureAccessor(),
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
globalSettings,
|
||||
new UrlProviderCollection(Enumerable.Empty<IUrlProvider>()),
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>());
|
||||
@@ -158,7 +158,7 @@ namespace Umbraco.Tests.Web.Mvc
|
||||
new TestDefaultCultureAccessor(),
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
globalSettings,
|
||||
new UrlProviderCollection(Enumerable.Empty<IUrlProvider>()),
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>());
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace Umbraco.Tests.Web.Mvc
|
||||
new TestDefaultCultureAccessor(),
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
globalSettings,
|
||||
new UrlProviderCollection(Enumerable.Empty<IUrlProvider>()),
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>());
|
||||
@@ -73,7 +73,7 @@ namespace Umbraco.Tests.Web.Mvc
|
||||
new TestDefaultCultureAccessor(),
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
globalSettings,
|
||||
new UrlProviderCollection(Enumerable.Empty<IUrlProvider>()),
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>());
|
||||
@@ -103,7 +103,7 @@ namespace Umbraco.Tests.Web.Mvc
|
||||
new TestDefaultCultureAccessor(),
|
||||
Mock.Of<IUmbracoSettingsSection>(section => section.WebRouting == Mock.Of<IWebRoutingSection>(routingSection => routingSection.UrlProviderMode == "Auto")),
|
||||
globalSettings,
|
||||
new UrlProviderCollection(Enumerable.Empty<IUrlProvider>()),
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>());
|
||||
@@ -140,7 +140,7 @@ namespace Umbraco.Tests.Web.Mvc
|
||||
new TestDefaultCultureAccessor(),
|
||||
Mock.Of<IUmbracoSettingsSection>(section => section.WebRouting == webRoutingSettings),
|
||||
globalSettings,
|
||||
new UrlProviderCollection(Enumerable.Empty<IUrlProvider>()),
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>());
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace Umbraco.Tests.Web
|
||||
new TestDefaultCultureAccessor(),
|
||||
Mock.Of<IUmbracoSettingsSection>(section => section.WebRouting == Mock.Of<IWebRoutingSection>(routingSection => routingSection.UrlProviderMode == "Auto")),
|
||||
globalSettings,
|
||||
new UrlProviderCollection(new[] { testUrlProvider.Object }),
|
||||
new[] { testUrlProvider.Object },
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
using (var reference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>()))
|
||||
|
||||
+21
-7
@@ -5210,12 +5210,14 @@
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
@@ -5230,17 +5232,20 @@
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
@@ -5357,7 +5362,8 @@
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
@@ -5369,6 +5375,7 @@
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
@@ -5383,6 +5390,7 @@
|
||||
"version": "3.0.4",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
@@ -5390,12 +5398,14 @@
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.2.4",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.1",
|
||||
"yallist": "^3.0.0"
|
||||
@@ -5414,6 +5424,7 @@
|
||||
"version": "0.5.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
@@ -5494,7 +5505,8 @@
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
@@ -5506,6 +5518,7 @@
|
||||
"version": "1.4.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
@@ -5627,6 +5640,7 @@
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
|
||||
+1
-1
@@ -344,8 +344,8 @@
|
||||
loadAuditTrail(true);
|
||||
loadRedirectUrls();
|
||||
setNodePublishStatus();
|
||||
updateCurrentUrls();
|
||||
}
|
||||
updateCurrentUrls();
|
||||
});
|
||||
|
||||
//ensure to unregister from all events!
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@
|
||||
item: '=',
|
||||
onOpen: '&',
|
||||
onOpenAnchor: '&',
|
||||
index: '@'
|
||||
hotkey: '<'
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ function navigationService($routeParams, $location, $q, $timeout, $injector, eve
|
||||
navReadyPromise.resolve(mainTreeApi);
|
||||
});
|
||||
|
||||
|
||||
|
||||
//A list of query strings defined that when changed will not cause a reload of the route
|
||||
var nonRoutingQueryStrings = ["mculture", "cculture", "lq"];
|
||||
var retainedQueryStrings = ["mculture"];
|
||||
|
||||
@@ -350,6 +350,9 @@ function treeService($q, treeResource, iconHelper, notificationsService, eventsS
|
||||
parent.children.splice(parent.children.indexOf(treeNode), 1);
|
||||
|
||||
parent.hasChildren = parent.children.length !== 0;
|
||||
|
||||
//Notify that the node has been removed
|
||||
eventsService.emit("treeService.removeNode", { node: treeNode });
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* @param {navigationService} navigationService A reference to the navigationService
|
||||
*/
|
||||
function NavigationController($scope, $rootScope, $location, $log, $q, $routeParams, $timeout, $cookies, treeService, appState, navigationService, keyboardService, historyService, eventsService, angularHelper, languageResource, contentResource) {
|
||||
function NavigationController($scope, $rootScope, $location, $log, $q, $routeParams, $timeout, $cookies, treeService, appState, navigationService, keyboardService, historyService, eventsService, angularHelper, languageResource, contentResource, editorState) {
|
||||
|
||||
//this is used to trigger the tree to start loading once everything is ready
|
||||
var treeInitPromise = $q.defer();
|
||||
@@ -249,6 +249,20 @@ function NavigationController($scope, $rootScope, $location, $log, $q, $routePar
|
||||
$scope.infiniteMode = args && args.editors.length > 0 ? true : false;
|
||||
}));
|
||||
|
||||
evts.push(eventsService.on("treeService.removeNode", function (e, args) {
|
||||
//check to see if the current page has been removed
|
||||
|
||||
var currentEditorState = editorState.getCurrent()
|
||||
if (currentEditorState && currentEditorState.id.toString() === args.node.id.toString()) {
|
||||
//current page is loaded, so navigate to root
|
||||
var section = appState.getSectionState("currentSection");
|
||||
$location.path("/" + section);
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Based on the current state of the application, this configures the scope variables that control the main tree and language drop down
|
||||
*/
|
||||
|
||||
@@ -113,12 +113,7 @@ var app = angular.module("umbraco.preview", ['umbraco.resources', 'umbraco.servi
|
||||
$scope.exitPreview = function () {
|
||||
|
||||
var culture = $location.search().culture || getParameterByName("culture");
|
||||
var relativeUrl = "/" + $scope.pageId;
|
||||
|
||||
if(culture){
|
||||
relativeUrl +='?culture='+ culture;
|
||||
}
|
||||
|
||||
var relativeUrl = "/" + $scope.pageId +'?culture='+ culture;
|
||||
window.top.location.href = "../preview/end?redir=" + encodeURIComponent(relativeUrl);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<div ng-controller="Umbraco.Overlays.UserController">
|
||||
|
||||
<div class="umb-control-group" ng-if="!showPasswordFields">
|
||||
|
||||
<h5><localize key="user_yourProfile" /></h5>
|
||||
@@ -79,7 +78,7 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div class="umb-control-group" ng-if="!showPasswordFields">
|
||||
<div class="umb-control-group" ng-if="!showPasswordFields && history.length">
|
||||
<h5><localize key="user_yourHistory" /></h5>
|
||||
<ul class="umb-tree">
|
||||
<li ng-repeat="item in history | orderBy:'time':true">
|
||||
@@ -127,7 +126,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
<div class="umb-control-group">
|
||||
<div class="umb-control-group" ng-if="tab.length">
|
||||
<div ng-repeat="tab in dashboard">
|
||||
<div ng-repeat="property in tab.properties">
|
||||
<div>
|
||||
|
||||
+6
-6
@@ -1,10 +1,10 @@
|
||||
<a data-element="sub-view-{{vm.item.alias}}"
|
||||
tabindex="-1"
|
||||
ng-href=""
|
||||
ng-click="vm.clicked()"
|
||||
hotkey="{{vm.index+1}}"
|
||||
hotkey-when-hidden="true"
|
||||
ng-class="{'is-active': vm.item.active, '-has-error': vm.item.hasError}">
|
||||
tabindex="-1"
|
||||
ng-href=""
|
||||
ng-click="vm.clicked()"
|
||||
hotkey="{{::vm.hotkey}}"
|
||||
hotkey-when-hidden="true"
|
||||
ng-class="{'is-active': vm.item.active, '-has-error': vm.item.hasError}">
|
||||
<i class="icon {{ vm.item.icon }}"></i>
|
||||
<span class="umb-sub-views-nav-item-text">{{ vm.item.name }}</span>
|
||||
<div ng-show="vm.item.badge" class="badge -type-{{vm.item.badge.type}}">{{vm.item.badge.count}}</div>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
item="navItem"
|
||||
on-open="openNavigationItem(item)"
|
||||
on-open-anchor="openAnchorItem(item, anchor)"
|
||||
index="{{$index}}">
|
||||
hotkey="$index + 1">
|
||||
</umb-editor-navigation-item>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
@@ -24,21 +24,20 @@
|
||||
<div>
|
||||
<label for="{{variant.htmlId}}" style="margin-bottom: 2px;">
|
||||
<span>{{ variant.language.name }}</span>
|
||||
|
||||
<span class="db umb-permission__description" ng-if="!publishVariantSelectorForm.publishVariantSelector.$invalid && !(variant.notifications && variant.notifications.length > 0)">
|
||||
<umb-variant-state variant="variant"></umb-variant-state>
|
||||
<span ng-if="variant.language.isMandatory"> - <localize key="languages_mandatoryLanguage"></localize></span>
|
||||
</span>
|
||||
|
||||
<span class="db" ng-messages="publishVariantSelectorForm.publishVariantSelector.$error" show-validation-on-submit>
|
||||
<span class="db umb-permission__description" style="color: #F02E28;" ng-message="valServerField">{{publishVariantSelectorForm.publishVariantSelector.errorMsg}}</span>
|
||||
</span>
|
||||
|
||||
<span class="db" ng-repeat="notification in variant.notifications">
|
||||
<span class="db umb-permission__description" style="color: #1FB572;">{{notification.message}}</span>
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<div class="umb-permission__description" ng-if="!publishVariantSelectorForm.publishVariantSelector.$invalid && !(variant.notifications && variant.notifications.length > 0)">
|
||||
<umb-variant-state variant="variant"></umb-variant-state>
|
||||
<span ng-if="variant.language.isMandatory"> - <localize key="languages_mandatoryLanguage"></localize></span>
|
||||
</div>
|
||||
|
||||
<div ng-messages="publishVariantSelectorForm.publishVariantSelector.$error" show-validation-on-submit>
|
||||
<div class="umb-permission__description" style="color: #F02E28;" ng-message="valServerField">{{publishVariantSelectorForm.publishVariantSelector.errorMsg}}</div>
|
||||
</div>
|
||||
|
||||
<div ng-repeat="notification in variant.notifications">
|
||||
<div class="umb-permission__description" style="color: #1FB572;">{{notification.message}}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -50,21 +50,20 @@
|
||||
<div>
|
||||
<label for="{{variant.htmlId}}" style="margin-bottom: 0;">
|
||||
<span>{{ variant.language.name }}</span>
|
||||
|
||||
<span class="db umb-permission__description" ng-if="!publishVariantSelectorForm.publishVariantSelector.$invalid && !(variant.notifications && variant.notifications.length > 0)">
|
||||
<umb-variant-state variant="variant"></umb-variant-state>
|
||||
<span ng-if="variant.language.isMandatory"> - <localize key="languages_mandatoryLanguage"></localize></span>
|
||||
</span>
|
||||
|
||||
<span class="db" ng-messages="publishVariantSelectorForm.publishVariantSelector.$error" show-validation-on-submit>
|
||||
<span class="db umb-permission__description" style="color: #F02E28;" ng-message="valServerField">{{publishVariantSelectorForm.publishVariantSelector.errorMsg}}</span>
|
||||
</span>
|
||||
|
||||
<span class="db" ng-repeat="notification in variant.notifications">
|
||||
<span class="db umb-permission__description" style="color: #1FB572;">{{notification.message}}</span>
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<div class="umb-permission__description" ng-if="!publishVariantSelectorForm.publishVariantSelector.$invalid && !(variant.notifications && variant.notifications.length > 0)">
|
||||
<umb-variant-state variant="variant"></umb-variant-state>
|
||||
<span ng-if="variant.language.isMandatory"> - <localize key="languages_mandatoryLanguage"></localize></span>
|
||||
</div>
|
||||
|
||||
<div ng-messages="publishVariantSelectorForm.publishVariantSelector.$error" show-validation-on-submit>
|
||||
<div class="umb-permission__description" style="color: #F02E28;" ng-message="valServerField">{{publishVariantSelectorForm.publishVariantSelector.errorMsg}}</div>
|
||||
</div>
|
||||
|
||||
<div ng-repeat="notification in variant.notifications">
|
||||
<div class="umb-permission__description" style="color: #1FB572;">{{notification.message}}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -28,20 +28,19 @@
|
||||
<label for="{{variant.htmlId}}" style="margin-bottom: 2px;">
|
||||
<span>{{ variant.language.name }}</span>
|
||||
<strong ng-if="variant.language.isMandatory" class="umb-control-required">*</strong>
|
||||
|
||||
<span class="db" ng-if="!saveVariantSelectorForm.$invalid && !(variant.notifications && variant.notifications.length > 0)">
|
||||
<umb-variant-state class="umb-permission__description" variant="variant"></umb-variant-state>
|
||||
</span>
|
||||
|
||||
<span class="db" ng-messages="saveVariantSelectorForm.saveVariantSelector.$error" show-validation-on-submit>
|
||||
<span class="db umb-permission__description" style="color: #F02E28;" ng-message="valServerField">{{saveVariantSelectorForm.saveVariantSelector.errorMsg}}</span>
|
||||
</span>
|
||||
|
||||
<span class="db" ng-repeat="notification in variant.notifications">
|
||||
<span class="db umb-permission__description" style="color: #1FB572;">{{notification.message}}</span>
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<div ng-if="!saveVariantSelectorForm.$invalid && !(variant.notifications && variant.notifications.length > 0)">
|
||||
<umb-variant-state class="umb-permission__description" variant="variant"></umb-variant-state>
|
||||
</div>
|
||||
|
||||
<div ng-messages="saveVariantSelectorForm.saveVariantSelector.$error" show-validation-on-submit>
|
||||
<div class="umb-permission__description" style="color: #F02E28;" ng-message="valServerField">{{saveVariantSelectorForm.saveVariantSelector.errorMsg}}</div>
|
||||
</div>
|
||||
|
||||
<div ng-repeat="notification in variant.notifications">
|
||||
<div class="umb-permission__description" style="color: #1FB572;">{{notification.message}}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -72,20 +71,19 @@
|
||||
<label for="{{variant.htmlId}}" style="margin-bottom: 2px;">
|
||||
<span>{{ variant.language.name }}</span>
|
||||
<strong ng-if="variant.language.isMandatory" class="umb-control-required">*</strong>
|
||||
|
||||
<span class="db" ng-if="!saveVariantSelectorForm.$invalid && !(variant.notifications && variant.notifications.length > 0)">
|
||||
<umb-variant-state class="umb-permission__description" variant="variant"></umb-variant-state>
|
||||
</span>
|
||||
|
||||
<span class="db" ng-messages="saveVariantSelectorForm.saveVariantSelector.$error" show-validation-on-submit>
|
||||
<span class="db umb-permission__description" style="color: #F02E28;" ng-message="valServerField">{{saveVariantSelectorForm.saveVariantSelector.errorMsg}}</span>
|
||||
</span>
|
||||
|
||||
<span class="db" ng-repeat="notification in variant.notifications">
|
||||
<span class="db umb-permission__description" style="color: #1FB572;">{{notification.message}}</span>
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<div ng-if="!saveVariantSelectorForm.$invalid && !(variant.notifications && variant.notifications.length > 0)">
|
||||
<umb-variant-state class="umb-permission__description" variant="variant"></umb-variant-state>
|
||||
</div>
|
||||
|
||||
<div ng-messages="saveVariantSelectorForm.saveVariantSelector.$error" show-validation-on-submit>
|
||||
<div class="umb-permission__description" style="color: #F02E28;" ng-message="valServerField">{{saveVariantSelectorForm.saveVariantSelector.errorMsg}}</div>
|
||||
</div>
|
||||
|
||||
<div ng-repeat="notification in variant.notifications">
|
||||
<div class="umb-permission__description" style="color: #1FB572;">{{notification.message}}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -97,13 +97,13 @@
|
||||
|
||||
<label for="{{'saveVariantSelector_' + variant.language.culture}}" style="margin-bottom: 2px;">
|
||||
<span>{{ variant.language.name }}</span>
|
||||
</label>
|
||||
|
||||
<div class="umb-permission__description"
|
||||
ng-if="!scheduleSelectorForm.$invalid && !(variant.notifications && variant.notifications.length > 0)">
|
||||
<umb-variant-state variant="variant"></umb-variant-state>
|
||||
<span ng-show="variant.language.isMandatory"> - <localize key="languages_mandatoryLanguage"></localize></span>
|
||||
</div>
|
||||
<span class="db umb-permission__description"
|
||||
ng-if="!scheduleSelectorForm.$invalid && !(variant.notifications && variant.notifications.length > 0)">
|
||||
<umb-variant-state variant="variant"></umb-variant-state>
|
||||
<span ng-show="variant.language.isMandatory"> - <localize key="languages_mandatoryLanguage"></localize></span>
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<div class="flex items-center" style="margin-top: 10px; margin-bottom: 10px;">
|
||||
|
||||
|
||||
@@ -23,6 +23,12 @@
|
||||
|
||||
|
||||
if (vm.variants.length !== 0) {
|
||||
_.each(vm.variants,
|
||||
function (variant) {
|
||||
variant.compositeId = variant.language.culture + "_" + (variant.segment ? variant.segment : "");
|
||||
variant.htmlId = "_content_variant_" + variant.compositeId;
|
||||
});
|
||||
|
||||
//now sort it so that the current one is at the top
|
||||
vm.variants = _.sortBy(vm.variants, function (v) {
|
||||
return v.active ? 0 : 1;
|
||||
|
||||
@@ -24,20 +24,19 @@
|
||||
<label for="{{variant.htmlId}}" style="margin-bottom: 2px;">
|
||||
<span>{{ variant.language.name }}</span>
|
||||
<strong ng-if="variant.language.isMandatory" class="umb-control-required">*</strong>
|
||||
|
||||
<span class="db" ng-if="!publishVariantSelectorForm.publishVariantSelector.$invalid && !(variant.notifications && variant.notifications.length > 0)">
|
||||
<umb-variant-state class="umb-permission__description" variant="variant"></umb-variant-state>
|
||||
</span>
|
||||
|
||||
<span class="db" ng-messages="publishVariantSelectorForm.publishVariantSelector.$error" show-validation-on-submit>
|
||||
<span class="db umb-permission__description" style="color: #F02E28;" ng-message="valServerField">{{publishVariantSelectorForm.publishVariantSelector.errorMsg}}</span>
|
||||
</span>
|
||||
|
||||
<span class="db" ng-repeat="notification in variant.notifications">
|
||||
<span class="db umb-permission__description" style="color: #1FB572;">{{notification.message}}</span>
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<div ng-if="!publishVariantSelectorForm.publishVariantSelector.$invalid && !(variant.notifications && variant.notifications.length > 0)">
|
||||
<umb-variant-state class="umb-permission__description" variant="variant"></umb-variant-state>
|
||||
</div>
|
||||
|
||||
<div ng-messages="publishVariantSelectorForm.publishVariantSelector.$error" show-validation-on-submit>
|
||||
<div class="umb-permission__description" style="color: #F02E28;" ng-message="valServerField">{{publishVariantSelectorForm.publishVariantSelector.errorMsg}}</div>
|
||||
</div>
|
||||
|
||||
<div ng-repeat="notification in variant.notifications">
|
||||
<div class="umb-permission__description" style="color: #1FB572;">{{notification.message}}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -21,6 +21,12 @@
|
||||
});
|
||||
}
|
||||
|
||||
_.each(vm.variants,
|
||||
function (variant) {
|
||||
variant.compositeId = variant.language.culture + "_" + (variant.segment ? variant.segment : "");
|
||||
variant.htmlId = "_content_variant_" + variant.compositeId;
|
||||
});
|
||||
|
||||
// node has variants
|
||||
if (vm.variants.length !== 1) {
|
||||
//now sort it so that the current one is at the top
|
||||
|
||||
@@ -27,13 +27,12 @@
|
||||
<div>
|
||||
<label for="{{variant.htmlId}}" style="margin-bottom: 2px;">
|
||||
<span>{{ variant.language.name }}</span>
|
||||
</label>
|
||||
|
||||
<div class="umb-permission__description">
|
||||
<umb-variant-state variant="variant"></umb-variant-state>
|
||||
<span ng-if="variant.language.isMandatory"> - <localize key="languages_mandatoryLanguage"></localize></span>
|
||||
</div>
|
||||
|
||||
|
||||
<span class="db umb-permission__description">
|
||||
<umb-variant-state variant="variant"></umb-variant-state>
|
||||
<span ng-if="variant.language.isMandatory"> - <localize key="languages_mandatoryLanguage"></localize></span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ function FormsController($scope, $cookies, packageResource, localizationService)
|
||||
return packageResource.installData(pack);
|
||||
}, vm.error)
|
||||
.then(function(pack) {
|
||||
vm.state = installStateComplete;
|
||||
vm.state = labels.installStateComplete;
|
||||
return packageResource.cleanUp(pack);
|
||||
}, vm.error)
|
||||
.then(vm.complete, vm.error);
|
||||
|
||||
@@ -22,7 +22,6 @@ function DataTypeDeleteController($scope, dataTypeResource, treeService, navigat
|
||||
treeService.removeNode($scope.currentNode);
|
||||
navigationService.hideMenu();
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
$scope.performContainerDelete = function () {
|
||||
|
||||
@@ -20,7 +20,8 @@ function DocumentTypesDeleteController($scope, dataTypeResource, contentTypeReso
|
||||
|
||||
// TODO: Need to sync tree, etc...
|
||||
treeService.removeNode($scope.currentNode);
|
||||
navigationService.hideMenu();
|
||||
navigationService.hideMenu();
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
@@ -38,6 +39,7 @@ function DocumentTypesDeleteController($scope, dataTypeResource, contentTypeReso
|
||||
// TODO: Need to sync tree, etc...
|
||||
treeService.removeNode($scope.currentNode);
|
||||
navigationService.hideMenu();
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* @description
|
||||
* The controller for deleting macro items
|
||||
*/
|
||||
function MacrosDeleteController($scope, $location, macroResource, navigationService, treeService) {
|
||||
function MacrosDeleteController($scope, macroResource, navigationService, treeService) {
|
||||
var vm = this;
|
||||
|
||||
vm.name = $scope.currentNode.name;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* @description
|
||||
* The controller for the media type delete dialog
|
||||
*/
|
||||
function MediaTypesDeleteController($scope, dataTypeResource, mediaTypeResource, treeService, navigationService) {
|
||||
function MediaTypesDeleteController($scope, mediaTypeResource, treeService, navigationService) {
|
||||
|
||||
$scope.performDelete = function() {
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ function MemberTypesDeleteController($scope, memberTypeResource, treeService, na
|
||||
// TODO: Need to sync tree, etc...
|
||||
treeService.removeNode($scope.currentNode);
|
||||
navigationService.hideMenu();
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
<div class="umb-info-local-item">
|
||||
<strong><localize key="packager_packageReadme">Read me</localize></strong>
|
||||
<br>
|
||||
<small> {{ vm.package.readme }} </small>
|
||||
<small ng-bind-html="vm.package.readme"></small>
|
||||
</div>
|
||||
|
||||
<div class="umb-info-local-item mt4 flex items-center flex-column" ng-if="vm.installState.status == ''">
|
||||
|
||||
@@ -21,6 +21,7 @@ function PartialViewMacrosDeleteController($scope, codefileResource, treeService
|
||||
// TODO: Need to sync tree, etc...
|
||||
treeService.removeNode($scope.currentNode);
|
||||
navigationService.hideMenu();
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ function PartialViewsDeleteController($scope, codefileResource, treeService, nav
|
||||
// TODO: Need to sync tree, etc...
|
||||
treeService.removeNode($scope.currentNode);
|
||||
navigationService.hideMenu();
|
||||
|
||||
}, function (err) {
|
||||
$scope.currentNode.loading = false;
|
||||
$scope.error = err;
|
||||
|
||||
@@ -122,25 +122,24 @@ angular.module("umbraco")
|
||||
},
|
||||
|
||||
over: function (event, ui) {
|
||||
|
||||
var area = event.target.getScope_HackForSortable().area;
|
||||
var area = $(event.target).scope().area;
|
||||
var allowedEditors = area.allowed;
|
||||
|
||||
if (($.inArray(ui.item[0].getScope_HackForSortable().control.editor.alias, allowedEditors) < 0 && allowedEditors) ||
|
||||
|
||||
if (($.inArray(ui.item.scope().control.editor.alias, allowedEditors) < 0 && allowedEditors) ||
|
||||
(startingArea != area && area.maxItems != '' && area.maxItems > 0 && area.maxItems < area.controls.length + 1)) {
|
||||
|
||||
$scope.$apply(function () {
|
||||
event.target.getScope_HackForSortable().area.dropNotAllowed = true;
|
||||
$(event.target).scope().area.dropNotAllowed = true;
|
||||
});
|
||||
|
||||
ui.placeholder.hide();
|
||||
cancelMove = true;
|
||||
}
|
||||
else {
|
||||
if (event.target.getScope_HackForSortable().area.controls.length == 0){
|
||||
if ($(event.target).scope().area.controls.length == 0){
|
||||
|
||||
$scope.$apply(function () {
|
||||
event.target.getScope_HackForSortable().area.dropOnEmpty = true;
|
||||
$(event.target).scope().area.dropOnEmpty = true;
|
||||
});
|
||||
ui.placeholder.hide();
|
||||
} else {
|
||||
@@ -152,9 +151,8 @@ angular.module("umbraco")
|
||||
|
||||
out: function(event, ui) {
|
||||
$scope.$apply(function () {
|
||||
var dropArea = event.target.getScope_HackForSortable().area;
|
||||
dropArea.dropNotAllowed = false;
|
||||
dropArea.dropOnEmpty = false;
|
||||
$(event.target).scope().area.dropNotAllowed = false;
|
||||
$(event.target).scope().area.dropOnEmpty = false;
|
||||
});
|
||||
},
|
||||
|
||||
@@ -180,9 +178,10 @@ angular.module("umbraco")
|
||||
currentForm.$setDirty();
|
||||
},
|
||||
|
||||
start: function (event, ui) {
|
||||
start: function (e, ui) {
|
||||
|
||||
//Get the starting area for reference
|
||||
var area = event.target.getScope_HackForSortable().area;
|
||||
var area = $(e.target).scope().area;
|
||||
startingArea = area;
|
||||
|
||||
// fade out control when sorting
|
||||
@@ -208,7 +207,7 @@ angular.module("umbraco")
|
||||
});
|
||||
},
|
||||
|
||||
stop: function (event, ui) {
|
||||
stop: function (e, ui) {
|
||||
|
||||
// Fade in control when sorting stops
|
||||
ui.item[0].style.opacity = "1";
|
||||
@@ -237,7 +236,7 @@ angular.module("umbraco")
|
||||
|
||||
$scope.$apply(function () {
|
||||
|
||||
var cell = event.target.getScope_HackForSortable().area;
|
||||
var cell = $(e.target).scope().area;
|
||||
cell.hasActiveChild = hasActiveChild(cell, cell.controls);
|
||||
cell.active = false;
|
||||
});
|
||||
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function umbGridHackScope() {
|
||||
|
||||
function link($scope, $element) {
|
||||
|
||||
// Since the grid used the el.scope() method, which should only be used by debugging, and only are avilable in debug-mode. I had to make a replica method doig the same:
|
||||
$element[0].getScope_HackForSortable = function() {
|
||||
return $scope;
|
||||
}
|
||||
}
|
||||
|
||||
var directive = {
|
||||
restrict: "A",
|
||||
link: link
|
||||
};
|
||||
|
||||
return directive;
|
||||
|
||||
}
|
||||
|
||||
angular.module("umbraco").directive("umbGridHackScope", umbGridHackScope);
|
||||
|
||||
})();
|
||||
@@ -159,7 +159,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-cell-inner" ui-sortable="sortableOptionsCell" umb-grid-hack-scope ng-model="area.controls">
|
||||
<div class="umb-cell-inner" ui-sortable="sortableOptionsCell" ng-model="area.controls">
|
||||
|
||||
<!-- Control placeholder -->
|
||||
<div class="umb-cell-placeholder" ng-if="area.controls.length === 0" ng-click="openEditorOverlay($event, area, 0, area.$uniqueId);">
|
||||
@@ -171,7 +171,6 @@
|
||||
|
||||
<!-- for each control in areas -->
|
||||
<div class="umb-control"
|
||||
umb-grid-hack-scope
|
||||
ng-repeat="control in area.controls"
|
||||
ng-click="clickControl($index, area.controls, area)"
|
||||
ng-class="{'-active': control.active}"
|
||||
|
||||
@@ -21,6 +21,7 @@ function ScriptsDeleteController($scope, codefileResource, treeService, navigati
|
||||
// TODO: Need to sync tree, etc...
|
||||
treeService.removeNode($scope.currentNode);
|
||||
navigationService.hideMenu();
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* @description
|
||||
* The controller for the template delete dialog
|
||||
*/
|
||||
function TemplatesDeleteController($scope, templateResource , treeService, navigationService) {
|
||||
function TemplatesDeleteController($scope, templateResource, treeService, navigationService) {
|
||||
|
||||
$scope.performDelete = function() {
|
||||
|
||||
@@ -25,6 +25,7 @@ function TemplatesDeleteController($scope, templateResource , treeService, navig
|
||||
// TODO: Need to sync tree, etc...
|
||||
treeService.removeNode($scope.currentNode);
|
||||
navigationService.hideMenu();
|
||||
|
||||
}, function (err) {
|
||||
$scope.currentNode.loading = false;
|
||||
$scope.error = err;
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
<PackageReference Include="CSharpTest.Net.Collections" Version="14.906.1403.1082" />
|
||||
<PackageReference Include="ClientDependency" Version="1.9.7" />
|
||||
<PackageReference Include="ClientDependency-Mvc5" Version="1.8.0.0" />
|
||||
<PackageReference Include="Examine" Version="1.0.0" />
|
||||
<PackageReference Include="Examine" Version="1.0.1" />
|
||||
<PackageReference Include="ImageProcessor.Web" Version="4.10.0.100" />
|
||||
<PackageReference Include="ImageProcessor.Web.Config" Version="2.5.0.100" />
|
||||
<PackageReference Include="Microsoft.AspNet.Identity.Owin" Version="2.2.2" />
|
||||
@@ -105,7 +105,7 @@
|
||||
<PackageReference Include="MiniProfiler" Version="4.0.138" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
|
||||
<PackageReference Include="Umbraco.ModelsBuilder.Ui">
|
||||
<Version>8.0.4</Version>
|
||||
<Version>8.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Umbraco.SqlServerCE" Version="4.0.0.1" />
|
||||
</ItemGroup>
|
||||
@@ -340,9 +340,9 @@
|
||||
<WebProjectProperties>
|
||||
<UseIIS>False</UseIIS>
|
||||
<AutoAssignPort>True</AutoAssignPort>
|
||||
<DevelopmentServerPort>8010</DevelopmentServerPort>
|
||||
<DevelopmentServerPort>8100</DevelopmentServerPort>
|
||||
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||
<IISUrl>http://localhost:8010</IISUrl>
|
||||
<IISUrl>http://localhost:8100</IISUrl>
|
||||
<NTLMAuthentication>False</NTLMAuthentication>
|
||||
<UseCustomServer>False</UseCustomServer>
|
||||
<CustomServerUrl>
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Umbraco.Web.ContentApps
|
||||
Weight = Weight
|
||||
});
|
||||
|
||||
case IMedia media when !media.ContentType.IsContainer || media.Properties.Count > 0:
|
||||
case IMedia media when !media.ContentType.IsContainer && media.ContentType.Alias != Core.Constants.Conventions.MediaTypes.Folder:
|
||||
return _mediaApp ?? (_mediaApp = new ContentApp
|
||||
{
|
||||
Alias = "umbContent",
|
||||
|
||||
@@ -6,7 +6,6 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Editors;
|
||||
using Umbraco.Web.Routing;
|
||||
@@ -199,10 +198,10 @@ namespace Umbraco.Web.Macros
|
||||
Id = _inner.Id;
|
||||
Key = _inner.Key;
|
||||
|
||||
// TODO: ARGH! need to fix this - this is not good because it uses ApplicationContext.Current
|
||||
CreatorName = _inner.GetCreatorProfile()?.Name;
|
||||
WriterName = _inner.GetWriterProfile()?.Name;
|
||||
|
||||
// TODO: inject
|
||||
var contentType = Current.Services.ContentTypeBaseServices.GetContentTypeOf(_inner);
|
||||
ContentType = Current.PublishedContentTypeFactory.CreateContentType(contentType);
|
||||
|
||||
@@ -253,9 +252,8 @@ namespace Umbraco.Web.Macros
|
||||
if (_cultureInfos != null)
|
||||
return _cultureInfos;
|
||||
|
||||
var urlSegmentProviders = Current.UrlSegmentProviders; // TODO inject
|
||||
return _cultureInfos = _inner.PublishCultureInfos.Values
|
||||
.ToDictionary(x => x.Culture, x => new PublishedCultureInfo(x.Culture, x.Name, _inner.GetUrlSegment(urlSegmentProviders, x.Culture), x.Date));
|
||||
.ToDictionary(x => x.Culture, x => new PublishedCultureInfo(x.Culture, x.Name, x.Date));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,6 @@ namespace Umbraco.Web.Models.Mapping
|
||||
.ForMember(x => x.RedirectId, expression => expression.MapFrom(item => item.Key));
|
||||
}
|
||||
|
||||
private static string GetUrl(IUmbracoContextAccessor umbracoContextAccessor, IRedirectUrl item) => umbracoContextAccessor?.UmbracoContext?.UrlProvider?.GetUrl(item.ContentId, item.Culture);
|
||||
private static string GetUrl(IUmbracoContextAccessor umbracoContextAccessor, IRedirectUrl item) => umbracoContextAccessor?.UmbracoContext?.UrlProvider?.GetUrl(item.Id, item.Culture);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,10 @@ using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Web.Mvc
|
||||
{
|
||||
// unless we want to modify the content of the collection
|
||||
// which we are not doing at the moment
|
||||
// we can inherit from BuilderCollectionBase and just be enumerable
|
||||
|
||||
public class SurfaceControllerTypeCollection : BuilderCollectionBase<Type>
|
||||
{
|
||||
public SurfaceControllerTypeCollection(IEnumerable<Type> items)
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Web.WebApi;
|
||||
|
||||
namespace Umbraco.Web.Mvc
|
||||
{
|
||||
public class SurfaceControllerTypeCollectionBuilder : TypeCollectionBuilderBase<SurfaceControllerTypeCollection, SurfaceController>
|
||||
{ }
|
||||
}
|
||||
@@ -14,7 +14,6 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
|
||||
{
|
||||
Published = PrimitiveSerializer.Boolean.ReadFrom(stream),
|
||||
Name = PrimitiveSerializer.String.ReadFrom(stream),
|
||||
UrlSegment = PrimitiveSerializer.String.ReadFrom(stream),
|
||||
VersionId = PrimitiveSerializer.Int32.ReadFrom(stream),
|
||||
VersionDate = PrimitiveSerializer.DateTime.ReadFrom(stream),
|
||||
WriterId = PrimitiveSerializer.Int32.ReadFrom(stream),
|
||||
@@ -28,7 +27,6 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
|
||||
{
|
||||
PrimitiveSerializer.Boolean.WriteTo(value.Published, stream);
|
||||
PrimitiveSerializer.String.WriteTo(value.Name, stream);
|
||||
PrimitiveSerializer.String.WriteTo(value.UrlSegment, stream);
|
||||
PrimitiveSerializer.Int32.WriteTo(value.VersionId, stream);
|
||||
PrimitiveSerializer.DateTime.WriteTo(value.VersionDate, stream);
|
||||
PrimitiveSerializer.Int32.WriteTo(value.WriterId, stream);
|
||||
|
||||
+1
-2
@@ -18,7 +18,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
|
||||
for (var i = 0; i < pcount; i++)
|
||||
{
|
||||
var languageId = PrimitiveSerializer.String.ReadFrom(stream);
|
||||
var cultureVariation = new CultureVariation { Name = ReadStringObject(stream), UrlSegment = ReadStringObject(stream), Date = ReadDateTime(stream) };
|
||||
var cultureVariation = new CultureVariation { Name = ReadStringObject(stream), Date = ReadDateTime(stream) };
|
||||
dict[languageId] = cultureVariation;
|
||||
}
|
||||
return dict;
|
||||
@@ -40,7 +40,6 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
|
||||
|
||||
PrimitiveSerializer.String.WriteTo(culture, stream); // should never be null
|
||||
WriteObject(variation.Name, stream); // write an object in case it's null (though... should not happen)
|
||||
WriteObject(variation.UrlSegment, stream); // write an object in case it's null (though... should not happen)
|
||||
PrimitiveSerializer.DateTime.WriteTo(variation.Date, stream);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
|
||||
internal class ContentData
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string UrlSegment { get; set; }
|
||||
public int VersionId { get; set; }
|
||||
public DateTime VersionDate { get; set; }
|
||||
public int WriterId { get; set; }
|
||||
|
||||
@@ -16,8 +16,5 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
|
||||
[JsonProperty("cultureData")]
|
||||
[JsonConverter(typeof(CaseInsensitiveDictionaryConverter<CultureVariation>))]
|
||||
public Dictionary<string, CultureVariation> CultureData { get; set; }
|
||||
|
||||
[JsonProperty("urlSegment")]
|
||||
public string UrlSegment { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,9 +11,6 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
|
||||
[JsonProperty("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[JsonProperty("urlSegment")]
|
||||
public string UrlSegment { get; set; }
|
||||
|
||||
[JsonProperty("date")]
|
||||
public DateTime Date { get; set; }
|
||||
|
||||
|
||||
@@ -223,7 +223,6 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
|
||||
p = new ContentData
|
||||
{
|
||||
Name = dto.PubName,
|
||||
UrlSegment = nested.UrlSegment,
|
||||
Published = true,
|
||||
TemplateId = dto.PubTemplateId,
|
||||
VersionId = dto.VersionId,
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
_publishedSnapshotAccessor = publishedSnapshotAccessor ?? throw new ArgumentNullException(nameof(publishedSnapshotAccessor));
|
||||
VariationContextAccessor = variationContextAccessor ?? throw new ArgumentNullException(nameof(variationContextAccessor));
|
||||
|
||||
_urlSegment = ContentData.UrlSegment;
|
||||
_urlSegment = ContentData.Name.ToUrlSegment();
|
||||
IsPreviewing = ContentData.Published == false;
|
||||
|
||||
var properties = new List<IPublishedProperty>();
|
||||
@@ -276,9 +276,8 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
if (ContentData.CultureInfos == null)
|
||||
throw new Exception("oops: _contentDate.CultureInfos is null.");
|
||||
|
||||
return _cultureInfos = ContentData.CultureInfos
|
||||
.ToDictionary(x => x.Key, x => new PublishedCultureInfo(x.Key, x.Value.Name, x.Value.UrlSegment, x.Value.Date), StringComparer.OrdinalIgnoreCase);
|
||||
.ToDictionary(x => x.Key, x => new PublishedCultureInfo(x.Key, x.Value.Name, x.Value.Date), StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ using Umbraco.Core.Scoping;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Services.Changes;
|
||||
using Umbraco.Core.Services.Implement;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Web.Cache;
|
||||
using Umbraco.Web.Install;
|
||||
using Umbraco.Web.PublishedCache.NuCache.DataSource;
|
||||
@@ -47,7 +46,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
private readonly ISiteDomainHelper _siteDomainHelper;
|
||||
private readonly IEntityXmlSerializer _entitySerializer;
|
||||
private readonly IDefaultCultureAccessor _defaultCultureAccessor;
|
||||
private readonly UrlSegmentProviderCollection _urlSegmentProviders;
|
||||
private readonly IPublishedModelFactory _publishedModelFactory;
|
||||
|
||||
// volatile because we read it with no lock
|
||||
private volatile bool _isReady;
|
||||
@@ -90,8 +89,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository,
|
||||
IDefaultCultureAccessor defaultCultureAccessor,
|
||||
IDataSource dataSource, IGlobalSettings globalSettings, ISiteDomainHelper siteDomainHelper,
|
||||
IEntityXmlSerializer entitySerializer, IPublishedModelFactory publishedModelFactory,
|
||||
UrlSegmentProviderCollection urlSegmentProviders)
|
||||
IEntityXmlSerializer entitySerializer, IPublishedModelFactory publishedModelFactory)
|
||||
: base(publishedSnapshotAccessor, variationContextAccessor)
|
||||
{
|
||||
//if (Interlocked.Increment(ref _singletonCheck) > 1)
|
||||
@@ -109,7 +107,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
_defaultCultureAccessor = defaultCultureAccessor;
|
||||
_globalSettings = globalSettings;
|
||||
_siteDomainHelper = siteDomainHelper;
|
||||
_urlSegmentProviders = urlSegmentProviders;
|
||||
_publishedModelFactory = publishedModelFactory;
|
||||
|
||||
// we need an Xml serializer here so that the member cache can support XPath,
|
||||
// for members this is done by navigating the serialized-to-xml member
|
||||
@@ -169,7 +167,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
_domainStore = new SnapDictionary<int, Domain>();
|
||||
|
||||
publishedModelFactory.WithSafeLiveFactory(LoadCaches);
|
||||
_publishedModelFactory.WithSafeLiveFactory(LoadCaches);
|
||||
|
||||
Guid GetUid(ContentStore store, int id) => store.LiveSnapshot.Get(id)?.Uid ?? default;
|
||||
int GetId(ContentStore store, Guid uid) => store.LiveSnapshot.Get(uid)?.Id ?? default;
|
||||
@@ -1271,13 +1269,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
foreach (var cultureInfo in infos)
|
||||
{
|
||||
var cultureIsDraft = !published && content is IContent d && d.IsCultureEdited(cultureInfo.Culture);
|
||||
cultureData[cultureInfo.Culture] = new CultureVariation
|
||||
{
|
||||
Name = cultureInfo.Name,
|
||||
UrlSegment = content.GetUrlSegment(_urlSegmentProviders, cultureInfo.Culture),
|
||||
Date = content.GetUpdateDate(cultureInfo.Culture) ?? DateTime.MinValue,
|
||||
IsDraft = cultureIsDraft
|
||||
};
|
||||
cultureData[cultureInfo.Culture] = new CultureVariation { Name = cultureInfo.Name, Date = content.GetUpdateDate(cultureInfo.Culture) ?? DateTime.MinValue, IsDraft = cultureIsDraft };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1285,8 +1277,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
var nestedData = new ContentNestedData
|
||||
{
|
||||
PropertyData = propertyData,
|
||||
CultureData = cultureData,
|
||||
UrlSegment = content.GetUrlSegment(_urlSegmentProviders)
|
||||
CultureData = cultureData
|
||||
};
|
||||
|
||||
var dto = new ContentNuDto
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Web.Mvc;
|
||||
|
||||
namespace Umbraco.Web.Routing
|
||||
{
|
||||
/// <summary>
|
||||
/// This url provider is used purely to deal with umbraco custom routes that utilize <see cref="UmbracoVirtualNodeRouteHandler"/> and will return
|
||||
/// the URL returned from the current PublishedContentRequest.PublishedContent (virtual node) if the request is in fact a virtual route and
|
||||
/// the id that is being requested matches the id of the current PublishedContentRequest.PublishedContent.
|
||||
/// </summary>
|
||||
internal class CustomRouteUrlProvider : IUrlProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// This will return the URL that is returned by the assigned custom <see cref="IPublishedContent"/> if this is a custom route
|
||||
/// </summary>
|
||||
public UrlInfo GetUrl(UmbracoContext umbracoContext, IPublishedContent content, UrlProviderMode mode, string culture, Uri current)
|
||||
{
|
||||
if (umbracoContext?.PublishedRequest?.PublishedContent == null) return null;
|
||||
if (umbracoContext.HttpContext?.Request?.RequestContext?.RouteData?.DataTokens == null) return null;
|
||||
if (umbracoContext.HttpContext.Request.RequestContext.RouteData.DataTokens.ContainsKey(Core.Constants.Web.CustomRouteDataToken) == false) return null;
|
||||
|
||||
|
||||
//If we get this far, it means it's a custom route with published content assigned, check if the id being requested for is the same id as the assigned published content
|
||||
//NOTE: This looks like it might cause an infinite loop because PublishedContentBase.Url calls into UmbracoContext.Current.UrlProvider.GetUrl which calls back into the IUrlProvider pipeline
|
||||
// but the specific purpose of this is that a developer is using their own IPublishedContent that returns a specific Url and doesn't go back into the UrlProvider pipeline.
|
||||
// TODO: We could put a try/catch here just in case, else we could do some reflection checking to see if the implementation is PublishedContentBase and the Url property is not overridden.
|
||||
return UrlInfo.Url(
|
||||
content.Id == umbracoContext.PublishedRequest.PublishedContent.Id
|
||||
? umbracoContext.PublishedRequest.PublishedContent.GetUrl(culture)
|
||||
: null,
|
||||
culture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This always returns an empty result because this url provider is used purely to deal with Umbraco custom routes with
|
||||
/// UmbracoVirtualNodeRouteHandler, we really only care about the normal URL so that RedirectToCurrentUmbracoPage() works
|
||||
/// with SurfaceControllers
|
||||
/// </summary>
|
||||
/// <param name="umbracoContext"></param>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="current"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<UrlInfo> GetOtherUrls(UmbracoContext umbracoContext, int id, Uri current)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -594,29 +594,38 @@ namespace Umbraco.Web.Routing
|
||||
}
|
||||
else
|
||||
{
|
||||
// grab the current member
|
||||
var member = membershipHelper.GetCurrentMember();
|
||||
// if the member has the "approved" and/or "locked out" properties, make sure they're correctly set before allowing access
|
||||
var memberIsActive = true;
|
||||
if (member != null)
|
||||
if (membershipHelper.IsUmbracoMembershipProviderActive())
|
||||
{
|
||||
if (member.HasProperty(Constants.Conventions.Member.IsApproved) == false)
|
||||
memberIsActive = member.Value<bool>(Constants.Conventions.Member.IsApproved);
|
||||
// grab the current member
|
||||
var member = membershipHelper.GetCurrentMember();
|
||||
// if the member has the "approved" and/or "locked out" properties, make sure they're correctly set before allowing access
|
||||
var memberIsActive = true;
|
||||
if (member != null)
|
||||
{
|
||||
if (member.HasProperty(Constants.Conventions.Member.IsApproved) == false)
|
||||
memberIsActive = member.Value<bool>(Constants.Conventions.Member.IsApproved);
|
||||
|
||||
if (member.HasProperty(Constants.Conventions.Member.IsLockedOut) == false)
|
||||
memberIsActive = member.Value<bool>(Constants.Conventions.Member.IsLockedOut) == false;
|
||||
}
|
||||
if (member.HasProperty(Constants.Conventions.Member.IsLockedOut) == false)
|
||||
memberIsActive = member.Value<bool>(Constants.Conventions.Member.IsLockedOut) == false;
|
||||
}
|
||||
|
||||
if (memberIsActive == false)
|
||||
{
|
||||
_logger.Debug<PublishedRouter>("Current member is either unapproved or locked out, redirect to error page");
|
||||
var errorPageId = publicAccessAttempt.Result.NoAccessNodeId;
|
||||
if (errorPageId != request.PublishedContent.Id)
|
||||
request.PublishedContent = request.UmbracoContext.PublishedSnapshot.Content.GetById(errorPageId);
|
||||
if (memberIsActive == false)
|
||||
{
|
||||
_logger.Debug<PublishedRouter>(
|
||||
"Current member is either unapproved or locked out, redirect to error page");
|
||||
var errorPageId = publicAccessAttempt.Result.NoAccessNodeId;
|
||||
if (errorPageId != request.PublishedContent.Id)
|
||||
request.PublishedContent =
|
||||
request.UmbracoContext.PublishedSnapshot.Content.GetById(errorPageId);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Debug<PublishedRouter>("Current member has access");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Debug<PublishedRouter>("Current member has access");
|
||||
_logger.Debug<PublishedRouter>("Current custom MembershipProvider member has access");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -666,6 +675,9 @@ namespace Umbraco.Web.Routing
|
||||
// TODO: When we remove the need for a database for templates, then this id should be irrelevant,
|
||||
// not sure how were going to do this nicely.
|
||||
|
||||
// TODO: We need to limit altTemplate to only allow templates that are assigned to the current document type!
|
||||
// if the template isn't assigned to the document type we should log a warning and return 404
|
||||
|
||||
var templateId = request.PublishedContent.TemplateId;
|
||||
request.TemplateModel = GetTemplateModel(templateId);
|
||||
}
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Web.Http;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Web.Install;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi;
|
||||
|
||||
namespace Umbraco.Web.Runtime
|
||||
{
|
||||
public class WebFinalComponent : IComponent
|
||||
{
|
||||
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
|
||||
private readonly SurfaceControllerTypeCollection _surfaceControllerTypes;
|
||||
private readonly UmbracoApiControllerTypeCollection _apiControllerTypes;
|
||||
private readonly IGlobalSettings _globalSettings;
|
||||
|
||||
public WebFinalComponent(IUmbracoContextAccessor umbracoContextAccessor, SurfaceControllerTypeCollection surfaceControllerTypes, UmbracoApiControllerTypeCollection apiControllerTypes, IGlobalSettings globalSettings)
|
||||
{
|
||||
_umbracoContextAccessor = umbracoContextAccessor;
|
||||
_surfaceControllerTypes = surfaceControllerTypes;
|
||||
_apiControllerTypes = apiControllerTypes;
|
||||
_globalSettings = globalSettings;
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
// set routes
|
||||
CreateRoutes(_umbracoContextAccessor, _globalSettings, _surfaceControllerTypes, _apiControllerTypes);
|
||||
|
||||
// ensure WebAPI is initialized, after everything
|
||||
GlobalConfiguration.Configuration.EnsureInitialized();
|
||||
}
|
||||
|
||||
public void Terminate()
|
||||
{ }
|
||||
|
||||
// internal for tests
|
||||
internal static void CreateRoutes(
|
||||
IUmbracoContextAccessor umbracoContextAccessor,
|
||||
IGlobalSettings globalSettings,
|
||||
SurfaceControllerTypeCollection surfaceControllerTypes,
|
||||
UmbracoApiControllerTypeCollection apiControllerTypes)
|
||||
{
|
||||
var umbracoPath = globalSettings.GetUmbracoMvcArea();
|
||||
|
||||
// create the front-end route
|
||||
var defaultRoute = RouteTable.Routes.MapRoute(
|
||||
"Umbraco_default",
|
||||
umbracoPath + "/RenderMvc/{action}/{id}",
|
||||
new { controller = "RenderMvc", action = "Index", id = UrlParameter.Optional }
|
||||
);
|
||||
defaultRoute.RouteHandler = new RenderRouteHandler(umbracoContextAccessor, ControllerBuilder.Current.GetControllerFactory());
|
||||
|
||||
// register install routes
|
||||
RouteTable.Routes.RegisterArea<UmbracoInstallArea>();
|
||||
|
||||
// register all back office routes
|
||||
RouteTable.Routes.RegisterArea(new BackOfficeArea(globalSettings));
|
||||
|
||||
// plugin controllers must come first because the next route will catch many things
|
||||
RoutePluginControllers(globalSettings, surfaceControllerTypes, apiControllerTypes);
|
||||
}
|
||||
|
||||
private static void RoutePluginControllers(
|
||||
IGlobalSettings globalSettings,
|
||||
SurfaceControllerTypeCollection surfaceControllerTypes,
|
||||
UmbracoApiControllerTypeCollection apiControllerTypes)
|
||||
{
|
||||
var umbracoPath = globalSettings.GetUmbracoMvcArea();
|
||||
|
||||
// need to find the plugin controllers and route them
|
||||
var pluginControllers = surfaceControllerTypes.Concat(apiControllerTypes).ToArray();
|
||||
|
||||
// local controllers do not contain the attribute
|
||||
var localControllers = pluginControllers.Where(x => PluginController.GetMetadata(x).AreaName.IsNullOrWhiteSpace());
|
||||
foreach (var s in localControllers)
|
||||
{
|
||||
if (TypeHelper.IsTypeAssignableFrom<SurfaceController>(s))
|
||||
RouteLocalSurfaceController(s, umbracoPath);
|
||||
else if (TypeHelper.IsTypeAssignableFrom<UmbracoApiController>(s))
|
||||
RouteLocalApiController(s, umbracoPath);
|
||||
}
|
||||
|
||||
// get the plugin controllers that are unique to each area (group by)
|
||||
var pluginSurfaceControlleres = pluginControllers.Where(x => PluginController.GetMetadata(x).AreaName.IsNullOrWhiteSpace() == false);
|
||||
var groupedAreas = pluginSurfaceControlleres.GroupBy(controller => PluginController.GetMetadata(controller).AreaName);
|
||||
// loop through each area defined amongst the controllers
|
||||
foreach (var g in groupedAreas)
|
||||
{
|
||||
// create & register an area for the controllers (this will throw an exception if all controllers are not in the same area)
|
||||
var pluginControllerArea = new PluginControllerArea(globalSettings, g.Select(PluginController.GetMetadata));
|
||||
RouteTable.Routes.RegisterArea(pluginControllerArea);
|
||||
}
|
||||
}
|
||||
|
||||
private static void RouteLocalApiController(Type controller, string umbracoPath)
|
||||
{
|
||||
var meta = PluginController.GetMetadata(controller);
|
||||
var url = umbracoPath + (meta.IsBackOffice ? "/BackOffice" : "") + "/Api/" + meta.ControllerName + "/{action}/{id}";
|
||||
var route = RouteTable.Routes.MapHttpRoute(
|
||||
$"umbraco-api-{meta.ControllerName}",
|
||||
url, // url to match
|
||||
new { controller = meta.ControllerName, id = UrlParameter.Optional },
|
||||
new[] { meta.ControllerNamespace });
|
||||
if (route.DataTokens == null) // web api routes don't set the data tokens object
|
||||
route.DataTokens = new RouteValueDictionary();
|
||||
route.DataTokens.Add(Core.Constants.Web.UmbracoDataToken, "api"); //ensure the umbraco token is set
|
||||
}
|
||||
|
||||
private static void RouteLocalSurfaceController(Type controller, string umbracoPath)
|
||||
{
|
||||
var meta = PluginController.GetMetadata(controller);
|
||||
var url = umbracoPath + "/Surface/" + meta.ControllerName + "/{action}/{id}";
|
||||
var route = RouteTable.Routes.MapRoute(
|
||||
$"umbraco-surface-{meta.ControllerName}",
|
||||
url, // url to match
|
||||
new { controller = meta.ControllerName, action = "Index", id = UrlParameter.Optional },
|
||||
new[] { meta.ControllerNamespace }); // look in this namespace to create the controller
|
||||
route.DataTokens.Add(Core.Constants.Web.UmbracoDataToken, "surface"); // ensure the umbraco token is set
|
||||
route.DataTokens.Add("UseNamespaceFallback", false); // don't look anywhere else except this namespace!
|
||||
// make it use our custom/special SurfaceMvcHandler
|
||||
route.RouteHandler = new SurfaceRouteHandler();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Web.Runtime
|
||||
{
|
||||
// web's final composer composes after all user composers
|
||||
[ComposeAfter(typeof(IUserComposer))]
|
||||
public class WebFinalComposer : ComponentComposer<WebFinalComponent>
|
||||
{ }
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Configuration;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Web.Configuration;
|
||||
using System.Web.Http;
|
||||
using System.Web.Http.Dispatcher;
|
||||
using System.Web.Mvc;
|
||||
using ClientDependency.Core.CompositeFiles.Providers;
|
||||
using ClientDependency.Core.Config;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Web.JavaScript;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi;
|
||||
|
||||
using Current = Umbraco.Web.Composing.Current;
|
||||
|
||||
namespace Umbraco.Web.Runtime
|
||||
{
|
||||
public sealed class WebInitialComponent : IComponent
|
||||
{
|
||||
private readonly IGlobalSettings _globalSettings;
|
||||
|
||||
public WebInitialComponent(IGlobalSettings globalSettings)
|
||||
{
|
||||
_globalSettings = globalSettings;
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
// setup mvc and webapi services
|
||||
SetupMvcAndWebApi();
|
||||
|
||||
// When using a non-web runtime and this component is loaded ClientDependency explodes because it'll
|
||||
// want to access HttpContext.Current, which doesn't exist
|
||||
if (IOHelper.IsHosted)
|
||||
{
|
||||
ConfigureClientDependency(_globalSettings);
|
||||
}
|
||||
|
||||
// Disable the X-AspNetMvc-Version HTTP Header
|
||||
MvcHandler.DisableMvcResponseHeader = true;
|
||||
|
||||
// wrap view engines in the profiling engine
|
||||
WrapViewEngines(ViewEngines.Engines);
|
||||
|
||||
// add global filters
|
||||
ConfigureGlobalFilters();
|
||||
}
|
||||
|
||||
public void Terminate()
|
||||
{ }
|
||||
|
||||
private static void ConfigureGlobalFilters()
|
||||
{
|
||||
GlobalFilters.Filters.Add(new EnsurePartialViewMacroViewContextFilterAttribute());
|
||||
}
|
||||
|
||||
// internal for tests
|
||||
internal static void WrapViewEngines(IList<IViewEngine> viewEngines)
|
||||
{
|
||||
if (viewEngines == null || viewEngines.Count == 0) return;
|
||||
|
||||
var originalEngines = viewEngines.ToList();
|
||||
viewEngines.Clear();
|
||||
foreach (var engine in originalEngines)
|
||||
{
|
||||
var wrappedEngine = engine is ProfilingViewEngine ? engine : new ProfilingViewEngine(engine);
|
||||
viewEngines.Add(wrappedEngine);
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetupMvcAndWebApi()
|
||||
{
|
||||
//don't output the MVC version header (security)
|
||||
MvcHandler.DisableMvcResponseHeader = true;
|
||||
|
||||
// set master controller factory
|
||||
var controllerFactory = new MasterControllerFactory(() => Current.FilteredControllerFactories);
|
||||
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
|
||||
|
||||
// set the render & plugin view engines
|
||||
ViewEngines.Engines.Add(new RenderViewEngine());
|
||||
ViewEngines.Engines.Add(new PluginViewEngine());
|
||||
|
||||
//set model binder
|
||||
ModelBinderProviders.BinderProviders.Add(ContentModelBinder.Instance); // is a provider
|
||||
|
||||
////add the profiling action filter
|
||||
//GlobalFilters.Filters.Add(new ProfilingActionFilter());
|
||||
|
||||
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector),
|
||||
new NamespaceHttpControllerSelector(GlobalConfiguration.Configuration));
|
||||
}
|
||||
|
||||
private static void ConfigureClientDependency(IGlobalSettings globalSettings)
|
||||
{
|
||||
// Backwards compatibility - set the path and URL type for ClientDependency 1.5.1 [LK]
|
||||
XmlFileMapper.FileMapDefaultFolder = SystemDirectories.TempData.EnsureEndsWith('/') + "ClientDependency";
|
||||
BaseCompositeFileProcessingProvider.UrlTypeDefault = CompositeUrlType.Base64QueryStrings;
|
||||
|
||||
// Now we need to detect if we are running 'Umbraco.Core.LocalTempStorage' as EnvironmentTemp and in that case we want to change the CDF file
|
||||
// location to be there
|
||||
if (globalSettings.LocalTempStorageLocation == LocalTempStorage.EnvironmentTemp)
|
||||
{
|
||||
var cachePath = globalSettings.LocalTempPath;
|
||||
|
||||
//set the file map and composite file default location to the %temp% location
|
||||
BaseCompositeFileProcessingProvider.CompositeFilePathDefaultFolder
|
||||
= XmlFileMapper.FileMapDefaultFolder
|
||||
= Path.Combine(cachePath, "ClientDependency");
|
||||
}
|
||||
|
||||
if (ConfigurationManager.GetSection("system.web/httpRuntime") is HttpRuntimeSection section)
|
||||
{
|
||||
//set the max url length for CDF to be the smallest of the max query length, max request length
|
||||
ClientDependency.Core.CompositeFiles.CompositeDependencyHandler.MaxHandlerUrlLength = Math.Min(section.MaxQueryStringLength, section.MaxRequestLength);
|
||||
}
|
||||
|
||||
//Register a custom renderer - used to process property editor dependencies
|
||||
var renderer = new DependencyPathRenderer();
|
||||
renderer.Initialize("Umbraco.DependencyPathRenderer", new NameValueCollection
|
||||
{
|
||||
{ "compositeFileHandlerPath", ClientDependencySettings.Instance.CompositeFileHandlerPath }
|
||||
});
|
||||
|
||||
ClientDependencySettings.Instance.MvcRendererCollection.Add(renderer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,265 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Configuration;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Configuration;
|
||||
using System.Web.Http;
|
||||
using System.Web.Http.Dispatcher;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using ClientDependency.Core.CompositeFiles.Providers;
|
||||
using ClientDependency.Core.Config;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Install;
|
||||
using Umbraco.Web.JavaScript;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
using Umbraco.Web.Routing;
|
||||
using Umbraco.Web.Security;
|
||||
using Umbraco.Web.Trees;
|
||||
using Umbraco.Web.WebApi;
|
||||
|
||||
using Current = Umbraco.Web.Composing.Current;
|
||||
|
||||
namespace Umbraco.Web.Runtime
|
||||
{
|
||||
public sealed class WebRuntimeComponent : IComponent
|
||||
{
|
||||
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
|
||||
private readonly SurfaceControllerTypeCollection _surfaceControllerTypes;
|
||||
private readonly UmbracoApiControllerTypeCollection _apiControllerTypes;
|
||||
private readonly IPublishedSnapshotService _publishedSnapshotService;
|
||||
private readonly IUserService _userService;
|
||||
private readonly IUmbracoSettingsSection _umbracoSettings;
|
||||
private readonly IGlobalSettings _globalSettings;
|
||||
private readonly IVariationContextAccessor _variationContextAccessor;
|
||||
private readonly UrlProviderCollection _urlProviders;
|
||||
|
||||
public WebRuntimeComponent(
|
||||
IUmbracoContextAccessor umbracoContextAccessor,
|
||||
SurfaceControllerTypeCollection surfaceControllerTypes,
|
||||
UmbracoApiControllerTypeCollection apiControllerTypes,
|
||||
IPublishedSnapshotService publishedSnapshotService,
|
||||
IUserService userService,
|
||||
IUmbracoSettingsSection umbracoSettings,
|
||||
IGlobalSettings globalSettings,
|
||||
IVariationContextAccessor variationContextAccessor,
|
||||
UrlProviderCollection urlProviders)
|
||||
{
|
||||
_umbracoContextAccessor = umbracoContextAccessor;
|
||||
_surfaceControllerTypes = surfaceControllerTypes;
|
||||
_apiControllerTypes = apiControllerTypes;
|
||||
_publishedSnapshotService = publishedSnapshotService;
|
||||
_userService = userService;
|
||||
_umbracoSettings = umbracoSettings;
|
||||
_globalSettings = globalSettings;
|
||||
_variationContextAccessor = variationContextAccessor;
|
||||
_urlProviders = urlProviders;
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
// setup mvc and webapi services
|
||||
SetupMvcAndWebApi();
|
||||
|
||||
// When using a non-web runtime and this component is loaded ClientDependency explodes because it'll
|
||||
// want to access HttpContext.Current, which doesn't exist
|
||||
if (IOHelper.IsHosted)
|
||||
{
|
||||
ConfigureClientDependency(_globalSettings);
|
||||
}
|
||||
|
||||
// Disable the X-AspNetMvc-Version HTTP Header
|
||||
MvcHandler.DisableMvcResponseHeader = true;
|
||||
|
||||
// wrap view engines in the profiling engine
|
||||
WrapViewEngines(ViewEngines.Engines);
|
||||
|
||||
// add global filters
|
||||
ConfigureGlobalFilters();
|
||||
|
||||
// set routes
|
||||
CreateRoutes(_umbracoContextAccessor, _globalSettings, _surfaceControllerTypes, _apiControllerTypes);
|
||||
|
||||
// ensure WebAPI is initialized, after everything
|
||||
GlobalConfiguration.Configuration.EnsureInitialized();
|
||||
}
|
||||
|
||||
public void Terminate()
|
||||
{ }
|
||||
|
||||
private static void ConfigureGlobalFilters()
|
||||
{
|
||||
GlobalFilters.Filters.Add(new EnsurePartialViewMacroViewContextFilterAttribute());
|
||||
}
|
||||
|
||||
// internal for tests
|
||||
internal static void WrapViewEngines(IList<IViewEngine> viewEngines)
|
||||
{
|
||||
if (viewEngines == null || viewEngines.Count == 0) return;
|
||||
|
||||
var originalEngines = viewEngines.ToList();
|
||||
viewEngines.Clear();
|
||||
foreach (var engine in originalEngines)
|
||||
{
|
||||
var wrappedEngine = engine is ProfilingViewEngine ? engine : new ProfilingViewEngine(engine);
|
||||
viewEngines.Add(wrappedEngine);
|
||||
}
|
||||
}
|
||||
|
||||
// internal for tests
|
||||
internal static void CreateRoutes(
|
||||
IUmbracoContextAccessor umbracoContextAccessor,
|
||||
IGlobalSettings globalSettings,
|
||||
SurfaceControllerTypeCollection surfaceControllerTypes,
|
||||
UmbracoApiControllerTypeCollection apiControllerTypes)
|
||||
{
|
||||
var umbracoPath = globalSettings.GetUmbracoMvcArea();
|
||||
|
||||
// create the front-end route
|
||||
var defaultRoute = RouteTable.Routes.MapRoute(
|
||||
"Umbraco_default",
|
||||
umbracoPath + "/RenderMvc/{action}/{id}",
|
||||
new { controller = "RenderMvc", action = "Index", id = UrlParameter.Optional }
|
||||
);
|
||||
defaultRoute.RouteHandler = new RenderRouteHandler(umbracoContextAccessor, ControllerBuilder.Current.GetControllerFactory());
|
||||
|
||||
// register install routes
|
||||
RouteTable.Routes.RegisterArea<UmbracoInstallArea>();
|
||||
|
||||
// register all back office routes
|
||||
RouteTable.Routes.RegisterArea(new BackOfficeArea(globalSettings));
|
||||
|
||||
// plugin controllers must come first because the next route will catch many things
|
||||
RoutePluginControllers(globalSettings, surfaceControllerTypes, apiControllerTypes);
|
||||
}
|
||||
|
||||
private static void RoutePluginControllers(
|
||||
IGlobalSettings globalSettings,
|
||||
SurfaceControllerTypeCollection surfaceControllerTypes,
|
||||
UmbracoApiControllerTypeCollection apiControllerTypes)
|
||||
{
|
||||
var umbracoPath = globalSettings.GetUmbracoMvcArea();
|
||||
|
||||
// need to find the plugin controllers and route them
|
||||
var pluginControllers = surfaceControllerTypes.Concat(apiControllerTypes).ToArray();
|
||||
|
||||
// local controllers do not contain the attribute
|
||||
var localControllers = pluginControllers.Where(x => PluginController.GetMetadata(x).AreaName.IsNullOrWhiteSpace());
|
||||
foreach (var s in localControllers)
|
||||
{
|
||||
if (TypeHelper.IsTypeAssignableFrom<SurfaceController>(s))
|
||||
RouteLocalSurfaceController(s, umbracoPath);
|
||||
else if (TypeHelper.IsTypeAssignableFrom<UmbracoApiController>(s))
|
||||
RouteLocalApiController(s, umbracoPath);
|
||||
}
|
||||
|
||||
// get the plugin controllers that are unique to each area (group by)
|
||||
var pluginSurfaceControlleres = pluginControllers.Where(x => PluginController.GetMetadata(x).AreaName.IsNullOrWhiteSpace() == false);
|
||||
var groupedAreas = pluginSurfaceControlleres.GroupBy(controller => PluginController.GetMetadata(controller).AreaName);
|
||||
// loop through each area defined amongst the controllers
|
||||
foreach (var g in groupedAreas)
|
||||
{
|
||||
// create & register an area for the controllers (this will throw an exception if all controllers are not in the same area)
|
||||
var pluginControllerArea = new PluginControllerArea(globalSettings, g.Select(PluginController.GetMetadata));
|
||||
RouteTable.Routes.RegisterArea(pluginControllerArea);
|
||||
}
|
||||
}
|
||||
|
||||
private static void RouteLocalApiController(Type controller, string umbracoPath)
|
||||
{
|
||||
var meta = PluginController.GetMetadata(controller);
|
||||
var url = umbracoPath + (meta.IsBackOffice ? "/BackOffice" : "") + "/Api/" + meta.ControllerName + "/{action}/{id}";
|
||||
var route = RouteTable.Routes.MapHttpRoute(
|
||||
$"umbraco-api-{meta.ControllerName}",
|
||||
url, // url to match
|
||||
new { controller = meta.ControllerName, id = UrlParameter.Optional },
|
||||
new[] { meta.ControllerNamespace });
|
||||
if (route.DataTokens == null) // web api routes don't set the data tokens object
|
||||
route.DataTokens = new RouteValueDictionary();
|
||||
route.DataTokens.Add(Core.Constants.Web.UmbracoDataToken, "api"); //ensure the umbraco token is set
|
||||
}
|
||||
|
||||
private static void RouteLocalSurfaceController(Type controller, string umbracoPath)
|
||||
{
|
||||
var meta = PluginController.GetMetadata(controller);
|
||||
var url = umbracoPath + "/Surface/" + meta.ControllerName + "/{action}/{id}";
|
||||
var route = RouteTable.Routes.MapRoute(
|
||||
$"umbraco-surface-{meta.ControllerName}",
|
||||
url, // url to match
|
||||
new { controller = meta.ControllerName, action = "Index", id = UrlParameter.Optional },
|
||||
new[] { meta.ControllerNamespace }); // look in this namespace to create the controller
|
||||
route.DataTokens.Add(Core.Constants.Web.UmbracoDataToken, "surface"); // ensure the umbraco token is set
|
||||
route.DataTokens.Add("UseNamespaceFallback", false); // don't look anywhere else except this namespace!
|
||||
// make it use our custom/special SurfaceMvcHandler
|
||||
route.RouteHandler = new SurfaceRouteHandler();
|
||||
}
|
||||
|
||||
private static void SetupMvcAndWebApi()
|
||||
{
|
||||
//don't output the MVC version header (security)
|
||||
MvcHandler.DisableMvcResponseHeader = true;
|
||||
|
||||
// set master controller factory
|
||||
var controllerFactory = new MasterControllerFactory(() => Current.FilteredControllerFactories);
|
||||
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
|
||||
|
||||
// set the render & plugin view engines
|
||||
ViewEngines.Engines.Add(new RenderViewEngine());
|
||||
ViewEngines.Engines.Add(new PluginViewEngine());
|
||||
|
||||
//set model binder
|
||||
ModelBinderProviders.BinderProviders.Add(ContentModelBinder.Instance); // is a provider
|
||||
|
||||
////add the profiling action filter
|
||||
//GlobalFilters.Filters.Add(new ProfilingActionFilter());
|
||||
|
||||
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector),
|
||||
new NamespaceHttpControllerSelector(GlobalConfiguration.Configuration));
|
||||
}
|
||||
|
||||
private static void ConfigureClientDependency(IGlobalSettings globalSettings)
|
||||
{
|
||||
// Backwards compatibility - set the path and URL type for ClientDependency 1.5.1 [LK]
|
||||
XmlFileMapper.FileMapDefaultFolder = SystemDirectories.TempData.EnsureEndsWith('/') + "ClientDependency";
|
||||
BaseCompositeFileProcessingProvider.UrlTypeDefault = CompositeUrlType.Base64QueryStrings;
|
||||
|
||||
// Now we need to detect if we are running 'Umbraco.Core.LocalTempStorage' as EnvironmentTemp and in that case we want to change the CDF file
|
||||
// location to be there
|
||||
if (globalSettings.LocalTempStorageLocation == LocalTempStorage.EnvironmentTemp)
|
||||
{
|
||||
var cachePath = globalSettings.LocalTempPath;
|
||||
|
||||
//set the file map and composite file default location to the %temp% location
|
||||
BaseCompositeFileProcessingProvider.CompositeFilePathDefaultFolder
|
||||
= XmlFileMapper.FileMapDefaultFolder
|
||||
= Path.Combine(cachePath, "ClientDependency");
|
||||
}
|
||||
|
||||
if (ConfigurationManager.GetSection("system.web/httpRuntime") is HttpRuntimeSection section)
|
||||
{
|
||||
//set the max url length for CDF to be the smallest of the max query length, max request length
|
||||
ClientDependency.Core.CompositeFiles.CompositeDependencyHandler.MaxHandlerUrlLength = Math.Min(section.MaxQueryStringLength, section.MaxRequestLength);
|
||||
}
|
||||
|
||||
//Register a custom renderer - used to process property editor dependencies
|
||||
var renderer = new DependencyPathRenderer();
|
||||
renderer.Initialize("Umbraco.DependencyPathRenderer", new NameValueCollection
|
||||
{
|
||||
{ "compositeFileHandlerPath", ClientDependencySettings.Instance.CompositeFileHandlerPath }
|
||||
});
|
||||
|
||||
ClientDependencySettings.Instance.MvcRendererCollection.Add(renderer);
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
-10
@@ -44,10 +44,8 @@ using Current = Umbraco.Web.Composing.Current;
|
||||
|
||||
namespace Umbraco.Web.Runtime
|
||||
{
|
||||
// web's initial composer composes after core's, and before all core composers
|
||||
[ComposeAfter(typeof(CoreInitialComposer))]
|
||||
[ComposeBefore(typeof(ICoreComposer))]
|
||||
public sealed class WebInitialComposer : ComponentComposer<WebInitialComponent>
|
||||
[ComposeAfter(typeof(CoreRuntimeComposer))]
|
||||
public sealed class WebRuntimeComposer : ComponentComposer<WebRuntimeComponent>, IRuntimeComposer
|
||||
{
|
||||
public override void Compose(Composition composition)
|
||||
{
|
||||
@@ -158,11 +156,12 @@ namespace Umbraco.Web.Runtime
|
||||
.Add(() => composition.TypeLoader.GetTypes<IAction>());
|
||||
|
||||
//we need to eagerly scan controller types since they will need to be routed
|
||||
composition.WithCollectionBuilder<SurfaceControllerTypeCollectionBuilder>()
|
||||
.Add(composition.TypeLoader.GetSurfaceControllers());
|
||||
var umbracoApiControllerTypes = composition.TypeLoader.GetUmbracoApiControllers().ToList();
|
||||
composition.WithCollectionBuilder<UmbracoApiControllerTypeCollectionBuilder>()
|
||||
.Add(umbracoApiControllerTypes);
|
||||
var surfaceControllerTypes = new SurfaceControllerTypeCollection(composition.TypeLoader.GetSurfaceControllers());
|
||||
composition.RegisterUnique(surfaceControllerTypes);
|
||||
|
||||
//we need to eagerly scan controller types since they will need to be routed
|
||||
var umbracoApiControllerTypes = new UmbracoApiControllerTypeCollection(composition.TypeLoader.GetUmbracoApiControllers());
|
||||
composition.RegisterUnique(umbracoApiControllerTypes);
|
||||
|
||||
// both TinyMceValueConverter (in Core) and RteMacroRenderingValueConverter (in Web) will be
|
||||
// discovered when CoreBootManager configures the converters. We HAVE to remove one of them
|
||||
@@ -181,7 +180,8 @@ namespace Umbraco.Web.Runtime
|
||||
|
||||
composition.WithCollectionBuilder<UrlProviderCollectionBuilder>()
|
||||
.Append<AliasUrlProvider>()
|
||||
.Append<DefaultUrlProvider>();
|
||||
.Append<DefaultUrlProvider>()
|
||||
.Append<CustomRouteUrlProvider>();
|
||||
|
||||
composition.RegisterUnique<IContentLastChanceFinder, ContentFinderByConfigured404>();
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
<PackageReference Include="AutoMapper" Version="8.0.0" />
|
||||
<PackageReference Include="ClientDependency" Version="1.9.7" />
|
||||
<PackageReference Include="CSharpTest.Net.Collections" Version="14.906.1403.1082" />
|
||||
<PackageReference Include="Examine" Version="1.0.0" />
|
||||
<PackageReference Include="Examine" Version="1.0.1" />
|
||||
<PackageReference Include="HtmlAgilityPack" Version="1.8.14" />
|
||||
<PackageReference Include="ImageProcessor">
|
||||
<Version>2.7.0.100</Version>
|
||||
@@ -204,7 +204,6 @@
|
||||
<Compile Include="Models\ContentEditing\MacroParameterDisplay.cs" />
|
||||
<Compile Include="Models\PublishedContent\HybridVariationContextAccessor.cs" />
|
||||
<Compile Include="Models\TemplateQuery\QueryConditionExtensions.cs" />
|
||||
<Compile Include="Mvc\SurfaceControllerTypeCollectionBuilder.cs" />
|
||||
<Compile Include="Routing\IPublishedRouter.cs" />
|
||||
<Compile Include="Services\DashboardService.cs" />
|
||||
<Compile Include="Services\IDashboardService.cs" />
|
||||
@@ -254,7 +253,7 @@
|
||||
<Compile Include="PropertyEditors\PropertyEditorsComposer.cs" />
|
||||
<Compile Include="PublishedCache\NuCache\NuCacheComposer.cs" />
|
||||
<Compile Include="Routing\RedirectTrackingComposer.cs" />
|
||||
<Compile Include="Runtime\WebInitialComposer.cs" />
|
||||
<Compile Include="Runtime\WebRuntimeComposer.cs" />
|
||||
<Compile Include="Scheduling\SchedulerComposer.cs" />
|
||||
<Compile Include="Search\ExamineComposer.cs" />
|
||||
<Compile Include="Search\GenericIndexDiagnostics.cs" />
|
||||
@@ -604,10 +603,9 @@
|
||||
<Compile Include="Editors\Filters\MemberSaveValidationAttribute.cs" />
|
||||
<Compile Include="WebApi\SessionHttpControllerRouteHandler.cs" />
|
||||
<Compile Include="WebApi\UmbracoApiControllerTypeCollection.cs" />
|
||||
<Compile Include="WebApi\UmbracoApiControllerTypeCollectionBuilder.cs" />
|
||||
<Compile Include="WebApi\UnhandedExceptionLoggerConfigurationAttribute.cs" />
|
||||
<Compile Include="WebApi\UnhandledExceptionLogger.cs" />
|
||||
<Compile Include="Runtime\WebInitialComponent.cs" />
|
||||
<Compile Include="Runtime\WebRuntimeComponent.cs" />
|
||||
<Compile Include="Editors\PublishedStatusController.cs" />
|
||||
<Compile Include="Editors\NuCacheStatusController.cs" />
|
||||
<Compile Include="Actions\ActionAssignDomain.cs" />
|
||||
@@ -877,6 +875,7 @@
|
||||
<Compile Include="PublishedContentQuery.cs" />
|
||||
<Compile Include="ImageCropperTemplateExtensions.cs" />
|
||||
<Compile Include="Mvc\UmbracoVirtualNodeRouteHandler.cs" />
|
||||
<Compile Include="Routing\CustomRouteUrlProvider.cs" />
|
||||
<Compile Include="Routing\UrlProviderExtensions.cs" />
|
||||
<Compile Include="Scheduling\BackgroundTaskRunnerOptions.cs" />
|
||||
<Compile Include="Scheduling\IBackgroundTaskRunner.cs" />
|
||||
@@ -1187,8 +1186,6 @@
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="WebViewPageExtensions.cs" />
|
||||
<Compile Include="Runtime\WebFinalComponent.cs" />
|
||||
<Compile Include="Runtime\WebFinalComposer.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="JavaScript\Resources.resx">
|
||||
|
||||
@@ -28,13 +28,13 @@ namespace Umbraco.Web
|
||||
|
||||
private readonly IUmbracoSettingsSection _umbracoSettings;
|
||||
private readonly IGlobalSettings _globalSettings;
|
||||
private readonly UrlProviderCollection _urlProviders;
|
||||
private readonly IEnumerable<IUrlProvider> _urlProviders;
|
||||
private readonly IUserService _userService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UmbracoContextFactory"/> class.
|
||||
/// </summary>
|
||||
public UmbracoContextFactory(IUmbracoContextAccessor umbracoContextAccessor, IPublishedSnapshotService publishedSnapshotService, IVariationContextAccessor variationContextAccessor, IDefaultCultureAccessor defaultCultureAccessor, IUmbracoSettingsSection umbracoSettings, IGlobalSettings globalSettings, UrlProviderCollection urlProviders, IUserService userService)
|
||||
public UmbracoContextFactory(IUmbracoContextAccessor umbracoContextAccessor, IPublishedSnapshotService publishedSnapshotService, IVariationContextAccessor variationContextAccessor, IDefaultCultureAccessor defaultCultureAccessor, IUmbracoSettingsSection umbracoSettings, IGlobalSettings globalSettings, IEnumerable<IUrlProvider> urlProviders, IUserService userService)
|
||||
{
|
||||
_umbracoContextAccessor = umbracoContextAccessor ?? throw new ArgumentNullException(nameof(umbracoContextAccessor));
|
||||
_publishedSnapshotService = publishedSnapshotService ?? throw new ArgumentNullException(nameof(publishedSnapshotService));
|
||||
@@ -65,7 +65,7 @@ namespace Umbraco.Web
|
||||
if (currentUmbracoContext != null)
|
||||
return new UmbracoContextReference(currentUmbracoContext, false, _umbracoContextAccessor);
|
||||
|
||||
|
||||
|
||||
httpContext = httpContext ?? new HttpContextWrapper(HttpContext.Current ?? new HttpContext(new SimpleWorkerRequest("null.aspx", "", NullWriterInstance)));
|
||||
|
||||
var umbracoContext = CreateUmbracoContext(httpContext);
|
||||
|
||||
@@ -5,11 +5,9 @@ using System.Web;
|
||||
using System.Xml.XPath;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Dictionary;
|
||||
using Umbraco.Core.Exceptions;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Xml;
|
||||
using Umbraco.Web.Routing;
|
||||
using Umbraco.Web.Security;
|
||||
|
||||
namespace Umbraco.Web
|
||||
@@ -367,6 +365,28 @@ namespace Umbraco.Web
|
||||
return ContentForObjects(ids);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the contents corresponding to the identifiers.
|
||||
/// </summary>
|
||||
/// <param name="ids">The content identifiers.</param>
|
||||
/// <returns>The existing contents corresponding to the identifiers.</returns>
|
||||
/// <remarks>If an identifier does not match an existing content, it will be missing in the returned value.</remarks>
|
||||
public IEnumerable<IPublishedContent> Content(params Udi[] ids)
|
||||
{
|
||||
return ids.Select(id => ContentQuery.Content(id)).WhereNotNull();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the contents corresponding to the identifiers.
|
||||
/// </summary>
|
||||
/// <param name="ids">The content identifiers.</param>
|
||||
/// <returns>The existing contents corresponding to the identifiers.</returns>
|
||||
/// <remarks>If an identifier does not match an existing content, it will be missing in the returned value.</remarks>
|
||||
public IEnumerable<IPublishedContent> Content(params GuidUdi[] ids)
|
||||
{
|
||||
return ids.Select(id => ContentQuery.Content(id));
|
||||
}
|
||||
|
||||
private IEnumerable<IPublishedContent> ContentForObjects(IEnumerable<object> ids)
|
||||
{
|
||||
var idsA = ids.ToArray();
|
||||
@@ -418,6 +438,27 @@ namespace Umbraco.Web
|
||||
{
|
||||
return ContentForObjects(ids);
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the contents corresponding to the identifiers.
|
||||
/// </summary>
|
||||
/// <param name="ids">The content identifiers.</param>
|
||||
/// <returns>The existing contents corresponding to the identifiers.</returns>
|
||||
/// <remarks>If an identifier does not match an existing content, it will be missing in the returned value.</remarks>
|
||||
public IEnumerable<IPublishedContent> Content(IEnumerable<Udi> ids)
|
||||
{
|
||||
return ids.Select(id => ContentQuery.Content(id)).WhereNotNull();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the contents corresponding to the identifiers.
|
||||
/// </summary>
|
||||
/// <param name="ids">The content identifiers.</param>
|
||||
/// <returns>The existing contents corresponding to the identifiers.</returns>
|
||||
/// <remarks>If an identifier does not match an existing content, it will be missing in the returned value.</remarks>
|
||||
public IEnumerable<IPublishedContent> Content(IEnumerable<GuidUdi> ids)
|
||||
{
|
||||
return ids.Select(id => ContentQuery.Content(id));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the contents corresponding to the identifiers.
|
||||
@@ -634,6 +675,29 @@ namespace Umbraco.Web
|
||||
return MediaForObjects(ids);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the medias corresponding to the identifiers.
|
||||
/// </summary>
|
||||
/// <param name="ids">The media identifiers.</param>
|
||||
/// <returns>The existing medias corresponding to the identifiers.</returns>
|
||||
/// <remarks>If an identifier does not match an existing media, it will be missing in the returned value.</remarks>
|
||||
public IEnumerable<IPublishedContent> Media(params Udi[] ids)
|
||||
{
|
||||
return ids.Select(id => ContentQuery.Media(id)).WhereNotNull();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the medias corresponding to the identifiers.
|
||||
/// </summary>
|
||||
/// <param name="ids">The media identifiers.</param>
|
||||
/// <returns>The existing medias corresponding to the identifiers.</returns>
|
||||
/// <remarks>If an identifier does not match an existing media, it will be missing in the returned value.</remarks>
|
||||
public IEnumerable<IPublishedContent> Media(params GuidUdi[] ids)
|
||||
{
|
||||
return ids.Select(id => ContentQuery.Media(id));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the medias corresponding to the identifiers.
|
||||
/// </summary>
|
||||
@@ -656,6 +720,28 @@ namespace Umbraco.Web
|
||||
return ContentQuery.Media(ids);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the medias corresponding to the identifiers.
|
||||
/// </summary>
|
||||
/// <param name="ids">The media identifiers.</param>
|
||||
/// <returns>The existing medias corresponding to the identifiers.</returns>
|
||||
/// <remarks>If an identifier does not match an existing media, it will be missing in the returned value.</remarks>
|
||||
public IEnumerable<IPublishedContent> Media(IEnumerable<Udi> ids)
|
||||
{
|
||||
return ids.Select(id => ContentQuery.Media(id)).WhereNotNull();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the medias corresponding to the identifiers.
|
||||
/// </summary>
|
||||
/// <param name="ids">The media identifiers.</param>
|
||||
/// <returns>The existing medias corresponding to the identifiers.</returns>
|
||||
/// <remarks>If an identifier does not match an existing media, it will be missing in the returned value.</remarks>
|
||||
public IEnumerable<IPublishedContent> Media(IEnumerable<GuidUdi> ids)
|
||||
{
|
||||
return ids.Select(id => ContentQuery.Media(id));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the medias corresponding to the identifiers.
|
||||
/// </summary>
|
||||
|
||||
@@ -4,6 +4,10 @@ using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Web.WebApi
|
||||
{
|
||||
// unless we want to modify the content of the collection
|
||||
// which we are not doing at the moment
|
||||
// we can inherit from BuilderCollectionBase and just be enumerable
|
||||
|
||||
public class UmbracoApiControllerTypeCollection : BuilderCollectionBase<Type>
|
||||
{
|
||||
public UmbracoApiControllerTypeCollection(IEnumerable<Type> items)
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Web.WebApi
|
||||
{
|
||||
public class UmbracoApiControllerTypeCollectionBuilder : TypeCollectionBuilderBase<UmbracoApiControllerTypeCollection, UmbracoApiController>
|
||||
{ }
|
||||
}
|
||||
Reference in New Issue
Block a user