public async Task PostSave_Validates_All_Cultures_Has_Domains()
    {
        var localizationService = GetRequiredService <ILocalizationService>();

        localizationService.Save(new LanguageBuilder()
                                 .WithCultureInfo(DkIso)
                                 .WithIsDefault(false)
                                 .Build());

        var contentTypeService = GetRequiredService <IContentTypeService>();
        var contentType        = new ContentTypeBuilder().WithContentVariation(ContentVariation.Culture).Build();

        contentTypeService.Save(contentType);

        var content = new ContentBuilder()
                      .WithoutIdentity()
                      .WithContentType(contentType)
                      .WithCultureName(UsIso, "Root")
                      .WithCultureName(DkIso, "Rod")
                      .Build();

        var contentService = GetRequiredService <IContentService>();

        contentService.Save(content);

        var model = new ContentItemSaveBuilder()
                    .WithContent(content)
                    .WithAction(ContentSaveAction.Publish)
                    .Build();

        var dkLanguage    = localizationService.GetLanguageByIsoCode(DkIso);
        var domainService = GetRequiredService <IDomainService>();
        var dkDomain      = new UmbracoDomain("/")
        {
            RootContentId = content.Id, LanguageId = dkLanguage.Id
        };

        domainService.Save(dkDomain);

        var url = PrepareApiControllerUrl <ContentController>(x => x.PostSave(null));

        var response = await Client.PostAsync(url, new MultipartFormDataContent { { new StringContent(JsonConvert.SerializeObject(model)), "contentItem" } });

        var body = await response.Content.ReadAsStringAsync();

        body = body.TrimStart(AngularJsonMediaTypeFormatter.XsrfPrefix);
        var display = JsonConvert.DeserializeObject <ContentItemDisplay>(body);


        var localizedTextService = GetRequiredService <ILocalizedTextService>();
        var expectedMessage      = localizedTextService.Localize("speechBubbles", "publishWithMissingDomain", new[] { UsIso });

        Assert.Multiple(() =>
        {
            Assert.NotNull(display);
            Assert.AreEqual(1, display.Notifications.Count(x => x.NotificationType == NotificationStyle.Warning));
            Assert.AreEqual(expectedMessage, display.Notifications.FirstOrDefault(x => x.NotificationType == NotificationStyle.Warning)?.Message);
        });
    }
