From a5f3b50699c5eaf5a3a50609e143b1d7b4990c26 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Wed, 3 Aug 2016 17:52:27 +0200 Subject: [PATCH 01/23] Needed to be fixed, just like for the ascending OrderBy - see U4-4474 --- src/Umbraco.Core/Persistence/PetaPocoSqlExtensions.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Core/Persistence/PetaPocoSqlExtensions.cs b/src/Umbraco.Core/Persistence/PetaPocoSqlExtensions.cs index cecb0e2982..04f4147155 100644 --- a/src/Umbraco.Core/Persistence/PetaPocoSqlExtensions.cs +++ b/src/Umbraco.Core/Persistence/PetaPocoSqlExtensions.cs @@ -77,7 +77,8 @@ namespace Umbraco.Core.Persistence var type = typeof(TColumn); var tableName = type.GetTableName(); - var syntax = string.Format("{0}.{1} DESC", + //need to ensure the order by is in brackets, see: https://github.com/toptensoftware/PetaPoco/issues/177 + var syntax = string.Format("({0}.{1}) DESC", sqlSyntax.GetQuotedTableName(tableName), sqlSyntax.GetQuotedColumnName(columnName)); From 11cafa2c4c59f333f968724064503790a68d7330 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Wed, 3 Aug 2016 17:54:21 +0200 Subject: [PATCH 02/23] Adds a setting to be able to disable redirect URL tracking --- .../UmbracoSettings/IWebRoutingSection.cs | 2 + .../UmbracoSettings/WebRoutingElement.cs | 6 +++ .../WebRoutingElementDefaultTests.cs | 6 +++ .../Redirects/RedirectTrackingEventHandler.cs | 40 +++++++++++-------- 4 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings/IWebRoutingSection.cs b/src/Umbraco.Core/Configuration/UmbracoSettings/IWebRoutingSection.cs index 2998fc2f78..9eb6d02aa7 100644 --- a/src/Umbraco.Core/Configuration/UmbracoSettings/IWebRoutingSection.cs +++ b/src/Umbraco.Core/Configuration/UmbracoSettings/IWebRoutingSection.cs @@ -9,6 +9,8 @@ bool DisableAlternativeTemplates { get; } bool DisableFindContentByIdPath { get; } + + bool DisableRedirectUrlTracking { get; } string UrlProviderMode { get; } diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings/WebRoutingElement.cs b/src/Umbraco.Core/Configuration/UmbracoSettings/WebRoutingElement.cs index 1ed9bc034c..82f5d46b28 100644 --- a/src/Umbraco.Core/Configuration/UmbracoSettings/WebRoutingElement.cs +++ b/src/Umbraco.Core/Configuration/UmbracoSettings/WebRoutingElement.cs @@ -27,6 +27,12 @@ namespace Umbraco.Core.Configuration.UmbracoSettings get { return (bool) base["disableFindContentByIdPath"]; } } + [ConfigurationProperty("disableRedirectUrlTracking", DefaultValue = "false")] + public bool DisableRedirectUrlTracking + { + get { return (bool) base["disableRedirectUrlTracking"]; } + } + [ConfigurationProperty("urlProviderMode", DefaultValue = "AutoLegacy")] public string UrlProviderMode { diff --git a/src/Umbraco.Tests/Configurations/UmbracoSettings/WebRoutingElementDefaultTests.cs b/src/Umbraco.Tests/Configurations/UmbracoSettings/WebRoutingElementDefaultTests.cs index 47b5e15b69..1e568c608e 100644 --- a/src/Umbraco.Tests/Configurations/UmbracoSettings/WebRoutingElementDefaultTests.cs +++ b/src/Umbraco.Tests/Configurations/UmbracoSettings/WebRoutingElementDefaultTests.cs @@ -28,5 +28,11 @@ namespace Umbraco.Tests.Configurations.UmbracoSettings { Assert.IsTrue(SettingsSection.WebRouting.DisableFindContentByIdPath == false); } + + [Test] + public void DisableRedirectUrlTracking() + { + Assert.IsTrue(SettingsSection.WebRouting.DisableRedirectUrlTracking == false); + } } } \ No newline at end of file diff --git a/src/Umbraco.Web/Redirects/RedirectTrackingEventHandler.cs b/src/Umbraco.Web/Redirects/RedirectTrackingEventHandler.cs index 42c5e6093b..82c06ca7d5 100644 --- a/src/Umbraco.Web/Redirects/RedirectTrackingEventHandler.cs +++ b/src/Umbraco.Web/Redirects/RedirectTrackingEventHandler.cs @@ -8,6 +8,7 @@ using Umbraco.Web.Routing; using System.Collections.Generic; using System.Linq; using Umbraco.Core.Cache; +using Umbraco.Core.Configuration; using Umbraco.Core.Models.PublishedContent; using Umbraco.Web.Cache; @@ -30,24 +31,31 @@ namespace Umbraco.Web.Redirects /// protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) { - // if any of these dlls are loaded we don't want to run our finder - var dlls = new[] + if (UmbracoConfig.For.UmbracoSettings().WebRouting.DisableRedirectUrlTracking) { - "InfoCaster.Umbraco.UrlTracker", - "SEOChecker", - "Simple301", - "Terabyte.Umbraco.Modules.PermanentRedirect", - "CMUmbracoTools", - "PWUrlRedirect" - }; - - // assuming all assemblies have been loaded already - // check if any of them matches one of the above dlls - var found = AppDomain.CurrentDomain.GetAssemblies() - .Select(x => x.FullName.Split(',')[0]) - .Any(x => dlls.Contains(x)); - if (found) ContentFinderResolver.Current.RemoveType(); + } + else + { + // if any of these dlls are loaded we don't want to run our finder + var dlls = new[] + { + "InfoCaster.Umbraco.UrlTracker", + "SEOChecker", + "Simple301", + "Terabyte.Umbraco.Modules.PermanentRedirect", + "CMUmbracoTools", + "PWUrlRedirect" + }; + + // assuming all assemblies have been loaded already + // check if any of them matches one of the above dlls + var found = AppDomain.CurrentDomain.GetAssemblies() + .Select(x => x.FullName.Split(',')[0]) + .Any(x => dlls.Contains(x)); + if (found) + ContentFinderResolver.Current.RemoveType(); + } } /// From b4d5140d077c567e87423725e45cb0282d1c0b43 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Wed, 3 Aug 2016 17:57:01 +0200 Subject: [PATCH 03/23] WIP Starting with taking Marc's code to get a rudimentary dashboard for the 301 URL tracker --- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 6 +- src/Umbraco.Web.UI/config/Dashboard.config | 10 +++ .../RedirectUrlManagementController.cs | 65 +++++++++++++++++++ .../Redirects/RedirectUrlSearchResults.cs | 16 +++++ src/Umbraco.Web/Umbraco.Web.csproj | 2 + 5 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs create mode 100644 src/Umbraco.Web/Redirects/RedirectUrlSearchResults.cs diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index da577d4ad0..f2be24e528 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -40,8 +40,7 @@ v4.5 true - - + 44319 @@ -579,6 +578,8 @@ + + @@ -638,6 +639,7 @@ + 404handlers.config diff --git a/src/Umbraco.Web.UI/config/Dashboard.config b/src/Umbraco.Web.UI/config/Dashboard.config index df45708e0f..cc20f70654 100644 --- a/src/Umbraco.Web.UI/config/Dashboard.config +++ b/src/Umbraco.Web.UI/config/Dashboard.config @@ -109,4 +109,14 @@ +
+ + developer + + + + /App_Plugins/RedirectUrlDashboard/redirecturlsearch.html + + +
diff --git a/src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs b/src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs new file mode 100644 index 0000000000..27791136e1 --- /dev/null +++ b/src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs @@ -0,0 +1,65 @@ +using System.Net.Http; +using System.Text; +using System.Web.Http; +using Umbraco.Web.WebApi; + +namespace Umbraco.Web.Redirects +{ + public class RedirectUrlManagementController : UmbracoAuthorizedApiController + { + //add paging + [HttpGet] + public RedirectUrlSearchResult SearchRedirectUrls(string searchTerm, int page = 0) + { + + int pageSize = 20; + var searchResult = new RedirectUrlSearchResult(); + var redirectUrlService = Services.RedirectUrlService; + long resultCount = 0L; + // need endpoint for search functionality + // by url, by domain ? it's the url that you want to find them by, that's what you see.. + + var redirects = redirectUrlService.GetAllRedirectUrls(page, 20, out resultCount); + searchResult.SearchResults = redirects; + searchResult.TotalCount = resultCount; + searchResult.CurrentPage = page; + //hmm how many results 'could there be ? + searchResult.PageCount = ((int)resultCount + pageSize - 1) / pageSize; + + searchResult.HasSearchResults = resultCount > 0; + searchResult.HasExactMatch = (resultCount == 1); + return searchResult; + + } + + [HttpGet] + public HttpResponseMessage GetPublishedUrl(int id) + { + var publishedUrl = "#"; + if (id > 0) + { + publishedUrl = Umbraco.Url(id); + } + + return new HttpResponseMessage { Content = new StringContent(publishedUrl, Encoding.UTF8, "text/html") }; + + } + + [HttpPost] + public HttpResponseMessage DeleteRedirectUrl(int id) + { + + var redirectUrlService = Services.RedirectUrlService; + // has the redirect already been deleted ? + //var redirectUrl = redirectUrlService.GetById(redirectUrl.Id); + //if (redirectUrl== null) + //{ + // return new HttpResponseMessage(System.Net.HttpStatusCode.NotFound); + //} + redirectUrlService.Delete(id); + return new HttpResponseMessage(System.Net.HttpStatusCode.OK); + } + + + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Redirects/RedirectUrlSearchResults.cs b/src/Umbraco.Web/Redirects/RedirectUrlSearchResults.cs new file mode 100644 index 0000000000..1dac259a88 --- /dev/null +++ b/src/Umbraco.Web/Redirects/RedirectUrlSearchResults.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Umbraco.Core.Models; + +namespace Umbraco.Web.Redirects +{ + public class RedirectUrlSearchResult + { + public string StatusMessage { get; set; } + public IEnumerable SearchResults { get; set; } + public bool HasSearchResults { get; set; } + public bool HasExactMatch { get; set; } + public long TotalCount { get; set; } + public int PageCount { get; set; } + public int CurrentPage { get; set; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index d1cab1b52d..78b88577a4 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -391,6 +391,8 @@ + + From 77cbdcf38f46eae183784e64f3cb81c6ab48c94a Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Wed, 3 Aug 2016 19:05:04 +0200 Subject: [PATCH 04/23] js files are ignored by default, need to force add them if we really want them --- .../redirecturlsearch.controller.js | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.controller.js diff --git a/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.controller.js b/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.controller.js new file mode 100644 index 0000000000..a3f809187b --- /dev/null +++ b/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.controller.js @@ -0,0 +1,106 @@ +angular.module("umbraco").controller("Umbraco.RedirectUrlSearch", function ($scope, $http, angularHelper, notificationsService, entityResource, $routeParams) { + + //...todo + //search by url or url part + //search by domain + //display domain in dashboard results? + + $scope.isSearch = false; + $scope.hasResults = false; + + $scope.pagination = []; + $scope.isNew = false; + $scope.actionInProgress = false; + $scope.listViewResultSet = { + totalPages: 0, + items: [] + }; + + $scope.options = { + pageSize: 10, + pageNumber: ($routeParams.page && Number($routeParams.page) !== NaN && Number($routeParams.page) > 0) ? $routeParams.page : 1 + }; + + $scope.next = function () { + if ($scope.options.pageNumber < $scope.listViewResultSet.totalPages) { + $scope.options.pageNumber++; + $scope.reloadView(); + } + }; + + $scope.goToPage = function (pageNumber) { + $scope.options.pageNumber = pageNumber + 1; + $scope.reloadView(); + }; + + $scope.prev = function () { + if ($scope.options.pageNumber > 1) { + $scope.options.pageNumber--; + $scope.reloadView(); + } + }; + + $scope.search = function () { + + //do we want to search by url and by domain... + + var searchTerm = $scope.searchTerm; + + $http.get("backoffice/api/RedirectUrlManagement/SearchRedirectUrls/?searchTerm=" + searchTerm + "&page=" + $scope.options.pageNumber + "&pageSize=" + $scope.options.pageSize).then(function (response) { + var matchingItems = response.data; + $scope.isSearch = true; + $scope.StatusMessage = matchingItems.StatusMessage; + $scope.hasResults = matchingItems.HasSearchResults; + $scope.redirectUrls = matchingItems.SearchResults; + angular.forEach($scope.redirectUrls, function (item) { + $http.get("backoffice/api/RedirectUrlManagement/GetPublishedUrl/?id=" + item.ContentId).then(function (response) { + item.ContentUrl = response.data; + }); + }); + }); + }; + + $scope.load = function () { + // $scope.searchTerm = ""; + $scope.search(); + }; + + $scope.removeRedirect = function (redirectToDelete) { + $http.post("backoffice/api/RedirectUrlManagement/DeleteRedirectUrl/" + redirectToDelete.Id).then(function (response) { + if (response.status === 200) { + notificationsService.success('Redirect Url Removed!', 'Redirect Url ' + redirectToDelete.Url + ' has been deleted'); + // now remove from table client sides + var index = -1; + var urlArr = eval($scope.redirectUrls); + for (var i = 0; i < urlArr.length; i++) { + if (urlArr[i].Id === redirectToDelete.Id) { + index = i; + break; + } + } + if (index === -1) { + notificationsService.warning('Redirect Url Removal Error!', 'Redirect Url ' + redirectToDelete.Url + ' may have already been removed'); + } + $scope.redirectUrls.splice(index, 1); + } + else { + notificationsService.warning('Redirect Url Error!','Redirect Url ' + redirectToDelete.Url + ' was not deleted'); + } + }); + }; + + $scope.disableUrlTracker = function() { + var disable = confirm("Are you sure you want to disable the URL tracker completely?"); + if (disable) { + $http.post("backoffice/api/RedirectUrlManagement/DisableUrlTracker/").then(function(response) { + if (response.status === 200) { + notificationsService.success("URL Tracker has now been diabled."); + } else { + notificationsService.warning("Error diabling the URL Tracker, more information can be found in your log file."); + } + }); + } + }; + + $scope.load(); +}); \ No newline at end of file From 6237d4a3e5e197705be33d5568eb8ae4d92323ee Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Wed, 3 Aug 2016 20:01:43 +0200 Subject: [PATCH 05/23] Adds a toggle to disable/enable the URL tracker Adds paging, adapted from https://github.com/robertjf/umbMemberListView/blob/master/MemberListView/App_Plugins/MemberManager/backoffice/dashboard/memberListView.controller.js --- .../redirecturlsearch.controller.js | 89 +++++++++++++++---- .../ImageProcessorValidation.cs | 54 +++++++++++ .../RedirectUrlManagementController.cs | 40 +++++++-- .../Redirects/RedirectUrlSearchResults.cs | 2 + 4 files changed, 162 insertions(+), 23 deletions(-) create mode 100644 src/Umbraco.Web.UI/ImageProcessorValidation.cs diff --git a/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.controller.js b/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.controller.js index a3f809187b..76101ab5c7 100644 --- a/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.controller.js +++ b/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.controller.js @@ -1,5 +1,4 @@ angular.module("umbraco").controller("Umbraco.RedirectUrlSearch", function ($scope, $http, angularHelper, notificationsService, entityResource, $routeParams) { - //...todo //search by url or url part //search by domain @@ -17,26 +16,26 @@ angular.module("umbraco").controller("Umbraco.RedirectUrlSearch", function ($sco }; $scope.options = { - pageSize: 10, + pageSize: 20, pageNumber: ($routeParams.page && Number($routeParams.page) !== NaN && Number($routeParams.page) > 0) ? $routeParams.page : 1 }; $scope.next = function () { - if ($scope.options.pageNumber < $scope.listViewResultSet.totalPages) { + if ($scope.options.pageNumber < $scope.pageCount) { $scope.options.pageNumber++; - $scope.reloadView(); + $scope.load(); } }; $scope.goToPage = function (pageNumber) { $scope.options.pageNumber = pageNumber + 1; - $scope.reloadView(); + $scope.load(); }; $scope.prev = function () { if ($scope.options.pageNumber > 1) { $scope.options.pageNumber--; - $scope.reloadView(); + $scope.load(); } }; @@ -52,6 +51,62 @@ angular.module("umbraco").controller("Umbraco.RedirectUrlSearch", function ($sco $scope.StatusMessage = matchingItems.StatusMessage; $scope.hasResults = matchingItems.HasSearchResults; $scope.redirectUrls = matchingItems.SearchResults; + + $scope.urlTrackerDisabled = matchingItems.UrlTrackerDisabled; + $scope.action = ""; + if ($scope.urlTrackerDisabled !== true) { + $scope.action = "Disable"; + } else { + $scope.action = "Enable"; + } + + $scope.pageCount = matchingItems.PageCount; + $scope.totalCount = matchingItems.TotalCount; + $scope.options.pageNumber = matchingItems.CurrentPage; + + if ($scope.options.pageNumber > $scope.pageCount) { + $scope.options.pageNumber = $scope.pageCount; + } + + $scope.pagination = []; + + var i; + if ($scope.pageCount <= 10) { + for (i = 0; i < $scope.pageCount; i++) { + $scope.pagination.push({ + val: (i + 1), + isActive: $scope.options.pageNumber === (i + 1) + }); + } + } + else { + //if there is more than 10 pages, we need to do some fancy bits + + //get the max index to start + var maxIndex = $scope.pageCount - 10; + //set the start, but it can't be below zero + var start = Math.max($scope.options.pageNumber - 5, 0); + //ensure that it's not too far either + start = Math.min(maxIndex, start); + + for (i = start; i < (10 + start) ; i++) { + $scope.pagination.push({ + val: (i + 1), + isActive: $scope.options.pageNumber === (i + 1) + }); + } + + //now, if the start is greater than 0 then '1' will not be displayed, so do the elipses thing + if (start > 0) { + $scope.pagination.unshift({ name: "First", val: 1, isActive: false }, { val: "...", isActive: false }); + } + + //same for the end + if (start < maxIndex) { + $scope.pagination.push({ val: "...", isActive: false }, { name: "Last", val: $scope.pageCount, isActive: false }); + } + } + angular.forEach($scope.redirectUrls, function (item) { $http.get("backoffice/api/RedirectUrlManagement/GetPublishedUrl/?id=" + item.ContentId).then(function (response) { item.ContentUrl = response.data; @@ -68,7 +123,7 @@ angular.module("umbraco").controller("Umbraco.RedirectUrlSearch", function ($sco $scope.removeRedirect = function (redirectToDelete) { $http.post("backoffice/api/RedirectUrlManagement/DeleteRedirectUrl/" + redirectToDelete.Id).then(function (response) { if (response.status === 200) { - notificationsService.success('Redirect Url Removed!', 'Redirect Url ' + redirectToDelete.Url + ' has been deleted'); + notificationsService.success("Redirect Url Removed!", "Redirect Url " + redirectToDelete.Url + " has been deleted"); // now remove from table client sides var index = -1; var urlArr = eval($scope.redirectUrls); @@ -79,26 +134,28 @@ angular.module("umbraco").controller("Umbraco.RedirectUrlSearch", function ($sco } } if (index === -1) { - notificationsService.warning('Redirect Url Removal Error!', 'Redirect Url ' + redirectToDelete.Url + ' may have already been removed'); + notificationsService.warning("Redirect Url Removal Error!", "Redirect Url " + redirectToDelete.Url + " may have already been removed"); } $scope.redirectUrls.splice(index, 1); } else { - notificationsService.warning('Redirect Url Error!','Redirect Url ' + redirectToDelete.Url + ' was not deleted'); + notificationsService.warning("Redirect Url Error!", "Redirect Url " + redirectToDelete.Url + " was not deleted"); } }); }; - $scope.disableUrlTracker = function() { - var disable = confirm("Are you sure you want to disable the URL tracker completely?"); - if (disable) { - $http.post("backoffice/api/RedirectUrlManagement/DisableUrlTracker/").then(function(response) { + $scope.toggleUrlTracker = function () { + var toggleConfirm = confirm("Are you sure you want to " + $scope.action.toLowerCase() + " the URL tracker?"); + if (toggleConfirm) { + $http.post("backoffice/api/RedirectUrlManagement/ToggleUrlTracker/?disable=" + (!$scope.urlTrackerDisabled)).then(function (response) { if (response.status === 200) { - notificationsService.success("URL Tracker has now been diabled."); + notificationsService.success("URL Tracker has now been " + $scope.action.toLowerCase() + "d."); + + $scope.load(); } else { - notificationsService.warning("Error diabling the URL Tracker, more information can be found in your log file."); + notificationsService.warning("Error " + $scope.action.toLowerCase() + "ing the URL Tracker, more information can be found in your log file."); } - }); + }); } }; diff --git a/src/Umbraco.Web.UI/ImageProcessorValidation.cs b/src/Umbraco.Web.UI/ImageProcessorValidation.cs new file mode 100644 index 0000000000..f788dcf30a --- /dev/null +++ b/src/Umbraco.Web.UI/ImageProcessorValidation.cs @@ -0,0 +1,54 @@ +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Web; +using ImageProcessor.Web.Processors; +using ImageProcessor.Web.Configuration; +using ImageProcessor.Web.HttpModules; +using Umbraco.Core; + +namespace Umbraco.Web.UI +{ + public class ImageProcessorValidation : ApplicationEventHandler + { + protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) + { + ImageProcessingModule.ValidatingRequest += ImageProcessingModule_ValidatingRequest; + } + + private static void ImageProcessingModule_ValidatingRequest(object sender, ImageProcessor.Web.Helpers.ValidatingRequestEventArgs e) + { +// Blur is disabled by default, add it to the list of available processors again +var configuration = ImageProcessorConfiguration.Instance; +var settings = new Dictionary +{ + { "MaxSize", "15" }, + { "MaxSigma", "1.5" }, + { "MaxThreshold", "10" } +}; + +configuration.AvailableWebGraphicsProcessors.TryAdd(typeof(GaussianBlur), settings); + + // Nothing to process, return immediately + if (string.IsNullOrWhiteSpace(e.QueryString)) + return; + + // Don't support alpha whatsoever + var queryCollection = HttpUtility.ParseQueryString(e.QueryString); + if (queryCollection.AllKeys.Contains("alpha")) + { + e.Cancel = true; + return; + } + + // If there's a crop parameter, force it to always just be a specific value + if (queryCollection.AllKeys.Contains("crop")) + { + queryCollection["crop"] = "100,100,100,100"; + // this performs the reverse of ParseQueryString since the result of ParseQueryString + // is actually an instance of System.Web.HttpValueCollection + e.QueryString = queryCollection.ToString(); + } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs b/src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs index 27791136e1..7f3334d3f2 100644 --- a/src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs +++ b/src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs @@ -1,6 +1,10 @@ -using System.Net.Http; +using System.IO; +using System.Net.Http; using System.Text; +using System.Web; using System.Web.Http; +using System.Xml; +using Umbraco.Core.Configuration; using Umbraco.Web.WebApi; namespace Umbraco.Web.Redirects @@ -9,20 +13,19 @@ namespace Umbraco.Web.Redirects { //add paging [HttpGet] - public RedirectUrlSearchResult SearchRedirectUrls(string searchTerm, int page = 0) + public RedirectUrlSearchResult SearchRedirectUrls(string searchTerm, int page = 0, int pageSize = 10) { - - int pageSize = 20; - var searchResult = new RedirectUrlSearchResult(); + page = page - 1; + var searchResult = new RedirectUrlSearchResult { UrlTrackerDisabled = UmbracoConfig.For.UmbracoSettings().WebRouting.DisableRedirectUrlTracking }; var redirectUrlService = Services.RedirectUrlService; long resultCount = 0L; // need endpoint for search functionality // by url, by domain ? it's the url that you want to find them by, that's what you see.. - var redirects = redirectUrlService.GetAllRedirectUrls(page, 20, out resultCount); + var redirects = redirectUrlService.GetAllRedirectUrls(page, pageSize, out resultCount); searchResult.SearchResults = redirects; searchResult.TotalCount = resultCount; - searchResult.CurrentPage = page; + searchResult.CurrentPage = page + 1; //hmm how many results 'could there be ? searchResult.PageCount = ((int)resultCount + pageSize - 1) / pageSize; @@ -60,6 +63,29 @@ namespace Umbraco.Web.Redirects return new HttpResponseMessage(System.Net.HttpStatusCode.OK); } + [HttpPost] + public HttpResponseMessage ToggleUrlTracker(bool disable) + { + var configFilePath = HttpContext.Current.Server.MapPath("~/config/umbracoSettings.config"); + if (File.Exists(configFilePath)) + { + var umbracoConfig = new XmlDocument {PreserveWhitespace = true}; + umbracoConfig.Load(configFilePath); + + var webRoutingElement = umbracoConfig.SelectSingleNode("//web.routing") as XmlElement; + if (webRoutingElement != null) + { + // note: this adds the attribute if it does not exist + webRoutingElement.SetAttribute("disableRedirectUrlTracking", disable.ToString().ToLowerInvariant()); + umbracoConfig.Save(configFilePath); + } + + + return new HttpResponseMessage(System.Net.HttpStatusCode.OK); + } + + return new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest); + } } } \ No newline at end of file diff --git a/src/Umbraco.Web/Redirects/RedirectUrlSearchResults.cs b/src/Umbraco.Web/Redirects/RedirectUrlSearchResults.cs index 1dac259a88..4fe790e588 100644 --- a/src/Umbraco.Web/Redirects/RedirectUrlSearchResults.cs +++ b/src/Umbraco.Web/Redirects/RedirectUrlSearchResults.cs @@ -12,5 +12,7 @@ namespace Umbraco.Web.Redirects public long TotalCount { get; set; } public int PageCount { get; set; } public int CurrentPage { get; set; } + + public bool UrlTrackerDisabled { get; set; } } } \ No newline at end of file From f1d9775a0f4455cffdf89a3291f571b33a4a89e0 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Wed, 3 Aug 2016 21:15:27 +0200 Subject: [PATCH 06/23] Fix the build --- .../RedirectUrlDashboard/package.manifest | Bin 0 -> 336 bytes .../redirecturlsearch.html | 73 ++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/package.manifest create mode 100644 src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.html diff --git a/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/package.manifest b/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/package.manifest new file mode 100644 index 0000000000000000000000000000000000000000..996d847a970ac78a86a2bf8587df2fe0e4afc821 GIT binary patch literal 336 zcmaKo%?g505QV?3LGK`!mQnk5K@Si`tB^3QEKEhSP1K`XXD$Vgp-;26=6ka6Hjta_%tW6GRL*N!DQEho+tBB!1zR2`*gxUuf3CtTDkMLNdb!yGQ! zd)I9~wUm`q=Cl10#=QPGuH=+TSL>ZfyU|z9!f(vj%P&?Z)dnN_Wb4UBT_fx-Cwf}G io9a?qa?NUWEw}S|>|_F>Uj9Tgn}+^ueyJl*KluP=xHyXd literal 0 HcmV?d00001 diff --git a/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.html b/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.html new file mode 100644 index 0000000000..9a025a796b --- /dev/null +++ b/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.html @@ -0,0 +1,73 @@ +
+ +
+ +
+ +

Redirect Url Search

+

When you move and rename pages in Umbraco, 301 permanent redirects are automatically created

+

Here is a list of the redirects

+ + + +
+ + + + + + + + + + + + + + + + + + + + +
Original UrlRedirected ToDate CreatedRemove
{{redirectUrl.Url}}{{redirectUrl.ContentUrl}} {{redirectUrl.CreateDateUtc | date:'medium'}}
+
+
+ + +
+
+ From ba5be0e22af25206a9abd3b6513f7b0cb4eb41e4 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Thu, 4 Aug 2016 11:21:42 +0200 Subject: [PATCH 07/23] Adds search function --- .../Interfaces/IRedirectUrlRepository.cs | 10 ++++++++++ .../Repositories/RedirectUrlRepository.cs | 14 +++++++++++++- .../Services/IRedirectUrlService.cs | 10 ++++++++++ .../Services/RedirectUrlService.cs | 10 ++++++++++ .../redirecturlsearch.controller.js | 17 ++++++++++------- .../redirecturlsearch.html | 8 ++++---- .../RedirectUrlManagementController.cs | 18 +++++++++--------- 7 files changed, 66 insertions(+), 21 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IRedirectUrlRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IRedirectUrlRepository.cs index 82f2e0e516..8af394d71e 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IRedirectUrlRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IRedirectUrlRepository.cs @@ -66,5 +66,15 @@ namespace Umbraco.Core.Persistence.Repositories /// The total count of redirect urls. /// The redirect urls. IEnumerable GetAllUrls(int rootContentId, long pageIndex, int pageSize, out long total); + + /// + /// Searches for all redirect urls that contain a given search term in their URL property. + /// + /// The term to search for. + /// The page index. + /// The page size. + /// The total count of redirect urls. + /// The redirect urls. + IEnumerable SearchUrls(string searchTerm, long pageIndex, int pageSize, out long total); } } diff --git a/src/Umbraco.Core/Persistence/Repositories/RedirectUrlRepository.cs b/src/Umbraco.Core/Persistence/Repositories/RedirectUrlRepository.cs index 3cde41fd18..16e0c44da2 100644 --- a/src/Umbraco.Core/Persistence/Repositories/RedirectUrlRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/RedirectUrlRepository.cs @@ -185,7 +185,19 @@ JOIN umbracoNode ON umbracoRedirectUrl.contentKey=umbracoNode.uniqueID"); public IEnumerable GetAllUrls(int rootContentId, long pageIndex, int pageSize, out long total) { var sql = GetBaseQuery(false) - .Where("umbracoNode.path LIKE @path", new { path = "%," + rootContentId + ",%" }) + .Where("[umbracoNode].[path] LIKE @path", new { path = "%," + rootContentId + ",%" }) + .OrderByDescending(x => x.CreateDateUtc, SqlSyntax); + var result = Database.Page(pageIndex + 1, pageSize, sql); + total = Convert.ToInt32(result.TotalItems); + + var rules = result.Items.Select(Map); + return rules; + } + + public IEnumerable SearchUrls(string searchTerm, long pageIndex, int pageSize, out long total) + { + var sql = GetBaseQuery(false) + .Where("[umbracoRedirectUrl].[Url] LIKE @url", new { url = "%" + searchTerm.Trim().ToLowerInvariant() + "%" }) .OrderByDescending(x => x.CreateDateUtc, SqlSyntax); var result = Database.Page(pageIndex + 1, pageSize, sql); total = Convert.ToInt32(result.TotalItems); diff --git a/src/Umbraco.Core/Services/IRedirectUrlService.cs b/src/Umbraco.Core/Services/IRedirectUrlService.cs index 7b21fa9bb7..453c296af4 100644 --- a/src/Umbraco.Core/Services/IRedirectUrlService.cs +++ b/src/Umbraco.Core/Services/IRedirectUrlService.cs @@ -72,5 +72,15 @@ namespace Umbraco.Core.Services /// The total count of redirect urls. /// The redirect urls. IEnumerable GetAllRedirectUrls(int rootContentId, long pageIndex, int pageSize, out long total); + + /// + /// Searches for all redirect urls that contain a given search term in their URL property. + /// + /// The term to search for. + /// The page index. + /// The page size. + /// The total count of redirect urls. + /// The redirect urls. + IEnumerable SearchRedirectUrls(string searchTerm, long pageIndex, int pageSize, out long total); } } diff --git a/src/Umbraco.Core/Services/RedirectUrlService.cs b/src/Umbraco.Core/Services/RedirectUrlService.cs index de698509d0..d71a38b8e9 100644 --- a/src/Umbraco.Core/Services/RedirectUrlService.cs +++ b/src/Umbraco.Core/Services/RedirectUrlService.cs @@ -112,5 +112,15 @@ namespace Umbraco.Core.Services return rules; } } + public IEnumerable SearchRedirectUrls(string searchTerm, long pageIndex, int pageSize, out long total) + { + using (var uow = UowProvider.GetUnitOfWork()) + using (var repo = RepositoryFactory.CreateRedirectUrlRepository(uow)) + { + var rules = repo.SearchUrls(searchTerm, pageIndex, pageSize, out total); + uow.Commit(); + return rules; + } + } } } diff --git a/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.controller.js b/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.controller.js index 76101ab5c7..5dc8f901b2 100644 --- a/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.controller.js +++ b/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.controller.js @@ -23,29 +23,32 @@ angular.module("umbraco").controller("Umbraco.RedirectUrlSearch", function ($sco $scope.next = function () { if ($scope.options.pageNumber < $scope.pageCount) { $scope.options.pageNumber++; + $scope.currentPage++; $scope.load(); } }; $scope.goToPage = function (pageNumber) { $scope.options.pageNumber = pageNumber + 1; + $scope.currentPage = pageNumber; $scope.load(); }; $scope.prev = function () { if ($scope.options.pageNumber > 1) { $scope.options.pageNumber--; + $scope.currentPage--; $scope.load(); } }; $scope.search = function () { - - //do we want to search by url and by domain... - var searchTerm = $scope.searchTerm; + if (searchTerm === undefined) { + searchTerm = ""; + } - $http.get("backoffice/api/RedirectUrlManagement/SearchRedirectUrls/?searchTerm=" + searchTerm + "&page=" + $scope.options.pageNumber + "&pageSize=" + $scope.options.pageSize).then(function (response) { + $http.get("backoffice/api/RedirectUrlManagement/SearchRedirectUrls/?searchTerm=" + searchTerm + "&page=" + $scope.currentPage + "&pageSize=" + $scope.options.pageSize).then(function (response) { var matchingItems = response.data; $scope.isSearch = true; $scope.StatusMessage = matchingItems.StatusMessage; @@ -62,7 +65,8 @@ angular.module("umbraco").controller("Umbraco.RedirectUrlSearch", function ($sco $scope.pageCount = matchingItems.PageCount; $scope.totalCount = matchingItems.TotalCount; - $scope.options.pageNumber = matchingItems.CurrentPage; + $scope.currentPage = matchingItems.CurrentPage; + $scope.options.pageNumber = matchingItems.CurrentPage + 1; if ($scope.options.pageNumber > $scope.pageCount) { $scope.options.pageNumber = $scope.pageCount; @@ -78,8 +82,7 @@ angular.module("umbraco").controller("Umbraco.RedirectUrlSearch", function ($sco isActive: $scope.options.pageNumber === (i + 1) }); } - } - else { + } else { //if there is more than 10 pages, we need to do some fancy bits //get the max index to start diff --git a/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.html b/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.html index 9a025a796b..dcc3c01b90 100644 --- a/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.html +++ b/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.html @@ -4,11 +4,11 @@ -

Redirect Url Search

+

Redirect Url Management

When you move and rename pages in Umbraco, 301 permanent redirects are automatically created

-

Here is a list of the redirects

+

Here is a list of the redirects you

- +
diff --git a/src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs b/src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs index 7f3334d3f2..604dea8cc5 100644 --- a/src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs +++ b/src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs @@ -1,11 +1,11 @@ -using System.IO; -using System.Net.Http; +using System.Net.Http; using System.Text; using System.Web; using System.Web.Http; using System.Xml; using Umbraco.Core.Configuration; using Umbraco.Web.WebApi; +using File = System.IO.File; namespace Umbraco.Web.Redirects { @@ -15,17 +15,17 @@ namespace Umbraco.Web.Redirects [HttpGet] public RedirectUrlSearchResult SearchRedirectUrls(string searchTerm, int page = 0, int pageSize = 10) { - page = page - 1; var searchResult = new RedirectUrlSearchResult { UrlTrackerDisabled = UmbracoConfig.For.UmbracoSettings().WebRouting.DisableRedirectUrlTracking }; var redirectUrlService = Services.RedirectUrlService; - long resultCount = 0L; - // need endpoint for search functionality - // by url, by domain ? it's the url that you want to find them by, that's what you see.. + var resultCount = 0L; + + var redirects = string.IsNullOrWhiteSpace(searchTerm) + ? redirectUrlService.GetAllRedirectUrls(page, pageSize, out resultCount) + : redirectUrlService.SearchRedirectUrls(searchTerm, page, pageSize, out resultCount); - var redirects = redirectUrlService.GetAllRedirectUrls(page, pageSize, out resultCount); searchResult.SearchResults = redirects; searchResult.TotalCount = resultCount; - searchResult.CurrentPage = page + 1; + searchResult.CurrentPage = page; //hmm how many results 'could there be ? searchResult.PageCount = ((int)resultCount + pageSize - 1) / pageSize; @@ -70,7 +70,7 @@ namespace Umbraco.Web.Redirects if (File.Exists(configFilePath)) { - var umbracoConfig = new XmlDocument {PreserveWhitespace = true}; + var umbracoConfig = new XmlDocument { PreserveWhitespace = true }; umbracoConfig.Load(configFilePath); var webRoutingElement = umbracoConfig.SelectSingleNode("//web.routing") as XmlElement; From 875070fed8196fe924c4f0bb482418d268c71ea4 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Thu, 4 Aug 2016 17:02:46 +0200 Subject: [PATCH 08/23] File should not have been committed --- .../ImageProcessorValidation.cs | 54 ------------------- 1 file changed, 54 deletions(-) delete mode 100644 src/Umbraco.Web.UI/ImageProcessorValidation.cs diff --git a/src/Umbraco.Web.UI/ImageProcessorValidation.cs b/src/Umbraco.Web.UI/ImageProcessorValidation.cs deleted file mode 100644 index f788dcf30a..0000000000 --- a/src/Umbraco.Web.UI/ImageProcessorValidation.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Web; -using ImageProcessor.Web.Processors; -using ImageProcessor.Web.Configuration; -using ImageProcessor.Web.HttpModules; -using Umbraco.Core; - -namespace Umbraco.Web.UI -{ - public class ImageProcessorValidation : ApplicationEventHandler - { - protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) - { - ImageProcessingModule.ValidatingRequest += ImageProcessingModule_ValidatingRequest; - } - - private static void ImageProcessingModule_ValidatingRequest(object sender, ImageProcessor.Web.Helpers.ValidatingRequestEventArgs e) - { -// Blur is disabled by default, add it to the list of available processors again -var configuration = ImageProcessorConfiguration.Instance; -var settings = new Dictionary -{ - { "MaxSize", "15" }, - { "MaxSigma", "1.5" }, - { "MaxThreshold", "10" } -}; - -configuration.AvailableWebGraphicsProcessors.TryAdd(typeof(GaussianBlur), settings); - - // Nothing to process, return immediately - if (string.IsNullOrWhiteSpace(e.QueryString)) - return; - - // Don't support alpha whatsoever - var queryCollection = HttpUtility.ParseQueryString(e.QueryString); - if (queryCollection.AllKeys.Contains("alpha")) - { - e.Cancel = true; - return; - } - - // If there's a crop parameter, force it to always just be a specific value - if (queryCollection.AllKeys.Contains("crop")) - { - queryCollection["crop"] = "100,100,100,100"; - // this performs the reverse of ParseQueryString since the result of ParseQueryString - // is actually an instance of System.Web.HttpValueCollection - e.QueryString = queryCollection.ToString(); - } - } - } -} \ No newline at end of file From 0280d832b554ef9781d6b6a38e27ee63421d6319 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Thu, 4 Aug 2016 17:48:50 +0200 Subject: [PATCH 09/23] Some fixing based on code review --- .../Repositories/RedirectUrlRepository.cs | 4 +- .../Services/RedirectUrlService.cs | 5 --- .../RedirectUrlManagementController.cs | 43 +++++++------------ 3 files changed, 18 insertions(+), 34 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Repositories/RedirectUrlRepository.cs b/src/Umbraco.Core/Persistence/Repositories/RedirectUrlRepository.cs index 16e0c44da2..ec6e57b7b3 100644 --- a/src/Umbraco.Core/Persistence/Repositories/RedirectUrlRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/RedirectUrlRepository.cs @@ -185,7 +185,7 @@ JOIN umbracoNode ON umbracoRedirectUrl.contentKey=umbracoNode.uniqueID"); public IEnumerable GetAllUrls(int rootContentId, long pageIndex, int pageSize, out long total) { var sql = GetBaseQuery(false) - .Where("[umbracoNode].[path] LIKE @path", new { path = "%," + rootContentId + ",%" }) + .Where(string.Format("{0}.{1} LIKE @path", SqlSyntax.GetQuotedTableName("umbracoNode"), SqlSyntax.GetQuotedColumnName("path")), new { path = "%," + rootContentId + ",%" }) .OrderByDescending(x => x.CreateDateUtc, SqlSyntax); var result = Database.Page(pageIndex + 1, pageSize, sql); total = Convert.ToInt32(result.TotalItems); @@ -197,7 +197,7 @@ JOIN umbracoNode ON umbracoRedirectUrl.contentKey=umbracoNode.uniqueID"); public IEnumerable SearchUrls(string searchTerm, long pageIndex, int pageSize, out long total) { var sql = GetBaseQuery(false) - .Where("[umbracoRedirectUrl].[Url] LIKE @url", new { url = "%" + searchTerm.Trim().ToLowerInvariant() + "%" }) + .Where(string.Format("{0}.{1} LIKE @url", SqlSyntax.GetQuotedTableName("umbracoRedirectUrl"), SqlSyntax.GetQuotedColumnName("Url")), new { url = "%" + searchTerm.Trim().ToLowerInvariant() + "%" }) .OrderByDescending(x => x.CreateDateUtc, SqlSyntax); var result = Database.Page(pageIndex + 1, pageSize, sql); total = Convert.ToInt32(result.TotalItems); diff --git a/src/Umbraco.Core/Services/RedirectUrlService.cs b/src/Umbraco.Core/Services/RedirectUrlService.cs index d71a38b8e9..d4c7614aa4 100644 --- a/src/Umbraco.Core/Services/RedirectUrlService.cs +++ b/src/Umbraco.Core/Services/RedirectUrlService.cs @@ -75,7 +75,6 @@ namespace Umbraco.Core.Services using (var repo = RepositoryFactory.CreateRedirectUrlRepository(uow)) { var rule = repo.GetMostRecentUrl(url); - uow.Commit(); return rule; } } @@ -86,7 +85,6 @@ namespace Umbraco.Core.Services using (var repo = RepositoryFactory.CreateRedirectUrlRepository(uow)) { var rules = repo.GetContentUrls(contentKey); - uow.Commit(); return rules; } } @@ -97,7 +95,6 @@ namespace Umbraco.Core.Services using (var repo = RepositoryFactory.CreateRedirectUrlRepository(uow)) { var rules = repo.GetAllUrls(pageIndex, pageSize, out total); - uow.Commit(); return rules; } } @@ -108,7 +105,6 @@ namespace Umbraco.Core.Services using (var repo = RepositoryFactory.CreateRedirectUrlRepository(uow)) { var rules = repo.GetAllUrls(rootContentId, pageIndex, pageSize, out total); - uow.Commit(); return rules; } } @@ -118,7 +114,6 @@ namespace Umbraco.Core.Services using (var repo = RepositoryFactory.CreateRedirectUrlRepository(uow)) { var rules = repo.SearchUrls(searchTerm, pageIndex, pageSize, out total); - uow.Commit(); return rules; } } diff --git a/src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs b/src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs index 604dea8cc5..a147d859e0 100644 --- a/src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs +++ b/src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs @@ -26,7 +26,6 @@ namespace Umbraco.Web.Redirects searchResult.SearchResults = redirects; searchResult.TotalCount = resultCount; searchResult.CurrentPage = page; - //hmm how many results 'could there be ? searchResult.PageCount = ((int)resultCount + pageSize - 1) / pageSize; searchResult.HasSearchResults = resultCount > 0; @@ -40,52 +39,42 @@ namespace Umbraco.Web.Redirects { var publishedUrl = "#"; if (id > 0) - { publishedUrl = Umbraco.Url(id); - } return new HttpResponseMessage { Content = new StringContent(publishedUrl, Encoding.UTF8, "text/html") }; } [HttpPost] - public HttpResponseMessage DeleteRedirectUrl(int id) + public IHttpActionResult DeleteRedirectUrl(int id) { - var redirectUrlService = Services.RedirectUrlService; - // has the redirect already been deleted ? - //var redirectUrl = redirectUrlService.GetById(redirectUrl.Id); - //if (redirectUrl== null) - //{ - // return new HttpResponseMessage(System.Net.HttpStatusCode.NotFound); - //} redirectUrlService.Delete(id); - return new HttpResponseMessage(System.Net.HttpStatusCode.OK); + return Ok(); } [HttpPost] - public HttpResponseMessage ToggleUrlTracker(bool disable) + public IHttpActionResult ToggleUrlTracker(bool disable) { var configFilePath = HttpContext.Current.Server.MapPath("~/config/umbracoSettings.config"); - if (File.Exists(configFilePath)) - { - var umbracoConfig = new XmlDocument { PreserveWhitespace = true }; - umbracoConfig.Load(configFilePath); + var action = disable ? "disable" : "enable"; - var webRoutingElement = umbracoConfig.SelectSingleNode("//web.routing") as XmlElement; - if (webRoutingElement != null) - { - // note: this adds the attribute if it does not exist - webRoutingElement.SetAttribute("disableRedirectUrlTracking", disable.ToString().ToLowerInvariant()); - umbracoConfig.Save(configFilePath); - } + if (File.Exists(configFilePath) == false) + return BadRequest(string.Format("Couldn't {0} URL Tracker, the umbracoSettings.config file does not exist.", action)); + var umbracoConfig = new XmlDocument { PreserveWhitespace = true }; + umbracoConfig.Load(configFilePath); - return new HttpResponseMessage(System.Net.HttpStatusCode.OK); - } + var webRoutingElement = umbracoConfig.SelectSingleNode("//web.routing") as XmlElement; + if (webRoutingElement == null) + return BadRequest(string.Format("Couldn't {0} URL Tracker, the web.routing element was not found in umbracoSettings.config.", action)); - return new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest); + // note: this adds the attribute if it does not exist + webRoutingElement.SetAttribute("disableRedirectUrlTracking", disable.ToString().ToLowerInvariant()); + umbracoConfig.Save(configFilePath); + + return Ok(string.Format("URL tracker is now {0}d", action)); } } } \ No newline at end of file From 2f0ba3ac076cf19bfda9284f89e5bfe4c698fa66 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 5 Aug 2016 10:51:32 +0200 Subject: [PATCH 10/23] First part of html + js cleanup - use angular components in dashboard view + make js fit. --- .../redirecturlsearch.controller.js | 216 ++++++++---------- .../redirecturlsearch.html | 151 +++++++----- 2 files changed, 180 insertions(+), 187 deletions(-) diff --git a/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.controller.js b/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.controller.js index 5dc8f901b2..51d50eebd6 100644 --- a/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.controller.js +++ b/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.controller.js @@ -1,166 +1,134 @@ -angular.module("umbraco").controller("Umbraco.RedirectUrlSearch", function ($scope, $http, angularHelper, notificationsService, entityResource, $routeParams) { +angular.module("umbraco").controller("Umbraco.RedirectUrlSearch", function ($scope, $http, angularHelper, notificationsService, entityResource, $routeParams, $q) { //...todo //search by url or url part //search by domain //display domain in dashboard results? - $scope.isSearch = false; - $scope.hasResults = false; + //used to cancel any request in progress if another one needs to take it's place + var canceler = null; - $scope.pagination = []; - $scope.isNew = false; - $scope.actionInProgress = false; - $scope.listViewResultSet = { - totalPages: 0, - items: [] + $scope.dashboard = { + searchTerm: "", + loading: false, + UrlTrackerDisabled: false }; - $scope.options = { - pageSize: 20, - pageNumber: ($routeParams.page && Number($routeParams.page) !== NaN && Number($routeParams.page) > 0) ? $routeParams.page : 1 + $scope.pagination = { + pageIndex: 0, + pageNumber: 1, + totalPages: 1, + pageSize: 20 }; - $scope.next = function () { - if ($scope.options.pageNumber < $scope.pageCount) { - $scope.options.pageNumber++; - $scope.currentPage++; - $scope.load(); - } - }; + function activate() { + $scope.search(); + } - $scope.goToPage = function (pageNumber) { - $scope.options.pageNumber = pageNumber + 1; - $scope.currentPage = pageNumber; - $scope.load(); - }; - - $scope.prev = function () { - if ($scope.options.pageNumber > 1) { - $scope.options.pageNumber--; - $scope.currentPage--; - $scope.load(); - } + $scope.goToPage = function(pageNumber) { + $scope.pagination.pageIndex = pageNumber - 1; + $scope.pagination.pageNumber = pageNumber; + $scope.search(); }; $scope.search = function () { - var searchTerm = $scope.searchTerm; + + $scope.dashboard.loading = true; + + var searchTerm = $scope.dashboard.searchTerm; if (searchTerm === undefined) { searchTerm = ""; } - $http.get("backoffice/api/RedirectUrlManagement/SearchRedirectUrls/?searchTerm=" + searchTerm + "&page=" + $scope.currentPage + "&pageSize=" + $scope.options.pageSize).then(function (response) { - var matchingItems = response.data; - $scope.isSearch = true; - $scope.StatusMessage = matchingItems.StatusMessage; - $scope.hasResults = matchingItems.HasSearchResults; - $scope.redirectUrls = matchingItems.SearchResults; + $http.get("backoffice/api/RedirectUrlManagement/SearchRedirectUrls/?searchTerm=" + searchTerm + "&page=" + $scope.pagination.pageIndex + "&pageSize=" + $scope.pagination.pageSize).then(function (response) { - $scope.urlTrackerDisabled = matchingItems.UrlTrackerDisabled; - $scope.action = ""; - if ($scope.urlTrackerDisabled !== true) { - $scope.action = "Disable"; - } else { - $scope.action = "Enable"; - } + console.log(response); - $scope.pageCount = matchingItems.PageCount; - $scope.totalCount = matchingItems.TotalCount; - $scope.currentPage = matchingItems.CurrentPage; - $scope.options.pageNumber = matchingItems.CurrentPage + 1; - - if ($scope.options.pageNumber > $scope.pageCount) { - $scope.options.pageNumber = $scope.pageCount; - } + $scope.redirectUrls = response.data.SearchResults; - $scope.pagination = []; + // update pagination + $scope.pagination.pageIndex = response.data.CurrentPage; + $scope.pagination.pageNumber = response.data.CurrentPage + 1; + $scope.pagination.totalPages = response.data.PageCount; - var i; - if ($scope.pageCount <= 10) { - for (i = 0; i < $scope.pageCount; i++) { - $scope.pagination.push({ - val: (i + 1), - isActive: $scope.options.pageNumber === (i + 1) - }); - } - } else { - //if there is more than 10 pages, we need to do some fancy bits + // Set enable/disable state for url tracker + $scope.dashboard.UrlTrackerDisabled = response.data.UrlTrackerDisabled; - //get the max index to start - var maxIndex = $scope.pageCount - 10; - //set the start, but it can't be below zero - var start = Math.max($scope.options.pageNumber - 5, 0); - //ensure that it's not too far either - start = Math.min(maxIndex, start); - - for (i = start; i < (10 + start) ; i++) { - $scope.pagination.push({ - val: (i + 1), - isActive: $scope.options.pageNumber === (i + 1) - }); - } - - //now, if the start is greater than 0 then '1' will not be displayed, so do the elipses thing - if (start > 0) { - $scope.pagination.unshift({ name: "First", val: 1, isActive: false }, { val: "...", isActive: false }); - } - - //same for the end - if (start < maxIndex) { - $scope.pagination.push({ val: "...", isActive: false }, { name: "Last", val: $scope.pageCount, isActive: false }); - } - } - - angular.forEach($scope.redirectUrls, function (item) { + angular.forEach($scope.redirectUrls, function (item) { $http.get("backoffice/api/RedirectUrlManagement/GetPublishedUrl/?id=" + item.ContentId).then(function (response) { item.ContentUrl = response.data; - }); + }); }); - }); - }; - $scope.load = function () { - // $scope.searchTerm = ""; - $scope.search(); + $scope.dashboard.loading = false; + + }); }; $scope.removeRedirect = function (redirectToDelete) { $http.post("backoffice/api/RedirectUrlManagement/DeleteRedirectUrl/" + redirectToDelete.Id).then(function (response) { if (response.status === 200) { - notificationsService.success("Redirect Url Removed!", "Redirect Url " + redirectToDelete.Url + " has been deleted"); - // now remove from table client sides - var index = -1; - var urlArr = eval($scope.redirectUrls); - for (var i = 0; i < urlArr.length; i++) { - if (urlArr[i].Id === redirectToDelete.Id) { - index = i; - break; - } - } - if (index === -1) { - notificationsService.warning("Redirect Url Removal Error!", "Redirect Url " + redirectToDelete.Url + " may have already been removed"); - } + + var index = $scope.redirectUrls.indexOf(redirectToDelete); $scope.redirectUrls.splice(index, 1); + + notificationsService.success("Redirect Url Removed!", "Redirect Url " + redirectToDelete.Url + " has been deleted"); } else { notificationsService.warning("Redirect Url Error!", "Redirect Url " + redirectToDelete.Url + " was not deleted"); - } - }); + } + }); }; - $scope.toggleUrlTracker = function () { - var toggleConfirm = confirm("Are you sure you want to " + $scope.action.toLowerCase() + " the URL tracker?"); + $scope.disableUrlTracker = function () { + var toggleConfirm = confirm("Are you sure you want to disable the URL tracker?"); if (toggleConfirm) { - $http.post("backoffice/api/RedirectUrlManagement/ToggleUrlTracker/?disable=" + (!$scope.urlTrackerDisabled)).then(function (response) { - if (response.status === 200) { - notificationsService.success("URL Tracker has now been " + $scope.action.toLowerCase() + "d."); - - $scope.load(); - } else { - notificationsService.warning("Error " + $scope.action.toLowerCase() + "ing the URL Tracker, more information can be found in your log file."); - } - }); + $http.post("backoffice/api/RedirectUrlManagement/ToggleUrlTracker/?disable=true").then(function (response) { + if (response.status === 200) { + notificationsService.success("URL Tracker has now been disabled"); + activate(); + } else { + notificationsService.warning("Error disabling the URL Tracker, more information can be found in your log file."); + } + }); } }; - $scope.load(); -}); \ No newline at end of file + $scope.enableUrlTracker = function () { + if (toggleConfirm) { + $http.post("backoffice/api/RedirectUrlManagement/ToggleUrlTracker/?disable=false").then(function (response) { + if (response.status === 200) { + notificationsService.success("URL Tracker has now been enabled"); + activate(); + } else { + notificationsService.warning("Error enabling the URL Tracker, more information can be found in your log file."); + } + }); + } + }; + + var filterDebounced = _.debounce(function(e) { + + $scope.$apply(function () { + + //a canceler exists, so perform the cancelation operation and reset + if (canceler) { + canceler.resolve(); + canceler = $q.defer(); + } + else { + canceler = $q.defer(); + } + + $scope.search(); + + }); + + }, 200); + + $scope.filter = function() { + filterDebounced(); + }; + + activate(); + +}); diff --git a/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.html b/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.html index dcc3c01b90..8c4a342aaa 100644 --- a/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.html +++ b/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.html @@ -1,73 +1,98 @@
-
- -
+ -

Redirect Url Management

-

When you move and rename pages in Umbraco, 301 permanent redirects are automatically created

-

Here is a list of the redirects you

+ -
-
- -
- + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+
Original Url
+
Redirected To
+
Date Created
+
+ +
+ +
+ +
+ +
+ + + + + +
+ {{redirectUrl.CreateDateUtc | date:'medium'}} +
+ +
+ Edit + +
+ +
+ +
+
-
-
- - - +
+ + +
- - - - - - - - - - - - - - - -
Original UrlRedirected ToDate CreatedRemove
{{redirectUrl.Url}}{{redirectUrl.ContentUrl}} {{redirectUrl.CreateDateUtc | date:'medium'}}
-
-
- - -
- From 1f8dc9a42463e04be9ecd4f63d5b11601c97696f Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 5 Aug 2016 12:36:10 +0200 Subject: [PATCH 11/23] move dashboard from App_Plugins to dashboards folder --- .../developer/redirecturls.controller.js} | 30 ++++++++---------- .../dashboard/developer/redirecturls.html} | 2 +- .../RedirectUrlDashboard/package.manifest | Bin 336 -> 0 bytes src/Umbraco.Web.UI/config/Dashboard.config | 2 +- 4 files changed, 16 insertions(+), 18 deletions(-) rename src/{Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.controller.js => Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.controller.js} (82%) rename src/{Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.html => Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html} (97%) delete mode 100644 src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/package.manifest diff --git a/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.controller.js b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.controller.js similarity index 82% rename from src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.controller.js rename to src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.controller.js index 51d50eebd6..0bf6c60427 100644 --- a/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.controller.js @@ -1,4 +1,4 @@ -angular.module("umbraco").controller("Umbraco.RedirectUrlSearch", function ($scope, $http, angularHelper, notificationsService, entityResource, $routeParams, $q) { +angular.module("umbraco").controller("Umbraco.Dashboard.RedirectUrlsController", function($scope, $http, angularHelper, notificationsService, entityResource, $routeParams, $q) { //...todo //search by url or url part //search by domain @@ -30,7 +30,7 @@ angular.module("umbraco").controller("Umbraco.RedirectUrlSearch", function ($sco $scope.search(); }; - $scope.search = function () { + $scope.search = function() { $scope.dashboard.loading = true; @@ -39,7 +39,7 @@ angular.module("umbraco").controller("Umbraco.RedirectUrlSearch", function ($sco searchTerm = ""; } - $http.get("backoffice/api/RedirectUrlManagement/SearchRedirectUrls/?searchTerm=" + searchTerm + "&page=" + $scope.pagination.pageIndex + "&pageSize=" + $scope.pagination.pageSize).then(function (response) { + $http.get("backoffice/api/RedirectUrlManagement/SearchRedirectUrls/?searchTerm=" + searchTerm + "&page=" + $scope.pagination.pageIndex + "&pageSize=" + $scope.pagination.pageSize).then(function(response) { console.log(response); @@ -53,8 +53,8 @@ angular.module("umbraco").controller("Umbraco.RedirectUrlSearch", function ($sco // Set enable/disable state for url tracker $scope.dashboard.UrlTrackerDisabled = response.data.UrlTrackerDisabled; - angular.forEach($scope.redirectUrls, function (item) { - $http.get("backoffice/api/RedirectUrlManagement/GetPublishedUrl/?id=" + item.ContentId).then(function (response) { + angular.forEach($scope.redirectUrls, function(item) { + $http.get("backoffice/api/RedirectUrlManagement/GetPublishedUrl/?id=" + item.ContentId).then(function(response) { item.ContentUrl = response.data; }); }); @@ -64,25 +64,24 @@ angular.module("umbraco").controller("Umbraco.RedirectUrlSearch", function ($sco }); }; - $scope.removeRedirect = function (redirectToDelete) { - $http.post("backoffice/api/RedirectUrlManagement/DeleteRedirectUrl/" + redirectToDelete.Id).then(function (response) { + $scope.removeRedirect = function(redirectToDelete) { + $http.post("backoffice/api/RedirectUrlManagement/DeleteRedirectUrl/" + redirectToDelete.Id).then(function(response) { if (response.status === 200) { var index = $scope.redirectUrls.indexOf(redirectToDelete); $scope.redirectUrls.splice(index, 1); notificationsService.success("Redirect Url Removed!", "Redirect Url " + redirectToDelete.Url + " has been deleted"); - } - else { + } else { notificationsService.warning("Redirect Url Error!", "Redirect Url " + redirectToDelete.Url + " was not deleted"); } }); }; - $scope.disableUrlTracker = function () { + $scope.disableUrlTracker = function() { var toggleConfirm = confirm("Are you sure you want to disable the URL tracker?"); if (toggleConfirm) { - $http.post("backoffice/api/RedirectUrlManagement/ToggleUrlTracker/?disable=true").then(function (response) { + $http.post("backoffice/api/RedirectUrlManagement/ToggleUrlTracker/?disable=true").then(function(response) { if (response.status === 200) { notificationsService.success("URL Tracker has now been disabled"); activate(); @@ -93,9 +92,9 @@ angular.module("umbraco").controller("Umbraco.RedirectUrlSearch", function ($sco } }; - $scope.enableUrlTracker = function () { + $scope.enableUrlTracker = function() { if (toggleConfirm) { - $http.post("backoffice/api/RedirectUrlManagement/ToggleUrlTracker/?disable=false").then(function (response) { + $http.post("backoffice/api/RedirectUrlManagement/ToggleUrlTracker/?disable=false").then(function(response) { if (response.status === 200) { notificationsService.success("URL Tracker has now been enabled"); activate(); @@ -108,14 +107,13 @@ angular.module("umbraco").controller("Umbraco.RedirectUrlSearch", function ($sco var filterDebounced = _.debounce(function(e) { - $scope.$apply(function () { + $scope.$apply(function() { //a canceler exists, so perform the cancelation operation and reset if (canceler) { canceler.resolve(); canceler = $q.defer(); - } - else { + } else { canceler = $q.defer(); } diff --git a/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.html b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html similarity index 97% rename from src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.html rename to src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html index 8c4a342aaa..26c2ad7e2d 100644 --- a/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/redirecturlsearch.html +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html @@ -1,4 +1,4 @@ -
+
diff --git a/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/package.manifest b/src/Umbraco.Web.UI/App_Plugins/RedirectUrlDashboard/package.manifest deleted file mode 100644 index 996d847a970ac78a86a2bf8587df2fe0e4afc821..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 336 zcmaKo%?g505QV?3LGK`!mQnk5K@Si`tB^3QEKEhSP1K`XXD$Vgp-;26=6ka6Hjta_%tW6GRL*N!DQEho+tBB!1zR2`*gxUuf3CtTDkMLNdb!yGQ! zd)I9~wUm`q=Cl10#=QPGuH=+TSL>ZfyU|z9!f(vj%P&?Z)dnN_Wb4UBT_fx-Cwf}G io9a?qa?NUWEw}S|>|_F>Uj9Tgn}+^ueyJl*KluP=xHyXd diff --git a/src/Umbraco.Web.UI/config/Dashboard.config b/src/Umbraco.Web.UI/config/Dashboard.config index cc20f70654..9eb808c67c 100644 --- a/src/Umbraco.Web.UI/config/Dashboard.config +++ b/src/Umbraco.Web.UI/config/Dashboard.config @@ -115,7 +115,7 @@ - /App_Plugins/RedirectUrlDashboard/redirecturlsearch.html + views/dashboard/developer/redirecturls.html From b8b30bdc6ed97d18363c13ddb1beec5b895e79ca Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 5 Aug 2016 14:35:58 +0200 Subject: [PATCH 12/23] make resource for all redirect url end points --- .../common/resources/redirecturls.resource.js | 127 ++++++++++++++++++ .../developer/redirecturls.controller.js | 72 +++++----- 2 files changed, 162 insertions(+), 37 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/common/resources/redirecturls.resource.js diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/redirecturls.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/redirecturls.resource.js new file mode 100644 index 0000000000..f79c773eea --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/common/resources/redirecturls.resource.js @@ -0,0 +1,127 @@ +/** + * @ngdoc service + * @name umbraco.resources.redirectUrlResource + * @function + * + * @description + * Used by the redirect url dashboard to get urls and send requests to remove redirects. + */ +(function() { + 'use strict'; + + function redirectUrlsResource($http, umbRequestHelper) { + + var redirectBaseUrl = "backoffice/api/RedirectUrlManagement/"; + + /** + * @ngdoc function + * @name umbraco.resources.redirectUrlResource#searchRedirectUrls + * @methodOf umbraco.resources.redirectUrlResource + * @function + * + * @description + * Called to search redirects + * ##usage + *
+         * redirectUrlsResource.searchRedirectUrls("", 0, 20)
+         *    .then(function(response) {
+         *
+         *    });
+         * 
+ * @param {String} searchTerm Searh term + * @param {Int} pageIndex index of the page to retrive items from + * @param {Int} pageSize The number of items on a page + */ + function searchRedirectUrls(searchTerm, pageIndex, pageSize) { + return umbRequestHelper.resourcePromise( + $http.get(redirectBaseUrl + "SearchRedirectUrls/?searchTerm=" + searchTerm + "&page=" + pageIndex + "&pageSize=" + pageSize), + "Failed to retrieve redirects" + ); + } + + /** + * @ngdoc function + * @name umbraco.resources.redirectUrlResource#deleteRedirectUrl + * @methodOf umbraco.resources.redirectUrlResource + * @function + * + * @description + * Called to delete a redirect + * ##usage + *
+         * redirectUrlsResource.deleteRedirectUrl(1234)
+         *    .then(function() {
+         *
+         *    });
+         * 
+ * @param {Int} id Id of the redirect + */ + function deleteRedirectUrl(id) { + return umbRequestHelper.resourcePromise( + $http.post(redirectBaseUrl + "DeleteRedirectUrl/" + id), + "Failed to remove redirect" + ); + } + + /** + * @ngdoc function + * @name umbraco.resources.redirectUrlResource#toggleUrlTracker + * @methodOf umbraco.resources.redirectUrlResource + * @function + * + * @description + * Called to enable or disable redirect url tracker + * ##usage + *
+         * redirectUrlsResource.toggleUrlTracker(true)
+         *    .then(function() {
+         *
+         *    });
+         * 
+ * @param {Bool} disable true/false to disable/enable the url tracker + */ + function toggleUrlTracker(disable) { + return umbRequestHelper.resourcePromise( + $http.post(redirectBaseUrl + "ToggleUrlTracker/?disable=" + disable), + "Failed to toggle redirect url tracker" + ); + } + + /** + * @ngdoc function + * @name umbraco.resources.redirectUrlResource#getPublishedUrl + * @methodOf umbraco.resources.redirectUrlResource + * @function + * + * @description + * Called to get the published url for a content item + * ##usage + *
+         * redirectUrlsResource.getPublishedUrl(1234)
+         *    .then(function() {
+         *
+         *    });
+         * 
+ * @param {Int} contentId The content id of the item to get the published url + */ + function getPublishedUrl(contentId) { + return umbRequestHelper.resourcePromise( + $http.get(redirectBaseUrl + "GetPublishedUrl/?id=" + contentId), + "Failed to get published url" + ); + } + + var resource = { + searchRedirectUrls: searchRedirectUrls, + deleteRedirectUrl: deleteRedirectUrl, + toggleUrlTracker: toggleUrlTracker, + getPublishedUrl: getPublishedUrl + }; + + return resource; + + } + + angular.module('umbraco.resources').factory('redirectUrlsResource', redirectUrlsResource); + +})(); diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.controller.js b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.controller.js index 0bf6c60427..439ecb08bd 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.controller.js @@ -1,4 +1,4 @@ -angular.module("umbraco").controller("Umbraco.Dashboard.RedirectUrlsController", function($scope, $http, angularHelper, notificationsService, entityResource, $routeParams, $q) { +angular.module("umbraco").controller("Umbraco.Dashboard.RedirectUrlsController", function($scope, redirectUrlsResource, notificationsService, $q) { //...todo //search by url or url part //search by domain @@ -39,23 +39,23 @@ angular.module("umbraco").controller("Umbraco.Dashboard.RedirectUrlsController", searchTerm = ""; } - $http.get("backoffice/api/RedirectUrlManagement/SearchRedirectUrls/?searchTerm=" + searchTerm + "&page=" + $scope.pagination.pageIndex + "&pageSize=" + $scope.pagination.pageSize).then(function(response) { + redirectUrlsResource.searchRedirectUrls(searchTerm, $scope.pagination.pageIndex, $scope.pagination.pageSize).then(function(response) { - console.log(response); - - $scope.redirectUrls = response.data.SearchResults; + $scope.redirectUrls = response.SearchResults; // update pagination - $scope.pagination.pageIndex = response.data.CurrentPage; - $scope.pagination.pageNumber = response.data.CurrentPage + 1; - $scope.pagination.totalPages = response.data.PageCount; + $scope.pagination.pageIndex = response.CurrentPage; + $scope.pagination.pageNumber = response.CurrentPage + 1; + $scope.pagination.totalPages = response.PageCount; // Set enable/disable state for url tracker - $scope.dashboard.UrlTrackerDisabled = response.data.UrlTrackerDisabled; + $scope.dashboard.UrlTrackerDisabled = response.UrlTrackerDisabled; - angular.forEach($scope.redirectUrls, function(item) { - $http.get("backoffice/api/RedirectUrlManagement/GetPublishedUrl/?id=" + item.ContentId).then(function(response) { - item.ContentUrl = response.data; + angular.forEach($scope.redirectUrls, function(redirect) { + redirectUrlsResource.getPublishedUrl(redirect.ContentId).then(function(response) { + redirect.ContentUrl = response; + }, function(error) { + notificationsService.error("Redirect Url Error!", "Failed to get published url for " + redirect.Url); }); }); @@ -65,44 +65,42 @@ angular.module("umbraco").controller("Umbraco.Dashboard.RedirectUrlsController", }; $scope.removeRedirect = function(redirectToDelete) { - $http.post("backoffice/api/RedirectUrlManagement/DeleteRedirectUrl/" + redirectToDelete.Id).then(function(response) { - if (response.status === 200) { - var index = $scope.redirectUrls.indexOf(redirectToDelete); - $scope.redirectUrls.splice(index, 1); + redirectUrlsResource.deleteRedirectUrl(redirectToDelete.Id).then(function() { + + var index = $scope.redirectUrls.indexOf(redirectToDelete); + $scope.redirectUrls.splice(index, 1); + notificationsService.success("Redirect Url Removed!", "Redirect Url " + redirectToDelete.Url + " has been deleted"); + + }, function(error) { + + notificationsService.error("Redirect Url Error!", "Redirect Url " + redirectToDelete.Url + " was not deleted"); - notificationsService.success("Redirect Url Removed!", "Redirect Url " + redirectToDelete.Url + " has been deleted"); - } else { - notificationsService.warning("Redirect Url Error!", "Redirect Url " + redirectToDelete.Url + " was not deleted"); - } }); + }; $scope.disableUrlTracker = function() { var toggleConfirm = confirm("Are you sure you want to disable the URL tracker?"); if (toggleConfirm) { - $http.post("backoffice/api/RedirectUrlManagement/ToggleUrlTracker/?disable=true").then(function(response) { - if (response.status === 200) { - notificationsService.success("URL Tracker has now been disabled"); - activate(); - } else { - notificationsService.warning("Error disabling the URL Tracker, more information can be found in your log file."); - } + + redirectUrlsResource.toggleUrlTracker(true).then(function() { + activate(); + notificationsService.success("URL Tracker has now been disabled"); + }, function(error) { + notificationsService.warning("Error disabling the URL Tracker, more information can be found in your log file."); }); + } }; $scope.enableUrlTracker = function() { - if (toggleConfirm) { - $http.post("backoffice/api/RedirectUrlManagement/ToggleUrlTracker/?disable=false").then(function(response) { - if (response.status === 200) { - notificationsService.success("URL Tracker has now been enabled"); - activate(); - } else { - notificationsService.warning("Error enabling the URL Tracker, more information can be found in your log file."); - } - }); - } + redirectUrlsResource.toggleUrlTracker(false).then(function() { + activate(); + notificationsService.success("URL Tracker has now been enabled"); + }, function(error) { + notificationsService.warning("Error enabling the URL Tracker, more information can be found in your log file."); + }); }; var filterDebounced = _.debounce(function(e) { From 19325ac52230cfd132ff666bc290274bfe2131c6 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Fri, 5 Aug 2016 14:44:37 +0200 Subject: [PATCH 13/23] Fixes the build --- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 7ec05f3265..51c3f4b053 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -578,8 +578,6 @@ - - @@ -639,7 +637,6 @@ - 404handlers.config From aa66fd6e335b9e71e4116880e5fe020f4da33e67 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 5 Aug 2016 16:59:03 +0200 Subject: [PATCH 14/23] rewrite controller as vm + refactor controller to follow angular style guide --- .../developer/redirecturls.controller.js | 236 ++++++++++-------- .../dashboard/developer/redirecturls.html | 32 +-- 2 files changed, 141 insertions(+), 127 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.controller.js b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.controller.js index 439ecb08bd..7cc3baca00 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.controller.js @@ -1,130 +1,144 @@ -angular.module("umbraco").controller("Umbraco.Dashboard.RedirectUrlsController", function($scope, redirectUrlsResource, notificationsService, $q) { - //...todo - //search by url or url part - //search by domain - //display domain in dashboard results? +(function() { + "use strict"; - //used to cancel any request in progress if another one needs to take it's place - var canceler = null; + function RedirectUrlsController($scope, redirectUrlsResource, notificationsService, $q) { + //...todo + //search by url or url part + //search by domain + //display domain in dashboard results? - $scope.dashboard = { - searchTerm: "", - loading: false, - UrlTrackerDisabled: false - }; + //used to cancel any request in progress if another one needs to take it's place + var vm = this; + var canceler = null; - $scope.pagination = { - pageIndex: 0, - pageNumber: 1, - totalPages: 1, - pageSize: 20 - }; + vm.dashboard = { + searchTerm: "", + loading: false, + UrlTrackerDisabled: false + }; - function activate() { - $scope.search(); - } + vm.pagination = { + pageIndex: 0, + pageNumber: 1, + totalPages: 1, + pageSize: 20 + }; - $scope.goToPage = function(pageNumber) { - $scope.pagination.pageIndex = pageNumber - 1; - $scope.pagination.pageNumber = pageNumber; - $scope.search(); - }; + vm.goToPage = goToPage; + vm.search = search; + vm.removeRedirect = removeRedirect; + vm.disableUrlTracker = disableUrlTracker; + vm.enableUrlTracker = enableUrlTracker; + vm.filter = filter; - $scope.search = function() { - - $scope.dashboard.loading = true; - - var searchTerm = $scope.dashboard.searchTerm; - if (searchTerm === undefined) { - searchTerm = ""; + function activate() { + vm.search(); } - redirectUrlsResource.searchRedirectUrls(searchTerm, $scope.pagination.pageIndex, $scope.pagination.pageSize).then(function(response) { - - $scope.redirectUrls = response.SearchResults; - - // update pagination - $scope.pagination.pageIndex = response.CurrentPage; - $scope.pagination.pageNumber = response.CurrentPage + 1; - $scope.pagination.totalPages = response.PageCount; - - // Set enable/disable state for url tracker - $scope.dashboard.UrlTrackerDisabled = response.UrlTrackerDisabled; - - angular.forEach($scope.redirectUrls, function(redirect) { - redirectUrlsResource.getPublishedUrl(redirect.ContentId).then(function(response) { - redirect.ContentUrl = response; - }, function(error) { - notificationsService.error("Redirect Url Error!", "Failed to get published url for " + redirect.Url); - }); - }); - - $scope.dashboard.loading = false; - - }); - }; - - $scope.removeRedirect = function(redirectToDelete) { - - redirectUrlsResource.deleteRedirectUrl(redirectToDelete.Id).then(function() { - - var index = $scope.redirectUrls.indexOf(redirectToDelete); - $scope.redirectUrls.splice(index, 1); - notificationsService.success("Redirect Url Removed!", "Redirect Url " + redirectToDelete.Url + " has been deleted"); - - }, function(error) { - - notificationsService.error("Redirect Url Error!", "Redirect Url " + redirectToDelete.Url + " was not deleted"); - - }); - - }; - - $scope.disableUrlTracker = function() { - var toggleConfirm = confirm("Are you sure you want to disable the URL tracker?"); - if (toggleConfirm) { - - redirectUrlsResource.toggleUrlTracker(true).then(function() { - activate(); - notificationsService.success("URL Tracker has now been disabled"); - }, function(error) { - notificationsService.warning("Error disabling the URL Tracker, more information can be found in your log file."); - }); - + function goToPage(pageNumber) { + vm.pagination.pageIndex = pageNumber - 1; + vm.pagination.pageNumber = pageNumber; + vm.search(); } - }; - $scope.enableUrlTracker = function() { - redirectUrlsResource.toggleUrlTracker(false).then(function() { - activate(); - notificationsService.success("URL Tracker has now been enabled"); - }, function(error) { - notificationsService.warning("Error enabling the URL Tracker, more information can be found in your log file."); - }); - }; + function search() { - var filterDebounced = _.debounce(function(e) { + vm.dashboard.loading = true; - $scope.$apply(function() { - - //a canceler exists, so perform the cancelation operation and reset - if (canceler) { - canceler.resolve(); - canceler = $q.defer(); - } else { - canceler = $q.defer(); + var searchTerm = vm.dashboard.searchTerm; + if (searchTerm === undefined) { + searchTerm = ""; } - $scope.search(); + redirectUrlsResource.searchRedirectUrls(searchTerm, vm.pagination.pageIndex, vm.pagination.pageSize).then(function(response) { - }); + vm.redirectUrls = response.SearchResults; - }, 200); + // update pagination + vm.pagination.pageIndex = response.CurrentPage; + vm.pagination.pageNumber = response.CurrentPage + 1; + vm.pagination.totalPages = response.PageCount; - $scope.filter = function() { - filterDebounced(); - }; + // Set enable/disable state for url tracker + vm.dashboard.UrlTrackerDisabled = response.UrlTrackerDisabled; - activate(); + angular.forEach(vm.redirectUrls, function(redirect) { + redirectUrlsResource.getPublishedUrl(redirect.ContentId).then(function(response) { + redirect.ContentUrl = response; + }, function(error) { + notificationsService.error("Redirect Url Error!", "Failed to get published url for " + redirect.Url); + }); + }); -}); + vm.dashboard.loading = false; + + }); + } + + function removeRedirect(redirectToDelete) { + + redirectUrlsResource.deleteRedirectUrl(redirectToDelete.Id).then(function() { + + var index = vm.redirectUrls.indexOf(redirectToDelete); + vm.redirectUrls.splice(index, 1); + notificationsService.success("Redirect Url Removed!", "Redirect Url " + redirectToDelete.Url + " has been deleted"); + + }, function(error) { + + notificationsService.error("Redirect Url Error!", "Redirect Url " + redirectToDelete.Url + " was not deleted"); + + }); + + } + + function disableUrlTracker() { + var toggleConfirm = confirm("Are you sure you want to disable the URL tracker?"); + if (toggleConfirm) { + + redirectUrlsResource.toggleUrlTracker(true).then(function() { + activate(); + notificationsService.success("URL Tracker has now been disabled"); + }, function(error) { + notificationsService.warning("Error disabling the URL Tracker, more information can be found in your log file."); + }); + + } + } + + function enableUrlTracker() { + redirectUrlsResource.toggleUrlTracker(false).then(function() { + activate(); + notificationsService.success("URL Tracker has now been enabled"); + }, function(error) { + notificationsService.warning("Error enabling the URL Tracker, more information can be found in your log file."); + }); + } + + var filterDebounced = _.debounce(function(e) { + + $scope.$apply(function() { + + //a canceler exists, so perform the cancelation operation and reset + if (canceler) { + canceler.resolve(); + canceler = $q.defer(); + } else { + canceler = $q.defer(); + } + + vm.search(); + + }); + + }, 200); + + function filter() { + filterDebounced(); + } + + activate(); + + } + + angular.module("umbraco").controller("Umbraco.Dashboard.RedirectUrlsController", RedirectUrlsController); +})(); diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html index 26c2ad7e2d..ebd007cb1a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html @@ -1,6 +1,6 @@ -
+
- + @@ -9,18 +9,18 @@ @@ -30,8 +30,8 @@ @@ -55,7 +55,7 @@
-
+
@@ -75,7 +75,7 @@
Edit - +
@@ -86,12 +86,12 @@
+ ng-if="vm.pagination.totalPages > 1 && !vm.dashboard.loading" + page-number="vm.pagination.pageNumber" + total-pages="vm.pagination.totalPages" + on-next="vm.goToPage" + on-prev="vm.goToPage" + on-go-to-page="vm.goToPage">
From a28c52aa167c2b13a14a034d58985cd930d05a93 Mon Sep 17 00:00:00 2001 From: Simon Busborg Date: Mon, 8 Aug 2016 09:36:10 +0200 Subject: [PATCH 15/23] Added styling to url list --- .../src/less/components/umb-packages.less | 5 +++ .../src/less/components/umb-table.less | 31 +++++++++++++++++++ .../dashboard/developer/redirecturls.html | 16 +++++----- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-packages.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-packages.less index cfbf425bef..f14df918c0 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-packages.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-packages.less @@ -331,6 +331,11 @@ width: 100%; } +.umb-era-button.umb-button--s { + height: 30px; + font-size: 13px; +} + /* CATEGORIES */ diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-table.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-table.less index 874f9e9551..415ccefff0 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-table.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-table.less @@ -3,6 +3,8 @@ display: flex; flex-direction: column; + position: relative; + border: 1px solid @grayLight; flex-wrap: nowrap; @@ -11,6 +13,25 @@ min-width: 640px; } +.umb-table.umb-table-inactive { + + &:before { + content: ""; + background: rgba(255, 255, 255, 0.8); + + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + + z-index: 10; + + outline: 1px solid rgba(255, 255, 255, 0.8); + } + +} + .umb-table a { text-decoration: none; cursor: pointer; @@ -93,6 +114,14 @@ input.umb-table__input { } } +.umb-table-body .umb-table-row.-solid { + cursor: default; + + &:hover { + background-color: white; + } +} + .umb-table-body__link { text-decoration: none; @@ -183,6 +212,8 @@ input.umb-table__input { user-select: none; } + + .umb-table-row.-selected, .umb-table-row.-selected:hover { background-color: fade(@blueDark, 4%); diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html index ebd007cb1a..a9ddeb1e88 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html @@ -11,7 +11,7 @@ @@ -19,7 +19,7 @@ @@ -55,27 +55,27 @@
-
+
{{redirectUrl.CreateDateUtc | date:'medium'}}
-
- Edit - +
+ Edit +
From 32d48b12d1bbe74945b2582b6301625ecc244b0a Mon Sep 17 00:00:00 2001 From: Simon Busborg Date: Mon, 8 Aug 2016 10:36:10 +0200 Subject: [PATCH 16/23] Changed button when inactive, added class to toggle when table in inactive --- .../src/less/components/umb-table.less | 6 +++--- .../src/views/dashboard/developer/redirecturls.html | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-table.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-table.less index 415ccefff0..219c15c7d5 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-table.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-table.less @@ -17,17 +17,17 @@ &:before { content: ""; - background: rgba(255, 255, 255, 0.8); + background: rgba(255, 255, 255, 0.75); position: absolute; top: 0; bottom: 0; left: 0; right: 0; - + z-index: 10; - outline: 1px solid rgba(255, 255, 255, 0.8); + outline: 1px solid rgba(255, 255, 255, 0.75); } } diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html index a9ddeb1e88..919394ca28 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html @@ -19,7 +19,7 @@ @@ -41,7 +41,7 @@ -
+
From 80d579891b059984e71114cfedfa60a134381acd Mon Sep 17 00:00:00 2001 From: Simon Busborg Date: Mon, 8 Aug 2016 11:33:56 +0200 Subject: [PATCH 17/23] Removes search when disabled --- .../src/views/dashboard/developer/redirecturls.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html index 919394ca28..f7fef60c8e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html @@ -26,9 +26,10 @@ - + Date: Mon, 8 Aug 2016 11:57:48 +0200 Subject: [PATCH 18/23] Fixes build and use Guid where necessary --- .../views/dashboard/developer/redirecturls.controller.js | 2 +- .../Redirects/RedirectUrlManagementController.cs | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.controller.js b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.controller.js index 7cc3baca00..61dbb2a709 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.controller.js @@ -77,7 +77,7 @@ function removeRedirect(redirectToDelete) { - redirectUrlsResource.deleteRedirectUrl(redirectToDelete.Id).then(function() { + redirectUrlsResource.deleteRedirectUrl(redirectToDelete.ContentKey).then(function () { var index = vm.redirectUrls.indexOf(redirectToDelete); vm.redirectUrls.splice(index, 1); diff --git a/src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs b/src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs index a147d859e0..47dd8c5eff 100644 --- a/src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs +++ b/src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs @@ -1,9 +1,11 @@ -using System.Net.Http; +using System; +using System.Net.Http; using System.Text; using System.Web; using System.Web.Http; using System.Xml; using Umbraco.Core.Configuration; +using Umbraco.Core.Services; using Umbraco.Web.WebApi; using File = System.IO.File; @@ -46,7 +48,7 @@ namespace Umbraco.Web.Redirects } [HttpPost] - public IHttpActionResult DeleteRedirectUrl(int id) + public IHttpActionResult DeleteRedirectUrl(Guid id) { var redirectUrlService = Services.RedirectUrlService; redirectUrlService.Delete(id); From 4ff728b62a5b77b244905d2e9dca10635ea3c77b Mon Sep 17 00:00:00 2001 From: Simon Busborg Date: Mon, 8 Aug 2016 12:55:52 +0200 Subject: [PATCH 19/23] added target blank so it opens in another tab --- .../src/views/dashboard/developer/redirecturls.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html index f7fef60c8e..d6c878e1d5 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html @@ -63,11 +63,11 @@
From 69c952ddda60cbc2423f9f3cba943f3a101ddcf9 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Mon, 8 Aug 2016 13:10:02 +0200 Subject: [PATCH 20/23] Don't use HttpContext --- src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs b/src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs index 47dd8c5eff..30e539f3ec 100644 --- a/src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs +++ b/src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs @@ -2,6 +2,7 @@ using System.Net.Http; using System.Text; using System.Web; +using System.Web.Hosting; using System.Web.Http; using System.Xml; using Umbraco.Core.Configuration; @@ -58,7 +59,7 @@ namespace Umbraco.Web.Redirects [HttpPost] public IHttpActionResult ToggleUrlTracker(bool disable) { - var configFilePath = HttpContext.Current.Server.MapPath("~/config/umbracoSettings.config"); + var configFilePath = HostingEnvironment.MapPath("~/config/umbracoSettings.config"); var action = disable ? "disable" : "enable"; From c331ba134a033f3a8e62222c5ad20d627a956e0b Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 8 Aug 2016 14:40:53 +0200 Subject: [PATCH 21/23] Fixes 301 redirect js naming conventions, fixes URL handling, moves c# classes to the correct/constistent namespaces, fixes up models and N+1 requests, adds model mapping to not return the business logic model, adds controller method to check if it's enabled instead of returning the result as part of the search. --- .../common/resources/redirecturls.resource.js | 64 ++++++++----------- .../developer/redirecturls.controller.js | 36 +++++------ .../dashboard/developer/redirecturls.html | 16 ++--- .../Editors/BackOfficeController.cs | 4 ++ .../RedirectUrlManagementController.cs | 50 +++++++++------ .../ContentEditing/ContentRedirectUrl.cs | 24 +++++++ .../RedirectUrlSearchResults.cs | 28 ++++++++ .../Models/Mapping/DashboardModelsMapper.cs | 27 ++++++++ .../Models/Mapping/LogModelMapper.cs | 17 ----- .../Redirects/RedirectUrlSearchResults.cs | 18 ------ .../RedirectTrackingEventHandler.cs | 13 ++-- src/Umbraco.Web/Umbraco.Web.csproj | 9 +-- 12 files changed, 178 insertions(+), 128 deletions(-) rename src/Umbraco.Web/{Redirects => Editors}/RedirectUrlManagementController.cs (66%) create mode 100644 src/Umbraco.Web/Models/ContentEditing/ContentRedirectUrl.cs create mode 100644 src/Umbraco.Web/Models/ContentEditing/RedirectUrlSearchResults.cs create mode 100644 src/Umbraco.Web/Models/Mapping/DashboardModelsMapper.cs delete mode 100644 src/Umbraco.Web/Models/Mapping/LogModelMapper.cs delete mode 100644 src/Umbraco.Web/Redirects/RedirectUrlSearchResults.cs rename src/Umbraco.Web/{Redirects => Routing}/RedirectTrackingEventHandler.cs (99%) diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/redirecturls.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/redirecturls.resource.js index f79c773eea..936c934320 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/redirecturls.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/redirecturls.resource.js @@ -11,8 +11,6 @@ function redirectUrlsResource($http, umbRequestHelper) { - var redirectBaseUrl = "backoffice/api/RedirectUrlManagement/"; - /** * @ngdoc function * @name umbraco.resources.redirectUrlResource#searchRedirectUrls @@ -33,10 +31,24 @@ * @param {Int} pageSize The number of items on a page */ function searchRedirectUrls(searchTerm, pageIndex, pageSize) { + return umbRequestHelper.resourcePromise( - $http.get(redirectBaseUrl + "SearchRedirectUrls/?searchTerm=" + searchTerm + "&page=" + pageIndex + "&pageSize=" + pageSize), - "Failed to retrieve redirects" - ); + $http.get( + umbRequestHelper.getApiUrl( + "redirectUrlManagementApiBaseUrl", + "SearchRedirectUrls", + { searchTerm: searchTerm, pageIndex: pageIndex, pageSize: pageSize })), + 'Failed to retrieve data for searching redirect urls'); + } + + function isEnabled() { + + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "redirectUrlManagementApiBaseUrl", + "IsEnabled")), + 'Failed to retrieve data to check if the 301 redirect is enabled'); } /** @@ -58,9 +70,11 @@ */ function deleteRedirectUrl(id) { return umbRequestHelper.resourcePromise( - $http.post(redirectBaseUrl + "DeleteRedirectUrl/" + id), - "Failed to remove redirect" - ); + $http.post( + umbRequestHelper.getApiUrl( + "redirectUrlManagementApiBaseUrl", + "DeleteRedirectUrl", { id: id })), + 'Failed to remove redirect'); } /** @@ -82,40 +96,18 @@ */ function toggleUrlTracker(disable) { return umbRequestHelper.resourcePromise( - $http.post(redirectBaseUrl + "ToggleUrlTracker/?disable=" + disable), - "Failed to toggle redirect url tracker" - ); - } - - /** - * @ngdoc function - * @name umbraco.resources.redirectUrlResource#getPublishedUrl - * @methodOf umbraco.resources.redirectUrlResource - * @function - * - * @description - * Called to get the published url for a content item - * ##usage - *
-         * redirectUrlsResource.getPublishedUrl(1234)
-         *    .then(function() {
-         *
-         *    });
-         * 
- * @param {Int} contentId The content id of the item to get the published url - */ - function getPublishedUrl(contentId) { - return umbRequestHelper.resourcePromise( - $http.get(redirectBaseUrl + "GetPublishedUrl/?id=" + contentId), - "Failed to get published url" - ); + $http.post( + umbRequestHelper.getApiUrl( + "redirectUrlManagementApiBaseUrl", + "ToggleUrlTracker", { disable: disable })), + 'Failed to toggle redirect url tracker'); } var resource = { searchRedirectUrls: searchRedirectUrls, deleteRedirectUrl: deleteRedirectUrl, toggleUrlTracker: toggleUrlTracker, - getPublishedUrl: getPublishedUrl + isEnabled: isEnabled }; return resource; diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.controller.js b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.controller.js index 61dbb2a709..76ebc5ff4d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.controller.js @@ -14,7 +14,7 @@ vm.dashboard = { searchTerm: "", loading: false, - UrlTrackerDisabled: false + urlTrackerDisabled: false }; vm.pagination = { @@ -30,9 +30,20 @@ vm.disableUrlTracker = disableUrlTracker; vm.enableUrlTracker = enableUrlTracker; vm.filter = filter; + vm.checkEnabled = checkEnabled; - function activate() { - vm.search(); + function activate() { + vm.checkEnabled().then(function() { + vm.search(); + }); + } + + function checkEnabled() { + vm.dashboard.loading = true; + return redirectUrlsResource.isEnabled().then(function (response) { + vm.dashboard.urlTrackerDisabled = response !== "true"; + vm.dashboard.loading = false; + }); } function goToPage(pageNumber) { @@ -52,24 +63,13 @@ redirectUrlsResource.searchRedirectUrls(searchTerm, vm.pagination.pageIndex, vm.pagination.pageSize).then(function(response) { - vm.redirectUrls = response.SearchResults; + vm.redirectUrls = response.searchResults; // update pagination - vm.pagination.pageIndex = response.CurrentPage; - vm.pagination.pageNumber = response.CurrentPage + 1; + vm.pagination.pageIndex = response.currentPage; + vm.pagination.pageNumber = response.currentPage + 1; vm.pagination.totalPages = response.PageCount; - // Set enable/disable state for url tracker - vm.dashboard.UrlTrackerDisabled = response.UrlTrackerDisabled; - - angular.forEach(vm.redirectUrls, function(redirect) { - redirectUrlsResource.getPublishedUrl(redirect.ContentId).then(function(response) { - redirect.ContentUrl = response; - }, function(error) { - notificationsService.error("Redirect Url Error!", "Failed to get published url for " + redirect.Url); - }); - }); - vm.dashboard.loading = false; }); @@ -77,7 +77,7 @@ function removeRedirect(redirectToDelete) { - redirectUrlsResource.deleteRedirectUrl(redirectToDelete.ContentKey).then(function () { + redirectUrlsResource.deleteRedirectUrl(redirectToDelete.redirectId).then(function () { var index = vm.redirectUrls.indexOf(redirectToDelete); vm.redirectUrls.splice(index, 1); diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html index f7fef60c8e..b2a7aa81ff 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/redirecturls.html @@ -9,7 +9,7 @@
diff --git a/src/Umbraco.Web/Editors/BackOfficeController.cs b/src/Umbraco.Web/Editors/BackOfficeController.cs index ccc339b3f8..9049aafac2 100644 --- a/src/Umbraco.Web/Editors/BackOfficeController.cs +++ b/src/Umbraco.Web/Editors/BackOfficeController.cs @@ -224,6 +224,10 @@ namespace Umbraco.Web.Editors {"gridConfig", Url.Action("GetGridConfig", "BackOffice")}, {"serverVarsJs", Url.Action("Application", "BackOffice")}, //API URLs + { + "redirectUrlManagementApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl( + controller => controller.IsEnabled()) + }, { "embedApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl( controller => controller.GetEmbed("", 0, 0)) diff --git a/src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs b/src/Umbraco.Web/Editors/RedirectUrlManagementController.cs similarity index 66% rename from src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs rename to src/Umbraco.Web/Editors/RedirectUrlManagementController.cs index 47dd8c5eff..58d29ba656 100644 --- a/src/Umbraco.Web/Redirects/RedirectUrlManagementController.cs +++ b/src/Umbraco.Web/Editors/RedirectUrlManagementController.cs @@ -1,31 +1,50 @@ using System; -using System.Net.Http; -using System.Text; -using System.Web; using System.Web.Http; using System.Xml; +using System.Collections.Generic; +using System.Linq; +using AutoMapper; using Umbraco.Core.Configuration; -using Umbraco.Core.Services; +using Umbraco.Web.Models.ContentEditing; +using Umbraco.Web.Mvc; using Umbraco.Web.WebApi; using File = System.IO.File; -namespace Umbraco.Web.Redirects +namespace Umbraco.Web.Editors { + [PluginController("UmbracoApi")] public class RedirectUrlManagementController : UmbracoAuthorizedApiController { + + /// + /// Returns true/false of whether redirect tracking is enabled or not + /// + /// + [HttpGet] + public bool IsEnabled() + { + return UmbracoConfig.For.UmbracoSettings().WebRouting.DisableRedirectUrlTracking == false; + } + //add paging [HttpGet] public RedirectUrlSearchResult SearchRedirectUrls(string searchTerm, int page = 0, int pageSize = 10) { - var searchResult = new RedirectUrlSearchResult { UrlTrackerDisabled = UmbracoConfig.For.UmbracoSettings().WebRouting.DisableRedirectUrlTracking }; + var searchResult = new RedirectUrlSearchResult(); var redirectUrlService = Services.RedirectUrlService; - var resultCount = 0L; + long resultCount; var redirects = string.IsNullOrWhiteSpace(searchTerm) ? redirectUrlService.GetAllRedirectUrls(page, pageSize, out resultCount) : redirectUrlService.SearchRedirectUrls(searchTerm, page, pageSize, out resultCount); - searchResult.SearchResults = redirects; + searchResult.SearchResults = Mapper.Map>(redirects).ToArray(); + //now map the Content/published url + foreach (var result in searchResult.SearchResults) + { + result.DestinationUrl = result.ContentId > 0 ? Umbraco.Url(result.ContentId) : "#"; + } + searchResult.TotalCount = resultCount; searchResult.CurrentPage = page; searchResult.PageCount = ((int)resultCount + pageSize - 1) / pageSize; @@ -36,17 +55,6 @@ namespace Umbraco.Web.Redirects } - [HttpGet] - public HttpResponseMessage GetPublishedUrl(int id) - { - var publishedUrl = "#"; - if (id > 0) - publishedUrl = Umbraco.Url(id); - - return new HttpResponseMessage { Content = new StringContent(publishedUrl, Encoding.UTF8, "text/html") }; - - } - [HttpPost] public IHttpActionResult DeleteRedirectUrl(Guid id) { @@ -58,7 +66,9 @@ namespace Umbraco.Web.Redirects [HttpPost] public IHttpActionResult ToggleUrlTracker(bool disable) { - var configFilePath = HttpContext.Current.Server.MapPath("~/config/umbracoSettings.config"); + var httpContext = TryGetHttpContext(); + if (httpContext.Success == false) throw new InvalidOperationException("Cannot acquire HttpContext"); + var configFilePath = httpContext.Result.Server.MapPath("~/config/umbracoSettings.config"); var action = disable ? "disable" : "enable"; diff --git a/src/Umbraco.Web/Models/ContentEditing/ContentRedirectUrl.cs b/src/Umbraco.Web/Models/ContentEditing/ContentRedirectUrl.cs new file mode 100644 index 0000000000..38fdb265b8 --- /dev/null +++ b/src/Umbraco.Web/Models/ContentEditing/ContentRedirectUrl.cs @@ -0,0 +1,24 @@ +using System; +using System.Runtime.Serialization; + +namespace Umbraco.Web.Models.ContentEditing +{ + [DataContract(Name = "contentRedirectUrl", Namespace = "")] + public class ContentRedirectUrl + { + [DataMember(Name = "redirectId")] + public Guid RedirectId { get; set; } + + [DataMember(Name = "originalUrl")] + public string OriginalUrl { get; set; } + + [DataMember(Name = "destinationUrl")] + public string DestinationUrl { get; set; } + + [DataMember(Name = "createDateUtc")] + public DateTime CreateDateUtc { get; set; } + + [DataMember(Name = "contentId")] + public int ContentId { get; set; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Models/ContentEditing/RedirectUrlSearchResults.cs b/src/Umbraco.Web/Models/ContentEditing/RedirectUrlSearchResults.cs new file mode 100644 index 0000000000..e022539f68 --- /dev/null +++ b/src/Umbraco.Web/Models/ContentEditing/RedirectUrlSearchResults.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; +using System.Runtime.Serialization; +using Umbraco.Core.Models; + +namespace Umbraco.Web.Models.ContentEditing +{ + [DataContract(Name = "redirectUrlSearchResult", Namespace = "")] + public class RedirectUrlSearchResult + { + [DataMember(Name = "searchResults")] + public IEnumerable SearchResults { get; set; } + + [DataMember(Name = "hasSearchResults")] + public bool HasSearchResults { get; set; } + + [DataMember(Name = "hasExactMatch")] + public bool HasExactMatch { get; set; } + + [DataMember(Name = "totalCount")] + public long TotalCount { get; set; } + + [DataMember(Name = "pageCount")] + public int PageCount { get; set; } + + [DataMember(Name = "currentPage")] + public int CurrentPage { get; set; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Models/Mapping/DashboardModelsMapper.cs b/src/Umbraco.Web/Models/Mapping/DashboardModelsMapper.cs new file mode 100644 index 0000000000..a87ea4eeb9 --- /dev/null +++ b/src/Umbraco.Web/Models/Mapping/DashboardModelsMapper.cs @@ -0,0 +1,27 @@ +using AutoMapper; +using Umbraco.Core; +using Umbraco.Core.Models.Mapping; +using Umbraco.Web.Models.ContentEditing; +using umbraco.BusinessLogic; +using Umbraco.Core.Models; + +namespace Umbraco.Web.Models.Mapping +{ + /// + /// A model mapper used to map models for the various dashboards + /// + internal class DashboardModelsMapper : MapperConfiguration + { + public override void ConfigureMappings(IConfiguration config, ApplicationContext applicationContext) + { + config.CreateMap() + .ForMember(x => x.OriginalUrl, expression => expression.MapFrom(item => item.Url)) + .ForMember(x => x.DestinationUrl, expression => expression.Ignore()) + .ForMember(x => x.RedirectId, expression => expression.MapFrom(item => item.Key)); + + //for the logging controller (and assuming dashboard that is used in uaas? otherwise not sure what that controller is used for) + config.CreateMap() + .ForMember(log => log.LogType, expression => expression.MapFrom(item => Enum.Parse(item.LogType.ToString()))); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Models/Mapping/LogModelMapper.cs b/src/Umbraco.Web/Models/Mapping/LogModelMapper.cs deleted file mode 100644 index db205f9d9e..0000000000 --- a/src/Umbraco.Web/Models/Mapping/LogModelMapper.cs +++ /dev/null @@ -1,17 +0,0 @@ -using AutoMapper; -using Umbraco.Core; -using Umbraco.Core.Models.Mapping; -using Umbraco.Web.Models.ContentEditing; -using umbraco.BusinessLogic; - -namespace Umbraco.Web.Models.Mapping -{ - internal class LogModelMapper : MapperConfiguration - { - public override void ConfigureMappings(IConfiguration config, ApplicationContext applicationContext) - { - config.CreateMap() - .ForMember(log => log.LogType, expression => expression.MapFrom(item => Enum.Parse(item.LogType.ToString()))); - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Web/Redirects/RedirectUrlSearchResults.cs b/src/Umbraco.Web/Redirects/RedirectUrlSearchResults.cs deleted file mode 100644 index 4fe790e588..0000000000 --- a/src/Umbraco.Web/Redirects/RedirectUrlSearchResults.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Collections.Generic; -using Umbraco.Core.Models; - -namespace Umbraco.Web.Redirects -{ - public class RedirectUrlSearchResult - { - public string StatusMessage { get; set; } - public IEnumerable SearchResults { get; set; } - public bool HasSearchResults { get; set; } - public bool HasExactMatch { get; set; } - public long TotalCount { get; set; } - public int PageCount { get; set; } - public int CurrentPage { get; set; } - - public bool UrlTrackerDisabled { get; set; } - } -} \ No newline at end of file diff --git a/src/Umbraco.Web/Redirects/RedirectTrackingEventHandler.cs b/src/Umbraco.Web/Routing/RedirectTrackingEventHandler.cs similarity index 99% rename from src/Umbraco.Web/Redirects/RedirectTrackingEventHandler.cs rename to src/Umbraco.Web/Routing/RedirectTrackingEventHandler.cs index 417238bdbe..c8adb551bb 100644 --- a/src/Umbraco.Web/Redirects/RedirectTrackingEventHandler.cs +++ b/src/Umbraco.Web/Routing/RedirectTrackingEventHandler.cs @@ -1,18 +1,17 @@ using System; -using Umbraco.Core; -using Umbraco.Core.Models; -using Umbraco.Core.Services; -using Umbraco.Core.Publishing; -using Umbraco.Core.Events; -using Umbraco.Web.Routing; using System.Collections.Generic; using System.Linq; +using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Configuration; +using Umbraco.Core.Events; +using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; +using Umbraco.Core.Publishing; +using Umbraco.Core.Services; using Umbraco.Web.Cache; -namespace Umbraco.Web.Redirects +namespace Umbraco.Web.Routing { /// /// Implements an Application Event Handler for managing redirect urls tracking. diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 78b88577a4..cc61d99b4a 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -344,6 +344,7 @@ + @@ -390,9 +391,9 @@ - - - + + + @@ -585,7 +586,7 @@ - + From 9ad84a7eaba2b5dbb2a4737c091dd1f657cde1bf Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 8 Aug 2016 14:47:48 +0200 Subject: [PATCH 22/23] fixes repository mapping the GUID id for redirect urls and removes unused properties --- .../Persistence/Repositories/RedirectUrlRepository.cs | 1 + .../Models/ContentEditing/RedirectUrlSearchResults.cs | 8 +------- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Repositories/RedirectUrlRepository.cs b/src/Umbraco.Core/Persistence/Repositories/RedirectUrlRepository.cs index 4dee350b0f..bd0f7aad7e 100644 --- a/src/Umbraco.Core/Persistence/Repositories/RedirectUrlRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/RedirectUrlRepository.cs @@ -117,6 +117,7 @@ JOIN umbracoNode ON umbracoRedirectUrl.contentKey=umbracoNode.uniqueID"); try { url.DisableChangeTracking(); + url.Key = dto.Id; url.Id = dto.Id.GetHashCode(); url.ContentId = dto.ContentId; url.ContentKey = dto.ContentKey; diff --git a/src/Umbraco.Web/Models/ContentEditing/RedirectUrlSearchResults.cs b/src/Umbraco.Web/Models/ContentEditing/RedirectUrlSearchResults.cs index e022539f68..6a64b0dbc4 100644 --- a/src/Umbraco.Web/Models/ContentEditing/RedirectUrlSearchResults.cs +++ b/src/Umbraco.Web/Models/ContentEditing/RedirectUrlSearchResults.cs @@ -9,13 +9,7 @@ namespace Umbraco.Web.Models.ContentEditing { [DataMember(Name = "searchResults")] public IEnumerable SearchResults { get; set; } - - [DataMember(Name = "hasSearchResults")] - public bool HasSearchResults { get; set; } - - [DataMember(Name = "hasExactMatch")] - public bool HasExactMatch { get; set; } - + [DataMember(Name = "totalCount")] public long TotalCount { get; set; } From bf61956b7f17200ba80c24a9acd1a5cab9c4e0a0 Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 8 Aug 2016 14:48:05 +0200 Subject: [PATCH 23/23] oops fixes build --- src/Umbraco.Web/Editors/RedirectUrlManagementController.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Umbraco.Web/Editors/RedirectUrlManagementController.cs b/src/Umbraco.Web/Editors/RedirectUrlManagementController.cs index b674a5e5e3..9c55e0df01 100644 --- a/src/Umbraco.Web/Editors/RedirectUrlManagementController.cs +++ b/src/Umbraco.Web/Editors/RedirectUrlManagementController.cs @@ -49,9 +49,7 @@ namespace Umbraco.Web.Editors searchResult.TotalCount = resultCount; searchResult.CurrentPage = page; searchResult.PageCount = ((int)resultCount + pageSize - 1) / pageSize; - - searchResult.HasSearchResults = resultCount > 0; - searchResult.HasExactMatch = (resultCount == 1); + return searchResult; }