HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/RMourik/bassol.nl/CMS/CMSModules/Workflows/Workflow_Documents.aspx.cs
using System;
using System.Data;
using System.Collections;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Web.UI.WebControls;
using System.Linq;

using CMS.DataEngine;
using CMS.EventLog;
using CMS.Helpers;
using CMS.Base;
using CMS.DocumentEngine;
using CMS.SiteProvider;
using CMS.UIControls;
using CMS.WorkflowEngine;
using CMS.Membership;

using TreeNode = CMS.DocumentEngine.TreeNode;

public partial class CMSModules_Workflows_Workflow_Documents : CMSWorkflowPage
{
    #region "Private variables & enumerations"

    private CurrentUserInfo currentUser;
    private string currentCulture = CultureHelper.DefaultUICultureCode;

    private static readonly Hashtable mInfos = new Hashtable();

    private const string GET_WORKFLOW_DOCS_WHERE = "DocumentWorkflowStepID IN (SELECT StepID FROM CMS_WorkflowStep WHERE StepWorkflowID = {0})";

    private enum Action
    {
        SelectAction = 0,
        PublishAndFinish = 1,
        RemoveWorkflow = 2
    }

    protected enum What
    {
        SelectedDocuments = 0,
        AllDocuments = 1
    }

    private What currentWhat = default(What);

    #endregion


    #region "Properties"

    /// <summary>
    /// Current log context.
    /// </summary>
    public LogContext CurrentLog
    {
        get
        {
            return EnsureLog();
        }
    }


    /// <summary>
    /// Current Error.
    /// </summary>
    private string CurrentError
    {
        get
        {
            return ValidationHelper.GetString(mInfos["WorkflowError_" + ctlAsyncLog.ProcessGUID], string.Empty);
        }
        set
        {
            mInfos["WorkflowError_" + ctlAsyncLog.ProcessGUID] = value;
        }
    }


    /// <summary>
    /// Current Info.
    /// </summary>
    private string CurrentInfo
    {
        get
        {
            return ValidationHelper.GetString(mInfos["WorkflowInfo_" + ctlAsyncLog.ProcessGUID], string.Empty);
        }
        set
        {
            mInfos["WorkflowInfo_" + ctlAsyncLog.ProcessGUID] = value;
        }
    }


    /// <summary>
    /// Gets or sets the cancel string.
    /// </summary>
    public string CanceledString
    {
        get
        {
            return ValidationHelper.GetString(mInfos["CanceledString_" + ctlAsyncLog.ProcessGUID], string.Empty);
        }
        set
        {
            mInfos["CanceledString_" + ctlAsyncLog.ProcessGUID] = value;
        }
    }

    #endregion


    #region "Page events"

