From b834744ff9a2d4ab2b2f780b891b5345398dc8fd Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Tue, 13 Sep 2011 14:25:12 -0700 Subject: [PATCH] #16476: Adding delete content types and parts actions Work Items: 16476 --HG-- branch : 1.x --- .../Metadata/ContentDefinitionManagerTests.cs | 38 ++++++++++++++ .../Metadata/ContentDefinitionManager.cs | 33 +++++++++++++ .../Modules/Orchard.ContentTypes/AdminMenu.cs | 9 ++-- .../Controllers/AdminController.cs | 49 ++++++++++++++++++- .../Views/Admin/Edit.cshtml | 4 +- .../Views/Admin/EditPart.cshtml | 4 +- .../Views/Admin/List.cshtml | 1 - .../Views/Admin/ListParts.cshtml | 1 - .../DisplayTemplates/EditPartViewModel.cshtml | 2 +- .../MetaData/IContentDefinitionManager.cs | 2 + 10 files changed, 131 insertions(+), 12 deletions(-) diff --git a/src/Orchard.Core.Tests/Settings/Metadata/ContentDefinitionManagerTests.cs b/src/Orchard.Core.Tests/Settings/Metadata/ContentDefinitionManagerTests.cs index f1fa72a95..f3ef73370 100644 --- a/src/Orchard.Core.Tests/Settings/Metadata/ContentDefinitionManagerTests.cs +++ b/src/Orchard.Core.Tests/Settings/Metadata/ContentDefinitionManagerTests.cs @@ -7,6 +7,7 @@ using Moq; using NHibernate; using NUnit.Framework; using Orchard.Caching; +using Orchard.ContentManagement; using Orchard.ContentManagement.MetaData; using Orchard.ContentManagement.MetaData.Builders; using Orchard.ContentManagement.MetaData.Models; @@ -204,6 +205,43 @@ namespace Orchard.Core.Tests.Settings.Metadata { Assert.That(manager.ListPartDefinitions().Count(), Is.EqualTo(3)); } + [Test] + public void PartsCanBeDeleted() { + var manager = _container.Resolve(); + manager.StoreTypeDefinition( + new ContentTypeDefinitionBuilder() + .Named("alpha") + .WithPart("foo", pb => { }) + .WithPart("bar", pb => { }) + .Build()); + + AssertThatTypeHasParts("alpha", "foo", "bar"); + Assert.That(manager.ListPartDefinitions().Count(), Is.EqualTo(2)); + + manager.DeletePartDefinition("foo"); + ResetSession(); + + AssertThatTypeHasParts("alpha", "bar"); + Assert.That(manager.ListPartDefinitions().Count(), Is.EqualTo(1)); + } + + [Test] + public void ContentTypesCanBeDeleted() { + var manager = _container.Resolve(); + manager.StoreTypeDefinition( + new ContentTypeDefinitionBuilder() + .Named("alpha") + .WithPart("foo", pb => { }) + .WithPart("bar", pb => { }) + .Build()); + + Assert.That(manager.GetTypeDefinition("alpha"), Is.Not.Null); + manager.DeleteTypeDefinition("alpha"); + ResetSession(); + + Assert.That(manager.GetTypeDefinition("alpha"), Is.Null); + } + private void AssertThatTypeHasParts(string typeName, params string[] partNames) { var type = _container.Resolve().GetTypeDefinition(typeName); Assert.That(type, Is.Not.Null); diff --git a/src/Orchard.Web/Core/Settings/Metadata/ContentDefinitionManager.cs b/src/Orchard.Web/Core/Settings/Metadata/ContentDefinitionManager.cs index f709eb4ef..7be131e76 100644 --- a/src/Orchard.Web/Core/Settings/Metadata/ContentDefinitionManager.cs +++ b/src/Orchard.Web/Core/Settings/Metadata/ContentDefinitionManager.cs @@ -83,6 +83,39 @@ namespace Orchard.Core.Settings.Metadata { Apply(contentPartDefinition, Acquire(contentPartDefinition)); } + public void DeleteTypeDefinition(string name) { + var record = _typeDefinitionRepository.Fetch(x => x.Name == name).SingleOrDefault(); + + // deletes the content type record associated + if (record != null) { + _typeDefinitionRepository.Delete(record); + } + + // invalidates the cache + TriggerContentDefinitionSignal(); + } + + public void DeletePartDefinition(string name) { + // remove parts from current types + var typesWithPart = ListTypeDefinitions().Where(typeDefinition => typeDefinition.Parts.Any(part => part.PartDefinition.Name == name)); + + foreach (var typeDefinition in typesWithPart) { + this.AlterTypeDefinition(typeDefinition.Name, builder => builder.RemovePart(name)); + } + + // delete part + var record = _partDefinitionRepository.Fetch(x => x.Name == name).SingleOrDefault(); + + if (record != null) { + _partDefinitionRepository.Delete(record); + } + + // invalidates the cache + TriggerContentDefinitionSignal(); + + } + + private void MonitorContentDefinitionSignal(AcquireContext ctx) { ctx.Monitor(_signals.When(ContentDefinitionSignal)); } diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/AdminMenu.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/AdminMenu.cs index 8f6f52e82..2010cae4c 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentTypes/AdminMenu.cs +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/AdminMenu.cs @@ -7,10 +7,13 @@ namespace Orchard.ContentTypes { public Localizer T { get; set; } public string MenuName { get { return "admin"; } } - public void GetNavigation(NavigationBuilder builder) { - + public void GetNavigation(NavigationBuilder builder) + { builder.Add(T("Content"), - menu => menu.Add(T("Content Types"), "3", item => item.Action("Index", "Admin", new { area = "Orchard.ContentTypes" }).LocalNav())); + menu => menu + .Add(T("Content Types"), "3", item => item.Action("Index", "Admin", new {area = "Orchard.ContentTypes"}).LocalNav()) + .Add(T("Content Parts"), "4", item => item.Action("ListParts", "Admin", new {area = "Orchard.ContentTypes"}).LocalNav())); + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Controllers/AdminController.cs index df8589a95..72cdf8ce3 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Controllers/AdminController.cs @@ -6,6 +6,7 @@ using Orchard.ContentManagement.MetaData; using Orchard.ContentManagement.MetaData.Models; using Orchard.ContentTypes.Services; using Orchard.ContentTypes.ViewModels; +using Orchard.Core.Contents.Controllers; using Orchard.Core.Contents.Settings; using Orchard.Localization; using Orchard.UI.Notify; @@ -97,6 +98,7 @@ namespace Orchard.ContentTypes.Controllers { } [HttpPost, ActionName("Edit")] + [FormValueRequired("submit.Save")] public ActionResult EditPOST(string id) { if (!Services.Authorizer.Authorize(Permissions.EditContentTypes, T("Not allowed to edit a content type."))) return new HttpUnauthorizedResult(); @@ -121,7 +123,6 @@ namespace Orchard.ContentTypes.Controllers { if (!ModelState.IsValid) return View(typeViewModel); - _contentDefinitionService.AlterType(typeViewModel, this); if (!ModelState.IsValid) { @@ -131,7 +132,32 @@ namespace Orchard.ContentTypes.Controllers { Services.Notifier.Information(T("\"{0}\" settings have been saved.", typeViewModel.DisplayName)); - return RedirectToAction("Index"); + return RedirectToAction("List"); + } + + + [HttpPost, ActionName("Edit")] + [FormValueRequired("submit.Delete")] + public ActionResult Delete(string id) { + if (!Services.Authorizer.Authorize(Permissions.EditContentTypes, T("Not allowed to delete a content type."))) + return new HttpUnauthorizedResult(); + + var typeViewModel = _contentDefinitionService.GetType(id); + + if (typeViewModel == null) + return HttpNotFound(); + + _contentDefinitionManager.DeleteTypeDefinition(id); + + // delete all content items (but keep versions) + var contentItems = Services.ContentManager.Query(id).List(); + foreach (var contentItem in contentItems) { + Services.ContentManager.Remove(contentItem); + } + + Services.Notifier.Information(T("\"{0}\" has been removed.", typeViewModel.DisplayName)); + + return RedirectToAction("List"); } public ActionResult AddPartsTo(string id) { @@ -273,6 +299,7 @@ namespace Orchard.ContentTypes.Controllers { } [HttpPost, ActionName("EditPart")] + [FormValueRequired("submit.Save")] public ActionResult EditPartPOST(string id) { if (!Services.Authorizer.Authorize(Permissions.EditContentTypes, T("Not allowed to edit a content part."))) return new HttpUnauthorizedResult(); @@ -297,6 +324,24 @@ namespace Orchard.ContentTypes.Controllers { return RedirectToAction("ListParts"); } + [HttpPost, ActionName("EditPart")] + [FormValueRequired("submit.Delete")] + public ActionResult DeletePart(string id) + { + if (!Services.Authorizer.Authorize(Permissions.EditContentTypes, T("Not allowed to delete a content part."))) + return new HttpUnauthorizedResult(); + + var partViewModel = _contentDefinitionService.GetPart(id); + + if (partViewModel == null) + return HttpNotFound(); + + _contentDefinitionManager.DeletePartDefinition(id); + Services.Notifier.Information(T("\"{0}\" has been removed.", partViewModel.DisplayName)); + + return RedirectToAction("ListParts"); + } + public ActionResult AddFieldTo(string id) { if (!Services.Authorizer.Authorize(Permissions.EditContentTypes, T("Not allowed to edit a content part."))) return new HttpUnauthorizedResult(); diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/Edit.cshtml b/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/Edit.cshtml index 8c496327d..b26d4ce0a 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/Edit.cshtml +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/Edit.cshtml @@ -5,7 +5,6 @@ Layout.Title = T("Edit Content Type").ToString(); } - @using (Html.BeginFormAntiForgeryPost()) { // todo: come up with real itemtype definitions and locations for said definitions
@@ -34,7 +33,8 @@ @Html.EditorFor(m => m.Parts, "TypeParts", "")
- + +
} diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/EditPart.cshtml b/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/EditPart.cshtml index d563df21d..470f6c49b 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/EditPart.cshtml +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/EditPart.cshtml @@ -5,7 +5,6 @@ Layout.Title = T("Edit Part").ToString(); } - @using (Html.BeginFormAntiForgeryPost()) { @Html.ValidationSummary()
@@ -23,7 +22,8 @@ @Html.EditorFor(m => m.Fields, "Fields", "")
- + +
} diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/List.cshtml b/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/List.cshtml index 5661070ea..bf80d408a 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/List.cshtml +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/List.cshtml @@ -6,7 +6,6 @@
@Html.ActionLink(T("Create new type").ToString(), "Create", new{Controller="Admin",Area="Orchard.ContentTypes"}, new { @class = "button primaryAction" }) - @Html.ActionLink(T("Content Parts").ToString(), "ListParts", new{Controller="Admin",Area="Orchard.ContentTypes"}, new { @class = "button" })
@Html.UnorderedList( Model.Types, diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/ListParts.cshtml b/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/ListParts.cshtml index 5aceeceb9..dbe1df815 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/ListParts.cshtml +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/ListParts.cshtml @@ -2,7 +2,6 @@ @{ Layout.Title = T("Content Parts").ToString(); } -
@Html.ActionLink(T("Create new part").ToString(), "CreatePart", new{Controller="Admin",Area="Orchard.ContentTypes"}, new { @class = "button primaryAction" })
diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/DisplayTemplates/EditPartViewModel.cshtml b/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/DisplayTemplates/EditPartViewModel.cshtml index e615b08a8..84c9319b2 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/DisplayTemplates/EditPartViewModel.cshtml +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/DisplayTemplates/EditPartViewModel.cshtml @@ -4,6 +4,6 @@

@Model.DisplayName

\ No newline at end of file diff --git a/src/Orchard/ContentManagement/MetaData/IContentDefinitionManager.cs b/src/Orchard/ContentManagement/MetaData/IContentDefinitionManager.cs index 80782163a..0f85f1761 100644 --- a/src/Orchard/ContentManagement/MetaData/IContentDefinitionManager.cs +++ b/src/Orchard/ContentManagement/MetaData/IContentDefinitionManager.cs @@ -12,6 +12,8 @@ namespace Orchard.ContentManagement.MetaData { ContentTypeDefinition GetTypeDefinition(string name); ContentPartDefinition GetPartDefinition(string name); + void DeleteTypeDefinition(string name); + void DeletePartDefinition(string name); void StoreTypeDefinition(ContentTypeDefinition contentTypeDefinition); void StorePartDefinition(ContentPartDefinition contentPartDefinition);