Adding content item clone functionality as per the Communit Meeting of 12 February

--HG--
branch : 1.x
This commit is contained in:
Zoltán Lehóczky
2013-04-13 23:18:56 +02:00
parent d773ce8c0a
commit 4d4c6af662
5 changed files with 50 additions and 12 deletions

View File

@@ -68,7 +68,7 @@ namespace Orchard.Core.Contents.Controllers {
: contentTypeDefinition.Name;
query = query.ForType(model.TypeName);
}
switch (model.Options.OrderBy) {
case ContentsOrder.Modified:
//query = query.OrderByDescending<ContentPartRecord, int>(ci => ci.ContentItemRecord.Versions.Single(civr => civr.Latest).Id);
@@ -105,7 +105,7 @@ namespace Orchard.Core.Contents.Controllers {
}
private IEnumerable<ContentTypeDefinition> GetCreatableTypes(bool andContainable) {
return _contentDefinitionManager.ListTypeDefinitions().Where(ctd => ctd.Settings.GetModel<ContentTypeSettings>().Creatable && (!andContainable || ctd.Parts.Any(p => p.PartDefinition.Name == "ContainablePart")) );
return _contentDefinitionManager.ListTypeDefinitions().Where(ctd => ctd.Settings.GetModel<ContentTypeSettings>().Creatable && (!andContainable || ctd.Parts.Any(p => p.PartDefinition.Name == "ContainablePart")));
}
[HttpPost, ActionName("List")]
@@ -124,7 +124,7 @@ namespace Orchard.Core.Contents.Controllers {
return RedirectToAction("List", routeValues);
}
[HttpPost, ActionName("List")]
[FormValueRequired("submit.BulkEdit")]
public ActionResult ListPOST(ContentOptions options, IEnumerable<int> itemIds, string returnUrl) {
@@ -214,7 +214,7 @@ namespace Orchard.Core.Contents.Controllers {
[HttpPost, ActionName("Create")]
[FormValueRequired("submit.Publish")]
public ActionResult CreateAndPublishPOST(string id, string returnUrl) {
// pass a dummy content to the authorization check to check for "own" variations
var dummyContent = _contentManager.New(id);
@@ -298,11 +298,11 @@ namespace Orchard.Core.Contents.Controllers {
return new HttpUnauthorizedResult();
string previousRoute = null;
if(contentItem.Has<IAliasAspect>()
&&!string.IsNullOrWhiteSpace(returnUrl)
if (contentItem.Has<IAliasAspect>()
&& !string.IsNullOrWhiteSpace(returnUrl)
&& Request.IsLocalUrl(returnUrl)
// only if the original returnUrl is the content itself
&& String.Equals(returnUrl, Url.ItemDisplayUrl(contentItem), StringComparison.OrdinalIgnoreCase)
&& String.Equals(returnUrl, Url.ItemDisplayUrl(contentItem), StringComparison.OrdinalIgnoreCase)
) {
previousRoute = contentItem.As<IAliasAspect>().Path;
}
@@ -316,12 +316,12 @@ namespace Orchard.Core.Contents.Controllers {
conditionallyPublish(contentItem);
if (!string.IsNullOrWhiteSpace(returnUrl)
&& previousRoute != null
if (!string.IsNullOrWhiteSpace(returnUrl)
&& previousRoute != null
&& !String.Equals(contentItem.As<IAliasAspect>().Path, previousRoute, StringComparison.OrdinalIgnoreCase)) {
returnUrl = Url.ItemDisplayUrl(contentItem);
}
Services.Notifier.Information(string.IsNullOrWhiteSpace(contentItem.TypeDefinition.DisplayName)
? T("Your content has been saved.")
: T("Your {0} has been saved.", contentItem.TypeDefinition.DisplayName));
@@ -329,6 +329,35 @@ namespace Orchard.Core.Contents.Controllers {
return this.RedirectLocal(returnUrl, () => RedirectToAction("Edit", new RouteValueDictionary { { "Id", contentItem.Id } }));
}
[HttpPost]
public ActionResult Clone(int id, string returnUrl) {
// Mostly taken from: http://orchard.codeplex.com/discussions/396664
var contentItem = _contentManager.GetLatest(id);
if (contentItem == null)
return HttpNotFound();
if (!Services.Authorizer.Authorize(Permissions.EditContent, contentItem, T("Couldn't clone content")))
return new HttpUnauthorizedResult();
var importContentSession = new ImportContentSession(_contentManager);
var element = _contentManager.Export(contentItem);
var elementId = element.Attribute("Id");
var copyId = elementId.Value + "-copy";
elementId.SetValue(copyId);
var status = element.Attribute("Status");
if (status != null) status.SetValue("Draft"); // So the copy is always a draft.
importContentSession.Set(copyId, element.Name.LocalName);
_contentManager.Import(element, importContentSession);
Services.Notifier.Information(T("Successfully cloned. The clone was saved as a draft."));
return this.RedirectLocal(returnUrl, () => RedirectToAction("List"));
}
[HttpPost]
public ActionResult Remove(int id, string returnUrl) {
var contentItem = _contentManager.Get(id, VersionOptions.Latest);

View File

@@ -12,7 +12,9 @@ namespace Orchard.Core.Contents.Drivers {
ContentShape("Parts_Contents_Publish_Summary",
() => shapeHelper.Parts_Contents_Publish_Summary()),
ContentShape("Parts_Contents_Publish_SummaryAdmin",
() => shapeHelper.Parts_Contents_Publish_SummaryAdmin())
() => shapeHelper.Parts_Contents_Publish_SummaryAdmin()),
ContentShape("Parts_Contents_Clone_SummaryAdmin",
() => shapeHelper.Parts_Contents_Clone_SummaryAdmin())
);
}

View File

@@ -12,6 +12,7 @@
<Place Parts_Contents_Publish="Content:5"/>
</Match>
<Match DisplayType="SummaryAdmin">
<Place Parts_Contents_Publish_SummaryAdmin="Actions:5"/>
<Place Parts_Contents_Publish_SummaryAdmin="Actions:5"
Parts_Contents_Clone_SummaryAdmin="Actions:6"/>
</Match>
</Placement>

View File

@@ -0,0 +1,3 @@
@using Orchard.Utility.Extensions;
<a href="@Url.Action("Clone", "Admin", new { Id = Model.ContentItem.Id, ReturnUrl = Request.ToUrlString(), Area = "Contents" })" itemprop="UnsafeUrl">@T("Clone")</a>@T(" | ")

View File

@@ -547,6 +547,9 @@
<ItemGroup>
<Content Include="Navigation\Views\MenuItemLink-ShapeMenuItem.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Contents\Views\Parts.Contents.Clone.SummaryAdmin.cshtml" />
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>