    protected void Page_Load(object sender, EventArgs e)
    {
        currentUser = MembershipContext.AuthenticatedUser;
        currentCulture = CultureHelper.PreferredUICultureCode;

        // Initialize events
        ctlAsyncLog.OnFinished += ctlAsyncLog_OnFinished;
        ctlAsyncLog.OnError += ctlAsyncLog_OnError;
        ctlAsyncLog.OnRequestLog += ctlAsyncLog_OnRequestLog;
        ctlAsyncLog.OnCancel += ctlAsyncLog_OnCancel;

        if (!RequestHelper.IsCallback())
        {
            // Set visibility of panels
            pnlContent.Visible = true;
            pnlLog.Visible = false;

            // Initialize unigrid
            docElem.ZeroRowsText = GetString(filterDocuments.FilterIsSet ? "unigrid.filteredzerorowstext" : "workflowdocuments.nodata");
            docElem.UniGrid.OnAfterDataReload += UniGrid_OnAfterDataReload;
            docElem.UniGrid.OnBeforeDataReload += UniGrid_OnBeforeDataReload;
            docElem.Tree = Tree;

            // Create action script
            StringBuilder actionScript = new StringBuilder();
            actionScript.AppendLine("function PerformAction(selectionFunction, selectionField, dropId)");
            actionScript.AppendLine("{");
            actionScript.AppendLine("   var selectionFieldElem = document.getElementById(selectionField);");
            actionScript.AppendLine("   var label = document.getElementById('" + lblValidation.ClientID + "');");
            actionScript.AppendLine("   var items = selectionFieldElem.value;");
            actionScript.AppendLine("   var whatDrp = document.getElementById('" + drpWhat.ClientID + "');");
            actionScript.AppendLine("   var action = document.getElementById(dropId).value;");
            actionScript.AppendLine("   if (action == '" + (int)Action.SelectAction + "')");
            actionScript.AppendLine("   {");
            actionScript.AppendLine("       label.innerHTML = " + ScriptHelper.GetLocalizedString("massaction.selectsomeaction") + ";");
            actionScript.AppendLine("       return false;");
            actionScript.AppendLine("   }");
            actionScript.AppendLine("   if(!eval(selectionFunction) || whatDrp.value == '" + (int)What.AllDocuments + "')");
            actionScript.AppendLine("   {");
            actionScript.AppendLine("       var confirmed = false;");
            actionScript.AppendLine("       var confMessage = '';");
            actionScript.AppendLine("       switch(action)");
            actionScript.AppendLine("       {");
            actionScript.AppendLine("           case '" + (int)Action.PublishAndFinish + "':");
            actionScript.AppendLine("               confMessage = " + ScriptHelper.GetLocalizedString("workflowdocuments.confrimpublish") + ";");
            actionScript.AppendLine("               break;");
            actionScript.AppendLine("           case '" + (int)Action.RemoveWorkflow + "':");
            actionScript.AppendLine("               confMessage = " + ScriptHelper.GetLocalizedString("workflowdocuments.confirmremove") + ";");
            actionScript.AppendLine("               break;");
            actionScript.AppendLine("       }");
            actionScript.AppendLine("       return confirm(confMessage);");
            actionScript.AppendLine("   }");
            actionScript.AppendLine("   else");
            actionScript.AppendLine("   {");
            actionScript.AppendLine("       label.innerHTML = " + ScriptHelper.GetLocalizedString("documents.selectdocuments") + ";");
            actionScript.AppendLine("       return false;");
            actionScript.AppendLine("   }");
            actionScript.AppendLine("}");
            ScriptHelper.RegisterClientScriptBlock(this, typeof(string), "actionScript", ScriptHelper.GetScript(actionScript.ToString()));

            // Add action to button
            btnOk.OnClientClick = "return PerformAction('" + docElem.UniGrid.GetCheckSelectionScript() + "','" + docElem.UniGrid.GetSelectionFieldClientID() + "','" + drpAction.ClientID + "');";

            // Initialize dropdown list with actions
            if (!RequestHelper.IsPostBack())
            {
                if (currentUser.IsGlobalAdministrator || currentUser.IsAuthorizedPerResource("CMS.Content", "manageworkflow"))
                {
                    drpAction.Items.Add(new ListItem(ResHelper.GetString("general." + Action.SelectAction), Convert.ToInt32(Action.SelectAction).ToString()));
                    drpAction.Items.Add(new ListItem(ResHelper.GetString("workflowdocuments." + Action.PublishAndFinish), Convert.ToInt32(Action.PublishAndFinish).ToString()));
                    drpAction.Items.Add(new ListItem(ResHelper.GetString("workflowdocuments." + Action.RemoveWorkflow), Convert.ToInt32(Action.RemoveWorkflow).ToString()));
                }

                drpWhat.Items.Add(new ListItem(ResHelper.GetString("contentlisting." + What.SelectedDocuments), Convert.ToInt32(What.SelectedDocuments).ToString()));
                drpWhat.Items.Add(new ListItem(ResHelper.GetString("contentlisting." + What.AllDocuments), Convert.ToInt32(What.AllDocuments).ToString()));
            }
        }
        docElem.SiteName = filterDocuments.SelectedSite;
    }

    #endregion


    #region "Other events"

    protected void UniGrid_OnBeforeDataReload()
    {
        string where = string.Format(GET_WORKFLOW_DOCS_WHERE, WorkflowId);
        where = SqlHelper.AddWhereCondition(where, filterDocuments.WhereCondition);
        docElem.UniGrid.WhereCondition = SqlHelper.AddWhereCondition(docElem.UniGrid.WhereCondition, where);
    }


    protected void UniGrid_OnAfterDataReload()
    {
        plcFilter.Visible = docElem.UniGrid.DisplayExternalFilter(filterDocuments.FilterIsSet);
        pnlFooter.Visible = !DataHelper.DataSourceIsEmpty(docElem.UniGrid.GridView.DataSource);
    }

    #endregion


    #region "Button handling"

