diff --git a/src/Umbraco.Tests/Integration/GetCultureTests.cs b/src/Umbraco.Tests/Integration/GetCultureTests.cs
new file mode 100644
index 0000000000..d4d1ea565b
--- /dev/null
+++ b/src/Umbraco.Tests/Integration/GetCultureTests.cs
@@ -0,0 +1,75 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using NUnit.Framework;
+using umbraco.cms.businesslogic.language;
+using umbraco.cms.businesslogic.web;
+using Umbraco.Tests.Services;
+using Umbraco.Tests.TestHelpers;
+using Umbraco.Tests.TestHelpers.Entities;
+using Umbraco.Web.Routing;
+
+namespace Umbraco.Tests.Integration
+{
+ [DatabaseTestBehavior(DatabaseBehavior.NewDbFileAndSchemaPerTest)]
+ [TestFixture, RequiresSTA]
+ public class GetCultureTests : BaseServiceTest
+ {
+ protected override void FreezeResolution()
+ {
+ SiteDomainHelperResolver.Current = new SiteDomainHelperResolver(new SiteDomainHelper());
+
+ base.FreezeResolution();
+ }
+
+ [Test]
+ public void GetCulture()
+ {
+ var contentTypeService = ServiceContext.ContentTypeService;
+ var contentType = MockedContentTypes.CreateSimpleContentType("umbBlah", "test Doc Type");
+ contentTypeService.Save(contentType);
+ var contentService = ServiceContext.ContentService;
+
+ var c1 = contentService.CreateContentWithIdentity("content", -1, "umbBlah");
+ var c2 = contentService.CreateContentWithIdentity("content", c1, "umbBlah");
+ var c3 = contentService.CreateContentWithIdentity("content", c1, "umbBlah");
+ var c4 = contentService.CreateContentWithIdentity("content", c3, "umbBlah");
+
+ var langs = Language.GetAllAsList();
+ foreach (var l in langs.Skip(1))
+ l.Delete();
+
+ Language.MakeNew("fr-FR");
+ Language.MakeNew("de-DE");
+
+ var langEn = Language.GetByCultureCode("en-US");
+ var langFr = Language.GetByCultureCode("fr-FR");
+ var langDe = Language.GetByCultureCode("de-DE");
+
+ var domains = Domain.GetDomains(true); // we want wildcards too here
+ foreach (var d in domains)
+ d.Delete();
+
+ Domain.MakeNew("domain1.com/", c1.Id, langEn.id);
+ Domain.MakeNew("domain1.fr/", c1.Id, langFr.id);
+ Domain.MakeNew("*100112", c3.Id, langDe.id);
+
+ var content = c2;
+ var culture = Web.Models.ContentExtensions.GetCulture(null, ServiceContext.LocalizationService, ServiceContext.ContentService, content.Id, content.Path,
+ new Uri("http://domain1.com/"));
+ Assert.AreEqual("en-US", culture.Name);
+
+ content = c2;
+ culture = Web.Models.ContentExtensions.GetCulture(null, ServiceContext.LocalizationService, ServiceContext.ContentService, content.Id, content.Path,
+ new Uri("http://domain1.fr/"));
+ Assert.AreEqual("fr-FR", culture.Name);
+
+ content = c4;
+ culture = Web.Models.ContentExtensions.GetCulture(null, ServiceContext.LocalizationService, ServiceContext.ContentService, content.Id, content.Path,
+ new Uri("http://domain1.fr/"));
+ Assert.AreEqual("de-DE", culture.Name);
+ }
+ }
+}
diff --git a/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs b/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs
index 27b00cf676..600830607c 100644
--- a/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs
+++ b/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs
@@ -3,10 +3,12 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
+using Umbraco.Core.Models;
using Umbraco.Tests.TestHelpers;
+using Umbraco.Web;
using Umbraco.Web.Routing;
using umbraco.cms.businesslogic.web;
-using umbraco.cms.businesslogic.language;
+using Language = umbraco.cms.businesslogic.language.Language;
namespace Umbraco.Tests.Routing
{
@@ -14,6 +16,13 @@ namespace Umbraco.Tests.Routing
[TestFixture]
class DomainsAndCulturesTests : BaseRoutingTest
{
+ protected override void FreezeResolution()
+ {
+ SiteDomainHelperResolver.Current = new SiteDomainHelperResolver(new SiteDomainHelper());
+
+ base.FreezeResolution();
+ }
+
public override void Initialize()
{
base.Initialize();
@@ -235,5 +244,32 @@ namespace Umbraco.Tests.Routing
Assert.AreEqual(expectedCulture, pcr.Culture.Name);
Assert.AreEqual(pcr.PublishedContent.Id, expectedNode);
}
+
+ #region Cases
+ [TestCase(10011, "http://domain1.com/", "en-US")]
+ [TestCase(100111, "http://domain1.com/", "en-US")]
+ [TestCase(10011, "http://domain1.fr/", "fr-FR")]
+ [TestCase(100111, "http://domain1.fr/", "fr-FR")]
+ [TestCase(1001121, "http://domain1.fr/", "de-DE")]
+ #endregion
+ public void GetCulture(int nodeId, string currentUrl, string expectedCulture)
+ {
+ var langEn = Language.GetByCultureCode("en-US");
+ var langFr = Language.GetByCultureCode("fr-FR");
+ var langDe = Language.GetByCultureCode("de-DE");
+
+ Domain.MakeNew("domain1.com/", 1001, langEn.id);
+ Domain.MakeNew("domain1.fr/", 1001, langFr.id);
+ Domain.MakeNew("*100112", 100112, langDe.id);
+
+ var routingContext = GetRoutingContext("http://anything/");
+ var umbracoContext = routingContext.UmbracoContext;
+
+ var content = umbracoContext.ContentCache.GetById(nodeId);
+ Assert.IsNotNull(content);
+
+ var culture = Web.Models.ContentExtensions.GetCulture(umbracoContext, null, null, content.Id, content.Path, new Uri(currentUrl));
+ Assert.AreEqual(expectedCulture, culture.Name);
+ }
}
}
diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj
index ef316f9e1a..4ad0fc29d1 100644
--- a/src/Umbraco.Tests/Umbraco.Tests.csproj
+++ b/src/Umbraco.Tests/Umbraco.Tests.csproj
@@ -170,6 +170,7 @@
+
diff --git a/src/Umbraco.Web/Models/ContentExtensions.cs b/src/Umbraco.Web/Models/ContentExtensions.cs
index ae93f13c7b..088f5b7646 100644
--- a/src/Umbraco.Web/Models/ContentExtensions.cs
+++ b/src/Umbraco.Web/Models/ContentExtensions.cs
@@ -1,6 +1,7 @@
using System;
using System.Globalization;
using System.Linq;
+using umbraco.cms.businesslogic.web;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
@@ -21,6 +22,7 @@ namespace Umbraco.Web.Models
{
return GetCulture(UmbracoContext.Current,
ApplicationContext.Current.Services.LocalizationService,
+ ApplicationContext.Current.Services.ContentService,
content.Id, content.Path,
current);
}
@@ -31,30 +33,62 @@ namespace Umbraco.Web.Models
///
/// An instance.
/// An implementation.
+ /// An implementation.
/// The content identifier.
/// The content path.
/// The request Uri.
/// The culture that would be selected to render the content.
- internal static CultureInfo GetCulture(UmbracoContext umbracoContext, ILocalizationService localizationService,
+ internal static CultureInfo GetCulture(UmbracoContext umbracoContext, ILocalizationService localizationService, IContentService contentService,
int contentId, string contentPath, Uri current)
{
- var route = umbracoContext.ContentCache.GetRouteById(contentId); // cached
- var pos = route.IndexOf('/');
+ var route = umbracoContext == null
+ ? null // for tests only
+ : umbracoContext.ContentCache.GetRouteById(contentId); // cached
- var domain = pos == 0
- ? null
- : DomainHelper.DomainForNode(int.Parse(route.Substring(0, pos)), current).Domain;
+ Domain domain;
+
+ if (route == null)
+ {
+ // if content is not published then route is null and we have to work
+ // on non-published content (note: could optimize by checking routes?)
+
+ var content = contentService.GetById(contentId);
+ if (content == null)
+ return GetDefaultCulture(localizationService);
+
+ var hasDomain = DomainHelper.NodeHasDomains(content.Id);
+ while (hasDomain == false && content != null)
+ {
+ content = content.Parent();
+ hasDomain = content != null && DomainHelper.NodeHasDomains(content.Id);
+ }
+
+ domain = hasDomain ? DomainHelper.DomainForNode(content.Id, current).Domain : null;
+ }
+ else
+ {
+ // if content is published then we have a (cached) route
+ // from which we can figure out the domain
+
+ var pos = route.IndexOf('/');
+ domain = pos == 0
+ ? null
+ : DomainHelper.DomainForNode(int.Parse(route.Substring(0, pos)), current).Domain;
+ }
if (domain == null)
- {
- var defaultLanguage = localizationService.GetAllLanguages().FirstOrDefault();
- return defaultLanguage == null ? CultureInfo.CurrentUICulture : new CultureInfo(defaultLanguage.IsoCode);
- }
+ return GetDefaultCulture(localizationService);
var wcDomain = DomainHelper.FindWildcardDomainInPath(DomainHelper.GetAllDomains(true), contentPath, domain.RootNodeId);
return wcDomain == null
? new CultureInfo(domain.Language.CultureAlias)
: new CultureInfo(wcDomain.Language.CultureAlias);
}
+
+ private static CultureInfo GetDefaultCulture(ILocalizationService localizationService)
+ {
+ var defaultLanguage = localizationService.GetAllLanguages().FirstOrDefault();
+ return defaultLanguage == null ? CultureInfo.CurrentUICulture : new CultureInfo(defaultLanguage.IsoCode);
+ }
}
}
diff --git a/src/Umbraco.Web/PublishedContentExtensions.cs b/src/Umbraco.Web/PublishedContentExtensions.cs
index 5e750e3f2b..b855139a3c 100644
--- a/src/Umbraco.Web/PublishedContentExtensions.cs
+++ b/src/Umbraco.Web/PublishedContentExtensions.cs
@@ -1899,6 +1899,7 @@ namespace Umbraco.Web
{
return Models.ContentExtensions.GetCulture(UmbracoContext.Current,
ApplicationContext.Current.Services.LocalizationService,
+ ApplicationContext.Current.Services.ContentService,
content.Id, content.Path,
current);
}