Webiant Logo Webiant Logo
  1. No results found.

    Try your search with a different keyword or use * as a wildcard.

GenericAttributeService.cs

using Nop.Core;
using Nop.Core.Caching;
using Nop.Core.Domain.Common;
using Nop.Data;

namespace Nop.Services.Common;

/// 
/// Generic attribute service
/// 
public partial class GenericAttributeService : IGenericAttributeService
{
    #region Fields

    protected readonly IRepository _genericAttributeRepository;
    protected readonly IShortTermCacheManager _shortTermCacheManager;
    protected readonly IStaticCacheManager _staticCacheManager;

    #endregion

    #region Ctor

    public GenericAttributeService(IRepository genericAttributeRepository,
        IShortTermCacheManager shortTermCacheManager,
        IStaticCacheManager staticCacheManager)
    {
        _genericAttributeRepository = genericAttributeRepository;
        _shortTermCacheManager = shortTermCacheManager;
        _staticCacheManager = staticCacheManager;
    }

    #endregion

    #region Methods

    /// 
    /// Deletes an attribute
    /// 
    /// Attribute
    /// A task that represents the asynchronous operation
    public virtual async Task DeleteAttributeAsync(GenericAttribute attribute)
    {
        await _genericAttributeRepository.DeleteAsync(attribute);
    }

    /// 
    /// Deletes an attributes
    /// 
    /// Attributes
    /// A task that represents the asynchronous operation
    public virtual async Task DeleteAttributesAsync(IList attributes)
    {
        await _genericAttributeRepository.DeleteAsync(attributes);
    }

    /// 
    /// Inserts an attribute
    /// 
    /// attribute
    /// A task that represents the asynchronous operation
    public virtual async Task InsertAttributeAsync(GenericAttribute attribute)
    {
        ArgumentNullException.ThrowIfNull(attribute);

        attribute.CreatedOrUpdatedDateUTC = DateTime.UtcNow;

        await _genericAttributeRepository.InsertAsync(attribute);
    }

    /// 
    /// Updates the attribute
    /// 
    /// Attribute
    /// A task that represents the asynchronous operation
    public virtual async Task UpdateAttributeAsync(GenericAttribute attribute)
    {
        ArgumentNullException.ThrowIfNull(attribute);

        attribute.CreatedOrUpdatedDateUTC = DateTime.UtcNow;

        await _genericAttributeRepository.UpdateAsync(attribute);
    }

    /// 
    /// Get attributes
    /// 
    /// Entity identifier
    /// Key group
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the get attributes
    /// 
    public virtual async Task> GetAttributesForEntityAsync(int entityId, string keyGroup)
    {
        var query = from ga in _genericAttributeRepository.Table
            where ga.EntityId == entityId &&
                  ga.KeyGroup == keyGroup
            select ga;
        var attributes = await _shortTermCacheManager.GetAsync(async () => await query.ToListAsync(), NopCommonDefaults.GenericAttributeCacheKey, entityId, keyGroup);

        return attributes;
    }

    /// 
    /// Save attribute value
    /// 
    /// Property type
    /// Entity
    /// Key
    /// Value
    /// Store identifier; pass 0 if this attribute will be available for all stores
    /// A task that represents the asynchronous operation
    public virtual async Task SaveAttributeAsync(BaseEntity entity, string key, TPropType value, int storeId = 0)
    {
        ArgumentNullException.ThrowIfNull(entity);

        ArgumentNullException.ThrowIfNull(key);

        var keyGroup = entity.GetType().Name;

        var props = (await GetAttributesForEntityAsync(entity.Id, keyGroup))
            .Where(x => x.StoreId == storeId)
            .ToList();
        var prop = props.FirstOrDefault(ga =>
            ga.Key.Equals(key, StringComparison.InvariantCultureIgnoreCase)); //should be culture invariant

        var valueStr = CommonHelper.To(value);

        if (prop != null)
        {
            if (string.IsNullOrWhiteSpace(valueStr))
                //delete
                await DeleteAttributeAsync(prop);
            else
            {
                //update
                prop.Value = valueStr;
                await UpdateAttributeAsync(prop);
            }
        }
        else
        {
            if (string.IsNullOrWhiteSpace(valueStr))
                return;

            //insert
            prop = new GenericAttribute
            {
                EntityId = entity.Id,
                Key = key,
                KeyGroup = keyGroup,
                Value = valueStr,
                StoreId = storeId
            };

            await InsertAttributeAsync(prop);
        }
    }

    /// 
    /// Get an attribute of an entity
    /// 
    /// Property type
    /// Entity
    /// Key
    /// Load a value specific for a certain store; pass 0 to load a value shared for all stores
    /// Default value
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the attribute
    /// 
    public virtual async Task GetAttributeAsync(BaseEntity entity, string key, int storeId = 0, TPropType defaultValue = default)
    {
        ArgumentNullException.ThrowIfNull(entity);

        var keyGroup = entity.GetType().Name;

        var props = await GetAttributesForEntityAsync(entity.Id, keyGroup);

        //little hack here (only for unit testing). we should write expect-return rules in unit tests for such cases
        if (props == null)
            return defaultValue;

        props = props.Where(x => x.StoreId == storeId).ToList();
        if (!props.Any())
            return defaultValue;

        var prop = props.FirstOrDefault(ga =>
            ga.Key.Equals(key, StringComparison.InvariantCultureIgnoreCase)); //should be culture invariant

        if (prop == null || string.IsNullOrEmpty(prop.Value))
            return defaultValue;

        return CommonHelper.To(prop.Value);
    }

    /// 
    /// Get an attribute of an entity
    /// 
    /// Property type
    /// Entity type
    /// Entity identifier
    /// Key
    /// Load a value specific for a certain store; pass 0 to load a value shared for all stores
    /// Default value
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the attribute
    /// 
    public virtual async Task GetAttributeAsync(int entityId, string key, int storeId = 0, TPropType defaultValue = default)
        where TEntity : BaseEntity
    {
        var entity = (TEntity)Activator.CreateInstance(typeof(TEntity));
        entity.Id = entityId;

        return await GetAttributeAsync(entity, key, storeId, defaultValue);
    }

    #endregion
}