public static async Task <PageInfoModel <BaseProduct, ProductModel> > SearchAsync(
            GlobalModel globalModel,
            Guid?parentCategorySystemId,
            RouteInfoService routeInfoService,
            string query,
            int take,
            int offset,
            IServiceProvider serviceProvider
            )
        {
            routeInfoService.Setup(globalModel, null);
            var searchQuery = new SearchQuery();

            searchQuery.CategorySystemId        = parentCategorySystemId;
            searchQuery.CategoryShowRecursively = true;
            searchQuery.ProductListSystemId     = null;
            searchQuery.Text            = query ?? string.Empty;
            searchQuery.PageSize        = take;
            searchQuery.PageNumber      = (int)Math.Floor((double)offset / take) + 1;
            searchQuery.WebsiteSystemId = globalModel.WebsiteSystemId;
            // Special treatment for scoped services https://graphql-dotnet.github.io/docs/getting-started/dependency-injection/#scoped-services-with-a-singleton-schema-lifetime
            // and make sure it is thread safe https://graphql-dotnet.github.io/docs/getting-started/dependency-injection/#thread-safety-with-scoped-services
            using var scope = serviceProvider.CreateScope();
            var productSearchService = scope.ServiceProvider.GetRequiredService <ProductSearchService>();
            var searchResults        = await productSearchService.SearchAsync(searchQuery, searchQuery.Tags, true, true, true);

            if (searchResults == null)
            {
                return(new PageInfoModel <BaseProduct, ProductModel>()
                {
                    List = Enumerable.Empty <ProductModel>(),
                    HasNextPage = false,
                    Total = 0
                });
            }
            var productItemBuilder = scope.ServiceProvider.GetRequiredService <ProductItemViewModelBuilder>();

            return(new PageInfoModel <BaseProduct, ProductModel>()
            {
                List = searchResults.Items.Value.Cast <ProductSearchResult>()
                       .Select(c => productItemBuilder.Build(c.Item))
                       .MapEnumerableTo <ProductModel>().ToList(),
                Total = searchResults.Total,
                HasNextPage = searchQuery.PageNumber * searchQuery.PageSize < searchResults.Total
            });
        }
        public BlockType(BlockService blockService, FieldTemplateService fieldTemplateService,
                         NamedServiceFactory <IBlockDataBuilder> blockDataBuilderFactory,
                         RouteInfoService routeInfoService)
        {
            Name        = "Block";
            Description = "Block data";
            Field(p => p.SystemId, type: typeof(IdGraphType)).Description("The block Id");

            Field <StringGraphType>(nameof(BlockModel.BlockType), "The block type",
                                    resolve: context =>
            {
                var block    = blockService.Get(context.Source.SystemId);
                var template = fieldTemplateService.Get <BlockFieldTemplate>(block.FieldTemplateSystemId);
                return(template.Id);
            });

            FieldAsync <StringGraphType>(nameof(BlockModel.ValueAsJSON), "Value as JSON string",
                                         arguments: new QueryArguments(
                                             new QueryArgument <GlobalInputType> {
                Name = "global", Description = "The global object"
            }
                                             ),
                                         resolve: async context =>
            {
                var block    = blockService.Get(context.Source.SystemId);
                var template = fieldTemplateService.Get <BlockFieldTemplate>(block.FieldTemplateSystemId);
                // Special treatment for scoped services https://graphql-dotnet.github.io/docs/getting-started/dependency-injection/#scoped-services-with-a-singleton-schema-lifetime
                // and make sure it is thread safe https://graphql-dotnet.github.io/docs/getting-started/dependency-injection/#thread-safety-with-scoped-services
                using var scope = context.RequestServices.CreateScope();
                var builder     = scope.ServiceProvider.GetNamedService <IBlockDataBuilder>(template.Id);
                if (builder == null)
                {
                    return(null);
                }
                var globalModel = context.GetArgument <GlobalModel>("global");
                routeInfoService.Setup(globalModel, context.Source.PageSystemId);
                var buildMethod = builder.GetType().GetMethod(nameof(IBlockDataBuilder <IViewModel> .BuildAsync));
                var value       = await(dynamic) buildMethod.Invoke(builder,
                                                                    new object[] { scope, new Web.Models.Blocks.BlockModel(block, block.Fields) });
                var jsonSerializerSettings = ApplicationConverter.JsonSerializerSettings();
                // jsonSerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                return(JsonConvert.SerializeObject(value, jsonSerializerSettings));
            });
        }
        public WebsiteType(WebsiteService websiteService,
                           RouteInfoService routeInfoService,
                           CategoryService categoryService,
                           UrlService urlService,
                           PageService pageService)
        {
            Name = "Website";
            Field(p => p.LogoUrl);
            Field(p => p.SystemId, type: typeof(IdGraphType));

            Field <FooterType>(nameof(WebsiteModel.Footer), "The website footer",
                               arguments: new QueryArguments(
                                   new QueryArgument <GlobalInputType> {
                Name = "global"
            }
                                   ),
                               resolve: context =>
            {
                var website = websiteService.Get(context.Source.SystemId);
                var footer  = website.Fields.GetValue <IList <MultiFieldItem> >(AcceleratorWebsiteFieldNameConstants.Footer);
                if (footer != null)
                {
                    var globalModel       = context.GetArgument <GlobalModel>("global");
                    var culture           = CultureInfo.GetCultureInfo(globalModel.CurrentUICulture);
                    var startPageSystemId = pageService.GetChildPages(Guid.Empty, globalModel.WebsiteSystemId).FirstOrDefault()?.SystemId;
                    routeInfoService.Setup(globalModel, startPageSystemId);
                    return(new FooterModel()
                    {
                        SectionList = footer.Select(c => new SectionModel()
                        {
                            SectionTitle = c.Fields.GetValue <string>(AcceleratorWebsiteFieldNameConstants.FooterHeader, culture) ?? string.Empty,
                            SectionLinkList = c.Fields.GetValue <IList <PointerItem> >(AcceleratorWebsiteFieldNameConstants.FooterLinkList)
                                              .OfType <PointerPageItem>().ToList()
                                              .Select(x => x.MapTo <Web.Models.LinkModel>()).Where(c => c != null).Select(l => new Models.LinkModel()
                            {
                                Href = l.Href,
                                Text = l.Text
                            }).ToList() ?? new List <Models.LinkModel>(),
                            SectionText = c.Fields.GetValue <string>(AcceleratorWebsiteFieldNameConstants.FooterText, culture) ?? string.Empty
                        }).ToList()
                    });
                }
                return(null);
            });

            Field <HeaderType>(nameof(WebsiteModel.Header), "The website header",
                               arguments: new QueryArguments(
                                   new QueryArgument <GlobalInputType> {
                Name = "global"
            }
                                   ),
                               resolve: context =>
            {
                var globalModel = context.GetArgument <GlobalModel>("global");
                var items       = categoryService.GetChildCategories(Guid.Empty, globalModel.AssortmentSystemId);
                var culture     = CultureInfo.GetCultureInfo(globalModel.CurrentCulture);
                return(new HeaderModel()
                {
                    SectionList = items.Select(c => new SectionModel()
                    {
                        SectionText = c.GetEntityName(culture),
                        SectionTitle = c.GetEntityName(culture),
                        Href = urlService.GetUrl(c, new CategoryUrlArgs(globalModel.ChannelSystemId)),
                        SectionLinkList = categoryService.GetChildCategories(c.SystemId).Select(subCategory => new LinkModel()
                        {
                            Href = urlService.GetUrl(subCategory, new CategoryUrlArgs(globalModel.ChannelSystemId)),
                            Text = subCategory.GetEntityName(culture)
                        }).ToList()
                    }).ToList()
                });
            });
        }
