skttl
7/5/2017 - 8:28 AM

Update LeBlender grid editors content from Nested Content 0.1 to Nested Content 0.2

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());

		}

	}
}