@@ -20,10 +20,9 @@ public partial class LinkResolver : ILinkResolver
2020 {
2121 /// <remarks>
2222 /// {0} : Expression w/o q
23- /// {1} : q
24- /// {2} : LanguageId
25- /// {3} : Store
26- /// {4} : RolesIdent
23+ /// {1} : LanguageId
24+ /// {2} : Store
25+ /// {3} : RolesIdent
2726 /// </remarks>
2827 internal const string LINKRESOLVER_KEY = "linkresolver:{0}-{1}-{2}-{3}" ;
2928
@@ -97,18 +96,19 @@ public virtual LinkResolverResult Resolve(string linkExpression, IEnumerable<Cus
9796 else
9897 {
9998 var cacheKey = LINKRESOLVER_KEY . FormatInvariant (
100- d . Link ,
101- d . QueryString . EmptyNull ( ) ,
99+ d . Expression ,
102100 languageId ,
103101 storeId ,
104102 string . Join ( "," , roles . Where ( x => x . Active ) . Select ( x => x . Id ) ) ) ;
105103
106- _services . Cache . Get ( cacheKey , ( ) =>
104+ d = _services . Cache . Get ( cacheKey , ( ) =>
107105 {
108- switch ( d . Type )
106+ var d2 = d . Clone ( ) ;
107+
108+ switch ( d2 . Type )
109109 {
110110 case LinkType . Product :
111- GetEntityData < Product > ( d , languageId , x => new ResolverEntitySummary
111+ GetEntityData < Product > ( d2 , languageId , x => new ResolverEntitySummary
112112 {
113113 Name = x . Name ,
114114 Published = x . Published ,
@@ -118,7 +118,7 @@ public virtual LinkResolverResult Resolve(string linkExpression, IEnumerable<Cus
118118 } ) ;
119119 break ;
120120 case LinkType . Category :
121- GetEntityData < Category > ( d , languageId , x => new ResolverEntitySummary
121+ GetEntityData < Category > ( d2 , languageId , x => new ResolverEntitySummary
122122 {
123123 Name = x . Name ,
124124 Published = x . Published ,
@@ -128,7 +128,7 @@ public virtual LinkResolverResult Resolve(string linkExpression, IEnumerable<Cus
128128 } ) ;
129129 break ;
130130 case LinkType . Manufacturer :
131- GetEntityData < Manufacturer > ( d , languageId , x => new ResolverEntitySummary
131+ GetEntityData < Manufacturer > ( d2 , languageId , x => new ResolverEntitySummary
132132 {
133133 Name = x . Name ,
134134 Published = x . Published ,
@@ -137,13 +137,13 @@ public virtual LinkResolverResult Resolve(string linkExpression, IEnumerable<Cus
137137 } ) ;
138138 break ;
139139 case LinkType . Topic :
140- GetEntityData < Topic > ( d , languageId , x => null ) ;
140+ GetEntityData < Topic > ( d2 , languageId , x => null ) ;
141141 break ;
142142 default :
143143 throw new SmartException ( "Unknown link builder type." ) ;
144144 }
145145
146- return d ;
146+ return d2 ;
147147 } ) ;
148148 }
149149
@@ -180,36 +180,74 @@ public virtual LinkResolverResult Resolve(string linkExpression, IEnumerable<Cus
180180 return result ;
181181 }
182182
183+ private bool TokenizeExpression ( string expression , out string type , out string path , out string query )
184+ {
185+ type = null ;
186+ path = null ;
187+ query = null ;
188+
189+ if ( string . IsNullOrWhiteSpace ( expression ) )
190+ {
191+ return false ;
192+ }
193+
194+ var colonIndex = expression . IndexOf ( ':' ) ;
195+ if ( colonIndex > - 1 )
196+ {
197+ type = expression . Substring ( 0 , colonIndex ) ;
198+ if ( type . StartsWith ( "http" , StringComparison . OrdinalIgnoreCase ) )
199+ {
200+ type = null ;
201+ colonIndex = - 1 ;
202+ }
203+ }
204+
205+ path = expression . Substring ( colonIndex + 1 ) ;
206+
207+ var qmIndex = path . IndexOf ( '?' ) ;
208+ if ( qmIndex > - 1 )
209+ {
210+ query = path . Substring ( qmIndex + 1 ) ;
211+ path = path . Substring ( 0 , qmIndex ) ;
212+ }
213+
214+ return true ;
215+ }
216+
183217 protected virtual LinkResolverData Parse ( string linkExpression )
184218 {
185- if ( ! string . IsNullOrWhiteSpace ( linkExpression ) )
186- {
187- var index = linkExpression . IndexOf ( ':' ) ;
219+ if ( TokenizeExpression ( linkExpression , out var type , out var path , out var query ) )
220+ {
221+ if ( ! string . IsNullOrWhiteSpace ( type ) && Enum . TryParse ( type , true , out LinkType linkType ) )
222+ {
223+ var result = new LinkResolverData { Type = linkType , Expression = string . Concat ( type , ":" , path ) } ;
188224
189- if ( index != - 1 && Enum . TryParse ( linkExpression . Substring ( 0 , index ) , true , out LinkType type ) )
190- {
191- var rawValue = linkExpression . Substring ( index + 1 ) ;
192- rawValue . SplitToPair ( out var value , out var queryString , "?" , true ) ;
225+ switch ( linkType )
226+ {
227+ case LinkType . Product :
228+ case LinkType . Category :
229+ case LinkType . Manufacturer :
230+ case LinkType . Topic :
231+ var id = path . ToInt ( ) ;
232+ result . Value = id != 0 ? ( object ) id : path ;
233+ result . QueryString = query ;
234+ break ;
235+ case LinkType . Url :
236+ result . Value = path + ( query . HasValue ( ) ? "?" + query : "" ) ;
237+ break ;
238+ case LinkType . File :
239+ result . Value = path ;
240+ result . QueryString = query ;
241+ break ;
242+ default :
243+ throw new SmartException ( "Unknown link builder type." ) ;
244+ }
193245
194- switch ( type )
195- {
196- case LinkType . Product :
197- case LinkType . Category :
198- case LinkType . Manufacturer :
199- case LinkType . Topic :
200- var id = value . ToInt ( ) ;
201- return new LinkResolverData { Type = type , Value = id != 0 ? ( object ) id : value , QueryString = queryString } ;
202- case LinkType . Url :
203- return new LinkResolverData { Type = type , Value = rawValue } ;
204- case LinkType . File :
205- return new LinkResolverData { Type = type , Value = value , QueryString = queryString } ;
206- default :
207- throw new SmartException ( "Unknown link builder type." ) ;
208- }
209- }
210- }
246+ return result ;
247+ }
248+ }
211249
212- return new LinkResolverData { Type = LinkType . Url , Value = linkExpression . EmptyNull ( ) } ;
250+ return new LinkResolverData { Type = LinkType . Url , Value = linkExpression . EmptyNull ( ) } ;
213251 }
214252
215253 internal void GetEntityData < T > ( LinkResolverData data , int languageId , Expression < Func < T , ResolverEntitySummary > > selector ) where T : BaseEntity
0 commit comments