Compare commits

...
42 Commits
Author SHA1 Message Date
Giordano PolidoroandGitHub 86aaf4ff03 Bump version to 7.15.10 (#13076) 2022-10-13 12:46:15 +02:00
Sebastiaan Janssen da6bc2bdea Bump version to 7.15.9 2022-09-13 10:44:29 +02:00
Sebastiaan Janssen fbbcf614d9 Fixes #12987
v7 still cannot update to Netwonsoft.Json because of NuGet restrictions
2022-09-13 10:42:51 +02:00
Sebastiaan Janssen 5fd336b50d Use user key as alias instead of username 2022-08-09 14:34:07 +02:00
Sebastiaan Janssen 3ac1947a1b Force the allowed avatar image types 2022-08-02 11:13:06 +02:00
Sebastiaan Janssen 17e32d9be2 Dependency on Ace was too flexible, keep it the same as in the last patch release 2022-07-07 15:30:47 +02:00
Sebastiaan Janssen 24447cbaa5 Update build to work on modern machines 2022-07-07 13:14:08 +02:00
Sebastiaan Janssen 613dbe27a9 Bump version to 7.15.8 2022-07-07 12:27:28 +02:00
Sebastiaan Janssen 4d5bd25442 #12235 Remove upper constraint of 12.99 for Newtonsoft.Json dependency for UmbracoCms.Core 2022-07-07 12:27:10 +02:00
Sebastiaan Janssen 7447cc4b7e Make the request var more specific 2021-02-05 12:08:09 +01:00
Sebastiaan Janssen b3a00f7224 Specific URL filter for the booting page, it can only be local urls 2021-02-04 20:42:30 +01:00
Sebastiaan Janssen e2bb2505fc Bump version to 7.15.7 2021-02-04 13:20:43 +01:00
Sebastiaan Janssen c4ddf40fe8 Fix for issue trying to circumvent the url validator 2021-02-04 13:18:49 +01:00
Sebastiaan Janssen 13af8d2809 Update to latest log4net 2021-02-04 12:01:40 +01:00
Claus 9d995f5054 bumping version to 7.15.6 2020-08-20 19:25:40 +02:00
ClausandGitHub da7200a559 Merge pull request #8675 from umbraco/v7/bugfix/8499-blueprint-cache-refreshing
Fix for V7- Error 'No Document Exists with id 'xxx' when saving a Content Template Blueprint #8499
2020-08-20 14:10:41 +02:00
Shannon 94088d3a61 Fix for V7- Error 'No Document Exists with id 'xxx' when saving a Content Template Blueprint #8499 2020-08-20 21:27:39 +10:00
Sebastiaan Janssen a1b532568c Merge branch 'v7/dev' into v7/7.15 2020-08-19 09:29:54 +02:00
Warren Buckley f76711d1a1 Attempt to fix up mess of bower/gulp dependencies 2020-07-30 09:48:26 +01:00
Arkadiusz BielandGitHub 8b362d8bbb v7: Revert previous changes, force writer in update of cache (#8464) 2020-07-22 16:27:57 +02:00
Arkadiusz BielandSebastiaan Janssen 753e56e2d9 fix removing with childnode 2020-07-21 15:17:11 +02:00
Kristian AndersenandSebastiaan Janssen 8c1e1fefb5 Call to ClearLoginSessions before inserting to db to avoid potential deadlock 2020-07-14 16:44:09 +02:00
Gareth EvansandSebastiaan Janssen 5f831818f9 #8412 Set ng-maxlength and maxlength attributes on the tag input (backport from u8)
(cherry picked from commit defcfb9530)
2020-07-14 15:00:13 +02:00
Gareth EvansandSebastiaan Janssen defcfb9530 #8412 Set ng-maxlength and maxlength attributes on the tag input (backport from u8) 2020-07-14 14:59:23 +02:00
Sebastiaan Janssen 2d4b3c7dc5 Fixes #8217
New installer/login background
2020-06-02 11:18:25 +02:00
Elitsa MarinovskaandGitHub 2d2197a11b Update old string format for a language area alias and a language key… (#2980) 2020-05-12 09:56:04 +02:00
Sebastiaan Janssen d644f796f5 Revert "Trigger closeDialogs on mousedown rather than click"
This reverts commit 0cf3ca0d47.
2020-05-05 11:42:49 +02:00
Sebastiaan Janssen b3d3f334c9 Merge branch 'v7/dev' into v7/7.15 2020-05-04 13:57:29 +02:00
Steve MegsonandSebastiaan Janssen 1a96553320 Pointless commit 2020-05-04 13:50:36 +02:00
Steve MegsonandSebastiaan Janssen 0cf3ca0d47 Trigger closeDialogs on mousedown rather than click 2020-05-04 13:50:36 +02:00
Steve MegsonandSebastiaan Janssen fec313e735 Stop ng-swipe binding to mouse events 2020-05-04 13:50:36 +02:00
Andy FeltonandSebastiaan Janssen eebf2a83d1 Allows members to be ordered by additional system fields 2020-05-04 13:35:00 +02:00
Nill MortensenandSebastiaan Janssen 4a15c0f4ba fix #7127 Unlock user account doesn't work on 7.14.0 and 15 2020-05-04 13:20:32 +02:00
Sebastiaan Janssen 8a3c9e82e2 Make sure the correct version of ClientDependency-Mvc5 is used everywhere 2020-05-04 13:15:33 +02:00
Sebastiaan Janssen 745125db3b Merge remote-tracking branch 'origin/v7/dev' into v7/7.15 2020-05-04 13:05:54 +02:00
Alan Mac KennaandSebastiaan Janssen 902dbf76db upgrade tinymce to 4.9.10 2020-05-04 13:04:28 +02:00
Sebastiaan Janssen 3395554389 Remove unused code, as suggested in #2996 2020-05-04 13:02:39 +02:00
Sebastiaan Janssen 1a9f94d979 Migration was not released for 7.15.4, so need to target the new version 2020-05-04 12:46:45 +02:00
Sebastiaan Janssen d81b320e10 Bump version to 7.15.5 2020-05-04 12:41:53 +02:00
Sebastiaan Janssen b46b75e920 Merge branch 'v7/dev' into v7/7.15 2020-05-04 12:02:14 +02:00
Sebastiaan Janssen 2f228a6bb2 Merge branch 'v7/dev' into v7/7.15 2020-03-24 17:10:26 +01:00
Sebastiaan Janssen f86cddc9b0 Update dependency for 7.15.4
(cherry picked from commit d52695d81f)

# Conflicts:
#	build/NuSpecs/UmbracoCms.Core.nuspec
2020-03-19 14:17:19 +01:00
63 changed files with 1101 additions and 2065 deletions
+1
View File
@@ -143,3 +143,4 @@ build.out/
build.tmp/
build/Modules/*/temp/
/src/.idea/*
/build/temp/
@@ -1,112 +0,0 @@
#
function Build-UmbracoDocs
{
$uenv = Get-UmbracoBuildEnv
$src = "$($uenv.SolutionRoot)\src"
$out = "$($uenv.SolutionRoot)\build.out"
$tmp = "$($uenv.SolutionRoot)\build.tmp"
$buildTemp = "$PSScriptRoot\temp"
$cache = 2
Prepare-Build -keep $uenv
################ Do the UI docs
# get a temp clean node env (will restore)
Sandbox-Node $uenv
Write-Host "Executing gulp docs"
push-location "$($uenv.SolutionRoot)\src\Umbraco.Web.UI.Client"
write "node version is:" > $tmp\belle-docs.log
&node -v >> $tmp\belle-docs.log 2>&1
write "npm version is:" >> $tmp\belle-docs.log 2>&1
&npm -v >> $tmp\belle-docs.log 2>&1
write "executing npm install" >> $tmp\belle-docs.log 2>&1
&npm install >> $tmp\belle-docs.log 2>&1
write "executing bower install" >> $tmp\belle-docs.log 2>&1
&npm install -g bower >> $tmp\belle-docs.log 2>&1
write "installing gulp" >> $tmp\belle-docs.log 2>&1
&npm install -g gulp >> $tmp\belle-docs.log 2>&1
write "installing gulp-cli" >> $tmp\belle-docs.log 2>&1
&npm install -g gulp-cli --quiet >> $tmp\belle-docs.log 2>&1
write "building docs using gulp" >> $tmp\belle-docs.log 2>&1
&gulp docs >> $tmp\belle-docs.log 2>&1
pop-location
Write-Host "Completed gulp docs build"
# fixme - should we filter the log to find errors?
#get-content .\build.tmp\belle-docs.log | %{ if ($_ -match "build") { write $_}}
# change baseUrl
$baseUrl = "https://our.umbraco.com/apidocs/ui/"
$indexPath = "$src/Umbraco.Web.UI.Client/docs/api/index.html"
(Get-Content $indexPath).Replace("origin + location.href.substr(origin.length).replace(rUrl, indexFile)", "'$baseUrl'") `
| Set-Content $indexPath
# restore
Restore-Node
# zip
&$uenv.Zip a -tzip -r "$out\ui-docs.zip" "$src\Umbraco.Web.UI.Client\docs\api\*.*" `
> $null
################ Do the c# docs
Write-Host "Build C# documentation"
# Build the solution in debug mode
# FIXME no only a simple compilation should be enough!
# FIXME we MUST handle msbuild & co error codes!
# FIXME deal with weird things in gitconfig?
#Build-Umbraco -Configuration Debug
Restore-NuGet $uenv
Compile-Umbraco $uenv "Debug" # FIXME different log file!
Restore-WebConfig "$src\Umbraco.Web.UI"
# ensure we have docfx
Get-DocFx $uenv $buildTemp
# clear
$docFxOutput = "$($uenv.SolutionRoot)\apidocs\_site"
if (test-path($docFxOutput))
{
Remove-Directory $docFxOutput
}
# run
$docFxJson = "$($uenv.SolutionRoot)\apidocs\docfx.json"
push-location "$($uenv.SolutionRoot)\build" # silly docfx.json wants this
Write-Host "Run DocFx metadata"
Write-Host "Logging to $tmp\docfx.metadata.log"
&$uenv.DocFx metadata $docFxJson > "$tmp\docfx.metadata.log"
Write-Host "Run DocFx build"
Write-Host "Logging to $tmp\docfx.build.log"
&$uenv.DocFx build $docFxJson > "$tmp\docfx.build.log"
pop-location
# zip
&$uenv.Zip a -tzip -r "$out\csharp-docs.zip" "$docFxOutput\*.*" `
> $null
}
function Get-DocFx($uenv, $buildTemp)
{
$docFx = "$buildTemp\docfx"
if (-not (test-path $docFx))
{
$source = "https://github.com/dotnet/docfx/releases/download/v2.19.2/docfx.zip"
Write-Host "Download DocFx from $source"
Invoke-WebRequest $source -OutFile "$buildTemp\docfx.zip"
&$uenv.Zip x "$buildTemp\docfx.zip" -o"$buildTemp\docfx" -aos > $nul
Remove-File "$buildTemp\docfx.zip"
}
$uenv | add-member -memberType NoteProperty -name DocFx -value "$docFx\docfx.exe"
}
@@ -1,187 +0,0 @@
#
# Get-UmbracoBuildEnv
# Gets the Umbraco build environment
# Downloads tools if necessary
#
function Get-UmbracoBuildEnv
{
# store tools in the module's directory
# and cache them for two days
$path = "$PSScriptRoot\temp"
$src = "$PSScriptRoot\..\..\..\src"
$cache = 2
if (-not (test-path $path))
{
mkdir $path > $null
}
# ensure we have NuGet
$nuget = "$path\nuget.exe"
$source = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
if ((test-path $nuget) -and ((ls $nuget).CreationTime -lt [DateTime]::Now.AddDays(-$cache)))
{
Remove-File $nuget
}
if (-not (test-path $nuget))
{
Write-Host "Download NuGet..."
Invoke-WebRequest $source -OutFile $nuget
}
# ensure we have 7-Zip
$sevenZip = "$path\7za.exe"
if ((test-path $sevenZip) -and ((ls $sevenZip).CreationTime -lt [DateTime]::Now.AddDays(-$cache)))
{
Remove-File $sevenZip
}
if (-not (test-path $sevenZip))
{
Write-Host "Download 7-Zip..."
&$nuget install 7-Zip.CommandLine -configFile "$src\NuGet.config" -OutputDirectory $path -Verbosity quiet
$dir = ls "$path\7-Zip.CommandLine.*" | sort -property Name -descending | select -first 1
$file = ls -path "$dir" -name 7za.exe -recurse
$file = ls -path "$dir" -name 7za.exe -recurse | select -first 1 #A select is because there is tools\7za.exe & tools\x64\7za.exe
mv "$dir\$file" $sevenZip
Remove-Directory $dir
}
# ensure we have vswhere
$vswhere = "$path\vswhere.exe"
if ((test-path $vswhere) -and ((ls $vswhere).CreationTime -lt [DateTime]::Now.AddDays(-$cache)))
{
Remove-File $vswhere
}
if (-not (test-path $vswhere))
{
Write-Host "Download VsWhere..."
&$nuget install vswhere -configFile "$src\NuGet.config" -OutputDirectory $path -Verbosity quiet
$dir = ls "$path\vswhere.*" | sort -property Name -descending | select -first 1
$file = ls -path "$dir" -name vswhere.exe -recurse
mv "$dir\$file" $vswhere
Remove-Directory $dir
}
# ensure we have semver
$semver = "$path\Semver.dll"
if ((test-path $semver) -and ((ls $semver).CreationTime -lt [DateTime]::Now.AddDays(-$cache)))
{
Remove-File $semver
}
if (-not (test-path $semver))
{
Write-Host "Download Semver..."
&$nuget install semver -configFile "$src\NuGet.config" -OutputDirectory $path -Verbosity quiet
$dir = ls "$path\semver.*" | sort -property Name -descending | select -first 1
$file = "$dir\lib\net452\Semver.dll"
if (-not (test-path $file))
{
Write-Error "Failed to file $file"
return
}
mv "$file" $semver
Remove-Directory $dir
}
try
{
[Reflection.Assembly]::LoadFile($semver) > $null
}
catch
{
Write-Error -Exception $_.Exception -Message "Failed to load $semver"
break
}
# ensure we have node
$node = "$path\node-v8.12.0-win-x86"
$source = "http://nodejs.org/dist/v8.12.0/node-v8.12.0-win-x86.7z "
if (-not (test-path $node))
{
Write-Host "Download Node..."
Invoke-WebRequest $source -OutFile "$path\node-v8.12.0-win-x86.7z"
&$sevenZip x "$path\node-v8.12.0-win-x86.7z" -o"$path" -aos > $nul
Remove-File "$path\node-v8.12.0-win-x86.7z"
}
# note: why? node already brings everything we need!
## ensure we have npm
#$npm = "$path\npm.*"
#$getNpm = $true
#if (test-path $npm)
#{
# $getNpm = $false
# $tmpNpm = ls "$path\npm.*" | sort -property Name -descending | select -first 1
# if ($tmpNpm.CreationTime -lt [DateTime]::Now.AddDays(-$cache))
# {
# $getNpm = $true
# }
# else
# {
# $npm = $tmpNpm.ToString()
# }
#}
#if ($getNpm)
#{
# Write-Host "Download Npm..."
# &$nuget install npm -OutputDirectory $path -Verbosity quiet
# $npm = ls "$path\npm.*" | sort -property Name -descending | select -first 1
# $npm.CreationTime = [DateTime]::Now
# $npm = $npm.ToString()
#}
# find visual studio
# will not work on VSO but VSO does not need it
$vsPath = ""
$vsVer = ""
$msBuild = $null
$params = @()
$params += "-prerelease"
&$vswhere @params | foreach {
if ($_.StartsWith("installationPath:")) { $vsPath = $_.SubString("installationPath:".Length).Trim() }
if ($_.StartsWith("installationVersion:")) { $vsVer = $_.SubString("installationVersion:".Length).Trim() }
}
if ($vsPath -ne "")
{
$vsVerParts = $vsVer.Split('.')
$vsMajor = [int]::Parse($vsVerParts[0])
$vsMinor = [int]::Parse($vsVerParts[1])
if ($vsMajor -eq 16) {
$msBuild = "$vsPath\MSBuild\Current\Bin"
}
elseif ($vsMajor -eq 15) {
$msBuild = "$vsPath\MSBuild\$vsMajor.0\Bin"
}
elseif ($vsMajor -eq 14) {
$msBuild = "c:\Program Files (x86)\MSBuild\$vsMajor\Bin"
}
else
{
$msBuild = $null
}
}
$vs = $null
if ($msBuild)
{
$vs = new-object -typeName PsObject
$vs | add-member -memberType NoteProperty -name Path -value $vsPath
$vs | add-member -memberType NoteProperty -name Major -value $vsMajor
$vs | add-member -memberType NoteProperty -name Minor -value $vsMinor
$vs | add-member -memberType NoteProperty -name MsBuild -value "$msBuild\MsBuild.exe"
}
$solutionRoot = Get-FullPath "$PSScriptRoot\..\..\.."
$uenv = new-object -typeName PsObject
$uenv | add-member -memberType NoteProperty -name SolutionRoot -value $solutionRoot
$uenv | add-member -memberType NoteProperty -name VisualStudio -value $vs
$uenv | add-member -memberType NoteProperty -name NuGet -value $nuget
$uenv | add-member -memberType NoteProperty -name Zip -value $sevenZip
$uenv | add-member -memberType NoteProperty -name VsWhere -value $vswhere
$uenv | add-member -memberType NoteProperty -name Semver -value $semver
$uenv | add-member -memberType NoteProperty -name NodePath -value $node
#$uenv | add-member -memberType NoteProperty -name NpmPath -value $npm
return $uenv
}
@@ -1,26 +0,0 @@
#
# Get-UmbracoVersion
# Gets the Umbraco version
#
function Get-UmbracoVersion
{
$uenv = Get-UmbracoBuildEnv
# parse SolutionInfo and retrieve the version string
$filepath = "$($uenv.SolutionRoot)\src\SolutionInfo.cs"
$text = [System.IO.File]::ReadAllText($filepath)
$match = [System.Text.RegularExpressions.Regex]::Matches($text, "AssemblyInformationalVersion\(`"(.+)?`"\)")
$version = $match.Groups[1]
# semver-parse the version string
$semver = [SemVer.SemVersion]::Parse($version)
$release = "" + $semver.Major + "." + $semver.Minor + "." + $semver.Patch
$versions = new-object -typeName PsObject
$versions | add-member -memberType NoteProperty -name Semver -value $semver
$versions | add-member -memberType NoteProperty -name Release -value $release
$versions | add-member -memberType NoteProperty -name Comment -value $semver.PreRelease
$versions | add-member -memberType NoteProperty -name Build -value $semver.Build
return $versions
}
@@ -1,30 +0,0 @@
# finds msbuild
function Get-VisualStudio($vswhere)
{
$vsPath = ""
$vsVer = ""
&$vswhere | foreach {
if ($_.StartsWith("installationPath:")) { $vsPath = $_.SubString("installationPath:".Length).Trim() }
if ($_.StartsWith("installationVersion:")) { $vsVer = $_.SubString("installationVersion:".Length).Trim() }
}
if ($vsPath -eq "") { return $null }
$vsVerParts = $vsVer.Split('.')
$vsMajor = [int]::Parse($vsVerParts[0])
$vsMinor = [int]::Parse($vsVerParts[1])
if ($vsMajor -eq 15) {
$msBuild = "$vsPath\MSBuild\$vsMajor.$vsMinor\Bin"
}
elseif ($vsMajor -eq 14) {
$msBuild = "c:\Program Files (x86)\MSBuild\$vsMajor\Bin"
}
else { return $null }
$msBuild = "$msBuild\MsBuild.exe"
$vs = new-object -typeName PsObject
$vs | add-member -memberType NoteProperty -name Path -value $vsPath
$vs | add-member -memberType NoteProperty -name Major -value $vsMajor
$vs | add-member -memberType NoteProperty -name Minor -value $vsMinor
$vs | add-member -memberType NoteProperty -name MsBuild -value $msBuild
return $vs
}
@@ -1,30 +0,0 @@
#
# Set-UmbracoContinuousVersion
# Sets the Umbraco version for continuous integration
#
# -Version <version>
# where <version> is a Semver valid version
# eg 1.2.3, 1.2.3-alpha, 1.2.3-alpha+456
#
# -BuildNumber <buildNumber>
# where <buildNumber> is a string coming from the build server
# eg 34, 126, 1
#
function Set-UmbracoContinuousVersion
{
param (
[Parameter(Mandatory=$true)]
[string]
$version,
[Parameter(Mandatory=$true)]
[string]
$buildNumber
)
Write-Host "Version is currently set to $version"
$umbracoVersion = "$($version.Trim())-alpha$($buildNumber)"
Write-Host "Setting Umbraco Version to $umbracoVersion"
Set-UmbracoVersion $umbracoVersion
}
@@ -1,117 +0,0 @@
#
# Set-UmbracoVersion
# Sets the Umbraco version
#
# -Version <version>
# where <version> is a Semver valid version
# eg 1.2.3, 1.2.3-alpha, 1.2.3-alpha+456
#
function Set-UmbracoVersion
{
param (
[Parameter(Mandatory=$true)]
[string]
$version
)
$uenv = Get-UmbracoBuildEnv
try
{
[Reflection.Assembly]::LoadFile($uenv.Semver) > $null
}
catch
{
Write-Error "Failed to load $uenv.Semver"
break
}
# validate input
$ok = [Regex]::Match($version, "^[0-9]+\.[0-9]+\.[0-9]+(\-[a-z0-9]+)?(\+[0-9]+)?$")
if (-not $ok.Success)
{
Write-Error "Invalid version $version"
break
}
# parse input
try
{
$semver = [SemVer.SemVersion]::Parse($version)
}
catch
{
Write-Error "Invalid version $version"
break
}
#
$release = "" + $semver.Major + "." + $semver.Minor + "." + $semver.Patch
# edit files and set the proper versions and dates
Write-Host "Update UmbracoVersion.cs"
Replace-FileText "$($uenv.SolutionRoot)\src\Umbraco.Core\Configuration\UmbracoVersion.cs" `
"(\d+)\.(\d+)\.(\d+)(.(\d+))?" `
"$release"
Replace-FileText "$($uenv.SolutionRoot)\src\Umbraco.Core\Configuration\UmbracoVersion.cs" `
"CurrentComment { get { return `"(.+)`"" `
"CurrentComment { get { return `"$($semver.PreRelease)`""
Write-Host "Update SolutionInfo.cs"
Replace-FileText "$($uenv.SolutionRoot)\src\SolutionInfo.cs" `
"AssemblyFileVersion\(`"(.+)?`"\)" `
"AssemblyFileVersion(`"$release`")"
Replace-FileText "$($uenv.SolutionRoot)\src\SolutionInfo.cs" `
"AssemblyInformationalVersion\(`"(.+)?`"\)" `
"AssemblyInformationalVersion(`"$semver`")"
$year = [System.DateTime]::Now.ToString("yyyy")
Replace-FileText "$($uenv.SolutionRoot)\src\SolutionInfo.cs" `
"AssemblyCopyright\(`"Copyright © Umbraco (\d{4})`"\)" `
"AssemblyCopyright(`"Copyright © Umbraco $year`")"
# edit csproj and set IIS Express port number
# this is a raw copy of ReplaceIISExpressPortNumber.exe
# it probably can be achieved in a much nicer way - l8tr
$source = @"
using System;
using System.IO;
using System.Xml;
using System.Globalization;
namespace Umbraco
{
public static class PortUpdater
{
public static void Update(string path, string release)
{
XmlDocument xmlDocument = new XmlDocument();
string fullPath = Path.GetFullPath(path);
xmlDocument.Load(fullPath);
int result = 1;
int.TryParse(release.Replace(`".`", `"`"), out result);
while (result < 1024)
result *= 10;
XmlNode xmlNode1 = xmlDocument.GetElementsByTagName(`"IISUrl`").Item(0);
if (xmlNode1 != null)
xmlNode1.InnerText = `"http://localhost:`" + (object) result;
XmlNode xmlNode2 = xmlDocument.GetElementsByTagName(`"DevelopmentServerPort`").Item(0);
if (xmlNode2 != null)
xmlNode2.InnerText = result.ToString((IFormatProvider) CultureInfo.InvariantCulture);
xmlDocument.Save(fullPath);
}
}
}
"@
$assem = (
"System.Xml",
"System.IO",
"System.Globalization"
)
Write-Host "Update Umbraco.Web.UI.csproj"
add-type -referencedAssemblies $assem -typeDefinition $source -language CSharp
$csproj = "$($uenv.SolutionRoot)\src\Umbraco.Web.UI\Umbraco.Web.UI.csproj"
[Umbraco.PortUpdater]::Update($csproj, $release)
return $semver
}
@@ -1,619 +0,0 @@
# Umbraco.Build.psm1
#
# $env:PSModulePath = "$pwd\build\Modules\;$env:PSModulePath"
# Import-Module Umbraco.Build -Force -DisableNameChecking
#
# PowerShell Modules:
# https://msdn.microsoft.com/en-us/library/dd878324%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
#
# PowerShell Module Manifest:
# https://msdn.microsoft.com/en-us/library/dd878337%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
#
# See also
# http://www.powershellmagazine.com/2014/08/15/pstip-taking-control-of-verbose-and-debug-output-part-5/
. "$PSScriptRoot\Utilities.ps1"
. "$PSScriptRoot\Get-VisualStudio.ps1"
. "$PSScriptRoot\Get-UmbracoBuildEnv.ps1"
. "$PSScriptRoot\Set-UmbracoVersion.ps1"
. "$PSScriptRoot\Set-UmbracoContinuousVersion.ps1"
. "$PSScriptRoot\Get-UmbracoVersion.ps1"
. "$PSScriptRoot\Verify-NuGet.ps1"
. "$PSScriptRoot\Build-UmbracoDocs.ps1"
#
# Prepares the build
#
function Prepare-Build
{
param (
$uenv, # an Umbraco build environment (see Get-UmbracoBuildEnv)
[Alias("k")]
[switch]
$keep = $false
)
Write-Host ">> Prepare Build"
$src = "$($uenv.SolutionRoot)\src"
$tmp = "$($uenv.SolutionRoot)\build.tmp"
$out = "$($uenv.SolutionRoot)\build.out"
# clear
Write-Host "Clear folders and files"
Remove-Directory "$src\Umbraco.Web.UI.Client\bower_components"
if (-not $keep)
{
Remove-Directory "$tmp"
Remove-Directory "$out"
}
if (-not (Test-Path "$tmp"))
{
mkdir "$tmp" > $null
}
if (-not (Test-Path "$out"))
{
mkdir "$out" > $null
}
# ensure proper web.config
$webUi = "$src\Umbraco.Web.UI"
Store-WebConfig $webUi
Write-Host "Create clean web.config"
Copy-File "$webUi\web.Template.config" "$webUi\web.config"
}
function Clear-EnvVar($var)
{
$value = [Environment]::GetEnvironmentVariable($var)
if (test-path "env:$var") { rm "env:$var" }
return $value
}
function Set-EnvVar($var, $value)
{
if ($value)
{
[Environment]::SetEnvironmentVariable($var, $value)
}
else
{
if (test-path "env:$var") { rm "env:$var" }
}
}
function Sandbox-Node
{
param (
$uenv # an Umbraco build environment (see Get-UmbracoBuildEnv)
)
$global:node_path = $env:path
$nodePath = $uenv.NodePath
$gitExe = (get-command git).Source
$gitPath = [System.IO.Path]::GetDirectoryName($gitExe)
$env:path = "$nodePath;$gitPath"
$global:node_nodepath = Clear-EnvVar "NODEPATH"
$global:node_npmcache = Clear-EnvVar "NPM_CONFIG_CACHE"
$global:node_npmprefix = Clear-EnvVar "NPM_CONFIG_PREFIX"
}
function Restore-Node
{
$env:path = $node_path
Set-EnvVar "NODEPATH" $node_nodepath
Set-EnvVar "NPM_CONFIG_CACHE" $node_npmcache
Set-EnvVar "NPM_CONFIG_PREFIX" $node_npmprefix
}
#
# Builds the Belle UI project
#
function Compile-Belle
{
param (
$uenv, # an Umbraco build environment (see Get-UmbracoBuildEnv)
$version # an Umbraco version object (see Get-UmbracoVersion)
)
$tmp = "$($uenv.SolutionRoot)\build.tmp"
$src = "$($uenv.SolutionRoot)\src"
Write-Host ">> Compile Belle"
Write-Host "Logging to $tmp\belle.log"
# get a temp clean node env (will restore)
Sandbox-Node $uenv
push-location "$($uenv.SolutionRoot)\src\Umbraco.Web.UI.Client"
write "node version is:" > $tmp\belle.log
&node -v >> $tmp\belle.log 2>&1
write "npm version is:" >> $tmp\belle.log 2>&1
&npm -v >> $tmp\belle.log 2>&1
write "cleaning npm cache" >> $tmp\belle.log 2>&1
&npm cache clean >> $tmp\belle.log 2>&1
write "installing bower" >> $tmp\belle.log 2>&1
&npm install -g bower >> $tmp\belle.log 2>&1
write "installing gulp" >> $tmp\belle.log 2>&1
&npm install -g gulp >> $tmp\belle.log 2>&1
write "installing gulp-cli" >> $tmp\belle.log 2>&1
&npm install -g gulp-cli --quiet >> $tmp\belle.log 2>&1
write "executing npm install" >> $tmp\belle.log 2>&1
&npm install >> $tmp\belle.log 2>&1
write "executing gulp build for version $version" >> $tmp\belle.log 2>&1
&gulp build --buildversion=$version.Release >> $tmp\belle.log 2>&1
pop-location
# fixme - should we filter the log to find errors?
#get-content .\build.tmp\belle.log | %{ if ($_ -match "build") { write $_}}
# restore
Restore-Node
# setting node_modules folder to hidden
# used to prevent VS13 from crashing on it while loading the websites project
# also makes sure aspnet compiler does not try to handle rogue files and chokes
# in VSO with Microsoft.VisualC.CppCodeProvider -related errors
# use get-item -force 'cos it might be hidden already
write "Set hidden attribute on node_modules"
$dir = get-item -force "$src\Umbraco.Web.UI.Client\node_modules"
$dir.Attributes = $dir.Attributes -bor ([System.IO.FileAttributes]::Hidden)
}
#
# Compiles Umbraco
#
function Compile-Umbraco
{
param (
$uenv, # an Umbraco build environment (see Get-UmbracoBuildEnv)
[string] $buildConfiguration = "Release"
)
$src = "$($uenv.SolutionRoot)\src"
$tmp = "$($uenv.SolutionRoot)\build.tmp"
$out = "$($uenv.SolutionRoot)\build.out"
if ($uenv.VisualStudio -eq $null)
{
Write-Error "Build environment does not provide VisualStudio."
break
}
$toolsVersion = "4.0"
if ($uenv.VisualStudio.Major -eq 15)
{
$toolsVersion = "15.0"
}
if ($uenv.VisualStudio.Major -eq 16)
{
$toolsVersion = "Current"
}
Write-Host ">> Compile Umbraco"
Write-Host "Logging to $tmp\msbuild.umbraco.log"
# beware of the weird double \\ at the end of paths
# see http://edgylogic.com/blog/powershell-and-external-commands-done-right/
&$uenv.VisualStudio.MsBuild "$src\Umbraco.Web.UI\Umbraco.Web.UI.csproj" `
/p:WarningLevel=0 `
/p:Configuration=$buildConfiguration `
/p:Platform=AnyCPU `
/p:UseWPP_CopyWebApplication=True `
/p:PipelineDependsOnBuild=False `
/p:OutDir=$tmp\bin\\ `
/p:WebProjectOutputDir=$tmp\WebApp\\ `
/p:Verbosity=minimal `
/t:Clean`;Rebuild `
/tv:$toolsVersion `
/p:UmbracoBuild=True `
> $tmp\msbuild.umbraco.log
# /p:UmbracoBuild tells the csproj that we are building from PS
}
#
# Prepare Tests
#
function Prepare-Tests
{
param (
$uenv # an Umbraco build environment (see Get-UmbracoBuildEnv)
)
$src = "$($uenv.SolutionRoot)\src"
$tmp = "$($uenv.SolutionRoot)\build.tmp"
Write-Host ">> Prepare Tests"
# fixme - idea is to avoid rebuilding everything for tests
# but because of our weird assembly versioning (with .* stuff)
# everything gets rebuilt all the time...
#Copy-Files "$tmp\bin" "." "$tmp\tests"
# data
Write-Host "Copy data files"
if (-Not (Test-Path -Path "$tmp\tests\Packaging" ) )
{
Write-Host "Create packaging directory"
mkdir "$tmp\tests\Packaging" > $null
}
Copy-Files "$src\Umbraco.Tests\Packaging\Packages" "*" "$tmp\tests\Packaging\Packages"
# required for package install tests
if (-Not (Test-Path -Path "$tmp\tests\bin" ) )
{
Write-Host "Create bin directory"
mkdir "$tmp\tests\bin" > $null
}
}
#
# Compiles Tests
#
function Compile-Tests
{
param (
$uenv # an Umbraco build environment (see Get-UmbracoBuildEnv)
)
$src = "$($uenv.SolutionRoot)\src"
$tmp = "$($uenv.SolutionRoot)\build.tmp"
$out = "$tmp\tests"
$buildConfiguration = "Release"
if ($uenv.VisualStudio -eq $null)
{
Write-Error "Build environment does not provide VisualStudio."
break
}
$toolsVersion = "4.0"
if ($uenv.VisualStudio.Major -eq 15)
{
$toolsVersion = "15.0"
}
Write-Host ">> Compile Tests"
Write-Host "Logging to $tmp\msbuild.tests.log"
# beware of the weird double \\ at the end of paths
# see http://edgylogic.com/blog/powershell-and-external-commands-done-right/
&$uenv.VisualStudio.MsBuild "$src\Umbraco.Tests\Umbraco.Tests.csproj" `
/p:WarningLevel=0 `
/p:Configuration=$buildConfiguration `
/p:Platform=AnyCPU `
/p:UseWPP_CopyWebApplication=True `
/p:PipelineDependsOnBuild=False `
/p:OutDir=$out\\ `
/p:Verbosity=minimal `
/t:Build `
/tv:$toolsVersion `
/p:UmbracoBuild=True `
/p:NugetPackages=$src\packages `
> $tmp\msbuild.tests.log
# /p:UmbracoBuild tells the csproj that we are building from PS
}
#
# Cleans things up and prepare files after compilation
#
function Prepare-Packages
{
param (
$uenv # an Umbraco build environment (see Get-UmbracoBuildEnv)
)
Write-Host ">> Prepare Packages"
$src = "$($uenv.SolutionRoot)\src"
$tmp = "$($uenv.SolutionRoot)\build.tmp"
$out = "$($uenv.SolutionRoot)\build.out"
$buildConfiguration = "Release"
# restore web.config
Restore-WebConfig "$src\Umbraco.Web.UI"
# cleanup build
Write-Host "Clean build"
Remove-File "$tmp\bin\*.dll.config"
Remove-File "$tmp\WebApp\bin\*.dll.config"
# cleanup presentation
Write-Host "Cleanup presentation"
Remove-Directory "$tmp\WebApp\umbraco.presentation"
# create directories
Write-Host "Create directories"
mkdir "$tmp\Configs" > $null
mkdir "$tmp\Configs\Lang" > $null
mkdir "$tmp\WebApp\App_Data" > $null
#mkdir "$tmp\WebApp\Media" > $null
#mkdir "$tmp\WebApp\Views" > $null
# copy various files
Write-Host "Copy xml documentation"
cp -force "$tmp\bin\*.xml" "$tmp\WebApp\bin"
Write-Host "Copy transformed configs and langs"
# note: exclude imageprocessor/*.config as imageprocessor pkg installs them
Copy-Files "$tmp\WebApp\config" "*.config" "$tmp\Configs" `
{ -not $_.RelativeName.StartsWith("imageprocessor") }
Copy-Files "$tmp\WebApp\config" "*.js" "$tmp\Configs"
Copy-Files "$tmp\WebApp\config\lang" "*.xml" "$tmp\Configs\Lang"
Copy-File "$tmp\WebApp\web.config" "$tmp\Configs\web.config.transform"
Write-Host "Copy transformed web.config"
Copy-File "$src\Umbraco.Web.UI\web.$buildConfiguration.Config.transformed" "$tmp\WebApp\web.config"
# offset the modified timestamps on all umbraco dlls, as WebResources
# break if date is in the future, which, due to timezone offsets can happen.
Write-Host "Offset dlls timestamps"
ls -r "$tmp\*.dll" | foreach {
$_.CreationTime = $_.CreationTime.AddHours(-11)
$_.LastWriteTime = $_.LastWriteTime.AddHours(-11)
}
# copy libs
Write-Host "Copy SqlCE libraries"
Copy-Files "$src\packages\SqlServerCE.4.0.0.1" "*.*" "$tmp\bin" `
{ -not $_.Extension.StartsWith(".nu") -and -not $_.RelativeName.StartsWith("lib\") }
Copy-Files "$src\packages\SqlServerCE.4.0.0.1" "*.*" "$tmp\WebApp\bin" `
{ -not $_.Extension.StartsWith(".nu") -and -not $_.RelativeName.StartsWith("lib\") }
# copy Belle
Write-Host "Copy Belle"
Copy-Files "$src\Umbraco.Web.UI\umbraco\assets" "*" "$tmp\WebApp\umbraco\assets"
Copy-Files "$src\Umbraco.Web.UI\umbraco\js" "*" "$tmp\WebApp\umbraco\js"
Copy-Files "$src\Umbraco.Web.UI\umbraco\lib" "*" "$tmp\WebApp\umbraco\lib"
Copy-Files "$src\Umbraco.Web.UI\umbraco\views" "*" "$tmp\WebApp\umbraco\views"
}
#
# Creates the Zip packages
#
function Package-Zip
{
param (
$uenv # an Umbraco build environment (see Get-UmbracoBuildEnv)
)
Write-Host ">> Create Zip packages"
$src = "$($uenv.SolutionRoot)\src"
$tmp = "$($uenv.SolutionRoot)\build.tmp"
$out = "$($uenv.SolutionRoot)\build.out"
Write-Host "Zip all binaries"
&$uenv.Zip a -r "$out\UmbracoCms.AllBinaries.$($version.Semver).zip" `
"$tmp\bin\*" `
"-x!dotless.Core.*" `
> $null
Write-Host "Zip cms"
&$uenv.Zip a -r "$out\UmbracoCms.$($version.Semver).zip" `
"$tmp\WebApp\*" `
"-x!dotless.Core.*" "-x!Content_Types.xml" "-x!*.pdb"`
> $null
}
#
# Prepares NuGet
#
function Prepare-NuGet
{
param (
$uenv # an Umbraco build environment (see Get-UmbracoBuildEnv)
)
Write-Host ">> Prepare NuGet"
$src = "$($uenv.SolutionRoot)\src"
$tmp = "$($uenv.SolutionRoot)\build.tmp"
$out = "$($uenv.SolutionRoot)\build.out"
# add Web.config transform files to the NuGet package
Write-Host "Add web.config transforms to NuGet package"
mv "$tmp\WebApp\Views\Web.config" "$tmp\WebApp\Views\Web.config.transform"
# fixme - that one does not exist in .bat build either?
#mv "$tmp\WebApp\Xslt\Web.config" "$tmp\WebApp\Xslt\Web.config.transform"
}
#
# Restores NuGet
#
function Restore-NuGet
{
param (
$uenv # an Umbraco build environment (see Get-UmbracoBuildEnv)
)
$src = "$($uenv.SolutionRoot)\src"
$tmp = "$($uenv.SolutionRoot)\build.tmp"
Write-Host ">> Restore NuGet"
Write-Host "Logging to $tmp\nuget.restore.log"
&$uenv.NuGet restore "$src\Umbraco.sln" -configfile "$src\NuGet.config" > "$tmp\nuget.restore.log"
}
#
# Copies the Azure Gallery script to output
#
function Prepare-AzureGallery
{
param (
$uenv # an Umbraco build environment (see Get-UmbracoBuildEnv)
)
$src = "$($uenv.SolutionRoot)\src"
$tmp = "$($uenv.SolutionRoot)\build.tmp"
$out = "$($uenv.SolutionRoot)\build.out"
$psScript = "$($uenv.SolutionRoot)\build\azuregalleryrelease.ps1"
Write-Host ">> Copy azuregalleryrelease.ps1 to output folder"
Copy-Item $psScript $out
}
#
# Creates the NuGet packages
#
function Package-NuGet
{
param (
$uenv, # an Umbraco build environment (see Get-UmbracoBuildEnv)
$version # an Umbraco version object (see Get-UmbracoVersion)
)
$src = "$($uenv.SolutionRoot)\src"
$tmp = "$($uenv.SolutionRoot)\build.tmp"
$out = "$($uenv.SolutionRoot)\build.out"
$nuspecs = "$($uenv.SolutionRoot)\build\NuSpecs"
Write-Host ">> Create NuGet packages"
# see https://docs.microsoft.com/en-us/nuget/schema/nuspec
# note - warnings about SqlCE native libs being outside of 'lib' folder,
# nothing much we can do about it as it's intentional yet there does not
# seem to be a way to disable the warning
&$uenv.NuGet Pack "$nuspecs\UmbracoCms.Core.nuspec" `
-Properties BuildTmp="$tmp" `
-Version $version.Semver.ToString() `
-Symbols -Verbosity quiet -outputDirectory $out
&$uenv.NuGet Pack "$nuspecs\UmbracoCms.nuspec" `
-Properties BuildTmp="$tmp" `
-Version $version.Semver.ToString() `
-Verbosity quiet -outputDirectory $out
}
#
# Builds Umbraco
#
function Build-Umbraco
{
[CmdletBinding()]
param (
[string]
$target = "all",
[string]
$buildConfiguration = "Release"
)
$target = $target.ToLowerInvariant()
Write-Host ">> Build-Umbraco <$target> <$buildConfiguration>"
Write-Host "Get Build Environment"
$uenv = Get-UmbracoBuildEnv
Write-Host "Get Version"
$version = Get-UmbracoVersion
Write-Host "Version $($version.Semver)"
if ($target -eq "pre-build")
{
Prepare-Build $uenv
#Compile-Belle $uenv $version
# set environment variables
$env:UMBRACO_VERSION=$version.Semver.ToString()
$env:UMBRACO_RELEASE=$version.Release
$env:UMBRACO_COMMENT=$version.Comment
$env:UMBRACO_BUILD=$version.Build
# set environment variable for VSO
# https://github.com/Microsoft/vsts-tasks/issues/375
# https://github.com/Microsoft/vsts-tasks/blob/master/docs/authoring/commands.md
Write-Host ("##vso[task.setvariable variable=UMBRACO_VERSION;]$($version.Semver.ToString())")
Write-Host ("##vso[task.setvariable variable=UMBRACO_RELEASE;]$($version.Release)")
Write-Host ("##vso[task.setvariable variable=UMBRACO_COMMENT;]$($version.Comment)")
Write-Host ("##vso[task.setvariable variable=UMBRACO_BUILD;]$($version.Build)")
Write-Host ("##vso[task.setvariable variable=UMBRACO_TMP;]$($uenv.SolutionRoot)\build.tmp")
}
elseif ($target -eq "pre-tests")
{
Prepare-Tests $uenv
}
elseif ($target -eq "compile-tests")
{
Compile-Tests $uenv
}
elseif ($target -eq "compile-umbraco")
{
Compile-Umbraco $uenv $buildConfiguration
}
elseif ($target -eq "pre-packages")
{
Prepare-Packages $uenv
}
elseif ($target -eq "pre-nuget")
{
Prepare-NuGet $uenv
}
elseif ($target -eq "restore-nuget")
{
Restore-NuGet $uenv
}
elseif ($target -eq "pkg-zip")
{
Package-Zip $uenv
}
elseif ($target -eq "compile-belle")
{
Compile-Belle $uenv $version
}
elseif ($target -eq "prepare-azuregallery")
{
Prepare-AzureGallery $uenv
}
elseif ($target -eq "all")
{
Prepare-Build $uenv
Restore-NuGet $uenv
Compile-Belle $uenv $version
Compile-Umbraco $uenv $buildConfiguration
Prepare-Tests $uenv
Compile-Tests $uenv
# not running tests...
Prepare-Packages $uenv
Package-Zip $uenv
Verify-NuGet $uenv
Prepare-NuGet $uenv
Package-NuGet $uenv $version
Prepare-AzureGallery $uenv
}
else
{
Write-Error "Unsupported target `"$target`"."
}
}
#
# export functions
#
Export-ModuleMember -function Get-UmbracoBuildEnv
Export-ModuleMember -function Set-UmbracoVersion
Export-ModuleMember -function Set-UmbracoContinuousVersion
Export-ModuleMember -function Get-UmbracoVersion
Export-ModuleMember -function Build-Umbraco
Export-ModuleMember -function Build-UmbracoDocs
Export-ModuleMember -function Verify-NuGet
#eof
-95
View File
@@ -1,95 +0,0 @@
# returns the full path if $file is relative to $pwd
function Get-FullPath($file)
{
$path = [System.IO.Path]::Combine($pwd, $file)
$path = [System.IO.Path]::GetFullPath($path)
return $path
}
# removes a directory, doesn't complain if it does not exist
function Remove-Directory($dir)
{
remove-item $dir -force -recurse -errorAction SilentlyContinue > $null
}
# removes a file, doesn't complain if it does not exist
function Remove-File($file)
{
remove-item $file -force -errorAction SilentlyContinue > $null
}
# copies a file, creates target dir if needed
function Copy-File($source, $target)
{
$ignore = new-item -itemType file -path $target -force
cp -force $source $target
}
# copies files to a directory
function Copy-Files($source, $select, $target, $filter)
{
$files = ls -r "$source\$select"
$files | foreach {
$relative = $_.FullName.SubString($source.Length+1)
$_ | add-member -memberType NoteProperty -name RelativeName -value $relative
}
if ($filter -ne $null) {
$files = $files | where $filter
}
$files |
foreach {
if ($_.PsIsContainer) {
$ignore = new-item -itemType directory -path "$target\$($_.RelativeName)" -force
}
else {
Copy-File $_.FullName "$target\$($_.RelativeName)"
}
}
}
# regex-replaces content in a file
function Replace-FileText($filename, $source, $replacement)
{
$filepath = Get-FullPath $filename
$text = [System.IO.File]::ReadAllText($filepath)
$text = [System.Text.RegularExpressions.Regex]::Replace($text, $source, $replacement)
$utf8bom = New-Object System.Text.UTF8Encoding $true
[System.IO.File]::WriteAllText($filepath, $text, $utf8bom)
}
# store web.config
function Store-WebConfig($webUi)
{
if (test-path "$webUi\web.config")
{
if (test-path "$webUi\web.config.temp-build")
{
Write-Host "Found existing web.config.temp-build"
$i = 0
while (test-path "$webUi\web.config.temp-build.$i")
{
$i = $i + 1
}
Write-Host "Save existing web.config as web.config.temp-build.$i"
Write-Host "(WARN: the original web.config.temp-build will be restored during post-build)"
mv "$webUi\web.config" "$webUi\web.config.temp-build.$i"
}
else
{
Write-Host "Save existing web.config as web.config.temp-build"
Write-Host "(will be restored during post-build)"
mv "$webUi\web.config" "$webUi\web.config.temp-build"
}
}
}
# restore web.config
function Restore-WebConfig($webUi)
{
if (test-path "$webUi\web.config.temp-build")
{
Write-Host "Restoring existing web.config"
Remove-File "$webUi\web.config"
mv "$webUi\web.config.temp-build" "$webUi\web.config"
}
}
@@ -1,444 +0,0 @@
#
# Verify-NuGet
#
function Format-Dependency
{
param ( $d )
$m = $d.Id + " "
if ($d.MinInclude) { $m = $m + "[" }
else { $m = $m + "(" }
$m = $m + $d.MinVersion
if ($d.MaxVersion -ne $d.MinVersion) { $m = $m + "," + $d.MaxVersion }
if ($d.MaxInclude) { $m = $m + "]" }
else { $m = $m + ")" }
return $m
}
function Write-NuSpec
{
param ( $name, $deps )
Write-Host ""
Write-Host "$name NuSpec dependencies:"
foreach ($d in $deps)
{
$m = Format-Dependency $d
Write-Host " $m"
}
}
function Write-Package
{
param ( $name, $pkgs )
Write-Host ""
Write-Host "$name packages:"
foreach ($p in $pkgs)
{
Write-Host " $($p.Id) $($p.Version)"
}
}
function Verify-NuGet
{
param (
$uenv # an Umbraco build environment (see Get-UmbracoBuildEnv)
)
if ($uenv -eq $null)
{
$uenv = Get-UmbracoBuildEnv
}
$source = @"
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using Semver;
namespace Umbraco.Build
{
public class NuGet
{
public static Dependency[] GetNuSpecDependencies(string filename)
{
NuSpec nuspec;
var serializer = new XmlSerializer(typeof(NuSpec));
using (var reader = new StreamReader(filename))
{
nuspec = (NuSpec) serializer.Deserialize(reader);
}
var nudeps = nuspec.Metadata.Dependencies;
var deps = new List<Dependency>();
foreach (var nudep in nudeps)
{
var dep = new Dependency();
dep.Id = nudep.Id;
var parts = nudep.Version.Split(',');
if (parts.Length == 1)
{
dep.MinInclude = parts[0].StartsWith("[");
dep.MaxInclude = parts[0].EndsWith("]");
SemVersion version;
if (!SemVersion.TryParse(parts[0].Substring(1, parts[0].Length-2).Trim(), out version)) continue;
dep.MinVersion = dep.MaxVersion = version; //parts[0].Substring(1, parts[0].Length-2).Trim();
}
else
{
SemVersion version;
if (!SemVersion.TryParse(parts[0].Substring(1).Trim(), out version)) continue;
dep.MinVersion = version; //parts[0].Substring(1).Trim();
if (!SemVersion.TryParse(parts[1].Substring(0, parts[1].Length-1).Trim(), out version)) continue;
dep.MaxVersion = version; //parts[1].Substring(0, parts[1].Length-1).Trim();
dep.MinInclude = parts[0].StartsWith("[");
dep.MaxInclude = parts[1].EndsWith("]");
}
deps.Add(dep);
}
return deps.ToArray();
}
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(/*this*/ IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
HashSet<TKey> knownKeys = new HashSet<TKey>();
foreach (TSource element in source)
{
if (knownKeys.Add(keySelector(element)))
{
yield return element;
}
}
}
public static Package[] GetProjectsPackages(string src, string[] projects)
{
var l = new List<Package>();
foreach (var project in projects)
{
var path = Path.Combine(src, project);
var packageConfig = Path.Combine(path, "packages.config");
if (File.Exists(packageConfig))
ReadPackagesConfig(packageConfig, l);
var csprojs = Directory.GetFiles(path, "*.csproj");
foreach (var csproj in csprojs)
{
ReadCsProj(csproj, l);
}
}
IEnumerable<Package> p = l.OrderBy(x => x.Id);
p = DistinctBy(p, x => x.Id + ":::" + x.Version);
return p.ToArray();
}
public static object[] GetPackageErrors(Package[] pkgs)
{
return pkgs
.GroupBy(x => x.Id)
.Where(x => x.Count() > 1)
.ToArray();
}
public static object[] GetNuSpecErrors(Package[] pkgs, Dependency[] deps)
{
var d = pkgs.ToDictionary(x => x.Id, x => x.Version);
return deps
.Select(x =>
{
SemVersion v;
if (!d.TryGetValue(x.Id, out v)) return null;
var ok = true;
/*
if (x.MinInclude)
{
if (v < x.MinVersion) ok = false;
}
else
{
if (v <= x.MinVersion) ok = false;
}
if (x.MaxInclude)
{
if (v > x.MaxVersion) ok = false;
}
else
{
if (v >= x.MaxVersion) ok = false;
}
*/
if (!x.MinInclude || v != x.MinVersion) ok = false;
return ok ? null : new { Dependency = x, Version = v };
})
.Where(x => x != null)
.ToArray();
}
/*
public static Package[] GetProjectPackages(string path)
{
var l = new List<Package>();
var packageConfig = Path.Combine(path, "packages.config");
if (File.Exists(packageConfig))
ReadPackagesConfig(packageConfig, l);
var csprojs = Directory.GetFiles(path, "*.csproj");
foreach (var csproj in csprojs)
{
ReadCsProj(csproj, l);
}
return l.ToArray();
}
*/
public static string GetDirectoryName(string filename)
{
return Path.GetFileName(Path.GetDirectoryName(filename));
}
public static void ReadPackagesConfig(string filename, List<Package> packages)
{
//Console.WriteLine("read " + filename);
PackagesConfigPackages pkgs;
var serializer = new XmlSerializer(typeof(PackagesConfigPackages));
using (var reader = new StreamReader(filename))
{
pkgs = (PackagesConfigPackages) serializer.Deserialize(reader);
}
foreach (var p in pkgs.Packages)
{
SemVersion version;
if (!SemVersion.TryParse(p.Version, out version)) continue;
packages.Add(new Package { Id = p.Id, Version = version, Project = GetDirectoryName(filename) });
}
}
public static void ReadCsProj(string filename, List<Package> packages)
{
//Console.WriteLine("read " + filename);
// if xmlns then it's not a VS2017 with PackageReference
var text = File.ReadAllLines(filename);
var line = text.FirstOrDefault(x => x.Contains("<Project"));
if (line == null) return;
if (line.Contains("xmlns")) return;
CsProjProject proj;
var serializer = new XmlSerializer(typeof(CsProjProject));
using (var reader = new StreamReader(filename))
{
proj = (CsProjProject) serializer.Deserialize(reader);
}
foreach (var p in proj.ItemGroups.Where(x => x.Packages != null).SelectMany(x => x.Packages))
{
var sversion = p.VersionE ?? p.VersionA;
SemVersion version;
if (!SemVersion.TryParse(sversion, out version)) continue;
packages.Add(new Package { Id = p.Id, Version = version, Project = GetDirectoryName(filename) });
}
}
public class Dependency
{
public string Id { get; set; }
public SemVersion MinVersion { get; set; }
public SemVersion MaxVersion { get; set; }
public bool MinInclude { get; set; }
public bool MaxInclude { get; set; }
}
public class Package
{
public string Id { get; set; }
public SemVersion Version { get; set; }
public string Project { get; set; }
}
[XmlType(AnonymousType = true, Namespace = "http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd")]
[XmlRoot(Namespace = "http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd", IsNullable = false, ElementName = "package")]
public class NuSpec
{
[XmlElement("metadata")]
public NuSpecMetadata Metadata { get; set; }
}
[XmlType(AnonymousType = true, Namespace = "http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd", TypeName = "metadata")]
public class NuSpecMetadata
{
[XmlArray("dependencies")]
[XmlArrayItem("dependency", IsNullable = false)]
public NuSpecDependency[] Dependencies { get; set; }
}
[XmlType(AnonymousType = true, Namespace = "http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd", TypeName = "dependencies")]
public class NuSpecDependency
{
[XmlAttribute(AttributeName = "id")]
public string Id { get; set; }
[XmlAttribute(AttributeName = "version")]
public string Version { get; set; }
}
[XmlType(AnonymousType = true)]
[XmlRoot(Namespace = "", IsNullable = false, ElementName = "packages")]
public class PackagesConfigPackages
{
[XmlElement("package")]
public PackagesConfigPackage[] Packages { get; set; }
}
[XmlType(AnonymousType = true, TypeName = "package")]
public class PackagesConfigPackage
{
[XmlAttribute(AttributeName = "id")]
public string Id { get; set; }
[XmlAttribute(AttributeName = "version")]
public string Version { get; set; }
}
[XmlType(AnonymousType = true)]
[XmlRoot(Namespace = "", IsNullable = false, ElementName = "Project")]
public class CsProjProject
{
[XmlElement("ItemGroup")]
public CsProjItemGroup[] ItemGroups { get; set; }
}
[XmlType(AnonymousType = true, TypeName = "ItemGroup")]
public class CsProjItemGroup
{
[XmlElement("PackageReference")]
public CsProjPackageReference[] Packages { get; set; }
}
[XmlType(AnonymousType = true, TypeName = "PackageReference")]
public class CsProjPackageReference
{
[XmlAttribute(AttributeName = "Include")]
public string Id { get; set; }
[XmlAttribute(AttributeName = "Version")]
public string VersionA { get; set; }
[XmlElement("Version")]
public string VersionE { get; set;}
}
}
}
"@
Write-Host ">> Verify NuGet consistency"
$assem = (
"System.Xml",
"System.Core", # "System.Collections.Generic"
"System.Linq",
"System.Xml.Serialization",
"System.IO",
"System.Globalization",
$uenv.Semver
)
try
{
# as long as the code hasn't changed it's fine to re-add, but if the code
# has changed this will throw - better warn the dev that we have an issue
add-type -referencedAssemblies $assem -typeDefinition $source -language CSharp
}
catch
{
if ($_.FullyQualifiedErrorId.StartsWith("TYPE_ALREADY_EXISTS,"))
{ Write-Error "Failed to add type, did you change the code?" }
else
{ Write-Error $_ }
}
if (-not $?) { break }
$nuspecs = (
"UmbracoCms",
"UmbracoCms.Core"
)
$projects = (
"Umbraco.Core",
"Umbraco.Web",
"Umbraco.Web.UI",
"UmbracoExamine"#,
#"Umbraco.Tests",
#"Umbraco.Tests.Benchmarks"
)
$src = "$($uenv.SolutionRoot)\src"
$pkgs = [Umbraco.Build.NuGet]::GetProjectsPackages($src, $projects)
if (-not $?) { break }
#Write-Package "All" $pkgs
$errs = [Umbraco.Build.NuGet]::GetPackageErrors($pkgs)
if (-not $?) { break }
if ($errs.Length -gt 0)
{
Write-Host ""
}
foreach ($err in $errs)
{
Write-Host $err.Key
foreach ($e in $err)
{
Write-Host " $($e.Version) required by $($e.Project)"
}
}
if ($errs.Length -gt 0)
{
Write-Error "Found non-consolidated package dependencies"
break
}
$nuerr = $false
$nupath = "$($uenv.SolutionRoot)\build\NuSpecs"
foreach ($nuspec in $nuspecs)
{
$deps = [Umbraco.Build.NuGet]::GetNuSpecDependencies("$nupath\$nuspec.nuspec")
if (-not $?) { break }
#Write-NuSpec $nuspec $deps
$errs = [Umbraco.Build.NuGet]::GetNuSpecErrors($pkgs, $deps)
if (-not $?) { break }
if ($errs.Length -gt 0)
{
Write-Host ""
Write-Host "$nuspec requires:"
$nuerr = $true
}
foreach ($err in $errs)
{
$m = Format-Dependency $err.Dependency
Write-Host " $m but projects require $($err.Version)"
}
}
if ($nuerr)
{
Write-Error "Found inconsistent NuGet dependencies"
break
}
}
+2 -2
View File
@@ -16,7 +16,7 @@
<tags>umbraco</tags>
<dependencies>
<group targetFramework="net452">
<dependency id="log4net" version="[2.0.8, 3.0.0)" />
<dependency id="log4net" version="[2.0.12, 3.0.0)" />
<dependency id="Log4Net.Async" version="[2.0.4, 3.0.0)" />
<dependency id="Microsoft.AspNet.Mvc" version="[5.2.7, 6.0.0)" />
<dependency id="Microsoft.AspNet.WebApi" version="[5.2.7, 6.0.0)" />
@@ -32,7 +32,7 @@
<dependency id="ClientDependency" version="[1.9.9, 2.0.0)" />
<dependency id="ClientDependency-Mvc5" version="[1.9.3,1.999999)" />
<dependency id="AutoMapper" version="[3.3.1, 4.0.0)" />
<dependency id="Newtonsoft.Json" version="[12.0.2, 13.0.0)" />
<dependency id="Newtonsoft.Json" version="[12.0.2, 13.999999)" />
<dependency id="Examine" version="[0.1.90, 1.0.0)" />
<dependency id="ImageProcessor" version="[2.7.0.100, 3.0.0)" />
<dependency id="ImageProcessor.Web" version="[4.10.0.100, 5.0.0)" />
+1 -1
View File
@@ -17,7 +17,7 @@
<dependencies>
<group targetFramework="net452">
<dependency id="UmbracoCms.Core" version="[$version$]" />
<dependency id="Newtonsoft.Json" version="[12.0.2, 13.0.0)" />
<dependency id="Newtonsoft.Json" version="[12.0.2, 13.999999)" />
<dependency id="Umbraco.ModelsBuilder" version="[3.0.10, 4.0.0)" />
<dependency id="Microsoft.AspNet.SignalR.Core" version="[2.4.1, 3.0.0)" />
<dependency id="ImageProcessor.Web.Config" version="[2.5.0.100, 3.0.0)" />
+1 -1
View File
@@ -394,7 +394,7 @@
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0"/>
<bindingRedirect oldVersion="0.0.0.0-2.0.12.0" newVersion="2.0.12.0"/>
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="System.Data.SqlServerCe" publicKeyToken="89845DCD8080CC91" culture="neutral"/>
+95
View File
@@ -0,0 +1,95 @@
# this script should be dot-sourced into the build.ps1 scripts
# right after the parameters declaration
# ie
# . "$PSScriptRoot\build-bootstrap.ps1"
# THIS FILE IS DISTRIBUTED AS PART OF UMBRACO.BUILD
# DO NOT MODIFY IT - ALWAYS USED THE COMMON VERSION
# ################################################################
# BOOTSTRAP
# ################################################################
# reset errors
$error.Clear()
# ensure we have temp folder for downloads
$scriptRoot = "$PSScriptRoot"
$scriptTemp = "$scriptRoot\temp"
if (-not (test-path $scriptTemp)) { mkdir $scriptTemp > $null }
# get NuGet
$cache = 4
$nuget = "$scriptTemp\nuget.exe"
# ensure the correct NuGet-source is used. This one is used by Umbraco
$nugetsourceUmbraco = "https://www.myget.org/F/umbracocore/api/v3/index.json"
if (-not $local)
{
$source = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
if ((test-path $nuget) -and ((ls $nuget).CreationTime -lt [DateTime]::Now.AddDays(-$cache)))
{
Remove-Item $nuget -force -errorAction SilentlyContinue > $null
}
if (-not (test-path $nuget))
{
Write-Host "Download NuGet..."
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest $source -OutFile $nuget
if (-not $?) { throw "Failed to download NuGet." }
}
}
elseif (-not (test-path $nuget))
{
throw "Failed to locate NuGet.exe."
}
# NuGet notes
# As soon as we use -ConfigFile, NuGet uses that file, and only that file, and does not
# merge configuration from system level. See comments in NuGet.Client solution, class
# NuGet.Configuration.Settings, method LoadDefaultSettings.
# For NuGet to merge configurations, it needs to "find" the file in the current directory,
# or above. Which means we cannot really use -ConfigFile but instead have to have Umbraco's
# NuGet.config file at root, and always run NuGet.exe while at root or in a directory below
# root.
$solutionRoot = "$scriptRoot\.."
$testPwd = [System.IO.Path]::GetFullPath($pwd.Path) + "\"
$testRoot = [System.IO.Path]::GetFullPath($solutionRoot) + "\"
if (-not $testPwd.ToLower().StartsWith($testRoot.ToLower()))
{
throw "Cannot run outside of the solution's root."
}
# get the build system
if (-not $local)
{
$params = "-OutputDirectory", $scriptTemp, "-Verbosity", "quiet", "-PreRelease", "-Source", $nugetsourceUmbraco
&$nuget install Umbraco.Build @params
if (-not $?) { throw "Failed to download Umbraco.Build." }
}
# ensure we have the build system
$ubuildPath = ls "$scriptTemp\Umbraco.Build.*" | sort -property CreationTime -descending | select -first 1
if (-not $ubuildPath)
{
throw "Failed to locate the build system."
}
# boot the build system
# this creates $global:ubuild
return &"$ubuildPath\ps\Boot.ps1"
# at that point the build.ps1 script must boot the build system
# eg
# $ubuild.Boot($ubuildPath.FullName, [System.IO.Path]::GetFullPath("$scriptRoot\.."),
# @{ Local = $local; With7Zip = $false; WithNode = $false },
# @{ continue = $continue })
# if (-not $?) { throw "Failed to boot the build system." }
#
# and it's good practice to report
# eg
# Write-Host "Umbraco.Whatever Build"
# Write-Host "Umbraco.Build v$($ubuild.BuildVersion)"
# eof
+547 -56
View File
@@ -1,67 +1,558 @@
param (
param (
# get, don't execute
[Parameter(Mandatory=$false)]
[string]
$version,
[Alias("g")]
[switch] $get = $false,
# run local, don't download, assume everything is ready
[Parameter(Mandatory=$false)]
[Alias("mo")]
[switch]
$moduleOnly = $false
)
[Alias("l")]
[Alias("loc")]
[switch] $local = $false,
# the script can run either from the solution root,
# or from the ./build directory - anything else fails
if ([System.IO.Path]::GetFileName($pwd) -eq "build")
{
$mpath = [System.IO.Path]::GetDirectoryName($pwd) + "\build\Modules\"
}
else
{
$mpath = "$pwd\build\Modules\"
}
# enable docfx
[Parameter(Mandatory=$false)]
[Alias("doc")]
[switch] $docfx = $false,
# look for the module and throw if not found
if (-not [System.IO.Directory]::Exists($mpath + "Umbraco.Build"))
{
Write-Error "Could not locate Umbraco build Powershell module."
break
}
# keep the build directories, don't clear them
[Parameter(Mandatory=$false)]
[Alias("c")]
[Alias("cont")]
[switch] $continue = $false,
# add the module path (if not already there)
if (-not $env:PSModulePath.Contains($mpath))
{
$env:PSModulePath = "$mpath;$env:PSModulePath"
}
# execute a command
[Parameter(Mandatory=$false, ValueFromRemainingArguments=$true)]
[String[]]
$command
)
# force-import (or re-import) the module
Write-Host "Import Umbraco build Powershell module"
Import-Module Umbraco.Build -Force -DisableNameChecking
# ################################################################
# BOOTSTRAP
# ################################################################
# module only?
if ($moduleOnly)
{
if (-not [string]::IsNullOrWhiteSpace($version))
# create and boot the buildsystem
$ubuild = &"$PSScriptRoot\build-bootstrap.ps1"
if (-not $?) { return }
$ubuild.Boot($PSScriptRoot,
@{ Local = $local; WithDocFx = $docfx },
@{ Continue = $continue })
if ($ubuild.OnError()) { return }
Write-Host "Umbraco Cms Build"
Write-Host "Umbraco.Build v$($ubuild.BuildVersion)"
# ################################################################
# TASKS
# ################################################################
$ubuild.DefineMethod("SetMoreUmbracoVersion",
{
Write-Host "(module only: ignoring version parameter)"
}
else
param ( $semver )
$release = "" + $semver.Major + "." + $semver.Minor + "." + $semver.Patch
Write-Host "Update IIS Express port in csproj"
$updater = New-Object "Umbraco.Build.ExpressPortUpdater"
$csproj = "$($this.SolutionRoot)\src\Umbraco.Web.UI\Umbraco.Web.UI.csproj"
$updater.Update($csproj, $release)
})
$ubuild.DefineMethod("SandboxNode",
{
Write-Host "(module only)"
$global:node_path = $env:path
$nodePath = $this.BuildEnv.NodePath
$gitExe = (Get-Command git).Source
if (-not $gitExe) { $gitExe = (Get-Command git).Path }
$gitPath = [System.IO.Path]::GetDirectoryName($gitExe)
$env:path = "$nodePath;$gitPath"
$global:node_nodepath = $this.ClearEnvVar("NODEPATH")
$global:node_npmcache = $this.ClearEnvVar("NPM_CONFIG_CACHE")
$global:node_npmprefix = $this.ClearEnvVar("NPM_CONFIG_PREFIX")
# https://github.com/gruntjs/grunt-contrib-connect/issues/235
$this.SetEnvVar("NODE_NO_HTTP2", "1")
})
$ubuild.DefineMethod("RestoreNode",
{
$env:path = $node_path
$this.SetEnvVar("NODEPATH", $node_nodepath)
$this.SetEnvVar("NPM_CONFIG_CACHE", $node_npmcache)
$this.SetEnvVar("NPM_CONFIG_PREFIX", $node_npmprefix)
$ignore = $this.ClearEnvVar("NODE_NO_HTTP2")
})
$ubuild.DefineMethod("CompileBelle",
{
$src = "$($this.SolutionRoot)\src"
$log = "$($this.BuildTemp)\belle.log"
Write-Host "Compile Belle"
Write-Host "Logging to $log"
# get a temp clean node env (will restore)
$this.SandboxNode()
# stupid PS is going to gather all "warnings" in $error
# so we have to take care of it else they'll bubble and kill the build
if ($error.Count -gt 0) { return }
try {
Push-Location "$($this.SolutionRoot)\src\Umbraco.Web.UI.Client"
Write-Output "" > $log
Write-Output "### node version is:" > $log
node -v >> $log 2>&1
if (-not $?) { throw "Failed to report node version." }
Write-Output "### npm version is:" >> $log 2>&1
npm -v >> $log 2>&1
if (-not $?) { throw "Failed to report npm version." }
Write-Output "### clean npm cache" >> $log 2>&1
npm cache clean --force >> $log 2>&1
$error.Clear() # that one can fail 'cos security bug - ignore
Write-Output "### npm install" >> $log 2>&1
npm install >> $log 2>&1
Write-Output ">> $? $($error.Count)" >> $log 2>&1
# Don't really care about the messages from npm install making us think there are errors
$error.Clear()
Write-Output "### gulp build for version $($this.Version.Release)" >> $log 2>&1
npx gulp build >> $log 2>&1
# We can ignore this warning, we need to update to node 12 at some point - https://github.com/jsdom/jsdom/issues/2939
$indexes = [System.Collections.ArrayList]::new()
$index = 0;
$error | ForEach-Object {
# Find which of the errors is the ExperimentalWarning
if($_.ToString().Contains("ExperimentalWarning: The fs.promises API is experimental")) {
[void]$indexes.Add($index)
}
$index++
}
$indexes | ForEach-Object {
# Loop through the list of indexes and remove the errors that we expect and feel confident we can ignore
$error.Remove($error[$_])
}
if (-not $?) { throw "Failed to build" } # that one is expected to work
} finally {
Pop-Location
# FIXME: should we filter the log to find errors?
#get-content .\build.tmp\belle.log | %{ if ($_ -match "build") { write $_}}
# restore
$this.RestoreNode()
}
# setting node_modules folder to hidden
# used to prevent VS13 from crashing on it while loading the websites project
# also makes sure aspnet compiler does not try to handle rogue files and chokes
# in VSO with Microsoft.VisualC.CppCodeProvider -related errors
# use get-item -force 'cos it might be hidden already
Write-Host "Set hidden attribute on node_modules"
$dir = Get-Item -force "$src\Umbraco.Web.UI.Client\node_modules"
$dir.Attributes = $dir.Attributes -bor ([System.IO.FileAttributes]::Hidden)
})
$ubuild.DefineMethod("CompileUmbraco",
{
$buildConfiguration = "Release"
$src = "$($this.SolutionRoot)\src"
$log = "$($this.BuildTemp)\msbuild.umbraco.log"
if ($this.BuildEnv.VisualStudio -eq $null)
{
throw "Build environment does not provide VisualStudio."
}
Write-Host "Compile Umbraco"
Write-Host "Logging to $log"
Write-Host "Msbuild location: " $this.BuildEnv.VisualStudio.MsBuild
# beware of the weird double \\ at the end of paths
# see http://edgylogic.com/blog/powershell-and-external-commands-done-right/
&$this.BuildEnv.VisualStudio.MsBuild "$src\Umbraco.Web.UI\Umbraco.Web.UI.csproj" `
/p:WarningLevel=0 `
/p:Configuration=$buildConfiguration `
/p:Platform=AnyCPU `
/p:UseWPP_CopyWebApplication=True `
/p:PipelineDependsOnBuild=False `
/p:OutDir="$($this.BuildTemp)\bin\\" `
/p:WebProjectOutputDir="$($this.BuildTemp)\WebApp\\" `
/p:Verbosity=minimal `
/t:Clean`;Rebuild `
/tv:"$($this.BuildEnv.VisualStudio.ToolsVersion)" `
/p:UmbracoBuild=True `
> $log
if (-not $?) { throw "Failed to compile Umbraco.Web.UI." }
# /p:UmbracoBuild tells the csproj that we are building from PS, not VS
})
$ubuild.DefineMethod("PrepareTests",
{
Write-Host "Prepare Tests"
# FIXME: - idea is to avoid rebuilding everything for tests
# but because of our weird assembly versioning (with .* stuff)
# everything gets rebuilt all the time...
#Copy-Files "$tmp\bin" "." "$tmp\tests"
# data
Write-Host "Copy data files"
if (-not (Test-Path -Path "$($this.BuildTemp)\tests\Packaging" ))
{
Write-Host "Create packaging directory"
mkdir "$($this.BuildTemp)\tests\Packaging" > $null
}
$this.CopyFiles("$($this.SolutionRoot)\src\Umbraco.Tests\Packaging\Packages", "*", "$($this.BuildTemp)\tests\Packaging\Packages")
# required for package install tests
if (-not (Test-Path -Path "$($this.BuildTemp)\tests\bin" ))
{
Write-Host "Create bin directory"
mkdir "$($this.BuildTemp)\tests\bin" > $null
}
# copy libs
Write-Host "Copy SqlCE libraries"
$nugetPackages = $env:NUGET_PACKAGES
if (-not $nugetPackages)
{
$nugetPackages = "$($this.SolutionRoot)\src\packages"
}
$this.CopyFiles("$nugetPackages\SqlServerCE.4.0.0.1\x86", "*.*", "$tmp\tests\x86")
$this.CopyFiles("$nugetPackages\SqlServerCE.4.0.0.1\amd64", "*.*", "$tmp\tests\amd64")
})
$ubuild.DefineMethod("CompileTests",
{
$buildConfiguration = "Release"
$log = "$($this.BuildTemp)\msbuild.tests.log"
if ($this.BuildEnv.VisualStudio -eq $null)
{
throw "Build environment does not provide VisualStudio."
}
Write-Host "Compile Tests"
Write-Host "Logging to $log"
# beware of the weird double \\ at the end of paths
# see http://edgylogic.com/blog/powershell-and-external-commands-done-right/
&$this.BuildEnv.VisualStudio.MsBuild "$($this.SolutionRoot)\src\Umbraco.Tests\Umbraco.Tests.csproj" `
/p:WarningLevel=0 `
/p:Configuration=$buildConfiguration `
/p:Platform=AnyCPU `
/p:UseWPP_CopyWebApplication=True `
/p:PipelineDependsOnBuild=False `
/p:OutDir="$($this.BuildTemp)\tests\\" `
/p:Verbosity=minimal `
/t:Build `
/tv:"$($this.BuildEnv.VisualStudio.ToolsVersion)" `
/p:UmbracoBuild=True `
> $log
if (-not $?) { throw "Failed to compile tests." }
# /p:UmbracoBuild tells the csproj that we are building from PS
})
$ubuild.DefineMethod("PreparePackages",
{
Write-Host "Prepare Packages"
$src = "$($this.SolutionRoot)\src"
$tmp = "$($this.BuildTemp)"
$out = "$($this.BuildOutput)"
$buildConfiguration = "Release"
# restore web.config
$this.TempRestoreFile("$src\Umbraco.Web.UI\web.config")
# cleanup build
Write-Host "Clean build"
$this.RemoveFile("$tmp\bin\*.dll.config")
$this.RemoveFile("$tmp\WebApp\bin\*.dll.config")
# cleanup presentation
Write-Host "Cleanup presentation"
$this.RemoveDirectory("$tmp\WebApp\umbraco.presentation")
# create directories
Write-Host "Create directories"
mkdir "$tmp\Configs" > $null
mkdir "$tmp\Configs\Lang" > $null
mkdir "$tmp\WebApp\App_Data" > $null
#mkdir "$tmp\WebApp\Media" > $null
#mkdir "$tmp\WebApp\Views" > $null
# copy various files
Write-Host "Copy xml documentation"
Copy-Item -force "$tmp\bin\*.xml" "$tmp\WebApp\bin"
Write-Host "Copy transformed configs and langs"
# note: exclude imageprocessor/*.config as imageprocessor pkg installs them
$this.CopyFiles("$tmp\WebApp\config", "*.config", "$tmp\Configs", `
{ -not $_.RelativeName.StartsWith("imageprocessor") })
$this.CopyFiles("$tmp\WebApp\config", "*.js", "$tmp\Configs")
$this.CopyFiles("$tmp\WebApp\config\lang", "*.xml", "$tmp\Configs\Lang")
$this.CopyFile("$tmp\WebApp\web.config", "$tmp\Configs\web.config.transform")
Write-Host "Copy transformed web.config"
$this.CopyFile("$src\Umbraco.Web.UI\web.$buildConfiguration.Config.transformed", "$tmp\WebApp\web.config")
# offset the modified timestamps on all umbraco dlls, as WebResources
# break if date is in the future, which, due to timezone offsets can happen.
Write-Host "Offset dlls timestamps"
Get-ChildItem -r "$tmp\*.dll" | ForEach-Object {
$_.CreationTime = $_.CreationTime.AddHours(-11)
$_.LastWriteTime = $_.LastWriteTime.AddHours(-11)
}
# copy libs
Write-Host "Copy SqlCE libraries"
$nugetPackages = $env:NUGET_PACKAGES
if (-not $nugetPackages)
{
$nugetPackages = "$($this.SolutionRoot)\src\packages"
}
$this.CopyFiles("$nugetPackages\SqlServerCE.4.0.0.1\x86", "*.*", "$tmp\bin\x86")
$this.CopyFiles("$nugetPackages\SqlServerCE.4.0.0.1\amd64", "*.*", "$tmp\bin\amd64")
$this.CopyFiles("$nugetPackages\SqlServerCE.4.0.0.1\x86", "*.*", "$tmp\WebApp\bin\x86")
$this.CopyFiles("$nugetPackages\SqlServerCE.4.0.0.1\amd64", "*.*", "$tmp\WebApp\bin\amd64")
# copy Belle
Write-Host "Copy Belle"
$this.CopyFiles("$src\Umbraco.Web.UI\umbraco\assets", "*", "$tmp\WebApp\umbraco\assets")
$this.CopyFiles("$src\Umbraco.Web.UI\umbraco\js", "*", "$tmp\WebApp\umbraco\js")
$this.CopyFiles("$src\Umbraco.Web.UI\umbraco\lib", "*", "$tmp\WebApp\umbraco\lib")
$this.CopyFiles("$src\Umbraco.Web.UI\umbraco\views", "*", "$tmp\WebApp\umbraco\views")
})
$ubuild.DefineMethod("PackageZip",
{
Write-Host "Create Zip packages"
$src = "$($this.SolutionRoot)\src"
$tmp = $this.BuildTemp
$out = $this.BuildOutput
Write-Host "Zip all binaries"
&$this.BuildEnv.Zip a -r "$out\UmbracoCms.AllBinaries.$($this.Version.Semver).zip" `
"$tmp\bin\*" `
"-x!dotless.Core.*" `
> $null
if (-not $?) { throw "Failed to zip UmbracoCms.AllBinaries." }
Write-Host "Zip cms"
&$this.BuildEnv.Zip a -r "$out\UmbracoCms.$($this.Version.Semver).zip" `
"$tmp\WebApp\*" `
"-x!dotless.Core.*" "-x!Content_Types.xml" "-x!*.pdb" `
> $null
if (-not $?) { throw "Failed to zip UmbracoCms." }
})
$ubuild.DefineMethod("PrepareBuild",
{
$this.TempStoreFile("$($this.SolutionRoot)\src\Umbraco.Web.UI\web.config")
Write-Host "Create clean web.config"
$this.CopyFile("$($this.SolutionRoot)\src\Umbraco.Web.UI\web.Template.config", "$($this.SolutionRoot)\src\Umbraco.Web.UI\web.config")
Write-host "Set environment"
$env:UMBRACO_VERSION=$this.Version.Semver.ToString()
$env:UMBRACO_RELEASE=$this.Version.Release
$env:UMBRACO_COMMENT=$this.Version.Comment
$env:UMBRACO_BUILD=$this.Version.Build
if ($args -and $args[0] -eq "vso")
{
Write-host "Set VSO environment"
# set environment variable for VSO
# https://github.com/Microsoft/vsts-tasks/issues/375
# https://github.com/Microsoft/vsts-tasks/blob/master/docs/authoring/commands.md
Write-Host ("##vso[task.setvariable variable=UMBRACO_VERSION;]$($this.Version.Semver.ToString())")
Write-Host ("##vso[task.setvariable variable=UMBRACO_RELEASE;]$($this.Version.Release)")
Write-Host ("##vso[task.setvariable variable=UMBRACO_COMMENT;]$($this.Version.Comment)")
Write-Host ("##vso[task.setvariable variable=UMBRACO_BUILD;]$($this.Version.Build)")
Write-Host ("##vso[task.setvariable variable=UMBRACO_TMP;]$($this.SolutionRoot)\build.tmp")
}
})
$ubuild.DefineMethod("PrepareNuGet",
{
Write-Host "Prepare NuGet"
# add Web.config transform files to the NuGet package
Write-Host "Add web.config transforms to NuGet package"
mv "$($this.BuildTemp)\WebApp\Views\Web.config" "$($this.BuildTemp)\WebApp\Views\Web.config.transform"
})
$ubuild.DefineMethod("RestoreNuGet",
{
Write-Host "Restore NuGet"
Write-Host "Logging to $($this.BuildTemp)\nuget.restore.log"
&$this.BuildEnv.NuGet restore "$($this.SolutionRoot)\src\Umbraco.sln" > "$($this.BuildTemp)\nuget.restore.log"
if (-not $?) { throw "Failed to restore NuGet packages." }
})
$ubuild.DefineMethod("PackageNuGet",
{
$nuspecs = "$($this.SolutionRoot)\build\NuSpecs"
Write-Host "Create NuGet packages"
&$this.BuildEnv.NuGet Pack "$nuspecs\UmbracoCms.Core.nuspec" `
-Properties BuildTmp="$($this.BuildTemp)" `
-Version "$($this.Version.Semver.ToString())" `
-Verbosity detailed -outputDirectory "$($this.BuildOutput)" > "$($this.BuildTemp)\nupack.cmscore.log"
if (-not $?) { throw "Failed to pack NuGet UmbracoCms.Core." }
&$this.BuildEnv.NuGet Pack "$nuspecs\UmbracoCms.nuspec" `
-Properties BuildTmp="$($this.BuildTemp)" `
-Version "$($this.Version.Semver.ToString())" `
-Verbosity detailed -outputDirectory "$($this.BuildOutput)" > "$($this.BuildTemp)\nupack.cms.log"
if (-not $?) { throw "Failed to pack NuGet UmbracoCms." }
# run hook
if ($this.HasMethod("PostPackageNuGet"))
{
Write-Host "Run PostPackageNuGet hook"
$this.PostPackageNuGet();
if (-not $?) { throw "Failed to run hook." }
}
})
$ubuild.DefineMethod("VerifyNuGet",
{
$this.VerifyNuGetConsistency(
("UmbracoCms", "UmbracoCms.Core"),
("Umbraco.Core", "Umbraco.Web", "Umbraco.Web.UI", "UmbracoExamine"))
if ($this.OnError()) { return }
})
$ubuild.DefineMethod("PrepareCSharpDocs",
{
Write-Host "Prepare C# Documentation"
$src = "$($this.SolutionRoot)\src"
$tmp = $this.BuildTemp
$out = $this.BuildOutput
$DocFxJson = Join-Path -Path $src "\ApiDocs\docfx.json"
$DocFxSiteOutput = Join-Path -Path $tmp "\_site\*.*"
# run DocFx
$DocFx = $this.BuildEnv.DocFx
& $DocFx metadata $DocFxJson
& $DocFx build $DocFxJson
# zip it
& $this.BuildEnv.Zip a -tzip -r "$out\csharp-docs.zip" $DocFxSiteOutput
})
$ubuild.DefineMethod("PrepareAngularDocs",
{
Write-Host "Prepare Angular Documentation"
$src = "$($this.SolutionRoot)\src"
$out = $this.BuildOutput
# Check if the solution has been built
if (!(Test-Path "$src\Umbraco.Web.UI.Client\node_modules")) {throw "Umbraco needs to be built before generating the Angular Docs"}
"Moving to Umbraco.Web.UI.Docs folder"
cd $src\Umbraco.Web.UI.Docs
"Generating the docs and waiting before executing the next commands"
& npm install
& npx gulp docs
Pop-Location
# change baseUrl
$BaseUrl = "https://our.umbraco.com/apidocs/v8/ui/"
$IndexPath = "./api/index.html"
(Get-Content $IndexPath).replace('origin + location.href.substr(origin.length).replace(rUrl, indexFile)', "`'" + $BaseUrl + "`'") | Set-Content $IndexPath
# zip it
& $this.BuildEnv.Zip a -tzip -r "$out\ui-docs.zip" "$src\Umbraco.Web.UI.Docs\api\*.*"
})
$ubuild.DefineMethod("Build",
{
$error.Clear()
$this.PrepareBuild()
if ($this.OnError()) { return }
$this.RestoreNuGet()
if ($this.OnError()) { return }
$this.CompileBelle()
if ($this.OnError()) { return }
$this.CompileUmbraco()
if ($this.OnError()) { return }
$this.PrepareTests()
if ($this.OnError()) { return }
$this.CompileTests()
if ($this.OnError()) { return }
# not running tests
$this.PreparePackages()
if ($this.OnError()) { return }
$this.PackageZip()
if ($this.OnError()) { return }
$this.VerifyNuGet()
if ($this.OnError()) { return }
$this.PrepareNuGet()
if ($this.OnError()) { return }
$this.PackageNuGet()
if ($this.OnError()) { return }
$this.PostPackageHook()
if ($this.OnError()) { return }
Write-Host "Done"
})
$ubuild.DefineMethod("PostPackageHook",
{
# run hook
if ($this.HasMethod("PostPackage"))
{
Write-Host "Run PostPackage hook"
$this.PostPackage();
if (-not $?) { throw "Failed to run hook." }
}
})
# ################################################################
# RUN
# ################################################################
# configure
$ubuild.ReleaseBranches = @( "master" )
# run
if (-not $get)
{
if ($command.Length -eq 0)
{
$command = @( "Build" )
}
$ubuild.RunMethod($command);
if ($ubuild.OnError()) { return }
}
break
}
# get build environment
Write-Host "Setup Umbraco build Environment"
$uenv = Get-UmbracoBuildEnv
# set the version if any
if (-not [string]::IsNullOrWhiteSpace($version))
{
Write-Host "Set Umbraco version to $version"
Set-UmbracoVersion $version
}
# full umbraco build
Write-Host "Build Umbraco"
Build-Umbraco
if ($get) { return $ubuild }
-18
View File
@@ -1,18 +0,0 @@
# Usage: powershell .\setversion.ps1 7.6.8
# Or: powershell .\setversion 7.6.8-beta001
param (
[Parameter(Mandatory=$true)]
[string]
$version
)
# report
Write-Host "Setting Umbraco version to $version"
# import Umbraco Build PowerShell module - $pwd is ./build
$env:PSModulePath = "$pwd\Modules\;$env:PSModulePath"
Import-Module Umbraco.Build -Force -DisableNameChecking
# run commands
$version = Set-UmbracoVersion -Version $version
+1 -1
View File
@@ -32,7 +32,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0" />
<bindingRedirect oldVersion="0.0.0.0-2.0.12.0" newVersion="2.0.12.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
+3 -3
View File
@@ -2,7 +2,7 @@
using System.Resources;
[assembly: AssemblyCompany("Umbraco")]
[assembly: AssemblyCopyright("Copyright © Umbraco 2018")]
[assembly: AssemblyCopyright("Copyright © Umbraco 2022")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -11,5 +11,5 @@ using System.Resources;
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("7.15.4")]
[assembly: AssemblyInformationalVersion("7.15.4")]
[assembly: AssemblyFileVersion("7.15.10")]
[assembly: AssemblyInformationalVersion("7.15.10")]
@@ -6,7 +6,7 @@ namespace Umbraco.Core.Configuration
{
public class UmbracoVersion
{
private static readonly Version Version = new Version("7.15.4");
private static readonly Version Version = new Version("7.15.10");
/// <summary>
/// Gets the current version of Umbraco.
@@ -259,7 +259,7 @@ namespace Umbraco.Core.Models.Identity
{
get
{
var isLocked = (LockoutEndDateUtc.HasValue && LockoutEndDateUtc.Value.ToLocalTime() >= DateTime.Now);
var isLocked = (LockoutEndDateUtc.HasValue && LockoutEndDateUtc.Value.ToLocalTime() > DateTime.Now);
return isLocked;
}
}
@@ -4,7 +4,7 @@ using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFifteenFour
{
[Migration("7.15.4", 1, Constants.System.UmbracoMigrationName)]
[Migration("7.15.5", 1, Constants.System.UmbracoMigrationName)]
public class PopulateMissingSecurityStamps : MigrationBase
{
public PopulateMissingSecurityStamps(ISqlSyntaxProvider sqlSyntax, ILogger logger) : base(sqlSyntax, logger)
@@ -205,10 +205,16 @@ ORDER BY colName";
}
public Guid CreateLoginSession(int userId, string requestingIpAddress, bool cleanStaleSessions = true)
{
//TODO: I know this doesn't follow the normal repository conventions which would require us to crete a UserSessionRepository
//and also business logic models for these objects but that's just so overkill for what we are doing
{
//TODO: I know this doesn't follow the normal repository conventions which would require us to crete a UserSessionRepository
//and also business logic models for these objects but that's just so overkill for what we are doing
//and now that everything is properly in a transaction (Scope) there doesn't seem to be much reason for using that anymore
if (cleanStaleSessions)
{
ClearLoginSessions(TimeSpan.FromDays(15));
}
var now = DateTime.UtcNow;
var dto = new UserLoginDto
{
@@ -220,11 +226,7 @@ ORDER BY colName";
SessionId = Guid.NewGuid()
};
Database.Insert(dto);
if (cleanStaleSessions)
{
ClearLoginSessions(TimeSpan.FromDays(15));
}
return dto.SessionId;
}
@@ -543,7 +543,7 @@ namespace Umbraco.Core.Security
var result = await base.SetLockoutEndDateAsync(userId, lockoutEnd);
// The way we unlock is by setting the lockoutEnd date to the current datetime
if (result.Succeeded && lockoutEnd >= DateTimeOffset.UtcNow)
if (result.Succeeded && lockoutEnd > DateTimeOffset.UtcNow)
{
RaiseAccountLockedEvent(userId);
}
@@ -16,12 +16,6 @@ namespace Umbraco.Core.Serialization
{
_settings = new JsonSerializerSettings();
//var customResolver = new CustomIgnoreResolver
// {
// DefaultMembersSearchFlags = BindingFlags.Instance | BindingFlags.Public
// };
//_settings.ContractResolver = customResolver;
var javaScriptDateTimeConverter = new JavaScriptDateTimeConverter();
_settings.Converters.Add(javaScriptDateTimeConverter);
@@ -61,7 +55,6 @@ namespace Umbraco.Core.Serialization
/// <returns></returns>
public IStreamedResult ToStream(object input)
{
var formatting = GlobalSettings.DebugMode ? Formatting.Indented : Formatting.None;
string s = JsonConvert.SerializeObject(input, Formatting.Indented, _settings);
byte[] bytes = Encoding.UTF8.GetBytes(s);
MemoryStream ms = new MemoryStream(bytes);
+3 -2
View File
@@ -55,8 +55,9 @@
<Reference Include="ImageProcessor, Version=2.7.0.100, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ImageProcessor.2.7.0.100\lib\net452\ImageProcessor.dll</HintPath>
</Reference>
<Reference Include="log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\packages\log4net.2.0.8\lib\net45-full\log4net.dll</HintPath>
<Reference Include="log4net, Version=2.0.12.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a">
<HintPath>..\packages\log4net.2.0.12\lib\net45\log4net.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Log4Net.Async, Version=2.0.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Log4Net.Async.2.0.4\lib\net40\Log4Net.Async.dll</HintPath>
+1 -1
View File
@@ -32,7 +32,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0" />
<bindingRedirect oldVersion="0.0.0.0-2.0.12.0" newVersion="2.0.12.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
+1 -1
View File
@@ -4,7 +4,7 @@
<package id="ClientDependency" version="1.9.9" targetFramework="net452" />
<package id="HtmlAgilityPack" version="1.8.8" targetFramework="net452" />
<package id="ImageProcessor" version="2.7.0.100" targetFramework="net452" />
<package id="log4net" version="2.0.8" targetFramework="net45" />
<package id="log4net" version="2.0.12" targetFramework="net452" />
<package id="Log4Net.Async" version="2.0.4" targetFramework="net45" />
<package id="Microsoft.AspNet.Identity.Core" version="2.2.2" targetFramework="net452" />
<package id="Microsoft.AspNet.Identity.Owin" version="2.2.2" targetFramework="net452" />
+1 -1
View File
@@ -12,7 +12,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0" />
<bindingRedirect oldVersion="0.0.0.0-2.0.12.0" newVersion="2.0.12.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+1 -1
View File
@@ -165,7 +165,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0" />
<bindingRedirect oldVersion="0.0.0.0-2.0.12.0" newVersion="2.0.12.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
@@ -70,7 +70,7 @@ namespace Umbraco.Tests.Services
var found = contentService.GetBlueprintsForContentTypes().ToArray();
Assert.AreEqual(1, found.Length);
//ensures it's not found by normal content
var contentFound = contentService.GetById(found[0].Id);
Assert.IsNull(contentFound);
@@ -141,7 +141,7 @@ namespace Umbraco.Tests.Services
{
var blueprint = MockedContent.CreateTextpageContent(i % 2 == 0 ? ct1 : ct2, "hello" + i, -1);
contentService.SaveBlueprint(blueprint);
}
}
var found = contentService.GetBlueprintsForContentTypes().ToArray();
Assert.AreEqual(10, found.Length);
@@ -1287,7 +1287,7 @@ namespace Umbraco.Tests.Services
Assert.That(content.Published, Is.True);
Assert.That(published, Is.True);
}
/// <summary>
/// Try to immitate a new child content item being created through the UI.
/// This content item will have no Id, Path or Identity.
@@ -1301,15 +1301,15 @@ namespace Umbraco.Tests.Services
// Arrange
var contentService = ServiceContext.ContentService;
var content = contentService.CreateContent("Home US", -1, "umbTextpage", 0);
content.SetValue("author", "Barack Obama");
content.SetValue("author", "Barack Obama");
// Act
var published = contentService.SaveAndPublish(content, 0);
var childContent = contentService.CreateContent("Child", content.Id, "umbTextpage", 0);
// Reset all identity properties
var childContent = contentService.CreateContent("Child", content.Id, "umbTextpage", 0);
// Reset all identity properties
childContent.Id = 0;
childContent.Path = null;
((Content)childContent).ResetIdentity();
childContent.Path = null;
((Content)childContent).ResetIdentity();
var childPublished = contentService.SaveAndPublish(childContent, 0);
// Assert
@@ -1492,6 +1492,44 @@ namespace Umbraco.Tests.Services
Assert.That(trashed.Any(), Is.False);
}
[Test]
public void Can_Move_Content_Structure_With_Unpublished_Parent_To_RecycleBin_And_Empty_RecycleBin()
{
// Arrange
var contentService = ServiceContext.ContentService;
var contentType = ServiceContext.ContentTypeService.GetContentType("umbTextpage");
// Publish all the content items in the tree
var content = contentService.GetById(NodeDto.NodeIdSeed + 1);
contentService.SaveAndPublishWithStatus(content, 0);
var descendants = contentService.GetDescendants(content).ToList();
foreach (var descendant in descendants)
contentService.SaveAndPublishWithStatus(descendant, 0);
var subsubpage = MockedContent.CreateSimpleContent(contentType, "Text Page 3", NodeDto.NodeIdSeed + 2);
contentService.SaveAndPublishWithStatus(subsubpage, 0);
// Unpublish only the parent - see issue https://github.com/umbraco/Umbraco-CMS/issues/8393
contentService.UnPublish(content, 0);
// Act
contentService.MoveToRecycleBin(content, 0);
descendants = contentService.GetDescendants(content).ToList();
// Assert
Assert.That(content.ParentId, Is.EqualTo(-20));
Assert.That(content.Trashed, Is.True);
Assert.That(descendants.Count, Is.EqualTo(3));
Assert.That(descendants.Any(x => x.Path.Contains("-20") == false), Is.False);
//Empty Recycle Bin
contentService.EmptyRecycleBin();
var trashed = contentService.GetContentInRecycleBin();
Assert.That(trashed.Any(), Is.False);
}
[Test]
public void Can_Empty_RecycleBin()
{
@@ -1521,14 +1559,14 @@ namespace Umbraco.Tests.Services
ServiceContext.ContentTypeService.Save(contentType);
var parentPage = MockedContent.CreateSimpleContent(contentType);
ServiceContext.ContentService.Save(parentPage);
ServiceContext.ContentService.Save(parentPage);
var childPage = MockedContent.CreateSimpleContent(contentType, "child", parentPage);
ServiceContext.ContentService.Save(childPage);
ServiceContext.ContentService.Save(childPage);
//assign explicit permissions to the child
ServiceContext.ContentService.AssignContentPermission(childPage, 'A', new[] { userGroup.Id });
//Ok, now copy, what should happen is the childPage will retain it's own permissions
ServiceContext.ContentService.AssignContentPermission(childPage, 'A', new[] { userGroup.Id });
//Ok, now copy, what should happen is the childPage will retain it's own permissions
var parentPage2 = MockedContent.CreateSimpleContent(contentType);
ServiceContext.ContentService.Save(parentPage2);
@@ -1565,7 +1603,7 @@ namespace Umbraco.Tests.Services
ServiceContext.ContentService.Save(childPage2);
var childPage3 = MockedContent.CreateSimpleContent(contentType, "child3", childPage2);
ServiceContext.ContentService.Save(childPage3);
//Verify that the children have the inherited permissions
var descendants = ServiceContext.ContentService.GetDescendants(parentPage).ToArray();
Assert.AreEqual(3, descendants.Length);
@@ -1576,7 +1614,7 @@ namespace Umbraco.Tests.Services
var allPermissions = permissions.GetAllPermissions().ToArray();
Assert.AreEqual(1, allPermissions.Length);
Assert.AreEqual("A", allPermissions[0]);
}
}
//create a new parent with a new permission structure
var parentPage2 = MockedContent.CreateSimpleContent(contentType);
@@ -1585,7 +1623,7 @@ namespace Umbraco.Tests.Services
//Now copy, what should happen is the child pages will now have permissions inherited from the new parent
var copy = ServiceContext.ContentService.Copy(childPage1, parentPage2.Id, false, true);
descendants = ServiceContext.ContentService.GetDescendants(parentPage2).ToArray();
Assert.AreEqual(3, descendants.Length);
@@ -1596,7 +1634,7 @@ namespace Umbraco.Tests.Services
Assert.AreEqual(1, allPermissions.Length);
Assert.AreEqual("B", allPermissions[0]);
}
}
}
[Test]
public void Can_Empty_RecycleBin_With_Content_That_Has_All_Related_Data()
@@ -1633,11 +1671,11 @@ namespace Umbraco.Tests.Services
var editorGroup = ServiceContext.UserService.GetUserGroupByAlias("editor");
editorGroup.StartContentId = content1.Id;
ServiceContext.UserService.Save(editorGroup);
ServiceContext.UserService.Save(editorGroup);
var admin = ServiceContext.UserService.GetUserById(0);
admin.StartContentIds = new[] {content1.Id};
ServiceContext.UserService.Save(admin);
ServiceContext.UserService.Save(admin);
ServiceContext.RelationService.Save(new RelationType(Constants.ObjectTypes.DocumentGuid, Constants.ObjectTypes.DocumentGuid, "test"));
Assert.IsNotNull(ServiceContext.RelationService.Relate(content1, content2, "test"));
@@ -2161,4 +2199,4 @@ namespace Umbraco.Tests.Services
return repository;
}
}
}
}
+3 -7
View File
@@ -30,7 +30,6 @@
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<TargetFrameworkProfile />
<NugetPackages Condition="$(NugetPackages) == '' Or $(NugetPackages) == '*Undefined*'">$(SolutionDir)\packages</NugetPackages>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
@@ -74,8 +73,9 @@
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
<Reference Include="log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\packages\log4net.2.0.8\lib\net45-full\log4net.dll</HintPath>
<Reference Include="log4net, Version=2.0.12.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a">
<HintPath>..\packages\log4net.2.0.12\lib\net45\log4net.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Log4Net.Async, Version=2.0.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Log4Net.Async.2.0.4\lib\net40\Log4Net.Async.dll</HintPath>
@@ -815,10 +815,6 @@
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
<PropertyGroup>
<PreBuildEvent>xcopy "$(NugetPackages)\SqlServerCE.4.0.0.1\amd64\*.*" "$(TargetDir)amd64\" /Y /F /E /I /C /D
xcopy "$(NugetPackages)\SqlServerCE.4.0.0.1\x86\*.*" "$(TargetDir)x86\" /Y /F /E /I /C /D</PreBuildEvent>
</PropertyGroup>
<Import Project="..\packages\AutoMapper.3.3.1\tools\AutoMapper.targets" Condition="Exists('..\packages\AutoMapper.3.3.1\tools\AutoMapper.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
+1 -1
View File
@@ -4,7 +4,7 @@
<package id="Castle.Core" version="4.0.0" targetFramework="net45" />
<package id="Examine" version="0.1.90" targetFramework="net45" />
<package id="HtmlAgilityPack" version="1.8.8" targetFramework="net452" />
<package id="log4net" version="2.0.8" targetFramework="net45" />
<package id="log4net" version="2.0.12" targetFramework="net452" />
<package id="Log4Net.Async" version="2.0.4" targetFramework="net45" />
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Identity.Core" version="2.2.2" targetFramework="net452" />
+5 -6
View File
@@ -21,15 +21,14 @@
"rgrove-lazyload": "*",
"bootstrap-social": "~4.8.0",
"jquery": "2.2.4",
"jquery-ui": "1.11.4",
"jquery-migrate": "1.4.0",
"angular-dynamic-locale": "0.1.28",
"ng-file-upload": "~7.3.8",
"tinymce": "~4.9.9",
"tinymce": "~4.9.10",
"codemirror": "~5.3.0",
"angular-local-storage": "~0.2.3",
"moment": "~2.10.3",
"ace-builds": "^1.2.3",
"ace-builds": "1.4.12",
"clipboard": "1.7.1",
"font-awesome": "~4.7"
},
@@ -42,7 +41,8 @@
"font-awesome",
"angular",
"bootstrap",
"codemirror"
"codemirror",
"ace-builds"
],
"sources": {
"moment": [
@@ -73,9 +73,8 @@
"typeahead.js": "bower_components/typeahead.js/dist/typeahead.bundle.min.js",
"rgrove-lazyload": "bower_components/rgrove-lazyload/lazyload.js",
"ng-file-upload": "bower_components/ng-file-upload/ng-file-upload.min.js",
"jquery-ui": "bower_components/jquery-ui/jquery-ui.min.js",
"jquery-migrate": "bower_components/jquery-migrate/jquery-migrate.min.js",
"clipboard": "bower_components/clipboard/dist/clipboard.min.js"
}
}
}
}
+37 -26
View File
@@ -31,7 +31,7 @@ var karmaServer = require('karma').Server;
Helper functions
***************************************************************/
function processJs(files, out) {
return gulp.src(files)
// check for js errors
.pipe(eslint())
@@ -58,7 +58,7 @@ function processLess(files, out) {
.pipe(postcss(processors))
.pipe(rename(out))
.pipe(gulp.dest(root + targets.css));
console.log(out + " compiled");
}
@@ -67,7 +67,7 @@ Paths and destinations
Each group is iterated automatically in the setup tasks below
***************************************************************/
var sources = {
//less files used by backoffice and preview
//processed in the less task
less: {
@@ -104,7 +104,7 @@ var sources = {
js: "./src/*.js",
lib: "./lib/**/*",
bower: "./lib-bower/**/*",
assets: "./src/assets/**"
assets: "./src/assets/**"
}
};
@@ -140,7 +140,7 @@ gulp.task('docserve', function(cb) {
/**************************
* Task processes and copies all dependencies, either installed by bower, npm or stored locally in the project
**************************/
gulp.task('dependencies', function () {
gulp.task('dependencies', function () {
//bower component specific copy rules
//this is to patch the sometimes wonky rules these libs are distrbuted under
@@ -163,8 +163,9 @@ gulp.task('dependencies', function () {
{ base: "./bower_components/font-awesome/" })
.pipe(gulp.dest(root + targets.lib + "/font-awesome"))
);
// ace Editor
console.log(`Copying 'ace-builds' from bower_components/ace-builds/src-min-noconflict/ to ${root + targets.lib + "/ace-builds"}`);
stream.add(
gulp.src(["bower_components/ace-builds/src-min-noconflict/ace.js",
"bower_components/ace-builds/src-min-noconflict/ext-language_tools.js",
@@ -180,6 +181,14 @@ gulp.task('dependencies', function () {
.pipe(gulp.dest(root + targets.lib + "/ace-builds"))
);
// jQuery-UI
console.log(`Copying 'jquery-ui-dist' from node_modules/jquery-ui-dist/jquery-ui.min.js/ to ${root + targets.lib + "/jquery-ui"}`);
stream.add(
gulp.src(["node_modules/jquery-ui-dist/jquery-ui.min.js"],
{ base: "./node_modules/jquery-ui-dist/" })
.pipe(gulp.dest(root + targets.lib + "/jquery-ui"))
);
// code mirror
stream.add(
gulp.src([
@@ -199,21 +208,23 @@ gulp.task('dependencies', function () {
.pipe(gulp.dest(root + targets.lib + "/codemirror"))
);
//copy over libs which are not on bower (/lib) and
//copy over libs which are not on bower (/lib) and
//libraries that have been managed by bower-installer (/lib-bower)
console.log(`Copying 'lib' ${sources.globs.lib} to ${root + targets.lib}`);
stream.add(
gulp.src(sources.globs.lib)
.pipe(gulp.dest(root + targets.lib))
);
console.log(`Copying 'bower' ${sources.globs.bower} to ${root + targets.lib}`);
stream.add(
gulp.src(sources.globs.bower)
.pipe(gulp.dest(root + targets.lib))
);
//Copies all static assets into /root / assets folder
//Copies all static assets into /root / assets folder
//css, fonts and image files
stream.add(
stream.add(
gulp.src(sources.globs.assets)
.pipe(imagemin([
imagemin.gifsicle({interlaced: true}),
@@ -231,20 +242,20 @@ gulp.task('dependencies', function () {
// Copies all the less files related to the preview into their folder
//these are not pre-processed as preview has its own less combiler client side
stream.add(
stream.add(
gulp.src("src/canvasdesigner/editors/*.less")
.pipe(gulp.dest(root + targets.assets + "/less"))
);
// Todo: check if we need these fileSize
stream.add(
stream.add(
gulp.src("src/views/propertyeditors/grid/config/*.*")
.pipe(gulp.dest(root + targets.views + "/propertyeditors/grid/config"))
);
stream.add(
);
stream.add(
gulp.src("src/views/dashboard/default/*.jpg")
.pipe(gulp.dest(root + targets.views + "/dashboard/default"))
);
);
return stream;
});
@@ -253,8 +264,8 @@ gulp.task('dependencies', function () {
/**************************
* Copies all angular JS files into their seperate umbraco.*.js file
**************************/
gulp.task('js', function () {
gulp.task('js', function () {
//we run multiple streams, so merge them all together
var stream = new MergeStream();
@@ -271,7 +282,7 @@ gulp.task('js', function () {
});
gulp.task('less', function () {
var stream = new MergeStream();
_.forEach(sources.less, function (group) {
@@ -294,9 +305,9 @@ gulp.task('views', function () {
gulp.src(group.files)
.pipe( gulp.dest(root + targets.views + group.folder) )
);
});
return stream;
});
@@ -311,13 +322,13 @@ gulp.task('watch', function () {
if(group.watch !== false){
stream.add(
stream.add(
watch(group.files, { ignoreInitial: true, interval: watchInterval }, function (file) {
console.info(file.path + " has changed, added to: " + group.out);
processJs(group.files, group.out);
})
);
@@ -326,7 +337,7 @@ gulp.task('watch', function () {
});
stream.add(
stream.add(
//watch all less files and trigger the less task
watch(sources.globs.less, { ignoreInitial: true, interval: watchInterval }, function () {
gulp.run(['less']);
@@ -334,13 +345,13 @@ gulp.task('watch', function () {
);
//watch all views - copy single file changes
stream.add(
stream.add(
watch(sources.globs.views, { interval: watchInterval })
.pipe(gulp.dest(root + targets.views))
);
//watch all app js files that will not be merged - copy single file changes
stream.add(
stream.add(
watch(sources.globs.js, { interval: watchInterval })
.pipe(gulp.dest(root + targets.js))
);
@@ -385,7 +396,7 @@ gulp.task('connect:docs', function (cb) {
});
gulp.task('open:docs', function (cb) {
var options = {
uri: 'http://localhost:8880/index.html'
};
@@ -293,6 +293,8 @@ ngMobile.directive('ngClick', ['$parse', '$timeout', '$rootElement',
* A leftward swipe is a quick, right-to-left slide of the finger.
* Though ngSwipeLeft is designed for touch-based devices, it will work with a mouse click and drag too.
*
* [well, it did until we disabled that feature to avoid problems with selecting text]
*
* @element ANY
* @param {expression} ngSwipeLeft {@link guide/expression Expression} to evaluate
* upon left swipe. (Event object is available as `$event`)
@@ -388,7 +390,7 @@ function makeSwipeDirective(directiveName, direction) {
deltaY / deltaX < MAX_VERTICAL_RATIO;
}
element.bind('touchstart mousedown', function(event) {
element.bind('touchstart', function(event) {
startCoords = getCoordinates(event);
valid = true;
totalX = 0;
@@ -401,7 +403,7 @@ function makeSwipeDirective(directiveName, direction) {
valid = false;
});
element.bind('touchmove mousemove', function(event) {
element.bind('touchmove', function(event) {
if (!valid) return;
// Android will send a touchcancel if it thinks we're starting to scroll.
@@ -440,7 +442,7 @@ function makeSwipeDirective(directiveName, direction) {
}
});
element.bind('touchend mouseup', function(event) {
element.bind('touchend', function(event) {
if (validSwipe(event)) {
// Prevent this swipe from bubbling up to any other elements with ngSwipes.
event.stopPropagation();
+43 -11
View File
@@ -4146,7 +4146,8 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"aproba": {
"version": "1.2.0",
@@ -4167,12 +4168,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"
@@ -4187,17 +4190,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",
@@ -4314,7 +4320,8 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"ini": {
"version": "1.3.5",
@@ -4326,6 +4333,7 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -4340,6 +4348,7 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -4347,12 +4356,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"
@@ -4371,6 +4382,7 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -4451,7 +4463,8 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"object-assign": {
"version": "4.1.1",
@@ -4463,6 +4476,7 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"wrappy": "1"
}
@@ -4548,7 +4562,8 @@
"safe-buffer": {
"version": "5.1.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -4584,6 +4599,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",
@@ -4603,6 +4619,7 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -4646,12 +4663,14 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"yallist": {
"version": "3.0.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
}
}
},
@@ -6867,6 +6886,19 @@
"logalot": "^2.0.0"
}
},
"jquery": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz",
"integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw=="
},
"jquery-ui-dist": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/jquery-ui-dist/-/jquery-ui-dist-1.13.1.tgz",
"integrity": "sha512-Y711Pu4BRVrAlL58KSxX4ail74jaCJZaZcdNDLava+MgZeNwmVWmyYiK7KxyoJu1MB73eSunjJvYDbOuNrOA7w==",
"requires": {
"jquery": ">=1.8.0 <4.0.0"
}
},
"js-base64": {
"version": "2.4.9",
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.9.tgz",
+3 -1
View File
@@ -4,7 +4,9 @@
"test": "karma start test/config/karma.conf.js --singlerun",
"build": "gulp"
},
"dependencies": {},
"dependencies": {
"jquery-ui-dist": "1.13.1"
},
"devDependencies": {
"autoprefixer": "^6.5.0",
"bower-installer": "^1.2.0",
Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 KiB

After

Width:  |  Height:  |  Size: 99 KiB

@@ -186,7 +186,9 @@ function listViewController($rootScope, $scope, $routeParams, $injector, $cookie
// Another special case for members, only fields on the base table (cmsMember) can be used for sorting
if (e.isSystem && $scope.entityType == "member") {
e.allowSorting = e.alias == 'username' || e.alias == 'email';
e.allowSorting = e.alias == 'username' ||
e.alias == 'email' ||
e.alias == 'updateDate';
}
if (e.isSystem) {
@@ -27,6 +27,8 @@
ng-model="$parent.tagToAdd"
ng-keydown="$parent.addTagOnEnter($event)"
on-blur="$parent.addTag()"
ng-maxlength="200"
maxlength="200"
localize="placeholder"
placeholder="@placeholders_enterTags" />
+13 -6
View File
@@ -126,8 +126,8 @@
<HintPath>..\packages\ClientDependency.1.9.9\lib\net45\ClientDependency.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="ClientDependency.Core.Mvc, Version=1.8.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ClientDependency-Mvc5.1.8.0.0\lib\net45\ClientDependency.Core.Mvc.dll</HintPath>
<Reference Include="ClientDependency.Core.Mvc, Version=1.9.3.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\packages\ClientDependency-Mvc5.1.9.3\lib\net45\ClientDependency.Core.Mvc.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="dotless.Core, Version=1.5.2.0, Culture=neutral, PublicKeyToken=96b446c9e63eae34, processorArchitecture=MSIL">
@@ -145,8 +145,9 @@
<Reference Include="ImageProcessor.Web, Version=4.10.0.100, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ImageProcessor.Web.4.10.0.100\lib\net452\ImageProcessor.Web.dll</HintPath>
</Reference>
<Reference Include="log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\packages\log4net.2.0.8\lib\net45-full\log4net.dll</HintPath>
<Reference Include="log4net, Version=2.0.12.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a">
<HintPath>..\packages\log4net.2.0.12\lib\net45\log4net.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Lucene.Net, Version=2.9.4.1, Culture=neutral, PublicKeyToken=85089178b9ac3181, processorArchitecture=MSIL">
<HintPath>..\packages\Lucene.Net.2.9.4.1\lib\net40\Lucene.Net.dll</HintPath>
@@ -1029,9 +1030,9 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\"
<WebProjectProperties>
<UseIIS>True</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>7154</DevelopmentServerPort>
<DevelopmentServerPort>71510</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:7154</IISUrl>
<IISUrl>http://localhost:71510</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
@@ -1043,6 +1044,12 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\"
</ProjectExtensions>
<Import Project="$(MSBuildProjectDirectory)\..\umbraco.presentation.targets" Condition="$(BuildingInsideVisualStudio) != true" />
<Import Project="$(SolutionDir)umbraco.presentation.targets" Condition="$(BuildingInsideVisualStudio) == true" />
<PropertyGroup Condition="$(WebPublishingTasks) == '' and Exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v17.0\Web\Microsoft.Web.Publishing.Tasks.dll')">
<WebPublishingTasks>$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v17.0\Web\Microsoft.Web.Publishing.Tasks.dll</WebPublishingTasks>
</PropertyGroup>
<PropertyGroup Condition="$(WebPublishingTasks) == '' and Exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v16.0\Web\Microsoft.Web.Publishing.Tasks.dll')">
<WebPublishingTasks>$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v16.0\Web\Microsoft.Web.Publishing.Tasks.dll</WebPublishingTasks>
</PropertyGroup>
<PropertyGroup Condition="$(WebPublishingTasks) == '' and Exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v15.0\Web\Microsoft.Web.Publishing.Tasks.dll')">
<WebPublishingTasks>$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v15.0\Web\Microsoft.Web.Publishing.Tasks.dll</WebPublishingTasks>
</PropertyGroup>
@@ -1,18 +1,18 @@
<%@ Page Language="C#" AutoEventWireup="true" Inherits="System.Web.UI.Page" %>
<%
// NH: Adds this inline check to avoid a simple codebehind file in the legacy project!
if (Request["url"].ToLower().Contains("booting.aspx") || !umbraco.cms.helpers.url.ValidateProxyUrl(Request["url"], Request.Url.AbsoluteUri))
var url = Request.QueryString["url"];
var isUrlLocal = System.Web.WebPages.RequestExtensions.IsUrlLocalToHost(null, url);
if (url.ToLower().Contains("booting.aspx") || isUrlLocal == false)
{
throw new ArgumentException("Can't redirect to the requested url - it's not local or an approved proxy url",
"url");
throw new ArgumentException("Can't redirect to the requested url - it's not local", "url");
}
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>The website is restarting</title>
<meta http-equiv="REFRESH" content="10; URL=<%=Request["url"] %>">
<meta http-equiv="REFRESH" content="10; URL=<%=url %>">
</head>
<body>
<h1>The website is restarting</h1>
+2 -2
View File
@@ -2,13 +2,13 @@
<packages>
<package id="AutoMapper" version="3.3.1" targetFramework="net45" />
<package id="ClientDependency" version="1.9.9" targetFramework="net452" />
<package id="ClientDependency-Mvc5" version="1.8.0.0" targetFramework="net45" />
<package id="ClientDependency-Mvc5" version="1.9.3" targetFramework="net452" />
<package id="dotless" version="1.5.2" targetFramework="net45" />
<package id="Examine" version="0.1.90" targetFramework="net45" />
<package id="ImageProcessor" version="2.7.0.100" targetFramework="net452" />
<package id="ImageProcessor.Web" version="4.10.0.100" targetFramework="net452" />
<package id="ImageProcessor.Web.Config" version="2.5.0.100" targetFramework="net452" />
<package id="log4net" version="2.0.8" targetFramework="net45" />
<package id="log4net" version="2.0.12" targetFramework="net452" />
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Identity.Core" version="2.2.2" targetFramework="net452" />
<package id="Microsoft.AspNet.Identity.Owin" version="2.2.2" targetFramework="net452" />
+1 -1
View File
@@ -434,7 +434,7 @@
xdt:Locator="Condition(_defaultNamespace:assemblyIdentity[@name='log4net']])" />
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0"/>
<bindingRedirect oldVersion="0.0.0.0-2.0.12.0" newVersion="2.0.12.0"/>
</dependentAssembly>
</assemblyBinding>
+1 -1
View File
@@ -432,7 +432,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0"/>
<bindingRedirect oldVersion="0.0.0.0-2.0.12.0" newVersion="2.0.12.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Data.SqlServerCe" publicKeyToken="89845DCD8080CC91" culture="neutral"/>
@@ -62,7 +62,8 @@ namespace Umbraco.Web.Cache
{
Id = x.Id,
Key = x.Key,
Operation = operationType
Operation = operationType,
IsBlueprint = x.IsBlueprint
}).ToArray();
var json = JsonConvert.SerializeObject(items);
return json;
@@ -83,6 +84,7 @@ namespace Umbraco.Web.Cache
public int Id { get; set; }
public Guid? Key { get; set; }
public OperationType Operation { get; set; }
public bool? IsBlueprint { get; set; }
}
#endregion
@@ -102,10 +104,18 @@ namespace Umbraco.Web.Cache
ClearRepositoryCacheItemById(id);
ClearAllIsolatedCacheByEntityType<PublicAccessEntry>();
content.Instance.UpdateSortOrder(id);
var d = new Document(id);
content.Instance.UpdateDocumentCache(d);
content.Instance.UpdatePreviewXmlContent(d);
DistributedCache.Instance.ClearDomainCacheOnCurrentServer();
Document d = null;
try
{
d = new Document(id);
}
catch (Exception){ } // not a document, cannot continue
if (d != null)
{
content.Instance.UpdateDocumentCache(d);
content.Instance.UpdatePreviewXmlContent(d);
DistributedCache.Instance.ClearDomainCacheOnCurrentServer();
}
base.Refresh(id);
}
@@ -124,11 +134,14 @@ namespace Umbraco.Web.Cache
{
ClearRepositoryCacheItemById(instance.Id);
ClearAllIsolatedCacheByEntityType<PublicAccessEntry>();
content.Instance.UpdateSortOrder(instance);
var d = new Document(instance);
content.Instance.UpdateDocumentCache(d);
content.Instance.UpdatePreviewXmlContent(d);
DistributedCache.Instance.ClearDomainCacheOnCurrentServer();
if (!instance.IsBlueprint)
{
content.Instance.UpdateSortOrder(instance);
var d = new Document(instance);
content.Instance.UpdateDocumentCache(d);
content.Instance.UpdatePreviewXmlContent(d);
DistributedCache.Instance.ClearDomainCacheOnCurrentServer();
}
base.Refresh(instance);
}
@@ -136,9 +149,12 @@ namespace Umbraco.Web.Cache
{
ApplicationContext.Current.Services.IdkMap.ClearCache(instance.Id);
ClearRepositoryCacheItemById(instance.Id);
ClearAllIsolatedCacheByEntityType<PublicAccessEntry>();
DistributedCache.Instance.ClearDomainCacheOnCurrentServer();
content.Instance.ClearPreviewXmlContent(instance.Id);
if (!instance.IsBlueprint)
{
ClearAllIsolatedCacheByEntityType<PublicAccessEntry>();
DistributedCache.Instance.ClearDomainCacheOnCurrentServer();
content.Instance.ClearPreviewXmlContent(instance.Id);
}
base.Remove(instance);
}
@@ -164,11 +180,31 @@ namespace Umbraco.Web.Cache
}
if (payload.Operation == OperationType.Refresh)
{
content.Instance.UpdateSortOrder(payload.Id);
var d = new Document(payload.Id);
content.Instance.UpdateDocumentCache(d);
content.Instance.UpdatePreviewXmlContent(d);
{
if (!payload.IsBlueprint.HasValue)
{
// if this is null (since it was added later) then we need to try/catch since we don't know what it is
Document d = null;
try
{
d = new Document(payload.Id);
}
catch (Exception) { } // not a document, cannot continue
if (d != null)
{
content.Instance.UpdateSortOrder(payload.Id);
content.Instance.UpdateDocumentCache(d);
content.Instance.UpdatePreviewXmlContent(d);
}
}
else if (!payload.IsBlueprint.Value)
{
// if it's not a blueprint, then need to refresh the published cache
var d = new Document(payload.Id);
content.Instance.UpdateSortOrder(payload.Id);
content.Instance.UpdateDocumentCache(d);
content.Instance.UpdatePreviewXmlContent(d);
}
base.Refresh(payload.Id);
}
+13 -16
View File
@@ -85,7 +85,7 @@ namespace Umbraco.Web.Editors
Core.Constants.Security.BackOfficeAuthenticationType,
Core.Constants.Security.BackOfficeExternalAuthenticationType);
}
if (invite == null)
{
Logger.Warn<BackOfficeController>("VerifyUser endpoint reached with invalid token: NULL");
@@ -143,10 +143,10 @@ namespace Umbraco.Web.Editors
}
/// <summary>
/// This Action is used by the installer when an upgrade is detected but the admin user is not logged in. We need to
/// This Action is used by the installer when an upgrade is detected but the admin user is not logged in. We need to
/// ensure the user is authenticated before the install takes place so we redirect here to show the standard login screen.
/// </summary>
/// <returns></returns>
/// <returns></returns>
[HttpGet]
public async Task<ActionResult> AuthorizeUpgrade()
{
@@ -177,7 +177,6 @@ namespace Umbraco.Web.Editors
//the dictionary returned is fine but the delimiter between an 'area' and a 'value' is a '/' but the javascript
// in the back office requres the delimiter to be a '_' so we'll just replace it
.ToDictionary(key => key.Key.Replace("/", "_"), val => val.Value);
var formatting = GlobalSettings.DebugMode ? Formatting.Indented : Formatting.None;
return new JsonNetResult { Data = textForCulture, Formatting = Formatting.Indented };
}
@@ -230,7 +229,6 @@ namespace Umbraco.Web.Editors
typeof(BackOfficeController) + "GetManifestAssetList",
() => getResult(),
new TimeSpan(0, 10, 0));
var formatting = GlobalSettings.DebugMode ? Formatting.Indented : Formatting.None;
return new JsonNetResult { Data = result, Formatting = Formatting.Indented };
}
@@ -244,11 +242,10 @@ namespace Umbraco.Web.Editors
new DirectoryInfo(Server.MapPath(SystemDirectories.AppPlugins)),
new DirectoryInfo(Server.MapPath(SystemDirectories.Config)),
HttpContext.IsDebuggingEnabled);
var formatting = GlobalSettings.DebugMode ? Formatting.Indented : Formatting.None;
return new JsonNetResult { Data = gridConfig.EditorsConfig.Editors, Formatting = Formatting.Indented };
}
/// <summary>
/// Returns the JavaScript object representing the static server variables javascript object
@@ -271,7 +268,7 @@ namespace Umbraco.Web.Editors
return JavaScript(result);
}
[HttpPost]
public ActionResult ExternalLogin(string provider, string redirectUrl = null)
@@ -341,10 +338,10 @@ namespace Umbraco.Web.Editors
}
/// <summary>
/// Used by Default and AuthorizeUpgrade to render as per normal if there's no external login info,
/// Used by Default and AuthorizeUpgrade to render as per normal if there's no external login info,
/// otherwise process the external login info.
/// </summary>
/// <returns></returns>
/// <returns></returns>
private async Task<ActionResult> RenderDefaultOrProcessExternalLoginAsync(
Func<ActionResult> defaultResponse,
Func<ActionResult> externalSignInResponse)
@@ -384,9 +381,9 @@ namespace Umbraco.Web.Editors
ExternalSignInAutoLinkOptions autoLinkOptions = null;
//Here we can check if the provider associated with the request has been configured to allow
// new users (auto-linked external accounts). This would never be used with public providers such as
// new users (auto-linked external accounts). This would never be used with public providers such as
// Google, unless you for some reason wanted anybody to be able to access the backend if they have a Google account
// .... not likely!
// .... not likely!
var authType = OwinContext.Authentication.GetExternalAuthenticationTypes().FirstOrDefault(x => x.AuthenticationType == loginInfo.Login.LoginProvider);
if (authType == null)
{
@@ -401,10 +398,10 @@ namespace Umbraco.Web.Editors
var user = await UserManager.FindAsync(loginInfo.Login);
if (user != null)
{
//TODO: It might be worth keeping some of the claims associated with the ExternalLoginInfo, in which case we
// wouldn't necessarily sign the user in here with the standard login, instead we'd update the
//TODO: It might be worth keeping some of the claims associated with the ExternalLoginInfo, in which case we
// wouldn't necessarily sign the user in here with the standard login, instead we'd update the
// UseUmbracoBackOfficeExternalCookieAuthentication extension method to have the correct provider and claims factory,
// ticket format, etc.. to create our back office user including the claims assigned and in this method we'd just ensure
// ticket format, etc.. to create our back office user including the claims assigned and in this method we'd just ensure
// that the ticket is created and stored and that the user is logged in.
var shouldSignIn = true;
@@ -477,7 +474,7 @@ namespace Umbraco.Web.Editors
{
autoLinkUser.AddRole(userGroup.Alias);
}
//call the callback if one is assigned
if (autoLinkOptions.OnAutoLinking != null)
{
+17 -16
View File
@@ -62,11 +62,11 @@ namespace Umbraco.Web.Editors
{
}
public UsersController(UmbracoContext umbracoContext, UmbracoHelper umbracoHelper, BackOfficeUserManager<BackOfficeIdentityUser> backOfficeUserManager)
public UsersController(UmbracoContext umbracoContext, UmbracoHelper umbracoHelper, BackOfficeUserManager<BackOfficeIdentityUser> backOfficeUserManager)
: base(umbracoContext, umbracoHelper, backOfficeUserManager)
{
}
/// <summary>
/// Returns a list of the sizes of gravatar urls for the user or null if the gravatar server cannot be reached
/// </summary>
@@ -122,8 +122,9 @@ namespace Umbraco.Web.Editors
var fileName = file.Headers.ContentDisposition.FileName.Trim(new[] { '\"' }).TrimEnd();
var safeFileName = fileName.ToSafeFileName();
var ext = safeFileName.Substring(safeFileName.LastIndexOf('.') + 1).ToLower();
const string allowedAvatarFileTypes = "jpeg,jpg,gif,bmp,png,tiff,tif,webp";
if (UmbracoConfig.For.UmbracoSettings().Content.DisallowedUploadFiles.Contains(ext) == false)
if (allowedAvatarFileTypes.Contains(ext) == true && UmbracoConfig.For.UmbracoSettings().Content.DisallowedUploadFiles.Contains(ext) == false)
{
//generate a path of known data, we don't want this path to be guessable
user.Avatar = "UserAvatars/" + (user.Id + safeFileName).ToSHA1() + "." + ext;
@@ -156,7 +157,7 @@ namespace Umbraco.Web.Editors
var filePath = found.Avatar;
//if the filePath is already null it will mean that the user doesn't have a custom avatar and their gravatar is currently
//being used (if they have one). This means they want to remove their gravatar too which we can do by setting a special value
//being used (if they have one). This means they want to remove their gravatar too which we can do by setting a special value
//for the avatar.
if (filePath.IsNullOrWhiteSpace() == false)
{
@@ -279,7 +280,7 @@ namespace Umbraco.Web.Editors
{
throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState));
}
if (UmbracoConfig.For.UmbracoSettings().Security.UsernameIsEmail)
{
//ensure they are the same if we're using it
@@ -348,7 +349,7 @@ namespace Umbraco.Web.Editors
/// <summary>
/// Invites a user
/// </summary>
/// <param name="userSave"></param>
/// <param name="userSave"></param>
/// <returns></returns>
/// <remarks>
/// This will email the user an invite and generate a token that will be validated in the email
@@ -364,7 +365,7 @@ namespace Umbraco.Web.Editors
{
throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState));
}
if (EmailSender.CanSendRequiredEmail == false)
{
throw new HttpResponseException(
@@ -383,7 +384,7 @@ namespace Umbraco.Web.Editors
user = CheckUniqueUsername(userSave.Username, u => u.LastLoginDate != default(DateTime) || u.EmailConfirmedDate.HasValue);
}
user = CheckUniqueEmail(userSave.Email, u => u.LastLoginDate != default(DateTime) || u.EmailConfirmedDate.HasValue);
//Perform authorization here to see if the current user can actually save this user with the info being requested
var authHelper = new UserEditorAuthorizationHelper(Services.ContentService, Services.MediaService, Services.UserService, Services.EntityService);
var canSaveUser = authHelper.IsAuthorized(Security.CurrentUser, user, null, null, userSave.UserGroups);
@@ -534,7 +535,7 @@ namespace Umbraco.Web.Editors
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.Unauthorized, canSaveUser.Result));
}
var hasErrors = false;
var existing = Services.UserService.GetByEmail(userSave.Email);
@@ -570,7 +571,7 @@ namespace Umbraco.Web.Editors
{
userSave.Username = userSave.Email;
}
if (userSave.ChangePassword != null)
{
var passwordChanger = new PasswordChanger(Logger, Services.UserService, UmbracoContext.HttpContext);
@@ -579,7 +580,7 @@ namespace Umbraco.Web.Editors
var passwordChangeResult = await passwordChanger.ChangePasswordWithIdentityAsync(Security.CurrentUser, found, userSave.ChangePassword, UserManager);
if (passwordChangeResult.Success)
{
//need to re-get the user
//need to re-get the user
found = Services.UserService.GetUserById(intId.Result);
}
else
@@ -602,7 +603,7 @@ namespace Umbraco.Web.Editors
Services.UserService.Save(user);
var display = Mapper.Map<UserDisplay>(user);
display.AddSuccessNotification(Services.TextService.Localize("speechBubbles/operationSavedHeader"), Services.TextService.Localize("speechBubbles/editUserSaved"));
return display;
}
@@ -659,7 +660,7 @@ namespace Umbraco.Web.Editors
}
return Request.CreateNotificationSuccessResponse(
Services.TextService.Localize("speechBubbles/enableUserSuccess", new[] { users[0].Name }));
Services.TextService.Localize("speechBubbles/enableUserSuccess", new[] { users[0].Name }));
}
/// <summary>
@@ -682,7 +683,7 @@ namespace Umbraco.Web.Editors
}
var user = await UserManager.FindByIdAsync(userIds[0]);
return Request.CreateNotificationSuccessResponse(
Services.TextService.Localize("speechBubbles/unlockUserSuccess", new[] { user.Name }));
Services.TextService.Localize("speechBubbles/unlockUserSuccess", new[] { user.Name }));
}
foreach (var u in userIds)
@@ -743,7 +744,7 @@ namespace Umbraco.Web.Editors
var userName = user.Name;
Services.UserService.Delete(user, true);
return Request.CreateNotificationSuccessResponse(
Services.TextService.Localize("speechBubbles/deleteUserSuccess", new[] { userName }));
}
@@ -761,6 +762,6 @@ namespace Umbraco.Web.Editors
[DataMember(Name = "userStates")]
public IDictionary<UserState, int> UserStates { get; set; }
}
}
}
@@ -53,7 +53,7 @@ namespace Umbraco.Web.Models.Mapping
.ForMember(basic => basic.Icon, expression => expression.UseValue("icon-user"))
.ForMember(basic => basic.Path, expression => expression.UseValue(""))
.ForMember(basic => basic.ParentId, expression => expression.UseValue(-1))
.ForMember(basic => basic.Alias, expression => expression.MapFrom(user => user.Username))
.ForMember(basic => basic.Alias, expression => expression.MapFrom(user => user.Key.ToString()))
.ForMember(dto => dto.Trashed, expression => expression.Ignore())
.ForMember(x => x.AdditionalData, expression => expression.Ignore());
@@ -95,7 +95,7 @@ namespace Umbraco.Web.Trees
menu.Items.Add<ActionNew>(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias)));
menu.Items.Add(new MenuItem("rename", Services.TextService.Localize(String.Format("actions/{0}", "rename")))
menu.Items.Add(new MenuItem("rename", Services.TextService.Localize(String.Format("actions/rename")))
{
Icon = "icon icon-edit"
});
+144 -144
View File
@@ -1,149 +1,149 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Formatting;
using AutoMapper;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Web.Models.Trees;
using Umbraco.Web.Mvc;
using Umbraco.Web.WebApi.Filters;
using umbraco.BusinessLogic.Actions;
using Umbraco.Core.Services;
using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.Search;
using Constants = Umbraco.Core.Constants;
namespace Umbraco.Web.Trees
{
[UmbracoTreeAuthorize(Constants.Trees.DataTypes)]
[Tree(Constants.Applications.Developer, Constants.Trees.DataTypes, null, sortOrder:1)]
[PluginController("UmbracoTrees")]
[CoreTree]
public class DataTypeTreeController : TreeController, ISearchableTree
{
protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings)
{
var intId = id.TryConvertTo<int>();
if (intId == false) throw new InvalidOperationException("Id must be an integer");
var nodes = new TreeNodeCollection();
//Folders first
nodes.AddRange(
Services.EntityService.GetChildren(intId.Result, UmbracoObjectTypes.DataTypeContainer)
.OrderBy(entity => entity.Name)
.Select(dt =>
{
var node = CreateTreeNode(dt, Constants.ObjectTypes.DataTypeGuid, id, queryStrings, "icon-folder", dt.HasChildren());
node.Path = dt.Path;
node.NodeType = "container";
//TODO: This isn't the best way to ensure a noop process for clicking a node but it works for now.
node.AdditionalData["jsClickCallback"] = "javascript:void(0);";
return node;
}));
//if the request is for folders only then just return
if (queryStrings["foldersonly"].IsNullOrWhiteSpace() == false && queryStrings["foldersonly"] == "1") return nodes;
//System ListView nodes
var systemListViewDataTypeIds = GetNonDeletableSystemListViewDataTypeIds();
nodes.AddRange(
Services.EntityService.GetChildren(intId.Result, UmbracoObjectTypes.DataType)
.OrderBy(entity => entity.Name)
.Select(dt =>
{
var node = CreateTreeNode(dt.Id.ToInvariantString(), id, queryStrings, dt.Name, "icon-autofill", false);
node.Path = dt.Path;
if (systemListViewDataTypeIds.Contains(dt.Id))
{
node.Icon = "icon-thumbnail-list";
}
return node;
}));
return nodes;
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Formatting;
using AutoMapper;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Web.Models.Trees;
using Umbraco.Web.Mvc;
using Umbraco.Web.WebApi.Filters;
using umbraco.BusinessLogic.Actions;
using Umbraco.Core.Services;
using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.Search;
using Constants = Umbraco.Core.Constants;
/// <summary>
/// Get all integer identifiers for the non-deletable system datatypes.
/// </summary>
private static IEnumerable<int> GetNonDeletableSystemDataTypeIds()
namespace Umbraco.Web.Trees
{
[UmbracoTreeAuthorize(Constants.Trees.DataTypes)]
[Tree(Constants.Applications.Developer, Constants.Trees.DataTypes, null, sortOrder:1)]
[PluginController("UmbracoTrees")]
[CoreTree]
public class DataTypeTreeController : TreeController, ISearchableTree
{
protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings)
{
var intId = id.TryConvertTo<int>();
if (intId == false) throw new InvalidOperationException("Id must be an integer");
var nodes = new TreeNodeCollection();
//Folders first
nodes.AddRange(
Services.EntityService.GetChildren(intId.Result, UmbracoObjectTypes.DataTypeContainer)
.OrderBy(entity => entity.Name)
.Select(dt =>
{
var node = CreateTreeNode(dt, Constants.ObjectTypes.DataTypeGuid, id, queryStrings, "icon-folder", dt.HasChildren());
node.Path = dt.Path;
node.NodeType = "container";
//TODO: This isn't the best way to ensure a noop process for clicking a node but it works for now.
node.AdditionalData["jsClickCallback"] = "javascript:void(0);";
return node;
}));
//if the request is for folders only then just return
if (queryStrings["foldersonly"].IsNullOrWhiteSpace() == false && queryStrings["foldersonly"] == "1") return nodes;
//System ListView nodes
var systemListViewDataTypeIds = GetNonDeletableSystemListViewDataTypeIds();
nodes.AddRange(
Services.EntityService.GetChildren(intId.Result, UmbracoObjectTypes.DataType)
.OrderBy(entity => entity.Name)
.Select(dt =>
{
var node = CreateTreeNode(dt.Id.ToInvariantString(), id, queryStrings, dt.Name, "icon-autofill", false);
node.Path = dt.Path;
if (systemListViewDataTypeIds.Contains(dt.Id))
{
node.Icon = "icon-thumbnail-list";
}
return node;
}));
return nodes;
}
/// <summary>
/// Get all integer identifiers for the non-deletable system datatypes.
/// </summary>
private static IEnumerable<int> GetNonDeletableSystemDataTypeIds()
{
var systemIds = new[]
{
Constants.System.DefaultLabelDataTypeId
};
return systemIds.Concat(GetNonDeletableSystemListViewDataTypeIds());
}
{
Constants.System.DefaultLabelDataTypeId
};
/// <summary>
/// Get all integer identifiers for the non-deletable system listviews.
/// </summary>
private static IEnumerable<int> GetNonDeletableSystemListViewDataTypeIds()
{
return new[]
{
Constants.System.DefaultContentListViewDataTypeId,
Constants.System.DefaultMediaListViewDataTypeId,
Constants.System.DefaultMembersListViewDataTypeId
};
}
protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings)
{
var menu = new MenuItemCollection();
if (id == Constants.System.Root.ToInvariantString())
{
//set the default to create
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
// root actions
menu.Items.Add<ActionNew>(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}"));
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize($"actions/{ActionRefresh.Instance.Alias}"), hasSeparator: true);
return menu;
}
var container = Services.EntityService.Get(int.Parse(id), UmbracoObjectTypes.DataTypeContainer);
if (container != null)
{
//set the default to create
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
menu.Items.Add<ActionNew>(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}"));
menu.Items.Add(new MenuItem("rename", Services.TextService.Localize("actions/rename"))
{
Icon = "icon icon-edit"
});
if (container.HasChildren() == false)
//can delete data type
menu.Items.Add<ActionDelete>(Services.TextService.Localize($"actions/{ActionDelete.Instance.Alias}"));
return systemIds.Concat(GetNonDeletableSystemListViewDataTypeIds());
}
/// <summary>
/// Get all integer identifiers for the non-deletable system listviews.
/// </summary>
private static IEnumerable<int> GetNonDeletableSystemListViewDataTypeIds()
{
return new[]
{
Constants.System.DefaultContentListViewDataTypeId,
Constants.System.DefaultMediaListViewDataTypeId,
Constants.System.DefaultMembersListViewDataTypeId
};
}
protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings)
{
var menu = new MenuItemCollection();
if (id == Constants.System.Root.ToInvariantString())
{
//set the default to create
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
// root actions
menu.Items.Add<ActionNew>(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}"));
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize($"actions/{ActionRefresh.Instance.Alias}"), hasSeparator: true);
}
else
{
var nonDeletableSystemDataTypeIds = GetNonDeletableSystemDataTypeIds();
if (nonDeletableSystemDataTypeIds.Contains(int.Parse(id)) == false)
menu.Items.Add<ActionDelete>(Services.TextService.Localize($"actions/{ActionDelete.Instance.Alias}"));
menu.Items.Add<ActionMove>(Services.TextService.Localize($"actions/{ActionMove.Instance.Alias}"), hasSeparator: true);
}
return menu;
}
public IEnumerable<SearchResultItem> Search(string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null)
{
var results = Services.EntityService.GetPagedDescendantsFromRoot(UmbracoObjectTypes.DataType, pageIndex, pageSize, out totalFound, filter: query);
return Mapper.Map<IEnumerable<SearchResultItem>>(results);
}
}
}
return menu;
}
var container = Services.EntityService.Get(int.Parse(id), UmbracoObjectTypes.DataTypeContainer);
if (container != null)
{
//set the default to create
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
menu.Items.Add<ActionNew>(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}"));
menu.Items.Add(new MenuItem("rename", Services.TextService.Localize("actions/rename"))
{
Icon = "icon icon-edit"
});
if (container.HasChildren() == false)
//can delete data type
menu.Items.Add<ActionDelete>(Services.TextService.Localize($"actions/{ActionDelete.Instance.Alias}"));
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize($"actions/{ActionRefresh.Instance.Alias}"), hasSeparator: true);
}
else
{
var nonDeletableSystemDataTypeIds = GetNonDeletableSystemDataTypeIds();
if (nonDeletableSystemDataTypeIds.Contains(int.Parse(id)) == false)
menu.Items.Add<ActionDelete>(Services.TextService.Localize($"actions/{ActionDelete.Instance.Alias}"));
menu.Items.Add<ActionMove>(Services.TextService.Localize($"actions/{ActionMove.Instance.Alias}"), hasSeparator: true);
}
return menu;
}
public IEnumerable<SearchResultItem> Search(string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null)
{
var results = Services.EntityService.GetPagedDescendantsFromRoot(UmbracoObjectTypes.DataType, pageIndex, pageSize, out totalFound, filter: query);
return Mapper.Map<IEnumerable<SearchResultItem>>(results);
}
}
}
@@ -88,7 +88,7 @@ namespace Umbraco.Web.Trees
menu.Items.Add<ActionNew>(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias)));
menu.Items.Add(new MenuItem("rename", Services.TextService.Localize(String.Format("actions/{0}", "rename")))
menu.Items.Add(new MenuItem("rename", Services.TextService.Localize(String.Format("actions/rename")))
{
Icon = "icon icon-edit"
});
+1 -1
View File
@@ -69,7 +69,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0" />
<bindingRedirect oldVersion="0.0.0.0-2.0.12.0" newVersion="2.0.12.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
@@ -306,6 +306,9 @@ namespace umbraco
// note that some threads could read from it while we hold the lock, though
using (var safeXml = GetSafeXmlWriter())
{
if (safeXml.IsWriter == false)
safeXml.UpgradeToWriter();
safeXml.Xml = PublishNodeDo(d, safeXml.Xml, true);
safeXml.AcceptChanges();
}
+1 -1
View File
@@ -32,7 +32,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0" />
<bindingRedirect oldVersion="0.0.0.0-2.0.12.0" newVersion="2.0.12.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
+1 -1
View File
@@ -44,7 +44,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0" />
<bindingRedirect oldVersion="0.0.0.0-2.0.12.0" newVersion="2.0.12.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
+1 -1
View File
@@ -32,7 +32,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0" />
<bindingRedirect oldVersion="0.0.0.0-2.0.12.0" newVersion="2.0.12.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
+1 -1
View File
@@ -32,7 +32,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0" />
<bindingRedirect oldVersion="0.0.0.0-2.0.12.0" newVersion="2.0.12.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
+3
View File
@@ -38,6 +38,9 @@ namespace umbraco.cms.helpers
return false;
}
if (url.StartsWith("'"))
return false;
if (url.StartsWith("//"))
return false;
+1 -1
View File
@@ -32,7 +32,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0" />
<bindingRedirect oldVersion="0.0.0.0-2.0.12.0" newVersion="2.0.12.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
+1 -1
View File
@@ -32,7 +32,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0" />
<bindingRedirect oldVersion="0.0.0.0-2.0.12.0" newVersion="2.0.12.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
+1 -1
View File
@@ -53,7 +53,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0" />
<bindingRedirect oldVersion="0.0.0.0-2.0.12.0" newVersion="2.0.12.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
+1 -1
View File
@@ -32,7 +32,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0" />
<bindingRedirect oldVersion="0.0.0.0-2.0.12.0" newVersion="2.0.12.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>