/// <summary> /// Get all themes /// </summary> /// <returns>List of the theme descriptor</returns> public IList <ThemeDescriptor> GetThemes() { if (_themeDescriptors != null) { return(_themeDescriptors); } //load all theme descriptors _themeDescriptors = new List <ThemeDescriptor>(); var themeDirectoryPath = _fileProvider.MapPath(NopPluginDefaults.ThemesPath); foreach (var descriptionFile in _fileProvider.GetFiles(themeDirectoryPath, NopPluginDefaults.ThemeDescriptionFileName, false)) { var text = _fileProvider.ReadAllText(descriptionFile, Encoding.UTF8); if (string.IsNullOrEmpty(text)) { continue; } //get theme descriptor var themeDescriptor = GetThemeDescriptorFromText(text); //some validation if (string.IsNullOrEmpty(themeDescriptor?.SystemName)) { throw new Exception($"A theme descriptor '{descriptionFile}' has no system name"); } _themeDescriptors.Add(themeDescriptor); } return(_themeDescriptors); }
/// <summary> /// Get plugins info /// </summary> /// <returns>Plugins info</returns> public static PluginsInfo LoadPluginInfo(INopFileProvider fileProvider) { //check whether plugins info file exists var filePath = fileProvider.MapPath(NopPluginDefaults.PluginsInfoFilePath); if (!fileProvider.FileExists(filePath)) { //file doesn't exist, so try to get only installed plugin names from the obsolete file var pluginsInfo = new PluginsInfo { InstalledPluginNames = GetObsoleteInstalledPluginNames(fileProvider) }; //and save info into a new file pluginsInfo.Save(fileProvider); return(pluginsInfo); } //try to get plugin info from the JSON file var text = fileProvider.ReadAllText(filePath, Encoding.UTF8); if (string.IsNullOrEmpty(text)) { return(new PluginsInfo()); } return(JsonConvert.DeserializeObject <PluginsInfo>(text)); }
/// <summary> /// Parse the JSON file /// </summary> /// <param name="file">Path to the file</param> /// <returns>Collection of keys and values from the parsed file</returns> protected virtual Dictionary <string, string> ParseJson(string file) { var result = new Dictionary <string, string>(); var json = string.Empty; try { json = _fileProvider.ReadAllText(file, Encoding.UTF8)?.Trim(); } catch { //ignore any exception } if (string.IsNullOrEmpty(json)) { return(result); } if (json.StartsWith("{")) { json = json.Substring(1, json.Length - 2); } json = json.Trim(); json = json.Substring(1, json.Length - 2); var lines = Regex.Split(json, "\"\\s*,\\s*\""); foreach (var line in lines) { var tmp = Regex.Split(line, "\"\\s*:\\s*\""); try { if (!string.IsNullOrEmpty(tmp[0]) && !result.ContainsKey(tmp[0])) { result.Add(tmp[0], tmp[1]); } } catch { //ignore any exception } } return(result); }
/// <summary> /// Get system names of installed plugins from obsolete file /// </summary> /// <returns>List of plugin system names</returns> protected virtual IList <string> GetObsoleteInstalledPluginNames() { //check whether file exists var filePath = _fileProvider.MapPath(NopPluginDefaults.InstalledPluginsFilePath); if (!_fileProvider.FileExists(filePath)) { //if not, try to parse the file that was used in previous nopCommerce versions filePath = _fileProvider.MapPath(NopPluginDefaults.ObsoleteInstalledPluginsFilePath); if (!_fileProvider.FileExists(filePath)) { return(new List <string>()); } //get plugin system names from the old txt file var pluginSystemNames = new List <string>(); using (var reader = new StringReader(_fileProvider.ReadAllText(filePath, Encoding.UTF8))) { string pluginName; while ((pluginName = reader.ReadLine()) != null) { if (!string.IsNullOrWhiteSpace(pluginName)) { pluginSystemNames.Add(pluginName.Trim()); } } } //and delete the old one _fileProvider.DeleteFile(filePath); return(pluginSystemNames); } var text = _fileProvider.ReadAllText(filePath, Encoding.UTF8); if (string.IsNullOrEmpty(text)) { return(new List <string>()); } //delete the old file _fileProvider.DeleteFile(filePath); //get plugin system names from the JSON file return(JsonConvert.DeserializeObject <IList <string> >(text)); }
/// <summary> /// Execute commands from a file with SQL script against the context database /// </summary> /// <param name="fileProvider">File provider</param> /// <param name="filePath">Path to the file</param> protected void ExecuteSqlScriptFromFile(INopFileProvider fileProvider, string filePath) { filePath = fileProvider.MapPath(filePath); if (!fileProvider.FileExists(filePath)) { return; } ExecuteSqlScript(fileProvider.ReadAllText(filePath, Encoding.Default)); }
/// <summary> /// Install locales /// </summary> protected virtual void InstallLocaleResources() { //'English' language var language = _languageRepository.Table.Single(l => l.Name == "English"); //save resources foreach (var filePath in _fileProvider.EnumerateFiles(_fileProvider.MapPath("~/App_Data/Localization/"), "*.nopres.xml")) { var localesXml = _fileProvider.ReadAllText(filePath, Encoding.UTF8); var localizationService = EngineContext.Current.Resolve <ILocalizationService>(); localizationService.ImportResourcesFromXml(language, localesXml); } }
/// <summary> /// Create app settings with the passed configurations and save it to the file /// </summary> /// <param name="configurations">Configurations to save</param> /// <param name="fileProvider">File provider</param> /// <param name="overwrite">Whether to overwrite appsettings file</param> /// <returns>App settings</returns> public static AppSettings SaveAppSettings(IList <IConfig> configurations, INopFileProvider fileProvider, bool overwrite = true) { if (configurations is null) { throw new ArgumentNullException(nameof(configurations)); } if (_configurationOrder is null) { _configurationOrder = configurations.ToDictionary(config => config.Name, config => config.GetOrder()); } //create app settings var appSettings = Singleton <AppSettings> .Instance ?? new AppSettings(); appSettings.Update(configurations); Singleton <AppSettings> .Instance = appSettings; //create file if not exists var filePath = fileProvider.MapPath(NopConfigurationDefaults.AppSettingsFilePath); var fileExists = fileProvider.FileExists(filePath); fileProvider.CreateFile(filePath); //get raw configuration parameters var configuration = JsonConvert.DeserializeObject <AppSettings>(fileProvider.ReadAllText(filePath, Encoding.UTF8)) ?.Configuration ?? new(); foreach (var config in configurations) { configuration[config.Name] = JToken.FromObject(config); } //sort configurations for display by order (e.g. data configuration with 0 will be the first) appSettings.Configuration = configuration .SelectMany(outConfig => _configurationOrder.Where(inConfig => inConfig.Key == outConfig.Key).DefaultIfEmpty(), (outConfig, inConfig) => new { OutConfig = outConfig, InConfig = inConfig }) .OrderBy(config => config.InConfig.Value) .Select(config => config.OutConfig) .ToDictionary(config => config.Key, config => config.Value); //save app settings to the file if (!fileExists || overwrite) { var text = JsonConvert.SerializeObject(appSettings, Formatting.Indented); fileProvider.WriteAllText(filePath, text, Encoding.UTF8); } return(appSettings); }
/// <summary> /// Install locales /// </summary> protected virtual void InstallLocaleResources() { //'English' language var language = _languageRepository.Table.Single(l => l.Name == "English"); //save resources var directoryPath = _fileProvider.MapPath(NopInstallationDefaults.LocalizationResourcesPath); var pattern = $"*.{NopInstallationDefaults.LocalizationResourcesFileExtension}"; foreach (var filePath in _fileProvider.EnumerateFiles(directoryPath, pattern)) { var localesXml = _fileProvider.ReadAllText(filePath, Encoding.UTF8); var localizationService = EngineContext.Current.Resolve <ILocalizationService>(); localizationService.ImportResourcesFromXml(language, localesXml); } }
/// <summary> /// Initializes theme provider /// </summary> protected virtual void Initialize() { if (_themeDescriptors != null) { return; } //prevent multi loading data lock (_locker) { //data can be loaded while we waited if (_themeDescriptors != null) { return; } //load all theme descriptors _themeDescriptors = new Dictionary <string, ThemeDescriptor>(StringComparer.InvariantCultureIgnoreCase); var themeDirectoryPath = _fileProvider.MapPath(NopPluginDefaults.ThemesPath); foreach (var descriptionFile in _fileProvider.GetFiles(themeDirectoryPath, NopPluginDefaults.ThemeDescriptionFileName, false)) { var text = _fileProvider.ReadAllText(descriptionFile, Encoding.UTF8); if (string.IsNullOrEmpty(text)) { continue; } //get theme descriptor var themeDescriptor = GetThemeDescriptorFromText(text); //some validation if (string.IsNullOrEmpty(themeDescriptor?.SystemName)) { throw new Exception($"A theme descriptor '{descriptionFile}' has no system name"); } _themeDescriptors.TryAdd(themeDescriptor.SystemName, themeDescriptor); } } }
/// <summary> /// Save app settings to the file /// </summary> /// <param name="appSettings">App settings</param> /// <param name="fileProvider">File provider</param> public static void SaveAppSettings(AppSettings appSettings, INopFileProvider fileProvider = null) { Singleton <AppSettings> .Instance = appSettings ?? throw new ArgumentNullException(nameof(appSettings)); fileProvider ??= CommonHelper.DefaultFileProvider; //create file if not exists var filePath = fileProvider.MapPath(NopConfigurationDefaults.AppSettingsFilePath); fileProvider.CreateFile(filePath); //check additional configuration parameters var additionalData = JsonConvert.DeserializeObject <AppSettings>(fileProvider.ReadAllText(filePath, Encoding.UTF8))?.AdditionalData; appSettings.AdditionalData = additionalData; //save app settings to the file var text = JsonConvert.SerializeObject(appSettings, Formatting.Indented); fileProvider.WriteAllText(filePath, text, Encoding.UTF8); }
/// <summary> /// Get robots.txt file /// </summary> /// <returns>Robots.txt file as string</returns> public virtual string PrepareRobotsTextFile() { var sb = new StringBuilder(); //if robots.custom.txt exists, let's use it instead of hard-coded data below var robotsFilePath = _fileProvider.Combine(_fileProvider.MapPath("~/"), "robots.custom.txt"); if (_fileProvider.FileExists(robotsFilePath)) { //the robots.txt file exists var robotsFileContent = _fileProvider.ReadAllText(robotsFilePath, Encoding.UTF8); sb.Append(robotsFileContent); } else { //doesn't exist. Let's generate it (default behavior) var disallowPaths = new List <string> { "/admin", "/bin/", "/files/", "/files/exportimport/", "/country/getstatesbycountryid", "/install", "/setproductreviewhelpfulness", }; var localizableDisallowPaths = new List <string> { "/addproducttocart/catalog/", "/addproducttocart/details/", "/backinstocksubscriptions/manage", "/boards/forumsubscriptions", "/boards/forumwatch", "/boards/postedit", "/boards/postdelete", "/boards/postcreate", "/boards/topicedit", "/boards/topicdelete", "/boards/topiccreate", "/boards/topicmove", "/boards/topicwatch", "/cart", "/checkout", "/checkout/billingaddress", "/checkout/completed", "/checkout/confirm", "/checkout/shippingaddress", "/checkout/shippingmethod", "/checkout/paymentinfo", "/checkout/paymentmethod", "/clearcomparelist", "/compareproducts", "/compareproducts/add/*", "/customer/avatar", "/customer/activation", "/customer/addresses", "/customer/changepassword", "/customer/checkusernameavailability", "/customer/downloadableproducts", "/customer/info", "/deletepm", "/emailwishlist", "/inboxupdate", "/newsletter/subscriptionactivation", "/onepagecheckout", "/order/history", "/orderdetails", "/passwordrecovery/confirm", "/poll/vote", "/privatemessages", "/returnrequest", "/returnrequest/history", "/rewardpoints/history", "/sendpm", "/sentupdate", "/shoppingcart/*", "/storeclosed", "/subscribenewsletter", "/topic/authenticate", "/viewpm", "/uploadfilecheckoutattribute", "/uploadfileproductattribute", "/uploadfilereturnrequest", "/wishlist", }; const string newLine = "\r\n"; //Environment.NewLine sb.Append("User-agent: *"); sb.Append(newLine); //sitemaps if (_commonSettings.SitemapEnabled) { if (_localizationSettings.SeoFriendlyUrlsForLanguagesEnabled) { //URLs are localizable. Append SEO code foreach (var language in _languageService.GetAllLanguages(storeId: _storeContext.CurrentStore.Id)) { sb.AppendFormat("Sitemap: {0}{1}/sitemap.xml", _webHelper.GetStoreLocation(), language.UniqueSeoCode); sb.Append(newLine); } } else { //localizable paths (without SEO code) sb.AppendFormat("Sitemap: {0}sitemap.xml", _webHelper.GetStoreLocation()); sb.Append(newLine); } } //host sb.AppendFormat("Host: {0}", _webHelper.GetStoreLocation()); sb.Append(newLine); //usual paths foreach (var path in disallowPaths) { sb.AppendFormat("Disallow: {0}", path); sb.Append(newLine); } //localizable paths (without SEO code) foreach (var path in localizableDisallowPaths) { sb.AppendFormat("Disallow: {0}", path); sb.Append(newLine); } if (_localizationSettings.SeoFriendlyUrlsForLanguagesEnabled) { //URLs are localizable. Append SEO code foreach (var language in _languageService.GetAllLanguages(storeId: _storeContext.CurrentStore.Id)) { foreach (var path in localizableDisallowPaths) { sb.AppendFormat("Disallow: /{0}{1}", language.UniqueSeoCode, path); sb.Append(newLine); } } } //load and add robots.txt additions to the end of file. var robotsAdditionsFile = _fileProvider.Combine(_fileProvider.MapPath("~/"), "robots.additions.txt"); if (_fileProvider.FileExists(robotsAdditionsFile)) { var robotsFileContent = _fileProvider.ReadAllText(robotsAdditionsFile, Encoding.UTF8); sb.Append(robotsFileContent); } } return(sb.ToString()); }
/// <summary> /// Load data settings /// </summary> /// <param name="filePath">File path; pass null to use the default settings file</param> /// <param name="reloadSettings">Whether to reload data, if they already loaded</param> /// <param name="fileProvider">File provider</param> /// <returns>Data settings</returns> public static DataSettings LoadSettings(string filePath = null, bool reloadSettings = false, INopFileProvider fileProvider = null) { if (!reloadSettings && Singleton <DataSettings> .Instance != null) { return(Singleton <DataSettings> .Instance); } fileProvider = fileProvider ?? CommonHelper.DefaultFileProvider; filePath = filePath ?? fileProvider.MapPath(NopDataSettingsDefaults.FilePath); //check whether file exists if (!fileProvider.FileExists(filePath)) { //if not, try to parse the file that was used in previous nopCommerce versions filePath = fileProvider.MapPath(NopDataSettingsDefaults.ObsoleteFilePath); if (!fileProvider.FileExists(filePath)) { return(new DataSettings()); } //get data settings from the old txt file var dataSettings = new DataSettings(); using (var reader = new StringReader(fileProvider.ReadAllText(filePath, Encoding.UTF8))) { string settingsLine; while ((settingsLine = reader.ReadLine()) != null) { var separatorIndex = settingsLine.IndexOf(':'); if (separatorIndex == -1) { continue; } var key = settingsLine.Substring(0, separatorIndex).Trim(); var value = settingsLine.Substring(separatorIndex + 1).Trim(); switch (key) { case "DataProvider": dataSettings.DataProvider = Enum.TryParse(value, true, out DataProviderType providerType) ? providerType : DataProviderType.Unknown; continue; case "DataConnectionString": dataSettings.DataConnectionString = value; continue; default: dataSettings.RawDataSettings.Add(key, value); continue; } } } //save data settings to the new file SaveSettings(dataSettings, fileProvider); //and delete the old one fileProvider.DeleteFile(filePath); Singleton <DataSettings> .Instance = dataSettings; return(Singleton <DataSettings> .Instance); } var text = fileProvider.ReadAllText(filePath, Encoding.UTF8); if (string.IsNullOrEmpty(text)) { return(new DataSettings()); } //get data settings from the JSON file Singleton <DataSettings> .Instance = JsonConvert.DeserializeObject <DataSettings>(text); return(Singleton <DataSettings> .Instance); }
/// <summary> /// Create configuration file for RoxyFileman /// </summary> public virtual void CreateConfiguration() { var filePath = GetFullPath(CONFIGURATION_FILE); //create file if not exists _fileProvider.CreateFile(filePath); //try to read existing configuration var existingText = _fileProvider.ReadAllText(filePath, Encoding.UTF8); var existingConfiguration = JsonConvert.DeserializeAnonymousType(existingText, new { FILES_ROOT = string.Empty, SESSION_PATH_KEY = string.Empty, THUMBS_VIEW_WIDTH = string.Empty, THUMBS_VIEW_HEIGHT = string.Empty, PREVIEW_THUMB_WIDTH = string.Empty, PREVIEW_THUMB_HEIGHT = string.Empty, MAX_IMAGE_WIDTH = string.Empty, MAX_IMAGE_HEIGHT = string.Empty, DEFAULTVIEW = string.Empty, FORBIDDEN_UPLOADS = string.Empty, ALLOWED_UPLOADS = string.Empty, FILEPERMISSIONS = string.Empty, DIRPERMISSIONS = string.Empty, LANG = string.Empty, DATEFORMAT = string.Empty, OPEN_LAST_DIR = string.Empty, INTEGRATION = string.Empty, RETURN_URL_PREFIX = string.Empty, DIRLIST = string.Empty, CREATEDIR = string.Empty, DELETEDIR = string.Empty, MOVEDIR = string.Empty, COPYDIR = string.Empty, RENAMEDIR = string.Empty, FILESLIST = string.Empty, UPLOAD = string.Empty, DOWNLOAD = string.Empty, DOWNLOADDIR = string.Empty, DELETEFILE = string.Empty, MOVEFILE = string.Empty, COPYFILE = string.Empty, RENAMEFILE = string.Empty, GENERATETHUMB = string.Empty }); //check whether the path base has changed, otherwise there is no need to overwrite the configuration file var currentPathBase = this.HttpContext.Request.PathBase.ToString(); if (existingConfiguration?.RETURN_URL_PREFIX?.Equals(currentPathBase) ?? false) { return; } //create configuration var configuration = new { FILES_ROOT = existingConfiguration?.FILES_ROOT ?? "/images/uploaded", SESSION_PATH_KEY = existingConfiguration?.SESSION_PATH_KEY ?? string.Empty, THUMBS_VIEW_WIDTH = existingConfiguration?.THUMBS_VIEW_WIDTH ?? "140", THUMBS_VIEW_HEIGHT = existingConfiguration?.THUMBS_VIEW_HEIGHT ?? "120", PREVIEW_THUMB_WIDTH = existingConfiguration?.PREVIEW_THUMB_WIDTH ?? "300", PREVIEW_THUMB_HEIGHT = existingConfiguration?.PREVIEW_THUMB_HEIGHT ?? "200", MAX_IMAGE_WIDTH = existingConfiguration?.MAX_IMAGE_WIDTH ?? "1000", MAX_IMAGE_HEIGHT = existingConfiguration?.MAX_IMAGE_HEIGHT ?? "1000", DEFAULTVIEW = existingConfiguration?.DEFAULTVIEW ?? "list", FORBIDDEN_UPLOADS = existingConfiguration?.FORBIDDEN_UPLOADS ?? "zip js jsp jsb mhtml mht xhtml xht php phtml " + "php3 php4 php5 phps shtml jhtml pl sh py cgi exe application gadget hta cpl msc jar vb jse ws wsf wsc wsh " + "ps1 ps2 psc1 psc2 msh msh1 msh2 inf reg scf msp scr dll msi vbs bat com pif cmd vxd cpl htpasswd htaccess", ALLOWED_UPLOADS = existingConfiguration?.ALLOWED_UPLOADS ?? string.Empty, FILEPERMISSIONS = existingConfiguration?.FILEPERMISSIONS ?? "0644", DIRPERMISSIONS = existingConfiguration?.DIRPERMISSIONS ?? "0755", LANG = existingConfiguration?.LANG ?? _workContext.WorkingLanguage.UniqueSeoCode, DATEFORMAT = existingConfiguration?.DATEFORMAT ?? "dd/MM/yyyy HH:mm", OPEN_LAST_DIR = existingConfiguration?.OPEN_LAST_DIR ?? "yes", //no need user to configure INTEGRATION = "tinymce4", RETURN_URL_PREFIX = currentPathBase, DIRLIST = $"{this.HttpContext.Request.PathBase}/Admin/RoxyFileman/ProcessRequest?a=DIRLIST", CREATEDIR = $"{this.HttpContext.Request.PathBase}/Admin/RoxyFileman/ProcessRequest?a=CREATEDIR", DELETEDIR = $"{this.HttpContext.Request.PathBase}/Admin/RoxyFileman/ProcessRequest?a=DELETEDIR", MOVEDIR = $"{this.HttpContext.Request.PathBase}/Admin/RoxyFileman/ProcessRequest?a=MOVEDIR", COPYDIR = $"{this.HttpContext.Request.PathBase}/Admin/RoxyFileman/ProcessRequest?a=COPYDIR", RENAMEDIR = $"{this.HttpContext.Request.PathBase}/Admin/RoxyFileman/ProcessRequest?a=RENAMEDIR", FILESLIST = $"{this.HttpContext.Request.PathBase}/Admin/RoxyFileman/ProcessRequest?a=FILESLIST", UPLOAD = $"{this.HttpContext.Request.PathBase}/Admin/RoxyFileman/ProcessRequest?a=UPLOAD", DOWNLOAD = $"{this.HttpContext.Request.PathBase}/Admin/RoxyFileman/ProcessRequest?a=DOWNLOAD", DOWNLOADDIR = $"{this.HttpContext.Request.PathBase}/Admin/RoxyFileman/ProcessRequest?a=DOWNLOADDIR", DELETEFILE = $"{this.HttpContext.Request.PathBase}/Admin/RoxyFileman/ProcessRequest?a=DELETEFILE", MOVEFILE = $"{this.HttpContext.Request.PathBase}/Admin/RoxyFileman/ProcessRequest?a=MOVEFILE", COPYFILE = $"{this.HttpContext.Request.PathBase}/Admin/RoxyFileman/ProcessRequest?a=COPYFILE", RENAMEFILE = $"{this.HttpContext.Request.PathBase}/Admin/RoxyFileman/ProcessRequest?a=RENAMEFILE", GENERATETHUMB = $"{this.HttpContext.Request.PathBase}/Admin/RoxyFileman/ProcessRequest?a=GENERATETHUMB" }; //save the file var text = JsonConvert.SerializeObject(configuration, Formatting.Indented); _fileProvider.WriteAllText(filePath, text, Encoding.UTF8); }
/// <summary> /// Load settings /// </summary> /// <param name="filePath">File path; pass null to use default settings file path</param> /// <param name="reloadSettings">Indicates whether to reload data, if they already loaded</param> /// <returns>Data settings</returns> public virtual DataSettings LoadSettings(string filePath = null, bool reloadSettings = false) { if (!reloadSettings && Singleton <DataSettings> .Instance != null) { return(Singleton <DataSettings> .Instance); } filePath = filePath ?? _fileProvider.MapPath(DataSettingsFilePath); //check whether file exists if (!_fileProvider.FileExists(filePath)) { //if not, try to parse the file that was used in previous nopCommerce versions filePath = _fileProvider.MapPath(OBSOLETE_DATA_SETTINGS_FILE_PATH); if (!_fileProvider.FileExists(filePath)) { return(new DataSettings()); } //get data settings from the old txt file var dataSettings = new DataSettings(); using (var reader = new StringReader(_fileProvider.ReadAllText(filePath, Encoding.UTF8))) { string settingsLine; while ((settingsLine = reader.ReadLine()) != null) { var separatorIndex = settingsLine.IndexOf(':'); if (separatorIndex == -1) { continue; } var key = settingsLine.Substring(0, separatorIndex).Trim(); var value = settingsLine.Substring(separatorIndex + 1).Trim(); switch (key) { case "DataProvider": dataSettings.DataProvider = value; continue; case "DataConnectionString": dataSettings.DataConnectionString = value; continue; default: dataSettings.RawDataSettings.Add(key, value); continue; } } } //save data settings to the new file SaveSettings(dataSettings); //and delete the old one _fileProvider.DeleteFile(filePath); Singleton <DataSettings> .Instance = dataSettings; return(Singleton <DataSettings> .Instance); } var text = _fileProvider.ReadAllText(filePath, Encoding.UTF8); if (string.IsNullOrEmpty(text)) { return(new DataSettings()); } //get data settings from the JSON file Singleton <DataSettings> .Instance = JsonConvert.DeserializeObject <DataSettings>(text); return(Singleton <DataSettings> .Instance); }