Created
February 23, 2016 14:23
-
-
Save tahirnaveed/62162bfd5c40e1302aa5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" }); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[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>(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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