public MediaFileInfo ReplaceFile(MediaFile file, Stream inStream, string newFileName) { Guard.NotNull(file, nameof(file)); Guard.NotNull(inStream, nameof(inStream)); Guard.NotEmpty(newFileName, nameof(newFileName)); var fileInfo = ConvertMediaFile(file); var pathData = CreatePathData(fileInfo.Path); pathData.FileName = newFileName; var storageItem = ProcessFile(ref file, pathData, inStream, false, DuplicateFileHandling.Overwrite, MimeValidationType.MediaTypeMustMatch); using (var scope = new DbContextScope(_fileRepo.Context, autoCommit: false)) { try { _storageProvider.Save(file, storageItem); scope.Commit(); } catch (Exception ex) { Logger.Error(ex); } } return(fileInfo); }
private void MoveMedia() { if (!_config.StoreMediaInDB) { // All pictures have initially been stored in the DB. Move the binaries to disk. var fileSystemStorageProvider = new FileSystemMediaStorageProvider(new MediaFileSystem()); var mediaStorages = _ctx.Set <MediaStorage>(); using (var scope = new DbContextScope(ctx: _ctx, autoDetectChanges: true, autoCommit: false)) { var mediaFiles = _ctx.Set <MediaFile>() .Expand(x => x.MediaStorage) .Where(x => x.MediaStorageId != null) .ToList(); foreach (var mediaFile in mediaFiles) { if (mediaFile.MediaStorage?.Data?.LongLength > 0) { fileSystemStorageProvider.Save(mediaFile, mediaFile.MediaStorage.Data.ToStream()); mediaFile.MediaStorageId = null; mediaFile.MediaStorage = null; } } scope.Commit(); } } }
public void CalculateFutureSchedules(IEnumerable <ScheduleTask> tasks, bool isAppStart = false) { Guard.ArgumentNotNull(() => tasks); using (var scope = new DbContextScope(autoCommit: false)) { var now = DateTime.UtcNow; foreach (var task in tasks) { task.NextRunUtc = GetNextSchedule(task); if (isAppStart) { task.ProgressPercent = null; task.ProgressMessage = null; if (task.LastEndUtc.GetValueOrDefault() < task.LastStartUtc) { task.LastEndUtc = task.LastStartUtc; task.LastError = T("Admin.System.ScheduleTasks.AbnormalAbort"); } } this.UpdateTask(task); } scope.Commit(); } }
public virtual void DeleteDeliveryTime(DeliveryTime deliveryTime) { if (deliveryTime == null) { return; } // Remove associations to deleted products. using (var scope = new DbContextScope(_productRepository.Context, autoDetectChanges: false, validateOnSave: false, hooksEnabled: false, autoCommit: false)) { var productsQuery = _productRepository.Table.Where(x => x.Deleted && x.DeliveryTimeId == deliveryTime.Id); var productsPager = new FastPager <Product>(productsQuery, 500); while (productsPager.ReadNextPage(out var products)) { if (products.Any()) { products.Each(x => x.DeliveryTimeId = null); scope.Commit(); } } var attributeCombinationQuery = from ac in _attributeCombinationRepository.Table join p in _productRepository.Table on ac.ProductId equals p.Id where p.Deleted && ac.DeliveryTimeId == deliveryTime.Id select ac; var attributeCombinationPager = new FastPager <ProductVariantAttributeCombination>(attributeCombinationQuery, 1000); while (attributeCombinationPager.ReadNextPage(out var attributeCombinations)) { if (attributeCombinations.Any()) { attributeCombinations.Each(x => x.DeliveryTimeId = null); scope.Commit(); } } } // Warn if there are associations to active products. if (IsAssociated(deliveryTime.Id)) { throw new SmartException(T("Admin.Configuration.DeliveryTimes.CannotDeleteAssignedProducts")); } _deliveryTimeRepository.Delete(deliveryTime); }
public void SeedDatabase(SmartObjectContext context) { using (var scope = new DbContextScope(context, hooksEnabled: false)) { Seed(context); scope.Commit(); } }
private void SaveRuleData(RuleEditItem[] ruleData, RuleScope ruleScope) { var rules = _ruleStorage.GetRulesByIds(ruleData?.Select(x => x.RuleId)?.ToArray(), true); if (!rules.Any()) { return; } using (var scope = new DbContextScope(ctx: Services.DbContext, autoCommit: false)) { var rulesDic = rules.ToDictionarySafe(x => x.Id); var provider = _ruleProvider(ruleScope); foreach (var data in ruleData) { if (rulesDic.TryGetValue(data.RuleId, out var entity)) { // TODO? Ugly. There should be a better way. Do not store culture variant values. if (data.Value.HasValue()) { var descriptor = provider.RuleDescriptors.FindDescriptor(entity.RuleType); if (descriptor.RuleType == RuleType.Money) { data.Value = data.Value.Convert <decimal>(CultureInfo.CurrentCulture).ToString(CultureInfo.InvariantCulture); } else if (descriptor.RuleType == RuleType.Float || descriptor.RuleType == RuleType.NullableFloat) { data.Value = data.Value.Convert <float>(CultureInfo.CurrentCulture).ToString(CultureInfo.InvariantCulture); } else if (descriptor.RuleType == RuleType.DateTime || descriptor.RuleType == RuleType.NullableDateTime) { data.Value = data.Value.Convert <DateTime>(CultureInfo.CurrentCulture).ToString(CultureInfo.InvariantCulture); } } //if (data.Value?.Contains(',') ?? false) //{ // var provider = _ruleProvider(ruleScope); // var descriptor = provider.RuleDescriptors.FindDescriptor(entity.RuleType); // var floatingPointTypes = new Type[] { typeof(decimal), typeof(decimal?), typeof(float), typeof(float?), typeof(double), typeof(double?) }; // if (floatingPointTypes.Contains(descriptor.RuleType.ClrType)) // { // data.Value = data.Value.Replace(",", "."); // } //} entity.Operator = data.Op; entity.Value = data.Value; _ruleStorage.UpdateRule(entity); } } scope.Commit(); } }
/// <summary> /// Install permissions /// </summary> /// <param name="permissionProvider">Permission provider</param> public virtual void InstallPermissions(IPermissionProvider permissionProvider) { using (var scope = new DbContextScope(_permissionRecordRepository.Context, autoDetectChanges: false, autoCommit: false)) { //install new permissions var permissions = permissionProvider.GetPermissions(); foreach (var permission in permissions) { var permission1 = GetPermissionRecordBySystemName(permission.SystemName); if (permission1 == null) { //new permission (install it) permission1 = new PermissionRecord() { Name = permission.Name, SystemName = permission.SystemName, Category = permission.Category, }; // default customer role mappings var defaultPermissions = permissionProvider.GetDefaultPermissions(); foreach (var defaultPermission in defaultPermissions) { var customerRole = _customerService.GetCustomerRoleBySystemName(defaultPermission.CustomerRoleSystemName); if (customerRole == null) { //new role (save it) customerRole = new CustomerRole { Name = defaultPermission.CustomerRoleSystemName, Active = true, SystemName = defaultPermission.CustomerRoleSystemName }; _customerService.InsertCustomerRole(customerRole); } var defaultMappingProvided = (from p in defaultPermission.PermissionRecords where p.SystemName == permission1.SystemName select p).Any(); var mappingExists = (from p in customerRole.PermissionRecords where p.SystemName == permission1.SystemName select p).Any(); if (defaultMappingProvided && !mappingExists) { permission1.CustomerRoles.Add(customerRole); } } //save new permission InsertPermissionRecord(permission1); } } scope.Commit(); } }
public void MigrateMediaFiles_Old(SmartObjectContext ctx) { var query = ctx.Set <MediaFile>(); //.Where(x => x.Version == 0) //.Include(x => x.MediaStorage); var pager = new FastPager <MediaFile>(query, 1000); using (var scope = new DbContextScope(ctx, hooksEnabled: false, autoCommit: false, proxyCreation: false, validateOnSave: false, lazyLoading: false)) { while (pager.ReadNextPage(out var files)) { foreach (var file in files) { if (file.Version > 0) { continue; } if (file.Extension.IsEmpty()) { file.Extension = MimeTypes.MapMimeTypeToExtension(file.MimeType); } var name = file.Name; if (name.IsEmpty()) { name = file.Id.ToString(System.Globalization.CultureInfo.InvariantCulture); } else { name = MediaHelper.NormalizeFileName(file.Name.Truncate(292)); } file.Name = name + "." + file.Extension; file.CreatedOnUtc = file.UpdatedOnUtc; file.Version = 1; ProcessMediaFile(file); } // Save to DB int num = scope.Commit(); // Breathe ctx.DetachEntities <MediaFile>(deep: true); } } }
public void Remove(params MediaFile[] mediaFiles) { using (var scope = new DbContextScope(ctx: _mediaFileRepo.Context, autoCommit: false)) { foreach (var media in mediaFiles) { media.ApplyBlob(null); } scope.Commit(); } }
public MediaFileInfo SaveFile(string path, Stream stream, bool isTransient = true, DuplicateFileHandling dupeFileHandling = DuplicateFileHandling.ThrowError) { var pathData = CreatePathData(path); var file = _fileRepo.Table.FirstOrDefault(x => x.Name == pathData.FileName && x.FolderId == pathData.Folder.Id); var isNewFile = file == null; var storageItem = ProcessFile(ref file, pathData, stream, isTransient, dupeFileHandling); using (var scope = new DbContextScope(_fileRepo.Context, autoCommit: false)) { if (file.Id == 0) { _fileRepo.Insert(file); scope.Commit(); } try { _storageProvider.Save(file, storageItem); scope.Commit(); } catch (Exception ex) { if (isNewFile) { // New file's metadata should be removed on storage save failure immediately DeleteFile(file, true, true); scope.Commit(); } Logger.Error(ex); } } return(ConvertMediaFile(file, pathData.Folder)); }
public override void OnAfterSaveCompleted() { if (_toDelete.Count == 0) { return; } using (var scope = new DbContextScope(autoCommit: false)) { _toDelete.Each(x => _productAttributeService.Value.DeleteProductBundleItemAttributeFilter(x)); scope.Commit(); } _toDelete.Clear(); }
public override void OnAfterSaveCompleted() { if (_toDelete.Count == 0) { return; } using (var scope = new DbContextScope(autoCommit: false)) { _toDelete.Each(x => _aclService.Value.DeleteAclRecord(x)); scope.Commit(); } _toDelete.Clear(); }
public override void OnAfterSaveCompleted() { if (_toDelete.Count == 0) return; using (var scope = new DbContextScope(autoCommit: false)) { using (_localizedEntityService.Value.BeginScope()) { _toDelete.Each(x => _localizedEntityService.Value.DeleteLocalizedProperty(x)); } scope.Commit(); _toDelete.Clear(); } }
public override void OnAfterSaveCompleted() { if (_toDelete.Count == 0) { return; } using (var scope = new DbContextScope(autoCommit: false)) { var pictures = _pictureService.Value.GetPicturesByIds(_toDelete.ToArray()); pictures.Each(x => _pictureService.Value.DeletePicture(x)); scope.Commit(); _toDelete.Clear(); } }
public void MigrateMediaFiles(SmartObjectContext ctx) { var query = ctx.Set <MediaFile>() //.Where(x => x.Version == 0) .Include(x => x.MediaStorage); var pager = new FastPager <MediaFile>(query, 1000); using (var scope = new DbContextScope(ctx, hooksEnabled: false, autoCommit: false, proxyCreation: false, validateOnSave: false, lazyLoading: false)) { while (pager.ReadNextPage(out var files)) { foreach (var file in files) { if (file.Version > 0) { continue; } if (file.Extension.IsEmpty()) { file.Extension = MimeTypes.MapMimeTypeToExtension(file.MimeType); } file.Name = file.Name + "." + file.Extension; file.CreatedOnUtc = file.UpdatedOnUtc; file.Version = 1; ProcessMediaFile(file); } // Save to DB int num = scope.Commit(); // Breathe ctx.DetachEntities <MediaFile>(deep: true); } } }
public ActionResult MoveItem(int menuId, int sourceId, string direction) { if (menuId == 0 || sourceId == 0 || direction.IsEmpty()) { return(new EmptyResult()); } if (!Services.Permissions.Authorize(StandardPermissionProvider.ManageMenus)) { NotifyAccessDenied(); return(new EmptyResult()); } using (var scope = new DbContextScope(ctx: Services.DbContext, autoCommit: false)) { var allItems = _menuStorage.GetMenuItems(menuId, 0, true).ToDictionary(x => x.Id, x => x); var sourceItem = allItems[sourceId]; var siblings = allItems.Select(x => x.Value) .Where(x => x.ParentItemId == sourceItem.ParentItemId) .OrderBy(x => x.DisplayOrder) .ToList(); var index = siblings.IndexOf(sourceItem) + (direction == "up" ? -1 : 1); if (index >= 0 && index < siblings.Count) { var targetItem = siblings[index]; // Ensure unique display order starting from 1. var count = 0; siblings.Each(x => x.DisplayOrder = ++count); // Swap display order of source and target item. var tmp = sourceItem.DisplayOrder; sourceItem.DisplayOrder = targetItem.DisplayOrder; targetItem.DisplayOrder = tmp; scope.Commit(); } } return(RedirectToAction("ItemList", new { id = menuId })); }
public void Seed(SmartObjectContext context) { if (!DataSettings.DatabaseIsInstalled()) { return; } // URL records of BlogPost and NewsItem must now have 0 for "Standard" as language ID otherwise no link is created. using (var scope = new DbContextScope(ctx: context, validateOnSave: false, hooksEnabled: false, autoCommit: false)) { var urlRecords = context.Set <UrlRecord>(); var entityNames = new[] { nameof(BlogPost), nameof(NewsItem) }; foreach (var entityName in entityNames) { var allEntityIds = urlRecords .Where(x => x.EntityName == entityName) .Select(x => x.EntityId) .Distinct() .ToList(); foreach (var chunk in allEntityIds.Slice(200)) { var entities = urlRecords .Where(x => x.EntityName == entityName && chunk.Contains(x.EntityId)) .ToList(); var entitiesMap = entities.ToMultimap(x => x.EntityId, x => x); foreach (var kvp in entitiesMap) { if (!kvp.Value.Any(x => x.LanguageId == 0)) { // Migrate active and inactive slugs. kvp.Value.Where(x => x.LanguageId != 0).Each(x => x.LanguageId = 0); } } scope.Commit(); context.DetachEntities <UrlRecord>(); } } } }
private void InternalCopyFileData(MediaFile file, MediaFile copy) { _storageProvider.Save(copy, MediaStorageItem.FromStream(_storageProvider.OpenRead(file))); _imageCache.Delete(copy); using (var scope = new DbContextScope(_fileRepo.Context, autoCommit: false)) { // Tags. _fileRepo.Context.LoadCollection(file, (MediaFile x) => x.Tags); var existingTagsIds = copy.Tags.Select(x => x.Id).ToList(); foreach (var tag in file.Tags) { if (!existingTagsIds.Contains(tag.Id)) { copy.Tags.Add(tag); existingTagsIds.Add(tag.Id); } } // Localized values. var languages = _languageService.GetAllLanguages(true); foreach (var language in languages) { var title = file.GetLocalized(x => x.Title, language.Id, false, false).Value; if (title.HasValue()) { _localizedEntityService.SaveLocalizedValue(copy, x => x.Title, title, language.Id); } var alt = file.GetLocalized(x => x.Alt, language.Id, false, false).Value; if (alt.HasValue()) { _localizedEntityService.SaveLocalizedValue(copy, x => x.Alt, alt, language.Id); } } scope.Commit(); _fileRepo.Context.DetachEntities <MediaTag>(); } }
public virtual ProductSummaryModel MapProductSummaryModel(IPagedList <Product> products, ProductSummaryMappingSettings settings) { Guard.NotNull(products, nameof(products)); if (settings == null) { settings = new ProductSummaryMappingSettings(); } using (_services.Chronometer.Step("MapProductSummaryModel")) { // PERF!! var store = _services.StoreContext.CurrentStore; var customer = _services.WorkContext.CurrentCustomer; var currency = _services.WorkContext.WorkingCurrency; var allowPrices = _services.Permissions.Authorize(StandardPermissionProvider.DisplayPrices); var sllowShoppingCart = _services.Permissions.Authorize(StandardPermissionProvider.EnableShoppingCart); var allowWishlist = _services.Permissions.Authorize(StandardPermissionProvider.EnableWishlist); var taxDisplayType = _services.WorkContext.GetTaxDisplayTypeFor(customer, store.Id); var cachedManufacturerModels = new Dictionary <int, ManufacturerOverviewModel>(); string taxInfo = T(taxDisplayType == TaxDisplayType.IncludingTax ? "Tax.InclVAT" : "Tax.ExclVAT"); var legalInfo = ""; var res = new Dictionary <string, LocalizedString>(StringComparer.OrdinalIgnoreCase) { { "Products.CallForPrice", T("Products.CallForPrice") }, { "Products.PriceRangeFrom", T("Products.PriceRangeFrom") }, { "Media.Product.ImageLinkTitleFormat", T("Media.Product.ImageLinkTitleFormat") }, { "Media.Product.ImageAlternateTextFormat", T("Media.Product.ImageAlternateTextFormat") }, { "Products.DimensionsValue", T("Products.DimensionsValue") }, { "Common.AdditionalShippingSurcharge", T("Common.AdditionalShippingSurcharge") } }; if (settings.MapLegalInfo) { if (_topicService.Value.GetTopicBySystemName("ShippingInfo", store.Id) == null) { legalInfo = T("Tax.LegalInfoShort2").Text.FormatInvariant(taxInfo); } else { var shippingInfoLink = _urlHelper.RouteUrl("Topic", new { SystemName = "shippinginfo" }); legalInfo = T("Tax.LegalInfoShort").Text.FormatInvariant(taxInfo, shippingInfoLink); } } using (var scope = new DbContextScope(ctx: _services.DbContext, autoCommit: false, validateOnSave: false)) { // Run in uncommitting scope, because pictures could be updated (IsNew property) var batchContext = _dataExporter.Value.CreateProductExportContext(products); if (settings.MapPrices) { batchContext.AppliedDiscounts.LoadAll(); batchContext.TierPrices.LoadAll(); } if (settings.MapAttributes || settings.MapColorAttributes) { batchContext.Attributes.LoadAll(); } if (settings.MapManufacturers) { batchContext.ProductManufacturers.LoadAll(); } if (settings.MapSpecificationAttributes) { batchContext.SpecificationAttributes.LoadAll(); } var model = new ProductSummaryModel(products) { ViewMode = settings.ViewMode, GridColumnSpan = _catalogSettings.GridStyleListColumnSpan, ShowSku = _catalogSettings.ShowProductSku, ShowWeight = _catalogSettings.ShowWeight, ShowDimensions = settings.MapDimensions, ShowLegalInfo = settings.MapLegalInfo, ShowDescription = settings.MapShortDescription, ShowFullDescription = settings.MapFullDescription, ShowRatings = settings.MapReviews, ShowDeliveryTimes = settings.MapDeliveryTimes, ShowPrice = settings.MapPrices, ShowBasePrice = settings.MapPrices && _catalogSettings.ShowBasePriceInProductLists && settings.ViewMode != ProductSummaryViewMode.Mini, ShowShippingSurcharge = settings.MapPrices && settings.ViewMode != ProductSummaryViewMode.Mini, ShowButtons = settings.ViewMode != ProductSummaryViewMode.Mini, ShowBrand = settings.MapManufacturers, ForceRedirectionAfterAddingToCart = settings.ForceRedirectionAfterAddingToCart, CompareEnabled = _catalogSettings.CompareProductsEnabled, WishlistEnabled = _permissionService.Value.Authorize(StandardPermissionProvider.EnableWishlist), BuyEnabled = !_catalogSettings.HideBuyButtonInLists, ThumbSize = settings.ThumbnailSize, ShowDiscountBadge = _catalogSettings.ShowDiscountSign, ShowNewBadge = _catalogSettings.LabelAsNewForMaxDays.HasValue }; var mapItemContext = new MapProductSummaryItemContext { BatchContext = batchContext, CachedManufacturerModels = cachedManufacturerModels, Currency = currency, LegalInfo = legalInfo, Model = model, Resources = res, Settings = settings, Customer = customer, Store = store, AllowPrices = allowPrices, AllowShoppingCart = sllowShoppingCart, AllowWishlist = allowWishlist, TaxDisplayType = taxDisplayType }; foreach (var product in products) { MapProductSummaryItem(product, mapItemContext); } _services.DisplayControl.AnnounceRange(products); scope.Commit(); batchContext.Clear(); // don't show stuff without data at all model.ShowDescription = model.ShowDescription && model.Items.Any(x => x.ShortDescription.HasValue()); model.ShowBrand = model.ShowBrand && model.Items.Any(x => x.Manufacturer != null); return(model); } } }
public virtual void InstallPermissions(IPermissionProvider[] permissionProviders, bool removeUnusedPermissions = false) { if (!(permissionProviders?.Any() ?? false)) { return; } Dictionary <string, CustomerRole> existingRoles = null; var allPermissionNames = _permissionRepository.TableUntracked.Select(x => x.SystemName).ToList(); var existing = new HashSet <string>(allPermissionNames, StringComparer.InvariantCultureIgnoreCase); var added = new HashSet <string>(StringComparer.InvariantCultureIgnoreCase); var providerPermissions = new HashSet <string>(StringComparer.InvariantCultureIgnoreCase); var log = existing.Any(); var clearCache = false; if (existing.Any()) { var permissionsMigrated = existing.Contains(Permissions.System.AccessShop) && !existing.Contains("PublicStoreAllowNavigation"); if (!permissionsMigrated) { // Migrations must have been completed before permissions can be added or deleted. return; } } try { using (var scope = new DbContextScope(_permissionRepository.Context, validateOnSave: false, hooksEnabled: false, autoCommit: false)) { // Add new permissions. foreach (var provider in permissionProviders) { try { var systemNames = provider.GetPermissions().Select(x => x.SystemName); var missingSystemNames = systemNames.Except(existing); if (removeUnusedPermissions) { providerPermissions.AddRange(systemNames); } if (missingSystemNames.Any()) { var defaultPermissions = provider.GetDefaultPermissions(); foreach (var systemName in missingSystemNames) { var roleNames = defaultPermissions .Where(x => x.PermissionRecords.Any(y => y.SystemName == systemName)) .Select(x => x.CustomerRoleSystemName); var newPermission = new PermissionRecord { SystemName = systemName }; foreach (var roleName in new HashSet <string>(roleNames, StringComparer.InvariantCultureIgnoreCase)) { if (existingRoles == null) { existingRoles = new Dictionary <string, CustomerRole>(); var rolesQuery = _customerService.Value.GetAllCustomerRoles(true).SourceQuery; rolesQuery = rolesQuery.Where(x => !string.IsNullOrEmpty(x.SystemName)); var rolesPager = new FastPager <CustomerRole>(rolesQuery, 500); while (rolesPager.ReadNextPage(out var roles)) { roles.Each(x => existingRoles[x.SystemName] = x); } } if (!existingRoles.TryGetValue(roleName, out var role)) { role = new CustomerRole { Active = true, Name = roleName, SystemName = roleName }; _customerService.Value.InsertCustomerRole(role); scope.Commit(); existingRoles[roleName] = role; } newPermission.PermissionRoleMappings.Add(new PermissionRoleMapping { Allow = true, CustomerRoleId = role.Id }); } _permissionRepository.Insert(newPermission); clearCache = true; added.Add(newPermission.SystemName); existing.Add(newPermission.SystemName); } } } catch (Exception ex) { Logger.Error(ex); } } scope.Commit(); if (log && added.Any()) { Logger.Info(T("Admin.Permissions.AddedPermissions", string.Join(", ", added))); } // Remove permissions no longer supported by providers. if (removeUnusedPermissions) { var toDelete = existing.Except(providerPermissions).ToList(); if (toDelete.Any()) { clearCache = true; foreach (var chunk in toDelete.Slice(500)) { var entities = _permissionRepository.Table.Where(x => chunk.Contains(x.SystemName)).ToList(); entities.Each(x => _permissionRepository.Delete(x)); scope.Commit(); } if (log) { Logger.Info(T("Admin.Permissions.RemovedPermissions", string.Join(", ", toDelete))); } } } } } finally { if (clearCache) { _cacheManager.RemoveByPattern(PERMISSION_TREE_PATTERN_KEY); } } }
public virtual int DeleteGuestCustomers(DateTime?registrationFrom, DateTime?registrationTo, bool onlyWithoutShoppingCart, int maxItemsToDelete = 5000) { var ctx = _customerRepository.Context; using (var scope = new DbContextScope(ctx: ctx, autoDetectChanges: false, proxyCreation: true, validateOnSave: false, forceNoTracking: true, autoCommit: false)) { var guestRole = GetCustomerRoleBySystemName(SystemCustomerRoleNames.Guests); if (guestRole == null) { throw new SmartException("'Guests' role could not be loaded"); } var query = _customerRepository.Table; if (registrationFrom.HasValue) { query = query.Where(c => registrationFrom.Value <= c.CreatedOnUtc); } if (registrationTo.HasValue) { query = query.Where(c => registrationTo.Value >= c.CreatedOnUtc); } query = query.Where(c => c.CustomerRoles.Select(cr => cr.Id).Contains(guestRole.Id)); if (onlyWithoutShoppingCart) { query = query.Where(c => !c.ShoppingCartItems.Any()); } // no orders query = JoinWith <Order>(query, x => x.CustomerId); // no customer content query = JoinWith <CustomerContent>(query, x => x.CustomerId); // no private messages (guests can only receive but not send messages) query = JoinWith <PrivateMessage>(query, x => x.ToCustomerId); // no forum posts query = JoinWith <ForumPost>(query, x => x.CustomerId); // no forum topics query = JoinWith <ForumTopic>(query, x => x.CustomerId); //don't delete system accounts query = query.Where(c => !c.IsSystemAccount); // only distinct items query = from c in query group c by c.Id into cGroup orderby cGroup.Key select cGroup.FirstOrDefault(); query = query.OrderBy(c => c.Id); var customers = query.Take(maxItemsToDelete).ToList(); int numberOfDeletedCustomers = 0; foreach (var c in customers) { try { // delete attributes (using GenericAttributeService would incorporate caching... which is bad in long running processes) var gaQuery = from ga in _gaRepository.Table where ga.EntityId == c.Id && ga.KeyGroup == "Customer" select ga; var attributes = gaQuery.ToList(); _gaRepository.DeleteRange(attributes); // delete customer _customerRepository.Delete(c); numberOfDeletedCustomers++; if (numberOfDeletedCustomers % 1000 == 0) { // save changes all 1000th item try { scope.Commit(); } catch (Exception ex) { Debug.WriteLine(ex); } } } catch (Exception ex) { Debug.WriteLine(ex); } } // save the rest scope.Commit(); return(numberOfDeletedCustomers); } }
protected virtual InstallationResult InstallCore(ILifetimeScope scope, InstallModel model) { UpdateResult(x => { x.ProgressMessage = _locService.GetResource("Progress.CheckingRequirements"); x.Completed = false; Logger.Info(x.ProgressMessage); }); if (DataSettings.DatabaseIsInstalled()) { return(UpdateResult(x => { x.Success = true; x.RedirectUrl = Url.Action("Index", "Home"); Logger.Info("Application already installed"); })); } // set page timeout to 5 minutes this.Server.ScriptTimeout = 300; if (model.DatabaseConnectionString != null) { model.DatabaseConnectionString = model.DatabaseConnectionString.Trim(); } // SQL Server if (model.DataProvider.Equals("sqlserver", StringComparison.InvariantCultureIgnoreCase)) { if (model.SqlConnectionInfo.Equals("sqlconnectioninfo_raw", StringComparison.InvariantCultureIgnoreCase)) { // raw connection string if (string.IsNullOrEmpty(model.DatabaseConnectionString)) { UpdateResult(x => { x.Errors.Add(_locService.GetResource("ConnectionStringRequired")); Logger.Error(x.Errors.Last()); }); } try { // try to create connection string new SqlConnectionStringBuilder(model.DatabaseConnectionString); } catch (Exception ex) { UpdateResult(x => { x.Errors.Add(_locService.GetResource("ConnectionStringWrongFormat")); Logger.Error(ex, x.Errors.Last()); }); } } else { // values if (string.IsNullOrEmpty(model.SqlServerName)) { UpdateResult(x => { x.Errors.Add(_locService.GetResource("SqlServerNameRequired")); Logger.Error(x.Errors.Last()); }); } if (string.IsNullOrEmpty(model.SqlDatabaseName)) { UpdateResult(x => { x.Errors.Add(_locService.GetResource("DatabaseNameRequired")); Logger.Error(x.Errors.Last()); }); } // authentication type if (model.SqlAuthenticationType.Equals("sqlauthentication", StringComparison.InvariantCultureIgnoreCase)) { // SQL authentication if (string.IsNullOrEmpty(model.SqlServerUsername)) { UpdateResult(x => { x.Errors.Add(_locService.GetResource("SqlServerUsernameRequired")); Logger.Error(x.Errors.Last()); }); } if (string.IsNullOrEmpty(model.SqlServerPassword)) { UpdateResult(x => { x.Errors.Add(_locService.GetResource("SqlServerPasswordRequired")); Logger.Error(x.Errors.Last()); }); } } } } // Consider granting access rights to the resource to the ASP.NET request identity. // ASP.NET has a base process identity // (typically {MACHINE}\ASPNET on IIS 5 or Network Service on IIS 6 and IIS 7, // and the configured application pool identity on IIS 7.5) that is used if the application is not impersonating. // If the application is impersonating via <identity impersonate="true"/>, // the identity will be the anonymous user (typically IUSR_MACHINENAME) or the authenticated request user. var webHelper = scope.Resolve <IWebHelper>(); // validate permissions var dirsToCheck = FilePermissionHelper.GetDirectoriesWrite(webHelper); foreach (string dir in dirsToCheck) { if (!FilePermissionHelper.CheckPermissions(dir, false, true, true, false)) { UpdateResult(x => { x.Errors.Add(string.Format(_locService.GetResource("ConfigureDirectoryPermissions"), WindowsIdentity.GetCurrent().Name, dir)); Logger.Error(x.Errors.Last()); }); } } var filesToCheck = FilePermissionHelper.GetFilesWrite(webHelper); foreach (string file in filesToCheck) { if (!FilePermissionHelper.CheckPermissions(file, false, true, true, true)) { UpdateResult(x => { x.Errors.Add(string.Format(_locService.GetResource("ConfigureFilePermissions"), WindowsIdentity.GetCurrent().Name, file)); Logger.Error(x.Errors.Last()); }); } } if (GetInstallResult().HasErrors) { return(UpdateResult(x => { x.Completed = true; x.Success = false; x.RedirectUrl = null; Logger.Error("Aborting installation."); })); } else { SmartObjectContext dbContext = null; var shouldDeleteDbOnFailure = false; try { string connectionString = null; if (model.DataProvider.Equals("sqlserver", StringComparison.InvariantCultureIgnoreCase)) { //SQL Server if (model.SqlConnectionInfo.Equals("sqlconnectioninfo_raw", StringComparison.InvariantCultureIgnoreCase)) { //raw connection string //we know that MARS option is required when using Entity Framework //let's ensure that it's specified var sqlCsb = new SqlConnectionStringBuilder(model.DatabaseConnectionString); sqlCsb.MultipleActiveResultSets = true; connectionString = sqlCsb.ToString(); } else { // values connectionString = CreateConnectionString( model.SqlAuthenticationType == "windowsauthentication", model.SqlServerName, model.SqlDatabaseName, model.SqlServerUsername, model.SqlServerPassword); } if (model.SqlServerCreateDatabase) { if (!SqlServerDatabaseExists(connectionString)) { //create database var collation = model.UseCustomCollation ? model.Collation : ""; var errorCreatingDatabase = CreateDatabase(connectionString, collation); if (errorCreatingDatabase.HasValue()) { return(UpdateResult(x => { x.Errors.Add(errorCreatingDatabase); x.Completed = true; x.Success = false; x.RedirectUrl = null; Logger.Error(errorCreatingDatabase); })); } else { // Database cannot be created sometimes. Weird! Seems to be Entity Framework issue // that's just wait 3 seconds Thread.Sleep(3000); shouldDeleteDbOnFailure = true; } } } else { // check whether database exists if (!SqlServerDatabaseExists(connectionString)) { return(UpdateResult(x => { x.Errors.Add(_locService.GetResource("DatabaseNotExists")); x.Completed = true; x.Success = false; x.RedirectUrl = null; Logger.Error(x.Errors.Last()); })); } } } else { // SQL CE string databaseFileName = "SmartStore.Db.sdf"; string databasePath = @"|DataDirectory|\Tenants\{0}\{1}".FormatInvariant(DataSettings.Current.TenantName, databaseFileName); connectionString = "Data Source=" + databasePath + "; Persist Security Info=False"; // drop database if exists string databaseFullPath = HostingEnvironment.MapPath(DataSettings.Current.TenantPath.EnsureEndsWith("/")) + databaseFileName; if (System.IO.File.Exists(databaseFullPath)) { System.IO.File.Delete(databaseFullPath); } shouldDeleteDbOnFailure = true; } // save settings var dataProvider = model.DataProvider; var settings = DataSettings.Current; settings.AppVersion = SmartStoreVersion.Version; settings.DataProvider = dataProvider; settings.DataConnectionString = connectionString; settings.Save(); // init data provider var dataProviderInstance = scope.Resolve <IEfDataProvider>(); // Although obsolete we have no other chance than using this here. // Delegating this to DbConfiguration is not possible during installation. #pragma warning disable 618 Database.DefaultConnectionFactory = dataProviderInstance.GetConnectionFactory(); #pragma warning restore 618 // resolve SeedData instance from primary language var lazyLanguage = _locService.GetAppLanguage(model.PrimaryLanguage); if (lazyLanguage == null) { return(UpdateResult(x => { x.Errors.Add(_locService.GetResource("Install.LanguageNotRegistered").FormatInvariant(model.PrimaryLanguage)); x.Completed = true; x.Success = false; x.RedirectUrl = null; Logger.Error(x.Errors.Last()); })); } // create the DataContext dbContext = new SmartObjectContext(); // AuditableHook must run during install dbContext.DbHookHandler = new DefaultDbHookHandler(new[] { new Lazy <IDbHook, HookMetadata>(() => new AuditableHook(), HookMetadata.Create <AuditableHook>(typeof(IAuditable), true), false) }); // IMPORTANT: Migration would run way too early otherwise Database.SetInitializer <SmartObjectContext>(null); // create Language domain object from lazyLanguage var languages = dbContext.Set <Language>(); var primaryLanguage = languages.Create(); // create a proxied type, resources cannot be saved otherwise primaryLanguage.Name = lazyLanguage.Metadata.Name; primaryLanguage.LanguageCulture = lazyLanguage.Metadata.Culture; primaryLanguage.UniqueSeoCode = lazyLanguage.Metadata.UniqueSeoCode; primaryLanguage.FlagImageFileName = lazyLanguage.Metadata.FlagImageFileName; // Build the seed configuration model var seedConfiguration = new SeedDataConfiguration { DefaultUserName = model.AdminEmail, DefaultUserPassword = model.AdminPassword, SeedSampleData = model.InstallSampleData, Data = lazyLanguage.Value, Language = primaryLanguage, StoreMediaInDB = model.MediaStorage == "db", ProgressMessageCallback = msg => UpdateResult(x => x.ProgressMessage = _locService.GetResource(msg)) }; var seeder = new InstallDataSeeder(seedConfiguration, Logger); Database.SetInitializer(new InstallDatabaseInitializer() { DataSeeders = new[] { seeder } }); UpdateResult(x => { x.ProgressMessage = _locService.GetResource("Progress.BuildingDatabase"); Logger.Info(x.ProgressMessage); }); // ===>>> actually performs the installation by calling "InstallDataSeeder.Seed()" internally. dbContext.Database.Initialize(true); // Install plugins. PluginManager.MarkAllPluginsAsUninstalled(); var pluginFinder = scope.Resolve <IPluginFinder>(); var plugins = pluginFinder.GetPlugins <IPlugin>(false) //.ToList() .OrderBy(x => x.PluginDescriptor.Group) .ThenBy(x => x.PluginDescriptor.DisplayOrder) .ToList(); var ignoredPluginsSetting = CommonHelper.GetAppSetting <string>("sm:PluginsIgnoredDuringInstallation"); var pluginsIgnoredDuringInstallation = String.IsNullOrEmpty(ignoredPluginsSetting) ? new List <string>() : ignoredPluginsSetting .Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries) .Select(x => x.Trim()) .ToList(); if (pluginsIgnoredDuringInstallation.Count > 0) { plugins = plugins.Where(x => !pluginsIgnoredDuringInstallation.Contains(x.PluginDescriptor.SystemName, StringComparer.OrdinalIgnoreCase)).ToList(); } var pluginsCount = plugins.Count; var idx = 0; using (var dbScope = new DbContextScope(autoDetectChanges: false, hooksEnabled: false)) { foreach (var plugin in plugins) { try { idx++; UpdateResult(x => { x.ProgressMessage = _locService.GetResource("Progress.InstallingPlugins").FormatInvariant(idx, pluginsCount); Logger.InfoFormat("Installing plugin '{0}'.", plugin.PluginDescriptor.FriendlyName ?? plugin.PluginDescriptor.SystemName); }); plugin.Install(); dbScope.Commit(); } catch (Exception ex) { Logger.Error(ex); if (plugin.PluginDescriptor.Installed) { PluginManager.MarkPluginAsUninstalled(plugin.PluginDescriptor.SystemName); } } } } // Detect media file tracks (must come after plugins installation) UpdateResult(x => { x.ProgressMessage = _locService.GetResource("Progress.ProcessingMedia"); Logger.Info(x.ProgressMessage); }); var mediaTracker = scope.Resolve <IMediaTracker>(); foreach (var album in scope.Resolve <IAlbumRegistry>().GetAlbumNames(true)) { mediaTracker.DetectAllTracks(album, false); } UpdateResult(x => { x.ProgressMessage = _locService.GetResource("Progress.Finalizing"); Logger.Info(x.ProgressMessage); }); // Do not ignore settings migrated by data seeder (e.g. default media storage provider). scope.Resolve <ISettingService>().ClearCache(); // SUCCESS: Redirect to home page return(UpdateResult(x => { x.Completed = true; x.Success = true; x.RedirectUrl = Url.Action("Index", "Home"); Logger.Info("Installation completed successfully"); })); } catch (Exception ex) { Logger.Error(ex); // Clear provider settings if something got wrong DataSettings.Delete(); // Delete Db if it was auto generated if (dbContext != null && shouldDeleteDbOnFailure) { try { Logger.Debug("Deleting database"); dbContext.Database.Delete(); } catch { } } var msg = ex.Message; var realException = ex; while (realException.InnerException != null) { realException = realException.InnerException; } if (!Object.Equals(ex, realException)) { msg += " (" + realException.Message + ")"; } return(UpdateResult(x => { x.Errors.Add(string.Format(_locService.GetResource("SetupFailed"), msg)); x.Success = false; x.Completed = true; x.RedirectUrl = null; })); } finally { if (dbContext != null) { dbContext.Dispose(); } } } }
public ActionResult Edit(CustomerRoleModel model, bool continueEditing, FormCollection form) { var customerRole = _customerService.GetCustomerRoleById(model.Id); if (customerRole == null) { return(RedirectToAction("List")); } try { if (ModelState.IsValid) { if (customerRole.IsSystemRole && !model.Active) { throw new SmartException(T("Admin.Customers.CustomerRoles.Fields.Active.CantEditSystem")); } if (customerRole.IsSystemRole && !customerRole.SystemName.Equals(model.SystemName, StringComparison.InvariantCultureIgnoreCase)) { throw new SmartException(T("Admin.Customers.CustomerRoles.Fields.SystemName.CantEditSystem")); } customerRole = model.ToEntity(customerRole); _customerService.UpdateCustomerRole(customerRole); // Update permissions. var permissionKey = "permission-"; var existingMappings = customerRole.PermissionRoleMappings.ToDictionarySafe(x => x.PermissionRecordId, x => x); var mappings = form.AllKeys.Where(x => x.StartsWith(permissionKey)) .Select(x => { var id = x.Substring(permissionKey.Length).ToInt(); bool?allow = null; var value = form[x].EmptyNull(); if (value.StartsWith("2")) { allow = true; } else if (value.StartsWith("1")) { allow = false; } return(new { id, allow }); }) .ToDictionary(x => x.id, x => x.allow); using (var scope = new DbContextScope(ctx: Services.DbContext, validateOnSave: false, autoDetectChanges: false, autoCommit: false)) { foreach (var item in mappings) { if (existingMappings.TryGetValue(item.Key, out var mapping)) { if (item.Value.HasValue) { mapping.Allow = item.Value.Value; Services.Permissions.UpdatePermissionRoleMapping(mapping); } else { Services.Permissions.DeletePermissionRoleMapping(mapping); } } else if (item.Value.HasValue) { Services.Permissions.InsertPermissionRoleMapping(new PermissionRoleMapping { Allow = item.Value.Value, PermissionRecordId = item.Key, CustomerRoleId = customerRole.Id }); } } scope.Commit(); } _customerActivityService.InsertActivity("EditCustomerRole", T("ActivityLog.EditCustomerRole"), customerRole.Name); NotifySuccess(T("Admin.Customers.CustomerRoles.Updated")); return(continueEditing ? RedirectToAction("Edit", customerRole.Id) : RedirectToAction("List")); } return(View(model)); } catch (Exception ex) { NotifyError(ex); return(RedirectToAction("Edit", new { id = customerRole.Id })); } }
public virtual void AnonymizeCustomer(Customer customer, bool pseudomyzeContent) { Guard.NotNull(customer, nameof(customer)); var language = customer.GetLanguage(); var customerName = customer.GetFullName() ?? customer.Username ?? customer.FindEmail(); using (var scope = new DbContextScope(_services.DbContext, autoCommit: false)) { // Set to deleted customer.Deleted = true; // Unassign roles customer.CustomerRoles.Clear(); customer.CustomerRoles.Add(_services.Resolve <ICustomerService>().GetCustomerRoleBySystemName(SystemCustomerRoleNames.Guests)); // Delete shopping cart & wishlist (TBD: (mc) Really?!?) _shoppingCartService.DeleteExpiredShoppingCartItems(DateTime.UtcNow, customer.Id); // Delete forum subscriptions var forumSubscriptions = _forumService.GetAllSubscriptions(customer.Id, 0, 0, 0, int.MaxValue); foreach (var forumSub in forumSubscriptions) { _forumService.DeleteSubscription(forumSub); } // Delete BackInStock subscriptions var backInStockSubscriptions = _backInStockSubscriptionService.GetAllSubscriptionsByCustomerId(customer.Id, 0, 0, int.MaxValue); foreach (var stockSub in backInStockSubscriptions) { _backInStockSubscriptionService.DeleteSubscription(stockSub); } // Generic attributes var attributes = _genericAttributeService.GetAttributesForEntity(customer.Id, "Customer"); foreach (var attr in attributes) { // we don't need to mask generic attrs, we just delete them. _genericAttributeService.DeleteAttribute(attr); } // Customer Data AnonymizeData(customer, x => x.Username, IdentifierDataType.UserName, language); AnonymizeData(customer, x => x.Email, IdentifierDataType.EmailAddress, language); AnonymizeData(customer, x => x.LastIpAddress, IdentifierDataType.IpAddress, language); if (pseudomyzeContent) { AnonymizeData(customer, x => x.AdminComment, IdentifierDataType.LongText, language); AnonymizeData(customer, x => x.LastLoginDateUtc, IdentifierDataType.DateTime, language); AnonymizeData(customer, x => x.LastActivityDateUtc, IdentifierDataType.DateTime, language); } // Addresses foreach (var address in customer.Addresses) { AnonymizeAddress(address, language); } // Private messages if (pseudomyzeContent) { var privateMessages = _forumService.GetAllPrivateMessages(0, customer.Id, 0, null, null, null, null, 0, int.MaxValue); foreach (var msg in privateMessages) { AnonymizeData(msg, x => x.Subject, IdentifierDataType.Text, language); AnonymizeData(msg, x => x.Text, IdentifierDataType.LongText, language); } } // Forum topics if (pseudomyzeContent) { foreach (var topic in customer.ForumTopics) { AnonymizeData(topic, x => x.Subject, IdentifierDataType.Text, language); } } // Forum posts foreach (var post in customer.ForumPosts) { AnonymizeData(post, x => x.IPAddress, IdentifierDataType.IpAddress, language); if (pseudomyzeContent) { AnonymizeData(post, x => x.Text, IdentifierDataType.LongText, language); } } // Customer Content foreach (var item in customer.CustomerContent) { AnonymizeData(item, x => x.IpAddress, IdentifierDataType.IpAddress, language); if (pseudomyzeContent) { switch (item) { case ProductReview c: AnonymizeData(c, x => x.ReviewText, IdentifierDataType.LongText, language); AnonymizeData(c, x => x.Title, IdentifierDataType.Text, language); break; case NewsComment c: AnonymizeData(c, x => x.CommentText, IdentifierDataType.LongText, language); AnonymizeData(c, x => x.CommentTitle, IdentifierDataType.Text, language); break; case BlogComment c: AnonymizeData(c, x => x.CommentText, IdentifierDataType.LongText, language); break; } } } //// Anonymize Order IPs //// TBD: Don't! Doesn't feel right because of fraud detection etc. //foreach (var order in customer.Orders) //{ // AnonymizeData(order, x => x.CustomerIp, IdentifierDataType.IpAddress, language); //} // SAVE!!! //_services.DbContext.DetachAll(); // TEST scope.Commit(); // Log Logger.Info(T("Gdpr.Anonymize.Success", language.Id, customerName)); } }
public static void CreateSystemMenus(IDbContext context) { var ctx = context as SmartObjectContext; if (ctx == null) { throw new ArgumentException("Passed context must be an instance of type '{0}'.".FormatInvariant(typeof(SmartObjectContext)), nameof(context)); } const string entityProvider = "entity"; const string routeProvider = "route"; const string routeTemplate = "{{\"routename\":\"{0}\"}}"; var resourceNames = new string[] { "Footer.Info", "Footer.Service", "Footer.Company", "Manufacturers.List", "Admin.Catalog.Categories", "Products.NewProducts", "Products.RecentlyViewedProducts", "Products.Compare.List", "ContactUs", "Blog", "Forum.Forums", "Account.Login", "Menu.ServiceMenu" }; var settingNames = new string[] { "CatalogSettings.RecentlyAddedProductsEnabled", "CatalogSettings.RecentlyViewedProductsEnabled", "CatalogSettings.CompareProductsEnabled", "BlogSettings.Enabled", "ForumSettings.ForumsEnabled", "CustomerSettings.UserRegistrationType" }; Dictionary<string, string> resources = null; Dictionary<string, string> settings = null; using (var scope = new DbContextScope(ctx: context, validateOnSave: false, hooksEnabled: false, autoCommit: false)) { var permissionMigrator = new PermissionMigrator(ctx); permissionMigrator.AddPermission(new PermissionRecord { Name = "Admin area. Manage Menus", SystemName = "ManageMenus", Category = "Content Management" }, new string[] { SystemCustomerRoleNames.Administrators }); var menuSet = context.Set<MenuRecord>(); var menuItemSet = context.Set<MenuItemRecord>(); var defaultLang = context.Set<Language>().OrderBy(x => x.DisplayOrder).First(); var manufacturerCount = context.Set<Manufacturer>().Count(); var order = 0; resources = context.Set<LocaleStringResource>().AsNoTracking() .Where(x => x.LanguageId == defaultLang.Id && resourceNames.Contains(x.ResourceName)) .Select(x => new { x.ResourceName, x.ResourceValue }) .ToList() .ToDictionarySafe(x => x.ResourceName, x => x.ResourceValue, StringComparer.OrdinalIgnoreCase); settings = context.Set<Setting>().AsNoTracking() .Where(x => x.StoreId == 0 && settingNames.Contains(x.Name)) .Select(x => new { x.Name, x.Value }) .ToList() .ToDictionarySafe(x => x.Name, x => x.Value, StringComparer.OrdinalIgnoreCase); #region System menus var mainMenu = menuSet.Add(new MenuRecord { SystemName = "Main", IsSystemMenu = true, Published = true, Template = "Navbar", Title = GetResource("Admin.Catalog.Categories") }); var footerInfo = menuSet.Add(new MenuRecord { SystemName = "FooterInformation", IsSystemMenu = true, Published = true, Template = "LinkList", Title = "Footer - " + GetResource("Footer.Info") }); var footerService = menuSet.Add(new MenuRecord { SystemName = "FooterService", IsSystemMenu = true, Published = true, Template = "LinkList", Title = "Footer - " + GetResource("Footer.Service") }); var footerCompany = menuSet.Add(new MenuRecord { SystemName = "FooterCompany", IsSystemMenu = true, Published = true, Template = "LinkList", Title = "Footer - " + GetResource("Footer.Company") }); var serviceMenu = menuSet.Add(new MenuRecord { SystemName = "HelpAndService", IsSystemMenu = true, Published = true, Template = "Dropdown", Title = GetResource("Menu.ServiceMenu").NullEmpty() ?? "Service" }); scope.Commit(); #endregion #region Main and footer menus menuItemSet.Add(new MenuItemRecord { MenuId = mainMenu.Id, ProviderName = "catalog", Published = true }); menuItemSet.Add(new MenuItemRecord { MenuId = footerInfo.Id, ProviderName = routeProvider, Model = routeTemplate.FormatInvariant("ManufacturerList"), Title = GetResource("Manufacturers.List"), DisplayOrder = ++order, Published = manufacturerCount > 0 }); menuItemSet.Add(new MenuItemRecord { MenuId = footerInfo.Id, ProviderName = routeProvider, Model = routeTemplate.FormatInvariant("RecentlyAddedProducts"), Title = GetResource("Products.NewProducts"), DisplayOrder = ++order, Published = GetSetting("CatalogSettings.RecentlyAddedProductsEnabled", true) }); menuItemSet.Add(new MenuItemRecord { MenuId = footerInfo.Id, ProviderName = routeProvider, Model = routeTemplate.FormatInvariant("RecentlyViewedProducts"), Title = GetResource("Products.RecentlyViewedProducts"), DisplayOrder = ++order, Published = GetSetting("CatalogSettings.RecentlyViewedProductsEnabled", true) }); menuItemSet.Add(new MenuItemRecord { MenuId = footerInfo.Id, ProviderName = routeProvider, Model = routeTemplate.FormatInvariant("CompareProducts"), Title = GetResource("Products.Compare.List"), DisplayOrder = ++order, Published = GetSetting("CatalogSettings.CompareProductsEnabled", true) }); scope.Commit(); order = 0; menuItemSet.Add(new MenuItemRecord { MenuId = footerService.Id, ProviderName = routeProvider, Model = routeTemplate.FormatInvariant("contactus"), Title = GetResource("ContactUs"), DisplayOrder = ++order }); menuItemSet.Add(new MenuItemRecord { MenuId = footerService.Id, ProviderName = routeProvider, Model = routeTemplate.FormatInvariant("Blog"), Title = GetResource("Blog"), DisplayOrder = ++order, Published = GetSetting("BlogSettings.Enabled", true) }); menuItemSet.Add(new MenuItemRecord { MenuId = footerService.Id, ProviderName = routeProvider, Model = routeTemplate.FormatInvariant("Boards"), Title = GetResource("Forum.Forums"), DisplayOrder = ++order, Published = GetSetting("ForumSettings.ForumsEnabled", true) }); menuItemSet.Add(new MenuItemRecord { MenuId = footerService.Id, ProviderName = entityProvider, Model = "topic:shippinginfo", DisplayOrder = ++order }); menuItemSet.Add(new MenuItemRecord { MenuId = footerService.Id, ProviderName = entityProvider, Model = "topic:paymentinfo", DisplayOrder = ++order }); scope.Commit(); order = 0; menuItemSet.Add(new MenuItemRecord { MenuId = footerCompany.Id, ProviderName = entityProvider, Model = "topic:aboutus", DisplayOrder = ++order }); menuItemSet.Add(new MenuItemRecord { MenuId = footerCompany.Id, ProviderName = entityProvider, Model = "topic:imprint", DisplayOrder = ++order }); menuItemSet.Add(new MenuItemRecord { MenuId = footerCompany.Id, ProviderName = entityProvider, Model = "topic:disclaimer", DisplayOrder = ++order }); menuItemSet.Add(new MenuItemRecord { MenuId = footerCompany.Id, ProviderName = entityProvider, Model = "topic:privacyinfo", DisplayOrder = ++order }); menuItemSet.Add(new MenuItemRecord { MenuId = footerCompany.Id, ProviderName = entityProvider, Model = "topic:conditionsofuse", DisplayOrder = ++order }); if (GetSetting("CustomerSettings.UserRegistrationType", "").IsCaseInsensitiveEqual("Disabled")) { menuItemSet.Add(new MenuItemRecord { MenuId = footerCompany.Id, ProviderName = routeProvider, Model = routeTemplate.FormatInvariant("Login"), Title = GetResource("Account.Login"), DisplayOrder = ++order }); } scope.Commit(); order = 0; #endregion #region Help & Service menuItemSet.Add(new MenuItemRecord { MenuId = serviceMenu.Id, ProviderName = routeProvider, Model = routeTemplate.FormatInvariant("RecentlyAddedProducts"), Title = GetResource("Products.NewProducts"), DisplayOrder = ++order, Published = GetSetting("CatalogSettings.RecentlyAddedProductsEnabled", true) }); menuItemSet.Add(new MenuItemRecord { MenuId = serviceMenu.Id, ProviderName = routeProvider, Model = routeTemplate.FormatInvariant("ManufacturerList"), Title = GetResource("Manufacturers.List"), DisplayOrder = ++order, Published = manufacturerCount > 0 }); menuItemSet.Add(new MenuItemRecord { MenuId = serviceMenu.Id, ProviderName = routeProvider, Model = routeTemplate.FormatInvariant("RecentlyViewedProducts"), Title = GetResource("Products.RecentlyViewedProducts"), DisplayOrder = ++order, Published = GetSetting("CatalogSettings.RecentlyViewedProductsEnabled", true) }); menuItemSet.Add(new MenuItemRecord { MenuId = serviceMenu.Id, ProviderName = routeProvider, Model = routeTemplate.FormatInvariant("CompareProducts"), Title = GetResource("Products.Compare.List"), DisplayOrder = ++order, Published = GetSetting("CatalogSettings.CompareProductsEnabled", true) }); menuItemSet.Add(new MenuItemRecord { MenuId = serviceMenu.Id, ProviderName = entityProvider, Model = "topic:aboutus", DisplayOrder = ++order, BeginGroup = true }); menuItemSet.Add(new MenuItemRecord { MenuId = serviceMenu.Id, ProviderName = entityProvider, Model = "topic:disclaimer", DisplayOrder = ++order }); menuItemSet.Add(new MenuItemRecord { MenuId = serviceMenu.Id, ProviderName = entityProvider, Model = "topic:shippinginfo", DisplayOrder = ++order }); menuItemSet.Add(new MenuItemRecord { MenuId = serviceMenu.Id, ProviderName = entityProvider, Model = "topic:conditionsofuse", DisplayOrder = ++order }); scope.Commit(); order = 0; #endregion #region Localization var resourceSet = context.Set<LocaleStringResource>(); var removeNames = new List<string> { "Menu.ServiceMenu" }; var removeResources = resourceSet.Where(x => removeNames.Contains(x.ResourceName)).ToList(); resourceSet.RemoveRange(removeResources); scope.Commit(); #endregion } #region Utilities string GetResource(string name) { return resources.TryGetValue(name, out var value) ? value : string.Empty; } T GetSetting<T>(string name, T defaultValue = default(T)) { try { if (settings.TryGetValue(name, out var str) && CommonHelper.TryConvert(str, out T value)) { return value; } } catch { } return defaultValue; } #endregion }
/// <summary> /// Moves several customer fields saved as generic attributes to customer entity (Title, FirstName, LastName, BirthDate, Company, CustomerNumber) /// </summary> /// <param name="context">Database context (must be <see cref="SmartObjectContext"/>)</param> /// <returns>The total count of fixed and updated customer entities</returns> public static int MoveCustomerFields(IDbContext context) { var ctx = context as SmartObjectContext; if (ctx == null) throw new ArgumentException("Passed context must be an instance of type '{0}'.".FormatInvariant(typeof(SmartObjectContext)), nameof(context)); // We delete attrs only if the WHOLE migration succeeded var attrIdsToDelete = new List<int>(1000); var gaTable = context.Set<GenericAttribute>(); var candidates = new[] { "Title", "FirstName", "LastName", "Company", "CustomerNumber", "DateOfBirth" }; var query = gaTable .AsNoTracking() .Where(x => x.KeyGroup == "Customer" && candidates.Contains(x.Key)) .OrderBy(x => x.Id); int numUpdated = 0; using (var scope = new DbContextScope(ctx: context, validateOnSave: false, hooksEnabled: false, autoCommit: false)) { for (var pageIndex = 0; pageIndex < 9999999; ++pageIndex) { var attrs = new PagedList<GenericAttribute>(query, pageIndex, 250); var customerIds = attrs.Select(a => a.EntityId).Distinct().ToArray(); var customers = context.Set<Customer>() .Where(x => customerIds.Contains(x.Id)) .ToDictionary(x => x.Id); // Move attrs one by one to customer foreach (var attr in attrs) { var customer = customers.Get(attr.EntityId); if (customer == null) continue; switch (attr.Key) { case "Title": customer.Title = attr.Value?.Truncate(100); break; case "FirstName": customer.FirstName = attr.Value?.Truncate(225); break; case "LastName": customer.LastName = attr.Value?.Truncate(225); break; case "Company": customer.Company = attr.Value?.Truncate(255); break; case "CustomerNumber": customer.CustomerNumber = attr.Value?.Truncate(100); break; case "DateOfBirth": customer.BirthDate = attr.Value?.Convert<DateTime?>(); break; } // Update FullName var parts = new[] { customer.Title, customer.FirstName, customer.LastName }; customer.FullName = string.Join(" ", parts.Where(x => x.HasValue())).NullEmpty(); attrIdsToDelete.Add(attr.Id); } // Save batch numUpdated += scope.Commit(); // Breathe context.DetachAll(); if (!attrs.HasNextPage) break; } // Everything worked out, now delete all orpahned attributes if (attrIdsToDelete.Count > 0) { try { // Don't rollback migration when this fails var stubs = attrIdsToDelete.Select(x => new GenericAttribute { Id = x }).ToList(); foreach (var chunk in stubs.Slice(500)) { chunk.Each(x => gaTable.Attach(x)); gaTable.RemoveRange(chunk); scope.Commit(); } } catch (Exception ex) { var msg = ex.Message; } } } return numUpdated; }
public void MigrateUploadedFiles(SmartObjectContext ctx) { var fileSet = ctx.Set <MediaFile>(); var folderSet = ctx.Set <MediaFolder>(); using (var scope = new DbContextScope(ctx, hooksEnabled: false, autoCommit: false, validateOnSave: false, lazyLoading: false, autoDetectChanges: false)) { var albumId = _albumRegistry.GetAlbumByName(SystemAlbumProvider.Files)?.Id; var rootFolder = _mediaFileSystem.GetFolder("Uploaded"); if (!rootFolder.Exists) { return; } ProcessFolder(rootFolder, albumId.Value); void ProcessFolder(IFolder folder, int mediaFolderId) { var newFiles = new List <FilePair>(); foreach (var uploadedFile in _mediaFileSystem.ListFiles(folder.Path)) { var file = new MediaFile { CreatedOnUtc = uploadedFile.LastUpdated, UpdatedOnUtc = uploadedFile.LastUpdated, Extension = uploadedFile.Extension.TrimStart('.'), Name = uploadedFile.Name, MimeType = MimeTypes.MapNameToMimeType(uploadedFile.Name), Size = Convert.ToInt32(uploadedFile.Size), FolderId = mediaFolderId, Version = 2 }; ProcessMediaFile(file); newFiles.Add(new FilePair { MediaFile = file, UploadedFile = uploadedFile }); fileSet.Add(file); } // Process/save files of current folder try { // Save files to DB int num = scope.Commit(); // Copy/Move files foreach (var newFile in newFiles) { if (_isFsProvider) { var newPath = GetStoragePath(newFile.MediaFile); if (!_mediaFileSystem.FileExists(newPath)) { // TODO: (mm) (mc) should we actually MOVE the file? _mediaFileSystem.CopyFile(newFile.UploadedFile.Path, newPath); } } else { _mediaStorageProvider.Save(newFile.MediaFile, MediaStorageItem.FromFile(newFile.UploadedFile)); } } if (!_isFsProvider) { // MediaFile.MediaStorageId has been updated, we need to save again. num = scope.Commit(); } } catch { throw; } finally { newFiles.Clear(); // Breathe ctx.DetachEntities <MediaFile>(deep: true); } foreach (var uploadedFolder in _mediaFileSystem.ListFolders(folder.Path)) { var mediaFolder = new MediaFolder { Name = uploadedFolder.Name, ParentId = mediaFolderId }; // Add folder and save ASAP, we need the folder id folderSet.Add(mediaFolder); ctx.SaveChanges(); ProcessFolder(uploadedFolder, mediaFolder.Id); } } } }
public virtual int DeleteHistoryEntries() { var count = 0; var idsToDelete = new HashSet <int>(); if (_commonSettings.Value.MaxScheduleHistoryAgeInDays > 0) { var earliestDate = DateTime.UtcNow.AddDays(-1 * _commonSettings.Value.MaxScheduleHistoryAgeInDays); var ids = _taskHistoryRepository.TableUntracked .Where(x => x.StartedOnUtc <= earliestDate && !x.IsRunning) .Select(x => x.Id) .ToList(); idsToDelete.AddRange(ids); } // We have to group by task otherwise we would only keep entries from very frequently executed tasks. if (_commonSettings.Value.MaxNumberOfScheduleHistoryEntries > 0) { var query = from th in _taskHistoryRepository.TableUntracked where !th.IsRunning group th by th.ScheduleTaskId into grp select grp .OrderByDescending(x => x.StartedOnUtc) .ThenByDescending(x => x.Id) .Skip(_commonSettings.Value.MaxNumberOfScheduleHistoryEntries) .Select(x => x.Id); var ids = query.SelectMany(x => x).ToList(); idsToDelete.AddRange(ids); } try { if (idsToDelete.Any()) { using (var scope = new DbContextScope(_taskHistoryRepository.Context, autoCommit: false)) { var pageIndex = 0; IPagedList <int> pagedIds = null; do { pagedIds = new PagedList <int>(idsToDelete, pageIndex++, 100); var entries = _taskHistoryRepository.Table .Where(x => pagedIds.Contains(x.Id)) .ToList(); entries.Each(x => DeleteHistoryEntry(x)); count += scope.Commit(); }while (pagedIds.HasNextPage); } } } catch (Exception ex) { Logger.Error(ex); } return(count); }
public virtual ProductSummaryModel MapProductSummaryModel(IPagedList <Product> products, ProductSummaryMappingSettings settings) { Guard.NotNull(products, nameof(products)); if (settings == null) { settings = new ProductSummaryMappingSettings(); } using (_services.Chronometer.Step("MapProductSummaryModel")) { var model = new ProductSummaryModel(products) { ViewMode = settings.ViewMode, GridColumnSpan = _catalogSettings.GridStyleListColumnSpan, ShowSku = _catalogSettings.ShowProductSku, ShowWeight = _catalogSettings.ShowWeight, ShowDimensions = settings.MapDimensions, ShowLegalInfo = settings.MapLegalInfo, ShowDescription = settings.MapShortDescription, ShowFullDescription = settings.MapFullDescription, ShowRatings = settings.MapReviews, ShowDeliveryTimes = settings.MapDeliveryTimes, ShowPrice = settings.MapPrices, ShowBasePrice = settings.MapPrices && _catalogSettings.ShowBasePriceInProductLists && settings.ViewMode != ProductSummaryViewMode.Mini, ShowShippingSurcharge = settings.MapPrices && settings.ViewMode != ProductSummaryViewMode.Mini, ShowButtons = settings.ViewMode != ProductSummaryViewMode.Mini, ShowBrand = settings.MapManufacturers, ForceRedirectionAfterAddingToCart = settings.ForceRedirectionAfterAddingToCart, CompareEnabled = _catalogSettings.CompareProductsEnabled, WishlistEnabled = _services.Permissions.Authorize(Permissions.Cart.AccessWishlist), BuyEnabled = !_catalogSettings.HideBuyButtonInLists, ThumbSize = settings.ThumbnailSize, ShowDiscountBadge = _catalogSettings.ShowDiscountSign, ShowNewBadge = _catalogSettings.LabelAsNewForMaxDays.HasValue }; if (products.Count == 0) { // No products, stop here. return(model); } // PERF!! var store = _services.StoreContext.CurrentStore; var customer = _services.WorkContext.CurrentCustomer; var currency = _services.WorkContext.WorkingCurrency; var language = _services.WorkContext.WorkingLanguage; var allowPrices = _services.Permissions.Authorize(Permissions.Catalog.DisplayPrice); var allowShoppingCart = _services.Permissions.Authorize(Permissions.Cart.AccessShoppingCart); var allowWishlist = _services.Permissions.Authorize(Permissions.Cart.AccessWishlist); var taxDisplayType = _services.WorkContext.GetTaxDisplayTypeFor(customer, store.Id); var cachedManufacturerModels = new Dictionary <int, ManufacturerOverviewModel>(); var prefetchTranslations = settings.PrefetchTranslations == true || (settings.PrefetchTranslations == null && _performanceSettings.AlwaysPrefetchTranslations); var prefetchSlugs = settings.PrefetchUrlSlugs == true || (settings.PrefetchUrlSlugs == null && _performanceSettings.AlwaysPrefetchUrlSlugs); var allProductIds = prefetchSlugs || prefetchTranslations?products.Select(x => x.Id).ToArray() : new int[0]; //var productIds = products.Select(x => x.Id).ToArray(); string taxInfo = T(taxDisplayType == TaxDisplayType.IncludingTax ? "Tax.InclVAT" : "Tax.ExclVAT"); var legalInfo = ""; var res = new Dictionary <string, LocalizedString>(StringComparer.OrdinalIgnoreCase) { { "Products.CallForPrice", T("Products.CallForPrice") }, { "Products.PriceRangeFrom", T("Products.PriceRangeFrom") }, { "Media.Product.ImageLinkTitleFormat", T("Media.Product.ImageLinkTitleFormat") }, { "Media.Product.ImageAlternateTextFormat", T("Media.Product.ImageAlternateTextFormat") }, { "Products.DimensionsValue", T("Products.DimensionsValue") }, { "Common.AdditionalShippingSurcharge", T("Common.AdditionalShippingSurcharge") } }; if (settings.MapLegalInfo) { var shippingInfoUrl = _urlHelper.Topic("shippinginfo").ToString(); legalInfo = shippingInfoUrl.HasValue() ? T("Tax.LegalInfoShort").Text.FormatInvariant(taxInfo, shippingInfoUrl) : T("Tax.LegalInfoShort2").Text.FormatInvariant(taxInfo); } if (prefetchSlugs) { _urlRecordService.PrefetchUrlRecords(nameof(Product), new[] { language.Id, 0 }, allProductIds); } if (prefetchTranslations) { // Prefetch all delivery time translations _localizedEntityService.PrefetchLocalizedProperties(nameof(DeliveryTime), language.Id, null); } using (var scope = new DbContextScope(ctx: _services.DbContext, autoCommit: false, validateOnSave: false)) { // Run in uncommitting scope, because pictures could be updated (IsNew property) var batchContext = _dataExporter.Value.CreateProductExportContext(products, customer, null, 1, false); if (settings.MapPrices) { batchContext.AppliedDiscounts.LoadAll(); batchContext.TierPrices.LoadAll(); } if (settings.MapAttributes || settings.MapColorAttributes) { batchContext.Attributes.LoadAll(); if (prefetchTranslations) { // Prefetch all product attribute translations PrefetchTranslations( nameof(ProductAttribute), language.Id, batchContext.Attributes.SelectMany(x => x.Value).Select(x => x.ProductAttribute)); // Prefetch all variant attribute value translations PrefetchTranslations( nameof(ProductVariantAttributeValue), language.Id, batchContext.Attributes.SelectMany(x => x.Value).SelectMany(x => x.ProductVariantAttributeValues)); } } if (settings.MapManufacturers) { batchContext.ProductManufacturers.LoadAll(); } if (settings.MapSpecificationAttributes) { batchContext.SpecificationAttributes.LoadAll(); if (prefetchTranslations) { // Prefetch all spec attribute option translations PrefetchTranslations( nameof(SpecificationAttributeOption), language.Id, batchContext.SpecificationAttributes.SelectMany(x => x.Value).Select(x => x.SpecificationAttributeOption)); // Prefetch all spec attribute translations PrefetchTranslations( nameof(SpecificationAttribute), language.Id, batchContext.SpecificationAttributes.SelectMany(x => x.Value).Select(x => x.SpecificationAttributeOption.SpecificationAttribute)); } } // If a size has been set in the view, we use it in priority int thumbSize = model.ThumbSize ?? _mediaSettings.ProductThumbPictureSize; var mapItemContext = new MapProductSummaryItemContext { BatchContext = batchContext, CachedManufacturerModels = cachedManufacturerModels, Currency = currency, LegalInfo = legalInfo, Model = model, Resources = res, Settings = settings, Customer = customer, Store = store, AllowPrices = allowPrices, AllowShoppingCart = allowShoppingCart, AllowWishlist = allowWishlist, TaxDisplayType = taxDisplayType }; if (settings.MapPictures) { var fileIds = products .Select(x => x.MainPictureId ?? 0) .Where(x => x != 0) .Distinct() .ToArray(); mapItemContext.MediaFiles = _mediaService.GetFilesByIds(fileIds).ToDictionarySafe(x => x.Id); } foreach (var product in products) { MapProductSummaryItem(product, mapItemContext); } _services.DisplayControl.AnnounceRange(products); scope.Commit(); batchContext.Clear(); // don't show stuff without data at all model.ShowDescription = model.ShowDescription && model.Items.Any(x => x.ShortDescription?.Value?.HasValue() == true); model.ShowBrand = model.ShowBrand && model.Items.Any(x => x.Manufacturer != null); return(model); } } }
public virtual void CreateAllProductVariantAttributeCombinations(Product product) { // Delete all existing combinations. _pvacRepository.DeleteAll(x => x.ProductId == product.Id); var attributes = GetProductVariantAttributesByProductId(product.Id); if (attributes == null || attributes.Count <= 0) { return; } var mappedAttributes = attributes .SelectMany(x => x.ProductVariantAttributeValues) .ToDictionarySafe(x => x.Id, x => x.ProductVariantAttribute); var toCombine = new List <List <ProductVariantAttributeValue> >(); var resultMatrix = new List <List <ProductVariantAttributeValue> >(); var tmp = new List <ProductVariantAttributeValue>(); foreach (var attr in attributes) { var attributeValues = attr.ProductVariantAttributeValues.ToList(); if (attributeValues.Count > 0) { toCombine.Add(attributeValues); } } if (toCombine.Count > 0) { CombineAll(toCombine, resultMatrix, 0, tmp); using (var scope = new DbContextScope(ctx: _pvacRepository.Context, autoCommit: false, autoDetectChanges: false, validateOnSave: false, hooksEnabled: false)) { ProductVariantAttributeCombination combination = null; var idx = 0; foreach (var values in resultMatrix) { idx++; var attributesXml = ""; foreach (var value in values) { attributesXml = mappedAttributes[value.Id].AddProductAttribute(attributesXml, value.Id.ToString()); } combination = new ProductVariantAttributeCombination { ProductId = product.Id, AttributesXml = attributesXml, StockQuantity = 10000, AllowOutOfStockOrders = true, IsActive = true }; _pvacRepository.Insert(combination); } scope.Commit(); } } //foreach (var y in resultMatrix) //{ // var sb = new System.Text.StringBuilder(); // foreach (var x in y) // { // sb.AppendFormat("{0} ", x.Name); // } // sb.ToString().Dump(); //} }