Taylohtio/CustomNavigationProvider/CustomNavigationCommon/FolderSorter.cs

167 lines
5.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.SharePoint;
namespace Taloyhtio.CustomNavigationCommon
{
// It sortes the folders based on SortOrder column added to content type.
// OTB Folder content type is sealed, so in order to be able manually rearrange
// folders sorting order custom content type should be created based on Folder content type.
// See http://sharepoint-guru.blogspot.com/2007/06/adding-metadata-to-folder.html for details
public static class FolderSorter
{
private const string ORDERED_FOLDER_CONTENT_TYPE_NAME = "Ordered Folder";
private const int DEFAULT_ORDER = 0;
private const string SORT_ORDER_FIELD_NAME = "SortOrder";
public static List<SPFolder> Sort(List<SPFolder> folders)
{
try
{
if (folders.IsNullOrEmpty())
{
return new List<SPFolder>();
}
// containts pairs (sortOrder, list of folders with that sortOrder)
var sortDict = new Dictionary<int, List<SPFolder>>();
int order;
foreach (var folder in folders)
{
var isOrdered = isOrderedFolder(folder);
if (isOrdered.HasValue && isOrdered.Value)
{
order = getOrder(folder);
}
else
{
// OTB folders are treated as having 0 order. They will be sorted after
// ordered folders
order = DEFAULT_ORDER;
}
addFolderWithOrder(sortDict, order, folder);
}
if (sortDict.IsNullOrEmpty())
{
// it should not happen
return new List<SPFolder>();
}
var result = sortFolders(sortDict);
return result;
}
catch (Exception x)
{
LogUtils.LogError("Error occured during sorting folders:\n{0}\n{1}",
x.Message, x.StackTrace);
return folders;
}
}
private static List<SPFolder> sortFolders(Dictionary<int, List<SPFolder>> sortDict)
{
if (sortDict.IsNullOrEmpty())
{
return new List<SPFolder>();
}
var result = new List<SPFolder>();
var orders = sortDict.Keys.ToList();
orders.Sort();
foreach (var order in orders)
{
if (order == DEFAULT_ORDER)
{
// folders with DEFAULT_ORDER are going last
continue;
}
addFoldersRange(sortDict, order, result);
}
if (orders.Contains(DEFAULT_ORDER))
{
addFoldersRange(sortDict, DEFAULT_ORDER, result);
}
return result;
}
private static void addFoldersRange(Dictionary<int, List<SPFolder>> sortDict, int order, List<SPFolder> result)
{
var folders = sortDict[order];
if (folders.IsNullOrEmpty())
{
return;
}
// within the same order folders are sorted alphabetically
var sortedFolders = folders.OrderBy(f => f.Name);
result.AddRange(sortedFolders);
}
private static void addFolderWithOrder(Dictionary<int, List<SPFolder>> sortDict, int order, SPFolder folder)
{
if (sortDict == null)
{
return;
}
if (!sortDict.ContainsKey(order))
{
sortDict[order] = new List<SPFolder>();
}
sortDict[order].Add(folder);
}
private static int getOrder(SPFolder folder)
{
try
{
if (folder == null)
{
return DEFAULT_ORDER;
}
if (!folder.Item.Fields.ContainsField(SORT_ORDER_FIELD_NAME))
{
return DEFAULT_ORDER;
}
var val = folder.Item[SORT_ORDER_FIELD_NAME] as double?;
if (!val.HasValue)
{
return DEFAULT_ORDER;
}
int order = Convert.ToInt32(val.Value);
if (order < 0)
{
order = 0;
}
return order;
}
catch (Exception x)
{
//LogUtils.LogError(x);
return DEFAULT_ORDER;
}
}
private static bool? isOrderedFolder(SPFolder folder)
{
try
{
if (folder == null)
{
return null;
}
string contentTypeName = (string)folder.Item[SPBuiltInFieldId.ContentType];
return (contentTypeName == ORDERED_FOLDER_CONTENT_TYPE_NAME);
}
catch (Exception x)
{
//LogUtils.LogError(x);
return null;
}
}
}
}