From ab14b65078e6e3e29bd1f9cbce5923aa5a9d6c2c Mon Sep 17 00:00:00 2001 From: TheBekker Date: Mon, 13 Mar 2017 22:54:20 +0100 Subject: [PATCH 01/27] [fix-U4-9038] get and set media start node for mediaPickerOverlay in grid --- .../propertyeditors/grid/editors/media.controller.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/media.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/media.controller.js index e289a389cb..bb580a906d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/media.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/media.controller.js @@ -1,10 +1,17 @@ angular.module("umbraco") .controller("Umbraco.PropertyEditors.Grid.MediaController", - function ($scope, $rootScope, $timeout) { + function ($scope, $rootScope, $timeout, userService) { + + if (!$scope.model.config.startNodeId) { + userService.getCurrentUser().then(function (userData) { + $scope.model.config.startNodeId = userData.startMediaId; + }); + } $scope.setImage = function(){ $scope.mediaPickerOverlay = {}; $scope.mediaPickerOverlay.view = "mediapicker"; + $scope.mediaPickerOverlay.startNodeId = $scope.model.config && $scope.model.config.startNodeId ? $scope.model.config.startNodeId : undefined; $scope.mediaPickerOverlay.cropSize = $scope.control.editor.config && $scope.control.editor.config.size ? $scope.control.editor.config.size : undefined; $scope.mediaPickerOverlay.showDetails = true; $scope.mediaPickerOverlay.disableFolderSelect = true; From 58f9ff4b798d33fed467e73bb61b2d279cd67b38 Mon Sep 17 00:00:00 2001 From: Marc Goodson Date: Tue, 11 Apr 2017 20:37:59 +0100 Subject: [PATCH 02/27] Add some debug logging when there is a distributed calls configuration issue --- src/Umbraco.Core/Sync/ConfigServerRegistrar.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Core/Sync/ConfigServerRegistrar.cs b/src/Umbraco.Core/Sync/ConfigServerRegistrar.cs index 8245491d97..841a229a33 100644 --- a/src/Umbraco.Core/Sync/ConfigServerRegistrar.cs +++ b/src/Umbraco.Core/Sync/ConfigServerRegistrar.cs @@ -4,6 +4,7 @@ using System.Web; using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.IO; +using Umbraco.Core.Logging; namespace Umbraco.Core.Sync { @@ -40,8 +41,9 @@ namespace Umbraco.Core.Sync .ToList(); if (serversA.Length == 0) - { + { _serverRole = ServerRole.Unknown; // config error, actually + LogHelper.Debug(string.Format("Server Role Unknown: DistributedCalls are enabled but no servers are listed")); } else { @@ -50,7 +52,10 @@ namespace Umbraco.Core.Sync var serverName = master.ServerName; if (appId.IsNullOrWhiteSpace() && serverName.IsNullOrWhiteSpace()) + { _serverRole = ServerRole.Unknown; // config error, actually + LogHelper.Debug(string.Format("Server Role Unknown: Server Name or AppId missing from Server configuration in DistributedCalls settings")); + } else _serverRole = IsCurrentServer(appId, serverName) ? ServerRole.Master From b88e71405017b786029ee3efe3ead219090641cb Mon Sep 17 00:00:00 2001 From: Dave Long Date: Fri, 21 Apr 2017 08:33:21 +0200 Subject: [PATCH 03/27] Fixed Serialization issue in Password Reset Validate Model --- src/Umbraco.Web/Models/ValidatePasswordResetCodeModel.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web/Models/ValidatePasswordResetCodeModel.cs b/src/Umbraco.Web/Models/ValidatePasswordResetCodeModel.cs index cba92eeff7..7e30e0881b 100644 --- a/src/Umbraco.Web/Models/ValidatePasswordResetCodeModel.cs +++ b/src/Umbraco.Web/Models/ValidatePasswordResetCodeModel.cs @@ -1,8 +1,10 @@ -using System.ComponentModel.DataAnnotations; +using System; +using System.ComponentModel.DataAnnotations; using System.Runtime.Serialization; namespace Umbraco.Web.Models { + [Serializable] [DataContract(Name = "validatePasswordReset", Namespace = "")] public class ValidatePasswordResetCodeModel { From 81354cea3c1920ed1c5d584ba1c8b90c61ae95a9 Mon Sep 17 00:00:00 2001 From: Harvey Williams Date: Mon, 24 Apr 2017 16:29:35 +0100 Subject: [PATCH 04/27] U4-9806 Media Picker media hover should show full title Added title to all media items in the media picker rather than just SVG and normal images. Solving an issue where whole titles could not be visible if the title was too long. --- .../src/views/components/umb-media-grid.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/components/umb-media-grid.html b/src/Umbraco.Web.UI.Client/src/views/components/umb-media-grid.html index f30851e62e..7c5f0f728f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/umb-media-grid.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/umb-media-grid.html @@ -1,5 +1,5 @@
-
+
@@ -12,10 +12,10 @@
- {{item.name}} + {{item.name}} - {{item.name}} + {{item.name}} {{item.name}} From 1520fa77d55d20712e578bad81d58cd61f720aba Mon Sep 17 00:00:00 2001 From: wanddy Date: Tue, 2 May 2017 14:12:58 +0800 Subject: [PATCH 05/27] Add missing translation item for en.xml and zh.xml Signed-off-by: wanddy --- src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 2 ++ src/Umbraco.Web.UI/umbraco/config/lang/zh.xml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index ad30f0c62f..aca237bc9f 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -1252,6 +1252,8 @@ To manage your website, simply open the Umbraco back office and start adding con Templates XSLT Files Analytics + Partial Views + Partial View Macro Files New update ready diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/zh.xml b/src/Umbraco.Web.UI/umbraco/config/lang/zh.xml index 1f538e7fa0..0341316f25 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/zh.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/zh.xml @@ -1252,6 +1252,8 @@ 模板 XSLT文件 分析 + 分部视图 + 分部视图宏文件 有可用更新 From ab551b2c966148f7f437ff84e32e36d91c7ade37 Mon Sep 17 00:00:00 2001 From: wanddy Date: Tue, 2 May 2017 14:20:44 +0800 Subject: [PATCH 06/27] Fix some menu tree header won't be translated. This may be caused by the explicit definition of tree node name. Signed-off-by: wanddy --- src/Umbraco.Web/Trees/PartialViewMacrosTree.cs | 2 +- src/Umbraco.Web/Trees/PartialViewsTree.cs | 2 +- src/Umbraco.Web/Trees/TemplatesTreeController.cs | 2 +- .../umbraco.presentation/umbraco/Trees/loadRelationTypes.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web/Trees/PartialViewMacrosTree.cs b/src/Umbraco.Web/Trees/PartialViewMacrosTree.cs index dfc0636804..cf13a24d36 100644 --- a/src/Umbraco.Web/Trees/PartialViewMacrosTree.cs +++ b/src/Umbraco.Web/Trees/PartialViewMacrosTree.cs @@ -9,7 +9,7 @@ namespace Umbraco.Web.Trees /// /// Tree for displaying partial view macros in the developer app /// - [Tree(Constants.Applications.Developer, "partialViewMacros", "Partial View Macro Files", sortOrder: 6)] + [Tree(Constants.Applications.Developer, "partialViewMacros", null, sortOrder: 6)] public class PartialViewMacrosTree : PartialViewsTree { public PartialViewMacrosTree(string application) : base(application) diff --git a/src/Umbraco.Web/Trees/PartialViewsTree.cs b/src/Umbraco.Web/Trees/PartialViewsTree.cs index 11d6e3e804..594355f6c7 100644 --- a/src/Umbraco.Web/Trees/PartialViewsTree.cs +++ b/src/Umbraco.Web/Trees/PartialViewsTree.cs @@ -18,7 +18,7 @@ namespace Umbraco.Web.Trees /// /// Tree for displaying partial views in the settings app /// - [Tree(Constants.Applications.Settings, "partialViews", "Partial Views", sortOrder: 2)] + [Tree(Constants.Applications.Settings, "partialViews", null, sortOrder: 2)] public class PartialViewsTree : FileSystemTree { public PartialViewsTree(string application) : base(application) { } diff --git a/src/Umbraco.Web/Trees/TemplatesTreeController.cs b/src/Umbraco.Web/Trees/TemplatesTreeController.cs index 61cff8f862..73f9389150 100644 --- a/src/Umbraco.Web/Trees/TemplatesTreeController.cs +++ b/src/Umbraco.Web/Trees/TemplatesTreeController.cs @@ -21,7 +21,7 @@ namespace Umbraco.Web.Trees { [UmbracoTreeAuthorize(Constants.Trees.Templates)] [LegacyBaseTree(typeof (loadTemplates))] - [Tree(Constants.Applications.Settings, Constants.Trees.Templates, "Templates", sortOrder:1)] + [Tree(Constants.Applications.Settings, Constants.Trees.Templates, null, sortOrder:1)] [PluginController("UmbracoTrees")] [CoreTree] public class TemplatesTreeController : TreeController diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadRelationTypes.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadRelationTypes.cs index d94ff6942e..a173926257 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadRelationTypes.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadRelationTypes.cs @@ -89,7 +89,7 @@ namespace umbraco /// the 'Relation Types' root node protected override void CreateRootNode(ref XmlTreeNode rootNode) { - rootNode.Text = "Relation Types"; + //rootNode.Text = "Relation Types"; rootNode.Icon = BaseTree.FolderIcon; rootNode.OpenIcon = BaseTree.FolderIconOpen; rootNode.NodeType = this.TreeAlias; // (Was prefixed with init) From 0eafa14246be70c8d3e4d14a2108781cda076fd4 Mon Sep 17 00:00:00 2001 From: Maciej Sadowski Date: Tue, 2 May 2017 15:36:39 +0200 Subject: [PATCH 07/27] fixed console error on media picker --- .../imaging/umbimagegravity.directive.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js index 836d998412..ad7466ce54 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js @@ -105,12 +105,14 @@ angular.module("umbraco.directives") }); //// INIT ///// - $image.load(function(){ - $timeout(function(){ - setDimensions(); - scope.loaded = true; - scope.onImageLoaded(); - }); + $image.load(function() { + $timeout(function() { + setDimensions(); + scope.loaded = true; + if (angular.isFunction(scope.onImageLoaded)) { + scope.onImageLoaded(); + } + }); }); $(window).on('resize.umbImageGravity', function(){ From 3e294e290bfe2a07ac35c7f2ccc9e230d99523a4 Mon Sep 17 00:00:00 2001 From: Tom Steer Date: Thu, 4 May 2017 09:10:35 +0100 Subject: [PATCH 08/27] Change Context to be public on MigrationBase --- src/Umbraco.Core/Persistence/Migrations/MigrationBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Core/Persistence/Migrations/MigrationBase.cs b/src/Umbraco.Core/Persistence/Migrations/MigrationBase.cs index a19aaa24ad..486f84b444 100644 --- a/src/Umbraco.Core/Persistence/Migrations/MigrationBase.cs +++ b/src/Umbraco.Core/Persistence/Migrations/MigrationBase.cs @@ -23,7 +23,7 @@ namespace Umbraco.Core.Persistence.Migrations Logger = logger; } - internal IMigrationContext Context; + public IMigrationContext Context; public abstract void Up(); public abstract void Down(); From e7eaf6959f5e4d9f9cd5e6e176e66bf6493b3d5f Mon Sep 17 00:00:00 2001 From: Claus Date: Thu, 4 May 2017 15:08:37 +0200 Subject: [PATCH 09/27] U4-9849 Query Builder not working in template editor. Always returns Model.Content.Site().Children() adding missing nullchecks in the endpoint action. ensuring promise returns before setting init data - the unresolved promise was being used on the query model instead of the actual text string the promise returns - causing the endpoint to fail to bind the model. --- .../querybuilder/querybuilder.controller.js | 119 +++++++++--------- .../Editors/TemplateQueryController.cs | 86 ++++++------- 2 files changed, 100 insertions(+), 105 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/querybuilder/querybuilder.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/overlays/querybuilder/querybuilder.controller.js index 979428de0c..ea9ad6ca97 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/querybuilder/querybuilder.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/querybuilder/querybuilder.controller.js @@ -1,14 +1,13 @@ -(function () { +(function() { "use strict"; function QueryBuilderOverlayController($scope, templateQueryResource, localizationService) { - var everything = localizationService.localize("template_allContent"); - var myWebsite = localizationService.localize("template_websiteRoot"); + var everything = ""; + var myWebsite = ""; + var ascendingTranslation = ""; + var descendingTranslation = ""; - var ascendingTranslation = localizationService.localize("template_ascending"); - var descendingTranslation = localizationService.localize("template_descending"); - var vm = this; vm.properties = []; @@ -21,34 +20,6 @@ format: "YYYY-MM-DD" }; - vm.query = { - contentType: { - name: everything - }, - source: { - name: myWebsite - }, - filters: [ - { - property: undefined, - operator: undefined - } - ], - sort: { - property: { - alias: "", - name: "", - }, - direction: "ascending", //This is the value for sorting sent to server - translation: { - currentLabel: ascendingTranslation, //This is the localized UI value in the the dialog - ascending: ascendingTranslation, - descending: descendingTranslation - } - - } - }; - vm.chooseSource = chooseSource; vm.getPropertyOperators = getPropertyOperators; vm.addFilter = addFilter; @@ -63,21 +34,48 @@ function onInit() { + vm.query = { + contentType: { + name: everything + }, + source: { + name: myWebsite + }, + filters: [ + { + property: undefined, + operator: undefined + } + ], + sort: { + property: { + alias: "", + name: "", + }, + direction: "ascending", //This is the value for sorting sent to server + translation: { + currentLabel: ascendingTranslation, //This is the localized UI value in the the dialog + ascending: ascendingTranslation, + descending: descendingTranslation + } + } + }; + templateQueryResource.getAllowedProperties() - .then(function (properties) { + .then(function(properties) { vm.properties = properties; }); templateQueryResource.getContentTypes() - .then(function (contentTypes) { + .then(function(contentTypes) { vm.contentTypes = contentTypes; }); templateQueryResource.getFilterConditions() - .then(function (conditions) { + .then(function(conditions) { vm.conditions = conditions; }); - + throttledFunc(); } @@ -111,10 +109,11 @@ } function getPropertyOperators(property) { - var conditions = _.filter(vm.conditions, function (condition) { - var index = condition.appliesTo.indexOf(property.type); - return index >= 0; - }); + var conditions = _.filter(vm.conditions, + function(condition) { + var index = condition.appliesTo.indexOf(property.type); + return index >= 0; + }); return conditions; } @@ -123,10 +122,8 @@ } function trashFilter(query, filter) { - for (var i = 0; i < query.filters.length; i++) - { - if (query.filters[i] == filter) - { + for (var i = 0; i < query.filters.length; i++) { + if (query.filters[i] == filter) { query.filters.splice(i, 1); } } @@ -173,7 +170,7 @@ function setFilterTerm(filter, term) { filter.term = term; - if(filter.constraintValue) { + if (filter.constraintValue) { throttledFunc(); } } @@ -183,22 +180,32 @@ } function datePickerChange(event, filter) { - if(event.date && event.date.isValid()) { + if (event.date && event.date.isValid()) { filter.constraintValue = event.date.format(vm.datePickerConfig.format); throttledFunc(); } } - var throttledFunc = _.throttle(function () { - - templateQueryResource.postTemplateQuery(vm.query) - .then(function (response) { - $scope.model.result = response; - }); + var throttledFunc = _.throttle(function() { - }, 200); + templateQueryResource.postTemplateQuery(vm.query) + .then(function(response) { + $scope.model.result = response; + }); - onInit(); + }, + 200); + + localizationService.localizeMany([ + "template_allContent", "template_websiteRoot", "template_ascending", "template_descending" + ]) + .then(function(res) { + everything = res[0]; + myWebsite = res[1]; + ascendingTranslation = res[2]; + descendingTranslation = res[3]; + onInit(); + }); } angular.module("umbraco").controller("Umbraco.Overlays.QueryBuilderController", QueryBuilderOverlayController); diff --git a/src/Umbraco.Web/Editors/TemplateQueryController.cs b/src/Umbraco.Web/Editors/TemplateQueryController.cs index cd004fe926..d7351b0e97 100644 --- a/src/Umbraco.Web/Editors/TemplateQueryController.cs +++ b/src/Umbraco.Web/Editors/TemplateQueryController.cs @@ -3,7 +3,6 @@ using System.Linq; using System.Text; using Umbraco.Core.Models; using Umbraco.Web.Mvc; -using Umbraco.Web.WebApi.Filters; using Umbraco.Web.WebApi; using System; using System.Diagnostics; @@ -13,8 +12,6 @@ using Umbraco.Core.Services; namespace Umbraco.Web.Editors { - - /// /// The API controller used for building content queries within the template /// @@ -26,10 +23,9 @@ namespace Umbraco.Web.Editors { } public TemplateQueryController(UmbracoContext umbracoContext) - :base(umbracoContext) + : base(umbracoContext) { } - private IEnumerable Terms { get @@ -77,20 +73,19 @@ namespace Umbraco.Web.Editors var sb = new StringBuilder(); var indention = Environment.NewLine + "\t\t\t\t\t\t"; - + sb.Append("Model.Content.Site()"); var timer = new Stopwatch(); - + timer.Start(); var currentPage = umbraco.TypedContentAtRoot().FirstOrDefault(); timer.Stop(); - var pointerNode = currentPage; // adjust the "FROM" - if (model != null && model.Source.Id > 0) + if (model != null && model.Source != null && model.Source.Id > 0) { var targetNode = umbraco.TypedContent(model.Source.Id); @@ -120,10 +115,10 @@ namespace Umbraco.Web.Editors } } } - - // TYPE to return if filtered by type + + // TYPE to return if filtered by type IEnumerable contents; - if (model != null && string.IsNullOrEmpty(model.ContentType.Alias) == false) + if (model != null && model.ContentType != null && string.IsNullOrEmpty(model.ContentType.Alias) == false) { timer.Start(); @@ -154,13 +149,13 @@ namespace Umbraco.Web.Editors foreach (var condition in model.Filters) { - if(string.IsNullOrEmpty( condition.ConstraintValue)) continue; - + if (string.IsNullOrEmpty(condition.ConstraintValue)) continue; + //x is passed in as the parameter alias for the linq where statement clause var operation = condition.BuildCondition("x"); var tokenizedOperation = condition.BuildTokenizedCondition(token); - clause = string.IsNullOrEmpty(clause) ? operation : string.Concat(new[] { clause, " && ", operation }); + clause = string.IsNullOrEmpty(clause) ? operation : string.Concat(new[] { clause, " && ", operation }); tokenizedClause = string.IsNullOrEmpty(tokenizedClause) ? tokenizedOperation : string.Concat(new[] { tokenizedClause, " && ", tokenizedOperation }); token++; @@ -168,7 +163,6 @@ namespace Umbraco.Web.Editors if (string.IsNullOrEmpty(clause) == false) { - timer.Start(); //trial-run the tokenized clause to time the execution @@ -178,14 +172,13 @@ namespace Umbraco.Web.Editors timer.Stop(); - + //the query to output to the editor sb.Append(indention); sb.Append(".Where(x => x.IsVisible())"); sb.Append(indention); sb.AppendFormat(".Where(x => {0})", clause); - } else { @@ -197,7 +190,6 @@ namespace Umbraco.Web.Editors sb.Append(indention); sb.Append(".Where(x => x.IsVisible())"); - } if (model.Sort != null && string.IsNullOrEmpty(model.Sort.Property.Alias) == false) @@ -231,20 +223,19 @@ namespace Umbraco.Web.Editors queryResult.ExecutionTime = timer.ElapsedMilliseconds; queryResult.ResultCount = contents.Count(); queryResult.SampleResults = contents.Take(20).Select(x => new TemplateQueryResult() - { - Icon = "icon-file", - Name = x.Name - }); + { + Icon = "icon-file", + Name = x.Name + }); - - return queryResult; + return queryResult; } private object GetConstraintValue(QueryCondition condition) { switch (condition.Property.Type) { - case "int" : + case "int": return int.Parse(condition.ConstraintValue); case "datetime": DateTime dt; @@ -254,42 +245,41 @@ namespace Umbraco.Web.Editors } } - private IEnumerable SortByDefaultPropertyValue(IEnumerable contents, SortExpression sortExpression) + private IEnumerable SortByDefaultPropertyValue(IEnumerable contents, SortExpression sortExpression) { switch (sortExpression.Property.Alias) { - case "id" : + case "id": return sortExpression.Direction == "ascending" - ? contents.OrderBy(x => x.Id) - : contents.OrderByDescending(x => x.Id); - case "createDate" : - + ? contents.OrderBy(x => x.Id) + : contents.OrderByDescending(x => x.Id); + case "createDate": + return sortExpression.Direction == "ascending" - ? contents.OrderBy(x => x.CreateDate) - : contents.OrderByDescending(x => x.CreateDate); + ? contents.OrderBy(x => x.CreateDate) + : contents.OrderByDescending(x => x.CreateDate); case "publishDate": - + return sortExpression.Direction == "ascending" - ? contents.OrderBy(x => x.UpdateDate) - : contents.OrderByDescending(x => x.UpdateDate); + ? contents.OrderBy(x => x.UpdateDate) + : contents.OrderByDescending(x => x.UpdateDate); case "name": return sortExpression.Direction == "ascending" - ? contents.OrderBy(x => x.Name) - : contents.OrderByDescending(x => x.Name); - default : + ? contents.OrderBy(x => x.Name) + : contents.OrderByDescending(x => x.Name); + default: return sortExpression.Direction == "ascending" - ? contents.OrderBy(x => x.Name) - : contents.OrderByDescending(x => x.Name); - + ? contents.OrderBy(x => x.Name) + : contents.OrderByDescending(x => x.Name); } } - + private IEnumerable GetChildContentTypeAliases(IPublishedContent targetNode, IPublishedContent current) { var aliases = new List(); - - if (targetNode.Id == current.Id) return aliases; + + if (targetNode == null || targetNode.Id == current.Id) return aliases; if (targetNode.Id != current.Id) { aliases.Add(targetNode.DocumentTypeAlias); @@ -309,7 +299,7 @@ namespace Umbraco.Web.Editors { var contentTypes = ApplicationContext.Services.ContentTypeService.GetAllContentTypes() - .Select(x => new ContentTypeModel() { Alias = x.Alias, Name = Services.TextService.Localize("template/contentOfType", tokens: new string[] { x.Name } ) }) + .Select(x => new ContentTypeModel() { Alias = x.Alias, Name = Services.TextService.Localize("template/contentOfType", tokens: new string[] { x.Name }) }) .OrderBy(x => x.Name).ToList(); contentTypes.Insert(0, new ContentTypeModel() { Alias = string.Empty, Name = Services.TextService.Localize("template/allContent") }); @@ -332,7 +322,5 @@ namespace Umbraco.Web.Editors { return Terms; } - - } } \ No newline at end of file From 8a096cd82661bdbdb294c51e533e91720dfcc3ff Mon Sep 17 00:00:00 2001 From: Claus Date: Fri, 5 May 2017 10:51:31 +0200 Subject: [PATCH 10/27] Merge pull request #1794 from TheBekker/fix-U4-9038 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [fix-U4-9038] get and set media start node for mediaPickerOverlay in … --- .../propertyeditors/grid/editors/media.controller.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/media.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/media.controller.js index e289a389cb..bb580a906d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/media.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/media.controller.js @@ -1,10 +1,17 @@ angular.module("umbraco") .controller("Umbraco.PropertyEditors.Grid.MediaController", - function ($scope, $rootScope, $timeout) { + function ($scope, $rootScope, $timeout, userService) { + + if (!$scope.model.config.startNodeId) { + userService.getCurrentUser().then(function (userData) { + $scope.model.config.startNodeId = userData.startMediaId; + }); + } $scope.setImage = function(){ $scope.mediaPickerOverlay = {}; $scope.mediaPickerOverlay.view = "mediapicker"; + $scope.mediaPickerOverlay.startNodeId = $scope.model.config && $scope.model.config.startNodeId ? $scope.model.config.startNodeId : undefined; $scope.mediaPickerOverlay.cropSize = $scope.control.editor.config && $scope.control.editor.config.size ? $scope.control.editor.config.size : undefined; $scope.mediaPickerOverlay.showDetails = true; $scope.mediaPickerOverlay.disableFolderSelect = true; From eb949e2cbc1a47619a259b807d59f4f00362e57a Mon Sep 17 00:00:00 2001 From: Stephan Date: Fri, 5 May 2017 12:46:04 +0200 Subject: [PATCH 11/27] Fix UdiString to escape paths --- src/Umbraco.Core/StringUdi.cs | 4 ++-- src/Umbraco.Core/Udi.cs | 5 +++-- src/Umbraco.Tests/UdiTests.cs | 28 ++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Core/StringUdi.cs b/src/Umbraco.Core/StringUdi.cs index 7f1189677f..0f42f4b5f6 100644 --- a/src/Umbraco.Core/StringUdi.cs +++ b/src/Umbraco.Core/StringUdi.cs @@ -20,7 +20,7 @@ namespace Umbraco.Core /// The entity type part of the udi. /// The string id part of the udi. public StringUdi(string entityType, string id) - : base(entityType, "umb://" + entityType + "/" + id) + : base(entityType, "umb://" + entityType + "/" + Uri.EscapeUriString(id)) { Id = id; } @@ -32,7 +32,7 @@ namespace Umbraco.Core public StringUdi(Uri uriValue) : base(uriValue) { - Id = uriValue.AbsolutePath.TrimStart('/'); + Id = Uri.UnescapeDataString(uriValue.AbsolutePath.TrimStart('/')); } /// diff --git a/src/Umbraco.Core/Udi.cs b/src/Umbraco.Core/Udi.cs index 9d67c6ccab..142bf025a9 100644 --- a/src/Umbraco.Core/Udi.cs +++ b/src/Umbraco.Core/Udi.cs @@ -101,7 +101,8 @@ namespace Umbraco.Core public override string ToString() { // UriValue is created in the ctor and is never null - return UriValue.ToString(); + // use AbsoluteUri here and not ToString else it's not encoded! + return UriValue.AbsoluteUri; } /// @@ -159,7 +160,7 @@ namespace Umbraco.Core } if (udiType == UdiType.StringUdi) { - udi = path == string.Empty ? GetRootUdi(uri.Host) : new StringUdi(uri.Host, path); + udi = path == string.Empty ? GetRootUdi(uri.Host) : new StringUdi(uri.Host, Uri.UnescapeDataString(path)); return true; } if (tryParse) return false; diff --git a/src/Umbraco.Tests/UdiTests.cs b/src/Umbraco.Tests/UdiTests.cs index 9b803d5fa3..6e7e4671a9 100644 --- a/src/Umbraco.Tests/UdiTests.cs +++ b/src/Umbraco.Tests/UdiTests.cs @@ -31,6 +31,34 @@ namespace Umbraco.Tests Assert.AreEqual("umb://" + Constants.UdiEntityType.AnyString + "/test-id", udi.ToString()); } + [Test] + public void StringEncodingTest() + { + // absolute path is unescaped + var uri = new Uri("umb://" + Constants.UdiEntityType.AnyString + "/this%20is%20a%20test"); + Assert.AreEqual("umb://" + Constants.UdiEntityType.AnyString + "/this is a test", uri.ToString()); + Assert.AreEqual("umb://" + Constants.UdiEntityType.AnyString + "/this%20is%20a%20test", uri.AbsoluteUri); + Assert.AreEqual("/this%20is%20a%20test", uri.AbsolutePath); + + Assert.AreEqual("/this is a test", Uri.UnescapeDataString(uri.AbsolutePath)); + Assert.AreEqual("%2Fthis%20is%20a%20test", Uri.EscapeDataString("/this is a test")); + Assert.AreEqual("/this%20is%20a%20test", Uri.EscapeUriString("/this is a test")); + + var udi = Udi.Parse("umb://" + Constants.UdiEntityType.AnyString + "/this%20is%20a%20test"); + Assert.AreEqual(Constants.UdiEntityType.AnyString, udi.EntityType); + Assert.IsInstanceOf(udi); + var stringEntityId = udi as StringUdi; + Assert.IsNotNull(stringEntityId); + Assert.AreEqual("this is a test", stringEntityId.Id); + Assert.AreEqual("umb://" + Constants.UdiEntityType.AnyString + "/this%20is%20a%20test", udi.ToString()); + + var udi2 = new StringUdi(Constants.UdiEntityType.AnyString, "this is a test"); + Assert.AreEqual(udi, udi2); + + var udi3 = new StringUdi(Constants.UdiEntityType.AnyString, "path to/this is a test.xyz"); + Assert.AreEqual("umb://" + Constants.UdiEntityType.AnyString + "/path%20to/this%20is%20a%20test.xyz", udi3.ToString()); + } + [Test] public void GuidEntityCtorTest() { From c5c87ff50df0f638a475042c35072f2163f6e96a Mon Sep 17 00:00:00 2001 From: Dave Woestenborghs Date: Fri, 5 May 2017 13:27:32 +0200 Subject: [PATCH 12/27] Return empty string when e-mail is not filled Fix for http://issues.umbraco.org/issue/U4-9862 --- .../ValueConverters/EmailAddressValueConverter.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/EmailAddressValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/EmailAddressValueConverter.cs index 7a2a06cf67..15a7a816bd 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/EmailAddressValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/EmailAddressValueConverter.cs @@ -20,6 +20,11 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview) { + if(source == null) + { + return string.Empty; + } + return source.ToString(); } From fcf5ecc16680849c859a25cd429c669345064f0c Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Fri, 5 May 2017 14:14:37 +0200 Subject: [PATCH 13/27] Uses vswhere to figure out where VS17 is installed (if needed) Removes targets file that was almost unused, moved the relevant bits to the main csproj Updates BuildBelle.bat to be completely independent of installed version of node & npm on the machine --- .gitignore | 2 + build/Build.bat | 44 ++++++++++- build/BuildBelle.bat | 69 +++++++++++------ src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 21 +++++- src/umbraco.presentation.targets | 96 ------------------------ 5 files changed, 111 insertions(+), 121 deletions(-) delete mode 100644 src/umbraco.presentation.targets diff --git a/.gitignore b/.gitignore index 16994e0ab1..fb8092468e 100644 --- a/.gitignore +++ b/.gitignore @@ -142,3 +142,5 @@ build/ui-docs.zip build/csharp-docs.zip build/msbuild.log .vs/ + +build/tools/ diff --git a/build/Build.bat b/build/Build.bat index fc0d8a69ea..660cfa34be 100644 --- a/build/Build.bat +++ b/build/Build.bat @@ -49,10 +49,52 @@ REM This is necessary because SETLOCAL is on in InstallGit.cmd so that one might REM but the path setting is lost due to SETLOCAL path=C:\Program Files (x86)\Git\cmd;C:\Program Files\Git\cmd;%PATH% +SET toolsFolder=%CD%\tools\ +IF NOT EXIST %toolsFolder% ( + MD tools +) + +SET nuGetExecutable=%CD%\tools\nuget.exe +IF NOT EXIST %nuGetExecutable% ( + ECHO Getting NuGet so we can fetch some tools + ECHO Downloading https://dist.nuget.org/win-x86-commandline/latest/nuget.exe to %nuGetExecutable% + powershell -Command "(New-Object Net.WebClient).DownloadFile('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', '%nuGetExecutable%')" +) + +:: We need 7za.exe for BuildBelle.bat +IF NOT EXIST %toolsFolder%7za.exe ( + ECHO 7zip not found - fetching now + %nuGetExecutable% install 7-Zip.CommandLine -OutputDirectory %toolsFolder% -Verbosity quiet +) + +:: We need 7za.exe for VS2017+ +IF NOT EXIST %toolsFolder%vswhere.exe ( + ECHO vswhere not found - fetching now + %nuGetExecutable% install vswhere -OutputDirectory %toolsFolder% -Verbosity quiet +) + +:: Put 7za.exe and vswhere.exe in a predictable path (not version specific) +FOR /f "delims=" %%A in ('dir %toolsFolder%7-Zip.CommandLine.* /b') DO SET "sevenZipExePath=%toolsFolder%%%A\" +MOVE %sevenZipExePath%tools\7za.exe %toolsFolder%7za.exe + +FOR /f "delims=" %%A in ('dir %toolsFolder%vswhere.* /b') DO SET "vswhereExePath=%toolsFolder%%%A\" +MOVE %vswhereExePath%tools\vswhere.exe %toolsFolder%vswhere.exe + ECHO. ECHO Making sure we have a web.config IF NOT EXIST %CD%\..\src\Umbraco.Web.UI\web.config COPY %CD%\..\src\Umbraco.Web.UI\web.Template.config %CD%\..\src\Umbraco.Web.UI\web.config +for /f "usebackq tokens=1* delims=: " %%i in (`%CD%\tools\vswhere.exe -latest -requires Microsoft.Component.MSBuild`) do ( + if /i "%%i"=="installationPath" set InstallDir=%%j +) + +SET VSWherePath="%InstallDir%\MSBuild" +ECHO. +ECHO Visual Studio is installed in: %InstallDir% + +SET MSBUILDPATH=C:\Program Files (x86)\MSBuild\14.0\Bin +SET MSBUILD="%MSBUILDPATH%\MsBuild.exe" + ECHO. ECHO. ECHO Performing MSBuild and producing Umbraco binaries zip files @@ -60,7 +102,7 @@ ECHO This takes a few minutes and logging is set to report warnings ECHO and errors only so it might seems like nothing is happening for a while. ECHO You can check the msbuild.log file for progress. ECHO. -%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe "Build.proj" /p:BUILD_RELEASE=%release% /p:BUILD_COMMENT=%comment% /p:NugetPackagesDirectory=%nuGetFolder% /consoleloggerparameters:Summary;ErrorsOnly;WarningsOnly /fileLogger +%MSBUILD% "Build.proj" /p:BUILD_RELEASE=%release% /p:BUILD_COMMENT=%comment% /p:NugetPackagesDirectory=%nuGetFolder% /p:VSWherePath=%VSWherePath% IF ERRORLEVEL 1 GOTO :error ECHO. diff --git a/build/BuildBelle.bat b/build/BuildBelle.bat index 8a07ee380a..ae2d5ba8b5 100644 --- a/build/BuildBelle.bat +++ b/build/BuildBelle.bat @@ -1,33 +1,58 @@ @ECHO OFF SETLOCAL + :: SETLOCAL is on, so changes to the path not persist to the actual user's path -SET release=%1 -ECHO Installing Npm NuGet Package - -SET nuGetFolder=%CD%\..\src\packages\ -ECHO Configured packages folder: %nuGetFolder% +SET toolsFolder=%CD%\tools\ ECHO Current folder: %CD% -%CD%\..\src\.nuget\NuGet.exe install Npm.js -OutputDirectory %nuGetFolder% -Verbosity quiet +SET nodeFileName=node-v6.9.1-win-x86.7z +SET nodeExtractFolder=%toolsFolder%node.js.691 -for /f "delims=" %%A in ('dir %nuGetFolder%node.js.* /b') do set "nodePath=%nuGetFolder%%%A\" -for /f "delims=" %%A in ('dir %nuGetFolder%npm.js.* /b') do set "npmPath=%nuGetFolder%%%A\tools\" +IF NOT EXIST %nodeExtractFolder% ( + ECHO Downloading http://nodejs.org/dist/v6.9.1/%nodeFileName% to %toolsFolder%%nodeFileName% + powershell -Command "(New-Object Net.WebClient).DownloadFile('http://nodejs.org/dist/v6.9.1/%nodeFileName%', '%toolsFolder%%nodeFileName%')" + ECHO Extracting %nodeFileName% to %nodeExtractFolder% + %toolsFolder%\7za.exe x %toolsFolder%\%nodeFileName% -o%nodeExtractFolder% -aos > nul +) +FOR /f "delims=" %%A in ('dir %nodeExtractFolder%\node* /b') DO SET "nodePath=%nodeExtractFolder%\%%A" -ECHO Adding Npm and Node to path -REM SETLOCAL is on, so changes to the path not persist to the actual user's path -PATH=%npmPath%;%nodePath%;%PATH% +SET nuGetExecutable=%CD%\tools\nuget.exe +IF NOT EXIST %nuGetExecutable% ( + ECHO Downloading https://dist.nuget.org/win-x86-commandline/latest/nuget.exe to %nuGetExecutable% + powershell -Command "(New-Object Net.WebClient).DownloadFile('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', '%nuGetExecutable%')" +) -SET buildFolder=%CD% +SET drive=%CD:~0,2% +SET nuGetFolder=%drive%\packages\ +FOR /f "delims=" %%A in ('dir %nuGetFolder%npm.* /b') DO SET "npmPath=%nuGetFolder%%%A\" +IF [%npmPath%] == [] GOTO :installnpm +IF NOT [%npmPath%] == [] GOTO :build -ECHO Change directory to %CD%\..\src\Umbraco.Web.UI.Client\ -CD %CD%\..\src\Umbraco.Web.UI.Client\ +:installnpm + ECHO Downloading npm + ECHO Configured packages folder: %nuGetFolder% + ECHO Installing Npm NuGet Package + %nuGetExecutable% install Npm -OutputDirectory %nuGetFolder% -Verbosity detailed + REM Ensures that we look for the just downloaded NPM, not whatever the user has installed on their machine + FOR /f "delims=" %%A in ('dir %nuGetFolder%npm.* /b') DO SET "npmPath=%nuGetFolder%%%A\" + GOTO :build -ECHO Do npm install and the grunt build of Belle -call npm cache clean --quiet -call npm install --quiet -call npm install -g grunt-cli --quiet -call npm install -g bower --quiet -call grunt build --buildversion=%release% +:build + ECHO Adding Npm and Node to path + REM SETLOCAL is on, so changes to the path not persist to the actual user's path + PATH=%npmPath%;%nodePath%;%PATH% -ECHO Move back to the build folder -CD %buildFolder% \ No newline at end of file + SET buildFolder=%CD% + + ECHO Change directory to %CD%\..\src\Umbraco.Web.UI.Client\ + CD %CD%\..\src\Umbraco.Web.UI.Client\ + + ECHO Do npm install and the grunt build of Belle + call npm cache clean --quiet + call npm install --quiet + call npm install -g grunt-cli --quiet + call npm install -g bower --quiet + call grunt build --buildversion=%release% + + ECHO Move back to the build folder + CD %buildFolder% \ No newline at end of file diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 54c8c2c59c..512cab02b1 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -2435,14 +2435,31 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\" - - + + $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll + + + $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v11.0\Web\Microsoft.Web.Publishing.Tasks.dll + + + $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v12.0\Web\Microsoft.Web.Publishing.Tasks.dll + + + $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v14.0\Web\Microsoft.Web.Publishing.Tasks.dll + + + $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v15.0\Web\Microsoft.Web.Publishing.Tasks.dll + + + + + diff --git a/src/umbraco.presentation.targets b/src/umbraco.presentation.targets deleted file mode 100644 index 2a33705d6f..0000000000 --- a/src/umbraco.presentation.targets +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - $(MSBuildStartupDirectory)\..\src\ - - - - - $(SolutionDir) - $(Computername). - - - - $(ProjectDir) - $(WebProjectOutputDir) - $(ProjDir)web.Template.$(ConfigEnvironment)$(Configuration).config - - - - $(ProjDir)web.Template.$(Configuration).config - - - - $(ProjDir) - - - - $(ProjOutputDir)\ - - - - - - - - - $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll - - - - $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v11.0\Web\Microsoft.Web.Publishing.Tasks.dll - - - - $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v12.0\Web\Microsoft.Web.Publishing.Tasks.dll - - - - $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v14.0\Web\Microsoft.Web.Publishing.Tasks.dll - - - - $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v15.0\Web\Microsoft.Web.Publishing.Tasks.dll - - - - - - - - - - - - @(ConfigFiles) - $(OriginalFileName.Replace("%(ConfigFiles.Extension)",".$(Configuration)%(ConfigFiles.Extension)")) - $(OriginalFileName.Replace("$(ProjDir)", "$(ProjOutputDir)")) - - - - - - - - - - \ No newline at end of file From 3c4b3f44c7b0cb9790a7f07839afbbb4c6a61b3f Mon Sep 17 00:00:00 2001 From: Claus Date: Fri, 5 May 2017 14:52:01 +0200 Subject: [PATCH 14/27] U4-9864 Missing import and xss check in other PermissionEditor.aspx --- .../umbraco.presentation/umbraco/users/PermissionEditor.aspx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/users/PermissionEditor.aspx b/src/Umbraco.Web/umbraco.presentation/umbraco/users/PermissionEditor.aspx index 815a420f88..75b5d6e66a 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/users/PermissionEditor.aspx +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/users/PermissionEditor.aspx @@ -1,5 +1,5 @@ <%@ Page Language="C#" AutoEventWireup="true" MasterPageFile="../masterpages/umbracoPage.Master" CodeBehind="PermissionEditor.aspx.cs" Inherits="umbraco.cms.presentation.user.PermissionEditor" %> - +<%@ Import Namespace="Umbraco.Web" %> <%@ Register Src="../controls/Tree/TreeControl.ascx" TagName="TreeControl" TagPrefix="umbraco" %> <%@ Register Src="NodePermissions.ascx" TagName="NodePermissions" TagPrefix="user" %> <%@ Register TagPrefix="ui" Namespace="umbraco.uicontrols" Assembly="controls" %> @@ -27,7 +27,7 @@