Skip to content

Instantly share code, notes, and snippets.

@tahirnaveed
Created February 23, 2016 14:23
Show Gist options
  • Save tahirnaveed/62162bfd5c40e1302aa5 to your computer and use it in GitHub Desktop.
Save tahirnaveed/62162bfd5c40e1302aa5 to your computer and use it in GitHub Desktop.
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
//Tip: Want to call the EPiServer API on startup? Add an initialization module instead (Add -> New Item.. -> EPiServer -> Initialization Module)
}
protected override void RegisterRoutes(RouteCollection routes)
{
base.RegisterRoutes(routes);
routes.MapRoute("ObjectBrowser", "ObjectBrowser/{action}",
new { controller = "ObjectBrowser", action = "Index" });
}
<!DOCTYPE html>
<html>
<head>
<title>Object Browser</title>
</head>
@{
Layout = null;
}
@using EPiServer.DataAbstraction
@using EPiServer.ServiceLocation
@model Dictionary<int, EPiServerSite2.Controllers.TypeTree>
<body>
<label>
<input type="checkbox" /> Hide Orphan properties
<input type="checkbox" /> Delete Orphan properties
</label>
<ul>
@foreach (var v in Model)
{
<li>
@{
var pageTypeId = v.Key;
var contentTypeRepository = ServiceLocator.Current.GetInstance<IContentTypeRepository>();
var contentType = contentTypeRepository.Load(pageTypeId);
}
<h2>@contentType.FullName</h2>
<ul>
@{
var tree = v.Value;
do
{
<li>
<h4> @tree.Type.FullName</h4>
<ul>
@{
foreach (var propertyDefinition in tree.AllProperties)
{
var style = string.Empty;
if (!propertyDefinition.ExistsOnModel)
{
style = "red";
}
<li data-propertyname="@propertyDefinition.Name" data-contenttypeguid="@contentType.GUID" data-existsonmodel="@propertyDefinition.ExistsOnModel" style="color: @style">@propertyDefinition.Name</li>
}
}
</ul>
</li>
tree = tree.BaseType;
} while (tree != null);
}
</ul>
</li>
}
</ul>
</body>
</html>
[GuiPlugIn(Area = PlugInArea.AdminMenu, Url = "/ObjectBrowser/Index", DisplayName = "Object Browser")]
// [Authorize(Roles = "WebAdmins")]
public class ObjectBrowserController : Controller
{
public ActionResult Index()
{
var allDict = new Dictionary<int, TypeTree>();
var pageTypes = GetAllPageTypes();
foreach (var ct in pageTypes.Where(x => x.ModelType != null).OrderBy(x => x.Name))
{
var dictionary = ct.Populate();
allDict.Add(ct.ID, dictionary);
}
return View(allDict);
}
private IEnumerable<ContentType> GetAllPageTypes()
{
var contentTypeRepository = ServiceLocator.Current.GetInstance<IContentTypeRepository>();
return contentTypeRepository.List().OfType<ContentType>();
}
}
public class TypeTree
{
public TypeTree()
{
AllProperties = new List<PropertyDefinition>();
}
public Type Type { get; set; }
public TypeTree BaseType { get; set; }
public IList<PropertyDefinition> AllProperties { get; set; }
}
public static class ExtensionMethods
{
public static TypeTree Populate(this ContentType ct)
{
var populateTree = PopulateTree(ct.ModelType);
PopulateTreeProperties(populateTree, ct);
return populateTree;
}
private static TypeTree PopulateTree(Type type)
{
var root = new TypeTree();
root.Type = type;
var tempVar = root;
var baseClassesAndInterfaces = type.GetParentTypes().ToList();
foreach (var baseClassesAndInterface in baseClassesAndInterfaces)
{
var node = new TypeTree();
node.Type = baseClassesAndInterface;
tempVar.BaseType = node;
tempVar = node;
}
return root;
}
public static IEnumerable<Type> GetParentTypes(this Type type)
{
// is there any base type?
if ((type == null) || (type.BaseType == null))
{
yield break;
}
// return all implemented or inherited interfaces
//foreach (var i in type.GetInterfaces())
//{
// yield return i;
//}
// return all inherited types
var currentBaseType = type.BaseType;
while (currentBaseType != null)
{
if (currentBaseType == typeof (ContentData) || currentBaseType == typeof (MediaData))
yield break;
yield return currentBaseType;
currentBaseType = currentBaseType.BaseType;
}
}
private static void PopulateTreeProperties(TypeTree tree, ContentType ct)
{
List<PropertyData> list = new EditableList<PropertyData>();
foreach (var pd in ct.PropertyDefinitions)
{
var d = new PropertyData();
d.Property = pd;
d.DefinedIn = FindType(ct.ModelType, pd);
list.Add(d);
}
var propertiesWithNoCodeBehind = list.Where(x => x.DefinedIn == null).Select(x => x.Property);
tree.AllProperties.AddRange(propertiesWithNoCodeBehind);
var myTree = tree;
do
{
var propertyDefinitions = list.Where(x => x.DefinedIn == myTree.Type).Select(x => x.Property);
myTree.AllProperties.AddRange(propertyDefinitions);
myTree = myTree.BaseType;
} while (myTree != null);
}
private static Type FindType(Type modelType, PropertyDefinition propertyDefinition)
{
if (modelType == null)
{
return null;
}
var allPublicProperties = GetAllPublicProperties(modelType);
var isExists = allPublicProperties.Any(x => x.Name == propertyDefinition.Name);
if (isExists)
{
return modelType;
}
return FindType(modelType.BaseType, propertyDefinition);
}
private static PropertyInfo[] GetAllPublicProperties(Type t)
{
// get all public static properties of MyClass type
var propertyInfos = t.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
// sort properties by name
Array.Sort(propertyInfos,
(propertyInfo1, propertyInfo2) =>
string.Compare(propertyInfo1.Name, propertyInfo2.Name, StringComparison.Ordinal));
return propertyInfos;
}
}
public class PropertyData
{
public PropertyDefinition Property { get; set; }
public Type DefinedIn { get; set; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment