using System;
using System.Data;
using System.Web.UI.WebControls;
using System.Collections.Generic;
using CMS.CMSHelper;
using CMS.GlobalHelper;
using CMS.SettingsProvider;
using CMS.SiteProvider;
using CMS.DocumentEngine;
using CMS.UIControls;
using CMS.WorkflowEngine;
using TreeNode = CMS.DocumentEngine.TreeNode;
public partial class CMSModules_Content_Controls_Workflow : CMSUserControl
{
#region "Private variables"
// Current Node
private TreeNode mNode = null;
private TreeProvider mTree = null;
private WorkflowManager mWorkflowManager = null;
private int mNodeId = -1;
private int currentStepId = 0;
private WorkflowInfo mWorkflowInfo = null;
private UserInfo currentUserInfo = null;
private SiteInfo currentSiteInfo = null;
private readonly bool displaySplitMode = CMSContext.DisplaySplitMode;
#endregion
#region "Properties"
///
/// Tree provider
///
public TreeProvider Tree
{
get
{
return mTree ?? (mTree = new TreeProvider(CMSContext.CurrentUser));
}
set
{
mTree = value;
}
}
///
/// Workflow manager
///
private WorkflowManager WorkflowManager
{
get
{
return mWorkflowManager ?? (mWorkflowManager = WorkflowManager.GetInstance(Tree));
}
}
///
/// Tree node.
///
public TreeNode Node
{
get
{
return mNode ?? (mNode = DocumentHelper.GetDocument(NodeID, CMSContext.PreferredCultureCode, Tree));
}
set
{
mNode = value;
mNodeId = -1;
if (value != null)
{
mNodeId = value.NodeID;
}
}
}
///
/// Determines whether document is checked out
///
private bool DocumentIsCheckedOut
{
get
{
return (Node != null) && Node.IsCheckedOut;
}
}
///
/// Identifier of current node
///
private int NodeID
{
get
{
return mNodeId;
}
set
{
mNodeId = value;
mNode = null;
}
}
///
/// Workflow info object
///
private WorkflowInfo WorkflowInfo
{
get
{
if (mWorkflowInfo == null)
{
if (Node != null)
{
mWorkflowInfo = Node.GetWorkflow();
}
}
return mWorkflowInfo;
}
}
#endregion
#region "Page events"
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
gridHistory.GridName = "~/CMSModules/Content/CMSDesk/Properties/WorkflowHistory.xml";
gridSteps.GridName = "~/CMSModules/Content/CMSDesk/Properties/WorkflowSteps.xml";
gridSteps.WhereCondition = "StepWorkflowID = @StepWorkflowID";
}
protected void Page_Load(object sender, EventArgs e)
{
// Turn sorting off
gridSteps.GridView.AllowSorting = false;
ReloadData();
string viewVersionUrl = null;
if (IsLiveSite)
{
viewVersionUrl = CMSContext.ResolveDialogUrl("~/CMSModules/Content/CMSPages/Versions/ViewVersion.aspx");
}
else
{
viewVersionUrl = ResolveUrl("~/CMSModules/Content/CMSDesk/Properties/ViewVersion.aspx");
}
string viewVersionScript = ScriptHelper.GetScript("function ViewVersion(versionHistoryId) {window.open('" + viewVersionUrl + "?versionHistoryId=' + versionHistoryId)}");
ScriptHelper.RegisterClientScriptBlock(this, typeof(string), "viewVersionScript", viewVersionScript);
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if (RequestHelper.IsPostBack())
{
ReloadData();
}
}
#endregion
#region "Grid events"
///
/// External step binding.
///
protected object gridSteps_OnExternalDataBound(object sender, string sourceName, object parameter)
{
switch (sourceName.ToLowerCSafe())
{
case "currentstepinfo":
DataRowView data = (DataRowView)parameter;
if (currentStepId <= 0)
{
WorkflowStepTypeEnum stepType = (WorkflowStepTypeEnum)ValidationHelper.GetInteger(data["StepType"], 1);
if (stepType == WorkflowStepTypeEnum.DocumentEdit)
{
return "
";
}
}
else
{
// Check if version history exists and node is published
if (Node.IsPublished && (Node.DocumentCheckedOutVersionHistoryID <= 0))
{
WorkflowStepTypeEnum stepType = (WorkflowStepTypeEnum)ValidationHelper.GetInteger(data["StepType"], 1);
if (stepType == WorkflowStepTypeEnum.DocumentPublished)
{
return "
";
}
}
else
{
int stepId = ValidationHelper.GetInteger(data["StepID"], 0);
if (stepId == currentStepId)
{
return "
";
}
}
}
return string.Empty;
case "steporder":
if (sender != null)
{
// Get grid row
GridViewRow row = (GridViewRow)((DataControlFieldCell)sender).Parent;
int pageOffset = (gridSteps.Pager.CurrentPage - 1) * gridSteps.Pager.CurrentPageSize;
// Return row index
return (pageOffset + row.RowIndex + 1).ToString();
}
return string.Empty;
}
return parameter;
}
///
/// External history binding.
///
protected object gridHistory_OnExternalDataBound(object sender, string sourceName, object parameter)
{
DataRowView drv = null;
switch (sourceName.ToLowerCSafe())
{
case "action":
drv = (DataRowView)parameter;
bool wasrejected = ValidationHelper.GetBoolean(drv["WasRejected"], false);
// Get type of the steps
WorkflowStepTypeEnum stepType = (WorkflowStepTypeEnum)ValidationHelper.GetInteger(DataHelper.GetDataRowViewValue(drv, "StepType"), 0);
WorkflowStepTypeEnum targetStepType = (WorkflowStepTypeEnum)ValidationHelper.GetInteger(DataHelper.GetDataRowViewValue(drv, "TargetStepType"), (int)stepType);
WorkflowTransitionTypeEnum transitionType = (WorkflowTransitionTypeEnum)ValidationHelper.GetInteger(DataHelper.GetDataRowViewValue(drv, "HistoryTransitionType"), 0);
// Get name of steps
string stepName = ValidationHelper.GetString(DataHelper.GetDataRowViewValue(drv, "StepName"), String.Empty);
string targetStepName = ValidationHelper.GetString(DataHelper.GetDataRowViewValue(drv, "TargetStepName"), stepName);
if (!wasrejected)
{
// If step type defined, use it for identification
if (targetStepType != WorkflowStepTypeEnum.Undefined)
{
bool isAutomatic = (transitionType == WorkflowTransitionTypeEnum.Automatic);
string actionString = isAutomatic ? GetString("WorfklowProperties.Automatic") + " ({0})" : "{0}";
// Return correct step title
switch (targetStepType)
{
case WorkflowStepTypeEnum.DocumentArchived:
actionString = string.Format(actionString, GetString("WorfklowProperties.Archived"));
break;
case WorkflowStepTypeEnum.DocumentPublished:
actionString = string.Format(actionString, GetString("WorfklowProperties.Published"));
break;
case WorkflowStepTypeEnum.DocumentEdit:
actionString = GetString("WorfklowProperties.NewVersion");
break;
default:
if(stepType == WorkflowStepTypeEnum.DocumentEdit)
{
actionString = GetString("WorfklowProperties.NewVersion");
}
else
{
actionString = isAutomatic ? GetString("WorfklowProperties.Automatic") : GetString("WorfklowProperties.Approved");
}
break;
}
return actionString;
}
// Backward compatibility
else
{
// Return correct step title
switch (targetStepName.ToLowerCSafe())
{
case "archived":
return GetString("WorfklowProperties.Archived");
case "published":
return GetString("WorfklowProperties.Published");
case "edit":
return GetString("WorfklowProperties.NewVersion");
default:
if (CMSString.Equals(stepName, "edit", true))
{
return GetString("WorfklowProperties.NewVersion");
}
return GetString("WorfklowProperties.Approved");
}
}
}
else
{
return GetString("WorfklowProperties.Rejected");
}
// Get approved time
case "approvedwhen":
case "approvedwhentooltip":
if (string.IsNullOrEmpty(parameter.ToString()))
{
return string.Empty;
}
else
{
if (currentUserInfo == null)
{
currentUserInfo = CMSContext.CurrentUser;
}
if (currentSiteInfo == null)
{
currentSiteInfo = CMSContext.CurrentSite;
}
// Apply time zone information
bool displayGMT = (sourceName == "approvedwhentooltip");
DateTime time = ValidationHelper.GetDateTime(parameter, DateTimeHelper.ZERO_TIME);
return TimeZoneHelper.ConvertToUserTimeZone(time, displayGMT, currentUserInfo, currentSiteInfo);
}
case "stepname":
drv = (DataRowView)parameter;
string step = ValidationHelper.GetString(DataHelper.GetDataRowViewValue(drv, "StepDisplayName"), String.Empty);
string targetStep = ValidationHelper.GetString(DataHelper.GetDataRowViewValue(drv, "TargetStepDisplayName"), String.Empty);
if (!string.IsNullOrEmpty(targetStep))
{
step += " -> " + targetStep;
}
return HTMLHelper.HTMLEncode(ResHelper.LocalizeString(step));
}
return parameter;
}
#endregion
#region "Protected methods"
///
/// Reloads the page data.
///
protected void ReloadData()
{
string where = string.Format("StepType IN ({0}, {1}, {2})", (int)WorkflowStepTypeEnum.DocumentEdit, (int)WorkflowStepTypeEnum.DocumentPublished, (int)WorkflowStepTypeEnum.DocumentArchived);
// Hide custom steps if license doesn't allow them or check automatically publish changes
if (!WorkflowInfoProvider.IsCustomStepAllowed())
{
gridSteps.WhereCondition = SqlHelperClass.AddWhereCondition(gridSteps.WhereCondition, where);
}
// Hide custom steps (without actual step) if functionality 'Automatically publish changes' is allowed
else if ((WorkflowInfo != null) && WorkflowInfo.WorkflowAutoPublishChanges)
{
gridSteps.WhereCondition = SqlHelperClass.AddWhereCondition(gridSteps.WhereCondition, where);
// Get current step info
WorkflowStepInfo currentStep = WorkflowManager.GetStepInfo(Node);
if (currentStep != null)
{
if (!currentStep.StepIsDefault)
{
gridSteps.WhereCondition = SqlHelperClass.AddWhereCondition(gridSteps.WhereCondition, "(StepName = '" + SqlHelperClass.GetSafeQueryString(currentStep.StepName, false) + "')", "OR");
}
}
}
// Do not display steps without order - advanced workflow steps
gridSteps.WhereCondition = SqlHelperClass.AddWhereCondition(gridSteps.WhereCondition, "StepOrder IS NOT NULL");
// Prepare the query parameters
QueryDataParameters parameters = new QueryDataParameters();
parameters.Add("@DocumentID", 0);
// Prepare the steps query parameters
QueryDataParameters stepsParameters = new QueryDataParameters();
stepsParameters.Add("@StepWorkflowID", 0);
if (Node != null)
{
// Check read permissions
if (CMSContext.CurrentUser.IsAuthorizedPerDocument(Node, NodePermissionsEnum.Read) == AuthorizationResultEnum.Denied)
{
RedirectToAccessDenied(String.Format(GetString("cmsdesk.notauthorizedtoreaddocument"), Node.NodeAliasPath));
}
// Prepare parameters
parameters[0].Value = Node.DocumentID;
currentStepId = ValidationHelper.GetInteger(Node.GetValue("DocumentWorkflowStepID"), 0);
if (WorkflowInfo != null)
{
plcBasic.Visible = WorkflowInfo.IsBasic;
plcAdvanced.Visible = !plcBasic.Visible;
if (plcAdvanced.Visible)
{
ucDesigner.WorkflowID = WorkflowInfo.WorkflowID;
ucDesigner.SelectedStepID = currentStepId;
ucDesigner.WorkflowType = WorkflowTypeEnum.Approval;
}
else
{
stepsParameters[0].Value = WorkflowInfo.WorkflowID;
}
// Initialize grids
gridHistory.OnExternalDataBound += gridHistory_OnExternalDataBound;
gridSteps.OnExternalDataBound += gridSteps_OnExternalDataBound;
gridHistory.ZeroRowsText = GetString("workflowproperties.nohistoryyet");
}
}
else
{
pnlWorkflow.Visible = false;
}
// Initialize query parameters of grids
gridSteps.QueryParameters = stepsParameters;
gridHistory.QueryParameters = parameters;
SetupForm();
gridHistory.ReloadData();
if (plcBasic.Visible)
{
gridSteps.ReloadData();
}
}
private void ShowInfo(string message, bool persistent)
{
if (IsLiveSite)
{
ShowInformation(message, null, persistent);
}
else
{
DocumentManager.DocumentInfo = message;
}
}
///
/// Reloads the form status.
///
protected void SetupForm()
{
// Check modify permissions
if ((CMSContext.CurrentUser.IsAuthorizedPerDocument(Node, NodePermissionsEnum.Modify) == AuthorizationResultEnum.Denied) &&
!CMSContext.CurrentUser.IsAuthorizedPerResource("CMS.Content", "ManageWorkflow"))
{
ShowInfo(String.Format(GetString("cmsdesk.notauthorizedtoeditdocument"), Node.NodeAliasPath), true);
}
else
{
bool autoPublishChanges = false;
// Check if auto publish changes is allowed
if (WorkflowInfo != null)
{
autoPublishChanges = WorkflowInfo.WorkflowAutoPublishChanges;
}
if ((WorkflowInfo != null) || (currentStepId > 0))
{
// Setup the form
WorkflowStepInfo stepInfo = null;
if (Node.IsPublished && (Node.DocumentCheckedOutVersionHistoryID <= 0))
{
stepInfo = WorkflowStepInfoProvider.GetPublishedStep(WorkflowInfo.WorkflowID);
}
else
{
stepInfo = WorkflowStepInfoProvider.GetWorkflowStepInfo(currentStepId) ?? WorkflowStepInfoProvider.GetFirstStep(WorkflowInfo.WorkflowID);
}
if (stepInfo != null)
{
currentStepId = stepInfo.StepID;
if (plcAdvanced.Visible)
{
ucDesigner.SelectedStepID = currentStepId;
}
}
}
}
// Check if document isn't checked out
if (DocumentIsCheckedOut)
{
ShowInfo(GetString("WorfklowProperties.DocumentIsCheckedOut"), true);
}
// If no workflow scope set for node, hide the data
if (WorkflowInfo == null)
{
lblWorkflow.Text = GetString("properties.scopenotset");
lblWorkflow.Visible = true;
pnlWorkflow.Visible = false;
}
}
#endregion
}