#20032: Adding a custom Form Submitted activity

Work Item: 20032
This commit is contained in:
Sebastien Ros
2013-08-20 15:07:33 -07:00
parent b95ce0cc7d
commit 936e790c95
11 changed files with 165 additions and 25 deletions

View File

@@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Orchard.Localization;
using Orchard.Workflows.Models;
using Orchard.Workflows.Services;
namespace Orchard.CustomForms.Activities {
public class FormSubmittedActivity : Event {
public const string EventName = "FormSubmitted";
public Localizer T { get; set; }
public override bool CanStartWorkflow {
get { return true; }
}
public override bool CanExecute(WorkflowContext workflowContext, ActivityContext activityContext) {
try {
var contentTypesState = activityContext.GetState<string>("ContentTypes");
// "" means 'any'
if (String.IsNullOrEmpty(contentTypesState)) {
return true;
}
string[] contentTypes = contentTypesState.Split(',');
var content = workflowContext.Content;
if (content == null) {
return false;
}
return contentTypes.Any(contentType => content.ContentItem.TypeDefinition.Name == contentType);
}
catch {
return false;
}
}
public override IEnumerable<LocalizedString> GetPossibleOutcomes(WorkflowContext workflowContext, ActivityContext activityContext) {
return new[] { T("Done") };
}
public override IEnumerable<LocalizedString> Execute(WorkflowContext workflowContext, ActivityContext activityContext) {
yield return T("Done");
}
public override string Form {
get {
return "SelectCustomForms";
}
}
public override string Name {
get { return EventName; }
}
public override LocalizedString Category {
get { return T("Content Items"); }
}
public override LocalizedString Description {
get { return T("A custom form is submitted."); }
}
}
}

View File

@@ -0,0 +1,53 @@
using System;
using System.Linq;
using System.Web.Mvc;
using Orchard.ContentManagement;
using Orchard.DisplayManagement;
using Orchard.Forms.Services;
using Orchard.Localization;
namespace Orchard.CustomForms.Activities {
public class SelectCustomForm : IFormProvider {
private readonly IContentManager _contentManager;
protected dynamic Shape { get; set; }
public Localizer T { get; set; }
public SelectCustomForm(IShapeFactory shapeFactory, IContentManager contentManager) {
_contentManager = contentManager;
Shape = shapeFactory;
T = NullLocalizer.Instance;
}
public void Describe(DescribeContext context) {
Func<IShapeFactory, dynamic> form =
shape => {
var f = Shape.Form(
Id: "AnyOfCustomForms",
_Parts: Shape.SelectList(
Id: "customforms", Name: "CustomForms",
Title: T("Content types"),
Description: T("Select some content types."),
Size: 10,
Multiple: true
)
);
f._Parts.Add(new SelectListItem { Value = "", Text = T("Any").Text });
var query = _contentManager.Query().ForType("CustomForm", "CustomFormWidget");
var customForms = query.List().Select(x => new { ContentItem = x, Metadata = _contentManager.GetItemMetadata(x)});
foreach (var customForm in customForms.OrderBy(x => x.Metadata.DisplayText)) {
f._Parts.Add(new SelectListItem { Value = customForm.Metadata.Identity.ToString(), Text = customForm.Metadata.DisplayText });
}
return f;
};
context.Form("SelectCustomForms", form);
}
}
}

View File

