Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cloning feature with fallback for 1.10.x #7409

Open
wants to merge 4 commits into
base: 1.10.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/Orchard.Web/Core/Common/Drivers/BodyPartDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Orchard.Services;
using System.Web.Mvc;
using System.Web.Routing;
using Orchard.ContentManagement.Handlers;

namespace Orchard.Core.Common.Drivers {
public class BodyPartDriver : ContentPartDriver<BodyPart> {
Expand Down Expand Up @@ -75,6 +76,10 @@ protected override void Exporting(BodyPart part, ContentManagement.Handlers.Expo
context.Element(part.PartDefinition.Name).SetAttributeValue("Text", part.Text);
}

protected override void Cloning(BodyPart originalPart, BodyPart clonePart, CloneContentContext context) {
clonePart.Text = originalPart.Text;
}

private static BodyEditorViewModel BuildEditorViewModel(BodyPart part,RequestContext requestContext) {
return new BodyEditorViewModel {
BodyPart = part,
Expand Down
4 changes: 4 additions & 0 deletions src/Orchard.Web/Core/Common/Drivers/CommonPartDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,5 +123,9 @@ protected override void Exporting(CommonPart part, ExportContentContext context)
.SetAttributeValue("ModifiedUtc", XmlConvert.ToString(part.ModifiedUtc.Value, XmlDateTimeSerializationMode.Utc));
}
}

protected override void Cloning(CommonPart originalPart, CommonPart clonePart, CloneContentContext context) {
clonePart.Container = originalPart.Container;
}
}
}
4 changes: 4 additions & 0 deletions src/Orchard.Web/Core/Common/Drivers/TextFieldDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ protected override void Exporting(ContentPart part, TextField field, ExportConte
context.Element(field.FieldDefinition.Name + "." + field.Name).SetAttributeValue("Text", field.Value);
}

protected override void Cloning(ContentPart part, TextField originalField, TextField cloneField, CloneContentContext context) {
cloneField.Value = originalField.Value;
}

