using System; using System.Security; using System.Text; using System.Web.UI; using System.Collections; using CMS.CMSHelper; using CMS.ExtendedControls; using CMS.GlobalHelper; using CMS.IO; using CMS.SettingsProvider; using CMS.UIControls; public partial class CMSModules_Content_Controls_Dialogs_Selectors_FileSystemSelector_FileSystemSelector : CMSUserControl { private const char ARG_SEPARATOR = '|'; #region "Private variables" // Content variables private string mNodeID = string.Empty; protected FileSystemDialogConfiguration mConfig; private Hashtable mParameters; #endregion #region "Properties" /// /// Gets or sets last searched value. /// private string LastSearchedValue { get { return hdnLastSearchedValue.Value; } set { hdnLastSearchedValue.Value = value; } } /// /// Gets current action name. /// private string CurrentAction { get { return hdnAction.Value.ToLowerCSafe().Trim(); } set { hdnAction.Value = value; } } /// /// Gets current action argument value. /// private string CurrentArgument { get { return hdnArgument.Value; } } /// /// Returns current properties (according to OutputFormat). /// protected ItemProperties Properties { get { return pathProperties; } } /// /// Update panel where properties control resides. /// protected UpdatePanel PropertiesUpdatePanel { get { return pnlUpdateProperties; } } /// /// Gets or sets ID of the node selected in the content tree. /// private string NodeID { get { if (String.IsNullOrEmpty(mNodeID)) { mNodeID = ValidationHelper.GetString(hdnLastNodeSlected.Value, string.Empty); } return mNodeID; } set { if (!value.StartsWithCSafe(FullStartingPath, true)) { value = FullStartingPath; } mNodeID = value; hdnLastNodeSlected.Value = value; } } /// /// Maximum number of tree nodes displayed within the tree. /// private int MaxTreeNodes { get { string siteName = CMSContext.CurrentSiteName; return SettingsKeyProvider.GetIntValue((String.IsNullOrEmpty(siteName) ? string.Empty : siteName + ".") + "CMSMaxTreeNodes"); } } /// /// Indicates whether the asynchronous postback occurs on the page. /// private bool IsAsyncPostback { get { return ScriptManager.GetCurrent(Page).IsInAsyncPostBack; } } /// /// Indicates whether the post back is result of some hidden action. /// private bool IsAction { get; set; } /// /// Indicates whether the content tree is displaying more than max tree nodes. /// private bool IsDisplayMore { get { return fileSystemView.IsDisplayMore; } set { fileSystemView.IsDisplayMore = value; } } /// /// Gets or sets selected item to colorize. /// private String ItemToColorize { get { return ValidationHelper.GetString(ViewState["ItemToColorize"], String.Empty); } set { ViewState["ItemToColorize"] = value; } } /// /// Value of node under which more content should be displayed. /// private string MoreContentNode { get { return ValidationHelper.GetString(ViewState["MoreContentNode"], string.Empty); } set { ViewState["MoreContentNode"] = value; } } /// /// Dialog configuration. /// public FileSystemDialogConfiguration Config { get { if (mConfig == null) { mConfig = new FileSystemDialogConfiguration(); } return mConfig; } set { mConfig = value; } } /// /// Full file system starting path of dialog. /// public string FullStartingPath { get { if (Config.StartingPath.StartsWithCSafe("~")) { return Server.MapPath(Config.StartingPath).TrimEnd('\\'); } else { if (Config.StartingPath.EndsWithCSafe(":\\")) { return Config.StartingPath; } } return Config.StartingPath.TrimEnd('\\'); } } /// /// Messages placeholder /// public override MessagesPlaceHolder MessagesPlaceHolder { get { return fileSystemView.MessagesPlaceHolder; } } #endregion #region "Public properties" /// /// Dialog parameters collection. /// public Hashtable Parameters { get { if (mParameters == null) { // Try to get parameters from the session object dp = SessionHelper.GetValue("DialogParameters"); if (dp != null) { mParameters = (dp as Hashtable); } } return mParameters; } set { mParameters = value; SessionHelper.SetValue("DialogParameters", value); } } /// /// Indicates if help icon should be hidden. /// public bool RemoveHelpIcon { get { return menuElem.RemoveHelpIcon; } set { menuElem.RemoveHelpIcon = value; } } #endregion #region "Control methods" /// /// Init. /// protected override void OnInit(EventArgs e) { base.OnInit(e); InitFromQueryString(); } /// /// Pre render. /// protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); // High-light item being edited if (ItemToColorize != String.Empty) { ColorizeRow(ItemToColorize); } // Display info on listing more content if (IsDisplayMore && !Config.ShowFolders) //curently selected more object && (TreeNodeObj != null)) { string closeLink = String.Format("{0}", GetString("general.close")); string currentPath = ""; // Display relative paths with tilda if (Config.StartingPath.StartsWithCSafe("~")) { string serverPath = Server.MapPath(Config.StartingPath).TrimEnd('\\'); currentPath += NodeID.Replace(serverPath.Substring(0, serverPath.LastIndexOfCSafe('\\') + 1), string.Empty); } else { currentPath += NodeID.Replace(NodeID.Substring(0, Config.StartingPath.TrimEnd('\\').LastIndexOfCSafe('\\') + 1), string.Empty); } currentPath += ""; string listingMsg = string.Format(GetString("dialogs.filesystem.listinginfo"), currentPath, closeLink); fileSystemView.DisplayListingInfo(listingMsg); } menuElem.EnableDeleteFolder = !FullStartingPath.EqualsCSafe(NodeID, true); } /// /// Page load. /// protected void Page_Load(object sender, EventArgs e) { if (!StopProcessing) { SetupControls(); EnsureLoadedData(); } else { Visible = false; } } #endregion #region "Control initialization" /// /// Initializes additional controls. /// private void SetupControls() { // Initialize design scripts InitializeDesignScripts(); fileSystemView.IsLiveSite = IsLiveSite; fileSystemView.ViewMode = menuElem.SelectedViewMode; InitializeFileSystemView(); InitializeMenuElem(); pathProperties.DialogConfig = Config; if (!IsAsyncPostback) { // Initialize scripts InitializeControlScripts(); // Initialize content tree control InitializeFileSystemTree(); string parameter = FullStartingPath; if (!String.IsNullOrEmpty(Config.DefaultPath)) { parameter = Path.Combine(parameter, Config.DefaultPath); } // Handle the folder action HandleFolderAction(parameter.Replace("'", "\\'"), false); if (!String.IsNullOrEmpty(Config.SelectedPath) || Config.ShowFolders) { if (Config.ShowFolders && String.IsNullOrEmpty(Config.SelectedPath)) { Config.SelectedPath = Config.StartingPath; } string fsPath = Config.SelectedPath; if (Config.StartingPath.StartsWithCSafe("~")) { try { fsPath = Server.MapPath(fsPath); } catch { // Set default path fsPath = string.Empty; } } bool isFile = File.Exists(fsPath); bool exist = isFile || Directory.Exists(fsPath); // If folder try to select default or starting folder if (!exist && Config.ShowFolders) { try { fsPath = parameter; exist = Directory.Exists(fsPath); if (!exist) { fsPath = Server.MapPath(Config.StartingPath); exist = Directory.Exists(fsPath); } } catch { } } if (exist) { string size = string.Empty; try { if (isFile) { FileInfo fi = FileInfo.New(fsPath); size = DataHelper.GetSizeString(ValidationHelper.GetLong(fi.Length, 0)); } } catch (Exception) { } SelectMediaItem(String.Format("{0}{1}{2}{1}{3}", fsPath, ARG_SEPARATOR, size, isFile)); } } } } /// /// Initialize design jQuery scripts. /// private void InitializeDesignScripts() { StringBuilder sb = new StringBuilder(); sb.Append("setTimeout('InitializeDesign();',10);"); sb.Append("$j(window).resize(function() { InitializeDesign(); });"); ScriptManager.RegisterStartupScript(Page, typeof(Page), "designScript", sb.ToString(), true); } /// /// Initializes all the script required for communication between controls. /// private void InitializeControlScripts() { // SetAction function setting action name and passed argument string script = String.Format(@" function SetAction(action, argument) {{ var hdnAction = document.getElementById('{0}'); var hdnArgument = document.getElementById('{1}'); if ((hdnAction != null) && (hdnArgument != null)) {{ if (action != null) {{ hdnAction.value = action; }} if (argument != null) {{ hdnArgument.value = argument; }} }} }} function imageEdit_FileSystemRefresh(arg){{{{ SetAction('imageedit', arg); RaiseHiddenPostBack(); }}}}", hdnAction.ClientID, hdnArgument.ClientID); // Get reffernce causing postback to hidden button script += String.Format("function RaiseHiddenPostBack(){{{0};}}\n", ControlsHelper.GetPostBackEventReference(hdnButton, string.Empty)); ltlScript.Text = ScriptHelper.GetScript(script); } /// /// Initialization of file grid control. /// private void InitializeFileSystemView() { fileSystemView.Config = Config; } /// /// Initializes content tree element. /// private void InitializeFileSystemTree() { treeFileSystem.Visible = true; treeFileSystem.DeniedNodePostback = false; treeFileSystem.AllowMarks = false; treeFileSystem.NodeTextTemplate = String.Format("##ICON####NODENAME##", ARG_SEPARATOR); treeFileSystem.SelectedNodeTextTemplate = String.Format("##ICON####NODENAME##", ARG_SEPARATOR); treeFileSystem.MaxTreeNodeText = String.Format("{0}", GetString("ContentTree.SeeListing")); treeFileSystem.IsLiveSite = IsLiveSite; treeFileSystem.ExpandDefaultPath = true; treeFileSystem.StartingPath = Config.StartingPath; if (treeFileSystem.DefaultPath == String.Empty) { treeFileSystem.DefaultPath = Config.DefaultPath; } treeFileSystem.AllowedFolders = Config.AllowedFolders; treeFileSystem.ExcludedFolders = Config.ExcludedFolders; } /// /// Ensures that required data are displayed. /// private void EnsureLoadedData() { // If no action takes place if ((CurrentAction == string.Empty) && (URLHelper.IsPostback())) { fileSystemView.StartingPath = NodeID; } } #endregion #region "Common event methods" /// /// Behaves as mediator in communication line between control taking action and the rest of the same level controls. /// protected void hdnButton_Click(object sender, EventArgs e) { IsAction = true; switch (CurrentAction) { case "insertitem": GetSelectedItem(); break; case "search": HandleSearchAction(CurrentArgument); break; case "select": HandleSelectAction(CurrentArgument); break; case "refresh": HandleRefreshAction(CurrentArgument); break; case "refreshtree": HandleTreeRefreshAction(CurrentArgument); break; case "delete": HandleDeleteAction(CurrentArgument); break; case "morecontentselect": case "contentselect": // Reset previous filter value ResetSearchFilter(); string[] argArr = CurrentArgument.Split(ARG_SEPARATOR); int childNodesCnt = argArr.Length == 2 ? ValidationHelper.GetInteger(argArr[1], 0) : 0; // If more content is requested IsDisplayMore = (!IsDisplayMore ? (((CurrentAction == "morecontentselect") || (childNodesCnt > MaxTreeNodes))) : IsDisplayMore); HandleFolderAction(argArr[0], IsDisplayMore); if (Config.ShowFolders) { HandleSelectAction(String.Format("{0}{1}{1}false", argArr[0], ARG_SEPARATOR)); } break; case "parentselect": try { DirectoryInfo dir = DirectoryInfo.New(CurrentArgument); int childNodes = 0; childNodes = dir.GetDirectories().Length; if (childNodes > MaxTreeNodes) { IsDisplayMore = (!IsDisplayMore ? (childNodes > MaxTreeNodes) : IsDisplayMore); } } // If error occured don't do a thing catch { } HandleFolderAction(CurrentArgument, true); break; case "closelisting": IsDisplayMore = false; MoreContentNode = null; HandleFolderAction(NodeID, false); break; case "cancelfolder": ScriptManager.RegisterStartupScript(Page, typeof(Page), "EnsureTopWindow", "if (self.focus) { self.focus(); }", true); ClearActionElems(); break; case "imageedit": HandleRefreshAction(CurrentArgument); ColorizeLastSelectedRow(); break; default: ColorizeLastSelectedRow(); pnlUpdateView.Update(); break; } } /// /// Handles actions occurring when some text is searched. /// /// Argument holding information on searched text private void HandleSearchAction(string argument) { LastSearchedValue = argument; // Load new data filtered by searched text fileSystemView.SearchText = argument; fileSystemView.StartingPath = NodeID; // Reload content fileSystemView.Reload(); pnlUpdateView.Update(); // Keep focus in search text box ScriptManager.RegisterStartupScript(Page, typeof(Page), "SetSearchFocus", "setTimeout('SetSearchFocus();', 200);", true); // Forget recent action ClearActionElems(); } /// /// Handles actions occurring when some item is selected. /// /// Argument holding information on selected item private void HandleSelectAction(string argument) { // Create new selected media item SelectMediaItem(argument); // Forget recent action ClearActionElems(); } /// /// Initializes menu element. /// private void InitializeMenuElem() { plcMenu.Visible = Config.AllowManage; menuElem.TargetFolderPath = NodeID; menuElem.AllowedExtensions = Config.AllowedExtensions; menuElem.NewTextFileExtension = Config.NewTextFileExtension; } /// /// Handles actions occurring when refresh is requested. /// /// Argument holding information on requested item private void HandleRefreshAction(string argument) { // Load new data filtered by searched text fileSystemView.SearchText = LastSearchedValue; fileSystemView.StartingPath = NodeID; // Reload the file system view fileSystemView.Reload(); pnlUpdateView.Update(); // Forget recent action ClearActionElems(); } /// /// Handles actions occurring when tree refresh is requested. /// /// Argument holding information on requested item private void HandleTreeRefreshAction(string argument) { InitializeFileSystemTree(); // Fill with new info NodeID = argument; treeFileSystem.DefaultPath = NodeID; treeFileSystem.ExpandDefaultPath = true; treeFileSystem.ReloadData(); pnlUpdateTree.Update(); pnlUpdateMenu.Update(); // Reload the file system view fileSystemView.StartingPath = NodeID; fileSystemView.Reload(); pnlUpdateView.Update(); InitializeMenuElem(); menuElem.EnableDeleteFolder = !FullStartingPath.EqualsCSafe(NodeID, true); menuElem.UpdateActionsMenu(); // Forget recent action ClearActionElems(); } /// /// Handles actions occurring when some item is deleted. /// /// Argument holding information on deleted item private void HandleDeleteAction(string argument) { if (!string.IsNullOrEmpty(argument)) { string[] argArr = argument.Split(ARG_SEPARATOR); if (argArr.Length >= 2) { // Get information from argument string path = argArr[0]; bool isFile = ValidationHelper.GetBoolean(argArr[2], true); if (path.StartsWithCSafe(NodeID, true)) { if (isFile && File.Exists(path)) { File.Delete(path); } else if (Directory.Exists(path)) { Directory.Delete(path); } } else { ShowError(GetString("dialogs.filesystem.invalidfilepath")); } // Load new data filtered by searched text fileSystemView.SearchText = LastSearchedValue; fileSystemView.StartingPath = NodeID; // Reload the file system view fileSystemView.Reload(); pnlUpdateView.Update(); // Clear selected item Properties.ClearProperties(); pnlUpdateProperties.Update(); } } // Forget recent action ClearActionElems(); } /// /// Handles actions related to the folders. /// /// Argument related to the folder action /// Indicates if is new folder private void HandleFolderAction(string argument, bool forceReload) { HandleFolderAction(argument, forceReload, true); } /// /// Handles actions related to the folders. /// /// Argument related to the folder action /// Indicates if is new folder /// Indicates if selection should be called private void HandleFolderAction(string argument, bool forceReload, bool callSelection) { NodeID = ValidationHelper.GetString(argument, string.Empty); // Reload content tree if neccessary if (forceReload) { InitializeFileSystemTree(); // Fill with new info treeFileSystem.DefaultPath = NodeID; treeFileSystem.ExpandDefaultPath = true; treeFileSystem.ReloadData(); pnlUpdateTree.Update(); ScriptManager.RegisterStartupScript(Page, typeof(Page), "EnsureTopWindow", "if (self.focus) { self.focus(); }", true); } ColorizeLastSelectedRow(); // Get parent node ID info string parentId = string.Empty; if (FullStartingPath.ToLowerCSafe() != NodeID.ToLowerCSafe()) { try { parentId = (DirectoryInfo.New(NodeID)).Parent.FullName; } // Access denied to parent catch (SecurityException) { } } fileSystemView.ShowParentButton = !String.IsNullOrEmpty(parentId); fileSystemView.NodeParentID = parentId; fileSystemView.Config = Config; // Load new data if ((Config.ShowFolders) && (NodeID.LastIndexOfCSafe('\\') != -1)) { fileSystemView.StartingPath = NodeID.Substring(0, argument.LastIndexOfCSafe('\\') + 1); } fileSystemView.StartingPath = NodeID; // Reload view control's content fileSystemView.Reload(); pnlUpdateView.Update(); InitializeMenuElem(); menuElem.UpdateActionsMenu(); pnlUpdateMenu.Update(); ClearActionElems(); } #endregion #region "Helper methods" /// /// Returns selected item parameters as name-value collection. /// public void GetSelectedItem() { if (Properties.Validate()) { // Get selected item information Hashtable properties = Properties.GetItemProperties(); // Get JavaScript for inserting the item string script = CMSDialogHelper.GetFileSystemItem(properties); if (!string.IsNullOrEmpty(script)) { ScriptManager.RegisterStartupScript(Page, typeof(Page), "insertItemScript", script, true); } } else { // Display error message pnlUpdateProperties.Update(); } } /// /// Performs actions necessary to select particular item from a list. /// private void SelectMediaItem(string argument) { if (!string.IsNullOrEmpty(argument)) { string[] argArr = argument.Split(ARG_SEPARATOR); if (argArr.Length >= 2) { // Get information from argument string path = argArr[0]; string size = ValidationHelper.GetString(argArr[1], string.Empty); bool isFile = ValidationHelper.GetBoolean(argArr[2], true); bool avoidPropUpdate = ItemToColorize.EqualsCSafe(path, true); if ((isFile) && (File.Exists(path))) { FileInfo fi = FileInfo.New(path); path = fi.FullName; } else { if (Directory.Exists(path)) { DirectoryInfo di = DirectoryInfo.New(path); path = di.FullName; } } ItemToColorize = path.Replace("\\", "\\\\").Replace("'", "\\'").ToLowerCSafe(); if (!avoidPropUpdate) { // Get selected properties from session Hashtable selectedParameters = SessionHelper.GetValue("DialogSelectedParameters") as Hashtable; if (selectedParameters == null) { selectedParameters = new Hashtable(); } // Update selected properties selectedParameters[DialogParameters.ITEM_PATH] = path; selectedParameters[DialogParameters.ITEM_RESOLVED_PATH] = URLHelper.ResolveUrl(path); selectedParameters[DialogParameters.ITEM_SIZE] = size; selectedParameters[DialogParameters.ITEM_ISFILE] = isFile; selectedParameters[DialogParameters.ITEM_RELATIVEPATH] = Config.StartingPath.StartsWithCSafe("~"); // Force media properties control to load selected item Properties.LoadItemProperties(selectedParameters); // Update properties panel PropertiesUpdatePanel.Update(); } } } } /// /// Highlights item specified by its ID. /// /// String representation of item ID protected void ColorizeRow(string itemId) { // Keep item selected ScriptManager.RegisterStartupScript(Page, typeof(Page), "ColorizeSelectedRow", String.Format("function tryColorizeRow(itemId) {{ if (window.ColorizeRow){{ ColorizeRow(itemId); }} else {{ setTimeout(\'tryColorizeRow(\"{0}\");\', 500); }} }}; tryColorizeRow(\"{0}\");", itemId), true); } /// /// Clears hidden control elements fo future use. /// private void ClearActionElems() { CurrentAction = string.Empty; hdnArgument.Value = string.Empty; } /// /// Highlights row recently selected. /// protected void ColorizeLastSelectedRow() { // Keep item selected ScriptManager.RegisterStartupScript(Page, typeof(Page), "ColorizeLastSelectedRow", "if (window.ColorizeLastRow) { window.ColorizeLastRow(); }", true); } /// /// Loads selected item parameters into the selector. /// public void LoadItemConfiguration() { // Load properties Properties.LoadItemProperties(Parameters); pnlUpdateProperties.Update(); // Remember item to colorize ItemToColorize = NodeID.Replace("\\", "\\\\").Replace("'", "\\'"); } /// /// Initialization from query string. /// public void InitFromQueryString() { // Get allowed and excluded folders and extensions FileSystemDialogConfiguration config = Config; config.AllowManage = QueryHelper.GetBoolean("allow_manage", config.AllowManage); config.AllowedExtensions = QueryHelper.GetString("allowed_extensions", config.AllowedExtensions); config.NewTextFileExtension = QueryHelper.GetString("newfile_extension", config.NewTextFileExtension); config.AllowedFolders = QueryHelper.GetString("allowed_folders", config.AllowedFolders); config.ExcludedExtensions = QueryHelper.GetString("excluded_extensions", config.ExcludedExtensions); config.ExcludedFolders = QueryHelper.GetString("excluded_folders", config.ExcludedFolders); config.AllowNonApplicationPath = QueryHelper.GetBoolean("allow_nonapp_path", config.AllowNonApplicationPath); // Get starting path config.StartingPath = QueryHelper.GetString("starting_path", "~/"); if (config.StartingPath.StartsWithCSafe("~") && (config.StartingPath != "~/")) { config.StartingPath = config.StartingPath.TrimEnd('/'); } else { // If only application path allowed, set it if (!config.AllowNonApplicationPath) { string startPath = config.StartingPath; if (config.StartingPath.StartsWithCSafe("~")) { startPath = Server.MapPath(config.StartingPath); } if (!startPath.StartsWithCSafe(Server.MapPath("~/"))) { config.StartingPath = "~/"; } } else { if (!config.StartingPath.EndsWithCSafe(":\\")) { config.StartingPath = config.StartingPath.TrimEnd('\\'); } } } // Get selected path config.SelectedPath = QueryHelper.GetString("selected_path", String.Empty); // If starting path under website try to map selected path if (config.StartingPath.StartsWithCSafe("~") && !String.IsNullOrEmpty(config.SelectedPath)) { try { config.SelectedPath = Server.MapPath(config.SelectedPath).Replace(Server.MapPath(config.StartingPath).TrimEnd('\\'), config.StartingPath); } catch { } } // Fix slashes config.SelectedPath = config.SelectedPath.StartsWithCSafe("~") ? config.SelectedPath.Replace("\\", "/").TrimEnd('/') : config.SelectedPath.Replace("/", "\\").TrimEnd('\\'); // Get default path config.DefaultPath = QueryHelper.GetString("default_path", String.Empty); string origDefaultPath = config.DefaultPath; if (config.SelectedPath.StartsWithCSafe(config.StartingPath)) { // item to be selected string selectedItem = config.SelectedPath.Replace(config.StartingPath, string.Empty); char slashChar = '\\'; if (config.SelectedPath.StartsWithCSafe("~")) { slashChar = '/'; } selectedItem = selectedItem.TrimStart(slashChar).TrimEnd(slashChar); if (selectedItem.LastIndexOfCSafe(slashChar) != -1) { selectedItem = selectedItem.Substring(0, selectedItem.LastIndexOfCSafe(slashChar)); } config.DefaultPath = selectedItem; } string defaultPath = String.Format("{0}\\{1}", config.StartingPath, config.DefaultPath); if (config.StartingPath.StartsWithCSafe("~")) { try { defaultPath = Server.MapPath(defaultPath); } catch { // Set default path defaultPath = string.Empty; } } if (!Directory.Exists(defaultPath)) { try { defaultPath = Server.MapPath(String.Format("{0}\\{1}", config.StartingPath, origDefaultPath)); } catch { // Set default path defaultPath = string.Empty; } config.DefaultPath = Directory.Exists(defaultPath) ? origDefaultPath : string.Empty; } // Get mode config.ShowFolders = QueryHelper.GetBoolean("show_folders", false); } /// /// Ensures that filter is no more applied. /// private void ResetSearchFilter() { fileSystemView.ResetSearch(); LastSearchedValue = string.Empty; } #endregion }