    protected void btnOk_OnClick(object sender, EventArgs e)
    {
        pnlLog.Visible = true;
        pnlContent.Visible = false;

        CurrentError = string.Empty;
        EnsureLog();

        int actionValue = ValidationHelper.GetInteger(drpAction.SelectedValue, 0);
        Action action = (Action)actionValue;

        int whatValue = ValidationHelper.GetInteger(drpWhat.SelectedValue, 0);
        currentWhat = (What)whatValue;

        ctlAsyncLog.Parameter = GetCurrentWhere();
        switch (action)
        {
            case Action.PublishAndFinish:
                // Publish and finish workflow
                ctlAsyncLog.TitleText = GetString("content.publishingdocuments");
                ctlAsyncLog.RunAsync(PublishAndFinish, WindowsIdentity.GetCurrent());
                break;

            case Action.RemoveWorkflow:
                // Remove workflow
                ctlAsyncLog.TitleText = GetString("workflowdocuments.removingwf");
                ctlAsyncLog.RunAsync(RemoveWorkflow, WindowsIdentity.GetCurrent());
                break;
        }
    }

    #endregion


    #region "Thread methods"

    private void PublishAndFinish(object parameter)
    {
        TreeNode node = null;
        Tree.AllowAsyncActions = false;
        CanceledString = ResHelper.GetString("content.publishcanceled", currentCulture);
        try
        {
            // Begin log
            AddLog(ResHelper.GetString("content.preparingdocuments", currentCulture));

            string where = parameter as string;

            // Get the documents
            DataSet documents = GetDocumentsToProcess(where);

            if (!DataHelper.DataSourceIsEmpty(documents))
            {
                // Create instance of workflow manager class
                WorkflowManager wm = WorkflowManager.GetInstance(Tree);

                // Begin publishing
                AddLog(ResHelper.GetString("content.publishingdocuments", currentCulture));
                foreach (DataTable classTable in documents.Tables)
                {
                    foreach (DataRow nodeRow in classTable.Rows)
                    {
                        // Get the current document
                        string className = ValidationHelper.GetString(nodeRow["ClassName"], string.Empty);
                        string aliasPath = ValidationHelper.GetString(nodeRow["NodeAliasPath"], string.Empty);
                        string docCulture = ValidationHelper.GetString(nodeRow["DocumentCulture"], string.Empty);
                        string siteName = ValidationHelper.GetString(nodeRow["SiteName"], string.Empty);

                        node = DocumentHelper.GetDocument(siteName, aliasPath, docCulture, false, className, null, null, -1, false, null, Tree);

                        // Publish document
                        if (Publish(node, wm))
                        {
                            return;
                        }
                    }
                }

                CurrentInfo = GetString("workflowdocuments.publishcomplete");
            }
            else
            {
                AddError(ResHelper.GetString("content.nothingtopublish", currentCulture));
            }
        }
        catch (ThreadAbortException ex)
        {
            string state = ValidationHelper.GetString(ex.ExceptionState, string.Empty);
            if (state == CMSThread.ABORT_REASON_STOP)
            {
                // When canceled
                CurrentInfo = CanceledString;
            }
            else
            {
                int siteId = (node != null) ? node.NodeSiteID : SiteContext.CurrentSiteID;
                // Log error
                LogExceptionToEventLog("PUBLISHDOC", "content.publishfailed", ex, siteId);
            }
        }
        catch (Exception ex)
        {
            int siteId = (node != null) ? node.NodeSiteID : SiteContext.CurrentSiteID;
            // Log error
            LogExceptionToEventLog("PUBLISHDOC", "content.publishfailed", ex, siteId);
        }
    }


