/// <summary>
    /// Loads summary box in the right upper corner.
    /// </summary>
    private void LoadSummaryBox()
    {
        var selectionParameters = new NodeSelectionParameters
        {
            AliasPath                 = ABTest.ABTestOriginalPage,
            CultureCode               = ABTest.ABTestCulture,
            SiteName                  = SiteContext.CurrentSiteName,
            SelectOnlyPublished       = true,
            CombineWithDefaultCulture = false
        };

        var node            = new TreeProvider().SelectSingleNode(selectionParameters);
        var shortUrl        = ShortenUrl(ABTest.ABTestOriginalPage);
        var encodedShortUrl = HTMLHelper.HTMLEncode(shortUrl);

        if (node == null)
        {
            lblTest.Text    = encodedShortUrl;
            lblTest.Visible = true;
        }
        else
        {
            lnkTest.HRef      = DocumentURLProvider.GetAbsoluteLiveSiteURL(node);
            lnkTest.InnerText = encodedShortUrl;
            lnkTest.Target    = "_blank";
            lnkTest.Visible   = true;
        }

        // If Visitors conversion methodology selected, use "Visitors" instead of "Visits"
        if (drpCountingMethodology.SelectedValue == ABTestConstants.ABSESSIONCONVERSION_FIRST)
        {
            lblVisits.ResourceString = "abtesting.overview.summary.visitors";
        }

        lblStatus.Text = ABTestStatusEvaluator.GetFormattedStatus(TestStatus).ToString();
        int visits      = VariantsStatisticsData.Sum(d => d.Value.Visits);
        int conversions = VariantsStatisticsData.Sum(d => d.Value.ConversionsCount);

        lblTotalVisitors.Text    = String.Format("{0:N0}", visits);
        lblTotalConversions.Text = String.Format("{0:N0}", conversions);

        if (TestStatus == ABTestStatusEnum.Finished)
        {
            txtDuration.ResourceString = "abtesting.daysrun";
        }

        DateTime start  = ABTest.ABTestOpenFrom;
        DateTime finish = GetFinishDate();

        lblDuration.Text = (finish - start).Days.ToString();
    }
    /// <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(DocumentColumnLists.SELECTNODES_REQUIRED_COLUMNS, "NodeAliasPath, ClassName, DocumentCulture, NodeParentID");

            bool combineWithDefaultCulture = false;
            string cultureCode = parameters[0];

            switch (parameters[4])
            {
                // Standard 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];
                    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
                        var 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)
        {
            if (CMSThread.Stopped(ex))
            {
                // 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));
                        }
                    }

                    ctlAsyncLog.Parameter = "window.refreshPageOnClose = true; window.reloadPageUrl = " + ScriptHelper.GetString(url) + "; CloseDialog();";
                }
            }
            else
            {
                ctlAsyncLog.Parameter = "RefreshTree(null, null);";
            }
        }
    }
    /// <summary>
    /// Handles the OnAfterValidate event of the Control control.
    /// </summary>
    void Control_OnAfterValidate(object sender, EventArgs e)
    {
        PageTemplateInfo pti = Control.EditedObject as PageTemplateInfo;

        if (pti == null)
        {
            return;
        }

        String result             = String.Empty;
        PageTemplateTypeEnum type = (Control.GetFieldValue("PageTemplateType") as String).ToEnum <PageTemplateTypeEnum>();
        String fileName           = Control.GetFieldValue("PageTemplateFile") as String;

        // Check dashboard prerequisites
        if ((pti.PageTemplateId > 0) && (type == PageTemplateTypeEnum.Dashboard))
        {
            // Check live site usage
            TreeProvider            tp         = new TreeProvider(MembershipContext.AuthenticatedUser);
            NodeSelectionParameters parameters = new NodeSelectionParameters
            {
                ClassNames  = TreeProvider.ALL_CLASSNAMES,
                SiteName    = TreeProvider.ALL_SITES,
                Columns     = "NodeID, DocumentCulture",
                Where       = String.Format("DocumentPageTemplateID = {0} OR NodeTemplateID = {0}", pti.PageTemplateId),
                CultureCode = TreeProvider.ALL_CULTURES,
                CombineWithDefaultCulture = true,
            };

            DataSet ds = tp.SelectNodes(parameters);
            if (!DataHelper.DataSourceIsEmpty(ds))
            {
                result = ResHelper.GetString("template.dahsboardliveused");
            }

            // Check valid zones
            if (String.IsNullOrEmpty(result))
            {
                PageTemplateInstance inst = pti.TemplateInstance;
                if (inst != null)
                {
                    foreach (WebPartZoneInstance zone in inst.WebPartZones)
                    {
                        switch (zone.WidgetZoneType)
                        {
                        case WidgetZoneTypeEnum.Dashboard:
                        case WidgetZoneTypeEnum.None:
                            continue;
                        }

                        result = ResHelper.GetString("template.dashboardinvalidzone");
                        break;
                    }
                }
            }
        }

        // Validate file
        if (((type == PageTemplateTypeEnum.Aspx) || (type == PageTemplateTypeEnum.AspxPortal)) &&
            String.IsNullOrEmpty(fileName))
        {
            result = ResHelper.GetString("development-webpart_edit.emptywebpartfilename");
        }

        if (result != String.Empty)
        {
            Control.StopProcessing = true;
            CMSPage pg = Control.Page as CMSPage;
            if (pg != null)
            {
                pg.ShowError(result);
                Control.StopProcessing = true;
            }
        }
    }
