using System; using System.Data; using System.Text; using System.Web.UI; using System.Web.UI.WebControls; using System.Collections; using CMS.CMSHelper; using CMS.Controls; using CMS.ExtendedControls; using CMS.FormEngine; using CMS.GlobalHelper; using CMS.LicenseProvider; using CMS.PortalEngine; using CMS.SettingsProvider; using CMS.SiteProvider; using CMS.DocumentEngine; using CMS.UIControls; using CMS.WorkflowEngine; using TimeZoneInfo = CMS.SiteProvider.TimeZoneInfo; using TreeNode = CMS.DocumentEngine.TreeNode; public partial class CMSModules_DocumentLibrary_Controls_DocumentLibrary : CMSUserControl, IPostBackEventHandler { #region "Constants" private const string CMS_FILE = "cms.file"; #endregion #region "Variables" private TimeZoneInfo usedTimeZone = null; private TreeNode mLibraryNode = null; private FormFieldInfo mFieldInfo = null; private DataClassInfo mDataClass = null; private string mNodeAliasPath = null; private string mPreferredCultureCode = null; private int mPageSize = 0; private int mGroupID = 0; private string mDocumentForm = null; private bool? mIsGroupAdmin = null; private bool? mIsAuthorizedToCreate = null; /// /// Document properties object. /// public CMSDataProperties mDocumentProperties = new CMSDataProperties(); #endregion #region "Properties" /// /// Messages placeholder /// public override MessagesPlaceHolder MessagesPlaceHolder { get { return plcMess; } } /// /// Component name /// public override string ComponentName { get { return base.ComponentName; } set { base.ComponentName = value; DocumentManager.ComponentName = value; localizeElem.ComponentName = value + "Localize"; propertiesElem.ComponentName = value + "Properties"; } } /// /// Document manager /// public override ICMSDocumentManager DocumentManager { get { docMan.LocalMessagesPlaceHolder = plcMess; docMan.Tree.UseCache = false; docMan.RenderScript = true; return docMan; } } /// /// Indicates if the control should perform the operations. /// public override bool StopProcessing { get { return base.StopProcessing; } set { base.StopProcessing = value; docMan.StopProcessing = value; } } /// /// Tree provider instance. /// public TreeProvider TreeProvider { get { return DocumentManager.Tree; } } /// /// Workflow manager instance. /// public WorkflowManager WorkflowManager { get { return DocumentManager.WorkflowManager; } } /// /// Version manager. /// public VersionManager VersionManager { get { return DocumentManager.VersionManager; } } /// /// Gets current document culture. /// public string PreferredCultureCode { get { return mPreferredCultureCode ?? (mPreferredCultureCode = CMSContext.PreferredCultureCode); } } /// /// Gets or sets the value that indicates whether documents are combined with default culture version. /// public bool CombineWithDefaultCulture { get { return mDocumentProperties.CombineWithDefaultCulture; } set { mDocumentProperties.CombineWithDefaultCulture = value; } } /// /// Alias path determining parent document of library. /// public string LibraryPath { get { string aliasPath = DataHelper.GetNotEmpty(mNodeAliasPath, CMSContext.CurrentAliasPath); return TreePathUtils.EnsureSingleNodePath(aliasPath); } set { mNodeAliasPath = value; } } /// /// Gets parent document of library. /// private TreeNode LibraryNode { get { return mLibraryNode ?? (mLibraryNode = DocumentHelper.GetDocument(CurrentSite.SiteName, LibraryPath, CMSContext.CurrentDocumentCulture.CultureCode, CombineWithDefaultCulture, null, null, null, -1, false, null, TreeProvider)); } } /// /// Number of displayed documents. /// public int PageSize { get { return mPageSize; } set { mPageSize = value; if (gridDocuments == null) { EnsureChildControls(); } gridDocuments.PageSize = value.ToString(); } } /// /// Gets or sets group identifier (if not set only non-group documents are being selected). /// public int GroupID { get { return mGroupID; } set { mGroupID = value; } } /// /// Specifies the form used for editing document properties. /// public string DocumentForm { get { if (string.IsNullOrEmpty(mDocumentForm)) { mDocumentForm = CMS_FILE + ".documentlibrary"; } return mDocumentForm; } set { mDocumentForm = value; } } /// /// Gets or sets identifier of current dialog. /// private string CurrentDialogID { get { return ValidationHelper.GetString(ViewState["CurrentDialogID"], string.Empty); } set { ViewState["CurrentDialogID"] = value; } } /// /// Gets or sets current modal dialog ID. /// private string CurrentModalID { get { return ValidationHelper.GetString(ViewState["CurrentModalID"], string.Empty); } set { ViewState["CurrentModalID"] = value; } } /// /// Gets current dialog control. /// private Panel CurrentDialog { get { return (Panel)FindControl(CurrentDialogID); } } /// /// Gets current modal control. /// private ModalPopupDialog CurrentModal { get { return (ModalPopupDialog)FindControl(CurrentModalID); } } /// /// Prefix used to avoid java-script function name collision. /// public string JS_PREFIX { get { return "DLCM_" + ClientID + "_"; } } /// /// Number of minutes the retrieved content is cached for. Zero indicates that the content will not be cached. /// /// /// This parameter allows you to set up caching of content so that it's not retrieved from the database each time a user requests the page. /// public virtual int CacheMinutes { get { return mDocumentProperties.CacheMinutes; } set { mDocumentProperties.CacheMinutes = value; } } /// /// Name of the cache item the control will use. /// /// /// By setting this name dynamically, you can achieve caching based on URL parameter or some other variable - simply put the value of the parameter to the CacheItemName property. If no value is set, the control stores its content to the item named "URL|ControlID". /// public virtual string CacheItemName { get { return mDocumentProperties.CacheItemName; } set { mDocumentProperties.CacheItemName = value; } } /// /// Cache dependencies, each cache dependency on a new line. /// public virtual string CacheDependencies { get { return mDocumentProperties.CacheDependencies; } set { mDocumentProperties.CacheDependencies = value; } } /// /// Gets or sets the text which is displayed for zero rows result. /// public string ZeroRowsText { get { return ValidationHelper.GetString(GetValue("ZeroRowsText"), gridDocuments.ZeroRowsText); } set { SetValue("ZeroRowsText", value); gridDocuments.ZeroRowsText = value; } } /// /// Permissions icon image URL. /// public string PermissionsIconImageUrl { get { return DataHelper.GetNotEmpty(GetValue("PermissionsIconImageUrl"), GetImageUrl("CMSModules/CMS_DocumentLibrary/LibraryPermissions.png", IsLiveSite)); } set { SetValue("PermissionsIconImageUrl", value); imgPermissions.ImageUrl = value; } } /// /// New file icon image URL. /// public string NewFileIconImageUrl { get { return DataHelper.GetNotEmpty(GetValue("NewFileIconImageUrl"), GetImageUrl("CMSModules/CMS_DocumentLibrary/NewDocument.png", IsLiveSite)); } set { SetValue("NewFileIconImageUrl", value); } } /// /// Allows you to specify whether to check permissions of the current user. If the value is 'false' (default value) no permissions are checked. Otherwise, only nodes for which the user has read permission are displayed. /// public virtual bool CheckPermissions { get { return mDocumentProperties.CheckPermissions; } set { mDocumentProperties.CheckPermissions = value; } } /// /// Indicates if user is authorized to create new document in the document library. /// private bool IsAuthorizedToCreate { get { if (mIsAuthorizedToCreate == null) { mIsAuthorizedToCreate = CurrentUser.IsAuthorizedToCreateNewDocument(LibraryNode, CMS_FILE); } return mIsAuthorizedToCreate.Value; } set { mIsAuthorizedToCreate = value; } } /// /// Identifies if user is group administrator. /// private bool IsGroupAdmin { get { if (mIsGroupAdmin == null) { mIsGroupAdmin = (GroupID > 0) && CurrentUser.IsGroupAdministrator(GroupID); } return mIsGroupAdmin.Value; } } /// /// Class field info for the attachment. /// private FormFieldInfo FieldInfo { get { if (mFieldInfo == null) { FormInfo fi = FormHelper.GetFormInfo(DataClass.ClassName, true); // Get valid extensions from form field info mFieldInfo = fi.GetFormField("FileAttachment"); } return mFieldInfo; } } /// /// Data class info for the cms.file. /// private DataClassInfo DataClass { get { if (mDataClass == null) { // Get document type ('cms.file') settings mDataClass = DataClassInfoProvider.GetDataClass(CMS_FILE); if (mDataClass == null) { throw new Exception("[DocumentLibrary.DataClass]: Class '" + CMS_FILE + "' is missing!"); } } return mDataClass; } } #endregion #region "Enums" private enum Action { RefreshGrid, RefreshGridSimple, WebDAVRefresh, InitRefresh, HidePopup, Localize, Copy, Delete, Properties, Permissions, VersionHistory, CheckOut, CheckIn, UndoCheckout, SubmitToApproval, Reject, Archive } #endregion #region "Page events" protected override void EnsureChildControls() { base.EnsureChildControls(); if (gridDocuments == null) { pnlUpdate.LoadContainer(); } } protected override void OnInit(EventArgs e) { base.OnInit(e); DocumentManager.OnAfterAction += DocumentManager_OnAfterAction; // Register trigger for async postbacks AsyncPostBackTrigger asyncPostBackTrigger = new AsyncPostBackTrigger(); asyncPostBackTrigger.ControlID = ID; pnlUpdate.Triggers.Add(asyncPostBackTrigger); } void DocumentManager_OnAfterAction(object sender, DocumentManagerEventArgs e) { RefreshGrid(); } protected void Page_Load(object sender, EventArgs e) { // Check license LicenseHelper.CheckFeatureAndRedirect(URLHelper.GetCurrentDomain(), FeatureEnum.DocumentLibrary); if (StopProcessing || (LibraryNode == null)) { gridDocuments.StopProcessing = true; arrowContextMenu.StopProcessing = true; rowContextMenu.StopProcessing = true; copyElem.StopProcessing = true; deleteElem.StopProcessing = true; localizeElem.StopProcessing = true; propertiesElem.StopProcessing = true; permissionsElem.StopProcessing = true; versionsElem.StopProcessing = true; DocumentManager.StopProcessing = true; pnlHeader.Visible = false; if (LibraryNode == null) { lblError.Text = ResHelper.Format("documentlibrary.libraryrootnotexist", LibraryPath); } } else { if (BrowserHelper.IsIE9()) { ScriptHelper.RegisterSpellChecker(Page); ScriptHelper.RegisterShortcuts(Page); ScriptHelper.RegisterSaveChanges(Page); } gridDocuments.OnDataReload += gridDocuments_OnDataReload; gridDocuments.OnExternalDataBound += gridDocuments_OnExternalDataBound; gridDocuments.OrderBy = "DocumentName ASC"; gridDocuments.IsLiveSite = IsLiveSite; copyTitle.IsLiveSite = IsLiveSite; propertiesTitle.IsLiveSite = IsLiveSite; permissionsElem.IsLiveSite = IsLiveSite; arrowContextMenu.IsLiveSite = IsLiveSite; arrowContextMenu.JavaScriptPrefix = JS_PREFIX; arrowContextMenu.DocumentForm = DocumentForm; rowContextMenu.IsLiveSite = IsLiveSite; rowContextMenu.JavaScriptPrefix = JS_PREFIX; rowContextMenu.DocumentForm = DocumentForm; DocumentManager.IsLiveSite = IsLiveSite; // Optimize context menu position for all supported browsers bool isRTL = (IsLiveSite && CultureHelper.IsPreferredCultureRTL()) || (!IsLiveSite && CultureHelper.IsUICultureRTL()); if (BrowserHelper.IsGecko() || BrowserHelper.IsIE8()) { arrowContextMenu.OffsetX = isRTL ? 0 : -1; if (BrowserHelper.IsIE8()) { arrowContextMenu.OffsetY = 21; } } else if (BrowserHelper.IsIE7()) { arrowContextMenu.OffsetX = isRTL ? 0 : -2; } else if (BrowserHelper.IsWebKit()) { arrowContextMenu.OffsetX = isRTL ? -1 : 1; arrowContextMenu.OffsetY = 21; } // Register full postback ControlsHelper.RegisterPostbackControl(btnLocalizeSaveClose); ControlsHelper.RegisterPostbackControl(btnPropertiesSaveClose); // Highlighting script StringBuilder highLightScript = new StringBuilder(); highLightScript.AppendLine("function DL_Highlight(element, highlight)"); highLightScript.AppendLine("{"); highLightScript.AppendLine(" if(element.className != 'SelectedRowContext')"); highLightScript.AppendLine(" {"); highLightScript.AppendLine(" if(highlight)"); highLightScript.AppendLine(" {"); highLightScript.AppendLine(" element.className = 'SelectedRow';"); highLightScript.AppendLine(" }"); highLightScript.AppendLine(" else"); highLightScript.AppendLine(" {"); highLightScript.AppendLine(" element.className = 'Row';"); highLightScript.AppendLine(" }"); highLightScript.AppendLine(" }"); highLightScript.AppendLine("}"); ScriptHelper.RegisterClientScriptBlock(this, typeof(string), "DL_highLightScript", ScriptHelper.GetScript(highLightScript.ToString())); // Ensure adequate z-index for UI dialogs ScriptHelper.RegisterStartupScript(this, typeof(string), "dialogZIndex", ScriptHelper.GetScript("window.dialogZIndex = 30000;")); // Action handling scripts StringBuilder actionScript = new StringBuilder(); actionScript.AppendLine("function SetParameter_" + ClientID + "(parameter)"); actionScript.AppendLine("{"); actionScript.AppendLine(" document.getElementById('" + hdnParameter.ClientID + "').value = parameter;"); actionScript.AppendLine("}"); actionScript.AppendLine("function " + Action.RefreshGridSimple + "_" + ClientID + "()"); actionScript.AppendLine("{"); actionScript.AppendLine(" " + ControlsHelper.GetPostBackEventReference(this, Action.RefreshGridSimple.ToString()) + ";"); actionScript.AppendLine("}"); actionScript.AppendLine("function " + Action.HidePopup + "_" + ClientID + "()"); actionScript.AppendLine("{"); actionScript.AppendLine(" " + ControlsHelper.GetPostBackEventReference(this, Action.HidePopup.ToString()) + ";"); actionScript.AppendLine("}"); actionScript.AppendLine("function " + Action.InitRefresh + "_" + ClientID + "(message, fullRefresh, mode)"); actionScript.AppendLine("{"); actionScript.AppendLine(" if(message != '')"); actionScript.AppendLine(" {"); actionScript.AppendLine(" alert(message);"); actionScript.AppendLine(" }"); actionScript.AppendLine(" else"); actionScript.AppendLine(" {"); actionScript.AppendLine(" " + Action.RefreshGridSimple + "_" + ClientID + "();"); actionScript.AppendLine(" }"); actionScript.AppendLine("}"); actionScript.AppendLine("function InitRefresh_" + arrowContextMenu.ClientID + "(message, fullRefresh, mode)"); actionScript.AppendLine("{"); actionScript.AppendLine(Action.InitRefresh + "_" + ClientID + "(message, fullRefresh, mode);"); actionScript.AppendLine("}"); actionScript.AppendLine("function InitRefresh_" + rowContextMenu.ClientID + "(message, fullRefresh, mode)"); actionScript.AppendLine("{"); actionScript.AppendLine(Action.InitRefresh + "_" + ClientID + "(message, fullRefresh, mode);"); actionScript.AppendLine("}"); actionScript.AppendLine("function " + JS_PREFIX + "PerformAction(parameter, action)"); actionScript.AppendLine("{"); actionScript.AppendLine(" SetParameter_" + ClientID + "(parameter);"); actionScript.AppendLine(" " + ControlsHelper.GetPostBackEventReference(this, "##PARAM##").Replace("'##PARAM##'", "action")); actionScript.AppendLine("}"); ScriptHelper.RegisterClientScriptBlock(Page, typeof(string), "actionScript" + ClientID, ScriptHelper.GetScript(actionScript.ToString())); // Setup title elements localizeTitle.TitleText = GetString("documentlibrary.localizedocument"); localizeTitle.TitleImage = GetImageUrl("CMSModules/CMS_DocumentLibrary/Localize.png", IsLiveSite); copyTitle.TitleText = GetString("documentlibrary.copydocument"); copyTitle.TitleImage = GetImageUrl("CMSModules/CMS_DocumentLibrary/Copy.png", IsLiveSite); deleteTitle.TitleText = GetString("documentlibrary.deletedocument"); deleteTitle.TitleImage = GetImageUrl("CMSModules/CMS_DocumentLibrary/Delete.png", IsLiveSite); propertiesTitle.TitleText = GetString("documentlibrary.documentproperties"); propertiesTitle.TitleImage = GetImageUrl("CMSModules/CMS_DocumentLibrary/Properties.png", IsLiveSite); permissionsTitle.TitleText = GetString("documentlibrary.documentpermissions"); permissionsTitle.TitleImage = GetImageUrl("CMSModules/CMS_DocumentLibrary/Permissions.png", IsLiveSite); versionsTitle.TitleText = GetString("LibraryContextMenu.VersionHistory"); versionsTitle.TitleImage = GetImageUrl("CMSModules/CMS_DocumentLibrary/VersionHistory.png", IsLiveSite); // Initialize new file uploader bool uploadVisible = (CurrentUser.IsAuthorizedPerDocument(LibraryNode, new NodePermissionsEnum[] { NodePermissionsEnum.Read, NodePermissionsEnum.Modify }) == AuthorizationResultEnum.Allowed) && IsAuthorizedToCreate; uploadAttachment.Visible = uploadVisible; if (uploadVisible) { string imgTag = String.IsNullOrEmpty(NewFileIconImageUrl) ? null : String.Format("\"\"", ResolveUrl(NewFileIconImageUrl)); uploadAttachment.InnerDivHtml = String.Format("{0}{1}", imgTag, GetString("documentlibrary.newdocument")); uploadAttachment.InnerDivClass = "LibraryUploader"; uploadAttachment.NodeParentNodeID = LibraryNode.NodeID; uploadAttachment.ParentElemID = ClientID; uploadAttachment.SourceType = MediaSourceEnum.Content; uploadAttachment.DisplayInline = true; uploadAttachment.IsLiveSite = IsLiveSite; uploadAttachment.NodeGroupID = GroupID; uploadAttachment.DocumentCulture = CMSContext.CurrentDocumentCulture.CultureCode; uploadAttachment.CheckPermissions = true; uploadAttachment.Width = 100; // Set allowed extensions if ((FieldInfo != null) && ValidationHelper.GetString(FieldInfo.Settings["extensions"], "") == "custom") { // Load allowed extensions uploadAttachment.AllowedExtensions = ValidationHelper.GetString(FieldInfo.Settings["allowed_extensions"], ""); } else { // Use site settings string siteName = CMSContext.CurrentSiteName; uploadAttachment.AllowedExtensions = SettingsKeyProvider.GetStringValue(siteName + ".CMSUploadExtensions"); } uploadAttachment.ReloadData(); } // Initialize library permissions link imgPermissions.ImageUrl = PermissionsIconImageUrl; imgPermissions.AlternateText = GetString("documentlibrary.librarypermissions"); // Check permissions, for group document library also group administrator can modify the permissions bool hasModifyPermission = (CurrentUser.IsAuthorizedPerDocument(LibraryNode, new NodePermissionsEnum[] { NodePermissionsEnum.Read, NodePermissionsEnum.ModifyPermissions }) == AuthorizationResultEnum.Allowed) || IsGroupAdmin; if (!hasModifyPermission) { lblPermissions.Style.Add(HtmlTextWriterStyle.Visibility, "hidden"); } lnkPermissions.Enabled = hasModifyPermission; pnlHeader.Visible = hasModifyPermission || uploadVisible; } } protected override void OnPreRender(EventArgs e) { bool errorOccurred = !string.IsNullOrEmpty(lblError.Text); if (StopProcessing) { Visible = false; } else { // Render the styles link if live site mode if (CMSContext.ViewMode == ViewModeEnum.LiveSite) { CSSHelper.RegisterDesignMode(Page); } pnlUpdate.Visible = !errorOccurred; btnPropertiesSaveClose.Visible = propertiesElem.Visible && propertiesElem.AllowSave; btnLocalizeSaveClose.Visible = localizeElem.Visible && localizeElem.AllowSave; // Ensure correct dialog buttons if ((CurrentModal != null) && (((CurrentModal == mdlProperties) && (propertiesElem.Node != null)) || ((CurrentModal == mdlLocalize) && (localizeElem.Node != null)))) { bool properties = (CurrentModal == mdlProperties); // Get workflow information WorkflowInfo wi = DocumentManager.Workflow; if (wi != null) { if (!wi.WorkflowAutoPublishChanges) { if (properties) { btnPropertiesSaveClose.Visible = false; } else { btnLocalizeSaveClose.Visible = false; } } } } } // Set up the captions btnClose1.ResourceString = btnLocalizeSaveClose.Visible ? "general.cancel" : "general.close"; btnClose2.ResourceString = btnPropertiesSaveClose.Visible ? "general.cancel" : "general.close"; if (Visible && pnlUpdate.Visible) { if (RequestHelper.IsPostBack() && (CurrentModal != null)) { // Show popup after postback CurrentModal.Show(); } } lblError.Visible = errorOccurred && (CMSContext.ViewMode == ViewModeEnum.Design); // Set viewstate pnlLocalizePopup.EnableViewState = (CurrentDialog == pnlLocalizePopup); pnlCopyPopup.EnableViewState = (CurrentDialog == pnlCopyPopup); pnlDeletePopup.EnableViewState = (CurrentDialog == pnlDeletePopup); pnlPermissionsPopup.EnableViewState = (CurrentDialog == pnlPermissionsPopup); pnlVersionsPopup.EnableViewState = (CurrentDialog == pnlVersionsPopup); pnlPropertiesPopup.EnableViewState = (CurrentDialog == pnlPropertiesPopup); } #endregion #region "Grid events" protected DataSet gridDocuments_OnDataReload(string completeWhere, string currentOrder, int currentTopN, string columns, int currentOffset, int currentPageSize, ref int totalRecords) { columns = SqlHelperClass.MergeColumns(DocumentHelper.GETDOCUMENTS_REQUIRED_COLUMNS, "NodeAlias, NodeGUID, DocumentName, DocumentCulture, DocumentModifiedWhen, Published, DocumentType, DocumentWorkflowStepID, DocumentCheckedOutByUserID, SiteName, NodeSiteID, NodeOwner, FileAttachment, FileDescription, DocumentName AS PublishedDocumentName, DocumentType AS PublishedDocumentType"); string whereCondition = null; // Filter group documents whereCondition = (GroupID != 0) ? SqlHelperClass.AddWhereCondition(whereCondition, "(NodeGroupID=" + GroupID + ") OR (NodeGroupID IS NULL)") : SqlHelperClass.AddWhereCondition(whereCondition, "NodeGroupID IS NULL"); // Retrieve documents DataSet documentsDataSet = DocumentHelper.GetDocuments(CurrentSite.SiteName, CMSContext.ResolveCurrentPath(LibraryPath) + "/%", null, CombineWithDefaultCulture, CMS_FILE, whereCondition, currentOrder, 1, false, currentTopN, columns, TreeProvider); NodePermissionsEnum[] permissionsToCheck = null; // Filter documents by permissions if (CheckPermissions) { documentsDataSet = TreeSecurityProvider.FilterDataSetByPermissions(documentsDataSet, NodePermissionsEnum.Read, CurrentUser); permissionsToCheck = new NodePermissionsEnum[] { NodePermissionsEnum.Modify, NodePermissionsEnum.ModifyPermissions, NodePermissionsEnum.Delete }; } else { permissionsToCheck = new NodePermissionsEnum[] { NodePermissionsEnum.Modify, NodePermissionsEnum.ModifyPermissions, NodePermissionsEnum.Delete, NodePermissionsEnum.Read }; } string cultures = PreferredCultureCode; if (CombineWithDefaultCulture) { string siteDefaultCulture = CultureHelper.GetDefaultCulture(CMSContext.CurrentSiteName); if (CMSString.Compare(siteDefaultCulture, PreferredCultureCode, true) != 0) { cultures += ";" + siteDefaultCulture; } } // Ensure permissions flags documentsDataSet = TreeSecurityProvider.FilterDataSetByPermissions(documentsDataSet, permissionsToCheck, CurrentUser, false, cultures); // Filter archived documents for users without modify permission if (!DataHelper.DataSourceIsEmpty(documentsDataSet)) { DataTable dt = documentsDataSet.Tables[0]; ArrayList deleteRows = new ArrayList(); foreach (DataRow dr in dt.Rows) { // If the document is not published and user hasn't modify permission, remove it from data set bool isPublished = ValidationHelper.GetBoolean(dr["Published"], true); string documentCulture = ValidationHelper.GetString(dr["DocumentCulture"], null); bool hasModify = TreeSecurityProvider.CheckPermission(dr, NodePermissionsEnum.Modify, documentCulture); if (!isPublished && !hasModify) { deleteRows.Add(dr); } } // Remove archived documents foreach (DataRow dr in deleteRows) { dt.Rows.Remove(dr); } } totalRecords = DataHelper.GetItemsCount(documentsDataSet); return documentsDataSet; } protected object gridDocuments_OnExternalDataBound(object sender, string sourceName, object parameter) { sourceName = sourceName.ToLowerCSafe(); DataRowView drv = null; bool modifyPermission = true; string documentCulture = null; switch (sourceName) { case "documentname": drv = parameter as DataRowView; string documentName = null; string encodedDocumentName = null; string documentType = null; documentCulture = ValidationHelper.GetString(drv.Row["DocumentCulture"], string.Empty); string alias = ValidationHelper.GetString(drv.Row["NodeAlias"], string.Empty); int nodeId = ValidationHelper.GetInteger(drv.Row["NodeID"], 0); int documentId = ValidationHelper.GetInteger(drv.Row["DocumentID"], 0); bool isLinked = (ValidationHelper.GetInteger(drv["NodeLinkedNodeID"], 0) != 0); string siteName = ValidationHelper.GetString(drv.Row["SiteName"], string.Empty); Guid nodeGuid = ValidationHelper.GetGuid(drv.Row["NodeGUID"], Guid.Empty); string fileDescription = ValidationHelper.GetString(drv.Row["FileDescription"], string.Empty); Guid fileAttachment = ValidationHelper.GetGuid(drv.Row["FileAttachment"], Guid.Empty); // Get permissions flags modifyPermission = TreeSecurityProvider.CheckPermission(drv.Row, NodePermissionsEnum.Modify, documentCulture); bool modifyCulturePermission = TreeSecurityProvider.CheckPermission(drv.Row, NodePermissionsEnum.Modify, PreferredCultureCode); bool deletePermission = TreeSecurityProvider.CheckPermission(drv.Row, NodePermissionsEnum.Delete, documentCulture); bool modifyPermissionsPermission = TreeSecurityProvider.CheckPermission(drv.Row, NodePermissionsEnum.ModifyPermissions, documentCulture); bool readPermission = TreeSecurityProvider.CheckPermission(drv.Row, NodePermissionsEnum.Read, documentCulture); if (modifyPermission) { documentName = ValidationHelper.GetString(drv.Row["DocumentName"], string.Empty); documentType = ValidationHelper.GetString(drv.Row["DocumentType"], string.Empty); } else { documentName = ValidationHelper.GetString(drv.Row["PublishedDocumentName"], string.Empty); documentType = ValidationHelper.GetString(drv.Row["PublishedDocumentType"], string.Empty); } encodedDocumentName = HTMLHelper.HTMLEncode(documentName); string fileTypeIcon = "\"""; string flagIcon = null; if (documentCulture.ToLowerCSafe() != PreferredCultureCode.ToLowerCSafe()) { flagIcon = "\"""; } string menuParameter = ScriptHelper.GetString(nodeId + "|" + documentCulture); string attachmentName = encodedDocumentName; string toolTip = UIHelper.GetTooltipAttributes(null, 0, 0, null, null, null, fileDescription, null, 300); // Generate link to open document if (fileAttachment != Guid.Empty) { // Get document URL string attachmentUrl = CMSContext.ResolveUIUrl(AttachmentURLProvider.GetPermanentAttachmentUrl(nodeGuid, alias)); if (modifyPermission) { attachmentUrl = URLHelper.AddParameterToUrl(attachmentUrl, "latestfordocid", ValidationHelper.GetString(documentId, string.Empty)); attachmentUrl = URLHelper.AddParameterToUrl(attachmentUrl, "hash", ValidationHelper.GetHashString("d" + documentId)); } attachmentUrl = URLHelper.UpdateParameterInUrl(attachmentUrl, "chset", Guid.NewGuid().ToString()); if (!string.IsNullOrEmpty(attachmentUrl)) { attachmentName = "" + encodedDocumentName + " "; } } else { attachmentName = "" + encodedDocumentName + ""; } // Add linked flag if (isLinked) { attachmentName += UIHelper.GetDocumentMarkImage(Page, DocumentMarkEnum.Link); } bool showContextMenu = readPermission && (modifyPermission || modifyPermissionsPermission || deletePermission || (IsAuthorizedToCreate && modifyCulturePermission)); // Generate row with icons, hover action and context menu StringBuilder contextMenuString = new StringBuilder(); contextMenuString.Append(""); contextMenuString.Append(" "); if (showContextMenu) { contextMenuString.Append(ContextMenuContainer.GetStartTag("libraryMenu_" + arrowContextMenu.ClientID, menuParameter, false, HtmlTextWriterTag.Td, "ArrowIcon", null)); contextMenuString.Append(" "); contextMenuString.Append(ContextMenuContainer.GetEndTag(HtmlTextWriterTag.Td)); } else { contextMenuString.Append(""); } if (showContextMenu) { contextMenuString.Append(ContextMenuContainer.GetStartTag("libraryMenu_" + rowContextMenu.ClientID, menuParameter, true, HtmlTextWriterTag.Td, "FileTypeIcon", null)); } else { contextMenuString.Append(""); contextMenuString.Append("
 "); } contextMenuString.Append(fileTypeIcon); contextMenuString.Append(ContextMenuContainer.GetEndTag(HtmlTextWriterTag.Td)); if (showContextMenu) { contextMenuString.Append(ContextMenuContainer.GetStartTag("libraryMenu_" + rowContextMenu.ClientID, menuParameter, true, HtmlTextWriterTag.Td, "RowContent", "width: 100%;")); } else { contextMenuString.Append(""); } contextMenuString.Append(attachmentName); contextMenuString.Append(ContextMenuContainer.GetEndTag(HtmlTextWriterTag.Td)); if (!string.IsNullOrEmpty(flagIcon)) { contextMenuString.Append(ContextMenuContainer.GetStartTag("libraryMenu_" + rowContextMenu.ClientID, menuParameter, true, HtmlTextWriterTag.Td, "FlagIcon", null)); contextMenuString.Append(flagIcon); contextMenuString.Append(ContextMenuContainer.GetEndTag(HtmlTextWriterTag.Td)); } contextMenuString.Append("
"); return contextMenuString.ToString(); case "modifiedwhen": case "modifiedwhentooltip": if (string.IsNullOrEmpty(parameter.ToString())) { return string.Empty; } else { // Handle time zones DateTime modifiedWhen = ValidationHelper.GetDateTime(parameter, DateTimeHelper.ZERO_TIME); if (sourceName == "modifiedwhen") { if (IsLiveSite) { return CMSContext.ConvertDateTime(modifiedWhen, this); } else { return TimeZoneHelper.GetCurrentTimeZoneDateTimeString(modifiedWhen, CurrentUser, CurrentSite, out usedTimeZone); } } else { if (!IsLiveSite) { if (TimeZoneHelper.TimeZonesEnabled() && (usedTimeZone == null)) { TimeZoneHelper.GetCurrentTimeZoneDateTimeString(modifiedWhen, CurrentUser, CurrentSite, out usedTimeZone); } return TimeZoneHelper.GetGMTLongStringOffset(usedTimeZone); } else { return null; } } } case "status": string stepName = string.Empty; string toReturn = string.Empty; // Extract datarow drv = parameter as DataRowView; // Gain desired values from datarow view int workflowStepId = ValidationHelper.GetInteger(drv["DocumentWorkflowStepID"], 0); int checkedOutByUserId = ValidationHelper.GetInteger(drv["DocumentCheckedOutByUserID"], 0); documentCulture = ValidationHelper.GetString(drv.Row["DocumentCulture"], string.Empty); modifyPermission = TreeSecurityProvider.CheckPermission(drv.Row, NodePermissionsEnum.Modify, documentCulture); // Add 'checked out' icon if ((checkedOutByUserId > 0) && modifyPermission) { toReturn = " " + UIHelper.GetDocumentMarkImage(Page, DocumentMarkEnum.CheckedOut); } // Add workflow step name if ((workflowStepId > 0) && modifyPermission) { WorkflowStepInfo workflowStepInfo = WorkflowStepInfoProvider.GetWorkflowStepInfo(workflowStepId); if (workflowStepInfo != null) { stepName = HTMLHelper.HTMLEncode(ResHelper.LocalizeString(workflowStepInfo.StepDisplayName)); } } else { // Add dash if step name is not present stepName = GetString("general.dash"); } toReturn = stepName + toReturn; return toReturn; } return parameter; } #endregion #region "Methods" /// /// Refreshes the unigrid control. /// private void RefreshGrid() { gridDocuments.ReloadData(); } /// /// Performs actions necessary to hide popup dialog. /// private void HideCurrentPopup() { if ((CurrentModal != null) && (CurrentDialog != null)) { // Hide modal dialog CurrentModal.Hide(); // Reset dialog control's viewstate and visibility CurrentDialog.EnableViewState = false; CurrentDialog.Visible = false; } // Reset identifiers CurrentModalID = null; CurrentDialogID = null; } /// /// Performs actions necessary to show the popup dialog. /// /// New dialog control /// Modal control private void ShowPopup(Control dialogControl, ModalPopupDialog modalPopup) { // Set new identifiers CurrentModalID = modalPopup.ID; CurrentDialogID = dialogControl.ID; if ((CurrentModal != null) && (CurrentDialog != null)) { // Enable dialog control's viewstate and visibility CurrentDialog.EnableViewState = true; CurrentDialog.Visible = true; // Show modal popup CurrentModal.Show(); } } #endregion #region "IPostBackEventHandler Members" public void RaisePostBackEvent(string eventArgument) { try { // Parse action to perform Action action = (Action)Enum.Parse(typeof(Action), eventArgument); // Parse action parameter string[] parameters = ValidationHelper.GetString(hdnParameter.Value, string.Empty).Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries); // Check whether all parameters are present for parameterized pop-ups if (parameters.Length == 2) { // Initialize document manager int nodeId = ValidationHelper.GetInteger(parameters[0], 0); string cultureCode = ValidationHelper.GetString(parameters[1], string.Empty); DocumentManager.Mode = FormModeEnum.Update; DocumentManager.ClearNode(); DocumentManager.DocumentID = 0; DocumentManager.NodeID = nodeId; DocumentManager.CultureCode = cultureCode; TreeNode currentNode = DocumentManager.Node; switch (action) { case Action.Localize: // Initialize localization dialog localizeElem.Action = "newculture"; localizeElem.NodeID = nodeId; localizeElem.AlternativeFormName = DocumentForm; localizeElem.CopyDefaultDataFromDocumentID = currentNode.DocumentID; localizeElem.CheckPermissions = true; pnlLocalizePopup.Visible = true; localizeElem.ReloadData(true); ShowPopup(pnlLocalizePopup, mdlLocalize); break; case Action.Copy: // Initialize copy dialog copyElem.CopiedNodeID = nodeId; copyElem.CopiedDocumentCulture = cultureCode; copyElem.TargetNodeID = LibraryNode.NodeID; copyElem.ReloadData(true); copyElem.CancelButton.OnClientClick = Action.HidePopup + "_" + ClientID + "();return false;"; ShowPopup(pnlCopyPopup, mdlCopy); break; case Action.Delete: // Initialize delete dialog deleteElem.DeletedNodeID = nodeId; deleteElem.DeletedDocumentCulture = cultureCode; deleteElem.ReloadData(true); deleteElem.CancelButton.OnClientClick = Action.HidePopup + "_" + ClientID + "();return false;"; ShowPopup(pnlDeletePopup, mdlDelete); break; case Action.Properties: // Initialize properties dialog propertiesElem.NodeID = nodeId; propertiesElem.CultureCode = cultureCode; propertiesElem.AlternativeFormName = DocumentForm; propertiesElem.CheckPermissions = true; pnlPropertiesPopup.Visible = true; propertiesElem.ReloadData(true); ShowPopup(pnlPropertiesPopup, mdlProperties); break; case Action.VersionHistory: // Initialize version history dialog versionsElem.NodeID = nodeId; versionsElem.DocumentCulture = cultureCode; versionsElem.SetupControl(); versionsElem.ReloadData(); ShowPopup(pnlVersionsPopup, mdlVersions); break; case Action.Permissions: // Initialize permissions dialog permissionsElem.Node = currentNode; permissionsElem.DisplayButtons = false; permissionsElem.ReloadData(true); ReloadPermissions(); ShowPopup(pnlPermissionsPopup, mdlPermissions); break; case Action.CheckOut: // Perform document checkout DocumentManager.CheckOutDocument(); break; case Action.CheckIn: // Perform document check-in DocumentManager.CheckInDocument(null); break; case Action.UndoCheckout: // Perform undo checkout on document DocumentManager.UndoCheckOutDocument(); break; case Action.SubmitToApproval: // Approve document DocumentManager.ApproveDocument(0, null); break; case Action.Reject: // Reject document DocumentManager.RejectDocument(0, null); break; case Action.Archive: // Archive document DocumentManager.ArchiveDocument(0, null); break; case Action.WebDAVRefresh: WorkflowInfo wi = DocumentManager.Workflow; // Check if document uses workflow and check-out/check-in is disabled if ((wi != null) && !wi.UseCheckInCheckOut(currentNode.NodeSiteName) && !wi.WorkflowAutoPublishChanges) { // Check permission to modify document if (CMSContext.CurrentUser.IsAuthorizedPerDocument(currentNode, NodePermissionsEnum.Modify) == AuthorizationResultEnum.Allowed) { // Get current step WorkflowStepInfo currentStep = DocumentManager.Step; // Check if document uses workflow and step is 'published' or 'archived' if (currentStep.StepIsPublished || currentStep.StepIsArchived) { // Ensure version for later detection whether node is published VersionManager.EnsureVersion(currentNode, currentNode.IsPublished); // Move to first step WorkflowManager.MoveToFirstStep(currentNode, null); // Refresh grid RefreshGrid(); } } } break; } } // General actions switch (action) { case Action.RefreshGrid: // Refresh unigrid RefreshGrid(); break; case Action.HidePopup: // Find and hide current popup HideCurrentPopup(); break; } } catch (Exception ex) { AddAlert(GetString("general.erroroccurred") + " " + ex.Message); } } #endregion #region "Control events" protected void btnClose_Click(object sender, EventArgs e) { if ((CurrentModal != null) && (CurrentModal == mdlPermissions)) { // Refresh header pnlUpdateHeader.Update(); } // Hide current popup dialog HideCurrentPopup(); } protected void btnSavePermissions_Click(object sender, EventArgs e) { // Save permissions permissionsElem.Save(); ReloadPermissions(); } protected void lnkPermissions_Click(object sender, EventArgs e) { // Display library permissions dialog permissionsElem.Node = LibraryNode; permissionsElem.GroupID = GroupID; permissionsElem.ReloadData(true); permissionsElem.DisplayButtons = false; ReloadPermissions(); ShowPopup(pnlPermissionsPopup, mdlPermissions); } protected void btnPropertiesSaveClose_Click(object sender, EventArgs e) { if (propertiesElem.SaveDocument()) { RefreshGrid(); HideCurrentPopup(); } } protected void btnLocalizeSaveClose_Click(object sender, EventArgs e) { if (localizeElem.SaveDocument()) { RefreshGrid(); HideCurrentPopup(); } } #endregion #region "Other methods" private void ReloadPermissions() { btnSavePermissions.Enabled = (CurrentUser.IsAuthorizedPerDocument(permissionsElem.Node, new NodePermissionsEnum[] { NodePermissionsEnum.Read, NodePermissionsEnum.ModifyPermissions }) == AuthorizationResultEnum.Allowed) || IsGroupAdmin; } private void AddAlert(string message) { AddScript(ScriptHelper.GetAlertScript(message)); } private void AddScript(string script) { ScriptHelper.RegisterStartupScript(this, typeof(string), script.GetHashCode().ToString(), script); } #endregion }