diff --git a/src/Libraries/Nop.Core/Domain/Common/CommonSettings.cs b/src/Libraries/Nop.Core/Domain/Common/CommonSettings.cs index 9184281f093..cec98ac6051 100644 --- a/src/Libraries/Nop.Core/Domain/Common/CommonSettings.cs +++ b/src/Libraries/Nop.Core/Domain/Common/CommonSettings.cs @@ -108,5 +108,10 @@ public CommonSettings() /// The length of time, in milliseconds, before the running schedule task times out. Set null to use default value /// public int? ScheduleTaskRunTimeout { get; set; } + + /// + /// Gets or sets the timeout (in milliseconds) before restarting the application; set null to use default value + /// + public int? RestartTimeout { get; set; } } } diff --git a/src/Libraries/Nop.Data/Nop.Data.csproj b/src/Libraries/Nop.Data/Nop.Data.csproj index b7540d1633a..df6c563d3b0 100644 --- a/src/Libraries/Nop.Data/Nop.Data.csproj +++ b/src/Libraries/Nop.Data/Nop.Data.csproj @@ -18,6 +18,7 @@ + diff --git a/src/Libraries/Nop.Services/Common/NopCommonDefaults.cs b/src/Libraries/Nop.Services/Common/NopCommonDefaults.cs index 1d584c3b3cd..ba157a27aaa 100644 --- a/src/Libraries/Nop.Services/Common/NopCommonDefaults.cs +++ b/src/Libraries/Nop.Services/Common/NopCommonDefaults.cs @@ -26,6 +26,11 @@ public static partial class NopCommonDefaults #region Maintenance + /// + /// Gets a default timeout (in milliseconds) before restarting the application + /// + public static int RestartTimeout => 3000; + /// /// Gets a path to the database backup files /// diff --git a/src/Libraries/Nop.Services/Installation/CodeFirstInstallationService.cs b/src/Libraries/Nop.Services/Installation/CodeFirstInstallationService.cs index dad67232eea..13a4a85bc77 100644 --- a/src/Libraries/Nop.Services/Installation/CodeFirstInstallationService.cs +++ b/src/Libraries/Nop.Services/Installation/CodeFirstInstallationService.cs @@ -5048,7 +5048,7 @@ protected virtual void InstallOrders() var fourthCustomerBillingAddress = InsertInstallationData(_addressService.CloneAddress(_addressRepository.ToCachedGetById(fourthCustomer.BillingAddressId))); var fourthCustomerShippingAddress = InsertInstallationData(_addressService.CloneAddress(_addressRepository.ToCachedGetById(fourthCustomer.ShippingAddressId))); var fourthCustomerPickupAddress = InsertInstallationData(_addressService.CloneAddress(_addressRepository.ToCachedGetById(fourthCustomer.ShippingAddressId))); - + var fourthOrder = new Order { StoreId = defaultStore.Id, @@ -6127,7 +6127,8 @@ protected virtual void InstallSettings() EnableHtmlMinification = true, //we disable bundling out of the box because it requires a lot of server resources EnableJsBundling = false, - EnableCssBundling = false + EnableCssBundling = false, + RestartTimeout = NopCommonDefaults.RestartTimeout }); settingService.SaveSetting(new SeoSettings @@ -6808,8 +6809,8 @@ protected virtual void InstallSettings() settingService.SaveSetting(new CookieSettings { - CompareProductsCookieExpires = 24 *10, - RecentlyViewedProductsCookieExpires = 24 *10, + CompareProductsCookieExpires = 24 * 10, + RecentlyViewedProductsCookieExpires = 24 * 10, CustomerCookieExpires = 24 * 365 }); @@ -12613,4 +12614,4 @@ public virtual void InstallSampleData(string defaultUserEmail) #endregion } -} +} \ No newline at end of file diff --git a/src/Presentation/Nop.Web/App_Data/Localization/Installation/installation.en.xml b/src/Presentation/Nop.Web/App_Data/Localization/Installation/installation.en.xml index f4a68f18c2a..83a7cd81e73 100644 --- a/src/Presentation/Nop.Web/App_Data/Localization/Installation/installation.en.xml +++ b/src/Presentation/Nop.Web/App_Data/Localization/Installation/installation.en.xml @@ -144,4 +144,7 @@ To complete this wizard, you must know some information regarding your database server ("connection string"). Please contact your ISP if necessary. If you're installing on a local machine or server, you might need information from your System Admin. + + Restarting... + \ No newline at end of file diff --git a/src/Presentation/Nop.Web/Areas/Admin/Controllers/CommonController.cs b/src/Presentation/Nop.Web/Areas/Admin/Controllers/CommonController.cs index 8f904c339bf..25dc693f2fa 100644 --- a/src/Presentation/Nop.Web/Areas/Admin/Controllers/CommonController.cs +++ b/src/Presentation/Nop.Web/Areas/Admin/Controllers/CommonController.cs @@ -352,18 +352,29 @@ public virtual IActionResult RestartApplication(string returnUrl = "") if (!_permissionService.Authorize(StandardPermissionProvider.ManageMaintenance)) return AccessDeniedView(); - //restart application - _webHelper.RestartAppDomain(); - //home page if (string.IsNullOrEmpty(returnUrl)) - return RedirectToAction("Index", "Home", new { area = AreaNames.Admin }); + returnUrl = Url.Action("Index", "Home", new { area = AreaNames.Admin }); //prevent open redirection attack if (!Url.IsLocalUrl(returnUrl)) - return RedirectToAction("Index", "Home", new { area = AreaNames.Admin }); + returnUrl = Url.Action("Index", "Home", new { area = AreaNames.Admin }); - return Redirect(returnUrl); + return View("RestartApplication", returnUrl); + } + + public virtual IActionResult RestartApplication() + { + if (!_permissionService.Authorize(StandardPermissionProvider.ManageMaintenance) && + !_permissionService.Authorize(StandardPermissionProvider.ManagePlugins)) + { + return AccessDeniedView(); + } + + //restart application + _webHelper.RestartAppDomain(); + + return new EmptyResult(); } public virtual IActionResult SeNames() diff --git a/src/Presentation/Nop.Web/Areas/Admin/Controllers/PluginController.cs b/src/Presentation/Nop.Web/Areas/Admin/Controllers/PluginController.cs index 727437d46a5..4aa9cf0992a 100644 --- a/src/Presentation/Nop.Web/Areas/Admin/Controllers/PluginController.cs +++ b/src/Presentation/Nop.Web/Areas/Admin/Controllers/PluginController.cs @@ -158,10 +158,7 @@ public virtual IActionResult UploadPluginsAndThemes(IFormFile archivefile) try { if (archivefile == null || archivefile.Length == 0) - { - _notificationService.ErrorNotification(_localizationService.GetResource("Admin.Common.UploadFile")); - return RedirectToAction("List"); - } + throw new NopException(_localizationService.GetResource("Admin.Common.UploadFile")); var descriptors = _uploadService.UploadPluginsAndThemes(archivefile); var pluginDescriptors = descriptors.OfType().ToList(); @@ -190,8 +187,7 @@ public virtual IActionResult UploadPluginsAndThemes(IFormFile archivefile) var message = string.Format(_localizationService.GetResource("Admin.Configuration.Plugins.Uploaded"), pluginDescriptors.Count, themeDescriptors.Count); _notificationService.SuccessNotification(message); - //restart application - _webHelper.RestartAppDomain(); + return View("RestartApplication", Url.Action("List", "Plugin")); } catch (Exception exc) { @@ -316,10 +312,7 @@ public virtual IActionResult ReloadList() _pluginService.UninstallPlugins(); _pluginService.DeletePlugins(); - //restart application - _webHelper.RestartAppDomain(); - - return RedirectToAction("List"); + return View("RestartApplication", Url.Action("List", "Plugin")); } [HttpPost, ActionName("List")] diff --git a/src/Presentation/Nop.Web/Areas/Admin/Views/Shared/RestartApplication.cshtml b/src/Presentation/Nop.Web/Areas/Admin/Views/Shared/RestartApplication.cshtml new file mode 100644 index 00000000000..e2a3e96bec6 --- /dev/null +++ b/src/Presentation/Nop.Web/Areas/Admin/Views/Shared/RestartApplication.cshtml @@ -0,0 +1,19 @@ +@model string + +@using Nop.Services.Common +@inject CommonSettings commonSettings + + \ No newline at end of file diff --git a/src/Presentation/Nop.Web/Controllers/InstallController.cs b/src/Presentation/Nop.Web/Controllers/InstallController.cs index f17d5fc416d..d3846bea6fc 100644 --- a/src/Presentation/Nop.Web/Controllers/InstallController.cs +++ b/src/Presentation/Nop.Web/Controllers/InstallController.cs @@ -60,11 +60,12 @@ public virtual IActionResult Index() ConnectionStringRaw = false, DataProvider = DataProviderType.SqlServer }; - + model.AvailableDataProviders.AddRange( _locService.GetAvailableProviderTypes() .OrderBy(v => v.Value) - .Select(pt => new SelectListItem { + .Select(pt => new SelectListItem + { Value = pt.Key.ToString(), Text = pt.Value })); @@ -103,7 +104,8 @@ public virtual async Task Index(InstallModel model) model.AvailableDataProviders.AddRange( _locService.GetAvailableProviderTypes() .OrderBy(v => v.Value) - .Select(pt => new SelectListItem { + .Select(pt => new SelectListItem + { Value = pt.Key.ToString(), Text = pt.Value })); @@ -219,11 +221,7 @@ public virtual async Task Index(InstallModel model) } catch { } - //restart application - webHelper.RestartAppDomain(); - - //Redirect to home page - return RedirectToRoute("Homepage"); + return View(new InstallModel { RestartUrl = Url.RouteUrl("Homepage") }); } catch (Exception exception) @@ -257,16 +255,22 @@ public virtual IActionResult ChangeLanguage(string language) [HttpPost] [IgnoreAntiforgeryToken] public virtual IActionResult RestartInstall() + { + if (DataSettingsManager.DatabaseIsInstalled) + return RedirectToRoute("Homepage"); + + return View("Index", new InstallModel { RestartUrl = Url.Action("Index", "Install") }); + } + + public virtual IActionResult RestartApplication() { if (DataSettingsManager.DatabaseIsInstalled) return RedirectToRoute("Homepage"); //restart application - var webHelper = EngineContext.Current.Resolve(); - webHelper.RestartAppDomain(); + EngineContext.Current.Resolve().RestartAppDomain(); - //Redirect to home page - return RedirectToRoute("Homepage"); + return new EmptyResult(); } #endregion diff --git a/src/Presentation/Nop.Web/Models/Install/InstallModel.cs b/src/Presentation/Nop.Web/Models/Install/InstallModel.cs index 322bfb5d942..179bd3ba646 100644 --- a/src/Presentation/Nop.Web/Models/Install/InstallModel.cs +++ b/src/Presentation/Nop.Web/Models/Install/InstallModel.cs @@ -46,5 +46,7 @@ public InstallModel() public List AvailableDataProviders { get; set; } public IDictionary RawDataSettings => new Dictionary(); + + public string RestartUrl { get; set; } } } \ No newline at end of file diff --git a/src/Presentation/Nop.Web/Views/Install/Index.cshtml b/src/Presentation/Nop.Web/Views/Install/Index.cshtml index 3cddcd822e6..c6980ef59d1 100644 --- a/src/Presentation/Nop.Web/Views/Install/Index.cshtml +++ b/src/Presentation/Nop.Web/Views/Install/Index.cshtml @@ -72,7 +72,7 @@ $(document).ready(function () { $('#restart-form').submit(function () { $("html, body").animate({ scrollTop: 0 }, 400); - showThrobber('@Html.Raw(JavaScriptEncoder.Default.Encode("Restarting..."))'); + showThrobber('@Html.Raw(JavaScriptEncoder.Default.Encode(ILS.GetResource("RestartProgress")))'); $('input[type=submit]', this).attr('disabled', 'disabled'); }); }); @@ -92,7 +92,7 @@ if(!integratedSecurityProviders.includes($(this).val())) { $('#@Html.IdFor(x => x.IntegratedSecurity)').prop('checked', false); $('#@Html.IdFor(x => x.IntegratedSecurity)').prop('disabled', true) - + toggleSqlAuthenticationType(); } else { $('#@Html.IdFor(x => x.IntegratedSecurity)').prop('disabled', false) @@ -112,7 +112,7 @@ } function toggleCollation() { - + var connectionStringRaw = $("#@Html.IdFor(x => x.UseCustomCollation)").is(':checked'); var collationInput = $("#@Html.IdFor(x => x.Collation)") if (connectionStringRaw) { @@ -121,6 +121,24 @@ collationInput.hide(); } } + + @if (!string.IsNullOrEmpty(Model.RestartUrl)) + { + + $(document).ready(function () { + showThrobber('@Html.Raw(JavaScriptEncoder.Default.Encode(ILS.GetResource("RestartProgress")))'); + $.ajax({ + type: "GET", + url: "@Url.Action("RestartApplication", "Install")", + complete: function() { + window.setTimeout(function () { + window.location.replace('@Model.RestartUrl'); + }, @NopCommonDefaults.RestartTimeout); + } + }); + }); + + }
diff --git a/src/Presentation/Nop.Web/Views/Install/_ViewImports.cshtml b/src/Presentation/Nop.Web/Views/Install/_ViewImports.cshtml index 707e332a643..30f16ad5e39 100644 --- a/src/Presentation/Nop.Web/Views/Install/_ViewImports.cshtml +++ b/src/Presentation/Nop.Web/Views/Install/_ViewImports.cshtml @@ -4,5 +4,6 @@ @inject IInstallationLocalizationService ILS @using Nop.Data +@using Nop.Services.Common @using Nop.Web.Models.Install @using Nop.Web.Infrastructure.Installation \ No newline at end of file diff --git a/upgradescripts/4.20-4.30 (under development)/upgrade.sql b/upgradescripts/4.20-4.30 (under development)/upgrade.sql index 910c6d6b40c..007a5a20184 100644 --- a/upgradescripts/4.20-4.30 (under development)/upgrade.sql +++ b/upgradescripts/4.20-4.30 (under development)/upgrade.sql @@ -3299,4 +3299,12 @@ BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'avalarataxsettings.enablelogging', N'True', 0) END +GO + +--new setting +IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [Name] = N'commonsettings.restarttimeout') +BEGIN + INSERT [Setting] ([Name], [Value], [StoreId]) + VALUES (N'commonsettings.restarttimeout', N'3000', 0) +END GO \ No newline at end of file