protected virtual void ConvertAvailability(CatalogSearchQuery query, RouteData routeData, string origin)
        {
            bool availability;

            GetValueFor(query, "a", FacetGroupKind.Availability, out availability);

            // Setting specifies the logical direction of the filter. That's smarter than just to specify a default value.
            if (_searchSettings.IncludeNotAvailable)
            {
                // False = show, True = hide unavailable products.
                if (availability)
                {
                    query.AvailableOnly(true);
                }
            }
            else
            {
                // False = hide, True = show unavailable products.
                if (!availability)
                {
                    query.AvailableOnly(true);
                }
            }

            AddFacet(query, FacetGroupKind.Availability, true, FacetSorting.LabelAsc, descriptor =>
            {
                descriptor.MinHitCount = 0;

                var newValue = availability
                                        ? new FacetValue(true, IndexTypeCode.Boolean)
                                        : new FacetValue(null, IndexTypeCode.Empty);

                newValue.IsSelected = availability;
                newValue.Label      = _services.Localization.GetResource(_searchSettings.IncludeNotAvailable ? "Search.Facet.ExcludeOutOfStock" : "Search.Facet.IncludeOutOfStock");

                descriptor.AddValue(newValue);
            });
        }
Пример #2
0
        public override void ResolveElementCounts(TreeNode <MenuItem> curNode, bool deep = false)
        {
            if (curNode == null || !ContainsProvider("catalog") || !_catalogSettings.Value.ShowCategoryProductNumber)
            {
                return;
            }

            try
            {
                using (Services.Chronometer.Step($"DatabaseMenu.ResolveElementsCount() for {curNode.Value.Text.NaIfEmpty()}"))
                {
                    // Perf: only resolve counts for categories in the current path.
                    while (curNode != null)
                    {
                        if (curNode.Children.Any(x => !x.Value.ElementsCount.HasValue))
                        {
                            lock (s_lock)
                            {
                                if (curNode.Children.Any(x => !x.Value.ElementsCount.HasValue))
                                {
                                    var nodes = deep ? curNode.SelectNodes(x => true, false) : curNode.Children.AsEnumerable();
                                    nodes = nodes.Where(x => x.Value.EntityId != 0);

                                    foreach (var node in nodes)
                                    {
                                        var isCategory     = node.Value.EntityName.IsCaseInsensitiveEqual(nameof(Category));
                                        var isManufacturer = node.Value.EntityName.IsCaseInsensitiveEqual(nameof(Manufacturer));

                                        if (isCategory || isManufacturer)
                                        {
                                            var entityIds = new HashSet <int>();
                                            if (isCategory && _catalogSettings.Value.ShowCategoryProductNumberIncludingSubcategories)
                                            {
                                                // Include sub-categories.
                                                node.Traverse(x =>
                                                {
                                                    entityIds.Add(x.Value.EntityId);
                                                }, true);
                                            }
                                            else
                                            {
                                                entityIds.Add(node.Value.EntityId);
                                            }

                                            var context = new CatalogSearchQuery()
                                                          .VisibleOnly()
                                                          .WithVisibility(ProductVisibility.Full)
                                                          .HasStoreId(Services.StoreContext.CurrentStoreIdIfMultiStoreMode)
                                                          .BuildFacetMap(false)
                                                          .BuildHits(false);

                                            if (isCategory)
                                            {
                                                context = context.WithCategoryIds(null, entityIds.ToArray());
                                            }
                                            else
                                            {
                                                context = context.WithManufacturerIds(null, entityIds.ToArray());
                                            }

                                            if (!_searchSettings.Value.IncludeNotAvailable)
                                            {
                                                context = context.AvailableOnly(true);
                                            }

                                            node.Value.ElementsCount = _catalogSearchService.Value.Search(context).TotalHitsCount;
                                        }
                                    }
                                }
                            }
                        }

                        curNode = curNode.Parent;
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
            }
        }