Exemple #4
0
        public PageType(PageService pageService, BlockService blockService, UrlService urlService,
                        FieldTemplateService fieldTemplateService, RouteInfoService routeInfoService)
        {
            Name        = "Page";
            Description = "Page data";
            Field(p => p.SystemId, type: typeof(IdGraphType)).Description("The System Id");
            Field(p => p.Slug, nullable: true).Description("The slug")
            .Argument <GlobalInputType>("global")
            .Resolve(context =>
            {
                var globalModel = context.GetArgument <GlobalModel>("global");
                var page        = pageService.Get(context.Source.SystemId);
                return(urlService.GetUrl(page, new PageUrlArgs(globalModel.ChannelSystemId)));
            });

            Field <ListGraphType <BlockAreaType> >(nameof(PageModel.Areas), "Block areas",
                                                   resolve: context =>
            {
                var page = pageService.Get(context.Source.SystemId);
                return(page.Blocks.Items.Select(container =>
                                                new BlockAreaModel()
                {
                    Id = container.Id,
                    Blocks = blockService.Get(container.Items.Select(block => ((BlockItemLink)block).BlockSystemId))
                             .MapEnumerableTo <BlockModel>()
                             .Select(b => { b.PageSystemId = context.Source.SystemId; return b; }).ToList()
                }).ToList());
            });

            Field <StringGraphType>(nameof(PageModel.TemplateId), "Template id",
                                    resolve: context =>
            {
                var page     = pageService.Get(context.Source.SystemId);
                var template = fieldTemplateService.Get <PageFieldTemplate>(page.FieldTemplateSystemId);
                return(template.Id);
            });

            Field <StringGraphType>(nameof(PageModel.Name), "The page name",
                                    arguments: new QueryArguments(
                                        new QueryArgument <GlobalInputType> {
                Name = "global", Description = "The global object"
            }
                                        ),
                                    resolve: context =>
            {
                var page        = pageService.Get(context.Source.SystemId);
                var globalModel = context.GetArgument <GlobalModel>("global");
                return(page.GetEntityName(true, CultureInfo.GetCultureInfo(globalModel.CurrentCulture)) ?? page.Id ?? "general.NameIsMissing".AsAngularResourceString());
            });

            Field <PageInfoPageType>(nameof(PageModel.Children), description: "Sub pages",
                                     arguments: new QueryArguments(
                                         new QueryArgument <IntGraphType> {
                Name = "offset"
            },
                                         new QueryArgument <IntGraphType> {
                Name = "take"
            }
                                         ),
                                     resolve: context =>
                                     new PageInfoModel <Page, PageModel>(pageService.GetChildPages(context.Source.SystemId),
                                                                         context.GetArgument("offset", 0), context.GetArgument("take", 10)));

            FieldAsync <StringGraphType>(nameof(PageModel.ValueAsJSON), "Value as JSON string",
                                         arguments: new QueryArguments(
                                             new QueryArgument <GlobalInputType> {
                Name = "global", Description = "The global object"
            }
                                             ),
                                         resolve: async context =>
            {
                var page     = pageService.Get(context.Source.SystemId);
                var template = fieldTemplateService.Get <PageFieldTemplate>(page.FieldTemplateSystemId);
                // Special treatment for scoped services https://graphql-dotnet.github.io/docs/getting-started/dependency-injection/#scoped-services-with-a-singleton-schema-lifetime
                // and make sure it is thread safe https://graphql-dotnet.github.io/docs/getting-started/dependency-injection/#thread-safety-with-scoped-services
                using var scope = context.RequestServices.CreateScope();
                var builder     = scope.ServiceProvider.GetNamedService <IPageDataBuilder>(template.Id);
                if (builder == null)
                {
                    return(null);
                }
                var globalModel = context.GetArgument <GlobalModel>("global");
                routeInfoService.Setup(globalModel, context.Source.SystemId);
                var buildMethod = builder.GetType().GetMethod(nameof(IPageDataBuilder <IViewModel> .BuildAsync));
                var value       = await(dynamic) buildMethod.Invoke(builder,
                                                                    new object[] { scope, new Web.Models.Websites.PageModel(page, page.Fields) });
                // ((IDictionary<string, object>)value).Remove("blocks");
                var jsonSerializerSettings = ApplicationConverter.JsonSerializerSettings();
                return(JsonConvert.SerializeObject(value, jsonSerializerSettings));
            });
        }