예제 #4
0
    /// <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"));
                        }
                    }
                }

                // 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 action for affected products
                        DeleteProductActionEnum deleteSKUsAction = DeleteProductActionEnum.NoAction;

                        switch (rblSKUAction.SelectedValue)
                        {
                        case "delete":
                            deleteSKUsAction = DeleteProductActionEnum.DeleteSKU;
                            break;

                        case "disable":
                            deleteSKUsAction = DeleteProductActionEnum.DisableSKU;
                            break;

                        case "deleteordisable":
                            deleteSKUsAction = DeleteProductActionEnum.DeleteOrDisableSKU;
                            break;
                        }

                        // Prepare settings for delete
                        DeleteDocumentSettings settings = new DeleteDocumentSettings(node, chkAllCultures.Checked, chkDestroy.Checked, tree)
                        {
                            DeleteProductAction = deleteSKUsAction
                        };

                        // Add additional settings if alternating document is specified
                        if (altNode != null)
                        {
                            settings.AlternatingDocument             = altNode;
                            settings.AlternatingDocumentCopyAllPaths = chkAltAliases.Checked;
                            settings.AlternatingDocumentMaxLevel     = chkAltSubNodes.Checked ? -1 : node.NodeLevel;
                        }

                        // Delete document
                        refreshId = 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)
                {
                    ctlAsync.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));
                        }
                    }

                    ctlAsync.Parameter = "window.refreshPageOnClose = true; window.reloadPageUrl = " + ScriptHelper.GetString(url) + "; CloseDialog();";
                }
            }
            else
            {
                ctlAsync.Parameter = "RefreshTree(null, null);";
            }
        }
    }
    /// <summary>
    /// Save button action.
    /// </summary>
    protected void ObjectManager_OnSaveData(object sender, SimpleObjectManagerEventArgs e)
    {
        // Template has to exist
        if (PageTemplate == null)
        {
            return;
        }

        // Limit text length
        txtTemplateCodeName.Text = TextHelper.LimitLength(txtTemplateCodeName.Text.Trim(), 100, "");
        txtTemplateDisplayName.Text = TextHelper.LimitLength(txtTemplateDisplayName.Text.Trim(), 200, "");

        // Finds whether required fields are not empty
        string result = String.Empty;

        result = new Validator().NotEmpty(txtTemplateDisplayName.Text, GetString("Administration-PageTemplate_General.ErrorEmptyTemplateDisplayName")).NotEmpty(txtTemplateCodeName.Text, GetString("Administration-PageTemplate_General.ErrorEmptyTemplateCodeName"))
            .IsCodeName(txtTemplateCodeName.Text, GetString("general.invalidcodename"))
            .Result;

        if ((result == String.Empty) && (SelectedPageType == PageTemplateTypeEnum.Aspx || SelectedPageType == PageTemplateTypeEnum.AspxPortal))
        {
            if (!FileSystemSelector.IsValid())
            {
                result = FileSystemSelector.ValidationError;
            }
        }

        // If name changed, check if new name is unique
        if ((result == String.Empty) && (CMSString.Compare(PageTemplate.CodeName, txtTemplateCodeName.Text, true) != 0))
        {
            if (PageTemplateInfoProvider.PageTemplateNameExists(txtTemplateCodeName.Text))
            {
                result = GetString("general.codenameexists");
            }
        }

        // Check dashboard prerequisites
        if ((PageTemplate.PageTemplateId > 0) && (SelectedPageType == PageTemplateTypeEnum.Dashboard))
        {
            // Check live site usage
            TreeProvider tp = new TreeProvider(CMSContext.CurrentUser);
            NodeSelectionParameters parameters = new NodeSelectionParameters()
            {
                ClassNames = TreeProvider.ALL_CLASSNAMES,
                SiteName = TreeProvider.ALL_SITES,
                Columns = "NodeID",
                Where = String.Format("DocumentPageTemplateID = {0} OR NodeTemplateID = {0} OR NodeWireframeTemplateID = {0}", PageTemplate.PageTemplateId)
            };

            DataSet ds = tp.SelectNodes(parameters);
            if (!DataHelper.DataSourceIsEmpty(ds))
            {
                result = GetString("template.dahsboardliveused");
            }

            // Check valid zones
            if (String.IsNullOrEmpty(result))
            {
                PageTemplateInstance inst = PageTemplate.TemplateInstance;
                if (inst != null)
                {
                    foreach (WebPartZoneInstance zone in inst.WebPartZones)
                    {
                        switch (zone.WidgetZoneType)
                        {
                            case WidgetZoneTypeEnum.Dashboard:
                            case WidgetZoneTypeEnum.None:
                                continue;
                        }

                        result = GetString("template.dashboardinvalidzone");
                        break;
                    }
                }
            }
        }

        if (String.IsNullOrEmpty(result))
        {
            // Update page template info
            PageTemplate.DisplayName = txtTemplateDisplayName.Text;
            PageTemplate.CodeName = txtTemplateCodeName.Text;
            PageTemplate.Description = txtTemplateDescription.Text;
            PageTemplate.CategoryID = Convert.ToInt32(categorySelector.Value);

            if (SelectedPageType == PageTemplateTypeEnum.MVC)
            {
                // MVC template
                PageTemplate.IsPortal = false;
                PageTemplate.FileName = String.Empty;

                PageTemplate.ShowAsMasterTemplate = false;
                PageTemplate.PageTemplateCloneAsAdHoc = false;

                PageTemplate.PageTemplateDefaultController = txtController.Text;
                PageTemplate.PageTemplateDefaultAction = txtAction.Text;
            }
            else if (SelectedPageType == PageTemplateTypeEnum.Portal)
            {
                // Portal template of various types
                PageTemplate.IsPortal = true;
                PageTemplate.FileName = String.Empty;

                // Save inherit levels
                if (!chkShowAsMasterTemplate.Checked)
                {
                    PageTemplate.InheritPageLevels = ValidationHelper.GetString(lvlElem.Value, "");
                }
                else
                {
                    PageTemplate.InheritPageLevels = "/";
                }

                // Show hide inherit levels radio buttons
                PageTemplate.ShowAsMasterTemplate = chkShowAsMasterTemplate.Checked;
                PageTemplate.PageTemplateCloneAsAdHoc = chkAdHoc.Checked;
            }
            else
            {
                // ASPX page templates
                PageTemplate.IsPortal = false;
                PageTemplate.FileName = FileSystemSelector.Value.ToString();

                PageTemplate.ShowAsMasterTemplate = false;
                PageTemplate.PageTemplateCloneAsAdHoc = false;

                PageTemplate.InheritPageLevels = "";
            }

            PageTemplate.PageTemplateType = SelectedPageType;

            // Set ad-hoc status
            PageTemplate.IsReusable = pageTemplateIsReusable;
            if (pageTemplateIsReusable)
            {
                PageTemplate.PageTemplateNodeGUID = Guid.Empty;
            }

            PageTemplate.WebParts = pageTemplateWebParts;

            try
            {
                // Save the template and update the header
                PageTemplateInfoProvider.SetPageTemplateInfo(PageTemplate);
                ScriptHelper.RegisterStartupScript(this, typeof(string), "pageTemplateSaveScript", ScriptHelper.GetScript("RefreshContent()"));
                ShowChangesSaved();
            }
            catch (UnauthorizedAccessException ex)
            {
                ShowError(ResHelper.GetStringFormat("general.sourcecontrolerror", ex.Message));
            }
            catch (Exception ex)
            {
                ShowError(ex.Message);
            }
        }
        else
        {
            rfvTemplateDisplayName.Visible = false;
            rfvTemplateCodeName.Visible = false;

            ShowError(result);
        }
    }
    /// <summary>
    /// Deletes document(s).
    /// </summary>
    private void Delete(object parameter)
    {
        if (parameter == null || nodeIds.Count < 1)
        {
            return;
        }

        if (!LicenseHelper.LicenseVersionCheck(URLHelper.GetCurrentDomain(), FeatureEnum.Blogs, VersionActionEnum.Edit))
        {
            AddError(ResHelper.GetString("cmsdesk.blogdeletelicenselimitations", currentCulture));
            return;
        }

        if (!LicenseHelper.LicenseVersionCheck(URLHelper.GetCurrentDomain(), FeatureEnum.Documents, VersionActionEnum.Edit))
        {
            AddError(ResHelper.GetString("cmsdesk.documentdeletelicenselimitations", currentCulture));
            return;
        }
        int refreshId = 0;

        TreeProvider tree = new TreeProvider(currentUser);
        tree.AllowAsyncActions = false;

        try
        {
            string[] parameters = ((string)parameter).Split(';');

            string siteName = parameters[1];

            // Prepare the where condition
            string where = SqlHelperClass.GetWhereCondition("NodeID", (int[])nodeIds.ToArray(typeof(int)));
            string columns = SqlHelperClass.MergeColumns(TreeProvider.SELECTNODES_REQUIRED_COLUMNS, "NodeAliasPath, ClassName, DocumentCulture, NodeParentID");

            bool combineWithDefaultCulture = chkAllCultures.Checked;
            string cultureCode = combineWithDefaultCulture ? TreeProvider.ALL_CULTURES : parameters[0];

            // Begin log
            AddLog(ResHelper.GetString("ContentDelete.DeletingDocuments", currentCulture));

            // Get the documents
            DataSet ds = tree.SelectNodes(siteName, "/%", cultureCode, combineWithDefaultCulture, null, where, "NodeAliasPath DESC", 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"));
                        }
                    }
                }

                // 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 action for affected products
                        DeleteProductActionEnum deleteSKUsAction = DeleteProductActionEnum.NoAction;

                        switch (rblSKUAction.SelectedValue)
                        {
                            case "delete":
                                deleteSKUsAction = DeleteProductActionEnum.DeleteSKU;
                                break;

                            case "disable":
                                deleteSKUsAction = DeleteProductActionEnum.DisableSKU;
                                break;

                            case "deleteordisable":
                                deleteSKUsAction = DeleteProductActionEnum.DeleteOrDisableSKU;
                                break;
                        }

                        // Prepare settings for delete
                        DeleteDocumentSettings settings = new DeleteDocumentSettings(node, tree, chkAllCultures.Checked, chkDestroy.Checked, deleteSKUsAction);

                        // Add additional settings if alternating document is specified
                        if (altNode != null)
                        {
                            settings.AlternatingDocument = altNode;
                            settings.AlternatingDocumentCopyAllPaths = chkAltAliases.Checked;
                            settings.AlternatingDocumentMaxLevel = chkAltSubNodes.Checked ? -1 : node.NodeLevel;
                        }

                        // Delete document
                        refreshId = DocumentHelper.DeleteDocument(settings) ? 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))
            {
                // Refresh tree or page (on-site editing)
                if (!RequiresDialog)
                {
                    ctlAsync.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(CMSContext.CurrentUser);
                        TreeNode tn = DocumentHelper.GetDocument(refreshId, TreeProvider.ALL_CULTURES, tp);
                        if (tn != null)
                        {
                            url = URLHelper.ResolveUrl(DocumentURLProvider.GetUrl(tn.NodeAliasPath));
                        }
                    }

                    ctlAsync.Parameter = "window.refreshPageOnClose = true; window.reloadPageUrl = " + ScriptHelper.GetString(url) + "; CloseDialog();";
                }
            }
            else
            {
                ctlAsync.Parameter = "RefreshTree(null, null);";
            }
        }
    }
    /// <summary>
    /// Handles Unigrid's OnExternalDataBound event.
    /// </summary>
    protected object gridElem_OnExternalDataBound(object sender, string sourceName, object parameter)
    {
        switch (sourceName.ToLowerInvariant())
        {
        case "status":
        {
            if (Enum.TryParse(parameter.ToString(), out ABTestStatusEnum status))
            {
                return(ABTestStatusEvaluator.GetFormattedStatus(status));
            }
            break;
        }

        case "page":
        {
            var dataRowView = parameter as DataRowView;
            if (dataRowView == null)
            {
                return(String.Empty);
            }

            var abTestInfo = new ABTestInfo(dataRowView.Row);

            var selectionParameters = new NodeSelectionParameters
            {
                AliasPath                 = abTestInfo.ABTestOriginalPage,
                CultureCode               = abTestInfo.ABTestCulture,
                SiteName                  = SiteContext.CurrentSiteName,
                SelectOnlyPublished       = true,
                CombineWithDefaultCulture = !SiteContext.CurrentSite.SiteIsContentOnly
            };

            var node            = new TreeProvider().SelectSingleNode(selectionParameters);
            var encodedTestPage = HTMLHelper.HTMLEncode(abTestInfo.ABTestOriginalPage);

            return(node == null
                        ? (object)encodedTestPage
                        : new HyperLink
                {
                    NavigateUrl = DocumentURLProvider.GetAbsoluteLiveSiteURL(node),
                    Text = encodedTestPage,
                    Target = "_blank"
                });
        }

        case "visitors":
        case "conversions":
        {
            string statisticsCodeName = (sourceName.ToLowerInvariant() == "visitors" ? "abvisitfirst" : "absessionconversionfirst");

            var dataRowView = parameter as DataRowView;
            if (dataRowView == null)
            {
                return(0);
            }

            var abTestInfo = new ABTestInfo(dataRowView.Row);

            return(ValidationHelper.GetInteger(HitsInfoProvider.GetAllHitsInfo(SiteContext.CurrentSiteID, HitsIntervalEnum.Year, statisticsCodeName + ";" + abTestInfo.ABTestName + ";%", "SUM(HitsCount)", abTestInfo.ABTestCulture).Tables[0].Rows[0][0], 0));
        }

        case "delete":
            CMSGridActionButton btn = (CMSGridActionButton)sender;
            btn.Enabled = IsAuthorizedToManage;
            if (!IsAuthorizedToManage)
            {
                btn.ToolTip = permissionsRequiredTooltip;
            }
            break;
        }

        return(null);
    }
    /// <summary>
    /// Save button action.
    /// </summary>
    protected void ObjectManager_OnSaveData(object sender, SimpleObjectManagerEventArgs e)
    {
        // Template has to exist
        if (PageTemplate == null)
        {
            return;
        }

        // Limit text length
        txtTemplateCodeName.Text    = TextHelper.LimitLength(txtTemplateCodeName.Text.Trim(), 100, "");
        txtTemplateDisplayName.Text = TextHelper.LimitLength(txtTemplateDisplayName.Text.Trim(), 200, "");

        // Finds whether required fields are not empty
        string result = String.Empty;

        result = new Validator().NotEmpty(txtTemplateDisplayName.Text, GetString("Administration-PageTemplate_General.ErrorEmptyTemplateDisplayName")).NotEmpty(txtTemplateCodeName.Text, GetString("Administration-PageTemplate_General.ErrorEmptyTemplateCodeName"))
                 .IsCodeName(txtTemplateCodeName.Text, GetString("general.invalidcodename"))
                 .Result;

        if ((result == String.Empty) && (SelectedPageType == PageTemplateTypeEnum.Aspx || SelectedPageType == PageTemplateTypeEnum.AspxPortal))
        {
            if (!FileSystemSelector.IsValid())
            {
                result = FileSystemSelector.ValidationError;
            }
        }

        // If name changed, check if new name is unique
        if ((result == String.Empty) && (CMSString.Compare(PageTemplate.CodeName, txtTemplateCodeName.Text, true) != 0))
        {
            if (PageTemplateInfoProvider.PageTemplateNameExists(txtTemplateCodeName.Text))
            {
                result = GetString("general.codenameexists");
            }
        }


        // Check dashboard prerequisites
        if ((PageTemplate.PageTemplateId > 0) && (SelectedPageType == PageTemplateTypeEnum.Dashboard))
        {
            // Check live site usage
            TreeProvider            tp         = new TreeProvider(CMSContext.CurrentUser);
            NodeSelectionParameters parameters = new NodeSelectionParameters()
            {
                ClassNames = TreeProvider.ALL_CLASSNAMES,
                SiteName   = TreeProvider.ALL_SITES,
                Columns    = "NodeID",
                Where      = String.Format("DocumentPageTemplateID = {0} OR NodeTemplateID = {0} OR NodeWireframeTemplateID = {0}", PageTemplate.PageTemplateId)
            };

            DataSet ds = tp.SelectNodes(parameters);
            if (!DataHelper.DataSourceIsEmpty(ds))
            {
                result = GetString("template.dahsboardliveused");
            }

            // Check valid zones
            if (String.IsNullOrEmpty(result))
            {
                PageTemplateInstance inst = PageTemplate.TemplateInstance;
                if (inst != null)
                {
                    foreach (WebPartZoneInstance zone in inst.WebPartZones)
                    {
                        switch (zone.WidgetZoneType)
                        {
                        case WidgetZoneTypeEnum.Dashboard:
                        case WidgetZoneTypeEnum.None:
                            continue;
                        }

                        result = GetString("template.dashboardinvalidzone");
                        break;
                    }
                }
            }
        }

        if (String.IsNullOrEmpty(result))
        {
            // Update page template info
            PageTemplate.DisplayName = txtTemplateDisplayName.Text;
            PageTemplate.CodeName    = txtTemplateCodeName.Text;
            PageTemplate.Description = txtTemplateDescription.Text;
            PageTemplate.CategoryID  = Convert.ToInt32(categorySelector.Value);

            if (SelectedPageType == PageTemplateTypeEnum.MVC)
            {
                // MVC template
                PageTemplate.IsPortal = false;
                PageTemplate.FileName = String.Empty;

                PageTemplate.ShowAsMasterTemplate     = false;
                PageTemplate.PageTemplateCloneAsAdHoc = false;

                PageTemplate.PageTemplateDefaultController = txtController.Text;
                PageTemplate.PageTemplateDefaultAction     = txtAction.Text;
            }
            else if (SelectedPageType == PageTemplateTypeEnum.Portal)
            {
                // Portal template of various types
                PageTemplate.IsPortal = true;
                PageTemplate.FileName = String.Empty;

                // Save inherit levels
                if (!chkShowAsMasterTemplate.Checked)
                {
                    PageTemplate.InheritPageLevels = ValidationHelper.GetString(lvlElem.Value, "");
                }
                else
                {
                    PageTemplate.InheritPageLevels = "/";
                }

                // Show hide inherit levels radio buttons
                PageTemplate.ShowAsMasterTemplate     = chkShowAsMasterTemplate.Checked;
                PageTemplate.PageTemplateCloneAsAdHoc = chkAdHoc.Checked;
            }
            else
            {
                // ASPX page templates
                PageTemplate.IsPortal = false;
                PageTemplate.FileName = FileSystemSelector.Value.ToString();

                PageTemplate.ShowAsMasterTemplate     = false;
                PageTemplate.PageTemplateCloneAsAdHoc = false;

                PageTemplate.InheritPageLevels = "";
            }

            PageTemplate.PageTemplateType = SelectedPageType;

            // Set ad-hoc status
            PageTemplate.IsReusable = pageTemplateIsReusable;
            if (pageTemplateIsReusable)
            {
                PageTemplate.PageTemplateNodeGUID = Guid.Empty;
            }

            PageTemplate.WebParts = pageTemplateWebParts;

            try
            {
                // Save the template and update the header
                PageTemplateInfoProvider.SetPageTemplateInfo(PageTemplate);
                ScriptHelper.RegisterStartupScript(this, typeof(string), "pageTemplateSaveScript", ScriptHelper.GetScript("RefreshContent()"));
                ShowChangesSaved();
            }
            catch (UnauthorizedAccessException ex)
            {
                ShowError(ResHelper.GetStringFormat("general.sourcecontrolerror", ex.Message));
            }
            catch (Exception ex)
            {
                ShowError(ex.Message);
            }
        }
        else
        {
            rfvTemplateDisplayName.Visible = false;
            rfvTemplateCodeName.Visible    = false;

            ShowError(result);
        }
    }