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  }