Exemple #5
0
        public LitiumQuery(BaseProductService baseProductService,
                           VariantService variantService,
                           ChannelService channelService,
                           MarketService marketService,
                           CountryService countryService,
                           LanguageService languageService,
                           RoutingHelperService routingHelperService,
                           CategoryService categoryService,
                           PageService pageService,
                           WebsiteService websiteService,
                           RouteInfoService routeInfoService,
                           DataService dataService)
        {
            Name = "LitiumQuery";

            Field <WebsiteType>(
                "website",
                arguments: new QueryArguments(
                    new QueryArgument <IdGraphType> {
                Name = "systemId"
            }
                    ),
                resolve: (context) =>
            {
                var systemId = context.GetArgument <Guid>("systemId");
                var logoUrl  = websiteService.Get(systemId).Fields
                               .GetValue <Guid?>(AcceleratorWebsiteFieldNameConstants.LogotypeMain).Value
                               .MapTo <Web.Models.ImageModel>().GetUrlToImage(System.Drawing.Size.Empty, new System.Drawing.Size(-1, 50)).Url;
                return(new WebsiteModel()
                {
                    LogoUrl = logoUrl,
                    SystemId = systemId
                });
            }
                );

            Field <GlobalType>(
                "global",
                resolve: (context) =>
            {
                var channel   = channelService.GetAll().First();
                var market    = marketService.Get(channel.MarketSystemId.Value);
                var country   = countryService.Get(channel.CountryLinks.First().CountrySystemId);
                var culture   = languageService.Get(channel.WebsiteLanguageSystemId.Value);
                var uiCulture = languageService.Get(channel.ProductLanguageSystemId.Value);

                return(new GlobalModel()
                {
                    ChannelSystemId = channel.SystemId,
                    WebsiteSystemId = channel.WebsiteSystemId.Value,
                    AssortmentSystemId = market.AssortmentSystemId.Value,
                    CountrySystemId = country.SystemId,
                    CurrencySystemId = country.CurrencySystemId,
                    CurrentCulture = culture.Id,
                    CurrentUICulture = uiCulture.Id,
                });
            }
                );

            Field <CategoryType>(
                "category",
                arguments: new QueryArguments(
                    new QueryArgument <IdGraphType> {
                Name = "systemId", Description = "id of the category, will be override if slug has value"
            },
                    new QueryArgument <GlobalInputType> {
                Name = "global"
            },
                    new QueryArgument <ListGraphType <StringGraphType> > {
                Name = "slug", Description = "category slug urls"
            }
                    ),
                resolve: context =>
            {
                var categoryId = context.GetArgument <Guid>("systemId");
                var slug       = context.GetArgument <string[]>("slug");
                if (slug != null && slug.Any())
                {
                    var globalModel = context.GetArgument <GlobalModel>("global");
                    return(GetCategoryFromSlug(slug, globalModel, routingHelperService, categoryService));
                }
                return(categoryService.Get(categoryId).MapTo <CategoryModel>());
            }
                );

            FieldAsync <PageInfoCategoryType>(
                "searchCategory",
                arguments: new QueryArguments(
                    new QueryArgument <IntGraphType> {
                Name = "offset"
            },
                    new QueryArgument <IntGraphType> {
                Name = "take"
            },
                    new QueryArgument <GlobalInputType> {
                Name = "global", Description = "The global object"
            },
                    new QueryArgument <StringGraphType> {
                Name = "query", Description = "The search query"
            }
                    ),
                resolve: async context =>
            {
                return(await CategoryQuery.SearchAsync(
                           context.GetArgument <GlobalModel>("global"),
                           routeInfoService,
                           context.GetArgument <string>("query") ?? string.Empty,
                           context.GetArgument("take", 8),
                           context.GetArgument("offset", 0),
                           context.RequestServices
                           ));
            }
                );

            Field <ProductType>(
                "product",
                arguments: new QueryArguments(
                    new QueryArgument <IdGraphType> {
                Name = "systemId", Description = "id of the product"
            },
                    new QueryArgument <StringGraphType> {
                Name = "slug", Description = "Product's slug url"
            },
                    new QueryArgument <GlobalInputType> {
                Name = "global"
            }
                    ),
                resolve: context =>
            {
                var systemId    = context.GetArgument <Guid>("systemId");
                var slug        = context.GetArgument <string>("slug");
                var globalModel = context.GetArgument <GlobalModel>("global");
                if (!string.IsNullOrEmpty(slug))
                {
                    systemId = GetProductSystemIdFromSlug(slug, globalModel, routingHelperService);
                }
                // Special treatment for scoped services https://graphql-dotnet.github.io/docs/getting-started/dependency-injection/#scoped-services-with-a-singleton-schema-lifetime
                // and make sure it is thread safe https://graphql-dotnet.github.io/docs/getting-started/dependency-injection/#thread-safety-with-scoped-services
                using var scope = context.RequestServices.CreateScope();
                return(GetProduct(systemId, scope, baseProductService, variantService, globalModel));
            }
                );

            FieldAsync <PageInfoProductType>(
                "products",
                arguments: new QueryArguments(
                    new QueryArgument <IntGraphType> {
                Name = "offset"
            },
                    new QueryArgument <IntGraphType> {
                Name = "take"
            },
                    new QueryArgument <IdGraphType> {
                Name = "parentCategorySystemId", Description = "The optional parent category system id"
            },
                    new QueryArgument <GlobalInputType> {
                Name = "global", Description = "The global object"
            },
                    new QueryArgument <StringGraphType> {
                Name = "query", Description = "The search query"
            }
                    ),
                resolve: async context =>
            {
                return(await ProductQuery.SearchAsync(
                           context.GetArgument <GlobalModel>("global"),
                           context.GetArgument <Guid?>("parentCategorySystemId"),
                           routeInfoService,
                           context.GetArgument <string>("query") ?? string.Empty,
                           context.GetArgument("take", 8),
                           context.GetArgument("offset", 0),
                           context.RequestServices
                           ));
            }
                );

            Field <PageType>(
                "page",
                arguments: new QueryArguments(
                    new QueryArgument <IdGraphType> {
                Name = "systemId", Description = "Id of the page. Can be empty GUID, the website's homepage will be returned in that case, where WebsiteSystemId should have value."
            },
                    new QueryArgument <ListGraphType <StringGraphType> > {
                Name = "slug", Description = "Page's slugs, will override systemId if available"
            },
                    new QueryArgument <GlobalInputType> {
                Name = "global", Description = "Global context, which is needed to get page from slug"
            }
                    ),
                resolve: context =>
            {
                var slug        = context.GetArgument <string[]>("slug");
                var globalModel = context.GetArgument <GlobalModel>("global");
                routeInfoService.Setup(globalModel, null);
                if (slug != null && slug.Any())
                {
                    return(GetPageFromSlug(slug, globalModel, pageService, routingHelperService));
                }

                var systemId = context.GetArgument <Guid?>("systemId");
                if (systemId.HasValue && systemId.Value != Guid.Empty)
                {
                    return(pageService.Get(systemId.Value)?.MapTo <PageModel>());
                }
                return(pageService.GetChildPages(Guid.Empty, globalModel.WebsiteSystemId).FirstOrDefault()?.MapTo <PageModel>());
            }
                );

            FieldAsync <PageInfoPageType>(
                "searchPage",
                arguments: new QueryArguments(
                    new QueryArgument <IntGraphType> {
                Name = "offset"
            },
                    new QueryArgument <IntGraphType> {
                Name = "take"
            },
                    new QueryArgument <GlobalInputType> {
                Name = "global", Description = "The global object"
            },
                    new QueryArgument <StringGraphType> {
                Name = "query", Description = "The search query"
            }
                    ),
                resolve: async context =>
            {
                return(await PageQuery.SearchAsync(
                           context.GetArgument <GlobalModel>("global"),
                           routeInfoService,
                           context.GetArgument <string>("query") ?? string.Empty,
                           context.GetArgument("take", 8),
                           context.GetArgument("offset", 0),
                           context.RequestServices
                           ));
            }
                );

            Field <ContentType>(
                "content",
                arguments: new QueryArguments(
                    new QueryArgument <GlobalInputType> {
                Name = "global", Description = "The global object"
            },
                    new QueryArgument <ListGraphType <StringGraphType> > {
                Name = "slug", Description = "The slug array"
            }
                    ),
                resolve: context =>
            {
                var slug        = context.GetArgument <string[]>("slug");
                var globalModel = context.GetArgument <GlobalModel>("global");
                routeInfoService.Setup(globalModel, null);

                var systemId = GetProductSystemIdFromSlug(slug[slug.Length - 1], globalModel, routingHelperService);
                if (systemId != Guid.Empty)
                {
                    // Special treatment for scoped services https://graphql-dotnet.github.io/docs/getting-started/dependency-injection/#scoped-services-with-a-singleton-schema-lifetime
                    // and make sure it is thread safe https://graphql-dotnet.github.io/docs/getting-started/dependency-injection/#thread-safety-with-scoped-services
                    using var scope = context.RequestServices.CreateScope();
                    return(GetProduct(systemId, scope, baseProductService, variantService, globalModel));
                }

                var category = GetCategoryFromSlug(slug, globalModel, routingHelperService, categoryService);
                if (category != null)
                {
                    return(category);
                }
                return(GetPageFromSlug(slug, globalModel, pageService, routingHelperService));
            }
                );
        }