Implemented tenant reset action.

This commit is contained in:
Daniel Stolt
2015-07-14 17:43:40 +01:00
parent 3f5919fa40
commit b6d0fa3dd2
10 changed files with 291 additions and 84 deletions

View File

@@ -19,7 +19,7 @@ namespace Orchard.MultiTenancy.Controllers {
public AdminController(ITenantService tenantService, IOrchardServices orchardServices, ShellSettings shellSettings) { public AdminController(ITenantService tenantService, IOrchardServices orchardServices, ShellSettings shellSettings) {
_tenantService = tenantService; _tenantService = tenantService;
_thisShellSettings = shellSettings; _thisShellSettings = shellSettings;
Services = orchardServices; Services = orchardServices;
T = NullLocalizer.Instance; T = NullLocalizer.Instance;
Logger = NullLogger.Instance; Logger = NullLogger.Instance;
@@ -30,32 +30,34 @@ namespace Orchard.MultiTenancy.Controllers {
public ILogger Logger { get; set; } public ILogger Logger { get; set; }
public ActionResult Index() { public ActionResult Index() {
return View(new TenantsIndexViewModel { TenantSettings = _tenantService.GetTenants() }); return View(new TenantsIndexViewModel {
TenantSettings = _tenantService.GetTenants()
});
} }
public ActionResult Add() { public ActionResult Add() {
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Cannot create tenant"))) if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("You don't have permission to create tenants.")))
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
if ( !EnsureDefaultTenant() ) if (!IsExecutingInDefaultTenant())
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
var model = new TenantAddViewModel(); var viewModel = new TenantAddViewModel();
// fetches all available themes and modules // Fetches all available themes and modules.
model.Themes = _tenantService.GetInstalledThemes().Select(x => new ThemeEntry { ThemeId = x.Id, ThemeName = x.Name }).ToList(); viewModel.Themes = _tenantService.GetInstalledThemes().Select(x => new ThemeEntry { ThemeId = x.Id, ThemeName = x.Name }).ToList();
model.Modules = _tenantService.GetInstalledModules().Select(x => new ModuleEntry { ModuleId = x.Id, ModuleName = x.Name }).ToList(); viewModel.Modules = _tenantService.GetInstalledModules().Select(x => new ModuleEntry { ModuleId = x.Id, ModuleName = x.Name }).ToList();
return View(model); return View(viewModel);
} }
[HttpPost, ActionName("Add")] [HttpPost, ActionName("Add")]
public ActionResult AddPOST(TenantAddViewModel viewModel) { public ActionResult AddPost(TenantAddViewModel viewModel) {
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Couldn't create tenant"))) { if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("You don't have permission to create tenants."))) {
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
} }
if (!EnsureDefaultTenant()) { if (!IsExecutingInDefaultTenant()) {
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
} }
@@ -63,7 +65,7 @@ namespace Orchard.MultiTenancy.Controllers {
ModelState.AddModelError("Name", T("A tenant with the same name already exists.", viewModel.Name).Text); ModelState.AddModelError("Name", T("A tenant with the same name already exists.", viewModel.Name).Text);
} }
// ensure tenants name are valid // Ensure tenants name are valid.
if (!String.IsNullOrEmpty(viewModel.Name) && !Regex.IsMatch(viewModel.Name, @"^\w+$")) { if (!String.IsNullOrEmpty(viewModel.Name) && !Regex.IsMatch(viewModel.Name, @"^\w+$")) {
ModelState.AddModelError("Name", T("Invalid tenant name. Must contain characters only and no spaces.").Text); ModelState.AddModelError("Name", T("Invalid tenant name. Must contain characters only and no spaces.").Text);
} }
@@ -88,56 +90,58 @@ namespace Orchard.MultiTenancy.Controllers {
return RedirectToAction("Index"); return RedirectToAction("Index");
} }
catch (ArgumentException exception) { catch (ArgumentException ex) {
Services.Notifier.Error(T("Creating Tenant failed: {0}", exception.Message)); Logger.Error(ex, "Error while creating tenant.");
Services.Notifier.Error(T("Tenant creation failed with error: {0}", ex.Message));
return View(viewModel); return View(viewModel);
} }
} }
public ActionResult Edit(string name) { public ActionResult Edit(string name) {
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Cannot edit tenant"))) if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("You don't have permission to edit tenants.")))
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
if ( !EnsureDefaultTenant() ) if (!IsExecutingInDefaultTenant())
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
var tenant = _tenantService.GetTenants().FirstOrDefault(ss => ss.Name == name); var tenant = _tenantService.GetTenants().FirstOrDefault(ss => ss.Name == name);
if (tenant == null) if (tenant == null)
return HttpNotFound(); return HttpNotFound();
return View(new TenantEditViewModel { return View(new TenantEditViewModel {
Name = tenant.Name, Name = tenant.Name,
RequestUrlHost = tenant.RequestUrlHost, RequestUrlHost = tenant.RequestUrlHost,
RequestUrlPrefix = tenant.RequestUrlPrefix, RequestUrlPrefix = tenant.RequestUrlPrefix,
DataProvider = tenant.DataProvider, DataProvider = tenant.DataProvider,
DatabaseConnectionString = tenant.DataConnectionString, DatabaseConnectionString = tenant.DataConnectionString,
DatabaseTablePrefix = tenant.DataTablePrefix, DatabaseTablePrefix = tenant.DataTablePrefix,
State = tenant.State, State = tenant.State,
Themes = _tenantService.GetInstalledThemes().Select(x => new ThemeEntry { Themes = _tenantService.GetInstalledThemes().Select(x => new ThemeEntry {
ThemeId = x.Id, ThemeId = x.Id,
ThemeName = x.Name, ThemeName = x.Name,
Checked = tenant.Themes.Contains(x.Id) Checked = tenant.Themes.Contains(x.Id)
}).ToList(), }).ToList(),
Modules = _tenantService.GetInstalledModules().Select(x => new ModuleEntry { Modules = _tenantService.GetInstalledModules().Select(x => new ModuleEntry {
ModuleId = x.Id, ModuleId = x.Id,
ModuleName = x.Name, ModuleName = x.Name,
Checked = tenant.Modules.Contains(x.Id) Checked = tenant.Modules.Contains(x.Id)
}).ToList() }).ToList()
}); });
} }
[HttpPost, ActionName("Edit")] [HttpPost, ActionName("Edit")]
public ActionResult EditPost(TenantEditViewModel viewModel) { public ActionResult EditPost(TenantEditViewModel viewModel) {
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Couldn't edit tenant"))) if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("You don't have permission to edit tenants.")))
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
if ( !EnsureDefaultTenant() ) if (!IsExecutingInDefaultTenant())
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
var tenant = _tenantService.GetTenants().FirstOrDefault(ss => ss.Name == viewModel.Name); var tenant = _tenantService.GetTenants().FirstOrDefault(ss => ss.Name == viewModel.Name);
if (tenant == null) if (tenant == null)
return HttpNotFound(); return HttpNotFound();
else if (tenant.Name == _thisShellSettings.Name)
return new HttpUnauthorizedResult();
if (!ModelState.IsValid) { if (!ModelState.IsValid) {
return View(viewModel); return View(viewModel);
@@ -163,18 +167,19 @@ namespace Orchard.MultiTenancy.Controllers {
return RedirectToAction("Index"); return RedirectToAction("Index");
} }
catch (Exception exception) { catch (Exception ex) {
Services.Notifier.Error(T("Failed to edit tenant: {0} ", exception.Message)); Logger.Error(ex, "Error while editing tenant.");
Services.Notifier.Error(T("Failed to edit tenant: {0} ", ex.Message));
return View(viewModel); return View(viewModel);
} }
} }
[HttpPost] [HttpPost]
public ActionResult Disable(string name) { public ActionResult Disable(string name) {
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Couldn't disable tenant"))) if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("You don't have permission to disable tenants.")))
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
if ( !EnsureDefaultTenant() ) if (!IsExecutingInDefaultTenant())
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
var tenant = _tenantService.GetTenants().FirstOrDefault(ss => ss.Name == name); var tenant = _tenantService.GetTenants().FirstOrDefault(ss => ss.Name == name);
@@ -189,10 +194,10 @@ namespace Orchard.MultiTenancy.Controllers {
[HttpPost] [HttpPost]
public ActionResult Enable(string name) { public ActionResult Enable(string name) {
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Couldn't enable tenant"))) if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("You don't have permission to enable tenants.")))
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
if ( !EnsureDefaultTenant() ) if (!IsExecutingInDefaultTenant())
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
var tenant = _tenantService.GetTenants().FirstOrDefault(ss => ss.Name == name); var tenant = _tenantService.GetTenants().FirstOrDefault(ss => ss.Name == name);
@@ -205,7 +210,55 @@ namespace Orchard.MultiTenancy.Controllers {
return RedirectToAction("Index"); return RedirectToAction("Index");
} }
private bool EnsureDefaultTenant() { public ActionResult Reset(string name) {
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("You don't have permission to reset tenants.")))
return new HttpUnauthorizedResult();
if (!IsExecutingInDefaultTenant())
return new HttpUnauthorizedResult();
var tenant = _tenantService.GetTenants().FirstOrDefault(ss => ss.Name == name);
if (tenant == null)
return HttpNotFound();
return View(new TenantResetViewModel() {
Name = name,
DatabaseTableNames = _tenantService.GetTenantDatabaseTableNames(tenant)
});
}
[HttpPost, ActionName("Reset")]
public ActionResult ResetPost(TenantResetViewModel viewModel) {
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("You don't have permission to reset tenants.")))
return new HttpUnauthorizedResult();
if (!IsExecutingInDefaultTenant())
return new HttpUnauthorizedResult();
var tenant = _tenantService.GetTenants().FirstOrDefault(ss => ss.Name == viewModel.Name);
if (tenant == null)
return HttpNotFound();
else if (tenant.Name == _thisShellSettings.Name)
return new HttpUnauthorizedResult();
if (!ModelState.IsValid) {
viewModel.DatabaseTableNames = _tenantService.GetTenantDatabaseTableNames(tenant);
return View(viewModel);
}
try {
_tenantService.ResetTenant(tenant, viewModel.DropDatabaseTables);
return RedirectToAction("Index");
}
catch (Exception ex) {
Logger.Error(ex, "Error while resetting tenant.");
Services.Notifier.Error(T("Failed to reset tenant: {0} ", ex.Message));
viewModel.DatabaseTableNames = _tenantService.GetTenantDatabaseTableNames(tenant);
return View(viewModel);
}
}
private bool IsExecutingInDefaultTenant() {
return _thisShellSettings.Name == ShellSettings.DefaultName; return _thisShellSettings.Name == ShellSettings.DefaultName;
} }
} }