@@ -8,7 +8,9 @@ namespace Orchard.CustomForms {
public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) {
builder.Add(T("Forms"), "4",
builder
.AddImageSet("customforms")
.Add(T("Custom Forms"), "4",
menu => menu
.Add(T("Manage Forms"), "1.0",
item => item.Action("Index", "Admin", new { area = "Orchard.CustomForms" }).Permission(Permissions.ManageForms))

View File

@@ -4,14 +4,11 @@ using System.Web.Mvc;
using System.Web.Routing;
using Orchard.ContentManagement;
using Orchard.Core.Common.Models;
using Orchard.Core.Title.Models;
using Orchard.CustomForms.Models;
using Orchard.CustomForms.ViewModels;
using Orchard.DisplayManagement;
using Orchard.Localization;
using Orchard.Mvc;
using Orchard.Security;
using System;
using Orchard.Settings;
using Orchard.UI.Navigation;

View File

@@ -6,6 +6,7 @@ using System.Web.Mvc;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Aspects;
using Orchard.Core.Contents.Settings;
using Orchard.CustomForms.Activities;
using Orchard.CustomForms.Models;
using Orchard.CustomForms.Rules;
using Orchard.Data;
@@ -17,6 +18,7 @@ using Orchard.Mvc.Extensions;
using Orchard.Themes;
using Orchard.Tokens;
using Orchard.UI.Notify;
using Orchard.Workflows.Services;
namespace Orchard.CustomForms.Controllers {
[Themed(true)]
@@ -26,6 +28,7 @@ namespace Orchard.CustomForms.Controllers {
private readonly ITransactionManager _transactionManager;
private readonly IRulesManager _rulesManager;
private readonly ITokenizer _tokenizer;
private readonly IWorkflowManager _workflowManager;
public ItemController(
IOrchardServices orchardServices,
@@ -33,12 +36,14 @@ namespace Orchard.CustomForms.Controllers {
ITransactionManager transactionManager,
IShapeFactory shapeFactory,
IRulesManager rulesManager,
ITokenizer tokenizer) {
ITokenizer tokenizer,
IWorkflowManager workflowManager) {
Services = orchardServices;
_contentManager = contentManager;
_transactionManager = transactionManager;
_rulesManager = rulesManager;
_tokenizer = tokenizer;
_workflowManager = workflowManager;
T = NullLocalizer.Instance;
Logger = NullLogger.Instance;
Shape = shapeFactory;
@@ -151,6 +156,10 @@ namespace Orchard.CustomForms.Controllers {
_rulesManager.TriggerEvent("CustomForm", "Submitted",
() => new Dictionary<string, object> { { "Content", contentItem } });
// trigger any workflow
_workflowManager.TriggerEvent(FormSubmittedActivity.EventName, contentItem,
() => new Dictionary<string, object> { { "Content", contentItem } });
if (customForm.Redirect) {
returnUrl = _tokenizer.Replace(customForm.RedirectUrl, new Dictionary<string, object> { { "Content", contentItem } });
}

View File

@@ -10,4 +10,4 @@ Features:
Name: Custom Forms
Description: Create custom forms like contact forms or content contributions.
Category: Forms
Dependencies: Contents, Orchard.Tokens
Dependencies: Contents, Orchard.Tokens, Orchard.Workflows

View File

@@ -65,10 +65,15 @@
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
<Content Include="Styles\images\menu.customforms.png" />
<Content Include="Styles\menu.customforms-admin.css" />
<Content Include="Styles\workflows-activity-form-submitted.css" />
<Content Include="Web.config" />
<Content Include="Views\Web.config" />
<Content Include="Scripts\Web.config" />
<Content Include="Styles\Web.config" />
<Compile Include="Activities\SelectCustomForm.cs" />
<Compile Include="Activities\FormSubmittedActivity.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Content Include="Module.txt" />
</ItemGroup>
@@ -81,10 +86,18 @@
<Project>{9916839C-39FC-4CEB-A5AF-89CA7E87119F}</Project>
<Name>Orchard.Core</Name>
</ProjectReference>
<ProjectReference Include="..\Orchard.Forms\Orchard.Forms.csproj">
<Project>{642a49d7-8752-4177-80d6-bfbbcfad3de0}</Project>
<Name>Orchard.Forms</Name>
</ProjectReference>
<ProjectReference Include="..\Orchard.Tokens\Orchard.Tokens.csproj">
<Project>{6F759635-13D7-4E94-BCC9-80445D63F117}</Project>
<Name>Orchard.Tokens</Name>
</ProjectReference>
<ProjectReference Include="..\Orchard.Workflows\Orchard.Workflows.csproj">
<Project>{7059493c-8251-4764-9c1e-2368b8b485bc}</Project>
<Name>Orchard.Workflows</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Compile Include="AdminMenu.cs" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 B

View File

@@ -0,0 +1,6 @@
.navicon-custom-forms {
background-image:url(images/menu.customforms.png) !important;
}
.navicon-custom-forms:hover {
background-position:0 -30px !important;
}

View File

@@ -6,7 +6,6 @@ using Orchard.Workflows.Services;
namespace Orchard.Workflows.Handlers {
public class WorkflowContentHandler : ContentHandler {
private readonly HashSet<int> _contentCreated = new HashSet<int>();
public WorkflowContentHandler(IWorkflowManager workflowManager) {
@@ -28,26 +27,15 @@ namespace Orchard.Workflows.Handlers {
context.BuildingContentItem,
() => new Dictionary<string, object> { { "Content", context.BuildingContentItem } }));
OnUpdated<ContentPart>(
(context, part) => {
workflowManager.TriggerEvent("ContentUpdated",
context.ContentItem,
() => new Dictionary<string, object> { { "Content", context.ContentItem } });
// Trigger the ContentCreated event only when its values have been updated
if(_contentCreated.Contains(context.ContentItem.Id)) {
workflowManager.TriggerEvent("ContentCreated",
context.ContentItem,
() => new Dictionary<string, object> {{"Content", context.ContentItem}});
}
});
OnCreated<ContentPart>(
// Flag the content item as "just created" but actually trigger the event
// when its content has been updated as it is what users would expect.
(context, part) => _contentCreated.Add(context.ContentItem.Id)
);
(context, part) =>
workflowManager.TriggerEvent("ContentCreated", context.ContentItem,
() => new Dictionary<string, object> { { "Content", context.ContentItem } }));
OnUpdated<ContentPart>(
(context, part) =>
workflowManager.TriggerEvent("ContentUpdated", context.ContentItem,
() => new Dictionary<string, object> { { "Content", context.ContentItem } }));
}
}
}