/// <summary>
 /// Reduce category details according to response group
 /// </summary>
 /// <param name="category"></param>
 /// <param name="respGroup"></param>
 protected virtual void ReduceDetails(Category category, CategoryResponseGroup responseGroup)
 {
     if (!responseGroup.HasFlag(CategoryResponseGroup.WithImages))
     {
         category.Images = null;
     }
     if (!responseGroup.HasFlag(CategoryResponseGroup.WithLinks))
     {
         category.Links = null;
     }
     if (!responseGroup.HasFlag(CategoryResponseGroup.WithParents))
     {
         category.Parents = null;
     }
     if (!responseGroup.HasFlag(CategoryResponseGroup.WithProperties))
     {
         category.Properties     = null;
         category.PropertyValues = null;
     }
     if (!responseGroup.HasFlag(CategoryResponseGroup.WithOutlines))
     {
         category.Outlines = null;
     }
     if (!responseGroup.HasFlag(CategoryResponseGroup.WithSeo))
     {
         category.SeoInfos = null;
     }
 }
Example #2
0
        public Category GetById(string categoryId, CategoryResponseGroup responseGroup, string catalogId = null)
        {
            var cacheKey = GetCacheKey("CategoryService.GetById", categoryId, responseGroup.ToString(), catalogId);
            var retVal   = _cacheManager.Get(cacheKey, RegionName, () => _categoryService.GetById(categoryId, responseGroup, catalogId));

            return(retVal);
        }
Example #3
0
        public Category[] GetByIds(string[] categoryIds, CategoryResponseGroup responseGroup, string catalogId = null)
        {
            var cacheKey = GetCacheKey("CategoryService.GetByIds", string.Join(", ", categoryIds), responseGroup.ToString(), catalogId);
            var retVal   = _cacheManager.Get(cacheKey, RegionName, () => _categoryService.GetByIds(categoryIds, responseGroup, catalogId));

            return(retVal);
        }
Example #4
0
        private static Category[] GetCategoriesByIds(string[] categoryIds, CategoryResponseGroup responseGroup)
        {
            var result = _categories
                         .Where(c => categoryIds.Contains(c.Id))
                         .Select(CloneCategory)
                         .ToArray();

            var withLinks   = (responseGroup & CategoryResponseGroup.WithLinks) == CategoryResponseGroup.WithLinks;
            var withParents = (responseGroup & CategoryResponseGroup.WithParents) == CategoryResponseGroup.WithParents;

            foreach (var category in result)
            {
                if (withLinks)
                {
                    category.OutgoingLinks = new ObservableCollection <CategoryRelation>(_categoryRelations.Where(r => r.SourceCategoryId == category.Id));
                }

                if (withParents)
                {
                    var parents = new List <Category>();

                    var currentCategory = category;
                    while (currentCategory != null && currentCategory.ParentCategoryId != null)
                    {
                        currentCategory = CloneCategory(_categories.FirstOrDefault(c => c.Id == currentCategory.ParentCategoryId));
                        parents.Insert(0, currentCategory);
                    }

                    category.AllParents = parents.ToArray();
                }
            }

            return(result);
        }
Example #5
0
        public async Task <Category[]> GetCategoriesAsync(string[] ids, CategoryResponseGroup responseGroup = CategoryResponseGroup.Info)
        {
            var workContext = _workContextFactory();

            var retVal = (await _catalogModuleApi.CatalogModuleCategoriesGetCategoriesByIdsAsync(ids.ToList(), ((int)responseGroup).ToString())).Select(x => x.ToWebModel(workContext.CurrentLanguage, workContext.CurrentStore)).ToArray();

            return(retVal);
        }
        public async Task<Category[]> GetCategoriesAsync(string[] ids, CategoryResponseGroup responseGroup = CategoryResponseGroup.Info)
        {
            var workContext = _workContextFactory();

            var retVal = (await _catalogModuleApi.CatalogModuleCategoriesGetCategoriesByIdsAsync(ids.ToList(), ((int)responseGroup).ToString())).Select(x => x.ToWebModel(workContext.CurrentLanguage, workContext.CurrentStore)).ToArray();

            return retVal;
        }
        public virtual async Task <Category[]> GetCategoriesAsync(string[] ids, CategoryResponseGroup responseGroup = CategoryResponseGroup.Info)
        {
            var workContext = _workContextFactory();

            var retVal = (await _catalogModuleApi.CatalogModuleCategories.GetCategoriesByIdsAsync(ids.ToList(), ((int)responseGroup).ToString())).Select(x => x.ToCategory(workContext.CurrentLanguage, workContext.CurrentStore)).ToArray();

            //Set  lazy loading for child categories
            SetChildCategoriesLazyLoading(retVal);
            return(retVal);
        }
