Merge remote-tracking branch 'origin/temp8' into temp8-implement-GetByContentType-nucache
This commit is contained in:
@@ -110,13 +110,6 @@ namespace Umbraco.Core.Components
|
||||
internal static ManifestValueValidatorCollectionBuilder Validators(this Composition composition)
|
||||
=> composition.WithCollectionBuilder<ManifestValueValidatorCollectionBuilder>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the post-migrations collection builder.
|
||||
/// </summary>
|
||||
/// <param name="composition">The composition.</param>
|
||||
internal static PostMigrationCollectionBuilder PostMigrations(this Composition composition)
|
||||
=> composition.WithCollectionBuilder<PostMigrationCollectionBuilder>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the components collection builder.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Umbraco.Core.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence;
|
||||
|
||||
namespace Umbraco.Core.Migrations
|
||||
@@ -32,5 +34,11 @@ namespace Umbraco.Core.Migrations
|
||||
/// Gets or sets a value indicating whether an expression is being built.
|
||||
/// </summary>
|
||||
bool BuildingExpression { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Adds a post-migrations.
|
||||
/// </summary>
|
||||
void AddPostMigration<TMigration>()
|
||||
where TMigration : IMigration;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
using Semver;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Scoping;
|
||||
|
||||
namespace Umbraco.Core.Migrations
|
||||
{
|
||||
public interface IPostMigration : IDiscoverable
|
||||
{
|
||||
void Execute(string name, IScope scope, SemVersion originVersion, SemVersion targetVersion, ILogger logger);
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,6 @@ namespace Umbraco.Core.Migrations.Install
|
||||
private readonly IRuntimeState _runtime;
|
||||
private readonly IMigrationBuilder _migrationBuilder;
|
||||
private readonly IKeyValueService _keyValueService;
|
||||
private readonly PostMigrationCollection _postMigrations;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
private DatabaseSchemaResult _databaseSchemaValidationResult;
|
||||
@@ -35,7 +34,7 @@ namespace Umbraco.Core.Migrations.Install
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DatabaseBuilder"/> class.
|
||||
/// </summary>
|
||||
public DatabaseBuilder(IScopeProvider scopeProvider, IGlobalSettings globalSettings, IUmbracoDatabaseFactory databaseFactory, IRuntimeState runtime, ILogger logger, IMigrationBuilder migrationBuilder, IKeyValueService keyValueService, PostMigrationCollection postMigrations)
|
||||
public DatabaseBuilder(IScopeProvider scopeProvider, IGlobalSettings globalSettings, IUmbracoDatabaseFactory databaseFactory, IRuntimeState runtime, ILogger logger, IMigrationBuilder migrationBuilder, IKeyValueService keyValueService)
|
||||
{
|
||||
_scopeProvider = scopeProvider;
|
||||
_globalSettings = globalSettings;
|
||||
@@ -44,7 +43,6 @@ namespace Umbraco.Core.Migrations.Install
|
||||
_logger = logger;
|
||||
_migrationBuilder = migrationBuilder;
|
||||
_keyValueService = keyValueService;
|
||||
_postMigrations = postMigrations;
|
||||
}
|
||||
|
||||
#region Status
|
||||
@@ -483,7 +481,7 @@ namespace Umbraco.Core.Migrations.Install
|
||||
/// configured and it is possible to connect to the database.</para>
|
||||
/// <para>Runs whichever migrations need to run.</para>
|
||||
/// </remarks>
|
||||
public Result UpgradeSchemaAndData()
|
||||
public Result UpgradeSchemaAndData(MigrationPlan plan)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -496,8 +494,8 @@ namespace Umbraco.Core.Migrations.Install
|
||||
_logger.Info<DatabaseBuilder>("Database upgrade started");
|
||||
|
||||
// upgrade
|
||||
var upgrader = new UmbracoUpgrader();
|
||||
upgrader.Execute(_scopeProvider, _migrationBuilder, _keyValueService, _logger, _postMigrations);
|
||||
var upgrader = new Upgrader(plan);
|
||||
upgrader.Execute(_scopeProvider, _migrationBuilder, _keyValueService, _logger);
|
||||
|
||||
var message = "<p>Upgrade completed!</p>";
|
||||
|
||||
|
||||
@@ -321,7 +321,7 @@ namespace Umbraco.Core.Migrations.Install
|
||||
{
|
||||
// on install, initialize the umbraco migration plan with the final state
|
||||
|
||||
var upgrader = new UmbracoUpgrader();
|
||||
var upgrader = new Upgrader(new UmbracoPlan());
|
||||
var stateValueKey = upgrader.StateValueKey;
|
||||
var finalState = upgrader.Plan.FinalState;
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence;
|
||||
|
||||
namespace Umbraco.Core.Migrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a migration context.
|
||||
/// Implements <see cref="IMigrationContext"/>.
|
||||
/// </summary>
|
||||
internal class MigrationContext : IMigrationContext
|
||||
{
|
||||
@@ -32,5 +33,15 @@ namespace Umbraco.Core.Migrations
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool BuildingExpression { get; set; }
|
||||
|
||||
// this is only internally exposed
|
||||
public List<Type> PostMigrations { get; } = new List<Type>();
|
||||
|
||||
/// <inheritdoc />
|
||||
public void AddPostMigration<TMigration>()
|
||||
where TMigration : IMigration
|
||||
{
|
||||
PostMigrations.Add(typeof(TMigration));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace Umbraco.Core.Migrations
|
||||
public class MigrationPlan
|
||||
{
|
||||
private readonly Dictionary<string, Transition> _transitions = new Dictionary<string, Transition>();
|
||||
private readonly List<Type> _postMigrationTypes = new List<Type>();
|
||||
|
||||
private string _prevState;
|
||||
private string _finalState;
|
||||
@@ -166,6 +167,25 @@ namespace Umbraco.Core.Migrations
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prepares post-migrations.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>This can be overriden to filter, complement, and/or re-order post-migrations.</para>
|
||||
/// </remarks>
|
||||
protected virtual IEnumerable<Type> PreparePostMigrations(IEnumerable<Type> types)
|
||||
=> types;
|
||||
|
||||
/// <summary>
|
||||
/// Adds a post-migration to the plan.
|
||||
/// </summary>
|
||||
public virtual MigrationPlan AddPostMigration<TMigration>()
|
||||
where TMigration : IMigration
|
||||
{
|
||||
_postMigrationTypes.Add(typeof(TMigration));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a random, unique state.
|
||||
/// </summary>
|
||||
@@ -270,6 +290,7 @@ namespace Umbraco.Core.Migrations
|
||||
throw new Exception($"Unknown state \"{origState}\".");
|
||||
|
||||
var context = new MigrationContext(scope.Database, logger);
|
||||
context.PostMigrations.AddRange(_postMigrationTypes);
|
||||
|
||||
while (transition != null)
|
||||
{
|
||||
@@ -285,6 +306,20 @@ namespace Umbraco.Core.Migrations
|
||||
throw new Exception($"Unknown state \"{origState}\".");
|
||||
}
|
||||
|
||||
// prepare and de-duplicate post-migrations, only keeping the 1st occurence
|
||||
var temp = new HashSet<Type>();
|
||||
var postMigrationTypes = PreparePostMigrations(context.PostMigrations)
|
||||
.Where(x => !temp.Contains(x))
|
||||
.Select(x => { temp.Add(x); return x; });
|
||||
|
||||
// run post-migrations
|
||||
foreach (var postMigrationType in postMigrationTypes)
|
||||
{
|
||||
logger.Info<MigrationPlan>($"PostMigration: {postMigrationType.FullName}.");
|
||||
var postMigration = migrationBuilder.Build(postMigrationType, context);
|
||||
postMigration.Migrate();
|
||||
}
|
||||
|
||||
logger.Info<MigrationPlan>("Done (pending scope completion).");
|
||||
|
||||
// safety check
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.Migrations
|
||||
{
|
||||
public class PostMigrationCollection : BuilderCollectionBase<IPostMigration>
|
||||
{
|
||||
public PostMigrationCollection(IEnumerable<IPostMigration> items)
|
||||
: base(items)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.Migrations
|
||||
{
|
||||
public class PostMigrationCollectionBuilder : LazyCollectionBuilderBase<PostMigrationCollectionBuilder, PostMigrationCollection, IPostMigration>
|
||||
{
|
||||
protected override PostMigrationCollectionBuilder This => this;
|
||||
|
||||
protected override Lifetime CollectionLifetime => Lifetime.Transient;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace Umbraco.Core.Migrations.PostMigrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Rebuilds the published snapshot.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>This interface exists because the entire published snapshot lives in Umbraco.Web
|
||||
/// but we may want to trigger rebuilds from Umbraco.Core. These two assemblies should
|
||||
/// be refactored, really.</para>
|
||||
/// </remarks>
|
||||
public interface IPublishedSnapshotRebuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// Rebuilds.
|
||||
/// </summary>
|
||||
void Rebuild();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace Umbraco.Core.Migrations.PostMigrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements <see cref="IPublishedSnapshotRebuilder"/> in Umbraco.Core (doing nothing).
|
||||
/// </summary>
|
||||
public class PublishedSnapshotRebuilder : IPublishedSnapshotRebuilder
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public void Rebuild()
|
||||
{ }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
namespace Umbraco.Core.Migrations.PostMigrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Rebuilds the published snapshot.
|
||||
/// </summary>
|
||||
public class RebuildPublishedSnapshot : IMigration
|
||||
{
|
||||
private readonly IPublishedSnapshotRebuilder _rebuilder;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RebuildPublishedSnapshot"/> class.
|
||||
/// </summary>
|
||||
public RebuildPublishedSnapshot(IPublishedSnapshotRebuilder rebuilder)
|
||||
{
|
||||
_rebuilder = rebuilder;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Migrate()
|
||||
{
|
||||
_rebuilder.Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using Semver;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Scoping;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the Umbraco upgrader.
|
||||
/// </summary>
|
||||
public class UmbracoUpgrader : Upgrader
|
||||
{
|
||||
private PostMigrationCollection _postMigrations;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see ref="UmbracoUpgrader" /> class.
|
||||
/// </summary>
|
||||
public UmbracoUpgrader()
|
||||
: base(new UmbracoPlan())
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Executes.
|
||||
/// </summary>
|
||||
public void Execute(IScopeProvider scopeProvider, IMigrationBuilder migrationBuilder, IKeyValueService keyValueService, ILogger logger, PostMigrationCollection postMigrations)
|
||||
{
|
||||
_postMigrations = postMigrations;
|
||||
Execute(scopeProvider, migrationBuilder, keyValueService, logger);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void AfterMigrations(IScope scope, ILogger logger)
|
||||
{
|
||||
// assume we have something in web.config that makes some sense = the origin version
|
||||
if (!SemVersion.TryParse(ConfigurationManager.AppSettings[Constants.AppSettings.ConfigurationStatus], out var originVersion))
|
||||
throw new InvalidOperationException($"Could not get current version from web.config {Constants.AppSettings.ConfigurationStatus} appSetting.");
|
||||
|
||||
// target version is the code version
|
||||
var targetVersion = UmbracoVersion.SemanticVersion;
|
||||
|
||||
foreach (var postMigration in _postMigrations)
|
||||
postMigration.Execute(Name, scope, originVersion, targetVersion, logger);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Migrations.PostMigrations;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
@@ -27,7 +28,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
|
||||
if (refreshCache)
|
||||
{
|
||||
//FIXME: trigger cache rebuild. Currently the data in the database tables is wrong.
|
||||
Context.AddPostMigration<RebuildPublishedSnapshot>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Manifest;
|
||||
using Umbraco.Core.Migrations;
|
||||
using Umbraco.Core.Migrations.Install;
|
||||
using Umbraco.Core.Migrations.PostMigrations;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PackageActions;
|
||||
using Umbraco.Core.Persistence;
|
||||
@@ -113,13 +114,13 @@ namespace Umbraco.Core.Runtime
|
||||
composition.WithCollectionBuilder<UrlSegmentProviderCollectionBuilder>()
|
||||
.Append<DefaultUrlSegmentProvider>();
|
||||
|
||||
composition.WithCollectionBuilder<PostMigrationCollectionBuilder>()
|
||||
.Add(() => composition.TypeLoader.GetTypes<IPostMigration>());
|
||||
|
||||
composition.RegisterUnique<IMigrationBuilder>(factory => new MigrationBuilder(factory));
|
||||
|
||||
// by default, register a noop factory
|
||||
composition.RegisterUnique<IPublishedModelFactory, NoopPublishedModelFactory>();
|
||||
|
||||
// by default, register a noop rebuilder
|
||||
composition.RegisterUnique<IPublishedSnapshotRebuilder, PublishedSnapshotRebuilder>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,7 +242,7 @@ namespace Umbraco.Core
|
||||
|
||||
protected virtual bool EnsureUmbracoUpgradeState(IUmbracoDatabaseFactory databaseFactory, ILogger logger)
|
||||
{
|
||||
var upgrader = new UmbracoUpgrader();
|
||||
var upgrader = new Upgrader(new UmbracoPlan());
|
||||
var stateValueKey = upgrader.StateValueKey;
|
||||
|
||||
// no scope, no service - just directly accessing the database
|
||||
|
||||
@@ -351,6 +351,9 @@
|
||||
<Compile Include="Migrations\IncompleteMigrationExpressionException.cs" />
|
||||
<Compile Include="Migrations\MergeBuilder.cs" />
|
||||
<Compile Include="Migrations\MigrationBase_Extra.cs" />
|
||||
<Compile Include="Migrations\PostMigrations\IPublishedSnapshotRebuilder.cs" />
|
||||
<Compile Include="Migrations\PostMigrations\PublishedSnapshotRebuilder.cs" />
|
||||
<Compile Include="Migrations\PostMigrations\RebuildPublishedSnapshot.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_7_10_0\RenamePreviewFolder.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_7_12_0\AddRelationTypeForMediaFolderOnDelete.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_7_12_0\IncreaseLanguageIsoCodeColumnLength.cs" />
|
||||
@@ -666,15 +669,11 @@
|
||||
<Compile Include="Media\IEmbedProvider.cs" />
|
||||
<Compile Include="Media\OEmbedResult.cs" />
|
||||
<Compile Include="Media\OEmbedStatus.cs" />
|
||||
<Compile Include="Migrations\IPostMigration.cs" />
|
||||
<Compile Include="Migrations\MigrationBuilder.cs" />
|
||||
<Compile Include="Migrations\MigrationPlan.cs" />
|
||||
<Compile Include="Migrations\NoopMigration.cs" />
|
||||
<Compile Include="Migrations\PostMigrationCollection.cs" />
|
||||
<Compile Include="Migrations\PostMigrationCollectionBuilder.cs" />
|
||||
<Compile Include="Migrations\Upgrade\UmbracoPlan.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\AddLockTable.cs" />
|
||||
<Compile Include="Migrations\Upgrade\UmbracoUpgrader.cs" />
|
||||
<Compile Include="Migrations\Upgrade\Upgrader.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\DropMigrationsTable.cs" />
|
||||
<Compile Include="Models\AuditItem.cs" />
|
||||
|
||||
@@ -16,32 +16,6 @@ namespace Umbraco.Tests.Migrations
|
||||
[TestFixture]
|
||||
public class MigrationTests
|
||||
{
|
||||
public class TestUpgraderWithPostMigrations : Upgrader
|
||||
{
|
||||
private PostMigrationCollection _postMigrations;
|
||||
|
||||
public TestUpgraderWithPostMigrations(MigrationPlan plan)
|
||||
: base(plan)
|
||||
{ }
|
||||
|
||||
public void Execute(IScopeProvider scopeProvider, IMigrationBuilder migrationBuilder, IKeyValueService keyValueService, ILogger logger, PostMigrationCollection postMigrations)
|
||||
{
|
||||
_postMigrations = postMigrations;
|
||||
Execute(scopeProvider, migrationBuilder, keyValueService, logger);
|
||||
}
|
||||
|
||||
public override void AfterMigrations(IScope scope, ILogger logger)
|
||||
{
|
||||
// run post-migrations
|
||||
var originVersion = new SemVersion(0);
|
||||
var targetVersion = new SemVersion(0);
|
||||
|
||||
// run post-migrations
|
||||
foreach (var postMigration in _postMigrations)
|
||||
postMigration.Execute(Name, scope, originVersion, targetVersion, logger);
|
||||
}
|
||||
}
|
||||
|
||||
public class TestScopeProvider : IScopeProvider
|
||||
{
|
||||
private readonly IScope _scope;
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
using Moq;
|
||||
using NPoco;
|
||||
using NUnit.Framework;
|
||||
using Semver;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Migrations;
|
||||
using Umbraco.Core.Migrations.Upgrade;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Scoping;
|
||||
@@ -18,15 +17,10 @@ namespace Umbraco.Tests.Migrations
|
||||
public class PostMigrationTests
|
||||
{
|
||||
[Test]
|
||||
public void Executes_For_Any_Product_Name_When_Not_Specified()
|
||||
public void ExecutesPlanPostMigration()
|
||||
{
|
||||
var logger = Mock.Of<ILogger>();
|
||||
|
||||
var changed1 = new Args { CountExecuted = 0 };
|
||||
var post1 = new TestPostMigration(changed1);
|
||||
|
||||
var posts = new PostMigrationCollection(new [] { post1 });
|
||||
|
||||
var builder = Mock.Of<IMigrationBuilder>();
|
||||
Mock.Get(builder)
|
||||
.Setup(x => x.Build(It.IsAny<Type>(), It.IsAny<IMigrationContext>()))
|
||||
@@ -34,8 +28,10 @@ namespace Umbraco.Tests.Migrations
|
||||
{
|
||||
switch (t.Name)
|
||||
{
|
||||
case "NoopMigration":
|
||||
case nameof(NoopMigration):
|
||||
return new NoopMigration();
|
||||
case nameof(TestPostMigration):
|
||||
return new TestPostMigration();
|
||||
default:
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
@@ -50,26 +46,23 @@ namespace Umbraco.Tests.Migrations
|
||||
var sqlContext = new SqlContext(new SqlCeSyntaxProvider(), DatabaseType.SQLCe, Mock.Of<IPocoDataFactory>());
|
||||
var scopeProvider = new MigrationTests.TestScopeProvider(scope) { SqlContext = sqlContext };
|
||||
|
||||
var u1 = new MigrationTests.TestUpgraderWithPostMigrations(
|
||||
new MigrationPlan("Test").From(string.Empty).To("done"));
|
||||
u1.Execute(scopeProvider, builder, Mock.Of<IKeyValueService>(), logger, posts);
|
||||
var plan = new MigrationPlan("Test")
|
||||
.From(string.Empty).To("done");
|
||||
|
||||
Assert.AreEqual(1, changed1.CountExecuted);
|
||||
plan.AddPostMigration<TestPostMigration>();
|
||||
TestPostMigration.MigrateCount = 0;
|
||||
|
||||
var upgrader = new Upgrader(plan);
|
||||
upgrader.Execute(scopeProvider, builder, Mock.Of<IKeyValueService>(), logger);
|
||||
|
||||
Assert.AreEqual(1, TestPostMigration.MigrateCount);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Executes_Only_For_Specified_Product_Name()
|
||||
public void MigrationCanAddPostMigration()
|
||||
{
|
||||
var logger = Mock.Of<ILogger>();
|
||||
|
||||
var changed1 = new Args { CountExecuted = 0};
|
||||
var post1 = new TestPostMigration("Test1", changed1);
|
||||
|
||||
var changed2 = new Args { CountExecuted = 0 };
|
||||
var post2 = new TestPostMigration("Test2", changed2);
|
||||
|
||||
var posts = new PostMigrationCollection(new [] { post1, post2 });
|
||||
|
||||
var builder = Mock.Of<IMigrationBuilder>();
|
||||
Mock.Get(builder)
|
||||
.Setup(x => x.Build(It.IsAny<Type>(), It.IsAny<IMigrationContext>()))
|
||||
@@ -77,8 +70,12 @@ namespace Umbraco.Tests.Migrations
|
||||
{
|
||||
switch (t.Name)
|
||||
{
|
||||
case "NoopMigration":
|
||||
case nameof(NoopMigration):
|
||||
return new NoopMigration();
|
||||
case nameof(TestMigration):
|
||||
return new TestMigration(c);
|
||||
case nameof(TestPostMigration):
|
||||
return new TestPostMigration();
|
||||
default:
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
@@ -93,52 +90,44 @@ namespace Umbraco.Tests.Migrations
|
||||
var sqlContext = new SqlContext(new SqlCeSyntaxProvider(), DatabaseType.SQLCe, Mock.Of<IPocoDataFactory>());
|
||||
var scopeProvider = new MigrationTests.TestScopeProvider(scope) { SqlContext = sqlContext };
|
||||
|
||||
var u1 = new MigrationTests.TestUpgraderWithPostMigrations(
|
||||
new MigrationPlan("Test1").From(string.Empty).To("done"));
|
||||
u1.Execute(scopeProvider, builder, Mock.Of<IKeyValueService>(), logger, posts);
|
||||
var plan = new MigrationPlan("Test")
|
||||
.From(string.Empty).To<TestMigration>("done");
|
||||
|
||||
Assert.AreEqual(1, changed1.CountExecuted);
|
||||
Assert.AreEqual(0, changed2.CountExecuted);
|
||||
TestMigration.MigrateCount = 0;
|
||||
TestPostMigration.MigrateCount = 0;
|
||||
|
||||
var u2 = new MigrationTests.TestUpgraderWithPostMigrations(
|
||||
new MigrationPlan("Test2").From(string.Empty).To("done"));
|
||||
u2.Execute(scopeProvider, builder, Mock.Of<IKeyValueService>(), logger, posts);
|
||||
new MigrationContext(database, logger);
|
||||
|
||||
Assert.AreEqual(1, changed1.CountExecuted);
|
||||
Assert.AreEqual(1, changed2.CountExecuted);
|
||||
var upgrader = new Upgrader(plan);
|
||||
upgrader.Execute(scopeProvider, builder, Mock.Of<IKeyValueService>(), logger);
|
||||
|
||||
Assert.AreEqual(1, TestMigration.MigrateCount);
|
||||
Assert.AreEqual(1, TestPostMigration.MigrateCount);
|
||||
}
|
||||
|
||||
public class Args
|
||||
public class TestMigration : MigrationBase
|
||||
{
|
||||
public int CountExecuted { get; set; }
|
||||
public TestMigration(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public static int MigrateCount { get; set; }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
MigrateCount++;
|
||||
|
||||
Context.AddPostMigration<TestPostMigration>();
|
||||
}
|
||||
}
|
||||
|
||||
public class TestPostMigration : IPostMigration
|
||||
public class TestPostMigration : IMigration
|
||||
{
|
||||
private readonly string _prodName;
|
||||
private readonly Args _changed;
|
||||
public static int MigrateCount { get; set; }
|
||||
|
||||
// need that one else it breaks IoC
|
||||
public TestPostMigration()
|
||||
public void Migrate()
|
||||
{
|
||||
_changed = new Args();
|
||||
}
|
||||
|
||||
public TestPostMigration(Args changed)
|
||||
{
|
||||
_changed = changed;
|
||||
}
|
||||
|
||||
public TestPostMigration(string prodName, Args changed)
|
||||
{
|
||||
_prodName = prodName;
|
||||
_changed = changed;
|
||||
}
|
||||
|
||||
public void Execute(string name, IScope scope, SemVersion originVersion, SemVersion targetVersion, ILogger logger)
|
||||
{
|
||||
if (_prodName.IsNullOrWhiteSpace() == false && name != _prodName) return;
|
||||
_changed.CountExecuted++;
|
||||
MigrateCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,6 +311,8 @@ namespace Umbraco.Tests.Models.Mapping
|
||||
public void IMemberType_To_MemberTypeDisplay()
|
||||
{
|
||||
//Arrange
|
||||
_dataTypeService.Setup(x => x.GetDataType(It.IsAny<int>()))
|
||||
.Returns(new DataType(new VoidEditor(Mock.Of<ILogger>())));
|
||||
|
||||
// setup the mocks to return the data we want to test against...
|
||||
|
||||
@@ -369,6 +371,8 @@ namespace Umbraco.Tests.Models.Mapping
|
||||
public void IMediaType_To_MediaTypeDisplay()
|
||||
{
|
||||
//Arrange
|
||||
_dataTypeService.Setup(x => x.GetDataType(It.IsAny<int>()))
|
||||
.Returns(new DataType(new VoidEditor(Mock.Of<ILogger>())));
|
||||
|
||||
// setup the mocks to return the data we want to test against...
|
||||
|
||||
@@ -422,6 +426,8 @@ namespace Umbraco.Tests.Models.Mapping
|
||||
public void IContentType_To_ContentTypeDisplay()
|
||||
{
|
||||
//Arrange
|
||||
_dataTypeService.Setup(x => x.GetDataType(It.IsAny<int>()))
|
||||
.Returns(new DataType(new VoidEditor(Mock.Of<ILogger>())));
|
||||
|
||||
// setup the mocks to return the data we want to test against...
|
||||
|
||||
@@ -687,6 +693,8 @@ namespace Umbraco.Tests.Models.Mapping
|
||||
public void IMediaTypeComposition_To_MediaTypeDisplay()
|
||||
{
|
||||
//Arrange
|
||||
_dataTypeService.Setup(x => x.GetDataType(It.IsAny<int>()))
|
||||
.Returns(new DataType(new VoidEditor(Mock.Of<ILogger>())));
|
||||
|
||||
// setup the mocks to return the data we want to test against...
|
||||
|
||||
@@ -778,6 +786,8 @@ namespace Umbraco.Tests.Models.Mapping
|
||||
public void IContentTypeComposition_To_ContentTypeDisplay()
|
||||
{
|
||||
//Arrange
|
||||
_dataTypeService.Setup(x => x.GetDataType(It.IsAny<int>()))
|
||||
.Returns(new DataType(new VoidEditor(Mock.Of<ILogger>())));
|
||||
|
||||
// setup the mocks to return the data we want to test against...
|
||||
|
||||
|
||||
@@ -133,7 +133,9 @@ Use this directive make an element sticky and follow the page when scrolling.
|
||||
clonedBar.addClass('-umb-sticky-bar');
|
||||
clonedBar.css({
|
||||
'position': 'fixed',
|
||||
'z-index': 500,
|
||||
// if you change this z-index value, make sure the sticky editor sub headers do not
|
||||
// clash with umb-dropdown (e.g. the content actions dropdown in content list view)
|
||||
'z-index': 99,
|
||||
'visibility': 'hidden'
|
||||
});
|
||||
|
||||
|
||||
@@ -51,11 +51,11 @@
|
||||
|
||||
<!-- Show in custom help dashboard -->
|
||||
<div class="umb-help-section" data-element="help-custom-dashboard" ng-if="vm.customDashboard.length > 0">
|
||||
<div ng-repeat="tab in vm.customDashboard">
|
||||
<div ng-repeat="property in tab.properties">
|
||||
<div ng-repeat="dashboard in vm.customDashboard">
|
||||
<h5 ng-show="dashboard.label">{{dashboard.label}}</h5>
|
||||
<div ng-repeat="property in dashboard.properties">
|
||||
<div>
|
||||
<h5 ng-if="property.caption">{{property.caption}}</h5>
|
||||
<div ng-include="property.path"></div>
|
||||
<div ng-include="property.view"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -188,17 +188,17 @@
|
||||
<Content Include="Config\serilog.user.config">
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
<Content Include="Config\serilog.user.Release.config">
|
||||
<None Include="Config\serilog.user.Release.config">
|
||||
<DependentUpon>serilog.user.config</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
</None>
|
||||
<Content Include="Config\serilog.config">
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
<Content Include="Config\serilog.Release.config">
|
||||
<None Include="Config\serilog.Release.config">
|
||||
<DependentUpon>serilog.config</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
</None>
|
||||
<Content Include="Config\logviewer.searches.config.js" />
|
||||
<None Include="Config\umbracoSettings.Release.config">
|
||||
<DependentUpon>umbracoSettings.config</DependentUpon>
|
||||
|
||||
@@ -14,8 +14,7 @@ namespace Umbraco.Web.Editors
|
||||
|
||||
public NuCacheStatusController(IPublishedSnapshotService publishedSnapshotService)
|
||||
{
|
||||
if (publishedSnapshotService == null) throw new ArgumentNullException(nameof(publishedSnapshotService));
|
||||
_publishedSnapshotService = publishedSnapshotService;
|
||||
_publishedSnapshotService = publishedSnapshotService ?? throw new ArgumentNullException(nameof(publishedSnapshotService));
|
||||
}
|
||||
|
||||
private PublishedSnapshotService PublishedSnapshotService
|
||||
|
||||
@@ -5,7 +5,10 @@ using System.Threading.Tasks;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Migrations.Install;
|
||||
using Umbraco.Core.Migrations.Upgrade;
|
||||
using Umbraco.Web.Install.Models;
|
||||
using Umbraco.Web.Migrations;
|
||||
using Umbraco.Web.Migrations.PostMigrations;
|
||||
|
||||
namespace Umbraco.Web.Install.InstallSteps
|
||||
{
|
||||
@@ -34,7 +37,10 @@ namespace Umbraco.Web.Install.InstallSteps
|
||||
{
|
||||
_logger.Info<DatabaseUpgradeStep>("Running 'Upgrade' service");
|
||||
|
||||
var result = _databaseBuilder.UpgradeSchemaAndData();
|
||||
var plan = new UmbracoPlan();
|
||||
plan.AddPostMigration<ClearCsrfCookies>(); // needed when running installer (back-office)
|
||||
|
||||
var result = _databaseBuilder.UpgradeSchemaAndData(plan);
|
||||
|
||||
if (result.Success == false)
|
||||
{
|
||||
|
||||
@@ -46,11 +46,6 @@ namespace Umbraco.Web.Install.InstallSteps
|
||||
security.PerformLogin(-1);
|
||||
}
|
||||
|
||||
// Some upgrade scripts "may modify the database (cmsContentXml...) tables directly" - not sure
|
||||
// that is still true but the idea is that after an upgrade we want to reset the local published snapshot, on
|
||||
// all LB nodes of course, so we need to use the distributed cache, and refresh everything.
|
||||
_distributedCache.RefreshAllPublishedSnapshot();
|
||||
|
||||
// Update configurationStatus
|
||||
_globalSettings.ConfigurationStatus = UmbracoVersion.SemanticVersion.ToSemanticString();
|
||||
|
||||
|
||||
@@ -1,21 +1,16 @@
|
||||
using System.Web;
|
||||
using Semver;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Migrations;
|
||||
using Umbraco.Core.Scoping;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
|
||||
namespace Umbraco.Web.Migrations
|
||||
namespace Umbraco.Web.Migrations.PostMigrations
|
||||
{
|
||||
/// <summary>
|
||||
/// After upgrade we clear out the csrf tokens
|
||||
/// Clears Csrf tokens.
|
||||
/// </summary>
|
||||
public class ClearCsrfCookiesAfterUpgrade : IPostMigration
|
||||
public class ClearCsrfCookies : IMigration
|
||||
{
|
||||
public void Execute(string name, IScope scope, SemVersion originVersion, SemVersion targetVersion, ILogger logger)
|
||||
public void Migrate()
|
||||
{
|
||||
if (name != Constants.System.UmbracoUpgradePlanName) return;
|
||||
if (HttpContext.Current == null) return;
|
||||
|
||||
var http = new HttpContextWrapper(HttpContext.Current);
|
||||
@@ -0,0 +1,31 @@
|
||||
using Umbraco.Core.Migrations.PostMigrations;
|
||||
using Umbraco.Web.Cache;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
|
||||
namespace Umbraco.Web.Migrations.PostMigrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements <see cref="IPublishedSnapshotRebuilder"/> in Umbraco.Web (rebuilding).
|
||||
/// </summary>
|
||||
public class PublishedSnapshotRebuilder : IPublishedSnapshotRebuilder
|
||||
{
|
||||
private readonly IPublishedSnapshotService _publishedSnapshotService;
|
||||
private readonly DistributedCache _distributedCache;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PublishedSnapshotRebuilder"/> class.
|
||||
/// </summary>
|
||||
public PublishedSnapshotRebuilder(IPublishedSnapshotService publishedSnapshotService, DistributedCache distributedCache)
|
||||
{
|
||||
_publishedSnapshotService = publishedSnapshotService;
|
||||
_distributedCache = distributedCache;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Rebuild()
|
||||
{
|
||||
_publishedSnapshotService.Rebuild();
|
||||
_distributedCache.RefreshAllPublishedSnapshot();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,6 +48,21 @@ namespace Umbraco.Web.PublishedCache
|
||||
|
||||
#endregion
|
||||
|
||||
#region Rebuild
|
||||
|
||||
/// <summary>
|
||||
/// Rebuilds internal caches (but does not reload).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Forces the snapshot service to rebuild its internal caches. For instance, some caches
|
||||
/// may rely on a database table to store pre-serialized version of documents.</para>
|
||||
/// <para>This does *not* reload the caches. Caches need to be reloaded, for instance via
|
||||
/// <see cref="DistributedCache" /> RefreshAllPublishedSnapshot method.</para>
|
||||
/// </remarks>
|
||||
void Rebuild();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Preview
|
||||
|
||||
/* Later on we can imagine that EnterPreview would handle a "level" that would be either
|
||||
|
||||
@@ -27,6 +27,7 @@ using Umbraco.Web.Cache;
|
||||
using Umbraco.Web.Install;
|
||||
using Umbraco.Web.PublishedCache.NuCache.DataSource;
|
||||
using Umbraco.Web.Routing;
|
||||
using File = System.IO.File;
|
||||
|
||||
namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
@@ -142,31 +143,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
if (registered)
|
||||
{
|
||||
string path;
|
||||
var tempLocation = globalSettings.LocalTempStorageLocation;
|
||||
switch (tempLocation)
|
||||
{
|
||||
case LocalTempStorage.AspNetTemp:
|
||||
path = Path.Combine(HttpRuntime.CodegenDir, "UmbracoData", "NuCache");
|
||||
break;
|
||||
case LocalTempStorage.EnvironmentTemp:
|
||||
// TODO: why has this to be repeated everywhere?!
|
||||
// include the appdomain hash is just a safety check, for example if a website is moved from worker A to worker B and then back
|
||||
// to worker A again, in theory the %temp% folder should already be empty but we really want to make sure that its not
|
||||
// utilizing an old path - assuming we cannot have SHA1 collisions on AppDomainAppId
|
||||
var appDomainHash = HttpRuntime.AppDomainAppId.GenerateHash();
|
||||
path = Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "UmbracoData", appDomainHash, "NuCache");
|
||||
break;
|
||||
//case LocalTempStorage.Default:
|
||||
//case LocalTempStorage.Unknown:
|
||||
default:
|
||||
path = IOHelper.MapPath("~/App_Data/TEMP/NuCache");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!Directory.Exists(path))
|
||||
Directory.CreateDirectory(path);
|
||||
|
||||
var path = GetLocalFilesPath();
|
||||
var localContentDbPath = Path.Combine(path, "NuCache.Content.db");
|
||||
var localMediaDbPath = Path.Combine(path, "NuCache.Media.db");
|
||||
_localDbExists = System.IO.File.Exists(localContentDbPath) && System.IO.File.Exists(localMediaDbPath);
|
||||
@@ -295,13 +272,69 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
#endregion
|
||||
|
||||
#region Local files
|
||||
|
||||
private string GetLocalFilesPath()
|
||||
{
|
||||
string path;
|
||||
var tempLocation = _globalSettings.LocalTempStorageLocation;
|
||||
switch (tempLocation)
|
||||
{
|
||||
case LocalTempStorage.AspNetTemp:
|
||||
path = Path.Combine(HttpRuntime.CodegenDir, "UmbracoData", "NuCache");
|
||||
break;
|
||||
case LocalTempStorage.EnvironmentTemp:
|
||||
// TODO: why has this to be repeated everywhere?!
|
||||
// include the appdomain hash is just a safety check, for example if a website is moved from worker A to worker B and then back
|
||||
// to worker A again, in theory the %temp% folder should already be empty but we really want to make sure that its not
|
||||
// utilizing an old path - assuming we cannot have SHA1 collisions on AppDomainAppId
|
||||
var appDomainHash = HttpRuntime.AppDomainAppId.GenerateHash();
|
||||
path = Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "UmbracoData", appDomainHash, "NuCache");
|
||||
break;
|
||||
//case LocalTempStorage.Default:
|
||||
//case LocalTempStorage.Unknown:
|
||||
default:
|
||||
path = IOHelper.MapPath("~/App_Data/TEMP/NuCache");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!Directory.Exists(path))
|
||||
Directory.CreateDirectory(path);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
private void DeleteLocalFilesForContent()
|
||||
{
|
||||
if (_isReady && _localContentDb != null)
|
||||
throw new InvalidOperationException("Cannot delete local files while the cache uses them.");
|
||||
|
||||
var path = GetLocalFilesPath();
|
||||
var localContentDbPath = Path.Combine(path, "NuCache.Content.db");
|
||||
if (File.Exists(localContentDbPath))
|
||||
File.Delete(localContentDbPath);
|
||||
}
|
||||
|
||||
private void DeleteLocalFilesForMedia()
|
||||
{
|
||||
if (_isReady && _localMediaDb != null)
|
||||
throw new InvalidOperationException("Cannot delete local files while the cache uses them.");
|
||||
|
||||
var path = GetLocalFilesPath();
|
||||
var localMediaDbPath = Path.Combine(path, "NuCache.Media.db");
|
||||
if (File.Exists(localMediaDbPath))
|
||||
File.Delete(localMediaDbPath);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Environment
|
||||
|
||||
public override bool EnsureEnvironment(out IEnumerable<string> errors)
|
||||
{
|
||||
// must have app_data and be able to write files into it
|
||||
var ok = FilePermissionHelper.TryCreateDirectory(SystemDirectories.Data);
|
||||
errors = ok ? Enumerable.Empty<string>() : new[] { "NuCache local DB files." };
|
||||
var ok = FilePermissionHelper.TryCreateDirectory(GetLocalFilesPath());
|
||||
errors = ok ? Enumerable.Empty<string>() : new[] { "NuCache local files." };
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -560,10 +593,11 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
public override void Notify(ContentCacheRefresher.JsonPayload[] payloads, out bool draftChanged, out bool publishedChanged)
|
||||
{
|
||||
// no cache, nothing we can do
|
||||
// no cache, trash everything
|
||||
if (_isReady == false)
|
||||
{
|
||||
draftChanged = publishedChanged = false;
|
||||
DeleteLocalFilesForContent();
|
||||
draftChanged = publishedChanged = true;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -655,10 +689,11 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
public override void Notify(MediaCacheRefresher.JsonPayload[] payloads, out bool anythingChanged)
|
||||
{
|
||||
// no cache, nothing we can do
|
||||
// no cache, trash everything
|
||||
if (_isReady == false)
|
||||
{
|
||||
anythingChanged = false;
|
||||
DeleteLocalFilesForMedia();
|
||||
anythingChanged = true;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1277,6 +1312,21 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
#region Rebuild Database PreCache
|
||||
|
||||
public override void Rebuild()
|
||||
{
|
||||
_logger.Debug<PublishedSnapshotService>("Rebuilding...");
|
||||
using (var scope = _scopeProvider.CreateScope(repositoryCacheMode: RepositoryCacheMode.Scoped))
|
||||
{
|
||||
scope.ReadLock(Constants.Locks.ContentTree);
|
||||
scope.ReadLock(Constants.Locks.MediaTree);
|
||||
scope.ReadLock(Constants.Locks.MemberTree);
|
||||
RebuildContentDbCacheLocked(scope, 5000, null);
|
||||
RebuildMediaDbCacheLocked(scope, 5000, null);
|
||||
RebuildMemberDbCacheLocked(scope, 5000, null);
|
||||
scope.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
public void RebuildContentDbCache(int groupSize = 5000, IEnumerable<int> contentTypeIds = null)
|
||||
{
|
||||
using (var scope = _scopeProvider.CreateScope(repositoryCacheMode: RepositoryCacheMode.Scoped))
|
||||
|
||||
@@ -33,6 +33,9 @@ namespace Umbraco.Web.PublishedCache
|
||||
public abstract void Notify(DataTypeCacheRefresher.JsonPayload[] payloads);
|
||||
public abstract void Notify(DomainCacheRefresher.JsonPayload[] payloads);
|
||||
|
||||
public virtual void Rebuild()
|
||||
{ }
|
||||
|
||||
public virtual void Dispose()
|
||||
{ }
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Dashboards;
|
||||
using Umbraco.Core.Dictionary;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Migrations.PostMigrations;
|
||||
using Umbraco.Web.Migrations.PostMigrations;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.PropertyEditors.ValueConverters;
|
||||
@@ -249,6 +251,9 @@ namespace Umbraco.Web.Runtime
|
||||
.Append<Soundcloud>()
|
||||
.Append<Issuu>()
|
||||
.Append<Hulu>();
|
||||
|
||||
// replace with web implementation
|
||||
composition.RegisterUnique<IPublishedSnapshotRebuilder, Migrations.PostMigrations.PublishedSnapshotRebuilder>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,6 +196,7 @@
|
||||
<Compile Include="Media\TypeDetector\SvgDetector.cs" />
|
||||
<Compile Include="Media\TypeDetector\TIFFDetector.cs" />
|
||||
<Compile Include="Media\UploadAutoFillProperties.cs" />
|
||||
<Compile Include="Migrations\PostMigrations\PublishedSnapshotRebuilder.cs" />
|
||||
<Compile Include="Models\ContentEditing\LinkDisplay.cs" />
|
||||
<Compile Include="Models\ContentEditing\MacroDisplay.cs" />
|
||||
<Compile Include="Models\ContentEditing\MacroParameterDisplay.cs" />
|
||||
@@ -885,7 +886,7 @@
|
||||
<Compile Include="Security\BackOfficeCookieManager.cs" />
|
||||
<Compile Include="Security\UmbracoBackOfficeCookieAuthOptions.cs" />
|
||||
<Compile Include="Scheduling\TaskAndFactoryExtensions.cs" />
|
||||
<Compile Include="Migrations\ClearCsrfCookiesAfterUpgrade.cs" />
|
||||
<Compile Include="Migrations\PostMigrations\ClearCsrfCookies.cs" />
|
||||
<Compile Include="Components\NotificationsComponent.cs" />
|
||||
<Compile Include="TagQuery.cs" />
|
||||
<Compile Include="Trees\CoreTreeAttribute.cs" />
|
||||
|
||||
Reference in New Issue
Block a user