예제 #1
0
        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);
        }
예제 #2
0
        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();
                }
            }
        }
예제 #3
0
        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();
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
 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();
            }
        }
예제 #7
0
        /// <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();
            }
        }
예제 #8
0
        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);
                }
            }
        }
예제 #9
0
        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();
            }
        }
예제 #10
0
        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();
        }
예제 #12
0
        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();
			}
		}
예제 #14
0
        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();
            }
        }
예제 #15
0
        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);
                }
            }
        }
예제 #16
0
        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>();
                    }
                }
            }
        }
예제 #18
0
        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>();
            }
        }
예제 #19
0
        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);
                }
            }
        }
예제 #20
0
        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);
                }
            }
        }
예제 #21
0
        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);
            }
        }
예제 #22
0
        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 }));
            }
        }
예제 #24
0
        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));
            }
        }
예제 #25
0
        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
        }
예제 #26
0
		/// <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;
		}
예제 #27
0
        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);
                    }
                }
            }
        }
예제 #28
0
        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);
        }
예제 #29
0
        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();
            //}
        }