Example #8
0
        public async Task <ActionResult <ListEntrySearchResult> > ListItemsSearchAsync([FromBody] CatalogListEntrySearchCriteria criteria)
        {
            var result           = new ListEntrySearchResult();
            var useIndexedSearch = _settingsManager.GetValue(ModuleConstants.Settings.Search.UseCatalogIndexedSearchInManager.Name, true);

            var authorizationResult = await _authorizationService.AuthorizeAsync(User, criteria, new CatalogAuthorizationRequirement(ModuleConstants.Security.Permissions.Read));

            if (!authorizationResult.Succeeded)
            {
                return(Unauthorized());
            }

            if (useIndexedSearch && !string.IsNullOrEmpty(criteria.Keyword))
            {
                // TODO: create outline for category
                // TODO: implement sorting

                var categoryIndexedSearchCriteria = AbstractTypeFactory <CategoryIndexedSearchCriteria> .TryCreateInstance().FromListEntryCriteria(criteria) as CategoryIndexedSearchCriteria;

                const CategoryResponseGroup catResponseGroup = CategoryResponseGroup.Info | CategoryResponseGroup.WithOutlines;
                categoryIndexedSearchCriteria.ResponseGroup = catResponseGroup.ToString();

                var catIndexedSearchResult = await _categoryIndexedSearchService.SearchAsync(categoryIndexedSearchCriteria);

                var totalCount = catIndexedSearchResult.TotalCount;
                var skip       = Math.Min(totalCount, criteria.Skip);
                var take       = Math.Min(criteria.Take, Math.Max(0, totalCount - criteria.Skip));

                result.Results = catIndexedSearchResult.Items.Select(x => AbstractTypeFactory <CategoryListEntry> .TryCreateInstance().FromModel(x)).ToList();

                criteria.Skip -= (int)skip;
                criteria.Take -= (int)take;

                const ItemResponseGroup itemResponseGroup = ItemResponseGroup.ItemInfo | ItemResponseGroup.Outlines;

                var productIndexedSearchCriteria = AbstractTypeFactory <ProductIndexedSearchCriteria> .TryCreateInstance().FromListEntryCriteria(criteria) as ProductIndexedSearchCriteria;

                productIndexedSearchCriteria.ResponseGroup = itemResponseGroup.ToString();

                var indexedSearchResult = await _productIndexedSearchService.SearchAsync(productIndexedSearchCriteria);

                result.TotalCount += (int)indexedSearchResult.TotalCount;
                result.Results.AddRange(indexedSearchResult.Items.Select(x => AbstractTypeFactory <ProductListEntry> .TryCreateInstance().FromModel(x)));
            }
            else
            {
                result = await _listEntrySearchService.SearchAsync(criteria);
            }
            return(Ok(result));
        }
Example #9
0
        public virtual async Task <Category[]> GetCategoriesAsync(string[] ids, CategoryResponseGroup responseGroup = CategoryResponseGroup.Info)
        {
            var workContext   = _workContextAccessor.WorkContext;
            var cacheKey      = CacheKey.With(GetType(), "GetCategoriesAsync", string.Join("-", ids.OrderBy(x => x)), responseGroup.ToString());
            var categoriesDto = await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                cacheEntry.AddExpirationToken(CatalogCacheRegion.CreateChangeToken());
                return(await _categoriesApi.GetCategoriesByPlentyIdsAsync(ids.ToList(), ((int)responseGroup).ToString()));
            });

            var result = categoriesDto.Select(x => x.ToCategory(workContext.CurrentLanguage, workContext.CurrentStore)).ToArray();

            //Set  lazy loading for child categories
            EstablishLazyDependenciesForCategories(result);
            return(result);
        }
        public Category[] GetByIds(string[] categoryIds, CategoryResponseGroup responseGroup, string catalogId = null)
        {
            var extCatalogs = GetExternalCatalogs();
            var retVal      = _categoryService.GetByIds(categoryIds, responseGroup, catalogId).ToList();

            foreach (var extCatalog in extCatalogs)
            {
                var apiUrl        = extCatalog.PropertyValues.FirstOrDefault(x => x.PropertyName.EqualsInvariant("apiUrl")).Value.ToString();
                var extCategories = _vcCatalogClientFactory(apiUrl).CatalogModuleCategories.GetCategoriesByIds(categoryIds.ToList(), responseGroup.ToString());
                foreach (var extCategory in extCategories)
                {
                    var category      = ConvertToCategory(extCategory);
                    var localCategory = retVal.FirstOrDefault(x => x.Id.EqualsInvariant(extCategory.Id));
                    if (localCategory != null)
                    {
                        retVal.Remove(localCategory);
                        category.Properties     = localCategory.Properties;
                        category.PropertyValues = localCategory.PropertyValues;
                        category.Links          = localCategory.Links;
                        if (category.Outlines.IsNullOrEmpty())
                        {
                            category.Outlines = localCategory.Outlines;
                        }
                        else if (!localCategory.Outlines.IsNullOrEmpty())
                        {
                            category.Outlines.AddRange(localCategory.Outlines);
                        }
                    }
                    retVal.Add(category);
                }
            }

            foreach (var category in retVal)
            {
                if (!category.PropertyValues.Any(x => x.PropertyName.EqualsInvariant("usergroups")))
                {
                    category.PropertyValues.Add(new PropertyValue
                    {
                        PropertyName = "usergroups",
                        Value        = "__NULL__",
                        ValueType    = PropertyValueType.ShortText
                    });
                }
            }
            return(retVal.ToArray());
        }
        public virtual Category[] GetByIds(string[] categoryIds, CategoryResponseGroup responseGroup, string catalogId = null)
        {
            var result = new List <Category>();
            var preloadedCategoriesMap = PreloadCategories(catalogId);

            foreach (var categoryId in categoryIds.Where(x => x != null))
            {
                Category category;
                if (preloadedCategoriesMap.TryGetValue(categoryId, out category))
                {
                    result.Add(MemberwiseCloneCategory(category));
                }
            }

            //Reduce details according to response group
            foreach (var category in result)
            {
                if (!responseGroup.HasFlag(CategoryResponseGroup.WithImages))
                {
                    category.Images = null;
                }
                if (!responseGroup.HasFlag(CategoryResponseGroup.WithLinks))
                {
                    category.Links = null;
                }
                if (!responseGroup.HasFlag(CategoryResponseGroup.WithParents))
                {
                    category.Parents = null;
                }
                if (!responseGroup.HasFlag(CategoryResponseGroup.WithProperties))
                {
                    category.Properties = null;
                }
                if (!responseGroup.HasFlag(CategoryResponseGroup.WithOutlines))
                {
                    category.Outlines = null;
                }
                if (!responseGroup.HasFlag(CategoryResponseGroup.WithSeo))
                {
                    category.SeoInfos = null;
                }
            }

            return(result.ToArray());
        }
        public virtual Category[] GetByIds(string[] categoryIds, CategoryResponseGroup responseGroup, string catalogId = null)
        {
            var result = new List <Category>();
            var preloadedCategoriesMap = PreloadCategories(catalogId);

            foreach (var categoryId in categoryIds.Where(x => x != null))
            {
                Category category;
                if (preloadedCategoriesMap.TryGetValue(categoryId, out category))
                {
                    result.Add(MemberwiseCloneCategory(category));
                }
            }

            //Reduce details according to response group
            foreach (var category in result)
            {
                category.ReduceDetails(responseGroup.ToString());
            }

            return(result.ToArray());
        }
 public virtual Category[] GetCategories(string[] ids, CategoryResponseGroup responseGroup = CategoryResponseGroup.Info)
 {
     return(GetCategoriesAsync(ids, responseGroup).GetAwaiter().GetResult());
 }