View File

@@ -25,6 +25,7 @@
<IISExpressAnonymousAuthentication /> <IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication /> <IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode /> <IISExpressUseClassicPipelineMode />
<UseGlobalApplicationHostFile />
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@@ -48,6 +49,12 @@
<Prefer32Bit>false</Prefer32Bit> <Prefer32Bit>false</Prefer32Bit>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Autofac">
<HintPath>..\..\..\..\lib\autofac\Autofac.dll</HintPath>
</Reference>
<Reference Include="NHibernate">
<HintPath>..\..\..\..\lib\nhibernate\NHibernate.dll</HintPath>
</Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations"> <Reference Include="System.ComponentModel.DataAnnotations">
<RequiredTargetFramework>3.5</RequiredTargetFramework> <RequiredTargetFramework>3.5</RequiredTargetFramework>
@@ -73,9 +80,11 @@
<Compile Include="Controllers\AdminController.cs" /> <Compile Include="Controllers\AdminController.cs" />
<Compile Include="Extensions\UrlHelperExtensions.cs" /> <Compile Include="Extensions\UrlHelperExtensions.cs" />
<Compile Include="Routes.cs" /> <Compile Include="Routes.cs" />
<Compile Include="Services\ITenantResetEventHandler.cs" />
<Compile Include="Services\ITenantService.cs" /> <Compile Include="Services\ITenantService.cs" />
<Compile Include="Services\TenantService.cs" /> <Compile Include="Services\TenantService.cs" />
<Compile Include="ViewModels\ModuleEntry.cs" /> <Compile Include="ViewModels\ModuleEntry.cs" />
<Compile Include="ViewModels\TenantResetViewModel.cs" />
<Compile Include="ViewModels\TenantEditViewModel.cs" /> <Compile Include="ViewModels\TenantEditViewModel.cs" />
<Compile Include="ViewModels\TenantAddViewModel.cs" /> <Compile Include="ViewModels\TenantAddViewModel.cs" />
<Compile Include="ViewModels\TenantsIndexViewModel.cs" /> <Compile Include="ViewModels\TenantsIndexViewModel.cs" />
@@ -123,6 +132,9 @@
</SubType> </SubType>
</Content> </Content>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Content Include="Views\Admin\Reset.cshtml" />
</ItemGroup>
<PropertyGroup> <PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion> <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>

