flamingo.me/flamingo-commerce/v3@v3.11.0/search/interfaces/controller.go (about) 1 package interfaces 2 3 import ( 4 "context" 5 "net/url" 6 "strconv" 7 8 "flamingo.me/flamingo-commerce/v3/search/application" 9 "flamingo.me/flamingo-commerce/v3/search/domain" 10 "flamingo.me/flamingo-commerce/v3/search/utils" 11 "flamingo.me/flamingo/v3/framework/web" 12 ) 13 14 type ( 15 // ViewController demonstrates a search view controller 16 ViewController struct { 17 responder *web.Responder 18 searchService *application.SearchService 19 paginationInfoFactory *utils.PaginationInfoFactory 20 } 21 22 viewData struct { 23 SearchMeta domain.SearchMeta 24 SearchResult map[string]*application.SearchResult 25 PaginationInfo utils.PaginationInfo 26 } 27 ) 28 29 // Inject dependencies 30 func (vc *ViewController) Inject(responder *web.Responder, 31 paginationInfoFactory *utils.PaginationInfoFactory, 32 searchService *application.SearchService, 33 ) *ViewController { 34 vc.responder = responder 35 vc.paginationInfoFactory = paginationInfoFactory 36 vc.searchService = searchService 37 38 return vc 39 } 40 41 // Get Response for search 42 func (vc *ViewController) Get(c context.Context, r *web.Request) web.Result { 43 query, _ := r.Query1("q") 44 45 vd := viewData{} 46 47 searchRequest := application.SearchRequest{ 48 Query: query, 49 } 50 for k, v := range r.QueryAll() { 51 switch k { 52 case "q": 53 continue 54 case "page": 55 page, _ := strconv.ParseInt(v[0], 10, 64) 56 searchRequest.Page = int(page) 57 case "sort": 58 searchRequest.SortBy = v[0] 59 default: 60 searchRequest.SetAdditionalFilter(domain.NewKeyValueFilter(k, v)) 61 } 62 } 63 64 if typ, ok := r.Params["type"]; ok { 65 //Search for a specific type of documents: 66 searchResult, err := vc.searchService.FindBy(c, typ, searchRequest) 67 if err != nil { 68 if re, ok := err.(*domain.RedirectError); ok { 69 u, _ := url.Parse(re.To) 70 return vc.responder.URLRedirect(u).Permanent() 71 } 72 return vc.responder.ServerError(err) 73 } 74 vd.SearchMeta = searchResult.SearchMeta 75 vd.SearchMeta.Query = query 76 vd.SearchResult = map[string]*application.SearchResult{typ: searchResult} 77 vd.PaginationInfo = vc.buildPagination(searchResult, searchRequest.PageSize, r.Request().URL) 78 return vc.responder.Render("search/"+typ, vd) 79 } 80 81 //Search for all types of documents 82 searchResult, err := vc.searchService.Find(c, searchRequest) 83 if err != nil { 84 if re, ok := err.(*domain.RedirectError); ok { 85 u, _ := url.Parse(re.To) 86 return vc.responder.URLRedirect(u).Permanent() 87 } 88 return vc.responder.ServerError(err) 89 } 90 vd.SearchMeta.Query = query 91 vd.SearchMeta.OriginalQuery = query 92 vd.SearchResult = searchResult 93 94 return vc.responder.Render("search/search", vd) 95 } 96 97 func (vc *ViewController) buildPagination(searchResult *application.SearchResult, pageSize int, url *url.URL) utils.PaginationInfo { 98 return vc.paginationInfoFactory.Build( 99 searchResult.SearchMeta.Page, 100 searchResult.SearchMeta.NumResults, 101 pageSize, 102 searchResult.SearchMeta.NumPages, 103 url, 104 ) 105 }