danwhite85
8/13/2015 - 10:00 AM

Umbraco Caching AtoZ Helper and Partial

Umbraco Caching AtoZ Helper and Partial

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using Umbraco.Core;
using Umbraco.Web.Mvc;
using Umbraco.Web;
using System.Web.Mvc;

using System.Web.Caching;
using System.Web.Configuration;
using Umbraco.Core.Logging;

using System.Diagnostics;
using umbraco.interfaces;
using Umbraco.Core.Services;
using Umbraco.Core.Events;
using Umbraco.Core.Publishing;
using Umbraco.Core.Models;

namespace Jumoo.UmbLocalGov
{
    // helper class, clears the cache - when things are published. 
    public class LocalGovTools : ApplicationEventHandler
    {
        protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
        {
            ContentService.Published += ContentServicePublishEvent;
            ContentService.UnPublished += ContentServicePublishEvent;
        }

        private void ContentServicePublishEvent(IPublishingStrategy sender, PublishEventArgs<IContent> args)
        {
            // Clear all AtoZs

            // could be cleverer - the cache has the root ID in it, so you could just clear caches where
            // the ID is a parent of the current page - not sure it makes much diffrence, because the 
            // rebuild only happens once, and it doesn't take 'that' long
            ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheByKeySearch("AtoZPages");
        }
    }


    // AtoZ 
    public static class AtoZHelper 
    {

        private static SortedDictionary<string, string> GetAtoZPages(UmbracoHelper umbHelper, string[] excludedTypes)
        {
            var root = umbHelper.TypedContentAtRoot().First();
            return GetAtoZPages(umbHelper, excludedTypes, root);
        }

        private static SortedDictionary<string, string> GetAtoZPages(UmbracoHelper umbHelper, string[] excludedTypes, IPublishedContent root)
        {
            var cacheName = string.Format("AtoZPages_{0}", root.Id);

            var cache = ApplicationContext.Current.ApplicationCache;
            SortedDictionary<string, string> azPages = cache.GetCacheItem <SortedDictionary<string, string>>(cacheName);

            if (azPages == null)
            {
                Stopwatch sw = new Stopwatch();
                sw.Start();
                
                // if its not in the cache build it.
                azPages = new SortedDictionary<string, string>();

                var sitePages = root.Descendants().Where(
                    x => x.IsVisible() 
                        && !excludedTypes.Contains(x.DocumentTypeAlias) 
                        && x.GetPropertyValue<bool>("includeInAtoZ"));

                foreach (var page in sitePages)
                {
                    var title = page.GetPropertyValue<string>("title", page.Name);
                    if (!azPages.ContainsKey(title))
                    {
                        azPages.Add(title.Trim(), page.Url);
                    }

                    if (page.HasProperty("aZNames"))
                    {
                        string[] others = page.GetPropertyValue<String>("aZNames")
                            .Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                        foreach (var entry in others)
                        {
                            if (!azPages.ContainsKey(entry))
                            {
                                azPages.Add(entry.Trim(), page.Url + "#" + entry.Trim() );
                            }
                        }
                    }
                }

                cache.InsertCacheItem<SortedDictionary<string, string>>(cacheName, CacheItemPriority.Default, () => azPages);
                sw.Stop();
                LogHelper.Info<LocalGovTools>("AtoZ Cache [{1}] {2} entries for {3} pages, built {0}ms", () => sw.ElapsedMilliseconds, ()=> cacheName, ()=> azPages.Count(), ()=> sitePages.Count() );
            }

            return azPages; 
        }

        public static SortedDictionary<string, string> GetAtoZEntries(this UmbracoHelper umbraco, string letter)
        {
            return GetAtoZEntries(umbraco, letter, new string[] { });
        }

        public static SortedDictionary<string,string> GetAtoZEntries(this UmbracoHelper umbraco, string letter, string[] exclude, IPublishedContent root)
        {
            SortedDictionary<string, string> AtoZ = GetAtoZPages(umbraco, exclude, root);

            SortedDictionary<string, string> filteredPages = new SortedDictionary<string, string>();
            foreach(var entry in AtoZ.Where(x => x.Key.ToLower().StartsWith(letter.ToLower())))
            {
                filteredPages.Add(entry.Key, entry.Value);
            }
            return filteredPages;
        }

        public static SortedDictionary<string, string>GetAtoZEntries(this UmbracoHelper umbraco, string letter, string[] exclude)
        {
            var root = umbraco.TypedContentAtRoot().First();
            return GetAtoZEntries(umbraco, letter, exclude, root);
        }
    }
}
@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@using Jumoo.UmbLocalGov;
@{
    var letter = Request.QueryString["letter"];

    if (!string.IsNullOrWhiteSpace(letter))
    {
        <h2>@letter.ToUpper()</h2>

        // get everthing with the letter.
        var entries = Umbraco.GetAtoZEntries(letter, new string[] { "DataTypeToIgnore" } );

        if (entries.Any()) { 
            <ul class="atoz-entries">
                @foreach(var entry in entries)
                {
                <li><a href="@entry.Value">@entry.Key</a></li>
                }
            </ul>
        }
        else
        {
            <div class="alert alert-error">No Entries found</div>
        }
    }
}