View File

@@ -0,0 +1,10 @@
using Orchard.Events;
namespace Orchard.MultiTenancy.Services {
/// <summary>
/// An event handler interface that allows implementers to execute code when a tenant is being reset.
/// </summary>
public interface ITenantResetEventHandler : IEventHandler {
void Resetting();
}
}

View File

@@ -5,23 +5,35 @@ using Orchard.Environment.Extensions.Models;
namespace Orchard.MultiTenancy.Services { namespace Orchard.MultiTenancy.Services {
public interface ITenantService : IDependency { public interface ITenantService : IDependency {
/// <summary> /// <summary>
/// Retrieves all tenants' shell settings. /// Retrieves ShellSettings objects for all tenants.
/// </summary> /// </summary>
/// <returns>All tenants' shell settings.</returns>
IEnumerable<ShellSettings> GetTenants(); IEnumerable<ShellSettings> GetTenants();
/// <summary> /// <summary>
/// Creates a new tenant. /// Creates a new tenant.
/// </summary> /// </summary>
/// <param name="settings">Shell settings of the tenant.</param> /// <param name="settings">A ShellSettings object specifying the settings for the new tenant.</param>
void CreateTenant(ShellSettings settings); void CreateTenant(ShellSettings settings);
/// <summary> /// <summary>
/// Updates the shell settings of a tenant. /// Updates the settings of a tenant.
/// </summary> /// </summary>
/// <param name="settings">Shell settings of the tenant.</param> /// <param name="settings">The new ShellSettings object for the tenant.</param>
void UpdateTenant(ShellSettings settings); void UpdateTenant(ShellSettings settings);
/// <summary>
/// Resets a tenant to its uninitialized state.
/// </summary>
/// <param name="tenantName">A ShellSettings object for the tenant to reset.</param>
/// <param name="dropDatabaseTables">A boolean indicated whether tenant database tables should be dropped also.</param>
void ResetTenant(ShellSettings settings, bool dropDatabaseTables);
/// <summary>
/// Returns a list of all known database tables in a tenant.
/// </summary>
/// <returns>A ShellSettings object for the tenant.</returns>
IEnumerable<string> GetTenantDatabaseTableNames(ShellSettings settings);
/// <summary> /// <summary>
/// Returns a list of all installed themes. /// Returns a list of all installed themes.
/// </summary> /// </summary>

View File

@@ -1,21 +1,36 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using Orchard.Environment.Configuration; using Orchard.Environment.Configuration;
using Orchard.Environment.Extensions.Models; using Orchard.Environment.Extensions.Models;
using Orchard.Environment.Extensions; using Orchard.Environment.Extensions;
using Orchard.Environment.ShellBuilders;
using Orchard.Data.Migration.Interpreters;
using Orchard.Data.Migration.Schema;
using Orchard.Data;
using Orchard.Logging;
namespace Orchard.MultiTenancy.Services { namespace Orchard.MultiTenancy.Services {
public class TenantService : ITenantService { public class TenantService : ITenantService {
private readonly IShellSettingsManager _shellSettingsManager; private readonly IShellSettingsManager _shellSettingsManager;
private readonly IExtensionManager _extensionManager; private readonly IExtensionManager _extensionManager;
private readonly IShellContextFactory _shellContextFactory;
private readonly IShellContainerFactory _shellContainerFactory;
public TenantService( public TenantService(
IShellSettingsManager shellSettingsManager, IShellSettingsManager shellSettingsManager,
IExtensionManager extensionManager) { IExtensionManager extensionManager,
IShellContextFactory shellContextFactory,
IShellContainerFactory shellContainerFactory) {
_shellSettingsManager = shellSettingsManager; _shellSettingsManager = shellSettingsManager;
_extensionManager = extensionManager; _extensionManager = extensionManager;
_shellContextFactory = shellContextFactory;
_shellContainerFactory = shellContainerFactory;
Logger = NullLogger.Instance;
} }
public ILogger Logger { get; set; }
public IEnumerable<ShellSettings> GetTenants() { public IEnumerable<ShellSettings> GetTenants() {
return _shellSettingsManager.LoadSettings(); return _shellSettingsManager.LoadSettings();
} }
@@ -28,16 +43,32 @@ namespace Orchard.MultiTenancy.Services {
_shellSettingsManager.SaveSettings(settings); _shellSettingsManager.SaveSettings(settings);
} }
/// <summary> public void ResetTenant(ShellSettings settings, bool dropDatabaseTables) {
/// Loads only installed themes if (settings.State != TenantState.Disabled)
/// </summary> throw new InvalidOperationException(String.Format("Tenant state is '{0}'; must be '{1}' to perform reset action.", settings.State, TenantState.Disabled));
ExecuteOnTenantScope(settings, environment => {
ExecuteResetEventHandlers(environment);
if (dropDatabaseTables)
DropTenantDatabaseTables(environment);
});
settings.State = TenantState.Uninitialized;
_shellSettingsManager.SaveSettings(settings);
}
public IEnumerable<string> GetTenantDatabaseTableNames(ShellSettings settings) {
IEnumerable<string> result = null;
ExecuteOnTenantScope(settings, environment => {
result = GetTenantDatabaseTableNames(environment);
});
return result;
}
public IEnumerable<ExtensionDescriptor> GetInstalledThemes() { public IEnumerable<ExtensionDescriptor> GetInstalledThemes() {
return GetThemes(_extensionManager.AvailableExtensions()); return GetThemes(_extensionManager.AvailableExtensions());
} }
/// <summary>
/// Loads only installed modules
/// </summary>
public IEnumerable<ExtensionDescriptor> GetInstalledModules() { public IEnumerable<ExtensionDescriptor> GetInstalledModules() {
return _extensionManager.AvailableExtensions().Where(descriptor => DefaultExtensionTypes.IsModule(descriptor.ExtensionType)); return _extensionManager.AvailableExtensions().Where(descriptor => DefaultExtensionTypes.IsModule(descriptor.ExtensionType));
} }
@@ -58,5 +89,45 @@ namespace Orchard.MultiTenancy.Services {
} }
return themes; return themes;
} }
private void ExecuteOnTenantScope(ShellSettings settings, Action<IWorkContextScope> action) {
var shellContext = _shellContextFactory.CreateShellContext(settings);
using (var container = _shellContainerFactory.CreateContainer(shellContext.Settings, shellContext.Blueprint)) {
using (var environment = container.CreateWorkContextScope()) {
action(environment);
}
}
}
private IEnumerable<string> GetTenantDatabaseTableNames(IWorkContextScope environment) {
var sessionFactoryHolder = environment.Resolve<ISessionFactoryHolder>();
var schemaBuilder = new SchemaBuilder(environment.Resolve<IDataMigrationInterpreter>());
var configuration = sessionFactoryHolder.GetConfiguration();
var result =
from mapping in configuration.ClassMappings
select mapping.Table.Name;
return result.ToArray();
}
private void DropTenantDatabaseTables(IWorkContextScope environment) {
var sessionFactoryHolder = environment.Resolve<ISessionFactoryHolder>();
var schemaBuilder = new SchemaBuilder(environment.Resolve<IDataMigrationInterpreter>());
var configuration = sessionFactoryHolder.GetConfiguration();
foreach (var mapping in configuration.ClassMappings) {
try {
schemaBuilder.DropTable(mapping.Table.Name);
}
catch (Exception ex) {
Logger.Warning(ex, "Failed to drop table '{0}'.", mapping.Table.Name);
}
}
}
private void ExecuteResetEventHandlers(IWorkContextScope environment) {
var handler = environment.Resolve<ITenantResetEventHandler>();
handler.Resetting();
}
} }
} }

