Webiant Logo Webiant Logo
  1. No results found.

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

StoreMappingService.cs

using Nop.Core;
using Nop.Core.Caching;
using Nop.Core.Domain.Catalog;
using Nop.Core.Domain.Stores;
using Nop.Data;

namespace Nop.Services.Stores;

/// 
/// Store mapping service
/// 
public partial class StoreMappingService : IStoreMappingService
{
    #region Fields

    protected readonly CatalogSettings _catalogSettings;
    protected readonly IRepository _storeMappingRepository;
    protected readonly IStaticCacheManager _staticCacheManager;
    protected readonly IStoreContext _storeContext;

    #endregion

    #region Ctor

    public StoreMappingService(CatalogSettings catalogSettings,
        IRepository storeMappingRepository,
        IStaticCacheManager staticCacheManager,
        IStoreContext storeContext)
    {
        _catalogSettings = catalogSettings;
        _storeMappingRepository = storeMappingRepository;
        _staticCacheManager = staticCacheManager;
        _storeContext = storeContext;
    }

    #endregion

    #region Utilities

    /// 
    /// Inserts a store mapping record
    /// 
    /// Store mapping
    /// A task that represents the asynchronous operation
    protected virtual async Task InsertStoreMappingAsync(StoreMapping storeMapping)
    {
        await _storeMappingRepository.InsertAsync(storeMapping);
    }

    /// 
    /// Get a value indicating whether a store mapping exists for an entity type
    /// 
    /// Type of entity that supports store mapping
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains true if exists; otherwise false
    /// 
    protected virtual async Task IsEntityMappingExistsAsync() where TEntity : BaseEntity, IStoreMappingSupported
    {
        var entityName = typeof(TEntity).Name;
        var key = _staticCacheManager.PrepareKeyForDefaultCache(NopStoreDefaults.StoreMappingExistsCacheKey, entityName);

        var query = from sm in _storeMappingRepository.Table
            where sm.EntityName == entityName
            select sm.StoreId;

        return await _staticCacheManager.GetAsync(key, query.Any);
    }

    #endregion

    #region Methods

    /// 
    /// Apply store mapping to the passed query
    /// 
    /// Type of entity that supports store mapping
    /// Query to filter
    /// Store identifier
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the filtered query
    /// 
    public virtual async Task> ApplyStoreMapping(IQueryable query, int storeId)
        where TEntity : BaseEntity, IStoreMappingSupported
    {
        ArgumentNullException.ThrowIfNull(query);

        if (storeId == 0 || _catalogSettings.IgnoreStoreLimitations || !await IsEntityMappingExistsAsync())
            return query;

        return from entity in query
            where !entity.LimitedToStores || _storeMappingRepository.Table.Any(sm =>
                sm.EntityName == typeof(TEntity).Name && sm.EntityId == entity.Id && sm.StoreId == storeId)
            select entity;
    }

    /// 
    /// Deletes a store mapping record
    /// 
    /// Store mapping record
    /// A task that represents the asynchronous operation
    public virtual async Task DeleteStoreMappingAsync(StoreMapping storeMapping)
    {
        await _storeMappingRepository.DeleteAsync(storeMapping);
    }

    /// 
    /// Gets store mapping records
    /// 
    /// Type of entity that supports store mapping
    /// Entity
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the store mapping records
    /// 
    public virtual async Task> GetStoreMappingsAsync(TEntity entity) where TEntity : BaseEntity, IStoreMappingSupported
    {
        ArgumentNullException.ThrowIfNull(entity);

        var entityId = entity.Id;
        var entityName = entity.GetType().Name;

        var key = _staticCacheManager.PrepareKeyForDefaultCache(NopStoreDefaults.StoreMappingsCacheKey, entityId, entityName);

        var query = from sm in _storeMappingRepository.Table
            where sm.EntityId == entityId &&
                  sm.EntityName == entityName
            select sm;

        var storeMappings = await _staticCacheManager.GetAsync(key, async () => await query.ToListAsync());

        return storeMappings;
    }

    /// 
    /// Inserts a store mapping record
    /// 
    /// Type of entity that supports store mapping
    /// Entity
    /// Store id
    /// A task that represents the asynchronous operation
    public virtual async Task InsertStoreMappingAsync(TEntity entity, int storeId) where TEntity : BaseEntity, IStoreMappingSupported
    {
        ArgumentNullException.ThrowIfNull(entity);

        if (storeId == 0)
            throw new ArgumentOutOfRangeException(nameof(storeId));

        var entityId = entity.Id;
        var entityName = entity.GetType().Name;

        var storeMapping = new StoreMapping
        {
            EntityId = entityId,
            EntityName = entityName,
            StoreId = storeId
        };

        await InsertStoreMappingAsync(storeMapping);
    }

    /// 
    /// Find store identifiers with granted access (mapped to the entity)
    /// 
    /// Type of entity that supports store mapping
    /// Entity
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the store identifiers
    /// 
    public virtual async Task GetStoresIdsWithAccessAsync(TEntity entity) where TEntity : BaseEntity, IStoreMappingSupported
    {
        ArgumentNullException.ThrowIfNull(entity);

        var entityId = entity.Id;
        var entityName = entity.GetType().Name;

        var key = _staticCacheManager.PrepareKeyForDefaultCache(NopStoreDefaults.StoreMappingIdsCacheKey, entityId, entityName);

        var query = from sm in _storeMappingRepository.Table
            where sm.EntityId == entityId &&
                  sm.EntityName == entityName
            select sm.StoreId;

        return await _staticCacheManager.GetAsync(key, () => query.ToArray());
    }

    /// 
    /// Find store identifiers with granted access (mapped to the entity)
    /// 
    /// Type of entity that supports store mapping
    /// Entity
    /// 
    /// The store identifiers
    /// 
    public virtual int[] GetStoresIdsWithAccess(TEntity entity) where TEntity : BaseEntity, IStoreMappingSupported
    {
        ArgumentNullException.ThrowIfNull(entity);

        var entityId = entity.Id;
        var entityName = entity.GetType().Name;

        var key = _staticCacheManager.PrepareKeyForDefaultCache(NopStoreDefaults.StoreMappingIdsCacheKey, entityId, entityName);

        var query = from sm in _storeMappingRepository.Table
            where sm.EntityId == entityId &&
                  sm.EntityName == entityName
            select sm.StoreId;

        return _staticCacheManager.Get(key, () => query.ToArray());
    }

    /// 
    /// Authorize whether entity could be accessed in the current store (mapped to this store)
    /// 
    /// Type of entity that supports store mapping
    /// Entity
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains true - authorized; otherwise, false
    /// 
    public virtual async Task AuthorizeAsync(TEntity entity) where TEntity : BaseEntity, IStoreMappingSupported
    {
        var store = await _storeContext.GetCurrentStoreAsync();

        return await AuthorizeAsync(entity, store.Id);
    }

    /// 
    /// Authorize whether entity could be accessed in a store (mapped to this store)
    /// 
    /// Type of entity that supports store mapping
    /// Entity
    /// Store identifier
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains true - authorized; otherwise, false
    /// 
    public virtual async Task AuthorizeAsync(TEntity entity, int storeId) where TEntity : BaseEntity, IStoreMappingSupported
    {
        if (entity == null)
            return false;

        if (storeId == 0)
            //return true if no store specified/found
            return true;

        if (_catalogSettings.IgnoreStoreLimitations)
            return true;

        if (!entity.LimitedToStores)
            return true;

        foreach (var storeIdWithAccess in await GetStoresIdsWithAccessAsync(entity))
            if (storeId == storeIdWithAccess)
                //yes, we have such permission
                return true;

        //no permission found
        return false;
    }

    /// 
    /// Authorize whether entity could be accessed in a store (mapped to this store)
    /// 
    /// Type of entity that supports store mapping
    /// Entity
    /// Store identifier
    /// 
    /// True - authorized; otherwise, false
    /// 
    public virtual bool Authorize(TEntity entity, int storeId) where TEntity : BaseEntity, IStoreMappingSupported
    {
        if (entity == null)
            return false;

        if (storeId == 0)
            //return true if no store specified/found
            return true;

        if (_catalogSettings.IgnoreStoreLimitations)
            return true;

        if (!entity.LimitedToStores)
            return true;

        foreach (var storeIdWithAccess in GetStoresIdsWithAccess(entity))
            if (storeId == storeIdWithAccess)
                //yes, we have such permission
                return true;

        //no permission found
        return false;
    }

    #endregion
}