using System;
using System.Data;
using CMS.CMSHelper;
using CMS.GlobalHelper;
using CMS.DocumentEngine;
using CMS.UIControls;
using CMS.WorkflowEngine;
[Title(Text = "Workflow advanced", ImageUrl = "Objects/CMS_Workflow/object.png")]
public partial class CMSAPIExamples_Code_Documents_Workflow_Advanced_Default : CMSAPIExamplePage
{
#region "Initialization"
protected void Page_Load(object sender, EventArgs e)
{
// Creating documents
apiCreateExampleObjects.RunExample += new CMSAPIExamples_Controls_APIExample.OnRunExample(CreateExampleObjects);
// Editing documents
apiCheckOut.RunExample += new CMSAPIExamples_Controls_APIExample.OnRunExample(CheckOut);
apiEditDocument.RunExample += new CMSAPIExamples_Controls_APIExample.OnRunExample(EditDocument);
apiCheckIn.RunExample += new CMSAPIExamples_Controls_APIExample.OnRunExample(CheckIn);
apiUndoCheckout.RunExample += new CMSAPIExamples_Controls_APIExample.OnRunExample(UndoCheckout);
// Workflow process
apiMoveToNextStep.RunExample += new CMSAPIExamples_Controls_APIExample.OnRunExample(MoveToNextStep);
apiMoveToPreviousStep.RunExample += new CMSAPIExamples_Controls_APIExample.OnRunExample(MoveToPreviousStep);
apiPublishDocument.RunExample += new CMSAPIExamples_Controls_APIExample.OnRunExample(PublishDocument);
apiArchiveDocument.RunExample += new CMSAPIExamples_Controls_APIExample.OnRunExample(ArchiveDocument);
// Versioning
apiRollbackVersion.RunExample += new CMSAPIExamples_Controls_APIExample.OnRunExample(RollbackVersion);
apiDeleteVersion.RunExample += new CMSAPIExamples_Controls_APIExample.OnRunExample(DeleteVersion);
apiDestroyHistory.RunExample += new CMSAPIExamples_Controls_APIExample.OnRunExample(DestroyHistory);
// Cleanup
apiDeleteExampleObjects.RunExample += new CMSAPIExamples_Controls_APIExample.OnRunExample(DeleteExampleObjects);
}
#endregion
#region "Mass actions"
///
/// Runs all creating and managing examples.
///
public override void RunAll()
{
base.RunAll();
// Preparation
apiCreateExampleObjects.Run();
// Editing documents
apiCheckOut.Run();
apiEditDocument.Run();
apiCheckIn.Run();
// Workflow process
apiMoveToNextStep.Run();
apiMoveToPreviousStep.Run();
apiPublishDocument.Run();
apiDestroyHistory.Run();
// Versioning
apiRollbackVersion.Run();
apiDeleteVersion.Run();
apiDestroyHistory.Run();
}
///
/// Runs all cleanup examples.
///
public override void CleanUpAll()
{
base.CleanUpAll();
apiDeleteExampleObjects.Run();
}
#endregion
#region "API examples - Preparation"
///
///Creates the document, workflow scope and step needed for this example. Called when the "Create example objects" button is pressed.
///
private bool CreateExampleObjects()
{
// Create a new tree provider
TreeProvider tree = new TreeProvider(CMSContext.CurrentUser);
// Get the root node
TreeNode parent = tree.SelectSingleNode(CMSContext.CurrentSiteName, "/", "en-us");
if (parent != null)
{
// Create the API document
TreeNode node = TreeNode.New("CMS.MenuItem", tree);
node.DocumentName = "API Example";
node.DocumentCulture = "en-us";
// Insert it to database
DocumentHelper.InsertDocument(node, parent, tree);
// Get the default workflow
WorkflowInfo workflow = WorkflowInfoProvider.GetWorkflowInfo("default");
if (workflow != null)
{
// Get the document data
node = DocumentHelper.GetDocument(node, tree);
// Create new workflow scope
WorkflowScopeInfo scope = new WorkflowScopeInfo();
// Assign to the default workflow and current site and set starting alias path to the example document
scope.ScopeWorkflowID = workflow.WorkflowID;
scope.ScopeStartingPath = node.NodeAliasPath;
scope.ScopeSiteID = CMSContext.CurrentSiteID;
// Save the scope into the database
WorkflowScopeInfoProvider.SetWorkflowScopeInfo(scope);
// Create a new workflow step
WorkflowStepInfo step = new WorkflowStepInfo();
// Set its properties
step.StepWorkflowID = workflow.WorkflowID;
step.StepName = "MyNewWorkflowStep";
step.StepDisplayName = "My new workflow step";
step.StepOrder = 1;
// Save the workflow step
WorkflowStepInfoProvider.SetWorkflowStepInfo(step);
// Ensure correct step order
WorkflowStepInfoProvider.InitStepOrders(workflow);
return true;
}
else
{
apiCreateExampleObjects.ErrorMessage = "The default workflow was not found.";
}
}
return false;
}
#endregion
#region "API examples - Managing documents"
///
/// Checks out the document. If check-in/check-out is disabled for the default workflow, the example can't be used. Called when the "Check out document" button is pressed.
/// Expects the "CreateExampleObjects" method to be run first.
///
private bool CheckOut()
{
TreeProvider tree = new TreeProvider(CMSContext.CurrentUser);
// Prepare parameters
string siteName = CMSContext.CurrentSiteName;
string aliasPath = "/API-Example";
string culture = "en-us";
bool combineWithDefaultCulture = false;
string classNames = TreeProvider.ALL_CLASSNAMES;
string where = null;
string orderBy = null;
int maxRelativeLevel = -1;
bool selectOnlyPublished = false;
string columns = null;
// Get the document
TreeNode node = DocumentHelper.GetDocument(siteName, aliasPath, culture, combineWithDefaultCulture, classNames, where, orderBy, maxRelativeLevel, selectOnlyPublished, columns, tree);
if (node != null)
{
// Create a new Workflow manager instance
WorkflowManager workflowmanager = WorkflowManager.GetInstance(tree);
// Make sure the document uses workflow
WorkflowInfo workflow = workflowmanager.GetNodeWorkflow(node);
if (workflow != null)
{
// Check if the workflow uses check-in/check-out functionality
if (workflow.UseCheckInCheckOut(CMSContext.CurrentSiteName))
{
// The document has to be checked in
if (!node.IsCheckedOut)
{
// Create a new version manager instance
VersionManager versionmanager = VersionManager.GetInstance(tree);
// Check out the document to create a new document version
versionmanager.CheckOut(node);
return true;
}
else
{
apiCheckOut.ErrorMessage = "The document has already been checked out.";
}
}
else
{
apiCheckOut.ErrorMessage = "The workflow does not use check-in/check-out. See the \"Edit document\" example, which checks the document out and in automatically.";
}
}
else
{
apiCheckOut.ErrorMessage = "The document doesn't use workflow.";
}
}
return false;
}
///
/// If the document hasn't been checked out, creates a new modified version of the document. If it has, the example modifies the checked out version. Called when the "Edit document" button is pressed.
/// Expects the "CreateExampleObjects" method and optionally the "CheckOut" method to be run first.
///
private bool EditDocument()
{
TreeProvider tree = new TreeProvider(CMSContext.CurrentUser);
// Prepare parameters
string siteName = CMSContext.CurrentSiteName;
string aliasPath = "/API-Example";
string culture = "en-us";
bool combineWithDefaultCulture = false;
string classNames = TreeProvider.ALL_CLASSNAMES;
string where = null;
string orderBy = null;
int maxRelativeLevel = -1;
bool selectOnlyPublished = false;
string columns = null;
// Get the document
TreeNode node = DocumentHelper.GetDocument(siteName, aliasPath, culture, combineWithDefaultCulture, classNames, where, orderBy, maxRelativeLevel, selectOnlyPublished, columns, tree);
if (node != null)
{
WorkflowManager workflowmanager = WorkflowManager.GetInstance(tree);
// Make sure the document uses workflow
WorkflowInfo workflow = workflowmanager.GetNodeWorkflow(node);
if (workflow != null)
{
// Check if the workflow uses check-in/check-out
bool autoCheck = !workflow.UseCheckInCheckOut(CMSContext.CurrentSiteName);
// Create a new version manager instance
VersionManager versionmanager = VersionManager.GetInstance(tree);
// If it does not use check-in/check-out, check out the document automatically
if (autoCheck)
{
versionmanager.CheckOut(node);
}
if (node.IsCheckedOut)
{
// Edit the last version of the document
string newName = node.DocumentName.ToLower();
node.DocumentName = newName;
node.SetValue("MenuItemName", newName);
// Save the document version
DocumentHelper.UpdateDocument(node, tree);
// Automatically check in
if (autoCheck)
{
versionmanager.CheckIn(node, null, null);
}
return true;
}
else
{
apiEditDocument.ErrorMessage = "The document hasn't been checked out.";
}
}
else
{
apiEditDocument.ErrorMessage = "The document doesn't use workflow.";
}
}
return false;
}
///
/// Checks in the document. If check-in/check-out is disabled for the default workflow, the example can't be used. Called when the "Check in document" button is pressed.
/// Expects the "CreateExampleObjects" and "CheckOut" methods to be run first.
///
private bool CheckIn()
{
TreeProvider tree = new TreeProvider(CMSContext.CurrentUser);
// Prepare parameters
string siteName = CMSContext.CurrentSiteName;
string aliasPath = "/API-Example";
string culture = "en-us";
bool combineWithDefaultCulture = false;
string classNames = TreeProvider.ALL_CLASSNAMES;
string where = null;
string orderBy = null;
int maxRelativeLevel = -1;
bool selectOnlyPublished = false;
string columns = null;
// Get the document
TreeNode node = DocumentHelper.GetDocument(siteName, aliasPath, culture, combineWithDefaultCulture, classNames, where, orderBy, maxRelativeLevel, selectOnlyPublished, columns, tree);
if (node != null)
{
WorkflowManager workflowmanager = WorkflowManager.GetInstance(tree);
// Make sure the document uses workflow
WorkflowInfo workflow = workflowmanager.GetNodeWorkflow(node);
if (workflow != null)
{
if (node.IsCheckedOut)
{
VersionManager versionmanager = VersionManager.GetInstance(tree);
// Check in the document
versionmanager.CheckIn(node, null, null);
return true;
}
else
{
apiCheckIn.ErrorMessage = "The document hasn't been checked out.";
}
}
else
{
apiCheckIn.ErrorMessage = "The document doesn't use workflow.";
}
}
return false;
}
///
/// Reverts back the changes made in the latest version if check-in/check-out is used. Called when the "Undo check-out" button is pressed.
/// Expects the "CreateExampleObjects" and "CheckOut" methods to be run first.
///
private bool UndoCheckout()
{
TreeProvider tree = new TreeProvider(CMSContext.CurrentUser);
// Prepare parameters
string siteName = CMSContext.CurrentSiteName;
string aliasPath = "/API-Example";
string culture = "en-us";
bool combineWithDefaultCulture = false;
string classNames = TreeProvider.ALL_CLASSNAMES;
string where = null;
string orderBy = null;
int maxRelativeLevel = -1;
bool selectOnlyPublished = false;
string columns = null;
// Get the document
TreeNode node = DocumentHelper.GetDocument(siteName, aliasPath, culture, combineWithDefaultCulture, classNames, where, orderBy, maxRelativeLevel, selectOnlyPublished, columns, tree);
if (node != null)
{
WorkflowManager workflowmanager = WorkflowManager.GetInstance(tree);
// Make sure the document uses workflow
WorkflowInfo workflow = workflowmanager.GetNodeWorkflow(node);
if (workflow != null)
{
if (node.IsCheckedOut)
{
VersionManager versionmanager = VersionManager.GetInstance(tree);
// Undo the checkout
versionmanager.UndoCheckOut(node);
return true;
}
else
{
apiUndoCheckout.ErrorMessage = "The document hasn't been checked out.";
}
}
else
{
apiUndoCheckout.ErrorMessage = "The document doesn't use workflow.";
}
}
return false;
}
#endregion
#region "API examples - Workflow process"
///
/// Moves the document to the next step in the workflow process. Called when the "Move to next step" button is pressed.
/// Expects the "CreateExampleObjects" and at least the "EditDocument" method to be run first.
///
private bool MoveToNextStep()
{
TreeProvider tree = new TreeProvider(CMSContext.CurrentUser);
// Prepare parameters
string siteName = CMSContext.CurrentSiteName;
string aliasPath = "/API-Example";
string culture = "en-us";
bool combineWithDefaultCulture = false;
string classNames = TreeProvider.ALL_CLASSNAMES;
string where = null;
string orderBy = null;
int maxRelativeLevel = -1;
bool selectOnlyPublished = false;
string columns = null;
// Get the document
TreeNode node = DocumentHelper.GetDocument(siteName, aliasPath, culture, combineWithDefaultCulture, classNames, where, orderBy, maxRelativeLevel, selectOnlyPublished, columns, tree);
if (node != null)
{
WorkflowManager workflowManager = WorkflowManager.GetInstance(tree);
WorkflowInfo workflow = workflowManager.GetNodeWorkflow(node);
// Check if the document uses workflow
if (workflow != null)
{
// Check if the workflow doesn't use automatic publishing, otherwise, documents can't change workflow steps.
if (!workflow.WorkflowAutoPublishChanges)
{
// Check if the current user can move the document to the next step
if (workflowManager.CheckStepPermissions(node, WorkflowActionEnum.Approve))
{
// Move the document to the next step
workflowManager.MoveToNextStep(node, null);
return true;
}
else
{
apiMoveToNextStep.ErrorMessage = "You are not authorized to approve the document.";
}
}
else
{
apiMoveToNextStep.ErrorMessage = "The document uses versioning without workflow, changes are published automatically.";
}
}
else
{
apiMoveToNextStep.ErrorMessage = "The document doesn't use workflow.";
}
}
return false;
}
///
/// Moves the document to the previous step in the workflow process. Called when the "Move to previous step" button is pressed.
/// Expects the "CreateExampleObjects" and "MoveToNextStep" method to be run first.
///
private bool MoveToPreviousStep()
{
TreeProvider tree = new TreeProvider(CMSContext.CurrentUser);
// Prepare parameters
string siteName = CMSContext.CurrentSiteName;
string aliasPath = "/API-Example";
string culture = "en-us";
bool combineWithDefaultCulture = false;
string classNames = TreeProvider.ALL_CLASSNAMES;
string where = null;
string orderBy = null;
int maxRelativeLevel = -1;
bool selectOnlyPublished = false;
string columns = null;
// Get the document
TreeNode node = DocumentHelper.GetDocument(siteName, aliasPath, culture, combineWithDefaultCulture, classNames, where, orderBy, maxRelativeLevel, selectOnlyPublished, columns, tree);
if (node != null)
{
WorkflowManager workflowManager = WorkflowManager.GetInstance(tree);
WorkflowInfo workflow = workflowManager.GetNodeWorkflow(node);
// Check if the document uses workflow
if (workflow != null)
{
// Check if the workflow doesn't use automatic publishing, otherwise, documents can't change workflow steps.
if (!workflow.WorkflowAutoPublishChanges)
{
// Check if the current user can move the document to the next step
if (workflowManager.CheckStepPermissions(node, WorkflowActionEnum.Reject))
{
// Move the document to the previous step
workflowManager.MoveToPreviousStep(node, null);
return true;
}
else
{
apiMoveToPreviousStep.ErrorMessage = "You are not authorized to reject the document.";
}
}
else
{
apiMoveToPreviousStep.ErrorMessage = "The document uses versioning without workflow, changes are published automatically.";
}
}
else
{
apiMoveToPreviousStep.ErrorMessage = "The document doesn't use workflow.";
}
}
return false;
}
///
/// Moves the document to the Published step in the workflow process. Called when the "Publish document" button is pressed.
/// Expects the "CreateExampleObjects" method to be run first.
///
private bool PublishDocument()
{
TreeProvider tree = new TreeProvider(CMSContext.CurrentUser);
// Prepare parameters
string siteName = CMSContext.CurrentSiteName;
string aliasPath = "/API-Example";
string culture = "en-us";
bool combineWithDefaultCulture = false;
string classNames = TreeProvider.ALL_CLASSNAMES;
string where = null;
string orderBy = null;
int maxRelativeLevel = -1;
bool selectOnlyPublished = false;
string columns = null;
// Get the document
TreeNode node = DocumentHelper.GetDocument(siteName, aliasPath, culture, combineWithDefaultCulture, classNames, where, orderBy, maxRelativeLevel, selectOnlyPublished, columns, tree);
if (node != null)
{
WorkflowManager workflowManager = WorkflowManager.GetInstance(tree);
WorkflowInfo workflow = workflowManager.GetNodeWorkflow(node);
// Check if the document uses workflow
if (workflow != null)
{
// Publish the document
workflowManager.PublishDocument(node, null);
return true;
}
else
{
apiArchiveDocument.ErrorMessage = "The document doesn't use workflow.";
}
}
return false;
}
///
/// Moves the document to the Archived step in the workflow process. Called when the "Archive document" button is pressed.
/// Expects the "CreateExampleObjects" method to be run first.
///
private bool ArchiveDocument()
{
TreeProvider tree = new TreeProvider(CMSContext.CurrentUser);
// Prepare parameters
string siteName = CMSContext.CurrentSiteName;
string aliasPath = "/API-Example";
string culture = "en-us";
bool combineWithDefaultCulture = false;
string classNames = TreeProvider.ALL_CLASSNAMES;
string where = null;
string orderBy = null;
int maxRelativeLevel = -1;
bool selectOnlyPublished = false;
string columns = null;
// Get the document
TreeNode node = DocumentHelper.GetDocument(siteName, aliasPath, culture, combineWithDefaultCulture, classNames, where, orderBy, maxRelativeLevel, selectOnlyPublished, columns, tree);
if (node != null)
{
WorkflowManager workflowManager = WorkflowManager.GetInstance(tree);
WorkflowInfo workflow = workflowManager.GetNodeWorkflow(node);
// Check if the document uses workflow
if (workflow != null)
{
// Archive the document
workflowManager.ArchiveDocument(node, null);
return true;
}
else
{
apiArchiveDocument.ErrorMessage = "The document doesn't use workflow.";
}
}
return false;
}
#endregion
#region "API examples - Versioning"
///
/// Rolls the document back to a specified document version. Called when the "Rollback version" button is pressed.
/// Expects the "CreateExampleObjects" and at least the "EditDocument" method to be run first.
///
private bool RollbackVersion()
{
TreeProvider tree = new TreeProvider(CMSContext.CurrentUser);
// Prepare parameters
string siteName = CMSContext.CurrentSiteName;
string aliasPath = "/API-Example";
string culture = "en-us";
bool combineWithDefaultCulture = false;
string classNames = TreeProvider.ALL_CLASSNAMES;
string where = null;
string orderBy = null;
int maxRelativeLevel = -1;
bool selectOnlyPublished = false;
string columns = null;
// Get the document
TreeNode node = DocumentHelper.GetDocument(siteName, aliasPath, culture, combineWithDefaultCulture, classNames, where, orderBy, maxRelativeLevel, selectOnlyPublished, columns, tree);
if (node != null)
{
// Prepare the WHERE condition for the oldest document version
where = "DocumentID = " + node.DocumentID;
orderBy = "ModifiedWhen ASC";
int topN = 1;
// Get the version ID
DataSet versionHistory = VersionHistoryInfoProvider.GetVersionHistories(where, orderBy, topN, columns);
if (!DataHelper.DataSourceIsEmpty(versionHistory))
{
// Create the Version history info object
VersionHistoryInfo version = new VersionHistoryInfo(versionHistory.Tables[0].Rows[0]);
VersionManager versionManager = VersionManager.GetInstance(tree);
// Roll back version
versionManager.RollbackVersion(version.VersionHistoryID);
return true;
}
else
{
apiRollbackVersion.ErrorMessage = "The document's version history is empty.";
}
}
return false;
}
///
/// Deletes a specified document version. Called when the "Delete version" button is pressed.
/// Expects the "CreateExampleObjects" and at least the "EditDocument" method to be run first.
///
private bool DeleteVersion()
{
TreeProvider tree = new TreeProvider(CMSContext.CurrentUser);
// Prepare parameters
string siteName = CMSContext.CurrentSiteName;
string aliasPath = "/API-Example";
string culture = "en-us";
bool combineWithDefaultCulture = false;
string classNames = TreeProvider.ALL_CLASSNAMES;
string where = null;
string orderBy = null;
int maxRelativeLevel = -1;
bool selectOnlyPublished = false;
string columns = null;
// Get the document
TreeNode node = DocumentHelper.GetDocument(siteName, aliasPath, culture, combineWithDefaultCulture, classNames, where, orderBy, maxRelativeLevel, selectOnlyPublished, columns, tree);
if (node != null)
{
// Prepare the WHERE condition for the latest document version
where = "DocumentID = " + node.DocumentID;
orderBy = "ModifiedWhen DESC";
int topN = 1;
// Get the version ID
DataSet versionHistory = VersionHistoryInfoProvider.GetVersionHistories(where, orderBy, topN, columns);
if (!DataHelper.DataSourceIsEmpty(versionHistory))
{
// Create the Version history info object
VersionHistoryInfo version = new VersionHistoryInfo(versionHistory.Tables[0].Rows[0]);
VersionManager versionManager = VersionManager.GetInstance(tree);
// Delete the version
versionManager.DestroyDocumentVersion(version.VersionHistoryID);
return true;
}
else
{
apiDeleteVersion.ErrorMessage = "The document's version history is empty.";
}
}
return false;
}
///
/// Destroys the entire document's version history. Called when the "Destroy version history" button is pressed.
/// Expects the "CreateExampleObjects" method to be run first.
///
private bool DestroyHistory()
{
TreeProvider tree = new TreeProvider(CMSContext.CurrentUser);
// Prepare parameters
string siteName = CMSContext.CurrentSiteName;
string aliasPath = "/API-Example";
string culture = "en-us";
bool combineWithDefaultCulture = false;
string classNames = TreeProvider.ALL_CLASSNAMES;
string where = null;
string orderBy = null;
int maxRelativeLevel = -1;
bool selectOnlyPublished = false;
string columns = null;
// Get the document
TreeNode node = DocumentHelper.GetDocument(siteName, aliasPath, culture, combineWithDefaultCulture, classNames, where, orderBy, maxRelativeLevel, selectOnlyPublished, columns, tree);
if (node != null)
{
VersionManager versionManager = VersionManager.GetInstance(tree);
// Destroy the version history
versionManager.DestroyDocumentHistory(node.DocumentID);
return true;
}
return false;
}
#endregion
#region "API examples - Cleanup"
///
/// Deletes the workflow scope, workflow step and the document used for this example. Called when the "Delete example objects" button is pressed.
/// Expects the "CreateExampleObjects" method to be run first.
///
private bool DeleteExampleObjects()
{
TreeProvider tree = new TreeProvider(CMSContext.CurrentUser);
// Get the example document
TreeNode node = tree.SelectSingleNode(CMSContext.CurrentSiteName, "/API-Example", "en-us");
if (node != null)
{
// Delete the document
DocumentHelper.DeleteDocument(node, tree, true, true, true);
}
string where = "ScopeStartingPath LIKE '/API-Example%'";
// Get example workflow scopes
DataSet scopes = WorkflowScopeInfoProvider.GetWorkflowScopes(where, null, 0, null);
if (!DataHelper.DataSourceIsEmpty(scopes))
{
// Loop through all the scopes in case more identical scopes were accidentally created
foreach (DataRow scopeRow in scopes.Tables[0].Rows)
{
// Create scope info object
WorkflowScopeInfo scope = new WorkflowScopeInfo(scopeRow);
// Delete the scope
WorkflowScopeInfoProvider.DeleteWorkflowScopeInfo(scope);
}
}
// Get the default workflow
WorkflowInfo workflow = WorkflowInfoProvider.GetWorkflowInfo("default");
if (workflow != null)
{
// Get the example step
WorkflowStepInfo step = WorkflowStepInfoProvider.GetWorkflowStepInfo("MyNewWorkflowStep", workflow.WorkflowID);
if (step != null)
{
// Delete the step
WorkflowStepInfoProvider.DeleteWorkflowStepInfo(step);
}
}
return true;
}
#endregion
}