Example #2
0
        public void AddCultureAndHostname(TenantDomain tenant, bool secureUrl)
        {
            const string protocolBase = "http";
            var          protocol     = secureUrl ? $"{protocolBase}s" : protocolBase;

            try
            {
                var tenantRoot = nodeHelper.GetTenantRoot(tenant.TenantUid);
                var languages  = localizationService.GetAllLanguages();
                var subDomain  = tenantRoot.GetValue <string>("subDomain");

                string domainName     = $"{protocol}://{subDomain}.{tenant.Domain}/";
                var    existingDomain = domainService.GetByName(domainName);
                if (Uri.IsWellFormedUriString(domainName, UriKind.RelativeOrAbsolute))
                {
                    if (existingDomain == null)
                    {
                        var defaultLanguageId = localizationService.GetDefaultLanguageId();
                        existingDomain = new UmbracoDomain(domainName)
                        {
                            LanguageId    = defaultLanguageId,
                            RootContentId = tenantRoot.Id
                        };

                        domainService.Save(existingDomain);
                        ConnectorContext.AuditService.Add(AuditType.New, -1, existingDomain.Id, "Language", $"Domain '{domainName}' for Tenant '{tenant.TenantUid}' has been created");
                    }

                    foreach (var language in languages)
                    {
                        var localizedDomainName = $"{domainName}{language.IsoCode}";
                        var localizedDomain     = domainService.GetByName(localizedDomainName);
                        if (localizedDomain == null)
                        {
                            localizedDomain = new UmbracoDomain(localizedDomainName)
                            {
                                LanguageId    = language.Id,
                                RootContentId = tenantRoot.Id
                            };
                            domainService.Save(localizedDomain);
                            ConnectorContext.AuditService.Add(AuditType.New, -1, existingDomain.Id, "Language", $"Domain '{localizedDomainName}' for Tenant '{tenant.TenantUid}' has been created");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                logger.Error(typeof(LanguageDictionaryService), ex.Message);
                logger.Error(typeof(LanguageDictionaryService), ex.StackTrace);
                throw;
            }
        }
Example #3
0
        public IDomain BuildEntity(DomainDto dto)
        {
            var domain = new UmbracoDomain(dto.DomainName, dto.IsoCode)
            {
                Id            = dto.Id,
                LanguageId    = dto.DefaultLanguage,
                RootContentId = dto.RootStructureId,
            };

            // reset dirty initial properties (U4-1946)
            domain.ResetDirtyProperties(false);
            return(domain);
        }
            public IDomain BuildEntity(DomainDto dto)
            {
                var domain = new UmbracoDomain(dto.DomainName, dto.IsoCode)
                {
                    Id            = dto.Id,
                    LanguageId    = dto.DefaultLanguage,
                    RootContentId = dto.RootStructureId
                };

                //on initial construction we don't want to have dirty properties tracked
                // http://issues.umbraco.org/issue/U4-1946
                domain.ResetDirtyProperties(false);
                return(domain);
            }
Example #5
0
        public static void MakeNew(string DomainName, int RootNodeId, int LanguageId)
        {
            var domain = new UmbracoDomain(DomainName)
            {
                RootContentId = RootNodeId,
                LanguageId    = LanguageId
            };

            if (ApplicationContext.Current.Services.DomainService.Save(domain))
            {
                var e           = new NewEventArgs();
                var legacyModel = new Domain(domain);
                legacyModel.OnNew(e);
            }
        }
        public async Task PostSave_Checks_Ancestors_For_Domains()
        {
            ILocalizationService localizationService = GetRequiredService <ILocalizationService>();

            localizationService.Save(new LanguageBuilder()
                                     .WithCultureInfo(DkIso)
                                     .WithIsDefault(false)
                                     .Build());

            IContentTypeService contentTypeService = GetRequiredService <IContentTypeService>();
            IContentType        contentType        = new ContentTypeBuilder().WithContentVariation(ContentVariation.Culture).Build();

            contentTypeService.Save(contentType);

            Content rootNode = new ContentBuilder()
                               .WithoutIdentity()
                               .WithContentType(contentType)
                               .WithCultureName(UsIso, "Root")
                               .WithCultureName(DkIso, "Rod")
                               .Build();

            IContentService contentService = GetRequiredService <IContentService>();

            contentService.SaveAndPublish(rootNode);

            Content childNode = new ContentBuilder()
                                .WithoutIdentity()
                                .WithParent(rootNode)
                                .WithContentType(contentType)
                                .WithCultureName(DkIso, "Barn")
                                .WithCultureName(UsIso, "Child")
                                .Build();

            contentService.SaveAndPublish(childNode);

            Content grandChild = new ContentBuilder()
                                 .WithoutIdentity()
                                 .WithParent(childNode)
                                 .WithContentType(contentType)
                                 .WithCultureName(DkIso, "BarneBarn")
                                 .WithCultureName(UsIso, "GrandChild")
                                 .Build();

            contentService.Save(grandChild);

            ILanguage      dkLanguage    = localizationService.GetLanguageByIsoCode(DkIso);
            ILanguage      usLanguage    = localizationService.GetLanguageByIsoCode(UsIso);
            IDomainService domainService = GetRequiredService <IDomainService>();
            var            dkDomain      = new UmbracoDomain("/")
            {
                RootContentId = rootNode.Id,
                LanguageId    = dkLanguage.Id
            };

            var usDomain = new UmbracoDomain("/en")
            {
                RootContentId = childNode.Id,
                LanguageId    = usLanguage.Id
            };

            domainService.Save(dkDomain);
            domainService.Save(usDomain);

            var url = PrepareApiControllerUrl <ContentController>(x => x.PostSave(null));

            ContentItemSave model = new ContentItemSaveBuilder()
                                    .WithContent(grandChild)
                                    .WithAction(ContentSaveAction.Publish)
                                    .Build();

            HttpResponseMessage response = await Client.PostAsync(url, new MultipartFormDataContent
            {
                { new StringContent(JsonConvert.SerializeObject(model)), "contentItem" }
            });

            var body = await response.Content.ReadAsStringAsync();

            body = body.TrimStart(AngularJsonMediaTypeFormatter.XsrfPrefix);
            ContentItemDisplay display = JsonConvert.DeserializeObject <ContentItemDisplay>(body);

            Assert.Multiple(() =>
            {
                Assert.NotNull(display);
                // Assert all is good, a success notification for each culture published and no warnings.
                Assert.AreEqual(2, display.Notifications.Count(x => x.NotificationType == NotificationStyle.Success));
                Assert.AreEqual(0, display.Notifications.Count(x => x.NotificationType == NotificationStyle.Warning));
            });
        }
        public async Task PostSave_Validates_All_Ancestor_Cultures_Are_Considered()
        {
            var sweIso = "sv-SE";
            ILocalizationService localizationService = GetRequiredService <ILocalizationService>();

            //Create 2 new languages
            localizationService.Save(new LanguageBuilder()
                                     .WithCultureInfo(DkIso)
                                     .WithIsDefault(false)
                                     .Build());

            localizationService.Save(new LanguageBuilder()
                                     .WithCultureInfo(sweIso)
                                     .WithIsDefault(false)
                                     .Build());

            IContentTypeService contentTypeService = GetRequiredService <IContentTypeService>();
            IContentType        contentType        = new ContentTypeBuilder().WithContentVariation(ContentVariation.Culture).Build();

            contentTypeService.Save(contentType);

            Content content = new ContentBuilder()
                              .WithoutIdentity()
                              .WithContentType(contentType)
                              .WithCultureName(UsIso, "Root")
                              .Build();

            IContentService contentService = GetRequiredService <IContentService>();

            contentService.SaveAndPublish(content);

            Content childContent = new ContentBuilder()
                                   .WithoutIdentity()
                                   .WithContentType(contentType)
                                   .WithParent(content)
                                   .WithCultureName(DkIso, "Barn")
                                   .WithCultureName(UsIso, "Child")
                                   .Build();

            contentService.SaveAndPublish(childContent);

            Content grandChildContent = new ContentBuilder()
                                        .WithoutIdentity()
                                        .WithContentType(contentType)
                                        .WithParent(childContent)
                                        .WithCultureName(sweIso, "Bjarn")
                                        .Build();


            ContentItemSave model = new ContentItemSaveBuilder()
                                    .WithContent(grandChildContent)
                                    .WithParentId(childContent.Id)
                                    .WithAction(ContentSaveAction.PublishNew)
                                    .Build();

            ILanguage      enLanguage    = localizationService.GetLanguageByIsoCode(UsIso);
            IDomainService domainService = GetRequiredService <IDomainService>();
            var            enDomain      = new UmbracoDomain("/en")
            {
                RootContentId = content.Id,
                LanguageId    = enLanguage.Id
            };

            domainService.Save(enDomain);

            ILanguage dkLanguage = localizationService.GetLanguageByIsoCode(DkIso);
            var       dkDomain   = new UmbracoDomain("/dk")
            {
                RootContentId = childContent.Id,
                LanguageId    = dkLanguage.Id
            };

            domainService.Save(dkDomain);

            var url = PrepareApiControllerUrl <ContentController>(x => x.PostSave(null));

            var result = JsonConvert.SerializeObject(model);
            HttpResponseMessage response = await Client.PostAsync(url, new MultipartFormDataContent
            {
                { new StringContent(JsonConvert.SerializeObject(model)), "contentItem" }
            });

            var body = await response.Content.ReadAsStringAsync();

            body = body.TrimStart(AngularJsonMediaTypeFormatter.XsrfPrefix);
            ContentItemDisplay display = JsonConvert.DeserializeObject <ContentItemDisplay>(body);


            ILocalizedTextService localizedTextService = GetRequiredService <ILocalizedTextService>();
            var expectedMessage = localizedTextService.Localize("speechBubbles", "publishWithMissingDomain", new [] { "sv-SE" });

            Assert.Multiple(() =>
            {
                Assert.NotNull(display);
                Assert.AreEqual(1, display.Notifications.Count(x => x.NotificationType == NotificationStyle.Warning));
                Assert.AreEqual(expectedMessage, display.Notifications.FirstOrDefault(x => x.NotificationType == NotificationStyle.Warning)?.Message);
            });
        }
        // can't pass multiple complex args in json post request...
        public PostBackModel SaveLanguageAndDomains(PostBackModel model)
        {
            var node = ApplicationContext.Current.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);
            }

            if (UmbracoUser.GetPermissions(node.Path).Contains(ActionAssignDomain.Instance.Letter) == 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.StatusType.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 <string>();

            // 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 <string>();
                        while (xcontent != null)
                        {
                            xnames.Add(xcontent.Name);
                            if (xcontent.ParentId < -1)
                            {
                                xnames.Add("Recycle Bin");
                            }
                            xcontent = xcontent.Parent();
                        }
                        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.StatusType.ToString();
                        throw new HttpResponseException(response);
                    }
                }
            }

            model.Valid = model.Domains.All(m => m.Duplicate == false);

            return(model);
        }
