diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedVariationContext.cs b/src/Umbraco.Core/Models/PublishedContent/CurrentVariation.cs
similarity index 52%
rename from src/Umbraco.Core/Models/PublishedContent/PublishedVariationContext.cs
rename to src/Umbraco.Core/Models/PublishedContent/CurrentVariation.cs
index 2440b1dc32..f52763ecf0 100644
--- a/src/Umbraco.Core/Models/PublishedContent/PublishedVariationContext.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/CurrentVariation.cs
@@ -1,17 +1,14 @@
namespace Umbraco.Core.Models.PublishedContent
{
///
- /// Represents the published variation context.
+ /// Represents the current variation.
///
- ///
- /// The published variation context indicates which variation is the current default variation.
- ///
- public class PublishedVariationContext
+ public class CurrentVariation
{
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
- public PublishedVariationContext(string culture = null, string segment = null)
+ public CurrentVariation(string culture = null, string segment = null)
{
Culture = culture;
Segment = segment;
@@ -27,4 +24,4 @@
///
public string Segment { get; set; }
}
-}
\ No newline at end of file
+}
diff --git a/src/Umbraco.Core/Models/PublishedContent/ICurrentVariationAccessor.cs b/src/Umbraco.Core/Models/PublishedContent/ICurrentVariationAccessor.cs
new file mode 100644
index 0000000000..969601f080
--- /dev/null
+++ b/src/Umbraco.Core/Models/PublishedContent/ICurrentVariationAccessor.cs
@@ -0,0 +1,13 @@
+namespace Umbraco.Core.Models.PublishedContent
+{
+ ///
+ /// Gives access to the current .
+ ///
+ public interface ICurrentVariationAccessor
+ {
+ ///
+ /// Gets or sets the current .
+ ///
+ CurrentVariation CurrentVariation { get; set; }
+ }
+}
diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedContent.cs b/src/Umbraco.Core/Models/PublishedContent/IPublishedContent.cs
index e8de7efeda..b3358c4676 100644
--- a/src/Umbraco.Core/Models/PublishedContent/IPublishedContent.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/IPublishedContent.cs
@@ -31,9 +31,8 @@ namespace Umbraco.Core.Models.PublishedContent
///
///
/// The value of this property is contextual. When the content type is multi-lingual,
- /// this is the name for the 'current' culture.
+ /// this is the name for the 'current' culture. Otherwise, it is the invariant name.
///
- /// FIXME culture aware - returns the value for the 'current' culture whatever it is + see ?? for others
string Name { get; }
///
@@ -41,9 +40,8 @@ namespace Umbraco.Core.Models.PublishedContent
///
///
/// The value of this property is contextual. When the content type is multi-lingual,
- /// this is the name for the 'current' culture.
+ /// this is the name for the 'current' culture. Otherwise, it is the invariant url segment.
///
- /// FIXME rename UrlSegment + culture aware
string UrlSegment { get; }
///
@@ -96,7 +94,8 @@ namespace Umbraco.Core.Models.PublishedContent
///
///
/// For published content items, this is also the date the item was published.
- /// This date is global to the content item, see FIXME for per-culture dates
+ /// This date is always global to the content item, see GetCulture().Date for the
+ /// date each culture was published.
///
DateTime UpdateDate { get; }
@@ -104,17 +103,35 @@ namespace Umbraco.Core.Models.PublishedContent
/// Gets the url of the content item.
///
///
- /// The value of this property is contextual. It depends on the 'current'
- /// In addition, when the content type is multi-lingual, this is the url for the
- /// 'current' culture.
+ /// The value of this property is contextual. It depends on the 'current' request uri,
+ /// if any. In addition, when the content type is multi-lingual, this is the url for the
+ /// 'current' culture. Otherwise, it is the invariant url.
///
- /// FIXME explain what 'current' means here
string Url { get; }
- // fixme document
- //PublishedCultureInfos Culture(string culture = ".");
- //string GetName(string culture = "."); // best naming? GetName? CultureName?
+ ///
+ /// Gets the url of the content item.
+ ///
+ ///
+ /// The value of this property is contextual. It depends on the 'current' request uri,
+ /// if any. In addition, when the content type is multi-lingual, this is the url for the
+ /// specified culture. Otherwise, it is the invariant url.
+ ///
+ string GetUrl(string culture = ".");
+
+ ///
+ /// Gets culture infos for a culture.
+ ///
PublishedCultureInfos GetCulture(string culture = ".");
+
+ ///
+ /// Gets culture infos.
+ ///
+ ///
+ /// Contains only those culture that are available. For a published content, these are
+ /// the cultures that are published. For a draft content, those that are 'available' ie
+ /// have a non-empty content name.
+ ///
IReadOnlyDictionary Cultures { get; }
///
diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedVariationContextAccessor.cs b/src/Umbraco.Core/Models/PublishedContent/IPublishedVariationContextAccessor.cs
deleted file mode 100644
index 2af4230665..0000000000
--- a/src/Umbraco.Core/Models/PublishedContent/IPublishedVariationContextAccessor.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace Umbraco.Core.Models.PublishedContent
-{
- ///
- /// Gives access to the current .
- ///
- public interface IPublishedVariationContextAccessor
- {
- ///
- /// Gets or sets the current .
- ///
- PublishedVariationContext Context { get; set; }
- }
-}
diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs
index 8d4888cf25..51fe3045f7 100644
--- a/src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs
@@ -96,6 +96,9 @@ namespace Umbraco.Core.Models.PublishedContent
///
public virtual string Url => _content.Url;
+ ///
+ public virtual string GetUrl(string culture = ".") => _content.GetUrl(culture);
+
///
public PublishedCultureInfos GetCulture(string culture = ".") => _content.GetCulture(culture);
diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedCultureInfos.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedCultureInfos.cs
index 7a563544a4..2522f0366f 100644
--- a/src/Umbraco.Core/Models/PublishedContent/PublishedCultureInfos.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/PublishedCultureInfos.cs
@@ -11,7 +11,7 @@ namespace Umbraco.Core.Models.PublishedContent
///
/// Initializes a new instance of the class.
///
- public PublishedCultureInfos(string culture, string name, bool published, DateTime publishedDate)
+ public PublishedCultureInfos(string culture, string name, bool published, DateTime date)
{
if (string.IsNullOrWhiteSpace(culture)) throw new ArgumentNullOrEmptyException(nameof(culture));
if (string.IsNullOrWhiteSpace(name)) throw new ArgumentNullOrEmptyException(nameof(name));
@@ -20,7 +20,7 @@ namespace Umbraco.Core.Models.PublishedContent
Name = name;
UrlSegment = name.ToUrlSegment(culture);
Published = published;
- PublishedDate = publishedDate;
+ Date = date;
}
///
@@ -48,8 +48,13 @@ namespace Umbraco.Core.Models.PublishedContent
public bool Published { get; }
///
- /// Gets the date when fixme?
+ /// Gets the date associated with the culture.
///
- public DateTime PublishedDate { get; } // fixme - model? model.UpdateDate - here?
+ ///
+ /// For published culture, this is the date the culture was published. For draft
+ /// cultures, this is the date the culture was made available, ie the last time its
+ /// name changed.
+ ///
+ public DateTime Date { get; }
}
}
diff --git a/src/Umbraco.Core/Models/PublishedContent/ThreadCulturePublishedVariationContextAccessor.cs b/src/Umbraco.Core/Models/PublishedContent/ThreadCultureCurrentVariationAccessor.cs
similarity index 54%
rename from src/Umbraco.Core/Models/PublishedContent/ThreadCulturePublishedVariationContextAccessor.cs
rename to src/Umbraco.Core/Models/PublishedContent/ThreadCultureCurrentVariationAccessor.cs
index 8bf02e3f9b..9883cf9e3f 100644
--- a/src/Umbraco.Core/Models/PublishedContent/ThreadCulturePublishedVariationContextAccessor.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/ThreadCultureCurrentVariationAccessor.cs
@@ -5,18 +5,18 @@ using System.Threading;
namespace Umbraco.Core.Models.PublishedContent
{
///
- /// Provides a CurrentUICulture-based implementation of .
+ /// Provides a CurrentUICulture-based implementation of .
///
///
/// This accessor does not support segments. There is no need to set the current context.
///
- public class ThreadCulturePublishedVariationContextAccessor : IPublishedVariationContextAccessor
+ public class ThreadCultureCurrentVariationAccessor : ICurrentVariationAccessor
{
- private readonly ConcurrentDictionary _contexts = new ConcurrentDictionary();
+ private readonly ConcurrentDictionary _contexts = new ConcurrentDictionary();
- public PublishedVariationContext Context
+ public CurrentVariation CurrentVariation
{
- get => _contexts.GetOrAdd(Thread.CurrentThread.CurrentUICulture.Name, culture => new PublishedVariationContext { Culture = culture });
+ get => _contexts.GetOrAdd(Thread.CurrentThread.CurrentUICulture.Name, culture => new CurrentVariation { Culture = culture });
set => throw new NotSupportedException();
}
}
diff --git a/src/Umbraco.Core/Models/PublishedContent/ThreadStaticPublishedVariationContextAccessor.cs b/src/Umbraco.Core/Models/PublishedContent/ThreadStaticCurrentVariationAccessor.cs
similarity index 62%
rename from src/Umbraco.Core/Models/PublishedContent/ThreadStaticPublishedVariationContextAccessor.cs
rename to src/Umbraco.Core/Models/PublishedContent/ThreadStaticCurrentVariationAccessor.cs
index b7391e8b0d..19ec89ff97 100644
--- a/src/Umbraco.Core/Models/PublishedContent/ThreadStaticPublishedVariationContextAccessor.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/ThreadStaticCurrentVariationAccessor.cs
@@ -3,18 +3,18 @@
namespace Umbraco.Core.Models.PublishedContent
{
///
- /// Provides a ThreadStatic-based implementation of .
+ /// Provides a ThreadStatic-based implementation of .
///
///
/// Something must set the current context.
///
- public class ThreadStaticPublishedVariationContextAccessor : IPublishedVariationContextAccessor
+ public class ThreadStaticCurrentVariationAccessor : ICurrentVariationAccessor
{
[ThreadStatic]
- private static PublishedVariationContext _context;
+ private static CurrentVariation _context;
///
- public PublishedVariationContext Context
+ public CurrentVariation CurrentVariation
{
get => _context;
set => _context = value;
diff --git a/src/Umbraco.Core/StringExtensions.cs b/src/Umbraco.Core/StringExtensions.cs
index 0a41b3c09e..cded44a7e9 100644
--- a/src/Umbraco.Core/StringExtensions.cs
+++ b/src/Umbraco.Core/StringExtensions.cs
@@ -1166,7 +1166,8 @@ namespace Umbraco.Core
/// The text to filter.
/// The culture.
/// The safe url segment.
- public static string ToUrlSegment(this string text, CultureInfo culture) // fixme obsolete that one, use the string one?
+ // todo: obsolete that one and use the string one (requires changes to IShortStringHelper)
+ public static string ToUrlSegment(this string text, CultureInfo culture)
{
return Current.ShortStringHelper.CleanStringForUrlSegment(text, culture);
}
diff --git a/src/Umbraco.Core/Strings/IUrlSegmentProvider.cs b/src/Umbraco.Core/Strings/IUrlSegmentProvider.cs
index 824ae50aa4..4674361b95 100644
--- a/src/Umbraco.Core/Strings/IUrlSegmentProvider.cs
+++ b/src/Umbraco.Core/Strings/IUrlSegmentProvider.cs
@@ -14,7 +14,7 @@ namespace Umbraco.Core.Strings
///
/// The content.
/// The url segment.
- string GetUrlSegment(IContentBase content);
+ string GetUrlSegment(IContentBase content); // fixme do we need to have both?
///
/// Gets the url segment for a specified content and culture.
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index 954391c8a6..9284a12cbd 100644
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -369,11 +369,11 @@
-
+
-
-
-
+
+
+
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentOtherTests.cs b/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs
similarity index 76%
rename from src/Umbraco.Tests/PublishedContent/PublishedContentOtherTests.cs
rename to src/Umbraco.Tests/PublishedContent/NuCacheTests.cs
index 3aa1fbf41f..ffdaf71711 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentOtherTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Data;
-using System.Linq;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
@@ -16,6 +15,7 @@ using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
using Umbraco.Core.Services.Changes;
using Umbraco.Tests.TestHelpers;
+using Umbraco.Tests.Testing.Objects;
using Umbraco.Tests.Testing.Objects.Accessors;
using Umbraco.Web;
using Umbraco.Web.Cache;
@@ -26,14 +26,18 @@ using Umbraco.Web.Routing;
namespace Umbraco.Tests.PublishedContent
{
[TestFixture]
- public class PublishedContentOtherTests // FIXME rename!
+ public class NuCacheTests
{
[Test]
- public void Test()
+ public void StandaloneVariations()
{
+ // this test implements a full standalone NuCache (based upon a test IDataSource, does not
+ // use any local db files, does not rely on any database) - and tests variations
+
SettingsForTests.ConfigureSettings(SettingsForTests.GenerateMockUmbracoSettings());
var globalSettings = UmbracoConfig.For.GlobalSettings();
+ // create a content node kit
var kit = new ContentNodeKit
{
ContentTypeId = 2,
@@ -66,11 +70,20 @@ namespace Umbraco.Tests.PublishedContent
}
};
+ // create a data source for NuCache
var dataSource = new TestDataSource(kit);
var runtime = Mock.Of();
Mock.Get(runtime).Setup(x => x.Level).Returns(RuntimeLevel.Run);
+ // create data types, property types and content types
+ var dataType = new DataType(new VoidEditor("Editor", Mock.Of())) { Id = 3 };
+
+ var dataTypes = new[]
+ {
+ dataType
+ };
+
var propertyType = new PropertyType("Umbraco.Void.Editor", ValueStorageType.Nvarchar) { Alias = "prop", DataTypeId = 3, Variations = ContentVariation.InvariantNeutral | ContentVariation.CultureNeutral };
var contentType = new ContentType(-1) { Id = 2, Alias = "alias-ct", Variations = ContentVariation.InvariantNeutral | ContentVariation.CultureNeutral };
contentType.AddPropertyType(propertyType);
@@ -80,13 +93,6 @@ namespace Umbraco.Tests.PublishedContent
contentType
};
- var dataType = new DataType(new VoidEditor("Editor", Mock.Of())) { Id = 3 };
-
- var dataTypes = new[]
- {
- dataType
- };
-
var contentTypeService = Mock.Of();
Mock.Get(contentTypeService).Setup(x => x.GetAll()).Returns(contentTypes);
Mock.Get(contentTypeService).Setup(x => x.GetAll(It.IsAny())).Returns(contentTypes);
@@ -94,6 +100,7 @@ namespace Umbraco.Tests.PublishedContent
var dataTypeService = Mock.Of();
Mock.Get(dataTypeService).Setup(x => x.GetAll()).Returns(dataTypes);
+ // create a service context
var serviceContext = new ServiceContext(
dataTypeService : dataTypeService,
memberTypeService: Mock.Of(),
@@ -102,17 +109,7 @@ namespace Umbraco.Tests.PublishedContent
localizationService: Mock.Of()
);
- var contentTypeFactory = new PublishedContentTypeFactory(
- Mock.Of(),
- new PropertyValueConverterCollection(Array.Empty()),
- dataTypeService);
-
- var documentRepository = Mock.Of();
- var mediaRepository = Mock.Of();
- var memberRepository = Mock.Of();
-
- var snapshotAccessor = new TestPublishedSnapshotAccessor();
-
+ // create a scope provider
var scopeProvider = Mock.Of();
Mock.Get(scopeProvider)
.Setup(x => x.CreateScope(
@@ -122,10 +119,18 @@ namespace Umbraco.Tests.PublishedContent
It.IsAny(),
It.IsAny(),
It.IsAny()))
- .Returns(() => Mock.Of());
+ .Returns(Mock.Of);
- var variationAccessor = new TestPublishedVariationContextAccessor();
+ // create a published content type factory
+ var contentTypeFactory = new PublishedContentTypeFactory(
+ Mock.Of(),
+ new PropertyValueConverterCollection(Array.Empty()),
+ dataTypeService);
+ // create a variation accessor
+ var variationAccessor = new TestCurrentVariationAccessor();
+
+ // at last, create the complete NuCache snapshot service!
var options = new PublishedSnapshotService.Options { IgnoreLocalDb = true };
var snapshotService = new PublishedSnapshotService(options,
null,
@@ -133,23 +138,24 @@ namespace Umbraco.Tests.PublishedContent
serviceContext,
contentTypeFactory,
null,
- snapshotAccessor,
+ new TestPublishedSnapshotAccessor(),
variationAccessor,
Mock.Of(),
scopeProvider,
- documentRepository,
- mediaRepository,
- memberRepository,
+ Mock.Of(),
+ Mock.Of(),
+ Mock.Of(),
new TestSystemDefaultCultureAccessor(),
dataSource,
globalSettings,
new SiteDomainHelper());
+ // get a snapshot, get a published content
var snapshot = snapshotService.CreatePublishedSnapshot(previewToken: null);
var publishedContent = snapshot.Content.GetById(1);
// invariant is the current default
- variationAccessor.Context = new PublishedVariationContext();
+ variationAccessor.CurrentVariation = new CurrentVariation();
Assert.IsNotNull(publishedContent);
Assert.AreEqual("It Works1!", publishedContent.Name);
@@ -170,86 +176,39 @@ namespace Umbraco.Tests.PublishedContent
Assert.AreEqual("name-uk2", draftContent.GetCulture("en-UK").Name);
// now french is default
- variationAccessor.Context = new PublishedVariationContext("fr-FR");
+ variationAccessor.CurrentVariation = new CurrentVariation("fr-FR");
Assert.AreEqual("val-fr1", publishedContent.Value("prop"));
Assert.AreEqual("name-fr1", publishedContent.GetCulture().Name);
Assert.AreEqual("name-fr1", publishedContent.Name);
- Assert.AreEqual(new DateTime(2018, 01, 01, 01, 00, 00), publishedContent.GetCulture().PublishedDate);
+ Assert.AreEqual(new DateTime(2018, 01, 01, 01, 00, 00), publishedContent.GetCulture().Date);
// now uk is default
- variationAccessor.Context = new PublishedVariationContext("en-UK");
+ variationAccessor.CurrentVariation = new CurrentVariation("en-UK");
Assert.AreEqual("val-uk1", publishedContent.Value("prop"));
Assert.AreEqual("name-uk1", publishedContent.GetCulture().Name);
Assert.AreEqual("name-uk1", publishedContent.Name);
- Assert.AreEqual(new DateTime(2018, 01, 02, 01, 00, 00), publishedContent.GetCulture().PublishedDate);
+ Assert.AreEqual(new DateTime(2018, 01, 02, 01, 00, 00), publishedContent.GetCulture().Date);
// invariant needs to be retrieved explicitely, when it's not default
Assert.AreEqual("val1", publishedContent.Value("prop", culture: null));
// but,
// if the content type / property type does not vary, then it's all invariant again
+ // modify the content type and property type, notify the snapshot service
contentType.Variations = ContentVariation.InvariantNeutral;
propertyType.Variations = ContentVariation.InvariantNeutral;
snapshotService.Notify(new[] { new ContentTypeCacheRefresher.JsonPayload("IContentType", publishedContent.ContentType.Id, ContentTypeChangeTypes.RefreshMain) });
+ // get a new snapshot (nothing changed in the old one), get the published content again
var anotherSnapshot = snapshotService.CreatePublishedSnapshot(previewToken: null);
var againContent = anotherSnapshot.Content.GetById(1);
Assert.AreEqual(ContentVariation.InvariantNeutral, againContent.ContentType.Variations);
Assert.AreEqual(ContentVariation.InvariantNeutral, againContent.ContentType.GetPropertyType("prop").Variations);
+ // now, "no culture" means "invariant"
Assert.AreEqual("It Works1!", againContent.Name);
Assert.AreEqual("val1", againContent.Value("prop"));
-
- // then, test fallback
- }
-
- internal class TestDataSource : IDataSource
- {
- private readonly Dictionary _kits;
-
- public TestDataSource(params ContentNodeKit[] kits)
- : this((IEnumerable) kits)
- { }
-
- public TestDataSource(IEnumerable kits)
- {
- _kits = kits.ToDictionary(x => x.Node.Id, x => x);
- }
-
- public ContentNodeKit GetContentSource(IScope scope, int id)
- => _kits.TryGetValue(id, out var kit) ? kit : default;
-
- public IEnumerable GetAllContentSources(IScope scope)
- => _kits.Values;
-
- public IEnumerable GetBranchContentSources(IScope scope, int id)
- {
- throw new NotImplementedException();
- }
-
- public IEnumerable GetTypeContentSources(IScope scope, IEnumerable ids)
- => _kits.Values.Where(x => ids.Contains(x.ContentTypeId));
-
- public ContentNodeKit GetMediaSource(IScope scope, int id)
- {
- throw new NotImplementedException();
- }
-
- public IEnumerable GetAllMediaSources(IScope scope)
- {
- throw new NotImplementedException();
- }
-
- public IEnumerable GetBranchMediaSources(IScope scope, int id)
- {
- throw new NotImplementedException();
- }
-
- public IEnumerable GetTypeMediaSources(IScope scope, IEnumerable ids)
- {
- throw new NotImplementedException();
- }
}
}
}
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs
index af63d2244b..70a349e0cb 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs
@@ -134,9 +134,6 @@ namespace Umbraco.Tests.PublishedContent
CreateDate = DateTime.Now,
CreatorId = 1,
CreatorName = "Shannon",
- // fixme what're we gonna do?
- //DocumentTypeAlias = contentTypeAlias,
- //DocumentTypeId = 2,
Id = 3,
SortOrder = 4,
TemplateId = 5,
@@ -186,7 +183,9 @@ namespace Umbraco.Tests.PublishedContent
// l8tr...
private class TestPublishedContent : IPublishedContent
{
- public string Url { get; set; }
+ public string Url { get; set; }
+ public string GetUrl(string culture = ".") => throw new NotSupportedException();
+
public PublishedItemType ItemType { get; set; }
IPublishedContent IPublishedContent.Parent
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentExtensionTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentExtensionTests.cs
index d6321af692..acff953503 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentExtensionTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentExtensionTests.cs
@@ -12,14 +12,14 @@ namespace Umbraco.Tests.PublishedContent
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerFixture)]
public class PublishedContentExtensionTests : PublishedContentTestBase
{
- private UmbracoContext ctx;
- private string xmlContent = "";
- private bool createContentTypes = true;
+ private UmbracoContext _ctx;
+ private string _xmlContent = "";
+ private bool _createContentTypes = true;
private Dictionary _contentTypes;
protected override string GetXmlContent(int templateId)
{
- return xmlContent;
+ return _xmlContent;
}
[Test]
@@ -27,7 +27,7 @@ namespace Umbraco.Tests.PublishedContent
{
InitializeInheritedContentTypes();
- var publishedContent = ctx.ContentCache.GetById(1100);
+ var publishedContent = _ctx.ContentCache.GetById(1100);
Assert.That(publishedContent.IsDocumentType("inherited", false));
}
@@ -36,7 +36,7 @@ namespace Umbraco.Tests.PublishedContent
{
InitializeInheritedContentTypes();
- var publishedContent = ctx.ContentCache.GetById(1100);
+ var publishedContent = _ctx.ContentCache.GetById(1100);
Assert.That(publishedContent.IsDocumentType("base", false), Is.False);
}
@@ -45,7 +45,7 @@ namespace Umbraco.Tests.PublishedContent
{
InitializeInheritedContentTypes();
- var publishedContent = ctx.ContentCache.GetById(1100);
+ var publishedContent = _ctx.ContentCache.GetById(1100);
Assert.That(publishedContent.IsDocumentType("inherited", true));
}
@@ -53,9 +53,9 @@ namespace Umbraco.Tests.PublishedContent
public void IsDocumentType_Recursive_BaseType_ReturnsTrue()
{
InitializeInheritedContentTypes();
- ContentTypesCache.GetPublishedContentTypeByAlias = null; // fixme this is not pretty
+ ContentTypesCache.GetPublishedContentTypeByAlias = null;
- var publishedContent = ctx.ContentCache.GetById(1100);
+ var publishedContent = _ctx.ContentCache.GetById(1100);
Assert.That(publishedContent.IsDocumentType("base", true));
}
@@ -64,14 +64,14 @@ namespace Umbraco.Tests.PublishedContent
{
InitializeInheritedContentTypes();
- var publishedContent = ctx.ContentCache.GetById(1100);
+ var publishedContent = _ctx.ContentCache.GetById(1100);
Assert.That(publishedContent.IsDocumentType("invalidbase", true), Is.False);
}
private void InitializeInheritedContentTypes()
{
- ctx = GetUmbracoContext("/", 1, null, true);
- if (createContentTypes)
+ _ctx = GetUmbracoContext("/", 1, null, true);
+ if (_createContentTypes)
{
var contentTypeService = Current.Services.ContentTypeService;
var baseType = new ContentType(-1) { Alias = "base", Name = "Base" };
@@ -85,12 +85,12 @@ namespace Umbraco.Tests.PublishedContent
{ inheritedType.Alias, new PublishedContentType(inheritedType, null) }
};
ContentTypesCache.GetPublishedContentTypeByAlias = alias => _contentTypes[alias];
- createContentTypes = false;
+ _createContentTypes = false;
}
ContentTypesCache.GetPublishedContentTypeByAlias = alias => _contentTypes[alias];
- xmlContent = @"
+ _xmlContent = @"
diff --git a/src/Umbraco.Tests/PublishedContent/SolidPublishedSnapshot.cs b/src/Umbraco.Tests/PublishedContent/SolidPublishedSnapshot.cs
index 38ba7e771b..7cdea14008 100644
--- a/src/Umbraco.Tests/PublishedContent/SolidPublishedSnapshot.cs
+++ b/src/Umbraco.Tests/PublishedContent/SolidPublishedSnapshot.cs
@@ -189,6 +189,7 @@ namespace Umbraco.Tests.PublishedContent
public Guid Version { get; set; }
public int Level { get; set; }
public string Url { get; set; }
+ public string GetUrl(string culture = ".") => throw new NotSupportedException();
public PublishedItemType ItemType { get { return PublishedItemType.Content; } }
public bool IsDraft { get; set; }
diff --git a/src/Umbraco.Tests/Routing/UrlProviderTests.cs b/src/Umbraco.Tests/Routing/UrlProviderTests.cs
index 185812002d..d3cd25ae92 100644
--- a/src/Umbraco.Tests/Routing/UrlProviderTests.cs
+++ b/src/Umbraco.Tests/Routing/UrlProviderTests.cs
@@ -5,6 +5,7 @@ using System.Linq;
using Moq;
using NUnit.Framework;
using Umbraco.Core.Configuration.UmbracoSettings;
+using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Stubs;
@@ -166,9 +167,15 @@ namespace Umbraco.Tests.Routing
var requestMock = Mock.Get(_umbracoSettings.RequestHandler);
requestMock.Setup(x => x.UseDomainPrefixes).Returns(false);
+ var contentType = new PublishedContentType(666, "alias", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(),
+ ContentVariation.CultureNeutral);
+ var publishedContent = new TestPublishedContent(contentType, 1234, Guid.NewGuid(), new Dictionary(), false);
+
var publishedContentCache = new Mock();
publishedContentCache.Setup(x => x.GetRouteById(1234, "fr-FR"))
.Returns("9876/home/test-fr"); //prefix with the root id node with the domain assigned as per the umbraco standard
+ publishedContentCache.Setup(x => x.GetById(It.IsAny()))
+ .Returns(id => id == 1234 ? publishedContent : null);
var domainCache = new Mock();
domainCache.Setup(x => x.GetAssigned(It.IsAny(), false))
@@ -209,9 +216,15 @@ namespace Umbraco.Tests.Routing
var requestMock = Mock.Get(_umbracoSettings.RequestHandler);
requestMock.Setup(x => x.UseDomainPrefixes).Returns(false);
+ var contentType = new PublishedContentType(666, "alias", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(),
+ ContentVariation.CultureNeutral);
+ var publishedContent = new TestPublishedContent(contentType, 1234, Guid.NewGuid(), new Dictionary(), false);
+
var publishedContentCache = new Mock();
publishedContentCache.Setup(x => x.GetRouteById(1234, "fr-FR"))
.Returns("9876/home/test-fr"); //prefix with the root id node with the domain assigned as per the umbraco standard
+ publishedContentCache.Setup(x => x.GetById(It.IsAny()))
+ .Returns(id => id == 1234 ? publishedContent : null);
var domainCache = new Mock();
domainCache.Setup(x => x.GetAssigned(It.IsAny(), false))
@@ -261,9 +274,15 @@ namespace Umbraco.Tests.Routing
var requestMock = Mock.Get(_umbracoSettings.RequestHandler);
requestMock.Setup(x => x.UseDomainPrefixes).Returns(false);
+ var contentType = new PublishedContentType(666, "alias", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(),
+ ContentVariation.CultureNeutral);
+ var publishedContent = new TestPublishedContent(contentType, 1234, Guid.NewGuid(), new Dictionary(), false);
+
var publishedContentCache = new Mock();
publishedContentCache.Setup(x => x.GetRouteById(1234, "fr-FR"))
.Returns("9876/home/test-fr"); //prefix with the root id node with the domain assigned as per the umbraco standard
+ publishedContentCache.Setup(x => x.GetById(It.IsAny()))
+ .Returns(id => id == 1234 ? publishedContent : null);
var domainCache = new Mock();
domainCache.Setup(x => x.GetAssigned(It.IsAny(), false))
@@ -306,7 +325,6 @@ namespace Umbraco.Tests.Routing
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false);
SettingsForTests.ConfigureSettings(globalSettings.Object);
-
var requestMock = Mock.Get(_umbracoSettings.RequestHandler);
requestMock.Setup(x => x.UseDomainPrefixes).Returns(false);
diff --git a/src/Umbraco.Tests/Routing/UrlsProviderWithDomainsTests.cs b/src/Umbraco.Tests/Routing/UrlsProviderWithDomainsTests.cs
index b064e9685c..627d95ea29 100644
--- a/src/Umbraco.Tests/Routing/UrlsProviderWithDomainsTests.cs
+++ b/src/Umbraco.Tests/Routing/UrlsProviderWithDomainsTests.cs
@@ -190,7 +190,7 @@ namespace Umbraco.Tests.Routing
SetDomains1();
var currentUri = new Uri(currentUrl);
- var result = umbracoContext.UrlProvider.GetUrl(nodeId, currentUri, absolute);
+ var result = umbracoContext.UrlProvider.GetUrl(nodeId, absolute, current: currentUri);
Assert.AreEqual(expected, result);
}
@@ -226,7 +226,7 @@ namespace Umbraco.Tests.Routing
SetDomains2();
var currentUri = new Uri(currentUrl);
- var result = umbracoContext.UrlProvider.GetUrl(nodeId, currentUri, absolute);
+ var result = umbracoContext.UrlProvider.GetUrl(nodeId, absolute, current : currentUri);
Assert.AreEqual(expected, result);
}
@@ -254,7 +254,7 @@ namespace Umbraco.Tests.Routing
SetDomains3();
var currentUri = new Uri(currentUrl);
- var result = umbracoContext.UrlProvider.GetUrl(nodeId, currentUri, absolute);
+ var result = umbracoContext.UrlProvider.GetUrl(nodeId, absolute, current : currentUri);
Assert.AreEqual(expected, result);
}
@@ -288,7 +288,7 @@ namespace Umbraco.Tests.Routing
SetDomains4();
var currentUri = new Uri(currentUrl);
- var result = umbracoContext.UrlProvider.GetUrl(nodeId, currentUri, absolute);
+ var result = umbracoContext.UrlProvider.GetUrl(nodeId, absolute, current : currentUri);
Assert.AreEqual(expected, result);
}
@@ -312,17 +312,17 @@ namespace Umbraco.Tests.Routing
SetDomains4();
string ignore;
- ignore = umbracoContext.UrlProvider.GetUrl(1001, new Uri("http://domain1.com"), false);
- ignore = umbracoContext.UrlProvider.GetUrl(10011, new Uri("http://domain1.com"), false);
- ignore = umbracoContext.UrlProvider.GetUrl(100111, new Uri("http://domain1.com"), false);
- ignore = umbracoContext.UrlProvider.GetUrl(10012, new Uri("http://domain1.com"), false);
- ignore = umbracoContext.UrlProvider.GetUrl(100121, new Uri("http://domain1.com"), false);
- ignore = umbracoContext.UrlProvider.GetUrl(10013, new Uri("http://domain1.com"), false);
- ignore = umbracoContext.UrlProvider.GetUrl(1002, new Uri("http://domain1.com"), false);
- ignore = umbracoContext.UrlProvider.GetUrl(1001, new Uri("http://domain2.com"), false);
- ignore = umbracoContext.UrlProvider.GetUrl(10011, new Uri("http://domain2.com"), false);
- ignore = umbracoContext.UrlProvider.GetUrl(100111, new Uri("http://domain2.com"), false);
- ignore = umbracoContext.UrlProvider.GetUrl(1002, new Uri("http://domain2.com"), false);
+ ignore = umbracoContext.UrlProvider.GetUrl(1001, false, current: new Uri("http://domain1.com"));
+ ignore = umbracoContext.UrlProvider.GetUrl(10011, false, current: new Uri("http://domain1.com"));
+ ignore = umbracoContext.UrlProvider.GetUrl(100111, false, current: new Uri("http://domain1.com"));
+ ignore = umbracoContext.UrlProvider.GetUrl(10012, false, current: new Uri("http://domain1.com"));
+ ignore = umbracoContext.UrlProvider.GetUrl(100121, false, current: new Uri("http://domain1.com"));
+ ignore = umbracoContext.UrlProvider.GetUrl(10013, false, current: new Uri("http://domain1.com"));
+ ignore = umbracoContext.UrlProvider.GetUrl(1002, false, current: new Uri("http://domain1.com"));
+ ignore = umbracoContext.UrlProvider.GetUrl(1001, false, current: new Uri("http://domain2.com"));
+ ignore = umbracoContext.UrlProvider.GetUrl(10011, false, current: new Uri("http://domain2.com"));
+ ignore = umbracoContext.UrlProvider.GetUrl(100111, false, current: new Uri("http://domain2.com"));
+ ignore = umbracoContext.UrlProvider.GetUrl(1002, false, current: new Uri("http://domain2.com"));
var cache = umbracoContext.ContentCache as PublishedContentCache;
if (cache == null) throw new Exception("Unsupported IPublishedContentCache, only the Xml one is supported.");
@@ -341,15 +341,15 @@ namespace Umbraco.Tests.Routing
CheckRoute(cachedRoutes, cachedIds, 1002, "/1002");
// use the cache
- Assert.AreEqual("/", umbracoContext.UrlProvider.GetUrl(1001, new Uri("http://domain1.com"), false));
- Assert.AreEqual("/en/", umbracoContext.UrlProvider.GetUrl(10011, new Uri("http://domain1.com"), false));
- Assert.AreEqual("/en/1001-1-1/", umbracoContext.UrlProvider.GetUrl(100111, new Uri("http://domain1.com"), false));
- Assert.AreEqual("/fr/", umbracoContext.UrlProvider.GetUrl(10012, new Uri("http://domain1.com"), false));
- Assert.AreEqual("/fr/1001-2-1/", umbracoContext.UrlProvider.GetUrl(100121, new Uri("http://domain1.com"), false));
- Assert.AreEqual("/1001-3/", umbracoContext.UrlProvider.GetUrl(10013, new Uri("http://domain1.com"), false));
- Assert.AreEqual("/1002/", umbracoContext.UrlProvider.GetUrl(1002, new Uri("http://domain1.com"), false));
+ Assert.AreEqual("/", umbracoContext.UrlProvider.GetUrl(1001, false, current: new Uri("http://domain1.com")));
+ Assert.AreEqual("/en/", umbracoContext.UrlProvider.GetUrl(10011, false, current: new Uri("http://domain1.com")));
+ Assert.AreEqual("/en/1001-1-1/", umbracoContext.UrlProvider.GetUrl(100111, false, current: new Uri("http://domain1.com")));
+ Assert.AreEqual("/fr/", umbracoContext.UrlProvider.GetUrl(10012, false, current: new Uri("http://domain1.com")));
+ Assert.AreEqual("/fr/1001-2-1/", umbracoContext.UrlProvider.GetUrl(100121, false, current: new Uri("http://domain1.com")));
+ Assert.AreEqual("/1001-3/", umbracoContext.UrlProvider.GetUrl(10013, false, current: new Uri("http://domain1.com")));
+ Assert.AreEqual("/1002/", umbracoContext.UrlProvider.GetUrl(1002, false, current: new Uri("http://domain1.com")));
- Assert.AreEqual("http://domain1.com/fr/1001-2-1/", umbracoContext.UrlProvider.GetUrl(100121, new Uri("http://domain2.com"), false));
+ Assert.AreEqual("http://domain1.com/fr/1001-2-1/", umbracoContext.UrlProvider.GetUrl(100121, false, current: new Uri("http://domain2.com")));
}
private static void CheckRoute(IDictionary routes, IDictionary ids, int id, string route)
diff --git a/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs b/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs
index fb9b3ee0e4..b6eff1e0ef 100644
--- a/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs
+++ b/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs
@@ -89,7 +89,7 @@ namespace Umbraco.Tests.Scoping
contentTypeFactory,
null,
publishedSnapshotAccessor,
- Mock.Of(),
+ Mock.Of(),
Logger,
ScopeProvider,
documentRepository, mediaRepository, memberRepository,
diff --git a/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs b/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs
index 97d88a680b..d5f10cc324 100644
--- a/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs
+++ b/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs
@@ -153,7 +153,7 @@ namespace Umbraco.Tests.TestHelpers.ControllerTesting
true); //replace it
var urlHelper = new Mock();
- urlHelper.Setup(provider => provider.GetUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()))
+ urlHelper.Setup(provider => provider.GetUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()))
.Returns("/hello/world/1234");
var membershipHelper = new MembershipHelper(umbCtx, Mock.Of(), Mock.Of());
diff --git a/src/Umbraco.Tests/TestHelpers/Stubs/TestPublishedContent.cs b/src/Umbraco.Tests/TestHelpers/Stubs/TestPublishedContent.cs
index 14a0979091..3f2a05dfda 100644
--- a/src/Umbraco.Tests/TestHelpers/Stubs/TestPublishedContent.cs
+++ b/src/Umbraco.Tests/TestHelpers/Stubs/TestPublishedContent.cs
@@ -18,12 +18,12 @@ namespace Umbraco.Tests.TestHelpers.Stubs
public int TemplateId { get; set; }
public int SortOrder { get; set; }
public string Name { get; set; }
- public IPublishedVariationContextAccessor VariationContextAccessor { get; set; }
+ public ICurrentVariationAccessor VariationAccessor { get; set; }
public PublishedCultureInfos GetCulture(string culture = ".")
{
// handle context culture
if (culture == ".")
- culture = VariationContextAccessor?.Context.Culture;
+ culture = VariationAccessor?.CurrentVariation.Culture;
// no invariant culture infos
if (culture == null || Cultures == null) return null;
@@ -45,6 +45,7 @@ namespace Umbraco.Tests.TestHelpers.Stubs
public Guid Version { get; set; }
public int Level { get; set; }
public string Url { get; set; }
+ public string GetUrl(string culture = ".") => throw new NotSupportedException();
public PublishedItemType ItemType => ContentType.ItemType;
public bool IsDraft { get; set; }
public IPublishedContent Parent { get; set; }
diff --git a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs
index 75b9d6b0fd..2c2b275e7f 100644
--- a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs
+++ b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs
@@ -264,7 +264,7 @@ namespace Umbraco.Tests.TestHelpers
// testing=true so XmlStore will not use the file nor the database
var publishedSnapshotAccessor = new UmbracoContextPublishedSnapshotAccessor(Umbraco.Web.Composing.Current.UmbracoContextAccessor);
- var variationContextAccessor = new TestPublishedVariationContextAccessor();
+ var variationContextAccessor = new TestCurrentVariationAccessor();
var service = new PublishedSnapshotService(
ServiceContext,
Container.GetInstance(),
diff --git a/src/Umbraco.Tests/Testing/Objects/Accessors/TestCurrentVariationAccessor.cs b/src/Umbraco.Tests/Testing/Objects/Accessors/TestCurrentVariationAccessor.cs
new file mode 100644
index 0000000000..3b2ad36f00
--- /dev/null
+++ b/src/Umbraco.Tests/Testing/Objects/Accessors/TestCurrentVariationAccessor.cs
@@ -0,0 +1,17 @@
+using Umbraco.Core.Models.PublishedContent;
+
+namespace Umbraco.Tests.Testing.Objects.Accessors
+{
+ ///
+ /// Provides an implementation of for tests.
+ ///
+ public class TestCurrentVariationAccessor : ICurrentVariationAccessor
+ {
+ ///
+ public CurrentVariation CurrentVariation
+ {
+ get;
+ set;
+ }
+ }
+}
diff --git a/src/Umbraco.Tests/Testing/Objects/Accessors/TestPublishedVariationContextAccessor.cs b/src/Umbraco.Tests/Testing/Objects/Accessors/TestPublishedVariationContextAccessor.cs
deleted file mode 100644
index 455e5795a9..0000000000
--- a/src/Umbraco.Tests/Testing/Objects/Accessors/TestPublishedVariationContextAccessor.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using Umbraco.Core.Models.PublishedContent;
-
-namespace Umbraco.Tests.Testing.Objects.Accessors
-{
- ///
- /// Provides an implementation of for tests.
- ///
- public class TestPublishedVariationContextAccessor : IPublishedVariationContextAccessor
- {
- ///
- public PublishedVariationContext Context
- {
- get;
- set;
- }
- }
-}
diff --git a/src/Umbraco.Tests/Testing/Objects/TestDataSource.cs b/src/Umbraco.Tests/Testing/Objects/TestDataSource.cs
new file mode 100644
index 0000000000..26bfff0e1a
--- /dev/null
+++ b/src/Umbraco.Tests/Testing/Objects/TestDataSource.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Umbraco.Core.Scoping;
+using Umbraco.Web.PublishedCache.NuCache;
+using Umbraco.Web.PublishedCache.NuCache.DataSource;
+
+namespace Umbraco.Tests.Testing.Objects
+{
+ internal class TestDataSource : IDataSource
+ {
+ private readonly Dictionary _kits;
+
+ public TestDataSource(params ContentNodeKit[] kits)
+ : this((IEnumerable) kits)
+ { }
+
+ public TestDataSource(IEnumerable kits)
+ {
+ _kits = kits.ToDictionary(x => x.Node.Id, x => x);
+ }
+
+ public ContentNodeKit GetContentSource(IScope scope, int id)
+ => _kits.TryGetValue(id, out var kit) ? kit : default;
+
+ public IEnumerable GetAllContentSources(IScope scope)
+ => _kits.Values;
+
+ public IEnumerable GetBranchContentSources(IScope scope, int id)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IEnumerable GetTypeContentSources(IScope scope, IEnumerable ids)
+ => _kits.Values.Where(x => ids.Contains(x.ContentTypeId));
+
+ public ContentNodeKit GetMediaSource(IScope scope, int id)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IEnumerable GetAllMediaSources(IScope scope)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IEnumerable GetBranchMediaSources(IScope scope, int id)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IEnumerable GetTypeMediaSources(IScope scope, IEnumerable ids)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/src/Umbraco.Tests/Testing/TestingTests/MockTests.cs b/src/Umbraco.Tests/Testing/TestingTests/MockTests.cs
index 9f06d0de17..f44cba624f 100644
--- a/src/Umbraco.Tests/Testing/TestingTests/MockTests.cs
+++ b/src/Umbraco.Tests/Testing/TestingTests/MockTests.cs
@@ -1,11 +1,13 @@
using System;
using System.Globalization;
+using System.Linq;
using System.Web.Security;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Dictionary;
+using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Services;
using Umbraco.Tests.TestHelpers;
@@ -75,13 +77,18 @@ namespace Umbraco.Tests.Testing.TestingTests
var umbracoContext = TestObjects.GetUmbracoContextMock();
var urlProviderMock = new Mock();
- urlProviderMock.Setup(provider => provider.GetUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()))
+ urlProviderMock.Setup(provider => provider.GetUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()))
.Returns("/hello/world/1234");
var urlProvider = urlProviderMock.Object;
var theUrlProvider = new UrlProvider(umbracoContext, new [] { urlProvider });
- Assert.AreEqual("/hello/world/1234", theUrlProvider.GetUrl(1234));
+ var contentType = new PublishedContentType(666, "alias", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(),
+ ContentVariation.InvariantNeutral);
+ var publishedContent = Mock.Of();
+ Mock.Get(publishedContent).Setup(x => x.ContentType).Returns(contentType);
+
+ Assert.AreEqual("/hello/world/1234", theUrlProvider.GetUrl(publishedContent));
}
}
}
diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj
index c1d1da0b54..bf8dc2285a 100644
--- a/src/Umbraco.Tests/Umbraco.Tests.csproj
+++ b/src/Umbraco.Tests/Umbraco.Tests.csproj
@@ -129,7 +129,8 @@
-
+
+
@@ -180,7 +181,7 @@
-
+
diff --git a/src/Umbraco.Tests/Web/TemplateUtilitiesTests.cs b/src/Umbraco.Tests/Web/TemplateUtilitiesTests.cs
index 165f103d43..27a4541733 100644
--- a/src/Umbraco.Tests/Web/TemplateUtilitiesTests.cs
+++ b/src/Umbraco.Tests/Web/TemplateUtilitiesTests.cs
@@ -1,5 +1,6 @@
using System;
using System.Globalization;
+using System.Linq;
using System.Web;
using LightInject;
using Moq;
@@ -10,6 +11,7 @@ using Umbraco.Core.Composing;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
+using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Services;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Stubs;
@@ -44,7 +46,7 @@ namespace Umbraco.Tests.Web
Current.Container = container.Object;
Umbraco.Web.Composing.Current.UmbracoContextAccessor = new TestUmbracoContextAccessor();
-
+
Udi.ResetUdiTypes();
}
@@ -66,26 +68,36 @@ namespace Umbraco.Tests.Web
//setup a mock entity service from the service context to return an integer for a GUID
var entityService = Mock.Get(serviceCtxMock.EntityService);
- entityService.Setup(x => x.GetId(It.IsAny(), It.IsAny()))
- .Returns((Guid id, UmbracoObjectTypes objType) =>
- {
- return Attempt.Succeed(1234);
- });
+ //entityService.Setup(x => x.GetId(It.IsAny(), It.IsAny()))
+ // .Returns((Guid id, UmbracoObjectTypes objType) =>
+ // {
+ // return Attempt.Succeed(1234);
+ // });
//setup a mock url provider which we'll use fo rtesting
var testUrlProvider = new Mock();
- testUrlProvider.Setup(x => x.GetUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()))
- .Returns((UmbracoContext umbCtx, int id, Uri url, UrlProviderMode mode, string culture) =>
- {
- return "/my-test-url";
- });
+ testUrlProvider
+ .Setup(x => x.GetUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()))
+ .Returns((UmbracoContext umbCtx, IPublishedContent content, UrlProviderMode mode, string culture, Uri url) => "/my-test-url");
var globalSettings = SettingsForTests.GenerateMockGlobalSettings();
+ var contentType = new PublishedContentType(666, "alia", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.InvariantNeutral);
+ var publishedContent = Mock.Of();
+ Mock.Get(publishedContent).Setup(x => x.Id).Returns(1234);
+ Mock.Get(publishedContent).Setup(x => x.ContentType).Returns(contentType);
+ var contentCache = Mock.Of();
+ Mock.Get(contentCache).Setup(x => x.GetById(It.IsAny())).Returns(publishedContent);
+ Mock.Get(contentCache).Setup(x => x.GetById(It.IsAny())).Returns(publishedContent);
+ var snapshot = Mock.Of();
+ Mock.Get(snapshot).Setup(x => x.Content).Returns(contentCache);
+ var snapshotService = Mock.Of();
+ Mock.Get(snapshotService).Setup(x => x.CreatePublishedSnapshot(It.IsAny())).Returns(snapshot);
+
using (var umbCtx = UmbracoContext.EnsureContext(
Umbraco.Web.Composing.Current.UmbracoContextAccessor,
Mock.Of(),
- Mock.Of(),
+ snapshotService,
new Mock(null, null, globalSettings).Object,
//setup a quick mock of the WebRouting section
Mock.Of(section => section.WebRouting == Mock.Of(routingSection => routingSection.UrlProviderMode == "AutoLegacy")),
diff --git a/src/Umbraco.Web/Editors/MacroController.cs b/src/Umbraco.Web/Editors/MacroController.cs
index ba23d4c8dd..bc0d1f4a0c 100644
--- a/src/Umbraco.Web/Editors/MacroController.cs
+++ b/src/Umbraco.Web/Editors/MacroController.cs
@@ -27,11 +27,11 @@ namespace Umbraco.Web.Editors
[PluginController("UmbracoApi")]
public class MacroController : UmbracoAuthorizedJsonController, IRequiresSessionState
{
- private readonly IPublishedVariationContextAccessor _variationContextAccessor;
+ private readonly ICurrentVariationAccessor _variationAccessor;
- public MacroController(IPublishedVariationContextAccessor variationContextAccessor)
+ public MacroController(ICurrentVariationAccessor variationAccessor)
{
- _variationContextAccessor = variationContextAccessor;
+ _variationAccessor = variationAccessor;
}
///
@@ -121,7 +121,7 @@ namespace Umbraco.Web.Editors
//the 'easiest' way might be to create an IPublishedContent manually and populate the legacy 'page' object with that
//and then set the legacy parameters.
- var legacyPage = new global::umbraco.page(doc, _variationContextAccessor);
+ var legacyPage = new global::umbraco.page(doc, _variationAccessor);
UmbracoContext.HttpContext.Items["pageID"] = doc.Id;
UmbracoContext.HttpContext.Items["pageElements"] = legacyPage.Elements;
UmbracoContext.HttpContext.Items[global::Umbraco.Core.Constants.Conventions.Url.AltTemplate] = null;
diff --git a/src/Umbraco.Web/Models/PublishedContentBase.cs b/src/Umbraco.Web/Models/PublishedContentBase.cs
index 0fe7bc0fc7..1c91b41bff 100644
--- a/src/Umbraco.Web/Models/PublishedContentBase.cs
+++ b/src/Umbraco.Web/Models/PublishedContentBase.cs
@@ -1,11 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
-using System.Globalization;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
using Umbraco.Core;
-using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PropertyEditors.ValueConverters;
@@ -19,7 +15,7 @@ namespace Umbraco.Web.Models
[DebuggerDisplay("Content Id: {Id}, Name: {Name}")]
public abstract class PublishedContentBase : IPublishedContent
{
- private string _url;
+ private string _url; // fixme meaning?
#region ContentType
@@ -75,34 +71,31 @@ namespace Umbraco.Web.Models
///
public abstract DateTime UpdateDate { get; }
+ ///
+ public virtual string Url => GetUrl();
+
///
///
/// The url of documents are computed by the document url providers. The url of medias are, at the moment,
/// computed here from the 'umbracoFile' property -- but we should move to media url providers at some point.
///
- public virtual string Url
+ public virtual string GetUrl(string culture = ".") // fixme - consider .GetCulture("fr-FR").Url
{
- // fixme contextual!
- get
- {
- // should be thread-safe although it won't prevent url from being resolved more than once
- if (_url != null)
- return _url; // fixme very bad idea with nucache? or?
-
switch (ItemType)
{
- case PublishedItemType.Content:
+ case PublishedItemType.Content:
+ // fixme inject an umbraco context accessor!
if (UmbracoContext.Current == null)
- throw new InvalidOperationException(
- "Cannot resolve a Url for a content item when UmbracoContext.Current is null.");
+ throw new InvalidOperationException("Cannot compute Url for a content item when UmbracoContext.Current is null.");
if (UmbracoContext.Current.UrlProvider == null)
- throw new InvalidOperationException(
- "Cannot resolve a Url for a content item when UmbracoContext.Current.UrlProvider is null.");
- _url = UmbracoContext.Current.UrlProvider.GetUrl(Id);
- break;
+ throw new InvalidOperationException("Cannot compute Url for a content item when UmbracoContext.Current.UrlProvider is null.");
+ return UmbracoContext.Current.UrlProvider.GetUrl(this);
+
case PublishedItemType.Media:
+ if (_url != null) return _url; // assume it will not depend on current uri/culture
+
var prop = GetProperty(Constants.Conventions.Media.File);
- if (prop == null || prop.GetValue() == null)
+ if (prop?.GetValue() == null)
{
_url = string.Empty;
return _url;
@@ -110,7 +103,7 @@ namespace Umbraco.Web.Models
var propType = ContentType.GetPropertyType(Constants.Conventions.Media.File);
- // fixme this is horrible we need url providers for media too
+ // fixme this is horrible we need url providers for media too + this does NOT support variations
//This is a hack - since we now have 2 properties that support a URL: upload and cropper, we need to detect this since we always
// want to return the normal URL and the cropper stores data as json
switch (propType.EditorAlias)
@@ -130,13 +123,12 @@ namespace Umbraco.Web.Models
_url = prop.GetValue()?.ToString();
break;
}
- break;
+
+ return _url;
+
default:
throw new NotSupportedException();
}
-
- return _url;
- }
}
///
@@ -174,7 +166,7 @@ namespace Umbraco.Web.Models
///
public virtual IPublishedProperty GetProperty(string alias, bool recurse)
{
- // fixme - but can this work with variants?
+ // fixme - but can recurse work with variants?
var property = GetProperty(alias);
if (recurse == false) return property;
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/ContentNode.cs b/src/Umbraco.Web/PublishedCache/NuCache/ContentNode.cs
index de658daeec..1a562dad79 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/ContentNode.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/ContentNode.cs
@@ -34,10 +34,10 @@ namespace Umbraco.Web.PublishedCache.NuCache
DateTime createDate, int creatorId,
ContentData draftData, ContentData publishedData,
IPublishedSnapshotAccessor publishedSnapshotAccessor,
- IPublishedVariationContextAccessor variationContextAccessor)
+ ICurrentVariationAccessor variationAccessor)
: this(id, uid, level, path, sortOrder, parentContentId, createDate, creatorId)
{
- SetContentTypeAndData(contentType, draftData, publishedData, publishedSnapshotAccessor, variationContextAccessor);
+ SetContentTypeAndData(contentType, draftData, publishedData, publishedSnapshotAccessor, variationAccessor);
}
// 2-phases ctor, phase 1
@@ -59,7 +59,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
}
// two-phase ctor, phase 2
- public void SetContentTypeAndData(PublishedContentType contentType, ContentData draftData, ContentData publishedData, IPublishedSnapshotAccessor publishedSnapshotAccessor, IPublishedVariationContextAccessor variationContextAccessor)
+ public void SetContentTypeAndData(PublishedContentType contentType, ContentData draftData, ContentData publishedData, IPublishedSnapshotAccessor publishedSnapshotAccessor, ICurrentVariationAccessor variationAccessor)
{
ContentType = contentType;
@@ -67,9 +67,9 @@ namespace Umbraco.Web.PublishedCache.NuCache
throw new ArgumentException("Both draftData and publishedData cannot be null at the same time.");
if (draftData != null)
- Draft = new PublishedContent(this, draftData, publishedSnapshotAccessor, variationContextAccessor).CreateModel();
+ Draft = new PublishedContent(this, draftData, publishedSnapshotAccessor, variationAccessor).CreateModel();
if (publishedData != null)
- Published = new PublishedContent(this, publishedData, publishedSnapshotAccessor, variationContextAccessor).CreateModel();
+ Published = new PublishedContent(this, publishedData, publishedSnapshotAccessor, variationAccessor).CreateModel();
}
// clone parent
@@ -98,7 +98,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
}
// clone with new content type
- public ContentNode(ContentNode origin, PublishedContentType contentType, IPublishedSnapshotAccessor publishedSnapshotAccessor, IPublishedVariationContextAccessor variationContextAccessor)
+ public ContentNode(ContentNode origin, PublishedContentType contentType, IPublishedSnapshotAccessor publishedSnapshotAccessor, ICurrentVariationAccessor variationAccessor)
{
Id = origin.Id;
Uid = origin.Uid;
@@ -113,8 +113,8 @@ namespace Umbraco.Web.PublishedCache.NuCache
var originDraft = origin.Draft == null ? null : PublishedContent.UnwrapIPublishedContent(origin.Draft);
var originPublished = origin.Published == null ? null : PublishedContent.UnwrapIPublishedContent(origin.Published);
- Draft = originDraft == null ? null : new PublishedContent(this, originDraft._contentData, publishedSnapshotAccessor, variationContextAccessor).CreateModel();
- Published = originPublished == null ? null : new PublishedContent(this, originPublished._contentData, publishedSnapshotAccessor, variationContextAccessor).CreateModel();
+ Draft = originDraft == null ? null : new PublishedContent(this, originDraft._contentData, publishedSnapshotAccessor, variationAccessor).CreateModel();
+ Published = originPublished == null ? null : new PublishedContent(this, originPublished._contentData, publishedSnapshotAccessor, variationAccessor).CreateModel();
ChildContentIds = origin.ChildContentIds; // can be the *same* list FIXME oh really?
}
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/ContentNodeKit.cs b/src/Umbraco.Web/PublishedCache/NuCache/ContentNodeKit.cs
index 19163d5e8d..d4d4221bf0 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/ContentNodeKit.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/ContentNodeKit.cs
@@ -17,9 +17,9 @@ namespace Umbraco.Web.PublishedCache.NuCache
public static ContentNodeKit Null { get; } = new ContentNodeKit { ContentTypeId = -1 };
- public void Build(PublishedContentType contentType, IPublishedSnapshotAccessor publishedSnapshotAccessor, IPublishedVariationContextAccessor variationContextAccessor)
+ public void Build(PublishedContentType contentType, IPublishedSnapshotAccessor publishedSnapshotAccessor, ICurrentVariationAccessor variationAccessor)
{
- Node.SetContentTypeAndData(contentType, DraftData, PublishedData, publishedSnapshotAccessor, variationContextAccessor);
+ Node.SetContentTypeAndData(contentType, DraftData, PublishedData, publishedSnapshotAccessor, variationAccessor);
}
}
}
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/ContentStore.cs b/src/Umbraco.Web/PublishedCache/NuCache/ContentStore.cs
index 95482bb6b1..b19e9f5ddf 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/ContentStore.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/ContentStore.cs
@@ -19,7 +19,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
// SnapDictionary has unit tests to ensure it all works correctly
private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor;
- private readonly IPublishedVariationContextAccessor _variationContextAccessor;
+ private readonly ICurrentVariationAccessor _variationAccessor;
private readonly ConcurrentDictionary> _contentNodes;
private readonly ConcurrentDictionary> _contentRootNodes;
private readonly ConcurrentDictionary> _contentTypesById;
@@ -44,10 +44,10 @@ namespace Umbraco.Web.PublishedCache.NuCache
#region Ctor
- public ContentStore(IPublishedSnapshotAccessor publishedSnapshotAccessor, IPublishedVariationContextAccessor variationContextAccessor, ILogger logger, BPlusTree localDb = null)
+ public ContentStore(IPublishedSnapshotAccessor publishedSnapshotAccessor, ICurrentVariationAccessor variationAccessor, ILogger logger, BPlusTree localDb = null)
{
_publishedSnapshotAccessor = publishedSnapshotAccessor;
- _variationContextAccessor = variationContextAccessor;
+ _variationAccessor = variationAccessor;
_logger = logger;
_localDb = localDb;
@@ -279,7 +279,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
if (node == null) continue;
var contentTypeId = node.ContentType.Id;
if (index.TryGetValue(contentTypeId, out PublishedContentType contentType) == false) continue;
- SetValueLocked(_contentNodes, node.Id, new ContentNode(node, contentType, _publishedSnapshotAccessor, _variationContextAccessor));
+ SetValueLocked(_contentNodes, node.Id, new ContentNode(node, contentType, _publishedSnapshotAccessor, _variationAccessor));
}
}
finally
@@ -393,7 +393,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
_contentNodes.TryGetValue(id, out LinkedNode link);
if (link?.Value == null)
continue;
- var node = new ContentNode(link.Value, contentType, _publishedSnapshotAccessor, _variationContextAccessor);
+ var node = new ContentNode(link.Value, contentType, _publishedSnapshotAccessor, _variationAccessor);
SetValueLocked(_contentNodes, id, node);
if (_localDb != null) RegisterChange(id, node.ToKit());
}
@@ -416,7 +416,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
return false;
// and use
- kit.Build(link.Value, _publishedSnapshotAccessor, _variationContextAccessor);
+ kit.Build(link.Value, _publishedSnapshotAccessor, _variationAccessor);
return true;
}
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/MemberCache.cs b/src/Umbraco.Web/PublishedCache/NuCache/MemberCache.cs
index 899fbd6eed..61f3d9862d 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/MemberCache.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/MemberCache.cs
@@ -16,7 +16,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
class MemberCache : IPublishedMemberCache, INavigableData
{
private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor;
- public readonly IPublishedVariationContextAccessor _variationContextAccessor;
+ public readonly ICurrentVariationAccessor VariationAccessor;
private readonly ICacheProvider _snapshotCache;
private readonly IMemberService _memberService;
private readonly IDataTypeService _dataTypeService;
@@ -24,11 +24,11 @@ namespace Umbraco.Web.PublishedCache.NuCache
private readonly PublishedContentTypeCache _contentTypeCache;
private readonly bool _previewDefault;
- public MemberCache(bool previewDefault, ICacheProvider snapshotCache, IMemberService memberService, IDataTypeService dataTypeService, ILocalizationService localizationService, PublishedContentTypeCache contentTypeCache, IPublishedSnapshotAccessor publishedSnapshotAccessor, IPublishedVariationContextAccessor variationContextAccessor)
+ public MemberCache(bool previewDefault, ICacheProvider snapshotCache, IMemberService memberService, IDataTypeService dataTypeService, ILocalizationService localizationService, PublishedContentTypeCache contentTypeCache, IPublishedSnapshotAccessor publishedSnapshotAccessor, ICurrentVariationAccessor variationAccessor)
{
_snapshotCache = snapshotCache;
_publishedSnapshotAccessor = publishedSnapshotAccessor;
- _variationContextAccessor = variationContextAccessor;
+ VariationAccessor = variationAccessor;
_memberService = memberService;
_dataTypeService = dataTypeService;
_localizationService = localizationService;
@@ -65,14 +65,14 @@ namespace Umbraco.Web.PublishedCache.NuCache
var member = _memberService.GetById(memberId);
return member == null
? null
- : PublishedMember.Create(member, GetContentType(member.ContentTypeId), _previewDefault, _publishedSnapshotAccessor, _variationContextAccessor);
+ : PublishedMember.Create(member, GetContentType(member.ContentTypeId), _previewDefault, _publishedSnapshotAccessor, VariationAccessor);
});
}
private IPublishedContent /*IPublishedMember*/ GetById(IMember member, bool previewing)
{
return GetCacheItem(CacheKeys.MemberCacheMember("ById", _previewDefault, member.Id), () =>
- PublishedMember.Create(member, GetContentType(member.ContentTypeId), previewing, _publishedSnapshotAccessor, _variationContextAccessor));
+ PublishedMember.Create(member, GetContentType(member.ContentTypeId), previewing, _publishedSnapshotAccessor, VariationAccessor));
}
public IPublishedContent /*IPublishedMember*/ GetByProviderKey(object key)
@@ -107,7 +107,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
public IPublishedContent /*IPublishedMember*/ GetByMember(IMember member)
{
- return PublishedMember.Create(member, GetContentType(member.ContentTypeId), _previewDefault, _publishedSnapshotAccessor, _variationContextAccessor);
+ return PublishedMember.Create(member, GetContentType(member.ContentTypeId), _previewDefault, _publishedSnapshotAccessor, VariationAccessor);
}
public IEnumerable GetAtRoot(bool preview)
@@ -115,7 +115,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
// because members are flat (not a tree) everything is at root
// because we're loading everything... let's just not cache?
var members = _memberService.GetAllMembers();
- return members.Select(m => PublishedMember.Create(m, GetContentType(m.ContentTypeId), preview, _publishedSnapshotAccessor, _variationContextAccessor));
+ return members.Select(m => PublishedMember.Create(m, GetContentType(m.ContentTypeId), preview, _publishedSnapshotAccessor, VariationAccessor));
}
public XPathNavigator CreateNavigator()
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/Property.cs b/src/Umbraco.Web/PublishedCache/NuCache/Property.cs
index 02dfc4e934..6231425e50 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/Property.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/Property.cs
@@ -191,7 +191,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
// use context values
// fixme CultureSegment?
- var publishedVariationContext = _content.VariationContextAccessor?.Context;
+ var publishedVariationContext = _content.VariationAccessor?.CurrentVariation;
if (culture == ".") culture = _variations.Has(ContentVariation.CultureNeutral) ? publishedVariationContext?.Culture : null;
if (segment == ".") segment = _variations.Has(ContentVariation.CultureNeutral) ? publishedVariationContext?.Segment : null;
}
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs
index 0ca20fd625..ea2480ec7a 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs
@@ -22,12 +22,12 @@ namespace Umbraco.Web.PublishedCache.NuCache
#region Constructors
- public PublishedContent(ContentNode contentNode, ContentData contentData, IPublishedSnapshotAccessor publishedSnapshotAccessor, IPublishedVariationContextAccessor variationContextAccessor)
+ public PublishedContent(ContentNode contentNode, ContentData contentData, IPublishedSnapshotAccessor publishedSnapshotAccessor, ICurrentVariationAccessor variationAccessor)
{
_contentNode = contentNode;
_contentData = contentData;
_publishedSnapshotAccessor = publishedSnapshotAccessor;
- VariationContextAccessor = variationContextAccessor; // fixme why is this a property? should be be on the base class?
+ VariationAccessor = variationAccessor; // fixme why is this a property? should be be on the base class?
_urlSegment = _contentData.Name.ToUrlSegment();
IsPreviewing = _contentData.Published == false;
@@ -70,7 +70,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
{
_contentNode = contentNode;
_publishedSnapshotAccessor = origin._publishedSnapshotAccessor;
- VariationContextAccessor = origin.VariationContextAccessor;
+ VariationAccessor = origin.VariationAccessor;
_contentData = origin._contentData;
_urlSegment = origin._urlSegment;
@@ -86,7 +86,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
private PublishedContent(PublishedContent origin)
{
_publishedSnapshotAccessor = origin._publishedSnapshotAccessor;
- VariationContextAccessor = origin.VariationContextAccessor;
+ VariationAccessor = origin.VariationAccessor;
_contentNode = origin._contentNode;
_contentData = origin._contentData;
@@ -181,7 +181,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
if (!ContentType.Variations.Has(ContentVariation.CultureNeutral)) // fixme CultureSegment?
return _contentData.Name;
- var culture = VariationContextAccessor.Context.Culture;
+ var culture = VariationAccessor.CurrentVariation.Culture;
if (culture == null)
return _contentData.Name;
@@ -197,7 +197,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
if (!ContentType.Variations.Has(ContentVariation.CultureNeutral)) // fixme CultureSegment?
return _urlSegment;
- var culture = VariationContextAccessor.Context.Culture;
+ var culture = VariationAccessor.CurrentVariation.Culture;
if (culture == null)
return _urlSegment;
@@ -244,7 +244,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
{
// handle context culture
if (culture == ".")
- culture = VariationContextAccessor.Context.Culture;
+ culture = VariationAccessor.CurrentVariation.Culture;
// no invariant culture infos
if (culture == null) return null;
@@ -397,7 +397,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
#region Internal
- internal IPublishedVariationContextAccessor VariationContextAccessor { get; }
+ internal ICurrentVariationAccessor VariationAccessor { get; }
// used by navigable content
internal IPublishedProperty[] PropertiesArray { get; }
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedMember.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedMember.cs
index 63ef1ae5aa..4e01df0cd9 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedMember.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedMember.cs
@@ -15,13 +15,13 @@ namespace Umbraco.Web.PublishedCache.NuCache
{
private readonly IMember _member;
- private PublishedMember(IMember member, ContentNode contentNode, ContentData contentData, IPublishedSnapshotAccessor publishedSnapshotAccessor, IPublishedVariationContextAccessor variationContextAccessor)
- : base(contentNode, contentData, publishedSnapshotAccessor, variationContextAccessor)
+ private PublishedMember(IMember member, ContentNode contentNode, ContentData contentData, IPublishedSnapshotAccessor publishedSnapshotAccessor, ICurrentVariationAccessor variationAccessor)
+ : base(contentNode, contentData, publishedSnapshotAccessor, variationAccessor)
{
_member = member;
}
- public static IPublishedContent Create(IMember member, PublishedContentType contentType, bool previewing, IPublishedSnapshotAccessor publishedSnapshotAccessor, IPublishedVariationContextAccessor variationContextAccessor)
+ public static IPublishedContent Create(IMember member, PublishedContentType contentType, bool previewing, IPublishedSnapshotAccessor publishedSnapshotAccessor, ICurrentVariationAccessor variationAccessor)
{
var d = new ContentData
{
@@ -37,7 +37,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
member.Level, member.Path, member.SortOrder,
member.ParentId,
member.CreateDate, member.CreatorId);
- return new PublishedMember(member, n, d, publishedSnapshotAccessor, variationContextAccessor).CreateModel();
+ return new PublishedMember(member, n, d, publishedSnapshotAccessor, variationAccessor).CreateModel();
}
private static Dictionary GetPropertyValues(PublishedContentType contentType, IMember member)
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs
index b2cb8bbcf8..3108f24090 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs
@@ -81,12 +81,12 @@ namespace Umbraco.Web.PublishedCache.NuCache
public PublishedSnapshotService(Options options, MainDom mainDom, IRuntimeState runtime,
ServiceContext serviceContext, IPublishedContentTypeFactory publishedContentTypeFactory, IdkMap idkMap,
- IPublishedSnapshotAccessor publishedSnapshotAccessor, IPublishedVariationContextAccessor variationContextAccessor,
+ IPublishedSnapshotAccessor publishedSnapshotAccessor, ICurrentVariationAccessor variationAccessor,
ILogger logger, IScopeProvider scopeProvider,
IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository,
ISystemDefaultCultureAccessor systemDefaultCultureAccessor,
IDataSource dataSource, IGlobalSettings globalSettings, ISiteDomainHelper siteDomainHelper)
- : base(publishedSnapshotAccessor, variationContextAccessor)
+ : base(publishedSnapshotAccessor, variationAccessor)
{
//if (Interlocked.Increment(ref _singletonCheck) > 1)
// throw new Exception("Singleton must be instancianted only once!");
@@ -145,13 +145,13 @@ namespace Umbraco.Web.PublishedCache.NuCache
// stores are created with a db so they can write to it, but they do not read from it,
// stores need to be populated, happens in OnResolutionFrozen which uses _localDbExists to
// figure out whether it can read the dbs or it should populate them from sql
- _contentStore = new ContentStore(publishedSnapshotAccessor, variationContextAccessor, logger, _localContentDb);
- _mediaStore = new ContentStore(publishedSnapshotAccessor, variationContextAccessor, logger, _localMediaDb);
+ _contentStore = new ContentStore(publishedSnapshotAccessor, variationAccessor, logger, _localContentDb);
+ _mediaStore = new ContentStore(publishedSnapshotAccessor, variationAccessor, logger, _localMediaDb);
}
else
{
- _contentStore = new ContentStore(publishedSnapshotAccessor, variationContextAccessor, logger);
- _mediaStore = new ContentStore(publishedSnapshotAccessor, variationContextAccessor, logger);
+ _contentStore = new ContentStore(publishedSnapshotAccessor, variationAccessor, logger);
+ _mediaStore = new ContentStore(publishedSnapshotAccessor, variationAccessor, logger);
}
_domainStore = new SnapDictionary();
@@ -173,7 +173,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
try
{
- if (_localDbExists) // fixme?
+ if (_localDbExists)
{
LockAndLoadContent(LoadContentFromLocalDbLocked);
LockAndLoadMedia(LoadMediaFromLocalDbLocked);
@@ -333,7 +333,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
//private void LoadContent(IContent content)
//{
// var contentService = _serviceContext.ContentService as ContentService;
- // if (contentService == null) throw new Exception("oops");
// var newest = content;
// var published = newest.Published
// ? newest
@@ -536,7 +535,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
}
if (draftChanged || publishedChanged)
- ((PublishedSnapshot)CurrentPublishedSnapshot).Resync();
+ ((PublishedSnapshot)CurrentPublishedSnapshot)?.Resync();
}
private void NotifyLocked(IEnumerable payloads, out bool draftChanged, out bool publishedChanged)
@@ -544,9 +543,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
publishedChanged = false;
draftChanged = false;
- if (!(_serviceContext.ContentService is ContentService))
- throw new Exception("oops");
-
// locks:
// content (and content types) are read-locked while reading content
// contentStore is wlocked (so readable, only no new views)
@@ -633,16 +629,13 @@ namespace Umbraco.Web.PublishedCache.NuCache
}
if (anythingChanged)
- ((PublishedSnapshot)CurrentPublishedSnapshot).Resync();
+ ((PublishedSnapshot)CurrentPublishedSnapshot)?.Resync();
}
private void NotifyLocked(IEnumerable payloads, out bool anythingChanged)
{
anythingChanged = false;
- if (!(_serviceContext.MediaService is MediaService))
- throw new Exception("oops");
-
// locks:
// see notes for content cache refresher
@@ -722,7 +715,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
Notify(_contentStore, payloads, RefreshContentTypesLocked);
Notify(_mediaStore, payloads, RefreshMediaTypesLocked);
- ((PublishedSnapshot)CurrentPublishedSnapshot)?.Resync(); // fixme all
+ ((PublishedSnapshot)CurrentPublishedSnapshot)?.Resync();
}
private void Notify(ContentStore store, ContentTypeCacheRefresher.JsonPayload[] payloads, Action, IEnumerable, IEnumerable, IEnumerable> action)
@@ -778,9 +771,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
// some locking on datatypes
_publishedContentTypeFactory.NotifyDataTypeChanges(idsA);
- if (!(_serviceContext.ContentService is ContentService))
- throw new Exception("oops");
-
using (var scope = _scopeProvider.CreateScope())
{
scope.ReadLock(Constants.Locks.ContentTree);
@@ -788,9 +778,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
scope.Complete();
}
- if (!(_serviceContext.MediaService is MediaService))
- throw new Exception("oops");
-
using (var scope = _scopeProvider.CreateScope())
{
scope.ReadLock(Constants.Locks.MediaTree);
@@ -799,7 +786,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
}
}
- ((PublishedSnapshot)CurrentPublishedSnapshot)?.Resync(); // fixme elsewhere!
+ ((PublishedSnapshot)CurrentPublishedSnapshot)?.Resync();
}
public override void Notify(DomainCacheRefresher.JsonPayload[] payloads)
@@ -815,8 +802,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
switch (payload.ChangeType)
{
case DomainChangeTypes.RefreshAll:
- if (!(_serviceContext.DomainService is DomainService))
- throw new Exception("oops");
using (var scope = _scopeProvider.CreateScope())
{
@@ -900,10 +885,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
// contentStore is wlocked (so readable, only no new views)
// and it can be wlocked by 1 thread only at a time
- // fixme wtf?
- //if (!(_serviceContext.ContentService is ContentService))
- // throw new Exception("oops");
-
var refreshedIdsA = refreshedIds.ToArray();
using (var scope = _scopeProvider.CreateScope())
@@ -925,9 +906,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
// mediaStore is wlocked (so readable, only no new views)
// and it can be wlocked by 1 thread only at a time
- if (!(_serviceContext.MediaService is MediaService))
- throw new Exception("oops");
-
var refreshedIdsA = refreshedIds.ToArray();
using (var scope = _scopeProvider.CreateScope())
@@ -1000,7 +978,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
// a MaxValue to make sure this one runs last, and it should be ok
scopeContext.Enlist("Umbraco.Web.PublishedCache.NuCache.PublishedSnapshotService.Resync", () => this, (completed, svc) =>
{
- ((PublishedSnapshot)svc.CurrentPublishedSnapshot).Resync();
+ ((PublishedSnapshot)svc.CurrentPublishedSnapshot)?.Resync();
}, int.MaxValue);
}
@@ -1026,7 +1004,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
{
ContentCache = new ContentCache(previewDefault, contentSnap, snapshotCache, elementsCache, domainHelper, _globalSettings, _serviceContext.LocalizationService),
MediaCache = new MediaCache(previewDefault, mediaSnap, snapshotCache, elementsCache),
- MemberCache = new MemberCache(previewDefault, snapshotCache, _serviceContext.MemberService, _serviceContext.DataTypeService, _serviceContext.LocalizationService, memberTypeCache, PublishedSnapshotAccessor, VariationContextAccessor),
+ MemberCache = new MemberCache(previewDefault, snapshotCache, _serviceContext.MemberService, _serviceContext.DataTypeService, _serviceContext.LocalizationService, memberTypeCache, PublishedSnapshotAccessor, VariationAccessor),
DomainCache = domainCache,
SnapshotCache = snapshotCache,
ElementsCache = elementsCache
@@ -1084,21 +1062,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
db.Execute("DELETE FROM cmsContentNu WHERE nodeId=@id", new { id = item.Id });
}
- private static readonly string[] PropertiesImpactingAllVersions = { "SortOrder", "ParentId", "Level", "Path", "Trashed" };
-
- private static bool HasChangesImpactingAllVersions(IContent icontent)
- {
- var content = (Content)icontent;
-
- // UpdateDate will be dirty
- // Published may be dirty if saving a Published entity
- // so cannot do this (would always be true):
- //return content.IsEntityDirty();
-
- // have to be more precise & specify properties
- return PropertiesImpactingAllVersions.Any(content.IsPropertyDirty);
- }
-
private void OnContentRefreshedEntity(DocumentRepository sender, DocumentRepository.ScopedEntityEventArgs args)
{
var db = args.Scope.Database;
diff --git a/src/Umbraco.Web/PublishedCache/PublishedSnapshotServiceBase.cs b/src/Umbraco.Web/PublishedCache/PublishedSnapshotServiceBase.cs
index 64dda9f20b..b5d721e03c 100644
--- a/src/Umbraco.Web/PublishedCache/PublishedSnapshotServiceBase.cs
+++ b/src/Umbraco.Web/PublishedCache/PublishedSnapshotServiceBase.cs
@@ -7,14 +7,14 @@ namespace Umbraco.Web.PublishedCache
{
abstract class PublishedSnapshotServiceBase : IPublishedSnapshotService
{
- protected PublishedSnapshotServiceBase(IPublishedSnapshotAccessor publishedSnapshotAccessor, IPublishedVariationContextAccessor variationContextAccessor)
+ protected PublishedSnapshotServiceBase(IPublishedSnapshotAccessor publishedSnapshotAccessor, ICurrentVariationAccessor variationAccessor)
{
PublishedSnapshotAccessor = publishedSnapshotAccessor;
- VariationContextAccessor = variationContextAccessor;
+ VariationAccessor = variationAccessor;
}
public IPublishedSnapshotAccessor PublishedSnapshotAccessor { get; }
- public IPublishedVariationContextAccessor VariationContextAccessor { get; }
+ public ICurrentVariationAccessor VariationAccessor { get; }
// note: NOT setting _publishedSnapshotAccessor.PublishedSnapshot here because it is the
// responsibility of the caller to manage what the 'current' facade is
diff --git a/src/Umbraco.Web/PublishedCache/SystemDefaultCultureAccessor.cs b/src/Umbraco.Web/PublishedCache/SystemDefaultCultureAccessor.cs
index 34910bfe1b..42e1c4dbca 100644
--- a/src/Umbraco.Web/PublishedCache/SystemDefaultCultureAccessor.cs
+++ b/src/Umbraco.Web/PublishedCache/SystemDefaultCultureAccessor.cs
@@ -19,6 +19,6 @@ namespace Umbraco.Web.PublishedCache
}
///
- public string DefaultCulture => _localizationService.GetDefaultLanguageIsoCode(); // capture - fast
+ public string DefaultCulture => _localizationService.GetDefaultLanguageIsoCode(); // fast
}
-}
\ No newline at end of file
+}
diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedSnapshotService.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedSnapshotService.cs
index 259229a600..ab59fc6aca 100644
--- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedSnapshotService.cs
+++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedSnapshotService.cs
@@ -43,7 +43,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
IScopeProvider scopeProvider,
ICacheProvider requestCache,
IEnumerable segmentProviders,
- IPublishedSnapshotAccessor publishedSnapshotAccessor, IPublishedVariationContextAccessor variationContextAccessor,
+ IPublishedSnapshotAccessor publishedSnapshotAccessor, ICurrentVariationAccessor variationAccessor,
IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository,
ISystemDefaultCultureAccessor systemDefaultCultureAccessor,
ILogger logger,
@@ -52,7 +52,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
MainDom mainDom,
bool testing = false, bool enableRepositoryEvents = true)
: this(serviceContext, publishedContentTypeFactory, scopeProvider, requestCache, segmentProviders,
- publishedSnapshotAccessor, variationContextAccessor,
+ publishedSnapshotAccessor, variationAccessor,
documentRepository, mediaRepository, memberRepository,
systemDefaultCultureAccessor,
logger, globalSettings, siteDomainHelper, null, mainDom, testing, enableRepositoryEvents)
@@ -63,7 +63,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
IPublishedContentTypeFactory publishedContentTypeFactory,
IScopeProvider scopeProvider,
ICacheProvider requestCache,
- IPublishedSnapshotAccessor publishedSnapshotAccessor, IPublishedVariationContextAccessor variationContextAccessor,
+ IPublishedSnapshotAccessor publishedSnapshotAccessor, ICurrentVariationAccessor variationAccessor,
IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository,
ISystemDefaultCultureAccessor systemDefaultCultureAccessor,
ILogger logger,
@@ -73,7 +73,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
MainDom mainDom,
bool testing, bool enableRepositoryEvents)
: this(serviceContext, publishedContentTypeFactory, scopeProvider, requestCache, Enumerable.Empty(),
- publishedSnapshotAccessor, variationContextAccessor,
+ publishedSnapshotAccessor, variationAccessor,
documentRepository, mediaRepository, memberRepository,
systemDefaultCultureAccessor,
logger, globalSettings, siteDomainHelper, contentTypeCache, mainDom, testing, enableRepositoryEvents)
@@ -84,7 +84,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
IScopeProvider scopeProvider,
ICacheProvider requestCache,
IEnumerable segmentProviders,
- IPublishedSnapshotAccessor publishedSnapshotAccessor, IPublishedVariationContextAccessor variationContextAccessor,
+ IPublishedSnapshotAccessor publishedSnapshotAccessor, ICurrentVariationAccessor variationAccessor,
IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository,
ISystemDefaultCultureAccessor systemDefaultCultureAccessor,
ILogger logger,
@@ -93,7 +93,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
PublishedContentTypeCache contentTypeCache,
MainDom mainDom,
bool testing, bool enableRepositoryEvents)
- : base(publishedSnapshotAccessor, variationContextAccessor)
+ : base(publishedSnapshotAccessor, variationAccessor)
{
_routesCache = new RoutesCache();
_publishedContentTypeFactory = publishedContentTypeFactory;
diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlCacheComponent.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlCacheComponent.cs
index a574575cbd..76af7102f5 100644
--- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlCacheComponent.cs
+++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlCacheComponent.cs
@@ -29,7 +29,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
factory.GetInstance().RequestCache,
factory.GetInstance(),
factory.GetInstance(),
- factory.GetInstance(),
+ factory.GetInstance(),
factory.GetInstance(),
factory.GetInstance(),
factory.GetInstance(),
diff --git a/src/Umbraco.Web/Routing/AliasUrlProvider.cs b/src/Umbraco.Web/Routing/AliasUrlProvider.cs
index 4b7cb48add..7b7a70cc2a 100644
--- a/src/Umbraco.Web/Routing/AliasUrlProvider.cs
+++ b/src/Umbraco.Web/Routing/AliasUrlProvider.cs
@@ -1,13 +1,10 @@
using System;
using System.Collections.Generic;
-using System.Globalization;
using System.Linq;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
-using Umbraco.Core.Services;
-using Umbraco.Web.Composing;
-using Umbraco.Web.PublishedCache;
+using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Web.Routing
{
@@ -17,15 +14,13 @@ namespace Umbraco.Web.Routing
public class AliasUrlProvider : IUrlProvider
{
private readonly IGlobalSettings _globalSettings;
- private readonly IRequestHandlerSection _requestConfig;
- private readonly ILocalizationService _localizationService;
+ private readonly IRequestHandlerSection _requestConfig;
private readonly ISiteDomainHelper _siteDomainHelper;
- public AliasUrlProvider(IGlobalSettings globalSettings, IRequestHandlerSection requestConfig, ILocalizationService localizationService, ISiteDomainHelper siteDomainHelper)
+ public AliasUrlProvider(IGlobalSettings globalSettings, IRequestHandlerSection requestConfig, ISiteDomainHelper siteDomainHelper)
{
_globalSettings = globalSettings;
- _requestConfig = requestConfig;
- _localizationService = localizationService;
+ _requestConfig = requestConfig;
_siteDomainHelper = siteDomainHelper;
}
@@ -35,20 +30,8 @@ namespace Umbraco.Web.Routing
#region GetUrl
- ///
- /// Gets the nice url of a published content.
- ///
- /// The Umbraco context.
- /// The published content id.
- /// The current absolute url.
- /// The url mode.
- /// The url for the published content.
- ///
- /// The url is absolute or relative depending on url indicated by current and settings, unless
- /// absolute is true, in which case the url is always absolute.
- /// If the provider is unable to provide a url, it should return null.
- ///
- public string GetUrl(UmbracoContext umbracoContext, int id, Uri current, UrlProviderMode mode, string culture = null)
+ ///
+ public string GetUrl(UmbracoContext umbracoContext, IPublishedContent content, UrlProviderMode mode, string culture, Uri current)
{
return null; // we have nothing to say
}
diff --git a/src/Umbraco.Web/Routing/CustomRouteUrlProvider.cs b/src/Umbraco.Web/Routing/CustomRouteUrlProvider.cs
index 926db253c8..893445add6 100644
--- a/src/Umbraco.Web/Routing/CustomRouteUrlProvider.cs
+++ b/src/Umbraco.Web/Routing/CustomRouteUrlProvider.cs
@@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
-using System.Globalization;
+using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Web.Routing
{
@@ -14,25 +14,15 @@ namespace Umbraco.Web.Routing
///
/// This will simply return the URL that is returned by the assigned IPublishedContent if this is a custom route
///
- ///
- ///
- ///
- ///
- ///
- public string GetUrl(UmbracoContext umbracoContext, int id, Uri current, UrlProviderMode mode, string culture = null)
+ public string GetUrl(UmbracoContext umbracoContext, IPublishedContent content, UrlProviderMode mode, string culture, Uri current)
{
- if (umbracoContext == null) return null;
- if (umbracoContext.PublishedRequest == null) return null;
- if (umbracoContext.PublishedRequest.PublishedContent == null) return null;
- if (umbracoContext.HttpContext == null) return null;
- if (umbracoContext.HttpContext.Request == null) return null;
- if (umbracoContext.HttpContext.Request.RequestContext == null) return null;
- if (umbracoContext.HttpContext.Request.RequestContext.RouteData == null) return null;
- if (umbracoContext.HttpContext.Request.RequestContext.RouteData.DataTokens == null) return null;
- if (umbracoContext.HttpContext.Request.RequestContext.RouteData.DataTokens.ContainsKey(Umbraco.Core.Constants.Web.CustomRouteDataToken) == false) return null;
+ if (umbracoContext?.PublishedRequest?.PublishedContent == null) return null;
+ if (umbracoContext.HttpContext?.Request?.RequestContext?.RouteData?.DataTokens == null) return null;
+ if (umbracoContext.HttpContext.Request.RequestContext.RouteData.DataTokens.ContainsKey(Core.Constants.Web.CustomRouteDataToken) == false) return null;
+
//ok so it's a custom route with published content assigned, check if the id being requested for is the same id as the assigned published content
- return id == umbracoContext.PublishedRequest.PublishedContent.Id
- ? umbracoContext.PublishedRequest.PublishedContent.Url
+ return content.Id == umbracoContext.PublishedRequest.PublishedContent.Id
+ ? umbracoContext.PublishedRequest.PublishedContent.GetUrl(culture) // fixme ∞ loop.
: null;
}
diff --git a/src/Umbraco.Web/Routing/DefaultUrlProvider.cs b/src/Umbraco.Web/Routing/DefaultUrlProvider.cs
index 37d38d521e..366bcd865f 100644
--- a/src/Umbraco.Web/Routing/DefaultUrlProvider.cs
+++ b/src/Umbraco.Web/Routing/DefaultUrlProvider.cs
@@ -1,14 +1,11 @@
using System;
using System.Collections.Generic;
-using System.Globalization;
using System.Linq;
-using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
-using Umbraco.Core.Models;
-using Umbraco.Core.Models.PublishedContent;
-
+using Umbraco.Core.Models.PublishedContent;
+
namespace Umbraco.Web.Routing
{
///
@@ -31,27 +28,15 @@ namespace Umbraco.Web.Routing
#region GetUrl
- ///
- /// Gets the url of a published content.
- ///
- /// The Umbraco context.
- /// The published content id.
- /// The current absolute url.
- /// The url mode.
- /// The culture.
- /// The url for the published content.
- ///
- /// The url is absolute or relative depending on mode and on current.
- /// If the provider is unable to provide a url, it should return null.
- ///
- public virtual string GetUrl(UmbracoContext umbracoContext, int id, Uri current, UrlProviderMode mode, string culture = null)
+ ///
+ public virtual string GetUrl(UmbracoContext umbracoContext, IPublishedContent content, UrlProviderMode mode, string culture, Uri current)
{
if (!current.IsAbsoluteUri) throw new ArgumentException("Current url must be absolute.", nameof(current));
-
+
// will not use cache if previewing
- var route = umbracoContext.ContentCache.GetRouteById(id, culture);
+ var route = umbracoContext.ContentCache.GetRouteById(content.Id, culture);
- return GetUrlFromRoute(route, umbracoContext, id, current, mode, culture);
+ return GetUrlFromRoute(route, umbracoContext, content.Id, current, mode, culture);
}
internal string GetUrlFromRoute(string route, UmbracoContext umbracoContext, int id, Uri current, UrlProviderMode mode, string culture)
diff --git a/src/Umbraco.Web/Routing/IUrlProvider.cs b/src/Umbraco.Web/Routing/IUrlProvider.cs
index 031f4670b2..53a7e9886c 100644
--- a/src/Umbraco.Web/Routing/IUrlProvider.cs
+++ b/src/Umbraco.Web/Routing/IUrlProvider.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
-using System.Globalization;
-using Umbraco.Web.PublishedCache;
+using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Web.Routing
{
@@ -14,16 +13,18 @@ namespace Umbraco.Web.Routing
/// Gets the nice url of a published content.
///
/// The Umbraco context.
- /// The published content id.
- /// The current absolute url.
+ /// The published content.
/// The url mode.
+ /// A culture.
+ /// The current absolute url.
/// The url for the published content.
///
/// The url is absolute or relative depending on mode and on current.
+ /// If the published content is multi-lingual, gets the url for the specified culture or,
+ /// when no culture is specified, the current culture.
/// If the provider is unable to provide a url, it should return null.
///
- string GetUrl(UmbracoContext umbracoContext, int id, Uri current, UrlProviderMode mode, string culture = null);
- // FIXME WE HAVE TO DOCUMENT CULTURE FFS
+ string GetUrl(UmbracoContext umbracoContext, IPublishedContent content, UrlProviderMode mode, string culture, Uri current);
///
/// Gets the other urls of a published content.
diff --git a/src/Umbraco.Web/Routing/UrlProvider.cs b/src/Umbraco.Web/Routing/UrlProvider.cs
index c23ff5fb86..b8c28814b5 100644
--- a/src/Umbraco.Web/Routing/UrlProvider.cs
+++ b/src/Umbraco.Web/Routing/UrlProvider.cs
@@ -1,15 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
-using Umbraco.Web.PublishedCache;
using Umbraco.Core;
using Umbraco.Core.Models;
-using Umbraco.Web.Composing;
-using Umbraco.Core.Services;
-using System.Globalization;
-
+using Umbraco.Core.Models.PublishedContent;
+using Umbraco.Core.Services;
+
namespace Umbraco.Web.Routing
{
///
@@ -57,7 +54,8 @@ namespace Umbraco.Web.Routing
private readonly UmbracoContext _umbracoContext;
private readonly IEnumerable _urlProviders;
- private readonly IEntityService _entityService;
+ private readonly IEntityService _entityService;
+ private readonly ICurrentVariationAccessor _variationAccessor; // fixme set!
///
/// Gets or sets the provider url mode.
@@ -68,150 +66,149 @@ namespace Umbraco.Web.Routing
#region GetUrl
+ private UrlProviderMode GetMode(bool absolute) => absolute ? UrlProviderMode.Absolute : Mode;
+ private IPublishedContent GetDocument(int id) => _umbracoContext.ContentCache.GetById(id);
+ private IPublishedContent GetDocument(Guid id) => _umbracoContext.ContentCache.GetById(id);
+
///
/// Gets the url of a published content.
///
- /// The published content identifier.
- /// The url for the published content.
- ///
- /// The url is absolute or relative depending on Mode and on the current url.
- /// If the provider is unable to provide a url, it returns "#".
- ///
- public string GetUrl(Guid id, string culture = null)
- {
- var intId = _entityService.GetId(id, UmbracoObjectTypes.Document);
- return GetUrl(intId.Success ? intId.Result : -1, culture);
- }
-
- ///
- /// Gets the nice url of a published content.
- ///
- /// The published content identifier.
- /// A value indicating whether the url should be absolute in any case.
- /// The url for the published content.
- ///
- /// The url is absolute or relative depending on Mode and on current, unless
- /// absolute is true, in which case the url is always absolute.
- /// If the provider is unable to provide a url, it returns "#".
- ///
- public string GetUrl(Guid id, bool absolute, string culture = null)
- {
- var intId = _entityService.GetId(id, UmbracoObjectTypes.Document);
- return GetUrl(intId.Success ? intId.Result : -1, absolute, culture);
- }
-
- ///
- /// Gets the nice url of a published content.
- ///
- /// The published content id.
+ /// The published content.
+ /// A culture.
/// The current absolute url.
- /// A value indicating whether the url should be absolute in any case.
/// The url for the published content.
- ///
- /// The url is absolute or relative depending on Mode and on current, unless
- /// absolute is true, in which case the url is always absolute.
- /// If the provider is unable to provide a url, it returns "#".
- ///
- public string GetUrl(Guid id, Uri current, bool absolute, string culture = null)
- {
- var intId = _entityService.GetId(id, UmbracoObjectTypes.Document);
- return GetUrl(intId.Success ? intId.Result : -1, current, absolute, culture);
- }
+ public string GetUrl(IPublishedContent content, string culture = ".", Uri current = null)
+ => GetUrl(content, Mode, culture, current);
///
/// Gets the nice url of a published content.
///
- /// The published content identifier.
- /// The url mode.
+ /// The published content.
+ /// A value indicating whether the url should be absolute in any case.
+ /// A culture.
+ /// The current absolute url.
/// The url for the published content.
///
- /// The url is absolute or relative depending on mode and on the current url.
- /// If the provider is unable to provide a url, it returns "#".
+ /// The url is absolute or relative depending on Mode and on current, unless
+ /// absolute is true, in which case the url is always absolute.
///
- public string GetUrl(Guid id, UrlProviderMode mode, string culture = null)
- {
- var intId = _entityService.GetId(id, UmbracoObjectTypes.Document);
- return GetUrl(intId.Success ? intId.Result : -1, mode, culture);
- }
+ public string GetUrl(IPublishedContent content, bool absolute, Uri current = null, string culture = ".")
+ => GetUrl(content, GetMode(absolute), culture, current);
+
+ ///
+ /// Gets the nice url of a published content.
+ ///
+ /// The published content.
+ /// The url mode.
+ /// A culture.
+ /// The current absolute url.
+ /// The url for the published content.
+ public string GetUrl(IPublishedContent content, UrlProviderMode mode, Uri current = null, string culture = ".")
+ => GetUrl(content, mode, culture, current);
///
/// Gets the url of a published content.
///
/// The published content identifier.
+ /// A culture.
+ /// The current absolute url.
/// The url for the published content.
- ///
- /// The url is absolute or relative depending on Mode and on the current url.
- /// If the provider is unable to provide a url, it returns "#".
- ///
- public string GetUrl(int id, string culture = null)
- {
- return GetUrl(id, _umbracoContext.CleanedUmbracoUrl, Mode, culture);
- }
+ public string GetUrl(Guid id, string culture = ".", Uri current = null)
+ => GetUrl(GetDocument(id), Mode, culture, current);
///
/// Gets the nice url of a published content.
///
/// The published content identifier.
/// A value indicating whether the url should be absolute in any case.
- /// The url for the published content.
- ///
- /// The url is absolute or relative depending on Mode and on current, unless
- /// absolute is true, in which case the url is always absolute.
- /// If the provider is unable to provide a url, it returns "#".
- ///
- public string GetUrl(int id, bool absolute, string culture = null)
- {
- var mode = absolute ? UrlProviderMode.Absolute : Mode;
- return GetUrl(id, _umbracoContext.CleanedUmbracoUrl, mode, culture);
- }
-
- ///
- /// Gets the nice url of a published content.
- ///
- /// The published content id.
+ /// A culture.
/// The current absolute url.
- /// A value indicating whether the url should be absolute in any case.
/// The url for the published content.
///
/// The url is absolute or relative depending on Mode and on current, unless
/// absolute is true, in which case the url is always absolute.
- /// If the provider is unable to provide a url, it returns "#".
///
- public string GetUrl(int id, Uri current, bool absolute, string culture = null)
- {
- var mode = absolute ? UrlProviderMode.Absolute : Mode;
- return GetUrl(id, current, mode, culture);
- }
+ public string GetUrl(Guid id, bool absolute, string culture = ".", Uri current = null)
+ => GetUrl(GetDocument(id), GetMode(absolute), culture, current);
///
/// Gets the nice url of a published content.
///
/// The published content identifier.
/// The url mode.
+ /// A culture.
+ /// The current absolute url.
/// The url for the published content.
- ///
- /// The url is absolute or relative depending on mode and on the current url.
- /// If the provider is unable to provide a url, it returns "#".
- ///
- public string GetUrl(int id, UrlProviderMode mode, string culture = null)
- {
- return GetUrl(id, _umbracoContext.CleanedUmbracoUrl, mode, culture);
- }
+ public string GetUrl(Guid id, UrlProviderMode mode, string culture = ".", Uri current = null)
+ => GetUrl(GetDocument(id), mode, culture, current);
+
+ ///
+ /// Gets the url of a published content.
+ ///
+ /// The published content identifier.
+ /// A culture.
+ /// The current absolute url.
+ /// The url for the published content.
+ public string GetUrl(int id, string culture = ".", Uri current = null)
+ => GetUrl(GetDocument(id), Mode, culture, current);
///
/// Gets the nice url of a published content.
///
- /// The published content id.
+ /// The published content identifier.
+ /// A value indicating whether the url should be absolute in any case.
+ /// A culture.
/// The current absolute url.
+ /// The url for the published content.
+ ///
+ /// The url is absolute or relative depending on Mode and on current, unless
+ /// absolute is true, in which case the url is always absolute.
+ ///
+ public string GetUrl(int id, bool absolute, string culture = ".", Uri current = null)
+ => GetUrl(GetDocument(id), GetMode(absolute), culture, current);
+
+ ///
+ /// Gets the nice url of a published content.
+ ///
+ /// The published content identifier.
/// The url mode.
+ /// A culture.
+ /// The current absolute url.
+ /// The url for the published content.
+ public string GetUrl(int id, UrlProviderMode mode, string culture = ".", Uri current = null)
+ => GetUrl(GetDocument(id), mode, culture, current);
+
+ ///
+ /// Gets the nice url of a published content.
+ ///
+ /// The published content.
+ /// The url mode.
+ /// A culture.
+ /// The current absolute url.
/// The url for the published content.
///
/// The url is absolute or relative depending on mode and on current.
+ /// If the published content is multi-lingual, gets the url for the specified culture or,
+ /// when no culture is specified, the current culture.
/// If the provider is unable to provide a url, it returns "#".
///
- public string GetUrl(int id, Uri current, UrlProviderMode mode, string culture = null) // FIXME DOCUMENT
+ public string GetUrl(IPublishedContent content, UrlProviderMode mode, string culture = ".", Uri current = null)
{
- var url = _urlProviders.Select(provider => provider.GetUrl(_umbracoContext, id, current, mode, culture))
+ if (content == null)
+ return "#";
+
+ // this the ONLY place where we deal with default culture - IUrlProvider always receive a culture
+ if (culture == ".")
+ {
+ culture = content.ContentType.Variations.Has(ContentVariation.CultureNeutral) // fixme CultureSegment
+ ? _variationAccessor.CurrentVariation.Culture
+ : null;
+ }
+
+ if (current == null)
+ current = _umbracoContext.CleanedUmbracoUrl;
+
+ var url = _urlProviders.Select(provider => provider.GetUrl(_umbracoContext, content, mode, culture, current))
.FirstOrDefault(u => u != null);
return url ?? "#"; // legacy wants this
}
diff --git a/src/Umbraco.Web/Runtime/WebRuntimeComponent.cs b/src/Umbraco.Web/Runtime/WebRuntimeComponent.cs
index 41d4d4883c..bd5acab5de 100644
--- a/src/Umbraco.Web/Runtime/WebRuntimeComponent.cs
+++ b/src/Umbraco.Web/Runtime/WebRuntimeComponent.cs
@@ -71,9 +71,8 @@ namespace Umbraco.Web.Runtime
composition.Container.RegisterFrom();
// register accessors for cultures
- // fixme merge the two accessors?
composition.Container.RegisterSingleton();
- composition.Container.RegisterSingleton();
+ composition.Container.RegisterSingleton();
var typeLoader = composition.Container.GetInstance();
var logger = composition.Container.GetInstance();
diff --git a/src/Umbraco.Web/umbraco.presentation/page.cs b/src/Umbraco.Web/umbraco.presentation/page.cs
index f65f04fb76..f7660987ea 100644
--- a/src/Umbraco.Web/umbraco.presentation/page.cs
+++ b/src/Umbraco.Web/umbraco.presentation/page.cs
@@ -108,8 +108,8 @@ namespace umbraco
///
/// The content.
/// This is for usage only.
- internal page(IContent content, IPublishedVariationContextAccessor variationContextAccessor)
- : this(new PagePublishedContent(content, variationContextAccessor))
+ internal page(IContent content, ICurrentVariationAccessor variationAccessor)
+ : this(new PagePublishedContent(content, variationAccessor))
{ }
#endregion
@@ -409,7 +409,7 @@ namespace umbraco
private readonly IPublishedProperty[] _properties;
private readonly IPublishedContent _parent;
private IReadOnlyDictionary _cultureInfos;
- private readonly IPublishedVariationContextAccessor _variationContextAccessor;
+ private readonly ICurrentVariationAccessor _variationAccessor;
private static readonly IReadOnlyDictionary NoCultureInfos = new Dictionary();
@@ -418,13 +418,13 @@ namespace umbraco
_id = id;
}
- public PagePublishedContent(IContent inner, IPublishedVariationContextAccessor variationContextAccessor)
+ public PagePublishedContent(IContent inner, ICurrentVariationAccessor variationAccessor)
{
if (inner == null)
throw new NullReferenceException("content");
_inner = inner;
- _variationContextAccessor = variationContextAccessor;
+ _variationAccessor = variationAccessor;
_id = _inner.Id;
_key = _inner.Key;
@@ -480,7 +480,7 @@ namespace umbraco
{
// handle context culture
if (culture == ".")
- culture = _variationContextAccessor.Context.Culture;
+ culture = _variationAccessor.CurrentVariation.Culture;
// no invariant culture infos
if (culture == null) return null;
@@ -564,6 +564,8 @@ namespace umbraco
get { throw new NotImplementedException(); }
}
+ public string GetUrl(string culture = ".") => throw new NotSupportedException();
+
public PublishedItemType ItemType
{
get { return PublishedItemType.Content; }