using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Security.Principal; using System.Text; using System.Threading; using CMS.DataEngine; using CMS.EventLog; using CMS.GlobalHelper; using CMS.OnlineMarketing; using CMS.SettingsProvider; using CMS.UIControls; public partial class CMSModules_ContactManagement_Pages_Tools_Account_Delete : CMSContactManagementAccountsPage { #region "Private variables" private IList accountIds = null; private int accountSiteId = 0; private static readonly Hashtable mErrors = new Hashtable(); private Hashtable mParameters = null; private string mReturnScript = null; private int mSiteID = 0; private bool issitemanager = false; private int numberOfDeletedAccounts = 0; #endregion #region "Properties" /// /// Current log context. /// public LogContext CurrentLog { get { return EnsureLog(); } } /// /// Current Error. /// private string CurrentError { get { return ValidationHelper.GetString(mErrors["DeleteError_" + ctlAsync.ProcessGUID], string.Empty); } set { mErrors["DeleteError_" + ctlAsync.ProcessGUID] = value; } } /// /// Where condition used for multiple actions. /// private string WhereCondition { get { string where = string.Empty; if (Parameters != null) { where = ValidationHelper.GetString(Parameters["where"], string.Empty); } return where; } } /// /// Hashtable containing dialog parameters. /// private Hashtable Parameters { get { if (mParameters == null) { string identifier = QueryHelper.GetString("params", null); mParameters = (Hashtable)WindowHelper.GetItem(identifier); } return mParameters; } } /// /// Returns script for returning back to list page. /// private string ReturnScript { get { if (string.IsNullOrEmpty(mReturnScript) && (Parameters != null)) { mReturnScript = "document.location.href = 'List.aspx?siteid=" + SiteID + (issitemanager ? "&issitemanager=1" : string.Empty) + "';"; } return mReturnScript; } } /// /// Returns script for returning back to list page with information that deleting process has been started. /// private string ReturnScriptDeleteAsync { get { if (string.IsNullOrEmpty(mReturnScript) && (Parameters != null)) { mReturnScript = "document.location.href = 'List.aspx?siteid=" + SiteID + (issitemanager ? "&issitemanager=1" : string.Empty) + "&deleteasync=1';"; } return mReturnScript; } } /// /// Site ID retrieved from dialog parameters. /// public override int SiteID { get { if ((mSiteID == 0) && (Parameters != null)) { mSiteID = ValidationHelper.GetInteger(Parameters["siteid"], 0); } ; return mSiteID; } } #endregion #region "Page events" protected void Page_Load(object sender, EventArgs e) { // Check hash validity if (QueryHelper.ValidateHash("hash")) { // Initialize events ctlAsync.OnFinished += ctlAsync_OnFinished; ctlAsync.OnError += ctlAsync_OnError; ctlAsync.OnRequestLog += ctlAsync_OnRequestLog; ctlAsync.OnCancel += ctlAsync_OnCancel; issitemanager = ValidationHelper.GetBoolean(Parameters["issitemanager"], false); if (!RequestHelper.IsCallback()) { // Setup page title text and image CurrentMaster.Title.TitleText = GetString("om.account.deletetitle"); CurrentMaster.Title.TitleImage = GetImageUrl("Objects/OM_Account/delete.png"); btnCancel.Attributes.Add("onclick", ctlAsync.GetCancelScript(true) + "return false;"); titleElemAsync.TitleText = GetString("om.account.deleting"); titleElemAsync.TitleImage = GetImageUrl("Objects/OM_Account/delete.png"); // Set visibility of panels pnlContent.Visible = true; pnlLog.Visible = false; // Get names of the accounts that are to be deleted DataSet ds = AccountInfoProvider.GetAccounts(WhereCondition, "AccountName", 1000, "AccountID, AccountName, AccountSiteID"); if (!DataHelper.DataSourceIsEmpty(ds)) { DataRowCollection rows = ds.Tables[0].Rows; // Data set contains only one item if (rows.Count == 1) { CurrentMaster.Title.TitleText += " \"" + HTMLHelper.HTMLEncode(ValidationHelper.GetString(DataHelper.GetDataRowValue(rows[0], "AccountName"), "N/A")) + "\""; accountIds = new List(1); accountIds.Add(ValidationHelper.GetString(DataHelper.GetDataRowValue(rows[0], "AccountID"), string.Empty)); accountSiteId = ValidationHelper.GetInteger(DataHelper.GetDataRowValue(rows[0], "AccountSiteID"), 0); numberOfDeletedAccounts = 1; } else if (rows.Count > 1) { // Modify title and question for multiple items CurrentMaster.Title.TitleText = GetString("om.account.deletetitlemultiple"); lblQuestion.ResourceString = "om.account.deletemultiplequestion"; // Display list with names of deleted items pnlAccountList.Visible = true; string name = null; StringBuilder builder = new StringBuilder(); for (int i = 0; i < rows.Count; i++) { name = ValidationHelper.GetString(DataHelper.GetDataRowValue(rows[i], "AccountName"), string.Empty); builder.Append(HTMLHelper.HTMLEncode(name)); builder.Append("
"); } // Display three dots after last record if (rows.Count == 1000) { builder.Append("..."); } lblAccounts.Text = builder.ToString(); accountSiteId = SiteID; // Get all IDs of deleted items ds = AccountInfoProvider.GetAccounts(WhereCondition, "AccountID", 0, "AccountID"); accountIds = SystemDataHelper.GetStringValues(ds.Tables[0], "AccountID"); numberOfDeletedAccounts = ds.Tables[0].Rows.Count; } } else { // Hide everything pnlContent.Visible = false; } } } else { pnlDelete.Visible = false; ShowError(GetString("dialogs.badhashtext")); } } protected override void OnPreRender(EventArgs e) { // Set visibility of controls brSeparator.Visible = pnlAccountList.Visible; btnNo.OnClientClick = ReturnScript + "return false;"; base.OnPreRender(e); } #endregion #region "Button actions" protected void btnOK_Click(object sender, EventArgs e) { // Check permissions if (AccountHelper.AuthorizedModifyAccount(accountSiteId, true)) { EnsureAsyncLog(); RunAsyncDelete(); } } #endregion #region "Methods" /// /// Ensures log for asynchronous control /// private void EnsureAsyncLog() { pnlLog.Visible = true; pnlContent.Visible = false; CurrentError = string.Empty; CurrentLog.Close(); EnsureLog(); } /// /// Starts asynchronous deleting of contacts. /// private void RunAsyncDelete() { // Run the async method ctlAsync.Parameter = ReturnScript; ctlAsync.RunAsync(Delete, WindowsIdentity.GetCurrent()); } /// /// Deletes document(s). /// private void Delete(object parameter) { if (parameter == null || accountIds.Count < 1) { return; } try { // Begin log AddLog(GetString("om.account.deleting")); AddLog(string.Empty); // When deleting children and not removing relations then we can run if (chkChildren.Checked && (numberOfDeletedAccounts > 1)) { BatchDeleteOnSql(); } else { DeleteItems(); } } catch (ThreadAbortException ex) { string state = ValidationHelper.GetString(ex.ExceptionState, string.Empty); if (state == CMSThread.ABORT_REASON_STOP) { // When canceled AddError(GetString("om.deletioncanceled")); } else { // Log error LogExceptionToEventLog(ex); } } catch (Exception ex) { // Log error LogExceptionToEventLog(ex); } } /// /// Delete accounts on SQL server. /// private void BatchDeleteOnSql() { StringBuilder where = new StringBuilder("AccountID IN ("); // Create where condition for deleting accounts int i; for (i = 0; i < accountIds.Count; i++) { where.Append(accountIds[i] + ","); // Delete accounts by 100's if ((i + 1) % 100 == 0) { BatchDeleteItems(where); where = new StringBuilder("AccountID IN ("); } } // Delete rest of the accounts if (i % 100 != 0) { BatchDeleteItems(where); } // Return to the list page with info label displayed ltlScript.Text += ScriptHelper.GetScript(ReturnScriptDeleteAsync); } /// /// Deletes group of accounts on SQL server. /// /// WHERE specifying group of accounts private void BatchDeleteItems(StringBuilder where) { where.Remove(where.Length - 1, 1); where.Append(")"); AccountInfoProvider.DeleteAccountInfos(where.ToString(), chkBranches.Checked); } /// /// Delete items. /// private void DeleteItems() { // Delete the accounts AccountInfo ai = null; foreach (string accountId in accountIds) { ai = AccountInfoProvider.GetAccountInfo(ValidationHelper.GetInteger(accountId, 0)); if (ai != null) { // Display name of deleted account AddLog(ai.AccountName); // Delete account with its dependencies AccountHelper.Delete(ai, chkChildren.Checked, chkBranches.Checked); } } } #endregion #region "Async methods" private void ctlAsync_OnCancel(object sender, EventArgs e) { ctlAsync.Parameter = null; string canceled = GetString("om.deletioncanceled"); AddLog(canceled); ltlScript.Text += ScriptHelper.GetScript("var __pendingCallbacks = new Array();RefreshCurrent();"); if (!String.IsNullOrEmpty(CurrentError)) { ShowError(CurrentError); } ShowConfirmation(canceled); CurrentLog.Close(); } private void ctlAsync_OnRequestLog(object sender, EventArgs e) { ctlAsync.Log = CurrentLog.Log; } private void ctlAsync_OnError(object sender, EventArgs e) { if (ctlAsync.Status == AsyncWorkerStatusEnum.Running) { ctlAsync.Stop(); } ctlAsync.Parameter = null; if (!String.IsNullOrEmpty(CurrentError)) { ShowError(CurrentError); } CurrentLog.Close(); } private void ctlAsync_OnFinished(object sender, EventArgs e) { CurrentLog.Close(); if (!string.IsNullOrEmpty(CurrentError)) { ctlAsync.Parameter = null; ShowError(CurrentError); } if (ctlAsync.Parameter != null) { // Return to the list page after successful deletion ltlScript.Text += ScriptHelper.GetScript(ctlAsync.Parameter.ToString()); // Do not set the window title anymore CurrentMaster.Title.SetWindowTitle = false; } } /// /// Ensures the logging context. /// protected LogContext EnsureLog() { LogContext log = LogContext.EnsureLog(ctlAsync.ProcessGUID); log.Reversed = true; log.LineSeparator = "
"; return log; } /// /// Adds the log information. /// /// New log information protected void AddLog(string newLog) { EnsureLog(); LogContext.AppendLine(newLog); } /// /// Adds the error to collection of errors. /// /// Error message protected void AddError(string error) { AddLog(error); CurrentError = (error + "
" + CurrentError); } /// /// When exception occurs, log it to event log. /// /// Exception to log private void LogExceptionToEventLog(Exception ex) { EventLogProvider.LogException("Contact management", "DELETEACCOUNT", ex); AddError(GetString("om.account.deletefailed") + ": " + ex.Message); } #endregion }