diff --git a/src/Umbraco.Web.UI/umbraco_client/Dialogs/AssignDomain2.js b/src/Umbraco.Web.UI/umbraco_client/Dialogs/AssignDomain2.js index 07c16e4055..ddf38733e1 100644 --- a/src/Umbraco.Web.UI/umbraco_client/Dialogs/AssignDomain2.js +++ b/src/Umbraco.Web.UI/umbraco_client/Dialogs/AssignDomain2.js @@ -105,7 +105,7 @@ mask.show(); var data = { nodeId: self._opts.nodeId, language: self.language ? self.language : 0, domains: self.domains }; - $.post(self._opts.restServiceLocation + 'SaveLanguageAndDomains', ko.toJSON(data), function (json) { + $.post(self._opts.restServiceLocation + 'PostSaveLanguageAndDomains', ko.toJSON(data), function (json) { mask.hide(); if (json.Valid) { diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs index 2caa64fc98..4153661dcb 100644 --- a/src/Umbraco.Web/Editors/ContentController.cs +++ b/src/Umbraco.Web/Editors/ContentController.cs @@ -26,6 +26,7 @@ using Umbraco.Web.PublishedCache; using Umbraco.Core.Events; using Umbraco.Core.Models.Validation; using Umbraco.Web.Models; +using Umbraco.Web.WebServices; using Umbraco.Web._Legacy.Actions; using Constants = Umbraco.Core.Constants; using ContentVariation = Umbraco.Core.Models.ContentVariation; @@ -1001,7 +1002,7 @@ namespace Umbraco.Web.Editors /// /// Unpublishes a node with a given Id and returns the unpublished entity /// - /// The content id to unpublish + /// The content id to unpublish /// The culture variant for the content id to unpublish, if none specified will unpublish all variants of the content /// [EnsureUserPermissionForContent("id", 'U')] @@ -1023,17 +1024,156 @@ namespace Umbraco.Web.Editors throw new HttpResponseException(Request.CreateValidationErrorResponse(content)); } else - { - //fixme should have a better localized method for when we have the UnpublishResultType.SuccessMandatoryCulture status + { + //fixme should have a better localized method for when we have the UnpublishResultType.SuccessMandatoryCulture status - content.AddSuccessNotification( - Services.TextService.Localize("content/unPublish"), - unpublishResult.Result == UnpublishResultType.SuccessVariant - ? Services.TextService.Localize("speechBubbles/contentVariationUnpublished", new[] { culture }) - : Services.TextService.Localize("speechBubbles/contentUnpublished")); + content.AddSuccessNotification( + Services.TextService.Localize("content/unPublish"), + unpublishResult.Result == UnpublishResultType.SuccessVariant + ? Services.TextService.Localize("speechBubbles/contentVariationUnpublished", new[] { culture }) + : Services.TextService.Localize("speechBubbles/contentUnpublished")); return content; } + } + + [HttpPost] + public DomainSave PostSaveLanguageAndDomains(DomainSave model) + { + var node = Services.ContentService.GetById(model.NodeId); + + if (node == null) + { + var response = Request.CreateResponse(HttpStatusCode.BadRequest); + response.Content = new StringContent($"There is no content node with id {model.NodeId}."); + response.ReasonPhrase = "Node Not Found."; + throw new HttpResponseException(response); + } + + var permission = Services.UserService.GetPermissions(Security.CurrentUser, node.Path); + + if (permission.AssignedPermissions.Contains(ActionAssignDomain.Instance.Letter.ToString(), StringComparer.Ordinal) == false) + { + var response = Request.CreateResponse(HttpStatusCode.BadRequest); + response.Content = new StringContent("You do not have permission to assign domains on that node."); + response.ReasonPhrase = "Permission Denied."; + throw new HttpResponseException(response); + } + + model.Valid = true; + var domains = Services.DomainService.GetAssignedDomains(model.NodeId, true).ToArray(); + var languages = Services.LocalizationService.GetAllLanguages().ToArray(); + var language = model.Language > 0 ? languages.FirstOrDefault(l => l.Id == model.Language) : null; + + // process wildcard + if (language != null) + { + // yet there is a race condition here... + var wildcard = domains.FirstOrDefault(d => d.IsWildcard); + if (wildcard != null) + { + wildcard.LanguageId = language.Id; + } + else + { + wildcard = new UmbracoDomain("*" + model.NodeId) + { + LanguageId = model.Language, + RootContentId = model.NodeId + }; + } + + var saveAttempt = Services.DomainService.Save(wildcard); + if (saveAttempt == false) + { + var response = Request.CreateResponse(HttpStatusCode.BadRequest); + response.Content = new StringContent("Saving domain failed"); + response.ReasonPhrase = saveAttempt.Result.Result.ToString(); + throw new HttpResponseException(response); + } + } + else + { + var wildcard = domains.FirstOrDefault(d => d.IsWildcard); + if (wildcard != null) + { + Services.DomainService.Delete(wildcard); + } + } + + // process domains + // delete every (non-wildcard) domain, that exists in the DB yet is not in the model + foreach (var domain in domains.Where(d => d.IsWildcard == false && model.Domains.All(m => m.Name.InvariantEquals(d.DomainName) == false))) + { + Services.DomainService.Delete(domain); + } + + var names = new List(); + + // create or update domains in the model + foreach (var domainModel in model.Domains.Where(m => string.IsNullOrWhiteSpace(m.Name) == false)) + { + language = languages.FirstOrDefault(l => l.Id == domainModel.Lang); + if (language == null) + { + continue; + } + + var name = domainModel.Name.ToLowerInvariant(); + if (names.Contains(name)) + { + domainModel.Duplicate = true; + continue; + } + names.Add(name); + var domain = domains.FirstOrDefault(d => d.DomainName.InvariantEquals(domainModel.Name)); + if (domain != null) + { + domain.LanguageId = language.Id; + Services.DomainService.Save(domain); + } + else if (Services.DomainService.Exists(domainModel.Name)) + { + domainModel.Duplicate = true; + var xdomain = Services.DomainService.GetByName(domainModel.Name); + var xrcid = xdomain.RootContentId; + if (xrcid.HasValue) + { + var xcontent = Services.ContentService.GetById(xrcid.Value); + var xnames = new List(); + while (xcontent != null) + { + xnames.Add(xcontent.Name); + if (xcontent.ParentId < -1) + xnames.Add("Recycle Bin"); + xcontent = xcontent.Parent(Services.ContentService); + } + xnames.Reverse(); + domainModel.Other = "/" + string.Join("/", xnames); + } + } + else + { + // yet there is a race condition here... + var newDomain = new UmbracoDomain(name) + { + LanguageId = domainModel.Lang, + RootContentId = model.NodeId + }; + var saveAttempt = Services.DomainService.Save(newDomain); + if (saveAttempt == false) + { + var response = Request.CreateResponse(HttpStatusCode.BadRequest); + response.Content = new StringContent("Saving new domain failed"); + response.ReasonPhrase = saveAttempt.Result.Result.ToString(); + throw new HttpResponseException(response); + } + } + } + + model.Valid = model.Domains.All(m => m.Duplicate == false); + + return model; } /// diff --git a/src/Umbraco.Web/Models/ContentEditing/DomainDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/DomainDisplay.cs new file mode 100644 index 0000000000..a6f7e499e4 --- /dev/null +++ b/src/Umbraco.Web/Models/ContentEditing/DomainDisplay.cs @@ -0,0 +1,16 @@ +namespace Umbraco.Web.Models.ContentEditing +{ + public class DomainDisplay + { + public DomainDisplay(string name, int lang) + { + Name = name; + Lang = lang; + } + + public string Name { get; } + public int Lang { get; } + public bool Duplicate { get; set; } + public string Other { get; set; } + } +} diff --git a/src/Umbraco.Web/Models/ContentEditing/DomainSave.cs b/src/Umbraco.Web/Models/ContentEditing/DomainSave.cs new file mode 100644 index 0000000000..3ad19cfd60 --- /dev/null +++ b/src/Umbraco.Web/Models/ContentEditing/DomainSave.cs @@ -0,0 +1,10 @@ +namespace Umbraco.Web.Models.ContentEditing +{ + public class DomainSave + { + public bool Valid { get; set; } + public int NodeId { get; set; } + public int Language { get; set; } + public DomainDisplay[] Domains { get; set; } + } +} diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 5281b307aa..e126eed7a4 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -207,6 +207,8 @@ + + @@ -1417,7 +1419,6 @@ - diff --git a/src/Umbraco.Web/WebServices/DomainsApiController.cs b/src/Umbraco.Web/WebServices/DomainsApiController.cs deleted file mode 100644 index d74a225aee..0000000000 --- a/src/Umbraco.Web/WebServices/DomainsApiController.cs +++ /dev/null @@ -1,190 +0,0 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using System.Net; -using System.Net.Http; -using System.Web.Http; -using Umbraco.Core; -using Umbraco.Core.Services; -using Umbraco.Core.Models; -using Umbraco.Web.WebApi; -//using umbraco.cms.businesslogic.language; -using Umbraco.Web.WebApi.Filters; -using Umbraco.Web._Legacy.Actions; - -namespace Umbraco.Web.WebServices -{ - /// - /// A REST controller used for managing domains. - /// - /// Nothing to do with Active Directory. - [ValidateAngularAntiForgeryToken] - public class DomainsApiController : UmbracoAuthorizedApiController - { - [HttpPost] - // can't pass multiple complex args in json post request... - public PostBackModel SaveLanguageAndDomains(PostBackModel model) - { - var node = Services.ContentService.GetById(model.NodeId); - - if (node == null) - { - var response = Request.CreateResponse(HttpStatusCode.BadRequest); - response.Content = new StringContent(string.Format("There is no content node with id {0}.", model.NodeId)); - response.ReasonPhrase = "Node Not Found."; - throw new HttpResponseException(response); - } - - var permission = Services.UserService.GetPermissions(Security.CurrentUser, node.Path); - - if (permission.AssignedPermissions.Contains(ActionAssignDomain.Instance.Letter.ToString(), StringComparer.Ordinal) == false) - { - var response = Request.CreateResponse(HttpStatusCode.BadRequest); - response.Content = new StringContent("You do not have permission to assign domains on that node."); - response.ReasonPhrase = "Permission Denied."; - throw new HttpResponseException(response); - } - - model.Valid = true; - var domains = Services.DomainService.GetAssignedDomains(model.NodeId, true).ToArray(); - var languages = Services.LocalizationService.GetAllLanguages().ToArray(); - var language = model.Language > 0 ? languages.FirstOrDefault(l => l.Id == model.Language) : null; - - // process wildcard - - if (language != null) - { - // yet there is a race condition here... - var wildcard = domains.FirstOrDefault(d => d.IsWildcard); - if (wildcard != null) - { - wildcard.LanguageId = language.Id; - } - else - { - wildcard = new UmbracoDomain("*" + model.NodeId) - { - LanguageId = model.Language, - RootContentId = model.NodeId - }; - } - - var saveAttempt = Services.DomainService.Save(wildcard); - if (saveAttempt == false) - { - var response = Request.CreateResponse(HttpStatusCode.BadRequest); - response.Content = new StringContent("Saving domain failed"); - response.ReasonPhrase = saveAttempt.Result.Result.ToString(); - throw new HttpResponseException(response); - } - } - else - { - var wildcard = domains.FirstOrDefault(d => d.IsWildcard); - if (wildcard != null) - { - Services.DomainService.Delete(wildcard); - } - } - - // process domains - - // delete every (non-wildcard) domain, that exists in the DB yet is not in the model - foreach (var domain in domains.Where(d => d.IsWildcard == false && model.Domains.All(m => m.Name.InvariantEquals(d.DomainName) == false))) - { - Services.DomainService.Delete(domain); - } - - - var names = new List(); - - // create or update domains in the model - foreach (var domainModel in model.Domains.Where(m => string.IsNullOrWhiteSpace(m.Name) == false)) - { - language = languages.FirstOrDefault(l => l.Id == domainModel.Lang); - if (language == null) - continue; - var name = domainModel.Name.ToLowerInvariant(); - if (names.Contains(name)) - { - domainModel.Duplicate = true; - continue; - } - names.Add(name); - var domain = domains.FirstOrDefault(d => d.DomainName.InvariantEquals(domainModel.Name)); - if (domain != null) - { - domain.LanguageId = language.Id; - Services.DomainService.Save(domain); - } - else if (Services.DomainService.Exists(domainModel.Name)) - { - domainModel.Duplicate = true; - var xdomain = Services.DomainService.GetByName(domainModel.Name); - var xrcid = xdomain.RootContentId; - if (xrcid.HasValue) - { - var xcontent = Services.ContentService.GetById(xrcid.Value); - var xnames = new List(); - while (xcontent != null) - { - xnames.Add(xcontent.Name); - if (xcontent.ParentId < -1) - xnames.Add("Recycle Bin"); - xcontent = xcontent.Parent(Services.ContentService); - } - xnames.Reverse(); - domainModel.Other = "/" + string.Join("/", xnames); - } - } - else - { - // yet there is a race condition here... - var newDomain = new UmbracoDomain(name) - { - LanguageId = domainModel.Lang, - RootContentId = model.NodeId - }; - var saveAttempt = Services.DomainService.Save(newDomain); - if (saveAttempt == false) - { - var response = Request.CreateResponse(HttpStatusCode.BadRequest); - response.Content = new StringContent("Saving new domain failed"); - response.ReasonPhrase = saveAttempt.Result.Result.ToString(); - throw new HttpResponseException(response); - } - } - } - - model.Valid = model.Domains.All(m => m.Duplicate == false); - - return model; - } - - #region Models - - public class PostBackModel - { - public bool Valid { get; set; } - public int NodeId { get; set; } - public int Language { get; set; } - public DomainModel[] Domains { get; set; } - } - - public class DomainModel - { - public DomainModel(string name, int lang) - { - Name = name; - Lang = lang; - } - - public string Name { get; private set; } - public int Lang { get; private set; } - public bool Duplicate { get; set; } - public string Other { get; set; } - } - - #endregion - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/AssignDomain2.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/AssignDomain2.aspx.cs index 51f1b4f114..00788fab3f 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/AssignDomain2.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/AssignDomain2.aspx.cs @@ -7,6 +7,7 @@ using Umbraco.Core.Services; using Umbraco.Web.UI.Pages; using Umbraco.Web; using Umbraco.Web.Composing; +using Umbraco.Web.Editors; using Umbraco.Web.WebServices; using Umbraco.Web._Legacy.Actions; @@ -75,7 +76,7 @@ namespace umbraco.dialogs protected string GetRestServicePath() { const string action = "ListDomains"; - var path = Url.GetUmbracoApiService(action); + var path = Url.GetUmbracoApiService(action); return path.TrimEnd(action).EnsureEndsWith('/'); } }