167 lines
5.3 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
}
|