View File

@@ -0,0 +1,17 @@
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
using System.Linq;
namespace Orchard.MultiTenancy.ViewModels {
public class TenantResetViewModel {
public TenantResetViewModel() {
DatabaseTableNames = Enumerable.Empty<string>();
}
[Required]
public string Name { get; set; }
public bool DropDatabaseTables { get; set; }
public IEnumerable<string> DatabaseTableNames { get; set; }
}
}

View File

@@ -1,7 +1,8 @@
@model Orchard.Environment.Configuration.ShellSettings @model Orchard.Environment.Configuration.ShellSettings
@using Orchard.MultiTenancy.Extensions; @using Orchard.MultiTenancy.Extensions;
@using(Html.BeginFormAntiForgeryPost(Url.Action("enable", new {area = "Orchard.MultiTenancy"}), FormMethod.Post, new {@class = "inline link"})) { @using(Html.BeginFormAntiForgeryPost(Url.Action("Enable", new {area = "Orchard.MultiTenancy"}), FormMethod.Post, new {@class = "inline link"})) {
@Html.HiddenFor(ss => ss.Name) @Html.HiddenFor(ss => ss.Name)
<button type="submit">@T("Resume")</button> <button type="submit">@T("Resume")</button>
} } @T(" | ")
@Html.ActionLink(T("Reset").ToString(), "Reset", new { name = Model.Name, area = "Orchard.MultiTenancy" })

