mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-12-02 11:44:41 +08:00
Making Import/Export extensible
--HG-- branch : 1.x
This commit is contained in:
@@ -14,10 +14,17 @@ namespace Orchard.ImportExport.Controllers {
|
||||
public class AdminController : Controller {
|
||||
private readonly IImportExportService _importExportService;
|
||||
private readonly IContentDefinitionManager _contentDefinitionManager;
|
||||
private readonly ICustomExportStep _customExportStep;
|
||||
|
||||
public AdminController(IOrchardServices services, IImportExportService importExportService, IContentDefinitionManager contentDefinitionManager) {
|
||||
public AdminController(
|
||||
IOrchardServices services,
|
||||
IImportExportService importExportService,
|
||||
IContentDefinitionManager contentDefinitionManager,
|
||||
ICustomExportStep customExportStep
|
||||
) {
|
||||
_importExportService = importExportService;
|
||||
_contentDefinitionManager = contentDefinitionManager;
|
||||
_customExportStep = customExportStep;
|
||||
Services = services;
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
@@ -50,10 +57,18 @@ namespace Orchard.ImportExport.Controllers {
|
||||
}
|
||||
|
||||
public ActionResult Export() {
|
||||
var viewModel = new ExportViewModel { ContentTypes = new List<ContentTypeEntry>() };
|
||||
var customSteps = new List<string>();
|
||||
_customExportStep.Register(customSteps);
|
||||
|
||||
var viewModel = new ExportViewModel {
|
||||
ContentTypes = new List<ContentTypeEntry>(),
|
||||
CustomSteps = customSteps.Select(x => new CustomStepEntry { CustomStep = x }).ToList()
|
||||
};
|
||||
|
||||
foreach (var contentType in _contentDefinitionManager.ListTypeDefinitions().OrderBy(c => c.Name)) {
|
||||
viewModel.ContentTypes.Add(new ContentTypeEntry { ContentTypeName = contentType.Name });
|
||||
}
|
||||
|
||||
return View(viewModel);
|
||||
}
|
||||
|
||||
@@ -62,11 +77,21 @@ namespace Orchard.ImportExport.Controllers {
|
||||
if (!Services.Authorizer.Authorize(Permissions.Export, T("Not allowed to export.")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
var viewModel = new ExportViewModel { ContentTypes = new List<ContentTypeEntry>() };
|
||||
var viewModel = new ExportViewModel {
|
||||
ContentTypes = new List<ContentTypeEntry>(),
|
||||
CustomSteps = new List<CustomStepEntry>()
|
||||
};
|
||||
|
||||
UpdateModel(viewModel);
|
||||
var contentTypesToExport = viewModel.ContentTypes.Where(c => c.IsChecked).Select(c => c.ContentTypeName);
|
||||
var exportOptions = new ExportOptions { ExportMetadata = viewModel.Metadata, ExportSiteSettings = viewModel.SiteSettings };
|
||||
var customSteps = viewModel.CustomSteps.Where(c => c.IsChecked).Select(c => c.CustomStep);
|
||||
|
||||
var exportOptions = new ExportOptions {
|
||||
ExportMetadata = viewModel.Metadata,
|
||||
ExportSiteSettings = viewModel.SiteSettings,
|
||||
CustomSteps = customSteps
|
||||
};
|
||||
|
||||
if (viewModel.Data) {
|
||||
exportOptions.ExportData = true;
|
||||
exportOptions.VersionHistoryOptions = (VersionHistoryOptions)Enum.Parse(typeof(VersionHistoryOptions), viewModel.DataImportChoice, true);
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
namespace Orchard.ImportExport.Models {
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Orchard.ImportExport.Models {
|
||||
public class ExportOptions {
|
||||
public bool ExportMetadata { get; set; }
|
||||
public bool ExportData { get; set; }
|
||||
public VersionHistoryOptions VersionHistoryOptions { get; set; }
|
||||
public bool ExportSiteSettings { get; set; }
|
||||
public IEnumerable<string> CustomSteps { get; set; }
|
||||
}
|
||||
|
||||
public enum VersionHistoryOptions {
|
||||
|
||||
@@ -53,6 +53,8 @@
|
||||
<Compile Include="Models\ExportOptions.cs" />
|
||||
<Compile Include="Permissions.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Services\ICustomExportStep.cs" />
|
||||
<Compile Include="Services\IExportEventHandler.cs" />
|
||||
<Compile Include="Services\IImportExportService.cs" />
|
||||
<Compile Include="Services\ImportExportService.cs" />
|
||||
<Compile Include="ViewModels\ExportViewModel.cs" />
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Events;
|
||||
|
||||
namespace Orchard.ImportExport.Services {
|
||||
public interface ICustomExportStep : IEventHandler {
|
||||
void Register(IList<string> steps);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
using Orchard.Events;
|
||||
using Orchard.ImportExport.Models;
|
||||
|
||||
namespace Orchard.ImportExport.Services {
|
||||
public class ExportContext {
|
||||
public XDocument Document { get; set; }
|
||||
public IEnumerable<string> ContentTypes { get; set; }
|
||||
public ExportOptions ExportOptions { get; set; }
|
||||
}
|
||||
|
||||
public interface IExportEventHandler : IEventHandler {
|
||||
void Exporting(ExportContext context);
|
||||
void Exported(ExportContext context);
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ namespace Orchard.ImportExport.Services {
|
||||
private readonly IRecipeParser _recipeParser;
|
||||
private readonly IRecipeManager _recipeManager;
|
||||
private readonly IShellDescriptorManager _shellDescriptorManager;
|
||||
private readonly IEnumerable<IExportEventHandler> _exportEventHandlers;
|
||||
private const string ExportsDirectory = "Exports";
|
||||
|
||||
public ImportExportService(
|
||||
@@ -32,7 +33,8 @@ namespace Orchard.ImportExport.Services {
|
||||
IAppDataFolder appDataFolder,
|
||||
IRecipeParser recipeParser,
|
||||
IRecipeManager recipeManager,
|
||||
IShellDescriptorManager shellDescriptorManager) {
|
||||
IShellDescriptorManager shellDescriptorManager,
|
||||
IEnumerable<IExportEventHandler> exportEventHandlers) {
|
||||
_orchardServices = orchardServices;
|
||||
_contentDefinitionManager = contentDefinitionManager;
|
||||
_contentDefinitionWriter = contentDefinitionWriter;
|
||||
@@ -40,6 +42,7 @@ namespace Orchard.ImportExport.Services {
|
||||
_recipeParser = recipeParser;
|
||||
_recipeManager = recipeManager;
|
||||
_shellDescriptorManager = shellDescriptorManager;
|
||||
_exportEventHandlers = exportEventHandlers;
|
||||
Logger = NullLogger.Instance;
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
@@ -56,6 +59,14 @@ namespace Orchard.ImportExport.Services {
|
||||
public string Export(IEnumerable<string> contentTypes, ExportOptions exportOptions) {
|
||||
var exportDocument = CreateExportRoot();
|
||||
|
||||
var context = new ExportContext {
|
||||
Document = exportDocument,
|
||||
ContentTypes = contentTypes,
|
||||
ExportOptions = exportOptions
|
||||
};
|
||||
|
||||
_exportEventHandlers.Invoke(x => x.Exporting(context), Logger);
|
||||
|
||||
if (exportOptions.ExportMetadata) {
|
||||
exportDocument.Element("Orchard").Add(ExportMetadata(contentTypes));
|
||||
}
|
||||
@@ -68,6 +79,8 @@ namespace Orchard.ImportExport.Services {
|
||||
exportDocument.Element("Orchard").Add(ExportData(contentTypes, exportOptions.VersionHistoryOptions));
|
||||
}
|
||||
|
||||
_exportEventHandlers.Invoke(x => x.Exported(context), Logger);
|
||||
|
||||
return WriteExportFile(exportDocument.ToString());
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace Orchard.ImportExport.ViewModels {
|
||||
public class ExportViewModel {
|
||||
public IList<ContentTypeEntry> ContentTypes { get; set; }
|
||||
public IList<CustomStepEntry> CustomSteps { get; set; }
|
||||
public virtual bool Metadata { get; set; }
|
||||
public virtual bool Data { get; set; }
|
||||
public virtual string DataImportChoice { get; set; }
|
||||
@@ -13,4 +14,9 @@ namespace Orchard.ImportExport.ViewModels {
|
||||
public string ContentTypeName { get; set; }
|
||||
public bool IsChecked { get; set; }
|
||||
}
|
||||
|
||||
public class CustomStepEntry {
|
||||
public string CustomStep { get; set; }
|
||||
public bool IsChecked { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
@{ Layout.Title = T("Export").ToString(); }
|
||||
|
||||
@using(Html.BeginFormAntiForgeryPost()) {
|
||||
@using (Html.BeginFormAntiForgeryPost()) {
|
||||
Html.ValidationSummary();
|
||||
<fieldset>
|
||||
<legend>@T("Choose the types to include in the export file:")</legend>
|
||||
@@ -15,36 +15,54 @@
|
||||
<input type="checkbox" value="true" name="@Html.NameOf(m => m.ContentTypes[contentTypeIndex].IsChecked)" id="@Html.NameOf(m => m.ContentTypes[contentTypeIndex].IsChecked)" />
|
||||
<label class="forcheckbox" for="@Html.NameOf(m => m.ContentTypes[contentTypeIndex].IsChecked)">@Model.ContentTypes[contentTypeIndex].ContentTypeName.CamelFriendly()</label>
|
||||
</li>
|
||||
contentTypeIndex = contentTypeIndex + 1;
|
||||
}
|
||||
contentTypeIndex = contentTypeIndex + 1;
|
||||
}
|
||||
</ol>
|
||||
</fieldset>
|
||||
<hr />
|
||||
<fieldset>
|
||||
<legend>@T("Choose what to save for these types:")</legend>
|
||||
<div>
|
||||
@Html.EditorFor(m => m.Metadata)
|
||||
<label class="forcheckbox" for="@Html.FieldIdFor( m => m.Metadata)">@T("Metadata")</label>
|
||||
<span class="hint">@T("Metadata is the definition of your content types: what parts and fields they have, with what settings.")</span>
|
||||
</div>
|
||||
<div>
|
||||
@Html.EditorFor(m => m.Data)
|
||||
<label class="forcheckbox" for="@Html.FieldIdFor( m => m.Data)">@T("Data")</label>
|
||||
<span class="hint">@T("Data is the actual content of your site.")</span>
|
||||
</div>
|
||||
<div>
|
||||
<p>@T("Version History")</p>
|
||||
<legend>@T("Choose what to save for these types:")</legend>
|
||||
<div>
|
||||
@Html.EditorFor(m => m.Metadata)
|
||||
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.Metadata)">@T("Metadata")</label>
|
||||
<span class="hint">@T("Metadata is the definition of your content types: what parts and fields they have, with what settings.")</span>
|
||||
</div>
|
||||
<div>
|
||||
@Html.EditorFor(m => m.Data)
|
||||
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.Data)">@T("Data")</label>
|
||||
<span class="hint">@T("Data is the actual content of your site.")</span>
|
||||
</div>
|
||||
<div>
|
||||
<p>@T("Version History")</p>
|
||||
@Html.RadioButtonFor(m => m.DataImportChoice, "Published", new { id = "Published", Checked = "Checked" })
|
||||
<label for="@Html.FieldIdFor(m => m.DataImportChoice)" class="forcheckbox">@T("Only Published Versions")</label>
|
||||
<br />
|
||||
<br />
|
||||
@Html.RadioButtonFor(m => m.DataImportChoice, "Draft", new { id = "Draft" })
|
||||
<label for="@Html.FieldIdFor(m => m.DataImportChoice)" class="forcheckbox">@T("Only Drafts")</label>
|
||||
</div>
|
||||
<div>
|
||||
@Html.EditorFor(m => m.SiteSettings)
|
||||
<label class="forcheckbox" for="@Html.FieldIdFor( m => m.SiteSettings)">@T("Site Settings")</label><br />
|
||||
<span class="hint">@T("Please verify that you are not exporting confidential information, such as passwords or application keys.")</span>
|
||||
</div>
|
||||
</fieldset>
|
||||
<button type="submit" class="primaryAction">@T("Export")</button>
|
||||
<div>
|
||||
@Html.EditorFor(m => m.SiteSettings)
|
||||
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.SiteSettings)">@T("Site Settings")</label><br />
|
||||
<span class="hint">@T("Please verify that you are not exporting confidential information, such as passwords or application keys.")</span>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
if (Model.CustomSteps.Any()) {
|
||||
<fieldset>
|
||||
<legend>@T("Choose the custom steps to execute in the export file:")</legend>
|
||||
<ol>
|
||||
@{ var customStepIndex = 0; }
|
||||
@foreach (var customStepEntry in Model.CustomSteps) {
|
||||
<li>
|
||||
<input type="hidden" value="@Model.CustomSteps[customStepIndex].CustomStep" name="@Html.NameOf(m => m.CustomSteps[customStepIndex].CustomStep)"/>
|
||||
<input type="checkbox" value="true" name="@Html.NameOf(m => m.CustomSteps[customStepIndex].IsChecked)" id="@Html.NameOf(m => m.CustomSteps[customStepIndex].IsChecked)" />
|
||||
<label class="forcheckbox" for="@Html.NameOf(m => m.CustomSteps[customStepIndex].IsChecked)">@Model.CustomSteps[customStepIndex].CustomStep.CamelFriendly()</label>
|
||||
</li>
|
||||
customStepIndex = customStepIndex + 1;
|
||||
}
|
||||
</ol>
|
||||
</fieldset>
|
||||
}
|
||||
|
||||
<button type="submit" class="primaryAction">@T("Export")</button>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user