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