Example #14
0
        public virtual Category[] GetCategories(string[] ids, CategoryResponseGroup responseGroup = CategoryResponseGroup.Info)
        {
            var workContext = _workContextAccessor.WorkContext;

            return(GetCategoriesAsync(ids, responseGroup).GetAwaiter().GetResult());
        }
Example #15
0
        private static Category[] GetCategoriesByIds(string[] categoryIds, CategoryResponseGroup responseGroup)
        {
            var result = _categories
                .Where(c => categoryIds.Contains(c.Id))
                .Select(CloneCategory)
                .ToArray();

            var withLinks = (responseGroup & CategoryResponseGroup.WithLinks) == CategoryResponseGroup.WithLinks;
            var withParents = (responseGroup & CategoryResponseGroup.WithParents) == CategoryResponseGroup.WithParents;

            foreach (var category in result)
            {
                if (withLinks)
                {
                    category.OutgoingLinks = new ObservableCollection<CategoryRelation>(_categoryRelations.Where(r => r.SourceCategoryId == category.Id));
                }

                if (withParents)
                {
                    var parents = new List<Category>();

                    var currentCategory = category;
                    while (currentCategory != null && currentCategory.ParentCategoryId != null)
                    {
                        currentCategory = CloneCategory(_categories.FirstOrDefault(c => c.Id == currentCategory.ParentCategoryId));
                        parents.Insert(0, currentCategory);
                    }

                    category.AllParents = parents.ToArray();
                }
            }

            return result;
        }
        public async Task <ActionResult> GetCategoriesByIds(string[] categoryIds, CategoryResponseGroup respGroup = CategoryResponseGroup.Full)
        {
            var retVal = await _catalogService.GetCategoriesAsync(categoryIds, respGroup);

            return(Json(retVal));
        }
Example #17
0
 public async Task <ActionResult <Category[]> > GetCategoriesByIds(string[] categoryIds, CategoryResponseGroup respGroup = CategoryResponseGroup.Full)
 {
     return(await _catalogService.GetCategoriesAsync(categoryIds, respGroup));
 }
 public virtual Category GetById(string categoryId, CategoryResponseGroup responseGroup, string catalogId = null)
 {
     return(GetByIds(new[] { categoryId }, responseGroup, catalogId).FirstOrDefault());
 }
Example #19
0
        private async Task <Category[]> InnerGetCategoriesAsync(string[] ids, WorkContext workContext, CategoryResponseGroup responseGroup = CategoryResponseGroup.Info)
        {
            var cacheKey      = CacheKey.With(GetType(), "InnerGetCategoriesAsync", string.Join("-", ids.OrderBy(x => x)), responseGroup.ToString());
            var categoriesDto = await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                cacheEntry.AddExpirationToken(CatalogCacheRegion.CreateChangeToken());
                return(await _categoriesApi.GetCategoriesByPlentyIdsAsync(ids.ToList(), ((int)responseGroup).ToString()));
            });

            var result = categoriesDto.Select(x => x.ToCategory(workContext.CurrentLanguage, workContext.CurrentStore)).ToArray();

            //Set  lazy loading for child categories
            SetChildCategoriesLazyLoading(result);
            return(result);
        }
