File: D:/HostingSpaces/RMourik/bassol.nl/wwwroot/CMSModules/Content/CMSDesk/Delete.aspx.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Security.Principal;
using System.Threading;
using System.Web.UI.WebControls;
using CMS.DataEngine;
using CMS.EventLog;
using CMS.ExtendedControls;
using CMS.ExtendedControls.ActionsConfig;
using CMS.Helpers;
using CMS.LicenseProvider;
using CMS.Base;
using CMS.Localization;
using CMS.SiteProvider;
using CMS.Membership;
using CMS.DocumentEngine;
using CMS.UIControls;
using TreeNode = CMS.DocumentEngine.TreeNode;
public partial class CMSModules_Content_CMSDesk_Delete : CMSContentPage
{
#region "Constants"
private const string DELETE_COMMAND = "delete";
#endregion
#region "Private variables"
private readonly List<int> nodeIds = new List<int>();
private string[] nodeIdsArr;
private int cancelNodeId;
private string mCultureCode;
private CurrentUserInfo currentUser;
private SiteInfo currentSite;
private static readonly Hashtable mErrors = new Hashtable();
private Hashtable mParameters;
private string currentCulture = CultureHelper.DefaultUICultureCode;
bool hasChildren;
#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(mErrors["DeleteError_" + ctlAsyncLog.ProcessGUID], string.Empty);
}
set
{
mErrors["DeleteError_" + ctlAsyncLog.ProcessGUID] = value;
}
}
/// <summary>
/// Indicates whether action is multiple.
/// </summary>
private bool IsMultipleAction
{
get
{
return QueryHelper.GetBoolean("multiple", false);
}
}
/// <summary>
/// Indicates whether action is multiple.
/// </summary>
private bool AllLevels
{
get
{
return QueryHelper.GetBoolean("alllevels", false);
}
}
/// <summary>
/// Gets selected class ID.
/// </summary>
private int ClassID
{
get
{
return QueryHelper.GetInteger("classid", 0);
}
}
/// <summary>
/// Culture to delete. (When deleting specific culture.)
/// </summary>
public override string CultureCode
{
get
{
return mCultureCode ?? (mCultureCode = QueryHelper.GetString("culture", LocalizationContext.PreferredCultureCode));
}
}
/// <summary>
/// Where condition used for multiple actions.
/// </summary>
private string WhereCondition
{
get
{
string where = string.Empty;
if (Parameters != null)
{
where = ValidationHelper.GetString(Parameters["where"], string.Empty);
}
return where;
}
}
/// <summary>
/// Hashtable containing dialog parameters.
/// </summary>
private Hashtable Parameters
{
get
{
if (mParameters == null)
{
string identifier = QueryHelper.GetString("params", null);
mParameters = (Hashtable)WindowHelper.GetItem(identifier);
}
return mParameters;
}
}
/// <summary>
/// Indicates if deleting products/products section in ecommerce context.
/// </summary>
private bool IsProductsMode
{
get
{
return QueryHelper.GetString("mode", "").ToLowerCSafe() == "productssection";
}
}
/// <summary>
/// Indicates if page shown in products UI
/// </summary>
protected override bool IsProductsUI
{
get
{
return IsProductsMode;
}
}
#endregion
#region "Page events"
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
EnsureDocumentManager = false;
// Perform check manually
CheckDocPermissions = false;
}
protected void Page_Load(object sender, EventArgs e)
{
// Register script files
ScriptHelper.RegisterCMS(this);
ScriptHelper.RegisterScriptFile(this, "~/CMSModules/Content/CMSDesk/Operation.js");
// Set current UI culture
currentCulture = CultureHelper.PreferredUICultureCode;
// Initialize current user
currentUser = MembershipContext.AuthenticatedUser;
// Initialize current site
currentSite = SiteContext.CurrentSite;
// Initialize events
ctlAsyncLog.OnFinished += ctlAsyncLog_OnFinished;
ctlAsyncLog.OnError += ctlAsyncLog_OnError;
ctlAsyncLog.OnRequestLog += ctlAsyncLog_OnRequestLog;
ctlAsyncLog.OnCancel += ctlAsyncLog_OnCancel;
if (!RequestHelper.IsCallback())
{
DataSet allDocs = null;
TreeProvider tree = new TreeProvider(currentUser);
// Current Node ID to delete
string parentAliasPath = string.Empty;
if (Parameters != null)
{
parentAliasPath = ValidationHelper.GetString(Parameters["parentaliaspath"], string.Empty);
}
if (string.IsNullOrEmpty(parentAliasPath))
{
nodeIdsArr = QueryHelper.GetString("nodeid", string.Empty).Trim('|').Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string nodeId in nodeIdsArr)
{
int id = ValidationHelper.GetInteger(nodeId, 0);
if (id != 0)
{
nodeIds.Add(id);
}
}
}
else
{
string where = "ClassName <> 'CMS.Root'";
if (!string.IsNullOrEmpty(WhereCondition))
{
where = SqlHelper.AddWhereCondition(where, WhereCondition);
}
allDocs = tree.SelectNodes(currentSite.SiteName, parentAliasPath.TrimEnd(new[] { '/' }) + "/%",
TreeProvider.ALL_CULTURES, true, ClassID > 0 ? DataClassInfoProvider.GetClassName(ClassID) : TreeProvider.ALL_CLASSNAMES, where,
"DocumentName", TreeProvider.ALL_LEVELS, false, 0,
TreeProvider.SELECTNODES_REQUIRED_COLUMNS + ",DocumentName,NodeParentID,NodeSiteID,NodeAliasPath,NodeSKUID");
if (!DataHelper.DataSourceIsEmpty(allDocs))
{
foreach (DataTable table in allDocs.Tables)
{
foreach (DataRow row in table.Rows)
{
nodeIds.Add(ValidationHelper.GetInteger(row["NodeID"], 0));
}
}
}
}
// Setup page title text and image
PageTitle.TitleText = GetString("Content.DeleteTitle");
EnsureDocumentBreadcrumbs(PageBreadcrumbs, action: PageTitle.TitleText);
// Register the dialog script
ScriptHelper.RegisterDialogScript(this);
ctlAsyncLog.TitleText = GetString("ContentDelete.DeletingDocuments");
// Set visibility of panels
pnlContent.Visible = true;
pnlLog.Visible = false;
bool isMultilingual = CultureSiteInfoProvider.IsSiteMultilingual(currentSite.SiteName);
if (!isMultilingual)
{
// Set all cultures checkbox
chkAllCultures.Checked = true;
pnlAllCultures.Visible = false;
}
if (nodeIds.Count > 0)
{
if (nodeIds.Count == 1)
{
// Single document deletion
int nodeId = ValidationHelper.GetInteger(nodeIds[0], 0);
TreeNode node = null;
if (string.IsNullOrEmpty(parentAliasPath))
{
// Get any culture if current not found
node = tree.SelectSingleNode(nodeId, CultureCode) ?? tree.SelectSingleNode(nodeId, TreeProvider.ALL_CULTURES);
}
else
{
if (allDocs != null)
{
DataRow dr = allDocs.Tables[0].Rows[0];
node = TreeNode.New(ValidationHelper.GetString(dr["ClassName"], string.Empty), dr, tree);
}
}
if (node != null)
{
bool rootDeleteDisabled = false;
if (IsProductsMode)
{
string startingPath = SettingsKeyInfoProvider.GetValue(CurrentSiteName + ".CMSStoreProductsStartingPath");
if (node.NodeAliasPath.CompareToCSafe(startingPath) == 0)
{
string closeLink = "<a href=\"#\"><span style=\"cursor: pointer;\" " +
"onclick=\"SelectNode(" + node.NodeID + "); return false;\">" + GetString("general.back") +
"</span></a>";
ShowError(string.Format(GetString("com.productsection.deleteroot"), closeLink, ""));
pnlDelete.Visible = false;
rootDeleteDisabled = true;
}
}
if (node.IsRoot() && isMultilingual)
{
// Hide 'Delete all cultures' checkbox
pnlAllCultures.Visible = false;
if (!URLHelper.IsPostback())
{
// Check if there are any documents in another culture or current culture has some documents
pnlDeleteRoot.Visible = IsAnyDocumentInAnotherCulture(node) && (tree.SelectNodesCount(SiteContext.CurrentSiteName, "/%", LocalizationContext.PreferredCultureCode, false, null, null, null, TreeProvider.ALL_LEVELS, false) > 0);
if (pnlDeleteRoot.Visible)
{
// Insert 'Delete current root' option if current root node is translated to current culture
if (node.DocumentCulture == LocalizationContext.PreferredCultureCode)
{
rblRoot.Items.Add(new ListItem(GetString("rootdeletion.currentroot"), "current"));
}
rblRoot.Items.Add(new ListItem(GetString("rootdeletion.currentculture"), "allculturepages"));
rblRoot.Items.Add(new ListItem(GetString("rootdeletion.allpages"), "allpages"));
}
else
{
rblRoot.Items.Add(new ListItem(GetString("rootdeletion.allpages"), "allpages"));
}
if (rblRoot.SelectedIndex < 0)
{
rblRoot.SelectedIndex = 0;
}
}
}
// Display warning for root node
if (!rootDeleteDisabled && node.IsRoot())
{
if (!currentUser.IsGlobalAdministrator)
{
pnlDelete.Visible = false;
ShowInformation(GetString("delete.rootonlyglobaladmin"));
}
else
{
if ((rblRoot.SelectedValue == "allpages") || !isMultilingual || ((rblRoot.SelectedValue == "allculturepages") && !IsAnyDocumentInAnotherCulture(node)))
{
messagesPlaceholder.ShowWarning(GetString("Delete.RootWarning"));
plcDeleteRoot.Visible = true;
}
else
{
plcDeleteRoot.Visible = false;
}
}
}
hasChildren = node.NodeHasChildren;
bool authorizedToDeleteSKU = !node.HasSKU || IsUserAuthorizedToModifySKU(node);
if (!RequestHelper.IsPostBack())
{
bool authorizedToDeleteDocument = IsUserAuthorizedToDeleteDocument(node);
if (!authorizedToDeleteDocument || !authorizedToDeleteSKU)
{
pnlDelete.Visible = false;
RedirectToAccessDenied(String.Format(GetString("cmsdesk.notauthorizedtodeletedocument"), HTMLHelper.HTMLEncode(node.NodeAliasPath)));
}
}
if (node.IsLink)
{
PageTitle.TitleText = GetString("Content.DeleteTitleLink") + " \"" + HTMLHelper.HTMLEncode(ResHelper.LocalizeString(node.GetDocumentName())) + "\"";
headQuestion.Text = GetString("ContentDelete.QuestionLink");
chkAllCultures.Checked = true;
plcCheck.Visible = false;
}
else
{
string nodeName = HTMLHelper.HTMLEncode(node.GetDocumentName());
// Get name for root document
if (node.NodeClassName.ToLowerCSafe() == "cms.root")
{
nodeName = HTMLHelper.HTMLEncode(currentSite.DisplayName);
}
PageTitle.TitleText = GetString("Content.DeleteTitle") + " \"" + HTMLHelper.HTMLEncode(ResHelper.LocalizeString(nodeName)) + "\"";
}
// Show or hide checkbox
pnlDestroy.Visible = CanDestroy(node);
cancelNodeId = IsMultipleAction ? node.NodeParentID : node.NodeID;
lblDocuments.Text = HTMLHelper.HTMLEncode(node.GetDocumentName());
if (node.IsRoot())
{
// Change SEO panel if root is selected
pnlSeo.Visible = false;
}
}
else
{
if (!RequestHelper.IsPostBack())
{
URLHelper.Redirect(UIHelper.GetInformationUrl("editeddocument.notexists"));
}
else
{
// Hide everything
pnlContent.Visible = false;
}
}
headQuestion.Text = GetString("ContentDelete.Question");
lblAllCultures.Text = GetString("ContentDelete.AllCultures");
lblDestroy.Text = GetString("ContentDelete.Destroy");
headDeleteDocument.Text = GetString("ContentDelete.Document");
}
else if (nodeIds.Count > 1)
{
string where = "NodeID IN (";
foreach (int nodeID in nodeIds)
{
where += nodeID + ",";
}
where = where.TrimEnd(',') + ")";
DataSet ds = allDocs ?? tree.SelectNodes(currentSite.SiteName, "/%", TreeProvider.ALL_CULTURES, true, null, where, "DocumentName", -1, false);
if (!DataHelper.DataSourceIsEmpty(ds))
{
string docList = null;
if (string.IsNullOrEmpty(parentAliasPath))
{
cancelNodeId = ValidationHelper.GetInteger(DataHelper.GetDataRowValue(ds.Tables[0].Rows[0], "NodeParentID"), 0);
}
else
{
cancelNodeId = TreePathUtils.GetNodeIdByAliasPath(currentSite.SiteName, parentAliasPath);
}
bool canDestroy = true;
bool permissions = true;
foreach (DataTable table in ds.Tables)
{
foreach (DataRow dr in table.Rows)
{
bool isLink = (dr["NodeLinkedNodeID"] != DBNull.Value);
string name = (string)dr["DocumentName"];
docList += HTMLHelper.HTMLEncode(name);
if (isLink)
{
docList += DocumentHelper.GetDocumentMarkImage(Page, DocumentMarkEnum.Link);
}
docList += "<br />";
lblDocuments.Text = docList;
// Set visibility of checkboxes
TreeNode node = TreeNode.New(ValidationHelper.GetString(dr["ClassName"], string.Empty), dr);
if (!IsUserAuthorizedToDeleteDocument(node))
{
permissions = false;
AddError(String.Format(
GetString("cmsdesk.notauthorizedtodeletedocument"),
HTMLHelper.HTMLEncode(node.NodeAliasPath)), null);
}
// Can destroy if "can destroy all previous AND current"
canDestroy = CanDestroy(node) && canDestroy;
if (!hasChildren)
{
hasChildren = node.NodeHasChildren;
}
}
}
pnlDelete.Visible = permissions;
pnlDestroy.Visible = canDestroy;
}
else
{
if (!RequestHelper.IsPostBack())
{
URLHelper.Redirect(UIHelper.GetInformationUrl("editeddocument.notexists"));
}
else
{
// Hide everything
pnlContent.Visible = false;
}
}
headQuestion.Text = GetString("ContentDelete.QuestionMultiple");
PageTitle.TitleText = GetString("Content.DeleteTitleMultiple");
lblAllCultures.Text = GetString("ContentDelete.AllCulturesMultiple");
lblDestroy.Text = GetString("ContentDelete.DestroyMultiple");
headDeleteDocument.Text = GetString("global.pages");
}
lblAltPath.AssociatedControlClientID = selAltPath.PathTextBox.ClientID;
selAltPath.SiteID = currentSite.SiteID;
chkUseDeletedPath.CheckedChanged += chkUseDeletedPath_CheckedChanged;
if (!RequestHelper.IsPostBack())
{
selAltPath.Enabled = false;
chkAltSubNodes.Enabled = false;
chkAltAliases.Enabled = false;
// Set default path if is defined
selAltPath.Value = SettingsKeyInfoProvider.GetValue(CurrentSiteName + ".CMSDefaultDeletedNodePath");
if (!hasChildren)
{
chkAltSubNodes.Checked = false;
chkAltSubNodes.Enabled = false;
}
}
// If user has allowed cultures specified
if (currentUser.UserHasAllowedCultures)
{
// Get all site cultures
DataSet siteCultures = CultureSiteInfoProvider.GetSiteCultures(currentSite.SiteName);
bool denyAllCulturesDeletion = false;
// Check that user can edit all site cultures
foreach (DataRow culture in siteCultures.Tables[0].Rows)
{
string cultureCode = ValidationHelper.GetString(DataHelper.GetDataRowValue(culture, "CultureCode"), string.Empty);
if (!currentUser.IsCultureAllowed(cultureCode, currentSite.SiteName))
{
denyAllCulturesDeletion = true;
}
}
// If user can't edit all site cultures
if (denyAllCulturesDeletion)
{
// Hide all cultures selector
pnlAllCultures.Visible = false;
chkAllCultures.Checked = false;
}
}
pnlDeleteDocument.Visible = pnlAllCultures.Visible || pnlDestroy.Visible;
}
else
{
// Hide everything
pnlContent.Visible = false;
}
}
// Initialize header action
InitializeActionMenu();
}
/// <summary>
/// Change controls usability for alternate document
/// </summary>
void chkUseDeletedPath_CheckedChanged(object sender, EventArgs e)
{
selAltPath.Enabled = chkUseDeletedPath.Checked;
chkAltSubNodes.Enabled = hasChildren & chkUseDeletedPath.Checked;
chkAltAliases.Enabled = chkUseDeletedPath.Checked;
plcDeleteSettings.Visible = chkUseDeletedPath.Checked;
}
protected override void OnPreRender(EventArgs e)
{
// Overwrite cancelNodeId variable if sub-levels are visible
if (AllLevels && Parameters.ContainsKey("refreshnodeid"))
{
cancelNodeId = ValidationHelper.GetInteger(Parameters["refreshnodeid"], 0);
}
string refreshCurrent = "function RefreshCurrent(){ RefreshTree(" + cancelNodeId + "," + cancelNodeId + "); }";
ScriptHelper.RegisterClientScriptBlock(this, typeof(string), "refreshCurrent", ScriptHelper.GetScript(refreshCurrent));
base.OnPreRender(e);
}
private void HeaderActions_ActionPerformed(object sender, CommandEventArgs e)
{
switch (e.CommandName.ToLowerCSafe())
{
case DELETE_COMMAND:
Delete();
break;
}
}
#endregion
#region "Header actions"
private void Delete()
{
// For root, the additional checkbox must be checked
if (plcDeleteRoot.Visible && !chkDeleteRoot.Checked)
{
ShowError(ResHelper.GetString("delete.rootnotchecked"));
return;
}
// Check whether path is selected
if (chkUseDeletedPath.Checked && String.IsNullOrEmpty(Convert.ToString(selAltPath.Value)))
{
ShowError(ResHelper.GetString("content.delete.altpathempty"));
return;
}
string deleteMode = pnlDeleteRoot.Visible ? "rootoptions" : "documentoptions";
pnlLog.Visible = true;
pnlContent.Visible = false;
CurrentError = string.Empty;
CurrentLog.Close();
EnsureLog();
ctlAsyncLog.Parameter = CultureCode + ";" + currentSite.SiteName + ";" + IsMultipleAction + ";" + AllLevels + ";" + deleteMode;
ctlAsyncLog.RunAsync(Delete, WindowsIdentity.GetCurrent());
}
#endregion
#region "Async methods"
/// <summary>
/// Deletes document(s).
/// </summary>
private void Delete(object parameter)
{
if (parameter == null || nodeIds.Count < 1)
{
return;
}
if (!LicenseHelper.LicenseVersionCheck(RequestContext.CurrentDomain, FeatureEnum.Blogs, ObjectActionEnum.Edit))
{
AddError(ResHelper.GetString("cmsdesk.blogdeletelicenselimitations", currentCulture));
return;
}
if (!LicenseHelper.LicenseVersionCheck(RequestContext.CurrentDomain, FeatureEnum.Documents, ObjectActionEnum.Edit))
{
AddError(ResHelper.GetString("cmsdesk.documentdeletelicenselimitations", currentCulture));
return;
}
int refreshId = 0;
TreeProvider tree = new TreeProvider(currentUser);
tree.AllowAsyncActions = false;
string[] parameters = ((string)parameter).Split(';');
bool allLevelsSelected = ValidationHelper.GetBoolean(parameters[3], false);
try
{
string siteName = parameters[1];
bool isMultipleDelete = ValidationHelper.GetBoolean(parameters[2], false);
// Prepare the where condition
string where = new WhereCondition().WhereIn("NodeID", nodeIds).ToString(true);
string columns = SqlHelper.MergeColumns(TreeProvider.SELECTNODES_REQUIRED_COLUMNS, "NodeAliasPath, ClassName, DocumentCulture, NodeParentID");
bool combineWithDefaultCulture = false;
string cultureCode = parameters[0];
switch (parameters[4])
{
// Normalne page deletion
case "documentoptions":
combineWithDefaultCulture = chkAllCultures.Checked;
cultureCode = combineWithDefaultCulture ? TreeProvider.ALL_CULTURES : parameters[0];
break;
// Root page deletion
case "rootoptions":
cultureCode = rblRoot.SelectedValue == "allpages" ? TreeProvider.ALL_CULTURES : parameters[0];
tree.DeleteChildNodes = rblRoot.SelectedValue != "current";
where = rblRoot.SelectedValue == "allculturepages" ? String.Empty : where;
break;
}
// Begin log
AddLog(ResHelper.GetString("ContentDelete.DeletingDocuments", currentCulture));
string orderBy = "NodeAliasPath DESC";
if (cultureCode == TreeProvider.ALL_CULTURES)
{
// Default culture has to be selected on last position
string defaultCulture = CultureHelper.GetDefaultCultureCode(siteName);
orderBy += ", CASE WHEN DocumentCulture = '" + SqlHelper.EscapeQuotes(defaultCulture) + "' THEN 1 ELSE 0 END";
}
// Get the documents
DataSet ds = tree.SelectNodes(siteName, "/%", cultureCode, combineWithDefaultCulture, null, where, orderBy, TreeProvider.ALL_LEVELS, false, 0, columns);
if (!DataHelper.DataSourceIsEmpty(ds))
{
string altPath = Convert.ToString(selAltPath.Value);
TreeNode altNode = null;
if (chkUseDeletedPath.Checked && !String.IsNullOrEmpty(altPath))
{
NodeSelectionParameters nsp = new NodeSelectionParameters();
nsp.AliasPath = altPath;
nsp.CultureCode = TreeProvider.ALL_CULTURES;
nsp.ClassNames = TreeProvider.ALL_CLASSNAMES;
nsp.CombineWithDefaultCulture = true;
nsp.SiteName = siteName;
nsp.MaxRelativeLevel = TreeProvider.ALL_LEVELS;
nsp.TopN = 1;
altNode = DocumentHelper.GetDocument(nsp, tree);
// Check whether user is authorized to use alternating document
if (altNode != null)
{
if (currentUser.IsAuthorizedPerDocument(altNode, NodePermissionsEnum.Modify) == AuthorizationResultEnum.Denied)
{
throw new Exception(GetString("contentdelete.notallowedalternating"));
}
}
else
{
// Do not allow to delete a page with specified redirection URL which is not valid
throw new Exception(GetString("contentdelete.redirectionurlisnotvalid"));
}
}
// Delete the documents
foreach (DataRow nodeRow in ds.Tables[0].Rows)
{
// Get the current document
string className = nodeRow["ClassName"].ToString();
string aliasPath = nodeRow["NodeAliasPath"].ToString();
string docCulture = nodeRow["DocumentCulture"].ToString();
refreshId = ValidationHelper.GetInteger(nodeRow["NodeParentID"], 0);
if (refreshId == 0)
{
refreshId = ValidationHelper.GetInteger(nodeRow["NodeID"], 0);
}
TreeNode node = DocumentHelper.GetDocument(siteName, aliasPath, docCulture, false, className, null, null, TreeProvider.ALL_LEVELS, false, null, tree);
if (node == null)
{
AddLog(string.Format(ResHelper.GetString("ContentRequest.DocumentNoLongerExists", currentCulture), HTMLHelper.HTMLEncode(aliasPath)));
continue;
}
// Ensure current parent ID
int parentId = node.NodeParentID;
// Check if bound SKU can be deleted (if any)
bool authorizedToDeleteSKU = !node.HasSKU || IsUserAuthorizedToModifySKU(node);
// Check delete permissions
if (IsUserAuthorizedToDeleteDocument(node) && (CanDestroy(node) || !chkDestroy.Checked) && authorizedToDeleteSKU)
{
// Delete the document
if (parentId <= 0)
{
parentId = node.NodeID;
}
// Prepare settings for delete
DeleteDocumentSettings settings = new DeleteDocumentSettings(node, chkAllCultures.Checked, chkDestroy.Checked, tree);
bool skip = false;
// Add additional settings if alternating document is specified
if (altNode != null)
{
var nodeAliasPath = node.NodeAliasPath;
var altNodeAliasPath = altNode.NodeAliasPath;
// Skip deletion for pages which have alternative node as their child or itself
if (altNodeAliasPath.EqualsCSafe(nodeAliasPath, true) || altNodeAliasPath.StartsWithCSafe(nodeAliasPath.TrimEnd('/') + "/", true))
{
AddError(String.Format(GetString("contentdelete.redirectionurltosamepage"), HTMLHelper.HTMLEncode(node.NodeAliasPath)));
skip = true;
}
else
{
settings.AlternatingDocument = altNode;
settings.AlternatingDocumentCopyAllPaths = chkAltAliases.Checked;
settings.AlternatingDocumentMaxLevel = chkAltSubNodes.Checked ? -1 : node.NodeLevel;
}
}
// Delete document
refreshId = !skip && DocumentHelper.DeleteDocument(settings) || isMultipleDelete ? parentId : node.NodeID;
}
// Access denied - not authorized to delete the document
else
{
AddError(string.Format(ResHelper.GetString("cmsdesk.notauthorizedtodeletedocument", currentCulture), HTMLHelper.HTMLEncode(node.NodeAliasPath)));
}
}
}
else
{
AddError(ResHelper.GetString("DeleteDocument.CultureNotExists", currentCulture));
}
}
catch (ThreadAbortException ex)
{
string state = ValidationHelper.GetString(ex.ExceptionState, string.Empty);
if (state == CMSThread.ABORT_REASON_STOP)
{
// When canceled
ShowError(ResHelper.GetString("DeleteDocument.DeletionCanceled", currentCulture));
}
else
{
// Log error
LogExceptionToEventLog(ex);
}
}
catch (Exception ex)
{
// Log error
LogExceptionToEventLog(ex);
}
finally
{
if (string.IsNullOrEmpty(CurrentError))
{
// Overwrite refreshId variable if sub-levels are visible
if (allLevelsSelected && Parameters.ContainsKey("refreshnodeid"))
{
refreshId = ValidationHelper.GetInteger(Parameters["refreshnodeid"], 0);
}
// Refresh tree or page (on-site editing)
if (!RequiresDialog)
{
ctlAsyncLog.Parameter = "RefreshTree(" + refreshId + ", " + refreshId + "); \n" + "SelectNode(" + refreshId + ");";
}
else
{
// Go to the root by default
string url = URLHelper.ResolveUrl("~/");
// Update the refresh node id when set in the parent dialog
if (Parameters != null)
{
int refreshNodeId = ValidationHelper.GetInteger(Parameters["refreshnodeid"], 0);
if (refreshNodeId > 0)
{
refreshId = refreshNodeId;
}
}
// Try go to the parent document
if (refreshId > 0)
{
TreeProvider tp = new TreeProvider(MembershipContext.AuthenticatedUser);
TreeNode tn = DocumentHelper.GetDocument(refreshId, TreeProvider.ALL_CULTURES, tp);
if (tn != null)
{
url = URLHelper.ResolveUrl(DocumentURLProvider.GetUrl(tn.NodeAliasPath));
}
}
ctlAsyncLog.Parameter = "window.refreshPageOnClose = true; window.reloadPageUrl = " + ScriptHelper.GetString(url) + "; CloseDialog();";
}
}
else
{
ctlAsyncLog.Parameter = "RefreshTree(null, null);";
}
}
}
#endregion
#region "Help methods"
/// <summary>
/// Return true if any document is in different culture than current.
/// </summary>
/// <param name="node">Tree node</param>
private bool IsAnyDocumentInAnotherCulture(TreeNode node)
{
return Tree.SelectNodesCount(node.NodeSiteName, "/%", TreeProvider.ALL_CULTURES, true, null, "DocumentCulture NOT LIKE '" + node.DocumentCulture + "'", null, TreeProvider.ALL_LEVELS, false) > 0;
}
/// <summary>
/// When exception occurs, log it to event log.
/// </summary>
/// <param name="ex">Exception to log</param>
private void LogExceptionToEventLog(Exception ex)
{
EventLogProvider.LogEvent(EventType.ERROR, "Content", "DELETEDOC", EventLogProvider.GetExceptionLogMessage(ex), RequestContext.RawURL, currentUser.UserID, currentUser.UserName, 0, null, RequestContext.UserHostAddress, currentSite.SiteID);
AddError(ResHelper.GetString("ContentRequest.DeleteFailed", currentCulture) + ": " + ex.Message);
}
/// <summary>
/// Adds the script to the output request window.
/// </summary>
/// <param name="script">Script to add</param>
public override void AddScript(string script)
{
ltlScript.Text += ScriptHelper.GetScript(script);
}
/// <summary>
/// Indicates whether specified node can be destroyed by current user.
/// </summary>
/// <param name="node">Tree node to check</param>
private bool CanDestroy(TreeNode node)
{
bool canDestroy = currentUser.IsAuthorizedPerDocument(node, NodePermissionsEnum.Destroy) == AuthorizationResultEnum.Allowed;
if (node.HasSKU)
{
canDestroy &= currentUser.IsAuthorizedPerResource("CMS.Ecommerce", "Destroy");
}
return (canDestroy);
}
/// <summary>
/// Checks whether the user is authorized to delete document.
/// </summary>
/// <param name="node">Document node</param>
protected bool IsUserAuthorizedToDeleteDocument(TreeNode node)
{
// Check delete permission for document
return (currentUser.IsAuthorizedPerDocument(node, new[] { NodePermissionsEnum.Delete, NodePermissionsEnum.Read }) == AuthorizationResultEnum.Allowed);
}
/// <summary>
/// Checks whether the user is authorized to delete SKU bound to given node.
/// </summary>
/// <param name="node">Node to be checked</param>
protected bool IsUserAuthorizedToModifySKU(TreeNode node)
{
bool authorized = false;
if ((node != null) && (node.HasSKU))
{
var product = BaseAbstractInfoProvider.GetInfoById(PredefinedObjectType.SKU, node.NodeSKUID);
if (product != null)
{
authorized = product.CheckPermissions(PermissionsEnum.Delete, node.NodeSiteName, currentUser);
}
}
return authorized;
}
/// <summary>
/// Returns true when given node has product related child.
/// </summary>
/// <param name="tree">Tree provider to use</param>
/// <param name="node">Node to check</param>
protected bool NodeHasChildWithProduct(TreeProvider tree, TreeNode node)
{
string aliasPath = node.NodeAliasPath.TrimEnd('/') + "/%";
return 0 < tree.SelectNodesCount(node.NodeSiteName, aliasPath, TreeProvider.ALL_CULTURES, true, null, "NodeLinkedNodeID IS NULL AND NodeSKUID IS NOT NULL", null, TreeProvider.ALL_LEVELS, false);
}
/// <summary>
/// Returns true when given node is bound to the same SKU as some other node does.
/// </summary>
/// <param name="tree">Tree provider to use</param>
/// <param name="node">Node to check</param>
protected bool NodeSharesSKUWithOtherNode(TreeProvider tree, TreeNode node)
{
string where = "NodeLinkedNodeID IS NULL AND NodeSKUID = " + node.NodeSKUID + " AND NodeID <> " + node.NodeID;
return 0 < tree.SelectNodesCount(TreeProvider.ALL_SITES, "/%", TreeProvider.ALL_CULTURES, true, null, where, null, TreeProvider.ALL_LEVELS, false);
}
/// <summary>
/// Initializes action menu in master page.
/// </summary>
private void InitializeActionMenu()
{
var actions = CurrentMaster.HeaderActions;
actions.ActionsList.Clear();
// Delete
actions.ActionsList.Add(new HeaderAction
{
Text = GetString("general.delete"),
CommandName = DELETE_COMMAND
});
// Cancel
actions.ActionsList.Add(new HeaderAction
{
Text = GetString("general.cancel"),
OnClientClick = (RequiresDialog) ? "CloseDialog(); return false" : "SelectNode(" + cancelNodeId + "); return false",
ButtonStyle = ButtonStyle.Default
});
actions.ActionPerformed += HeaderActions_ActionPerformed;
}
#endregion
#region "Handling async thread"
private void ctlAsyncLog_OnCancel(object sender, EventArgs e)
{
ctlAsyncLog.Parameter = null;
string cancel = GetString("DeleteDocument.DeletionCanceled");
AddLog(cancel);
ltlScript.Text += ScriptHelper.GetScript("var __pendingCallbacks = new Array();RefreshCurrent();");
ShowConfirmation(cancel);
CurrentLog.Close();
}
private void ctlAsyncLog_OnRequestLog(object sender, EventArgs e)
{
ctlAsyncLog.LogContext = CurrentLog;
}
private void ctlAsyncLog_OnError(object sender, EventArgs e)
{
if (ctlAsyncLog.Status == AsyncWorkerStatusEnum.Running)
{
ctlAsyncLog.Stop();
}
ctlAsyncLog.Parameter = null;
ShowError(CurrentError);
CurrentLog.Close();
}
private void ctlAsyncLog_OnFinished(object sender, EventArgs e)
{
ShowError(CurrentError);
CurrentLog.Close();
if (!string.IsNullOrEmpty(CurrentError))
{
ctlAsyncLog.Parameter = null;
AddScript("RefreshTree(null, null);");
}
if (ctlAsyncLog.Parameter != null)
{
AddScript(ctlAsyncLog.Parameter.ToString());
}
}
/// <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
}