/// <summary> /// Imports a ZIP file (from stream) /// </summary> /// <param name="zipStream"></param> /// <param name="server"></param> /// <param name="portalSettings"></param> /// <param name="messages"></param> /// <returns></returns> public bool ImportZip(Stream zipStream, HttpServerUtility server, PortalSettings portalSettings, List<ExportImportMessage> messages) { if (messages == null) messages = new List<ExportImportMessage>(); var temporaryDirectory = server.MapPath(Path.Combine(Settings.TemporaryDirectory, Guid.NewGuid().ToString())); var success = true; try { if (!Directory.Exists(temporaryDirectory)) Directory.CreateDirectory(temporaryDirectory); // Extract ZIP archive to the temporary folder ExtractZipFile(zipStream, temporaryDirectory); var currentWorkingDir = temporaryDirectory; var baseDirectories = Directory.GetDirectories(currentWorkingDir); // Loop through each root-folder. For now only contains the "Apps" folder. foreach (var directoryPath in baseDirectories) { switch (Path.GetFileName(directoryPath)) { // Handle the App folder case "Apps": currentWorkingDir = Path.Combine(currentWorkingDir, "Apps"); // Loop through each app directory foreach (var appDirectory in Directory.GetDirectories(currentWorkingDir)) { var appId = new int?(); // Stores the number of the current xml file to process var xmlIndex = 0; // Import XML file(s) foreach (var xmlFileName in Directory.GetFiles(appDirectory, "*.xml")) { var fileContents = File.ReadAllText(Path.Combine(appDirectory, xmlFileName)); var doc = XDocument.Parse(fileContents); var import = new XmlImport(PortalSettings.Current.DefaultLanguage, Environment.Dnn7.UserIdentity.CurrentUserIdentityToken /*PortalSettings.Current.UserInfo.Username*/); if (!import.IsCompatible(doc)) throw new Exception("The app / package is not compatible with this version of 2sxc."); var isAppImport = doc.Element("SexyContent").Element("Header").Elements("App").Any() && doc.Element("SexyContent").Element("Header").Element("App").Attribute("Guid").Value != "Default"; if (!isAppImport && !_appId.HasValue) _appId = ((BaseCache) DataSource.GetCache(_zoneId)).ZoneApps[_zoneId].DefaultAppId; if (isAppImport) { var appConfig = XDocument.Parse(fileContents).Element("SexyContent") .Element("Entities") .Elements("Entity") .Single(e => e.Attribute("AttributeSetStaticName").Value == "2SexyContent-App"); #region Version Checks (new in 08.03.03) var reqVersionNode = appConfig.Elements("Value")?.FirstOrDefault(v => v.Attribute("Key").Value == "RequiredVersion")?.Attribute("Value")?.Value; var reqVersionNodeDnn = appConfig.Elements("Value")?.FirstOrDefault(v => v.Attribute("Key").Value == "RequiredDnnVersion")?.Attribute("Value")?.Value; CheckRequiredEnvironmentVersions(reqVersionNode, reqVersionNodeDnn); #endregion var folder = appConfig.Elements("Value").First(v => v.Attribute("Key").Value == "Folder").Attribute("Value").Value; var appPath = Path.Combine(AppHelpers.AppBasePath(PortalSettings.Current), folder); // Do not import (throw error) if the app directory already exists if(Directory.Exists(HttpContext.Current.Server.MapPath(appPath))) { throw new Exception("The app could not be installed because the app-folder '" + appPath + "' already exists. Please remove or rename the folder and install the app again."); } if (xmlIndex == 0) { // Handle PortalFiles folder var portalTempRoot = Path.Combine(appDirectory, "PortalFiles"); if (Directory.Exists(portalTempRoot)) CopyAllFilesDnnPortal(portalTempRoot, "", false, messages); } import.ImportApp(_zoneId, doc, out appId); } else { appId = _appId.Value; if (xmlIndex == 0 && import.IsCompatible(doc)) { // Handle PortalFiles folder var portalTempRoot = Path.Combine(appDirectory, "PortalFiles"); if (Directory.Exists(portalTempRoot)) CopyAllFilesDnnPortal(portalTempRoot, "", false, messages); } import.ImportXml(_zoneId, appId.Value, doc); } messages.AddRange(import.ImportLog); xmlIndex++; } //var sexy = new SxcInstance(_zoneId, appId.Value); var app = new App(_zoneId, appId.Value, PortalSettings.Current, false); // Copy all files in 2sexy folder to (portal file system) 2sexy folder var templateRoot = server.MapPath(Internal.TemplateManager.GetTemplatePathRoot(Settings.TemplateLocations.PortalFileSystem, app)); var appTemplateRoot = Path.Combine(appDirectory, "2sexy"); if (Directory.Exists(appTemplateRoot)) (new FileManager(appTemplateRoot)).CopyAllFiles(templateRoot, false, messages); } // Reset CurrentWorkingDir currentWorkingDir = temporaryDirectory; break; } } } catch (Exception e) { // Add error message and return false messages.Add(new ExportImportMessage("Could not import the app / package: " + e.Message, ExportImportMessage.MessageTypes.Error)); Exceptions.LogException(e); success = false; } finally { try { // Finally delete the temporary directory Directory.Delete(temporaryDirectory, true); } catch(Exception ex) when (ex is FormatException || ex is OverflowException) { // The folder itself or files inside may be used by other processes. // Deleting the folder recursively will fail in such cases // If deleting is not possible, just leave the temporary folder as it is } } return success; }
/// <summary> /// Imports a ZIP file (from stream) /// </summary> /// <param name="zipStream"></param> /// <param name="server"></param> /// <param name="portalSettings"></param> /// <param name="messages"></param> /// <returns></returns> public bool ImportZip(Stream zipStream, HttpServerUtility server, PortalSettings portalSettings, List <ExportImportMessage> messages, bool isAppImport) { if (!isAppImport && !_appId.HasValue) { throw new Exception("Could not import zip: No valid app id"); } if (messages == null) { messages = new List <ExportImportMessage>(); } var temporaryDirectory = server.MapPath(Path.Combine(SexyContent.TemporaryDirectory, System.Guid.NewGuid().ToString())); var success = true; try { if (!Directory.Exists(temporaryDirectory)) { Directory.CreateDirectory(temporaryDirectory); } // Extract ZIP archive to the temporary folder ExtractZipFile(zipStream, temporaryDirectory); string currentWorkingDir = temporaryDirectory; string[] baseDirectories = Directory.GetDirectories(currentWorkingDir); // Loop through each root-folder. For now only contains the "Apps" folder. foreach (var directoryPath in baseDirectories) { switch (Path.GetFileName(directoryPath)) { // Handle the App folder case "Apps": currentWorkingDir = Path.Combine(currentWorkingDir, "Apps"); // Loop through each app directory foreach (var appDirectory in Directory.GetDirectories(currentWorkingDir)) { var appId = new int?(); var xmlSearchPattern = isAppImport ? "App.xml" : "*.xml"; // Stores the number of the current xml file to process var xmlIndex = 0; // Import XML file(s) foreach (var xmlFileName in Directory.GetFiles(appDirectory, "*.xml")) { var fileContents = File.ReadAllText(Path.Combine(appDirectory, xmlFileName)); var import = new XmlImport(); if (isAppImport) { if (!import.IsCompatible(_zoneId, fileContents)) { throw new Exception("The " + (isAppImport ? "app" : "package") + " is not compatible with this version of 2sxc."); } var folder = XDocument.Parse(fileContents).Element("SexyContent") .Element("Entities").Elements("Entity").Single(e => e.Attribute("AttributeSetStaticName").Value == "2SexyContent-App") .Elements("Value").First(v => v.Attribute("Key").Value == "Folder").Attribute("Value").Value; var appPath = System.IO.Path.Combine(SexyContent.AppBasePath(PortalSettings.Current), folder); // Do not import (throw error) if the app directory already exists if (Directory.Exists(HttpContext.Current.Server.MapPath(appPath))) { throw new Exception("The app could not be installed because the app-folder '" + appPath + "' already exists. Please remove or rename the folder and install the app again."); } if (xmlIndex == 0) { // Handle PortalFiles folder string portalTempRoot = Path.Combine(appDirectory, "PortalFiles"); if (Directory.Exists(portalTempRoot)) { CopyAllFilesDnnPortal(portalTempRoot, "", false, messages); } } import.ImportApp(_zoneId, fileContents, out appId); } else { appId = _appId.Value; if (xmlIndex == 0 && import.IsCompatible(_zoneId, fileContents)) { // Handle PortalFiles folder string portalTempRoot = Path.Combine(appDirectory, "PortalFiles"); if (Directory.Exists(portalTempRoot)) { CopyAllFilesDnnPortal(portalTempRoot, "", false, messages); } } import.ImportXml(_zoneId, appId.Value, fileContents); } messages.AddRange(import.ImportLog); xmlIndex++; } var sexy = new SexyContent(_zoneId, appId.Value); // Copy all files in 2sexy folder to (portal file system) 2sexy folder string templateRoot = server.MapPath(SexyContent.GetTemplatePathRoot(SexyContent.TemplateLocations.PortalFileSystem, sexy.App)); string appTemplateRoot = Path.Combine(appDirectory, "2sexy"); if (Directory.Exists(appTemplateRoot)) { ImportExportHelpers.CopyAllFiles(appTemplateRoot, templateRoot, false, messages); } } // Reset CurrentWorkingDir currentWorkingDir = temporaryDirectory; break; } } } catch (Exception e) { // Add error message and return false messages.Add(new ExportImportMessage("Could not import the " + (isAppImport ? "app" : "package") + ": " + e.Message, ExportImportMessage.MessageTypes.Error)); Exceptions.LogException(e); success = false; } finally { try { // Finally delete the temporary directory Directory.Delete(temporaryDirectory, true); } catch (IOException e) { // The folder itself or files inside may be used by other processes. // Deleting the folder recursively will fail in such cases // If deleting is not possible, just leave the temporary folder as it is } } return(success); }
/// <summary> /// Imports a ZIP file (from stream) /// </summary> /// <param name="zipStream"></param> /// <param name="server"></param> /// <param name="portalSettings"></param> /// <param name="messages"></param> /// <returns></returns> public bool ImportZip(Stream zipStream, HttpServerUtility server, PortalSettings portalSettings, List <ExportImportMessage> messages) { if (messages == null) { messages = new List <ExportImportMessage>(); } var temporaryDirectory = server.MapPath(Path.Combine(Settings.TemporaryDirectory, Guid.NewGuid().ToString())); var success = true; try { if (!Directory.Exists(temporaryDirectory)) { Directory.CreateDirectory(temporaryDirectory); } // Extract ZIP archive to the temporary folder ExtractZipFile(zipStream, temporaryDirectory); var currentWorkingDir = temporaryDirectory; var baseDirectories = Directory.GetDirectories(currentWorkingDir); // Loop through each root-folder. For now only contains the "Apps" folder. foreach (var directoryPath in baseDirectories) { switch (Path.GetFileName(directoryPath)) { // Handle the App folder case "Apps": currentWorkingDir = Path.Combine(currentWorkingDir, "Apps"); // Loop through each app directory foreach (var appDirectory in Directory.GetDirectories(currentWorkingDir)) { var appId = new int?(); // Stores the number of the current xml file to process var xmlIndex = 0; // Import XML file(s) foreach (var xmlFileName in Directory.GetFiles(appDirectory, "*.xml")) { var fileContents = File.ReadAllText(Path.Combine(appDirectory, xmlFileName)); var doc = XDocument.Parse(fileContents); var import = new XmlImport(PortalSettings.Current.DefaultLanguage, Environment.Dnn7.UserIdentity.CurrentUserIdentityToken /*PortalSettings.Current.UserInfo.Username*/); if (!import.IsCompatible(doc)) { throw new Exception("The app / package is not compatible with this version of 2sxc."); } var isAppImport = doc.Element("SexyContent").Element("Header").Elements("App").Any() && doc.Element("SexyContent").Element("Header").Element("App").Attribute("Guid").Value != "Default"; if (!isAppImport && !_appId.HasValue) { _appId = ((BaseCache)DataSource.GetCache(_zoneId)).ZoneApps[_zoneId].DefaultAppId; } if (isAppImport) { var appConfig = XDocument.Parse(fileContents).Element("SexyContent") .Element("Entities") .Elements("Entity") .Single(e => e.Attribute("AttributeSetStaticName").Value == "2SexyContent-App"); #region Version Checks (new in 08.03.03) var reqVersionNode = appConfig.Elements("Value")?.FirstOrDefault(v => v.Attribute("Key").Value == "RequiredVersion")?.Attribute("Value")?.Value; var reqVersionNodeDnn = appConfig.Elements("Value")?.FirstOrDefault(v => v.Attribute("Key").Value == "RequiredDnnVersion")?.Attribute("Value")?.Value; CheckRequiredEnvironmentVersions(reqVersionNode, reqVersionNodeDnn); #endregion var folder = appConfig.Elements("Value").First(v => v.Attribute("Key").Value == "Folder").Attribute("Value").Value; var appPath = Path.Combine(AppHelpers.AppBasePath(PortalSettings.Current), folder); // Do not import (throw error) if the app directory already exists if (Directory.Exists(HttpContext.Current.Server.MapPath(appPath))) { throw new Exception("The app could not be installed because the app-folder '" + appPath + "' already exists. Please remove or rename the folder and install the app again."); } if (xmlIndex == 0) { // Handle PortalFiles folder var portalTempRoot = Path.Combine(appDirectory, "PortalFiles"); if (Directory.Exists(portalTempRoot)) { CopyAllFilesDnnPortal(portalTempRoot, "", false, messages); } } import.ImportApp(_zoneId, doc, out appId); } else { appId = _appId.Value; if (xmlIndex == 0 && import.IsCompatible(doc)) { // Handle PortalFiles folder var portalTempRoot = Path.Combine(appDirectory, "PortalFiles"); if (Directory.Exists(portalTempRoot)) { CopyAllFilesDnnPortal(portalTempRoot, "", false, messages); } } import.ImportXml(_zoneId, appId.Value, doc); } messages.AddRange(import.ImportLog); xmlIndex++; } //var sexy = new SxcInstance(_zoneId, appId.Value); var app = new App(_zoneId, appId.Value, PortalSettings.Current, false); // Copy all files in 2sexy folder to (portal file system) 2sexy folder var templateRoot = server.MapPath(Internal.TemplateManager.GetTemplatePathRoot(Settings.TemplateLocations.PortalFileSystem, app)); var appTemplateRoot = Path.Combine(appDirectory, "2sexy"); if (Directory.Exists(appTemplateRoot)) { (new FileManager(appTemplateRoot)).CopyAllFiles(templateRoot, false, messages); } } // Reset CurrentWorkingDir currentWorkingDir = temporaryDirectory; break; } } } catch (Exception e) { // Add error message and return false messages.Add(new ExportImportMessage("Could not import the app / package: " + e.Message, ExportImportMessage.MessageTypes.Error)); Exceptions.LogException(e); success = false; } finally { try { // Finally delete the temporary directory Directory.Delete(temporaryDirectory, true); } catch (Exception ex) when(ex is FormatException || ex is OverflowException) { // The folder itself or files inside may be used by other processes. // Deleting the folder recursively will fail in such cases // If deleting is not possible, just leave the temporary folder as it is } } return(success); }