Example #20
0
        public virtual CategorySearchResult SearchCategories(string scope, ISearchCriteria criteria, CategoryResponseGroup responseGroup)
        {
            var response      = new CategorySearchResult();
            var searchResults = _searchProvider.Search <DocumentDictionary>(scope, criteria);

            if (searchResults?.Documents != null)
            {
                var categoryDtos = new ConcurrentBag <CatalogModule.Web.Model.Category>();
                var taskList     = new List <Task>();

                var documents = searchResults.Documents;
                if (_settingsManager.GetValue("VirtoCommerce.SearchApi.UseFullObjectIndexStoring", true))
                {
                    var fullIndexedDocuments = documents.Where(doc => doc.ContainsKey(IndexHelper.ObjectFieldName) && !string.IsNullOrEmpty(doc[IndexHelper.ObjectFieldName].ToString())).ToList();
                    documents = documents.Except(fullIndexedDocuments).ToList();

                    var deserializeProductsTask = Task.Factory.StartNew(() =>
                    {
                        Parallel.ForEach(fullIndexedDocuments, new ParallelOptions {
                            MaxDegreeOfParallelism = 5
                        }, doc =>
                        {
                            var category = doc.GetObjectFieldValue <CatalogModule.Web.Model.Category>();
                            categoryDtos.Add(category);
                        });
                    });
                    taskList.Add(deserializeProductsTask);
                }

                if (documents.Any())
                {
                    var loadProductsTask = Task.Factory.StartNew(() =>
                    {
                        string catalog = null;
                        var catalogItemSearchCriteria = criteria as CatalogItemSearchCriteria;
                        if (catalogItemSearchCriteria != null)
                        {
                            catalog = catalogItemSearchCriteria.Catalog;
                        }

                        var categoryIds = documents.Select(x => x.Id.ToString()).Distinct().ToArray();
                        if (categoryIds.Any())
                        {
                            // Now load items from repository
                            var categories = _categoryService.GetByIds(categoryIds, responseGroup, catalog);
                            Parallel.ForEach(categories, x =>
                            {
                                categoryDtos.Add(x.ToWebModel(_blobUrlResolver));
                            });
                        }
                    }
                                                                 );
                    taskList.Add(loadProductsTask);
                }

                Task.WaitAll(taskList.ToArray());

                //Preserver original sorting order
                var orderedIds = searchResults.Documents.Select(x => x.Id.ToString()).ToList();
                response.Categories = categoryDtos.OrderBy(i => orderedIds.IndexOf(i.Id)).ToArray();
            }


            if (searchResults != null)
            {
                response.TotalCount = searchResults.TotalCount;
            }

            return(response);
        }