Example #9
0
        public void AddCultureAndHostnameDomain(TenantDomain tenant, bool secureUrl)
        {
            const string protocolBase = "http";
            var          protocol     = secureUrl ? $"{protocolBase}s" : protocolBase;

            try
            {
                var tenantRoot = nodeHelper.GetTenantRoot(tenant.TenantUid);
                var languages  = localizationService.GetAllLanguages();
                var subDomain  = tenantRoot.GetValue <string>("subDomain");

                var tenantHome = nodeHelper.GetTenantRoot(tenant.TenantUid);
                var domains    = nodeHelper.GetTenantDomains(tenant.TenantUid);


                string[] langs = new string[] { };
                if (tenantRoot.HasProperty("languages") && tenantRoot.GetValue("languages") != null)
                {
                    var languages_val = tenantRoot.GetValue("languages").ToString();
                    if (languages_val.Contains(","))
                    {
                        langs = languages_val.Split(',');
                    }
                    else
                    {
                        langs = new string[] { languages_val };
                    }
                }
                string defaultLang = tenantRoot.GetValue("defaultLanguage").ToString();

                string domainName     = $"{protocol}://{tenant.Domain}/";
                var    existingDomain = domainService.GetByName(domainName);
                if (Uri.IsWellFormedUriString(domainName, UriKind.RelativeOrAbsolute))
                {
                    if (existingDomain == null)
                    {
                        var defaultLanguageId = localizationService.GetLanguageIdByIsoCode(defaultLang);
                        existingDomain = new UmbracoDomain(domainName)
                        {
                            LanguageId    = defaultLanguageId,
                            RootContentId = tenantRoot.Id
                        };

                        domainService.Save(existingDomain);
                        ConnectorContext.AuditService.Add(AuditType.New, -1, existingDomain.Id, "Language", $"Domain '{domainName}' for Tenant '{tenant.TenantUid}' has been created");
                    }

                    foreach (var language in languages)
                    {
                        if (langs.Contains(language.IsoCode))
                        {
                            var localizedDomainName = $"{domainName}{language.IsoCode}";
                            var localizedDomain     = domainService.GetByName(localizedDomainName);
                            if (localizedDomain == null)
                            {
                                localizedDomain = new UmbracoDomain(localizedDomainName)
                                {
                                    LanguageId    = language.Id,
                                    RootContentId = tenantRoot.Id
                                };
                                domainService.Save(localizedDomain);
                                ConnectorContext.AuditService.Add(AuditType.New, -1, existingDomain.Id, "Language", $"Domain '{localizedDomainName}' for Tenant '{tenant.TenantUid}' has been created");
                            }
                        }
                    }
                }

                string domainWWW         = $"{protocol}://www.{tenant.Domain}/";
                var    existingDomainWWW = domainService.GetByName(domainWWW);
                if (Uri.IsWellFormedUriString(domainWWW, UriKind.RelativeOrAbsolute))
                {
                    if (existingDomainWWW == null)
                    {
                        var defaultLanguageId = localizationService.GetLanguageIdByIsoCode(defaultLang);
                        existingDomainWWW = new UmbracoDomain(domainWWW)
                        {
                            LanguageId    = defaultLanguageId,
                            RootContentId = tenantRoot.Id
                        };

                        domainService.Save(existingDomainWWW);
                        ConnectorContext.AuditService.Add(AuditType.New, -1, existingDomainWWW.Id, "Language", $"Domain '{domainWWW}' for Tenant '{tenant.TenantUid}' has been created");
                    }

                    foreach (var language in languages)
                    {
                        if (langs.Contains(language.IsoCode))
                        {
                            var localizedDomainName = $"{domainWWW}{language.IsoCode}";
                            var localizedDomain     = domainService.GetByName(localizedDomainName);
                            if (localizedDomain == null)
                            {
                                localizedDomain = new UmbracoDomain(localizedDomainName)
                                {
                                    LanguageId    = language.Id,
                                    RootContentId = tenantRoot.Id
                                };
                                domainService.Save(localizedDomain);
                                ConnectorContext.AuditService.Add(AuditType.New, -1, existingDomainWWW.Id, "Language", $"Domain '{localizedDomainName}' for Tenant '{tenant.TenantUid}' has been created");
                            }
                        }
                    }
                }

                string domainSubdomain         = $"{protocol}://{subDomain}.{tenant.Domain}/";
                var    existingDomainSubdomain = domainService.GetByName(domainSubdomain);
                if (Uri.IsWellFormedUriString(domainSubdomain, UriKind.RelativeOrAbsolute))
                {
                    if (existingDomainSubdomain == null)
                    {
                        var defaultLanguageId = localizationService.GetLanguageIdByIsoCode(defaultLang);
                        existingDomainSubdomain = new UmbracoDomain(domainSubdomain)
                        {
                            LanguageId    = defaultLanguageId,
                            RootContentId = tenantRoot.Id
                        };

                        domainService.Save(existingDomainSubdomain);
                        ConnectorContext.AuditService.Add(AuditType.New, -1, existingDomainSubdomain.Id, "Language", $"Domain '{domainSubdomain}' for Tenant '{tenant.TenantUid}' has been created");
                    }

                    foreach (var language in languages)
                    {
                        if (langs.Contains(language.IsoCode))
                        {
                            var localizedDomainName = $"{domainSubdomain}{language.IsoCode}";
                            var localizedDomain     = domainService.GetByName(localizedDomainName);
                            if (localizedDomain == null)
                            {
                                localizedDomain = new UmbracoDomain(localizedDomainName)
                                {
                                    LanguageId    = language.Id,
                                    RootContentId = tenantRoot.Id
                                };
                                domainService.Save(localizedDomain);
                                ConnectorContext.AuditService.Add(AuditType.New, -1, existingDomainSubdomain.Id, "Language", $"Domain '{localizedDomainName}' for Tenant '{tenant.TenantUid}' has been created");
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                logger.Error(typeof(LanguageDictionaryService), ex.Message);
                logger.Error(typeof(LanguageDictionaryService), ex.StackTrace);
                throw;
            }
        }
Example #10
0
        public void SetCulturesAndHostnames(ExtendedTenant tenant, bool setupLocal = false, bool secureUrl = false)
        {
            Validate(tenant.Tenant);
            const string protocolBase = "http";
            var          protocol     = secureUrl ? $"{protocolBase}s" : protocolBase;

            try
            {
                var langExists = localizationService.GetLanguageByIsoCode(tenant.Tenant.Languages.Default) != null;
                if (langExists)
                {
                    // Create hostname and multi language
                    //string domainName = $"{tenant.Tenant.SubDomain}.{tenant.Tenant.Domain}/{tenant.Tenant.Languages.Default.ToLower()}/";
                    string domainName = $"{protocol}://{tenant.Tenant.SubDomain}.{tenant.Tenant.Domain}/";
                    var    domain     = domainService.GetByName(domainName);
                    if (Uri.IsWellFormedUriString(domainName, UriKind.RelativeOrAbsolute))
                    {
                        if (domain == null)
                        {
                            domain = new UmbracoDomain(domainName)
                            {
                                LanguageId    = localizationService.GetLanguageIdByIsoCode(tenant.Tenant.Languages.Default),
                                RootContentId = tenant.StartContentId
                            };
                            domainService.Save(domain);
                            ConnectorContext.AuditService.Add(AuditType.New, -1, domain.Id, "Language", $"Default Domain for {tenant.Tenant.Languages.Default} has been created");
                        }

                        if (setupLocal)
                        {
                            string domainNameLocal = $"/{tenant.Tenant.SubDomain}/{tenant.Tenant.Languages.Default.ToLower()}";
                            var    domainLocal     = domainService.GetByName(domainNameLocal);
                            if (domainLocal == null)
                            {
                                domainLocal = new UmbracoDomain(domainNameLocal)
                                {
                                    LanguageId    = localizationService.GetLanguageIdByIsoCode(tenant.Tenant.Languages.Default),
                                    RootContentId = tenant.StartContentId
                                };
                                domainService.Save(domainLocal);
                                ConnectorContext.AuditService.Add(AuditType.New, -1, domain.Id, "Language", $"Domain {domainNameLocal} (local) has been created for {tenant.Tenant.TenantUId}");
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                logger.Error(typeof(LanguageDictionaryService), ex.Message);
                logger.Error(typeof(LanguageDictionaryService), ex.StackTrace);
                throw;
            }
            try
            {
                foreach (var language in tenant.Tenant.Languages.Alternate ?? new List <string>())
                {
                    var langExists = localizationService.GetLanguageByIsoCode(language) != null;
                    if (langExists)
                    {
                        var lang = language.Replace(" ", string.Empty);
                        // Create hostname and multi language for secondary languages
                        var altDomainName = $"{protocol}://{tenant.Tenant.SubDomain}.{tenant.Tenant.Domain}/{language.ToLower()}/";
                        var altDomain     = domainService.GetByName(altDomainName);
                        if (altDomain == null)
                        {
                            altDomain = new UmbracoDomain(altDomainName)
                            {
                                LanguageId    = localizationService.GetLanguageIdByIsoCode(lang),
                                RootContentId = tenant.StartContentId
                            };
                            domainService.Save(altDomain);
                            ConnectorContext.AuditService.Add(AuditType.New, -1, altDomain.Id, "Language", $"Alternative Domain {altDomain} has been created");
                        }

                        if (setupLocal)
                        {
                            string altDomainNameLocal = $"/{tenant.Tenant.SubDomain}/{language.ToLower()}";
                            var    altDomainLocal     = domainService.GetByName(altDomainNameLocal);
                            if (altDomainLocal == null)
                            {
                                altDomainLocal = new UmbracoDomain(altDomainNameLocal)
                                {
                                    LanguageId    = localizationService.GetLanguageIdByIsoCode(lang),
                                    RootContentId = tenant.StartContentId
                                };
                                domainService.Save(altDomainLocal);
                            }
                            ConnectorContext.AuditService.Add(AuditType.New, -1, altDomainLocal.Id, "Language", $"Alternative Domain {altDomainLocal} (local) has been created");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                logger.Error(typeof(LanguageDictionaryService), ex.Message);
                logger.Error(typeof(LanguageDictionaryService), ex.StackTrace);
                throw;
            }
        }