using System; using System.Collections.Generic; using System.Data; using System.Collections; using System.Security.Principal; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; using CMS.CMSHelper; using CMS.ExtendedControls; using CMS.GlobalHelper; using CMS.IO; using CMS.SettingsProvider; using CMS.SiteProvider; using CMS.UIControls; public partial class CMSModules_System_Files_System_FilesMetafiles : SiteManagerPage { #region "Variables" protected int currentSiteId = 0; protected int siteId = 0; protected string filterWhere = null; private static readonly Hashtable mErrors = new Hashtable(); #endregion #region "Properties" /// /// Current log context. /// public LogContext CurrentLog { get { return EnsureLog(); } } /// /// Current Error. /// private string CurrentError { get { return ValidationHelper.GetString(mErrors["DeleteError_" + ctlAsync.ProcessGUID], string.Empty); } set { mErrors["DeleteError_" + ctlAsync.ProcessGUID] = value; } } #endregion #region "Methods" protected void Page_Load(object sender, EventArgs e) { ScriptHelper.RegisterTooltip(Page); // Initialize events ctlAsync.OnFinished += ctlAsync_OnFinished; ctlAsync.OnError += ctlAsync_OnError; ctlAsync.OnRequestLog += ctlAsync_OnRequestLog; ctlAsync.OnCancel += ctlAsync_OnCancel; if (RequestHelper.IsCallback()) { pnlContent.Visible = false; gridFiles.StopProcessing = true; siteSelector.StopProcessing = true; return; } // Setup the controls gridFiles.OnExternalDataBound += new OnExternalDataBoundEventHandler(gridFiles_OnExternalDataBound); gridFiles.OnAction += new OnActionEventHandler(gridFiles_OnAction); ControlsHelper.RegisterPostbackControl(btnOk); currentSiteId = CMSContext.CurrentSiteID; // Setup the filters siteSelector.DropDownSingleSelect.AutoPostBack = true; siteSelector.UniSelector.OnSelectionChanged += new EventHandler(UniSelector_OnSelectionChanged); if (!RequestHelper.IsPostBack() && (currentSiteId > 0)) { siteSelector.Value = currentSiteId; } siteId = ValidationHelper.GetInteger(siteSelector.Value, 0); if (siteId > 0) { filterWhere = "MetaFileSiteID = " + siteId; gridFiles.WhereCondition = filterWhere; } else if (siteId == UniSelector.US_GLOBAL_RECORD) { // Global files filterWhere = "MetaFileSiteID IS NULL"; gridFiles.WhereCondition = filterWhere; } // Fill the objecttype DDL if (!RequestHelper.IsPostBack()) { LoadObjectTypes(); } // Add object type condition string selectedType = SqlHelperClass.GetSafeQueryString(drpObjectType.SelectedValue, false); if (!string.IsNullOrEmpty(selectedType)) { filterWhere = SqlHelperClass.AddWhereCondition(filterWhere, "MetaFileObjectType = '" + selectedType + "'", "AND"); gridFiles.WhereCondition = filterWhere; } if (!RequestHelper.IsPostBack()) { // Fill in the actions drpAction.Items.Add(new ListItem(GetString("general.selectaction"), "")); bool copyDB = true; bool copyFS = true; bool deleteDB = true; bool deleteFS = true; if (siteId > 0) { bool fs = StoreInFileSystem(siteId); bool db = StoreInDatabase(siteId); copyFS = deleteDB = fs; deleteFS = db; copyDB = db && fs; } if (copyDB) { drpAction.Items.Add(new ListItem("Copy to database", "copytodatabase")); } if (copyFS) { drpAction.Items.Add(new ListItem("Copy to file system", "copytofilesystem")); } if (deleteDB) { drpAction.Items.Add(new ListItem("Delete from database", "deleteindatabase")); } if (deleteFS) { drpAction.Items.Add(new ListItem("Delete from file system", "deleteinfilesystem")); } } } protected void UniSelector_OnSelectionChanged(object sender, EventArgs e) { LoadObjectTypes(); } private void LoadObjectTypes() { drpObjectType.Items.Clear(); drpObjectType.Items.Add(new ListItem(GetString("general.selectall"), "")); // Used object types List objTypes = MetaFileInfoProvider.GetMetaFilesObjectTypes(siteId); ListItem[] items = new ListItem[objTypes.Count]; int i = 0; foreach (string type in objTypes) { items[i++] = new ListItem(GetString("ObjectTasks." + type.Replace(".", "_").Replace("#", "_")), type); } Array.Sort(items, CompareObjectType); drpObjectType.Items.AddRange(items); } /// /// Comparison method for two ListItems (to sort the drop down with object types). /// /// First item to compare /// Second item to compare private static int CompareObjectType(ListItem item1, ListItem item2) { return item1.Text.CompareToCSafe(item2.Text, true); } protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); if ((siteId > 0) || (siteId == UniSelector.US_GLOBAL_RECORD)) { // Hide the Site ID column if (gridFiles.GridView.Columns.Count > 0) { gridFiles.NamedColumns["SiteName"].Visible = false; } } pnlFooter.Visible = (gridFiles.GridView.Rows.Count > 0); } protected void gridFiles_OnAction(string actionName, object actionArgument) { int fileId = ValidationHelper.GetInteger(actionArgument, 0); string name = null; if (ProcessFile(fileId, actionName, ref name)) { gridFiles.ReloadData(); switch (actionName) { case "copytodatabase": // Copy the file from file system to the database ShowConfirmation("The file '" + name + "' was copied to the database."); break; case "copytofilesystem": // Copy to file system ShowConfirmation("The file '" + name + "' was copied to the file system."); break; case "deleteindatabase": // Delete from database ShowConfirmation("The file '" + name + "' binary was deleted from the database."); break; case "deleteinfilesystem": // Delete from file system ShowConfirmation("The file '" + name + "' binary was deleted from the file system."); break; } } } /// /// Copies the file binary to the database. /// /// MetaFile ID /// Returning the metafile name protected bool CopyToDatabase(int fileId, ref string name) { // Copy the file from file system to the database MetaFileInfo mi = MetaFileInfoProvider.GetMetaFileInfo(fileId); if (mi != null) { name = mi.MetaFileName; if (mi.MetaFileBinary == null) { // Ensure the binary data mi.MetaFileBinary = MetaFileInfoProvider.GetFile(mi, GetSiteName(mi.MetaFileSiteID)); mi.Generalized.UpdateData(); return true; } } return false; } /// /// Copies the file binary to the file system. /// /// MetaFile ID /// Returning the metafile name protected bool CopyToFileSystem(int fileId, ref string name) { // Copy the file from database to the file system MetaFileInfo mi = MetaFileInfoProvider.GetMetaFileInfo(fileId); if (mi != null) { name = mi.MetaFileName; // Ensure the physical file MetaFileInfoProvider.EnsurePhysicalFile(mi, GetSiteName(mi.MetaFileSiteID)); return true; } return false; } /// /// Deletes the file binary from the database. /// /// MetaFile ID /// Returning the metafile name protected bool DeleteFromDatabase(int fileId, ref string name) { // Delete the file in database and ensure it in the file system MetaFileInfo mi = MetaFileInfoProvider.GetMetaFileInfo(fileId); if (mi != null) { name = mi.MetaFileName; MetaFileInfoProvider.EnsurePhysicalFile(mi, GetSiteName(mi.MetaFileSiteID)); // Clear the binary data mi.MetaFileBinary = null; mi.Generalized.UpdateData(); return true; } return false; } /// /// Deletes the file binary from the file system. /// /// MetaFile ID /// Returning the metafile name protected bool DeleteFromFileSystem(int fileId, ref string name) { // Delete the file in file system MetaFileInfo mi = MetaFileInfoProvider.GetMetaFileInfo(fileId); if (mi != null) { name = mi.MetaFileName; // Ensure the binary column first (check if exists) DataSet ds = MetaFileInfoProvider.GetMetaFiles("MetaFileID = " + fileId, null, "CASE WHEN MetaFileBinary IS NULL THEN 0 ELSE 1 END AS HasBinary", -1); if (!DataHelper.DataSourceIsEmpty(ds)) { bool hasBinary = ValidationHelper.GetBoolean(ds.Tables[0].Rows[0][0], false); if (!hasBinary) { // Copy the binary data to database mi.MetaFileBinary = MetaFileInfoProvider.GetFile(mi, GetSiteName(mi.MetaFileSiteID)); mi.Generalized.UpdateData(); } // Delete the file from the disk MetaFileInfoProvider.DeleteFile(GetSiteName(mi.MetaFileSiteID), mi.MetaFileGUID.ToString(), true, false); return true; } } return false; } /// /// Processes the given file. /// /// MetaFile ID /// Action name /// Returning the file name protected bool ProcessFile(int fileId, string actionName, ref string name) { if (fileId > 0) { switch (actionName) { case "copytodatabase": // Copy the file from file system to the database return CopyToDatabase(fileId, ref name); case "copytofilesystem": // Copy to file system return CopyToFileSystem(fileId, ref name); case "deleteindatabase": // Delete from database return DeleteFromDatabase(fileId, ref name); case "deleteinfilesystem": // Delete from file system return DeleteFromFileSystem(fileId, ref name); } } return false; } /// /// Processes the files. /// /// Parameter for the action protected void ProcessFiles(object parameter) { // Begin log AddLog("Processing files ..."); object[] parameters = (object[])parameter; List items = (List)parameters[0]; string action = (string)parameters[1]; if ((items != null) && (items.Count > 0)) { string name = null; int count = 0; // Process all items foreach (object id in items) { // Process the file int fileId = ValidationHelper.GetInteger(id, 0); if (ProcessFile(fileId, action, ref name)) { count++; AddLog(name); } else if (!string.IsNullOrEmpty(name)) { AddLog(name + " SKIPPED"); } } } } /// /// Gets the site name for the given site ID. /// /// Site ID protected string GetSiteName(int siteId) { if (siteId <= 0) { return null; } // Get the site name SiteInfo si = SiteInfoProvider.GetSiteInfo(siteId); if (si != null) { return si.SiteName; } return null; } /// /// Returns true if the files are stored in file system on the given site. /// /// Site ID protected bool StoreInFileSystem(int siteId) { return MetaFileInfoProvider.StoreFilesInFileSystem(GetSiteName(siteId)); } /// /// Returns true if the files are stored in database on the given site. /// /// Site ID protected bool StoreInDatabase(int siteId) { return MetaFileInfoProvider.StoreFilesInDatabase(GetSiteName(siteId)); } /// /// Grid external data bound handler. /// protected object gridFiles_OnExternalDataBound(object sender, string sourceName, object parameter) { // Get the data row view from parameter DataRowView drv = null; if (parameter is DataRowView) { drv = (DataRowView)parameter; } else if (parameter is GridViewRow) { // Get data from the grid view row GridViewRow gvr = (parameter as GridViewRow); if (gvr != null) { drv = (DataRowView)gvr.DataItem; } } // Get the action button ImageButton btn = null; if (sender is ImageButton) { btn = (ImageButton)sender; } switch (sourceName) { case "delete": { // Delete action int siteId = ValidationHelper.GetInteger(drv["MetaFileSiteID"], 0); string siteName = GetSiteName(siteId); Guid guid = ValidationHelper.GetGuid(drv["MetaFileGUID"], Guid.Empty); string extension = ValidationHelper.GetString(drv["MetaFileExtension"], ""); // Check if the file is in DB bool db = ValidationHelper.GetBoolean(drv["HasBinary"], false); // Check if the file is in the file system bool fs = false; string path = MetaFileInfoProvider.GetFilePhysicalPath(siteName, guid.ToString(), extension); if (File.Exists(path)) { fs = true; } // If the file is present in both file system and database, delete is allowed if (fs && db) { // If the files are stored in file system, delete is allowed in database if (StoreInFileSystem(siteId)) { btn.Attributes["onclick"] = btn.Attributes["onclick"].Replace("'delete'", "'deleteindatabase'"); btn.ToolTip = "Delete from database"; return parameter; } // If the files are stored in database, delete is allowed in file system if (StoreInDatabase(siteId)) { btn.Attributes["onclick"] = btn.Attributes["onclick"].Replace("'delete'", "'deleteinfilesystem'"); btn.ToolTip = "Delete from file system"; return parameter; } } btn.Visible = false; } break; case "copy": { // Delete action int siteId = ValidationHelper.GetInteger(drv["MetaFileSiteID"], 0); string siteName = GetSiteName(siteId); Guid guid = ValidationHelper.GetGuid(drv["MetaFileGUID"], Guid.Empty); string extension = ValidationHelper.GetString(drv["MetaFileExtension"], ""); // Check if the file is in DB bool db = ValidationHelper.GetBoolean(drv["HasBinary"], false); // Check if the file is in the file system bool fs = false; string path = MetaFileInfoProvider.GetFilePhysicalPath(siteName, guid.ToString(), extension); if (File.Exists(path)) { fs = true; } // If the file is stored in file system and the file is not present in database, copy to database is allowed if (fs && !db && StoreInDatabase(siteId) && StoreInFileSystem(siteId)) { btn.Attributes["onclick"] = btn.Attributes["onclick"].Replace("'copy'", "'copytodatabase'"); btn.ToolTip = "Copy to database"; //btn.ImageUrl = return parameter; } // If the file is stored in database and the file is not present in file system, copy to file system is allowed if (db && !fs && StoreInFileSystem(siteId)) { btn.Attributes["onclick"] = btn.Attributes["onclick"].Replace("'copy'", "'copytofilesystem'"); btn.ToolTip = "Copy to file system"; return parameter; } btn.Visible = false; } break; case "name": { // MetaFile name string name = ValidationHelper.GetString(drv["MetaFileName"], ""); Guid guid = ValidationHelper.GetGuid(drv["MetaFileGUID"], Guid.Empty); int siteId = ValidationHelper.GetInteger(drv["MetaFileSiteID"], 0); string extension = ValidationHelper.GetString(drv["MetaFileExtension"], ""); // File name name = Path.GetFileNameWithoutExtension(name); string url = ResolveUrl("~/CMSPages/GetMetaFile.aspx?fileguid=") + guid; if (siteId != currentSiteId) { // Add the site name to the URL if not current site SiteInfo si = SiteInfoProvider.GetSiteInfo(siteId); if (si != null) { url += "&sitename=" + si.SiteName; } } string tooltipSpan = name; bool isImage = ImageHelper.IsImage(extension); if (isImage) { int imageWidth = ValidationHelper.GetInteger(DataHelper.GetDataRowViewValue(drv, "MetaFileImageWidth"), 0); int imageHeight = ValidationHelper.GetInteger(DataHelper.GetDataRowViewValue(drv, "MetaFileImageHeight"), 0); string tooltip = UIHelper.GetTooltipAttributes(url, imageWidth, imageHeight, null, name, extension, null, null, 300); tooltipSpan = "" + name + ""; } return "\"" " + tooltipSpan + ""; } case "size": // File size return DataHelper.GetSizeString(ValidationHelper.GetInteger(parameter, 0)); case "yesno": // Yes / No return UniGridFunctions.ColoredSpanYesNo(parameter); case "site": { int siteId = ValidationHelper.GetInteger(parameter, 0); if (siteId > 0) { SiteInfo si = SiteInfoProvider.GetSiteInfo(siteId); if (si != null) { return si.DisplayName; } } return null; } case "storedinfilesystem": { // Delete action int siteId = ValidationHelper.GetInteger(drv["MetaFileSiteID"], 0); string siteName = GetSiteName(siteId); Guid guid = ValidationHelper.GetGuid(drv["MetaFileGUID"], Guid.Empty); string extension = ValidationHelper.GetString(drv["MetaFileExtension"], ""); // Check if the file is in DB bool db = ValidationHelper.GetBoolean(drv["HasBinary"], false); // Check if the file is in the file system bool fs = false; string path = MetaFileInfoProvider.GetFilePhysicalPath(siteName, guid.ToString(), extension); if (File.Exists(path)) { fs = true; } return UniGridFunctions.ColoredSpanYesNo(fs); } } return parameter; } /// /// Action button handler. /// protected void btnOK_Click(object sender, EventArgs e) { if (!String.IsNullOrEmpty(drpAction.SelectedValue)) { List items = null; if (drpWhat.SelectedValue == "all") { // Get only the appropriate set of items string where = filterWhere; switch (drpAction.SelectedValue) { case "deleteindatabase": case "copytofilesystem": // Only process those where binary is available in DB where = SqlHelperClass.AddWhereCondition(where, "MetaFileBinary IS NOT NULL"); break; case "copytodatabase": // Only copy those where the binary is missing where = SqlHelperClass.AddWhereCondition(where, "MetaFileBinary IS NULL"); break; } // Get all, build the list of items DataSet ds = MetaFileInfoProvider.GetMetaFiles(where, null, "MetaFileID", 0); if (!DataHelper.DataSourceIsEmpty(ds)) { items = new List(); // Process all rows foreach (DataRow dr in ds.Tables[0].Rows) { int fileId = ValidationHelper.GetInteger(dr["MetaFileID"], 0); items.Add(fileId.ToString()); } } } else { // Take selected items items = gridFiles.SelectedItems; } if ((items != null) && (items.Count > 0)) { // Setup the async log pnlLog.Visible = true; pnlContent.Visible = false; titleElemAsync.TitleText = drpAction.SelectedItem.Text; btnCancel.Attributes.Add("onclick", ctlAsync.GetCancelScript(true) + "return false;"); CurrentError = string.Empty; CurrentLog.Close(); EnsureLog(); // Process the file asynchronously ctlAsync.Parameter = new object[] { items, drpAction.SelectedValue }; ctlAsync.RunAsync(ProcessFiles, WindowsIdentity.GetCurrent()); } } } #endregion #region "Handling async thread" /// /// Cancel event handler. /// private void ctlAsync_OnCancel(object sender, EventArgs e) { ctlAsync.Parameter = null; string canceled = "The operation was canceled."; AddLog(canceled); ShowConfirmation(canceled); if (!String.IsNullOrEmpty(CurrentError)) { ShowError(CurrentError); } CurrentLog.Close(); pnlContent.Visible = true; pnlLog.Visible = false; // Reload the grid gridFiles.ClearSelectedItems(); gridFiles.ReloadData(); } /// /// Logs event handler. /// private void ctlAsync_OnRequestLog(object sender, EventArgs e) { ctlAsync.Log = CurrentLog.Log; } /// /// Error event handler. /// private void ctlAsync_OnError(object sender, EventArgs e) { if (ctlAsync.Status == AsyncWorkerStatusEnum.Running) { ctlAsync.Stop(); } ctlAsync.Parameter = null; if (!String.IsNullOrEmpty(CurrentError)) { ShowError(CurrentError); } CurrentLog.Close(); // Reload the grid gridFiles.ClearSelectedItems(); gridFiles.ReloadData(); } /// /// Finished event handler. /// private void ctlAsync_OnFinished(object sender, EventArgs e) { CurrentLog.Close(); if (!String.IsNullOrEmpty(CurrentError)) { ctlAsync.Parameter = null; ShowError(CurrentError); } pnlContent.Visible = true; pnlLog.Visible = false; // Reload the grid gridFiles.ClearSelectedItems(); gridFiles.ReloadData(); } /// /// Ensures the logging context. /// protected LogContext EnsureLog() { LogContext log = LogContext.EnsureLog(ctlAsync.ProcessGUID); log.Reversed = true; log.LineSeparator = "
"; return log; } /// /// Adds the log information. /// /// New log information protected void AddLog(string newLog) { EnsureLog(); LogContext.AppendLine(newLog); } /// /// Adds the error to collection of errors. /// /// Error message protected void AddError(string error) { AddLog(error); CurrentError = (error + "
" + CurrentError); } #endregion }