From fa9ed8e63d5bc50b6295b1630c48cff6c00a1f70 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Tue, 31 May 2016 13:47:02 +0200 Subject: [PATCH 01/73] Fixed: Base price in product list ignored PriceDisplayType (catalog settings) and possibly displayed the wrong base price info. f2a904a related --- changelog.md | 3 +- .../Catalog/PriceCalculationService.cs | 6 +++ .../Catalog/ProductExtensions.cs | 37 ++++++++++++++++--- .../Controllers/CatalogHelper.cs | 22 ++++++----- 4 files changed, 52 insertions(+), 16 deletions(-) diff --git a/changelog.md b/changelog.md index 2d597b0d26..97798e8f54 100644 --- a/changelog.md +++ b/changelog.md @@ -48,7 +48,8 @@ * Copied product must not share sample download of source product. Could produce "The DELETE statement conflicted with the REFERENCE constraint 'FK_dbo.Product_dbo.Download_SampleDownloadId'". * #921 Specification attribute options with single quotation marks are causing a Javascript error * #971 Product is added to cart automatically if it has a non-required file upload attribute -* #973 Bundle item upload is nowhere linked +* #973 Bundle item upload is nowhere linked +* Base price in product list ignored PriceDisplayType (catalog settings) and possibly displayed the wrong base price info ## SmartStore.NET 2.5 diff --git a/src/Libraries/SmartStore.Services/Catalog/PriceCalculationService.cs b/src/Libraries/SmartStore.Services/Catalog/PriceCalculationService.cs index 1aef3aeb63..ca45f495d7 100644 --- a/src/Libraries/SmartStore.Services/Catalog/PriceCalculationService.cs +++ b/src/Libraries/SmartStore.Services/Catalog/PriceCalculationService.cs @@ -251,6 +251,12 @@ protected virtual decimal GetPreselectedPrice(Product product, PriceCalculationC if (selectedCombination != null && selectedCombination.IsActive && selectedCombination.Price.HasValue) { product.MergedDataValues = new Dictionary { { "Price", selectedCombination.Price.Value } }; + + if (selectedCombination.BasePriceAmount.HasValue) + product.MergedDataValues.Add("BasePriceAmount", selectedCombination.BasePriceAmount.Value); + + if (selectedCombination.BasePriceBaseAmount.HasValue) + product.MergedDataValues.Add("BasePriceBaseAmount", selectedCombination.BasePriceBaseAmount.Value); } } diff --git a/src/Libraries/SmartStore.Services/Catalog/ProductExtensions.cs b/src/Libraries/SmartStore.Services/Catalog/ProductExtensions.cs index a76113c777..5675097c9e 100644 --- a/src/Libraries/SmartStore.Services/Catalog/ProductExtensions.cs +++ b/src/Libraries/SmartStore.Services/Catalog/ProductExtensions.cs @@ -14,7 +14,7 @@ namespace SmartStore.Services.Catalog { - public static class ProductExtensions + public static class ProductExtensions { public static ProductVariantAttributeCombination MergeWithCombination(this Product product, string selectedAttributes) { @@ -299,7 +299,7 @@ public static int[] ParseRequiredProductIds(this Product product) } /// - /// Gets the base price + /// Gets the base price info /// /// Product /// Localization service @@ -310,7 +310,7 @@ public static int[] ParseRequiredProductIds(this Product product) /// Target currency /// Price adjustment /// Whether the result string should be language independent - /// The base price + /// The base price info public static string GetBasePriceInfo(this Product product, ILocalizationService localizationService, IPriceFormatter priceFormatter, ICurrencyService currencyService, ITaxService taxService, IPriceCalculationService priceCalculationService, Currency currency, decimal priceAdjustment = decimal.Zero, bool languageIndependent = false) @@ -331,8 +331,33 @@ public static string GetBasePriceInfo(this Product product, ILocalizationService price = currencyService.ConvertFromPrimaryStoreCurrency(price, currency); - var value = Convert.ToDecimal((price / product.BasePriceAmount) * product.BasePriceBaseAmount); - var valueFormatted = priceFormatter.FormatPrice(value, true, currency); + return product.GetBasePriceInfo(price, localizationService, priceFormatter, currency, languageIndependent); + } + + return ""; + } + + /// + /// Gets the base price info + /// + /// Product + /// The calculated product price + /// Localization service + /// Price formatter + /// Target currency + /// Whether the result string should be language independent + /// The base price info + public static string GetBasePriceInfo(this Product product, + decimal productPrice, + ILocalizationService localizationService, + IPriceFormatter priceFormatter, + Currency currency, + bool languageIndependent = false) + { + if (product.BasePriceHasValue && product.BasePriceAmount != Decimal.Zero) + { + var value = Convert.ToDecimal((productPrice / product.BasePriceAmount) * product.BasePriceBaseAmount); + var valueFormatted = priceFormatter.FormatPrice(value, true, currency); var amountFormatted = Math.Round(product.BasePriceAmount.Value, 2).ToString("G29"); var result = "{0} {1} ({2} / {3} {1})".FormatInvariant( @@ -351,7 +376,7 @@ public static string GetBasePriceInfo(this Product product, ILocalizationService } return ""; - } + } public static string GetProductTypeLabel(this Product product, ILocalizationService localizationService) { diff --git a/src/Presentation/SmartStore.Web/Controllers/CatalogHelper.cs b/src/Presentation/SmartStore.Web/Controllers/CatalogHelper.cs index 2c0f3ef2be..55793edc65 100644 --- a/src/Presentation/SmartStore.Web/Controllers/CatalogHelper.cs +++ b/src/Presentation/SmartStore.Web/Controllers/CatalogHelper.cs @@ -1108,6 +1108,7 @@ public IEnumerable PrepareProductOverviewModels( foreach (var product in products) { var contextProduct = product; + var finalPrice = decimal.Zero; var model = new ProductOverviewModel { @@ -1188,7 +1189,7 @@ public IEnumerable PrepareProductOverviewModels( decimal taxRate = decimal.Zero; decimal oldPriceBase = _taxService.GetProductPrice(contextProduct, contextProduct.OldPrice, out taxRate); decimal finalPriceBase = _taxService.GetProductPrice(contextProduct, displayPrice.Value, out taxRate); - decimal finalPrice = _currencyService.ConvertFromPrimaryStoreCurrency(finalPriceBase, workingCurrency); + finalPrice = _currencyService.ConvertFromPrimaryStoreCurrency(finalPriceBase, workingCurrency); priceModel.OldPrice = null; @@ -1256,7 +1257,7 @@ public IEnumerable PrepareProductOverviewModels( decimal finalPriceBase = _taxService.GetProductPrice(product, displayPrice, out taxRate); decimal oldPrice = _currencyService.ConvertFromPrimaryStoreCurrency(oldPriceBase, workingCurrency); - decimal finalPrice = _currencyService.ConvertFromPrimaryStoreCurrency(finalPriceBase, workingCurrency); + finalPrice = _currencyService.ConvertFromPrimaryStoreCurrency(finalPriceBase, workingCurrency); priceModel.HasDiscount = (finalPriceBase != oldPriceBase && oldPriceBase != decimal.Zero); @@ -1396,16 +1397,19 @@ from a in colorAttribute.ProductVariantAttributeValues.Take(50) model.Manufacturers = PrepareManufacturersOverviewModel(_manufacturerService.GetProductManufacturersByProductId(product.Id), cachedManufacturerModels, false); } - if (_catalogSettings.ShowBasePriceInProductLists || isCompareList) + if (finalPrice != decimal.Zero && (_catalogSettings.ShowBasePriceInProductLists || isCompareList)) { - model.BasePriceInfo = contextProduct.GetBasePriceInfo(_localizationService, _priceFormatter, _currencyService, _taxService, _priceCalculationService, workingCurrency); + model.BasePriceInfo = contextProduct.GetBasePriceInfo(finalPrice, _localizationService, _priceFormatter, workingCurrency); } - var addShippingPrice = _currencyService.ConvertCurrency(contextProduct.AdditionalShippingCharge, currentStore.PrimaryStoreCurrency, workingCurrency); - - if (addShippingPrice > 0 && displayPrices) + if (displayPrices) { - model.TransportSurcharge = res["Common.AdditionalShippingSurcharge"].Text.FormatWith(_priceFormatter.FormatPrice(addShippingPrice, true, false)); + var addShippingPrice = _currencyService.ConvertCurrency(contextProduct.AdditionalShippingCharge, currentStore.PrimaryStoreCurrency, workingCurrency); + + if (addShippingPrice > 0) + { + model.TransportSurcharge = res["Common.AdditionalShippingSurcharge"].Text.FormatCurrent(_priceFormatter.FormatPrice(addShippingPrice, true, false)); + } } if (contextProduct.Weight > 0) @@ -1416,7 +1420,7 @@ from a in colorAttribute.ProductVariantAttributeValues.Take(50) // IsNew if (_catalogSettings.LabelAsNewForMaxDays.HasValue) { - model.IsNew = (DateTime.UtcNow - product.CreatedOnUtc).Days <= _catalogSettings.LabelAsNewForMaxDays.Value; + model.IsNew = ((DateTime.UtcNow - product.CreatedOnUtc).Days <= _catalogSettings.LabelAsNewForMaxDays.Value); } models.Add(model); From c073be3258e6668ee55968f5adca3e63503a147d Mon Sep 17 00:00:00 2001 From: Murat Cakir Date: Tue, 31 May 2016 18:26:17 +0200 Subject: [PATCH 02/73] DRY: use StringExtensions.RemoveHtml() --- .../SmartStore.Web/Views/Product/_BundleItems.cshtml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Presentation/SmartStore.Web/Views/Product/_BundleItems.cshtml b/src/Presentation/SmartStore.Web/Views/Product/_BundleItems.cshtml index 6c588c5d96..be033b6957 100644 --- a/src/Presentation/SmartStore.Web/Views/Product/_BundleItems.cshtml +++ b/src/Presentation/SmartStore.Web/Views/Product/_BundleItems.cshtml @@ -1,7 +1,6 @@ @model ProductDetailsModel @using SmartStore.Web.Models.Catalog; @using SmartStore.Web; -@using System.Text.RegularExpressions; @foreach (var item in Model.BundledItems.Where(x => x.BundleItem.Visible)) { @@ -35,8 +34,8 @@ @if (!String.IsNullOrWhiteSpace(item.ShortDescription)) { - var strippedShortDesc = Regex.Replace(item.ShortDescription, @"<[^>]*>", String.Empty); - + var strippedShortDesc = item.ShortDescription.RemoveHtml(); +
@Html.Raw(strippedShortDesc.Truncate(170, "..."))
From 45db3df1fc1d47428b06f01ed51f51860c8d61f3 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Tue, 31 May 2016 20:53:31 +0200 Subject: [PATCH 03/73] Base price info template should be localizable. Closes #977. --- .../201605201911421_ExportRevision.cs | 13 ++++-- .../Catalog/ProductExtensions.cs | 46 +++++++++++-------- 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/src/Libraries/SmartStore.Data/Migrations/201605201911421_ExportRevision.cs b/src/Libraries/SmartStore.Data/Migrations/201605201911421_ExportRevision.cs index d89896b820..4618512963 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201605201911421_ExportRevision.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201605201911421_ExportRevision.cs @@ -154,17 +154,20 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) "There was no file uploaded.", "Es wurde keine Datei hochgeladen."); - builder.AddOrUpdate("Common.Content", - "Content", - "Inhalt"); + builder.AddOrUpdate("Products.BasePriceInfo", + "Content: {0} {1} ({2} / {3} {1})", + "Inhalt: {0} {1} ({2} / {3} {1})"); + + builder.AddOrUpdate("Products.BasePriceInfo.LanguageInsensitive", + "{0} {1} ({2} / {3} {1})", + "{0} {1} ({2} / {3} {1})"); builder.Delete( "Admin.DataExchange.Export.FolderAndFileName.Validate", "Admin.DataExchange.Export.Deployment.IsPublic", "Admin.DataExchange.Export.Deployment.CreateZip", "Admin.Common.TemporaryFiles", - "Admin.Common.NoTempFilesFound", - "Products.BasePriceInfo"); + "Admin.Common.NoTempFilesFound"); } } } diff --git a/src/Libraries/SmartStore.Services/Catalog/ProductExtensions.cs b/src/Libraries/SmartStore.Services/Catalog/ProductExtensions.cs index 5675097c9e..051fc841f2 100644 --- a/src/Libraries/SmartStore.Services/Catalog/ProductExtensions.cs +++ b/src/Libraries/SmartStore.Services/Catalog/ProductExtensions.cs @@ -309,17 +309,23 @@ public static int[] ParseRequiredProductIds(this Product product) /// Price calculation service /// Target currency /// Price adjustment - /// Whether the result string should be language independent + /// Whether the result string should be language insensitive /// The base price info - public static string GetBasePriceInfo(this Product product, ILocalizationService localizationService, IPriceFormatter priceFormatter, - ICurrencyService currencyService, ITaxService taxService, IPriceCalculationService priceCalculationService, - Currency currency, decimal priceAdjustment = decimal.Zero, bool languageIndependent = false) + public static string GetBasePriceInfo(this Product product, + ILocalizationService localizationService, + IPriceFormatter priceFormatter, + ICurrencyService currencyService, + ITaxService taxService, + IPriceCalculationService priceCalculationService, + Currency currency, + decimal priceAdjustment = decimal.Zero, + bool languageInsensitive = false) { - if (product == null) - throw new ArgumentNullException("product"); - - if (localizationService == null && !languageIndependent) - throw new ArgumentNullException("localizationService"); + Guard.ArgumentNotNull(() => product); + Guard.ArgumentNotNull(() => currencyService); + Guard.ArgumentNotNull(() => taxService); + Guard.ArgumentNotNull(() => priceCalculationService); + Guard.ArgumentNotNull(() => currency); if (product.BasePriceHasValue && product.BasePriceAmount != Decimal.Zero) { @@ -331,7 +337,7 @@ public static string GetBasePriceInfo(this Product product, ILocalizationService price = currencyService.ConvertFromPrimaryStoreCurrency(price, currency); - return product.GetBasePriceInfo(price, localizationService, priceFormatter, currency, languageIndependent); + return product.GetBasePriceInfo(price, localizationService, priceFormatter, currency, languageInsensitive); } return ""; @@ -345,34 +351,36 @@ public static string GetBasePriceInfo(this Product product, ILocalizationService /// Localization service /// Price formatter /// Target currency - /// Whether the result string should be language independent + /// Whether the result string should be language insensitive /// The base price info public static string GetBasePriceInfo(this Product product, decimal productPrice, ILocalizationService localizationService, IPriceFormatter priceFormatter, Currency currency, - bool languageIndependent = false) + bool languageInsensitive = false) { + Guard.ArgumentNotNull(() => product); + Guard.ArgumentNotNull(() => localizationService); + Guard.ArgumentNotNull(() => priceFormatter); + Guard.ArgumentNotNull(() => currency); + if (product.BasePriceHasValue && product.BasePriceAmount != Decimal.Zero) { var value = Convert.ToDecimal((productPrice / product.BasePriceAmount) * product.BasePriceBaseAmount); var valueFormatted = priceFormatter.FormatPrice(value, true, currency); var amountFormatted = Math.Round(product.BasePriceAmount.Value, 2).ToString("G29"); - var result = "{0} {1} ({2} / {3} {1})".FormatInvariant( + var infoTemplate = localizationService.GetResource(languageInsensitive ? "Products.BasePriceInfo.LanguageInsensitive" : "Products.BasePriceInfo"); + + var result = infoTemplate.FormatInvariant( amountFormatted, product.BasePriceMeasureUnit, valueFormatted, product.BasePriceBaseAmount ); - if (languageIndependent) - { - return result; - } - - return string.Concat(localizationService.GetResource("Common.Content"), ": ", result); + return result; } return ""; From 06ba5bb79196550f0e115cadb21aaa22b7f7a5a0 Mon Sep 17 00:00:00 2001 From: Murat Cakir Date: Wed, 1 Jun 2016 00:37:51 +0200 Subject: [PATCH 04/73] Enhanced safe local http call helper --- .../Utilities/FileDownloadManager.cs | 16 +++- src/Libraries/SmartStore.Core/WebHelper.cs | 76 +++++++++++++------ 2 files changed, 67 insertions(+), 25 deletions(-) diff --git a/src/Libraries/SmartStore.Core/Utilities/FileDownloadManager.cs b/src/Libraries/SmartStore.Core/Utilities/FileDownloadManager.cs index 7759a8bc93..d3fcef7874 100644 --- a/src/Libraries/SmartStore.Core/Utilities/FileDownloadManager.cs +++ b/src/Libraries/SmartStore.Core/Utilities/FileDownloadManager.cs @@ -31,14 +31,24 @@ public FileDownloadManager(HttpRequestBase httpRequest) /// The URL to download the file from (either a fully qualified URL or an app relative/absolute path) /// Specifies whether the FormsAuthenticationCookie should be sent /// Timeout in milliseconds - public FileDownloadResponse DownloadFile(string url, bool sendAuthCookie = false, int? timeout = null) + /// Specifiers whether the file is located on the local server + public FileDownloadResponse DownloadFile(string url, bool sendAuthCookie = false, int? timeout = null, bool isLocal = false) { Guard.ArgumentNotEmpty(() => url); url = WebHelper.GetAbsoluteUrl(url, _httpRequest); - var req = WebRequest.CreateHttp(url); - req.UserAgent = "SmartStore.NET"; + HttpWebRequest req; + + if (isLocal) + { + req = WebHelper.CreateHttpRequestForSafeLocalCall(new Uri(url)); + } + else + { + req = WebRequest.CreateHttp(url); + req.UserAgent = "SmartStore.NET"; + } if (timeout.HasValue) { diff --git a/src/Libraries/SmartStore.Core/WebHelper.cs b/src/Libraries/SmartStore.Core/WebHelper.cs index 2f622643d9..d170abc60c 100644 --- a/src/Libraries/SmartStore.Core/WebHelper.cs +++ b/src/Libraries/SmartStore.Core/WebHelper.cs @@ -2,6 +2,7 @@ using System.Configuration; using System.Diagnostics.CodeAnalysis; using System.IO; +using System.Linq; using System.Text.RegularExpressions; using System.Threading; using System.Web; @@ -13,6 +14,9 @@ using SmartStore.Utilities; using System.Net; using System.Text; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Net.Sockets; namespace SmartStore.Core { @@ -24,7 +28,7 @@ public partial class WebHelper : IWebHelper private static readonly Regex s_staticExts = new Regex(@"(.*?)\.(css|js|png|jpg|jpeg|gif|bmp|html|htm|xml|pdf|doc|xls|rar|zip|ico|eot|svg|ttf|woff|otf|axd|ashx|less)", RegexOptions.Compiled | RegexOptions.IgnoreCase); private static readonly Regex s_htmlPathPattern = new Regex(@"(?<=(?:href|src)=(?:""|'))(?!https?://)(?[^(?:""|')]+)", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Multiline); private static readonly Regex s_cssPathPattern = new Regex(@"url\('(?.+)'\)", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Multiline); - private static string s_safeLocalHostName = null; + private static ConcurrentDictionary s_safeLocalHostNames = new ConcurrentDictionary(); private readonly HttpContextBase _httpContext; private bool? _isCurrentConnectionSecured; @@ -678,15 +682,15 @@ public static HttpWebRequest CreateHttpRequestForSafeLocalCall(Uri requestUri) { Guard.ArgumentNotNull(() => requestUri); - EnsureSafeLocalHostNameDetermined(requestUri); + var safeHostName = GetSafeLocalHostName(requestUri); var uri = requestUri; - if (!requestUri.Host.Equals(s_safeLocalHostName, StringComparison.OrdinalIgnoreCase)) + if (!requestUri.Host.Equals(safeHostName, StringComparison.OrdinalIgnoreCase)) { var url = String.Format("{0}://{1}{2}", requestUri.Scheme, - requestUri.Port == 80 ? s_safeLocalHostName : s_safeLocalHostName + ":" + requestUri.Port, + requestUri.IsDefaultPort ? safeHostName : safeHostName + ":" + requestUri.Port, requestUri.PathAndQuery); uri = new Uri(url); } @@ -699,30 +703,58 @@ public static HttpWebRequest CreateHttpRequestForSafeLocalCall(Uri requestUri) return request; } - private static void EnsureSafeLocalHostNameDetermined(Uri requestUri) + private static string GetSafeLocalHostName(Uri requestUri) { - if (s_safeLocalHostName == null) + return s_safeLocalHostNames.GetOrAdd(requestUri.Port, (port) => { - lock (s_lock) + var hostName = Dns.GetHostName(); + var hosts = new List { requestUri.Host, "localhost", hostName, "127.0.0.1" }; + + // now add all local IP addresses + var ipAddresses = Dns.GetHostAddresses(hostName).Where(x => x.AddressFamily == AddressFamily.InterNetwork).Select(x => x.ToString()); + hosts.AddRange(ipAddresses); + + var firstHost = true; + + foreach (var host in hosts) { - if (s_safeLocalHostName == null) + var url = String.Format("{0}://{1}/taskscheduler/noop", + requestUri.Scheme, + requestUri.IsDefaultPort ? host : host + ":" + requestUri.Port); + var uri = new Uri(url); + + var request = WebRequest.CreateHttp(uri); + request.ServerCertificateValidationCallback += (sender, cert, chain, errors) => true; + request.ServicePoint.Expect100Continue = false; + request.UserAgent = "SmartStore.NET"; + request.Timeout = firstHost ? 5000 : 500; + + firstHost = false; + + HttpWebResponse response = null; + + try { - //var hosts = new string[] - //{ - // requestUri.Host, - // "localhost", - // Dns.GetHostName(), // TODO: add local IPs also - // "127.0.0.1" - //}; - - //foreach (var host in hosts) - //{ - // // ... - //} - s_safeLocalHostName = "localhost"; // TBD: what about ssl and differing ports? + response = (HttpWebResponse)request.GetResponse(); + if (response.StatusCode == HttpStatusCode.OK) + { + return host; + } + } + catch + { + // try the next host + } + finally + { + if (response != null) + response.Dispose(); } } - } + + // None of the hosts are callable. WTF? + return requestUri.Host; + }); } } } From 1bb75a8f037ec9dceba198f7edf6afd5ccb43161 Mon Sep 17 00:00:00 2001 From: Murat Cakir Date: Wed, 1 Jun 2016 19:51:36 +0200 Subject: [PATCH 05/73] TaskScheduler could fail polling when primary store url is an external IP address --- changelog.md | 2 + src/Libraries/SmartStore.Core/WebHelper.cs | 95 +++++++++++-------- .../Tasks/TaskScheduler.cs | 6 +- .../Seo/CanonicalHostNameAttribute.cs | 2 +- .../Controllers/CommonController.cs | 2 +- 5 files changed, 65 insertions(+), 42 deletions(-) diff --git a/changelog.md b/changelog.md index 97798e8f54..50fde28956 100644 --- a/changelog.md +++ b/changelog.md @@ -27,8 +27,10 @@ * Added paging to frontend order list * Added paging to backend checkout attribute list * #977 Show PAngV base/delivery amount also +* Updated LiveEngage LiveChat plugin ### Bugfixes +* TaskScheduler could fail polling when primary store url is an external IP address * Fixed ajax cache issue when saving payment or shipping restrictions. Internet Explorer showed the old data state (before storage). * "The provider failed at the Execute method: Member 'CurrentValues' cannot be called for the entity of type 'Product'" when exporting product attribute combinations * Bundles without selected attributes could throw an exception on product detail page diff --git a/src/Libraries/SmartStore.Core/WebHelper.cs b/src/Libraries/SmartStore.Core/WebHelper.cs index d170abc60c..fee592e852 100644 --- a/src/Libraries/SmartStore.Core/WebHelper.cs +++ b/src/Libraries/SmartStore.Core/WebHelper.cs @@ -198,12 +198,12 @@ private string GetStoreHost(bool useSsl, out bool appPathPossiblyAppended) if (_currentStore != null) { - var securityMode = _currentStore.GetSecurityMode(useSsl); + var securityMode = _currentStore.GetSecurityMode(); if (httpHost.IsEmpty()) { - //HTTP_HOST variable is not available. - //It's possible only when HttpContext is not available (for example, running in a schedule task) + // HTTP_HOST variable is not available. + // It's possible only when HttpContext is not available (for example, running in a schedule task) result = _currentStore.Url.EnsureEndsWith("/"); appPathPossiblyAppended = true; @@ -707,48 +707,33 @@ private static string GetSafeLocalHostName(Uri requestUri) { return s_safeLocalHostNames.GetOrAdd(requestUri.Port, (port) => { + // first try original host + if (TestHost(requestUri, requestUri.Host, 5000)) + { + return requestUri.Host; + } + + // try loopback var hostName = Dns.GetHostName(); - var hosts = new List { requestUri.Host, "localhost", hostName, "127.0.0.1" }; + var hosts = new List { "localhost", hostName, "127.0.0.1" }; + foreach (var host in hosts) + { + if (TestHost(requestUri, host, 500)) + { + return host; + } + } - // now add all local IP addresses + // try local IP addresses + hosts.Clear(); var ipAddresses = Dns.GetHostAddresses(hostName).Where(x => x.AddressFamily == AddressFamily.InterNetwork).Select(x => x.ToString()); hosts.AddRange(ipAddresses); - var firstHost = true; - foreach (var host in hosts) { - var url = String.Format("{0}://{1}/taskscheduler/noop", - requestUri.Scheme, - requestUri.IsDefaultPort ? host : host + ":" + requestUri.Port); - var uri = new Uri(url); - - var request = WebRequest.CreateHttp(uri); - request.ServerCertificateValidationCallback += (sender, cert, chain, errors) => true; - request.ServicePoint.Expect100Continue = false; - request.UserAgent = "SmartStore.NET"; - request.Timeout = firstHost ? 5000 : 500; - - firstHost = false; - - HttpWebResponse response = null; - - try - { - response = (HttpWebResponse)request.GetResponse(); - if (response.StatusCode == HttpStatusCode.OK) - { - return host; - } - } - catch - { - // try the next host - } - finally + if (TestHost(requestUri, host, 500)) { - if (response != null) - response.Dispose(); + return host; } } @@ -756,5 +741,41 @@ private static string GetSafeLocalHostName(Uri requestUri) return requestUri.Host; }); } + + private static bool TestHost(Uri originalUri, string host, int timeout) + { + var url = String.Format("{0}://{1}/taskscheduler/noop", + originalUri.Scheme, + originalUri.IsDefaultPort ? host : host + ":" + originalUri.Port); + var uri = new Uri(url); + + var request = WebRequest.CreateHttp(uri); + request.ServerCertificateValidationCallback += (sender, cert, chain, errors) => true; + request.ServicePoint.Expect100Continue = false; + request.UserAgent = "SmartStore.NET"; + request.Timeout = timeout; + + HttpWebResponse response = null; + + try + { + response = (HttpWebResponse)request.GetResponse(); + if (response.StatusCode == HttpStatusCode.OK) + { + return true; + } + } + catch + { + // try the next host + } + finally + { + if (response != null) + response.Dispose(); + } + + return false; + } } } diff --git a/src/Libraries/SmartStore.Services/Tasks/TaskScheduler.cs b/src/Libraries/SmartStore.Services/Tasks/TaskScheduler.cs index 4ca2101c29..0e055029a3 100644 --- a/src/Libraries/SmartStore.Services/Tasks/TaskScheduler.cs +++ b/src/Libraries/SmartStore.Services/Tasks/TaskScheduler.cs @@ -167,9 +167,9 @@ protected internal virtual void CallEndpoint(Uri uri) { if (_shuttingDown) return; - - var req = WebHelper.CreateHttpRequestForSafeLocalCall(uri); - req.Method = "POST"; + + var req = WebHelper.CreateHttpRequestForSafeLocalCall(uri); + req.Method = "POST"; req.ContentType = "text/plain"; req.ContentLength = 0; req.Timeout = 10000; // 10 sec. diff --git a/src/Presentation/SmartStore.Web.Framework/Seo/CanonicalHostNameAttribute.cs b/src/Presentation/SmartStore.Web.Framework/Seo/CanonicalHostNameAttribute.cs index 2b3d2f2bd5..f683d550e1 100644 --- a/src/Presentation/SmartStore.Web.Framework/Seo/CanonicalHostNameAttribute.cs +++ b/src/Presentation/SmartStore.Web.Framework/Seo/CanonicalHostNameAttribute.cs @@ -57,7 +57,7 @@ public virtual void OnAuthorization(AuthorizationContext filterContext) if (securityMode == HttpSecurityMode.SharedSsl) { // Don't attempt to redirect when shared SSL is being used and current request is secured. - // Redirecting from https://ssl.bla.com to https://www.ssl.bla.com will most probably fail. + // Redirecting from http://ssl.bla.com to https://www.ssl.bla.com will most probably fail. return; } } diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/CommonController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/CommonController.cs index 1da4e0fed7..4bebf35ee1 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/CommonController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/CommonController.cs @@ -522,7 +522,7 @@ public ActionResult Warnings() string sitemapUrl = null; try { - sitemapUrl = Url.RouteUrl("SitemapSEO", (object)null, _securitySettings.Value.ForceSslForAllPages ? "https" : "http"); + sitemapUrl = WebHelper.GetAbsoluteUrl(Url.RouteUrl("SitemapSEO"), this.Request); var request = WebHelper.CreateHttpRequestForSafeLocalCall(new Uri(sitemapUrl)); request.Method = "HEAD"; request.Timeout = 15000; From 2eb3c1ce1bde9bb6b3fafec6026fb58d27a8bdd3 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Thu, 2 Jun 2016 15:18:15 +0200 Subject: [PATCH 06/73] Minor fix in string extension --- .../SmartStore.Core/Extensions/StringExtensions.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Libraries/SmartStore.Core/Extensions/StringExtensions.cs b/src/Libraries/SmartStore.Core/Extensions/StringExtensions.cs index 5a172fc17f..9131705215 100644 --- a/src/Libraries/SmartStore.Core/Extensions/StringExtensions.cs +++ b/src/Libraries/SmartStore.Core/Extensions/StringExtensions.cs @@ -490,16 +490,19 @@ public static string[] SplitSafe(this string value, string separator) /// true: success, false: failure [DebuggerStepThrough] [SuppressMessage("ReSharper", "StringIndexOfIsCultureSpecific.1")] - public static bool SplitToPair(this string value, out string strLeft, out string strRight, string delimiter) { + public static bool SplitToPair(this string value, out string strLeft, out string strRight, string delimiter) + { int idx = -1; - if (value.IsEmpty() || delimiter.IsEmpty() || (idx = value.IndexOf(delimiter)) == -1) + if (string.IsNullOrEmpty(value) || string.IsNullOrEmpty(delimiter) || (idx = value.IndexOf(delimiter)) == -1) { strLeft = value; strRight = ""; return false; } + strLeft = value.Substring(0, idx); strRight = value.Substring(idx + delimiter.Length); + return true; } From 253103745bf32f8b0615d6cde073760c8ed543bf Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Fri, 3 Jun 2016 13:04:47 +0200 Subject: [PATCH 07/73] Private messages: Fixes "No route in the route table matches the supplied values" --- changelog.md | 1 + .../Controllers/PrivateMessagesController.cs | 69 +++++++++---------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/changelog.md b/changelog.md index 50fde28956..826a9778de 100644 --- a/changelog.md +++ b/changelog.md @@ -52,6 +52,7 @@ * #971 Product is added to cart automatically if it has a non-required file upload attribute * #973 Bundle item upload is nowhere linked * Base price in product list ignored PriceDisplayType (catalog settings) and possibly displayed the wrong base price info +* Private messages: Fixes "No route in the route table matches the supplied values" ## SmartStore.NET 2.5 diff --git a/src/Presentation/SmartStore.Web/Controllers/PrivateMessagesController.cs b/src/Presentation/SmartStore.Web/Controllers/PrivateMessagesController.cs index 81ed0af2d8..8171bf6d4f 100644 --- a/src/Presentation/SmartStore.Web/Controllers/PrivateMessagesController.cs +++ b/src/Presentation/SmartStore.Web/Controllers/PrivateMessagesController.cs @@ -4,20 +4,19 @@ using SmartStore.Core; using SmartStore.Core.Domain.Customers; using SmartStore.Core.Domain.Forums; +using SmartStore.Core.Logging; using SmartStore.Services.Customers; using SmartStore.Services.Forums; using SmartStore.Services.Helpers; -using SmartStore.Services.Localization; using SmartStore.Web.Framework.Controllers; +using SmartStore.Web.Framework.Filters; using SmartStore.Web.Framework.Security; using SmartStore.Web.Models.Common; using SmartStore.Web.Models.PrivateMessages; -using SmartStore.Core.Logging; -using SmartStore.Web.Framework.Filters; namespace SmartStore.Web.Controllers { - [RequireHttpsByConfigAttribute(SslRequirement.Yes)] + [RequireHttpsByConfigAttribute(SslRequirement.Yes)] public partial class PrivateMessagesController : PublicControllerBase { #region Fields @@ -25,7 +24,6 @@ public partial class PrivateMessagesController : PublicControllerBase private readonly IForumService _forumService; private readonly ICustomerService _customerService; private readonly ICustomerActivityService _customerActivityService; - private readonly ILocalizationService _localizationService; private readonly IWorkContext _workContext; private readonly IStoreContext _storeContext; private readonly IDateTimeHelper _dateTimeHelper; @@ -37,16 +35,17 @@ public partial class PrivateMessagesController : PublicControllerBase #region Constructors public PrivateMessagesController(IForumService forumService, - ICustomerService customerService, ICustomerActivityService customerActivityService, - ILocalizationService localizationService, - IWorkContext workContext, IStoreContext storeContext, + ICustomerService customerService, + ICustomerActivityService customerActivityService, + IWorkContext workContext, + IStoreContext storeContext, IDateTimeHelper dateTimeHelper, - ForumSettings forumSettings, CustomerSettings customerSettings) + ForumSettings forumSettings, + CustomerSettings customerSettings) { this._forumService = forumService; this._customerService = customerService; this._customerActivityService = customerActivityService; - this._localizationService = localizationService; this._workContext = workContext; this._storeContext = storeContext; this._dateTimeHelper = dateTimeHelper; @@ -131,7 +130,7 @@ public ActionResult Inbox(int page, string tab) foreach (var pm in list) { - inbox.Add(new PrivateMessageModel() + inbox.Add(new PrivateMessageModel { Id = pm.Id, FromCustomerId = pm.FromCustomer.Id, @@ -175,7 +174,7 @@ public ActionResult SentItems(int page, string tab) foreach (var pm in list) { - sentItems.Add(new PrivateMessageModel() + sentItems.Add(new PrivateMessageModel { Id = pm.Id, FromCustomerId = pm.FromCustomer.Id, @@ -227,8 +226,8 @@ public ActionResult DeleteInboxPM(FormCollection formCollection) } } } - return RedirectToRoute("PrivateMessages"); - } + return RedirectToAction("Index"); + } [HttpPost, FormValueRequired("mark-unread"), ActionName("InboxUpdate")] public ActionResult MarkUnread(FormCollection formCollection) @@ -256,7 +255,7 @@ public ActionResult MarkUnread(FormCollection formCollection) } } } - return RedirectToRoute("PrivateMessages"); + return RedirectToAction("Index"); } //updates sent items (deletes PrivateMessages) @@ -306,8 +305,8 @@ public ActionResult Send(int id /* toCustomerId */, int? replyToMessageId) if (customerTo == null || customerTo.IsGuest()) { - return RedirectToRoute("PrivateMessages"); - } + return RedirectToAction("Index"); + } var model = new SendPrivateMessageModel(); model.ToCustomerId = customerTo.Id; @@ -319,8 +318,8 @@ public ActionResult Send(int id /* toCustomerId */, int? replyToMessageId) var replyToPM = _forumService.GetPrivateMessageById(replyToMessageId.Value); if (replyToPM == null) { - return RedirectToRoute("PrivateMessages"); - } + return RedirectToAction("Index"); + } if (replyToPM.ToCustomerId == _workContext.CurrentCustomer.Id || replyToPM.FromCustomerId == _workContext.CurrentCustomer.Id) { @@ -329,10 +328,10 @@ public ActionResult Send(int id /* toCustomerId */, int? replyToMessageId) } else { - return RedirectToRoute("PrivateMessages"); - } + return RedirectToAction("Index"); + } } - return View(model); + return View(model); } [HttpPost] @@ -358,8 +357,8 @@ public ActionResult Send(SendPrivateMessageModel model) } else { - return RedirectToRoute("PrivateMessages"); - } + return RedirectToAction("Index"); + } } else { @@ -368,8 +367,8 @@ public ActionResult Send(SendPrivateMessageModel model) if (toCustomer == null || toCustomer.IsGuest()) { - return RedirectToRoute("PrivateMessages"); - } + return RedirectToAction("Index"); + } model.ToCustomerId = toCustomer.Id; model.CustomerToName = toCustomer.FormatUserName(); model.AllowViewingToProfile = _customerSettings.AllowViewingProfiles && !toCustomer.IsGuest(); @@ -408,9 +407,9 @@ public ActionResult Send(SendPrivateMessageModel model) _forumService.InsertPrivateMessage(privateMessage); //activity log - _customerActivityService.InsertActivity("PublicStore.SendPM", _localizationService.GetResource("ActivityLog.PublicStore.SendPM"), toCustomer.Email); + _customerActivityService.InsertActivity("PublicStore.SendPM", T("ActivityLog.PublicStore.SendPM", toCustomer.Email)); - return RedirectToRoute("PrivateMessages", new { tab = "sent" }); + return RedirectToAction("Index", new { tab = "sent" }); } catch (Exception ex) { @@ -438,8 +437,8 @@ public ActionResult View(int id /* privateMessageId */) { if (pm.ToCustomerId != _workContext.CurrentCustomer.Id && pm.FromCustomerId != _workContext.CurrentCustomer.Id) { - return RedirectToRoute("PrivateMessages"); - } + return RedirectToAction("Index"); + } if (!pm.IsRead && pm.ToCustomerId == _workContext.CurrentCustomer.Id) { @@ -449,10 +448,10 @@ public ActionResult View(int id /* privateMessageId */) } else { - return RedirectToRoute("PrivateMessages"); - } + return RedirectToAction("Index"); + } - var model = new PrivateMessageModel() + var model = new PrivateMessageModel { Id = pm.Id, FromCustomerId = pm.FromCustomer.Id, @@ -497,8 +496,8 @@ public ActionResult Delete(int id /* privateMessageId */) _forumService.UpdatePrivateMessage(pm); } } - return RedirectToRoute("PrivateMessages"); - } + return RedirectToAction("Index"); + } #endregion } From e2d903b5e04e294cd8013d9d6fe11ba6510856b0 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Fri, 3 Jun 2016 14:04:20 +0200 Subject: [PATCH 08/73] Localized some hard coded strings --- .../201605201911421_ExportRevision.cs | 10 ++++++ .../Controllers/CustomerController.cs | 35 ++++++++----------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/Libraries/SmartStore.Data/Migrations/201605201911421_ExportRevision.cs b/src/Libraries/SmartStore.Data/Migrations/201605201911421_ExportRevision.cs index 4618512963..485fa9fdec 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201605201911421_ExportRevision.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201605201911421_ExportRevision.cs @@ -162,6 +162,16 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) "{0} {1} ({2} / {3} {1})", "{0} {1} ({2} / {3} {1})"); + builder.AddOrUpdate("PrivateMessages.Disabled", + "Private messages are disabled.", + "Private Nachrichten sind deaktiviert."); + + builder.AddOrUpdate("Common.MethodNotSupportedForGuests", + "This function is not available for guests.", + "Diese Funktion steht für Gäste nicht zur Verfügung."); + + + builder.Delete( "Admin.DataExchange.Export.FolderAndFileName.Validate", "Admin.DataExchange.Export.Deployment.IsPublic", diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/CustomerController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/CustomerController.cs index ee08e3f976..44b6c10a0f 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/CustomerController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/CustomerController.cs @@ -974,19 +974,22 @@ public ActionResult ChangePassword(CustomerModel model) var customer = _customerService.GetCustomerById(model.Id); if (customer == null) - //No customer found with the specified id return RedirectToAction("List"); if (ModelState.IsValid) { - var changePassRequest = new ChangePasswordRequest(model.Email, - false, _customerSettings.DefaultPasswordFormat, model.Password); + var changePassRequest = new ChangePasswordRequest(model.Email, false, _customerSettings.DefaultPasswordFormat, model.Password); var changePassResult = _customerRegistrationService.ChangePassword(changePassRequest); - if (changePassResult.Success) - NotifySuccess(_localizationService.GetResource("Admin.Customers.Customers.PasswordChanged")); - else - foreach (var error in changePassResult.Errors) + + if (changePassResult.Success) + { + NotifySuccess(_localizationService.GetResource("Admin.Customers.Customers.PasswordChanged")); + } + else + { + foreach (var error in changePassResult.Errors) NotifyError(error); + } } return RedirectToAction("Edit", customer.Id); @@ -1001,7 +1004,6 @@ public ActionResult MarkVatNumberAsValid(CustomerModel model) var customer = _customerService.GetCustomerById(model.Id); if (customer == null) - //No customer found with the specified id return RedirectToAction("List"); _genericAttributeService.SaveAttribute(customer, @@ -1020,7 +1022,6 @@ public ActionResult MarkVatNumberAsInvalid(CustomerModel model) var customer = _customerService.GetCustomerById(model.Id); if (customer == null) - //No customer found with the specified id return RedirectToAction("List"); _genericAttributeService.SaveAttribute(customer, @@ -1078,7 +1079,6 @@ public ActionResult Impersonate(int id) var customer = _customerService.GetCustomerById(id); if (customer == null) - //No customer found with the specified id return RedirectToAction("List"); // ensure that a non-admin user cannot impersonate as an administrator @@ -1150,19 +1150,18 @@ public ActionResult SendPm(CustomerModel model) var customer = _customerService.GetCustomerById(model.Id); if (customer == null) - //No customer found with the specified id return RedirectToAction("List"); try { if (!_forumSettings.AllowPrivateMessages) - throw new SmartException("Private messages are disabled"); + throw new SmartException(T("PrivateMessages.Disabled")); if (customer.IsGuest()) - throw new SmartException("Customer should be registered"); + throw new SmartException(T("Common.MethodNotSupportedForGuests")); if (String.IsNullOrWhiteSpace(model.SendPm.Subject)) - throw new SmartException("PM subject is empty"); + throw new SmartException(T("Admin.Customers.Customers.SendPM.Subject.Hint")); if (String.IsNullOrWhiteSpace(model.SendPm.Message)) - throw new SmartException("PM message is empty"); + throw new SmartException(T("Admin.Customers.Customers.SendPM.Message.Hint")); var privateMessage = new PrivateMessage @@ -1314,7 +1313,6 @@ public ActionResult AddressCreate(int customerId) var customer = _customerService.GetCustomerById(customerId); if (customer == null) - //No customer found with the specified id return RedirectToAction("List"); var model = new CustomerAddressModel(); @@ -1359,7 +1357,6 @@ public ActionResult AddressCreate(CustomerAddressModel model) var customer = _customerService.GetCustomerById(model.CustomerId); if (customer == null) - //No customer found with the specified id return RedirectToAction("List"); if (ModelState.IsValid) @@ -1408,12 +1405,10 @@ public ActionResult AddressEdit(int addressId, int customerId) var customer = _customerService.GetCustomerById(customerId); if (customer == null) - //No customer found with the specified id return RedirectToAction("List"); var address = _addressService.GetAddressById(addressId); if (address == null) - //No address found with the specified id return RedirectToAction("Edit", new { id = customer.Id }); var model = new CustomerAddressModel(); @@ -1466,12 +1461,10 @@ public ActionResult AddressEdit(CustomerAddressModel model) var customer = _customerService.GetCustomerById(model.CustomerId); if (customer == null) - //No customer found with the specified id return RedirectToAction("List"); var address = _addressService.GetAddressById(model.Address.Id); if (address == null) - //No address found with the specified id return RedirectToAction("Edit", new { id = customer.Id }); if (ModelState.IsValid) From fb2d4cc63f926092ee641a7fb6fd4142656b38cd Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Fri, 3 Jun 2016 15:27:07 +0200 Subject: [PATCH 09/73] DRY Fix: Merged GetOverrideKeys & UpdateSettings with their corresponding methods for updating localized settings --- .../Settings/StoreDependingSettingHelper.cs | 136 ++++++------------ 1 file changed, 44 insertions(+), 92 deletions(-) diff --git a/src/Presentation/SmartStore.Web.Framework/Settings/StoreDependingSettingHelper.cs b/src/Presentation/SmartStore.Web.Framework/Settings/StoreDependingSettingHelper.cs index 0c73aa1f3a..80a2d035e8 100644 --- a/src/Presentation/SmartStore.Web.Framework/Settings/StoreDependingSettingHelper.cs +++ b/src/Presentation/SmartStore.Web.Framework/Settings/StoreDependingSettingHelper.cs @@ -19,6 +19,7 @@ public StoreDependingSettingHelper(ViewDataDictionary viewData) } public static string ViewDataKey { get { return "StoreDependingSettingData"; } } + public StoreDependingSettingData Data { get @@ -38,16 +39,19 @@ private bool IsOverrideChecked(string settingKey, FormCollection form) } return false; } + public bool IsOverrideChecked(object settings, string name, FormCollection form) { var key = settings.GetType().Name + "." + name; return IsOverrideChecked(key, form); } + public void AddOverrideKey(object settings, string name) { var key = settings.GetType().Name + "." + name; Data.OverrideSettingKeys.Add(key); } + public void CreateViewDataObject(int activeStoreScopeConfiguration, string rootSettingClass = null) { _viewData[ViewDataKey] = new StoreDependingSettingData() @@ -57,112 +61,60 @@ public void CreateViewDataObject(int activeStoreScopeConfiguration, string rootS }; } - public void GetOverrideKeys(object settings, object model, int storeId, ISettingService settingService, bool isRootModel = true) - { - if (storeId <= 0) - return; // single store mode -> there are no overrides + public void GetOverrideKeys(object settings, object model, int storeId, ISettingService settingService, bool isRootModel = true, ILocalizedModelLocal localized = null, int? index = null) + { + if (storeId <= 0) + return; // single store mode -> there are no overrides - var data = Data; - if (data == null) - data = new StoreDependingSettingData(); + var data = Data; + if (data == null) + data = new StoreDependingSettingData(); - var settingName = settings.GetType().Name; - var properties = settings.GetType().GetProperties(); + var settingName = settings.GetType().Name; + var properties = settings.GetType().GetProperties(); + var localizedEntityService = EngineContext.Current.Resolve(); var modelType = model.GetType(); - foreach (var prop in properties) - { - var name = prop.Name; - var modelProperty = modelType.GetProperty(name); - - if (modelProperty == null) - continue; // setting is not configurable or missing or whatever... however we don't need the override info - - var key = settingName + "." + name; - var setting = settingService.GetSettingByKey(key, storeId: storeId); - - if (setting != null) - data.OverrideSettingKeys.Add(key); - } - - if (isRootModel) - { - data.ActiveStoreScopeConfiguration = storeId; - data.RootSettingClass = settingName; - - _viewData[ViewDataKey] = data; - } - } - - // DRY? - public void GetOverrideKeysLocalized(object settings, object model, int storeId, ISettingService settingService, bool isRootModel = true, ILocalizedModelLocal localized = null, int? index = null) - { - if (storeId <= 0) - return; // single store mode -> there are no overrides - - var data = Data; - if (data == null) - data = new StoreDependingSettingData(); - - var settingName = settings.GetType().Name; - var properties = localized.GetType().GetProperties(); - var localizedEntityService = EngineContext.Current.Resolve(); - - var modelType = model.GetType(); - - foreach (var prop in properties) - { - var name = prop.Name; + foreach (var prop in properties) + { + var name = prop.Name; var modelProperty = modelType.GetProperty(name); - if (modelProperty == null) - continue; // setting is not configurable or missing or whatever... however we don't need the override info - - var key = "Locales[" + index.ToString() + "]." + name; + if (modelProperty == null) + continue; // setting is not configurable or missing or whatever... however we don't need the override info - var resultStr = localizedEntityService.GetLocalizedValue(localized.LanguageId, 0, settingName, name); + var key = String.Empty; + var setting = String.Empty; - if (!String.IsNullOrEmpty(resultStr)) - data.OverrideSettingKeys.Add(key); - } + if (localized == null) + { + key = settingName + "." + name; + setting = settingService.GetSettingByKey(key, storeId: storeId); + } + else + { + key = "Locales[" + index.ToString() + "]." + name; + setting = localizedEntityService.GetLocalizedValue(localized.LanguageId, 0, settingName, name); + } - if (isRootModel) - { - data.ActiveStoreScopeConfiguration = storeId; - data.RootSettingClass = settingName; + if (!String.IsNullOrEmpty(setting)) + data.OverrideSettingKeys.Add(key); + } - _viewData[ViewDataKey] = data; - } - } + if (isRootModel) + { + data.ActiveStoreScopeConfiguration = storeId; + data.RootSettingClass = settingName; - public void UpdateSettings(object settings, FormCollection form, int storeId, ISettingService settingService) - { - var settingName = settings.GetType().Name; - var properties = FastProperty.GetProperties(settings.GetType()).Values; - - foreach (var prop in properties) - { - var name = prop.Name; - var key = settingName + "." + name; - - if (storeId == 0 || IsOverrideChecked(key, form)) - { - dynamic value = prop.GetValue(settings); - settingService.SetSetting(key, value == null ? "" : value, storeId, false); - } - else if (storeId > 0) - { - settingService.DeleteSetting(key, storeId); - } - } - } + _viewData[ViewDataKey] = data; + } + } - // DRY? - public void UpdateLocalizedSettings(object settings, FormCollection form, int storeId, ISettingService settingService, ILocalizedModelLocal localized) + public void UpdateSettings(object settings, FormCollection form, int storeId, ISettingService settingService, ILocalizedModelLocal localized = null) { var settingName = settings.GetType().Name; - var properties = FastProperty.GetProperties(localized.GetType()).Values; + var properties = FastProperty.GetProperties(localized == null ? settings.GetType() : localized.GetType()).Values; foreach (var prop in properties) { @@ -171,7 +123,7 @@ public void UpdateLocalizedSettings(object settings, FormCollection form, int st if (storeId == 0 || IsOverrideChecked(key, form)) { - dynamic value = prop.GetValue(settings); + dynamic value = prop.GetValue(localized == null ? settings : localized); settingService.SetSetting(key, value == null ? "" : value, storeId, false); } else if (storeId > 0) From c86f744de409ce8034921b7e69be05c136272a3e Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 6 Jun 2016 12:33:58 +0200 Subject: [PATCH 10/73] Minor improvements --- .../DataExchange/Export/DataExporter.cs | 9 +++++++-- .../DataExchange/Export/DynamicEntityHelper.cs | 17 +++++++++++++---- .../DataExchange/Export/ExportXmlHelper.cs | 1 + .../Export/Internal/DataExporterContext.cs | 6 ++++-- .../Views/Category/_CreateOrUpdate.cshtml | 4 +++- .../Product/_CreateOrUpdate.Discounts.cshtml | 6 ++++-- 6 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs index 4b818df859..b910cf23df 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs @@ -61,7 +61,8 @@ public partial class DataExporter : IDataExporter private readonly Lazy _productAttributeParser; private readonly Lazy _productAttributeService; private readonly Lazy _productTemplateService; - private readonly Lazy _productService; + private readonly Lazy _categoryTemplateService; + private readonly Lazy _productService; private readonly Lazy _orderService; private readonly Lazy _manufacturerService; private readonly ICustomerService _customerService; @@ -101,6 +102,7 @@ public DataExporter( Lazy productAttributeParser, Lazy productAttributeService, Lazy productTemplateService, + Lazy categoryTemplateService, Lazy productService, Lazy orderService, Lazy manufacturerService, @@ -138,6 +140,7 @@ public DataExporter( _productAttributeParser = productAttributeParser; _productAttributeService = productAttributeService; _productTemplateService = productTemplateService; + _categoryTemplateService = categoryTemplateService; _productService = productService; _orderService = orderService; _manufacturerService = manufacturerService; @@ -1199,7 +1202,8 @@ private void ExportCoreOuter(DataExporterContext ctx) { ctx.DeliveryTimes = _deliveryTimeService.Value.GetAllDeliveryTimes().ToDictionary(x => x.Id); ctx.QuantityUnits = _quantityUnitService.Value.GetAllQuantityUnits().ToDictionary(x => x.Id); - ctx.ProductTemplates = _productTemplateService.Value.GetAllProductTemplates().ToDictionary(x => x.Id); + ctx.ProductTemplates = _productTemplateService.Value.GetAllProductTemplates().ToDictionary(x => x.Id, x => x.ViewPath); + ctx.CategoryTemplates = _categoryTemplateService.Value.GetAllCategoryTemplates().ToDictionary(x => x.Id, x => x.ViewPath); if (ctx.Request.Provider.Value.EntityType == ExportEntityType.Product) { @@ -1293,6 +1297,7 @@ private void ExportCoreOuter(DataExporterContext ctx) { ctx.NewsletterSubscriptions.Clear(); ctx.ProductTemplates.Clear(); + ctx.CategoryTemplates.Clear(); ctx.Countries.Clear(); ctx.Languages.Clear(); ctx.QuantityUnits.Clear(); diff --git a/src/Libraries/SmartStore.Services/DataExchange/Export/DynamicEntityHelper.cs b/src/Libraries/SmartStore.Services/DataExchange/Export/DynamicEntityHelper.cs index e6e4f39a81..f9e4bd158a 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Export/DynamicEntityHelper.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Export/DynamicEntityHelper.cs @@ -487,6 +487,11 @@ private dynamic ToDynamic(DataExporterContext ctx, Category category) result.Picture = null; + if (ctx.CategoryTemplates.ContainsKey(category.CategoryTemplateId)) + result._CategoryTemplateViewPath = ctx.CategoryTemplates[category.CategoryTemplateId]; + else + result._CategoryTemplateViewPath = ""; + result._Localized = GetLocalized(ctx, category, x => x.Name, x => x.FullName, @@ -547,7 +552,6 @@ private dynamic ToDynamic( product.MergeWithCombination(combination); var languageId = (ctx.Projection.LanguageId ?? 0); - var productTemplate = ctx.ProductTemplates.FirstOrDefault(x => x.Key == product.ProductTemplateId); var pictureSize = _mediaSettings.Value.ProductDetailsPictureSize; var numberOfPictures = (ctx.Projection.NumberOfPictures ?? int.MaxValue); int[] pictureIds = (combination == null ? new int[0] : combination.GetAssignedPictureIds()); @@ -586,7 +590,10 @@ private dynamic ToDynamic( dynObject._BasePriceInfo = product.GetBasePriceInfo(_services.Localization, _priceFormatter.Value, _currencyService.Value, _taxService.Value, _priceCalculationService.Value, ctx.ContextCurrency, decimal.Zero, true); - dynObject._ProductTemplateViewPath = (productTemplate.Value == null ? "" : productTemplate.Value.ViewPath); + if (ctx.ProductTemplates.ContainsKey(product.ProductTemplateId)) + dynObject._ProductTemplateViewPath = ctx.ProductTemplates[product.ProductTemplateId]; + else + dynObject._ProductTemplateViewPath = ""; var detailUrl = ctx.Store.Url.EnsureEndsWith("/") + (string)dynObject.SeName; @@ -1081,9 +1088,11 @@ private List Convert(DataExporterContext ctx, Order order) .Select(e => { dynamic dyn = ToDynamic(ctx, e); - var productTemplate = ctx.ProductTemplates.FirstOrDefault(x => x.Key == e.Product.ProductTemplateId); - dyn.Product._ProductTemplateViewPath = (productTemplate.Value == null ? "" : productTemplate.Value.ViewPath); + if (ctx.ProductTemplates.ContainsKey(e.Product.ProductTemplateId)) + dyn.Product._ProductTemplateViewPath = ctx.ProductTemplates[e.Product.ProductTemplateId]; + else + dyn.Product._ProductTemplateViewPath = ""; dyn.Product._BasePriceInfo = e.Product.GetBasePriceInfo(_services.Localization, _priceFormatter.Value, _currencyService.Value, _taxService.Value, _priceCalculationService.Value, ctx.ContextCurrency, decimal.Zero, true); diff --git a/src/Libraries/SmartStore.Services/DataExchange/Export/ExportXmlHelper.cs b/src/Libraries/SmartStore.Services/DataExchange/Export/ExportXmlHelper.cs index 6f84b5f064..605a5dafd3 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Export/ExportXmlHelper.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Export/ExportXmlHelper.cs @@ -335,6 +335,7 @@ public void WriteCategory(dynamic category, string node) _writer.Write("Description", (string)category.Description); _writer.Write("BottomDescription", (string)category.BottomDescription); _writer.Write("CategoryTemplateId", entity.CategoryTemplateId.ToString()); + _writer.Write("CategoryTemplateViewPath", (string)category._CategoryTemplateViewPath); _writer.Write("MetaKeywords", (string)category.MetaKeywords); _writer.Write("MetaDescription", (string)category.MetaDescription); _writer.Write("MetaTitle", (string)category.MetaTitle); diff --git a/src/Libraries/SmartStore.Services/DataExchange/Export/Internal/DataExporterContext.cs b/src/Libraries/SmartStore.Services/DataExchange/Export/Internal/DataExporterContext.cs index f909b93678..5c6c1315dd 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Export/Internal/DataExporterContext.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Export/Internal/DataExporterContext.cs @@ -34,7 +34,8 @@ public DataExporterContext( Stores = new Dictionary(); Languages = new Dictionary(); Countries = new Dictionary(); - ProductTemplates = new Dictionary(); + ProductTemplates = new Dictionary(); + CategoryTemplates = new Dictionary(); NewsletterSubscriptions = new HashSet(); RecordsPerStore = new Dictionary(); @@ -109,7 +110,8 @@ public bool IsFileBasedExport public Dictionary Stores { get; set; } public Dictionary Languages { get; set; } public Dictionary Countries { get; set; } - public Dictionary ProductTemplates { get; set; } + public Dictionary ProductTemplates { get; set; } + public Dictionary CategoryTemplates { get; set; } public HashSet NewsletterSubscriptions { get; set; } // data loaded once per page diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Category/_CreateOrUpdate.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Category/_CreateOrUpdate.cshtml index 507546d242..f78aa0983e 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Category/_CreateOrUpdate.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Category/_CreateOrUpdate.cshtml @@ -456,7 +456,9 @@ } else { - @T("Admin.Catalog.Categories.Discounts.NoDiscounts") +
+ @T("Admin.Catalog.Categories.Discounts.NoDiscounts") +
} } diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Product/_CreateOrUpdate.Discounts.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Product/_CreateOrUpdate.Discounts.cshtml index 23e3aa1efb..694263f00a 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Product/_CreateOrUpdate.Discounts.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Product/_CreateOrUpdate.Discounts.cshtml @@ -6,13 +6,15 @@ { } } else { - @T("Admin.Catalog.Products.Discounts.NoDiscounts") +
+ @T("Admin.Catalog.Products.Discounts.NoDiscounts") +
} From fa2388e55be5a601b238ec90b3d766ecc83ceb59 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 6 Jun 2016 14:22:13 +0200 Subject: [PATCH 11/73] Flag to exclude data from XML export --- .../DataExchange/Export/ExportXmlHelper.cs | 75 ++++++++++++------- 1 file changed, 46 insertions(+), 29 deletions(-) diff --git a/src/Libraries/SmartStore.Services/DataExchange/Export/ExportXmlHelper.cs b/src/Libraries/SmartStore.Services/DataExchange/Export/ExportXmlHelper.cs index 605a5dafd3..68c8b78d55 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Export/ExportXmlHelper.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Export/ExportXmlHelper.cs @@ -49,6 +49,8 @@ public static XmlWriterSettings DefaultSettings } } + public ExportXmlExclude Exclude { get; set; } + public XmlWriter Writer { get { return _writer; } @@ -330,37 +332,41 @@ public void WriteCategory(dynamic category, string node) } _writer.Write("Id", entity.Id.ToString()); - _writer.Write("Name", (string)category.Name); - _writer.Write("FullName", (string)category.FullName); - _writer.Write("Description", (string)category.Description); - _writer.Write("BottomDescription", (string)category.BottomDescription); - _writer.Write("CategoryTemplateId", entity.CategoryTemplateId.ToString()); - _writer.Write("CategoryTemplateViewPath", (string)category._CategoryTemplateViewPath); - _writer.Write("MetaKeywords", (string)category.MetaKeywords); - _writer.Write("MetaDescription", (string)category.MetaDescription); - _writer.Write("MetaTitle", (string)category.MetaTitle); - _writer.Write("SeName", (string)category.SeName); - _writer.Write("ParentCategoryId", entity.ParentCategoryId.ToString()); - _writer.Write("PictureId", entity.PictureId.HasValue ? entity.PictureId.Value.ToString() : ""); - _writer.Write("PageSize", entity.PageSize.ToString()); - _writer.Write("AllowCustomersToSelectPageSize", entity.AllowCustomersToSelectPageSize.ToString()); - _writer.Write("PageSizeOptions", entity.PageSizeOptions); - _writer.Write("PriceRanges", entity.PriceRanges); - _writer.Write("ShowOnHomePage", entity.ShowOnHomePage.ToString()); - _writer.Write("HasDiscountsApplied", entity.HasDiscountsApplied.ToString()); - _writer.Write("Published", entity.Published.ToString()); - _writer.Write("Deleted", entity.Deleted.ToString()); - _writer.Write("DisplayOrder", entity.DisplayOrder.ToString()); - _writer.Write("CreatedOnUtc", entity.CreatedOnUtc.ToString(_culture)); - _writer.Write("UpdatedOnUtc", entity.UpdatedOnUtc.ToString(_culture)); - _writer.Write("SubjectToAcl", entity.SubjectToAcl.ToString()); - _writer.Write("LimitedToStores", entity.LimitedToStores.ToString()); - _writer.Write("Alias", (string)category.Alias); - _writer.Write("DefaultViewMode", entity.DefaultViewMode); - WritePicture(category.Picture, "Picture"); + if (!Exclude.HasFlag(ExportXmlExclude.Category)) + { + _writer.Write("Name", (string)category.Name); + _writer.Write("FullName", (string)category.FullName); + _writer.Write("Description", (string)category.Description); + _writer.Write("BottomDescription", (string)category.BottomDescription); + _writer.Write("CategoryTemplateId", entity.CategoryTemplateId.ToString()); + _writer.Write("CategoryTemplateViewPath", (string)category._CategoryTemplateViewPath); + _writer.Write("MetaKeywords", (string)category.MetaKeywords); + _writer.Write("MetaDescription", (string)category.MetaDescription); + _writer.Write("MetaTitle", (string)category.MetaTitle); + _writer.Write("SeName", (string)category.SeName); + _writer.Write("ParentCategoryId", entity.ParentCategoryId.ToString()); + _writer.Write("PictureId", entity.PictureId.HasValue ? entity.PictureId.Value.ToString() : ""); + _writer.Write("PageSize", entity.PageSize.ToString()); + _writer.Write("AllowCustomersToSelectPageSize", entity.AllowCustomersToSelectPageSize.ToString()); + _writer.Write("PageSizeOptions", entity.PageSizeOptions); + _writer.Write("PriceRanges", entity.PriceRanges); + _writer.Write("ShowOnHomePage", entity.ShowOnHomePage.ToString()); + _writer.Write("HasDiscountsApplied", entity.HasDiscountsApplied.ToString()); + _writer.Write("Published", entity.Published.ToString()); + _writer.Write("Deleted", entity.Deleted.ToString()); + _writer.Write("DisplayOrder", entity.DisplayOrder.ToString()); + _writer.Write("CreatedOnUtc", entity.CreatedOnUtc.ToString(_culture)); + _writer.Write("UpdatedOnUtc", entity.UpdatedOnUtc.ToString(_culture)); + _writer.Write("SubjectToAcl", entity.SubjectToAcl.ToString()); + _writer.Write("LimitedToStores", entity.LimitedToStores.ToString()); + _writer.Write("Alias", (string)category.Alias); + _writer.Write("DefaultViewMode", entity.DefaultViewMode); - WriteLocalized(category); + WritePicture(category.Picture, "Picture"); + + WriteLocalized(category); + } if (node.HasValue()) { @@ -898,4 +904,15 @@ public void WriteCustomer(dynamic customer, string node) } } } + + + /// + /// Allows to exclude XML nodes from export + /// + [Flags] + public enum ExportXmlExclude + { + None = 0, + Category = 1 + } } From 9952273f3813dd184ae455f4bc3097e3d55a501a Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Tue, 7 Jun 2016 12:21:50 +0200 Subject: [PATCH 12/73] Confirm order: Do not display empty cart or empty order summary together with buy button. Do not display duplicate warnings. --- .../Controllers/CheckoutController.cs | 93 +++++++++++-------- 1 file changed, 55 insertions(+), 38 deletions(-) diff --git a/src/Presentation/SmartStore.Web/Controllers/CheckoutController.cs b/src/Presentation/SmartStore.Web/Controllers/CheckoutController.cs index 7856167fb5..5047764d52 100644 --- a/src/Presentation/SmartStore.Web/Controllers/CheckoutController.cs +++ b/src/Presentation/SmartStore.Web/Controllers/CheckoutController.cs @@ -796,18 +796,22 @@ public ActionResult Confirm() [ValidateInput(false)] public ActionResult ConfirmOrder(FormCollection form) { - //validation - var cart = _workContext.CurrentCustomer.GetCartItems(ShoppingCartType.ShoppingCart, _storeContext.CurrentStore.Id); + //validation + var storeId = _storeContext.CurrentStore.Id; + var customer = _workContext.CurrentCustomer; + var cart = customer.GetCartItems(ShoppingCartType.ShoppingCart, storeId); if (cart.Count == 0) return RedirectToRoute("ShoppingCart"); - if ((_workContext.CurrentCustomer.IsGuest() && !_orderSettings.AnonymousCheckoutAllowed)) + if ((customer.IsGuest() && !_orderSettings.AnonymousCheckoutAllowed)) return new HttpUnauthorizedResult(); - //model var model = new CheckoutConfirmModel(); - try + PlaceOrderResult placeOrderResult = null; + PostProcessPaymentRequest postProcessPaymentRequest = null; + + try { var processPaymentRequest = _httpContext.Session["OrderPaymentInfo"] as ProcessPaymentRequest; if (processPaymentRequest == null) @@ -820,55 +824,68 @@ public ActionResult ConfirmOrder(FormCollection form) } //prevent 2 orders being placed within an X seconds time frame - if (!IsMinimumOrderPlacementIntervalValid(_workContext.CurrentCustomer)) - throw new Exception(_localizationService.GetResource("Checkout.MinOrderPlacementInterval")); + if (!IsMinimumOrderPlacementIntervalValid(customer)) + throw new Exception(T("Checkout.MinOrderPlacementInterval")); //place order - processPaymentRequest.StoreId = _storeContext.CurrentStore.Id; - processPaymentRequest.CustomerId = _workContext.CurrentCustomer.Id; - processPaymentRequest.PaymentMethodSystemName = _workContext.CurrentCustomer.GetAttribute( - SystemCustomerAttributeNames.SelectedPaymentMethod, _genericAttributeService, _storeContext.CurrentStore.Id); + processPaymentRequest.StoreId = storeId; + processPaymentRequest.CustomerId = customer.Id; + processPaymentRequest.PaymentMethodSystemName = customer.GetAttribute(SystemCustomerAttributeNames.SelectedPaymentMethod, _genericAttributeService, storeId); var placeOrderExtraData = new Dictionary(); placeOrderExtraData["CustomerComment"] = form["customercommenthidden"]; placeOrderExtraData["SubscribeToNewsLetter"] = form["SubscribeToNewsLetterHidden"]; placeOrderExtraData["AcceptThirdPartyEmailHandOver"] = form["AcceptThirdPartyEmailHandOverHidden"]; - var placeOrderResult = _orderProcessingService.PlaceOrder(processPaymentRequest, placeOrderExtraData); - - if (placeOrderResult.Success) - { - var postProcessPaymentRequest = new PostProcessPaymentRequest - { - Order = placeOrderResult.PlacedOrder - }; - - _paymentService.PostProcessPayment(postProcessPaymentRequest); - - _httpContext.Session["PaymentData"] = null; - _httpContext.Session["OrderPaymentInfo"] = null; - _httpContext.RemoveCheckoutState(); - - if (postProcessPaymentRequest.RedirectUrl.HasValue()) - { - return Redirect(postProcessPaymentRequest.RedirectUrl); - } + placeOrderResult = _orderProcessingService.PlaceOrder(processPaymentRequest, placeOrderExtraData); - return RedirectToAction("Completed"); - } - else + if (!placeOrderResult.Success) { model.Warnings.AddRange(placeOrderResult.Errors.Select(x => HtmlUtils.ConvertPlainTextToHtml(x))); } } - catch (Exception exc) + catch (Exception exception) { - Logger.Warning(exc.Message, exc); - model.Warnings.Add(exc.Message); + Logger.Warning(exception.Message, exception); + + if (!model.Warnings.Any(x => x == exception.Message)) + { + model.Warnings.Add(exception.Message); + } } - return View(model); - } + if (placeOrderResult == null || !placeOrderResult.Success || model.Warnings.Any()) + { + return View(model); + } + + try + { + postProcessPaymentRequest = new PostProcessPaymentRequest + { + Order = placeOrderResult.PlacedOrder + }; + + _paymentService.PostProcessPayment(postProcessPaymentRequest); + } + catch (Exception exception) + { + NotifyError(exception); + } + finally + { + _httpContext.Session["PaymentData"] = null; + _httpContext.Session["OrderPaymentInfo"] = null; + _httpContext.RemoveCheckoutState(); + } + + if (postProcessPaymentRequest != null && postProcessPaymentRequest.RedirectUrl.HasValue()) + { + return Redirect(postProcessPaymentRequest.RedirectUrl); + } + + return RedirectToAction("Completed"); + } public ActionResult Completed() From 21d76ad0f4250bf7cd7e56839d6365a9c2dc8d20 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Tue, 7 Jun 2016 13:22:33 +0200 Subject: [PATCH 13/73] Re-post payment should friendly output exceptions --- .../Controllers/OrderController.cs | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/Presentation/SmartStore.Web/Controllers/OrderController.cs b/src/Presentation/SmartStore.Web/Controllers/OrderController.cs index bf9e11078e..448a1983d3 100644 --- a/src/Presentation/SmartStore.Web/Controllers/OrderController.cs +++ b/src/Presentation/SmartStore.Web/Controllers/OrderController.cs @@ -680,21 +680,29 @@ public ActionResult RePostPayment(int id) if (IsUnauthorizedOrder(order)) return new HttpUnauthorizedResult(); - if (_paymentService.CanRePostProcessPayment(order)) + try { - var postProcessPaymentRequest = new PostProcessPaymentRequest + if (_paymentService.CanRePostProcessPayment(order)) { - Order = order, - IsRePostProcessPayment = true - }; + var postProcessPaymentRequest = new PostProcessPaymentRequest + { + Order = order, + IsRePostProcessPayment = true + }; - _paymentService.PostProcessPayment(postProcessPaymentRequest); + _paymentService.PostProcessPayment(postProcessPaymentRequest); - if (postProcessPaymentRequest.RedirectUrl.HasValue()) - { - return Redirect(postProcessPaymentRequest.RedirectUrl); + if (postProcessPaymentRequest.RedirectUrl.HasValue()) + { + return Redirect(postProcessPaymentRequest.RedirectUrl); + } } } + catch (Exception exception) + { + NotifyError(exception); + } + return RedirectToAction("Details", "Order", new { id = order.Id }); } From 9b6b5b3dba4961d17ca2dd1ff30acd2cbe4a1c26 Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Tue, 7 Jun 2016 14:32:48 +0200 Subject: [PATCH 14/73] Obsolete because of client-side validation --- src/Presentation/SmartStore.Web/Views/Customer/Info.cshtml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Presentation/SmartStore.Web/Views/Customer/Info.cshtml b/src/Presentation/SmartStore.Web/Views/Customer/Info.cshtml index 22eca6cfcf..fbf29a96b4 100644 --- a/src/Presentation/SmartStore.Web/Views/Customer/Info.cshtml +++ b/src/Presentation/SmartStore.Web/Views/Customer/Info.cshtml @@ -52,11 +52,6 @@ { @Html.AntiForgeryToken() - if (!ViewData.ModelState.IsValid) - { - @Html.ValidationSummary(true) - } -
@T("Account.YourPersonalDetails") From e1e35e7f396560a9630b2bd24cd9ff0ecc6f7723 Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Wed, 8 Jun 2016 13:41:19 +0200 Subject: [PATCH 15/73] SEO fix: Google doesn't like review pages without reviews --- src/Presentation/SmartStore.Web/Views/Product/Reviews.cshtml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Presentation/SmartStore.Web/Views/Product/Reviews.cshtml b/src/Presentation/SmartStore.Web/Views/Product/Reviews.cshtml index 0d8f9ba9a8..c0fa631da9 100644 --- a/src/Presentation/SmartStore.Web/Views/Product/Reviews.cshtml +++ b/src/Presentation/SmartStore.Web/Views/Product/Reviews.cshtml @@ -6,6 +6,11 @@ //title Html.AddTitleParts(Model.ProductName); Html.AddTitleParts(T("PageTitle.ProductReviews").Text); + + if (Model.Items.Count == 0) + { + Html.AddCustomHeadParts(""); + } }

@T("Reviews.ProductReviewsFor")

From 16cc815d629d43c5b86649e083aae4ea96e579be Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Thu, 9 Jun 2016 12:10:17 +0200 Subject: [PATCH 16/73] Addendum to the last commit --- src/Presentation/SmartStore.Web/Views/Product/Reviews.cshtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Presentation/SmartStore.Web/Views/Product/Reviews.cshtml b/src/Presentation/SmartStore.Web/Views/Product/Reviews.cshtml index c0fa631da9..f819e40646 100644 --- a/src/Presentation/SmartStore.Web/Views/Product/Reviews.cshtml +++ b/src/Presentation/SmartStore.Web/Views/Product/Reviews.cshtml @@ -9,7 +9,7 @@ if (Model.Items.Count == 0) { - Html.AddCustomHeadParts(""); + Html.AddCustomHeadParts(""); } }
From 414ecfcc075c7147aff02d584c94ce1f750c0fbb Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Thu, 9 Jun 2016 12:50:53 +0200 Subject: [PATCH 17/73] PayPal Plus: minor correction --- src/Libraries/SmartStore.Core/Domain/Orders/Order.cs | 2 +- src/Plugins/SmartStore.PayPal/Services/IPayPalService.cs | 2 +- src/Plugins/SmartStore.PayPal/Services/PayPalService.cs | 9 +++++---- .../Administration/Views/Order/Edit.cshtml | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Libraries/SmartStore.Core/Domain/Orders/Order.cs b/src/Libraries/SmartStore.Core/Domain/Orders/Order.cs index d59871a751..9db5f14733 100644 --- a/src/Libraries/SmartStore.Core/Domain/Orders/Order.cs +++ b/src/Libraries/SmartStore.Core/Domain/Orders/Order.cs @@ -451,7 +451,7 @@ protected virtual SortedDictionary ParseTaxRates(string taxRat public int? RewardPointsRemaining { get; set; } /// - /// Gets or sets a value indicating whether a new payment notification (IPN) arrived + /// Gets or sets a value indicating whether a new payment notification arrived (IPN, webhook, callback etc.) /// [DataMember] public bool HasNewPaymentNotification { get; set; } diff --git a/src/Plugins/SmartStore.PayPal/Services/IPayPalService.cs b/src/Plugins/SmartStore.PayPal/Services/IPayPalService.cs index cfb377fabb..6a799e16a1 100644 --- a/src/Plugins/SmartStore.PayPal/Services/IPayPalService.cs +++ b/src/Plugins/SmartStore.PayPal/Services/IPayPalService.cs @@ -12,7 +12,7 @@ namespace SmartStore.PayPal.Services { public interface IPayPalService { - void AddOrderNote(PayPalSettingsBase settings, Order order, string anyString); + void AddOrderNote(PayPalSettingsBase settings, Order order, string anyString, bool isIpn = false); void LogError(Exception exception, string shortMessage = null, string fullMessage = null, bool notify = false, IList errors = null, bool isWarning = false); diff --git a/src/Plugins/SmartStore.PayPal/Services/PayPalService.cs b/src/Plugins/SmartStore.PayPal/Services/PayPalService.cs index 0b96289c19..f5819da195 100644 --- a/src/Plugins/SmartStore.PayPal/Services/PayPalService.cs +++ b/src/Plugins/SmartStore.PayPal/Services/PayPalService.cs @@ -184,7 +184,7 @@ public static Dictionary GetSecurityProtocols() return dic; } - public void AddOrderNote(PayPalSettingsBase settings, Order order, string anyString) + public void AddOrderNote(PayPalSettingsBase settings, Order order, string anyString, bool isIpn = false) { try { @@ -201,6 +201,9 @@ public void AddOrderNote(PayPalSettingsBase settings, Order order, string anyStr sb.AppendFormat("{0}", note); + if (isIpn) + order.HasNewPaymentNotification = true; + _orderService.AddOrderNote(order, sb.ToString()); } catch { } @@ -1034,9 +1037,7 @@ public HttpStatusCode ProcessWebhook( break; } - order.HasNewPaymentNotification = true; - - AddOrderNote(settings, order, (string)ToInfoString(json)); + AddOrderNote(settings, order, (string)ToInfoString(json), true); return HttpStatusCode.OK; } diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Order/Edit.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Order/Edit.cshtml index 6749179a34..75fefead92 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Order/Edit.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Order/Edit.cshtml @@ -1775,7 +1775,7 @@ @Html.SmartLabelFor(model => model.AddOrderNoteMessage) - @Html.TextAreaFor(model => model.AddOrderNoteMessage, new { style = "Width: 350px; Height: 150px;" }) + @Html.TextAreaFor(model => model.AddOrderNoteMessage, new { @class = "control-xlarge", style = "height: 120px;" }) @Html.ValidationMessageFor(model => model.AddOrderNoteMessage) From 698a89b496b2b57fe1a022f805b1725de6c85a42 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Fri, 10 Jun 2016 14:51:58 +0200 Subject: [PATCH 18/73] Minor change --- .../Administration/Views/Export/_ProfileList.cshtml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Export/_ProfileList.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Export/_ProfileList.cshtml index ffa740bd96..7ae123c0a9 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Export/_ProfileList.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Export/_ProfileList.cshtml @@ -87,7 +87,10 @@ } else { -
@T("Admin.DataExchange.Export.NoProfiles")
+
+ + @T("Admin.DataExchange.Export.NoProfiles") +
} @if (!isSystemProfiles) From fe245b30927ebd529a50b88612e56b19a51fc913 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Sat, 11 Jun 2016 10:32:34 +0200 Subject: [PATCH 19/73] Updated changelog --- changelog.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index 826a9778de..c714683f3e 100644 --- a/changelog.md +++ b/changelog.md @@ -3,7 +3,8 @@ ## SmartStore.NET 2.5.1 ### Highlights -* #637 Integrated PayPal PLUS payment Provider +* #637 Integrated PayPal PLUS payment provider +* #932 Implement paydirekt payment plugin * Major improvements in Importer: better field mapping, higher performance, bug fixes etc. ### New Features From 2768f18454303b6fb5b211e7f413dab816290ee6 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 13 Jun 2016 10:33:35 +0200 Subject: [PATCH 20/73] Updated changelog --- changelog.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index c714683f3e..156e86078c 100644 --- a/changelog.md +++ b/changelog.md @@ -3,9 +3,10 @@ ## SmartStore.NET 2.5.1 ### Highlights +* Major improvements in Importer: better field mapping, higher performance, bug fixes etc. * #637 Integrated PayPal PLUS payment provider * #932 Implement paydirekt payment plugin -* Major improvements in Importer: better field mapping, higher performance, bug fixes etc. +* New Viveum payment plugin ### New Features * #637 Integrated PayPal PLUS payment Provider @@ -54,6 +55,7 @@ * #973 Bundle item upload is nowhere linked * Base price in product list ignored PriceDisplayType (catalog settings) and possibly displayed the wrong base price info * Private messages: Fixes "No route in the route table matches the supplied values" +* Payone: Hash string incorrect for frontend API payments where the order has more than 9 products ## SmartStore.NET 2.5 From 3e7abd62d82e1d113016f8a9d4463f1cb92b2241 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 13 Jun 2016 21:02:38 +0200 Subject: [PATCH 21/73] Export mail notification: Download link not working if SSL is enabled --- changelog.md | 1 + .../DataExchange/Export/DataExporter.cs | 9 +++------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/changelog.md b/changelog.md index 156e86078c..3a070fd2f2 100644 --- a/changelog.md +++ b/changelog.md @@ -56,6 +56,7 @@ * Base price in product list ignored PriceDisplayType (catalog settings) and possibly displayed the wrong base price info * Private messages: Fixes "No route in the route table matches the supplied values" * Payone: Hash string incorrect for frontend API payments where the order has more than 9 products +* Export mail notification: Download link not working if SSL is enabled ## SmartStore.NET 2.5 diff --git a/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs index b910cf23df..173b61b475 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs @@ -535,7 +535,7 @@ private void SendCompletionEmail(DataExporterContext ctx, string zipPath) if (emailAccount == null) emailAccount = _emailAccountService.Value.GetDefaultEmailAccount(); - var downloadUrl = "{0}Admin/Export/DownloadExportFile/{1}?name=".FormatInvariant(_services.WebHelper.GetStoreLocation(false), ctx.Request.Profile.Id); + var downloadUrl = "{0}Admin/Export/DownloadExportFile/{1}?name=".FormatInvariant(_services.WebHelper.GetStoreLocation(ctx.Store.SslEnabled), ctx.Request.Profile.Id); var languageId = ctx.Projection.LanguageId ?? 0; var smtpContext = new SmtpContext(emailAccount); @@ -553,7 +553,7 @@ private void SendCompletionEmail(DataExporterContext ctx, string zipPath) if (ctx.IsFileBasedExport && File.Exists(zipPath)) { var fileName = Path.GetFileName(zipPath); - body.AppendFormat("

{1}

", downloadUrl + HttpUtility.UrlDecode(fileName), fileName); + body.AppendFormat("

{2}

", downloadUrl, HttpUtility.UrlEncode(fileName), fileName); } if (ctx.IsFileBasedExport && ctx.Result.Files.Any()) @@ -561,7 +561,7 @@ private void SendCompletionEmail(DataExporterContext ctx, string zipPath) body.Append("

"); foreach (var file in ctx.Result.Files) { - body.AppendFormat("

", downloadUrl + HttpUtility.UrlDecode(file.FileName), file.FileName); + body.AppendFormat("", downloadUrl, HttpUtility.UrlEncode(file.FileName), file.FileName); } body.Append("

"); } @@ -571,9 +571,6 @@ private void SendCompletionEmail(DataExporterContext ctx, string zipPath) if (ctx.Request.Profile.CompletedEmailAddresses.HasValue()) message.To.AddRange(ctx.Request.Profile.CompletedEmailAddresses.SplitSafe(",").Where(x => x.IsEmail()).Select(x => new EmailAddress(x))); - if (message.To.Count == 0 && _contactDataSettings.Value.WebmasterEmailAddress.HasValue()) - message.To.Add(new EmailAddress(_contactDataSettings.Value.WebmasterEmailAddress)); - if (message.To.Count == 0 && _contactDataSettings.Value.CompanyEmailAddress.HasValue()) message.To.Add(new EmailAddress(_contactDataSettings.Value.CompanyEmailAddress)); From 7a06b158770eb869523faeca93289493d9037802 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Wed, 15 Jun 2016 12:01:18 +0200 Subject: [PATCH 22/73] Export: _IsChild indicates that current row is a child row (e.g. an attribute combination exported as a product) --- .../DataExchange/Export/DynamicEntityHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Libraries/SmartStore.Services/DataExchange/Export/DynamicEntityHelper.cs b/src/Libraries/SmartStore.Services/DataExchange/Export/DynamicEntityHelper.cs index f9e4bd158a..96362b5999 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Export/DynamicEntityHelper.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Export/DynamicEntityHelper.cs @@ -606,8 +606,8 @@ private dynamic ToDynamic( } } + dynObject._IsChild = (combination != null); dynObject._DetailUrl = detailUrl; - dynObject._CategoryName = null; if (ctx.Categories.Count > 0) From 373c19dbac856baaed66f23951975297167d30fb Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Thu, 16 Jun 2016 10:50:56 +0200 Subject: [PATCH 23/73] Product details: Select attribute and gift card values by query string parameters --- changelog.md | 1 + .../Controllers/CatalogHelper.cs | 86 +++++++++++++++++++ .../Controllers/ProductController.cs | 2 + 3 files changed, 89 insertions(+) diff --git a/changelog.md b/changelog.md index 3a070fd2f2..4206394556 100644 --- a/changelog.md +++ b/changelog.md @@ -17,6 +17,7 @@ * Import localized SEO names for product and categories * #477 Implement option to specify the number of exported and imported pictures * #859 Make checkout attributes suitable for multi-stores +* Product details: Select attribute and gift card values by query string parameters ### Improvements * Major improvements in Importer: better field mapping, higher performance, bug fixes etc. diff --git a/src/Presentation/SmartStore.Web/Controllers/CatalogHelper.cs b/src/Presentation/SmartStore.Web/Controllers/CatalogHelper.cs index 55793edc65..8e2a4f8ca7 100644 --- a/src/Presentation/SmartStore.Web/Controllers/CatalogHelper.cs +++ b/src/Presentation/SmartStore.Web/Controllers/CatalogHelper.cs @@ -285,6 +285,92 @@ public ProductDetailsModel PrepareProductDetailsPageModel( return model; } + public void SelectProductAttributeValues(ProductDetailsModel model, NameValueCollection queryData) + { + Guard.ArgumentNotNull(() => model); + + if (queryData == null || queryData.Count <= 0) + return; + + try + { + var items = queryData.AllKeys + .Where(x => x.EmptyNull().StartsWith("product_attribute_")) + .SelectMany(queryData.GetValues, (k, v) => new { key = k, value = v }); + + foreach (var item in items) + { + var ids = item.key.Replace("product_attribute_", "").SplitSafe("_"); + if (ids.Count() > 3) + { + var productId = ids[0].ToInt(); + var bundleItemId = ids[1].ToInt(); + var productAttributeId = ids[2].ToInt(); + //var attributeId = ids[3].ToInt(); + + var attribute = model.ProductVariantAttributes.FirstOrDefault(x => + x.ProductId == productId && + x.BundleItemId == bundleItemId && + x.ProductAttributeId == productAttributeId); + + if (attribute != null) + { + switch (attribute.AttributeControlType) + { + case AttributeControlType.DropdownList: + case AttributeControlType.RadioList: + case AttributeControlType.Checkboxes: + case AttributeControlType.ColorSquares: + var attributeValue = attribute.Values.FirstOrDefault(x => x.Name.IsCaseInsensitiveEqual(item.value)); + if (attributeValue != null) + { + attribute.Values.Each(x => x.IsPreSelected = false); + attributeValue.IsPreSelected = true; + } + break; + case AttributeControlType.TextBox: + case AttributeControlType.MultilineTextbox: + attribute.TextValue = item.value; + break; + case AttributeControlType.Datepicker: + if (item.value.Length == 8) + { + attribute.SelectedYear = item.value.Substring(0, 4).ToInt(); + attribute.SelectedMonth = item.value.Substring(4, 2).ToInt(); + attribute.SelectedDay = item.value.Substring(6, 2).ToInt(); + } + break; + } + } + } + } + + items = queryData.AllKeys + .Where(x => x.EmptyNull().StartsWith("giftcard_")) + .SelectMany(queryData.GetValues, (k, v) => new { key = k, value = v }); + + foreach (var item in items) + { + var key = item.key.EmptyNull().ToLower(); + + if (key.EndsWith("recipientname")) + model.GiftCard.RecipientName = item.value; + else if (key.EndsWith("recipientemail")) + model.GiftCard.RecipientEmail = item.value; + else if (key.EndsWith("sendername")) + model.GiftCard.SenderName = item.value; + else if (key.EndsWith("senderemail")) + model.GiftCard.SenderEmail = item.value; + else if (key.EndsWith("message")) + model.GiftCard.Message = item.value; + } + } + catch (Exception exception) + { + Logger.Warning(exception.ToAllMessages(), exception); + } + } + public void PrepareProductReviewsModel(ProductReviewsModel model, Product product) { if (product == null) diff --git a/src/Presentation/SmartStore.Web/Controllers/ProductController.cs b/src/Presentation/SmartStore.Web/Controllers/ProductController.cs index 60bd17bca2..fa13176e2a 100644 --- a/src/Presentation/SmartStore.Web/Controllers/ProductController.cs +++ b/src/Presentation/SmartStore.Web/Controllers/ProductController.cs @@ -177,6 +177,8 @@ public ActionResult ProductDetails(int productId, string attributes) var model = _helper.PrepareProductDetailsPageModel(product, selectedAttributes: selectedAttributes); + _helper.SelectProductAttributeValues(model, Request.QueryString); + //save as recently viewed _recentlyViewedProductsService.AddProductToRecentlyViewedList(product.Id); From 9b922b529533573f03536dca5b91c0d84ac8150c Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Thu, 16 Jun 2016 15:12:34 +0200 Subject: [PATCH 24/73] Display friendly error message if the rendering of an export provider configuration failed --- .../Administration/Views/Export/Edit.cshtml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Export/Edit.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Export/Edit.cshtml index e3cd585606..f47ae86481 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Export/Edit.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Export/Edit.cshtml @@ -296,7 +296,18 @@ viewData.TemplateInfo.HtmlFieldPrefix = "CustomProperties[ProviderConfigData]"; viewData.ModelState.Merge(ViewData.ModelState); @Html.Hidden("CustomProperties[ProviderConfigData].__Type__", Model.Provider.ConfigDataType.AssemblyQualifiedName) - @Html.Partial(Model.Provider.ConfigPartialViewName, Model.Provider.ConfigData, viewData) + + try + { + @Html.Partial(Model.Provider.ConfigPartialViewName, Model.Provider.ConfigData, viewData) + } + catch (Exception exception) + { +
+ @T("Admin.Configuration.Plugins.UnknownError") +
+
@exception.ToString()
+ } } else { From 965ac71fb4ee9021289f6d52d48a2b9dd8834292 Mon Sep 17 00:00:00 2001 From: Murat Cakir Date: Fri, 17 Jun 2016 17:19:43 +0200 Subject: [PATCH 25/73] Smarter import of plugin resource files (de-DE > de > de-* > en-US > en > en-* > *) --- .../Localization/ILocalizationService.cs | 9 +- .../Localization/LanguageService.cs | 7 +- .../Localization/LocalizationService.cs | 250 +++++++++++++----- .../Controllers/ProductController.cs | 2 +- 4 files changed, 191 insertions(+), 77 deletions(-) diff --git a/src/Libraries/SmartStore.Services/Localization/ILocalizationService.cs b/src/Libraries/SmartStore.Services/Localization/ILocalizationService.cs index 918ad1be88..c2a57e6ad5 100644 --- a/src/Libraries/SmartStore.Services/Localization/ILocalizationService.cs +++ b/src/Libraries/SmartStore.Services/Localization/ILocalizationService.cs @@ -131,11 +131,14 @@ void ImportResourcesFromXml(Language language, /// /// codehint: sm-add /// Descriptor of the plugin - /// Load them into list rather than into database + /// Load them into the passed list rather than into database /// Specifies whether user touched resources should also be updated /// Import only files for particular languages - void ImportPluginResourcesFromXml(PluginDescriptor pluginDescriptor, - List forceToList = null, bool updateTouchedResources = true, IList filterLanguages = null); + void ImportPluginResourcesFromXml( + PluginDescriptor pluginDescriptor, + IList targetList = null, + bool updateTouchedResources = true, + IList filterLanguages = null); /// /// Flattens all nested LocaleResource child nodes into a new document diff --git a/src/Libraries/SmartStore.Services/Localization/LanguageService.cs b/src/Libraries/SmartStore.Services/Localization/LanguageService.cs index bc8e7d0999..db75218b54 100644 --- a/src/Libraries/SmartStore.Services/Localization/LanguageService.cs +++ b/src/Libraries/SmartStore.Services/Localization/LanguageService.cs @@ -110,18 +110,19 @@ public virtual IList GetAllLanguages(bool showHidden = false, int stor { var query = _languageRepository.Table; if (!showHidden) - query = query.Where(l => l.Published); - query = query.OrderBy(l => l.DisplayOrder); + query = query.Where(x => x.Published); + query = query.OrderBy(x => x.DisplayOrder); return query.ToList(); }); - //store mapping + // store mapping if (storeId > 0) { languages = languages .Where(l => _storeMappingService.Authorize(l, storeId)) .ToList(); } + return languages; } diff --git a/src/Libraries/SmartStore.Services/Localization/LocalizationService.cs b/src/Libraries/SmartStore.Services/Localization/LocalizationService.cs index 8610072e92..9f3a0bf29f 100644 --- a/src/Libraries/SmartStore.Services/Localization/LocalizationService.cs +++ b/src/Libraries/SmartStore.Services/Localization/LocalizationService.cs @@ -16,6 +16,8 @@ using SmartStore.Core.Events; using SmartStore.Core.Logging; using SmartStore.Core.Plugins; +using SmartStore.Core.Localization; +using System.Globalization; namespace SmartStore.Services.Localization { @@ -172,6 +174,7 @@ orderby lsr.ResourceName if (localeStringResource == null && logIfNotFound) _logger.Warning(string.Format("Resource string ({0}) not found. Language ID = {1}", resourceName, languageId)); + return localeStringResource; } @@ -415,6 +418,182 @@ public virtual string ExportResourcesToXml(Language language) return stringWriter.ToString(); } + public virtual void ImportPluginResourcesFromXml( + PluginDescriptor pluginDescriptor, + IList targetList = null, + bool updateTouchedResources = true, + IList filterLanguages = null) + { + var directory = new DirectoryInfo(Path.Combine(pluginDescriptor.OriginalAssemblyFile.Directory.FullName, "Localization")); + + if (!directory.Exists) + return; + + if (targetList == null && updateTouchedResources) + { + DeleteLocaleStringResources(pluginDescriptor.ResourceRootKey); + } + + var unprocessedLanguages = new List(); + + var defaultLanguageId = _languageService.GetDefaultLanguageId(); + var languages = filterLanguages ?? _languageService.GetAllLanguages(true); + + string code = null; + foreach (var language in languages) + { + code = ImportPluginResourcesForLanguage( + language, + null, + directory, + pluginDescriptor.ResourceRootKey, + targetList, + updateTouchedResources, + false); + + if (code == null) + { + unprocessedLanguages.Add(language); + } + } + + if (filterLanguages == null && unprocessedLanguages.Count > 0) + { + // There were unprocessed languages (no corresponding resource file could be found). + // In order for GetResource() to be able to gracefully fallback to the default language's resources, + // we need to import resources for the current default language.... + var processedLanguages = languages.Except(unprocessedLanguages).ToList(); + if (!processedLanguages.Any(x => x.Id == defaultLanguageId)) + { + // ...but only if no resource file could be mapped to the default language before, + // namely because in this case the following operation would be redundant. + var defaultLanguage = _languageService.GetLanguageById(_languageService.GetDefaultLanguageId()); + if (defaultLanguage != null) + { + ImportPluginResourcesForLanguage( + defaultLanguage, + "en-us", + directory, + pluginDescriptor.ResourceRootKey, + targetList, + updateTouchedResources, + true); + } + } + } + } + + /// + /// Resolves a resource file for the specified language and processes the import + /// + /// Language + /// The culture code of the processed resource file + private string ImportPluginResourcesForLanguage( + Language language, + string fileCode, + DirectoryInfo directory, + string resourceRootKey, + IList targetList, + bool updateTouchedResources, + bool canFallBackToAnyResourceFile) + { + var fileNamePattern = "resources.{0}.xml"; + + var codeCandidates = GetResourceFileCodeCandidates( + fileCode ?? language.LanguageCulture, + directory, + canFallBackToAnyResourceFile); + + string path = null; + string code = null; + + foreach (var candidate in codeCandidates) + { + var pathCandidate = Path.Combine(directory.FullName, fileNamePattern.FormatInvariant(candidate)); + if (File.Exists(pathCandidate)) + { + code = candidate; + path = pathCandidate; + break; + } + } + + if (code != null) + { + var doc = new XmlDocument(); + + doc.Load(path); + doc = FlattenResourceFile(doc); + + if (targetList == null) + { + ImportResourcesFromXml(language, doc, resourceRootKey, true, updateTouchedResources: updateTouchedResources); + } + else + { + var nodes = doc.SelectNodes(@"//Language/LocaleResource"); + foreach (XmlNode node in nodes) + { + var valueNode = node.SelectSingleNode("Value"); + var res = new LocaleStringResource() + { + ResourceName = node.Attributes["Name"].InnerText.Trim(), + ResourceValue = (valueNode == null ? "" : valueNode.InnerText), + LanguageId = language.Id, + IsFromPlugin = true + }; + + if (res.ResourceName.HasValue()) + { + targetList.Add(res); + } + } + } + } + + return code; + } + + private IEnumerable GetResourceFileCodeCandidates(string code, DirectoryInfo directory, bool canFallBackToAnyResourceFile) + { + // exact match (de-DE) + yield return code; + + // neutral culture (de) + var ci = CultureInfo.GetCultureInfo(code); + if (ci.Parent != null && !ci.IsNeutralCulture) + { + code = ci.Parent.Name; + yield return code; + } + + var rgFileName = new Regex("^resources.(.+?).xml$", RegexOptions.Compiled | RegexOptions.IgnoreCase); + + // any other region with same language (de-*) + foreach (var fi in directory.EnumerateFiles("resources.{0}-*.xml".FormatInvariant(code), SearchOption.TopDirectoryOnly)) + { + code = rgFileName.Match(fi.Name).Groups[1].Value; + if (LocalizationHelper.IsValidCultureCode(code)) + { + yield return code; + yield break; + } + } + + if (canFallBackToAnyResourceFile) + { + foreach (var fi in directory.EnumerateFiles("resources.*.xml", SearchOption.TopDirectoryOnly)) + { + code = rgFileName.Match(fi.Name).Groups[1].Value; + if (LocalizationHelper.IsValidCultureCode(code)) + { + yield return code; + yield break; + } + } + } + } + /// /// Import language resources from XML file /// @@ -490,80 +669,11 @@ public virtual void ImportResourcesFromXml( _lsrRepository.UpdateRange(toUpdate); toUpdate.Clear(); - //clear cache + // clear cache _cacheManager.RemoveByPattern(LOCALESTRINGRESOURCES_PATTERN_KEY); } } - /// - /// Import plugin resources from xml files in plugin's localization directory. - /// - /// Descriptor of the plugin - /// Load them into list rather than into database - /// Specifies whether user touched resources should also be updated - /// Import only files for particular languages - public virtual void ImportPluginResourcesFromXml(PluginDescriptor pluginDescriptor, - List forceToList = null, bool updateTouchedResources = true, IList filterLanguages = null) - { - string pluginDir = pluginDescriptor.OriginalAssemblyFile.Directory.FullName; - string localizationDir = Path.Combine(pluginDir, "Localization"); - - if (!System.IO.Directory.Exists(localizationDir)) - return; - - if (forceToList == null && updateTouchedResources) - DeleteLocaleStringResources(pluginDescriptor.ResourceRootKey); - - var languages = _languageService.GetAllLanguages(true); - var doc = new XmlDocument(); - - foreach (var filePath in System.IO.Directory.EnumerateFiles(localizationDir, "*.xml")) - { - Match match = Regex.Match(Path.GetFileName(filePath), Regex.Escape("resources.") + "(.*?)" + Regex.Escape(".xml")); - string languageCode = match.Groups[1].Value; - - Language language = languages.Where(l => l.LanguageCulture.IsCaseInsensitiveEqual(languageCode)).FirstOrDefault(); - if (language != null) - { - language = _languageService.GetLanguageById(language.Id); - } - - if (languageCode.HasValue() && language != null) - { - if (filterLanguages != null && !filterLanguages.Any(x => x.Id == language.Id)) - { - continue; - } - - doc.Load(filePath); - doc = FlattenResourceFile(doc); - - if (forceToList == null) - { - ImportResourcesFromXml(language, doc, pluginDescriptor.ResourceRootKey, true, updateTouchedResources: updateTouchedResources); - } - else - { - var nodes = doc.SelectNodes(@"//Language/LocaleResource"); - foreach (XmlNode node in nodes) - { - var valueNode = node.SelectSingleNode("Value"); - var res = new LocaleStringResource() - { - ResourceName = node.Attributes["Name"].InnerText.Trim(), - ResourceValue = (valueNode == null ? "" : valueNode.InnerText), - LanguageId = language.Id, - IsFromPlugin = true - }; - - if (res.ResourceName.HasValue()) - forceToList.Add(res); - } - } - } - } - } - public virtual XmlDocument FlattenResourceFile(XmlDocument source) { Guard.ArgumentNotNull(() => source); diff --git a/src/Presentation/SmartStore.Web/Controllers/ProductController.cs b/src/Presentation/SmartStore.Web/Controllers/ProductController.cs index fa13176e2a..b3f13e7653 100644 --- a/src/Presentation/SmartStore.Web/Controllers/ProductController.cs +++ b/src/Presentation/SmartStore.Web/Controllers/ProductController.cs @@ -168,7 +168,7 @@ public ActionResult ProductDetails(int productId, string attributes) } } - //prepare the model + // prepare the model var selectedAttributes = new NameValueCollection(); selectedAttributes.ConvertAttributeQueryData( From f4f0da67e171871679ccf7f4c27bd1247e42c5f5 Mon Sep 17 00:00:00 2001 From: Murat Cakir Date: Fri, 17 Jun 2016 19:32:08 +0200 Subject: [PATCH 26/73] Updated changelog --- changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.md b/changelog.md index 4206394556..058b7fcddb 100644 --- a/changelog.md +++ b/changelog.md @@ -23,6 +23,7 @@ * Major improvements in Importer: better field mapping, higher performance, bug fixes etc. * (Dev) Publishing SmartStore.Web from within Visual Studio now deploys the project correctly. No need to execute ClickToBuild.cmd anymore. Just publish directly to any target, including Azure. * Localization & SEO: language switcher now takes language specific SEO slugs into account when building links +* Smarter import of plugin resource files with graceful fallbacks (de-DE > de > de-* > en-US > en > en-* > *) * Exports the product detail link including the attribute query string when exporting attribute combinations * #918 Compare products: Display base price information * Export email attachments needs to be stored in database because the temp file may not exist anymore when sending the email From c6baefa0eac717f66b814d18ca9f6c9caa58ba49 Mon Sep 17 00:00:00 2001 From: Murat Cakir Date: Fri, 17 Jun 2016 23:26:43 +0200 Subject: [PATCH 27/73] (Perf) Faster language resource file import --- changelog.md | 1 + src/Libraries/SmartStore.Data/EfRepository.cs | 2 +- .../Localization/ILocalizationService.cs | 7 ++- .../Localization/LocalizationService.cs | 56 ++++++++++++------- 4 files changed, 41 insertions(+), 25 deletions(-) diff --git a/changelog.md b/changelog.md index 058b7fcddb..ddeda6310a 100644 --- a/changelog.md +++ b/changelog.md @@ -24,6 +24,7 @@ * (Dev) Publishing SmartStore.Web from within Visual Studio now deploys the project correctly. No need to execute ClickToBuild.cmd anymore. Just publish directly to any target, including Azure. * Localization & SEO: language switcher now takes language specific SEO slugs into account when building links * Smarter import of plugin resource files with graceful fallbacks (de-DE > de > de-* > en-US > en > en-* > *) +* (Perf) Faster language resource file import * Exports the product detail link including the attribute query string when exporting attribute combinations * #918 Compare products: Display base price information * Export email attachments needs to be stored in database because the temp file may not exist anymore when sending the email diff --git a/src/Libraries/SmartStore.Data/EfRepository.cs b/src/Libraries/SmartStore.Data/EfRepository.cs index 860551f723..5afd5e5d41 100644 --- a/src/Libraries/SmartStore.Data/EfRepository.cs +++ b/src/Libraries/SmartStore.Data/EfRepository.cs @@ -161,7 +161,7 @@ public virtual void UpdateRange(IEnumerable entities) private void SetEntityStateToModifiedIfApplicable(T entity) { var entry = InternalContext.Entry(entity); - if (entry.State == System.Data.Entity.EntityState.Detached || (this.AutoCommitEnabledInternal && !InternalContext.Configuration.AutoDetectChangesEnabled)) + if (entry.State < System.Data.Entity.EntityState.Added || (this.AutoCommitEnabledInternal && !InternalContext.Configuration.AutoDetectChangesEnabled)) { entry.State = System.Data.Entity.EntityState.Modified; } diff --git a/src/Libraries/SmartStore.Services/Localization/ILocalizationService.cs b/src/Libraries/SmartStore.Services/Localization/ILocalizationService.cs index c2a57e6ad5..6195301c03 100644 --- a/src/Libraries/SmartStore.Services/Localization/ILocalizationService.cs +++ b/src/Libraries/SmartStore.Services/Localization/ILocalizationService.cs @@ -117,9 +117,10 @@ LocaleStringResource GetLocaleStringResourceByName(string resourceName, int lang /// Language /// XML document /// Prefix for resource key name - /// Specifies whether resource should be inserted or updated (or both) - /// Specifies whether user touched resources should also be updated - void ImportResourcesFromXml(Language language, + /// Specifies whether resource should be inserted or updated (or both) + /// Specifies whether user touched resources should also be updated + /// The number of processed (added or updated) resource entries + int ImportResourcesFromXml(Language language, XmlDocument xmlDocument, string rootKey = null, bool sourceIsPlugin = false, diff --git a/src/Libraries/SmartStore.Services/Localization/LocalizationService.cs b/src/Libraries/SmartStore.Services/Localization/LocalizationService.cs index 9f3a0bf29f..c6ac869c27 100644 --- a/src/Libraries/SmartStore.Services/Localization/LocalizationService.cs +++ b/src/Libraries/SmartStore.Services/Localization/LocalizationService.cs @@ -273,6 +273,7 @@ orderby l.ResourceName string cacheKey = string.Format(LOCALESTRINGRESOURCES_ALL_KEY, languageId); var dict = _cacheManager.Get(cacheKey, () => { + // TODO: make result cacheable in distributed cache (IDictionary) var result = new ConcurrentDictionary>(8, 2000, StringComparer.CurrentCultureIgnoreCase); if (forceAll || _localizationSettings.LoadAllLocaleRecordsOnStartup) { @@ -594,13 +595,7 @@ private IEnumerable GetResourceFileCodeCandidates(string code, Directory } } - /// - /// Import language resources from XML file - /// - /// Language - /// XML document - /// Prefix for resource key name - public virtual void ImportResourcesFromXml( + public virtual int ImportResourcesFromXml( Language language, XmlDocument xmlDocument, string rootKey = null, @@ -608,12 +603,16 @@ public virtual void ImportResourcesFromXml( ImportModeFlags mode = ImportModeFlags.Insert | ImportModeFlags.Update, bool updateTouchedResources = false) { - using (var scope = new DbContextScope(autoDetectChanges: false, proxyCreation: false, validateOnSave: false, autoCommit: false)) + using (var scope = new DbContextScope(autoDetectChanges: false, proxyCreation: false, validateOnSave: false, autoCommit: false, forceNoTracking: true, hooksEnabled: false)) { var toAdd = new List(); var toUpdate = new List(); var nodes = xmlDocument.SelectNodes(@"//Language/LocaleResource"); + var resources = language.LocaleStringResources.ToDictionarySafe(x => x.ResourceName, StringComparer.OrdinalIgnoreCase); + + LocaleStringResource resource; + foreach (var xel in nodes.Cast()) { string name = xel.GetAttribute("Name").TrimSafe(); @@ -631,18 +630,23 @@ public virtual void ImportResourcesFromXml( name = "{0}.{1}".FormatWith(rootKey, name); } + resource = null; + // do not use "Insert"/"Update" methods because they clear cache // let's bulk insert - var resource = language.LocaleStringResources.Where(x => x.ResourceName.Equals(name, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault(); - if (resource != null) + //var resource = language.LocaleStringResources.Where(x => x.ResourceName.Equals(name, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault(); + if (resources.TryGetValue(name, out resource)) { if (mode.HasFlag(ImportModeFlags.Update)) { if (updateTouchedResources || !resource.IsTouched.GetValueOrDefault()) { - resource.ResourceValue = value; - resource.IsTouched = null; - toUpdate.Add(resource); + if (value != resource.ResourceValue) + { + resource.ResourceValue = value; + resource.IsTouched = null; + toUpdate.Add(resource); + } } } } @@ -651,7 +655,7 @@ public virtual void ImportResourcesFromXml( if (mode.HasFlag(ImportModeFlags.Insert)) { toAdd.Add( - new LocaleStringResource() + new LocaleStringResource { LanguageId = language.Id, ResourceName = name, @@ -662,15 +666,25 @@ public virtual void ImportResourcesFromXml( } } - _lsrRepository.AutoCommitEnabled = true; - _lsrRepository.InsertRange(toAdd, 500); - toAdd.Clear(); + //_lsrRepository.AutoCommitEnabled = true; - _lsrRepository.UpdateRange(toUpdate); - toUpdate.Clear(); + if (toAdd.Any() || toUpdate.Any()) + { + _lsrRepository.InsertRange(toAdd); + toAdd.Clear(); + + _lsrRepository.UpdateRange(toUpdate); + toUpdate.Clear(); + + int num = _lsrRepository.Context.SaveChanges(); + + // clear cache + _cacheManager.RemoveByPattern(LOCALESTRINGRESOURCES_PATTERN_KEY); + + return num; + } - // clear cache - _cacheManager.RemoveByPattern(LOCALESTRINGRESOURCES_PATTERN_KEY); + return 0; } } From 1a810e2c1ca95cdad0e62b6235963a813d26bf41 Mon Sep 17 00:00:00 2001 From: Murat Cakir Date: Sat, 18 Jun 2016 00:04:56 +0200 Subject: [PATCH 28/73] Minor enhancements in data layer --- .../SmartStore.Data/ObjectContextBase.cs | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/src/Libraries/SmartStore.Data/ObjectContextBase.cs b/src/Libraries/SmartStore.Data/ObjectContextBase.cs index 579994d654..26b4e52171 100644 --- a/src/Libraries/SmartStore.Data/ObjectContextBase.cs +++ b/src/Libraries/SmartStore.Data/ObjectContextBase.cs @@ -16,6 +16,7 @@ using SmartStore.Core.Data; using SmartStore.Core.Data.Hooks; using SmartStore.Core.Events; +using System.Data.Entity.Core.Objects; namespace SmartStore.Data { @@ -138,7 +139,7 @@ public bool HooksEnabled public virtual string CreateDatabaseScript() { - return ((IObjectContextAdapter)this).ObjectContext.CreateDatabaseScript(); + return ObjectContext.CreateDatabaseScript(); } public new DbSet Set() where TEntity : BaseEntity @@ -219,7 +220,7 @@ private IEnumerable ToParameters(params object[] parameters) // database call var reader = cmd.ExecuteReader(); - var result = ((IObjectContextAdapter)(this)).ObjectContext.Translate(reader).ToList(); + var result = ObjectContext.Translate(reader).ToList(); if (!ForceNoTracking) { for (int i = 0; i < result.Count; i++) @@ -263,8 +264,8 @@ public int ExecuteSqlCommand(string sql, bool doNotEnsureTransaction = false, in if (timeout.HasValue) { //store previous timeout - previousTimeout = ((IObjectContextAdapter)this).ObjectContext.CommandTimeout; - ((IObjectContextAdapter)this).ObjectContext.CommandTimeout = timeout; + previousTimeout = ObjectContext.CommandTimeout; + ObjectContext.CommandTimeout = timeout; } var transactionalBehavior = doNotEnsureTransaction @@ -275,7 +276,7 @@ public int ExecuteSqlCommand(string sql, bool doNotEnsureTransaction = false, in if (timeout.HasValue) { //Set previous timeout back - ((IObjectContextAdapter)this).ObjectContext.CommandTimeout = previousTimeout; + ObjectContext.CommandTimeout = previousTimeout; } return result; @@ -498,27 +499,29 @@ protected internal bool IsSqlServer2012OrHigher() public TEntity Attach(TEntity entity) where TEntity : BaseEntity { - var dbSet = Set(); - var alreadyAttached = dbSet.Local.FirstOrDefault(x => x.Id == entity.Id); - - if (alreadyAttached == null) + ObjectStateEntry entry; + if (ObjectContext.ObjectStateManager.TryGetObjectStateEntry(entity, out entry)) { - dbSet.Attach(entity); - return entity; + if (entry.State != System.Data.Entity.EntityState.Detached) + { + return (TEntity)entry.Entity; + } } - return alreadyAttached; + Set().Attach(entity); + return entity; } public bool IsAttached(TEntity entity) where TEntity : BaseEntity { - if (entity != null) + ObjectStateEntry entry; + if (ObjectContext.ObjectStateManager.TryGetObjectStateEntry(entity, out entry)) { - return Set().Local.Any(x => x.Id == entity.Id); + return (entry.State != System.Data.Entity.EntityState.Detached); } - + return false; - } + } public void DetachEntity(TEntity entity) where TEntity : BaseEntity { @@ -550,7 +553,6 @@ public int DetachEntities(bool unchangedEntitiesOnly = true) where TEnt public void ChangeState(TEntity entity, System.Data.Entity.EntityState newState) where TEntity : BaseEntity { - Console.WriteLine("ChangeState ORIGINAL"); this.Entry(entity).State = newState; } @@ -559,6 +561,11 @@ public void ReloadEntity(TEntity entity) where TEntity : BaseEntity this.Entry(entity).Reload(); } + internal ObjectContext ObjectContext + { + get { return ((IObjectContextAdapter)this).ObjectContext; } + } + private string FormatValidationExceptionMessage(IEnumerable results) { var sb = new StringBuilder(); From 9069036320a6d38aa16a2c20d6ceae2eacf7e6cf Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Sat, 18 Jun 2016 17:06:37 +0200 Subject: [PATCH 29/73] Reviewed "Product details: Select attribute and gift card values by query string parameters" --- .../Catalog/ProductAttributeParser.cs | 15 +- .../NameValueCollectionExtensions.cs | 48 ++++-- ...teOrUpdateAttributeCombinationPopup.cshtml | 9 +- .../Controllers/CatalogHelper.cs | 143 +++++++----------- .../Controllers/ProductController.cs | 13 +- 5 files changed, 108 insertions(+), 120 deletions(-) diff --git a/src/Libraries/SmartStore.Services/Catalog/ProductAttributeParser.cs b/src/Libraries/SmartStore.Services/Catalog/ProductAttributeParser.cs index 23ee794f0b..9c87960614 100644 --- a/src/Libraries/SmartStore.Services/Catalog/ProductAttributeParser.cs +++ b/src/Libraries/SmartStore.Services/Catalog/ProductAttributeParser.cs @@ -374,15 +374,20 @@ public virtual ProductVariantAttributeCombination FindProductVariantAttributeCom public virtual List> DeserializeQueryData(string jsonData) { - if (jsonData.HasValue()) + try { - if (jsonData.StartsWith("[")) + if (jsonData.HasValue()) { - return JsonConvert.DeserializeObject>>(jsonData); - } + if (jsonData.StartsWith("[")) + { + return JsonConvert.DeserializeObject>>(jsonData); + } - return new List> { JsonConvert.DeserializeObject>(jsonData) }; + return new List> { JsonConvert.DeserializeObject>(jsonData) }; + } } + catch { } + return new List>(); } diff --git a/src/Libraries/SmartStore.Services/Extensions/NameValueCollectionExtensions.cs b/src/Libraries/SmartStore.Services/Extensions/NameValueCollectionExtensions.cs index a14c25e424..216894b2d2 100644 --- a/src/Libraries/SmartStore.Services/Extensions/NameValueCollectionExtensions.cs +++ b/src/Libraries/SmartStore.Services/Extensions/NameValueCollectionExtensions.cs @@ -13,6 +13,7 @@ namespace SmartStore { public static class NameValueCollectionExtensions { + // TODO: find place to make it public static private static string AttributeFormatedName(int productAttributeId, int attributeId, int productId = 0, int bundleItemId = 0) { if (productId == 0) @@ -25,34 +26,57 @@ public static void AddProductAttribute(this NameValueCollection collection, int { if (productAttributeId != 0 && attributeId != 0 && valueId != 0) { - string name = AttributeFormatedName(productAttributeId, attributeId, productId, bundleItemId); + var name = AttributeFormatedName(productAttributeId, attributeId, productId, bundleItemId); collection.Add(name, valueId.ToString()); } } /// - /// Converts attribute query data + /// Get selected attributes from query string /// - /// Name value collection + /// Name value collection with selected attributes + /// Query string parameters /// Attribute query data items with following structure: /// Product.Id, ProductAttribute.Id, Product_ProductAttribute_Mapping.Id, ProductVariantAttributeValue.Id, [BundleItem.Id] /// Product identifier to filter - public static void ConvertAttributeQueryData(this NameValueCollection collection, List> queryData, int productId = 0) + public static void GetSelectedAttributes(this NameValueCollection collection, NameValueCollection queryString, List> attributes, int productId = 0) { - if (collection == null || queryData == null || queryData.Count <= 0) - return; + Guard.NotNull(() => collection); - var items = queryData.Where(i => i.Count > 3); + // ambiguous parameters: let other query string parameters win over the json formatted attributes parameter + if (queryString != null && queryString.Count > 0) + { + var items = queryString.AllKeys + .Where(x => x.EmptyNull().StartsWith("product_attribute_")) + .SelectMany(queryString.GetValues, (k, v) => new { key = k.EmptyNull(), value = v.TrimSafe() }); - if (productId != 0) - items = items.Where(i => i[0] == productId); + foreach (var item in items) + { + var ids = item.key.Replace("product_attribute_", "").SplitSafe("_"); + if (ids.Count() > 3) + { + if (productId == 0 || (productId != 0 && productId == ids[0].ToInt())) + { + collection.Add(item.key, item.value); + } + } + } + } - foreach (var item in items) + if (attributes != null && attributes.Count > 0) { - var name = AttributeFormatedName(item[1], item[2], item[0], item.Count > 4 ? item[4] : 0); + var items = attributes.Where(i => i.Count > 3); + + if (productId != 0) + items = items.Where(i => i[0] == productId); - collection.Add(name, item[3].ToString()); + foreach (var item in items) + { + var name = AttributeFormatedName(item[1], item[2], item[0], item.Count > 4 ? item[4] : 0); + + collection.Add(name, item[3].ToString()); + } } } diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Product/_CreateOrUpdateAttributeCombinationPopup.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Product/_CreateOrUpdateAttributeCombinationPopup.cshtml index 92de51ade3..9e07dff329 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Product/_CreateOrUpdateAttributeCombinationPopup.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Product/_CreateOrUpdateAttributeCombinationPopup.cshtml @@ -29,12 +29,13 @@ @if (!ViewBag.IsEdit) { -
+
@if (Model.Warnings.Count > 0) { -
- @foreach (var warning in Model.Warnings) { -

 @warning

+
+ @foreach (var warning in Model.Warnings) + { +

 @warning

}
} diff --git a/src/Presentation/SmartStore.Web/Controllers/CatalogHelper.cs b/src/Presentation/SmartStore.Web/Controllers/CatalogHelper.cs index 8e2a4f8ca7..ebc506887c 100644 --- a/src/Presentation/SmartStore.Web/Controllers/CatalogHelper.cs +++ b/src/Presentation/SmartStore.Web/Controllers/CatalogHelper.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; +using System.Collections.Specialized; using System.Diagnostics; using System.Linq; -using System.Linq.Expressions; using System.Web; using System.Web.Mvc; using SmartStore.Collections; @@ -25,14 +25,12 @@ using SmartStore.Services.Security; using SmartStore.Services.Seo; using SmartStore.Services.Tax; +using SmartStore.Services.Topics; using SmartStore.Web.Framework.UI; using SmartStore.Web.Framework.UI.Captcha; using SmartStore.Web.Infrastructure.Cache; using SmartStore.Web.Models.Catalog; using SmartStore.Web.Models.Media; -using SmartStore.Core.Data; -using System.Collections.Specialized; -using SmartStore.Services.Topics; namespace SmartStore.Web.Controllers { @@ -152,7 +150,8 @@ public ProductDetailsModel PrepareProductDetailsPageModel( bool isAssociatedProduct = false, ProductBundleItemData productBundleItem = null, IList productBundleItems = null, - NameValueCollection selectedAttributes = null) + NameValueCollection selectedAttributes = null, + NameValueCollection queryData = null) { if (product == null) throw new ArgumentNullException("product"); @@ -187,6 +186,30 @@ public ProductDetailsModel PrepareProductDetailsPageModel( IsCurrentCustomerRegistered = _services.WorkContext.CurrentCustomer.IsRegistered() }; + // get gift card values from query string + if (queryData != null && queryData.Count > 0) + { + var giftCardItems = queryData.AllKeys + .Where(x => x.EmptyNull().StartsWith("giftcard_")) + .SelectMany(queryData.GetValues, (k, v) => new { key = k, value = v.TrimSafe() }); + + foreach (var item in giftCardItems) + { + var key = item.key.EmptyNull().ToLower(); + + if (key.EndsWith("recipientname")) + model.GiftCard.RecipientName = item.value; + else if (key.EndsWith("recipientemail")) + model.GiftCard.RecipientEmail = item.value; + else if (key.EndsWith("sendername")) + model.GiftCard.SenderName = item.value; + else if (key.EndsWith("senderemail")) + model.GiftCard.SenderEmail = item.value; + else if (key.EndsWith("message")) + model.GiftCard.Message = item.value; + } + } + // Back in stock subscriptions if (product.ManageInventoryMethod == ManageInventoryMethod.ManageStock && product.BackorderMode == BackorderMode.NoBackorders && @@ -285,92 +308,6 @@ public ProductDetailsModel PrepareProductDetailsPageModel( return model; } - public void SelectProductAttributeValues(ProductDetailsModel model, NameValueCollection queryData) - { - Guard.ArgumentNotNull(() => model); - - if (queryData == null || queryData.Count <= 0) - return; - - try - { - var items = queryData.AllKeys - .Where(x => x.EmptyNull().StartsWith("product_attribute_")) - .SelectMany(queryData.GetValues, (k, v) => new { key = k, value = v }); - - foreach (var item in items) - { - var ids = item.key.Replace("product_attribute_", "").SplitSafe("_"); - if (ids.Count() > 3) - { - var productId = ids[0].ToInt(); - var bundleItemId = ids[1].ToInt(); - var productAttributeId = ids[2].ToInt(); - //var attributeId = ids[3].ToInt(); - - var attribute = model.ProductVariantAttributes.FirstOrDefault(x => - x.ProductId == productId && - x.BundleItemId == bundleItemId && - x.ProductAttributeId == productAttributeId); - - if (attribute != null) - { - switch (attribute.AttributeControlType) - { - case AttributeControlType.DropdownList: - case AttributeControlType.RadioList: - case AttributeControlType.Checkboxes: - case AttributeControlType.ColorSquares: - var attributeValue = attribute.Values.FirstOrDefault(x => x.Name.IsCaseInsensitiveEqual(item.value)); - if (attributeValue != null) - { - attribute.Values.Each(x => x.IsPreSelected = false); - attributeValue.IsPreSelected = true; - } - break; - case AttributeControlType.TextBox: - case AttributeControlType.MultilineTextbox: - attribute.TextValue = item.value; - break; - case AttributeControlType.Datepicker: - if (item.value.Length == 8) - { - attribute.SelectedYear = item.value.Substring(0, 4).ToInt(); - attribute.SelectedMonth = item.value.Substring(4, 2).ToInt(); - attribute.SelectedDay = item.value.Substring(6, 2).ToInt(); - } - break; - } - } - } - } - - items = queryData.AllKeys - .Where(x => x.EmptyNull().StartsWith("giftcard_")) - .SelectMany(queryData.GetValues, (k, v) => new { key = k, value = v }); - - foreach (var item in items) - { - var key = item.key.EmptyNull().ToLower(); - - if (key.EndsWith("recipientname")) - model.GiftCard.RecipientName = item.value; - else if (key.EndsWith("recipientemail")) - model.GiftCard.RecipientEmail = item.value; - else if (key.EndsWith("sendername")) - model.GiftCard.SenderName = item.value; - else if (key.EndsWith("senderemail")) - model.GiftCard.SenderEmail = item.value; - else if (key.EndsWith("message")) - model.GiftCard.Message = item.value; - } - } - catch (Exception exception) - { - Logger.Warning(exception.ToAllMessages(), exception); - } - } - public void PrepareProductReviewsModel(ProductReviewsModel model, Product product) { if (product == null) @@ -591,9 +528,31 @@ public ProductDetailsModel PrepareProductDetailModel( pvaModel.BeginYear = match.Groups[1].Value.ToInt(); pvaModel.EndYear = match.Groups[2].Value.ToInt(); } + + if (hasSelectedAttributes) + { + var attributeKey = "product_attribute_{0}_{1}_{2}_{3}".FormatInvariant(product.Id, bundleItemId, attribute.ProductAttributeId, attribute.Id); + var day = selectedAttributes[attributeKey + "_day"].ToInt(); + var month = selectedAttributes[attributeKey + "_month"].ToInt(); + var year = selectedAttributes[attributeKey + "_year"].ToInt(); + if (day > 0 && month > 0 && year > 0) + { + pvaModel.SelectedDay = day; + pvaModel.SelectedMonth = month; + pvaModel.SelectedYear = year; + } + } + } + else if (attribute.AttributeControlType == AttributeControlType.TextBox || attribute.AttributeControlType == AttributeControlType.MultilineTextbox) + { + if (hasSelectedAttributes) + { + var attributeKey = "product_attribute_{0}_{1}_{2}_{3}".FormatInvariant(product.Id, bundleItemId, attribute.ProductAttributeId, attribute.Id); + pvaModel.TextValue = selectedAttributes[attributeKey]; + } } - int preSelectedValueId = 0; + var preSelectedValueId = 0; var pvaValues = (attribute.ShouldHaveValues() ? _productAttributeService.GetProductVariantAttributeValues(attribute.Id) : new List()); foreach (var pvaValue in pvaValues) diff --git a/src/Presentation/SmartStore.Web/Controllers/ProductController.cs b/src/Presentation/SmartStore.Web/Controllers/ProductController.cs index b3f13e7653..79497418a9 100644 --- a/src/Presentation/SmartStore.Web/Controllers/ProductController.cs +++ b/src/Presentation/SmartStore.Web/Controllers/ProductController.cs @@ -8,7 +8,6 @@ using SmartStore.Core.Domain.Localization; using SmartStore.Core.Domain.Media; using SmartStore.Core.Domain.Orders; -using SmartStore.Core.Localization; using SmartStore.Services; using SmartStore.Services.Catalog; using SmartStore.Services.Common; @@ -31,7 +30,7 @@ namespace SmartStore.Web.Controllers { - public partial class ProductController : PublicControllerBase + public partial class ProductController : PublicControllerBase { #region Fields @@ -168,16 +167,16 @@ public ActionResult ProductDetails(int productId, string attributes) } } - // prepare the model var selectedAttributes = new NameValueCollection(); - selectedAttributes.ConvertAttributeQueryData( + // get selected attributes from query string + selectedAttributes.GetSelectedAttributes( + Request.QueryString, _productAttributeParser.DeserializeQueryData(attributes), product.ProductType == ProductType.BundledProduct && product.BundlePerItemPricing ? 0 : product.Id); - var model = _helper.PrepareProductDetailsPageModel(product, selectedAttributes: selectedAttributes); - - _helper.SelectProductAttributeValues(model, Request.QueryString); + // prepare the view model + var model = _helper.PrepareProductDetailsPageModel(product, selectedAttributes: selectedAttributes, queryData: Request.QueryString); //save as recently viewed _recentlyViewedProductsService.AddProductToRecentlyViewedList(product.Id); From 3b10ce6a44de3fa805074267b4940a68adfd2416 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Sat, 18 Jun 2016 17:51:18 +0200 Subject: [PATCH 30/73] Updated licensing component --- .../SmartStore.Licensing.dll | Bin 280576 -> 282624 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/lib/SmartStore.Licensing/SmartStore.Licensing.dll b/lib/SmartStore.Licensing/SmartStore.Licensing.dll index 51e391ce236bd865fee64fdd1a7c9ad3e42ef34e..8acdf39c24bdd3254678ba27247be601f4ecfe75 100644 GIT binary patch literal 282624 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%0Dmx76k@#ViE&9zajKWW< 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
Rx-nNx50{K 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 z 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 Date: Sat, 18 Jun 2016 21:49:21 +0200 Subject: [PATCH 31/73] Revert "Minor enhancements in data layer" This reverts commit 1a810e2c1ca95cdad0e62b6235963a813d26bf41. --- .../SmartStore.Data/ObjectContextBase.cs | 41 ++++++++----------- 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/src/Libraries/SmartStore.Data/ObjectContextBase.cs b/src/Libraries/SmartStore.Data/ObjectContextBase.cs index 26b4e52171..579994d654 100644 --- a/src/Libraries/SmartStore.Data/ObjectContextBase.cs +++ b/src/Libraries/SmartStore.Data/ObjectContextBase.cs @@ -16,7 +16,6 @@ using SmartStore.Core.Data; using SmartStore.Core.Data.Hooks; using SmartStore.Core.Events; -using System.Data.Entity.Core.Objects; namespace SmartStore.Data { @@ -139,7 +138,7 @@ public bool HooksEnabled public virtual string CreateDatabaseScript() { - return ObjectContext.CreateDatabaseScript(); + return ((IObjectContextAdapter)this).ObjectContext.CreateDatabaseScript(); } public new DbSet Set() where TEntity : BaseEntity @@ -220,7 +219,7 @@ private IEnumerable ToParameters(params object[] parameters) // database call var reader = cmd.ExecuteReader(); - var result = ObjectContext.Translate(reader).ToList(); + var result = ((IObjectContextAdapter)(this)).ObjectContext.Translate(reader).ToList(); if (!ForceNoTracking) { for (int i = 0; i < result.Count; i++) @@ -264,8 +263,8 @@ public int ExecuteSqlCommand(string sql, bool doNotEnsureTransaction = false, in if (timeout.HasValue) { //store previous timeout - previousTimeout = ObjectContext.CommandTimeout; - ObjectContext.CommandTimeout = timeout; + previousTimeout = ((IObjectContextAdapter)this).ObjectContext.CommandTimeout; + ((IObjectContextAdapter)this).ObjectContext.CommandTimeout = timeout; } var transactionalBehavior = doNotEnsureTransaction @@ -276,7 +275,7 @@ public int ExecuteSqlCommand(string sql, bool doNotEnsureTransaction = false, in if (timeout.HasValue) { //Set previous timeout back - ObjectContext.CommandTimeout = previousTimeout; + ((IObjectContextAdapter)this).ObjectContext.CommandTimeout = previousTimeout; } return result; @@ -499,29 +498,27 @@ protected internal bool IsSqlServer2012OrHigher() public TEntity Attach(TEntity entity) where TEntity : BaseEntity { - ObjectStateEntry entry; - if (ObjectContext.ObjectStateManager.TryGetObjectStateEntry(entity, out entry)) + var dbSet = Set(); + var alreadyAttached = dbSet.Local.FirstOrDefault(x => x.Id == entity.Id); + + if (alreadyAttached == null) { - if (entry.State != System.Data.Entity.EntityState.Detached) - { - return (TEntity)entry.Entity; - } + dbSet.Attach(entity); + return entity; } - Set().Attach(entity); - return entity; + return alreadyAttached; } public bool IsAttached(TEntity entity) where TEntity : BaseEntity { - ObjectStateEntry entry; - if (ObjectContext.ObjectStateManager.TryGetObjectStateEntry(entity, out entry)) + if (entity != null) { - return (entry.State != System.Data.Entity.EntityState.Detached); + return Set().Local.Any(x => x.Id == entity.Id); } - + return false; - } + } public void DetachEntity(TEntity entity) where TEntity : BaseEntity { @@ -553,6 +550,7 @@ public int DetachEntities(bool unchangedEntitiesOnly = true) where TEnt public void ChangeState(TEntity entity, System.Data.Entity.EntityState newState) where TEntity : BaseEntity { + Console.WriteLine("ChangeState ORIGINAL"); this.Entry(entity).State = newState; } @@ -561,11 +559,6 @@ public void ReloadEntity(TEntity entity) where TEntity : BaseEntity this.Entry(entity).Reload(); } - internal ObjectContext ObjectContext - { - get { return ((IObjectContextAdapter)this).ObjectContext; } - } - private string FormatValidationExceptionMessage(IEnumerable results) { var sb = new StringBuilder(); From 7158f24d8d752e43317e61bda0ef063ef7e9fe5f Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 20 Jun 2016 11:06:23 +0200 Subject: [PATCH 32/73] Export: Some improvements --- changelog.md | 1 + .../Domain/DataExchange/ExportEnums.cs | 7 ++- .../Catalog/IProductAttributeParser.cs | 4 +- .../Catalog/ProductAttributeParser.cs | 9 ++-- .../DataExchange/Csv/CsvWriter.cs | 4 +- .../DataExchange/Export/DataExporter.cs | 8 +++- .../Export/DynamicEntityHelper.cs | 46 +++++++++++-------- .../Views/Export/_Tab.Deployment.cshtml | 2 +- 8 files changed, 49 insertions(+), 32 deletions(-) diff --git a/changelog.md b/changelog.md index ddeda6310a..480d9476d6 100644 --- a/changelog.md +++ b/changelog.md @@ -7,6 +7,7 @@ * #637 Integrated PayPal PLUS payment provider * #932 Implement paydirekt payment plugin * New Viveum payment plugin +* #979 Implement BeezUP product feed ### New Features * #637 Integrated PayPal PLUS payment Provider diff --git a/src/Libraries/SmartStore.Core/Domain/DataExchange/ExportEnums.cs b/src/Libraries/SmartStore.Core/Domain/DataExchange/ExportEnums.cs index a5b5a48763..6ea68ec73c 100644 --- a/src/Libraries/SmartStore.Core/Domain/DataExchange/ExportEnums.cs +++ b/src/Libraries/SmartStore.Core/Domain/DataExchange/ExportEnums.cs @@ -126,7 +126,12 @@ public enum ExportFeatures /// /// Whether to not automatically send a completion email /// - CanOmitCompletionMail = 1 << 12 + CanOmitCompletionMail = 1 << 12, + + /// + /// Whether to provide additional data of attribute combinations + /// + UsesAttributeCombination = 1 << 13 } /// diff --git a/src/Libraries/SmartStore.Services/Catalog/IProductAttributeParser.cs b/src/Libraries/SmartStore.Services/Catalog/IProductAttributeParser.cs index 64a412d339..a02648a747 100644 --- a/src/Libraries/SmartStore.Services/Catalog/IProductAttributeParser.cs +++ b/src/Libraries/SmartStore.Services/Catalog/IProductAttributeParser.cs @@ -35,11 +35,11 @@ public partial interface IProductAttributeParser /// /// Get list of localized product variant attribute values /// - /// XML formatted attributes + /// Map of combined attributes /// Product variant attributes /// Language identifier /// List of localized product variant attribute values - IList ParseProductVariantAttributeValues(string attributesXml, IEnumerable attributes, int languageId = 0); + IList ParseProductVariantAttributeValues(Multimap attributeCombination, IEnumerable attributes, int languageId = 0); /// /// Gets selected product variant attribute value diff --git a/src/Libraries/SmartStore.Services/Catalog/ProductAttributeParser.cs b/src/Libraries/SmartStore.Services/Catalog/ProductAttributeParser.cs index 9c87960614..0afe47049b 100644 --- a/src/Libraries/SmartStore.Services/Catalog/ProductAttributeParser.cs +++ b/src/Libraries/SmartStore.Services/Catalog/ProductAttributeParser.cs @@ -194,21 +194,20 @@ where id.HasValue() return values; } - public IList ParseProductVariantAttributeValues(string attributesXml, IEnumerable attributes, int languageId = 0) + public virtual IList ParseProductVariantAttributeValues(Multimap attributeCombination, IEnumerable attributes, int languageId = 0) { var values = new List(); - if (attributesXml.IsEmpty()) + if (attributeCombination == null || !attributeCombination.Any()) return values; var allValueIds = new List(); - var combinedAttributes = DeserializeProductVariantAttributes(attributesXml); foreach (var pva in attributes.Where(x => x.ShouldHaveValues()).OrderBy(x => x.DisplayOrder)) { - if (combinedAttributes.ContainsKey(pva.Id)) + if (attributeCombination.ContainsKey(pva.Id)) { - var pvaValuesStr = combinedAttributes[pva.Id]; + var pvaValuesStr = attributeCombination[pva.Id]; var ids = pvaValuesStr.Where(x => x.HasValue()).Select(x => x.ToInt()); allValueIds.AddRange(ids); diff --git a/src/Libraries/SmartStore.Services/DataExchange/Csv/CsvWriter.cs b/src/Libraries/SmartStore.Services/DataExchange/Csv/CsvWriter.cs index 83eee20228..8bb9942052 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Csv/CsvWriter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Csv/CsvWriter.cs @@ -51,7 +51,7 @@ public CsvConfiguration Configuration /// to complete writing of the current row. /// /// The fields to write. - public virtual void WriteFields(string[] fields) + public virtual void WriteFields(IEnumerable fields) { Guard.ArgumentNotNull(() => fields); fields.Each(x => WriteField(x)); @@ -69,7 +69,7 @@ public virtual void WriteFields(string[] fields) /// /// The fields to write. /// True to quote the fields, otherwise false. - public virtual void WriteFields(string[] fields, bool shouldQuote) + public virtual void WriteFields(IEnumerable fields, bool shouldQuote) { Guard.ArgumentNotNull(() => fields); fields.Each(x => WriteField(x, shouldQuote)); diff --git a/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs index 173b61b475..41cb53a69f 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs @@ -1065,8 +1065,12 @@ private void ExportCoreInner(DataExporterContext ctx, Store store) logHead.AppendLine("Entity:\t\t\t" + ctx.Request.Provider.Value.EntityType.ToString()); - var storeInfo = (ctx.Request.Profile.PerStore ? "{0} (Id {1})".FormatInvariant(ctx.Store.Name, ctx.Store.Id) : "All stores"); - logHead.AppendLine("Store:\t\t\t" + storeInfo); + try + { + var uri = new Uri(store.Url); + logHead.AppendLine("Store:\t\t\t{0} (Id {1})".FormatInvariant(uri.DnsSafeHost.NaIfEmpty(), ctx.Store.Id)); + } + catch { } var customer = _services.WorkContext.CurrentCustomer; logHead.Append("Executed by:\t\t" + (customer.Email.HasValue() ? customer.Email : customer.SystemName)); diff --git a/src/Libraries/SmartStore.Services/DataExchange/Export/DynamicEntityHelper.cs b/src/Libraries/SmartStore.Services/DataExchange/Export/DynamicEntityHelper.cs index 96362b5999..e925553e9f 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Export/DynamicEntityHelper.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Export/DynamicEntityHelper.cs @@ -578,14 +578,14 @@ private dynamic ToDynamic( #region gerneral data - dynObject.Price = CalculatePrice(ctx, product, combination != null); - - if (combination != null && ctx.Projection.AttributeCombinationValueMerging == ExportAttributeValueMerging.AppendAllValuesToName) - { - var values = _productAttributeParser.Value.ParseProductVariantAttributeValues(combination.AttributesXml, productAttributes, ctx.Projection.LanguageId ?? 0); + dynObject._CategoryName = null; + dynObject._CategoryPath = null; + dynObject._AttributeCombination = null; + dynObject._AttributeCombinationValues = null; + dynObject._AttributeCombinationId = (combination == null ? 0 : combination.Id); + dynObject._DetailUrl = ctx.Store.Url.EnsureEndsWith("/") + (string)dynObject.SeName; - dynObject.Name = ((string)dynObject.Name).Grow(string.Join(", ", values), " "); - } + dynObject.Price = CalculatePrice(ctx, product, combination != null); dynObject._BasePriceInfo = product.GetBasePriceInfo(_services.Localization, _priceFormatter.Value, _currencyService.Value, _taxService.Value, _priceCalculationService.Value, ctx.ContextCurrency, decimal.Zero, true); @@ -595,21 +595,34 @@ private dynamic ToDynamic( else dynObject._ProductTemplateViewPath = ""; - var detailUrl = ctx.Store.Url.EnsureEndsWith("/") + (string)dynObject.SeName; - if (combination != null) { + if (ctx.Supports(ExportFeatures.UsesAttributeCombination) || + ctx.Projection.AttributeCombinationValueMerging == ExportAttributeValueMerging.AppendAllValuesToName) + { + var variantAttributes = _productAttributeParser.Value.DeserializeProductVariantAttributes(combination.AttributesXml); + var variantAttributeValues = _productAttributeParser.Value.ParseProductVariantAttributeValues(variantAttributes, productAttributes, languageId); + + if (ctx.Supports(ExportFeatures.UsesAttributeCombination)) + { + dynObject._AttributeCombination = variantAttributes; + dynObject._AttributeCombinationValues = variantAttributeValues; + } + + if (ctx.Projection.AttributeCombinationValueMerging == ExportAttributeValueMerging.AppendAllValuesToName) + { + dynObject.Name = ((string)dynObject.Name).Grow(string.Join(", ", variantAttributeValues), " "); + } + } + var attributeQueryString = _productAttributeParser.Value.SerializeQueryData(combination.AttributesXml, product.Id); if (attributeQueryString.HasValue()) { - detailUrl = string.Concat(detailUrl, detailUrl.Contains("?") ? "&" : "?", "attributes=", attributeQueryString); + var url = (string)dynObject._DetailUrl; + dynObject._DetailUrl = string.Concat(url, url.Contains("?") ? "&" : "?", "attributes=", attributeQueryString); } } - dynObject._IsChild = (combination != null); - dynObject._DetailUrl = detailUrl; - dynObject._CategoryName = null; - if (ctx.Categories.Count > 0) { dynObject._CategoryPath = _categoryService.Value.GetCategoryPath( @@ -621,13 +634,8 @@ private dynamic ToDynamic( productCategories.OrderBy(x => x.DisplayOrder).FirstOrDefault() ); } - else - { - dynObject._CategoryPath = null; - } ToDeliveryTime(ctx, dynObject, product.DeliveryTimeId); - ToQuantityUnit(ctx, dynObject, product.QuantityUnitId); dynObject.ProductPictures = productPictures diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Export/_Tab.Deployment.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Export/_Tab.Deployment.cshtml index 1db883b2d3..d77bc3cf54 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Export/_Tab.Deployment.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Export/_Tab.Deployment.cshtml @@ -104,7 +104,7 @@ {
- @T("Admin.DataExchange.Export.NoProfiles") + @T("Admin.DataExchange.Export.Deployment.NoProfiles")
} From 59186e1f3520cb43887e048cb7b4068a8d1fc254 Mon Sep 17 00:00:00 2001 From: Michael-Herzog Date: Tue, 21 Jun 2016 11:20:14 +0200 Subject: [PATCH 33/73] Update README.md Updated link to new website --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d3402dc825..a7a83aee3a 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ A comprehensive set of tools for CRM & CMS, sales, marketing, payment & shipping The state-of-the-art architecture of SmartStore.NET - with `ASP.NET 4.5` + `MVC 5`, `Entity Framework 6` and Domain Driven Design approach - makes it easy to extend, extremely flexible and essentially fun to work with ;-) -* **Website:** [http://www.smartstore.com/net](http://www.smartstore.com/net) +* **Website:** [http://www.smartstore.com/en/net](http://www.smartstore.com/en/net) * **Forum:** [http://community.smartstore.com](http://community.smartstore.com) * **Marketplace:** [http://community.smartstore.com/marketplace](http://community.smartstore.com/marketplace) * **Documentation:** [SmartStore.NET Documentation in English](http://docs.smartstore.com/display/SMNET/SmartStore.NET+Documentation+Home) From d604fd1b244e07593bfa81dc2f837fc69b6d8682 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Tue, 21 Jun 2016 11:35:24 +0200 Subject: [PATCH 34/73] Duplicate entry in changelog --- changelog.md | 1 - 1 file changed, 1 deletion(-) diff --git a/changelog.md b/changelog.md index 480d9476d6..db0febbc6f 100644 --- a/changelog.md +++ b/changelog.md @@ -10,7 +10,6 @@ * #979 Implement BeezUP product feed ### New Features -* #637 Integrated PayPal PLUS payment Provider * #961 Fix "Open Redirection Vulnerability" * #571 Option to display another checkbox on confirm page to let the customer accept that his email address can be handed over to a third party * #870 Implement address import for customers (both billing & shipping address) From 30713d24ba65b31babf271cb688b09e933dedc3c Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Tue, 21 Jun 2016 15:13:31 +0200 Subject: [PATCH 35/73] Enabled import context to accept strings as progress messages --- .../Import/ImportExecuteContext.cs | 14 ++++++++++++++ .../Administration/Content/admin.less | 6 ++++++ .../Views/Export/InfoProfile.cshtml | 18 +++++++++--------- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportExecuteContext.cs b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportExecuteContext.cs index 67e3c090a1..70170c0fd3 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Import/ImportExecuteContext.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Import/ImportExecuteContext.cs @@ -209,5 +209,19 @@ public void SetProgress(int value, int maximum) } catch { } } + + /// + /// Allows to set a message + /// + /// Message to display + public void SetProgress(string message) + { + try + { + if (_progressValueSetter != null && message.HasValue()) + _progressValueSetter.Invoke(0, 0, message); + } + catch { } + } } } diff --git a/src/Presentation/SmartStore.Web/Administration/Content/admin.less b/src/Presentation/SmartStore.Web/Administration/Content/admin.less index c31aff72bc..5483f5971f 100644 --- a/src/Presentation/SmartStore.Web/Administration/Content/admin.less +++ b/src/Presentation/SmartStore.Web/Administration/Content/admin.less @@ -1580,6 +1580,8 @@ table.payment-method-features td { } + + /* Data exchange -------------------------------------------------------------- */ .profile-list { @@ -1587,6 +1589,10 @@ table.payment-method-features td { border-bottom: 1px solid #ddd; } +.info-profile td { + padding-top: 20px; +} + /* Import column mapping -------------------------------------------------------------- */ @media (max-width: 1280px) { diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Export/InfoProfile.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Export/InfoProfile.cshtml index 54799e977b..912809feb9 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Export/InfoProfile.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Export/InfoProfile.cshtml @@ -16,15 +16,15 @@ } @foreach (var profile in Model.Profiles) { - - - @Html.SmartLabelFor(m => m.Profiles) - - -
- @profile.Name - - + + + @Html.SmartLabelFor(m => m.Profiles) + + + + @profile.Name + + if (profile.ScheduleTaskId.HasValue) { From e10d4f8c6cebc36bac0626f10a7a54dd7590d74c Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Tue, 21 Jun 2016 15:33:32 +0200 Subject: [PATCH 36/73] Removed promotion feeds node from admin menu --- src/Plugins/SmartStore.GoogleMerchantCenter/AdminMenu.cs | 6 +----- .../SmartStore.Web/Administration/sitemap.config | 1 - 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/AdminMenu.cs b/src/Plugins/SmartStore.GoogleMerchantCenter/AdminMenu.cs index b6c3684093..2dbc226f57 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/AdminMenu.cs +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/AdminMenu.cs @@ -7,17 +7,13 @@ public class AdminMenu : AdminMenuProvider { protected override void BuildMenuCore(TreeNode pluginsNode) { - var root = pluginsNode.SelectNode(x => x.Value.Id == "promotion-feeds"); - if (root == null) - return; - var menuItem = new MenuItem().ToBuilder() .Text("Google Merchant Center") .ResKey("Plugins.FriendlyName.SmartStore.GoogleMerchantCenter") .Action("ConfigurePlugin", "Plugin", new { systemName = GoogleMerchantCenterFeedPlugin.SystemName, area = "Admin" }) .ToItem(); - root.Append(menuItem); + pluginsNode.Prepend(menuItem); } } diff --git a/src/Presentation/SmartStore.Web/Administration/sitemap.config b/src/Presentation/SmartStore.Web/Administration/sitemap.config index 179ac3a5c4..a1501d7653 100644 --- a/src/Presentation/SmartStore.Web/Administration/sitemap.config +++ b/src/Presentation/SmartStore.Web/Administration/sitemap.config @@ -147,7 +147,6 @@ - From 3b58ca04740eeaeb10239063d2e80f9fafeb2db4 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Tue, 21 Jun 2016 20:32:20 +0200 Subject: [PATCH 37/73] Cart and mini cart should not have different item order --- .../Customers/CustomerExtentions.cs | 11 ++++++----- .../Controllers/ShoppingCartController.cs | 3 +-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Libraries/SmartStore.Services/Customers/CustomerExtentions.cs b/src/Libraries/SmartStore.Services/Customers/CustomerExtentions.cs index 719f144ed5..a3525e9cac 100644 --- a/src/Libraries/SmartStore.Services/Customers/CustomerExtentions.cs +++ b/src/Libraries/SmartStore.Services/Customers/CustomerExtentions.cs @@ -287,14 +287,15 @@ public static int CountProductsInCart(this Customer customer, ShoppingCartType c return count; } - public static List GetCartItems(this Customer customer, ShoppingCartType cartType, int? storeId = null, bool orderById = false) + + public static List GetCartItems(this Customer customer, ShoppingCartType cartType, int? storeId = null) { var rawItems = customer.ShoppingCartItems.Filter(cartType, storeId); - if (orderById) - rawItems = rawItems.OrderByDescending(x => x.Id); - - var organizedItems = rawItems.ToList().Organize(); + var organizedItems = rawItems + .OrderByDescending(x => x.Id) + .ToList() + .Organize(); return organizedItems.ToList(); } diff --git a/src/Presentation/SmartStore.Web/Controllers/ShoppingCartController.cs b/src/Presentation/SmartStore.Web/Controllers/ShoppingCartController.cs index f194738cb8..e4ff2cb6a7 100644 --- a/src/Presentation/SmartStore.Web/Controllers/ShoppingCartController.cs +++ b/src/Presentation/SmartStore.Web/Controllers/ShoppingCartController.cs @@ -996,7 +996,6 @@ protected MiniShoppingCartModel PrepareMiniShoppingCartModel() //products. sort descending (recently added products) foreach (var sci in cart - .OrderByDescending(x => x.Item.Id) .Take(_shoppingCartSettings.MiniShoppingCartProductNumber) .ToList()) { @@ -2633,7 +2632,7 @@ public ActionResult FlyoutWishlist() { Customer customer = _workContext.CurrentCustomer; - var cart = customer.GetCartItems(ShoppingCartType.Wishlist, _storeContext.CurrentStore.Id, true); + var cart = customer.GetCartItems(ShoppingCartType.Wishlist, _storeContext.CurrentStore.Id); var model = new WishlistModel(); PrepareWishlistModel(model, cart, true); From ee9a7c0ba9da185fc6fa98032102f5483e697a01 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Tue, 21 Jun 2016 21:41:02 +0200 Subject: [PATCH 38/73] Minor perf improvement --- .../Discounts/DiscountService.cs | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/Libraries/SmartStore.Services/Discounts/DiscountService.cs b/src/Libraries/SmartStore.Services/Discounts/DiscountService.cs index 9b75b86e8b..b973e84153 100644 --- a/src/Libraries/SmartStore.Services/Discounts/DiscountService.cs +++ b/src/Libraries/SmartStore.Services/Discounts/DiscountService.cs @@ -12,6 +12,7 @@ using SmartStore.Services.Customers; using SmartStore.Services.Common; using SmartStore.Services.Configuration; +using SmartStore.Services.Orders; namespace SmartStore.Services.Discounts { @@ -317,18 +318,18 @@ public virtual bool IsDiscountValid(Discount discount, Customer customer, string } //check date range - DateTime now = DateTime.UtcNow; - int storeId = _storeContext.CurrentStore.Id; + var now = DateTime.UtcNow; + var store = _storeContext.CurrentStore; if (discount.StartDateUtc.HasValue) { - DateTime startDate = DateTime.SpecifyKind(discount.StartDateUtc.Value, DateTimeKind.Utc); + var startDate = DateTime.SpecifyKind(discount.StartDateUtc.Value, DateTimeKind.Utc); if (startDate.CompareTo(now) > 0) return false; } if (discount.EndDateUtc.HasValue) { - DateTime endDate = DateTime.SpecifyKind(discount.EndDateUtc.Value, DateTimeKind.Utc); + var endDate = DateTime.SpecifyKind(discount.EndDateUtc.Value, DateTimeKind.Utc); if (endDate.CompareTo(now) < 0) return false; } @@ -336,33 +337,36 @@ public virtual bool IsDiscountValid(Discount discount, Customer customer, string if (!CheckDiscountLimitations(discount, customer)) return false; - // discount requirements - var requirements = discount.DiscountRequirements; + // better not to apply discounts if there are gift cards in the cart cause the customer could "earn" money through that. + if (discount.DiscountType == DiscountType.AssignedToOrderTotal || discount.DiscountType == DiscountType.AssignedToOrderSubTotal) + { + var cart = customer.ShoppingCartItems + .Filter(ShoppingCartType.ShoppingCart, store.Id) + .ToList(); + + if (cart.Any(x => x.Product.IsGiftCard)) + return false; + } + + // discount requirements + var requirements = discount.DiscountRequirements; foreach (var req in requirements) { - var requirementRule = LoadDiscountRequirementRuleBySystemName(req.DiscountRequirementRuleSystemName, storeId); + var requirementRule = LoadDiscountRequirementRuleBySystemName(req.DiscountRequirementRuleSystemName, store.Id); if (requirementRule == null) continue; - var request = new CheckDiscountRequirementRequest() + var request = new CheckDiscountRequirementRequest { DiscountRequirement = req, Customer = customer, - Store = _storeContext.CurrentStore + Store = store }; + if (!requirementRule.Value.CheckRequirement(request)) return false; } - // better not to apply discounts if there are gift cards in the cart cause the customer could "earn" money through that. - if (discount.DiscountType == DiscountType.AssignedToOrderTotal || discount.DiscountType == DiscountType.AssignedToOrderSubTotal) - { - var cart = customer.GetCartItems(ShoppingCartType.ShoppingCart, storeId); - - if (cart.Any(x => x.Item.Product.IsGiftCard)) - return false; - } - return true; } From 2a8f648f10e106ac5a0e367827fb260b965ec1f9 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Wed, 22 Jun 2016 11:38:15 +0200 Subject: [PATCH 39/73] Discount rule has spent amount including sub total option can cause wrong discount calculation if the cart contains a product several times --- changelog.md | 1 + .../Discounts/DiscountService.cs | 3 +- .../SmartStore.DiscountRules/Description.txt | 2 +- .../Providers/HadSpentAmountRule.cs | 54 +++++++++++++------ 4 files changed, 43 insertions(+), 17 deletions(-) diff --git a/changelog.md b/changelog.md index db0febbc6f..097390ed9d 100644 --- a/changelog.md +++ b/changelog.md @@ -60,6 +60,7 @@ * Private messages: Fixes "No route in the route table matches the supplied values" * Payone: Hash string incorrect for frontend API payments where the order has more than 9 products * Export mail notification: Download link not working if SSL is enabled +* Discount rule has spent amount including sub total option can cause wrong discount calculation if the cart contains a product several times ## SmartStore.NET 2.5 diff --git a/src/Libraries/SmartStore.Services/Discounts/DiscountService.cs b/src/Libraries/SmartStore.Services/Discounts/DiscountService.cs index b973e84153..ffa0fa2615 100644 --- a/src/Libraries/SmartStore.Services/Discounts/DiscountService.cs +++ b/src/Libraries/SmartStore.Services/Discounts/DiscountService.cs @@ -363,7 +363,8 @@ public virtual bool IsDiscountValid(Discount discount, Customer customer, string Store = store }; - if (!requirementRule.Value.CheckRequirement(request)) + // TODO: cache result... CheckRequirement is very often called + if (!requirementRule.Value.CheckRequirement(request)) return false; } diff --git a/src/Plugins/SmartStore.DiscountRules/Description.txt b/src/Plugins/SmartStore.DiscountRules/Description.txt index 2a17b4fcd9..a2336d8b8e 100644 --- a/src/Plugins/SmartStore.DiscountRules/Description.txt +++ b/src/Plugins/SmartStore.DiscountRules/Description.txt @@ -2,7 +2,7 @@ Description: Contains common discount requirement rule providers like "Billing country is", "Customer role is", "Had spent amount" etc. Group: Marketing SystemName: SmartStore.DiscountRules -Version: 2.5.0 +Version: 2.5.0.1 MinAppVersion: 2.5.0 DisplayOrder: 0 FileName: SmartStore.DiscountRules.dll diff --git a/src/Plugins/SmartStore.DiscountRules/Providers/HadSpentAmountRule.cs b/src/Plugins/SmartStore.DiscountRules/Providers/HadSpentAmountRule.cs index b67d2a7efd..69d7f2614b 100644 --- a/src/Plugins/SmartStore.DiscountRules/Providers/HadSpentAmountRule.cs +++ b/src/Plugins/SmartStore.DiscountRules/Providers/HadSpentAmountRule.cs @@ -1,15 +1,16 @@ using System; +using System.Collections.Generic; using System.Linq; +using Newtonsoft.Json; using SmartStore.Core.Domain.Orders; +using SmartStore.Core.Logging; using SmartStore.Core.Plugins; -using SmartStore.Services.Discounts; +using SmartStore.DiscountRules.Settings; +using SmartStore.Services.Catalog; using SmartStore.Services.Customers; +using SmartStore.Services.Discounts; using SmartStore.Services.Orders; -using SmartStore.Services.Catalog; using SmartStore.Services.Tax; -using SmartStore.Core.Localization; -using SmartStore.DiscountRules.Settings; -using Newtonsoft.Json; namespace SmartStore.DiscountRules { @@ -21,15 +22,18 @@ public partial class HadSpentAmountRule : DiscountRequirementRuleBase private readonly IOrderService _orderService; private readonly IPriceCalculationService _priceCalculationService; private readonly ITaxService _taxService; + private readonly ILogger _logger; public HadSpentAmountRule( IOrderService orderService, IPriceCalculationService priceCalculationService, - ITaxService taxService) + ITaxService taxService, + ILogger logger) { - this._orderService = orderService; - this._priceCalculationService = priceCalculationService; - this._taxService = taxService; + _orderService = orderService; + _priceCalculationService = priceCalculationService; + _taxService = taxService; + _logger = logger; } public override bool CheckRequirement(CheckDiscountRequirementRequest request) @@ -88,14 +92,34 @@ private bool CheckTotalHistoryRequirement(CheckDiscountRequirementRequest reques private bool CheckCurrentSubTotalRequirement(CheckDiscountRequirementRequest request) { - var cartItems = request.Customer.GetCartItems(ShoppingCartType.ShoppingCart, request.Store.Id); + var spentAmount = decimal.Zero; - decimal spentAmount = decimal.Zero; - decimal taxRate = decimal.Zero; - foreach (var sci in cartItems) + try { - // includeDiscounts == true produces a stack overflow! - spentAmount += sci.Item.Quantity * _taxService.GetProductPrice(sci.Item.Product, _priceCalculationService.GetUnitPrice(sci, false), out taxRate); + var taxRate = decimal.Zero; + var cartItems = request.Customer.GetCartItems(ShoppingCartType.ShoppingCart, request.Store.Id); + + foreach (var cartItem in cartItems) + { + var product = cartItem.Item.Product; + Dictionary mergedValuesClone = null; + + // we must reapply merged values because CheckCurrentSubTotalRequirement uses price calculation and is called by it itself. + // this can cause wrong discount calculation if the cart contains a product several times. + if (product.MergedDataValues != null) + mergedValuesClone = new Dictionary(product.MergedDataValues); + + // includeDiscounts == true produces a stack overflow! + spentAmount += cartItem.Item.Quantity * _taxService.GetProductPrice(product, _priceCalculationService.GetUnitPrice(cartItem, false), out taxRate); + + if (mergedValuesClone != null) + product.MergedDataValues = new Dictionary(mergedValuesClone); + } + } + catch (Exception exception) + { + _logger.Error(exception); + return false; } return spentAmount >= request.DiscountRequirement.SpentAmount; From c3753153b07b91e2cf0fbf0122f1eaf0a4509959 Mon Sep 17 00:00:00 2001 From: Murat Cakir Date: Wed, 22 Jun 2016 18:11:46 +0200 Subject: [PATCH 40/73] CronExpression.GetFriendlyDescription() should not throw exception when expression is empty --- .../SmartStore.Services/Tasks/CronExpression.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Libraries/SmartStore.Services/Tasks/CronExpression.cs b/src/Libraries/SmartStore.Services/Tasks/CronExpression.cs index 25243b0ad5..c35b4b7128 100644 --- a/src/Libraries/SmartStore.Services/Tasks/CronExpression.cs +++ b/src/Libraries/SmartStore.Services/Tasks/CronExpression.cs @@ -59,14 +59,16 @@ public static string GetFriendlyDescription(string expression) Use24HourTimeFormat = Thread.CurrentThread.CurrentUICulture.DateTimeFormat.AMDesignator.IsEmpty() }; - try - { - return ExpressionDescriptor.GetDescription(expression, options); - } - catch + if (expression.HasValue()) { - return null; + try + { + return ExpressionDescriptor.GetDescription(expression, options); + } + catch { } } + + return "?"; } } From ecc787a1ad4ec3e02b369ac1b8651852c5c39831 Mon Sep 17 00:00:00 2001 From: Murat Cakir Date: Wed, 22 Jun 2016 18:33:35 +0200 Subject: [PATCH 41/73] Updated changelog --- changelog.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/changelog.md b/changelog.md index 097390ed9d..8efe9bbc11 100644 --- a/changelog.md +++ b/changelog.md @@ -1,13 +1,14 @@ # Release Notes -## SmartStore.NET 2.5.1 +## SmartStore.NET 2.6 ### Highlights -* Major improvements in Importer: better field mapping, higher performance, bug fixes etc. -* #637 Integrated PayPal PLUS payment provider -* #932 Implement paydirekt payment plugin -* New Viveum payment plugin -* #979 Implement BeezUP product feed +* Major improvements in Importer & Exporter: better field mapping, higher performance, bug fixes etc. +* 'PayPal PLUS' payment plugin +* 'paydirekt' payment plugin +* 'Viveum' payment plugin +* 'BeezUP' export provider +* (Dev) Publishing SmartStore.Web from within Visual Studio now deploys the project correctly. No need to execute ClickToBuild.cmd anymore. Just publish directly to any target, including Azure. ### New Features * #961 Fix "Open Redirection Vulnerability" From c2ef0419896c0cc383dc327dca8afe94266f3cf5 Mon Sep 17 00:00:00 2001 From: Murat Cakir Date: Wed, 22 Jun 2016 18:58:07 +0200 Subject: [PATCH 42/73] Updated ua-parser-regexes.yaml --- .../App_Data/ua-parser.regexes.yaml | 53 +++++++++++++++---- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/src/Presentation/SmartStore.Web/App_Data/ua-parser.regexes.yaml b/src/Presentation/SmartStore.Web/App_Data/ua-parser.regexes.yaml index 6ef74a0d89..c160ade711 100644 --- a/src/Presentation/SmartStore.Web/App_Data/ua-parser.regexes.yaml +++ b/src/Presentation/SmartStore.Web/App_Data/ua-parser.regexes.yaml @@ -17,6 +17,10 @@ user_agent_parsers: - regex: 'Google.*/\+/web/snippet' family_replacement: 'GooglePlusBot' + # Twitter + - regex: '(Twitterbot)/(\d+)\.(\d+)' + family_replacement: 'TwitterBot' + # Bots Pattern '/name-0.0' - regex: '/((?:Ant-)?Nutch|[A-z]+[Bb]ot|[A-z]+[Ss]pider|Axtaris|fetchurl|Isara|ShopSalad|Tailsweep)[ \-](\d+)(?:\.(\d+)(?:\.(\d+))?)?' # Bots Pattern 'name/0.0' @@ -106,7 +110,7 @@ user_agent_parsers: # Opera will stop at 9.80 and hide the real version in the Version string. # see: http://dev.opera.com/articles/view/opera-ua-string-changes/ - regex: '(Opera Tablet).*Version/(\d+)\.(\d+)(?:\.(\d+))?' - - regex: '(Opera Mini)(?:/att)?/(\d+)?(?:\.(\d+))?(?:\.(\d+))?' + - regex: '(Opera Mini)(?:/att)?/?(\d+)?(?:\.(\d+))?(?:\.(\d+))?' - regex: '(Opera)/.+Opera Mobi.+Version/(\d+)\.(\d+)' family_replacement: 'Opera Mobile' - regex: '(Opera)/(\d+)\.(\d+).+Opera Mobi' @@ -205,6 +209,10 @@ user_agent_parsers: - regex: 'Windows Phone .*(Edge)/(\d+)\.(\d+)' family_replacement: 'Edge Mobile' + # Samsung Internet (based on Chrome, but lacking some features) + - regex: '(SamsungBrowser)/(\d+)\.(\d+)' + family_replacement: 'Samsung Internet' + # Chrome Mobile - regex: '(CrMo)/(\d+)\.(\d+)\.(\d+)\.(\d+)' family_replacement: 'Chrome Mobile' @@ -272,12 +280,12 @@ user_agent_parsers: - regex: '(AdobeAIR|FireWeb|Jasmine|ANTGalio|Midori|Fresco|Lobo|PaleMoon|Maxthon|Lynx|OmniWeb|Dillo|Camino|Demeter|Fluid|Fennec|Epiphany|Shiira|Sunrise|Spotify|Flock|Netscape|Lunascape|WebPilot|NetFront|Netfront|Konqueror|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|Opera Mini|iCab|NetNewsWire|ThunderBrowse|Iris|UP\.Browser|Bunjalloo|Google Earth|Raven for Mac|Openwave)/(\d+)\.(\d+)\.(\d+)' # Outlook 2007 - - regex: 'MSOffice 12' + - regex: 'Microsoft Office Outlook 12\.\d+\.\d+|MSOffice 12' family_replacement: 'Outlook' v1_replacement: '2007' # Outlook 2010 - - regex: 'MSOffice 14' + - regex: 'Microsoft Outlook 14\.\d+\.\d+|MSOffice 14' family_replacement: 'Outlook' v1_replacement: '2010' @@ -286,6 +294,15 @@ user_agent_parsers: family_replacement: 'Outlook' v1_replacement: '2013' + # Outlook 2016 + - regex: 'Microsoft Outlook (?:Mail )?16\.\d+\.\d+' + family_replacement: 'Outlook' + v1_replacement: '2016' + + # Windows Live Mail + - regex: 'Outlook-Express\/7\.0.*' + family_replacement: 'Windows Live Mail' + # Apple Air Mail - regex: '(Airmail) (\d+)\.(\d+)(?:\.(\d+))?' @@ -299,6 +316,10 @@ user_agent_parsers: # Edge/major_version.minor_version - regex: '(Edge)/(\d+)\.(\d+)' + # Brave Browser https://brave.com/ + - regex: '(brave)/(\d+)\.(\d+)\.(\d+) Chrome' + family_replacement: 'Brave' + # Chrome/Chromium/major_version.minor_version.beta_version - regex: '(Chromium|Chrome)/(\d+)\.(\d+)\.(\d+)' @@ -388,15 +409,15 @@ user_agent_parsers: - regex: '(iPod|iPhone|iPad).+Version/(\d+)\.(\d+)(?:\.(\d+))?.* Safari' family_replacement: 'Mobile Safari' - regex: '(iPod|iPhone|iPad).+Version/(\d+)\.(\d+)(?:\.(\d+))?' - family_replacement: 'Mobile Safari UIWebView' + family_replacement: 'Mobile Safari UI/WKWebView' - regex: '(iPod|iPhone|iPad);.*CPU.*OS (\d+)_(\d+)(?:_(\d+))?.*Mobile.* Safari' family_replacement: 'Mobile Safari' - regex: '(iPod|iPhone|iPad);.*CPU.*OS (\d+)_(\d+)(?:_(\d+))?.*Mobile' - family_replacement: 'Mobile Safari UIWebView' + family_replacement: 'Mobile Safari UI/WKWebView' - regex: '(iPod|iPhone|iPad).* Safari' family_replacement: 'Mobile Safari' - regex: '(iPod|iPhone|iPad)' - family_replacement: 'Mobile Safari UIWebView' + family_replacement: 'Mobile Safari UI/WKWebView' - regex: '(AvantGo) (\d+).(\d+)' @@ -498,7 +519,7 @@ user_agent_parsers: # apple mail - not directly detectable, have it after Safari stuff - regex: '(AppleWebKit)/(\d+)\.(\d+)\.(\d+)' - family_replacement: 'AppleMail' + family_replacement: 'Apple Mail' # AFTER THE EDGE CASES ABOVE! # AFTER IE11 @@ -514,6 +535,9 @@ user_agent_parsers: - regex: '(Java)[/ ]{0,1}\d+\.(\d+)\.(\d+)[_-]*([a-zA-Z0-9]+)*' + # Roku Digital-Video-Players https://www.roku.com/ + - regex: '^(Roku)/DVP-(\d+)\.(\d+)' + os_parsers: ########## # HbbTV vendors @@ -981,6 +1005,9 @@ os_parsers: - regex: 'SunOS' os_replacement: 'Solaris' + # Roku Digital-Video-Players https://www.roku.com/ + - regex: '^(Roku)/DVP-(\d+)\.(\d+)' + device_parsers: ######### @@ -2049,7 +2076,7 @@ device_parsers: device_replacement: 'Huawei Ideos$1' brand_replacement: 'Huawei' model_replacement: 'Ideos$1' - - regex: '; *(Orange Daytona|Pulse|Pulse Mini|Vodafone 858|C8500|C8600|C8650|C8660) Build' + - regex: '; *(Orange Daytona|Pulse|Pulse Mini|Vodafone 858|C8500|C8600|C8650|C8660|Nexus 6P) Build' device_replacement: 'Huawei $1' brand_replacement: 'Huawei' model_replacement: '$1' @@ -2571,7 +2598,7 @@ device_parsers: # LG # @ref: http://www.lg.com/uk/mobile ######### - - regex: '; *(E[34][0-9]{2}|LS[6-8][0-9]{2}|VS[6-9][0-9]+[^;/]+|Nexus [45]|GT540f?|Optimus (?:2X|G|4X HD)|OptimusX4HD) *(?:Build|;)' + - regex: '; *(E[34][0-9]{2}|LS[6-8][0-9]{2}|VS[6-9][0-9]+[^;/]+|Nexus 4|Nexus 5X?|GT540f?|Optimus (?:2X|G|4X HD)|OptimusX4HD) *(?:Build|;)' device_replacement: '$1' brand_replacement: 'LG' model_replacement: '$1' @@ -3841,7 +3868,7 @@ device_parsers: # XiaoMi # @ref: http://www.xiaomi.com/event/buyphone ######### - - regex: '; *((MI|HM|MI-ONE|Redmi)[ -](NOTE |Note )?[^;/]*) Build/' + - regex: '; *((MI|HM|MI-ONE|Redmi)[ -](NOTE |Note )?[^;/]*) (Build|MIUI)/' device_replacement: 'XiaoMi $1' brand_replacement: 'XiaoMi' model_replacement: '$1' @@ -4700,6 +4727,10 @@ device_parsers: - regex: '(WebTV)/\d+.\d+' brand_replacement: 'Generic_Inettv' model_replacement: '$1' + # Roku Digital-Video-Players https://www.roku.com/ + - regex: '^(Roku)/DVP-\d+\.\d+' + brand_replacement: 'Generic_Inettv' + model_replacement: '$1' ########## # Generic Tablet @@ -4764,4 +4795,4 @@ device_parsers: regex_flag: 'i' device_replacement: 'Generic Feature Phone' brand_replacement: 'Generic' - model_replacement: 'Feature Phone' + model_replacement: 'Feature Phone' \ No newline at end of file From 97918a561971ee21cbf3b888f50458f108efaec0 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Wed, 22 Jun 2016 22:24:04 +0200 Subject: [PATCH 43/73] Resolves #986 File uploads possible through /content/filemanager/index.html --- changelog.md | 1 + .../Content/filemanager/LICENSE.txt | 0 .../Content/filemanager/conf.json | 33 + .../css/images/animated-overlay.gif | Bin .../css/images/ui-bg_flat_0_aaaaaa_40x100.png | Bin .../images/ui-bg_flat_75_ffffff_40x100.png | Bin .../images/ui-bg_glass_55_fbf9ee_1x400.png | Bin .../images/ui-bg_glass_65_ffffff_1x400.png | Bin .../images/ui-bg_glass_75_dadada_1x400.png | Bin .../images/ui-bg_glass_75_e6e6e6_1x400.png | Bin .../images/ui-bg_glass_95_fef1ec_1x400.png | Bin .../ui-bg_highlight-soft_75_cccccc_1x100.png | Bin .../css/images/ui-icons_222222_256x240.png | Bin .../css/images/ui-icons_2e83ff_256x240.png | Bin .../css/images/ui-icons_454545_256x240.png | Bin .../css/images/ui-icons_888888_256x240.png | Bin .../css/images/ui-icons_cd0a0a_256x240.png | Bin .../css/jquery-ui-1.10.4.custom.css | 0 .../css/jquery-ui-1.10.4.custom.min.css | 0 .../Content/filemanager/css/main.css | 0 .../Content/filemanager/css/main.min.css | 0 .../images/action-folder-paste.png | Bin .../images/action-folder-rename.png | Bin .../Content/filemanager/images/arrow_down.png | Bin .../Content/filemanager/images/arrow_up.png | Bin .../Content/filemanager/images/blank.gif | Bin .../Content/filemanager/images/copy.png | Bin .../Content/filemanager/images/cut.png | Bin .../Content/filemanager/images/dir-minus.png | Bin .../Content/filemanager/images/dir-plus.png | Bin .../Content/filemanager/images/file-add.png | Bin .../filemanager/images/file-delete.png | Bin .../filemanager/images/file-download.png | Bin .../filemanager/images/file-duplicate.png | Bin .../filemanager/images/file-upload.png | Bin .../filetypes/big/file_extension_3gp.png | Bin .../filetypes/big/file_extension_7z.png | Bin .../filetypes/big/file_extension_ace.png | Bin .../filetypes/big/file_extension_ai.png | Bin .../filetypes/big/file_extension_aif.png | Bin .../filetypes/big/file_extension_aiff.png | Bin .../filetypes/big/file_extension_amr.png | Bin .../filetypes/big/file_extension_asf.png | Bin .../filetypes/big/file_extension_asx.png | Bin .../filetypes/big/file_extension_bat.png | Bin .../filetypes/big/file_extension_bin.png | Bin .../filetypes/big/file_extension_bmp.png | Bin .../filetypes/big/file_extension_bup.png | Bin .../filetypes/big/file_extension_cab.png | Bin .../filetypes/big/file_extension_cbr.png | Bin .../filetypes/big/file_extension_cda.png | Bin .../filetypes/big/file_extension_cdl.png | Bin .../filetypes/big/file_extension_cdr.png | Bin .../filetypes/big/file_extension_chm.png | Bin .../filetypes/big/file_extension_dat.png | Bin .../filetypes/big/file_extension_divx.png | Bin .../filetypes/big/file_extension_dll.png | Bin .../filetypes/big/file_extension_dmg.png | Bin .../filetypes/big/file_extension_doc.png | Bin .../filetypes/big/file_extension_dss.png | Bin .../filetypes/big/file_extension_dvf.png | Bin .../filetypes/big/file_extension_dwg.png | Bin .../filetypes/big/file_extension_eml.png | Bin .../filetypes/big/file_extension_eps.png | Bin .../filetypes/big/file_extension_exe.png | Bin .../filetypes/big/file_extension_fla.png | Bin .../filetypes/big/file_extension_flv.png | Bin .../filetypes/big/file_extension_gif.png | Bin .../filetypes/big/file_extension_gz.png | Bin .../filetypes/big/file_extension_hqx.png | Bin .../filetypes/big/file_extension_htm.png | Bin .../filetypes/big/file_extension_html.png | Bin .../filetypes/big/file_extension_ifo.png | Bin .../filetypes/big/file_extension_indd.png | Bin .../filetypes/big/file_extension_iso.png | Bin .../filetypes/big/file_extension_jar.png | Bin .../filetypes/big/file_extension_jpeg.png | Bin .../filetypes/big/file_extension_jpg.png | Bin .../filetypes/big/file_extension_lnk.png | Bin .../filetypes/big/file_extension_log.png | Bin .../filetypes/big/file_extension_m4a.png | Bin .../filetypes/big/file_extension_m4b.png | Bin .../filetypes/big/file_extension_m4p.png | Bin .../filetypes/big/file_extension_m4v.png | Bin .../filetypes/big/file_extension_mcd.png | Bin .../filetypes/big/file_extension_mdb.png | Bin .../filetypes/big/file_extension_mid.png | Bin .../filetypes/big/file_extension_mov.png | Bin .../filetypes/big/file_extension_mp2.png | Bin .../filetypes/big/file_extension_mp4.png | Bin .../filetypes/big/file_extension_mpeg.png | Bin .../filetypes/big/file_extension_mpg.png | Bin .../filetypes/big/file_extension_msi.png | Bin .../filetypes/big/file_extension_mswmm.png | Bin .../filetypes/big/file_extension_ogg.png | Bin .../filetypes/big/file_extension_pdf.png | Bin .../filetypes/big/file_extension_png.png | Bin .../filetypes/big/file_extension_pps.png | Bin .../filetypes/big/file_extension_ps.png | Bin .../filetypes/big/file_extension_psd.png | Bin .../filetypes/big/file_extension_pst.png | Bin .../filetypes/big/file_extension_ptb.png | Bin .../filetypes/big/file_extension_pub.png | Bin .../filetypes/big/file_extension_qbb.png | Bin .../filetypes/big/file_extension_qbw.png | Bin .../filetypes/big/file_extension_qxd.png | Bin .../filetypes/big/file_extension_ram.png | Bin .../filetypes/big/file_extension_rar.png | Bin .../filetypes/big/file_extension_rm.png | Bin .../filetypes/big/file_extension_rmvb.png | Bin .../filetypes/big/file_extension_rtf.png | Bin .../filetypes/big/file_extension_sea.png | Bin .../filetypes/big/file_extension_ses.png | Bin .../filetypes/big/file_extension_sit.png | Bin .../filetypes/big/file_extension_sitx.png | Bin .../filetypes/big/file_extension_ss.png | Bin .../filetypes/big/file_extension_swf.png | Bin .../filetypes/big/file_extension_tgz.png | Bin .../filetypes/big/file_extension_thm.png | Bin .../filetypes/big/file_extension_tif.png | Bin .../filetypes/big/file_extension_tmp.png | Bin .../filetypes/big/file_extension_torrent.png | Bin .../filetypes/big/file_extension_ttf.png | Bin .../filetypes/big/file_extension_txt.png | Bin .../filetypes/big/file_extension_vcd.png | Bin .../filetypes/big/file_extension_vob.png | Bin .../filetypes/big/file_extension_wav.png | Bin .../filetypes/big/file_extension_wma.png | Bin .../filetypes/big/file_extension_wmv.png | Bin .../filetypes/big/file_extension_wps.png | Bin .../filetypes/big/file_extension_xls.png | Bin .../filetypes/big/file_extension_xpi.png | Bin .../filetypes/big/file_extension_zip.png | Bin .../images/filetypes/big/unknown.png | Bin .../images/filetypes/file_extension_3gp.png | Bin .../images/filetypes/file_extension_7z.png | Bin .../images/filetypes/file_extension_ace.png | Bin .../images/filetypes/file_extension_ai.png | Bin .../images/filetypes/file_extension_aif.png | Bin .../images/filetypes/file_extension_aiff.png | Bin .../images/filetypes/file_extension_amr.png | Bin .../images/filetypes/file_extension_asf.png | Bin .../images/filetypes/file_extension_asx.png | Bin .../images/filetypes/file_extension_bat.png | Bin .../images/filetypes/file_extension_bin.png | Bin .../images/filetypes/file_extension_bmp.png | Bin .../images/filetypes/file_extension_bup.png | Bin .../images/filetypes/file_extension_cab.png | Bin .../images/filetypes/file_extension_cbr.png | Bin .../images/filetypes/file_extension_cda.png | Bin .../images/filetypes/file_extension_cdl.png | Bin .../images/filetypes/file_extension_cdr.png | Bin .../images/filetypes/file_extension_chm.png | Bin .../images/filetypes/file_extension_dat.png | Bin .../images/filetypes/file_extension_divx.png | Bin .../images/filetypes/file_extension_dll.png | Bin .../images/filetypes/file_extension_dmg.png | Bin .../images/filetypes/file_extension_doc.png | Bin .../images/filetypes/file_extension_dss.png | Bin .../images/filetypes/file_extension_dvf.png | Bin .../images/filetypes/file_extension_dwg.png | Bin .../images/filetypes/file_extension_eml.png | Bin .../images/filetypes/file_extension_eps.png | Bin .../images/filetypes/file_extension_exe.png | Bin .../images/filetypes/file_extension_fla.png | Bin .../images/filetypes/file_extension_flv.png | Bin .../images/filetypes/file_extension_gif.png | Bin .../images/filetypes/file_extension_gz.png | Bin .../images/filetypes/file_extension_hqx.png | Bin .../images/filetypes/file_extension_htm.png | Bin .../images/filetypes/file_extension_html.png | Bin .../images/filetypes/file_extension_ifo.png | Bin .../images/filetypes/file_extension_indd.png | Bin .../images/filetypes/file_extension_iso.png | Bin .../images/filetypes/file_extension_jar.png | Bin .../images/filetypes/file_extension_jpeg.png | Bin .../images/filetypes/file_extension_jpg.png | Bin .../images/filetypes/file_extension_lnk.png | Bin .../images/filetypes/file_extension_log.png | Bin .../images/filetypes/file_extension_m4a.png | Bin .../images/filetypes/file_extension_m4b.png | Bin .../images/filetypes/file_extension_m4p.png | Bin .../images/filetypes/file_extension_m4v.png | Bin .../images/filetypes/file_extension_mcd.png | Bin .../images/filetypes/file_extension_mdb.png | Bin .../images/filetypes/file_extension_mid.png | Bin .../images/filetypes/file_extension_mov.png | Bin .../images/filetypes/file_extension_mp2.png | Bin .../images/filetypes/file_extension_mp4.png | Bin .../images/filetypes/file_extension_mpeg.png | Bin .../images/filetypes/file_extension_mpg.png | Bin .../images/filetypes/file_extension_msi.png | Bin .../images/filetypes/file_extension_mswmm.png | Bin .../images/filetypes/file_extension_ogg.png | Bin .../images/filetypes/file_extension_pdf.png | Bin .../images/filetypes/file_extension_png.png | Bin .../images/filetypes/file_extension_pps.png | Bin .../images/filetypes/file_extension_ps.png | Bin .../images/filetypes/file_extension_psd.png | Bin .../images/filetypes/file_extension_pst.png | Bin .../images/filetypes/file_extension_ptb.png | Bin .../images/filetypes/file_extension_pub.png | Bin .../images/filetypes/file_extension_qbb.png | Bin .../images/filetypes/file_extension_qbw.png | Bin .../images/filetypes/file_extension_qxd.png | Bin .../images/filetypes/file_extension_ram.png | Bin .../images/filetypes/file_extension_rar.png | Bin .../images/filetypes/file_extension_rm.png | Bin .../images/filetypes/file_extension_rmvb.png | Bin .../images/filetypes/file_extension_rtf.png | Bin .../images/filetypes/file_extension_sea.png | Bin .../images/filetypes/file_extension_ses.png | Bin .../images/filetypes/file_extension_sit.png | Bin .../images/filetypes/file_extension_sitx.png | Bin .../images/filetypes/file_extension_ss.png | Bin .../images/filetypes/file_extension_swf.png | Bin .../images/filetypes/file_extension_tgz.png | Bin .../images/filetypes/file_extension_thm.png | Bin .../images/filetypes/file_extension_tif.png | Bin .../images/filetypes/file_extension_tmp.png | Bin .../filetypes/file_extension_torrent.png | Bin .../images/filetypes/file_extension_ttf.png | Bin .../images/filetypes/file_extension_txt.png | Bin .../images/filetypes/file_extension_vcd.png | Bin .../images/filetypes/file_extension_vob.png | Bin .../images/filetypes/file_extension_wav.png | Bin .../images/filetypes/file_extension_wma.png | Bin .../images/filetypes/file_extension_wmv.png | Bin .../images/filetypes/file_extension_wps.png | Bin .../images/filetypes/file_extension_xls.png | Bin .../images/filetypes/file_extension_xpi.png | Bin .../images/filetypes/file_extension_zip.png | Bin .../filemanager/images/filetypes/unknown.png | Bin .../Content/filemanager/images/find.png | Bin .../Content/filemanager/images/folder-add.png | Bin .../filemanager/images/folder-delete.png | Bin .../filemanager/images/folder-download.png | Bin .../filemanager/images/folder-green.png | Bin .../filemanager/images/folder-opened.png | Bin .../Content/filemanager/images/folder.png | Bin .../filemanager/images/loading-dir.gif | Bin .../Content/filemanager/images/loading.gif | Bin .../Content/filemanager/images/paste.png | Bin .../Content/filemanager/images/preview.png | Bin .../Content/filemanager/images/rename.png | Bin .../Content/filemanager/images/search.png | Bin .../Content/filemanager/images/select.png | Bin .../Content/filemanager/images/upload-big.png | Bin .../Content/filemanager/images/view-list.png | Bin .../Content/filemanager/images/view-tile.png | Bin .../Content/filemanager/index.html | 0 .../Content/filemanager/js/custom.js | 0 .../Content/filemanager/js/directory.js | 0 .../Content/filemanager/js/file.js | 0 .../filemanager/js/fileman-modified.zip | Bin .../Content/filemanager/js/filetypes.js | 0 .../filemanager/js/jquery-1.10.2.min.js | 0 .../filemanager/js/jquery-dateFormat.min.js | 0 .../js/jquery-ui-1.10.4.custom.min.js | 0 .../Content/filemanager/js/main.js | 0 .../Content/filemanager/js/main.min.js | 0 .../Content/filemanager/js/mini-main.js | 0 .../Content/filemanager/js/tiny_mce_popup.js | 0 .../Content/filemanager/js/utils.js | 0 .../Content/filemanager/lang/bg.json | 0 .../Content/filemanager/lang/de.json | 0 .../Content/filemanager/lang/en.json | 0 .../Content/filemanager/lang/fr.json | 0 .../Controllers/RoxyFileManagerController.cs | 828 ++++++++++++++++++ .../Administration/SmartStore.Admin.csproj | 269 ++++++ .../Shared/EditorTemplates/RichEditor.cshtml | 2 +- .../Content/filemanager/asp_net/main.ashx | 719 --------------- .../Content/filemanager/conf.json | 34 - .../SmartStore.Web/SmartStore.Web.csproj | 268 ------ 274 files changed, 1132 insertions(+), 1022 deletions(-) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/LICENSE.txt (100%) create mode 100644 src/Presentation/SmartStore.Web/Administration/Content/filemanager/conf.json rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/css/images/animated-overlay.gif (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/css/images/ui-bg_flat_0_aaaaaa_40x100.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/css/images/ui-bg_flat_75_ffffff_40x100.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/css/images/ui-bg_glass_55_fbf9ee_1x400.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/css/images/ui-bg_glass_65_ffffff_1x400.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/css/images/ui-bg_glass_75_dadada_1x400.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/css/images/ui-bg_glass_75_e6e6e6_1x400.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/css/images/ui-bg_glass_95_fef1ec_1x400.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/css/images/ui-icons_222222_256x240.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/css/images/ui-icons_2e83ff_256x240.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/css/images/ui-icons_454545_256x240.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/css/images/ui-icons_888888_256x240.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/css/images/ui-icons_cd0a0a_256x240.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/css/jquery-ui-1.10.4.custom.css (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/css/jquery-ui-1.10.4.custom.min.css (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/css/main.css (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/css/main.min.css (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/action-folder-paste.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/action-folder-rename.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/arrow_down.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/arrow_up.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/blank.gif (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/copy.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/cut.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/dir-minus.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/dir-plus.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/file-add.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/file-delete.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/file-download.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/file-duplicate.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/file-upload.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_3gp.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_7z.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_ace.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_ai.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_aif.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_aiff.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_amr.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_asf.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_asx.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_bat.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_bin.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_bmp.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_bup.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_cab.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_cbr.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_cda.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_cdl.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_cdr.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_chm.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_dat.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_divx.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_dll.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_dmg.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_doc.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_dss.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_dvf.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_dwg.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_eml.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_eps.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_exe.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_fla.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_flv.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_gif.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_gz.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_hqx.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_htm.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_html.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_ifo.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_indd.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_iso.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_jar.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_jpeg.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_jpg.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_lnk.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_log.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_m4a.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_m4b.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_m4p.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_m4v.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_mcd.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_mdb.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_mid.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_mov.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_mp2.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_mp4.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_mpeg.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_mpg.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_msi.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_mswmm.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_ogg.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_pdf.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_png.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_pps.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_ps.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_psd.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_pst.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_ptb.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_pub.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_qbb.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_qbw.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_qxd.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_ram.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_rar.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_rm.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_rmvb.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_rtf.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_sea.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_ses.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_sit.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_sitx.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_ss.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_swf.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_tgz.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_thm.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_tif.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_tmp.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_torrent.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_ttf.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_txt.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_vcd.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_vob.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_wav.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_wma.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_wmv.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_wps.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_xls.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_xpi.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/file_extension_zip.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/big/unknown.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_3gp.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_7z.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_ace.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_ai.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_aif.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_aiff.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_amr.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_asf.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_asx.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_bat.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_bin.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_bmp.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_bup.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_cab.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_cbr.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_cda.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_cdl.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_cdr.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_chm.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_dat.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_divx.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_dll.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_dmg.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_doc.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_dss.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_dvf.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_dwg.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_eml.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_eps.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_exe.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_fla.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_flv.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_gif.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_gz.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_hqx.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_htm.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_html.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_ifo.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_indd.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_iso.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_jar.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_jpeg.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_jpg.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_lnk.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_log.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_m4a.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_m4b.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_m4p.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_m4v.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_mcd.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_mdb.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_mid.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_mov.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_mp2.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_mp4.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_mpeg.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_mpg.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_msi.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_mswmm.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_ogg.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_pdf.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_png.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_pps.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_ps.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_psd.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_pst.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_ptb.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_pub.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_qbb.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_qbw.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_qxd.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_ram.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_rar.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_rm.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_rmvb.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_rtf.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_sea.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_ses.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_sit.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_sitx.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_ss.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_swf.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_tgz.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_thm.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_tif.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_tmp.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_torrent.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_ttf.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_txt.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_vcd.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_vob.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_wav.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_wma.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_wmv.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_wps.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_xls.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_xpi.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/file_extension_zip.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/filetypes/unknown.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/find.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/folder-add.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/folder-delete.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/folder-download.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/folder-green.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/folder-opened.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/folder.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/loading-dir.gif (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/loading.gif (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/paste.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/preview.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/rename.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/search.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/select.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/upload-big.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/view-list.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/images/view-tile.png (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/index.html (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/js/custom.js (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/js/directory.js (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/js/file.js (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/js/fileman-modified.zip (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/js/filetypes.js (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/js/jquery-1.10.2.min.js (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/js/jquery-dateFormat.min.js (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/js/jquery-ui-1.10.4.custom.min.js (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/js/main.js (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/js/main.min.js (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/js/mini-main.js (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/js/tiny_mce_popup.js (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/js/utils.js (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/lang/bg.json (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/lang/de.json (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/lang/en.json (100%) rename src/Presentation/SmartStore.Web/{ => Administration}/Content/filemanager/lang/fr.json (100%) create mode 100644 src/Presentation/SmartStore.Web/Administration/Controllers/RoxyFileManagerController.cs delete mode 100644 src/Presentation/SmartStore.Web/Content/filemanager/asp_net/main.ashx delete mode 100644 src/Presentation/SmartStore.Web/Content/filemanager/conf.json diff --git a/changelog.md b/changelog.md index 8efe9bbc11..47f492ff48 100644 --- a/changelog.md +++ b/changelog.md @@ -62,6 +62,7 @@ * Payone: Hash string incorrect for frontend API payments where the order has more than 9 products * Export mail notification: Download link not working if SSL is enabled * Discount rule has spent amount including sub total option can cause wrong discount calculation if the cart contains a product several times +* #986 File uploads possible through /content/filemanager/index.html ## SmartStore.NET 2.5 diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/LICENSE.txt b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/LICENSE.txt similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/LICENSE.txt rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/LICENSE.txt diff --git a/src/Presentation/SmartStore.Web/Administration/Content/filemanager/conf.json b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/conf.json new file mode 100644 index 0000000000..c08220bdfe --- /dev/null +++ b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/conf.json @@ -0,0 +1,33 @@ +{ + "FILES_ROOT": "~/Media/Uploaded", + "SESSION_PATH_KEY": "", + "THUMBS_VIEW_WIDTH": "140", + "THUMBS_VIEW_HEIGHT": "120", + "PREVIEW_THUMB_WIDTH": "300", + "PREVIEW_THUMB_HEIGHT": "200", + "MAX_IMAGE_WIDTH": "0", + "MAX_IMAGE_HEIGHT": "0", + "INTEGRATION": "ckeditor", + "DIRLIST": "../../../Admin/RoxyFileManager/ProcessRequest?a=DIRLIST", + "CREATEDIR": "../../../Admin/RoxyFileManager/ProcessRequest?a=CREATEDIR", + "DELETEDIR": "../../../Admin/RoxyFileManager/ProcessRequest?a=DELETEDIR", + "MOVEDIR": "../../../Admin/RoxyFileManager/ProcessRequest?a=MOVEDIR", + "COPYDIR": "../../../Admin/RoxyFileManager/ProcessRequest?a=COPYDIR", + "RENAMEDIR": "../../../Admin/RoxyFileManager/ProcessRequest?a=RENAMEDIR", + "FILESLIST": "../../../Admin/RoxyFileManager/ProcessRequest?a=FILESLIST", + "UPLOAD": "../../../Admin/RoxyFileManager/ProcessRequest?a=UPLOAD", + "DOWNLOAD": "../../../Admin/RoxyFileManager/ProcessRequest?a=DOWNLOAD", + "DOWNLOADDIR": "../../../Admin/RoxyFileManager/ProcessRequest?a=DOWNLOADDIR", + "DELETEFILE": "../../../Admin/RoxyFileManager/ProcessRequest?a=DELETEFILE", + "MOVEFILE": "../../../Admin/RoxyFileManager/ProcessRequest?a=MOVEFILE", + "COPYFILE": "../../../Admin/RoxyFileManager/ProcessRequest?a=COPYFILE", + "RENAMEFILE": "../../../Admin/RoxyFileManager/ProcessRequest?a=RENAMEFILE", + "GENERATETHUMB": "../../../Admin/RoxyFileManager/ProcessRequest?a=GENERATETHUMB", + "DEFAULTVIEW": "list", + "FORBIDDEN_UPLOADS": "zip js jsp jsb mhtml mht xhtml xht php phtml php3 php4 php5 phps shtml jhtml pl sh py cgi exe scr dll msi vbs bat com pif cmd vxd cpl htpasswd htaccess", + "ALLOWED_UPLOADS": "", + "FILEPERMISSIONS": "0644", + "DIRPERMISSIONS": "0755", + "LANG": "auto", + "DATEFORMAT": "dd.MM.yyyy HH:mm" +} \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/css/images/animated-overlay.gif b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/animated-overlay.gif similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/css/images/animated-overlay.gif rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/animated-overlay.gif diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/css/images/ui-bg_flat_0_aaaaaa_40x100.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/ui-bg_flat_0_aaaaaa_40x100.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/css/images/ui-bg_flat_0_aaaaaa_40x100.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/ui-bg_flat_0_aaaaaa_40x100.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/css/images/ui-bg_flat_75_ffffff_40x100.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/ui-bg_flat_75_ffffff_40x100.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/css/images/ui-bg_flat_75_ffffff_40x100.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/ui-bg_flat_75_ffffff_40x100.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/css/images/ui-bg_glass_55_fbf9ee_1x400.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/ui-bg_glass_55_fbf9ee_1x400.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/css/images/ui-bg_glass_55_fbf9ee_1x400.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/ui-bg_glass_55_fbf9ee_1x400.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/css/images/ui-bg_glass_65_ffffff_1x400.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/ui-bg_glass_65_ffffff_1x400.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/css/images/ui-bg_glass_65_ffffff_1x400.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/ui-bg_glass_65_ffffff_1x400.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/css/images/ui-bg_glass_75_dadada_1x400.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/ui-bg_glass_75_dadada_1x400.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/css/images/ui-bg_glass_75_dadada_1x400.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/ui-bg_glass_75_dadada_1x400.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/css/images/ui-bg_glass_75_e6e6e6_1x400.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/ui-bg_glass_75_e6e6e6_1x400.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/css/images/ui-bg_glass_75_e6e6e6_1x400.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/ui-bg_glass_75_e6e6e6_1x400.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/css/images/ui-bg_glass_95_fef1ec_1x400.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/ui-bg_glass_95_fef1ec_1x400.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/css/images/ui-bg_glass_95_fef1ec_1x400.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/ui-bg_glass_95_fef1ec_1x400.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/css/images/ui-icons_222222_256x240.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/ui-icons_222222_256x240.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/css/images/ui-icons_222222_256x240.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/ui-icons_222222_256x240.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/css/images/ui-icons_2e83ff_256x240.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/ui-icons_2e83ff_256x240.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/css/images/ui-icons_2e83ff_256x240.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/ui-icons_2e83ff_256x240.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/css/images/ui-icons_454545_256x240.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/ui-icons_454545_256x240.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/css/images/ui-icons_454545_256x240.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/ui-icons_454545_256x240.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/css/images/ui-icons_888888_256x240.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/ui-icons_888888_256x240.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/css/images/ui-icons_888888_256x240.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/ui-icons_888888_256x240.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/css/images/ui-icons_cd0a0a_256x240.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/ui-icons_cd0a0a_256x240.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/css/images/ui-icons_cd0a0a_256x240.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/images/ui-icons_cd0a0a_256x240.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/css/jquery-ui-1.10.4.custom.css b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/jquery-ui-1.10.4.custom.css similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/css/jquery-ui-1.10.4.custom.css rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/jquery-ui-1.10.4.custom.css diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/css/jquery-ui-1.10.4.custom.min.css b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/jquery-ui-1.10.4.custom.min.css similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/css/jquery-ui-1.10.4.custom.min.css rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/jquery-ui-1.10.4.custom.min.css diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/css/main.css b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/main.css similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/css/main.css rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/main.css diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/css/main.min.css b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/main.min.css similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/css/main.min.css rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/css/main.min.css diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/action-folder-paste.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/action-folder-paste.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/action-folder-paste.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/action-folder-paste.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/action-folder-rename.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/action-folder-rename.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/action-folder-rename.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/action-folder-rename.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/arrow_down.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/arrow_down.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/arrow_down.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/arrow_down.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/arrow_up.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/arrow_up.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/arrow_up.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/arrow_up.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/blank.gif b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/blank.gif similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/blank.gif rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/blank.gif diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/copy.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/copy.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/copy.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/copy.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/cut.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/cut.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/cut.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/cut.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/dir-minus.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/dir-minus.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/dir-minus.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/dir-minus.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/dir-plus.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/dir-plus.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/dir-plus.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/dir-plus.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/file-add.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/file-add.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/file-add.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/file-add.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/file-delete.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/file-delete.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/file-delete.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/file-delete.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/file-download.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/file-download.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/file-download.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/file-download.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/file-duplicate.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/file-duplicate.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/file-duplicate.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/file-duplicate.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/file-upload.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/file-upload.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/file-upload.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/file-upload.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_3gp.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_3gp.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_3gp.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_3gp.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_7z.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_7z.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_7z.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_7z.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_ace.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_ace.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_ace.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_ace.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_ai.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_ai.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_ai.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_ai.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_aif.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_aif.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_aif.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_aif.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_aiff.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_aiff.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_aiff.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_aiff.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_amr.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_amr.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_amr.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_amr.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_asf.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_asf.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_asf.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_asf.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_asx.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_asx.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_asx.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_asx.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_bat.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_bat.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_bat.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_bat.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_bin.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_bin.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_bin.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_bin.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_bmp.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_bmp.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_bmp.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_bmp.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_bup.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_bup.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_bup.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_bup.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_cab.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_cab.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_cab.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_cab.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_cbr.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_cbr.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_cbr.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_cbr.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_cda.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_cda.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_cda.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_cda.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_cdl.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_cdl.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_cdl.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_cdl.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_cdr.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_cdr.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_cdr.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_cdr.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_chm.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_chm.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_chm.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_chm.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_dat.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_dat.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_dat.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_dat.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_divx.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_divx.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_divx.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_divx.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_dll.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_dll.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_dll.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_dll.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_dmg.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_dmg.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_dmg.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_dmg.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_doc.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_doc.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_doc.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_doc.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_dss.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_dss.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_dss.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_dss.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_dvf.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_dvf.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_dvf.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_dvf.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_dwg.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_dwg.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_dwg.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_dwg.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_eml.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_eml.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_eml.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_eml.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_eps.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_eps.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_eps.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_eps.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_exe.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_exe.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_exe.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_exe.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_fla.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_fla.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_fla.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_fla.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_flv.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_flv.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_flv.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_flv.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_gif.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_gif.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_gif.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_gif.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_gz.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_gz.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_gz.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_gz.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_hqx.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_hqx.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_hqx.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_hqx.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_htm.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_htm.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_htm.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_htm.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_html.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_html.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_html.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_html.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_ifo.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_ifo.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_ifo.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_ifo.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_indd.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_indd.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_indd.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_indd.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_iso.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_iso.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_iso.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_iso.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_jar.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_jar.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_jar.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_jar.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_jpeg.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_jpeg.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_jpeg.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_jpeg.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_jpg.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_jpg.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_jpg.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_jpg.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_lnk.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_lnk.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_lnk.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_lnk.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_log.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_log.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_log.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_log.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_m4a.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_m4a.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_m4a.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_m4a.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_m4b.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_m4b.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_m4b.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_m4b.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_m4p.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_m4p.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_m4p.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_m4p.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_m4v.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_m4v.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_m4v.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_m4v.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_mcd.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_mcd.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_mcd.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_mcd.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_mdb.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_mdb.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_mdb.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_mdb.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_mid.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_mid.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_mid.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_mid.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_mov.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_mov.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_mov.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_mov.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_mp2.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_mp2.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_mp2.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_mp2.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_mp4.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_mp4.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_mp4.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_mp4.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_mpeg.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_mpeg.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_mpeg.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_mpeg.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_mpg.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_mpg.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_mpg.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_mpg.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_msi.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_msi.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_msi.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_msi.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_mswmm.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_mswmm.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_mswmm.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_mswmm.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_ogg.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_ogg.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_ogg.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_ogg.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_pdf.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_pdf.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_pdf.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_pdf.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_png.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_png.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_png.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_png.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_pps.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_pps.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_pps.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_pps.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_ps.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_ps.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_ps.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_ps.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_psd.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_psd.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_psd.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_psd.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_pst.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_pst.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_pst.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_pst.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_ptb.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_ptb.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_ptb.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_ptb.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_pub.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_pub.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_pub.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_pub.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_qbb.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_qbb.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_qbb.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_qbb.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_qbw.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_qbw.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_qbw.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_qbw.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_qxd.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_qxd.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_qxd.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_qxd.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_ram.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_ram.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_ram.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_ram.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_rar.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_rar.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_rar.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_rar.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_rm.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_rm.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_rm.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_rm.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_rmvb.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_rmvb.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_rmvb.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_rmvb.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_rtf.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_rtf.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_rtf.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_rtf.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_sea.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_sea.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_sea.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_sea.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_ses.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_ses.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_ses.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_ses.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_sit.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_sit.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_sit.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_sit.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_sitx.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_sitx.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_sitx.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_sitx.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_ss.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_ss.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_ss.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_ss.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_swf.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_swf.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_swf.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_swf.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_tgz.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_tgz.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_tgz.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_tgz.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_thm.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_thm.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_thm.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_thm.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_tif.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_tif.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_tif.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_tif.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_tmp.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_tmp.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_tmp.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_tmp.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_torrent.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_torrent.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_torrent.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_torrent.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_ttf.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_ttf.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_ttf.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_ttf.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_txt.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_txt.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_txt.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_txt.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_vcd.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_vcd.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_vcd.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_vcd.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_vob.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_vob.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_vob.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_vob.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_wav.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_wav.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_wav.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_wav.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_wma.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_wma.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_wma.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_wma.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_wmv.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_wmv.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_wmv.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_wmv.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_wps.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_wps.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_wps.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_wps.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_xls.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_xls.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_xls.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_xls.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_xpi.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_xpi.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_xpi.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_xpi.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_zip.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_zip.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/file_extension_zip.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/file_extension_zip.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/unknown.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/unknown.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/big/unknown.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/big/unknown.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_3gp.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_3gp.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_3gp.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_3gp.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_7z.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_7z.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_7z.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_7z.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_ace.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_ace.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_ace.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_ace.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_ai.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_ai.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_ai.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_ai.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_aif.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_aif.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_aif.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_aif.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_aiff.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_aiff.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_aiff.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_aiff.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_amr.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_amr.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_amr.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_amr.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_asf.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_asf.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_asf.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_asf.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_asx.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_asx.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_asx.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_asx.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_bat.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_bat.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_bat.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_bat.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_bin.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_bin.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_bin.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_bin.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_bmp.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_bmp.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_bmp.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_bmp.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_bup.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_bup.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_bup.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_bup.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_cab.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_cab.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_cab.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_cab.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_cbr.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_cbr.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_cbr.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_cbr.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_cda.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_cda.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_cda.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_cda.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_cdl.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_cdl.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_cdl.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_cdl.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_cdr.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_cdr.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_cdr.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_cdr.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_chm.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_chm.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_chm.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_chm.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_dat.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_dat.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_dat.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_dat.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_divx.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_divx.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_divx.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_divx.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_dll.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_dll.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_dll.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_dll.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_dmg.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_dmg.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_dmg.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_dmg.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_doc.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_doc.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_doc.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_doc.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_dss.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_dss.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_dss.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_dss.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_dvf.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_dvf.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_dvf.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_dvf.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_dwg.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_dwg.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_dwg.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_dwg.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_eml.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_eml.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_eml.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_eml.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_eps.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_eps.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_eps.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_eps.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_exe.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_exe.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_exe.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_exe.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_fla.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_fla.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_fla.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_fla.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_flv.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_flv.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_flv.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_flv.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_gif.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_gif.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_gif.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_gif.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_gz.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_gz.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_gz.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_gz.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_hqx.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_hqx.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_hqx.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_hqx.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_htm.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_htm.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_htm.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_htm.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_html.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_html.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_html.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_html.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_ifo.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_ifo.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_ifo.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_ifo.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_indd.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_indd.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_indd.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_indd.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_iso.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_iso.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_iso.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_iso.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_jar.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_jar.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_jar.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_jar.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_jpeg.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_jpeg.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_jpeg.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_jpeg.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_jpg.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_jpg.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_jpg.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_jpg.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_lnk.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_lnk.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_lnk.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_lnk.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_log.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_log.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_log.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_log.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_m4a.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_m4a.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_m4a.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_m4a.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_m4b.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_m4b.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_m4b.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_m4b.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_m4p.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_m4p.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_m4p.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_m4p.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_m4v.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_m4v.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_m4v.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_m4v.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_mcd.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_mcd.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_mcd.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_mcd.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_mdb.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_mdb.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_mdb.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_mdb.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_mid.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_mid.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_mid.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_mid.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_mov.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_mov.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_mov.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_mov.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_mp2.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_mp2.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_mp2.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_mp2.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_mp4.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_mp4.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_mp4.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_mp4.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_mpeg.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_mpeg.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_mpeg.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_mpeg.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_mpg.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_mpg.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_mpg.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_mpg.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_msi.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_msi.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_msi.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_msi.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_mswmm.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_mswmm.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_mswmm.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_mswmm.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_ogg.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_ogg.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_ogg.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_ogg.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_pdf.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_pdf.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_pdf.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_pdf.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_png.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_png.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_png.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_png.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_pps.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_pps.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_pps.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_pps.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_ps.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_ps.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_ps.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_ps.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_psd.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_psd.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_psd.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_psd.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_pst.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_pst.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_pst.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_pst.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_ptb.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_ptb.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_ptb.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_ptb.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_pub.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_pub.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_pub.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_pub.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_qbb.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_qbb.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_qbb.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_qbb.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_qbw.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_qbw.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_qbw.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_qbw.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_qxd.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_qxd.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_qxd.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_qxd.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_ram.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_ram.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_ram.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_ram.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_rar.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_rar.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_rar.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_rar.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_rm.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_rm.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_rm.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_rm.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_rmvb.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_rmvb.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_rmvb.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_rmvb.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_rtf.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_rtf.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_rtf.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_rtf.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_sea.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_sea.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_sea.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_sea.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_ses.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_ses.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_ses.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_ses.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_sit.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_sit.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_sit.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_sit.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_sitx.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_sitx.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_sitx.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_sitx.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_ss.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_ss.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_ss.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_ss.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_swf.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_swf.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_swf.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_swf.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_tgz.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_tgz.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_tgz.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_tgz.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_thm.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_thm.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_thm.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_thm.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_tif.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_tif.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_tif.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_tif.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_tmp.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_tmp.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_tmp.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_tmp.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_torrent.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_torrent.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_torrent.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_torrent.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_ttf.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_ttf.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_ttf.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_ttf.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_txt.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_txt.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_txt.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_txt.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_vcd.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_vcd.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_vcd.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_vcd.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_vob.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_vob.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_vob.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_vob.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_wav.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_wav.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_wav.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_wav.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_wma.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_wma.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_wma.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_wma.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_wmv.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_wmv.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_wmv.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_wmv.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_wps.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_wps.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_wps.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_wps.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_xls.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_xls.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_xls.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_xls.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_xpi.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_xpi.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_xpi.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_xpi.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_zip.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_zip.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/file_extension_zip.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/file_extension_zip.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/unknown.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/unknown.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/filetypes/unknown.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/filetypes/unknown.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/find.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/find.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/find.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/find.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/folder-add.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/folder-add.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/folder-add.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/folder-add.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/folder-delete.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/folder-delete.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/folder-delete.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/folder-delete.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/folder-download.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/folder-download.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/folder-download.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/folder-download.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/folder-green.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/folder-green.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/folder-green.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/folder-green.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/folder-opened.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/folder-opened.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/folder-opened.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/folder-opened.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/folder.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/folder.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/folder.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/folder.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/loading-dir.gif b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/loading-dir.gif similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/loading-dir.gif rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/loading-dir.gif diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/loading.gif b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/loading.gif similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/loading.gif rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/loading.gif diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/paste.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/paste.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/paste.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/paste.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/preview.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/preview.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/preview.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/preview.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/rename.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/rename.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/rename.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/rename.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/search.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/search.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/search.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/search.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/select.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/select.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/select.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/select.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/upload-big.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/upload-big.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/upload-big.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/upload-big.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/view-list.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/view-list.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/view-list.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/view-list.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/images/view-tile.png b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/view-tile.png similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/images/view-tile.png rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/images/view-tile.png diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/index.html b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/index.html similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/index.html rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/index.html diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/js/custom.js b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/js/custom.js similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/js/custom.js rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/js/custom.js diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/js/directory.js b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/js/directory.js similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/js/directory.js rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/js/directory.js diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/js/file.js b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/js/file.js similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/js/file.js rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/js/file.js diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/js/fileman-modified.zip b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/js/fileman-modified.zip similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/js/fileman-modified.zip rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/js/fileman-modified.zip diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/js/filetypes.js b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/js/filetypes.js similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/js/filetypes.js rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/js/filetypes.js diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/js/jquery-1.10.2.min.js b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/js/jquery-1.10.2.min.js similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/js/jquery-1.10.2.min.js rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/js/jquery-1.10.2.min.js diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/js/jquery-dateFormat.min.js b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/js/jquery-dateFormat.min.js similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/js/jquery-dateFormat.min.js rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/js/jquery-dateFormat.min.js diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/js/jquery-ui-1.10.4.custom.min.js b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/js/jquery-ui-1.10.4.custom.min.js similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/js/jquery-ui-1.10.4.custom.min.js rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/js/jquery-ui-1.10.4.custom.min.js diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/js/main.js b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/js/main.js similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/js/main.js rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/js/main.js diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/js/main.min.js b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/js/main.min.js similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/js/main.min.js rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/js/main.min.js diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/js/mini-main.js b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/js/mini-main.js similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/js/mini-main.js rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/js/mini-main.js diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/js/tiny_mce_popup.js b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/js/tiny_mce_popup.js similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/js/tiny_mce_popup.js rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/js/tiny_mce_popup.js diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/js/utils.js b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/js/utils.js similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/js/utils.js rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/js/utils.js diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/lang/bg.json b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/lang/bg.json similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/lang/bg.json rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/lang/bg.json diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/lang/de.json b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/lang/de.json similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/lang/de.json rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/lang/de.json diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/lang/en.json b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/lang/en.json similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/lang/en.json rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/lang/en.json diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/lang/fr.json b/src/Presentation/SmartStore.Web/Administration/Content/filemanager/lang/fr.json similarity index 100% rename from src/Presentation/SmartStore.Web/Content/filemanager/lang/fr.json rename to src/Presentation/SmartStore.Web/Administration/Content/filemanager/lang/fr.json diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/RoxyFileManagerController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/RoxyFileManagerController.cs new file mode 100644 index 0000000000..e0c2ca36c2 --- /dev/null +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/RoxyFileManagerController.cs @@ -0,0 +1,828 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.IO.Compression; +using System.Text.RegularExpressions; +using System.Web; +using SmartStore.Services.Security; +using SmartStore.Web.Framework.Controllers; +using SmartStore.Web.Framework.Security; + +namespace SmartStore.Admin.Controllers +{ + [AdminAuthorize] + public class RoxyFileManagerController : AdminControllerBase + { + private const string CONFIG_FILE = "~/Administration/Content/filemanager/conf.json"; + + private Dictionary _lang = null; + private Dictionary _settings = null; + + private readonly IPermissionService _permissionService; + private readonly HttpContextBase _context; + private readonly HttpResponseBase _response; + + public RoxyFileManagerController( + IPermissionService permissionService, + HttpContextBase context) + { + _permissionService = permissionService; + _context = context; + _response = _context.Response; + } + + #region Utilities + + private string FixPath(string path) + { + if (path == null) + { + path = ""; + } + + if (!path.StartsWith("~")) + { + if (!path.StartsWith("/")) + path = "/" + path; + path = "~" + path; + } + + //var filesRoot = GetSetting("FILES_ROOT"); + //if (!path.ToLowerInvariant().Contains(filesRoot.ToLowerInvariant())) + //{ + // path = filesRoot; + //} + + return _context.Server.MapPath(path); + } + + private string GetLangFile() + { + //return "../lang/en.json"; + + var filename = "../lang/" + GetSetting("LANG") + ".json"; + + if (!System.IO.File.Exists(_context.Server.MapPath(filename))) + filename = "../lang/en.json"; + + return filename; + } + + protected string LangRes(string name) + { + string ret = name; + if (_lang == null) + _lang = ParseJSON(GetLangFile()); + if (_lang.ContainsKey(name)) + ret = _lang[name]; + + return ret; + } + + protected string GetFileType(string ext) + { + string ret = "file"; + ext = ext.ToLower(); + if (ext == ".jpg" || ext == ".jpeg" || ext == ".png" || ext == ".gif") + ret = "image"; + else if (ext == ".swf" || ext == ".flv") + ret = "flash"; + return ret; + } + + protected bool CanHandleFile(string filename) + { + bool ret = false; + FileInfo file = new FileInfo(filename); + string ext = file.Extension.Replace(".", "").ToLower(); + string setting = GetSetting("FORBIDDEN_UPLOADS").Trim().ToLower(); + if (setting != "") + { + ArrayList tmp = new ArrayList(); + tmp.AddRange(Regex.Split(setting, "\\s+")); + if (!tmp.Contains(ext)) + ret = true; + } + setting = GetSetting("ALLOWED_UPLOADS").Trim().ToLower(); + if (setting != "") + { + ArrayList tmp = new ArrayList(); + tmp.AddRange(Regex.Split(setting, "\\s+")); + if (!tmp.Contains(ext)) + ret = false; + } + + return ret; + } + + protected Dictionary ParseJSON(string file) + { + Dictionary ret = new Dictionary(); + string json = ""; + try + { + json = System.IO.File.ReadAllText(_context.Server.MapPath(file), System.Text.Encoding.UTF8); + } + catch { } + + json = json.Trim(); + if (json != "") + { + if (json.StartsWith("{")) + json = json.Substring(1, json.Length - 2); + json = json.Trim(); + json = json.Substring(1, json.Length - 2); + string[] lines = Regex.Split(json, "\"\\s*,\\s*\""); + foreach (string line in lines) + { + string[] tmp = Regex.Split(line, "\"\\s*:\\s*\""); + try + { + if (tmp[0] != "" && !ret.ContainsKey(tmp[0])) + { + ret.Add(tmp[0], tmp[1]); + } + } + catch { } + } + } + return ret; + } + + protected string GetFilesRoot() + { + string ret = GetSetting("FILES_ROOT"); + if (GetSetting("SESSION_PATH_KEY") != "" && _context.Session[GetSetting("SESSION_PATH_KEY")] != null) + ret = (string)_context.Session[GetSetting("SESSION_PATH_KEY")]; + + if (ret == "") + ret = _context.Server.MapPath("../Uploads"); + else + ret = FixPath(ret); + return ret; + } + + protected void LoadConf() + { + if (_settings == null) + _settings = ParseJSON(CONFIG_FILE); + } + + protected string GetSetting(string name) + { + string ret = ""; + LoadConf(); + if (_settings.ContainsKey(name)) + ret = _settings[name]; + + return ret; + } + + protected void CheckPath(string path) + { + if (FixPath(path).IndexOf(GetFilesRoot()) != 0) + { + throw new Exception("Access to " + path + " is denied"); + } + } + + protected void VerifyAction(string action) + { + string setting = GetSetting(action); + if (setting.IndexOf("?") > -1) + setting = setting.Substring(0, setting.IndexOf("?")); + if (!setting.StartsWith("/")) + setting = "/" + setting; + setting = ".." + setting; + + if (_context.Server.MapPath(setting) != _context.Server.MapPath(_context.Request.Url.LocalPath)) + throw new Exception(LangRes("E_ActionDisabled")); + } + + protected string GetResultStr(string type, string msg) + { + return "{\"res\":\"" + type + "\",\"msg\":\"" + msg.Replace("\"", "\\\"") + "\"}"; + } + + protected string GetSuccessRes(string msg) + { + return GetResultStr("ok", msg); + } + + protected string GetSuccessRes() + { + return GetSuccessRes(""); + } + + protected string GetErrorRes(string msg) + { + return GetResultStr("error", msg); + } + + private void _copyDir(string path, string dest) + { + if (!Directory.Exists(dest)) + Directory.CreateDirectory(dest); + foreach (string f in Directory.GetFiles(path)) + { + FileInfo file = new FileInfo(f); + if (!System.IO.File.Exists(Path.Combine(dest, file.Name))) + { + System.IO.File.Copy(f, Path.Combine(dest, file.Name)); + } + } + foreach (string d in Directory.GetDirectories(path)) + { + DirectoryInfo dir = new DirectoryInfo(d); + _copyDir(d, Path.Combine(dest, dir.Name)); + } + } + + protected void CopyDir(string path, string newPath) + { + CheckPath(path); + CheckPath(newPath); + DirectoryInfo dir = new DirectoryInfo(FixPath(path)); + DirectoryInfo newDir = new DirectoryInfo(FixPath(newPath + "/" + dir.Name)); + + if (!dir.Exists) + { + throw new Exception(LangRes("E_CopyDirInvalidPath")); + } + else if (newDir.Exists) + { + throw new Exception(LangRes("E_DirAlreadyExists")); + } + else + { + _copyDir(dir.FullName, newDir.FullName); + } + _response.Write(GetSuccessRes()); + } + + protected string MakeUniqueFilename(string dir, string filename) + { + string ret = filename; + int i = 0; + while (System.IO.File.Exists(Path.Combine(dir, ret))) + { + i++; + ret = Path.GetFileNameWithoutExtension(filename) + " - Copy " + i.ToString() + Path.GetExtension(filename); + } + return ret; + } + + protected void CopyFile(string path, string newPath) + { + CheckPath(path); + FileInfo file = new FileInfo(FixPath(path)); + newPath = FixPath(newPath); + if (!file.Exists) + throw new Exception(LangRes("E_CopyFileInvalisPath")); + else + { + string newName = MakeUniqueFilename(newPath, file.Name); + try + { + System.IO.File.Copy(file.FullName, Path.Combine(newPath, newName)); + _response.Write(GetSuccessRes()); + } + catch + { + throw new Exception(LangRes("E_CopyFile")); + } + } + } + + protected void CreateDir(string path, string name) + { + CheckPath(path); + path = FixPath(path); + if (!Directory.Exists(path)) + throw new Exception(LangRes("E_CreateDirInvalidPath")); + else + { + try + { + path = Path.Combine(path, name); + if (!Directory.Exists(path)) + Directory.CreateDirectory(path); + _response.Write(GetSuccessRes()); + } + catch + { + throw new Exception(LangRes("E_CreateDirFailed")); + } + } + } + + protected void DeleteDir(string path) + { + CheckPath(path); + path = FixPath(path); + if (!Directory.Exists(path)) + throw new Exception(LangRes("E_DeleteDirInvalidPath")); + else if (path == GetFilesRoot()) + throw new Exception(LangRes("E_CannotDeleteRoot")); + else if (Directory.GetDirectories(path).Length > 0 || Directory.GetFiles(path).Length > 0) + throw new Exception(LangRes("E_DeleteNonEmpty")); + else + { + try + { + Directory.Delete(path); + _response.Write(GetSuccessRes()); + } + catch + { + throw new Exception(LangRes("E_CannotDeleteDir")); + } + } + } + + protected void DeleteFile(string path) + { + CheckPath(path); + path = FixPath(path); + if (!System.IO.File.Exists(path)) + throw new Exception(LangRes("E_DeleteFileInvalidPath")); + else + { + try + { + System.IO.File.Delete(path); + _response.Write(GetSuccessRes()); + } + catch + { + throw new Exception(LangRes("E_DeletеFile")); + } + } + } + + private List GetFiles(string path, string type) + { + List ret = new List(); + if (type == "#") + type = ""; + string[] files = Directory.GetFiles(path); + foreach (string f in files) + { + if ((GetFileType(new FileInfo(f).Extension) == type) || (type == "")) + ret.Add(f); + } + return ret; + } + + private ArrayList ListDirs(string path) + { + string[] dirs = Directory.GetDirectories(path); + ArrayList ret = new ArrayList(); + foreach (string dir in dirs) + { + ret.Add(dir); + ret.AddRange(ListDirs(dir)); + } + return ret; + } + + protected void ListDirTree(string type) + { + DirectoryInfo d = new DirectoryInfo(GetFilesRoot()); + if (!d.Exists) + throw new Exception("Invalid files root directory. Check your configuration."); + + ArrayList dirs = ListDirs(d.FullName); + dirs.Insert(0, d.FullName); + + string localPath = _context.Server.MapPath("~/"); + _response.Write("["); + for (int i = 0; i < dirs.Count; i++) + { + string dir = (string)dirs[i]; + _response.Write("{\"p\":\"/" + dir.Replace(localPath, "").Replace("\\", "/") + "\",\"f\":\"" + GetFiles(dir, type).Count.ToString() + "\",\"d\":\"" + Directory.GetDirectories(dir).Length.ToString() + "\"}"); + if (i < dirs.Count - 1) + _response.Write(","); + } + _response.Write("]"); + } + + protected double LinuxTimestamp(DateTime d) + { + DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0).ToLocalTime(); + TimeSpan timeSpan = (d.ToLocalTime() - epoch); + + return timeSpan.TotalSeconds; + + } + + protected void ListFiles(string path, string type) + { + CheckPath(path); + string fullPath = FixPath(path); + List files = GetFiles(fullPath, type); + _response.Write("["); + for (int i = 0; i < files.Count; i++) + { + FileInfo f = new FileInfo(files[i]); + int w = 0, h = 0; + if (GetFileType(f.Extension) == "image") + { + try + { + FileStream fs = new FileStream(f.FullName, FileMode.Open); + Image img = Image.FromStream(fs); + w = img.Width; + h = img.Height; + fs.Close(); + fs.Dispose(); + img.Dispose(); + } + catch (Exception ex) + { + throw ex; + } + } + _response.Write("{"); + _response.Write("\"p\":\"" + path + "/" + f.Name + "\""); + _response.Write(",\"t\":\"" + Math.Ceiling(LinuxTimestamp(f.LastWriteTime)).ToString() + "\""); + _response.Write(",\"s\":\"" + f.Length.ToString() + "\""); + _response.Write(",\"w\":\"" + w.ToString() + "\""); + _response.Write(",\"h\":\"" + h.ToString() + "\""); + _response.Write("}"); + if (i < files.Count - 1) + _response.Write(","); + } + _response.Write("]"); + } + + public void DownloadDir(string path) + { + path = FixPath(path); + if (!Directory.Exists(path)) + throw new Exception(LangRes("E_CreateArchive")); + string dirName = new FileInfo(path).Name; + string tmpZip = _context.Server.MapPath("../tmp/" + dirName + ".zip"); + if (System.IO.File.Exists(tmpZip)) + System.IO.File.Delete(tmpZip); + ZipFile.CreateFromDirectory(path, tmpZip, CompressionLevel.Fastest, true); + _response.Clear(); + _response.Headers.Add("Content-Disposition", "attachment; filename=\"" + dirName + ".zip\""); + _response.ContentType = "application/force-download"; + _response.TransmitFile(tmpZip); + _response.Flush(); + System.IO.File.Delete(tmpZip); + _response.End(); + } + + protected void DownloadFile(string path) + { + CheckPath(path); + FileInfo file = new FileInfo(FixPath(path)); + if (file.Exists) + { + _response.Clear(); + _response.Headers.Add("Content-Disposition", "attachment; filename=\"" + file.Name + "\""); + _response.ContentType = "application/force-download"; + _response.TransmitFile(file.FullName); + _response.Flush(); + _response.End(); + } + } + + protected void MoveDir(string path, string newPath) + { + CheckPath(path); + CheckPath(newPath); + DirectoryInfo source = new DirectoryInfo(FixPath(path)); + DirectoryInfo dest = new DirectoryInfo(FixPath(Path.Combine(newPath, source.Name))); + if (dest.FullName.IndexOf(source.FullName) == 0) + throw new Exception(LangRes("E_CannotMoveDirToChild")); + else if (!source.Exists) + throw new Exception(LangRes("E_MoveDirInvalisPath")); + else if (dest.Exists) + throw new Exception(LangRes("E_DirAlreadyExists")); + else + { + try + { + source.MoveTo(dest.FullName); + _response.Write(GetSuccessRes()); + } + catch + { + throw new Exception(LangRes("E_MoveDir") + " \"" + path + "\""); + } + } + } + + protected void MoveFile(string path, string newPath) + { + CheckPath(path); + CheckPath(newPath); + FileInfo source = new FileInfo(FixPath(path)); + FileInfo dest = new FileInfo(FixPath(newPath)); + if (!source.Exists) + throw new Exception(LangRes("E_MoveFileInvalisPath")); + else if (dest.Exists) + throw new Exception(LangRes("E_MoveFileAlreadyExists")); + else + { + try + { + source.MoveTo(dest.FullName); + _response.Write(GetSuccessRes()); + } + catch + { + throw new Exception(LangRes("E_MoveFile") + " \"" + path + "\""); + } + } + } + + protected void RenameDir(string path, string name) + { + CheckPath(path); + DirectoryInfo source = new DirectoryInfo(FixPath(path)); + DirectoryInfo dest = new DirectoryInfo(Path.Combine(source.Parent.FullName, name)); + if (source.FullName == GetFilesRoot()) + throw new Exception(LangRes("E_CannotRenameRoot")); + else if (!source.Exists) + throw new Exception(LangRes("E_RenameDirInvalidPath")); + else if (dest.Exists) + throw new Exception(LangRes("E_DirAlreadyExists")); + else + { + try + { + source.MoveTo(dest.FullName); + _response.Write(GetSuccessRes()); + } + catch + { + throw new Exception(LangRes("E_RenameDir") + " \"" + path + "\""); + } + } + } + + protected void RenameFile(string path, string name) + { + CheckPath(path); + FileInfo source = new FileInfo(FixPath(path)); + FileInfo dest = new FileInfo(Path.Combine(source.Directory.FullName, name)); + if (!source.Exists) + throw new Exception(LangRes("E_RenameFileInvalidPath")); + else if (!CanHandleFile(name)) + throw new Exception(LangRes("E_FileExtensionForbidden")); + else + { + try + { + source.MoveTo(dest.FullName); + _response.Write(GetSuccessRes()); + } + catch (Exception ex) + { + throw new Exception(ex.Message + "; " + LangRes("E_RenameFile") + " \"" + path + "\""); + } + } + } + + public bool ThumbnailCallback() + { + return false; + } + + protected void ShowThumbnail(string path, int width, int height) + { + CheckPath(path); + FileStream fs = new FileStream(FixPath(path), FileMode.Open); + Bitmap img = new Bitmap(Bitmap.FromStream(fs)); + fs.Close(); + fs.Dispose(); + int cropWidth = img.Width, cropHeight = img.Height; + int cropX = 0, cropY = 0; + + double imgRatio = (double)img.Width / (double)img.Height; + + if (height == 0) + height = Convert.ToInt32(Math.Floor((double)width / imgRatio)); + + if (width > img.Width) + width = img.Width; + if (height > img.Height) + height = img.Height; + + double cropRatio = (double)width / (double)height; + cropWidth = Convert.ToInt32(Math.Floor((double)img.Height * cropRatio)); + cropHeight = Convert.ToInt32(Math.Floor((double)cropWidth / cropRatio)); + if (cropWidth > img.Width) + { + cropWidth = img.Width; + cropHeight = Convert.ToInt32(Math.Floor((double)cropWidth / cropRatio)); + } + if (cropHeight > img.Height) + { + cropHeight = img.Height; + cropWidth = Convert.ToInt32(Math.Floor((double)cropHeight * cropRatio)); + } + if (cropWidth < img.Width) + { + cropX = Convert.ToInt32(Math.Floor((double)(img.Width - cropWidth) / 2)); + } + if (cropHeight < img.Height) + { + cropY = Convert.ToInt32(Math.Floor((double)(img.Height - cropHeight) / 2)); + } + + Rectangle area = new Rectangle(cropX, cropY, cropWidth, cropHeight); + Bitmap cropImg = img.Clone(area, System.Drawing.Imaging.PixelFormat.DontCare); + img.Dispose(); + Image.GetThumbnailImageAbort imgCallback = new Image.GetThumbnailImageAbort(ThumbnailCallback); + + _response.AddHeader("Content-Type", "image/png"); + cropImg.GetThumbnailImage(width, height, imgCallback, IntPtr.Zero).Save(_response.OutputStream, ImageFormat.Png); + _response.OutputStream.Close(); + cropImg.Dispose(); + } + + private ImageFormat GetImageFormat(string filename) + { + ImageFormat ret = ImageFormat.Jpeg; + switch (new FileInfo(filename).Extension.ToLower()) + { + case ".png": + ret = ImageFormat.Png; + break; + case ".gif": + ret = ImageFormat.Gif; + break; + } + return ret; + } + + protected void ImageResize(string path, string dest, int width, int height) + { + FileStream fs = new FileStream(path, FileMode.Open); + Image img = Image.FromStream(fs); + fs.Close(); + fs.Dispose(); + float ratio = (float)img.Width / (float)img.Height; + if ((img.Width <= width && img.Height <= height) || (width == 0 && height == 0)) + return; + + int newWidth = width; + int newHeight = Convert.ToInt16(Math.Floor((float)newWidth / ratio)); + if ((height > 0 && newHeight > height) || (width == 0)) + { + newHeight = height; + newWidth = Convert.ToInt16(Math.Floor((float)newHeight * ratio)); + } + Bitmap newImg = new Bitmap(newWidth, newHeight); + Graphics g = Graphics.FromImage((Image)newImg); + g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; + g.DrawImage(img, 0, 0, newWidth, newHeight); + img.Dispose(); + g.Dispose(); + if (dest != "") + { + newImg.Save(dest, GetImageFormat(dest)); + } + newImg.Dispose(); + } + + protected void Upload(string path) + { + CheckPath(path); + path = FixPath(path); + string res = GetSuccessRes(); + try + { + for (int i = 0; i < Request.Files.Count; i++) + { + if (CanHandleFile(Request.Files[i].FileName)) + { + string filename = MakeUniqueFilename(path, Request.Files[i].FileName); + string dest = Path.Combine(path, filename); + Request.Files[i].SaveAs(dest); + if (GetFileType(new FileInfo(filename).Extension) == "image") + { + int w = 0; + int h = 0; + int.TryParse(GetSetting("MAX_IMAGE_WIDTH"), out w); + int.TryParse(GetSetting("MAX_IMAGE_HEIGHT"), out h); + ImageResize(dest, dest, w, h); + } + } + else + res = GetSuccessRes(LangRes("E_UploadNotAll")); + } + } + catch (Exception ex) + { + res = GetErrorRes(ex.Message); + } + _response.Write(""); + } + + public bool IsReusable + { + get + { + return false; + } + } + + #endregion + + public void ProcessRequest() + { + if (!_permissionService.Authorize(StandardPermissionProvider.UploadPictures)) + { + _response.Write(GetErrorRes("You do not have the required permission")); + return; + } + + string action = "DIRLIST"; + try + { + if (_context.Request["a"] != null) + action = (string)_context.Request["a"]; + + //VerifyAction(action); + switch (action.ToUpper()) + { + case "DIRLIST": + ListDirTree(_context.Request["type"]); + break; + case "FILESLIST": + ListFiles(_context.Request["d"], _context.Request["type"]); + break; + case "COPYDIR": + CopyDir(_context.Request["d"], _context.Request["n"]); + break; + case "COPYFILE": + CopyFile(_context.Request["f"], _context.Request["n"]); + break; + case "CREATEDIR": + CreateDir(_context.Request["d"], _context.Request["n"]); + break; + case "DELETEDIR": + DeleteDir(_context.Request["d"]); + break; + case "DELETEFILE": + DeleteFile(_context.Request["f"]); + break; + case "DOWNLOAD": + DownloadFile(_context.Request["f"]); + break; + case "DOWNLOADDIR": + DownloadDir(_context.Request["d"]); + break; + case "MOVEDIR": + MoveDir(_context.Request["d"], _context.Request["n"]); + break; + case "MOVEFILE": + MoveFile(_context.Request["f"], _context.Request["n"]); + break; + case "RENAMEDIR": + RenameDir(_context.Request["d"], _context.Request["n"]); + break; + case "RENAMEFILE": + RenameFile(_context.Request["f"], _context.Request["n"]); + break; + case "GENERATETHUMB": + int w = 140, h = 0; + int.TryParse(_context.Request["width"].Replace("px", ""), out w); + int.TryParse(_context.Request["height"].Replace("px", ""), out h); + ShowThumbnail(_context.Request["f"], w, h); + break; + case "UPLOAD": + Upload(_context.Request["d"]); + break; + default: + _response.Write(GetErrorRes("This action is not implemented.")); + break; + } + } + catch (Exception ex) + { + if (action == "UPLOAD") + { + _response.Write(""); + } + else + { + _response.Write(GetErrorRes(ex.Message)); + } + } + } + } +} \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj b/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj index 15852be9a4..603f623aa1 100644 --- a/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj +++ b/src/Presentation/SmartStore.Web/Administration/SmartStore.Admin.csproj @@ -102,6 +102,7 @@ + False @@ -213,6 +214,7 @@ + @@ -429,6 +431,267 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -461,6 +724,12 @@ + + + + + + diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Shared/EditorTemplates/RichEditor.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Shared/EditorTemplates/RichEditor.cshtml index 1ba69f79da..04db8e0e26 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Shared/EditorTemplates/RichEditor.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Shared/EditorTemplates/RichEditor.cshtml @@ -29,7 +29,7 @@ "); - } - else{ - _r.Write(GetErrorRes(ex.Message)); - } - } - - } - private string FixPath(string path) - { - if (!path.StartsWith("~")){ - if (!path.StartsWith("/")) - path = "/" + path; - path = "~" + path; - } - return _context.Server.MapPath(path); - } - private string GetLangFile(){ - return "../lang/en.json"; - } - protected string LangRes(string name) - { - string ret = name; - if (_lang == null) - _lang = ParseJSON(GetLangFile()); - if (_lang.ContainsKey(name)) - ret = _lang[name]; - - return ret; - } - protected string GetFileType(string ext){ - string ret = "file"; - ext = ext.ToLower(); - if(ext == ".jpg" || ext == ".jpeg" || ext == ".png" || ext == ".gif") - ret = "image"; - else if(ext == ".swf" || ext == ".flv") - ret = "flash"; - return ret; - } - protected bool CanHandleFile(string filename) - { - bool ret = false; - FileInfo file = new FileInfo(filename); - string ext = file.Extension.Replace(".", "").ToLower(); - string setting = GetSetting("FORBIDDEN_UPLOADS").Trim().ToLower(); - if (setting != "") - { - ArrayList tmp = new ArrayList(); - tmp.AddRange(Regex.Split(setting, "\\s+")); - if (!tmp.Contains(ext)) - ret = true; - } - setting = GetSetting("ALLOWED_UPLOADS").Trim().ToLower(); - if (setting != "") - { - ArrayList tmp = new ArrayList(); - tmp.AddRange(Regex.Split(setting, "\\s+")); - if (!tmp.Contains(ext)) - ret = false; - } - - return ret; - } - protected Dictionary ParseJSON(string file){ - Dictionary ret = new Dictionary(); - string json = ""; - try{ - json = File.ReadAllText(_context.Server.MapPath(file), System.Text.Encoding.UTF8); - } - catch {} - - json = json.Trim(); - if(json != ""){ - if (json.StartsWith("{")) - json = json.Substring(1, json.Length - 2); - json = json.Trim(); - json = json.Substring(1, json.Length - 2); - string[] lines = Regex.Split(json, "\"\\s*,\\s*\""); - foreach(string line in lines){ - string[] tmp = Regex.Split(line, "\"\\s*:\\s*\""); - try{ - if (tmp[0] != "" && !ret.ContainsKey(tmp[0])) - { - ret.Add(tmp[0], tmp[1]); - } - } - catch {} - } - } - return ret; - } - protected string GetFilesRoot(){ - string ret = GetSetting("FILES_ROOT"); - if (GetSetting("SESSION_PATH_KEY") != "" && _context.Session[GetSetting("SESSION_PATH_KEY")] != null) - ret = (string)_context.Session[GetSetting("SESSION_PATH_KEY")]; - - if(ret == "") - ret = _context.Server.MapPath("../Uploads"); - else - ret = FixPath(ret); - return ret; - } - protected void LoadConf(){ - if(_settings == null) - _settings = ParseJSON(confFile); - } - protected string GetSetting(string name){ - string ret = ""; - LoadConf(); - if(_settings.ContainsKey(name)) - ret = _settings[name]; - - return ret; - } - protected void CheckPath(string path) - { - if (FixPath(path).IndexOf(GetFilesRoot()) != 0) - { - throw new Exception("Access to " + path + " is denied"); - } - } - protected void VerifyAction(string action) - { - string setting = GetSetting(action); - if (setting.IndexOf("?") > -1) - setting = setting.Substring(0, setting.IndexOf("?")); - if (!setting.StartsWith("/")) - setting = "/" + setting; - setting = ".." + setting; - - if (_context.Server.MapPath(setting) != _context.Server.MapPath(_context.Request.Url.LocalPath)) - throw new Exception(LangRes("E_ActionDisabled")); - } - protected string GetResultStr(string type, string msg) - { - return "{\"res\":\"" + type + "\",\"msg\":\"" + msg.Replace("\"","\\\"") + "\"}"; - } - protected string GetSuccessRes(string msg) - { - return GetResultStr("ok", msg); - } - protected string GetSuccessRes() - { - return GetSuccessRes(""); - } - protected string GetErrorRes(string msg) - { - return GetResultStr("error", msg); - } - private void _copyDir(string path, string dest){ - if(!Directory.Exists(dest)) - Directory.CreateDirectory(dest); - foreach(string f in Directory.GetFiles(path)){ - FileInfo file = new FileInfo(f); - if (!File.Exists(Path.Combine(dest, file.Name))){ - File.Copy(f, Path.Combine(dest, file.Name)); - } - } - foreach (string d in Directory.GetDirectories(path)) - { - DirectoryInfo dir = new DirectoryInfo(d); - _copyDir(d, Path.Combine(dest, dir.Name)); - } - } - protected void CopyDir(string path, string newPath) - { - CheckPath(path); - CheckPath(newPath); - DirectoryInfo dir = new DirectoryInfo(FixPath(path)); - DirectoryInfo newDir = new DirectoryInfo(FixPath(newPath + "/" + dir.Name)); - - if (!dir.Exists) - { - throw new Exception(LangRes("E_CopyDirInvalidPath")); - } - else if (newDir.Exists) - { - throw new Exception(LangRes("E_DirAlreadyExists")); - } - else{ - _copyDir(dir.FullName, newDir.FullName); - } - _r.Write(GetSuccessRes()); - } - protected string MakeUniqueFilename(string dir, string filename){ - string ret = filename; - int i = 0; - while (File.Exists(Path.Combine(dir, ret))) - { - i++; - ret = Path.GetFileNameWithoutExtension(filename) + " - Copy " + i.ToString() + Path.GetExtension(filename); - } - return ret; - } - protected void CopyFile(string path, string newPath) - { - CheckPath(path); - FileInfo file = new FileInfo(FixPath(path)); - newPath = FixPath(newPath); - if (!file.Exists) - throw new Exception(LangRes("E_CopyFileInvalisPath")); - else{ - string newName = MakeUniqueFilename(newPath, file.Name); - try{ - File.Copy(file.FullName, Path.Combine(newPath, newName)); - _r.Write(GetSuccessRes()); - } - catch { - throw new Exception(LangRes("E_CopyFile")); - } - } - } - protected void CreateDir(string path, string name) - { - CheckPath(path); - path = FixPath(path); - if(!Directory.Exists(path)) - throw new Exception(LangRes("E_CreateDirInvalidPath")); - else{ - try - { - path = Path.Combine(path, name); - if(!Directory.Exists(path)) - Directory.CreateDirectory(path); - _r.Write(GetSuccessRes()); - } - catch - { - throw new Exception(LangRes("E_CreateDirFailed")); - } - } - } - protected void DeleteDir(string path) - { - CheckPath(path); - path = FixPath(path); - if (!Directory.Exists(path)) - throw new Exception(LangRes("E_DeleteDirInvalidPath")); - else if (path == GetFilesRoot()) - throw new Exception(LangRes("E_CannotDeleteRoot")); - else if(Directory.GetDirectories(path).Length > 0 || Directory.GetFiles(path).Length > 0) - throw new Exception(LangRes("E_DeleteNonEmpty")); - else - { - try - { - Directory.Delete(path); - _r.Write(GetSuccessRes()); - } - catch - { - throw new Exception(LangRes("E_CannotDeleteDir")); - } - } - } - protected void DeleteFile(string path) - { - CheckPath(path); - path = FixPath(path); - if (!File.Exists(path)) - throw new Exception(LangRes("E_DeleteFileInvalidPath")); - else - { - try - { - File.Delete(path); - _r.Write(GetSuccessRes()); - } - catch - { - throw new Exception(LangRes("E_DeletеFile")); - } - } - } - private List GetFiles(string path, string type){ - List ret = new List(); - if(type == "#") - type = ""; - string[] files = Directory.GetFiles(path); - foreach(string f in files){ - if ((GetFileType(new FileInfo(f).Extension) == type) || (type == "")) - ret.Add(f); - } - return ret; - } - private ArrayList ListDirs(string path){ - string[] dirs = Directory.GetDirectories(path); - ArrayList ret = new ArrayList(); - foreach(string dir in dirs){ - ret.Add(dir); - ret.AddRange(ListDirs(dir)); - } - return ret; - } - protected void ListDirTree(string type) - { - DirectoryInfo d = new DirectoryInfo(GetFilesRoot()); - if(!d.Exists) - throw new Exception("Invalid files root directory. Check your configuration."); - - ArrayList dirs = ListDirs(d.FullName); - dirs.Insert(0, d.FullName); - - string localPath = _context.Server.MapPath("~/"); - _r.Write("["); - for(int i = 0; i files = GetFiles(fullPath, type); - _r.Write("["); - for(int i = 0; i < files.Count; i++){ - FileInfo f = new FileInfo(files[i]); - int w = 0, h = 0; - if (GetFileType(f.Extension) == "image"){ - try{ - FileStream fs = new FileStream(f.FullName, FileMode.Open); - Image img = Image.FromStream(fs); - w = img.Width; - h = img.Height; - fs.Close(); - fs.Dispose(); - img.Dispose(); - } - catch(Exception ex) - { - throw ex; - } - } - _r.Write("{"); - _r.Write("\"p\":\""+path + "/" + f.Name+"\""); - _r.Write(",\"t\":\"" + Math.Ceiling(LinuxTimestamp(f.LastWriteTime)).ToString() + "\""); - _r.Write(",\"s\":\""+f.Length.ToString()+"\""); - _r.Write(",\"w\":\""+w.ToString()+"\""); - _r.Write(",\"h\":\""+h.ToString()+"\""); - _r.Write("}"); - if (i < files.Count - 1) - _r.Write(","); - } - _r.Write("]"); - } - public void DownloadDir(string path) - { - path = FixPath(path); - if(!Directory.Exists(path)) - throw new Exception(LangRes("E_CreateArchive")); - string dirName = new FileInfo(path).Name; - string tmpZip = _context.Server.MapPath("../tmp/" + dirName + ".zip"); - if(File.Exists(tmpZip)) - File.Delete(tmpZip); - ZipFile.CreateFromDirectory(path, tmpZip,CompressionLevel.Fastest, true); - _r.Clear(); - _r.Headers.Add("Content-Disposition", "attachment; filename=\"" + dirName + ".zip\""); - _r.ContentType = "application/force-download"; - _r.TransmitFile(tmpZip); - _r.Flush(); - File.Delete(tmpZip); - _r.End(); - } - protected void DownloadFile(string path) - { - CheckPath(path); - FileInfo file = new FileInfo(FixPath(path)); - if(file.Exists){ - _r.Clear(); - _r.Headers.Add("Content-Disposition", "attachment; filename=\"" + file.Name + "\""); - _r.ContentType = "application/force-download"; - _r.TransmitFile(file.FullName); - _r.Flush(); - _r.End(); - } - } - protected void MoveDir(string path, string newPath) - { - CheckPath(path); - CheckPath(newPath); - DirectoryInfo source = new DirectoryInfo(FixPath(path)); - DirectoryInfo dest = new DirectoryInfo(FixPath(Path.Combine(newPath, source.Name))); - if(dest.FullName.IndexOf(source.FullName) == 0) - throw new Exception(LangRes("E_CannotMoveDirToChild")); - else if (!source.Exists) - throw new Exception(LangRes("E_MoveDirInvalisPath")); - else if (dest.Exists) - throw new Exception(LangRes("E_DirAlreadyExists")); - else{ - try{ - source.MoveTo(dest.FullName); - _r.Write(GetSuccessRes()); - } - catch { - throw new Exception(LangRes("E_MoveDir") + " \"" + path + "\""); - } - } - - } - protected void MoveFile(string path, string newPath) - { - CheckPath(path); - CheckPath(newPath); - FileInfo source = new FileInfo(FixPath(path)); - FileInfo dest = new FileInfo(FixPath(newPath)); - if (!source.Exists) - throw new Exception(LangRes("E_MoveFileInvalisPath")); - else if (dest.Exists) - throw new Exception(LangRes("E_MoveFileAlreadyExists")); - else - { - try - { - source.MoveTo(dest.FullName); - _r.Write(GetSuccessRes()); - } - catch - { - throw new Exception(LangRes("E_MoveFile") + " \"" + path + "\""); - } - } - } - protected void RenameDir(string path, string name) - { - CheckPath(path); - DirectoryInfo source = new DirectoryInfo(FixPath(path)); - DirectoryInfo dest = new DirectoryInfo(Path.Combine(source.Parent.FullName, name)); - if(source.FullName == GetFilesRoot()) - throw new Exception(LangRes("E_CannotRenameRoot")); - else if (!source.Exists) - throw new Exception(LangRes("E_RenameDirInvalidPath")); - else if (dest.Exists) - throw new Exception(LangRes("E_DirAlreadyExists")); - else - { - try - { - source.MoveTo(dest.FullName); - _r.Write(GetSuccessRes()); - } - catch - { - throw new Exception(LangRes("E_RenameDir") + " \"" + path + "\""); - } - } - } - protected void RenameFile(string path, string name) - { - CheckPath(path); - FileInfo source = new FileInfo(FixPath(path)); - FileInfo dest = new FileInfo(Path.Combine(source.Directory.FullName, name)); - if (!source.Exists) - throw new Exception(LangRes("E_RenameFileInvalidPath")); - else if (!CanHandleFile(name)) - throw new Exception(LangRes("E_FileExtensionForbidden")); - else - { - try - { - source.MoveTo(dest.FullName); - _r.Write(GetSuccessRes()); - } - catch (Exception ex) - { - throw new Exception(ex.Message + "; " + LangRes("E_RenameFile") + " \"" + path + "\""); - } - } - } - public bool ThumbnailCallback() - { - return false; - } - - protected void ShowThumbnail(string path, int width, int height) - { - CheckPath(path); - FileStream fs = new FileStream(FixPath(path), FileMode.Open); - Bitmap img = new Bitmap(Bitmap.FromStream(fs)); - fs.Close(); - fs.Dispose(); - int cropWidth = img.Width, cropHeight = img.Height; - int cropX = 0, cropY = 0; - - double imgRatio = (double)img.Width / (double)img.Height; - - if(height == 0) - height = Convert.ToInt32(Math.Floor((double)width / imgRatio)); - - if (width > img.Width) - width = img.Width; - if (height > img.Height) - height = img.Height; - - double cropRatio = (double)width / (double)height; - cropWidth = Convert.ToInt32(Math.Floor((double)img.Height * cropRatio)); - cropHeight = Convert.ToInt32(Math.Floor((double)cropWidth / cropRatio)); - if (cropWidth > img.Width) - { - cropWidth = img.Width; - cropHeight = Convert.ToInt32(Math.Floor((double)cropWidth / cropRatio)); - } - if (cropHeight > img.Height) - { - cropHeight = img.Height; - cropWidth = Convert.ToInt32(Math.Floor((double)cropHeight * cropRatio)); - } - if(cropWidth < img.Width){ - cropX = Convert.ToInt32(Math.Floor((double)(img.Width - cropWidth) / 2)); - } - if(cropHeight < img.Height){ - cropY = Convert.ToInt32(Math.Floor((double)(img.Height - cropHeight) / 2)); - } - - Rectangle area = new Rectangle(cropX, cropY, cropWidth, cropHeight); - Bitmap cropImg = img.Clone(area, System.Drawing.Imaging.PixelFormat.DontCare); - img.Dispose(); - Image.GetThumbnailImageAbort imgCallback = new Image.GetThumbnailImageAbort(ThumbnailCallback); - - _r.AddHeader("Content-Type", "image/png"); - cropImg.GetThumbnailImage(width, height, imgCallback, IntPtr.Zero).Save(_r.OutputStream, ImageFormat.Png); - _r.OutputStream.Close(); - cropImg.Dispose(); - } - private ImageFormat GetImageFormat(string filename){ - ImageFormat ret = ImageFormat.Jpeg; - switch(new FileInfo(filename).Extension.ToLower()){ - case ".png": ret = ImageFormat.Png; break; - case ".gif": ret = ImageFormat.Gif; break; - } - return ret; - } - protected void ImageResize(string path, string dest, int width, int height) - { - FileStream fs = new FileStream(path, FileMode.Open); - Image img = Image.FromStream(fs); - fs.Close(); - fs.Dispose(); - float ratio = (float)img.Width / (float)img.Height; - if ((img.Width <= width && img.Height <= height) || (width == 0 && height == 0)) - return; - - int newWidth = width; - int newHeight = Convert.ToInt16(Math.Floor((float)newWidth / ratio)); - if ((height > 0 && newHeight > height) || (width == 0)) - { - newHeight = height; - newWidth = Convert.ToInt16(Math.Floor((float)newHeight * ratio)); - } - Bitmap newImg = new Bitmap(newWidth, newHeight); - Graphics g = Graphics.FromImage((Image)newImg); - g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; - g.DrawImage(img, 0, 0, newWidth, newHeight); - img.Dispose(); - g.Dispose(); - if(dest != ""){ - newImg.Save(dest, GetImageFormat(dest)); - } - newImg.Dispose(); - } - - protected void Upload(string path) - { - CheckPath(path); - path = FixPath(path); - string res = GetSuccessRes(); - try{ - for(int i = 0; i < HttpContext.Current.Request.Files.Count; i++){ - if (CanHandleFile(HttpContext.Current.Request.Files[i].FileName)) - { - string filename = MakeUniqueFilename(path, HttpContext.Current.Request.Files[i].FileName); - string dest = Path.Combine(path, filename); - HttpContext.Current.Request.Files[i].SaveAs(dest); - if(GetFileType(new FileInfo(filename).Extension) == "image"){ - int w = 0; - int h = 0; - int.TryParse(GetSetting("MAX_IMAGE_WIDTH"), out w); - int.TryParse(GetSetting("MAX_IMAGE_HEIGHT"), out h); - ImageResize(dest, dest, w, h); - } - } - else - res = GetSuccessRes(LangRes("E_UploadNotAll")); - } - } - catch(Exception ex){ - res = GetErrorRes(ex.Message); - } - _r.Write(""); - } - - public bool IsReusable { - get { - return false; - } - } - -} \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/Content/filemanager/conf.json b/src/Presentation/SmartStore.Web/Content/filemanager/conf.json deleted file mode 100644 index 3df29bf505..0000000000 --- a/src/Presentation/SmartStore.Web/Content/filemanager/conf.json +++ /dev/null @@ -1,34 +0,0 @@ -{ -"FILES_ROOT": "~/Media/Uploaded", -"SESSION_PATH_KEY": "", -"THUMBS_VIEW_WIDTH": "140", -"THUMBS_VIEW_HEIGHT": "120", -"PREVIEW_THUMB_WIDTH":"300", -"PREVIEW_THUMB_HEIGHT":"200", -"MAX_IMAGE_WIDTH": "0", -"MAX_IMAGE_HEIGHT": "0", -"INTEGRATION": "ckeditor", -"DIRLIST": "asp_net/main.ashx?a=DIRLIST", -"CREATEDIR": "asp_net/main.ashx?a=CREATEDIR", -"DELETEDIR": "asp_net/main.ashx?a=DELETEDIR", -"MOVEDIR": "asp_net/main.ashx?a=MOVEDIR", -"COPYDIR": "asp_net/main.ashx?a=COPYDIR", -"RENAMEDIR": "asp_net/main.ashx?a=RENAMEDIR", -"FILESLIST": "asp_net/main.ashx?a=FILESLIST", -"UPLOAD": "asp_net/main.ashx?a=UPLOAD", -"DOWNLOAD": "asp_net/main.ashx?a=DOWNLOAD", -"DOWNLOADDIR": "asp_net/main.ashx?a=DOWNLOADDIR", -"DOWNLOADDIR": "asp_net/main.ashx?a=DOWNLOADDIR", -"DELETEFILE": "asp_net/main.ashx?a=DELETEFILE", -"MOVEFILE": "asp_net/main.ashx?a=MOVEFILE", -"COPYFILE": "asp_net/main.ashx?a=COPYFILE", -"RENAMEFILE": "asp_net/main.ashx?a=RENAMEFILE", -"GENERATETHUMB": "asp_net/main.ashx?a=GENERATETHUMB", -"DEFAULTVIEW": "list", -"FORBIDDEN_UPLOADS": "zip js jsp jsb mhtml mht xhtml xht php phtml php3 php4 php5 phps shtml jhtml pl sh py cgi exe scr dll msi vbs bat com pif cmd vxd cpl htpasswd htaccess", -"ALLOWED_UPLOADS": "", -"FILEPERMISSIONS": "0644", -"DIRPERMISSIONS": "0755", -"LANG": "auto", -"DATEFORMAT": "dd.MM.yyyy HH:mm" -} \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/SmartStore.Web.csproj b/src/Presentation/SmartStore.Web/SmartStore.Web.csproj index 2bd35ba917..8340a62bfb 100644 --- a/src/Presentation/SmartStore.Web/SmartStore.Web.csproj +++ b/src/Presentation/SmartStore.Web/SmartStore.Web.csproj @@ -645,267 +645,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -919,13 +658,6 @@ - - - - - - - From 8e1c3f47188692020652696177667d4149bf59dc Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Thu, 23 Jun 2016 09:39:37 +0200 Subject: [PATCH 44/73] Delete old static files of file manager by migration --- .../Migrations/201605201911421_ExportRevision.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Libraries/SmartStore.Data/Migrations/201605201911421_ExportRevision.cs b/src/Libraries/SmartStore.Data/Migrations/201605201911421_ExportRevision.cs index 485fa9fdec..486bff7969 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201605201911421_ExportRevision.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201605201911421_ExportRevision.cs @@ -5,6 +5,7 @@ namespace SmartStore.Data.Migrations using Core.Domain; using Core.Domain.DataExchange; using Setup; + using Utilities; public partial class ExportRevision : DbMigration, ILocaleResourcesProvider, IDataSeeder { @@ -58,6 +59,9 @@ public void Seed(SmartObjectContext context) context.ColumnDelete("ExportDeployment", "IsPublic"); } + + var oldFileManagerPath = CommonHelper.MapPath("~/Content/filemanager"); + FileSystemHelper.ClearDirectory(oldFileManagerPath, true); } public void MigrateLocaleResources(LocaleResourcesBuilder builder) From e79c397d0e39d03a22de7418744a880da833b9e8 Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Thu, 23 Jun 2016 14:05:05 +0200 Subject: [PATCH 45/73] Resolves #950 make contact form comply with current German law --- changelog.md | 1 + .../Domain/Customers/CustomerSettings.cs | 6 +++++ .../201605201911421_ExportRevision.cs | 17 ++++++++++++ .../Settings/CustomerUserSettingsModel.cs | 3 +++ .../Views/Setting/CustomerUser.cshtml | 9 +++++++ .../Controllers/HomeController.cs | 10 +++++-- .../Models/Common/ContactUsModel.cs | 5 ++++ .../Validators/Common/ContactUsValidator.cs | 5 ++++ .../Views/Home/ContactUs.cshtml | 27 +++++++++++++++---- 9 files changed, 76 insertions(+), 7 deletions(-) diff --git a/changelog.md b/changelog.md index 47f492ff48..0dac88a9fd 100644 --- a/changelog.md +++ b/changelog.md @@ -19,6 +19,7 @@ * #477 Implement option to specify the number of exported and imported pictures * #859 Make checkout attributes suitable for multi-stores * Product details: Select attribute and gift card values by query string parameters +* #950 make contact form comply with current German law ### Improvements * Major improvements in Importer: better field mapping, higher performance, bug fixes etc. diff --git a/src/Libraries/SmartStore.Core/Domain/Customers/CustomerSettings.cs b/src/Libraries/SmartStore.Core/Domain/Customers/CustomerSettings.cs index d0dbf678e5..e6d7f56f56 100644 --- a/src/Libraries/SmartStore.Core/Domain/Customers/CustomerSettings.cs +++ b/src/Libraries/SmartStore.Core/Domain/Customers/CustomerSettings.cs @@ -24,6 +24,7 @@ public CustomerSettings() NewsletterEnabled = true; OnlineCustomerMinutes = 20; StoreLastVisitedPage = true; + DisplayPrivacyAgreementOnContactUs = false; } /// @@ -151,6 +152,11 @@ public CustomerSettings() /// public bool StoreLastVisitedPage { get; set; } + /// + /// Gets or sets a value indicating whether to display a checkbox to the customer where he can agree to privacy terms + /// + public bool DisplayPrivacyAgreementOnContactUs { get; set; } + #region Form fields /// diff --git a/src/Libraries/SmartStore.Data/Migrations/201605201911421_ExportRevision.cs b/src/Libraries/SmartStore.Data/Migrations/201605201911421_ExportRevision.cs index 486bff7969..d168932260 100644 --- a/src/Libraries/SmartStore.Data/Migrations/201605201911421_ExportRevision.cs +++ b/src/Libraries/SmartStore.Data/Migrations/201605201911421_ExportRevision.cs @@ -174,6 +174,23 @@ public void MigrateLocaleResources(LocaleResourcesBuilder builder) "This function is not available for guests.", "Diese Funktion steht für Gäste nicht zur Verfügung."); + builder.AddOrUpdate("ContactUs.PrivacyAgreement", + "Privacy consent", + "Einwilligungserklärung Datenschutz"); + + builder.AddOrUpdate("ContactUs.PrivacyAgreement.MustBeAccepted", + "Please agree to the storage of your data.", + "Bitte stimmen Sie der Speicherung Ihrer Daten zu."); + + builder.AddOrUpdate("ContactUs.PrivacyAgreement.DetailText", + "Yes I've read the privacy terms and agree that my data given by me can be stored electronically. My data will thereby only be used to process my inquiry.", + "Ja, ich habe die Datenschutzerklärung zur Kenntnis genommen und bin damit einverstanden, dass die von mir angegebenen Daten elektronisch erhoben und gespeichert werden. Meine Daten werden dabei nur zur Bearbeitung meiner Anfrage genutzt."); + + builder.AddOrUpdate("Admin.Configuration.Settings.CustomerUser.DisplayPrivacyAgreementOnContactUs", + "Get privacy consent for contact requests", + "Einwilligungserklärung im Kontaktformular fordern", + "Specifies whether a checkbox will be displayed on the contact page which requests the user to agree on storage of his data.", + "Bestimmt ob im Kontaktformular eine Checkbox angezeigt wird, die den Benutzer auffordert der Speicherung seiner Daten zuzustimmen."); builder.Delete( diff --git a/src/Presentation/SmartStore.Web/Administration/Models/Settings/CustomerUserSettingsModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/Settings/CustomerUserSettingsModel.cs index bfbb495345..f395584d6c 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/Settings/CustomerUserSettingsModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/Settings/CustomerUserSettingsModel.cs @@ -89,6 +89,9 @@ public partial class CustomerSettingsModel [SmartResourceDisplayName("Admin.Configuration.Settings.CustomerUser.StoreLastVisitedPage")] public bool StoreLastVisitedPage { get; set; } + [SmartResourceDisplayName("Admin.Configuration.Settings.CustomerUser.DisplayPrivacyAgreementOnContactUs")] + public bool DisplayPrivacyAgreementOnContactUs { get; set; } + [SmartResourceDisplayName("Admin.Configuration.Settings.CustomerUser.GenderEnabled")] public bool GenderEnabled { get; set; } diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Setting/CustomerUser.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Setting/CustomerUser.cshtml index 1d868a640d..ccb0eb2876 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Setting/CustomerUser.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Setting/CustomerUser.cshtml @@ -259,6 +259,15 @@ @Html.ValidationMessageFor(model => model.CustomerSettings.StoreLastVisitedPage) + + + @Html.SmartLabelFor(model => model.CustomerSettings.DisplayPrivacyAgreementOnContactUs) + + + @Html.SettingEditorFor(model => model.CustomerSettings.DisplayPrivacyAgreementOnContactUs) + @Html.ValidationMessageFor(model => model.CustomerSettings.DisplayPrivacyAgreementOnContactUs) + + } @helper TabCustomerFormFields() diff --git a/src/Presentation/SmartStore.Web/Controllers/HomeController.cs b/src/Presentation/SmartStore.Web/Controllers/HomeController.cs index e16d5e80b7..58e6eb4ace 100644 --- a/src/Presentation/SmartStore.Web/Controllers/HomeController.cs +++ b/src/Presentation/SmartStore.Web/Controllers/HomeController.cs @@ -6,6 +6,7 @@ using SmartStore.Core.Domain.Catalog; using SmartStore.Core.Domain.Cms; using SmartStore.Core.Domain.Common; +using SmartStore.Core.Domain.Customers; using SmartStore.Core.Domain.Messages; using SmartStore.Core.Infrastructure; using SmartStore.Core.Localization; @@ -41,6 +42,7 @@ public partial class HomeController : PublicControllerBase private readonly Lazy _sitemapGenerator; private readonly Lazy _captchaSettings; private readonly Lazy _commonSettings; + private readonly Lazy _customerSettings; #endregion @@ -56,7 +58,8 @@ public HomeController( Lazy emailAccountService, Lazy sitemapGenerator, Lazy captchaSettings, - Lazy commonSettings) + Lazy commonSettings, + Lazy customerSettings) { this._services = services; this._categoryService = categoryService; @@ -68,6 +71,7 @@ public HomeController( this._sitemapGenerator = sitemapGenerator; this._captchaSettings = captchaSettings; this._commonSettings = commonSettings; + this._customerSettings = customerSettings; } #endregion @@ -119,7 +123,9 @@ public ActionResult ContactUs() { Email = _services.WorkContext.CurrentCustomer.Email, FullName = _services.WorkContext.CurrentCustomer.GetFullName(), - DisplayCaptcha = _captchaSettings.Value.Enabled && _captchaSettings.Value.ShowOnContactUsPage + DisplayCaptcha = _captchaSettings.Value.Enabled && _captchaSettings.Value.ShowOnContactUsPage, + DisplayPrivacyAgreement = _customerSettings.Value.DisplayPrivacyAgreementOnContactUs + }; return View(model); diff --git a/src/Presentation/SmartStore.Web/Models/Common/ContactUsModel.cs b/src/Presentation/SmartStore.Web/Models/Common/ContactUsModel.cs index f20fd69129..db9ab838bc 100644 --- a/src/Presentation/SmartStore.Web/Models/Common/ContactUsModel.cs +++ b/src/Presentation/SmartStore.Web/Models/Common/ContactUsModel.cs @@ -10,6 +10,11 @@ namespace SmartStore.Web.Models.Common [Validator(typeof(ContactUsValidator))] public partial class ContactUsModel : ModelBase { + [SmartResourceDisplayName("ContactUs.PrivacyAgreement")] + public bool PrivacyAgreement { get; set; } + + public bool DisplayPrivacyAgreement { get; set; } + [AllowHtml] [SmartResourceDisplayName("ContactUs.Email")] [DataType(DataType.EmailAddress)] diff --git a/src/Presentation/SmartStore.Web/Validators/Common/ContactUsValidator.cs b/src/Presentation/SmartStore.Web/Validators/Common/ContactUsValidator.cs index 7e9b037037..9e42f7ed02 100644 --- a/src/Presentation/SmartStore.Web/Validators/Common/ContactUsValidator.cs +++ b/src/Presentation/SmartStore.Web/Validators/Common/ContactUsValidator.cs @@ -8,6 +8,11 @@ public class ContactUsValidator : AbstractValidator { public ContactUsValidator(ILocalizationService localizationService) { + RuleFor(x => x.PrivacyAgreement) + .Must(x => x == true) + .WithMessage(localizationService.GetResource("ContactUs.PrivacyAgreement.MustBeAccepted")) + .When(x => x.DisplayPrivacyAgreement == true); + RuleFor(x => x.Email).NotEmpty().WithMessage(localizationService.GetResource("ContactUs.Email.Required")); RuleFor(x => x.Email).EmailAddress().WithMessage(localizationService.GetResource("Common.WrongEmail")); RuleFor(x => x.FullName).NotEmpty().WithMessage(localizationService.GetResource("ContactUs.FullName.Required")); diff --git a/src/Presentation/SmartStore.Web/Views/Home/ContactUs.cshtml b/src/Presentation/SmartStore.Web/Views/Home/ContactUs.cshtml index d0b173f3f2..7105b3d794 100644 --- a/src/Presentation/SmartStore.Web/Views/Home/ContactUs.cshtml +++ b/src/Presentation/SmartStore.Web/Views/Home/ContactUs.cshtml @@ -24,11 +24,6 @@ {
- @if (!ViewData.ModelState.IsValid) - { - @Html.ValidationSummary(true) - } - @T("PageTitle.ContactUs")
@@ -55,6 +50,28 @@
+ @if(Model.DisplayPrivacyAgreement) + { + @Html.HiddenFor(model => model.DisplayPrivacyAgreement) + +
+ @Html.LabelFor(model => model.PrivacyAgreement, new { @class = "control-label required", @for = "PrivacyAgreement" }) +
+
+ +
+
+ @Html.ValidationMessageFor(model => model.PrivacyAgreement) +
+
+
+ } + @if (Model.DisplayCaptcha) {
From da1e3d1cd857bbb41b615b85e6d90d55820edfb3 Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Thu, 23 Jun 2016 14:53:38 +0200 Subject: [PATCH 46/73] Increased version number to 2.6.0 --- SmartStoreNET.Tasks.Targets | 2 +- src/AssemblyVersionInfo.cs | 6 +- .../SmartStore.AmazonPay/Description.txt | 2 +- .../SmartStore.Clickatell/Description.txt | 2 +- .../SmartStore.DevTools/Description.txt | 2 +- .../SmartStore.DiscountRules/Description.txt | 2 +- .../SmartStore.FacebookAuth/Description.txt | 2 +- .../Description.txt | 2 +- .../Description.txt | 2 +- .../SmartStore.OfflinePayment/Description.txt | 2 +- src/Plugins/SmartStore.PayPal/Description.txt | 2 +- .../SmartStore.Shipping/Description.txt | 2 +- .../Description.txt | 2 +- src/Plugins/SmartStore.Tax/Description.txt | 2 +- src/Plugins/SmartStore.WebApi/Description.txt | 2 +- .../Localization/App/de/all.smres.xml | 339 ++++++++++++++++-- .../App_Data/Localization/App/de/head.txt | 2 +- .../Localization/App/en/all.smres.xml | 333 +++++++++++++++-- .../App_Data/Localization/App/en/head.txt | 2 +- 19 files changed, 616 insertions(+), 94 deletions(-) diff --git a/SmartStoreNET.Tasks.Targets b/SmartStoreNET.Tasks.Targets index 4fb755fcf5..f184eaa7eb 100644 --- a/SmartStoreNET.Tasks.Targets +++ b/SmartStoreNET.Tasks.Targets @@ -44,7 +44,7 @@ x86 $(BUILD_NUMBER) - 2.5.0 + 2.6.0 $(StageFolder) .$(Version) diff --git a/src/AssemblyVersionInfo.cs b/src/AssemblyVersionInfo.cs index 67335b18c1..f74f0edf78 100644 --- a/src/AssemblyVersionInfo.cs +++ b/src/AssemblyVersionInfo.cs @@ -9,7 +9,7 @@ // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("2.5.0.0")] +[assembly: AssemblyVersion("2.6.0.0")] -[assembly: AssemblyFileVersion("2.5.0.0")] -[assembly: AssemblyInformationalVersion("2.5.0.0")] +[assembly: AssemblyFileVersion("2.6.0.0")] +[assembly: AssemblyInformationalVersion("2.6.0.0")] diff --git a/src/Plugins/SmartStore.AmazonPay/Description.txt b/src/Plugins/SmartStore.AmazonPay/Description.txt index 3e203915e6..8237c4a7ad 100644 --- a/src/Plugins/SmartStore.AmazonPay/Description.txt +++ b/src/Plugins/SmartStore.AmazonPay/Description.txt @@ -1,6 +1,6 @@ FriendlyName: Pay with Amazon SystemName: SmartStore.AmazonPay -Version: 2.5.0 +Version: 2.6.0 Group: Payment MinAppVersion: 2.5.0 Author: SmartStore AG diff --git a/src/Plugins/SmartStore.Clickatell/Description.txt b/src/Plugins/SmartStore.Clickatell/Description.txt index d5e561a2fc..177b509843 100644 --- a/src/Plugins/SmartStore.Clickatell/Description.txt +++ b/src/Plugins/SmartStore.Clickatell/Description.txt @@ -1,7 +1,7 @@ FriendlyName: Clickatell SMS Provider SystemName: SmartStore.Clickatell Group: Mobile -Version: 2.5.0 +Version: 2.6.0 MinAppVersion: 2.5.0 DisplayOrder: 1 FileName: SmartStore.Clickatell.dll diff --git a/src/Plugins/SmartStore.DevTools/Description.txt b/src/Plugins/SmartStore.DevTools/Description.txt index fff9df57de..b169d8b16a 100644 --- a/src/Plugins/SmartStore.DevTools/Description.txt +++ b/src/Plugins/SmartStore.DevTools/Description.txt @@ -1,7 +1,7 @@ FriendlyName: SmartStore.NET Developer Tools (MiniProfiler and other goodies) SystemName: SmartStore.DevTools Group: Developer -Version: 2.5.0 +Version: 2.6.0 MinAppVersion: 2.5.0 DisplayOrder: 1 FileName: SmartStore.DevTools.dll diff --git a/src/Plugins/SmartStore.DiscountRules/Description.txt b/src/Plugins/SmartStore.DiscountRules/Description.txt index a2336d8b8e..f4bb29d728 100644 --- a/src/Plugins/SmartStore.DiscountRules/Description.txt +++ b/src/Plugins/SmartStore.DiscountRules/Description.txt @@ -2,7 +2,7 @@ Description: Contains common discount requirement rule providers like "Billing country is", "Customer role is", "Had spent amount" etc. Group: Marketing SystemName: SmartStore.DiscountRules -Version: 2.5.0.1 +Version: 2.6.0 MinAppVersion: 2.5.0 DisplayOrder: 0 FileName: SmartStore.DiscountRules.dll diff --git a/src/Plugins/SmartStore.FacebookAuth/Description.txt b/src/Plugins/SmartStore.FacebookAuth/Description.txt index 6e028c02d4..b5411fc4ac 100644 --- a/src/Plugins/SmartStore.FacebookAuth/Description.txt +++ b/src/Plugins/SmartStore.FacebookAuth/Description.txt @@ -1,7 +1,7 @@ FriendlyName: Facebook SystemName: SmartStore.FacebookAuth Group: Security -Version: 2.5.0 +Version: 2.6.0 MinAppVersion: 2.5.0 DisplayOrder: 5 FileName: SmartStore.FacebookAuth.dll diff --git a/src/Plugins/SmartStore.GoogleAnalytics/Description.txt b/src/Plugins/SmartStore.GoogleAnalytics/Description.txt index 908e329118..59bf21b018 100644 --- a/src/Plugins/SmartStore.GoogleAnalytics/Description.txt +++ b/src/Plugins/SmartStore.GoogleAnalytics/Description.txt @@ -1,7 +1,7 @@ FriendlyName: Google Analytics SystemName: SmartStore.GoogleAnalytics Group: Analytics -Version: 2.5.0 +Version: 2.6.0 MinAppVersion: 2.5.0 DisplayOrder: 1 FileName: SmartStore.GoogleAnalytics.dll diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Description.txt b/src/Plugins/SmartStore.GoogleMerchantCenter/Description.txt index 8187db5c15..5bc3e9ad59 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/Description.txt +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Description.txt @@ -1,7 +1,7 @@ FriendlyName: Google Merchant Center (GMC) feed SystemName: SmartStore.GoogleMerchantCenter Group: Marketing -Version: 2.5.0.1 +Version: 2.6.0 MinAppVersion: 2.5.0 Author: SmartStore AG DisplayOrder: 1 diff --git a/src/Plugins/SmartStore.OfflinePayment/Description.txt b/src/Plugins/SmartStore.OfflinePayment/Description.txt index 0b09221978..db6f0241f9 100644 --- a/src/Plugins/SmartStore.OfflinePayment/Description.txt +++ b/src/Plugins/SmartStore.OfflinePayment/Description.txt @@ -2,7 +2,7 @@ Description: Contains common offline payment methods like Direct Debit, Invoice, Prepayment etc. Group: Payment SystemName: SmartStore.OfflinePayment -Version: 2.5.0 +Version: 2.6.0 MinAppVersion: 2.5.0 DisplayOrder: 0 FileName: SmartStore.OfflinePayment.dll diff --git a/src/Plugins/SmartStore.PayPal/Description.txt b/src/Plugins/SmartStore.PayPal/Description.txt index c78ff1bd32..75a43e5adb 100644 --- a/src/Plugins/SmartStore.PayPal/Description.txt +++ b/src/Plugins/SmartStore.PayPal/Description.txt @@ -2,7 +2,7 @@ Description: Provides the PayPal payment methods PayPal Standard, PayPal Direct, PayPal Express and PayPal PLUS. SystemName: SmartStore.PayPal Group: Payment -Version: 2.5.0.2 +Version: 2.6.0 MinAppVersion: 2.5.0 DisplayOrder: 1 FileName: SmartStore.PayPal.dll diff --git a/src/Plugins/SmartStore.Shipping/Description.txt b/src/Plugins/SmartStore.Shipping/Description.txt index 5d85eddbb8..f241173e84 100644 --- a/src/Plugins/SmartStore.Shipping/Description.txt +++ b/src/Plugins/SmartStore.Shipping/Description.txt @@ -2,7 +2,7 @@ Description: Provides shipping methods for fixed rate shipping and computation based on weight. SystemName: SmartStore.Shipping Group: Shipping -Version: 2.5.0 +Version: 2.6.0 MinAppVersion: 2.5.0 DisplayOrder: 1 FileName: SmartStore.Shipping.dll diff --git a/src/Plugins/SmartStore.ShippingByWeight/Description.txt b/src/Plugins/SmartStore.ShippingByWeight/Description.txt index 76876783c9..218a277c2b 100644 --- a/src/Plugins/SmartStore.ShippingByWeight/Description.txt +++ b/src/Plugins/SmartStore.ShippingByWeight/Description.txt @@ -1,7 +1,7 @@ FriendlyName: Shipping by weight SystemName: SmartStore.ShippingByWeight Group: Shipping -Version: 2.5.0.1 +Version: 2.6.0 MinAppVersion: 2.5.0 DisplayOrder: 1 FileName: SmartStore.ShippingByWeight.dll diff --git a/src/Plugins/SmartStore.Tax/Description.txt b/src/Plugins/SmartStore.Tax/Description.txt index 79d79ec7a8..ec211f9efe 100644 --- a/src/Plugins/SmartStore.Tax/Description.txt +++ b/src/Plugins/SmartStore.Tax/Description.txt @@ -2,7 +2,7 @@ Description: Contains default tax providers like FixedRate, ByRegion etc. Group: Tax SystemName: SmartStore.Tax -Version: 2.5.0 +Version: 2.6.0 MinAppVersion: 2.5.0 DisplayOrder: 0 FileName: SmartStore.Tax.dll diff --git a/src/Plugins/SmartStore.WebApi/Description.txt b/src/Plugins/SmartStore.WebApi/Description.txt index eacdc805f8..646ac2fd0d 100644 --- a/src/Plugins/SmartStore.WebApi/Description.txt +++ b/src/Plugins/SmartStore.WebApi/Description.txt @@ -1,6 +1,6 @@ FriendlyName: SmartStore.NET Web Api SystemName: SmartStore.WebApi -Version: 2.5.0.1 +Version: 2.6.0 Group: Api MinAppVersion: 2.5.0 Author: SmartStore AG diff --git a/src/Presentation/SmartStore.Web/App_Data/Localization/App/de/all.smres.xml b/src/Presentation/SmartStore.Web/App_Data/Localization/App/de/all.smres.xml index e7e5d5e8fa..8e379a8055 100644 --- a/src/Presentation/SmartStore.Web/App_Data/Localization/App/de/all.smres.xml +++ b/src/Presentation/SmartStore.Web/App_Data/Localization/App/de/all.smres.xml @@ -3136,6 +3136,12 @@ Bearbeiten + + Die E-Mail wurde erfolgreich versendet. + + + Bitte geben Sie eine E-Mail-Adresse ein. + Objekt @@ -3187,6 +3193,12 @@ Als XML exportieren + + Die Datei ist in Benutzung und kann daher nicht geöffnet werden. + + + Datei nicht gefunden + {0} Dateien wurden gelöscht @@ -3196,6 +3208,9 @@ {0} Verzeichnisse wurden gelöscht + + FTP-Status {0} ({1}). + Allgemein @@ -3220,6 +3235,12 @@ Verbergen + + HTTP-Status {0} ({1}). + + + Ignorieren + Importdatei @@ -3232,6 +3253,9 @@ Info + + Letzte Ausführung + Lizenzieren @@ -3256,9 +3280,6 @@ Es wurden keine Einträge ausgewählt. - - Es sind keine temporären Dateien vorhanden. - von @@ -3328,6 +3349,9 @@ Anzeigen + + Werte für Überspringen und Begrenzen müssen größer oder gleich 0 sein. + Ausgelassen @@ -3361,12 +3385,12 @@ Alle Shops + + Erfolgreich am + Der Vorgang wurde erfolgreich ausgeführt. - - Temporäre Dateien - Zeilen insgesamt @@ -4045,6 +4069,9 @@ Die E-Mail wurde erfolgreich versandt. + + Test der E-Mail-Funktion. + Das E-Mail-Konto wurde erfolgreich bearbeitet. @@ -4474,6 +4501,9 @@ Regionale Einstellungen + + Sie müssen zunächst speichern, bevor Sie Einschränkungen festlegen können. + Einstellungen @@ -4666,6 +4696,12 @@ Legt fest, ob das Standardbild bei Warengruppen ausgeblendet werden soll. Das Standardbild wird angezeigt, wenn der Warengruppe kein Bild zugeordnet ist. + + Standardbild bei Herstellern ausblenden + + + Legt fest, ob das Standardbild bei Herstellern ausgeblendet werden soll. Das Standardbild wird angezeigt, wenn dem Hersteller kein Bild zugeordnet ist. + Standardbild bei Produkten ausblenden @@ -4972,6 +5008,12 @@ Bestimmt ob Hersteller auf der Homepage als Bilder oder textuelle Links angezeigt werden. + + Bilder von Herstellern anzeigen + + + Legt fest, ob Herstellerbilder auf der Produktdetailseite angezeigt werden sollen. + Zeige Hersteller auf der Homepage @@ -5242,6 +5284,18 @@ Bestimmt ob Kundennummern hinterlegt werden können. + + Kundennummern + + + Legt fest, ob Kundennummern vergeben werden und ob diese automatisch vergeben werden sollen. + + + Darstellung der Kundennummer + + + Legt die Darstellung und Handhabung der Kundennummer gegenüber dem Kunden fest. + Kundeneinstellungen @@ -5278,6 +5332,12 @@ Bestimmt ob Kunden ihre Kundennummer in Ihrem Account-Bereich einsehen können. + + Einwilligungserklärung im Kontaktformular fordern + + + Bestimmt ob im Kontaktformular eine Checkbox angezeigt wird, die den Benutzer auffordert der Speicherung seiner Daten zuzustimmen. + Automatische Registrierung aktiviert @@ -6382,6 +6442,12 @@ Legen Sie einen Startwert für Bestellnummern fest. Dies ist nützlich, wenn Sie Ihre Aufträge ab einem Bestimmten Wert starten lassen möchten. Der Wert muss größer sein, als die aktuell höchste Bestellnummer und gilt für zukünftige Bestellungen. + + Anzahl der Aufträge pro Seite + + + Legt die Anzahl der dargestellten Aufträge pro Seite fest. + Auftragseinstellungen @@ -6712,6 +6778,21 @@ Legt fest ob das Produktgewicht im Warenkorb angezeigt wird. + + Zustimmung zur E-Mail Weitergabe an Dritte + + + Legt fest, ob Kunden bei einer Bestellung der Weitergabe ihrer E-Mail Adresse an Dritte zustimmen können und ob die Checkbox dafür standardmäßig aktiviert ist. + + + Text für E-Mail Weitergabe + + + Mit der Übermittlung und Speicherung meiner E-Mail-Adresse durch dritte Parteien bin ich einverstanden. + + + Legt den Text für die Zustimmung zur Weitergabe der E-Mail Adresse an Dritte fest. Wählen Sie bitte einen konkreten Grund für die Weitergabe, z.B. 'Mit der Übermittlung und Speicherung meiner E-Mail-Adresse zur Abwicklung des Käuferschutzes durch Trusted Shops bin ich einverstanden.' + Wunschzettel @@ -8629,6 +8710,9 @@ Dashboard + + Neues Profil + Standardwert @@ -8644,9 +8728,6 @@ Die gespeicherten Feldzuordnungen sind aufgrund der Änderung des Trennzeichens ungültig und wurden zurückgesetzt. - - Die folgenden Objekteigenschaft wurden mehrfach zugeodnet und deshalb ignoriert: {0} - Trennzeichen @@ -8708,10 +8789,10 @@ Ein System-Exportprofil kann nicht gelöscht werden. - Zum Schluss aufräumen + Nach erfolgreicher Veröffentlichung aufräumen - Legt fest, ob nicht mehr benötigte Dateien nach der Bereitstellung gelöscht werden sollen. + Legt fest, ob nicht mehr benötigte Dateien gelöscht werden sollen, nachdem alle Veröffentlichungen erfolgreich waren. Einstellungen übernehmen von @@ -8726,10 +8807,10 @@ Export von Profil "{0}" ist abgeschlossen - E-Mail-Addressen an + E-Mail Adressen an - Legt die E-Mail Addressen fest, an die die Benachrichtigung geschickt werden soll. + Legt die E-Mail Adressen fest, an die die Benachrichtigung geschickt werden soll. Die folgenden spezifischen Angaben werden durch den Provider beim Export berücksichtigt. @@ -8743,17 +8824,17 @@ Legt fest, ob die Exportdateien in einem ZIP-Archiv zusammengefasst werden sollen. Das Archiv verbleibt im temporären Ordner des Exportprofils ohne weitere Vearbeitung. - - ZIP-Archiv erstellen + + Mindestens eine Datei konnte nicht kopiert werden. Legt fest, ob die Exportdateien in einem ZIP-Archiv zusammengefasst und nur das Archiv bereitgestellt werden soll. - Art der Bereitstellung + Art der Veröffentlichung - Legt die Art Bereitstellung fest. + Legt die Art Veröffentlichung fest. E-Mail Konto @@ -8762,10 +8843,10 @@ Legt das E-Mail Konto fest, über welches die Daten verschickt werden sollen. - E-Mail-Addressen an + E-Mail Adressen an - Legt die E-Mail Addressen fest, an die die Daten verschickt werden soll. + Legt die E-Mail Adressen fest, an die die Daten verschickt werden soll. E-Mail Betreff @@ -8785,20 +8866,20 @@ Legt fest, aus welcher Art die Exportdateien per HTTP übertragen werden sollen. - - In öffentlichen Ordner kopieren - Legt fest, ob die exportierten Daten in einen übers Internet zugänglichen Ordner kopiert werden sollen. - Name + Name des Profils - Legt den Namen der Bereitstellung fest. + Legt den Namen des Veröffentlichungsprofils fest. + + + Es liegen keine Veröffentlichungsprofile vor. - Legen Sie über <b>Hinzufügen</b> ein oder mehrere Veröffentlichungsprofile an, um festzulegen wie mit den Exportdateien weiter zu verfahren ist. + Legen Sie über <b>Neues Profil</b> ein oder mehrere Veröffentlichungsprofile an, um festzulegen wie mit den Exportdateien weiter zu verfahren ist. Passiver Modus @@ -8812,6 +8893,18 @@ Legt das Passwort fest. + + Veröffentlichungsprofile + + + Veröffentlichungsziel + + + Name des Unterordners + + + Legt den Namen eines Unterordners fest, in den die Daten veröffentlicht werden sollen. + URL\Host @@ -8830,6 +8923,9 @@ Legt fest, ob einen SSL (Secure Sockets Layer) Verbindung genutzt werden soll. + + Bei einer großen Anzahl an Exportdateien wird empfohlen die Option <b>ZIP-Archiv erstellen</b> zu benutzen. Das spart Zeit und vermeidet Probleme, wie z.B. ein volles E-Mail Postfach. + E-Mail Benachrichtigung @@ -8860,6 +8956,9 @@ Legt das Muster fest, nach dem Dateinamen erzeugt werden. + + Bitte ein gültiges Muster für Dateinamen eingeben. Beispiel: %Store.Id%-%Profile.Id%-%File.Index%-%Profile.SeoName% + ID des Exportprofils;Ordername des Exportprofils;SEO Name des Exportprofils;Shop ID;SEO Name des Shops;Mit 1 beginnender Dateiindex;Zufallszahl;UTC Zeitstempel @@ -8875,6 +8974,12 @@ Nach der Verfügbarkeitsmenge filtern. + + Rechnungsländer + + + Nach Rechnungsländern filtern. + Warengruppen @@ -8905,6 +9010,18 @@ Nach empfohlenen Produkten filtern. Wird nur bei der Filterung nach Warengruppen und Hersteller angewendet. + + Hat x Bestellungen + + + Nach der Anzahl der getätigten Bestellungen filtern. + + + Hat Betrag x ausgegeben + + + Nach dem insgesamt ausgegebenen Betrag filtern. + Produkt-ID bis @@ -8917,12 +9034,42 @@ Nach der Produkt-ID filtern. + + Nur aktive Kunden + + + Nach aktiven bzw. inaktiven Kunden filtern. + + + Nur aktive Abonnenten + + + Nach aktiven bzw. inaktiven Newsletter Abonnenten filtern. + Veröffentlicht Nach Veröffentlichung filtern. + + Nur MwSt. befreite Kunden + + + Nach MwSt. befreiten Kunden filtern. + + + Zuletzt aktiv von + + + Nach dem Datum der letzten Shop Aktivität filtern. + + + Zuletzt aktiv bis + + + Nach dem Datum der letzten Shop-Aktivität filtern. + Hersteller @@ -8968,6 +9115,12 @@ Nach Produkttyp filtern. + + Versandländer + + + Nach Versandländern filtern. + Versandstatus @@ -8992,14 +9145,14 @@ Nach fehlender Herstellerzuordnung filtern. - - Bitte einen gültigen Ordner- und Dateinamen eingeben. Beispiel für Dateinamen: %File.Index%-%Profile.Id%-gmc-%Store.Name% - - Ordnername + Ordnerpfad - Legt den Namen des Ordners fest, in den die Daten exportiert werden. + Legt den relativen Pfad des Ordners fest, in den die Daten exportiert werden. + + + Bitte einen gültigen, relativen Ordnerpfad für die zu exportierenden Daten eingeben. Systemprofil @@ -9040,6 +9193,12 @@ Diese Option wird in der Vorschau nicht berücksichtigt. + + Mit den folgenden Einstellungen lassen sich die zu exportierenden Daten aufteilen. Dazu zählt<ul><li>Das Überspringen der ersten n Datensätze</li><li>Die maximale Anzahl zu exportierender Datensätze</li><li>Die Anzahl der Datensätze pro Exportdatei</li><li>Daten von jedem Shop in eine separate Datei exportieren</li></ul>Standardmäßig werden alle Daten eines Shops in eine Datei exportiert. + + + Einstellungen zur Aufteilung müssen größer oder gleich 0 sein. + Per Shop @@ -9196,6 +9355,15 @@ Der Systemname des Exportprofils. + + Die folgende Liste enthält Systemprofile, die von Plugins wie bspw. dem <a href='http://community.smartstore.com/index.php?/files/file/85-smartstorenet-common-export-providers/' target='_blank'>Datenexporte Plugin</a> bereitgestellt werden. Sie können Systemprofile nach Belieben anpassen, aber keine Neuen erstellen. Für diese Profile stehen außerdem zusätzliche Aktions-Buttons zur Verfügung. Sie finden diese über den entsprechenden Listen, wie z.B. der Produkt- oder Auftragsliste. + + + Systemprofile + + + Benutzerprofile + Importdatei hinzufügen... @@ -9241,11 +9409,14 @@ Es wurden keine Importprofile gefunden. - - Laden Sie bitte eine Importdatei hoch, legen Sie einen aussagekräftigen Namen für das Importprofil fest und speichern Sie. + + Anzahl der Bilder + + + Legt die Anzahl der zu importierenden Bilder pro Objekt fest. - - Wählen Sie bitte ein Objekt aus, das Sie importieren möchten. + + Wählen Sie bitte das zu importierende Objekt und laden Sie eine Importdatei hoch. {0} von {1} Datensätzen verarbeitet @@ -9500,7 +9671,7 @@ Zahlung wurde erfasst - Fehler bei Zahlungserfassung für Auftrag #{0}. Fehler: {1} + Es ist ein Fehler bei der Zahlungsbuchung zu Auftrag {0} aufgetreten. Auftrag wurde gelöscht @@ -9607,6 +9778,12 @@ Auftragsdetails bearbeiten + + Akzeptiert Weitergabe der E-Mail + + + Gibt an, ob der Kunde bei der Bestellung einer Weitergabe seiner E-Mail Adresse an Dritte zugestimmt hat oder nicht. + Partner @@ -11560,6 +11737,9 @@ Abbruch erzwungen durch Herunterfahren der Anwendung + + Die geplante Aufgabe "{0}" wurde abgebrochen + Abbruchanforderung wurde übermittelt. @@ -11617,6 +11797,9 @@ Datum der nächsten geplanten Ausführung + + Fehler beim Ausführen der Aufgabe "{0}" + Jetzt ausführen @@ -11866,6 +12049,9 @@ Es wird empfohlen, nur eine Versandkosten-Offline-Berechnungsmethode zu benutzen. + + Die Erreichbarkeit der Sitemap konnte nicht überprüft werden. + Die Sitemap für den Shop ist erreichbar. @@ -12169,6 +12355,9 @@ Bitte geben Sie Benutzername und Passwort ein + + Der Wert muss größer 0 sein. + API ist nicht erreichbar. @@ -12577,6 +12766,15 @@ Fortsetzen + + In die Zwischenablage kopieren + + + Kopieren ist fehlgeschlagen. + + + Kopiert! + Anzahl @@ -12769,6 +12967,9 @@ Lade nächsten Schritt… + + Diese Funktion steht für Gäste nicht zur Verfügung. + Verschiedenes @@ -12778,6 +12979,9 @@ Mehr Info + + Mein + Navigation @@ -12793,6 +12997,12 @@ Nein, abbrechen + + Es sind keine Dateien vorhanden. + + + Es wurde keine Datei hochgeladen. + Der Vorgang wurde aus Sicherheitsgründen nicht ausgeführt. @@ -12865,6 +13075,9 @@ Veröffentlicht + + Veröffentlichung + Frage @@ -13036,6 +13249,15 @@ Namen eingeben + + Einwilligungserklärung Datenschutz + + + Ja, ich habe die <a href="{0}">Datenschutzerklärung</a> zur Kenntnis genommen und bin damit einverstanden, dass die von mir angegebenen Daten elektronisch erhoben und gespeichert werden. Meine Daten werden dabei nur zur Bearbeitung meiner Anfrage genutzt. + + + Bitte stimmen Sie der Speicherung Ihrer Daten zu. + Ihre Anfrage wurde erfolgreich übermittelt. @@ -13252,6 +13474,27 @@ Benutzernamen anzeigen + + Automatisch vergeben + + + Deaktiviert + + + Aktiviert + + + Anzeigen + + + Immer editierbar + + + Editierbar falls leer + + + Nicht anzeigen + Lesbar @@ -13277,7 +13520,10 @@ FTP - HTTP + HTTP POST + + + Öffentlicher Ordner Detailbeschreibung @@ -13295,7 +13541,7 @@ Produktname + Kurzbeschreibung - Nicht spezifiziert + Keine Kurzbeschreibung @@ -13447,6 +13693,15 @@ Nicht anzeigen + + Aktiviert anzeigen + + + Deaktiviert anzeigen + + + Nicht anzeigen + Abgebrochen @@ -14807,6 +15062,9 @@ Datenschutzerklärung + + Private Nachrichten sind deaktiviert. + Posteingang @@ -14937,7 +15195,10 @@ Nicht am Lager - Grundpreis: {0} pro {1} + Inhalt: {0} {1} ({2} / {3} {1}) + + + {0} {1} ({2} / {3} {1}) Home @@ -15138,7 +15399,7 @@ Dieses Produkt ist ausverkauft. - Dieses Produkt ist ausverkauft. + Keine Bundle-Bestandteile vorhanden Das Produkt {0} wurde nicht gefunden. diff --git a/src/Presentation/SmartStore.Web/App_Data/Localization/App/de/head.txt b/src/Presentation/SmartStore.Web/App_Data/Localization/App/de/head.txt index fb2d850500..f822a9cb76 100644 --- a/src/Presentation/SmartStore.Web/App_Data/Localization/App/de/head.txt +++ b/src/Presentation/SmartStore.Web/App_Data/Localization/App/de/head.txt @@ -1 +1 @@ -201601262000441_ImportFramework1 \ No newline at end of file +201605201911421_ExportRevision \ No newline at end of file diff --git a/src/Presentation/SmartStore.Web/App_Data/Localization/App/en/all.smres.xml b/src/Presentation/SmartStore.Web/App_Data/Localization/App/en/all.smres.xml index 6b493fa664..734f05e1de 100644 --- a/src/Presentation/SmartStore.Web/App_Data/Localization/App/en/all.smres.xml +++ b/src/Presentation/SmartStore.Web/App_Data/Localization/App/en/all.smres.xml @@ -3232,6 +3232,12 @@ Edit + + The email has been successfully sent. + + + Please enter an email address. + Object @@ -3283,6 +3289,12 @@ Export to XML + + The file is in use and cannot be opened. + + + File not found + {0} files were deleted @@ -3292,6 +3304,9 @@ {0} folders were deleted + + FTP status {0} ({1}). + General @@ -3316,6 +3331,12 @@ Hide + + HTTP status {0} ({1}). + + + Ignore + Import file @@ -3328,6 +3349,9 @@ Info + + Last run + License @@ -3352,9 +3376,6 @@ No entries have been selected. - - There are no temporary files. - of @@ -3424,6 +3445,9 @@ Show + + Values for skip and limit must be greater than or equal to 0. + Skipped @@ -3457,12 +3481,12 @@ All stores + + Successful on + The task was successfully processed. - - Temporary files - Total rows @@ -4171,6 +4195,9 @@ Email has been successfully sent. + + Testing email functionality. + The email account has been updated successfully. @@ -4627,6 +4654,9 @@ Regional Settings + + You need to save before you can specify restrictions. + Settings @@ -4751,7 +4781,7 @@ Check the box to allow customers to use the 'Compare Products' option in your store - Amount of displayed products per page + Number of displayed products per page Determines the amount of displayed products per page. @@ -4822,6 +4852,12 @@ Specifies whether to hide the default image for categories. The default image is shown when no image is assigned to a category. + + Hide default picture for manufacturers + + + Specifies whether to hide the default image for manufacturers. The default image is shown when no image is assigned to a manufacturer. + Hide default picture for products @@ -5128,6 +5164,12 @@ Specifies whether manufacturers will be displayed as images or textual links on the homepage. + + Show manufacturer pictures + + + Specifies whether to show manufacturer pictures on product detail page. + Show manufacturers on homepage @@ -5398,6 +5440,18 @@ Specifies whether customer numbers can be saved. + + Customer numbers + + + Specifies whether to assign customer numbers and whether they should be created automatically. + + + Customer number presentation + + + Specifies the presentation and handling of the customer number to the customer. + Customer settings @@ -5434,6 +5488,12 @@ Specifies whether customer numbers will be displayed to customers in their account area. + + Get privacy consent for contact requests + + + Specifies whether a checkbox will be displayed on the contact page which requests the user to agree on storage of his data. + Auto register enabled @@ -6550,6 +6610,12 @@ Set the order ID counter. This is useful if you want your orders to start at a certain number. This only affects orders created going forward. The value must be greater than the current maximum order ID. + + Number of displayed orders per page + + + Specifies the number of displayed orders per page. + Order settings @@ -6880,6 +6946,21 @@ Determines whether the product weight is shown in shopping cart + + Consent for email transfer to third parties + + + Specifies whether customers can agree to a transferring of their email address to third parties when ordering, and whether the checkbox is enabled by default during checkout. + + + Text for email transfer consent + + + I agree to the transfer and storage of my email address by third parties. + + + Specifies the text to be displayed to the customer. Please choose a specific reason, e.g. 'I agree to the transfer and storage of my email address for TrustedShops buyer protection.' + Wishlist @@ -8887,6 +8968,9 @@ Store Statistics + + New profile + Default Value @@ -8902,9 +8986,6 @@ The stored field assignments are invalid due to the change of the delimiter and were reset. - - The following object properties were multiple assigned and thus ignored: {0} - Delimiter @@ -8966,10 +9047,10 @@ Cannot delete a system export profile. - Clean up at the end + Clean up after successful deployment - Specifies whether to delete unneeded files after deployment. + Specifies whether to delete unneeded files after all deployments succeeded. Apply settings from @@ -9001,17 +9082,17 @@ Specifies whether to combine the export files in temporary a ZIP archive. The archive remains in the temporary folder of the export profile without further processing. - - Create ZIP archive + + At least one file could not be copied. Specifies whether to combine the export files in a ZIP archive and only to deploy the archive. - Type of deployment + Publishing type - Specifies the deployment type. + Specifies the type of publishing. Email account @@ -9043,20 +9124,20 @@ Specifies how to transmit the export files via HTTP. - - Copy to public folder - Specifies whether to copy the exported data into a folder that is accessible through the internet. - Name + Name of profile - Specifies the name of the deployment. + Specifies the name of the publishing profile. + + + There are no publishing profiles. - Click <b>Insert</b> to add one or multiple publishing profiles to specify how to further proceed with the export files. + Click <b>New profile</b> to add one or multiple publishing profiles to specify how to further proceed with the export files. Passive mode @@ -9070,6 +9151,18 @@ Specifies the password. + + Publishing profiles + + + Publishing target + + + Name of subfolder + + + Specifies the name of a subfolder where to publish the data. + URL\Host @@ -9088,6 +9181,9 @@ Specifies whether to use a SSL (Secure Sockets Layer) connection. + + If there are a large number of export files, it is recommended to use the option <b>Create ZIP archive</b>. This saves time and avoids problems, such as a full email mailbox. + Email notification @@ -9118,6 +9214,9 @@ Specifies the pattern for creating file names. + + Please enter a valid pattern for file names. Example for file names: %Store.Id%-%Profile.Id%-%File.Index%-%Profile.SeoName% + ID of export profil;Folder name of export profil;SEO name of export profil;Store ID;SEO name of store;One based file index;Random number;UTC timestamp @@ -9133,6 +9232,12 @@ Filter by availability quantity. + + Billing countries + + + Filter by billing countries. + Categories @@ -9163,6 +9268,18 @@ Filter by featured products. Is only applied when the filtering by categories and manufacturers. + + Has placed x orders + + + Filter by number of placed orders. + + + Has spent amount x + + + Filter by spent amount. + Product Id to @@ -9175,12 +9292,42 @@ Filter by product identifier. + + Only active customers + + + Filter by active or inactive customers. + + + Only active subscribers + + + Filter by active or inactive newsletter subscribers. + Published Filter by publishing. + + Only tax exempt customers + + + Filter by tax exempt customers. + + + Last activity from + + + Filter by date of last store activity. + + + Last active until + + + Filter by date of last store activity. + Manufacturer @@ -9226,6 +9373,12 @@ Filter by product type. + + Shipping countries + + + Filter by shipping countries. + Shipping status @@ -9250,14 +9403,14 @@ Filter by missing manufacturer mapping. - - Please enter a valid folder and file name. Example for file names: %File.Index%-%Profile.Id%-gmc-%Store.Name% - - Folder name + Folder path - Specifies the name of the folder where to export the data. + Specifies the relative path of the folder where to export the data. + + + Please enter a valid, relative folder path for the export data. System profile @@ -9298,6 +9451,12 @@ This option is not taken into account in the preview. + + With the following settings you can partition the data to be exported. This includes<ul><li>Skipping the first n records</li><li>The maximum number of records to be exported</li><li>The number of records per export file</li><li>Export data for each shop in a separate file</li></ul>By default, all data of a store will be exported into one file. + + + Partitioning setting values must be greater than or equal to 0. + Per store @@ -9454,6 +9613,15 @@ The system name of the export profile. + + The following list contains system profiles, which are provided by plugins such as the <a href='http://community.smartstore.com/index.php?/files/file/85-smartstorenet-common-export-providers/' target='_blank'>Data Export Plugin</a>. You can customize system profiles as desired, but cannot create new ones. These profiles also add additional action buttons. You will find these above data lists, such as the product or order list. + + + System profiles + + + User profiles + Add import file... @@ -9499,11 +9667,14 @@ There were no import profiles found. - - Please upload an import file, enter a meaningful name for the import profile and save. + + Number of pictures + + + Specifies the number of images per object to be imported. - - Please select an object that you want to import. + + Please select the import object and upload an import file. {0} of {1} records processed @@ -9773,7 +9944,7 @@ Order has been captured - Error capturing order #{0}. Error: {1} + Unable to capture payment for order {0}. Order has been deleted @@ -9886,6 +10057,12 @@ Affiliate + + Accepts transfer of email + + + Indicates whether the customer has agreed to a transfer of his email address to third parties. + Affiliate @@ -11893,6 +12070,9 @@ Abnormally aborted due to application shutdown + + The scheduled task "{0}" has been canceled + Cancellation request has been submitted. @@ -11950,6 +12130,9 @@ Date of the next scheduled execution + + Error while running scheduled task "{0}" + Run now @@ -12223,6 +12406,9 @@ Only one offline shipping rate computation method is recommended to use + + The reachability of the sitemap could not be validated. + The sitemap for the store is reachable. @@ -12544,6 +12730,9 @@ Please enter username and password + + The value must be greater than 0. + API not available. @@ -12952,6 +13141,15 @@ Continue + + Copy to clipboard + + + Failed to copy. + + + Copied! + Count @@ -13144,6 +13342,9 @@ Loading next step... + + This function is not available for guests. + Miscellaneous @@ -13153,6 +13354,9 @@ More info + + My + Navigation @@ -13168,6 +13372,12 @@ No, cancel + + There are no files available. + + + There was no file uploaded. + The operation was not carried out for security reasons. @@ -13240,6 +13450,9 @@ Published + + Publishing + Question @@ -13411,6 +13624,15 @@ Enter your name + + Privacy consent + + + Yes I've read the <a href="{0}">privacy terms</a> and agree that my data given by me can be stored electronically. My data will thereby only be used to process my inquiry. + + + Please agree to the storage of your data. + Your enquiry has been successfully sent to the store owner. @@ -13624,6 +13846,27 @@ Show usernames + + Automatically assigned + + + Disabled + + + Enabled + + + Display + + + Always editable + + + Editable if empty + + + Do not display + Clear @@ -13649,7 +13892,10 @@ FTP - HTTP + HTTP POST + + + Public folder Description @@ -13667,7 +13913,7 @@ Product name + short description - Not specified + None Short description @@ -13819,6 +14065,15 @@ Do not show + + Show activated + + + Show deactivated + + + Do not show + Cancelled @@ -15156,6 +15411,9 @@ Privacy Notice + + Private messages are disabled. + Inbox @@ -15286,7 +15544,10 @@ Out of stock - base price: {0} per {1} + Content: {0} {1} ({2} / {3} {1}) + + + {0} {1} ({2} / {3} {1}) Top @@ -15487,7 +15748,7 @@ This product is sold out. - This product is sold out. + No bundle items available The product {0} was not found. diff --git a/src/Presentation/SmartStore.Web/App_Data/Localization/App/en/head.txt b/src/Presentation/SmartStore.Web/App_Data/Localization/App/en/head.txt index fb2d850500..f822a9cb76 100644 --- a/src/Presentation/SmartStore.Web/App_Data/Localization/App/en/head.txt +++ b/src/Presentation/SmartStore.Web/App_Data/Localization/App/en/head.txt @@ -1 +1 @@ -201601262000441_ImportFramework1 \ No newline at end of file +201605201911421_ExportRevision \ No newline at end of file From f15dcc25220a96d4f326978e048c15b781124f1d Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Thu, 30 Jun 2016 10:55:41 +0200 Subject: [PATCH 47/73] PayPal PLUS throws an exception if an initially empty configuration page is saved --- src/Plugins/SmartStore.PayPal/Models/ApiConfigurationModels.cs | 3 ++- src/Plugins/SmartStore.PayPal/SmartStore.PayPal.csproj | 2 +- .../SmartStore.PayPal/Validators/PayPalPlusConfigValidator.cs | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Plugins/SmartStore.PayPal/Models/ApiConfigurationModels.cs b/src/Plugins/SmartStore.PayPal/Models/ApiConfigurationModels.cs index d7752e61f5..f81f6c2d7f 100644 --- a/src/Plugins/SmartStore.PayPal/Models/ApiConfigurationModels.cs +++ b/src/Plugins/SmartStore.PayPal/Models/ApiConfigurationModels.cs @@ -3,7 +3,6 @@ using System.ComponentModel.DataAnnotations; using System.Net; using System.Web.Mvc; -using SmartStore.PayPal.Services; using SmartStore.PayPal.Settings; using SmartStore.Web.Framework; using SmartStore.Web.Framework.Modelling; @@ -164,6 +163,7 @@ public void Copy(PayPalPlusPaymentSettings settings, bool fromSettings) { SecurityProtocol = settings.SecurityProtocol; UseSandbox = settings.UseSandbox; + TransactMode = (int)Settings.TransactMode.AuthorizeAndCapture; AdditionalFee = settings.AdditionalFee; AdditionalFeePercentage = settings.AdditionalFeePercentage; @@ -179,6 +179,7 @@ public void Copy(PayPalPlusPaymentSettings settings, bool fromSettings) { settings.SecurityProtocol = SecurityProtocol; settings.UseSandbox = UseSandbox; + settings.TransactMode = Settings.TransactMode.AuthorizeAndCapture; settings.AdditionalFee = AdditionalFee; settings.AdditionalFeePercentage = AdditionalFeePercentage; diff --git a/src/Plugins/SmartStore.PayPal/SmartStore.PayPal.csproj b/src/Plugins/SmartStore.PayPal/SmartStore.PayPal.csproj index 2690f97cb2..e82c4a4097 100644 --- a/src/Plugins/SmartStore.PayPal/SmartStore.PayPal.csproj +++ b/src/Plugins/SmartStore.PayPal/SmartStore.PayPal.csproj @@ -70,7 +70,7 @@ ..\..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll - True + False diff --git a/src/Plugins/SmartStore.PayPal/Validators/PayPalPlusConfigValidator.cs b/src/Plugins/SmartStore.PayPal/Validators/PayPalPlusConfigValidator.cs index 54fa987d14..b7355b4299 100644 --- a/src/Plugins/SmartStore.PayPal/Validators/PayPalPlusConfigValidator.cs +++ b/src/Plugins/SmartStore.PayPal/Validators/PayPalPlusConfigValidator.cs @@ -25,7 +25,7 @@ public PayPalPlusConfigValidator(ILocalizationService localize, Func x.ThirdPartyPaymentMethods) - .Must(x => x.Count <= 5) + .Must(x => x == null || x.Count <= 5) .WithMessage(localize.GetResource("Plugins.Payments.PayPalPlus.ValidateThirdPartyPaymentMethods")); } } From ab3c8b192840817ba25d92a1574888f8e6a119f7 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 4 Jul 2016 12:10:31 +0200 Subject: [PATCH 48/73] Export all product categories rather than all of current store (causes shop connector to not import all categories) --- .../SmartStore.Services/DataExchange/Export/DataExporter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs index 41cb53a69f..26d20b72a8 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs @@ -293,7 +293,7 @@ private IExportDataSegmenterProvider CreateSegmenter(DataExporterContext ctx, in x => _productAttributeService.Value.GetProductVariantAttributesByProductIds(x, null), x => _productAttributeService.Value.GetProductVariantAttributeCombinations(x), x => _productService.Value.GetTierPricesByProductIds(x, (ctx.Projection.CurrencyId ?? 0) != 0 ? ctx.ContextCustomer : null, ctx.Store.Id), - x => _categoryService.Value.GetProductCategoriesByProductIds(x), + x => _categoryService.Value.GetProductCategoriesByProductIds(x, null, true), x => _manufacturerService.Value.GetProductManufacturersByProductIds(x), x => _productService.Value.GetProductPicturesByProductIds(x), x => _productService.Value.GetProductTagsByProductIds(x), From dfb6e116f640cfc5e71d5a1631183c7e74046276 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 4 Jul 2016 20:38:03 +0200 Subject: [PATCH 49/73] SKU, EAN, MPN of last attribute combination was exported for all combinations --- .../Export/DynamicEntityHelper.cs | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/Libraries/SmartStore.Services/DataExchange/Export/DynamicEntityHelper.cs b/src/Libraries/SmartStore.Services/DataExchange/Export/DynamicEntityHelper.cs index e925553e9f..70ef30f356 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Export/DynamicEntityHelper.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Export/DynamicEntityHelper.cs @@ -1013,19 +1013,17 @@ private List Convert(DataExporterContext ctx, Product product) //var productValues = new Dictionary(); var dbContext = _dbContext as DbContext; - product = _dbContext.Attach(product); - - var entry = dbContext.Entry(product); - - // the returned object is not the entity and is not being tracked by the context. - // it also does not have any relationships set to other objects. - // CurrentValues only includes database (thus primitive) values. - var productClone = entry.CurrentValues.ToObject() as Product; - - _dbContext.DetachEntity(product); - foreach (var combination in combinations.Where(x => x.IsActive)) { + product = _dbContext.Attach(product); + var entry = dbContext.Entry(product); + + // the returned object is not the entity and is not being tracked by the context. + // it also does not have any relationships set to other objects. + // CurrentValues only includes database (thus primitive) values. + var productClone = entry.CurrentValues.ToObject() as Product; + _dbContext.DetachEntity(product); + var dynObject = ToDynamic(ctx, productClone, combinations, combination); result.Add(dynObject); } From 07a38ef3d9a18119a867b1b0295581b746eb718c Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 4 Jul 2016 20:43:48 +0200 Subject: [PATCH 50/73] GMC: Id should be unique when exporting attribute combinations as products --- .../DataExchange/Export/DynamicEntityHelper.cs | 5 +++++ src/Plugins/SmartStore.GoogleMerchantCenter/Description.txt | 2 +- .../Providers/GmcXmlExportProvider.cs | 3 ++- src/Plugins/SmartStore.GoogleMerchantCenter/changelog.md | 4 ++++ 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Libraries/SmartStore.Services/DataExchange/Export/DynamicEntityHelper.cs b/src/Libraries/SmartStore.Services/DataExchange/Export/DynamicEntityHelper.cs index 70ef30f356..c8687ac97e 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Export/DynamicEntityHelper.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Export/DynamicEntityHelper.cs @@ -585,6 +585,11 @@ private dynamic ToDynamic( dynObject._AttributeCombinationId = (combination == null ? 0 : combination.Id); dynObject._DetailUrl = ctx.Store.Url.EnsureEndsWith("/") + (string)dynObject.SeName; + if (combination == null) + dynObject._UniqueId = product.Id.ToString(); + else + dynObject._UniqueId = string.Concat(product.Id, "-", combination.Id); + dynObject.Price = CalculatePrice(ctx, product, combination != null); dynObject._BasePriceInfo = product.GetBasePriceInfo(_services.Localization, _priceFormatter.Value, _currencyService.Value, _taxService.Value, diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Description.txt b/src/Plugins/SmartStore.GoogleMerchantCenter/Description.txt index 5bc3e9ad59..6f343b6b69 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/Description.txt +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Description.txt @@ -1,7 +1,7 @@ FriendlyName: Google Merchant Center (GMC) feed SystemName: SmartStore.GoogleMerchantCenter Group: Marketing -Version: 2.6.0 +Version: 2.6.0.1 MinAppVersion: 2.5.0 Author: SmartStore AG DisplayOrder: 1 diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs b/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs index bc9047d888..9be5e6e3ca 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs @@ -204,6 +204,7 @@ protected override void Export(ExportExecuteContext context) string mainImageUrl = product._MainPictureUrl; var futureSpecialPrice = product._FutureSpecialPrice as decimal?; var price = (decimal)product.Price; + var uniqueId = (string)product._UniqueId; string brand = product._Brand; string gtin = product.Gtin; string mpn = product.ManufacturerPartNumber; @@ -244,7 +245,7 @@ protected override void Export(ExportExecuteContext context) } } - writer.WriteElementString("g", "id", _googleNamespace, entity.Id.ToString()); + writer.WriteElementString("g", "id", _googleNamespace, uniqueId); writer.WriteStartElement("title"); writer.WriteCData(((string)product.Name).Truncate(70).RemoveInvalidXmlChars()); diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/changelog.md b/src/Plugins/SmartStore.GoogleMerchantCenter/changelog.md index c368c87dd7..c51035cfc6 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/changelog.md +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/changelog.md @@ -1,5 +1,9 @@ #Release Notes +##Google Merchant Center (GMC) 2.6.0.1 + ###Bugfixes + * Id should be unique when exporting attribute combinations as products + ##Google Merchant Center (GMC) 2.5.0.1 ###Bugfixes * GMC feed does not generate the sale price if the sale price is set for a future date From 7526f3f8cee44564e3912cdd86d4bb8499456618 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 4 Jul 2016 20:56:04 +0200 Subject: [PATCH 51/73] GMC: No special price exported when the special price period was not specified --- .../Providers/GmcXmlExportProvider.cs | 19 +++++++++++++------ .../changelog.md | 1 + 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs b/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs index 9be5e6e3ca..3edd31e361 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/Providers/GmcXmlExportProvider.cs @@ -202,7 +202,6 @@ protected override void Export(ExportExecuteContext context) string category = (gmc == null ? null : gmc.Taxonomy); string productType = product._CategoryPath; string mainImageUrl = product._MainPictureUrl; - var futureSpecialPrice = product._FutureSpecialPrice as decimal?; var price = (decimal)product.Price; var uniqueId = (string)product._UniqueId; string brand = product._Brand; @@ -211,6 +210,10 @@ protected override void Export(ExportExecuteContext context) string condition = "new"; string availability = "in stock"; + var specialPrice = product._FutureSpecialPrice as decimal?; + if (!specialPrice.HasValue) + specialPrice = product._SpecialPrice; + if (category.IsEmpty()) category = config.DefaultGoogleCategory; @@ -296,13 +299,17 @@ protected override void Export(ExportExecuteContext context) writer.WriteElementString("g", "availability_date", _googleNamespace, availabilityDate); } - if (config.SpecialPrice && futureSpecialPrice.HasValue && entity.SpecialPriceStartDateTimeUtc.HasValue && entity.SpecialPriceEndDateTimeUtc.HasValue) + if (config.SpecialPrice && specialPrice.HasValue) { - var specialPriceDate = "{0}/{1}".FormatInvariant( - entity.SpecialPriceStartDateTimeUtc.Value.ToString(dateFormat), entity.SpecialPriceEndDateTimeUtc.Value.ToString(dateFormat)); + writer.WriteElementString("g", "sale_price", _googleNamespace, specialPrice.Value.FormatInvariant() + " " + (string)currency.CurrencyCode); + + if (entity.SpecialPriceStartDateTimeUtc.HasValue && entity.SpecialPriceEndDateTimeUtc.HasValue) + { + var specialPriceDate = "{0}/{1}".FormatInvariant( + entity.SpecialPriceStartDateTimeUtc.Value.ToString(dateFormat), entity.SpecialPriceEndDateTimeUtc.Value.ToString(dateFormat)); - writer.WriteElementString("g", "sale_price", _googleNamespace, futureSpecialPrice.Value.FormatInvariant() + " " + (string)currency.CurrencyCode); - writer.WriteElementString("g", "sale_price_effective_date", _googleNamespace, specialPriceDate); + writer.WriteElementString("g", "sale_price_effective_date", _googleNamespace, specialPriceDate); + } price = (product._RegularPrice as decimal?) ?? price; } diff --git a/src/Plugins/SmartStore.GoogleMerchantCenter/changelog.md b/src/Plugins/SmartStore.GoogleMerchantCenter/changelog.md index c51035cfc6..2c1f7000cf 100644 --- a/src/Plugins/SmartStore.GoogleMerchantCenter/changelog.md +++ b/src/Plugins/SmartStore.GoogleMerchantCenter/changelog.md @@ -3,6 +3,7 @@ ##Google Merchant Center (GMC) 2.6.0.1 ###Bugfixes * Id should be unique when exporting attribute combinations as products + * No special price exported when the special price period was not specified ##Google Merchant Center (GMC) 2.5.0.1 ###Bugfixes From 1a6ff6fb6b6394a9eb2cf9d28d5def49e63d7031 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Thu, 7 Jul 2016 15:25:51 +0200 Subject: [PATCH 52/73] GMC: Attribute price adjustments were ignored when exporting attribute combinations as products --- .../Catalog/IProductAttributeParser.cs | 19 +++--- .../Catalog/ProductAttributeParser.cs | 39 ++++++------ .../Export/DynamicEntityHelper.cs | 60 ++++++++++++------- 3 files changed, 63 insertions(+), 55 deletions(-) diff --git a/src/Libraries/SmartStore.Services/Catalog/IProductAttributeParser.cs b/src/Libraries/SmartStore.Services/Catalog/IProductAttributeParser.cs index a02648a747..f8565562e5 100644 --- a/src/Libraries/SmartStore.Services/Catalog/IProductAttributeParser.cs +++ b/src/Libraries/SmartStore.Services/Catalog/IProductAttributeParser.cs @@ -33,21 +33,20 @@ public partial interface IProductAttributeParser IEnumerable ParseProductVariantAttributeValues(string attributesXml); /// - /// Get list of localized product variant attribute values + /// Get list of product variant attribute values /// /// Map of combined attributes /// Product variant attributes - /// Language identifier - /// List of localized product variant attribute values - IList ParseProductVariantAttributeValues(Multimap attributeCombination, IEnumerable attributes, int languageId = 0); + /// List of product variant attribute values + IList ParseProductVariantAttributeValues(Multimap attributeCombination, IEnumerable attributes); - /// - /// Gets selected product variant attribute value - /// + /// + /// Gets selected product variant attribute value + /// /// XML formatted attributes - /// Product variant attribute identifier - /// Product variant attribute value - IList ParseValues(string attributesXml, int productVariantAttributeId); + /// Product variant attribute identifier + /// Product variant attribute value + IList ParseValues(string attributesXml, int productVariantAttributeId); /// /// Adds an attribute diff --git a/src/Libraries/SmartStore.Services/Catalog/ProductAttributeParser.cs b/src/Libraries/SmartStore.Services/Catalog/ProductAttributeParser.cs index 0afe47049b..cf4531f322 100644 --- a/src/Libraries/SmartStore.Services/Catalog/ProductAttributeParser.cs +++ b/src/Libraries/SmartStore.Services/Catalog/ProductAttributeParser.cs @@ -13,14 +13,13 @@ using SmartStore.Core.Caching; using SmartStore.Core.Data; using SmartStore.Core.Domain.Catalog; -using SmartStore.Services.Localization; namespace SmartStore.Services.Catalog { - /// - /// Product attribute parser - /// - public partial class ProductAttributeParser : IProductAttributeParser + /// + /// Product attribute parser + /// + public partial class ProductAttributeParser : IProductAttributeParser { // 0 = ProductId, 1 = AttributeXml Hash private const string ATTRIBUTECOMBINATION_BY_ID_HASH = "SmartStore.parsedattributecombination.id-{0}-{1}"; @@ -194,12 +193,12 @@ where id.HasValue() return values; } - public virtual IList ParseProductVariantAttributeValues(Multimap attributeCombination, IEnumerable attributes, int languageId = 0) + public virtual IList ParseProductVariantAttributeValues(Multimap attributeCombination, IEnumerable attributes) { - var values = new List(); + var result = new List(); if (attributeCombination == null || !attributeCombination.Any()) - return values; + return result; var allValueIds = new List(); @@ -219,28 +218,24 @@ public virtual IList ParseProductVariantAttributeValues(Multimap x.Id == id); - if (attributeValue != null) + if (attributeValue != null && !result.Any(x => x.Id == attributeValue.Id)) { - var value = attributeValue.GetLocalized(x => x.Name, languageId, true, false); - - if (!values.Any(x => x.IsCaseInsensitiveEqual(value))) - values.Add(value); + result.Add(attributeValue); break; } } } - return values; + return result; } - - /// - /// Gets selected product variant attribute value - /// - /// Attributes - /// Product variant attribute identifier - /// Product variant attribute value - public virtual IList ParseValues(string attributesXml, int productVariantAttributeId) + /// + /// Gets selected product variant attribute value + /// + /// Attributes + /// Product variant attribute identifier + /// Product variant attribute value + public virtual IList ParseValues(string attributesXml, int productVariantAttributeId) { var selectedProductVariantAttributeValues = new List(); try diff --git a/src/Libraries/SmartStore.Services/DataExchange/Export/DynamicEntityHelper.cs b/src/Libraries/SmartStore.Services/DataExchange/Export/DynamicEntityHelper.cs index c8687ac97e..288d05ab59 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Export/DynamicEntityHelper.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Export/DynamicEntityHelper.cs @@ -136,15 +136,30 @@ private void PrepareProductDescription(DataExporterContext ctx, dynamic dynObjec return price; } - private decimal CalculatePrice(DataExporterContext ctx, Product product, bool forAttributeCombination) + private decimal CalculatePrice( + DataExporterContext ctx, + Product product, + ProductVariantAttributeCombination combination, + IList attributeValues) { - decimal price = product.Price; + var price = product.Price; + var priceCalculationContext = ctx.ProductExportContext as PriceCalculationContext; - // price type - if (ctx.Projection.PriceType.HasValue && !forAttributeCombination) + if (combination != null) { - var priceCalculationContext = ctx.ProductExportContext as PriceCalculationContext; + // price for attribute combination + var attributesTotalPriceBase = decimal.Zero; + + if (attributeValues != null) + { + attributeValues.Each(x => attributesTotalPriceBase += _priceCalculationService.Value.GetProductVariantAttributeValuePriceAdjustment(x)); + } + price = _priceCalculationService.Value.GetFinalPrice(product, null, ctx.ContextCustomer, attributesTotalPriceBase, true, 1, null, priceCalculationContext); + } + else if (ctx.Projection.PriceType.HasValue) + { + // price for product if (ctx.Projection.PriceType.Value == PriceDisplayType.LowestPrice) { bool displayFromMessage; @@ -163,7 +178,6 @@ private decimal CalculatePrice(DataExporterContext ctx, Product product, bool fo return ConvertPrice(ctx, product, price) ?? price; } - private List GetLocalized(DataExporterContext ctx, T entity, params Expression>[] keySelectors) where T : BaseEntity, ILocalizedEntity { @@ -567,10 +581,11 @@ private dynamic ToDynamic( var productTags = ctx.ProductExportContext.ProductTags.Load(product.Id); var specificationAttributes = ctx.ProductExportContext.ProductSpecificationAttributes.Load(product.Id); + var variantAttributes = (combination != null ? _productAttributeParser.Value.DeserializeProductVariantAttributes(combination.AttributesXml) : null); + var variantAttributeValues = (combination != null ? _productAttributeParser.Value.ParseProductVariantAttributeValues(variantAttributes, productAttributes) : null); + if (pictureIds.Length > 0) - { productPictures = productPictures.Where(x => pictureIds.Contains(x.PictureId)); - } productPictures = productPictures.Take(numberOfPictures); @@ -590,7 +605,7 @@ private dynamic ToDynamic( else dynObject._UniqueId = string.Concat(product.Id, "-", combination.Id); - dynObject.Price = CalculatePrice(ctx, product, combination != null); + dynObject.Price = CalculatePrice(ctx, product, combination, variantAttributeValues); dynObject._BasePriceInfo = product.GetBasePriceInfo(_services.Localization, _priceFormatter.Value, _currencyService.Value, _taxService.Value, _priceCalculationService.Value, ctx.ContextCurrency, decimal.Zero, true); @@ -602,22 +617,19 @@ private dynamic ToDynamic( if (combination != null) { - if (ctx.Supports(ExportFeatures.UsesAttributeCombination) || - ctx.Projection.AttributeCombinationValueMerging == ExportAttributeValueMerging.AppendAllValuesToName) + if (ctx.Supports(ExportFeatures.UsesAttributeCombination)) { - var variantAttributes = _productAttributeParser.Value.DeserializeProductVariantAttributes(combination.AttributesXml); - var variantAttributeValues = _productAttributeParser.Value.ParseProductVariantAttributeValues(variantAttributes, productAttributes, languageId); + dynObject._AttributeCombination = variantAttributes; + dynObject._AttributeCombinationValues = variantAttributeValues; + } - if (ctx.Supports(ExportFeatures.UsesAttributeCombination)) - { - dynObject._AttributeCombination = variantAttributes; - dynObject._AttributeCombinationValues = variantAttributeValues; - } + if (ctx.Projection.AttributeCombinationValueMerging == ExportAttributeValueMerging.AppendAllValuesToName) + { + var valueNames = variantAttributeValues + .Select(x => x.GetLocalized(y => y.Name, languageId, true, false)) + .ToList(); - if (ctx.Projection.AttributeCombinationValueMerging == ExportAttributeValueMerging.AppendAllValuesToName) - { - dynObject.Name = ((string)dynObject.Name).Grow(string.Join(", ", variantAttributeValues), " "); - } + dynObject.Name = ((string)dynObject.Name).Grow(string.Join(", ", valueNames), " "); } var attributeQueryString = _productAttributeParser.Value.SerializeQueryData(combination.AttributesXml, product.Id); @@ -884,7 +896,9 @@ private dynamic ToDynamic( { decimal tmpSpecialPrice = product.SpecialPrice.Value; product.SpecialPrice = null; - dynObject._RegularPrice = CalculatePrice(ctx, product, combination != null); + + dynObject._RegularPrice = CalculatePrice(ctx, product, combination, variantAttributeValues); + product.SpecialPrice = tmpSpecialPrice; } } From 783bf8729ba587ade2c6113af774871bf88e46e5 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 11 Jul 2016 12:16:16 +0200 Subject: [PATCH 53/73] GMC: Associated products that are not individually visible are not exported anymore. GMC rejects them because the frontend redirects to the grouped product. --- .../SmartStore.Services/DataExchange/Export/DataExporter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs index 26d20b72a8..e6b182c270 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs @@ -686,7 +686,7 @@ private List GetProducts(DataExporterContext ctx, int skip) OrderBy = ProductSortingEnum.Position, PageSize = int.MaxValue, StoreId = (ctx.Request.Profile.PerStore ? ctx.Store.Id : ctx.Filter.StoreId), - VisibleIndividuallyOnly = false, + VisibleIndividuallyOnly = true, ParentGroupedProductId = product.Id }; From d9455aa4935943c69cc187b8bd18051cb2284f38 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Mon, 11 Jul 2016 18:41:11 +0200 Subject: [PATCH 54/73] Fixes "Cannot insert the value NULL into column 'IsPublic', table 'dbo.ExportDeployment'; column does not allow nulls. INSERT fails" --- ...71_FixExportDeploymentIsPublic.Designer.cs | 29 ++++ ...07111548571_FixExportDeploymentIsPublic.cs | 21 +++ ...111548571_FixExportDeploymentIsPublic.resx | 126 ++++++++++++++++++ .../SmartStore.Data/SmartStore.Data.csproj | 7 + 4 files changed, 183 insertions(+) create mode 100644 src/Libraries/SmartStore.Data/Migrations/201607111548571_FixExportDeploymentIsPublic.Designer.cs create mode 100644 src/Libraries/SmartStore.Data/Migrations/201607111548571_FixExportDeploymentIsPublic.cs create mode 100644 src/Libraries/SmartStore.Data/Migrations/201607111548571_FixExportDeploymentIsPublic.resx diff --git a/src/Libraries/SmartStore.Data/Migrations/201607111548571_FixExportDeploymentIsPublic.Designer.cs b/src/Libraries/SmartStore.Data/Migrations/201607111548571_FixExportDeploymentIsPublic.Designer.cs new file mode 100644 index 0000000000..16b788408f --- /dev/null +++ b/src/Libraries/SmartStore.Data/Migrations/201607111548571_FixExportDeploymentIsPublic.Designer.cs @@ -0,0 +1,29 @@ +// +namespace SmartStore.Data.Migrations +{ + using System.CodeDom.Compiler; + using System.Data.Entity.Migrations; + using System.Data.Entity.Migrations.Infrastructure; + using System.Resources; + + [GeneratedCode("EntityFramework.Migrations", "6.1.3-40302")] + public sealed partial class FixExportDeploymentIsPublic : IMigrationMetadata + { + private readonly ResourceManager Resources = new ResourceManager(typeof(FixExportDeploymentIsPublic)); + + string IMigrationMetadata.Id + { + get { return "201607111548571_FixExportDeploymentIsPublic"; } + } + + string IMigrationMetadata.Source + { + get { return null; } + } + + string IMigrationMetadata.Target + { + get { return Resources.GetString("Target"); } + } + } +} diff --git a/src/Libraries/SmartStore.Data/Migrations/201607111548571_FixExportDeploymentIsPublic.cs b/src/Libraries/SmartStore.Data/Migrations/201607111548571_FixExportDeploymentIsPublic.cs new file mode 100644 index 0000000000..f48207c9fc --- /dev/null +++ b/src/Libraries/SmartStore.Data/Migrations/201607111548571_FixExportDeploymentIsPublic.cs @@ -0,0 +1,21 @@ +namespace SmartStore.Data.Migrations +{ + using System.Data.Entity.Migrations; + using System.Web.Hosting; + using Core.Data; + + public partial class FixExportDeploymentIsPublic : DbMigration + { + public override void Up() + { + if (HostingEnvironment.IsHosted && DataSettings.Current.IsSqlServer) + { + Sql("IF EXISTS(SELECT TOP 1 1 FROM sys.objects o INNER JOIN sys.columns c ON o.object_id = c.object_id WHERE o.name = 'ExportDeployment' AND c.name = 'IsPublic') ALTER TABLE [dbo].[ExportDeployment] DROP COLUMN [IsPublic];"); + } + } + + public override void Down() + { + } + } +} diff --git a/src/Libraries/SmartStore.Data/Migrations/201607111548571_FixExportDeploymentIsPublic.resx b/src/Libraries/SmartStore.Data/Migrations/201607111548571_FixExportDeploymentIsPublic.resx new file mode 100644 index 0000000000..55e598ca59 --- /dev/null +++ b/src/Libraries/SmartStore.Data/Migrations/201607111548571_FixExportDeploymentIsPublic.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 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 + + + dbo + + \ No newline at end of file diff --git a/src/Libraries/SmartStore.Data/SmartStore.Data.csproj b/src/Libraries/SmartStore.Data/SmartStore.Data.csproj index 715e87aaf6..ff7fd39e2b 100644 --- a/src/Libraries/SmartStore.Data/SmartStore.Data.csproj +++ b/src/Libraries/SmartStore.Data/SmartStore.Data.csproj @@ -404,6 +404,10 @@ 201605201911421_ExportRevision.cs + + + 201607111548571_FixExportDeploymentIsPublic.cs + @@ -752,6 +756,9 @@ 201605201911421_ExportRevision.cs + + 201607111548571_FixExportDeploymentIsPublic.cs + From e6ef17b71e5c8f07cf965c7cb730d63bce4c3d68 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Wed, 13 Jul 2016 11:05:59 +0200 Subject: [PATCH 55/73] Export: Projected customer id was ignored in price calculation --- .../DataExchange/Export/DataExporter.cs | 14 +++++++++++--- .../Export/Internal/DataExporterContext.cs | 1 + 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs index e6b182c270..387b360a06 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs @@ -969,9 +969,12 @@ private List Init(DataExporterContext ctx, int? totalRecords = null) ctx.ContextCurrency = _services.WorkContext.WorkingCurrency; if (ctx.Projection.CustomerId.HasValue) - ctx.ContextCustomer = _customerService.GetCustomerById(ctx.Projection.CustomerId.Value); - else - ctx.ContextCustomer = _services.WorkContext.CurrentCustomer; + { + ctx.OldCurrentCustomer = _services.WorkContext.CurrentCustomer; + _services.WorkContext.CurrentCustomer = _customerService.GetCustomerById(ctx.Projection.CustomerId.Value); + } + + ctx.ContextCustomer = _services.WorkContext.CurrentCustomer; if (ctx.Projection.LanguageId.HasValue) ctx.ContextLanguage = _languageService.Value.GetLanguageById(ctx.Projection.LanguageId.Value); @@ -1286,6 +1289,11 @@ private void ExportCoreOuter(DataExporterContext ctx) _exportProfileService.Value.UpdateExportProfile(ctx.Request.Profile); } + + if (ctx.OldCurrentCustomer != null) + { + _services.WorkContext.CurrentCustomer = ctx.OldCurrentCustomer; + } } catch (Exception exception) { diff --git a/src/Libraries/SmartStore.Services/DataExchange/Export/Internal/DataExporterContext.cs b/src/Libraries/SmartStore.Services/DataExchange/Export/Internal/DataExporterContext.cs index 5c6c1315dd..4c41efd0d4 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Export/Internal/DataExporterContext.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Export/Internal/DataExporterContext.cs @@ -89,6 +89,7 @@ public bool Supports(ExportFeatures feature) public ExportFilter Filter { get; private set; } public ExportProjection Projection { get; private set; } public Currency ContextCurrency { get; set; } + public Customer OldCurrentCustomer { get; set; } public Customer ContextCustomer { get; set; } public Language ContextLanguage { get; set; } From e654f1530f540ba1d540afecd1080b29109aa60e Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Wed, 13 Jul 2016 11:41:44 +0200 Subject: [PATCH 56/73] Revert "Export: Projected customer id was ignored in price calculation" This reverts commit e6ef17b71e5c8f07cf965c7cb730d63bce4c3d68. --- .../DataExchange/Export/DataExporter.cs | 14 +++----------- .../Export/Internal/DataExporterContext.cs | 1 - 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs b/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs index 387b360a06..e6b182c270 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Export/DataExporter.cs @@ -969,12 +969,9 @@ private List Init(DataExporterContext ctx, int? totalRecords = null) ctx.ContextCurrency = _services.WorkContext.WorkingCurrency; if (ctx.Projection.CustomerId.HasValue) - { - ctx.OldCurrentCustomer = _services.WorkContext.CurrentCustomer; - _services.WorkContext.CurrentCustomer = _customerService.GetCustomerById(ctx.Projection.CustomerId.Value); - } - - ctx.ContextCustomer = _services.WorkContext.CurrentCustomer; + ctx.ContextCustomer = _customerService.GetCustomerById(ctx.Projection.CustomerId.Value); + else + ctx.ContextCustomer = _services.WorkContext.CurrentCustomer; if (ctx.Projection.LanguageId.HasValue) ctx.ContextLanguage = _languageService.Value.GetLanguageById(ctx.Projection.LanguageId.Value); @@ -1289,11 +1286,6 @@ private void ExportCoreOuter(DataExporterContext ctx) _exportProfileService.Value.UpdateExportProfile(ctx.Request.Profile); } - - if (ctx.OldCurrentCustomer != null) - { - _services.WorkContext.CurrentCustomer = ctx.OldCurrentCustomer; - } } catch (Exception exception) { diff --git a/src/Libraries/SmartStore.Services/DataExchange/Export/Internal/DataExporterContext.cs b/src/Libraries/SmartStore.Services/DataExchange/Export/Internal/DataExporterContext.cs index 4c41efd0d4..5c6c1315dd 100644 --- a/src/Libraries/SmartStore.Services/DataExchange/Export/Internal/DataExporterContext.cs +++ b/src/Libraries/SmartStore.Services/DataExchange/Export/Internal/DataExporterContext.cs @@ -89,7 +89,6 @@ public bool Supports(ExportFeatures feature) public ExportFilter Filter { get; private set; } public ExportProjection Projection { get; private set; } public Currency ContextCurrency { get; set; } - public Customer OldCurrentCustomer { get; set; } public Customer ContextCustomer { get; set; } public Language ContextLanguage { get; set; } From 53d614128ee9922d0d319224480dd3c51279b823 Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Fri, 12 Aug 2016 15:08:21 +0200 Subject: [PATCH 57/73] Awarded reward points should be rounded towards zero rather than to nearest integer --- .../SmartStore.Services/Orders/OrderProcessingService.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Libraries/SmartStore.Services/Orders/OrderProcessingService.cs b/src/Libraries/SmartStore.Services/Orders/OrderProcessingService.cs index d92e6212a0..0993597da4 100644 --- a/src/Libraries/SmartStore.Services/Orders/OrderProcessingService.cs +++ b/src/Libraries/SmartStore.Services/Orders/OrderProcessingService.cs @@ -242,12 +242,8 @@ protected void AwardRewardPoints(Order order, decimal? amount = null) if (order.RewardPointsWereAdded) return; - // Truncate increases the risk of inaccuracy of rounding - //int points = (int)Math.Truncate((amount ?? order.OrderTotal) / _rewardPointsSettings.PointsForPurchases_Amount * _rewardPointsSettings.PointsForPurchases_Points); - - // why are points awarded for OrderTotal? wouldn't be OrderSubtotalInclTax better? - - int points = (int)Math.Round((amount ?? order.OrderTotal) / _rewardPointsSettings.PointsForPurchases_Amount * _rewardPointsSettings.PointsForPurchases_Points); + // Trucate same as Floor for positive amounts + int points = (int)Math.Truncate((amount ?? order.OrderTotal) / _rewardPointsSettings.PointsForPurchases_Amount * _rewardPointsSettings.PointsForPurchases_Points); if (points == 0) return; From 972e2170f9c9874a3895259e0ade9ca0218b935c Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Wed, 17 Aug 2016 15:32:34 +0200 Subject: [PATCH 58/73] Added PayPal partner attribution Id as request header --- src/Plugins/SmartStore.PayPal/Description.txt | 2 +- src/Plugins/SmartStore.PayPal/Services/PayPalService.cs | 1 + src/Plugins/SmartStore.PayPal/changelog.md | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Plugins/SmartStore.PayPal/Description.txt b/src/Plugins/SmartStore.PayPal/Description.txt index 75a43e5adb..84ba16461c 100644 --- a/src/Plugins/SmartStore.PayPal/Description.txt +++ b/src/Plugins/SmartStore.PayPal/Description.txt @@ -2,7 +2,7 @@ Description: Provides the PayPal payment methods PayPal Standard, PayPal Direct, PayPal Express and PayPal PLUS. SystemName: SmartStore.PayPal Group: Payment -Version: 2.6.0 +Version: 2.6.0.1 MinAppVersion: 2.5.0 DisplayOrder: 1 FileName: SmartStore.PayPal.dll diff --git a/src/Plugins/SmartStore.PayPal/Services/PayPalService.cs b/src/Plugins/SmartStore.PayPal/Services/PayPalService.cs index f5819da195..0b41486b94 100644 --- a/src/Plugins/SmartStore.PayPal/Services/PayPalService.cs +++ b/src/Plugins/SmartStore.PayPal/Services/PayPalService.cs @@ -451,6 +451,7 @@ public PayPalResponse CallApi(string method, string path, string accessToken, Pa request.Headers["Authorization"] = "Bearer " + accessToken.EmptyNull(); } + request.Headers["PayPal-Partner-Attribution-Id"] = "SmartStoreAG_Cart_PayPalPlus"; if (data.HasValue() && (method.IsCaseInsensitiveEqual("POST") || method.IsCaseInsensitiveEqual("PUT") || method.IsCaseInsensitiveEqual("PATCH"))) { diff --git a/src/Plugins/SmartStore.PayPal/changelog.md b/src/Plugins/SmartStore.PayPal/changelog.md index 70ed0765b7..80c08c683b 100644 --- a/src/Plugins/SmartStore.PayPal/changelog.md +++ b/src/Plugins/SmartStore.PayPal/changelog.md @@ -1,5 +1,9 @@ #Release Notes +##PayPal 2.6.0.1 +###Improvements +* Added PayPal partner attribution Id as request header + ##Paypal 2.5.0.2 ###New Features * PayPal PLUS payment provider From 6cf721ef06b7cc2f1e04754afca5e672049c096b Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Thu, 1 Sep 2016 16:11:29 +0200 Subject: [PATCH 59/73] PayPal PLUS: Integration review through PayPal --- .../Controllers/PayPalPlusController.cs | 26 ++ src/Plugins/SmartStore.PayPal/Description.txt | 2 +- .../Services/IPayPalService.cs | 6 + .../Services/PayPalService.cs | 237 +++++++++++------- .../PayPalPlus/PaymentWallScripting.cshtml | 18 +- src/Plugins/SmartStore.PayPal/changelog.md | 4 + 6 files changed, 200 insertions(+), 93 deletions(-) diff --git a/src/Plugins/SmartStore.PayPal/Controllers/PayPalPlusController.cs b/src/Plugins/SmartStore.PayPal/Controllers/PayPalPlusController.cs index 1c20f4b032..d2fc262e9b 100644 --- a/src/Plugins/SmartStore.PayPal/Controllers/PayPalPlusController.cs +++ b/src/Plugins/SmartStore.PayPal/Controllers/PayPalPlusController.cs @@ -194,6 +194,9 @@ public ActionResult Configure(PayPalPlusConfigurationModel model, FormCollection var storeDependingSettingHelper = new StoreDependingSettingHelper(ViewData); var storeScope = this.GetActiveStoreScopeConfiguration(Services.StoreService, Services.WorkContext); var settings = Services.Settings.LoadSetting(storeScope); + var oldClientId = settings.ClientId; + var oldSecret = settings.Secret; + var oldProfileId = settings.ExperienceProfileId; var validator = new PayPalPlusConfigValidator(Services.Localization, x => { @@ -209,6 +212,15 @@ public ActionResult Configure(PayPalPlusConfigurationModel model, FormCollection model.Copy(settings, false); + // credentials changed: reset profile and webhook id to avoid errors + if (!oldClientId.IsCaseInsensitiveEqual(settings.ClientId) || !oldSecret.IsCaseInsensitiveEqual(settings.Secret)) + { + if (oldProfileId.IsCaseInsensitiveEqual(settings.ExperienceProfileId)) + settings.ExperienceProfileId = null; + + settings.WebhookId = null; + } + storeDependingSettingHelper.UpdateSettings(settings, form, storeScope, Services.Settings); Services.Settings.SaveSetting(settings, x => x.UseSandbox, 0, false); @@ -314,6 +326,20 @@ public ActionResult PaymentWall() return View(model); } + [HttpPost] + public ActionResult PatchShipping() + { + var store = Services.StoreContext.CurrentStore; + var customer = Services.WorkContext.CurrentCustomer; + var settings = Services.Settings.LoadSetting(store.Id); + var cart = customer.GetCartItems(ShoppingCartType.ShoppingCart, store.Id); + var session = HttpContext.GetPayPalSessionData(); + + var apiResult = PayPalService.PatchShipping(settings, session, cart, PayPalPlusProvider.SystemName); + + return new JsonResult { Data = new { success = apiResult.Success, error = apiResult.ErrorMessage } }; + } + public ActionResult CheckoutCompleted() { var instruct = _httpContext.Session[PayPalPlusProvider.CheckoutCompletedKey] as string; diff --git a/src/Plugins/SmartStore.PayPal/Description.txt b/src/Plugins/SmartStore.PayPal/Description.txt index 84ba16461c..7123a24071 100644 --- a/src/Plugins/SmartStore.PayPal/Description.txt +++ b/src/Plugins/SmartStore.PayPal/Description.txt @@ -2,7 +2,7 @@ Description: Provides the PayPal payment methods PayPal Standard, PayPal Direct, PayPal Express and PayPal PLUS. SystemName: SmartStore.PayPal Group: Payment -Version: 2.6.0.1 +Version: 2.6.0.2 MinAppVersion: 2.5.0 DisplayOrder: 1 FileName: SmartStore.PayPal.dll diff --git a/src/Plugins/SmartStore.PayPal/Services/IPayPalService.cs b/src/Plugins/SmartStore.PayPal/Services/IPayPalService.cs index 6a799e16a1..2f4b94c1c9 100644 --- a/src/Plugins/SmartStore.PayPal/Services/IPayPalService.cs +++ b/src/Plugins/SmartStore.PayPal/Services/IPayPalService.cs @@ -36,6 +36,12 @@ PayPalResponse CreatePayment( string returnUrl, string cancelUrl); + PayPalResponse PatchShipping( + PayPalApiSettingsBase settings, + PayPalSessionData session, + List cart, + string providerSystemName); + PayPalResponse ExecutePayment(PayPalApiSettingsBase settings, PayPalSessionData session); PayPalResponse Refund(PayPalApiSettingsBase settings, PayPalSessionData session, RefundPaymentRequest request); diff --git a/src/Plugins/SmartStore.PayPal/Services/PayPalService.cs b/src/Plugins/SmartStore.PayPal/Services/PayPalService.cs index 0b41486b94..3d5d66d20b 100644 --- a/src/Plugins/SmartStore.PayPal/Services/PayPalService.cs +++ b/src/Plugins/SmartStore.PayPal/Services/PayPalService.cs @@ -41,6 +41,7 @@ public class PayPalService : IPayPalService private readonly IOrderService _orderService; private readonly IOrderProcessingService _orderProcessingService; private readonly IOrderTotalCalculationService _orderTotalCalculationService; + private readonly IGenericAttributeService _genericAttributeService; private readonly IPaymentService _paymentService; private readonly IPriceCalculationService _priceCalculationService; private readonly ITaxService _taxService; @@ -54,6 +55,7 @@ public PayPalService( IOrderService orderService, IOrderProcessingService orderProcessingService, IOrderTotalCalculationService orderTotalCalculationService, + IGenericAttributeService genericAttributeService, IPaymentService paymentService, IPriceCalculationService priceCalculationService, ITaxService taxService, @@ -66,6 +68,7 @@ public PayPalService( _orderService = orderService; _orderProcessingService = orderProcessingService; _orderTotalCalculationService = orderTotalCalculationService; + _genericAttributeService = genericAttributeService; _paymentService = paymentService; _priceCalculationService = priceCalculationService; _taxService = taxService; @@ -113,6 +116,99 @@ private Dictionary CreateAddress(Address addr, bool addRecipient return dic; } + private Dictionary CreateAmount( + Store store, + Customer customer, + List cart, + string providerSystemName, + List> items) + { + var amount = new Dictionary(); + var amountDetails = new Dictionary(); + var language = _services.WorkContext.WorkingLanguage; + var currencyCode = store.PrimaryStoreCurrency.CurrencyCode; + var includingTax = (_services.WorkContext.GetTaxDisplayTypeFor(customer, store.Id) == TaxDisplayType.IncludingTax); + + Discount orderAppliedDiscount; + List appliedGiftCards; + int redeemedRewardPoints = 0; + decimal redeemedRewardPointsAmount; + decimal orderDiscountInclTax; + decimal totalOrderItems = decimal.Zero; + + var shipping = (_orderTotalCalculationService.GetShoppingCartShippingTotal(cart) ?? decimal.Zero); + + var paymentFee = _paymentService.GetAdditionalHandlingFee(cart, providerSystemName); + + var total = (_orderTotalCalculationService.GetShoppingCartTotal(cart, out orderDiscountInclTax, out orderAppliedDiscount, out appliedGiftCards, + out redeemedRewardPoints, out redeemedRewardPointsAmount) ?? decimal.Zero); + + // line items + foreach (var item in cart) + { + decimal unitPriceTaxRate = decimal.Zero; + decimal unitPrice = _priceCalculationService.GetUnitPrice(item, true); + decimal productPrice = _taxService.GetProductPrice(item.Item.Product, unitPrice, includingTax, customer, out unitPriceTaxRate); + + if (items != null) + { + var line = new Dictionary(); + line.Add("quantity", item.Item.Quantity); + line.Add("name", item.Item.Product.GetLocalized(x => x.Name, language.Id, true, false).Truncate(127)); + line.Add("price", productPrice.FormatInvariant()); + line.Add("currency", currencyCode); + line.Add("sku", item.Item.Product.Sku.Truncate(50)); + items.Add(line); + } + + totalOrderItems += (productPrice * item.Item.Quantity); + } + + var itemsPlusMisc = (totalOrderItems + shipping + paymentFee); + + if (total != itemsPlusMisc) + { + if (items != null) + { + // e.g. discount applied to cart total + var line = new Dictionary(); + line.Add("quantity", "1"); + line.Add("name", T("Plugins.SmartStore.PayPal.Other").Text.Truncate(127)); + line.Add("price", (total - itemsPlusMisc).FormatInvariant()); + line.Add("currency", currencyCode); + items.Add(line); + } + + totalOrderItems += (total - itemsPlusMisc); + } + + // fill amount object + amountDetails.Add("shipping", shipping.FormatInvariant()); + amountDetails.Add("subtotal", totalOrderItems.FormatInvariant()); + if (!includingTax) + { + // "To avoid rounding errors we recommend not submitting tax amounts on line item basis. + // Calculated tax amounts for the entire shopping basket may be submitted in the amount objects. + // In this case the item amounts will be treated as amounts excluding tax. + // In a B2C scenario, where taxes are included, no taxes should be submitted to PayPal." + + SortedDictionary taxRates = null; + var taxTotal = _orderTotalCalculationService.GetTaxTotal(cart, out taxRates); + + amountDetails.Add("tax", taxTotal.FormatInvariant()); + } + if (paymentFee != decimal.Zero) + { + amountDetails.Add("handling_fee", paymentFee.FormatInvariant()); + } + + amount.Add("total", total.FormatInvariant()); + amount.Add("currency", currencyCode); + amount.Add("details", amountDetails); + + return amount; + } + private string ToInfoString(dynamic json) { var sb = new StringBuilder(); @@ -412,7 +508,7 @@ public PaymentStatus GetPaymentStatus(string state, string reasonCode, PaymentSt public PayPalResponse CallApi(string method, string path, string accessToken, PayPalApiSettingsBase settings, string data) { - var isJson = (data.HasValue() && data.StartsWith("{")); + var isJson = (data.HasValue() && (data.StartsWith("{") || data.StartsWith("["))); var encoding = (isJson ? Encoding.UTF8 : Encoding.ASCII); var result = new PayPalResponse(); HttpWebResponse webResponse = null; @@ -600,34 +696,16 @@ public PayPalResponse CreatePayment( { var store = _services.StoreContext.CurrentStore; var customer = _services.WorkContext.CurrentCustomer; - var language = _services.WorkContext.WorkingLanguage; - var currencyCode = store.PrimaryStoreCurrency.CurrencyCode; - - var dateOfBirth = customer.GetAttribute(SystemCustomerAttributeNames.DateOfBirth); - Discount orderAppliedDiscount; - List appliedGiftCards; - int redeemedRewardPoints = 0; - decimal redeemedRewardPointsAmount; - decimal orderDiscountInclTax; - decimal totalOrderItems = decimal.Zero; + //var dateOfBirth = customer.GetAttribute(SystemCustomerAttributeNames.DateOfBirth); - var includingTax = (_services.WorkContext.GetTaxDisplayTypeFor(customer, store.Id) == TaxDisplayType.IncludingTax); - - var shipping = (_orderTotalCalculationService.GetShoppingCartShippingTotal(cart) ?? decimal.Zero); - - var paymentFee = _paymentService.GetAdditionalHandlingFee(cart, providerSystemName); - - var total = (_orderTotalCalculationService.GetShoppingCartTotal(cart, out orderDiscountInclTax, out orderAppliedDiscount, out appliedGiftCards, - out redeemedRewardPoints, out redeemedRewardPointsAmount) ?? decimal.Zero); + _genericAttributeService.SaveAttribute(customer, SystemCustomerAttributeNames.SelectedPaymentMethod, PayPalPlusProvider.SystemName, store.Id); var data = new Dictionary(); var redirectUrls = new Dictionary(); var payer = new Dictionary(); - var payerInfo = new Dictionary(); + //var payerInfo = new Dictionary(); var transaction = new Dictionary(); - var amount = new Dictionary(); - var amountDetails = new Dictionary(); var items = new List>(); var itemList = new Dictionary(); @@ -651,80 +729,23 @@ public PayPalResponse CreatePayment( data.Add("redirect_urls", redirectUrls); // payer, payer_info - if (dateOfBirth.HasValue) - { - payerInfo.Add("birth_date", dateOfBirth.Value.ToString("yyyy-MM-dd")); - } - if (customer.BillingAddress != null) - { - payerInfo.Add("billing_address", CreateAddress(customer.BillingAddress, false)); - } + // paypal review: do not transmit + //if (dateOfBirth.HasValue) + //{ + // payerInfo.Add("birth_date", dateOfBirth.Value.ToString("yyyy-MM-dd")); + //} + //if (customer.BillingAddress != null) + //{ + // payerInfo.Add("billing_address", CreateAddress(customer.BillingAddress, false)); + //} payer.Add("payment_method", "paypal"); - payer.Add("payer_info", payerInfo); + //payer.Add("payer_info", payerInfo); data.Add("payer", payer); - // line items - foreach (var item in cart) - { - decimal unitPriceTaxRate = decimal.Zero; - decimal unitPrice = _priceCalculationService.GetUnitPrice(item, true); - decimal productPrice = _taxService.GetProductPrice(item.Item.Product, unitPrice, includingTax, customer, out unitPriceTaxRate); - - var line = new Dictionary(); - line.Add("quantity", item.Item.Quantity); - line.Add("name", item.Item.Product.GetLocalized(x => x.Name, language.Id, true, false).Truncate(127)); - line.Add("price", productPrice.FormatInvariant()); - line.Add("currency", currencyCode); - line.Add("sku", item.Item.Product.Sku.Truncate(50)); - items.Add(line); - - totalOrderItems += (productPrice * item.Item.Quantity); - } - - var itemsPlusMisc = (totalOrderItems + shipping + paymentFee); - - if (total != itemsPlusMisc) - { - var line = new Dictionary(); - line.Add("quantity", "1"); - line.Add("name", T("Plugins.SmartStore.PayPal.Other").Text.Truncate(127)); - line.Add("price", (total - itemsPlusMisc).FormatInvariant()); - line.Add("currency", currencyCode); - items.Add(line); - - totalOrderItems += (total - itemsPlusMisc); - } + var amount = CreateAmount(store, customer, cart, providerSystemName, items); itemList.Add("items", items); - if (customer.ShippingAddress != null) - { - itemList.Add("shipping_address", CreateAddress(customer.ShippingAddress, true)); - } - - // transactions - amountDetails.Add("shipping", shipping.FormatInvariant()); - amountDetails.Add("subtotal", totalOrderItems.FormatInvariant()); - if (!includingTax) - { - // "To avoid rounding errors we recommend not submitting tax amounts on line item basis. - // Calculated tax amounts for the entire shopping basket may be submitted in the amount objects. - // In this case the item amounts will be treated as amounts excluding tax. - // In a B2C scenario, where taxes are included, no taxes should be submitted to PayPal." - - SortedDictionary taxRates = null; - var taxTotal = _orderTotalCalculationService.GetTaxTotal(cart, out taxRates); - - amountDetails.Add("tax", taxTotal.FormatInvariant()); - } - if (paymentFee != decimal.Zero) - { - amountDetails.Add("handling_fee", paymentFee.FormatInvariant()); - } - - amount.Add("total", total.FormatInvariant()); - amount.Add("currency", currencyCode); - amount.Add("details", amountDetails); transaction.Add("amount", amount); transaction.Add("item_list", itemList); @@ -744,6 +765,42 @@ public PayPalResponse CreatePayment( return result; } + public PayPalResponse PatchShipping( + PayPalApiSettingsBase settings, + PayPalSessionData session, + List cart, + string providerSystemName) + { + var data = new List>(); + var amountTotal = new Dictionary(); + + var store = _services.StoreContext.CurrentStore; + var customer = _services.WorkContext.CurrentCustomer; + + if (customer.ShippingAddress != null) + { + var shippingAddress = new Dictionary(); + shippingAddress.Add("op", "add"); + shippingAddress.Add("path", "/transactions/0/item_list/shipping_address"); + shippingAddress.Add("value", CreateAddress(customer.ShippingAddress, true)); + data.Add(shippingAddress); + } + + // update of whole amount object required. patching single amount values not possible (MALFORMED_REQUEST). + var amount = CreateAmount(store, customer, cart, providerSystemName, null); + + amountTotal.Add("op", "replace"); + amountTotal.Add("path", "/transactions/0/amount"); + amountTotal.Add("value", amount); + data.Add(amountTotal); + + var result = CallApi("PATCH", "/v1/payments/payment/{0}".FormatInvariant(session.PaymentId), session.AccessToken, settings, JsonConvert.SerializeObject(data)); + + //Logger.InsertLog(LogLevel.Information, "PayPal PLUS", JsonConvert.SerializeObject(data, Formatting.Indented) + "\r\n\r\n" + (result.Json != null ? result.Json.ToString() : "")); + + return result; + } + public PayPalResponse ExecutePayment(PayPalApiSettingsBase settings, PayPalSessionData session) { var data = new Dictionary(); diff --git a/src/Plugins/SmartStore.PayPal/Views/PayPalPlus/PaymentWallScripting.cshtml b/src/Plugins/SmartStore.PayPal/Views/PayPalPlus/PaymentWallScripting.cshtml index 212ae653cc..c1f2cdf6f0 100644 --- a/src/Plugins/SmartStore.PayPal/Views/PayPalPlus/PaymentWallScripting.cshtml +++ b/src/Plugins/SmartStore.PayPal/Views/PayPalPlus/PaymentWallScripting.cshtml @@ -1,4 +1,5 @@ -@using SmartStore.PayPal.Models; +@using SmartStore.PayPal +@using SmartStore.PayPal.Models @model PayPalPlusCheckoutModel