8
8
using VirtoCommerce . Client . Model ;
9
9
using VirtoCommerce . Storefront . Common ;
10
10
using VirtoCommerce . Storefront . Model ;
11
- using VirtoCommerce . Storefront . Model . Catalog ;
12
11
using VirtoCommerce . Storefront . Model . Common ;
13
- using VirtoCommerce . Storefront . Model . Services ;
14
12
using VirtoCommerce . Storefront . Model . StaticContent ;
15
13
16
14
namespace VirtoCommerce . Storefront . Routing
@@ -19,15 +17,13 @@ public class SeoRoute : Route
19
17
{
20
18
private readonly Func < WorkContext > _workContextFactory ;
21
19
private readonly ICommerceCoreModuleApi _commerceCoreApi ;
22
- private readonly IStaticContentService _contentService ;
23
20
private readonly ICacheManager < object > _cacheManager ;
24
21
25
- public SeoRoute ( string url , IRouteHandler routeHandler , Func < WorkContext > workContextFactory , ICommerceCoreModuleApi commerceCoreApi , IStaticContentService staticContentService , ICacheManager < object > cacheManager )
22
+ public SeoRoute ( string url , IRouteHandler routeHandler , Func < WorkContext > workContextFactory , ICommerceCoreModuleApi commerceCoreApi , ICacheManager < object > cacheManager )
26
23
: base ( url , routeHandler )
27
24
{
28
25
_workContextFactory = workContextFactory ;
29
26
_commerceCoreApi = commerceCoreApi ;
30
- _contentService = staticContentService ;
31
27
_cacheManager = cacheManager ;
32
28
}
33
29
@@ -43,108 +39,124 @@ public override RouteData GetRouteData(HttpContextBase httpContext)
43
39
var path = data . Values [ "path" ] as string ;
44
40
var store = data . Values [ "store" ] as string ;
45
41
//Special workaround for case when url contains only slug without store (one store case)
46
- if ( string . IsNullOrEmpty ( path ) && ! string . IsNullOrEmpty ( store ) && workContext . AllStores != null )
42
+ if ( string . IsNullOrEmpty ( path ) && ! string . IsNullOrEmpty ( store ) && workContext . AllStores != null )
47
43
{
48
- //use {store} as {path} if not exist any store with name {store}
49
- path = workContext . AllStores . Any ( x => string . Equals ( store , x . Id , StringComparison . InvariantCultureIgnoreCase ) ) ? null : store ;
44
+ //use {store} as {path} if not exist any store with name {store}
45
+ path = workContext . AllStores . Any ( x => string . Equals ( store , x . Id , StringComparison . InvariantCultureIgnoreCase ) ) ? null : store ;
50
46
}
51
47
//Get all seo records for requested slug and also all other seo records with different slug and languages but related to same object
52
48
// GetSeoRecords('A') returns
53
49
// { objectType: 'Product', objectId: '1', SemanticUrl: 'A', Language: 'en-us', active : false }
54
50
// { objectType: 'Product', objectId: '1', SemanticUrl: 'AA', Language: 'en-us', active : true }
55
51
var seoRecords = GetSeoRecords ( path ) ;
56
- var seoRecord = seoRecords . Where ( x => path . Equals ( x . SemanticUrl , StringComparison . OrdinalIgnoreCase ) )
57
- . FindBestSeoMatch ( workContext . CurrentLanguage , workContext . CurrentStore ) ;
58
-
59
- if ( seoRecord != null )
52
+ if ( seoRecords != null )
60
53
{
61
- // Ensure the slug is active
62
- if ( seoRecord . IsActive == null || ! seoRecord . IsActive . Value )
54
+ var seoRecord = seoRecords
55
+ . Where ( x => string . Equals ( path , x . SemanticUrl , StringComparison . OrdinalIgnoreCase ) )
56
+ . FindBestSeoMatch ( workContext . CurrentLanguage , workContext . CurrentStore ) ;
57
+
58
+ if ( seoRecord != null )
63
59
{
64
- // Slug is not active. Try to find the active one for the same entity and language.
65
- seoRecord = seoRecords . Where ( x=> x . ObjectType == seoRecord . ObjectType && x . ObjectId == seoRecord . ObjectId && x . IsActive != null && x . IsActive . Value )
66
- . FindBestSeoMatch ( workContext . CurrentLanguage , workContext . CurrentStore ) ;
67
-
68
- if ( seoRecord == null )
60
+ // Ensure the slug is active
61
+ if ( seoRecord . IsActive == null || ! seoRecord . IsActive . Value )
69
62
{
70
- // No active slug found
71
- data . Values [ "controller" ] = "Error" ;
72
- data . Values [ "action" ] = "Http404" ;
63
+ // Slug is not active. Try to find the active one for the same entity and language.
64
+ seoRecord = seoRecords . Where ( x => x . ObjectType == seoRecord . ObjectType && x . ObjectId == seoRecord . ObjectId && x . IsActive != null && x . IsActive . Value )
65
+ . FindBestSeoMatch ( workContext . CurrentLanguage , workContext . CurrentStore ) ;
66
+
67
+ if ( seoRecord == null )
68
+ {
69
+ // No active slug found
70
+ data . Values [ "controller" ] = "Error" ;
71
+ data . Values [ "action" ] = "Http404" ;
72
+ }
73
+ else
74
+ {
75
+ // The active slug is found
76
+ var response = httpContext . Response ;
77
+ response . Status = "301 Moved Permanently" ;
78
+ response . RedirectLocation = string . Format ( "{0}{1}" , workContext . CurrentStore . Url , seoRecord . SemanticUrl ) ;
79
+ response . End ( ) ;
80
+ data = null ;
81
+ }
73
82
}
74
83
else
75
84
{
76
- // The active slug is found
77
- var response = httpContext . Response ;
78
- response . Status = "301 Moved Permanently" ;
79
- response . RedirectLocation = string . Format ( "{0}{1}" , workContext . CurrentStore . Url , seoRecord . SemanticUrl ) ;
80
- response . End ( ) ;
81
- data = null ;
85
+ // Redirect to the slug for the current language if it differs from the requested slug
86
+ var actualActiveSeoRecord = seoRecords . Where ( x => x . ObjectType == seoRecord . ObjectType && x . ObjectId == seoRecord . ObjectId && x . IsActive != null && x . IsActive . Value )
87
+ . FindBestSeoMatch ( workContext . CurrentLanguage , workContext . CurrentStore ) ;
88
+ //If actual seo different that requested need redirect 302
89
+ if ( ! string . Equals ( actualActiveSeoRecord . SemanticUrl , seoRecord . SemanticUrl , StringComparison . OrdinalIgnoreCase ) )
90
+ {
91
+ var response = httpContext . Response ;
92
+ response . Status = "302 Moved Temporarily" ;
93
+ response . RedirectLocation = string . Concat ( workContext . CurrentStore . Url , actualActiveSeoRecord . SemanticUrl ) ;
94
+ response . End ( ) ;
95
+ data = null ;
96
+ }
97
+ else
98
+ {
99
+ // Process the URL
100
+ switch ( seoRecord . ObjectType )
101
+ {
102
+ case "CatalogProduct" :
103
+ data . Values [ "controller" ] = "Product" ;
104
+ data . Values [ "action" ] = "ProductDetails" ;
105
+ data . Values [ "productId" ] = seoRecord . ObjectId ;
106
+ break ;
107
+ case "Category" :
108
+ data . Values [ "controller" ] = "CatalogSearch" ;
109
+ data . Values [ "action" ] = "CategoryBrowsing" ;
110
+ data . Values [ "categoryId" ] = seoRecord . ObjectId ;
111
+ break ;
112
+ }
113
+ }
82
114
}
83
115
}
84
- else
116
+ else if ( ! string . IsNullOrEmpty ( path ) )
85
117
{
86
- // Redirect to the slug for the current language if it differs from the requested slug
87
- var actualActiveSeoRecord = seoRecords . Where ( x => x . ObjectType == seoRecord . ObjectType && x . ObjectId == seoRecord . ObjectId && x . IsActive != null && x . IsActive . Value )
88
- . FindBestSeoMatch ( workContext . CurrentLanguage , workContext . CurrentStore ) ;
89
- //If actual seo different that requested need redirect 302
90
- if ( ! string . Equals ( actualActiveSeoRecord . SemanticUrl , seoRecord . SemanticUrl , StringComparison . OrdinalIgnoreCase ) )
118
+ var contentPage = TryToFindContentPageWithUrl ( workContext , path ) ;
119
+ if ( contentPage != null )
91
120
{
92
- var response = httpContext . Response ;
93
- response . Status = "302 Moved Temporarily" ;
94
- response . RedirectLocation = string . Format ( "{0}{1}" , workContext . CurrentStore . Url , actualActiveSeoRecord . SemanticUrl ) ;
95
- response . End ( ) ;
96
- data = null ;
121
+ data . Values [ "controller" ] = "Page" ;
122
+ data . Values [ "action" ] = "GetContentPage" ;
123
+ data . Values [ "page" ] = contentPage ;
97
124
}
98
125
else
99
126
{
100
- // Process the URL
101
- switch ( seoRecord . ObjectType )
102
- {
103
- case "CatalogProduct" :
104
- data . Values [ "controller" ] = "Product" ;
105
- data . Values [ "action" ] = "ProductDetails" ;
106
- data . Values [ "productId" ] = seoRecord . ObjectId ;
107
- break ;
108
- case "Category" :
109
- data . Values [ "controller" ] = "CatalogSearch" ;
110
- data . Values [ "action" ] = "CategoryBrowsing" ;
111
- data . Values [ "categoryId" ] = seoRecord . ObjectId ;
112
- break ;
113
- }
127
+ data . Values [ "controller" ] = "Error" ;
128
+ data . Values [ "action" ] = "Http404" ;
114
129
}
115
130
}
116
131
}
117
- else if ( ! String . IsNullOrEmpty ( path ) )
118
- {
119
- var contentPage = TryToFindContentPageWithUrl ( workContext , path ) ;
120
- if ( contentPage != null )
121
- {
122
- data . Values [ "controller" ] = "Page" ;
123
- data . Values [ "action" ] = "GetContentPage" ;
124
- data . Values [ "page" ] = contentPage ;
125
- }
126
- else
127
- {
128
- data . Values [ "controller" ] = "Error" ;
129
- data . Values [ "action" ] = "Http404" ;
130
- }
131
- }
132
132
}
133
133
134
134
return data ;
135
135
}
136
136
137
- private ContentItem TryToFindContentPageWithUrl ( WorkContext workContext , string url )
137
+
138
+ private static ContentItem TryToFindContentPageWithUrl ( WorkContext workContext , string url )
138
139
{
139
- url = url . TrimStart ( '/' ) ;
140
- var pages = workContext . Pages . Where ( x => string . Equals ( x . Permalink , url , StringComparison . CurrentCultureIgnoreCase ) || string . Equals ( x . Url , url , StringComparison . InvariantCultureIgnoreCase ) ) ;
141
- //Need return page with current or invariant language
142
- var retVal = pages . FirstOrDefault ( x => x . Language == workContext . CurrentLanguage ) ;
143
- if ( retVal == null )
140
+ ContentItem result = null ;
141
+
142
+ if ( workContext . Pages != null )
144
143
{
145
- retVal = pages . FirstOrDefault ( x => x . Language . IsInvariant ) ;
144
+ url = url . TrimStart ( '/' ) ;
145
+ var pages = workContext . Pages
146
+ . Where ( x =>
147
+ string . Equals ( x . Permalink , url , StringComparison . CurrentCultureIgnoreCase ) ||
148
+ string . Equals ( x . Url , url , StringComparison . InvariantCultureIgnoreCase ) )
149
+ . ToList ( ) ;
150
+
151
+ // Return page with current language or invariant language
152
+ result = pages . FirstOrDefault ( x => x . Language == workContext . CurrentLanguage ) ;
153
+ if ( result == null )
154
+ {
155
+ result = pages . FirstOrDefault ( x => x . Language . IsInvariant ) ;
156
+ }
146
157
}
147
- return retVal ;
158
+
159
+ return result ;
148
160
}
149
161
150
162
private List < VirtoCommerceDomainCommerceModelSeoInfo > GetSeoRecords ( string path )
@@ -156,16 +168,13 @@ private List<VirtoCommerceDomainCommerceModelSeoInfo> GetSeoRecords(string path)
156
168
var tokens = path . Split ( '/' ) ;
157
169
// TODO: Store path tokens as breadcrumbs to the work context
158
170
var slug = tokens . LastOrDefault ( ) ;
159
- if ( ! String . IsNullOrEmpty ( slug ) )
171
+ if ( ! string . IsNullOrEmpty ( slug ) )
160
172
{
161
- seoRecords = _cacheManager . Get ( string . Join ( ":" , "CommerceGetSeoInfoBySlug" , slug ) , "ApiRegion" , ( ) => { return _commerceCoreApi . CommerceGetSeoInfoBySlug ( slug ) ; } ) ;
173
+ seoRecords = _cacheManager . Get ( string . Join ( ":" , "CommerceGetSeoInfoBySlug" , slug ) , "ApiRegion" , ( ) => _commerceCoreApi . CommerceGetSeoInfoBySlug ( slug ) ) ;
162
174
}
163
175
}
164
176
165
177
return seoRecords ;
166
178
}
167
-
168
-
169
-
170
179
}
171
180
}
0 commit comments