Created
November 20, 2013 20:27
-
-
Save rcurlette/7570425 to your computer and use it in GitHub Desktop.
Tridion Workflow Helpers using Core Service
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Web; | |
using FlowPub.Model; | |
using Tridion.ContentManager.CoreService.Client; | |
using System.Configuration; | |
namespace FlowPub.Tridion | |
{ | |
public class WorkflowHelper | |
{ | |
private readonly string _binding = ConfigurationManager.AppSettings["PreferredCoreServiceBinding"]; | |
/// <summary> | |
/// Get the Users in a Group | |
/// </summary> | |
/// <param name="nextGroupAssigneeUri">Tridion Group URI</param> | |
/// <returns>List of users in the group</returns> | |
public List<User> GetUsersInGroup(string nextGroupAssigneeUri) | |
{ | |
List<User> usersInGroup = new List<User>(); | |
using (SessionAwareCoreServiceClient client = new SessionAwareCoreServiceClient(_binding)) | |
{ | |
client.Impersonate(ConfigurationManager.AppSettings["ImpersonationAdmin"]); | |
try | |
{ | |
var users = client.GetSystemWideList(new UsersFilterData { BaseColumns = ListBaseColumns.IdAndTitle, IsPredefined = false }); | |
foreach (IdentifiableObjectData userObj in users) | |
{ | |
UserData userData = client.Read(userObj.Id, new ReadOptions()) as UserData; | |
foreach (GroupMembershipData groupData in userData.GroupMemberships) | |
{ | |
if (groupData.Group.IdRef == nextGroupAssigneeUri) | |
{ | |
usersInGroup.Add(new User { Name = userData.Title, Uri = userData.Id }); | |
} | |
} | |
} | |
} | |
catch (Exception ex) | |
{ | |
throw new Exception("Cannot get list of users. Try accessing the method by impersonating with a different user account in the GetUsersInGroup method." + ex.Message + ex.Source + ex); | |
} | |
} | |
return usersInGroup; | |
} | |
public List<User> GetUsersFromNextWfGroup(string componentUri) | |
{ | |
List<User> users = new List<User>(); | |
using (SessionAwareCoreServiceClient client = new SessionAwareCoreServiceClient(_binding)) | |
{ | |
client.Impersonate(ConfigurationManager.AppSettings["ImpersonationAdmin"]); | |
var wfItem = client.Read(componentUri, new ReadOptions()) as ComponentData; | |
if (wfItem == null) | |
return users; | |
var activityUri = wfItem.WorkflowInfo.ActivityInstance.IdRef; | |
var activityTitle = wfItem.WorkflowInfo.ActivityInstance.Title; | |
WorkflowHelper workflowHelper = new WorkflowHelper(); | |
ActivityDefinitionData nextActivity = workflowHelper.GetNextActivityDefinition(componentUri, activityUri, activityTitle); | |
string nextGroupAssigneeUri = workflowHelper.GetNextAssigneeGroupUri(nextActivity); | |
users = workflowHelper.GetUsersInGroup(nextGroupAssigneeUri); | |
} | |
return users; | |
} | |
public List<User> GetUsersFromNextWfGroup(string componentUri, string currentGroupDepartmentUri) | |
{ | |
List<User> users = new List<User>(); | |
using (SessionAwareCoreServiceClient client = new SessionAwareCoreServiceClient(_binding)) | |
{ | |
client.Impersonate(ConfigurationManager.AppSettings["ImpersonationAdmin"]); | |
var wfItem = client.Read(componentUri, new ReadOptions()) as ComponentData; | |
if (wfItem == null) | |
return users; | |
var activityUri = wfItem.WorkflowInfo.ActivityInstance.IdRef; | |
var activityTitle = wfItem.WorkflowInfo.ActivityInstance.Title; | |
WorkflowHelper workflowHelper = new WorkflowHelper(); | |
ActivityDefinitionData nextActivity = workflowHelper.GetNextActivityDefinition(componentUri, activityUri, activityTitle); | |
string nextGroupAssigneeUri = workflowHelper.GetNextAssigneeGroupUri(nextActivity); | |
users = workflowHelper.GetUsersInGroup(nextGroupAssigneeUri); | |
} | |
return users; | |
} | |
/// <summary> | |
/// Finish the current workflow activity | |
/// </summary> | |
/// <param name="compUri">Component URI</param> | |
/// <param name="finishMessage">Finish message for the workflow activity</param> | |
/// <param name="nextAssignee">Next person to assign to. If not specified, assigns to pre-defined group from Visio</param> | |
public void SendToNextActivityFromWfDecision(string compUri, string finishMessage, string nextAssignee = "") | |
{ | |
using (SessionAwareCoreServiceClient client = new SessionAwareCoreServiceClient(_binding)) | |
{ | |
if (compUri == "") | |
throw new ArgumentException("Component URI required"); | |
client.Impersonate(ConfigurationManager.AppSettings["ImpersonationAdmin"]); | |
// get Component and activity URI | |
ComponentData wfItem = client.Read(compUri, new ReadOptions()) as ComponentData; | |
var activityUri = wfItem.WorkflowInfo.ActivityInstance.IdRef; | |
var nextActivity = GetNextActivity(wfItem); | |
// set next person and activity | |
var decisionActivityFinishData = new DecisionActivityFinishData(); | |
decisionActivityFinishData.NextActivity = new LinkToActivityDefinitionData { IdRef = nextActivity.Id }; | |
decisionActivityFinishData.Message = finishMessage; | |
if(nextAssignee != "") | |
{ | |
decisionActivityFinishData.NextAssignee = new LinkToTrusteeData { IdRef = nextAssignee }; | |
} | |
// Finish | |
if (wfItem.WorkflowInfo.ActivityState != ActivityState.Started) | |
{ | |
client.StartActivity(activityUri, new ReadOptions()); | |
} | |
client.FinishActivity(activityUri, decisionActivityFinishData, new ReadOptions()); | |
} | |
} | |
public ActivityDefinitionData GetNextActivity(ComponentData wfItem) | |
{ | |
var activityUri = wfItem.WorkflowInfo.ActivityInstance.IdRef; | |
var nextActivity = GetNextActivityDefinition(wfItem.Id, activityUri, wfItem.WorkflowInfo.ActivityInstance.Title); | |
return nextActivity; | |
} | |
public string GetCurrentActivityTitle(string componentUri) | |
{ | |
using (SessionAwareCoreServiceClient client = new SessionAwareCoreServiceClient(_binding)) | |
{ | |
client.Impersonate(ConfigurationManager.AppSettings["ImpersonationAdmin"]); | |
var wfItem = client.Read(componentUri, new ReadOptions()) as ComponentData; | |
if (wfItem == null) | |
return ""; | |
if (wfItem.WorkflowInfo == null) | |
return ""; | |
return wfItem.WorkflowInfo.ActivityInstance.Title; | |
} | |
} | |
/// <summary> | |
/// Send workflow item back to previous performer | |
/// </summary> | |
/// <param name="componentUri">Component URI</param> | |
/// <param name="finishMessage">Message for previous performer</param> | |
/// <param name="activityDefUriToSendBackTo">Activity URI to send back to</param> | |
/// <param name="activityTitleToSendBackTo">Activity Title to send back to</param> | |
public void SendBack(string componentUri, string finishMessage, string activityDefUriToSendBackTo, string activityTitleToSendBackTo) | |
{ | |
using (SessionAwareCoreServiceClient client = new SessionAwareCoreServiceClient(_binding)) | |
{ | |
client.Impersonate(ConfigurationManager.AppSettings["ImpersonationAdmin"]); | |
// Get Component | |
var wfItem = client.Read(componentUri, new ReadOptions()) as ComponentData; | |
if (wfItem == null) | |
return; | |
var activityUri = wfItem.WorkflowInfo.ActivityInstance.IdRef; | |
ActivityData[] activities = GetActivities(wfItem); | |
// Set Previous performer | |
LinkToUserData guiltyPerson = GetActivityPerformer(activities, activityTitleToSendBackTo); | |
// set next person and activity | |
var decisionActivityFinishData = new DecisionActivityFinishData | |
{ | |
NextAssignee = new LinkToTrusteeData { IdRef = guiltyPerson.IdRef }, | |
NextActivity = new LinkToActivityDefinitionData { IdRef = activityDefUriToSendBackTo }, | |
Message = finishMessage | |
}; | |
// Finish | |
client.FinishActivity(activityUri, decisionActivityFinishData, new ReadOptions()); | |
} | |
} | |
/// <summary> | |
/// Get the ActivityDefinitionData for the next workflow activity | |
/// </summary> | |
/// <param name="uri">Component URI</param> | |
/// <param name="currentactivityUri">Current Workflow URI</param> | |
/// <param name="activityTitle">Workflow activity title</param> | |
/// <returns>ActivityDefinitionData</returns> | |
public ActivityDefinitionData GetNextActivityDefinition(string uri, string currentactivityUri, string activityTitle) | |
{ | |
using (SessionAwareCoreServiceClient client = new SessionAwareCoreServiceClient(_binding)) | |
{ | |
if (uri == "") | |
throw new ArgumentException("Component URI Required"); | |
client.Impersonate(ConfigurationManager.AppSettings["ImpersonationAdmin"]); | |
List<ActivityDefinitionData> activities = GetWorkflowActivityDefinitions(uri); | |
ActivityDefinitionData nextActivity = null; | |
int i = 0; | |
foreach (ActivityDefinitionData activity in activities) | |
{ | |
// current activity | |
if (activity.Title == activityTitle) | |
{ | |
// next activity | |
if ((i + 1) < activities.Count) | |
{ | |
nextActivity = activities[i + 1]; | |
} | |
} | |
i++; | |
} | |
return nextActivity; | |
} | |
} | |
/// <summary> | |
/// Get the ActivityDefinitionData for the previous workflow activity | |
/// </summary> | |
/// <param name="uri">Component URI</param> | |
/// <param name="currentactivityUri">Current Workflow URI</param> | |
/// <param name="activityTitle">Workflow activity title</param> | |
/// <returns>ActivityDefinitionData</returns> | |
public ActivityDefinitionData GetPreviousActivityDefinition(string uri, string currentactivityUri, string activityTitle) | |
{ | |
using (SessionAwareCoreServiceClient client = new SessionAwareCoreServiceClient(_binding)) | |
{ | |
if (uri == "") | |
throw new ArgumentException("Component URI Required"); | |
client.Impersonate(ConfigurationManager.AppSettings["ImpersonationAdmin"]); | |
List<ActivityDefinitionData> activities = GetWorkflowActivityDefinitions(uri); | |
int currentActivityPosition = GetPositionOfCurrentWfActivity(activityTitle, activities); | |
ActivityDefinitionData previousActivity = activities[currentActivityPosition - 1]; | |
return previousActivity; | |
} | |
} | |
/// <summary> | |
/// Get the ActivityDefinitionData for the previous workflow activity to be used in Send Back list | |
/// </summary> | |
/// <param name="uri">Component URI</param> | |
/// <param name="currentactivityUri">Current Workflow URI</param> | |
/// <param name="activityTitle">Workflow activity title</param> | |
/// <returns>ActivityDefinitionData</returns> | |
public List<ActivityDefinitionData> GetPreviousActivityDefinitionItems(string uri, string currentactivityUri, string activityTitle) | |
{ | |
List<ActivityDefinitionData> previousActivitySteps = new List<ActivityDefinitionData>(); | |
using (SessionAwareCoreServiceClient client = new SessionAwareCoreServiceClient(_binding)) | |
{ | |
if (uri == "") | |
throw new ArgumentException("Component URI Required"); | |
client.Impersonate(ConfigurationManager.AppSettings["ImpersonationAdmin"]); | |
List<ActivityDefinitionData> activities = GetWorkflowActivityDefinitions(uri); | |
int currentActivityPosition = GetPositionOfCurrentWfActivity(activityTitle, activities); | |
int i = 0; | |
foreach (ActivityDefinitionData activity in activities) | |
{ | |
if (i < currentActivityPosition) | |
{ | |
previousActivitySteps.Add(activity); | |
} | |
i++; | |
} | |
return previousActivitySteps; | |
} | |
} | |
/// <summary> | |
/// Get position of current workflow activity | |
/// </summary> | |
/// <param name="currentActivityTitle">Current Activity Title</param> | |
/// <param name="activities">List of activity definitions</param> | |
/// <returns></returns> | |
private int GetPositionOfCurrentWfActivity(string currentActivityTitle, IEnumerable<ActivityDefinitionData> activities) | |
{ | |
int position = 0; | |
foreach (ActivityDefinitionData activity in activities) | |
{ | |
if (activity.Title == currentActivityTitle) | |
{ | |
break; | |
} | |
position++; | |
} | |
return position; | |
} | |
/// <summary> | |
/// Get Workflow activity definitions | |
/// </summary> | |
/// <param name="componentUri"></param> | |
/// <returns>List of ActivityDefinitionData items</returns> | |
private List<ActivityDefinitionData> GetWorkflowActivityDefinitions(string componentUri) | |
{ | |
using (SessionAwareCoreServiceClient client = new SessionAwareCoreServiceClient(_binding)) | |
{ | |
if (componentUri == "") | |
throw new ArgumentException("Component URI Required"); | |
client.Impersonate(ConfigurationManager.AppSettings["ImpersonationAdmin"]); | |
var wfItem = client.Read(componentUri, new ReadOptions()) as ComponentData; | |
var activityUri = wfItem.WorkflowInfo.ActivityInstance.IdRef; | |
ActivityInstanceData currentactivity = (ActivityInstanceData)client.Read(activityUri, new ReadOptions()); | |
TridionActivityDefinitionData activitydefinition = (TridionActivityDefinitionData)client.Read(currentactivity.ActivityDefinition.IdRef, new ReadOptions()); | |
ProcessDefinitionData processdefinition = (ProcessDefinitionData)client.Read(activitydefinition.ProcessDefinition.IdRef, new ReadOptions()); | |
List<ActivityDefinitionData> activities = new List<ActivityDefinitionData>(processdefinition.ActivityDefinitions); | |
return activities; | |
} | |
} | |
/// <summary> | |
/// Get the Tridion Group URI for the next workflow activity | |
/// </summary> | |
/// <param name="activityDefData">Activity definition data for the current item</param> | |
/// <returns></returns> | |
public string GetNextAssigneeGroupUri(ActivityDefinitionData activityDefData) | |
{ | |
return activityDefData.Assignee.IdRef; | |
} | |
/// <summary> | |
/// Get the Tridion Group Name for the next workflow activity | |
/// </summary> | |
/// <param name="activityDefData">Activity definition data for the current item</param> | |
/// <returns></returns> | |
public string GetNextAssigneeGroupName(ActivityDefinitionData activityDefData) | |
{ | |
return activityDefData.Assignee.Title; | |
} | |
// **** | |
// get the group the (first) user in the WF belongs to. Then, keep the workflow within that | |
// group, passing it to the role_group, and not use the pre-defined Visio workflow role | |
// **** | |
public List<LinkToGroupData> GetUserDepartmentGroupsInfo(string userUri) | |
{ | |
// find the group for the combination of department and the role | |
// ie. science_author | |
List<LinkToGroupData> deptGroups = new List<LinkToGroupData>(); | |
string departmentGroupSeparator = ConfigurationManager.AppSettings["DepartmentGroupSeparator"]; | |
using (SessionAwareCoreServiceClient client = new SessionAwareCoreServiceClient(_binding)) | |
{ | |
client.Impersonate(ConfigurationManager.AppSettings["ImpersonationAdmin"]); | |
UserData user = client.Read(userUri, new ReadOptions()) as UserData; | |
GroupMembershipData[] groups = user.GroupMemberships; | |
foreach (GroupMembershipData group in groups) | |
{ | |
string groupTitle = group.Group.Title; | |
if (groupTitle.Contains(departmentGroupSeparator)) | |
{ | |
deptGroups.Add(group.Group); | |
} | |
} | |
} | |
deptGroups.Sort((group1, group2) => group1.Title.CompareTo(group2.Title)); | |
return deptGroups; | |
} | |
/// <summary> | |
/// Get the group name from group_role | |
/// </summary> | |
/// <param name="userUri">URI of User</param> | |
/// <returns>Group name of user from group_role</returns> | |
public string FindUserDepartmentGroupName(string userUri) | |
{ | |
// find the group for the combination of department and the role | |
// ie. author_science | |
string departmentGroupName = ""; | |
string departmentGroupSeparator = ConfigurationManager.AppSettings["DepartmentGroupSeparator"]; | |
using (SessionAwareCoreServiceClient client = new SessionAwareCoreServiceClient(_binding)) | |
{ | |
client.Impersonate(ConfigurationManager.AppSettings["ImpersonationAdmin"]); | |
UserData user = client.Read(userUri, new ReadOptions()) as UserData; | |
GroupMembershipData[] groups = user.GroupMemberships; | |
foreach (GroupMembershipData group in groups) | |
{ | |
string groupTitle = group.Group.Title; | |
if (groupTitle.Contains(departmentGroupSeparator)) | |
{ | |
string[] groupParts = groupTitle.Split('_'); | |
string role = groupParts[0]; | |
departmentGroupName = groupParts[1]; | |
} | |
} | |
} | |
return departmentGroupName; | |
} | |
/// <summary> | |
/// Get the URI of a group based on the GroupName | |
/// </summary> | |
/// <param name="groupName"></param> | |
/// <param name="userUri"></param> | |
/// <returns></returns> | |
public string GetGroupUri(string groupName, string userUri) | |
{ | |
string groupUri = "tcm:0-0-0"; | |
using (SessionAwareCoreServiceClient client = new SessionAwareCoreServiceClient(_binding)) | |
{ | |
client.Impersonate(ConfigurationManager.AppSettings["ImpersonationAdmin"]); | |
UserData user = client.Read(userUri, new ReadOptions()) as UserData; | |
GroupMembershipData[] groups = user.GroupMemberships; | |
foreach (GroupMembershipData group in groups) | |
{ | |
string groupTitle = group.Group.Title; | |
if (groupTitle.Contains(groupName)) | |
{ | |
groupUri = group.Group.IdRef; | |
} | |
} | |
} | |
return groupUri; | |
} | |
/// <summary> | |
/// Using the user's department group memebership, get the next group to assign the workflow item to | |
/// </summary> | |
/// <param name="componentUri"></param> | |
/// <param name="wfItem"></param> | |
/// <param name="userUri"></param> | |
/// <returns></returns> | |
public string GetGroupUriToAssignTo(string componentUri, ComponentData wfItem, string userUri) | |
{ | |
// ** Start to get the wf activity definition to get the title of next activity | |
ActivityDefinitionData nextActivity = | |
GetNextActivityDefinition( | |
componentUri, | |
wfItem.WorkflowInfo.ActivityInstance.IdRef, | |
wfItem.WorkflowInfo.ActivityInstance.Title); | |
// -Build the role and group info | |
// Visio defined role of next activity | |
string roleName = GetNextAssigneeGroupName(nextActivity); | |
// User-determined department group, based on having '_' in group name | |
string departmentName = FindUserDepartmentGroupName(userUri); | |
// Group to assign to and list users in group | |
string groupToAssignTo = roleName; | |
if (departmentName != "") | |
{ | |
groupToAssignTo = GetCombinedGroupName(roleName, departmentName); | |
} | |
string groupUri = GetGroupUri(groupToAssignTo, userUri); | |
// ** End Assign-to code | |
return groupUri; | |
} | |
/// <summary> | |
/// Get the combination of Visio defined group and user's department group | |
/// </summary> | |
/// <param name="roleName">Visio workflow group</param> | |
/// <param name="departmentName">Department group person belongs to</param> | |
/// <returns>ie. Editors_Science</returns> | |
public string GetCombinedGroupName(string roleName, string departmentName) | |
{ | |
string separator = ConfigurationManager.AppSettings["DepartmentGroupSeparator"]; | |
string groupToAssignTo = roleName + separator + departmentName; | |
return groupToAssignTo; | |
} | |
/// <summary> | |
/// Get the URI of a user | |
/// </summary> | |
/// <param name="username">username to match with Tridion user list</param> | |
/// <returns></returns> | |
public string FindUserUri(string username) | |
{ | |
string userUri = "tcm:0-0-0"; | |
var loggedInUser = HttpContext.Current.User.Identity.Name.ToLower(); | |
using (SessionAwareCoreServiceClient client = new SessionAwareCoreServiceClient(_binding)) | |
{ | |
var users = | |
client.GetSystemWideList(new UsersFilterData | |
{ | |
BaseColumns = ListBaseColumns.IdAndTitle, | |
IsPredefined = false | |
}); | |
foreach (UserData user in users) | |
{ | |
if (user.Title.ToLower() == loggedInUser) | |
{ | |
userUri = user.Id; | |
} | |
} | |
} | |
return userUri; | |
} | |
/// <summary> | |
/// Get the User URI of the previous workflow activity | |
/// </summary> | |
/// <param name="uri">Component URI</param> | |
/// <param name="currentactivityUri">Workflow Activity URI</param> | |
/// <param name="prevActivityTitle">Previous Activity Title</param> | |
/// <returns></returns> | |
public ActivityData GetPreviousActivityInstanceItem(string uri, string currentactivityUri, string prevActivityTitle) | |
{ | |
ActivityData previousActivity = null; | |
using (SessionAwareCoreServiceClient client = new SessionAwareCoreServiceClient(_binding)) | |
{ | |
if (uri == "") | |
return null; | |
client.Impersonate(ConfigurationManager.AppSettings["ImpersonationAdmin"]); | |
try | |
{ | |
var wfItem = client.Read(uri, new ReadOptions()) as ComponentData; | |
ActivityData[] activityInstances = GetActivities(wfItem); | |
int i = 0; | |
foreach (ActivityData activityData in activityInstances) | |
{ | |
if (activityData.Id == currentactivityUri) | |
{ | |
if ((i - 1) > -1) | |
{ | |
previousActivity = activityInstances[i - 1]; | |
} | |
} | |
i++; | |
} | |
} | |
catch (Exception ex) | |
{ | |
throw new Exception("Cannot get list of users. Try accessing the method by impersonating with a different user account in the GetUsersInGroup method." + ex.Message + ex.Source + ex); | |
} | |
return previousActivity; | |
} | |
} | |
/// <summary> | |
/// //Get list of Workflow activities in the current active workflow | |
/// </summary> | |
/// <param name="wfItem"></param> | |
/// <returns></returns> | |
private ActivityData[] GetActivities(ComponentData wfItem) | |
{ | |
using (SessionAwareCoreServiceClient client = new SessionAwareCoreServiceClient(_binding)) | |
{ | |
client.Impersonate(ConfigurationManager.AppSettings["ImpersonationAdmin"]); | |
var processInstance = (ProcessInstanceData)client.Read(wfItem.WorkflowInfo.ProcessInstance.IdRef, new ReadOptions()); | |
ActivityData[] activityInstances = processInstance.Activities; | |
return activityInstances; | |
} | |
} | |
/// <summary> | |
/// Get the person who performed the activity in the specified activity definition. | |
/// </summary> | |
/// <param name="activities"></param> | |
/// <param name="activityDefinitionStepTitle"></param> | |
/// <returns></returns> | |
public LinkToUserData GetActivityPerformer(ActivityData[] activities, string activityDefinitionStepTitle) | |
{ | |
LinkToUserData activityPerformer = null; | |
foreach (ActivityData activity in activities) | |
{ | |
// Activity definition includes #s in front of the title... so we need to use contains | |
if (activity.Title.Contains(activityDefinitionStepTitle)) | |
{ | |
activityPerformer = activity.Performers[0]; | |
break; | |
} | |
} | |
return activityPerformer; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment