Skip to content

Instantly share code, notes, and snippets.

@Grinderofl
Created March 19, 2018 13:32
Show Gist options
  • Save Grinderofl/ec749d7dd6f17fd37b609b8290ac221e to your computer and use it in GitHub Desktop.
Save Grinderofl/ec749d7dd6f17fd37b609b8290ac221e to your computer and use it in GitHub Desktop.
Episerver recently visited content
[ServiceConfiguration(typeof(RecentlyVisitedContentService))]
public class RecentlyVisitedContentService
{
private static ApplicationEnvironmentContext EnvironmentContext => new ApplicationEnvironmentContext();
private static string CookieKey => $".DotComRecents.{EnvironmentContext.CurrentEnvironment}.Cookie";
private static int MaximumEntries => 100;
private readonly ICookieService _cookieService;
private readonly IContentRouteHelper _routeHelper;
private readonly IContentLoader _contentLoader;
public RecentlyVisitedContentService(ICookieService cookieService, IContentRouteHelper routeHelper, IContentLoader contentLoader)
{
_cookieService = cookieService;
_routeHelper = routeHelper;
_contentLoader = contentLoader;
}
public void Track()
{
if (_routeHelper.Content == null || !ShouldRecordVisit(_routeHelper.Content))
return;
var recentlyVisited = GetRecentlyVisited();
// Ensure the page gets bumped to top
if (recentlyVisited.ContentIds.Contains(_routeHelper.Content.ContentGuid))
recentlyVisited.ContentIds.Remove(_routeHelper.Content.ContentGuid);
recentlyVisited.ContentIds.Add(_routeHelper.Content.ContentGuid);
if (recentlyVisited.ContentIds.Count > MaximumEntries)
recentlyVisited.ContentIds = recentlyVisited.ContentIds.Take(MaximumEntries).ToList();
_cookieService.Set(CookieKey, JsonConvert.SerializeObject(recentlyVisited));
}
private RecentlyVisitedContentCache GetRecentlyVisited()
{
var cookie = _cookieService.Get(CookieKey) ?? "";
var recentlyVisited = JsonConvert.DeserializeObject<RecentlyVisitedContentCache>(cookie) ?? new RecentlyVisitedContentCache();
return recentlyVisited;
}
/// <summary>
/// Returns visited pages, optionally limiting by max amount.
/// </summary>
/// <param name="count"></param>
/// <returns></returns>
public ICollection<RecentlyVisitedPageModel> VisitedPages(int? count = null)
{
count = count ?? int.MaxValue;
return GetRecentlyVisited().ContentIds
.Select(CreateRecentlyVisitedPage)
.Where(x => x != null)
.Take(count.Value)
.ToArray();
}
private RecentlyVisitedPageModel CreateRecentlyVisitedPage(Guid guid)
{
var item = _contentLoader.Get<IContent>(guid);
if (item == null)
return null;
if (item.IsDeleted)
return null;
var link = item.ContentLink;
var category = GetCategory(item);
var title = GetTitle(item);
if (link.IsNullOrEmpty() || category.IsNullOrWhiteSpace() || title.IsNullOrWhiteSpace())
return null;
return new RecentlyVisitedPageModel()
{
Title = title,
ContentLink = link,
Category = category
};
}
private string GetTitle(IContent item)
{
var tag = item as TaggablePageBase;
if (tag != null)
return tag.Title;
return item.Name;
}
private string GetCategory(IContent item)
{
if (item is EventPage)
return "Event";
var article = item as AbstractArticlePage;
if (article != null)
return article.ArticleCategory;
var product = item as ReportProduct;
if (product != null)
return product.Category;
var page = item as PageData;
if (page != null)
return "Page";
return null;
}
private bool ShouldRecordVisit(IContent page)
{
return page is PageData && page?.ContentLink != ContentReference.StartPage;
}
}
public class VisitedPageFilter : ActionFilterAttribute
{
/// <summary>Called by the ASP.NET MVC framework after the action method executes.</summary>
/// <param name="filterContext">The filter context.</param>
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
ServiceLocator.Current
.GetInstance<RecentlyVisitedContentService>()
.Track();
base.OnActionExecuted(filterContext);
}
}
public void Initialize(InitializationEngine context)
{
// ...
GlobalFilters.Filters.Add(new VisitedPageFilter());
// ...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment