My Cart (0)  |  My Orders  |  My Downloads  |  My Auction  |  My Account  |  Help


Login |Register        Search

Implementing DNN 7.4 Workflow

                Print      Add To Favorite     Add To Watch List     Contact Author

Creator: host   12/21/2015 10:30:07 AM    Author: Scott Wilkinson   Source: http://www.dnnsoftware.com/community-blog/cid/155185/implementing-workflow-in-a-custom-dnn-module   Views: 2156    0    0  
Tags:
Workflow dnn 7 Module develop

Introduction

DNN introduced the Workflow API in version 7.4 which allows custom modules to leverage the core workflow processes in their custom module.  You can watch the overview of the 7.4 features here.  Big thanks to Francesco Rivola and Xepient Solutions for their work in this feature.  I finished a code project and training tutorial for DNNHero.com on this topic.  I created a module project from the ChrisHammond DAL2 C# template using the sample code in the template and layered on a complete workflow process.  This project is only available to Premium DNNHero subscribers at the moment.  If you’re planning on dealing with this topic, I recommend reading further and subscribing.

What is Workflow?

Workflow allows you to create a publishing flow that provides an approval process between when a user creates the content and when the content becomes live.  DNN has built a few different workflow processes for the HTML and File Manager modules.  Now that release 7.4 is out, third-party module developers can tap into the same workflow mechanism and definitions.  Content workflow in a DNN module, when done right, has the following attributes:

  • Review & Approve Content
  • Different workflow processes can be chosen or defined
  • Notifications to appropriate users
  • Versioning and Rollback capability

Setup work for Workflow

The first thing you need to know about using the Workflow API is that it works inherently with Content Items.  My suggestion is to use the Content Items API as a storage mechanism for your versioned content (more on this later).  To do this, you need to create a content item type for your custom versioned content.  You also need to register your 5 workflow action classes as per Francesco’s instructions in the introduction video.  To do this, I suggest implementing IUpgradeable in your module in order to perform these one-time actions.
string IUpgradeable.UpgradeModule(string Version) { WorkflowActionManager _workflowActionManager = new WorkflowActionManager(); var message = String.Format("DotNetNuclear Workflow Upgradeable actions for version {0}.)", Version); switch (Version) { case "00.00.01": // Register content type id necessary for participating in the workflow api int contentTypeId = Integration.Content.Instance.AddContentType(Common.Constants.CONTENTTYPENAME); message += "Added content type for workflow. " + Environment.NewLine; // Register 5 workflow actions: StartWorkflow, CompleteWorkflow, DiscardWorkflow, DiscardState, CompleteState _workflowActionManager.RegisterWorkflowAction(new WorkflowAction { ContentTypeId = contentTypeId, ActionType = WorkflowActionTypes.StartWorkflow.ToString(), ActionSource = typeof(WorkflowStartAction).AssemblyQualifiedName }); _workflowActionManager.RegisterWorkflowAction(new WorkflowAction { ContentTypeId = contentTypeId, ActionType = WorkflowActionTypes.CompleteWorkflow.ToString(), ActionSource = typeof(WorkflowCompleteAction).AssemblyQualifiedName }); _workflowActionManager.RegisterWorkflowAction(new WorkflowAction { ContentTypeId = contentTypeId, ActionType = WorkflowActionTypes.DiscardWorkflow.ToString(), ActionSource = typeof(WorkflowDiscardAction).AssemblyQualifiedName }); _workflowActionManager.RegisterWorkflowAction(new WorkflowAction { ContentTypeId = contentTypeId, ActionType = WorkflowActionTypes.DiscardState.ToString(), ActionSource = typeof(StateDiscardAction).AssemblyQualifiedName }); _workflowActionManager.RegisterWorkflowAction(new WorkflowAction { ContentTypeId = contentTypeId, ActionType = WorkflowActionTypes.CompleteState.ToString(), ActionSource = typeof(StateCompleteAction).AssemblyQualifiedName }); message += "Added workflow actions. " + Environment.NewLine; break; } return message; } 

The other thing we need to setup is a module setting for allowing the administrator to select the workflow they want to implement. These workflows are defined in the DNN core. Here is a screenshot of the module setting I added.


To get the list of workflows defined in the current portal, I use the following code:

WorkflowManager _workflowManager = new DotNetNuke.Entities.Content.Workflow. WorkflowManager(); var workflows = _workflowManager.GetWorkflows(PortalId).Select(w => new { WorkflowID = w.WorkflowID, WorkflowName = w.WorkflowName }); 

Versioning and Workflow

The basis for how I do versioning is as follows: I create my main “Item” which is my module’s domain object. This would be equivalent to an “Article” or “HTML” entity in other publishing modules. I use the DAL2 data layer to persist my object which is the same code created by the template. At the same time, I use the Content Items API in DNN to create my versioned items. The content field of the versioned item is a json-serialized version of my Item entity class. I also use the DAL2 Item ID (primary key) as the Content Key of the Content Item to relate back to the main Item. This approach has the advantage of not adding overhead to the “reads” of our main Item repository – we only need to read from the DAL2 controller to get the main items. Version items (content items) are only needed in the editing process.

Create New “Item”


When you save an item, this is the flow that should happen. You need to create the DAL2 item and then create the versioned content item with the Item ID as its Content Key. Then you will send that versioned content item into the workflow process.

WorkflowEngine _workflowEngine = new WorkflowEngine(); _workflowEngine.StartWorkflow(workflowId, contentItem.ContentItemId, PortalSettings.Current.UserId); 

The workflow ID in the StartWorkflow parameters comes from the module setting the user has selected as the desired workflow. The content Item ID comes from your versioned content item.

Update an “Item”


Updating an item is not much different than the create process. You don’t need to do anything to the main item, just create the versioned item and send it to the workflow process

Workflow State Actions

So how do we control what happens when we start the workflow? Remember the IUpgradeable method? Those action state classes that we registered will get called by the framework when users interact with the workflow items from the Notifications area of the User Messaging page. Here is a sample flow:

Create new item and start workflow using Content Approval workflow.

  1. My WorkflowStartAction’s DoActionOnStateChanging() is fired (no action)
  2. My WorkflowStartAction’s DoActionOnStateChanged() is fired (no action)
  3. My WorkflowStartAction’s GetActionMessage() is fired (produce message content)
  4. A Notification is sent to the appropriate user (if Content Approval, then it is the content creator to Submit for review). The subject and body of this message is defined in the GetActionMessage() return.
  5. Creator user gets Notification message with action links for Submit and Discard. User clicks the Submit link.
  6. My StateCompleteAction’s DoActionOnStateChanging() is fired (no action)
  7. My StateCompleteAction’s DoActionOnStateChanged () is fired (no action)
  8. My StateCompleteAction’s GetActionMessage() is fired (produce message content)
  9. A Notification is sent to the appropriate users with the action links to Approve or Discard the content. The review clicks Approve link.
  10. My WorkflowCompleteAction’s DoActionOnStateChanging() is fired (no action)
  11. My WorkflowCompleteAction’s DoActionOnStateChanged () is fired. Here I have code that will take the content item from the workflow, deserialize it, update the main content item, and set the main content item to active.

Version History

The Workflow API doesn't help us with showing users the version history. We need to handle this. I created a simple module view that lays out all content items related to the main item and provides some viewing and workflow actions.  In this screenshot you can see I added a Version History button to the main module view.  When clicked it takes you to the History module view.


The version History view shows the versions associated with the main item.  The bold indicates the versioned item that matches the main item (current).  You can delete, view, and move the item to the next state, where applicable.

Next Steps

Get the code and watch the full tutorial on DNNHero.com.  If you are a subscribing member, you get access to the Premium Forums, many other advanced module development tutorials and code projects, and over a hundred hours of other administration videos and how to’s.


Rating People: 0   Average Rating:     

     DnnModule.com is built to provide DNN quality modules and DNN skins, some of them are free, some not. We wish these stuffs (free or not ) can be useful to you.

     Besides that, we also provide a full range of professional services, ranging from web site build, seo, system management, administration, support, senior consultancy and security services. We act as if your development project or network was ours, with care and respect. We are not satisfied until it works the way you want it to, and we don't silently ignore found issues as somebody else's problem.