From 16c9ca9e4b6ae2874dfd45b402cf176dd2f0dcfe Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 27 Jul 2015 12:53:09 +0200 Subject: [PATCH] Refactors IDomain model, simplifies it so that it doesn't contain references, simplifies the domain repository to no longer require lookups of content and languages, updates all other code referencing IDomain and now if a language lookup is required it is made when appropriate. --- src/Umbraco.Core/Models/IDomain.cs | 4 +- src/Umbraco.Core/Models/UmbracoDomain.cs | 36 +- .../Persistence/Mappers/DomainMapper.cs | 11 +- .../Repositories/DomainRepository.cs | 343 +++++------------- .../Persistence/RepositoryFactory.cs | 2 +- .../Integration/GetCultureTests.cs | 6 +- .../Repositories/DomainRepositoryTest.cs | 44 +-- .../ContentFinderByNiceUrlWithDomainsTests.cs | 14 +- .../Routing/DomainsAndCulturesTests.cs | 70 ++-- .../NiceUrlsProviderWithDomainsTests.cs | 34 +- .../Routing/UrlRoutingTestBase.cs | 26 +- .../Routing/UrlsWithNestedDomains.cs | 4 +- src/Umbraco.Web/Cache/DomainCacheRefresher.cs | 3 +- src/Umbraco.Web/Models/ContentExtensions.cs | 21 +- .../Routing/ContentFinderByLegacy404.cs | 3 +- src/Umbraco.Web/Routing/DomainAndUri.cs | 2 +- src/Umbraco.Web/Routing/DomainHelper.cs | 4 +- .../Routing/NotFoundHandlerHelper.cs | 14 +- .../Routing/PublishedContentRequestEngine.cs | 66 ++-- .../WebServices/DomainsApiController.cs | 12 +- .../umbraco.presentation/NotFoundHandlers.cs | 3 +- .../umbraco/dialogs/AssignDomain2.aspx.cs | 4 +- src/umbraco.cms/businesslogic/web/Domain.cs | 36 +- 23 files changed, 323 insertions(+), 439 deletions(-) diff --git a/src/Umbraco.Core/Models/IDomain.cs b/src/Umbraco.Core/Models/IDomain.cs index 9fb3e8019d..d7cea0f6a1 100644 --- a/src/Umbraco.Core/Models/IDomain.cs +++ b/src/Umbraco.Core/Models/IDomain.cs @@ -4,9 +4,9 @@ namespace Umbraco.Core.Models { public interface IDomain : IAggregateRoot, IRememberBeingDirty, ICanBeDirty { - ILanguage Language { get; set; } + int? LanguageId { get; set; } string DomainName { get; set; } - IContent RootContent { get; set; } + int? RootContentId { get; set; } bool IsWildcard { get; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/UmbracoDomain.cs b/src/Umbraco.Core/Models/UmbracoDomain.cs index 963535729c..3252df0365 100644 --- a/src/Umbraco.Core/Models/UmbracoDomain.cs +++ b/src/Umbraco.Core/Models/UmbracoDomain.cs @@ -5,8 +5,6 @@ using Umbraco.Core.Models.EntityBase; namespace Umbraco.Core.Models { - //TODO: Need to custom serialize this - [Serializable] [DataContract(IsReference = true)] public class UmbracoDomain : Entity, IDomain @@ -16,25 +14,26 @@ namespace Umbraco.Core.Models _domainName = domainName; } - private IContent _content; - private ILanguage _language; + private int? _contentId; + private int? _languageId; private string _domainName; - private static readonly PropertyInfo DefaultLanguageSelector = ExpressionHelper.GetPropertyInfo(x => x.Language); + private static readonly PropertyInfo ContentSelector = ExpressionHelper.GetPropertyInfo(x => x.RootContentId); + private static readonly PropertyInfo DefaultLanguageSelector = ExpressionHelper.GetPropertyInfo(x => x.LanguageId); private static readonly PropertyInfo DomainNameSelector = ExpressionHelper.GetPropertyInfo(x => x.DomainName); - private static readonly PropertyInfo ContentSelector = ExpressionHelper.GetPropertyInfo(x => x.RootContent); + [DataMember] - public ILanguage Language + public int? LanguageId { - get { return _language; } + get { return _languageId; } set { SetPropertyValueAndDetectChanges(o => { - _language = value; - return _language; - }, _language, DefaultLanguageSelector); + _languageId = value; + return _languageId; + }, _languageId, DefaultLanguageSelector); } } @@ -53,16 +52,16 @@ namespace Umbraco.Core.Models } [DataMember] - public IContent RootContent + public int? RootContentId { - get { return _content; } + get { return _contentId; } set { SetPropertyValueAndDetectChanges(o => { - _content = value; - return _content; - }, _content, ContentSelector); + _contentId = value; + return _contentId; + }, _contentId, ContentSelector); } } @@ -70,5 +69,10 @@ namespace Umbraco.Core.Models { get { return string.IsNullOrWhiteSpace(DomainName) || DomainName.StartsWith("*"); } } + + public string IsoCode + { + get { throw new NotImplementedException(); } + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Mappers/DomainMapper.cs b/src/Umbraco.Core/Persistence/Mappers/DomainMapper.cs index 63ae627c62..bc38f72dab 100644 --- a/src/Umbraco.Core/Persistence/Mappers/DomainMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/DomainMapper.cs @@ -5,7 +5,8 @@ using Umbraco.Core.Persistence.Repositories; namespace Umbraco.Core.Persistence.Mappers { - [MapperFor(typeof(DomainRepository.CacheableDomain))] + [MapperFor(typeof(IDomain))] + [MapperFor(typeof(UmbracoDomain))] public sealed class DomainMapper : BaseMapper { private static readonly ConcurrentDictionary PropertyInfoCacheInstance = new ConcurrentDictionary(); @@ -22,10 +23,10 @@ namespace Umbraco.Core.Persistence.Mappers internal override void BuildMap() { - CacheMap(src => src.Id, dto => dto.Id); - CacheMap(src => src.RootContentId, dto => dto.RootStructureId); - CacheMap(src => src.DefaultLanguageId, dto => dto.DefaultLanguage); - CacheMap(src => src.DomainName, dto => dto.DomainName); + CacheMap(src => src.Id, dto => dto.Id); + CacheMap(src => src.RootContentId, dto => dto.RootStructureId); + CacheMap(src => src.LanguageId, dto => dto.DefaultLanguage); + CacheMap(src => src.DomainName, dto => dto.DomainName); } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/DomainRepository.cs b/src/Umbraco.Core/Persistence/Repositories/DomainRepository.cs index 9e1ccb01a7..a7451a77d5 100644 --- a/src/Umbraco.Core/Persistence/Repositories/DomainRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/DomainRepository.cs @@ -16,48 +16,42 @@ namespace Umbraco.Core.Persistence.Repositories { internal class DomainRepository : PetaPocoRepositoryBase, IDomainRepository { - private readonly IContentRepository _contentRepository; - private readonly ILanguageRepository _languageRepository; + private readonly RepositoryCacheOptions _cacheOptions; - public DomainRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IContentRepository contentRepository, ILanguageRepository languageRepository) + public DomainRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax) : base(work, cache, logger, sqlSyntax) { - _contentRepository = contentRepository; - _languageRepository = languageRepository; + //Custom cache options for better performance + _cacheOptions = new RepositoryCacheOptions + { + GetAllCacheAllowZeroCount = true, + GetAllCacheValidateCount = false + }; } /// - /// Override the cache, this repo will not perform any cache, the caching is taken care of in the inner repository + /// Returns the repository cache options /// - /// - /// This is required because IDomain is a deep object and we dont' want to cache it since it contains an ILanguage and an IContent, when these - /// are deep cloned the object graph that will be cached will be huge. Instead we'll have an internal repository that caches the simple - /// Domain structure and we'll use the other repositories to resolve the entities to attach - /// - protected override IRuntimeCacheProvider RuntimeCache + protected override RepositoryCacheOptions RepositoryCacheOptions { - get { return new NullCacheProvider(); } + get { return _cacheOptions; } } protected override IDomain PerformGet(int id) { - using (var repo = new CachedDomainRepository(this, UnitOfWork, RepositoryCache, Logger, SqlSyntax)) - { - var factory = new DomainModelFactory(); - return factory.BuildDomainEntity(repo.Get(id), _contentRepository, _languageRepository); - } + //use the underlying GetAll which will force cache all domains + return GetAll().FirstOrDefault(x => x.Id == id); } protected override IEnumerable PerformGetAll(params int[] ids) { - using (var repo = new CachedDomainRepository(this, UnitOfWork, RepositoryCache, Logger, SqlSyntax)) + var sql = GetBaseQuery(false).Where("umbracoDomains.id > 0"); + if (ids.Any()) { - var factory = new DomainModelFactory(); - return factory.BuildDomainEntities( - ids.Length == 0 ? Enumerable.Empty().ToArray() : repo.GetAll(ids).ToArray(), - _contentRepository, - _languageRepository); + sql.Where("umbracoDomains.id in (@ids)", new { ids = ids }); } + + return Database.Fetch(sql).Select(ConvertFromDto); } protected override IEnumerable PerformGetByQuery(IQuery query) @@ -77,18 +71,13 @@ namespace Umbraco.Core.Persistence.Repositories return "umbracoDomains.id = @Id"; } - protected override void PersistDeletedItem(IDomain entity) - { - using (var repo = new CachedDomainRepository(this, UnitOfWork, RepositoryCache, Logger, SqlSyntax)) - { - var factory = new DomainModelFactory(); - repo.PersistDeletedItem(factory.BuildEntity(entity)); - } - } - protected override IEnumerable GetDeleteClauses() { - throw new NotImplementedException(); + var list = new List + { + "DELETE FROM umbracoDomains WHERE id = @Id" + }; + return list; } protected override Guid NodeObjectTypeId @@ -98,269 +87,105 @@ namespace Umbraco.Core.Persistence.Repositories protected override void PersistNewItem(IDomain entity) { - using (var repo = new CachedDomainRepository(this, UnitOfWork, RepositoryCache, Logger, SqlSyntax)) + var exists = Database.ExecuteScalar("SELECT COUNT(*) FROM umbracoDomains WHERE domainName = @domainName", new { domainName = entity.DomainName }); + if (exists > 0) throw new DuplicateNameException(string.Format("The domain name {0} is already assigned", entity.DomainName)); + + if (entity.RootContentId.HasValue) { - var factory = new DomainModelFactory(); - var cacheableEntity = factory.BuildEntity(entity); - repo.PersistNewItem(cacheableEntity); - //re-map the id - entity.Id = cacheableEntity.Id; - entity.ResetDirtyProperties(); + var contentExists = Database.ExecuteScalar("SELECT COUNT(*) FROM cmsContent WHERE nodeId = @id", new { id = entity.RootContentId.Value }); + if (contentExists == 0) throw new NullReferenceException("No content exists with id " + entity.RootContentId.Value); } + + if (entity.LanguageId.HasValue) + { + var languageExists = Database.ExecuteScalar("SELECT COUNT(*) FROM umbracoLanguage WHERE id = @id", new { id = entity.LanguageId.Value }); + if (languageExists == 0) throw new NullReferenceException("No language exists with id " + entity.LanguageId.Value); + } + + ((UmbracoDomain)entity).AddingEntity(); + + var factory = new DomainModelFactory(); + var dto = factory.BuildDto(entity); + + var id = Convert.ToInt32(Database.Insert(dto)); + entity.Id = id; + + entity.ResetDirtyProperties(); } protected override void PersistUpdatedItem(IDomain entity) { - using (var repo = new CachedDomainRepository(this, UnitOfWork, RepositoryCache, Logger, SqlSyntax)) + ((UmbracoDomain)entity).UpdatingEntity(); + + var exists = Database.ExecuteScalar("SELECT COUNT(*) FROM umbracoDomains WHERE domainName = @domainName AND umbracoDomains.id <> @id", + new { domainName = entity.DomainName, id = entity.Id }); + //ensure there is no other domain with the same name on another entity + if (exists > 0) throw new DuplicateNameException(string.Format("The domain name {0} is already assigned", entity.DomainName)); + + if (entity.RootContentId.HasValue) { - var factory = new DomainModelFactory(); - repo.PersistUpdatedItem(factory.BuildEntity(entity)); - entity.ResetDirtyProperties(); + var contentExists = Database.ExecuteScalar("SELECT COUNT(*) FROM cmsContent WHERE nodeId = @id", new { id = entity.RootContentId.Value }); + if (contentExists == 0) throw new NullReferenceException("No content exists with id " + entity.RootContentId.Value); } + + if (entity.LanguageId.HasValue) + { + var languageExists = Database.ExecuteScalar("SELECT COUNT(*) FROM umbracoLanguage WHERE id = @id", new { id = entity.LanguageId.Value }); + if (languageExists == 0) throw new NullReferenceException("No language exists with id " + entity.LanguageId.Value); + } + + var factory = new DomainModelFactory(); + var dto = factory.BuildDto(entity); + + Database.Update(dto); + + entity.ResetDirtyProperties(); } public IDomain GetByName(string domainName) { - using (var repo = new CachedDomainRepository(this, UnitOfWork, RepositoryCache, Logger, SqlSyntax)) - { - var factory = new DomainModelFactory(); - return factory.BuildDomainEntity( - repo.GetAll().FirstOrDefault(x => x.DomainName.InvariantEquals(domainName)), - _contentRepository, _languageRepository); - } + return GetAll().FirstOrDefault(x => x.DomainName.InvariantEquals(domainName)); } public bool Exists(string domainName) { - using (var repo = new CachedDomainRepository(this, UnitOfWork, RepositoryCache, Logger, SqlSyntax)) - { - return repo.GetAll().Any(x => x.DomainName.InvariantEquals(domainName)); - } + return GetAll().Any(x => x.DomainName.InvariantEquals(domainName)); } public IEnumerable GetAll(bool includeWildcards) { - using (var repo = new CachedDomainRepository(this, UnitOfWork, RepositoryCache, Logger, SqlSyntax)) - { - var factory = new DomainModelFactory(); - return factory.BuildDomainEntities(repo.GetAll().ToArray(), _contentRepository, _languageRepository) - .Where(x => includeWildcards || x.IsWildcard == false); - } + return GetAll().Where(x => includeWildcards || x.IsWildcard == false); } public IEnumerable GetAssignedDomains(int contentId, bool includeWildcards) { - using (var repo = new CachedDomainRepository(this, UnitOfWork, RepositoryCache, Logger, SqlSyntax)) - { - var factory = new DomainModelFactory(); - - return factory.BuildDomainEntities( - repo.GetAll().Where(x => x.RootContentId == contentId).ToArray(), - _contentRepository, _languageRepository) - .Where(x => includeWildcards || x.IsWildcard == false); - } + return GetAll() + .Where(x => x.RootContentId == contentId) + .Where(x => includeWildcards || x.IsWildcard == false); } - /// - /// Dispose disposable properties - /// - /// - /// Ensure the unit of work is disposed - /// - protected override void DisposeResources() + private IDomain ConvertFromDto(DomainDto dto) { - _contentRepository.Dispose(); - _languageRepository.Dispose(); - } - - /// - /// A simple domain model that is cacheable without a large object graph - /// - internal class CacheableDomain : Entity, IAggregateRoot - { - public int? DefaultLanguageId { get; set; } - public string DomainName { get; set; } - public int? RootContentId { get; set; } - } - - /// - /// Inner repository responsible for CRUD for domains that allows caching simple data - /// - /// - /// Since there's never very many domains, any query against this repo, should query against the result of GetAll - /// - private class CachedDomainRepository : PetaPocoRepositoryBase - { - private readonly DomainRepository _domainRepo; - private readonly RepositoryCacheOptions _cacheOptions; - - public CachedDomainRepository(DomainRepository domainRepo, IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax) - : base(work, cache, logger, sqlSyntax) - { - _domainRepo = domainRepo; - - //Custom cache options for better performance - _cacheOptions = new RepositoryCacheOptions - { - GetAllCacheAllowZeroCount = true, - GetAllCacheValidateCount = false - }; - } - - /// - /// Returns the repository cache options - /// - protected override RepositoryCacheOptions RepositoryCacheOptions - { - get { return _cacheOptions; } - } - - protected override CacheableDomain PerformGet(int id) - { - //use the underlying GetAll which will force cache all domains - return GetAll().FirstOrDefault(x => x.Id == id); - } - - protected override IEnumerable PerformGetAll(params int[] ids) - { - var sql = GetBaseQuery(false).Where("umbracoDomains.id > 0"); - if (ids.Any()) - { - sql.Where("umbracoDomains.id in (@ids)", new { ids = ids }); - } - - return Database.Fetch(sql).Select(ConvertFromDto); - } - - protected override IEnumerable PerformGetByQuery(IQuery query) - { - throw new NotSupportedException("This repository does not support this method"); - } - - protected override Sql GetBaseQuery(bool isCount) - { - return _domainRepo.GetBaseQuery(isCount); - } - - protected override string GetBaseWhereClause() - { - return _domainRepo.GetBaseWhereClause(); - } - - protected override IEnumerable GetDeleteClauses() - { - var list = new List - { - "DELETE FROM umbracoDomains WHERE id = @Id" - }; - return list; - } - - protected override Guid NodeObjectTypeId - { - get { throw new NotImplementedException(); } - } - - protected override void PersistNewItem(CacheableDomain entity) - { - var exists = Database.ExecuteScalar("SELECT COUNT(*) FROM umbracoDomains WHERE domainName = @domainName", new { domainName = entity.DomainName }); - if (exists > 0) throw new DuplicateNameException(string.Format("The domain name {0} is already assigned", entity.DomainName)); - - entity.AddingEntity(); - - var factory = new DomainModelFactory(); - var dto = factory.BuildDto(entity); - - var id = Convert.ToInt32(Database.Insert(dto)); - entity.Id = id; - - entity.ResetDirtyProperties(); - } - - protected override void PersistUpdatedItem(CacheableDomain entity) - { - entity.UpdatingEntity(); - - var factory = new DomainModelFactory(); - var dto = factory.BuildDto(entity); - - Database.Update(dto); - - entity.ResetDirtyProperties(); - } - - private CacheableDomain ConvertFromDto(DomainDto dto) - { - var factory = new DomainModelFactory(); - var entity = factory.BuildEntity(dto); - return entity; - } - } + var factory = new DomainModelFactory(); + var entity = factory.BuildEntity(dto); + return entity; + } internal class DomainModelFactory { - public IEnumerable BuildDomainEntities(CacheableDomain[] cacheableDomains, IContentRepository contentRepository, ILanguageRepository languageRepository) + + public IDomain BuildEntity(DomainDto dto) { - var contentIds = cacheableDomains.Select(x => x.RootContentId).Where(x => x.HasValue).Select(x => x.Value).Distinct().ToArray(); - var langIds = cacheableDomains.Select(x => x.DefaultLanguageId).Where(x => x.HasValue).Select(x => x.Value).Distinct().ToArray(); - - //Ensure to not look anything up if there are no items, otherwise this will look up ALL items!!! :( which would be terrible - var contentItems = contentIds.Length == 0 ? Enumerable.Empty() : contentRepository.GetAll(contentIds); - var langItems = langIds.Length == 0 ? Enumerable.Empty(): languageRepository.GetAll(langIds); - - return cacheableDomains - .WhereNotNull() - .Select(cacheableDomain => new UmbracoDomain(cacheableDomain.DomainName) - { - Id = cacheableDomain.Id, - //lookup from repo - this will be cached - Language = cacheableDomain.DefaultLanguageId.HasValue ? langItems.FirstOrDefault(l => l.Id == cacheableDomain.DefaultLanguageId.Value) : null, - //lookup from repo - this will be cached - RootContent = cacheableDomain.RootContentId.HasValue ? contentItems.FirstOrDefault(l => l.Id == cacheableDomain.RootContentId.Value) : null, - }); - } - - public IDomain BuildDomainEntity(CacheableDomain cacheableDomain, IContentRepository contentRepository, ILanguageRepository languageRepository) - { - if (cacheableDomain == null) return null; - - return new UmbracoDomain(cacheableDomain.DomainName) - { - Id = cacheableDomain.Id, - //lookup from repo - this will be cached - Language = cacheableDomain.DefaultLanguageId.HasValue ? languageRepository.Get(cacheableDomain.DefaultLanguageId.Value) : null, - //lookup from repo - this will be cached - RootContent = cacheableDomain.RootContentId.HasValue ? contentRepository.Get(cacheableDomain.RootContentId.Value) : null - }; - } - - public CacheableDomain BuildEntity(IDomain entity) - { - var domain = new CacheableDomain - { - Id = entity.Id, - DefaultLanguageId = entity.Language == null ? null : (int?)entity.Language.Id, - DomainName = entity.DomainName, - RootContentId = entity.RootContent == null ? null : (int?)entity.RootContent.Id - }; + var domain = new UmbracoDomain(dto.DomainName) { 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; } - public CacheableDomain BuildEntity(DomainDto dto) + public DomainDto BuildDto(IDomain entity) { - var domain = new CacheableDomain { Id = dto.Id, DefaultLanguageId = dto.DefaultLanguage, DomainName = dto.DomainName, 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; - } - - public DomainDto BuildDto(CacheableDomain entity) - { - var dto = new DomainDto { DefaultLanguage = entity.DefaultLanguageId, DomainName = entity.DomainName, Id = entity.Id, RootStructureId = entity.RootContentId }; + var dto = new DomainDto { DefaultLanguage = entity.LanguageId, DomainName = entity.DomainName, Id = entity.Id, RootStructureId = entity.RootContentId }; return dto; } } diff --git a/src/Umbraco.Core/Persistence/RepositoryFactory.cs b/src/Umbraco.Core/Persistence/RepositoryFactory.cs index 19556b1f31..bb213eb50f 100644 --- a/src/Umbraco.Core/Persistence/RepositoryFactory.cs +++ b/src/Umbraco.Core/Persistence/RepositoryFactory.cs @@ -294,7 +294,7 @@ namespace Umbraco.Core.Persistence public IDomainRepository CreateDomainRepository(IDatabaseUnitOfWork uow) { - return new DomainRepository(uow, _cacheHelper, _logger, _sqlSyntax, CreateContentRepository(uow), CreateLanguageRepository(uow)); + return new DomainRepository(uow, _cacheHelper, _logger, _sqlSyntax); } public ITaskTypeRepository CreateTaskTypeRepository(IDatabaseUnitOfWork uow) diff --git a/src/Umbraco.Tests/Integration/GetCultureTests.cs b/src/Umbraco.Tests/Integration/GetCultureTests.cs index 977e0f313e..0b630b9a41 100644 --- a/src/Umbraco.Tests/Integration/GetCultureTests.cs +++ b/src/Umbraco.Tests/Integration/GetCultureTests.cs @@ -51,9 +51,9 @@ namespace Umbraco.Tests.Integration foreach (var d in ServiceContext.DomainService.GetAll(true).ToArray()) ServiceContext.DomainService.Delete(d); - ServiceContext.DomainService.Save(new UmbracoDomain("domain1.com") {DomainName="domain1.com", RootContent = c1, Language = l0}); - ServiceContext.DomainService.Save(new UmbracoDomain("domain1.fr") { DomainName = "domain1.fr", RootContent = c1, Language = l1 }); - ServiceContext.DomainService.Save(new UmbracoDomain("*100112") { DomainName = "*100112", RootContent = c3, Language = l2 }); + ServiceContext.DomainService.Save(new UmbracoDomain("domain1.com") {DomainName="domain1.com", RootContentId = c1.Id, LanguageId = l0.Id}); + ServiceContext.DomainService.Save(new UmbracoDomain("domain1.fr") { DomainName = "domain1.fr", RootContentId = c1.Id, LanguageId = l1.Id }); + ServiceContext.DomainService.Save(new UmbracoDomain("*100112") { DomainName = "*100112", RootContentId = c3.Id, LanguageId = l2.Id }); var content = c2; var culture = Web.Models.ContentExtensions.GetCulture(null, diff --git a/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs index 08fae6d3ef..d53959f37c 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs @@ -27,7 +27,7 @@ namespace Umbraco.Tests.Persistence.Repositories contentTypeRepository = new ContentTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, SqlSyntax, templateRepository); contentRepository = new ContentRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, SqlSyntax, contentTypeRepository, templateRepository, tagRepository, Mock.Of()); languageRepository = new LanguageRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, SqlSyntax); - var domainRepository = new DomainRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, SqlSyntax, contentRepository, languageRepository); + var domainRepository = new DomainRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, SqlSyntax); return domainRepository; } @@ -72,7 +72,7 @@ namespace Umbraco.Tests.Persistence.Repositories var lang = langRepo.GetByIsoCode("en-AU"); var content = contentRepo.Get(contentId); - var domain = (IDomain)new UmbracoDomain("test.com") { RootContent = content, Language = lang }; + var domain = (IDomain)new UmbracoDomain("test.com") { RootContentId = content.Id, LanguageId = lang.Id }; repo.AddOrUpdate(domain); unitOfWork.Commit(); @@ -83,8 +83,8 @@ namespace Umbraco.Tests.Persistence.Repositories Assert.IsTrue(domain.HasIdentity); Assert.Greater(domain.Id, 0); Assert.AreEqual("test.com", domain.DomainName); - Assert.AreEqual(content.Id, domain.RootContent.Id); - Assert.AreEqual(lang.Id, domain.Language.Id); + Assert.AreEqual(content.Id, domain.RootContentId); + Assert.AreEqual(lang.Id, domain.LanguageId); } @@ -108,11 +108,11 @@ namespace Umbraco.Tests.Persistence.Repositories var lang = langRepo.GetByIsoCode("en-AU"); var content = contentRepo.Get(contentId); - var domain1 = (IDomain)new UmbracoDomain("test.com") { RootContent = content, Language = lang }; + var domain1 = (IDomain)new UmbracoDomain("test.com") { RootContentId = content.Id, LanguageId = lang.Id }; repo.AddOrUpdate(domain1); unitOfWork.Commit(); - var domain2 = (IDomain)new UmbracoDomain("test.com") { RootContent = content, Language = lang }; + var domain2 = (IDomain)new UmbracoDomain("test.com") { RootContentId = content.Id, LanguageId = lang.Id }; repo.AddOrUpdate(domain2); Assert.Throws(unitOfWork.Commit); @@ -141,7 +141,7 @@ namespace Umbraco.Tests.Persistence.Repositories var lang = langRepo.GetByIsoCode("en-AU"); var content = contentRepo.Get(contentId); - var domain = (IDomain)new UmbracoDomain("test.com") { RootContent = content, Language = lang }; + var domain = (IDomain)new UmbracoDomain("test.com") { RootContentId = content.Id, LanguageId = lang.Id }; repo.AddOrUpdate(domain); unitOfWork.Commit(); @@ -184,7 +184,7 @@ namespace Umbraco.Tests.Persistence.Repositories unitOfWork.Commit(); - var domain = (IDomain)new UmbracoDomain("test.com") { RootContent = content1, Language = lang1 }; + var domain = (IDomain)new UmbracoDomain("test.com") { RootContentId = content1.Id, LanguageId = lang1.Id }; repo.AddOrUpdate(domain); unitOfWork.Commit(); @@ -192,8 +192,8 @@ namespace Umbraco.Tests.Persistence.Repositories domain = repo.Get(domain.Id); domain.DomainName = "blah.com"; - domain.RootContent = content2; - domain.Language = lang2; + domain.RootContentId = content2.Id; + domain.LanguageId = lang2.Id; repo.AddOrUpdate(domain); unitOfWork.Commit(); @@ -201,8 +201,8 @@ namespace Umbraco.Tests.Persistence.Repositories domain = repo.Get(domain.Id); Assert.AreEqual("blah.com", domain.DomainName); - Assert.AreEqual(content2.Id, domain.RootContent.Id); - Assert.AreEqual(lang2.Id, domain.Language.Id); + Assert.AreEqual(content2.Id, domain.RootContentId); + Assert.AreEqual(lang2.Id, domain.LanguageId); } @@ -228,7 +228,7 @@ namespace Umbraco.Tests.Persistence.Repositories for (int i = 0; i < 10; i++) { - var domain = (IDomain)new UmbracoDomain("test" + i + ".com") { RootContent = content, Language = lang }; + var domain = (IDomain)new UmbracoDomain("test" + i + ".com") { RootContentId = content.Id, LanguageId = lang.Id }; repo.AddOrUpdate(domain); unitOfWork.Commit(); } @@ -259,7 +259,7 @@ namespace Umbraco.Tests.Persistence.Repositories for (int i = 0; i < 10; i++) { - var domain = (IDomain)new UmbracoDomain("test" + i + ".com") { RootContent = content, Language = lang }; + var domain = (IDomain)new UmbracoDomain("test" + i + ".com") { RootContentId = content.Id, LanguageId = lang.Id }; repo.AddOrUpdate(domain); unitOfWork.Commit(); } @@ -290,7 +290,7 @@ namespace Umbraco.Tests.Persistence.Repositories for (int i = 0; i < 10; i++) { - var domain = (IDomain)new UmbracoDomain("test " + i + ".com") { RootContent = content, Language = lang }; + var domain = (IDomain)new UmbracoDomain("test " + i + ".com") { RootContentId = content.Id, LanguageId = lang.Id }; repo.AddOrUpdate(domain); unitOfWork.Commit(); } @@ -322,7 +322,7 @@ namespace Umbraco.Tests.Persistence.Repositories var ids = new List(); for (int i = 0; i < 10; i++) { - var domain = (IDomain)new UmbracoDomain("test " + i + ".com") { RootContent = content, Language = lang }; + var domain = (IDomain)new UmbracoDomain("test " + i + ".com") { RootContentId = content.Id, LanguageId = lang.Id }; repo.AddOrUpdate(domain); unitOfWork.Commit(); ids.Add(domain.Id); @@ -356,8 +356,8 @@ namespace Umbraco.Tests.Persistence.Repositories { var domain = (IDomain)new UmbracoDomain((i % 2 == 0) ? "test " + i + ".com" : ("*" + i)) { - RootContent = content, - Language = lang + RootContentId = content.Id, + LanguageId = lang.Id }; repo.AddOrUpdate(domain); unitOfWork.Commit(); @@ -402,8 +402,8 @@ namespace Umbraco.Tests.Persistence.Repositories { var domain = (IDomain)new UmbracoDomain((i % 2 == 0) ? "test " + i + ".com" : ("*" + i)) { - RootContent = (i % 2 == 0) ? contentItems[0] : contentItems[1], - Language = lang + RootContentId = ((i % 2 == 0) ? contentItems[0] : contentItems[1]).Id, + LanguageId = lang.Id }; repo.AddOrUpdate(domain); unitOfWork.Commit(); @@ -453,8 +453,8 @@ namespace Umbraco.Tests.Persistence.Repositories { var domain = (IDomain)new UmbracoDomain((i % 2 == 0) ? "test " + i + ".com" : ("*" + i)) { - RootContent = (i % 2 == 0) ? contentItems[0] : contentItems[1], - Language = lang + RootContentId = ((i % 2 == 0) ? contentItems[0] : contentItems[1]).Id, + LanguageId = lang.Id }; repo.AddOrUpdate(domain); unitOfWork.Commit(); diff --git a/src/Umbraco.Tests/Routing/ContentFinderByNiceUrlWithDomainsTests.cs b/src/Umbraco.Tests/Routing/ContentFinderByNiceUrlWithDomainsTests.cs index 9b23b1c5e8..ea6e096fbf 100644 --- a/src/Umbraco.Tests/Routing/ContentFinderByNiceUrlWithDomainsTests.cs +++ b/src/Umbraco.Tests/Routing/ContentFinderByNiceUrlWithDomainsTests.cs @@ -13,7 +13,7 @@ namespace Umbraco.Tests.Routing { SetupDomainServiceMock(new[] { - new UmbracoDomain("domain1.com/") {Id = 1, Language = new Language("de-DE"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 1001}} + new UmbracoDomain("domain1.com/") {Id = 1, LanguageId = LangDeId, RootContentId = 1001} }); } @@ -22,12 +22,12 @@ namespace Umbraco.Tests.Routing { SetupDomainServiceMock(new[] { - new UmbracoDomain("domain1.com/") {Id = 1, Language = new Language("en-US"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 1001}}, - new UmbracoDomain("domain1.com/en") {Id = 1, Language = new Language("en-US"), RootContent = new Content("test2", -1, new ContentType(-1)) {Id = 10011}}, - new UmbracoDomain("domain1.com/fr") {Id = 1, Language = new Language("fr-FR"), RootContent = new Content("test3", -1, new ContentType(-1)) {Id = 10012}}, - new UmbracoDomain("http://domain3.com/") {Id = 1, Language = new Language("en-US"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 1003}}, - new UmbracoDomain("http://domain3.com/en") {Id = 1, Language = new Language("en-US"), RootContent = new Content("test2", -1, new ContentType(-1)) {Id = 10031}}, - new UmbracoDomain("http://domain3.com/fr") {Id = 1, Language = new Language("fr-FR"), RootContent = new Content("test3", -1, new ContentType(-1)) {Id = 10032}} + new UmbracoDomain("domain1.com/") {Id = 1, LanguageId = LangEngId, RootContentId = 1001}, + new UmbracoDomain("domain1.com/en") {Id = 1, LanguageId = LangEngId, RootContentId = 10011}, + new UmbracoDomain("domain1.com/fr") {Id = 1, LanguageId = LangFrId, RootContentId = 10012}, + new UmbracoDomain("http://domain3.com/") {Id = 1, LanguageId = LangEngId, RootContentId = 1003}, + new UmbracoDomain("http://domain3.com/en") {Id = 1, LanguageId = LangEngId, RootContentId = 10031}, + new UmbracoDomain("http://domain3.com/fr") {Id = 1, LanguageId = LangFrId, RootContentId = 10032} }); } diff --git a/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs b/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs index a11eef335f..6af00d6127 100644 --- a/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs +++ b/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs @@ -18,7 +18,7 @@ namespace Umbraco.Tests.Routing { protected override void FreezeResolution() { - SiteDomainHelperResolver.Current = new SiteDomainHelperResolver(new SiteDomainHelper()); + SiteDomainHelperResolver.Current = new SiteDomainHelperResolver(new SiteDomainHelper()); base.FreezeResolution(); } @@ -29,20 +29,20 @@ namespace Umbraco.Tests.Routing new UmbracoDomain("domain1.com/") { Id = 1, - Language = new Language("de-DE"), - RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 1001} + LanguageId = LangDeId, + RootContentId = 1001 }, new UmbracoDomain("domain1.com/en") { Id = 1, - Language = new Language("en-US"), - RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10011} + LanguageId = LangEngId, + RootContentId = 10011 }, new UmbracoDomain("domain1.com/fr") { Id = 1, - Language = new Language("fr-FR"), - RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10012} + LanguageId = LangFrId, + RootContentId = 10012 } }); } @@ -54,56 +54,56 @@ namespace Umbraco.Tests.Routing new UmbracoDomain("domain1.com/") { Id = 1, - Language = new Language("de-DE"), - RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 1001} + LanguageId = LangDeId, + RootContentId = 1001 }, new UmbracoDomain("domain1.com/en") { Id = 1, - Language = new Language("en-US"), - RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10011} + LanguageId = LangEngId, + RootContentId = 10011 }, new UmbracoDomain("domain1.com/fr") { Id = 1, - Language = new Language("fr-FR"), - RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10012} + LanguageId = LangFrId, + RootContentId = 10012 }, new UmbracoDomain("*1001") { Id = 1, - Language = new Language("de-DE"), - RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 1001} + LanguageId = LangDeId, + RootContentId = 1001 }, new UmbracoDomain("*10011") { Id = 1, - Language = new Language("cs-CZ"), - RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10011} + LanguageId = LangCzId, + RootContentId = 10011 }, new UmbracoDomain("*100112") { Id = 1, - Language = new Language("nl-NL"), - RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 100112} + LanguageId = LangNlId, + RootContentId = 100112 }, new UmbracoDomain("*1001122") { Id = 1, - Language = new Language("da-DK"), - RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 1001122} + LanguageId = LangDkId, + RootContentId = 1001122 }, new UmbracoDomain("*10012") { Id = 1, - Language = new Language("nl-NL"), - RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10012} + LanguageId = LangNlId, + RootContentId = 10012 }, new UmbracoDomain("*10031") { Id = 1, - Language = new Language("nl-NL"), - RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10031} + LanguageId = LangNlId, + RootContentId =10031 } }); } @@ -259,7 +259,7 @@ namespace Umbraco.Tests.Routing var routingContext = GetRoutingContext(inputUrl); var url = routingContext.UmbracoContext.CleanedUmbracoUrl; - //very important to use the cleaned up umbraco url + //very important to use the cleaned up umbraco url var pcr = new PublishedContentRequest(url, routingContext); // lookup domain @@ -307,7 +307,7 @@ namespace Umbraco.Tests.Routing var routingContext = GetRoutingContext(inputUrl); var url = routingContext.UmbracoContext.CleanedUmbracoUrl; - //very important to use the cleaned up umbraco url + //very important to use the cleaned up umbraco url var pcr = new PublishedContentRequest(url, routingContext); // lookup domain @@ -326,7 +326,7 @@ namespace Umbraco.Tests.Routing Assert.AreEqual(pcr.PublishedContent.Id, expectedNode); } - + #region Cases [TestCase(10011, "http://domain1.com/", "en-US")] @@ -342,20 +342,20 @@ namespace Umbraco.Tests.Routing new UmbracoDomain("domain1.com/") { Id = 1, - Language = new Language("en-US"), - RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 1001} + LanguageId = LangEngId, + RootContentId = 1001 }, new UmbracoDomain("domain1.fr/") { Id = 1, - Language = new Language("fr-FR"), - RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 1001} + LanguageId = LangFrId, + RootContentId = 1001 }, new UmbracoDomain("*100112") { Id = 1, - Language = new Language("de-DE"), - RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 100112} + LanguageId = LangDeId, + RootContentId = 100112 } }); @@ -365,7 +365,7 @@ namespace Umbraco.Tests.Routing var content = umbracoContext.ContentCache.GetById(nodeId); Assert.IsNotNull(content); - var culture = Web.Models.ContentExtensions.GetCulture(umbracoContext, domainService, null, null, content.Id, content.Path, new Uri(currentUrl)); + var culture = Web.Models.ContentExtensions.GetCulture(umbracoContext, domainService, ServiceContext.LocalizationService, null, content.Id, content.Path, new Uri(currentUrl)); Assert.AreEqual(expectedCulture, culture.Name); } } diff --git a/src/Umbraco.Tests/Routing/NiceUrlsProviderWithDomainsTests.cs b/src/Umbraco.Tests/Routing/NiceUrlsProviderWithDomainsTests.cs index 3a64389104..ffbed3e2f4 100644 --- a/src/Umbraco.Tests/Routing/NiceUrlsProviderWithDomainsTests.cs +++ b/src/Umbraco.Tests/Routing/NiceUrlsProviderWithDomainsTests.cs @@ -28,7 +28,7 @@ namespace Umbraco.Tests.Routing SetupDomainServiceMock(new[] { - new UmbracoDomain("domain1.com") {Id = 1, Language = new Language("fr-FR"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 1001}} + new UmbracoDomain("domain1.com") {Id = 1, LanguageId = LangFrId, RootContentId = 1001} }); } @@ -36,7 +36,7 @@ namespace Umbraco.Tests.Routing { SetupDomainServiceMock(new[] { - new UmbracoDomain("http://domain1.com/foo") {Id = 1, Language = new Language("fr-FR"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 1001}} + new UmbracoDomain("http://domain1.com/foo") {Id = 1, LanguageId = LangFrId, RootContentId = 1001} }); } @@ -44,7 +44,7 @@ namespace Umbraco.Tests.Routing { SetupDomainServiceMock(new[] { - new UmbracoDomain("http://domain1.com/") {Id = 1, Language = new Language("fr-FR"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10011}} + new UmbracoDomain("http://domain1.com/") {Id = 1, LanguageId = LangFrId, RootContentId = 10011} }); } @@ -52,12 +52,12 @@ namespace Umbraco.Tests.Routing { SetupDomainServiceMock(new[] { - new UmbracoDomain("http://domain1.com/") {Id = 1, Language = new Language("en-US"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 1001}}, - new UmbracoDomain("http://domain1.com/en") {Id = 1, Language = new Language("en-US"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10011}}, - new UmbracoDomain("http://domain1.com/fr") {Id = 1, Language = new Language("fr-FR"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10012}}, - new UmbracoDomain("http://domain3.com/") {Id = 1, Language = new Language("en-US"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 1003}}, - new UmbracoDomain("http://domain3.com/en") {Id = 1, Language = new Language("en-US"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10031}}, - new UmbracoDomain("http://domain3.com/fr") {Id = 1, Language = new Language("fr-FR"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10032}} + new UmbracoDomain("http://domain1.com/") {Id = 1, LanguageId = LangEngId, RootContentId = 1001}, + new UmbracoDomain("http://domain1.com/en") {Id = 1, LanguageId = LangEngId, RootContentId = 10011}, + new UmbracoDomain("http://domain1.com/fr") {Id = 1, LanguageId = LangFrId, RootContentId = 10012}, + new UmbracoDomain("http://domain3.com/") {Id = 1, LanguageId = LangEngId, RootContentId = 1003}, + new UmbracoDomain("http://domain3.com/en") {Id = 1, LanguageId = LangEngId, RootContentId = 10031}, + new UmbracoDomain("http://domain3.com/fr") {Id = 1, LanguageId = LangFrId, RootContentId = 10032} }); } @@ -65,14 +65,14 @@ namespace Umbraco.Tests.Routing { SetupDomainServiceMock(new[] { - new UmbracoDomain("http://domain1.com/en") {Id = 1, Language = new Language("en-US"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10011}}, - new UmbracoDomain("http://domain1a.com/en") {Id = 1, Language = new Language("en-US"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10011}}, - new UmbracoDomain("http://domain1b.com/en") {Id = 1, Language = new Language("en-US"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10011}}, - new UmbracoDomain("http://domain1.com/fr") {Id = 1, Language = new Language("fr-FR"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10012}}, - new UmbracoDomain("http://domain1a.com/fr") {Id = 1, Language = new Language("fr-FR"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10012}}, - new UmbracoDomain("http://domain1b.com/fr") {Id = 1, Language = new Language("fr-FR"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10012}}, - new UmbracoDomain("http://domain3.com/en") {Id = 1, Language = new Language("en-US"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10031}}, - new UmbracoDomain("http://domain3.com/fr") {Id = 1, Language = new Language("fr-FR"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10032}} + new UmbracoDomain("http://domain1.com/en") {Id = 1, LanguageId = LangEngId, RootContentId = 10011}, + new UmbracoDomain("http://domain1a.com/en") {Id = 1, LanguageId = LangEngId, RootContentId = 10011}, + new UmbracoDomain("http://domain1b.com/en") {Id = 1, LanguageId = LangEngId, RootContentId = 10011}, + new UmbracoDomain("http://domain1.com/fr") {Id = 1, LanguageId = LangFrId, RootContentId = 10012}, + new UmbracoDomain("http://domain1a.com/fr") {Id = 1, LanguageId = LangFrId, RootContentId = 10012}, + new UmbracoDomain("http://domain1b.com/fr") {Id = 1, LanguageId = LangFrId, RootContentId = 10012}, + new UmbracoDomain("http://domain3.com/en") {Id = 1, LanguageId = LangEngId, RootContentId = 10031}, + new UmbracoDomain("http://domain3.com/fr") {Id = 1, LanguageId = LangFrId, RootContentId = 10032} }); } diff --git a/src/Umbraco.Tests/Routing/UrlRoutingTestBase.cs b/src/Umbraco.Tests/Routing/UrlRoutingTestBase.cs index 5802e023f0..643d007889 100644 --- a/src/Umbraco.Tests/Routing/UrlRoutingTestBase.cs +++ b/src/Umbraco.Tests/Routing/UrlRoutingTestBase.cs @@ -28,7 +28,7 @@ namespace Umbraco.Tests.Routing domainService.Setup(service => service.GetAll(It.IsAny())) .Returns((bool incWildcards) => incWildcards ? allDomains : allDomains.Where(d => d.IsWildcard == false)); domainService.Setup(service => service.GetAssignedDomains(It.IsAny(), It.IsAny())) - .Returns((int id, bool incWildcards) => allDomains.Where(d => d.RootContent.Id == id && (incWildcards || d.IsWildcard == false))); + .Returns((int id, bool incWildcards) => allDomains.Where(d => d.RootContentId == id && (incWildcards || d.IsWildcard == false))); return domainService.Object; } @@ -36,18 +36,36 @@ namespace Umbraco.Tests.Routing { //get the mocked service context to get the mocked domain service var svcCtx = MockHelper.GetMockedServiceContext(); + var domainService = Mock.Get(svcCtx.DomainService); //setup mock domain service domainService.Setup(service => service.GetAll(It.IsAny())) .Returns((bool incWildcards) => new[] { - new UmbracoDomain("domain1.com/"){Id = 1, Language = new Language("de-DE"), RootContent = new Content("test1", -1, new ContentType(-1)){ Id = 1001}}, - new UmbracoDomain("domain1.com/en"){Id = 1, Language = new Language("en-US"), RootContent = new Content("test2", -1, new ContentType(-1)){ Id = 10011}}, - new UmbracoDomain("domain1.com/fr"){Id = 1, Language = new Language("fr-FR"), RootContent = new Content("test3", -1, new ContentType(-1)){ Id = 10012}} + new UmbracoDomain("domain1.com/"){Id = 1, LanguageId = 333, RootContentId = 1001}, + new UmbracoDomain("domain1.com/en"){Id = 1, LanguageId = 334, RootContentId = 10011}, + new UmbracoDomain("domain1.com/fr"){Id = 1, LanguageId = 335, RootContentId = 10012} }); + + var langService = Mock.Get(svcCtx.LocalizationService); + //setup mock domain service + langService.Setup(service => service.GetLanguageById(LangDeId)).Returns(new Language("de-DE") {Id = LangDeId }); + langService.Setup(service => service.GetLanguageById(LangEngId)).Returns(new Language("en-US") { Id = LangEngId }); + langService.Setup(service => service.GetLanguageById(LangFrId)).Returns(new Language("fr-FR") { Id = LangFrId }); + langService.Setup(service => service.GetLanguageById(LangCzId)).Returns(new Language("cs-CZ") { Id = LangCzId }); + langService.Setup(service => service.GetLanguageById(LangNlId)).Returns(new Language("nl-NL") { Id = LangNlId }); + langService.Setup(service => service.GetLanguageById(LangDkId)).Returns(new Language("da-DK") { Id = LangDkId }); + return svcCtx; } + public const int LangDeId = 333; + public const int LangEngId = 334; + public const int LangFrId = 335; + public const int LangCzId = 336; + public const int LangNlId = 337; + public const int LangDkId = 338; + protected override void SetupApplicationContext() { var settings = SettingsForTests.GetDefault(); diff --git a/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs b/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs index 1378cd3547..79feac0b28 100644 --- a/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs +++ b/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs @@ -80,8 +80,8 @@ namespace Umbraco.Tests.Routing { SetupDomainServiceMock(new[] { - new UmbracoDomain("http://domain1.com/") {Id = 1, Language = new Language("en-US"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 1001}}, - new UmbracoDomain("http://domain2.com/") {Id = 1, Language = new Language("en-US"), RootContent = new Content("test1", -1, new ContentType(-1)) {Id = 10011}} + new UmbracoDomain("http://domain1.com/") {Id = 1, LanguageId = LangEngId, RootContentId = 1001}, + new UmbracoDomain("http://domain2.com/") {Id = 1, LanguageId = LangEngId, RootContentId = 10011} }); } diff --git a/src/Umbraco.Web/Cache/DomainCacheRefresher.cs b/src/Umbraco.Web/Cache/DomainCacheRefresher.cs index aabe95548f..51a2c79b2d 100644 --- a/src/Umbraco.Web/Cache/DomainCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/DomainCacheRefresher.cs @@ -1,6 +1,7 @@ using System; using Umbraco.Core; using Umbraco.Core.Cache; +using Umbraco.Core.Models; using Umbraco.Core.Persistence.Repositories; using Umbraco.Web.PublishedCache; using Umbraco.Web.PublishedCache.XmlPublishedCache; @@ -41,7 +42,7 @@ namespace Umbraco.Web.Cache private void ClearCache() { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); // SD: we need to clear the routes cache here! // diff --git a/src/Umbraco.Web/Models/ContentExtensions.cs b/src/Umbraco.Web/Models/ContentExtensions.cs index a832235bb0..4479555326 100644 --- a/src/Umbraco.Web/Models/ContentExtensions.cs +++ b/src/Umbraco.Web/Models/ContentExtensions.cs @@ -83,10 +83,23 @@ namespace Umbraco.Web.Models if (domain == null) return GetDefaultCulture(localizationService); - var wcDomain = DomainHelper.FindWildcardDomainInPath(domainService.GetAll(true), contentPath, domain.RootContent.Id); - return wcDomain == null - ? new CultureInfo(domain.Language.IsoCode) - : new CultureInfo(wcDomain.Language.IsoCode); + //NOTE: The domain service IDomain model has changed and no longer holds a reference to IContent or ILanguage to + // improve performance, this means that we need to lookup the language below, but this was already the case previously + // in the repository and since the language lookup is cached it should be ok. If we want however we could create + // another method on the DomainService to return domains with their culture info on them + var wcDomain = DomainHelper.FindWildcardDomainInPath(domainService.GetAll(true), contentPath, domain.RootContentId); + if (wcDomain != null && wcDomain.LanguageId.HasValue) + { + var lang = localizationService.GetLanguageById(wcDomain.LanguageId.Value); + if (lang != null) return new CultureInfo(lang.IsoCode); + } + else if (domain.LanguageId.HasValue) + { + var lang = localizationService.GetLanguageById(domain.LanguageId.Value); + if (lang != null) return new CultureInfo(lang.IsoCode); + } + + return GetDefaultCulture(localizationService); } private static CultureInfo GetDefaultCulture(ILocalizationService localizationService) diff --git a/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs b/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs index 22c4364891..aae16b5fa9 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs +++ b/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs @@ -28,7 +28,8 @@ namespace Umbraco.Web.Routing pcr.RoutingContext.UmbracoContext.HttpContext.Request.ServerVariables["SERVER_NAME"], pcr.RoutingContext.UmbracoContext.Application.Services.EntityService, new PublishedContentQuery(pcr.RoutingContext.UmbracoContext.ContentCache, pcr.RoutingContext.UmbracoContext.MediaCache), - pcr.RoutingContext.UmbracoContext.Application.Services.DomainService); + pcr.RoutingContext.UmbracoContext.Application.Services.DomainService, + pcr.RoutingContext.UmbracoContext.Application.Services.LocalizationService); IPublishedContent content = null; diff --git a/src/Umbraco.Web/Routing/DomainAndUri.cs b/src/Umbraco.Web/Routing/DomainAndUri.cs index cef8231375..6395e937df 100644 --- a/src/Umbraco.Web/Routing/DomainAndUri.cs +++ b/src/Umbraco.Web/Routing/DomainAndUri.cs @@ -32,7 +32,7 @@ namespace Umbraco.Web.Routing { var name = domain.DomainName.ToCSharpString(); throw new ArgumentException(string.Format("Failed to parse invalid domain: node id={0}, hostname=\"{1}\"." - + " Hostname should be a valid uri.", domain.RootContent.Id, name), "domain"); + + " Hostname should be a valid uri.", domain.RootContentId, name), "domain"); } } diff --git a/src/Umbraco.Web/Routing/DomainHelper.cs b/src/Umbraco.Web/Routing/DomainHelper.cs index 72360d9f22..6934b08cf2 100644 --- a/src/Umbraco.Web/Routing/DomainHelper.cs +++ b/src/Umbraco.Web/Routing/DomainHelper.cs @@ -235,7 +235,7 @@ namespace Umbraco.Web.Routing .Reverse() .Select(int.Parse) .TakeWhile(id => id != stopNodeId) - .Select(id => domains.FirstOrDefault(d => d.RootContent.Id == id && d.IsWildcard == false)) + .Select(id => domains.FirstOrDefault(d => d.RootContentId == id && d.IsWildcard == false)) .SkipWhile(domain => domain == null) .FirstOrDefault(); } @@ -256,7 +256,7 @@ namespace Umbraco.Web.Routing .Reverse() .Select(int.Parse) .TakeWhile(id => id != stopNodeId) - .Select(id => domains.FirstOrDefault(d => d.RootContent.Id == id && d.IsWildcard)) + .Select(id => domains.FirstOrDefault(d => d.RootContentId == id && d.IsWildcard)) .FirstOrDefault(domain => domain != null); } diff --git a/src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs b/src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs index 20441b6c11..be0b908c4f 100644 --- a/src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs +++ b/src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs @@ -230,28 +230,30 @@ namespace Umbraco.Web.Routing /// /// /// + /// /// internal static int? GetCurrentNotFoundPageId( IContentErrorPage[] error404Collection, string requestServerName, IEntityService entityService, ITypedPublishedContentQuery publishedContentQuery, - IDomainService domainService) + IDomainService domainService, + ILocalizationService localizationService) { if (error404Collection.Count() > 1) { // try to get the 404 based on current culture (via domain) IContentErrorPage cultureErr; - //TODO: Remove the dependency on this legacy Domain service, - // in 7.3 the real domain service should be passed in as a parameter. - if (domainService.Exists(requestServerName)) + var d = domainService.GetByName(requestServerName); + + if (d != null && d.LanguageId.HasValue) { - var d = domainService.GetByName(requestServerName); + var lang = localizationService.GetLanguageById(d.LanguageId.Value); // test if a 404 page exists with current culture cultureErr = error404Collection - .FirstOrDefault(x => x.Culture == d.Language.IsoCode); + .FirstOrDefault(x => x.Culture == lang.IsoCode); if (cultureErr != null) { diff --git a/src/Umbraco.Web/Routing/PublishedContentRequestEngine.cs b/src/Umbraco.Web/Routing/PublishedContentRequestEngine.cs index b8b454e197..30fac66607 100644 --- a/src/Umbraco.Web/Routing/PublishedContentRequestEngine.cs +++ b/src/Umbraco.Web/Routing/PublishedContentRequestEngine.cs @@ -242,26 +242,39 @@ namespace Umbraco.Web.Routing var domainAndUri = DomainHelper.DomainForUri(Services.DomainService.GetAll(false), _pcr.Uri); // handle domain - if (domainAndUri != null) + if (domainAndUri != null && domainAndUri.UmbracoDomain.LanguageId.HasValue) { - // matching an existing domain - ProfilingLogger.Logger.Debug("{0}Matches domain=\"{1}\", rootId={2}, culture=\"{3}\"", - () => tracePrefix, - () => domainAndUri.UmbracoDomain.DomainName, - () => domainAndUri.UmbracoDomain.RootContent.Id, - () => domainAndUri.UmbracoDomain.Language.IsoCode); + var lang = Services.LocalizationService.GetLanguageById(domainAndUri.UmbracoDomain.LanguageId.Value); - _pcr.UmbracoDomain = domainAndUri.UmbracoDomain; - _pcr.DomainUri = domainAndUri.Uri; - _pcr.Culture = new CultureInfo(domainAndUri.UmbracoDomain.Language.IsoCode); + if (lang != null) + { + // matching an existing domain + ProfilingLogger.Logger.Debug("{0}Matches domain=\"{1}\", rootId={2}, culture=\"{3}\"", + () => tracePrefix, + () => domainAndUri.UmbracoDomain.DomainName, + () => domainAndUri.UmbracoDomain.RootContentId, + () => lang.IsoCode); - // canonical? not implemented at the moment - // if (...) - // { - // _pcr.RedirectUrl = "..."; - // return true; - // } - } + _pcr.UmbracoDomain = domainAndUri.UmbracoDomain; + _pcr.DomainUri = domainAndUri.Uri; + _pcr.Culture = new CultureInfo(lang.IsoCode); + + // canonical? not implemented at the moment + // if (...) + // { + // _pcr.RedirectUrl = "..."; + // return true; + // } + } + else + { + // not matching any language + ProfilingLogger.Logger.Debug("{0}No language with id {1}", () => tracePrefix, () => domainAndUri.UmbracoDomain.LanguageId.Value); + + var defaultLanguage = Services.LocalizationService.GetAllLanguages().FirstOrDefault(); + _pcr.Culture = defaultLanguage == null ? CultureInfo.CurrentUICulture : new CultureInfo(defaultLanguage.IsoCode); + } + } else { // not matching any existing domain @@ -288,14 +301,23 @@ namespace Umbraco.Web.Routing var nodePath = _pcr.PublishedContent.Path; ProfilingLogger.Logger.Debug("{0}Path=\"{1}\"", () => tracePrefix, () => nodePath); - var rootNodeId = _pcr.HasDomain ? _pcr.UmbracoDomain.RootContent.Id : (int?)null; + var rootNodeId = _pcr.HasDomain ? _pcr.UmbracoDomain.RootContentId : (int?)null; var domain = DomainHelper.FindWildcardDomainInPath(Services.DomainService.GetAll(true), nodePath, rootNodeId); - if (domain != null) + if (domain != null && domain.LanguageId.HasValue) { - _pcr.Culture = new CultureInfo(domain.Language.IsoCode); - ProfilingLogger.Logger.Debug("{0}Got domain on node {1}, set culture to \"{2}\".", () => tracePrefix, - () => domain.RootContent.Id, () => _pcr.Culture.Name); + var lang = Services.LocalizationService.GetLanguageById(domain.LanguageId.Value); + + if (lang != null) + { + _pcr.Culture = new CultureInfo(lang.IsoCode); + ProfilingLogger.Logger.Debug("{0}Got domain on node {1}, set culture to \"{2}\".", () => tracePrefix, + () => domain.RootContentId, () => _pcr.Culture.Name); + } + else + { + ProfilingLogger.Logger.Debug("{0}No language with id {1}", () => tracePrefix, () => domain.LanguageId.Value); + } } else { diff --git a/src/Umbraco.Web/WebServices/DomainsApiController.cs b/src/Umbraco.Web/WebServices/DomainsApiController.cs index a72f7537b0..f3344a7fb7 100644 --- a/src/Umbraco.Web/WebServices/DomainsApiController.cs +++ b/src/Umbraco.Web/WebServices/DomainsApiController.cs @@ -54,14 +54,14 @@ namespace Umbraco.Web.WebServices { var wildcard = domains.FirstOrDefault(d => d.IsWildcard); if (wildcard != null) - wildcard.Language = language; + wildcard.LanguageId = language.Id; else { // yet there is a race condition here... var newDomain = new UmbracoDomain("*" + model.NodeId) { - Language = Services.LocalizationService.GetLanguageById(model.Language), - RootContent = Services.ContentService.GetById(model.NodeId) + LanguageId = model.Language, + RootContentId = model.NodeId }; Services.DomainService.Save(newDomain); } @@ -103,7 +103,7 @@ namespace Umbraco.Web.WebServices names.Add(name); var domain = domains.FirstOrDefault(d => d.DomainName.InvariantEquals(domainModel.Name)); if (domain != null) - domain.Language = language; + domain.LanguageId = language.Id; else if (Services.DomainService.Exists(domainModel.Name)) domainModel.Duplicate = true; else @@ -111,8 +111,8 @@ namespace Umbraco.Web.WebServices // yet there is a race condition here... var newDomain = new UmbracoDomain(name) { - Language = Services.LocalizationService.GetLanguageById(domainModel.Lang), - RootContent = Services.ContentService.GetById(model.NodeId) + LanguageId = domainModel.Lang, + RootContentId = model.NodeId }; Services.DomainService.Save(newDomain); } diff --git a/src/Umbraco.Web/umbraco.presentation/NotFoundHandlers.cs b/src/Umbraco.Web/umbraco.presentation/NotFoundHandlers.cs index 27e62888d4..6854bb9a4d 100644 --- a/src/Umbraco.Web/umbraco.presentation/NotFoundHandlers.cs +++ b/src/Umbraco.Web/umbraco.presentation/NotFoundHandlers.cs @@ -326,7 +326,8 @@ namespace umbraco { HttpContext.Current.Request.ServerVariables["SERVER_NAME"], ApplicationContext.Current.Services.EntityService, new PublishedContentQuery(UmbracoContext.Current.ContentCache, UmbracoContext.Current.MediaCache), - ApplicationContext.Current.Services.DomainService); + ApplicationContext.Current.Services.DomainService, + ApplicationContext.Current.Services.LocalizationService); if (error404.HasValue) { 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 136cc1a27d..4f71e20d08 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/AssignDomain2.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/AssignDomain2.aspx.cs @@ -54,12 +54,12 @@ namespace umbraco.dialogs sb.AppendFormat("{0}{{ \"Id\": {1}, \"Code\": \"{2}\" }}", (i++ == 0 ? "" : ","), language.Id, language.IsoCode); sb.Append("]\r\n"); - sb.AppendFormat(",language: {0}", wildcard == null ? "undefined" : wildcard.Language.Id.ToString()); + sb.AppendFormat(",language: {0}", wildcard == null ? "undefined" : wildcard.LanguageId.ToString()); sb.Append(",domains: ["); i = 0; foreach (var domain in nodeDomains.Where(d => d.IsWildcard == false)) - sb.AppendFormat("{0}{{ \"Name\": \"{1}\", \"Lang\": \"{2}\" }}", (i++ == 0 ? "" :","), domain.DomainName, domain.Language.Id); + sb.AppendFormat("{0}{{ \"Name\": \"{1}\", \"Lang\": \"{2}\" }}", (i++ == 0 ? "" :","), domain.DomainName, domain.LanguageId); sb.Append("]\r\n"); data.Text = sb.ToString(); diff --git a/src/umbraco.cms/businesslogic/web/Domain.cs b/src/umbraco.cms/businesslogic/web/Domain.cs index 370d75b4db..fe695a25d6 100644 --- a/src/umbraco.cms/businesslogic/web/Domain.cs +++ b/src/umbraco.cms/businesslogic/web/Domain.cs @@ -64,22 +64,23 @@ namespace umbraco.cms.businesslogic.web public Language Language { - get { return new Language(DomainEntity.Language); } - set { DomainEntity.Language = value.LanguageEntity; } + get + { + if (DomainEntity.LanguageId.HasValue == false) return null; + var lang = ApplicationContext.Current.Services.LocalizationService.GetLanguageById(DomainEntity.LanguageId.Value); + if (lang == null) throw new InvalidOperationException("No language exists with id " + DomainEntity.LanguageId.Value); + return new Language(lang); + } + set + { + DomainEntity.LanguageId = value.LanguageEntity.Id; + } } public int RootNodeId { - get { return DomainEntity.RootContent.Id; } - set - { - var content = ApplicationContext.Current.Services.ContentService.GetById(value); - if (content == null) - { - throw new NullReferenceException("No content found with id " + value); - } - DomainEntity.RootContent = content; - } + get { return DomainEntity.RootContentId ?? -1; } + set { DomainEntity.RootContentId = value; } } public int Id @@ -135,7 +136,7 @@ namespace umbraco.cms.businesslogic.web public static int GetRootFromDomain(string DomainName) { var found = ApplicationContext.Current.Services.DomainService.GetByName(DomainName); - return found == null ? -1 : found.RootContent.Id; + return found == null ? -1 : found.RootContentId ?? -1; } public static Domain[] GetDomainsById(int nodeId) @@ -159,15 +160,10 @@ namespace umbraco.cms.businesslogic.web public static void MakeNew(string DomainName, int RootNodeId, int LanguageId) { - var content = ApplicationContext.Current.Services.ContentService.GetById(RootNodeId); - if (content == null) throw new NullReferenceException("No content exists with id " + RootNodeId); - var lang = ApplicationContext.Current.Services.LocalizationService.GetLanguageById(LanguageId); - if (lang == null) throw new NullReferenceException("No language exists with id " + LanguageId); - var domain = new UmbracoDomain(DomainName) { - RootContent = content, - Language = lang + RootContentId = RootNodeId, + LanguageId = LanguageId }; ApplicationContext.Current.Services.DomainService.Save(domain);