Merge pull request #2101 from sbwalker/dev
include theme resources on server page load, add IUpgradeable interface to provide site-based versioning support
This commit is contained in:
commit
1ad0ee4a71
|
@ -190,6 +190,10 @@ namespace Oqtane.Infrastructure
|
|||
if (result.Success)
|
||||
{
|
||||
result = CreateSite(install);
|
||||
if (result.Success)
|
||||
{
|
||||
result = MigrateSites();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -665,6 +669,78 @@ namespace Oqtane.Infrastructure
|
|||
return result;
|
||||
}
|
||||
|
||||
private Installation MigrateSites()
|
||||
{
|
||||
var result = new Installation { Success = false, Message = string.Empty };
|
||||
|
||||
// find upgrade type
|
||||
Type upgradetype = null;
|
||||
var assemblies = AppDomain.CurrentDomain.GetOqtaneAssemblies();
|
||||
foreach (Assembly assembly in assemblies)
|
||||
{
|
||||
var types = assembly.GetTypes().Where(item => item.GetInterfaces().Contains(typeof(IUpgradeable)));
|
||||
if (types.Any())
|
||||
{
|
||||
upgradetype = types.First();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// execute upgrade
|
||||
if (upgradetype != null)
|
||||
{
|
||||
var obj = Activator.CreateInstance(upgradetype) as IUpgradeable;
|
||||
if (obj != null)
|
||||
{
|
||||
using (var scope = _serviceScopeFactory.CreateScope())
|
||||
{
|
||||
var aliases = scope.ServiceProvider.GetRequiredService<IAliasRepository>();
|
||||
var tenantManager = scope.ServiceProvider.GetRequiredService<ITenantManager>();
|
||||
var sites = scope.ServiceProvider.GetRequiredService<ISiteRepository>();
|
||||
|
||||
foreach (var alias in aliases.GetAliases().ToList().Where(item => item.IsDefault))
|
||||
{
|
||||
var versions = obj.GetVersions(alias);
|
||||
if (!string.IsNullOrEmpty(versions))
|
||||
{
|
||||
tenantManager.SetTenant(alias.TenantId);
|
||||
var site = sites.GetSites().FirstOrDefault(item => item.SiteId == alias.SiteId);
|
||||
if (site != null)
|
||||
{
|
||||
foreach (var version in versions.Split(',', StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
if (string.IsNullOrEmpty(site.Version) || Version.Parse(version) > Version.Parse(site.Version))
|
||||
{
|
||||
if (obj.Upgrade(alias, version))
|
||||
{
|
||||
site.Version = version;
|
||||
sites.UpdateSite(site);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Message = "An Error Occurred Executing IUpgradeable Interface For " + alias.Name + " For Version " + version;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(result.Message))
|
||||
{
|
||||
result.Success = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_filelogger.LogError(Utilities.LogMessage(this, result.Message));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private string DenormalizeConnectionString(string connectionString)
|
||||
{
|
||||
var dataDirectory = AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString();
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Oqtane.Enums;
|
||||
using Oqtane.Models;
|
||||
|
||||
namespace Oqtane.Infrastructure
|
||||
|
|
11
Oqtane.Server/Infrastructure/Interfaces/IUpgradeable.cs
Normal file
11
Oqtane.Server/Infrastructure/Interfaces/IUpgradeable.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
using Oqtane.Models;
|
||||
|
||||
namespace Oqtane.Infrastructure
|
||||
{
|
||||
public interface IUpgradeable
|
||||
{
|
||||
string GetVersions(Alias alias);
|
||||
|
||||
bool Upgrade(Alias alias, string version);
|
||||
}
|
||||
}
|
40
Oqtane.Server/Infrastructure/SiteUpgrade/ExampleUpgrade.cs
Normal file
40
Oqtane.Server/Infrastructure/SiteUpgrade/ExampleUpgrade.cs
Normal file
|
@ -0,0 +1,40 @@
|
|||
using Oqtane.Models;
|
||||
using Oqtane.Documentation;
|
||||
|
||||
namespace Oqtane.Infrastructure
|
||||
{
|
||||
[PrivateApi("Mark Site-Template classes as private, since it's not very useful in the public docs")]
|
||||
public class ExampleUpgrade : IUpgradeable
|
||||
{
|
||||
string IUpgradeable.GetVersions(Alias alias)
|
||||
{
|
||||
var versions = "";
|
||||
switch (alias.Name)
|
||||
{
|
||||
case "localhost:44357":
|
||||
// return the list of official release versions for the specific site
|
||||
versions = "1.0.0";
|
||||
break;
|
||||
}
|
||||
return versions;
|
||||
}
|
||||
|
||||
bool IUpgradeable.Upgrade(Alias alias, string version)
|
||||
{
|
||||
bool success = true;
|
||||
switch (alias.Name)
|
||||
{
|
||||
case "localhost:44357":
|
||||
switch (version)
|
||||
{
|
||||
case "1.0.0":
|
||||
// execute some version-specific upgrade logic for the site here such as adding pages, modules, content, etc...
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
}
|
||||
}
|
29
Oqtane.Server/Migrations/Tenant/03010004_AddSiteVersion.cs
Normal file
29
Oqtane.Server/Migrations/Tenant/03010004_AddSiteVersion.cs
Normal file
|
@ -0,0 +1,29 @@
|
|||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Oqtane.Databases.Interfaces;
|
||||
using Oqtane.Migrations.EntityBuilders;
|
||||
using Oqtane.Repository;
|
||||
|
||||
namespace Oqtane.Migrations.Tenant
|
||||
{
|
||||
[DbContext(typeof(TenantDBContext))]
|
||||
[Migration("Tenant.03.01.00.04")]
|
||||
public class AddSiteVersion : MultiDatabaseMigration
|
||||
{
|
||||
public AddSiteVersion(IDatabase database) : base(database)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder, ActiveDatabase);
|
||||
siteEntityBuilder.AddStringColumn("Version", 50, true);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder, ActiveDatabase);
|
||||
siteEntityBuilder.DropColumn("Version");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,6 +20,7 @@ using Microsoft.Extensions.Primitives;
|
|||
using Oqtane.Enums;
|
||||
using Oqtane.Security;
|
||||
using Oqtane.Extensions;
|
||||
using Oqtane.Themes;
|
||||
|
||||
namespace Oqtane.Pages
|
||||
{
|
||||
|
@ -69,7 +70,6 @@ namespace Oqtane.Pages
|
|||
public string Meta = "";
|
||||
public string FavIcon = "favicon.ico";
|
||||
public string PWAScript = "";
|
||||
public string ThemeType = "";
|
||||
public string Message = "";
|
||||
|
||||
public IActionResult OnGet()
|
||||
|
@ -134,7 +134,7 @@ namespace Oqtane.Pages
|
|||
PWAScript = CreatePWAScript(alias, site, route);
|
||||
}
|
||||
Title = site.Name;
|
||||
ThemeType = site.DefaultThemeType;
|
||||
var ThemeType = site.DefaultThemeType;
|
||||
|
||||
// get jwt token for downstream APIs
|
||||
if (User.Identity.IsAuthenticated)
|
||||
|
@ -153,7 +153,7 @@ namespace Oqtane.Pages
|
|||
}
|
||||
|
||||
var page = _pages.GetPage(route.PagePath, site.SiteId);
|
||||
if (page != null)
|
||||
if (page != null & !page.IsDeleted)
|
||||
{
|
||||
// set page title
|
||||
if (!string.IsNullOrEmpty(page.Title))
|
||||
|
@ -171,6 +171,7 @@ namespace Oqtane.Pages
|
|||
{
|
||||
ThemeType = page.ThemeType;
|
||||
}
|
||||
ProcessThemeResources(ThemeType);
|
||||
}
|
||||
else // page not found
|
||||
{
|
||||
|
@ -407,19 +408,43 @@ namespace Oqtane.Pages
|
|||
var obj = Activator.CreateInstance(type) as IHostResources;
|
||||
foreach (var resource in obj.Resources)
|
||||
{
|
||||
ProcessResource(resource);
|
||||
resource.Level = ResourceLevel.App;
|
||||
ProcessResource(resource, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessResource(Resource resource)
|
||||
private void ProcessThemeResources(string ThemeType)
|
||||
{
|
||||
var type = Type.GetType(ThemeType);
|
||||
if (type != null)
|
||||
{
|
||||
var obj = Activator.CreateInstance(type) as IThemeControl;
|
||||
if (obj.Resources != null)
|
||||
{
|
||||
int count = 1;
|
||||
foreach (var resource in obj.Resources.Where(item => item.ResourceType == ResourceType.Stylesheet))
|
||||
{
|
||||
resource.Level = ResourceLevel.Page;
|
||||
ProcessResource(resource, count++);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessResource(Resource resource, int count)
|
||||
{
|
||||
switch (resource.ResourceType)
|
||||
{
|
||||
case ResourceType.Stylesheet:
|
||||
if (!HeadResources.Contains(resource.Url, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
HeadResources += "<link rel=\"stylesheet\" href=\"" + resource.Url + "\"" + CrossOrigin(resource.CrossOrigin) + Integrity(resource.Integrity) + " />" + Environment.NewLine;
|
||||
string id = "";
|
||||
if (resource.Level == ResourceLevel.Page)
|
||||
{
|
||||
id = "id=\"app-stylesheet-" + resource.Level.ToString().ToLower() + "-" + DateTime.UtcNow.ToString("yyyyMMddHHmmssfff") + "-" + count.ToString("00") + "\" ";
|
||||
}
|
||||
HeadResources += "<link " + id + "rel=\"stylesheet\" href=\"" + resource.Url + "\"" + CrossOrigin(resource.CrossOrigin) + Integrity(resource.Integrity) + " />" + Environment.NewLine;
|
||||
}
|
||||
break;
|
||||
case ResourceType.Script:
|
||||
|
|
|
@ -2,6 +2,7 @@ namespace Oqtane.Shared
|
|||
{
|
||||
public enum ResourceLevel
|
||||
{
|
||||
App,
|
||||
Page,
|
||||
Module
|
||||
}
|
||||
|
|
|
@ -78,6 +78,11 @@ namespace Oqtane.Models
|
|||
/// </summary>
|
||||
public string RenderMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Keeps track of site configuration changes and is used by the IUpgradeable interface
|
||||
/// </summary>
|
||||
public string Version { get; set; }
|
||||
|
||||
#region IAuditable Properties
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
|
Loading…
Reference in New Issue
Block a user