protected override void Describe(DescribeMembersContext context) {
context
.Member(null, typeof(string), T("Value"), T("The text associated with the field."))
Expand Down
30 changes: 16 additions & 14 deletions src/Orchard.Web/Core/Contents/Controllers/AdminController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,11 @@ public ActionResult List(ListContentsViewModel model, PagerParameters pagerParam
break;
}

if(!String.IsNullOrWhiteSpace(model.Options.SelectedCulture)) {
if (!String.IsNullOrWhiteSpace(model.Options.SelectedCulture)) {
query = _cultureFilter.FilterCulture(query, model.Options.SelectedCulture);
}

if(model.Options.ContentsStatus == ContentsStatus.Owner) {
if (model.Options.ContentsStatus == ContentsStatus.Owner) {
query = query.Where<CommonPartRecord>(cr => cr.OwnerId == Services.WorkContext.CurrentUser.Id);
}

Expand Down Expand Up @@ -388,25 +388,27 @@ private ActionResult EditPOST(int id, string returnUrl, Action<ContentItem> cond

[HttpPost]
public ActionResult Clone(int id, string returnUrl) {
var contentItem = _contentManager.GetLatest(id);
var originalContentItem = _contentManager.GetLatest(id);

if (contentItem == null)
return HttpNotFound();
if (!Services.Authorizer.Authorize(Permissions.ViewContent, originalContentItem, T("Couldn't open original content")))
return new HttpUnauthorizedResult();

// pass a dummy content to the authorization check to check for "own" variations
var dummyContent = _contentManager.New(originalContentItem.ContentType);

if (!Services.Authorizer.Authorize(Permissions.EditContent, contentItem, T("Couldn't clone content")))
if (!Services.Authorizer.Authorize(Permissions.EditContent, dummyContent, T("Couldn't create clone content")))
return new HttpUnauthorizedResult();

try {
Services.ContentManager.Clone(contentItem);
var cloneContentItem = _contentManager.Clone(originalContentItem);

Services.Notifier.Information(T("Successfully cloned. The clone was saved as a draft."));
if (string.IsNullOrWhiteSpace(returnUrl)) {
var adminRouteValues = _contentManager.GetItemMetadata(cloneContentItem).AdminRouteValues;
return RedirectToRoute(adminRouteValues);
}
catch (InvalidOperationException) {
Services.Notifier.Warning(T("Could not clone the content item."));
else {
return this.RedirectLocal(returnUrl, () => RedirectToAction("List"));
}

Services.Notifier.Information(T("Successfully cloned. The clone was saved as a draft."));

return this.RedirectLocal(returnUrl, () => RedirectToAction("List"));
}

[HttpPost]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
@using Orchard.ContentManagement
@using Orchard.Core.Contents
@using Orchard.Utility.Extensions
@{
ContentPart contentPart = Model.ContentPart;
}
@if (Authorizer.Authorize(Permissions.EditContent, contentPart)) {
<a href="@Url.Action("Clone", "Admin", new { Id = Model.ContentItem.Id, ReturnUrl = Request.ToUrlString(), Area = "Contents" })" itemprop="UnsafeUrl">@T("Clone")</a>
<a href="@Url.Action("Clone", "Admin", new { Id = Model.ContentItem.Id, Area = "Contents" })" itemprop="UnsafeUrl">@T("Clone")</a>
@T(" | ")
}
4 changes: 4 additions & 0 deletions src/Orchard.Web/Core/Title/Drivers/TitlePartDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,9 @@ protected override void Importing(TitlePart part, ImportContentContext context)
protected override void Exporting(TitlePart part, ExportContentContext context) {
context.Element(part.PartDefinition.Name).SetAttributeValue("Title", part.Title);
}

protected override void Cloning(TitlePart originalPart, TitlePart clonePart, CloneContentContext context) {
clonePart.Title = originalPart.Title;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -177,5 +177,7 @@ protected override void Exporting(AutoroutePart part, ExportContentContext conte
context.Element(part.PartDefinition.Name).SetAttributeValue("UseCulturePattern", part.Record.UseCulturePattern);
context.Element(part.PartDefinition.Name).SetAttributeValue("PromoteToHomePage", part.PromoteToHomePage);
}

protected override void Cloning(AutoroutePart originalPart, AutoroutePart clonePart, CloneContentContext context) { }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Orchard.Comments.Settings;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using Orchard.ContentManagement.Handlers;
using System.Collections.Generic;

namespace Orchard.Comments.Drivers {
Expand Down Expand Up @@ -97,7 +98,7 @@ protected override DriverResult Editor(CommentsPart part, dynamic shapeHelper) {
return ContentShape("Parts_Comments_Enable",
() => {
// if the part is new, then apply threaded comments defaults
if(!part.ContentItem.HasDraft() && !part.ContentItem.HasPublished()) {
if (!part.ContentItem.HasDraft() && !part.ContentItem.HasPublished()) {
var settings = part.TypePartDefinition.Settings.GetModel<CommentsPartSettings>();
part.ThreadedComments = settings.DefaultThreadedComments;
}
Expand All @@ -110,7 +111,7 @@ protected override DriverResult Editor(CommentsPart part, IUpdateModel updater,
return Editor(part, shapeHelper);
}

protected override void Importing(CommentsPart part, ContentManagement.Handlers.ImportContentContext context) {
protected override void Importing(CommentsPart part, ImportContentContext context) {
// Don't do anything if the tag is not specified.
if (context.Data.Element(part.PartDefinition.Name) == null) {
return;
Expand All @@ -129,10 +130,16 @@ protected override void Importing(CommentsPart part, ContentManagement.Handlers.
);
}

protected override void Exporting(CommentsPart part, ContentManagement.Handlers.ExportContentContext context) {
protected override void Exporting(CommentsPart part, ExportContentContext context) {
context.Element(part.PartDefinition.Name).SetAttributeValue("CommentsShown", part.CommentsShown);
context.Element(part.PartDefinition.Name).SetAttributeValue("CommentsActive", part.CommentsActive);
context.Element(part.PartDefinition.Name).SetAttributeValue("ThreadedComments", part.ThreadedComments);
}

protected override void Cloning(CommentsPart originalPart, CommentsPart clonePart, CloneContentContext context) {
clonePart.CommentsShown = originalPart.CommentsShown;
clonePart.CommentsActive = originalPart.CommentsActive;
// ThreadedComments will be overrided with settings default
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Orchard.Core.Contents.ViewModels;
using Orchard.DisplayManagement;
using Orchard.Localization;
using Orchard.Localization.Services;
using Orchard.Mvc;
using Orchard.Settings;
using Orchard.Themes;
Expand All @@ -22,16 +23,22 @@ public class AdminController : Controller {
private readonly ISiteService _siteService;
private readonly IContentDefinitionManager _contentDefinitionManager;
private readonly INavigationManager _navigationManager;
private readonly ICultureManager _cultureManager;
private readonly ICultureFilter _cultureFilter;

public AdminController(
IOrchardServices orchardServices,
ISiteService siteService,
IContentDefinitionManager contentDefinitionManager,
INavigationManager navigationManager) {
INavigationManager navigationManager,
ICultureManager cultureManager,
ICultureFilter cultureFilter) {
_siteService = siteService;
_contentDefinitionManager = contentDefinitionManager;
_navigationManager = navigationManager;
Services = orchardServices;
_cultureManager = cultureManager;
_cultureFilter = cultureFilter;

T = NullLocalizer.Instance;
}
Expand Down Expand Up @@ -123,10 +130,16 @@ public ActionResult Index(ListContentsViewModel model, PagerParameters pagerPara
break;
}

if (!String.IsNullOrWhiteSpace(model.Options.SelectedCulture)) {
query = _cultureFilter.FilterCulture(query, model.Options.SelectedCulture);
}

model.Options.FilterOptions = contentTypes
.Select(ctd => new KeyValuePair<string, string>(ctd.Name, ctd.DisplayName))
.ToList().OrderBy(kvp => kvp.Value);

model.Options.Cultures = _cultureManager.ListCultures();

var pagerShape = Services.New.Pager(pager).TotalItemCount(query.Count());
var pageOfContentItems = query.Slice(pager.GetStartIndex(), pager.PageSize).ToList();
var list = Services.New.List();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Orchard.ContentPicker.ViewModels;
using Orchard.Localization;
using Orchard.Utility.Extensions;
using Orchard.ContentPicker.Fields;

namespace Orchard.ContentPicker.Drivers {
public class ContentPickerFieldDriver : ContentFieldDriver<Fields.ContentPickerField> {
Expand Down Expand Up @@ -98,6 +99,10 @@ protected override void Exporting(ContentPart part, Fields.ContentPickerField fi
}
}

protected override void Cloning(ContentPart part, ContentPickerField originalField, ContentPickerField cloneField, CloneContentContext context) {
cloneField.Ids = originalField.Ids;
}

protected override void Describe(DescribeMembersContext context) {
context
.Member(null, typeof(string), T("Ids"), T("A formatted list of the ids, e.g., {1},{42}"));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System.Linq;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using Orchard.ContentPicker.Fields;
using Orchard.ContentPicker.ViewModels;
using Orchard.Environment.Extensions;

namespace Orchard.ContentPicker.Drivers {
[OrchardFeature("Orchard.ContentPicker.LocalizationExtensions")]
public class ContentPickerFieldLocalizationDriver : ContentFieldDriver<Fields.ContentPickerField> {
private readonly IContentManager _contentManager;

public ContentPickerFieldLocalizationDriver(IContentManager contentManager) {
_contentManager = contentManager;
}

private static string GetPrefix(Fields.ContentPickerField field, ContentPart part) {
return part.PartDefinition.Name + "." + field.Name;
}

private static string GetDifferentiator(Fields.ContentPickerField field, ContentPart part) {
return field.Name;
}

protected override DriverResult Editor(ContentPart part, Fields.ContentPickerField field, dynamic shapeHelper) {
return ContentShape("Fields_ContentPickerLocalization_Edit", GetDifferentiator(field, part),
() => {
var model = new ContentPickerFieldViewModel {
Field = field,
Part = part,
ContentItems = _contentManager.GetMany<ContentItem>(field.Ids, VersionOptions.Latest, QueryHints.Empty).ToList()
};

model.SelectedIds = string.Join(",", field.Ids);

return shapeHelper.EditorTemplate(TemplateName: "Fields/ContentPickerLocalization.Edit", Model: model, Prefix: GetPrefix(field, part));
});
}

protected override DriverResult Editor(ContentPart part, ContentPickerField field, IUpdateModel updater, dynamic shapeHelper) {
return Editor(part, field, shapeHelper);
}
}
}
Loading