Example #21
0
        public virtual CategorySearchResult SearchCategories(string scope, ISearchCriteria criteria, CategoryResponseGroup responseGroup)
        {
            var items            = new List <Category>();
            var itemsOrderedList = new List <string>();

            var foundItemCount = 0;
            var dbItemCount    = 0;
            var searchRetry    = 0;

            //var myCriteria = criteria.Clone();
            var myCriteria = criteria;

            ISearchResults <DocumentDictionary> searchResults = null;

            do
            {
                // Search using criteria, it will only return IDs of the items
                searchResults = _searchProvider.Search <DocumentDictionary>(scope, criteria);

                searchRetry++;

                if (searchResults == null || searchResults.Documents == null)
                {
                    continue;
                }

                //Get only new found itemIds
                var uniqueKeys = searchResults.Documents.Select(x => x.Id.ToString()).Except(itemsOrderedList).ToArray();
                foundItemCount = uniqueKeys.Length;

                if (!searchResults.Documents.Any())
                {
                    continue;
                }

                itemsOrderedList.AddRange(uniqueKeys);

                // if we can determine catalog, pass it to the service
                string catalog = null;
                if (criteria is CatalogItemSearchCriteria)
                {
                    catalog = (criteria as CatalogItemSearchCriteria).Catalog;
                }

                // Now load items from repository
                var currentItems = _categoryService.GetByIds(uniqueKeys.ToArray(), responseGroup, catalog);

                var orderedList = currentItems.OrderBy(i => itemsOrderedList.IndexOf(i.Id));
                items.AddRange(orderedList);
                dbItemCount = currentItems.Length;

                //If some items where removed and search is out of sync try getting extra items
                if (foundItemCount > dbItemCount)
                {
                    //Retrieve more items to fill missing gap
                    myCriteria.RecordsToRetrieve += (foundItemCount - dbItemCount);
                }
            }while (foundItemCount > dbItemCount && searchResults != null && searchResults.Documents.Any() && searchRetry <= 3 &&
                    (myCriteria.RecordsToRetrieve + myCriteria.StartingRecord) < searchResults.TotalCount);

            var response = new CategorySearchResult();

            if (items != null)
            {
                var categoryDtos = new ConcurrentBag <CatalogModule.Web.Model.Category>();
                Parallel.ForEach(items, (x) =>
                {
                    categoryDtos.Add(x.ToWebModel(_blobUrlResolver));
                });
                response.Categories = categoryDtos.OrderBy(i => itemsOrderedList.IndexOf(i.Id)).ToArray();
            }

            if (searchResults != null)
            {
                response.TotalCount = searchResults.TotalCount;
            }

            return(response);
        }
        public virtual Category[] GetCategories(string[] ids, CategoryResponseGroup responseGroup = CategoryResponseGroup.Info)
        {
            var workContext = _workContextFactory();

            return(Task.Factory.StartNew(() => InnerGetCategoriesAsync(ids, workContext, responseGroup), CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult());
        }
 public async Task<ActionResult> GetCategoriesByIds(string[] categoryIds, CategoryResponseGroup respGroup = CategoryResponseGroup.Full)
 {
     var retVal = await _catalogSearchService.GetCategoriesAsync(categoryIds, respGroup);
     return Json(retVal);
 }
        public async Task <CategoryEntity[]> GetCategoriesByIdsAsync(string[] categoriesIds, CategoryResponseGroup respGroup)
        {
            if (categoriesIds == null)
            {
                throw new ArgumentNullException(nameof(categoriesIds));
            }

            if (!categoriesIds.Any())
            {
                return(new CategoryEntity[] { });
            }

            if (respGroup.HasFlag(CategoryResponseGroup.WithOutlines))
            {
                respGroup |= CategoryResponseGroup.WithLinks | CategoryResponseGroup.WithParents;
            }

            var result = await Categories.Where(x => categoriesIds.Contains(x.Id)).ToArrayAsync();

            if (respGroup.HasFlag(CategoryResponseGroup.WithLinks))
            {
                var incommingLinksTask = CategoryLinks.Where(x => categoriesIds.Contains(x.TargetCategoryId)).ToArrayAsync();
                var outgoingLinksTask  = CategoryLinks.Where(x => categoriesIds.Contains(x.SourceCategoryId)).ToArrayAsync();
                await Task.WhenAll(incommingLinksTask, outgoingLinksTask);
            }

            if (respGroup.HasFlag(CategoryResponseGroup.WithImages))
            {
                var images = await Images.Where(x => categoriesIds.Contains(x.CategoryId)).ToArrayAsync();
            }

            //Load all properties meta information and information for inheritance
            if (respGroup.HasFlag(CategoryResponseGroup.WithProperties))
            {
                //Load category property values by separate query
                var propertyValues = await PropertyValues.Include(x => x.DictionaryItem.DictionaryItemValues).Where(x => categoriesIds.Contains(x.CategoryId)).ToArrayAsync();

                var categoryPropertiesIds = await Properties.Where(x => categoriesIds.Contains(x.CategoryId)).Select(x => x.Id).ToArrayAsync();

                var categoryProperties = await GetPropertiesByIdsAsync(categoryPropertiesIds);
            }

            return(result);
        }
        public virtual async Task <Category[]> GetCategoriesAsync(string[] ids, CategoryResponseGroup responseGroup = CategoryResponseGroup.Info)
        {
            var workContext = _workContextFactory();

            return(await InnerGetCategoriesAsync(ids, workContext, responseGroup));
        }
Example #26
0
        private CategorySearchResult SearchCategories(string scope, string storeId, CategorySearch criteria, CategoryResponseGroup responseGroup)
        {
            var store = _storeService.GetById(storeId);

            if (store == null)
            {
                return(null);
            }

            var serviceCriteria = criteria.AsCriteria <CategorySearchCriteria>(store.Catalog);

            var searchResults = _categoryBrowseService.SearchCategories(scope, serviceCriteria, responseGroup);

            return(searchResults);
        }