protected override void OnUpdating(Store entity, IHookedEntity entry) { if (entry.IsPropertyModified(nameof(entity.ContentDeliveryNetwork))) { _pictureService.ClearUrlCache(); } }
protected override void OnDeleted(ILocalizedEntity entity, IHookedEntity entry) { var entityType = entry.EntityType; var localizedEntities = _localizedEntityService.Value.GetLocalizedProperties(entry.Entity.Id, entityType.Name); _toDelete.AddRange(localizedEntities); }
protected override void OnUpdating(Order entity, IHookedEntity entry) { if (entry.State == Core.Data.EntityState.Modified) { var isShipped = IsStatusPropertyModifiedTo(entry, nameof(entity.ShippingStatusId), (int)ShippingStatus.Shipped); var isDelivered = IsStatusPropertyModifiedTo(entry, nameof(entity.ShippingStatusId), (int)ShippingStatus.Delivered); if (isShipped || isDelivered) { var settings = _services.Value.Settings.LoadSetting <PaymentSettings>(entity.StoreId); if (settings.CapturePaymentReason.HasValue) { if (isShipped && settings.CapturePaymentReason.Value == CapturePaymentReason.OrderShipped) { _toCapture.Add(entity); } else if (isDelivered && settings.CapturePaymentReason.Value == CapturePaymentReason.OrderDelivered) { _toCapture.Add(entity); } } } //if (IsStatusPropertyModifiedTo(entry, nameof(entity.OrderStatusId), (int)OrderStatus.Complete)) //{ // That's too late. The payment is already marked as paid and the capture process would never be executed. //} } }
private IEnumerable <IDbSaveHook> GetSaveHookInstancesFor(IHookedEntity entry, HookStage stage, bool importantOnly) { if (entry.EntityType == null) { return(Enumerable.Empty <IDbSaveHook>()); } IEnumerable <IDbSaveHook> hooks; // For request cache lookup var requestKey = new RequestHookKey(entry, stage, importantOnly); if (_hooksRequestCache.ContainsKey(requestKey)) { hooks = _hooksRequestCache[requestKey]; } else { hooks = _saveHooks // Reduce by data context types .Where(x => x.Metadata.DbContextType.IsAssignableFrom(entry.ContextType)) // Reduce by entity types which can be processed by this hook .Where(x => x.Metadata.HookedType.IsAssignableFrom(entry.EntityType)) // When importantOnly, only include hook types with [ImportantAttribute] .Where(x => !importantOnly || _importantSaveHookTypes.Contains(x.Metadata.ImplType)) // Exclude void hooks (hooks known to be useless for the current EntityType/State/Stage combination) .Where(x => !_voidHooks.Contains(new HookKey(x.Metadata.ImplType, entry, stage))) .Select(x => x.Value) .ToArray(); _hooksRequestCache.AddRange(requestKey, hooks); } return(hooks); }
public override void OnAfterSave(IHookedEntity entry) { if (entry.Entity is ThemeVariable) { var themeVar = entry.Entity as ThemeVariable; AddEvictableThemeScope(themeVar.Theme, themeVar.StoreId); } else if (entry.Entity is CustomerRole) { _cacheManager.RemoveByPattern(CUSTOMERROLES_TAX_DISPLAY_TYPES_PATTERN_KEY); } else if (entry.Entity is UrlRecord ur) { var entityName = ur.EntityName.ToLowerInvariant(); if (entityName == "topic") { _cacheManager.RemoveByPattern(TOPIC_SENAME_PATTERN_KEY); } } else if (entry.Entity is Setting && entry.InitialState == EntityState.Modified) { var setting = entry.Entity as Setting; if (setting.Name.IsCaseInsensitiveEqual(TypeHelper.NameOf <TaxSettings>(x => x.TaxDisplayType, true))) { _cacheManager.RemoveByPattern(CUSTOMERROLES_TAX_DISPLAY_TYPES_PATTERN_KEY); // depends on TaxSettings.TaxDisplayType } } else { throw new NotImplementedException(); } }
private void UpdateFullName(Customer entity, IHookedEntity entry) { var shouldUpdate = entity.IsTransientRecord(); if (!shouldUpdate) { shouldUpdate = entity.FullName.IsEmpty() && (entity.FirstName.HasValue() || entity.LastName.HasValue()); } if (!shouldUpdate) { var modProps = _ctx.Resolve <IDbContext>().GetModifiedProperties(entity); shouldUpdate = _candidateProps.Any(x => modProps.ContainsKey(x)); } if (shouldUpdate) { var parts = new[] { entity.Salutation, entity.Title, entity.FirstName, entity.LastName }; entity.FullName = string.Join(" ", parts.Where(x => x.HasValue())).NullEmpty(); } }
public override async Task <HookResult> OnAfterSaveAsync(IHookedEntity entry, CancellationToken cancelToken) { if (!_combinationsInvalidationTypes.Contains(entry.EntityType)) { return(HookResult.Void); } var entity = entry.Entity; var productId = 0; if (entity is Setting setting) { if (setting.Name.EqualsNoCase(TypeHelper.NameOf <PerformanceSettings>(x => x.MaxUnavailableAttributeCombinations, true))) { await _cache.RemoveByPatternAsync(ProductAttributeMaterializer.UNAVAILABLE_COMBINATIONS_PATTERN_KEY); } } else if (entity is Product) { productId = entity.Id; } else if (entity is ProductVariantAttributeCombination combination) { productId = combination.ProductId; } if (productId != 0) { await _cache.RemoveAsync(ProductAttributeMaterializer.UNAVAILABLE_COMBINATIONS_KEY.FormatInvariant(productId)); } return(HookResult.Ok); }
private bool IsPropertyModified(IHookedEntity entry, string propertyName) { var result = false; if (entry.State != EntityState.Detached) { var prop = entry.Entry.Property(propertyName); if (prop != null) { switch (entry.State) { case EntityState.Added: // OriginalValues cannot be used for entities in the Added state. result = prop.CurrentValue != null; break; case EntityState.Deleted: // CurrentValues cannot be used for entities in the Deleted state. result = prop.OriginalValue != null; break; default: result = (prop.CurrentValue != null && !prop.CurrentValue.Equals(prop.OriginalValue)) || (prop.OriginalValue != null && !prop.OriginalValue.Equals(prop.CurrentValue)); break; } } } return(result); }
public void OnBeforeSave(IHookedEntity entry) { if (entry.EntityType != typeof(Category)) { throw new NotSupportedException(); } }
public void OnAfterSave(IHookedEntity entry) { if (entry.EntityType != typeof(Product)) { throw new NotSupportedException(); } }
public override async Task <HookResult> OnBeforeSaveAsync(IHookedEntity entry, CancellationToken cancelToken) { if (entry.Entity is Customer customer) { if (customer.Deleted && customer.IsSystemAccount) { _hookErrorMessage = $"System customer account '{customer.SystemName}' cannot not be deleted."; } else if (entry.InitialState == EState.Added) { if (customer.Email.HasValue() && await _db.Customers.AsQueryable().AnyAsync(x => x.Email == customer.Email, cancelToken)) { _hookErrorMessage = T("Account.Register.Errors.EmailAlreadyExists"); } else if (customer.Username.HasValue() && _customerSettings.CustomerLoginType != CustomerLoginType.Email && await _db.Customers.AsQueryable().AnyAsync(x => x.Username == customer.Username, cancelToken)) { _hookErrorMessage = T("Account.Register.Errors.UsernameAlreadyExists"); } } if (_hookErrorMessage.HasValue()) { return(RevertChanges(entry)); } } return(HookResult.Ok); }
protected override void OnDeleted(ISlugSupported entity, IHookedEntity entry) { var entityType = entry.EntityType; var records = _urlRecordService.Value.GetUrlRecordsFor(entityType.Name, entry.Entity.Id); _toDelete.AddRange(records); }
public override async Task <HookResult> OnAfterSaveAsync(IHookedEntity entry, CancellationToken cancelToken) { var entity = entry.Entity as StoreMapping; await ClearCacheSegmentAsync(entity.EntityName, entity.EntityId); return(HookResult.Ok); }
protected override void OnUpdated(BaseEntity entity, IHookedEntity entry) { if (entry.EntityType != typeof(Language)) { throw new NotImplementedException(); } _cacheManager.Remove(STORE_LANGUAGE_MAP_KEY); }
protected override void OnInserted(BaseEntity entity, IHookedEntity entry) { if (entry.EntityType != typeof(Store) && entry.EntityType != typeof(Language)) { throw new NotSupportedException(); } _cacheManager.Remove(STORE_LANGUAGE_MAP_KEY); }
public Task <HookResult> OnBeforeSaveAsync(IHookedEntity entry, CancellationToken cancelToken) { if (entry.EntityType != typeof(Category)) { return(Task.FromResult(HookResult.Void)); } return(Task.FromResult(HookResult.Ok)); }
public override void OnAfterSave(IHookedEntity entry) { var setting = entry.Entity as Setting; if (_mapInvalidatorSettingKeys.Contains(setting.Name)) { _cache.Remove(MapCacheKey); } }
public Task <HookResult> OnAfterSaveAsync(IHookedEntity entry, CancellationToken cancelToken) { if (entry.EntityType != typeof(Product)) { return(Task.FromResult(HookResult.Void)); } return(Task.FromResult(HookResult.Ok)); }
protected override void OnDeleted(IStoreMappingSupported entity, IHookedEntity entry) { var entityType = entry.EntityType; var records = _storeMappingService.Value .GetStoreMappingsFor(entityType.Name, entry.Entity.Id) .ToList(); _toDelete.AddRange(records); }
private IEnumerable <IDbSaveHook> GetSaveHookInstancesFor(IHookedEntity entry, HookStage stage, bool importantOnly) { return(GetHookInstancesFor <IDbSaveHook>( entry.EntityType, entry.InitialState, stage, importantOnly, _saveHooks, _importantSaveHookTypes)); }
protected override Task <HookResult> OnUpdatingAsync(MenuItemEntity entity, IHookedEntity entry, CancellationToken cancelToken) { // Prevent inconsistent tree structure. if (entity.ParentItemId != 0 && entity.ParentItemId == entity.Id) { entity.ParentItemId = 0; } return(Task.FromResult(HookResult.Ok)); }
public override async Task <HookResult> OnAfterSaveAsync(IHookedEntity entry, CancellationToken cancelToken) { if (entry.EntityType != typeof(Store) && entry.EntityType != typeof(Language)) { return(HookResult.Void); } await _cache.RemoveAsync(STORE_LANGUAGE_MAP_KEY); return(HookResult.Ok); }
private bool IsHookableEntry(IHookedEntity entry) { var entity = entry.Entity; if (entity == null) { return(false); } return(IsHookableEntityType(entry.EntityType)); }
protected override void OnDeleting(BaseEntity entity, IHookedEntity entry) { var type = entry.EntityType; if (!_candidateTypes.Contains(type)) { throw new NotSupportedException(); } if (type == typeof(ProductAttributeOption)) { var pictureId = ((ProductAttributeOption)entry.Entity).PictureId; if (pictureId != 0) { _toDelete.Add(pictureId); } } else if (type == typeof(ProductAttributeOptionsSet)) { var options = _productAttributeService.Value.GetProductAttributeOptionsByOptionsSetId(entity.Id); _toDelete.AddRange(options.Where(x => x.PictureId != 0).Select(x => x.PictureId)); } else if (type == typeof(ProductAttribute)) { var options = _productAttributeService.Value.GetProductAttributeOptionsByAttributeId(entity.Id); _toDelete.AddRange(options.Where(x => x.PictureId != 0).Select(x => x.PictureId)); } else if (type == typeof(ProductVariantAttribute)) { var options = _productAttributeService.Value.GetProductVariantAttributeValues(entity.Id); _toDelete.AddRange(options.Where(x => x.PictureId != 0).Select(x => x.PictureId)); } else if (type == typeof(ProductVariantAttributeValue)) { var pictureId = ((ProductVariantAttributeValue)entry.Entity).PictureId; if (pictureId != 0) { _toDelete.Add(pictureId); } } else if (type == typeof(SpecificationAttribute)) { var options = _specificationAttributeService.Value.GetSpecificationAttributeOptionsBySpecificationAttribute(entity.Id); _toDelete.AddRange(options.Where(x => x.PictureId != 0).Select(x => x.PictureId)); } else if (type == typeof(SpecificationAttributeOption)) { var pictureId = ((SpecificationAttributeOption)entry.Entity).PictureId; if (pictureId != 0) { _toDelete.Add(pictureId); } } }
public override void OnAfterSave(IHookedEntity entry) { if (entry.Entity is Store || entry.Entity is Currency) { _cache.Remove(CacheKey); } else { throw new NotSupportedException(); } }
protected override void OnDeleting(BaseEntity entity, IHookedEntity entry) { var type = entry.EntityType; if (!_candidateTypes.Contains(type)) { throw new NotSupportedException(); } if (type == typeof(SpecificationAttribute)) { var attribute = (SpecificationAttribute)entry.Entity; var attributeOptions = attribute.SpecificationAttributeOptions.ToList(); if (!attributeOptions.Any()) { attributeOptions = _specificationAttributeService.Value.GetSpecificationAttributeOptionsBySpecificationAttribute(attribute.Id).ToList(); } attributeOptions.ForEach(x => _toDelete.AddRange(_localizedEntityService.Value.GetLocalizedProperties(x.Id, "SpecificationAttributeOption"))); } else if (type == typeof(ProductVariantAttribute)) { var attribute = (ProductVariantAttribute)entry.Entity; var attributeOptions = attribute.ProductVariantAttributeValues.ToList(); if (!attributeOptions.Any()) { attributeOptions = _productAttributeService.Value.GetProductVariantAttributeValues(attribute.Id).ToList(); } attributeOptions.ForEach(x => _toDelete.AddRange(_localizedEntityService.Value.GetLocalizedProperties(x.Id, "ProductVariantAttributeValue"))); } else if (type == typeof(ProductAttribute)) { var optionIds = ( from a in _productAttributeRepository.Value.TableUntracked from os in a.ProductAttributeOptionsSets from ao in os.ProductAttributeOptions where a.Id == entry.Entity.Id select ao.Id).ToList(); optionIds.ForEach(x => _toDelete.AddRange(_localizedEntityService.Value.GetLocalizedProperties(x, "ProductAttributeOption"))); } else if (type == typeof(ProductAttributeOptionsSet)) { var set = (ProductAttributeOptionsSet)entry.Entity; var attributeOptions = set.ProductAttributeOptions.ToList(); if (!attributeOptions.Any()) { attributeOptions = _productAttributeService.Value.GetProductAttributeOptionsByOptionsSetId(set.Id).ToList(); } attributeOptions.ForEach(x => _toDelete.AddRange(_localizedEntityService.Value.GetLocalizedProperties(x.Id, "ProductAttributeOption"))); } }
protected override async Task <HookResult> OnDeletedAsync(Shipment entity, IHookedEntity entry, CancellationToken cancelToken) { var order = await _db.Orders.FindByIdAsync(entity.OrderId, cancellationToken : cancelToken); if (order != null) { await _eventPublisher.PublishOrderUpdatedAsync(order); } return(HookResult.Ok); }
public override HookResult OnAfterSave(IHookedEntity entry) { if (entry.Entity is Store || entry.Entity is Currency) { _cache.Remove(CacheKey); return(HookResult.Ok); } else { return(HookResult.Void); } }
public override void OnBeforeSave(IHookedEntity entry) { var cache = _services.Cache; var e = entry.Entity; var evict = e is Topic || e is Product || e is Category || e is Manufacturer || e is StoreMapping || e is UrlRecord; if (!evict) { throw new NotSupportedException(); // Perf } if (evict && entry.InitialState == EntityState.Modified) { var modProps = entry.Entry.GetModifiedProperties(_services.DbContext); evict = modProps.Keys.Any(x => _toxicProps.Contains(x)); } if (!evict) { return; } int?evictTopicId = null; if (e is Topic t) { cache.RemoveByPattern(BuildPatternKey("topic", t.Id)); cache.RemoveByPattern(BuildPatternKey("topic", t.SystemName)); } else if (e is Category || e is Product || e is Manufacturer) { cache.RemoveByPattern(BuildPatternKey(e.GetEntityName().ToLowerInvariant(), e.Id)); } else if (e is UrlRecord ur) { cache.RemoveByPattern(BuildPatternKey(ur.EntityName.ToLowerInvariant(), ur.EntityId)); evictTopicId = ur.EntityId; } else if (e is StoreMapping sm) { cache.RemoveByPattern(BuildPatternKey(sm.EntityName.ToLowerInvariant(), sm.EntityId)); evictTopicId = sm.EntityId; } if (evictTopicId.HasValue) { var systemName = _services.DbContext.Set <Topic>().Where(x => x.Id == evictTopicId.Value).Select(x => x.SystemName).FirstOrDefault(); if (systemName.HasValue()) { cache.RemoveByPattern(BuildPatternKey("topic", systemName)); } } }
protected override Task <HookResult> OnUpdatingAsync(ExportProfile entity, IHookedEntity entry, CancellationToken cancelToken) { entity.FolderName = PathHelper.NormalizeRelativePath(entity.FolderName); // TODO: (mg) (core) complete hook in ExportProfileService (PathHelper.IsSafeAppRootPath required). //if (!PathHelper.IsSafeAppRootPath(entity.FolderName)) //{ // throw new SmartException(T("Admin.DataExchange.Export.FolderName.Validate")); //} return(Task.FromResult(HookResult.Ok)); }