    private void RemoveWorkflow(object parameter)
    {
        VersionManager verMan = VersionManager.GetInstance(Tree);
        TreeNode node = null;
        // Custom logging
        Tree.LogEvents = false;
        Tree.AllowAsyncActions = false;
        CanceledString = ResHelper.GetString("workflowdocuments.removingcanceled", currentCulture);
        try
        {
            // Begin log
            AddLog(ResHelper.GetString("content.preparingdocuments", currentCulture));

            string where = parameter as string;

            // Get the documents
            DataSet documents = GetDocumentsToProcess(where);

            if (!DataHelper.DataSourceIsEmpty(documents))
            {
                // Begin log
                AddLog(ResHelper.GetString("workflowdocuments.removingwf", currentCulture));

                foreach (DataTable classTable in documents.Tables)
                {
                    foreach (DataRow nodeRow in classTable.Rows)
                    {
                        // Get the current document
                        string className = ValidationHelper.GetString(nodeRow["ClassName"], string.Empty);
                        string aliasPath = ValidationHelper.GetString(nodeRow["NodeAliasPath"], string.Empty);
                        string docCulture = ValidationHelper.GetString(nodeRow["DocumentCulture"], string.Empty);
                        string siteName = ValidationHelper.GetString(nodeRow["SiteName"], string.Empty);

                        // Get published version
                        node = Tree.SelectSingleNode(siteName, aliasPath, docCulture, false, className, false);
                        string encodedAliasPath = HTMLHelper.HTMLEncode(ValidationHelper.GetString(aliasPath, string.Empty) + " (" + node.GetValue("DocumentCulture") + ")");

                        // Destroy document history
                        verMan.DestroyDocumentHistory(node.DocumentID);

                        using (new CMSActionContext { LogEvents = false })
                        {
                            // Clear workflow
                            DocumentHelper.ClearWorkflowInformation(node);
                            node.Update();
                        }

                        // Add log record
                        AddLog(encodedAliasPath);

                        // Add record to eventlog
                        LogContext.LogEvent(EventType.INFORMATION, "Content", "REMOVEDOCWORKFLOW", string.Format(GetString("workflowdocuments.removeworkflowsuccess"), encodedAliasPath), RequestContext.RawURL, currentUser.UserID, currentUser.UserName, node.NodeID, node.GetDocumentName(), RequestContext.UserHostAddress, node.NodeSiteID, SystemContext.MachineName, RequestContext.URLReferrer, RequestContext.UserAgent, DateTime.Now);
                    }
                }
                CurrentInfo = GetString("workflowdocuments.removecomplete");
            }
            else
            {
                AddError(ResHelper.GetString("workflowdocuments.nodocumentstoclear", currentCulture));
            }
        }
        catch (ThreadAbortException ex)
        {
            string state = ValidationHelper.GetString(ex.ExceptionState, string.Empty);
            if (state == CMSThread.ABORT_REASON_STOP)
            {
                // When canceled
                CurrentInfo = CanceledString;
            }
            else
            {
                int siteId = (node != null) ? node.NodeSiteID : SiteContext.CurrentSiteID;
                // Log error
                LogExceptionToEventLog("REMOVEDOCWORKFLOW", "workflowdocuments.removefailed", ex, siteId);
            }
        }
        catch (Exception ex)
        {
            int siteId = (node != null) ? node.NodeSiteID : SiteContext.CurrentSiteID;
            // Log error
            LogExceptionToEventLog("REMOVEDOCWORKFLOW", "workflowdocuments.removefailed", ex, siteId);
        }
    }

    #endregion


    #region "Private methods"

    /// <summary>
    /// Gets a set of documents to be processed.
    /// </summary>
    /// <returns>Set of documents based on where condition and other settings</returns>
    private DataSet GetDocumentsToProcess(string where)
    {
        string columns = SqlHelper.MergeColumns(TreeProvider.SELECTNODES_REQUIRED_COLUMNS, "NodeAliasPath, ClassName, DocumentCulture, SiteName");
        return DocumentHelper.GetDocuments(TreeProvider.ALL_SITES, "/%", TreeProvider.ALL_CULTURES, false, TreeProvider.ALL_CLASSNAMES, where, "NodeAliasPath DESC", -1, false, -1, columns, Tree);
    }


    /// <summary>
    /// Gets current where condition.
    /// </summary>
    /// <returns>Where condition determining documents to process</returns>
    private string GetCurrentWhere()
    {
        var documentIds = docElem.UniGrid.SelectedItems;

        // Prepare the where condition
        var condition = new WhereCondition();

        if (currentWhat == What.SelectedDocuments)
        {
            // Get where for selected documents
            condition.WhereIn("DocumentID", documentIds.ToList());
        }
        else
        {
            if (!string.IsNullOrEmpty(filterDocuments.WhereCondition))
            {
                // Add filter condition
                condition.Where(filterDocuments.WhereCondition);
            }

            // Select documents only under current workflow
            condition.WhereIn("DocumentWorkflowStepID", new IDQuery<WorkflowStepInfo>().WhereEquals("StepWorkflowID", WorkflowId));
        }
        return condition.ToString(true);
    }