View File

@@ -1,7 +1,7 @@
@model Orchard.Environment.Configuration.ShellSettings @model Orchard.Environment.Configuration.ShellSettings
@using Orchard.MultiTenancy.Extensions; @using Orchard.MultiTenancy.Extensions;
@using(Html.BeginFormAntiForgeryPost(Url.Action("disable", new {area = "Orchard.MultiTenancy"}), FormMethod.Post, new {@class = "inline link"})) { @using(Html.BeginFormAntiForgeryPost(Url.Action("Disable", new {area = "Orchard.MultiTenancy"}), FormMethod.Post, new {@class = "inline link"})) {
@Html.HiddenFor(ss => ss.Name) @Html.HiddenFor(ss => ss.Name)
<button type="submit">@T("Suspend")</button> <button type="submit">@T("Suspend")</button>
} }

View File

@@ -7,30 +7,31 @@
Layout.Title = T("List of Site's Tenants").ToString(); Layout.Title = T("List of Site's Tenants").ToString();
} }
<div class="manage">@Html.ActionLink(T("Add a Tenant").ToString(), "Add", new {area = "Orchard.MultiTenancy"}, new { @class = "button primaryAction" })</div> <div class="manage">@Html.ActionLink(T("Add a Tenant").ToString(), "Add", new { area = "Orchard.MultiTenancy" }, new { @class = "button primaryAction" })</div>
<ul class="contentItems tenants"> <ul class="contentItems tenants">
@foreach (var tenant in Model.TenantSettings) { @foreach (var tenant in Model.TenantSettings) {
<li class="tenant @tenant.State"> <li class="tenant @tenant.State">
<div class="summary"> <div class="summary">
<div class="properties"> <div class="properties">
<h3>@tenant.Name @if (!string.IsNullOrEmpty(tenant.RequestUrlHost)) { <h3>
var tenantClone = new ShellSettings(tenant); @tenant.Name @if (!string.IsNullOrEmpty(tenant.RequestUrlHost)) {
foreach (var t in tenant.RequestUrlHost.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { var tenantClone = new ShellSettings(tenant);
tenantClone.RequestUrlHost = t; foreach (var t in tenant.RequestUrlHost.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) {
var url = Url.Tenant(tenantClone); tenantClone.RequestUrlHost = t;
<span class="tenantHost"> - @Html.Link(url, url)</span> var url = Url.Tenant(tenantClone);
} <span class="tenantHost"> - @Html.Link(url, url)</span>
} }
</h3> }
</div> </h3>
<div class="related"> </div>
@if (!string.Equals(tenant.Name, "default", StringComparison.OrdinalIgnoreCase)) { //todo: (heskew) base this off the view model so logic on what can be removed and have its state changed stays in the controller <div class="related">
@if (!String.Equals(tenant.Name, "default", StringComparison.OrdinalIgnoreCase)) { //todo: (heskew) base this off the view model so logic on what can be removed and have its state changed stays in the controller
var t = tenant; var t = tenant;
@Html.DisplayFor(m => t, string.Format("ActionsFor{0}", tenant.State.ToString()), "") @T(" | ") @Html.DisplayFor(m => t, String.Format("ActionsFor{0}", tenant.State.ToString()), "") @T(" | ")
} }
@Html.ActionLink(T("Edit").ToString(), "Edit", new {name = tenant.Name, area = "Orchard.MultiTenancy"}) @Html.ActionLink(T("Edit").ToString(), "Edit", new { name = tenant.Name, area = "Orchard.MultiTenancy" })
</div>
</div> </div>
</div> </li>
</li>
} }
</ul> </ul>

View File

@@ -0,0 +1,30 @@
@model Orchard.MultiTenancy.ViewModels.TenantResetViewModel
@{
Layout.Title = T("Reset Tenant").ToString();
Script.Require("jQuery");
Script.Include(Url.Content("~/Themes/TheAdmin/Scripts/admin.js")).AtFoot();
}
@using (Html.BeginFormAntiForgeryPost()) {
@Html.ValidationSummary()
<fieldset>
<p>@T("This will reset the tenant <strong>{0}</strong> to its uninitialized state, allowing you to set it up again.", Model.Name)</p>
</fieldset>
<fieldset>
@Html.CheckBoxFor(m => Model.DropDatabaseTables)
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.DropDatabaseTables)">@("Also delete tenant database tables:")</label>
<ul style="margin-left: 4em; margin-top: 1em; -webkit-column-width: 24em; -moz-column-width: 24em; column-width: 24em;">
@foreach (var tableName in Model.DatabaseTableNames) {
<li><span class="hint">@tableName</span></li>
}
</ul>
</fieldset>
<fieldset>
<button class="primaryAction" type="submit">@T("Reset")</button>
</fieldset>
}