Merge remote-tracking branch 'origin/dev-v8' into temp8-temp-gather-url-for-list-items
# Conflicts: # src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/list/list.listviewlayout.controller.js
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
_Looking for Umbraco version 8? [Click here](https://github.com/umbraco/Umbraco-CMS/blob/temp8/.github/V8_GETTING_STARTED.md) to go to the v8 branch_
|
||||
_Looking for Umbraco version 8? [Click here](https://github.com/umbraco/Umbraco-CMS/blob/dev-v8/.github/V8_GETTING_STARTED.md) to go to the v8 branch_
|
||||
# Contributing to Umbraco CMS
|
||||
|
||||
👍🎉 First off, thanks for taking the time to contribute! 🎉👍
|
||||
|
||||
@@ -103,11 +103,9 @@ There's two big areas that you should know about:
|
||||
1. The Umbraco backoffice is a extensible AngularJS app and requires you to run a `gulp dev` command while you're working with it, so changes are copied over to the appropriate directories and you can refresh your browser to view the results of your changes.
|
||||
You may need to run the following commands to set up gulp properly:
|
||||
```
|
||||
npm cache clean
|
||||
npm install -g gulp
|
||||
npm install -g gulp-cli
|
||||
npm cache clean --force
|
||||
npm install
|
||||
gulp build
|
||||
npm run build
|
||||
```
|
||||
2. "The rest" is a C# based codebase, with some traces of our WebForms past but mostly ASP.NET MVC based these days. You can make changes, build them in Visual Studio, and hit `F5` to see the result.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
- [ ] I have added steps to test this contribution in the description below
|
||||
|
||||
If there's an existing issue for this PR then this fixes: <!-- link to the issue here! -->
|
||||
If there's an existing issue for this PR then this fixes <!-- link to the issue here! -->
|
||||
|
||||
### Description
|
||||
<!-- A description of the changes proposed in the pull-request and how to test these changes -->
|
||||
|
||||
+5
-3
@@ -1,7 +1,9 @@
|
||||
_You are browsing the Umbraco v8 branch. Umbraco 8 is currently under development._
|
||||
[](https://pullreminders.com?ref=badge)
|
||||
[](https://umbraco.visualstudio.com/Umbraco%20Cms/_build?definitionId=75) [](https://pullreminders.com?ref=badge)
|
||||
|
||||
_Looking for Umbraco version 7? [Click here](https://github.com/umbraco/Umbraco-CMS) to go to the v7 branch._
|
||||
|
||||
_You are browsing the Umbraco v8 branch. Umbraco 8 is currently under development._
|
||||
|
||||
_Looking for Umbraco version 7? [Click here](https://github.com/umbraco/Umbraco-CMS/tree/dev-v7) to go to the v7 branch._
|
||||
|
||||
_Ready to try out Version 8? [See the quick start guide](V8_GETTING_STARTED.md)._
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* [Visual Studio 2017 Community (Free)](https://www.visualstudio.com/vs/community/), or Professional, Enterprise, etc... _(**Minimum of Version 15.7** or higher, this is important, you WILL get issues with lesser versions)_
|
||||
* .NET Framework 4.7.2 installed, get it here: https://www.microsoft.com/net/download/thank-you/net472?survey=false
|
||||
* .NET Framework 4.7.2 developer pack, get it here: https://www.microsoft.com/net/download/thank-you/net472-developer-pack _(be sure this is the ENU file which will be named `NDP472-DevPack-ENU.exe`)_
|
||||
* Clone the Umbraco repository using the `temp8` branch. If your git client doesn't support specifying the branch as you clone then use the command `git clone --single-branch -b temp8 <your fork url>`. _(If you clone the repo using the default v7 branch and then checkout the `temp8` branch you **might** get problems)_
|
||||
* Clone the Umbraco repository using the `dev-v8` branch. If your git client doesn't support specifying the branch as you clone then use the command `git clone --single-branch -b dev-v8 <your fork url>`. _(If you clone the repo using the default v7 branch and then checkout the `dev-v8` branch you **might** get problems)_
|
||||
|
||||
### Start the solution
|
||||
|
||||
|
||||
+161
-158
@@ -1,160 +1,163 @@
|
||||
#
|
||||
# Umbraco Cms Git Ignore
|
||||
#
|
||||
|
||||
# common files
|
||||
*.obj
|
||||
*.pdb
|
||||
*.user
|
||||
*.aps
|
||||
*.pch
|
||||
*.vspscc
|
||||
*.orig
|
||||
*.suo
|
||||
*.vs10x
|
||||
*.ndproj
|
||||
#
|
||||
# Umbraco Cms Git Ignore
|
||||
#
|
||||
|
||||
# common files
|
||||
*.obj
|
||||
*.pdb
|
||||
*.user
|
||||
*.aps
|
||||
*.pch
|
||||
*.vspscc
|
||||
*.orig
|
||||
*.suo
|
||||
*.vs10x
|
||||
*.ndproj
|
||||
*.ignorer.*
|
||||
|
||||
# common directories
|
||||
.DS_Store
|
||||
._.DS_Store
|
||||
.vs/
|
||||
/local/
|
||||
|
||||
# build directories
|
||||
[Bb]in/
|
||||
[Db]ebug*/
|
||||
[Rr]elease*/
|
||||
obj/
|
||||
|
||||
# tools
|
||||
_ReSharper*/
|
||||
_NCrunch_*/
|
||||
*.ncrunchsolution
|
||||
*.ncrunchsolution.user
|
||||
*.ncrunchproject
|
||||
*.crunchsolution.cache
|
||||
tools/NDepend/
|
||||
|
||||
|
||||
|
||||
|
||||
[Tt]est[Rr]esult*
|
||||
[Bb]uild[Ll]og.*
|
||||
*.[Pp]ublish.xml
|
||||
[sS]ource
|
||||
[sS]andbox
|
||||
umbraco.config
|
||||
App_Data/TEMP/*
|
||||
[Uu]mbraco/[Pp]resentation/[Uu]mbraco/[Pp]lugins/*
|
||||
[Uu]mbraco/[Pp]resentation/[Uu]ser[Cc]ontrols/*
|
||||
[Uu]mbraco/[Pp]resentation/[Ss]cripts/*
|
||||
[Uu]mbraco/[Pp]resentation/[Ff]onts/*
|
||||
[Uu]mbraco/[Pp]resentation/[Cc]ss/*
|
||||
|
||||
src/Umbraco.Web.UI/[Cc]ss/*
|
||||
src/Umbraco.Web.UI/App_Code/*
|
||||
src/Umbraco.Web.UI/App_Data/*
|
||||
src/Umbraco.Tests/App_Data/*
|
||||
src/Umbraco.Web.UI/[Mm]edia/*
|
||||
src/Umbraco.Web.UI/[Mm]aster[Pp]ages/*
|
||||
src/Umbraco.Web.UI/[Mm]acro[Ss]cripts/*
|
||||
!src/Umbraco.Web.UI/[Mm]acro[Ss]cripts/[Ww]eb.[Cc]onfig
|
||||
src/Umbraco.Web.UI/[Xx]slt/*
|
||||
src/Umbraco.Web.UI/[Ii]mages/*
|
||||
src/Umbraco.Web.UI/[Ss]cripts/*
|
||||
src/Umbraco.Web.UI/Web.*.config.transformed
|
||||
|
||||
umbraco/presentation/umbraco/plugins/uComponents/uComponentsInstaller.ascx
|
||||
umbraco/presentation/packages/uComponents/MultiNodePicker/CustomTreeService.asmx
|
||||
|
||||
src/Umbraco.Tests/config/applications.config
|
||||
src/Umbraco.Tests/config/trees.config
|
||||
src/Umbraco.Web.UI/web.config
|
||||
src/Umbraco.Web.UI/[Cc]onfig/ClientDependency.config
|
||||
src/Umbraco.Tests/config/404handlers.config
|
||||
src/Umbraco.Web.UI/[Vv]iews/*.cshtml
|
||||
src/Umbraco.Web.UI/[Vv]iews/*.vbhtml
|
||||
src/Umbraco.Tests/[Cc]onfig/umbracoSettings.config
|
||||
src/Umbraco.Web.UI/[Vv]iews/*
|
||||
src/packages/
|
||||
src/packages/repositories.config
|
||||
|
||||
src/Umbraco.Web.UI/[Ww]eb.config
|
||||
*.transformed
|
||||
|
||||
node_modules
|
||||
lib-bower
|
||||
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Ll]ib/*
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/umbraco.*
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/*.loader.js
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/init.js
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/routes.js
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/app.dev.js
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/loader.js
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/loader.dev.js
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/main.js
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/app.js
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/canvasdesigner.*.js
|
||||
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Vv]iews/
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Vv]iews/**/*.js
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Vv]iews/**/*.css
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Vv]iews/**/*.html
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Aa]ssets/*
|
||||
src/Umbraco.Web.UI.Client/[Bb]uild/*
|
||||
src/Umbraco.Web.UI.Client/[Bb]uild/[Bb]elle/
|
||||
src/Umbraco.Web.UI/[Uu]ser[Cc]ontrols/
|
||||
|
||||
src/Umbraco.Web.UI.Client/src/[Ll]ess/*.css
|
||||
src/Umbraco.Web.UI.Client/vwd.webinfo
|
||||
|
||||
src/Umbraco.Web.UI/App_Plugins/*
|
||||
src/*.psess
|
||||
src/*.vspx
|
||||
|
||||
NDependOut/*
|
||||
QueryResult.htm
|
||||
|
||||
src/Umbraco.Web.UI/[Cc]onfig/appSettings.config
|
||||
src/Umbraco.Web.UI/[Cc]onfig/connectionStrings.config
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/plugins/*
|
||||
build/ApiDocs/*
|
||||
build/ApiDocs/Output/*
|
||||
src/Umbraco.Web.UI.Client/bower_components/*
|
||||
/src/Umbraco.Web.UI/[Uu]mbraco/preview
|
||||
/src/Umbraco.Web.UI/[Uu]mbraco/preview.old
|
||||
|
||||
# ignore rule for clearing out Belle (avoid rebuilding all the time)
|
||||
preserve.belle
|
||||
|
||||
#Ignore Rule for output of generated documentation files from Grunt docserve
|
||||
src/Umbraco.Web.UI.Client/docs/api
|
||||
src/*.boltdata/
|
||||
src/umbraco.sln.ide/*
|
||||
src/.vs/
|
||||
|
||||
src/Umbraco.Web.UI/[Jj]s/*
|
||||
src/Umbraco.Tests/[Mm]edia
|
||||
tools/docfx/*
|
||||
apidocs/_site/*
|
||||
src/*/project.lock.json
|
||||
src/.idea/*
|
||||
|
||||
apidocs/api/*
|
||||
build/docs.zip
|
||||
build/ui-docs.zip
|
||||
build/csharp-docs.zip
|
||||
src/packages/
|
||||
src/PrecompiledWeb/*
|
||||
|
||||
# build
|
||||
build.out/
|
||||
build.tmp/
|
||||
build/hooks/
|
||||
build/temp/
|
||||
|
||||
|
||||
|
||||
|
||||
# common directories
|
||||
.DS_Store
|
||||
._.DS_Store
|
||||
.vs/
|
||||
/local/
|
||||
|
||||
# build directories
|
||||
[Bb]in/
|
||||
[Db]ebug*/
|
||||
[Rr]elease*/
|
||||
obj/
|
||||
|
||||
# tools
|
||||
_ReSharper*/
|
||||
_NCrunch_*/
|
||||
*.ncrunchsolution
|
||||
*.ncrunchsolution.user
|
||||
*.ncrunchproject
|
||||
*.crunchsolution.cache
|
||||
tools/NDepend/
|
||||
|
||||
|
||||
|
||||
|
||||
[Tt]est[Rr]esult*
|
||||
[Bb]uild[Ll]og.*
|
||||
*.[Pp]ublish.xml
|
||||
[sS]ource
|
||||
[sS]andbox
|
||||
umbraco.config
|
||||
App_Data/TEMP/*
|
||||
[Uu]mbraco/[Pp]resentation/[Uu]mbraco/[Pp]lugins/*
|
||||
[Uu]mbraco/[Pp]resentation/[Uu]ser[Cc]ontrols/*
|
||||
[Uu]mbraco/[Pp]resentation/[Ss]cripts/*
|
||||
[Uu]mbraco/[Pp]resentation/[Ff]onts/*
|
||||
[Uu]mbraco/[Pp]resentation/[Cc]ss/*
|
||||
|
||||
src/Umbraco.Web.UI/[Cc]ss/*
|
||||
src/Umbraco.Web.UI/App_Code/*
|
||||
src/Umbraco.Web.UI/App_Data/*
|
||||
src/Umbraco.Tests/App_Data/*
|
||||
src/Umbraco.Web.UI/[Mm]edia/*
|
||||
src/Umbraco.Web.UI/[Mm]aster[Pp]ages/*
|
||||
src/Umbraco.Web.UI/[Mm]acro[Ss]cripts/*
|
||||
!src/Umbraco.Web.UI/[Mm]acro[Ss]cripts/[Ww]eb.[Cc]onfig
|
||||
src/Umbraco.Web.UI/[Xx]slt/*
|
||||
src/Umbraco.Web.UI/[Ii]mages/*
|
||||
src/Umbraco.Web.UI/[Ss]cripts/*
|
||||
src/Umbraco.Web.UI/Web.*.config.transformed
|
||||
|
||||
umbraco/presentation/umbraco/plugins/uComponents/uComponentsInstaller.ascx
|
||||
umbraco/presentation/packages/uComponents/MultiNodePicker/CustomTreeService.asmx
|
||||
|
||||
src/Umbraco.Tests/config/applications.config
|
||||
src/Umbraco.Tests/config/trees.config
|
||||
src/Umbraco.Web.UI/web.config
|
||||
src/Umbraco.Web.UI/[Cc]onfig/ClientDependency.config
|
||||
src/Umbraco.Web.UI/[Cc]onfig/serilog.config
|
||||
src/Umbraco.Web.UI/[Cc]onfig/serilog.user.config
|
||||
src/Umbraco.Tests/config/404handlers.config
|
||||
src/Umbraco.Web.UI/[Vv]iews/*.cshtml
|
||||
src/Umbraco.Web.UI/[Vv]iews/*.vbhtml
|
||||
src/Umbraco.Tests/[Cc]onfig/umbracoSettings.config
|
||||
src/Umbraco.Web.UI/[Vv]iews/*
|
||||
src/packages/
|
||||
src/packages/repositories.config
|
||||
|
||||
src/Umbraco.Web.UI/[Ww]eb.config
|
||||
*.transformed
|
||||
|
||||
node_modules
|
||||
lib-bower
|
||||
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Ll]ib/*
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/umbraco.*
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/*.loader.js
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/init.js
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/routes.js
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/app.dev.js
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/loader.js
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/loader.dev.js
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/main.js
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/app.js
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/canvasdesigner.*.js
|
||||
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Vv]iews/
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Vv]iews/**/*.js
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Vv]iews/**/*.css
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Vv]iews/**/*.html
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Aa]ssets/*
|
||||
src/Umbraco.Web.UI.Client/[Bb]uild/*
|
||||
src/Umbraco.Web.UI.Client/[Bb]uild/[Bb]elle/
|
||||
src/Umbraco.Web.UI/[Uu]ser[Cc]ontrols/
|
||||
|
||||
src/Umbraco.Web.UI.Client/src/[Ll]ess/*.css
|
||||
src/Umbraco.Web.UI.Client/vwd.webinfo
|
||||
|
||||
src/Umbraco.Web.UI/App_Plugins/*
|
||||
src/*.psess
|
||||
src/*.vspx
|
||||
|
||||
NDependOut/*
|
||||
QueryResult.htm
|
||||
|
||||
src/Umbraco.Web.UI/[Cc]onfig/appSettings.config
|
||||
src/Umbraco.Web.UI/[Cc]onfig/connectionStrings.config
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/plugins/*
|
||||
build/ApiDocs/*
|
||||
build/ApiDocs/Output/*
|
||||
src/Umbraco.Web.UI.Client/bower_components/*
|
||||
/src/Umbraco.Web.UI/[Uu]mbraco/preview
|
||||
/src/Umbraco.Web.UI/[Uu]mbraco/preview.old
|
||||
|
||||
# ignore rule for clearing out Belle (avoid rebuilding all the time)
|
||||
preserve.belle
|
||||
|
||||
#Ignore Rule for output of generated documentation files from Grunt docserve
|
||||
src/Umbraco.Web.UI.Client/docs/api
|
||||
src/*.boltdata/
|
||||
src/umbraco.sln.ide/*
|
||||
src/.vs/
|
||||
|
||||
src/Umbraco.Web.UI/[Jj]s/*
|
||||
src/Umbraco.Tests/[Mm]edia
|
||||
tools/docfx/*
|
||||
apidocs/_site/*
|
||||
src/*/project.lock.json
|
||||
src/.idea/*
|
||||
|
||||
apidocs/api/*
|
||||
build/docs.zip
|
||||
build/ui-docs.zip
|
||||
build/csharp-docs.zip
|
||||
src/packages/
|
||||
src/PrecompiledWeb/*
|
||||
|
||||
# build
|
||||
build.out/
|
||||
build.tmp/
|
||||
build/hooks/
|
||||
build/temp/
|
||||
|
||||
|
||||
|
||||
# eof
|
||||
/src/Umbraco.Web.UI.Client/TESTS-*.xml
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata minClientVersion="3.4.4">
|
||||
<metadata minClientVersion="4.6.0">
|
||||
<id>UmbracoCms.Core</id>
|
||||
<version>8.0.0</version>
|
||||
<title>Umbraco Cms Core Binaries</title>
|
||||
@@ -15,31 +15,35 @@
|
||||
<language>en-US</language>
|
||||
<tags>umbraco</tags>
|
||||
<dependencies>
|
||||
<!--
|
||||
note: dependencies are specified as [x.y.z,x.999999) eg [2.1.0,2.999999) and NOT [2.1.0,3.0.0) because
|
||||
the latter would pick anything below 3.0.0 and that includes prereleases such as 3.0.0-alpha, and we do
|
||||
not want this to happen as the alpha of the next major is, really, the next major already.
|
||||
-->
|
||||
<dependency id="AutoMapper" version="[7.0.1,7.999999)" />
|
||||
<dependency id="LightInject" version="[5.1.2,5.999999)" />
|
||||
<dependency id="LightInject.Annotation" version="[1.1.0,1.999999)" />
|
||||
<dependency id="LightInject.Web" version="[2.0.0,2.999999)" />
|
||||
<dependency id="Microsoft.AspNet.Identity.Core" version="[2.2.2,2.999999)" />
|
||||
<dependency id="Microsoft.AspNet.WebApi.Client" version="[5.2.6,5.999999)" />
|
||||
<dependency id="Microsoft.Owin" version="[4.0.0,4.999999)" />
|
||||
<dependency id="MiniProfiler" version="[3.2.0.157,3.999999)" />
|
||||
<dependency id="Newtonsoft.Json" version="[11.0.2,11.999999)" />
|
||||
<dependency id="Semver" version="[2.0.4,2.999999)" />
|
||||
<dependency id="Serilog" version="[2.7.1,2.999999)" />
|
||||
<dependency id="Serilog.Enrichers.Process" version="[2.0.1,2.999999)" />
|
||||
<dependency id="Serilog.Enrichers.Thread" version="[3.0.0,3.999999)" />
|
||||
<dependency id="Serilog.Filters.Expressions" version="[2.0.0,2.999999)" />
|
||||
<dependency id="Serilog.Formatting.Compact" version="[1.0.0,1.999999)" />
|
||||
<dependency id="Serilog.Formatting.Compact.Reader" version="[1.0.2,1.999999)" />
|
||||
<dependency id="Serilog.Settings.AppSettings" version="[2.2.2,2.999999)" />
|
||||
<dependency id="Serilog.Sinks.File" version="[4.0.0,4.999999)" />
|
||||
<dependency id="Umbraco.SqlServerCE" version="[4.0.0.1,4.999999)" />
|
||||
<dependency id="NPoco" version="[3.9.4,3.999999)" />
|
||||
|
||||
<group targetFramework="net472">
|
||||
<!--
|
||||
note: dependencies are specified as [x.y.z,x.999999) eg [2.1.0,2.999999) and NOT [2.1.0,3.0.0) because
|
||||
the latter would pick anything below 3.0.0 and that includes prereleases such as 3.0.0-alpha, and we do
|
||||
not want this to happen as the alpha of the next major is, really, the next major already.
|
||||
-->
|
||||
<dependency id="AutoMapper" version="[8.0.0,8.999999)" />
|
||||
<dependency id="LightInject" version="[5.4.0,5.999999)" />
|
||||
<dependency id="LightInject.Annotation" version="[1.1.0,1.999999)" />
|
||||
<dependency id="LightInject.Web" version="[2.0.0,2.999999)" />
|
||||
<dependency id="Microsoft.AspNet.Identity.Core" version="[2.2.2,2.999999)" />
|
||||
<dependency id="Microsoft.AspNet.WebApi.Client" version="[5.2.7,5.999999)" />
|
||||
<dependency id="Microsoft.Owin" version="[4.0.1,4.999999)" />
|
||||
<dependency id="MiniProfiler" version="[4.0.138,4.999999)" />
|
||||
<dependency id="Newtonsoft.Json" version="[12.0.1,12.999999)" />
|
||||
<dependency id="Semver" version="[2.0.4,2.999999)" />
|
||||
<dependency id="Serilog" version="[2.8.0,2.999999)" />
|
||||
<dependency id="Serilog.Enrichers.Process" version="[2.0.1,2.999999)" />
|
||||
<dependency id="Serilog.Enrichers.Thread" version="[3.0.0,3.999999)" />
|
||||
<dependency id="Serilog.Filters.Expressions" version="[2.0.0,2.999999)" />
|
||||
<dependency id="Serilog.Formatting.Compact" version="[1.0.0,1.999999)" />
|
||||
<dependency id="Serilog.Formatting.Compact.Reader" version="[1.0.3,1.999999)" />
|
||||
<dependency id="Serilog.Settings.AppSettings" version="[2.2.2,2.999999)" />
|
||||
<dependency id="Serilog.Sinks.File" version="[4.0.0,4.999999)" />
|
||||
<dependency id="Umbraco.SqlServerCE" version="[4.0.0.1,4.999999)" />
|
||||
<dependency id="NPoco" version="[3.9.4,3.999999)" />
|
||||
</group>
|
||||
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata minClientVersion="3.4.4">
|
||||
<metadata minClientVersion="4.6.0">
|
||||
<id>UmbracoCms.Web</id>
|
||||
<version>8.0.0</version>
|
||||
<title>Umbraco Cms Core Binaries</title>
|
||||
@@ -15,30 +15,35 @@
|
||||
<language>en-US</language>
|
||||
<tags>umbraco</tags>
|
||||
<dependencies>
|
||||
<!--
|
||||
note: dependencies are specified as [x.y.z,x.999999) eg [2.1.0,2.999999) and NOT [2.1.0,3.0.0) because
|
||||
the latter would pick anything below 3.0.0 and that includes prereleases such as 3.0.0-alpha, and we do
|
||||
not want this to happen as the alpha of the next major is, really, the next major already.
|
||||
-->
|
||||
<dependency id="UmbracoCms.Core" version="[$version$]" />
|
||||
<dependency id="AutoMapper" version="[7.0.1,7.999999)" />
|
||||
<dependency id="ClientDependency" version="[1.9.7,1.999999)" />
|
||||
<dependency id="ClientDependency-Mvc5" version="[1.8.0,1.999999)" />
|
||||
<dependency id="CSharpTest.Net.Collections" version="[14.906.1403.1082,14.999999)" />
|
||||
<dependency id="Examine" version="[1.0.0-beta078,1.999999)" />
|
||||
<dependency id="HtmlAgilityPack" version="[1.8.9,1.999999)" />
|
||||
<dependency id="ImageProcessor" version="[2.6.2.25,2.999999)" />
|
||||
<dependency id="LightInject.Mvc" version="[2.0.0,2.999999)" />
|
||||
<dependency id="LightInject.WebApi" version="[2.0.0,2.999999)" />
|
||||
<dependency id="Markdown" version="[2.2.1,2.999999)" />
|
||||
<dependency id="Microsoft.AspNet.Identity.Owin" version="[2.2.2,2.999999)" />
|
||||
<dependency id="Microsoft.AspNet.Mvc" version="[5.2.6,5.999999)" />
|
||||
<dependency id="Microsoft.AspNet.SignalR.Core" version="[2.2.3,2.999999)" />
|
||||
<dependency id="Microsoft.AspNet.WebApi" version="[5.2.6,5.999999)" />
|
||||
<dependency id="Microsoft.Owin.Host.SystemWeb" version="[4.0.0,4.999999)" />
|
||||
<dependency id="Microsoft.Owin.Security.Cookies" version="[4.0.0,4.999999)" />
|
||||
<dependency id="Microsoft.Owin.Security.OAuth" version="[4.0.0,4.999999)" />
|
||||
<dependency id="System.Threading.Tasks.Dataflow" version="[4.8.0,4.999999)" />
|
||||
|
||||
<group targetFramework="net472">
|
||||
|
||||
<!--
|
||||
note: dependencies are specified as [x.y.z,x.999999) eg [2.1.0,2.999999) and NOT [2.1.0,3.0.0) because
|
||||
the latter would pick anything below 3.0.0 and that includes prereleases such as 3.0.0-alpha, and we do
|
||||
not want this to happen as the alpha of the next major is, really, the next major already.
|
||||
-->
|
||||
<dependency id="UmbracoCms.Core" version="[$version$]" />
|
||||
<dependency id="ClientDependency" version="[1.9.7,1.999999)" />
|
||||
<dependency id="ClientDependency-Mvc5" version="[1.8.0,1.999999)" />
|
||||
<dependency id="CSharpTest.Net.Collections" version="[14.906.1403.1082,14.999999)" />
|
||||
<dependency id="Examine" version="[1.0.0,1.999999)" />
|
||||
<dependency id="HtmlAgilityPack" version="[1.8.14,1.999999)" />
|
||||
<dependency id="ImageProcessor" version="[2.7.0.100,2.999999)" />
|
||||
<dependency id="LightInject.Mvc" version="[2.0.0,2.999999)" />
|
||||
<dependency id="LightInject.WebApi" version="[2.0.0,2.999999)" />
|
||||
<dependency id="Markdown" version="[2.2.1,2.999999)" />
|
||||
<dependency id="Microsoft.AspNet.Identity.Owin" version="[2.2.2,2.999999)" />
|
||||
<dependency id="Microsoft.AspNet.Mvc" version="[5.2.7,5.999999)" />
|
||||
<dependency id="Microsoft.AspNet.SignalR.Core" version="[2.4.0,2.999999)" />
|
||||
<dependency id="Microsoft.AspNet.WebApi" version="[5.2.7,5.999999)" />
|
||||
<dependency id="Microsoft.Owin.Host.SystemWeb" version="[4.0.1,4.999999)" />
|
||||
<dependency id="Microsoft.Owin.Security.Cookies" version="[4.0.1,4.999999)" />
|
||||
<dependency id="Microsoft.Owin.Security.OAuth" version="[4.0.1,4.999999)" />
|
||||
<dependency id="System.Threading.Tasks.Dataflow" version="[4.9.0,4.999999)" />
|
||||
|
||||
</group>
|
||||
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata minClientVersion="3.4.4">
|
||||
<metadata minClientVersion="4.6.0">
|
||||
<id>UmbracoCms</id>
|
||||
<version>8.0.0</version>
|
||||
<title>Umbraco Cms</title>
|
||||
@@ -15,18 +15,25 @@
|
||||
<language>en-US</language>
|
||||
<tags>umbraco</tags>
|
||||
<dependencies>
|
||||
<dependency id="UmbracoCms.Web" version="[$version$]" />
|
||||
<!--
|
||||
note: dependencies are specified as [x.y.z,x.999999) eg [2.1.0,2.999999) and NOT [2.1.0,3.0.0) because
|
||||
the latter would pick anything below 3.0.0 and that includes prereleases such as 3.0.0-alpha, and we do
|
||||
not want this to happen as the alpha of the next major is, really, the next major already.
|
||||
-->
|
||||
<dependency id="Microsoft.AspNet.SignalR.Core" version="[2.2.3, 2.999999)" />
|
||||
<dependency id="Umbraco.ModelsBuilder.Ui" version="[8.0.0-alpha.34]" />
|
||||
<dependency id="ImageProcessor.Web" version="[4.9.3.25,4.999999)" />
|
||||
<dependency id="ImageProcessor.Web.Config" version="[2.4.1.19,2.999999)" />
|
||||
<dependency id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="[2.0.1,2.999999)" />
|
||||
<dependency id="Microsoft.Net.Compilers" version="[2.10.0,2.999999)" />
|
||||
|
||||
<group targetFramework="net472">
|
||||
|
||||
<dependency id="UmbracoCms.Web" version="[$version$]" />
|
||||
<!--
|
||||
note: dependencies are specified as [x.y.z,x.999999) eg [2.1.0,2.999999) and NOT [2.1.0,3.0.0) because
|
||||
the latter would pick anything below 3.0.0 and that includes prereleases such as 3.0.0-alpha, and we do
|
||||
not want this to happen as the alpha of the next major is, really, the next major already.
|
||||
-->
|
||||
<dependency id="Microsoft.AspNet.SignalR.Core" version="[2.4.0, 2.999999)" />
|
||||
<dependency id="Umbraco.ModelsBuilder.Ui" version="[8.0.1]" />
|
||||
<dependency id="ImageProcessor.Web" version="[4.10.0.100,4.999999)" />
|
||||
<dependency id="ImageProcessor.Web.Config" version="[2.5.0.100,2.999999)" />
|
||||
<dependency id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="[2.0.1,2.999999)" />
|
||||
<dependency id="Microsoft.Net.Compilers" version="[2.10.0,2.999999)" />
|
||||
|
||||
</group>
|
||||
|
||||
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
|
||||
@@ -126,45 +126,55 @@
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='Microsoft.CodeAnalysis.CSharp')" xdt:Transform="Remove" />
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='log4net')" xdt:Transform="Remove" />
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Data.SqlServerCe')" xdt:Transform="Remove" />
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.ValueTuple')" xdt:Transform="Remove" />
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Net.Http.Formatting')" xdt:Transform="Remove" />
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-11.0.0.0" newVersion="11.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.2.1.0" newVersion="1.2.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.2.6.0" newVersion="5.2.6.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.2.6.0" newVersion="5.2.6.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.2.3.0" newVersion="1.2.3.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
||||
<system.web.webPages.razor xdt:Transform="Remove" />
|
||||
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
param($installPath, $toolsPath, $package, $project)
|
||||
|
||||
Write-Host "installPath:" "${installPath}"
|
||||
Write-Host "toolsPath:" "${toolsPath}"
|
||||
|
||||
Write-Host " "
|
||||
|
||||
if ($project) {
|
||||
$dateTime = Get-Date -Format yyyyMMdd-HHmmss
|
||||
|
||||
# Create paths and list them
|
||||
$projectPath = (Get-Item $project.Properties.Item("FullPath").Value).FullName
|
||||
Write-Host "projectPath:" "${projectPath}"
|
||||
$backupPath = Join-Path $projectPath "App_Data\NuGetBackup\$dateTime"
|
||||
Write-Host "backupPath:" "${backupPath}"
|
||||
$copyLogsPath = Join-Path $backupPath "CopyLogs"
|
||||
Write-Host "copyLogsPath:" "${copyLogsPath}"
|
||||
$umbracoBinFolder = Join-Path $projectPath "bin"
|
||||
Write-Host "umbracoBinFolder:" "${umbracoBinFolder}"
|
||||
|
||||
# Create backup folder and logs folder if it doesn't exist yet
|
||||
New-Item -ItemType Directory -Force -Path $backupPath
|
||||
New-Item -ItemType Directory -Force -Path $copyLogsPath
|
||||
|
||||
# After backing up, remove all umbraco dlls from bin folder in case dll files are included in the VS project
|
||||
# See: http://issues.umbraco.org/issue/U4-4930
|
||||
|
||||
if(Test-Path $umbracoBinFolder) {
|
||||
$umbracoBinBackupPath = Join-Path $backupPath "bin"
|
||||
|
||||
New-Item -ItemType Directory -Force -Path $umbracoBinBackupPath
|
||||
|
||||
robocopy $umbracoBinFolder $umbracoBinBackupPath /e /LOG:$copyLogsPath\UmbracoBinBackup.log
|
||||
|
||||
# Delete files Umbraco ships with
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.ApplicationBlocks.Data.dll) { Remove-Item $umbracoBinFolder\Microsoft.ApplicationBlocks.Data.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Data.SqlServerCe.dll) { Remove-Item $umbracoBinFolder\System.Data.SqlServerCe.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Data.SqlServerCe.Entity.dll) { Remove-Item $umbracoBinFolder\System.Data.SqlServerCe.Entity.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Umbraco.Web.dll) { Remove-Item $umbracoBinFolder\Umbraco.Web.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Umbraco.Core.dll) { Remove-Item $umbracoBinFolder\Umbraco.Core.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Umbraco.ModelsBuilder.dll) { Remove-Item $umbracoBinFolder\Umbraco.ModelsBuilder.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Umbraco.ModelsBuilder.AspNet.dll) { Remove-Item $umbracoBinFolder\Umbraco.ModelsBuilder.AspNet.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Umbraco.Web.UI.dll) { Remove-Item $umbracoBinFolder\Umbraco.Web.UI.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Umbraco.Examine.dll) { Remove-Item $umbracoBinFolder\Umbraco.Examine.dll -Force -Confirm:$false }
|
||||
|
||||
# Delete files Umbraco depends upon
|
||||
$amd64Folder = Join-Path $umbracoBinFolder "amd64"
|
||||
if(Test-Path $amd64Folder) { Remove-Item $amd64Folder -Force -Recurse -Confirm:$false }
|
||||
$x86Folder = Join-Path $umbracoBinFolder "x86"
|
||||
if(Test-Path $x86Folder) { Remove-Item $x86Folder -Force -Recurse -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\AutoMapper.dll) { Remove-Item $umbracoBinFolder\AutoMapper.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\AutoMapper.Net4.dll) { Remove-Item $umbracoBinFolder\AutoMapper.Net4.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\ClientDependency.Core.dll) { Remove-Item $umbracoBinFolder\ClientDependency.Core.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\ClientDependency.Core.Mvc.dll) { Remove-Item $umbracoBinFolder\ClientDependency.Core.Mvc.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\CookComputing.XmlRpcV2.dll) { Remove-Item $umbracoBinFolder\CookComputing.XmlRpcV2.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Examine.dll) { Remove-Item $umbracoBinFolder\Examine.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\HtmlAgilityPack.dll) { Remove-Item $umbracoBinFolder\HtmlAgilityPack.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\ICSharpCode.SharpZipLib.dll) { Remove-Item $umbracoBinFolder\ICSharpCode.SharpZipLib.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\ImageProcessor.dll) { Remove-Item $umbracoBinFolder\ImageProcessor.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\ImageProcessor.Web.dll) { Remove-Item $umbracoBinFolder\ImageProcessor.Web.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Lucene.Net.dll) { Remove-Item $umbracoBinFolder\Lucene.Net.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.IO.RecyclableMemoryStream.dll) { Remove-Item $umbracoBinFolder\Microsoft.IO.RecyclableMemoryStream.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.AspNet.Identity.Core.dll) { Remove-Item $umbracoBinFolder\Microsoft.AspNet.Identity.Core.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.AspNet.Identity.Owin.dll) { Remove-Item $umbracoBinFolder\Microsoft.AspNet.Identity.Owin.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.CodeAnalysis.CSharp.dll) { Remove-Item $umbracoBinFolder\Microsoft.CodeAnalysis.CSharp.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.CodeAnalysis.dll) { Remove-Item $umbracoBinFolder\Microsoft.CodeAnalysis.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.Owin.dll) { Remove-Item $umbracoBinFolder\Microsoft.Owin.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.Owin.Host.SystemWeb.dll) { Remove-Item $umbracoBinFolder\Microsoft.Owin.Host.SystemWeb.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.Owin.Security.dll) { Remove-Item $umbracoBinFolder\Microsoft.Owin.Security.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.Owin.Security.Cookies.dll) { Remove-Item $umbracoBinFolder\Microsoft.Owin.Security.Cookies.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.Owin.Security.OAuth.dll) { Remove-Item $umbracoBinFolder\Microsoft.Owin.Security.OAuth.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.Web.Infrastructure.dll) { Remove-Item $umbracoBinFolder\Microsoft.Web.Infrastructure.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.Web.Helpers.dll) { Remove-Item $umbracoBinFolder\Microsoft.Web.Helpers.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.Web.Mvc.FixedDisplayModes.dll) { Remove-Item $umbracoBinFolder\Microsoft.Web.Mvc.FixedDisplayModes.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\MiniProfiler.dll) { Remove-Item $umbracoBinFolder\MiniProfiler.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Newtonsoft.Json.dll) { Remove-Item $umbracoBinFolder\Newtonsoft.Json.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Owin.dll) { Remove-Item $umbracoBinFolder\Owin.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Semver.dll) { Remove-Item $umbracoBinFolder\Semver.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Collections.Immutable.dll) { Remove-Item $umbracoBinFolder\System.Collections.Immutable.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Reflection.Metadata.dll) { Remove-Item $umbracoBinFolder\System.Reflection.Metadata.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Net.Http.Extensions.dll) { Remove-Item $umbracoBinFolder\System.Net.Http.Extensions.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Net.Http.Formatting.dll) { Remove-Item $umbracoBinFolder\System.Net.Http.Formatting.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Net.Http.Primitives.dll) { Remove-Item $umbracoBinFolder\System.Net.Http.Primitives.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.Helpers.dll) { Remove-Item $umbracoBinFolder\System.Web.Helpers.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.Http.dll) { Remove-Item $umbracoBinFolder\System.Web.Http.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.Http.WebHost.dll) { Remove-Item $umbracoBinFolder\System.Web.Http.WebHost.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.Mvc.dll) { Remove-Item $umbracoBinFolder\System.Web.Mvc.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.Razor.dll) { Remove-Item $umbracoBinFolder\System.Web.Razor.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.WebPages.dll) { Remove-Item $umbracoBinFolder\System.Web.WebPages.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.WebPages.Deployment.dll) { Remove-Item $umbracoBinFolder\System.Web.WebPages.Deployment.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.WebPages.Razor.dll) { Remove-Item $umbracoBinFolder\System.Web.WebPages.Razor.dll -Force -Confirm:$false }
|
||||
}
|
||||
}
|
||||
@@ -11,37 +11,15 @@ if ($project) {
|
||||
# Create paths and list them
|
||||
$projectPath = (Get-Item $project.Properties.Item("FullPath").Value).FullName
|
||||
Write-Host "projectPath:" "${projectPath}"
|
||||
$backupPath = Join-Path $projectPath "App_Data\NuGetBackup\$dateTime"
|
||||
Write-Host "backupPath:" "${backupPath}"
|
||||
$copyLogsPath = Join-Path $backupPath "CopyLogs"
|
||||
Write-Host "copyLogsPath:" "${copyLogsPath}"
|
||||
$webConfigSource = Join-Path $projectPath "Web.config"
|
||||
Write-Host "webConfigSource:" "${webConfigSource}"
|
||||
$configFolder = Join-Path $projectPath "Config"
|
||||
Write-Host "configFolder:" "${configFolder}"
|
||||
|
||||
# Create backup folder and logs folder if it doesn't exist yet
|
||||
New-Item -ItemType Directory -Force -Path $backupPath
|
||||
New-Item -ItemType Directory -Force -Path $copyLogsPath
|
||||
|
||||
# Create a backup of original web.config
|
||||
Copy-Item $webConfigSource $backupPath -Force
|
||||
|
||||
# Backup config files folder
|
||||
if(Test-Path $configFolder) {
|
||||
$umbracoBackupPath = Join-Path $backupPath "Config"
|
||||
New-Item -ItemType Directory -Force -Path $umbracoBackupPath
|
||||
|
||||
robocopy $configFolder $umbracoBackupPath /e /LOG:$copyLogsPath\ConfigBackup.log
|
||||
}
|
||||
|
||||
# Copy umbraco and umbraco_files from package to project folder
|
||||
$umbracoFolder = Join-Path $projectPath "Umbraco"
|
||||
New-Item -ItemType Directory -Force -Path $umbracoFolder
|
||||
$umbracoFolderSource = Join-Path $installPath "UmbracoFiles\Umbraco"
|
||||
$umbracoBackupPath = Join-Path $backupPath "Umbraco"
|
||||
New-Item -ItemType Directory -Force -Path $umbracoBackupPath
|
||||
robocopy $umbracoFolder $umbracoBackupPath /e /LOG:$copyLogsPath\UmbracoBackup.log
|
||||
robocopy $umbracoFolderSource $umbracoFolder /is /it /e /xf UI.xml /LOG:$copyLogsPath\UmbracoCopy.log
|
||||
|
||||
$copyWebconfig = $true
|
||||
@@ -54,7 +32,7 @@ if ($project) {
|
||||
[xml]$config = Get-Content $destinationWebConfig
|
||||
|
||||
$config.configuration.appSettings.ChildNodes | ForEach-Object {
|
||||
if($_.key -eq "umbracoConfigurationStatus")
|
||||
if($_.key -eq "Umbraco.Core.ConfigurationStatus")
|
||||
{
|
||||
# The web.config has an umbraco-specific appSetting in it
|
||||
# don't overwrite it and let config transforms do their thing
|
||||
@@ -100,11 +78,6 @@ if ($project) {
|
||||
}
|
||||
}
|
||||
|
||||
$installFolder = Join-Path $projectPath "Install"
|
||||
if(Test-Path $installFolder) {
|
||||
Remove-Item $installFolder -Force -Recurse -Confirm:$false
|
||||
}
|
||||
|
||||
# Open appropriate readme
|
||||
if($copyWebconfig -eq $true)
|
||||
{
|
||||
|
||||
+11
-2
@@ -15,7 +15,12 @@
|
||||
[Parameter(Mandatory=$false)]
|
||||
[Alias("c")]
|
||||
[Alias("cont")]
|
||||
[switch] $continue = $false
|
||||
[switch] $continue = $false,
|
||||
|
||||
# execute a command
|
||||
[Parameter(Mandatory=$false, ValueFromRemainingArguments=$true)]
|
||||
[String[]]
|
||||
$command
|
||||
)
|
||||
|
||||
# ################################################################
|
||||
@@ -475,7 +480,11 @@
|
||||
# run
|
||||
if (-not $get)
|
||||
{
|
||||
$ubuild.Build()
|
||||
if ($command.Length -eq 0)
|
||||
{
|
||||
$command = @( "Build" )
|
||||
}
|
||||
$ubuild.RunMethod($command);
|
||||
if ($ubuild.OnError()) { return }
|
||||
}
|
||||
if ($get) { return $ubuild }
|
||||
|
||||
+3
-3
@@ -2,7 +2,7 @@
|
||||
using System.Resources;
|
||||
|
||||
[assembly: AssemblyCompany("Umbraco")]
|
||||
[assembly: AssemblyCopyright("Copyright © Umbraco 2018")]
|
||||
[assembly: AssemblyCopyright("Copyright © Umbraco 2019")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
@@ -18,5 +18,5 @@ using System.Resources;
|
||||
[assembly: AssemblyVersion("8.0.0")]
|
||||
|
||||
// these are FYI and changed automatically
|
||||
[assembly: AssemblyFileVersion("8.0.0")]
|
||||
[assembly: AssemblyInformationalVersion("8.0.0-alpha.58")]
|
||||
[assembly: AssemblyFileVersion("8.1.0")]
|
||||
[assembly: AssemblyInformationalVersion("8.1.0")]
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Web;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
@@ -110,7 +111,7 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
#region Lock
|
||||
|
||||
private bool _entered;
|
||||
private const string ContextItemsLockKey = "Umbraco.Core.Cache.HttpRequestCache::LockEntered";
|
||||
|
||||
protected override void EnterReadLock() => EnterWriteLock();
|
||||
|
||||
@@ -118,7 +119,13 @@ namespace Umbraco.Core.Cache
|
||||
{
|
||||
if (HasContextItems)
|
||||
{
|
||||
System.Threading.Monitor.Enter(ContextItems.SyncRoot, ref _entered);
|
||||
// note: cannot keep 'entered' as a class variable here,
|
||||
// since there is one per request - so storing it within
|
||||
// ContextItems - which is locked, so this should be safe
|
||||
|
||||
var entered = false;
|
||||
Monitor.Enter(ContextItems.SyncRoot, ref entered);
|
||||
ContextItems[ContextItemsLockKey] = entered;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,11 +133,10 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
protected override void ExitWriteLock()
|
||||
{
|
||||
if (_entered)
|
||||
{
|
||||
_entered = false;
|
||||
System.Threading.Monitor.Exit(ContextItems.SyncRoot);
|
||||
}
|
||||
var entered = (bool?) ContextItems[ContextItemsLockKey] ?? false;
|
||||
if (entered)
|
||||
Monitor.Exit(ContextItems.SyncRoot);
|
||||
ContextItems.Remove(ContextItemsLockKey);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
namespace Umbraco.Core.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a core <see cref="IComposer"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>All core composers are required by (compose before) all user composers,
|
||||
/// and require (compose after) all runtime composers.</para>
|
||||
/// </remarks>
|
||||
[ComposeAfter(typeof(IRuntimeComposer))]
|
||||
public interface ICoreComposer : IComposer
|
||||
{ }
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
namespace Umbraco.Core.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a runtime <see cref="IComposer"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>All runtime composers are required by (compose before) all core composers</para>
|
||||
/// </remarks>
|
||||
public interface IRuntimeComposer : IComposer
|
||||
{ }
|
||||
}
|
||||
+2
-1
@@ -3,6 +3,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Web;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
@@ -10,7 +11,7 @@ using Umbraco.Core.Security;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Services.Implement;
|
||||
|
||||
namespace Umbraco.Core.Components
|
||||
namespace Umbraco.Core.Compose
|
||||
{
|
||||
public sealed class AuditEventsComponent : IComponent
|
||||
{
|
||||
+3
-1
@@ -1,4 +1,6 @@
|
||||
namespace Umbraco.Core.Components
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.Compose
|
||||
{
|
||||
public sealed class AuditEventsComposer : ComponentComposer<AuditEventsComponent>, ICoreComposer
|
||||
{ }
|
||||
+2
-1
@@ -1,9 +1,10 @@
|
||||
using System.IO;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Manifest;
|
||||
|
||||
namespace Umbraco.Core.Components
|
||||
namespace Umbraco.Core.Compose
|
||||
{
|
||||
public sealed class ManifestWatcherComponent : IComponent
|
||||
{
|
||||
+3
-1
@@ -1,4 +1,6 @@
|
||||
namespace Umbraco.Core.Components
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.Compose
|
||||
{
|
||||
[RuntimeLevel(MinLevel = RuntimeLevel.Run)]
|
||||
public class ManifestWatcherComposer : ComponentComposer<ManifestWatcherComponent>, ICoreComposer
|
||||
+1
-1
@@ -3,7 +3,7 @@ using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Services.Implement;
|
||||
|
||||
namespace Umbraco.Core.Components
|
||||
namespace Umbraco.Core.Compose
|
||||
{
|
||||
// TODO: This should just exist in the content service/repo!
|
||||
public sealed class RelateOnCopyComponent : IComponent
|
||||
+3
-1
@@ -1,4 +1,6 @@
|
||||
namespace Umbraco.Core.Components
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.Compose
|
||||
{
|
||||
[RuntimeLevel(MinLevel = RuntimeLevel.Run)]
|
||||
public sealed class RelateOnCopyComposer : ComponentComposer<RelateOnCopyComponent>, ICoreComposer
|
||||
+1
-1
@@ -5,7 +5,7 @@ using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Services.Implement;
|
||||
|
||||
namespace Umbraco.Core.Components
|
||||
namespace Umbraco.Core.Compose
|
||||
{
|
||||
public sealed class RelateOnTrashComponent : IComponent
|
||||
{
|
||||
+3
-1
@@ -1,4 +1,6 @@
|
||||
namespace Umbraco.Core.Components
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.Compose
|
||||
{
|
||||
[RuntimeLevel(MinLevel = RuntimeLevel.Run)]
|
||||
public sealed class RelateOnTrashComposer : ComponentComposer<RelateOnTrashComponent>, ICoreComposer
|
||||
+2
-3
@@ -1,9 +1,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core.Components
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the collection of <see cref="IComponent"/> implementations.
|
||||
@@ -24,7 +23,7 @@ namespace Umbraco.Core.Components
|
||||
{
|
||||
using (_logger.DebugDuration<ComponentCollection>($"Initializing. (log components when >{LogThresholdMilliseconds}ms)", "Initialized."))
|
||||
{
|
||||
foreach (var component in this.Reverse()) // terminate components in reverse order
|
||||
foreach (var component in this)
|
||||
{
|
||||
var componentType = component.GetType();
|
||||
using (_logger.DebugDuration<ComponentCollection>($"Initializing {componentType.FullName}.", $"Initialized {componentType.FullName}.", thresholdMilliseconds: LogThresholdMilliseconds))
|
||||
+2
-3
@@ -1,9 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core.Components
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
/// <summary>
|
||||
/// Builds a <see cref="ComponentCollection"/>.
|
||||
@@ -31,7 +30,7 @@ namespace Umbraco.Core.Components
|
||||
|
||||
protected override IComponent CreateItem(IFactory factory, Type itemType)
|
||||
{
|
||||
using (_logger.DebugDuration<Composers>($"Creating {itemType.FullName}.", $"Created {itemType.FullName}.", thresholdMilliseconds: LogThresholdMilliseconds))
|
||||
using (_logger.DebugDuration<ComponentCollectionBuilder>($"Creating {itemType.FullName}.", $"Created {itemType.FullName}.", thresholdMilliseconds: LogThresholdMilliseconds))
|
||||
{
|
||||
return base.CreateItem(factory, itemType);
|
||||
}
|
||||
+3
-1
@@ -1,4 +1,6 @@
|
||||
namespace Umbraco.Core.Components
|
||||
using Umbraco.Core.Compose;
|
||||
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a base class for composers which compose a component.
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Components
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that a composer requires another composer.
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Components
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that a component is required by another composer.
|
||||
+32
-13
@@ -6,7 +6,7 @@ using System.Text;
|
||||
using Umbraco.Core.Collections;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core.Components
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
// note: this class is NOT thread-safe in any ways
|
||||
|
||||
@@ -173,27 +173,46 @@ namespace Umbraco.Core.Components
|
||||
// what happens in case of conflicting remote declarations is unspecified. more
|
||||
// precisely, the last declaration to be processed wins, but the order of the
|
||||
// declarations depends on the type finder and is unspecified.
|
||||
|
||||
void UpdateEnableInfo(Type composerType, int weight2, Dictionary<Type, EnableInfo> enabled2, bool value)
|
||||
{
|
||||
if (enabled.TryGetValue(composerType, out var enableInfo) == false) enableInfo = enabled2[composerType] = new EnableInfo();
|
||||
if (enableInfo.Weight > weight2) return;
|
||||
|
||||
enableInfo.Enabled = value;
|
||||
enableInfo.Weight = weight2;
|
||||
}
|
||||
|
||||
var assemblies = types.Select(x => x.Assembly).Distinct();
|
||||
foreach (var assembly in assemblies)
|
||||
{
|
||||
foreach (var attr in assembly.GetCustomAttributes<EnableComposerAttribute>())
|
||||
{
|
||||
var type = attr.EnabledType;
|
||||
UpdateEnableInfo(type, 2, enabled, true);
|
||||
}
|
||||
|
||||
foreach (var attr in assembly.GetCustomAttributes<DisableComposerAttribute>())
|
||||
{
|
||||
var type = attr.DisabledType;
|
||||
UpdateEnableInfo(type, 2, enabled, false);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var composerType in types)
|
||||
{
|
||||
foreach (var attr in composerType.GetCustomAttributes<EnableAttribute>())
|
||||
{
|
||||
var type = attr.EnabledType ?? composerType;
|
||||
if (enabled.TryGetValue(type, out var enableInfo) == false) enableInfo = enabled[type] = new EnableInfo();
|
||||
var weight = type == composerType ? 1 : 2;
|
||||
if (enableInfo.Weight > weight) continue;
|
||||
|
||||
enableInfo.Enabled = true;
|
||||
enableInfo.Weight = weight;
|
||||
var weight = type == composerType ? 1 : 3;
|
||||
UpdateEnableInfo(type, weight, enabled, true);
|
||||
}
|
||||
|
||||
foreach (var attr in composerType.GetCustomAttributes<DisableAttribute>())
|
||||
{
|
||||
var type = attr.DisabledType ?? composerType;
|
||||
if (enabled.TryGetValue(type, out var enableInfo) == false) enableInfo = enabled[type] = new EnableInfo();
|
||||
var weight = type == composerType ? 1 : 2;
|
||||
if (enableInfo.Weight > weight) continue;
|
||||
|
||||
enableInfo.Enabled = false;
|
||||
enableInfo.Weight = weight;
|
||||
var weight = type == composerType ? 1 : 3;
|
||||
UpdateEnableInfo(type, weight, enabled, false);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -1,10 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core.Components
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a composition.
|
||||
+3
-5
@@ -1,13 +1,11 @@
|
||||
using Umbraco.Core.Components;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
|
||||
namespace Umbraco.Core.Composing.Composers
|
||||
namespace Umbraco.Core.Composing.CompositionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Compose configurations.
|
||||
/// </summary>
|
||||
public static class ConfigurationComposer
|
||||
public static class Configuration
|
||||
{
|
||||
public static Composition ComposeConfiguration(this Composition composition)
|
||||
{
|
||||
+2
-3
@@ -1,11 +1,10 @@
|
||||
using AutoMapper;
|
||||
using Umbraco.Core.Components;
|
||||
using Umbraco.Core.Models.Identity;
|
||||
|
||||
namespace Umbraco.Core.Composing.Composers
|
||||
namespace Umbraco.Core.Composing.CompositionExtensions
|
||||
|
||||
{
|
||||
public static class CoreMappingProfilesComposer
|
||||
public static class CoreMappingProfiles
|
||||
{
|
||||
public static Composition ComposeCoreMappingProfiles(this Composition composition)
|
||||
{
|
||||
+6
-6
@@ -1,10 +1,10 @@
|
||||
using Umbraco.Core.Components;
|
||||
using Umbraco.Core.Compose;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.IO.MediaPathSchemes;
|
||||
|
||||
namespace Umbraco.Core.Composing.Composers
|
||||
namespace Umbraco.Core.Composing.CompositionExtensions
|
||||
{
|
||||
public static class FileSystemsComposer
|
||||
public static class FileSystems
|
||||
{
|
||||
/*
|
||||
* HOW TO REPLACE THE MEDIA UNDERLYING FILESYSTEM
|
||||
@@ -73,13 +73,13 @@ namespace Umbraco.Core.Composing.Composers
|
||||
// it needs to be registered (not only the interface) because it provides additional
|
||||
// functionality eg for scoping, and is injected in the scope provider - whereas the
|
||||
// interface is really for end-users to get access to filesystems.
|
||||
composition.RegisterUnique(factory => factory.CreateInstance<FileSystems>(factory));
|
||||
composition.RegisterUnique(factory => factory.CreateInstance<IO.FileSystems>(factory));
|
||||
|
||||
// register IFileSystems, which gives access too all filesystems
|
||||
composition.RegisterUnique<IFileSystems>(factory => factory.GetInstance<FileSystems>());
|
||||
composition.RegisterUnique<IFileSystems>(factory => factory.GetInstance<IO.FileSystems>());
|
||||
|
||||
// register the scheme for media paths
|
||||
composition.RegisterUnique<IMediaPathScheme, TwoGuidsMediaPathScheme>();
|
||||
composition.RegisterUnique<IMediaPathScheme, UniqueMediaPathScheme>();
|
||||
|
||||
// register the IMediaFileSystem implementation
|
||||
composition.RegisterFileSystem<IMediaFileSystem, MediaFileSystem>();
|
||||
+3
-4
@@ -1,13 +1,12 @@
|
||||
using Umbraco.Core.Components;
|
||||
using Umbraco.Core.Persistence.Repositories;
|
||||
using Umbraco.Core.Persistence.Repositories;
|
||||
using Umbraco.Core.Persistence.Repositories.Implement;
|
||||
|
||||
namespace Umbraco.Core.Composing.Composers
|
||||
namespace Umbraco.Core.Composing.CompositionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Composes repositories.
|
||||
/// </summary>
|
||||
public static class RepositoriesComposer
|
||||
public static class Repositories
|
||||
{
|
||||
public static Composition ComposeRepositories(this Composition composition)
|
||||
{
|
||||
+3
-3
@@ -2,7 +2,6 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Components;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
@@ -10,9 +9,9 @@ using Umbraco.Core.Packaging;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Services.Implement;
|
||||
|
||||
namespace Umbraco.Core.Composing.Composers
|
||||
namespace Umbraco.Core.Composing.CompositionExtensions
|
||||
{
|
||||
public static class ServicesComposer
|
||||
public static class Services
|
||||
{
|
||||
public static Composition ComposeServices(this Composition composition)
|
||||
{
|
||||
@@ -37,6 +36,7 @@ namespace Umbraco.Core.Composing.Composers
|
||||
composition.RegisterUnique<IMemberService, MemberService>();
|
||||
composition.RegisterUnique<IMediaService, MediaService>();
|
||||
composition.RegisterUnique<IContentTypeService, ContentTypeService>();
|
||||
composition.RegisterUnique<IContentTypeBaseServiceProvider, ContentTypeBaseServiceProvider>();
|
||||
composition.RegisterUnique<IMediaTypeService, MediaTypeService>();
|
||||
composition.RegisterUnique<IDataTypeService, DataTypeService>();
|
||||
composition.RegisterUnique<IFileService, FileService>();
|
||||
+3
-4
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Components
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that a composer should be disabled.
|
||||
@@ -9,9 +9,8 @@ namespace Umbraco.Core.Components
|
||||
/// <para>If a type is specified, disables the composer of that type, else disables the composer marked with the attribute.</para>
|
||||
/// <para>This attribute is *not* inherited.</para>
|
||||
/// <para>This attribute applies to classes only, it is not possible to enable/disable interfaces.</para>
|
||||
/// <para>If a composer ends up being both enabled and disabled: attributes marking the composer itself have lower priority
|
||||
/// than attributes on *other* composers, eg if a composer declares itself as disabled it is possible to enable it from
|
||||
/// another composer. Anything else is unspecified.</para>
|
||||
/// <para>Assembly-level <see cref="DisableComposerAttribute"/> has greater priority than <see cref="DisableAttribute"/>
|
||||
/// attribute when it is marking the composer itself, but lower priority that when it is referencing another composer.</para>
|
||||
/// </remarks>
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
|
||||
public class DisableAttribute : Attribute
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that a composer should be disabled.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Assembly-level <see cref="DisableComposerAttribute"/> has greater priority than <see cref="DisableAttribute"/>
|
||||
/// attribute when it is marking the composer itself, but lower priority that when it is referencing another composer.</para>
|
||||
/// </remarks>
|
||||
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)]
|
||||
public class DisableComposerAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DisableComposerAttribute"/> class.
|
||||
/// </summary>
|
||||
public DisableComposerAttribute(Type disabledType)
|
||||
{
|
||||
DisabledType = disabledType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the disabled type, or null if it is the composer marked with the attribute.
|
||||
/// </summary>
|
||||
public Type DisabledType { get; }
|
||||
}
|
||||
}
|
||||
+3
-4
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Components
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that a composer should be enabled.
|
||||
@@ -9,9 +9,8 @@ namespace Umbraco.Core.Components
|
||||
/// <para>If a type is specified, enables the composer of that type, else enables the composer marked with the attribute.</para>
|
||||
/// <para>This attribute is *not* inherited.</para>
|
||||
/// <para>This attribute applies to classes only, it is not possible to enable/disable interfaces.</para>
|
||||
/// <para>If a composer ends up being both enabled and disabled: attributes marking the composer itself have lower priority
|
||||
/// than attributes on *other* composers, eg if a composer declares itself as disabled it is possible to enable it from
|
||||
/// another composer. Anything else is unspecified.</para>
|
||||
/// <para>Assembly-level <see cref="DisableComposerAttribute"/> has greater priority than <see cref="DisableAttribute"/>
|
||||
/// attribute when it is marking the composer itself, but lower priority that when it is referencing another composer.</para>
|
||||
/// </remarks>
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
|
||||
public class EnableAttribute : Attribute
|
||||
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that a composer should be enabled.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>If a type is specified, enables the composer of that type, else enables the composer marked with the attribute.</para>
|
||||
/// <para>This attribute is *not* inherited.</para>
|
||||
/// <para>This attribute applies to classes only, it is not possible to enable/disable interfaces.</para>
|
||||
/// <para>Assembly-level <see cref="DisableComposerAttribute"/> has greater priority than <see cref="DisableAttribute"/>
|
||||
/// attribute when it is marking the composer itself, but lower priority that when it is referencing another composer.</para>
|
||||
/// </remarks>
|
||||
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)]
|
||||
public class EnableComposerAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EnableComposerAttribute"/> class.
|
||||
/// </summary>
|
||||
public EnableComposerAttribute(Type enabledType)
|
||||
{
|
||||
EnabledType = enabledType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the enabled type, or null if it is the composer marked with the attribute.
|
||||
/// </summary>
|
||||
public Type EnabledType { get; }
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
namespace Umbraco.Core.Components
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a component.
|
||||
@@ -1,6 +1,4 @@
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.Components
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a composer.
|
||||
@@ -10,7 +8,6 @@ namespace Umbraco.Core.Components
|
||||
/// <summary>
|
||||
/// Compose.
|
||||
/// </summary>
|
||||
/// <param name="composition"></param>
|
||||
void Compose(Composition composition);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a core <see cref="IComposer"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Core composers compose after the initial composer, and before user composers.</para>
|
||||
/// </remarks>
|
||||
public interface ICoreComposer : IComposer
|
||||
{ }
|
||||
}
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
namespace Umbraco.Core.Components
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a user <see cref="IComposer"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>All user composers require (compose after) all core composers.</para>
|
||||
/// <para>User composers compose after core composers, and before the final composer.</para>
|
||||
/// </remarks>
|
||||
[ComposeAfter(typeof(ICoreComposer))]
|
||||
public interface IUserComposer : IComposer
|
||||
{ }
|
||||
}
|
||||
}
|
||||
@@ -78,33 +78,6 @@ namespace Umbraco.Core.Composing
|
||||
return This;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Appends a type after another type.
|
||||
/// </summary>
|
||||
/// <typeparam name="TAfter">The other type.</typeparam>
|
||||
/// <typeparam name="T">The type to append.</typeparam>
|
||||
/// <returns>The builder.</returns>
|
||||
/// <remarks>Throws if both types are identical, or if the other type does not already belong to the collection.</remarks>
|
||||
public TBuilder AppendAfter<TAfter, T>()
|
||||
where TAfter : TItem
|
||||
where T : TItem
|
||||
{
|
||||
Configure(types =>
|
||||
{
|
||||
var typeAfter = typeof (TAfter);
|
||||
var type = typeof(T);
|
||||
if (typeAfter == type) throw new InvalidOperationException();
|
||||
|
||||
var index = types.IndexOf(typeAfter);
|
||||
if (index < 0) throw new InvalidOperationException();
|
||||
|
||||
if (types.Contains(type)) types.Remove(type);
|
||||
index = types.IndexOf(typeAfter); // in case removing type changed index
|
||||
types.Insert(index + 1, type);
|
||||
});
|
||||
return This;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a type into the collection.
|
||||
/// </summary>
|
||||
@@ -206,6 +179,69 @@ namespace Umbraco.Core.Composing
|
||||
return This;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a type after another type.
|
||||
/// </summary>
|
||||
/// <typeparam name="TAfter">The other type.</typeparam>
|
||||
/// <typeparam name="T">The type to append.</typeparam>
|
||||
/// <returns>The builder.</returns>
|
||||
/// <remarks>Throws if both types are identical, or if the other type does not already belong to the collection.</remarks>
|
||||
public TBuilder InsertAfter<TAfter, T>()
|
||||
where TAfter : TItem
|
||||
where T : TItem
|
||||
{
|
||||
Configure(types =>
|
||||
{
|
||||
var typeAfter = typeof(TAfter);
|
||||
var type = typeof(T);
|
||||
if (typeAfter == type) throw new InvalidOperationException();
|
||||
|
||||
var index = types.IndexOf(typeAfter);
|
||||
if (index < 0) throw new InvalidOperationException();
|
||||
|
||||
if (types.Contains(type)) types.Remove(type);
|
||||
index = types.IndexOf(typeAfter); // in case removing type changed index
|
||||
index += 1; // insert here
|
||||
|
||||
if (index == types.Count)
|
||||
types.Add(type);
|
||||
else
|
||||
types.Insert(index, type);
|
||||
});
|
||||
return This;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a type after another type.
|
||||
/// </summary>
|
||||
/// <param name="typeAfter">The other type.</param>
|
||||
/// <param name="type">The type to insert.</param>
|
||||
/// <returns>The builder.</returns>
|
||||
/// <remarks>Throws if both types are identical, or if the other type does not already belong to the collection.</remarks>
|
||||
public TBuilder InsertAfter(Type typeAfter, Type type)
|
||||
{
|
||||
Configure(types =>
|
||||
{
|
||||
EnsureType(typeAfter, "find");
|
||||
EnsureType(type, "register");
|
||||
|
||||
if (typeAfter == type) throw new InvalidOperationException();
|
||||
|
||||
var index = types.IndexOf(typeAfter);
|
||||
if (index < 0) throw new InvalidOperationException();
|
||||
|
||||
if (types.Contains(type)) types.Remove(type);
|
||||
index = types.IndexOf(typeAfter); // in case removing type changed index
|
||||
index += 1; // insert here
|
||||
|
||||
if (index == types.Count)
|
||||
types.Add(type);
|
||||
else
|
||||
types.Insert(index, type);
|
||||
});
|
||||
return This;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a type from the collection.
|
||||
/// </summary>
|
||||
|
||||
@@ -18,14 +18,14 @@ namespace Umbraco.Core.Composing
|
||||
/// Creates a new instance of the configured container.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// To override the default LightInjectContainer, add an appSetting named umbracoContainerType with
|
||||
/// To override the default LightInjectContainer, add an appSetting named 'Umbraco.Core.RegisterType' with
|
||||
/// a fully qualified type name to a class with a static method "Create" returning an IRegister.
|
||||
/// </remarks>
|
||||
public static IRegister Create()
|
||||
{
|
||||
Type type;
|
||||
|
||||
var configuredTypeName = ConfigurationManager.AppSettings["umbracoRegisterType"];
|
||||
var configuredTypeName = ConfigurationManager.AppSettings[Constants.AppSettings.RegisterType];
|
||||
if (configuredTypeName.IsNullOrWhiteSpace())
|
||||
{
|
||||
// try to get the web LightInject container type,
|
||||
|
||||
+1
-2
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.Components
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
/// <summary>
|
||||
/// Marks a composer to indicate a minimum and/or maximum runtime level for which the composer would compose.
|
||||
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a base class for collections of types.
|
||||
/// </summary>
|
||||
public abstract class TypeCollectionBuilderBase<TCollection, TConstraint> : ICollectionBuilder<TCollection, Type>
|
||||
where TCollection : class, IBuilderCollection<Type>
|
||||
{
|
||||
private readonly HashSet<Type> _types = new HashSet<Type>();
|
||||
|
||||
private Type Validate(Type type, string action)
|
||||
{
|
||||
if (!typeof(TConstraint).IsAssignableFrom(type))
|
||||
throw new InvalidOperationException($"Cannot {action} type {type.FullName} as it does not inherit from/implement {typeof(TConstraint).FullName}.");
|
||||
return type;
|
||||
}
|
||||
|
||||
public void Add(Type type) => _types.Add(Validate(type, "add"));
|
||||
|
||||
public void Add<T>() => Add(typeof(T));
|
||||
|
||||
public void Add(IEnumerable<Type> types)
|
||||
{
|
||||
foreach (var type in types) Add(type);
|
||||
}
|
||||
|
||||
public void Remove(Type type) => _types.Remove(Validate(type, "remove"));
|
||||
|
||||
public void Remove<T>() => Remove(typeof(T));
|
||||
|
||||
public TCollection CreateCollection(IFactory factory)
|
||||
{
|
||||
return factory.CreateInstance<TCollection>(_types);
|
||||
}
|
||||
|
||||
public void RegisterWith(IRegister register)
|
||||
{
|
||||
register.Register(CreateCollection, Lifetime.Singleton);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ namespace Umbraco.Core.Composing
|
||||
if (_assembliesAcceptingLoadExceptions != null)
|
||||
return _assembliesAcceptingLoadExceptions;
|
||||
|
||||
var s = ConfigurationManager.AppSettings["Umbraco.AssembliesAcceptingLoadExceptions"];
|
||||
var s = ConfigurationManager.AppSettings[Constants.AppSettings.AssembliesAcceptingLoadExceptions];
|
||||
return _assembliesAcceptingLoadExceptions = string.IsNullOrWhiteSpace(s)
|
||||
? Array.Empty<string>()
|
||||
: s.Split(',').Select(x => x.Trim()).ToArray();
|
||||
|
||||
@@ -42,30 +42,30 @@ namespace Umbraco.Core.Composing
|
||||
private string _currentAssembliesHash;
|
||||
private IEnumerable<Assembly> _assemblies;
|
||||
private bool _reportedChange;
|
||||
private static LocalTempStorage _localTempStorage;
|
||||
private static string _localTempPath;
|
||||
private static string _fileBasePath;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TypeLoader"/> class.
|
||||
/// </summary>
|
||||
/// <param name="runtimeCache">The application runtime cache.</param>
|
||||
/// <param name="localTempStorage">Files storage mode.</param>
|
||||
/// <param name="localTempPath">Files storage location.</param>
|
||||
/// <param name="logger">A profiling logger.</param>
|
||||
public TypeLoader(IAppPolicyCache runtimeCache, LocalTempStorage localTempStorage, IProfilingLogger logger)
|
||||
: this(runtimeCache, localTempStorage, logger, true)
|
||||
public TypeLoader(IAppPolicyCache runtimeCache, string localTempPath, IProfilingLogger logger)
|
||||
: this(runtimeCache, localTempPath, logger, true)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TypeLoader"/> class.
|
||||
/// </summary>
|
||||
/// <param name="runtimeCache">The application runtime cache.</param>
|
||||
/// <param name="localTempStorage">Files storage mode.</param>
|
||||
/// <param name="localTempPath">Files storage location.</param>
|
||||
/// <param name="logger">A profiling logger.</param>
|
||||
/// <param name="detectChanges">Whether to detect changes using hashes.</param>
|
||||
internal TypeLoader(IAppPolicyCache runtimeCache, LocalTempStorage localTempStorage, IProfilingLogger logger, bool detectChanges)
|
||||
internal TypeLoader(IAppPolicyCache runtimeCache, string localTempPath, IProfilingLogger logger, bool detectChanges)
|
||||
{
|
||||
_runtimeCache = runtimeCache ?? throw new ArgumentNullException(nameof(runtimeCache));
|
||||
_localTempStorage = localTempStorage == LocalTempStorage.Unknown ? LocalTempStorage.Default : localTempStorage;
|
||||
_localTempPath = localTempPath;
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
if (detectChanges)
|
||||
@@ -211,7 +211,7 @@ namespace Umbraco.Core.Composing
|
||||
/// file properties (false) or the file contents (true).</remarks>
|
||||
private static string GetFileHash(IEnumerable<Tuple<FileSystemInfo, bool>> filesAndFolders, IProfilingLogger logger)
|
||||
{
|
||||
using (logger.TraceDuration<TypeLoader>("Determining hash of code files on disk", "Hash determined"))
|
||||
using (logger.DebugDuration<TypeLoader>("Determining hash of code files on disk", "Hash determined"))
|
||||
{
|
||||
// get the distinct file infos to hash
|
||||
var uniqInfos = new HashSet<string>();
|
||||
@@ -269,7 +269,7 @@ namespace Umbraco.Core.Composing
|
||||
// internal for tests
|
||||
internal static string GetFileHash(IEnumerable<FileSystemInfo> filesAndFolders, IProfilingLogger logger)
|
||||
{
|
||||
using (logger.TraceDuration<TypeLoader>("Determining hash of code files on disk", "Hash determined"))
|
||||
using (logger.DebugDuration<TypeLoader>("Determining hash of code files on disk", "Hash determined"))
|
||||
{
|
||||
using (var generator = new HashGenerator())
|
||||
{
|
||||
@@ -388,25 +388,7 @@ namespace Umbraco.Core.Composing
|
||||
if (_fileBasePath != null)
|
||||
return _fileBasePath;
|
||||
|
||||
switch (_localTempStorage)
|
||||
{
|
||||
case LocalTempStorage.AspNetTemp:
|
||||
_fileBasePath = Path.Combine(HttpRuntime.CodegenDir, "UmbracoData", "umbraco-types");
|
||||
break;
|
||||
case LocalTempStorage.EnvironmentTemp:
|
||||
// include the appdomain hash is just a safety check, for example if a website is moved from worker A to worker B and then back
|
||||
// to worker A again, in theory the %temp% folder should already be empty but we really want to make sure that its not
|
||||
// utilizing an old path - assuming we cannot have SHA1 collisions on AppDomainAppId
|
||||
var appDomainHash = HttpRuntime.AppDomainAppId.ToSHA1();
|
||||
var cachePath = Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "UmbracoData", appDomainHash);
|
||||
_fileBasePath = Path.Combine(cachePath, "umbraco-types");
|
||||
break;
|
||||
case LocalTempStorage.Default:
|
||||
default:
|
||||
var tempFolder = IOHelper.MapPath(SystemDirectories.TempData.EnsureEndsWith('/') + "TypesCache");
|
||||
_fileBasePath = Path.Combine(tempFolder, "umbraco-types." + NetworkHelper.FileSafeMachineName);
|
||||
break;
|
||||
}
|
||||
_fileBasePath = Path.Combine(_localTempPath, "TypesCache", "umbraco-types." + NetworkHelper.FileSafeMachineName);
|
||||
|
||||
// ensure that the folder exists
|
||||
var directory = Path.GetDirectoryName(_fileBasePath);
|
||||
@@ -666,7 +648,7 @@ namespace Umbraco.Core.Composing
|
||||
var name = GetName(baseType, attributeType);
|
||||
|
||||
lock (_locko)
|
||||
using (_logger.TraceDuration<TypeLoader>(
|
||||
using (_logger.DebugDuration<TypeLoader>(
|
||||
"Getting " + name,
|
||||
"Got " + name)) // cannot contain typesFound.Count as it's evaluated before the find
|
||||
{
|
||||
|
||||
+5
-53
@@ -1,64 +1,23 @@
|
||||
using System;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Dictionary;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Dictionary;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Migrations;
|
||||
using Umbraco.Core.Logging.Viewer;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PackageActions;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Core.Sync;
|
||||
using Umbraco.Core.Logging.Viewer;
|
||||
using Umbraco.Core.PackageActions;
|
||||
|
||||
namespace Umbraco.Core.Components
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides extension methods to the <see cref="Composition"/> class.
|
||||
/// </summary>
|
||||
public static class CompositionExtensions
|
||||
public static partial class CompositionExtensions
|
||||
{
|
||||
#region FileSystems
|
||||
|
||||
/// <summary>
|
||||
/// Registers a filesystem.
|
||||
/// </summary>
|
||||
/// <typeparam name="TFileSystem">The type of the filesystem.</typeparam>
|
||||
/// <typeparam name="TImplementing">The implementing type.</typeparam>
|
||||
/// <param name="composition">The composition.</param>
|
||||
/// <returns>The register.</returns>
|
||||
public static void RegisterFileSystem<TFileSystem, TImplementing>(this Composition composition)
|
||||
where TImplementing : FileSystemWrapper, TFileSystem
|
||||
where TFileSystem : class
|
||||
{
|
||||
composition.RegisterUnique<TFileSystem>(factory =>
|
||||
{
|
||||
var fileSystems = factory.GetInstance<FileSystems>();
|
||||
var supporting = factory.GetInstance<SupportingFileSystems>();
|
||||
return fileSystems.GetFileSystem<TImplementing>(supporting.For<TFileSystem>());
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a filesystem.
|
||||
/// </summary>
|
||||
/// <typeparam name="TFileSystem">The type of the filesystem.</typeparam>
|
||||
/// <param name="composition">The composition.</param>
|
||||
/// <returns>The register.</returns>
|
||||
public static void RegisterFileSystem<TFileSystem>(this Composition composition)
|
||||
where TFileSystem : FileSystemWrapper
|
||||
{
|
||||
composition.RegisterUnique(factory =>
|
||||
{
|
||||
var fileSystems = factory.GetInstance<FileSystems>();
|
||||
var supporting = factory.GetInstance<SupportingFileSystems>();
|
||||
return fileSystems.GetFileSystem<TFileSystem>(supporting.For<TFileSystem>());
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Collection Builders
|
||||
|
||||
/// <summary>
|
||||
@@ -110,13 +69,6 @@ namespace Umbraco.Core.Components
|
||||
internal static ManifestValueValidatorCollectionBuilder Validators(this Composition composition)
|
||||
=> composition.WithCollectionBuilder<ManifestValueValidatorCollectionBuilder>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the post-migrations collection builder.
|
||||
/// </summary>
|
||||
/// <param name="composition">The composition.</param>
|
||||
internal static PostMigrationCollectionBuilder PostMigrations(this Composition composition)
|
||||
=> composition.WithCollectionBuilder<PostMigrationCollectionBuilder>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the components collection builder.
|
||||
/// </summary>
|
||||
@@ -0,0 +1,35 @@
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides extension methods to the <see cref="Composition"/> class.
|
||||
/// </summary>
|
||||
public static partial class CompositionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Registers essential services.
|
||||
/// </summary>
|
||||
public static void RegisterEssentials(this Composition composition,
|
||||
ILogger logger, IProfiler profiler, IProfilingLogger profilingLogger,
|
||||
IMainDom mainDom,
|
||||
AppCaches appCaches,
|
||||
IUmbracoDatabaseFactory databaseFactory,
|
||||
TypeLoader typeLoader,
|
||||
IRuntimeState state)
|
||||
{
|
||||
composition.RegisterUnique(logger);
|
||||
composition.RegisterUnique(profiler);
|
||||
composition.RegisterUnique(profilingLogger);
|
||||
composition.RegisterUnique(mainDom);
|
||||
composition.RegisterUnique(appCaches);
|
||||
composition.RegisterUnique(databaseFactory);
|
||||
composition.RegisterUnique(factory => factory.GetInstance<IUmbracoDatabaseFactory>().SqlContext);
|
||||
composition.RegisterUnique(typeLoader);
|
||||
composition.RegisterUnique(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.IO;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides extension methods to the <see cref="Composition"/> class.
|
||||
/// </summary>
|
||||
public static partial class CompositionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Registers a filesystem.
|
||||
/// </summary>
|
||||
/// <typeparam name="TFileSystem">The type of the filesystem.</typeparam>
|
||||
/// <typeparam name="TImplementing">The implementing type.</typeparam>
|
||||
/// <param name="composition">The composition.</param>
|
||||
/// <returns>The register.</returns>
|
||||
public static void RegisterFileSystem<TFileSystem, TImplementing>(this Composition composition)
|
||||
where TImplementing : FileSystemWrapper, TFileSystem
|
||||
where TFileSystem : class
|
||||
{
|
||||
composition.RegisterUnique<TFileSystem>(factory =>
|
||||
{
|
||||
var fileSystems = factory.GetInstance<FileSystems>();
|
||||
var supporting = factory.GetInstance<SupportingFileSystems>();
|
||||
return fileSystems.GetFileSystem<TImplementing>(supporting.For<TFileSystem>());
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a filesystem.
|
||||
/// </summary>
|
||||
/// <typeparam name="TFileSystem">The type of the filesystem.</typeparam>
|
||||
/// <param name="composition">The composition.</param>
|
||||
/// <returns>The register.</returns>
|
||||
public static void RegisterFileSystem<TFileSystem>(this Composition composition)
|
||||
where TFileSystem : FileSystemWrapper
|
||||
{
|
||||
composition.RegisterUnique(factory =>
|
||||
{
|
||||
var fileSystems = factory.GetInstance<FileSystems>();
|
||||
var supporting = factory.GetInstance<SupportingFileSystems>();
|
||||
return fileSystems.GetFileSystem<TFileSystem>(supporting.For<TFileSystem>());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-37
@@ -1,43 +1,12 @@
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Components;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.Composing
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides extension methods to the <see cref="Composition"/> class.
|
||||
/// </summary>
|
||||
public static class CompositionExtensions
|
||||
public static partial class CompositionExtensions
|
||||
{
|
||||
#region Essentials
|
||||
|
||||
/// <summary>
|
||||
/// Registers essential services.
|
||||
/// </summary>
|
||||
public static void RegisterEssentials(this Composition composition,
|
||||
ILogger logger, IProfiler profiler, IProfilingLogger profilingLogger,
|
||||
IMainDom mainDom,
|
||||
AppCaches appCaches,
|
||||
IUmbracoDatabaseFactory databaseFactory,
|
||||
TypeLoader typeLoader,
|
||||
IRuntimeState state)
|
||||
{
|
||||
composition.RegisterUnique(logger);
|
||||
composition.RegisterUnique(profiler);
|
||||
composition.RegisterUnique(profilingLogger);
|
||||
composition.RegisterUnique(mainDom);
|
||||
composition.RegisterUnique(appCaches);
|
||||
composition.RegisterUnique(databaseFactory);
|
||||
composition.RegisterUnique(factory => factory.GetInstance<IUmbracoDatabaseFactory>().SqlContext);
|
||||
composition.RegisterUnique(typeLoader);
|
||||
composition.RegisterUnique(state);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Unique
|
||||
|
||||
/// <summary>
|
||||
/// Registers a unique service as its own implementation.
|
||||
/// </summary>
|
||||
@@ -62,7 +31,5 @@ namespace Umbraco.Core.Composing
|
||||
/// </summary>
|
||||
public static void RegisterUnique<TService>(this Composition composition, TService instance)
|
||||
=> composition.RegisterUnique(typeof(TService), instance);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,8 @@ namespace Umbraco.Core.Configuration
|
||||
public CoreDebug()
|
||||
{
|
||||
var appSettings = System.Configuration.ConfigurationManager.AppSettings;
|
||||
LogUncompletedScopes = string.Equals("true", appSettings["Umbraco.CoreDebug.LogUncompletedScopes"], StringComparison.OrdinalIgnoreCase);
|
||||
DumpOnTimeoutThreadAbort = string.Equals("true", appSettings["Umbraco.CoreDebug.DumpOnTimeoutThreadAbort"], StringComparison.OrdinalIgnoreCase);
|
||||
LogUncompletedScopes = string.Equals("true", appSettings[Constants.AppSettings.Debug.LogUncompletedScopes], StringComparison.OrdinalIgnoreCase);
|
||||
DumpOnTimeoutThreadAbort = string.Equals("true", appSettings[Constants.AppSettings.Debug.DumpOnTimeoutThreadAbort], StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
// when true, Scope logs the stack trace for any scope that gets disposed without being completed.
|
||||
|
||||
@@ -4,15 +4,8 @@ using System.Linq;
|
||||
using System.Net.Configuration;
|
||||
using System.Web;
|
||||
using System.Web.Configuration;
|
||||
using System.Web.Hosting;
|
||||
using System.Web.Security;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using System.Xml.XPath;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Security;
|
||||
|
||||
namespace Umbraco.Core.Configuration
|
||||
{
|
||||
@@ -31,7 +24,7 @@ namespace Umbraco.Core.Configuration
|
||||
private static string _reservedPaths;
|
||||
private static string _reservedUrls;
|
||||
//ensure the built on (non-changeable) reserved paths are there at all times
|
||||
internal const string StaticReservedPaths = "~/app_plugins/,~/install/,"; //must end with a comma!
|
||||
internal const string StaticReservedPaths = "~/app_plugins/,~/install/,~/mini-profiler-resources/,"; //must end with a comma!
|
||||
internal const string StaticReservedUrls = "~/config/splashes/noNodes.aspx,~/.well-known,"; //must end with a comma!
|
||||
#endregion
|
||||
|
||||
@@ -85,8 +78,8 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
if (_reservedUrls != null) return _reservedUrls;
|
||||
|
||||
var urls = ConfigurationManager.AppSettings.ContainsKey("umbracoReservedUrls")
|
||||
? ConfigurationManager.AppSettings["umbracoReservedUrls"]
|
||||
var urls = ConfigurationManager.AppSettings.ContainsKey(Constants.AppSettings.ReservedUrls)
|
||||
? ConfigurationManager.AppSettings[Constants.AppSettings.ReservedUrls]
|
||||
: string.Empty;
|
||||
|
||||
//ensure the built on (non-changeable) reserved paths are there at all times
|
||||
@@ -107,14 +100,14 @@ namespace Umbraco.Core.Configuration
|
||||
if (_reservedPaths != null) return _reservedPaths;
|
||||
|
||||
var reservedPaths = StaticReservedPaths;
|
||||
var umbPath = ConfigurationManager.AppSettings.ContainsKey("umbracoPath") && !ConfigurationManager.AppSettings["umbracoPath"].IsNullOrWhiteSpace()
|
||||
? ConfigurationManager.AppSettings["umbracoPath"]
|
||||
var umbPath = ConfigurationManager.AppSettings.ContainsKey(Constants.AppSettings.Path) && !ConfigurationManager.AppSettings[Constants.AppSettings.Path].IsNullOrWhiteSpace()
|
||||
? ConfigurationManager.AppSettings[Constants.AppSettings.Path]
|
||||
: "~/umbraco";
|
||||
//always add the umbraco path to the list
|
||||
reservedPaths += umbPath.EnsureEndsWith(',');
|
||||
|
||||
var allPaths = ConfigurationManager.AppSettings.ContainsKey("umbracoReservedPaths")
|
||||
? ConfigurationManager.AppSettings["umbracoReservedPaths"]
|
||||
var allPaths = ConfigurationManager.AppSettings.ContainsKey(Constants.AppSettings.ReservedPaths)
|
||||
? ConfigurationManager.AppSettings[Constants.AppSettings.ReservedPaths]
|
||||
: string.Empty;
|
||||
|
||||
_reservedPaths = reservedPaths + allPaths;
|
||||
@@ -133,8 +126,8 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
get
|
||||
{
|
||||
return ConfigurationManager.AppSettings.ContainsKey("umbracoContentXML")
|
||||
? ConfigurationManager.AppSettings["umbracoContentXML"]
|
||||
return ConfigurationManager.AppSettings.ContainsKey(Constants.AppSettings.ContentXML)
|
||||
? ConfigurationManager.AppSettings[Constants.AppSettings.ContentXML]
|
||||
: "~/App_Data/umbraco.config";
|
||||
}
|
||||
}
|
||||
@@ -147,8 +140,8 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
get
|
||||
{
|
||||
return ConfigurationManager.AppSettings.ContainsKey("umbracoPath")
|
||||
? IOHelper.ResolveUrl(ConfigurationManager.AppSettings["umbracoPath"])
|
||||
return ConfigurationManager.AppSettings.ContainsKey(Constants.AppSettings.Path)
|
||||
? IOHelper.ResolveUrl(ConfigurationManager.AppSettings[Constants.AppSettings.Path])
|
||||
: string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -161,13 +154,13 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
get
|
||||
{
|
||||
return ConfigurationManager.AppSettings.ContainsKey("umbracoConfigurationStatus")
|
||||
? ConfigurationManager.AppSettings["umbracoConfigurationStatus"]
|
||||
return ConfigurationManager.AppSettings.ContainsKey(Constants.AppSettings.ConfigurationStatus)
|
||||
? ConfigurationManager.AppSettings[Constants.AppSettings.ConfigurationStatus]
|
||||
: string.Empty;
|
||||
}
|
||||
set
|
||||
{
|
||||
SaveSetting("umbracoConfigurationStatus", value);
|
||||
SaveSetting(Constants.AppSettings.ConfigurationStatus, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,7 +242,7 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
try
|
||||
{
|
||||
return int.Parse(ConfigurationManager.AppSettings["umbracoTimeOutInMinutes"]);
|
||||
return int.Parse(ConfigurationManager.AppSettings[Constants.AppSettings.TimeOutInMinutes]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -268,7 +261,7 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
try
|
||||
{
|
||||
return int.Parse(ConfigurationManager.AppSettings["umbracoVersionCheckPeriod"]);
|
||||
return int.Parse(ConfigurationManager.AppSettings[Constants.AppSettings.VersionCheckPeriod]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -277,17 +270,12 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is the location type to store temporary files such as cache files or other localized files for a given machine
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Currently used for the xml cache file and the plugin cache files
|
||||
/// </remarks>
|
||||
/// <inheritdoc />
|
||||
public LocalTempStorage LocalTempStorageLocation
|
||||
{
|
||||
get
|
||||
{
|
||||
var setting = ConfigurationManager.AppSettings["umbracoLocalTempStorage"];
|
||||
var setting = ConfigurationManager.AppSettings[Constants.AppSettings.LocalTempStorage];
|
||||
if (!string.IsNullOrWhiteSpace(setting))
|
||||
return Enum<LocalTempStorage>.Parse(setting);
|
||||
|
||||
@@ -295,6 +283,30 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string LocalTempPath
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (LocalTempStorageLocation)
|
||||
{
|
||||
case LocalTempStorage.AspNetTemp:
|
||||
return System.IO.Path.Combine(HttpRuntime.CodegenDir, "UmbracoData");
|
||||
case LocalTempStorage.EnvironmentTemp:
|
||||
// include the appdomain hash is just a safety check, for example if a website is moved from worker A to worker B and then back
|
||||
// to worker A again, in theory the %temp% folder should already be empty but we really want to make sure that its not
|
||||
// utilizing an old path - assuming we cannot have SHA1 collisions on AppDomainAppId
|
||||
var appDomainHash = HttpRuntime.AppDomainAppId.GenerateHash();
|
||||
return System.IO.Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "UmbracoData", appDomainHash);
|
||||
//case LocalTempStorage.Default:
|
||||
//case LocalTempStorage.Unknown:
|
||||
default:
|
||||
return IOHelper.MapPath("~/App_Data/TEMP");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default UI language.
|
||||
/// </summary>
|
||||
@@ -304,8 +316,8 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
get
|
||||
{
|
||||
return ConfigurationManager.AppSettings.ContainsKey("umbracoDefaultUILanguage")
|
||||
? ConfigurationManager.AppSettings["umbracoDefaultUILanguage"]
|
||||
return ConfigurationManager.AppSettings.ContainsKey(Constants.AppSettings.DefaultUILanguage)
|
||||
? ConfigurationManager.AppSettings[Constants.AppSettings.DefaultUILanguage]
|
||||
: string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -322,7 +334,7 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
try
|
||||
{
|
||||
return bool.Parse(ConfigurationManager.AppSettings["umbracoHideTopLevelNodeFromPath"]);
|
||||
return bool.Parse(ConfigurationManager.AppSettings[Constants.AppSettings.HideTopLevelNodeFromPath]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -340,7 +352,7 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
try
|
||||
{
|
||||
return bool.Parse(ConfigurationManager.AppSettings["umbracoUseHttps"]);
|
||||
return bool.Parse(ConfigurationManager.AppSettings[Constants.AppSettings.UseHttps]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -348,10 +360,5 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -128,6 +128,7 @@ namespace Umbraco.Core.Configuration
|
||||
if (routes == null) throw new ArgumentNullException(nameof(routes));
|
||||
|
||||
//check if the current request matches a route, if so then it is reserved.
|
||||
//TODO: This value should be cached! Else this is doing double routing in MVC every request!
|
||||
var route = routes.GetRouteData(httpContext);
|
||||
if (route != null)
|
||||
return true;
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Configuration
|
||||
namespace Umbraco.Core.Configuration
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains general settings information for the entire Umbraco instance based on information from web.config appsettings
|
||||
@@ -61,11 +59,13 @@ namespace Umbraco.Core.Configuration
|
||||
int VersionCheckPeriod { get; }
|
||||
|
||||
/// <summary>
|
||||
/// This is the location type to store temporary files such as cache files or other localized files for a given machine
|
||||
/// Gets the configuration for the location of temporary files.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Used for some cache files and for specific environments such as Azure
|
||||
/// </remarks>
|
||||
LocalTempStorage LocalTempStorageLocation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the location of temporary files.
|
||||
/// </summary>
|
||||
string LocalTempPath { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace Umbraco.Core.Configuration
|
||||
try
|
||||
{
|
||||
// TODO: https://github.com/umbraco/Umbraco-CMS/issues/4238 - stop having version in web.config appSettings
|
||||
var value = ConfigurationManager.AppSettings["umbracoConfigurationStatus"];
|
||||
var value = ConfigurationManager.AppSettings[Constants.AppSettings.ConfigurationStatus];
|
||||
return value.IsNullOrWhiteSpace() ? null : SemVersion.TryParse(value, out var semver) ? semver : null;
|
||||
}
|
||||
catch
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static partial class Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// Specific web.config AppSetting keys for Umbraco.Core application
|
||||
/// </summary>
|
||||
public static class AppSettings
|
||||
{
|
||||
// TODO: Kill me - still used in Umbraco.Core.IO.SystemFiles:27
|
||||
[Obsolete("We need to kill this appsetting as we do not use XML content cache umbraco.config anymore due to NuCache")]
|
||||
public const string ContentXML = "Umbraco.Core.ContentXML"; //umbracoContentXML
|
||||
|
||||
/// <summary>
|
||||
/// TODO: FILL ME IN
|
||||
/// </summary>
|
||||
public const string RegisterType = "Umbraco.Core.RegisterType";
|
||||
|
||||
/// <summary>
|
||||
/// This is used for a unit test in PublishedMediaCache
|
||||
/// </summary>
|
||||
public const string PublishedMediaCacheSeconds = "Umbraco.Core.PublishedMediaCacheSeconds";
|
||||
|
||||
/// <summary>
|
||||
/// TODO: FILL ME IN
|
||||
/// </summary>
|
||||
public const string AssembliesAcceptingLoadExceptions = "Umbraco.Core.AssembliesAcceptingLoadExceptions";
|
||||
|
||||
/// <summary>
|
||||
/// This will return the version number of the currently installed umbraco instance
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Umbraco will automatically set & modify this value when installing & upgrading
|
||||
/// </remarks>
|
||||
public const string ConfigurationStatus = "Umbraco.Core.ConfigurationStatus";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path to umbraco's root directory (/umbraco by default).
|
||||
/// </summary>
|
||||
public const string Path = "Umbraco.Core.Path";
|
||||
|
||||
/// <summary>
|
||||
/// The reserved urls from web.config.
|
||||
/// </summary>
|
||||
public const string ReservedUrls = "Umbraco.Core.ReservedUrls";
|
||||
|
||||
/// <summary>
|
||||
/// The reserved paths from web.config
|
||||
/// </summary>
|
||||
public const string ReservedPaths = "Umbraco.Core.ReservedPaths";
|
||||
|
||||
/// <summary>
|
||||
/// Set the timeout for the Umbraco backoffice in minutes
|
||||
/// </summary>
|
||||
public const string TimeOutInMinutes = "Umbraco.Core.TimeOutInMinutes";
|
||||
|
||||
/// <summary>
|
||||
/// The number of days to check for a new version of Umbraco
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Default is set to 7. Setting this to 0 will never check
|
||||
/// This is used to help track statistics
|
||||
/// </remarks>
|
||||
public const string VersionCheckPeriod = "Umbraco.Core.VersionCheckPeriod";
|
||||
|
||||
/// <summary>
|
||||
/// This is the location type to store temporary files such as cache files or other localized files for a given machine
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Currently used for the xml cache file and the plugin cache files
|
||||
/// </remarks>
|
||||
public const string LocalTempStorage = "Umbraco.Core.LocalTempStorage";
|
||||
|
||||
/// <summary>
|
||||
/// The default UI language of the backoffice such as 'en-US'
|
||||
/// </summary>
|
||||
public const string DefaultUILanguage = "Umbraco.Core.DefaultUILanguage";
|
||||
|
||||
/// <summary>
|
||||
/// A true/false value indicating whether umbraco should hide top level nodes from generated urls.
|
||||
/// </summary>
|
||||
public const string HideTopLevelNodeFromPath = "Umbraco.Core.HideTopLevelNodeFromPath";
|
||||
|
||||
/// <summary>
|
||||
/// A true or false indicating whether umbraco should force a secure (https) connection to the backoffice.
|
||||
/// </summary>
|
||||
public const string UseHttps = "Umbraco.Core.UseHttps";
|
||||
|
||||
/// <summary>
|
||||
/// TODO: FILL ME IN
|
||||
/// </summary>
|
||||
public const string DisableElectionForSingleServer = "Umbraco.Core.DisableElectionForSingleServer";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Debug specific web.config AppSetting keys for Umbraco
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Do not use these keys in a production environment
|
||||
/// </remarks>
|
||||
public static class Debug
|
||||
{
|
||||
/// <summary>
|
||||
/// When set to true, Scope logs the stack trace for any scope that gets disposed without being completed.
|
||||
/// this helps troubleshooting rogue scopes that we forget to complete
|
||||
/// </summary>
|
||||
public const string LogUncompletedScopes = "Umbraco.Core.Debug.LogUncompletedScopes";
|
||||
|
||||
/// <summary>
|
||||
/// When set to true, the Logger creates a mini dump of w3wp in ~/App_Data/MiniDump whenever it logs
|
||||
/// an error due to a ThreadAbortException that is due to a timeout.
|
||||
/// </summary>
|
||||
public const string DumpOnTimeoutThreadAbort = "Umbraco.Core.Debug.DumpOnTimeoutThreadAbort";
|
||||
|
||||
/// <summary>
|
||||
/// TODO: FILL ME IN
|
||||
/// </summary>
|
||||
public const string DatabaseFactoryServerVersion = "Umbraco.Core.Debug.DatabaseFactoryServerVersion";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,7 +77,7 @@
|
||||
/// alias for the macro tree.
|
||||
/// </summary>
|
||||
public const string Macros = "macros";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// alias for the datatype tree.
|
||||
/// </summary>
|
||||
@@ -92,7 +92,7 @@
|
||||
/// alias for the dictionary tree.
|
||||
/// </summary>
|
||||
public const string Dictionary = "dictionary";
|
||||
|
||||
|
||||
public const string Stylesheets = "stylesheets";
|
||||
|
||||
/// <summary>
|
||||
@@ -121,7 +121,7 @@
|
||||
public const string Templates = "templates";
|
||||
|
||||
public const string RelationTypes = "relationTypes";
|
||||
|
||||
|
||||
public const string Languages = "languages";
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -219,7 +219,7 @@ namespace Umbraco.Core
|
||||
},
|
||||
{
|
||||
FailedPasswordAttempts,
|
||||
new PropertyType(PropertyEditors.Aliases.NoEdit, ValueStorageType.Integer, true, FailedPasswordAttempts)
|
||||
new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Integer, true, FailedPasswordAttempts)
|
||||
{
|
||||
Name = FailedPasswordAttemptsLabel
|
||||
}
|
||||
@@ -240,35 +240,35 @@ namespace Umbraco.Core
|
||||
},
|
||||
{
|
||||
LastLockoutDate,
|
||||
new PropertyType(PropertyEditors.Aliases.NoEdit, ValueStorageType.Date, true, LastLockoutDate)
|
||||
new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Date, true, LastLockoutDate)
|
||||
{
|
||||
Name = LastLockoutDateLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
LastLoginDate,
|
||||
new PropertyType(PropertyEditors.Aliases.NoEdit, ValueStorageType.Date, true, LastLoginDate)
|
||||
new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Date, true, LastLoginDate)
|
||||
{
|
||||
Name = LastLoginDateLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
LastPasswordChangeDate,
|
||||
new PropertyType(PropertyEditors.Aliases.NoEdit, ValueStorageType.Date, true, LastPasswordChangeDate)
|
||||
new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Date, true, LastPasswordChangeDate)
|
||||
{
|
||||
Name = LastPasswordChangeDateLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
PasswordAnswer,
|
||||
new PropertyType(PropertyEditors.Aliases.NoEdit, ValueStorageType.Nvarchar, true, PasswordAnswer)
|
||||
new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Nvarchar, true, PasswordAnswer)
|
||||
{
|
||||
Name = PasswordAnswerLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
PasswordQuestion,
|
||||
new PropertyType(PropertyEditors.Aliases.NoEdit, ValueStorageType.Nvarchar, true, PasswordQuestion)
|
||||
new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Nvarchar, true, PasswordQuestion)
|
||||
{
|
||||
Name = PasswordQuestionLabel
|
||||
}
|
||||
|
||||
@@ -34,11 +34,7 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public const string ContentPicker = "Umbraco.ContentPicker";
|
||||
|
||||
/// <summary>
|
||||
/// Date.
|
||||
/// </summary>
|
||||
public const string Date = "Umbraco.Date";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// DateTime.
|
||||
/// </summary>
|
||||
@@ -48,7 +44,7 @@ namespace Umbraco.Core
|
||||
/// DropDown List.
|
||||
/// </summary>
|
||||
public const string DropDownListFlexible = "Umbraco.DropDown.Flexible";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Grid.
|
||||
/// </summary>
|
||||
@@ -105,9 +101,9 @@ namespace Umbraco.Core
|
||||
public const string MultipleTextstring = "Umbraco.MultipleTextstring";
|
||||
|
||||
/// <summary>
|
||||
/// NoEdit.
|
||||
/// Label.
|
||||
/// </summary>
|
||||
public const string NoEdit = "Umbraco.NoEdit";
|
||||
public const string Label = "Umbraco.Label";
|
||||
|
||||
/// <summary>
|
||||
/// Picker Relations.
|
||||
@@ -118,7 +114,7 @@ namespace Umbraco.Core
|
||||
/// RadioButton list.
|
||||
/// </summary>
|
||||
public const string RadioButtonList = "Umbraco.RadioButtonList";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Slider.
|
||||
/// </summary>
|
||||
@@ -142,7 +138,7 @@ namespace Umbraco.Core
|
||||
/// <summary>
|
||||
/// TinyMCE
|
||||
/// </summary>
|
||||
public const string TinyMce = "Umbraco.TinyMCEv3";
|
||||
public const string TinyMce = "Umbraco.TinyMCE";
|
||||
|
||||
/// <summary>
|
||||
/// Boolean.
|
||||
@@ -163,7 +159,7 @@ namespace Umbraco.Core
|
||||
/// Upload Field.
|
||||
/// </summary>
|
||||
public const string UploadField = "Umbraco.UploadField";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Email Address.
|
||||
/// </summary>
|
||||
|
||||
@@ -52,36 +52,8 @@ namespace Umbraco.Core
|
||||
return ContentStatus.Unpublished;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cultures that have been flagged for unpublishing.
|
||||
/// </summary>
|
||||
/// <remarks>Gets cultures for which content.UnpublishCulture() has been invoked.</remarks>
|
||||
internal static IReadOnlyList<string> GetCulturesUnpublishing(this IContent content)
|
||||
{
|
||||
if (!content.Published || !content.ContentType.VariesByCulture() || !content.IsPropertyDirty("PublishCultureInfos"))
|
||||
return Array.Empty<string>();
|
||||
|
||||
var culturesChanging = content.CultureInfos.Where(x => x.Value.IsDirty()).Select(x => x.Key);
|
||||
return culturesChanging
|
||||
.Where(x => !content.IsCulturePublished(x) && // is not published anymore
|
||||
content.WasCulturePublished(x)) // but was published before
|
||||
.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this entity was just published as part of a recent save operation (i.e. it wasn't previously published)
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This is helpful for determining if the published event will execute during the saved event for a content item.
|
||||
/// </remarks>
|
||||
internal static bool JustPublished(this IContent entity)
|
||||
{
|
||||
var dirty = (IRememberBeingDirty)entity;
|
||||
return dirty.WasPropertyDirty("Published") && entity.Published;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
@@ -129,7 +101,7 @@ namespace Umbraco.Core
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns properties that do not belong to a group
|
||||
/// </summary>
|
||||
@@ -137,10 +109,9 @@ namespace Umbraco.Core
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Property> GetNonGroupedProperties(this IContentBase content)
|
||||
{
|
||||
var propertyIdsInTabs = content.PropertyGroups.SelectMany(pg => pg.PropertyTypes);
|
||||
return content.Properties
|
||||
.Where(property => propertyIdsInTabs.Contains(property.PropertyType) == false)
|
||||
.OrderBy(x => x.PropertyType.SortOrder);
|
||||
.Where(x => x.PropertyType.PropertyGroupId == null)
|
||||
.OrderBy(x => x.PropertyType.SortOrder);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -158,16 +129,6 @@ namespace Umbraco.Core
|
||||
.Contains(property.PropertyTypeId));
|
||||
}
|
||||
|
||||
public static IContentTypeComposition GetContentType(this IContentBase contentBase)
|
||||
{
|
||||
if (contentBase == null) throw new ArgumentNullException(nameof(contentBase));
|
||||
|
||||
if (contentBase is IContent content) return content.ContentType;
|
||||
if (contentBase is IMedia media) return media.ContentType;
|
||||
if (contentBase is IMember member) return member.ContentType;
|
||||
throw new NotSupportedException("Unsupported IContentBase implementation: " + contentBase.GetType().FullName + ".");
|
||||
}
|
||||
|
||||
#region SetValue for setting file contents
|
||||
|
||||
/// <summary>
|
||||
@@ -176,7 +137,7 @@ namespace Umbraco.Core
|
||||
/// <remarks>This really is for FileUpload fields only, and should be obsoleted. For anything else,
|
||||
/// you need to store the file by yourself using Store and then figure out
|
||||
/// how to deal with auto-fill properties (if any) and thumbnails (if any) by yourself.</remarks>
|
||||
public static void SetValue(this IContentBase content, string propertyTypeAlias, string filename, Stream filestream, string culture = null, string segment = null)
|
||||
public static void SetValue(this IContentBase content, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, string propertyTypeAlias, string filename, Stream filestream, string culture = null, string segment = null)
|
||||
{
|
||||
if (filename == null || filestream == null) return;
|
||||
|
||||
@@ -185,12 +146,12 @@ namespace Umbraco.Core
|
||||
if (string.IsNullOrWhiteSpace(filename)) return;
|
||||
filename = filename.ToLower();
|
||||
|
||||
SetUploadFile(content, propertyTypeAlias, filename, filestream, culture, segment);
|
||||
SetUploadFile(content,contentTypeBaseServiceProvider, propertyTypeAlias, filename, filestream, culture, segment);
|
||||
}
|
||||
|
||||
private static void SetUploadFile(this IContentBase content, string propertyTypeAlias, string filename, Stream filestream, string culture = null, string segment = null)
|
||||
private static void SetUploadFile(this IContentBase content, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, string propertyTypeAlias, string filename, Stream filestream, string culture = null, string segment = null)
|
||||
{
|
||||
var property = GetProperty(content, propertyTypeAlias);
|
||||
var property = GetProperty(content, contentTypeBaseServiceProvider, propertyTypeAlias);
|
||||
|
||||
// Fixes https://github.com/umbraco/Umbraco-CMS/issues/3937 - Assigning a new file to an
|
||||
// existing IMedia with extension SetValue causes exception 'Illegal characters in path'
|
||||
@@ -211,12 +172,13 @@ namespace Umbraco.Core
|
||||
}
|
||||
|
||||
// gets or creates a property for a content item.
|
||||
private static Property GetProperty(IContentBase content, string propertyTypeAlias)
|
||||
private static Property GetProperty(IContentBase content, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, string propertyTypeAlias)
|
||||
{
|
||||
var property = content.Properties.FirstOrDefault(x => x.Alias.InvariantEquals(propertyTypeAlias));
|
||||
if (property != null) return property;
|
||||
|
||||
var propertyType = content.GetContentType().CompositionPropertyTypes
|
||||
var contentType = contentTypeBaseServiceProvider.GetContentTypeOf(content);
|
||||
var propertyType = contentType.CompositionPropertyTypes
|
||||
.FirstOrDefault(x => x.Alias.InvariantEquals(propertyTypeAlias));
|
||||
if (propertyType == null)
|
||||
throw new Exception("No property type exists with alias " + propertyTypeAlias + ".");
|
||||
@@ -242,9 +204,10 @@ namespace Umbraco.Core
|
||||
/// the "folder number" that was assigned to the previous file referenced by the property,
|
||||
/// if any.</para>
|
||||
/// </remarks>
|
||||
public static string StoreFile(this IContentBase content, string propertyTypeAlias, string filename, Stream filestream, string filepath)
|
||||
public static string StoreFile(this IContentBase content, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, string propertyTypeAlias, string filename, Stream filestream, string filepath)
|
||||
{
|
||||
var propertyType = content.GetContentType()
|
||||
var contentType = contentTypeBaseServiceProvider.GetContentTypeOf(content);
|
||||
var propertyType = contentType
|
||||
.CompositionPropertyTypes.FirstOrDefault(x => x.Alias.InvariantEquals(propertyTypeAlias));
|
||||
if (propertyType == null) throw new ArgumentException("Invalid property type alias " + propertyTypeAlias + ".");
|
||||
return MediaFileSystem.StoreFile(content, propertyType, filename, filestream, filepath);
|
||||
@@ -325,7 +288,7 @@ namespace Umbraco.Core
|
||||
{
|
||||
return serializer.Serialize(content, false, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates the xml representation for the <see cref="IMedia"/> object
|
||||
|
||||
@@ -9,6 +9,16 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public static class ContentVariationExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines whether the content type is invariant.
|
||||
/// </summary>
|
||||
public static bool VariesByNothing(this ISimpleContentType contentType) => contentType.Variations.VariesByNothing();
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the content type varies by culture.
|
||||
/// </summary>
|
||||
public static bool VariesByCulture(this ISimpleContentType contentType) => contentType.Variations.VariesByCulture();
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the content type is invariant.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Abstract implementation of IDisposable.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is for objects that DO have unmanaged resources. Use <see cref="DisposableObjectSlim"/>
|
||||
/// for objects that do NOT have unmanaged resources, and avoid creating a finalizer.
|
||||
///
|
||||
/// Can also be used as a pattern for when inheriting is not possible.
|
||||
///
|
||||
/// See also: https://msdn.microsoft.com/en-us/library/b1yfkh5e%28v=vs.110%29.aspx
|
||||
/// See also: https://lostechies.com/chrispatterson/2012/11/29/idisposable-done-right/
|
||||
///
|
||||
/// Note: if an object's ctor throws, it will never be disposed, and so if that ctor
|
||||
/// has allocated disposable objects, it should take care of disposing them.
|
||||
/// </remarks>
|
||||
public abstract class DisposableObject : IDisposable
|
||||
{
|
||||
private readonly object _locko = new object();
|
||||
|
||||
// gets a value indicating whether this instance is disposed.
|
||||
// for internal tests only (not thread safe)
|
||||
public bool Disposed { get; private set; }
|
||||
|
||||
// implements IDisposable
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
// finalizer
|
||||
~DisposableObject()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
// can happen if the object construction failed
|
||||
if (_locko == null)
|
||||
return;
|
||||
|
||||
lock (_locko)
|
||||
{
|
||||
if (Disposed) return;
|
||||
Disposed = true;
|
||||
}
|
||||
|
||||
DisposeUnmanagedResources();
|
||||
|
||||
if (disposing)
|
||||
DisposeResources();
|
||||
}
|
||||
|
||||
protected abstract void DisposeResources();
|
||||
|
||||
protected virtual void DisposeUnmanagedResources()
|
||||
{ }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Events
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents event data, for events that support cancellation, and expose impacted objects.
|
||||
/// </summary>
|
||||
/// <typeparam name="TEventObject">The type of the exposed, impacted objects.</typeparam>
|
||||
public class CancellableEnumerableObjectEventArgs<TEventObject> : CancellableObjectEventArgs<IEnumerable<TEventObject>>, IEquatable<CancellableEnumerableObjectEventArgs<TEventObject>>
|
||||
{
|
||||
public CancellableEnumerableObjectEventArgs(IEnumerable<TEventObject> eventObject, bool canCancel, EventMessages messages, IDictionary<string, object> additionalData)
|
||||
: base(eventObject, canCancel, messages, additionalData)
|
||||
{ }
|
||||
|
||||
public CancellableEnumerableObjectEventArgs(IEnumerable<TEventObject> eventObject, bool canCancel, EventMessages eventMessages)
|
||||
: base(eventObject, canCancel, eventMessages)
|
||||
{ }
|
||||
|
||||
public CancellableEnumerableObjectEventArgs(IEnumerable<TEventObject> eventObject, EventMessages eventMessages)
|
||||
: base(eventObject, eventMessages)
|
||||
{ }
|
||||
|
||||
public CancellableEnumerableObjectEventArgs(IEnumerable<TEventObject> eventObject, bool canCancel)
|
||||
: base(eventObject, canCancel)
|
||||
{ }
|
||||
|
||||
public CancellableEnumerableObjectEventArgs(IEnumerable<TEventObject> eventObject)
|
||||
: base(eventObject)
|
||||
{ }
|
||||
|
||||
public bool Equals(CancellableEnumerableObjectEventArgs<TEventObject> other)
|
||||
{
|
||||
if (other is null) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
|
||||
return EventObject.SequenceEqual(other.EventObject);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is null) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != this.GetType()) return false;
|
||||
return Equals((CancellableEnumerableObjectEventArgs<TEventObject>)obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCodeHelper.GetHashCode(EventObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Security.Permissions;
|
||||
|
||||
namespace Umbraco.Core.Events
|
||||
{
|
||||
/// <summary>
|
||||
/// Event args for that can support cancellation
|
||||
/// Represents event data for events that support cancellation.
|
||||
/// </summary>
|
||||
[HostProtection(SecurityAction.LinkDemand, SharedState = true)]
|
||||
public class CancellableEventArgs : EventArgs, IEquatable<CancellableEventArgs>
|
||||
{
|
||||
private bool _cancel;
|
||||
private Dictionary<string, object> _eventState;
|
||||
private IDictionary<string, object> _eventState;
|
||||
|
||||
private static readonly ReadOnlyDictionary<string, object> EmptyAdditionalData = new ReadOnlyDictionary<string, object>(new Dictionary<string, object>());
|
||||
|
||||
@@ -89,7 +87,7 @@ namespace Umbraco.Core.Events
|
||||
/// <summary>
|
||||
/// Returns the EventMessages object which is used to add messages to the message collection for this event
|
||||
/// </summary>
|
||||
public EventMessages Messages { get; private set; }
|
||||
public EventMessages Messages { get; }
|
||||
|
||||
/// <summary>
|
||||
/// In some cases raised evens might need to contain additional arbitrary readonly data which can be read by event subscribers
|
||||
@@ -98,7 +96,7 @@ namespace Umbraco.Core.Events
|
||||
/// This allows for a bit of flexibility in our event raising - it's not pretty but we need to maintain backwards compatibility
|
||||
/// so we cannot change the strongly typed nature for some events.
|
||||
/// </remarks>
|
||||
public ReadOnlyDictionary<string, object> AdditionalData { get; private set; }
|
||||
public ReadOnlyDictionary<string, object> AdditionalData { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// This can be used by event subscribers to store state in the event args so they easily deal with custom state data between a starting ("ing")
|
||||
@@ -106,7 +104,8 @@ namespace Umbraco.Core.Events
|
||||
/// </summary>
|
||||
public IDictionary<string, object> EventState
|
||||
{
|
||||
get { return _eventState ?? (_eventState = new Dictionary<string, object>()); }
|
||||
get => _eventState ?? (_eventState = new Dictionary<string, object>());
|
||||
internal set => _eventState = value;
|
||||
}
|
||||
|
||||
public bool Equals(CancellableEventArgs other)
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Permissions;
|
||||
using Umbraco.Core.Models;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Events
|
||||
{
|
||||
/// <summary>
|
||||
/// Used as a base class for the generic type CancellableObjectEventArgs{T} so that we can get direct 'object' access to the underlying EventObject
|
||||
/// Provides a base class for classes representing event data, for events that support cancellation, and expose an impacted object.
|
||||
/// </summary>
|
||||
[HostProtection(SecurityAction.LinkDemand, SharedState = true)]
|
||||
public abstract class CancellableObjectEventArgs : CancellableEventArgs
|
||||
{
|
||||
protected CancellableObjectEventArgs(object eventObject, bool canCancel, EventMessages messages, IDictionary<string, object> additionalData)
|
||||
@@ -42,135 +36,11 @@ namespace Umbraco.Core.Events
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the object relating to the event
|
||||
/// Gets or sets the impacted object.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is protected so that inheritors can expose it with their own name
|
||||
/// </remarks>
|
||||
internal object EventObject { get; set; }
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event args for a strongly typed object that can support cancellation
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
[HostProtection(SecurityAction.LinkDemand, SharedState = true)]
|
||||
public class CancellableObjectEventArgs<T> : CancellableObjectEventArgs, IEquatable<CancellableObjectEventArgs<T>>
|
||||
{
|
||||
public CancellableObjectEventArgs(T eventObject, bool canCancel, EventMessages messages, IDictionary<string, object> additionalData)
|
||||
: base(eventObject, canCancel, messages, additionalData)
|
||||
{
|
||||
}
|
||||
|
||||
public CancellableObjectEventArgs(T eventObject, bool canCancel, EventMessages eventMessages)
|
||||
: base(eventObject, canCancel, eventMessages)
|
||||
{
|
||||
}
|
||||
|
||||
public CancellableObjectEventArgs(T eventObject, EventMessages eventMessages)
|
||||
: base(eventObject, eventMessages)
|
||||
{
|
||||
}
|
||||
|
||||
public CancellableObjectEventArgs(T eventObject, bool canCancel)
|
||||
: base(eventObject, canCancel)
|
||||
{
|
||||
}
|
||||
|
||||
public CancellableObjectEventArgs(T eventObject)
|
||||
: base(eventObject)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the object relating to the event
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is protected so that inheritors can expose it with their own name
|
||||
/// </remarks>
|
||||
protected new T EventObject
|
||||
{
|
||||
get { return (T) base.EventObject; }
|
||||
set { base.EventObject = value; }
|
||||
}
|
||||
|
||||
public bool Equals(CancellableObjectEventArgs<T> other)
|
||||
{
|
||||
if (other is null) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
return base.Equals(other) && EqualityComparer<T>.Default.Equals(EventObject, other.EventObject);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is null) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != this.GetType()) return false;
|
||||
return Equals((CancellableObjectEventArgs<T>)obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return (base.GetHashCode() * 397) ^ EqualityComparer<T>.Default.GetHashCode(EventObject);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool operator ==(CancellableObjectEventArgs<T> left, CancellableObjectEventArgs<T> right)
|
||||
{
|
||||
return Equals(left, right);
|
||||
}
|
||||
|
||||
public static bool operator !=(CancellableObjectEventArgs<T> left, CancellableObjectEventArgs<T> right)
|
||||
{
|
||||
return !Equals(left, right);
|
||||
}
|
||||
}
|
||||
|
||||
[HostProtection(SecurityAction.LinkDemand, SharedState = true)]
|
||||
public class CancellableEnumerableObjectEventArgs<T> : CancellableObjectEventArgs<IEnumerable<T>>, IEquatable<CancellableEnumerableObjectEventArgs<T>>
|
||||
{
|
||||
public CancellableEnumerableObjectEventArgs(IEnumerable<T> eventObject, bool canCancel, EventMessages messages, IDictionary<string, object> additionalData)
|
||||
: base(eventObject, canCancel, messages, additionalData)
|
||||
{ }
|
||||
|
||||
public CancellableEnumerableObjectEventArgs(IEnumerable<T> eventObject, bool canCancel, EventMessages eventMessages)
|
||||
: base(eventObject, canCancel, eventMessages)
|
||||
{ }
|
||||
|
||||
public CancellableEnumerableObjectEventArgs(IEnumerable<T> eventObject, EventMessages eventMessages)
|
||||
: base(eventObject, eventMessages)
|
||||
{ }
|
||||
|
||||
public CancellableEnumerableObjectEventArgs(IEnumerable<T> eventObject, bool canCancel)
|
||||
: base(eventObject, canCancel)
|
||||
{ }
|
||||
|
||||
public CancellableEnumerableObjectEventArgs(IEnumerable<T> eventObject)
|
||||
: base(eventObject)
|
||||
{ }
|
||||
|
||||
public bool Equals(CancellableEnumerableObjectEventArgs<T> other)
|
||||
{
|
||||
if (other is null) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
|
||||
return EventObject.SequenceEqual(other.EventObject);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is null) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != this.GetType()) return false;
|
||||
return Equals((CancellableEnumerableObjectEventArgs<T>)obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCodeHelper.GetHashCode(EventObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Events
|
||||
{
|
||||
/// <summary>
|
||||
/// Represent event data, for events that support cancellation, and expose an impacted object.
|
||||
/// </summary>
|
||||
/// <typeparam name="TEventObject">The type of the exposed, impacted object.</typeparam>
|
||||
public class CancellableObjectEventArgs<TEventObject> : CancellableObjectEventArgs, IEquatable<CancellableObjectEventArgs<TEventObject>>
|
||||
{
|
||||
public CancellableObjectEventArgs(TEventObject eventObject, bool canCancel, EventMessages messages, IDictionary<string, object> additionalData)
|
||||
: base(eventObject, canCancel, messages, additionalData)
|
||||
{
|
||||
}
|
||||
|
||||
public CancellableObjectEventArgs(TEventObject eventObject, bool canCancel, EventMessages eventMessages)
|
||||
: base(eventObject, canCancel, eventMessages)
|
||||
{
|
||||
}
|
||||
|
||||
public CancellableObjectEventArgs(TEventObject eventObject, EventMessages eventMessages)
|
||||
: base(eventObject, eventMessages)
|
||||
{
|
||||
}
|
||||
|
||||
public CancellableObjectEventArgs(TEventObject eventObject, bool canCancel)
|
||||
: base(eventObject, canCancel)
|
||||
{
|
||||
}
|
||||
|
||||
public CancellableObjectEventArgs(TEventObject eventObject)
|
||||
: base(eventObject)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the impacted object.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is protected so that inheritors can expose it with their own name
|
||||
/// </remarks>
|
||||
protected new TEventObject EventObject
|
||||
{
|
||||
get => (TEventObject) base.EventObject;
|
||||
set => base.EventObject = value;
|
||||
}
|
||||
|
||||
public bool Equals(CancellableObjectEventArgs<TEventObject> other)
|
||||
{
|
||||
if (other is null) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
return base.Equals(other) && EqualityComparer<TEventObject>.Default.Equals(EventObject, other.EventObject);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is null) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != this.GetType()) return false;
|
||||
return Equals((CancellableObjectEventArgs<TEventObject>)obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return (base.GetHashCode() * 397) ^ EqualityComparer<TEventObject>.Default.GetHashCode(EventObject);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool operator ==(CancellableObjectEventArgs<TEventObject> left, CancellableObjectEventArgs<TEventObject> right)
|
||||
{
|
||||
return Equals(left, right);
|
||||
}
|
||||
|
||||
public static bool operator !=(CancellableObjectEventArgs<TEventObject> left, CancellableObjectEventArgs<TEventObject> right)
|
||||
{
|
||||
return !Equals(left, right);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Events
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents event data for the Published event.
|
||||
/// </summary>
|
||||
public class ContentPublishedEventArgs : PublishEventArgs<IContent>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ContentPublishedEventArgs"/> class.
|
||||
/// </summary>
|
||||
public ContentPublishedEventArgs(IEnumerable<IContent> eventObject, bool canCancel, EventMessages eventMessages)
|
||||
: base(eventObject, canCancel, eventMessages)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether a culture has been published, during a Published event.
|
||||
/// </summary>
|
||||
public bool HasPublishedCulture(IContent content, string culture)
|
||||
=> content.WasPropertyDirty(ContentBase.ChangeTrackingPrefix.ChangedCulture + culture);
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether a culture has been unpublished, during a Published event.
|
||||
/// </summary>
|
||||
public bool HasUnpublishedCulture(IContent content, string culture)
|
||||
=> content.WasPropertyDirty(ContentBase.ChangeTrackingPrefix.UnpublishedCulture + culture);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Events
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents event data for the Publishing event.
|
||||
/// </summary>
|
||||
public class ContentPublishingEventArgs : PublishEventArgs<IContent>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ContentPublishingEventArgs"/> class.
|
||||
/// </summary>
|
||||
public ContentPublishingEventArgs(IEnumerable<IContent> eventObject, EventMessages eventMessages)
|
||||
: base(eventObject, eventMessages)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether a culture is being published, during a Publishing event.
|
||||
/// </summary>
|
||||
public bool IsPublishingCulture(IContent content, string culture)
|
||||
=> content.PublishCultureInfos.TryGetValue(culture, out var cultureInfo) && cultureInfo.IsDirty();
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether a culture is being unpublished, during a Publishing event.
|
||||
/// </summary>
|
||||
public bool IsUnpublishingCulture(IContent content, string culture)
|
||||
=> content.IsPropertyDirty(ContentBase.ChangeTrackingPrefix.UnpublishedCulture + culture); //bit of a hack since we know that the content implementation tracks changes this way
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Events
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents event data for the Saved event.
|
||||
/// </summary>
|
||||
public class ContentSavedEventArgs : SaveEventArgs<IContent>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ContentSavedEventArgs"/> class.
|
||||
/// </summary>
|
||||
public ContentSavedEventArgs(IEnumerable<IContent> eventObject, EventMessages messages, IDictionary<string, object> additionalData)
|
||||
: base(eventObject, false, messages, additionalData)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether a culture has been saved, during a Saved event.
|
||||
/// </summary>
|
||||
public bool HasSavedCulture(IContent content, string culture)
|
||||
=> content.WasPropertyDirty(ContentBase.ChangeTrackingPrefix.UpdatedCulture + culture);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Events
|
||||
{
|
||||
/// <summary>
|
||||
/// Represent event data for the Saving event.
|
||||
/// </summary>
|
||||
public class ContentSavingEventArgs : SaveEventArgs<IContent>
|
||||
{
|
||||
#region Factory Methods
|
||||
|
||||
/// <summary>
|
||||
/// Converts <see cref="ContentSavingEventArgs"/> to <see cref="ContentSavedEventArgs"/> while preserving all args state
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ContentSavedEventArgs ToContentSavedEventArgs()
|
||||
{
|
||||
return new ContentSavedEventArgs(EventObject, Messages, AdditionalData)
|
||||
{
|
||||
EventState = EventState
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts <see cref="ContentSavingEventArgs"/> to <see cref="ContentPublishedEventArgs"/> while preserving all args state
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ContentPublishedEventArgs ToContentPublishedEventArgs()
|
||||
{
|
||||
return new ContentPublishedEventArgs(EventObject, false, Messages)
|
||||
{
|
||||
EventState = EventState,
|
||||
AdditionalData = AdditionalData
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts <see cref="ContentSavingEventArgs"/> to <see cref="ContentPublishingEventArgs"/> while preserving all args state
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ContentPublishingEventArgs ToContentPublishingEventArgs()
|
||||
{
|
||||
return new ContentPublishingEventArgs(EventObject, Messages)
|
||||
{
|
||||
EventState = EventState,
|
||||
AdditionalData = AdditionalData
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ContentSavingEventArgs"/> class.
|
||||
/// </summary>
|
||||
public ContentSavingEventArgs(IEnumerable<IContent> eventObject, EventMessages eventMessages)
|
||||
: base(eventObject, eventMessages)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ContentSavingEventArgs"/> class.
|
||||
/// </summary>
|
||||
public ContentSavingEventArgs(IContent eventObject, EventMessages eventMessages)
|
||||
: base(eventObject, eventMessages)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether a culture is being saved, during a Saving event.
|
||||
/// </summary>
|
||||
public bool IsSavingCulture(IContent content, string culture)
|
||||
=> content.CultureInfos.TryGetValue(culture, out var cultureInfo) && cultureInfo.IsDirty();
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,24 @@ namespace Umbraco.Core.Events
|
||||
/// null if not found or an ambiguous match
|
||||
/// </returns>
|
||||
public static Attempt<EventNameExtractorResult> FindEvent(Type senderType, Type argsType, Func<string, bool> exclude)
|
||||
{
|
||||
var events = FindEvents(senderType, argsType, exclude);
|
||||
|
||||
switch (events.Length)
|
||||
{
|
||||
case 0:
|
||||
return Attempt.Fail(new EventNameExtractorResult(EventNameExtractorError.NoneFound));
|
||||
|
||||
case 1:
|
||||
return Attempt.Succeed(new EventNameExtractorResult(events[0]));
|
||||
|
||||
default:
|
||||
//there's more than one left so it's ambiguous!
|
||||
return Attempt.Fail(new EventNameExtractorResult(EventNameExtractorError.Ambiguous));
|
||||
}
|
||||
}
|
||||
|
||||
internal static string[] FindEvents(Type senderType, Type argsType, Func<string, bool> exclude)
|
||||
{
|
||||
var found = MatchedEventNames.GetOrAdd(new Tuple<Type, Type>(senderType, argsType), tuple =>
|
||||
{
|
||||
@@ -78,16 +96,7 @@ namespace Umbraco.Core.Events
|
||||
}).Select(x => x.EventInfo.Name).ToArray();
|
||||
});
|
||||
|
||||
var filtered = found.Where(x => exclude(x) == false).ToArray();
|
||||
|
||||
if (filtered.Length == 0)
|
||||
return Attempt.Fail(new EventNameExtractorResult(EventNameExtractorError.NoneFound));
|
||||
|
||||
if (filtered.Length == 1)
|
||||
return Attempt.Succeed(new EventNameExtractorResult(filtered[0]));
|
||||
|
||||
//there's more than one left so it's ambiguous!
|
||||
return Attempt.Fail(new EventNameExtractorResult(EventNameExtractorError.Ambiguous));
|
||||
return found.Where(x => exclude(x) == false).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -10,12 +10,10 @@ namespace Umbraco.Core.Events
|
||||
/// </summary>
|
||||
/// <param name="eventObject"></param>
|
||||
/// <param name="canCancel"></param>
|
||||
/// <param name="isAllPublished"></param>
|
||||
/// <param name="eventMessages"></param>
|
||||
public PublishEventArgs(IEnumerable<TEntity> eventObject, bool canCancel, bool isAllPublished, EventMessages eventMessages)
|
||||
public PublishEventArgs(IEnumerable<TEntity> eventObject, bool canCancel, EventMessages eventMessages)
|
||||
: base(eventObject, canCancel, eventMessages)
|
||||
{
|
||||
IsAllRepublished = isAllPublished;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -43,12 +41,10 @@ namespace Umbraco.Core.Events
|
||||
/// </summary>
|
||||
/// <param name="eventObject"></param>
|
||||
/// <param name="canCancel"></param>
|
||||
/// <param name="isAllPublished"></param>
|
||||
/// <param name="eventMessages"></param>
|
||||
public PublishEventArgs(TEntity eventObject, bool canCancel, bool isAllPublished, EventMessages eventMessages)
|
||||
public PublishEventArgs(TEntity eventObject, bool canCancel, EventMessages eventMessages)
|
||||
: base(new List<TEntity> { eventObject }, canCancel, eventMessages)
|
||||
{
|
||||
IsAllRepublished = isAllPublished;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -60,7 +56,6 @@ namespace Umbraco.Core.Events
|
||||
public PublishEventArgs(IEnumerable<TEntity> eventObject, bool canCancel, bool isAllPublished)
|
||||
: base(eventObject, canCancel)
|
||||
{
|
||||
IsAllRepublished = isAllPublished;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -90,24 +85,18 @@ namespace Umbraco.Core.Events
|
||||
public PublishEventArgs(TEntity eventObject, bool canCancel, bool isAllPublished)
|
||||
: base(new List<TEntity> { eventObject }, canCancel)
|
||||
{
|
||||
IsAllRepublished = isAllPublished;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all entities that were published during the operation
|
||||
/// </summary>
|
||||
public IEnumerable<TEntity> PublishedEntities
|
||||
{
|
||||
get { return EventObject; }
|
||||
}
|
||||
|
||||
public bool IsAllRepublished { get; private set; }
|
||||
public IEnumerable<TEntity> PublishedEntities => EventObject;
|
||||
|
||||
public bool Equals(PublishEventArgs<TEntity> other)
|
||||
{
|
||||
if (ReferenceEquals(null, other)) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
return base.Equals(other) && IsAllRepublished == other.IsAllRepublished;
|
||||
return base.Equals(other);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
@@ -122,7 +111,7 @@ namespace Umbraco.Core.Events
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return (base.GetHashCode() * 397) ^ IsAllRepublished.GetHashCode();
|
||||
return (base.GetHashCode() * 397);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Events
|
||||
{
|
||||
@@ -113,9 +112,6 @@ namespace Umbraco.Core.Events
|
||||
/// <summary>
|
||||
/// Returns all entities that were saved during the operation
|
||||
/// </summary>
|
||||
public IEnumerable<TEntity> SavedEntities
|
||||
{
|
||||
get { return EventObject; }
|
||||
}
|
||||
public IEnumerable<TEntity> SavedEntities => EventObject;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Umbraco.Core.Exceptions
|
||||
/// <summary>
|
||||
/// Defines the default boot failed exception message.
|
||||
/// </summary>
|
||||
public const string DefaultMessage = "Boot failed: Umbraco cannot run. Sad. See Umbraco's log file for more details.";
|
||||
public const string DefaultMessage = "Boot failed: Umbraco cannot run. See Umbraco's log file for more details.";
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Exception"/> class with a specified error message.
|
||||
|
||||
+2
-1
@@ -1,8 +1,9 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.Composing
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides extension methods to the <see cref="IFactory"/> class.
|
||||
@@ -40,5 +40,72 @@ namespace Umbraco.Core
|
||||
|
||||
public DecomposedGuid(Guid value) : this() => this.Value = value;
|
||||
}
|
||||
|
||||
private static readonly char[] Base32Table =
|
||||
{
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
|
||||
'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5'
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Converts a Guid into a base-32 string.
|
||||
/// </summary>
|
||||
/// <param name="guid">A Guid.</param>
|
||||
/// <param name="length">The string length.</param>
|
||||
/// <returns>A base-32 encoded string.</returns>
|
||||
/// <remarks>
|
||||
/// <para>A base-32 string representation of a Guid is the shortest, efficient, representation
|
||||
/// that is case insensitive (base-64 is case sensitive).</para>
|
||||
/// <para>Length must be 1-26, anything else becomes 26.</para>
|
||||
/// </remarks>
|
||||
public static string ToBase32String(Guid guid, int length = 26)
|
||||
{
|
||||
if (length <= 0 || length > 26)
|
||||
length = 26;
|
||||
|
||||
var bytes = guid.ToByteArray(); // a Guid is 128 bits ie 16 bytes
|
||||
|
||||
// this could be optimized by making it unsafe,
|
||||
// and fixing the table + bytes + chars (see Convert.ToBase64CharArray)
|
||||
|
||||
// each block of 5 bytes = 5*8 = 40 bits
|
||||
// becomes 40 bits = 8*5 = 8 byte-32 chars
|
||||
// a Guid is 3 blocks + 8 bits
|
||||
|
||||
// so it turns into a 3*8+2 = 26 chars string
|
||||
var chars = new char[length];
|
||||
|
||||
var i = 0;
|
||||
var j = 0;
|
||||
|
||||
while (i < 15)
|
||||
{
|
||||
if (j == length) break;
|
||||
chars[j++] = Base32Table[(bytes[i] & 0b1111_1000) >> 3];
|
||||
if (j == length) break;
|
||||
chars[j++] = Base32Table[((bytes[i] & 0b0000_0111) << 2) | ((bytes[i + 1] & 0b1100_0000) >> 6)];
|
||||
if (j == length) break;
|
||||
chars[j++] = Base32Table[(bytes[i + 1] & 0b0011_1110) >> 1];
|
||||
if (j == length) break;
|
||||
chars[j++] = Base32Table[(bytes[i + 1] & 0b0000_0001) | ((bytes[i + 2] & 0b1111_0000) >> 4)];
|
||||
if (j == length) break;
|
||||
chars[j++] = Base32Table[((bytes[i + 2] & 0b0000_1111) << 1) | ((bytes[i + 3] & 0b1000_0000) >> 7)];
|
||||
if (j == length) break;
|
||||
chars[j++] = Base32Table[(bytes[i + 3] & 0b0111_1100) >> 2];
|
||||
if (j == length) break;
|
||||
chars[j++] = Base32Table[((bytes[i + 3] & 0b0000_0011) << 3) | ((bytes[i + 4] & 0b1110_0000) >> 5)];
|
||||
if (j == length) break;
|
||||
chars[j++] = Base32Table[bytes[i + 4] & 0b0001_1111];
|
||||
|
||||
i += 5;
|
||||
}
|
||||
|
||||
if (j < length)
|
||||
chars[j++] = Base32Table[(bytes[i] & 0b1111_1000) >> 3];
|
||||
if (j < length)
|
||||
chars[j] = Base32Table[(bytes[i] & 0b0000_0111) << 2];
|
||||
|
||||
return new string(chars);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Umbraco.Core.IO
|
||||
// shadow support
|
||||
private readonly List<ShadowWrapper> _shadowWrappers = new List<ShadowWrapper>();
|
||||
private readonly object _shadowLocker = new object();
|
||||
private static Guid _shadowCurrentId = Guid.Empty; // static - unique!!
|
||||
private static string _shadowCurrentId; // static - unique!!
|
||||
#region Constructor
|
||||
|
||||
// DI wants a public ctor
|
||||
@@ -45,13 +45,13 @@ namespace Umbraco.Core.IO
|
||||
_shadowWrappers.Clear();
|
||||
_filesystems.Clear();
|
||||
Volatile.Write(ref _wkfsInitialized, false);
|
||||
_shadowCurrentId = Guid.Empty;
|
||||
_shadowCurrentId = null;
|
||||
}
|
||||
|
||||
// for tests only, totally unsafe
|
||||
internal static void ResetShadowId()
|
||||
{
|
||||
_shadowCurrentId = Guid.Empty;
|
||||
_shadowCurrentId = null;
|
||||
}
|
||||
|
||||
// set by the scope provider when taking control of filesystems
|
||||
@@ -126,11 +126,11 @@ namespace Umbraco.Core.IO
|
||||
var scriptsFileSystem = new PhysicalFileSystem(SystemDirectories.Scripts);
|
||||
var mvcViewsFileSystem = new PhysicalFileSystem(SystemDirectories.MvcViews);
|
||||
|
||||
_macroPartialFileSystem = new ShadowWrapper(macroPartialFileSystem, "Views/MacroPartials", IsScoped);
|
||||
_partialViewsFileSystem = new ShadowWrapper(partialViewsFileSystem, "Views/Partials", IsScoped);
|
||||
_macroPartialFileSystem = new ShadowWrapper(macroPartialFileSystem, "macro-partials", IsScoped);
|
||||
_partialViewsFileSystem = new ShadowWrapper(partialViewsFileSystem, "partials", IsScoped);
|
||||
_stylesheetsFileSystem = new ShadowWrapper(stylesheetsFileSystem, "css", IsScoped);
|
||||
_scriptsFileSystem = new ShadowWrapper(scriptsFileSystem, "scripts", IsScoped);
|
||||
_mvcViewsFileSystem = new ShadowWrapper(mvcViewsFileSystem, "Views", IsScoped);
|
||||
_mvcViewsFileSystem = new ShadowWrapper(mvcViewsFileSystem, "views", IsScoped);
|
||||
|
||||
// TODO: do we need a lock here?
|
||||
_shadowWrappers.Add(_macroPartialFileSystem);
|
||||
@@ -146,6 +146,11 @@ namespace Umbraco.Core.IO
|
||||
|
||||
#region Providers
|
||||
|
||||
private readonly Dictionary<Type, string> _paths = new Dictionary<Type, string>();
|
||||
|
||||
// internal for tests
|
||||
internal IReadOnlyDictionary<Type, string> Paths => _paths;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a strongly-typed filesystem.
|
||||
/// </summary>
|
||||
@@ -162,10 +167,33 @@ namespace Umbraco.Core.IO
|
||||
|
||||
return (TFileSystem) _filesystems.GetOrAdd(typeof(TFileSystem), _ => new Lazy<IFileSystem>(() =>
|
||||
{
|
||||
var name = typeof(TFileSystem).FullName;
|
||||
if (name == null) throw new Exception("panic!");
|
||||
var typeofTFileSystem = typeof(TFileSystem);
|
||||
|
||||
var shadowWrapper = CreateShadowWrapper(supporting, "typed/" + name);
|
||||
// path must be unique and not collide with paths used in CreateWellKnownFileSystems
|
||||
// for our well-known 'media' filesystem we can use the short 'media' path
|
||||
// for others, put them under 'x/' and use ... something
|
||||
string path;
|
||||
if (typeofTFileSystem == typeof(MediaFileSystem))
|
||||
{
|
||||
path = "media";
|
||||
}
|
||||
else
|
||||
{
|
||||
lock (_paths)
|
||||
{
|
||||
if (!_paths.TryGetValue(typeofTFileSystem, out path))
|
||||
{
|
||||
path = Guid.NewGuid().ToString("N").Substring(0, 6);
|
||||
while (_paths.ContainsValue(path)) // this can't loop forever, right?
|
||||
path = Guid.NewGuid().ToString("N").Substring(0, 6);
|
||||
_paths[typeofTFileSystem] = path;
|
||||
}
|
||||
}
|
||||
|
||||
path = "x/" + path;
|
||||
}
|
||||
|
||||
var shadowWrapper = CreateShadowWrapper(supporting, path);
|
||||
return _container.CreateInstance<TFileSystem>(shadowWrapper);
|
||||
})).Value;
|
||||
}
|
||||
@@ -179,35 +207,37 @@ namespace Umbraco.Core.IO
|
||||
// global shadow for the entire application, so great care should be taken to ensure that the
|
||||
// application is *not* doing anything else when using a shadow.
|
||||
|
||||
internal ICompletable Shadow(Guid id)
|
||||
internal ICompletable Shadow()
|
||||
{
|
||||
if (Volatile.Read(ref _wkfsInitialized) == false) EnsureWellKnownFileSystems();
|
||||
|
||||
var id = ShadowWrapper.CreateShadowId();
|
||||
return new ShadowFileSystems(this, id); // will invoke BeginShadow and EndShadow
|
||||
}
|
||||
|
||||
internal void BeginShadow(Guid id)
|
||||
internal void BeginShadow(string id)
|
||||
{
|
||||
lock (_shadowLocker)
|
||||
{
|
||||
// if we throw here, it means that something very wrong happened.
|
||||
if (_shadowCurrentId != Guid.Empty)
|
||||
if (_shadowCurrentId != null)
|
||||
throw new InvalidOperationException("Already shadowing.");
|
||||
|
||||
_shadowCurrentId = id;
|
||||
|
||||
_logger.Debug<ShadowFileSystems>("Shadow '{ShadowId}'", id);
|
||||
_logger.Debug<ShadowFileSystems>("Shadow '{ShadowId}'", _shadowCurrentId);
|
||||
|
||||
foreach (var wrapper in _shadowWrappers)
|
||||
wrapper.Shadow(id);
|
||||
wrapper.Shadow(_shadowCurrentId);
|
||||
}
|
||||
}
|
||||
|
||||
internal void EndShadow(Guid id, bool completed)
|
||||
internal void EndShadow(string id, bool completed)
|
||||
{
|
||||
lock (_shadowLocker)
|
||||
{
|
||||
// if we throw here, it means that something very wrong happened.
|
||||
if (_shadowCurrentId == Guid.Empty)
|
||||
if (_shadowCurrentId == null)
|
||||
throw new InvalidOperationException("Not shadowing.");
|
||||
if (id != _shadowCurrentId)
|
||||
throw new InvalidOperationException("Not the current shadow.");
|
||||
@@ -228,7 +258,7 @@ namespace Umbraco.Core.IO
|
||||
}
|
||||
}
|
||||
|
||||
_shadowCurrentId = Guid.Empty;
|
||||
_shadowCurrentId = null;
|
||||
|
||||
if (exceptions.Count > 0)
|
||||
throw new AggregateException(completed ? "Failed to apply all changes (see exceptions)." : "Failed to abort (see exceptions).", exceptions);
|
||||
@@ -240,7 +270,7 @@ namespace Umbraco.Core.IO
|
||||
lock (_shadowLocker)
|
||||
{
|
||||
var wrapper = new ShadowWrapper(filesystem, shadowPath, IsScoped);
|
||||
if (_shadowCurrentId != Guid.Empty)
|
||||
if (_shadowCurrentId != null)
|
||||
wrapper.Shadow(_shadowCurrentId);
|
||||
_shadowWrappers.Add(wrapper);
|
||||
return wrapper;
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Umbraco.Core.IO.MediaPathSchemes
|
||||
/// Implements a combined-guids media path scheme.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Path is "{combinedGuid}/{filename>}" where combinedGuid is a combination of itemGuid and propertyGuid.</para>
|
||||
/// <para>Path is "{combinedGuid}/{filename}" where combinedGuid is a combination of itemGuid and propertyGuid.</para>
|
||||
/// </remarks>
|
||||
public class CombinedGuidsMediaPathScheme : IMediaPathScheme
|
||||
{
|
||||
@@ -16,7 +16,9 @@ namespace Umbraco.Core.IO.MediaPathSchemes
|
||||
{
|
||||
// assumes that cuid and puid keys can be trusted - and that a single property type
|
||||
// for a single content cannot store two different files with the same name
|
||||
var directory = HexEncoder.Encode(GuidUtils.Combine(itemGuid, propertyGuid).ToByteArray()/*'/', 2, 4*/); // could use ext to fragment path eg 12/e4/f2/...
|
||||
|
||||
var combinedGuid = GuidUtils.Combine(itemGuid, propertyGuid);
|
||||
var directory = HexEncoder.Encode(combinedGuid.ToByteArray()/*'/', 2, 4*/); // could use ext to fragment path eg 12/e4/f2/...
|
||||
return Path.Combine(directory, filename).Replace('\\', '/');
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Umbraco.Core.IO.MediaPathSchemes
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements a unique directory media path scheme.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>This scheme provides deterministic short paths, with potential collisions.</para>
|
||||
/// </remarks>
|
||||
public class UniqueMediaPathScheme : IMediaPathScheme
|
||||
{
|
||||
private const int DirectoryLength = 8;
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetFilePath(IMediaFileSystem fileSystem, Guid itemGuid, Guid propertyGuid, string filename, string previous = null)
|
||||
{
|
||||
var combinedGuid = GuidUtils.Combine(itemGuid, propertyGuid);
|
||||
var directory = GuidUtils.ToBase32String(combinedGuid, DirectoryLength);
|
||||
|
||||
return Path.Combine(directory, filename).Replace('\\', '/');
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <remarks>
|
||||
/// <para>Returning null so that <see cref="MediaFileSystem.DeleteMediaFiles"/> does *not*
|
||||
/// delete any directory. This is because the above shortening of the Guid to 8 chars
|
||||
/// means we're increasing the risk of collision, and we don't want to delete files
|
||||
/// belonging to other media items.</para>
|
||||
/// <para>And, at the moment, we cannot delete directory "only if it is empty" because of
|
||||
/// race conditions. We'd need to implement locks in <see cref="MediaFileSystem"/> for
|
||||
/// this.</para>
|
||||
/// </remarks>
|
||||
public string GetDeleteDirectory(IMediaFileSystem fileSystem, string filepath) => null;
|
||||
}
|
||||
}
|
||||
@@ -304,7 +304,13 @@ namespace Umbraco.Core.IO
|
||||
// permissions to reach that path, but it may nevertheless be outside of
|
||||
// our root path, due to relative segments, so better check
|
||||
if (IOHelper.PathStartsWith(path, _rootPath, Path.DirectorySeparatorChar))
|
||||
{
|
||||
// this says that 4.7.2 supports long paths - but Windows does not
|
||||
// https://docs.microsoft.com/en-us/dotnet/api/system.io.pathtoolongexception?view=netframework-4.7.2
|
||||
if (path.Length > 260)
|
||||
throw new PathTooLongException($"Path {path} is too long.");
|
||||
return path;
|
||||
}
|
||||
|
||||
// nothing prevents us to reach the file, security-wise, yet it is outside
|
||||
// this filesystem's root - throw
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Umbraco.Core.IO
|
||||
private bool _completed;
|
||||
|
||||
// invoked by the filesystems when shadowing
|
||||
public ShadowFileSystems(FileSystems fileSystems, Guid id)
|
||||
public ShadowFileSystems(FileSystems fileSystems, string id)
|
||||
{
|
||||
_fileSystems = fileSystems;
|
||||
Id = id;
|
||||
@@ -19,7 +19,7 @@ namespace Umbraco.Core.IO
|
||||
}
|
||||
|
||||
// for tests
|
||||
public Guid Id { get; }
|
||||
public string Id { get; }
|
||||
|
||||
// invoked by the scope when exiting, if completed
|
||||
public void Complete()
|
||||
|
||||
@@ -22,7 +22,33 @@ namespace Umbraco.Core.IO
|
||||
_isScoped = isScoped;
|
||||
}
|
||||
|
||||
internal void Shadow(Guid id)
|
||||
public static string CreateShadowId()
|
||||
{
|
||||
const int retries = 50; // avoid infinite loop
|
||||
const int idLength = 8; // 6 chars
|
||||
|
||||
// shorten a Guid to idLength chars, and see whether it collides
|
||||
// with an existing directory or not - if it does, try again, and
|
||||
// we should end up with a unique identifier eventually - but just
|
||||
// detect infinite loops (just in case)
|
||||
|
||||
for (var i = 0; i < retries; i++)
|
||||
{
|
||||
var id = GuidUtils.ToBase32String(Guid.NewGuid(), idLength);
|
||||
|
||||
var virt = ShadowFsPath + "/" + id;
|
||||
var shadowDir = IOHelper.MapPath(virt);
|
||||
if (Directory.Exists(shadowDir))
|
||||
continue;
|
||||
|
||||
Directory.CreateDirectory(shadowDir);
|
||||
return id;
|
||||
}
|
||||
|
||||
throw new Exception($"Could not get a shadow identifier (tried {retries} times)");
|
||||
}
|
||||
|
||||
internal void Shadow(string id)
|
||||
{
|
||||
// note: no thread-safety here, because ShadowFs is thread-safe due to the check
|
||||
// on ShadowFileSystemsScope.None - and if None is false then we should be running
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
using System.IO;
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
@@ -8,26 +6,11 @@ namespace Umbraco.Core.IO
|
||||
public class SystemFiles
|
||||
{
|
||||
public static string TinyMceConfig => SystemDirectories.Config + "/tinyMceConfig.config";
|
||||
|
||||
|
||||
// TODO: Kill this off we don't have umbraco.config XML cache we now have NuCache
|
||||
public static string GetContentCacheXml(IGlobalSettings globalSettings)
|
||||
{
|
||||
switch (globalSettings.LocalTempStorageLocation)
|
||||
{
|
||||
case LocalTempStorage.AspNetTemp:
|
||||
return Path.Combine(HttpRuntime.CodegenDir, @"UmbracoData\umbraco.config");
|
||||
case LocalTempStorage.EnvironmentTemp:
|
||||
var appDomainHash = HttpRuntime.AppDomainAppId.ToSHA1();
|
||||
var cachePath = Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "UmbracoData",
|
||||
//include the appdomain hash is just a safety check, for example if a website is moved from worker A to worker B and then back
|
||||
// to worker A again, in theory the %temp% folder should already be empty but we really want to make sure that its not
|
||||
// utilizing an old path
|
||||
appDomainHash);
|
||||
return Path.Combine(cachePath, "umbraco.config");
|
||||
case LocalTempStorage.Default:
|
||||
return IOHelper.ReturnPath("umbracoContentXML", "~/App_Data/umbraco.config");
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
return Path.Combine(globalSettings.LocalTempPath, "umbraco.config");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Umbraco.Core.Logging
|
||||
}
|
||||
|
||||
// a lightweight disposable timer
|
||||
private class LightDisposableTimer : DisposableObject
|
||||
private class LightDisposableTimer : DisposableObjectSlim
|
||||
{
|
||||
private readonly Action<long> _callback;
|
||||
private readonly Stopwatch _stopwatch = Stopwatch.StartNew();
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace Umbraco.Core.Logging.Serilog
|
||||
//Set this environment variable - so that it can be used in external config file
|
||||
//add key="serilog:write-to:RollingFile.pathFormat" value="%BASEDIR%\logs\log.txt" />
|
||||
Environment.SetEnvironmentVariable("BASEDIR", AppDomain.CurrentDomain.BaseDirectory, EnvironmentVariableTarget.Process);
|
||||
Environment.SetEnvironmentVariable("MACHINENAME", Environment.MachineName, EnvironmentVariableTarget.Process);
|
||||
|
||||
logConfig.MinimumLevel.Verbose() //Set to highest level of logging (as any sinks may want to restrict it to Errors only)
|
||||
.Enrich.WithProcessId()
|
||||
|
||||
@@ -41,8 +41,6 @@ namespace Umbraco.Core.Logging.Serilog
|
||||
var loggerConfig = new LoggerConfiguration();
|
||||
loggerConfig
|
||||
.MinimalConfiguration()
|
||||
.OutputDefaultTextFile(LogEventLevel.Debug)
|
||||
.OutputDefaultJsonFile()
|
||||
.ReadFromConfigFile()
|
||||
.ReadFromUserConfigFile();
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Serilog.Events;
|
||||
using Serilog.Formatting.Compact.Reader;
|
||||
|
||||
@@ -10,13 +11,15 @@ namespace Umbraco.Core.Logging.Viewer
|
||||
internal class JsonLogViewer : LogViewerSourceBase
|
||||
{
|
||||
private readonly string _logsPath;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public JsonLogViewer(string logsPath = "", string searchPath = "") : base(searchPath)
|
||||
public JsonLogViewer(ILogger logger, string logsPath = "", string searchPath = "") : base(searchPath)
|
||||
{
|
||||
if (string.IsNullOrEmpty(logsPath))
|
||||
logsPath = $@"{AppDomain.CurrentDomain.BaseDirectory}\App_Data\Logs\";
|
||||
|
||||
_logsPath = logsPath;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
private const int FileSizeCap = 100;
|
||||
@@ -77,8 +80,14 @@ namespace Umbraco.Core.Logging.Viewer
|
||||
using (var stream = new StreamReader(fs))
|
||||
{
|
||||
var reader = new LogEventReader(stream);
|
||||
while (reader.TryRead(out var evt))
|
||||
while (TryRead(reader, out var evt))
|
||||
{
|
||||
//We may get a null if log line is malformed
|
||||
if (evt == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (count > skip + take)
|
||||
{
|
||||
break;
|
||||
@@ -105,5 +114,21 @@ namespace Umbraco.Core.Logging.Viewer
|
||||
return logs;
|
||||
}
|
||||
|
||||
private bool TryRead(LogEventReader reader, out LogEvent evt)
|
||||
{
|
||||
try
|
||||
{
|
||||
return reader.TryRead(out evt);
|
||||
}
|
||||
catch (JsonReaderException ex)
|
||||
{
|
||||
// As we are reading/streaming one line at a time in the JSON file
|
||||
// Thus we can not report the line number, as it will always be 1
|
||||
_logger.Error<JsonLogViewer>(ex, "Unable to parse a line in the JSON log file");
|
||||
|
||||
evt = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Umbraco.Core.Components;
|
||||
using Umbraco.Core.Compose;
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.Logging.Viewer
|
||||
{
|
||||
@@ -8,7 +9,7 @@ namespace Umbraco.Core.Logging.Viewer
|
||||
{
|
||||
public void Compose(Composition composition)
|
||||
{
|
||||
composition.SetLogViewer(_ => new JsonLogViewer());
|
||||
composition.SetLogViewer(_ => new JsonLogViewer(composition.Logger));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Umbraco.Core.Logging
|
||||
public void Stop(bool discardResults = false)
|
||||
{ }
|
||||
|
||||
private class VoidDisposable : DisposableObject
|
||||
private class VoidDisposable : DisposableObjectSlim
|
||||
{
|
||||
protected override void DisposeResources()
|
||||
{ }
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace Umbraco.Core.Manifest
|
||||
var gridEditors = new List<GridEditor>();
|
||||
var contentApps = new List<ManifestContentAppDefinition>();
|
||||
var dashboards = new List<ManifestDashboard>();
|
||||
var sections = new List<ManifestBackOfficeSection>();
|
||||
var sections = new List<ManifestSection>();
|
||||
|
||||
foreach (var manifest in manifests)
|
||||
{
|
||||
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.Trees;
|
||||
using Umbraco.Core.Models.Sections;
|
||||
|
||||
namespace Umbraco.Core.Manifest
|
||||
{
|
||||
[DataContract(Name = "section", Namespace = "")]
|
||||
public class ManifestBackOfficeSection : IBackOfficeSection
|
||||
public class ManifestSection : ISection
|
||||
{
|
||||
[DataMember(Name = "alias")]
|
||||
public string Alias { get; set; }
|
||||
@@ -55,6 +55,6 @@ namespace Umbraco.Core.Manifest
|
||||
/// Gets or sets the sections listed in the manifest.
|
||||
/// </summary>
|
||||
[JsonProperty("sections")]
|
||||
public ManifestBackOfficeSection[] Sections { get; set; } = Array.Empty<ManifestBackOfficeSection>();
|
||||
public ManifestSection[] Sections { get; set; } = Array.Empty<ManifestSection>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,24 @@
|
||||
namespace Umbraco.Core.Media
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Media
|
||||
{
|
||||
public interface IEmbedProvider
|
||||
{
|
||||
bool SupportsDimensions { get; }
|
||||
/// <summary>
|
||||
/// The OEmbed API Endpoint
|
||||
/// </summary>
|
||||
string ApiEndpoint { get; }
|
||||
|
||||
/// <summary>
|
||||
/// A string array of Regex patterns to match against the pasted OEmbed URL
|
||||
/// </summary>
|
||||
string[] UrlSchemeRegex { get; }
|
||||
|
||||
/// <summary>
|
||||
/// A collection of querystring request parameters to append to the API Url
|
||||
/// </summary>
|
||||
/// <example>?key=value&key2=value2</example>
|
||||
Dictionary<string, string> RequestParams { get; }
|
||||
|
||||
string GetMarkup(string url, int maxWidth = 0, int maxHeight = 0);
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
using System.Xml;
|
||||
|
||||
namespace Umbraco.Core.Media
|
||||
{
|
||||
public interface IEmbedSettingProvider
|
||||
{
|
||||
object GetSetting(XmlNode settingNode);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
namespace Umbraco.Core.Media
|
||||
{
|
||||
|
||||
// TODO: Could definitely have done with a better name
|
||||
public class Result
|
||||
public class OEmbedResult
|
||||
{
|
||||
public Status Status { get; set; }
|
||||
public OEmbedStatus OEmbedStatus { get; set; }
|
||||
public bool SupportsDimensions { get; set; }
|
||||
public string Markup { get; set; }
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user