Update LeBlender grid editors content from Nested Content 0.1 to Nested Content 0.2
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using Umbraco.Web.WebApi;
using Umbraco.Core;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Project.App_Code
{
public class UpdateGridItemController : UmbracoApiController
{
[HttpGet]
public string GetUpdate()
{
var result = new StringBuilder();
var cs = ApplicationContext.Current.Services.ContentService;
// Here I find all the pages in my solution, but filter out those that I know doesn't contain a grid
var pages = cs.GetRootContent().SelectMany(x => cs.GetDescendants(x)).Where(x => x.ContentType.Alias != "DocTypeWithoutGridEditor");
foreach (var page in pages)
{
// Set a variable to remember if I change a page. If I don't change it, there is no reason to waste resources by saving and publishing again.
var changed = false;
// check if the page has the property containing the grid
if (page.HasProperty("content"))
{
try
{
result.AppendLine("--");
result.AppendLine(page.Name);
// if the grid is empty, it should just skip the page
if (string.IsNullOrEmpty(page.GetValue("content").ToString()))
{
result.AppendLine("no content");
}
else
{
// convert the grid to json
var grid = JsonConvert.DeserializeObject<dynamic>(page.GetValue("content").ToString());
// then traverse through the grid
for (var s = 0; s < grid.sections.Count; s++)
{
for (var r = 0; r < grid.sections[s].rows.Count; r++)
{
for (var a = 0; a < grid.sections[s].rows[r].areas.Count; a++)
{
for (var c = 0; c < grid.sections[s].rows[r].areas[a].controls.Count; c++)
{
// check each control, if it's one of my Nested Content enabled editors.
// for each found, add the property ncContentTypeAlias with the right content type alias, to make Nested Content work
string alias = grid.sections[s].rows[r].areas[a].controls[c].editor.alias;
switch (alias)
{
case "editorWithNestedContent":
result.AppendLine("Found editorWithNestedContent");
for (var v = 0; v < grid.sections[s].rows[r].areas[a].controls[c].value[0].paragraphs.value.Count; v++)
{
grid.sections[s].rows[r].areas[a].controls[c].value[0].paragraphs.value[v].Add(new JProperty("ncContentTypeAlias", "NestedContentDocTypeAlias"));
changed = true;
}
break;
}
}
}
}
}
result.AppendLine("changed: " + changed);
if (changed)
{
// if the content is changed, save and publish it. Remember to raise events, so a revision is made, and rollback will be possible.
page.SetValue("content", (object)JsonConvert.SerializeObject(grid));
cs.SaveAndPublishWithStatus(page, 0, true);
result.AppendLine("SAVED");
}
}
}
// the whole thing is wrapped in try/catch, because I expect some of them to break.
catch (Exception e)
{
// when something breaks, show me the exception, except if it's an exception I can live with (if the ncContentTypeAlias property already exists).
result.AppendLine("--");
result.AppendLine(page.Name + " failed " + page.Id);
if (!e.ToString().Contains("Property with the same name already exists on object"))
{
result.AppendLine(e.ToString());
}
}
}
}
HttpContext.Current.Response.ContentType = "text/html";
return Umbraco.ReplaceLineBreaksForHtml(result.ToString());
}
}
}