    /// <summary>
    /// When exception occurs, log it to event log.
    /// </summary>
    /// <param name="eventCode">Code of event</param>
    /// <param name="errorTitle">Message to log to asynchronous log</param>
    /// <param name="ex">Exception to log</param>
    /// <param name="siteId">ID of site</param>
    private void LogExceptionToEventLog(string eventCode, string errorTitle, Exception ex, int siteId)
    {
        AddError(ResHelper.GetString(errorTitle, currentCulture) + ": " + ex.Message);
        LogContext.LogEvent(EventType.ERROR, "Content", eventCode, EventLogProvider.GetExceptionLogMessage(ex), RequestContext.RawURL, currentUser.UserID, currentUser.UserName, 0, null, RequestContext.UserHostAddress, siteId, SystemContext.MachineName, RequestContext.URLReferrer, RequestContext.UserAgent, DateTime.Now);
    }


    /// <summary>
    /// Publishes document.
    /// </summary>
    /// <param name="node">Node to publish</param>
    /// <param name="wm">Workflow manager</param>
    /// <returns>Whether node is already published</returns>
    private bool Publish(TreeNode node, WorkflowManager wm)
    {
        string pathCulture = HTMLHelper.HTMLEncode(node.NodeAliasPath + " (" + node.DocumentCulture + ")");
        WorkflowStepInfo currentStep = wm.GetStepInfo(node);
        bool alreadyPublished = (currentStep == null) || currentStep.StepIsPublished;

        if (!alreadyPublished)
        {
            using (new CMSActionContext { LogEvents = false })
            {
                // Remove possible checkout
                if (node.DocumentCheckedOutByUserID > 0)
                {
                    TreeProvider.ClearCheckoutInformation(node);
                    node.Update();
                }
            }

            // Publish document
            currentStep = wm.PublishDocument(node);
        }

        // Document is already published, check if still under workflow
        if (alreadyPublished && (currentStep != null) && currentStep.StepIsPublished)
        {
            WorkflowScopeInfo wsi = wm.GetNodeWorkflowScope(node);
            if (wsi == null)
            {
                VersionManager vm = VersionManager.GetInstance(node.TreeProvider);
                vm.RemoveWorkflow(node);
            }
        }

        // Document already published
        if (alreadyPublished)
        {
            AddLog(string.Format(ResHelper.GetString("content.publishedalready"), pathCulture));
        }
        else if ((currentStep == null) || !currentStep.StepIsPublished)
        {
            AddError(string.Format(ResHelper.GetString("content.PublishWasApproved"), pathCulture));
            return true;
        }
        else
        {
            // Add log record
            AddLog(pathCulture);
        }

        return false;
    }


    private void HandlePossibleError()
    {
        if (!string.IsNullOrEmpty(CurrentError))
        {
            ShowError(CurrentError);
        }
        if (!string.IsNullOrEmpty(CurrentInfo))
        {
            ShowConfirmation(CurrentInfo);
        }
        // Clear selection
        docElem.UniGrid.ResetSelection();
        CurrentLog.Close();
    }


    /// <summary>
    /// Ensures the logging context.
    /// </summary>
    protected LogContext EnsureLog()
    {
        LogContext log = LogContext.EnsureLog(ctlAsyncLog.ProcessGUID);

        return log;
    }


    /// <summary>
    /// Adds the log information.
    /// </summary>
    /// <param name="newLog">New log information</param>
    protected void AddLog(string newLog)
    {
        EnsureLog();
        LogContext.AppendLine(newLog);
    }


    /// <summary>
    /// Adds the error to collection of errors.
    /// </summary>
    /// <param name="error">Error message</param>
    protected void AddError(string error)
    {
        AddLog(error);
        CurrentError = (error + "<br />" + CurrentError);
    }

    #endregion


    #region "Handling async thread"

    private void ctlAsyncLog_OnCancel(object sender, EventArgs e)
    {
        CurrentInfo = CanceledString;
        ltlScript.Text += ScriptHelper.GetScript("var __pendingCallbacks = new Array();");
        HandlePossibleError();
    }


    private void ctlAsyncLog_OnRequestLog(object sender, EventArgs e)
    {
        ctlAsyncLog.LogContext = CurrentLog;
    }


    private void ctlAsyncLog_OnError(object sender, EventArgs e)
    {
        HandlePossibleError();
    }


    private void ctlAsyncLog_OnFinished(object sender, EventArgs e)
    {
        HandlePossibleError();
    }

    #endregion
}