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() }); }); }
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)); }); }
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)); } ); }