This repository was archived by the owner on Aug 17, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 95
Expand file tree
/
Copy pathSiteInitialization.cs
More file actions
233 lines (196 loc) · 10.3 KB
/
SiteInitialization.cs
File metadata and controls
233 lines (196 loc) · 10.3 KB
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
using EPiServer.Commerce.Marketing;
using EPiServer.Commerce.Marketing.Promotions;
using EPiServer.Commerce.Routing;
using EPiServer.Editor;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.Framework.Web;
using EPiServer.Globalization;
using EPiServer.Personalization.Commerce;
using EPiServer.Personalization.Commerce.Widgets;
using EPiServer.Reference.Commerce.Site.Features.Market.Services;
using EPiServer.Reference.Commerce.Site.Features.Recommendations.Services;
using EPiServer.Reference.Commerce.Site.Infrastructure.Attributes;
using EPiServer.Reference.Commerce.Site.Infrastructure.Facades;
using EPiServer.Reference.Commerce.Site.Infrastructure.WebApi;
using EPiServer.ServiceLocation;
using EPiServer.Tracking.Commerce;
using EPiServer.Web;
using EPiServer.Web.Routing;
using Mediachase.Commerce;
using Mediachase.Commerce.Core;
using Newtonsoft.Json;
using System;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.WebPages;
using EPiServer.Personalization.Commerce.Tracking;
namespace EPiServer.Reference.Commerce.Site.Infrastructure
{
[ModuleDependency(typeof(EPiServer.Commerce.Initialization.InitializationModule))]
public class SiteInitialization : IConfigurableModule
{
public void Initialize(InitializationEngine context)
{
CatalogRouteHelper.MapDefaultHierarchialRouter(RouteTable.Routes, false);
GlobalFilters.Filters.Add(new HandleErrorAttribute());
GlobalFilters.Filters.Add(new ReadOnlyFilter());
GlobalFilters.Filters.Add(new AJAXLocalizationFilterAttribute());
context.Locate.Advanced.GetInstance<IDisplayChannelService>().RegisterDisplayMode(new DefaultDisplayMode(RenderingTags.Mobile)
{
ContextCondition = r => r.GetOverriddenBrowser().IsMobileDevice
});
AreaRegistration.RegisterAllAreas();
context.Locate.Advanced.GetInstance<OrderEventListener>().AddEvents();
#if DISABLE_PROMOTION_TYPES_FEATURE
DisablePromotionTypes(context);
#endif
#if EXCLUDE_ITEMS_FROM_PROMOTION_ENGINE_FEATURE
SetupExcludePromotionEntries(context);
#endif
#if ACTIVATE_DEFAULT_PERSONALIZATION_WIDGETS_FEATURE
SetupPersonalizationsWidgets(context);
#endif
}
public void ConfigureContainer(ServiceConfigurationContext context)
{
var services = context.Services;
services.AddSingleton<IRecommendationContext, RecommendationContext>();
services.AddSingleton<ICurrentMarket, CurrentMarket>();
services.AddSingleton<ITrackingResponseDataInterceptor, TrackingResponseDataInterceptor>();
//Register for auto injection of edit mode check, should be default life cycle (per request to service locator)
services.AddTransient<IsInEditModeAccessor>(locator => () => PageEditing.PageIsInEditMode);
services.Intercept<IUpdateCurrentLanguage>(
(locator, defaultImplementation) =>
new LanguageService(
locator.GetInstance<ICurrentMarket>(),
locator.GetInstance<CookieService>(),
defaultImplementation));
services.AddTransient<IModelBinderProvider, ModelBinderProvider>();
services.AddHttpContextOrThreadScoped<SiteContext, CustomCurrencySiteContext>();
services.AddTransient<HttpContextBase>(locator => HttpContext.Current.ContextBaseOrNull());
services.AddSingleton<ServiceAccessor<IContentRouteHelper>>(locator => locator.GetInstance<IContentRouteHelper>);
DependencyResolver.SetResolver(new StructureMapDependencyResolver(context.StructureMap()));
GlobalConfiguration.Configure(config =>
{
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.LocalOnly;
config.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings();
config.Formatters.XmlFormatter.UseXmlSerializer = true;
config.DependencyResolver = new StructureMapResolver(context.StructureMap());
config.MapHttpAttributeRoutes();
});
#if IRI_CHARACTERS_IN_URL_FEATURE
EnableIriCharactersInUrls(context);
#endif
}
public void Uninitialize(InitializationEngine context)
{
context.Locate.Advanced.GetInstance<OrderEventListener>().RemoveEvents();
}
/// <summary>
/// Enables the IRI characters in Urls.
/// </summary>
/// <param name="context">The service configuration context.</param>
/// <remarks>
/// To use this feature, define IRI_CHARACTERS_IN_URL_FEATURE symbol - this should be done both in Commerce Manager and Front-end sites.
/// More information about this feature: http://world.episerver.com/documentation/developer-guides/CMS/routing/internationalized-resource-identifiers-iris/
/// To support more Unicode blocks, update the regular expression for ValidCharacters.
/// For example, to support Thai Unicode block, add \p{IsThai} to it.
/// The supported Unicode blocks can be found here: https://msdn.microsoft.com/en-us/library/20bw873z(v=vs.110).aspx#Anchor_12
/// </remarks>
private void EnableIriCharactersInUrls(ServiceConfigurationContext context)
{
context.Services.RemoveAll<UrlSegmentOptions>();
context.Services.AddSingleton(s => new UrlSegmentOptions
{
SupportIriCharacters = true,
ValidCharacters = @"\p{L}0-9\-_~\.\$"
});
}
/// <summary>
/// Disables promotion types.
/// </summary>
/// <param name="context">The initialization engine.</param>
/// <remarks>
/// To use this feature, define DISABLE_PROMOTION_TYPES_FEATURE symbol.
/// </remarks>
private void DisablePromotionTypes(InitializationEngine context)
{
var promotionTypeHandler = context.Locate.Advanced.GetInstance<PromotionTypeHandler>();
// To disable one of the built-in promotion types, for example the BuyQuantityGetFreeItems promotion.
promotionTypeHandler.DisablePromotions(new[] { typeof(BuyQuantityGetFreeItems) });
// To disable all built-in promotion types.
promotionTypeHandler.DisableBuiltinPromotions();
}
/// <summary>
/// Excludes items from promotion engine.
/// </summary>
/// <param name="context">The initialization engine.</param>
/// <remarks>
/// To use this feature, define EXCLUDE_ITEMS_FROM_PROMOTION_ENGINE_FEATURE symbol.
/// </remarks>
private void SetupExcludePromotionEntries(InitializationEngine context)
{
//To exclude some entries from promotion engine we need an implementation of IEntryFilter.
//In most cases you can just use EntryFilterSettings to configure the default implementation. Otherwise you can create your own implementation of IEntryFilter if needed.
//var filterSettings = context.Locate.Advanced.GetInstance<EntryFilterSettings>();
//filterSettings.ClearFilters();
//Add filter predicates for a whole content type.
//filterSettings.AddFilter<TypeThatShouldNeverBeIncluded>(x => false);
//Add filter predicates based on any property of the content type, including implemented interfaces.
//filterSettings.AddFilter<IInterfaceThatCanBeImplementedToDetermineExclusion>(x => !x.ShouldBeExcluded);
//Add filter predicates based on meta fields that are not part of the content type models, e.g. if the field is dynamically added to entries in an import or integration.
//filterSettings.AddFilter<EntryContentBase>(x => !(bool)(x["ShouldBeExcludedPromotionMetaField"] ?? false));
//Add filter predicates base on codes like below.
//var ExcludingCodes = new string[] { "SKU-36127195", "SKU-39850363", "SKU-39101253" };
//filterSettings.AddFilter<EntryContentBase>(x => !ExcludingCodes.Contains(x.Code));
}
/// <summary>
/// Creates and activates the default Personalization widgets.
/// </summary>
/// <param name="context">The initialization engine.</param>
/// <remarks>
/// To use this feature, define ACTIVATE_DEFAULT_PERSONALIZATION_WIDGETS_FEATURE symbol.
/// It only needs to run once, not upon every initialization, and only if you use the Recommendations feature.
/// Instructions:
/// Enter the configuration values for Personalization in web.config.
/// Make sure that the episerver:tracking.Enabled setting is set to true, and other personalization settings have proper values.
/// </remarks>
private void SetupPersonalizationWidgets(InitializationEngine context)
{
var configuration = context.Locate.Advanced.GetInstance<PersonalizationClientConfiguration>();
if (!configuration.TrackingEnabled)
{
return;
}
foreach (var scope in configuration.GetScopes())
{
var widgetService = context.Locate.Advanced.GetInstance<WidgetService>();
var response = widgetService.CreateWidgets(scope);
if (response.Status != "OK")
{
var error = response.Errors.First();
var message = new StringBuilder($"Code: {error.Code}, Message: {error.Error}");
if (error.Field != null)
{
message.Append($", Field: {error.Field}");
}
throw new Exception(message.ToString());
}
foreach (var widget in response.EpiPerPage.Pages.SelectMany(x => x.Widgets))
{
widget.Active = true;
var success = widgetService.UpdateWidget(widget, scope);
if (!success)
{
throw new Exception($"Failed to activate widget {widget.WidgetName}");
}
}
}
}
}
}