flamingo.me/flamingo-commerce/v3@v3.11.0/product/application/urlService.go (about)

     1  package application
     2  
     3  import (
     4  	"errors"
     5  
     6  	"flamingo.me/flamingo-commerce/v3/product/domain"
     7  	"flamingo.me/flamingo/v3/framework/web"
     8  )
     9  
    10  type (
    11  	// URLService to manage product urls
    12  	URLService struct {
    13  		router            *web.Router
    14  		generateSlug      bool
    15  		slugAttributecode string
    16  	}
    17  )
    18  
    19  // Inject dependencies
    20  func (s *URLService) Inject(
    21  	r *web.Router,
    22  	c *struct {
    23  		GenerateSlug      bool   `inject:"config:commerce.product.generateSlug,optional"`
    24  		SlugAttributecode string `inject:"config:commerce.product.slugAttributeCode,optional"`
    25  	},
    26  ) *URLService {
    27  	s.router = r
    28  
    29  	if c != nil {
    30  		s.generateSlug = c.GenerateSlug
    31  		s.slugAttributecode = c.SlugAttributecode
    32  	}
    33  
    34  	return s
    35  }
    36  
    37  // Get a product variant url
    38  func (s *URLService) Get(product domain.BasicProduct, variantCode string) (string, error) {
    39  	if product == nil {
    40  		return "-", errors.New("no product given")
    41  	}
    42  	params := s.GetURLParams(product, variantCode)
    43  	url, err := s.router.Relative("product.view", params)
    44  	return url.String(), err
    45  }
    46  
    47  // GetAbsolute url for a product variant url
    48  func (s *URLService) GetAbsolute(r *web.Request, product domain.BasicProduct, variantCode string) (string, error) {
    49  	if product == nil {
    50  		return "-", errors.New("no product given")
    51  	}
    52  	params := s.GetURLParams(product, variantCode)
    53  	url, err := s.router.Absolute(r, "product.view", params)
    54  	return url.String(), err
    55  }
    56  
    57  // GetURLParams get product url params
    58  func (s *URLService) GetURLParams(product domain.BasicProduct, variantCode string) map[string]string {
    59  	params := make(map[string]string)
    60  	if product == nil {
    61  		return params
    62  	}
    63  
    64  	if product.Type() == domain.TypeSimple {
    65  		params["marketplacecode"] = product.BaseData().MarketPlaceCode
    66  		params["name"] = s.getSlug(product.BaseData(), product.BaseData().Title)
    67  	}
    68  	if product.Type() == domain.TypeConfigurableWithActiveVariant {
    69  		if configurableProduct, ok := product.(domain.ConfigurableProductWithActiveVariant); ok {
    70  			params["marketplacecode"] = configurableProduct.ConfigurableBaseData().MarketPlaceCode
    71  			params["name"] = s.getSlug(configurableProduct.ConfigurableBaseData(), configurableProduct.ConfigurableBaseData().Title)
    72  			if variantCode != "" && configurableProduct.HasVariant(variantCode) {
    73  				variantInstance, err := configurableProduct.Variant(variantCode)
    74  				if err == nil {
    75  					params["variantcode"] = variantCode
    76  					params["name"] = s.getSlug(variantInstance.BaseData(), variantInstance.BaseData().Title)
    77  				}
    78  			} else {
    79  				params["variantcode"] = configurableProduct.ActiveVariant.MarketPlaceCode
    80  				params["name"] = s.getSlug(configurableProduct.ActiveVariant.BaseData(), configurableProduct.ActiveVariant.BaseData().Title)
    81  			}
    82  		}
    83  	}
    84  
    85  	if product.Type() == domain.TypeConfigurable {
    86  		if configurableProduct, ok := product.(domain.ConfigurableProduct); ok {
    87  			params["marketplacecode"] = configurableProduct.BaseData().MarketPlaceCode
    88  			params["name"] = s.getSlug(configurableProduct.BaseData(), configurableProduct.BaseData().Title)
    89  			// if the teaser teasers a variant then link to this
    90  			if configurableProduct.TeaserData().PreSelectedVariantSku != "" {
    91  				params["variantcode"] = configurableProduct.TeaserData().PreSelectedVariantSku
    92  				params["name"] = func(d domain.TeaserData) string {
    93  					if s.generateSlug {
    94  						return web.URLTitle(d.ShortTitle)
    95  					}
    96  
    97  					if d.URLSlug == "" {
    98  						return web.URLTitle(d.ShortTitle)
    99  					}
   100  
   101  					return d.URLSlug
   102  				}(configurableProduct.TeaserData())
   103  			}
   104  			// if a variantCode is given then link to that variant
   105  			if variantCode != "" && configurableProduct.HasVariant(variantCode) {
   106  				variantInstance, err := configurableProduct.Variant(variantCode)
   107  				if err == nil {
   108  					params["variantcode"] = variantCode
   109  					params["name"] = s.getSlug(variantInstance.BaseData(), variantInstance.BaseData().Title)
   110  				}
   111  			}
   112  		}
   113  	}
   114  
   115  	return params
   116  }
   117  
   118  // GetNameParam retrieve the proper name parameter
   119  func (s *URLService) GetNameParam(product domain.BasicProduct, variantCode string) string {
   120  	params := s.GetURLParams(product, variantCode)
   121  	if name, ok := params["name"]; ok {
   122  		return name
   123  	}
   124  	return ""
   125  }
   126  
   127  // getSlug fetches the slug from the BasicProductData if available, returns web.URLTitle encoded fallback if disabled, attribute does not exist or attribute is empty
   128  func (s *URLService) getSlug(b domain.BasicProductData, fallback string) string {
   129  	if s.generateSlug {
   130  		return web.URLTitle(fallback)
   131  	}
   132  
   133  	if !b.HasAttribute(s.slugAttributecode) {
   134  		return web.URLTitle(fallback)
   135  	}
   136  
   137  	if nil == b.Attributes[s.slugAttributecode].RawValue {
   138  		return web.URLTitle(fallback)
   139  	}
   140  
   141  	return b.Attributes[s.slugAttributecode].Value()
   142  }