Skip to content

Instantly share code, notes, and snippets.

@Silverstriper
Created March 12, 2016 21:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Silverstriper/f19d199a2a24f3630ec1 to your computer and use it in GitHub Desktop.
Save Silverstriper/f19d199a2a24f3630ec1 to your computer and use it in GitHub Desktop.
MaintenanceServicesAPIController is a collection of methods used in the upgrade path of an Umbraco 6.x version site into the Umbraco 7.x realm. This code was written to move from 6.1.6 to 7.2.4, but it may be useful for someone else as reference.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Mvc;
using Umbraco.Core.Models;
using Umbraco.Web;
using Examine;
using Examine.LuceneEngine;
using Examine.LuceneEngine.Providers;
using Examine.Providers;
using Lucene.Net.Search;
using Umbraco.Core;
using Umbraco.Web.Search;
using Umbraco.Web.WebApi;
using log4net;
using System.Reflection;
using System.Xml;
using System.Text;
using System.Collections.Specialized;
using System.Threading;
using System.Threading.Tasks;
using System.Net.Sockets;
using Umbraco.Core.Configuration;
using Umbraco.Core.Services;
using System.Xml.Serialization;
using System.IO;
using System.Xml.Linq;
using System.Web.Script.Serialization;
using umbraco.cms.businesslogic.web;
using umbraco.BusinessLogic;
namespace MaintenanceServices.Logic.Controllers
{
public class MaintenanceServicesAPIController : UmbracoApiController
{
//NOTE: "root" is declared in many instances here as the top level node. We call it the "SiteConfig" and all pages sit under that one root node.
//SetUp Logging for to the UmbracoTraceLog
private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
#region Informational Services (Return Items in Draft / Unpublished)
/// <summary>
/// ListDraftItems returns a JSON response with all Items currently in Draft State
/// </summary>
/// <returns></returns>
[HttpPost]
public HttpResponseMessage ListDraftItems(int startNode)
{
//Define an Umbraco Context to Help us Navigate Content
UmbracoHelper help = new UmbracoHelper(UmbracoContext);
var root = help.TypedContentAtRoot().Single(x => x.DocumentTypeAlias == "SiteConfig");
if (startNode == null)
{
startNode = root.Id;
}
List<string> NodesInDraftState = new List<string>();
var contentService = Services.ContentService;
var targetNodes = contentService.GetDescendants(startNode);
foreach (var item in targetNodes)
{
//The logic here is as follows
// Draft Items return False for the "Published" State, but they do have a Published Version
if (!item.Published && contentService.HasPublishedVersion(item.Id))
{
NodesInDraftState.Add(item.Name + " :: " + item.Id);
}
}
//Build up the result for the Web Service Return.
Dictionary<string, List<string>> result = new Dictionary<string, List<string>>();
result.Add("Drafts", NodesInDraftState);
return Request.CreateResponse(HttpStatusCode.OK, result);
}
/// <summary>
/// ListUnPublishedItems returns a JSON response with all Items currently in Unpublished
/// </summary>
/// <returns></returns>
[HttpPost]
public HttpResponseMessage ListUnPublishedItems()
{
//Define an Umbraco Context to Help us Navigate Content
UmbracoHelper help = new UmbracoHelper(UmbracoContext);
var root = help.TypedContentAtRoot().Single(x => x.DocumentTypeAlias == "SiteConfig");
List<string> NodesUnPublished = new List<string>();
var contentService = Services.ContentService;
var targetNodes = contentService.GetDescendants(root.Id);
foreach (var item in targetNodes)
{
//The logic here is as follows
// Unpublished Items return False for the "Published" State, and have no Published Version
if (!item.Published && !contentService.HasPublishedVersion(item.Id))
{
NodesUnPublished.Add(item.Id.ToString());
}
}
//Build up the result for the Web Service Return.
string NodesUnPublishedCSV = String.Join(",", NodesUnPublished);
Dictionary<string, string> result = new Dictionary<string, string>();
result.Add("Unpublished", NodesUnPublishedCSV);
return Request.CreateResponse(HttpStatusCode.OK, result);
}
#endregion
#region Umbraco7 Upgrade Helpers
//This section is dedicated to functions that will assist in the migration to Umbraco 7 from 6.x
//At the initial outset this looks to be a collection of ContentService Updates
/// <summary>
/// Migrate7MultiURLPicker targets to celan up the data elements of MultiURl Pickers.
/// Turns a Ucomponents Multi-URL Picker into a Related Links Data Type.
/// Pass in the DocumentType and the DocumentTypeAlias to convert.
/// Sample: /umbraco/api/MaintenanceServicesAPI/Migrate7MultiURLPicker?DocumentType=SiteConfig&DocumentTypeAlias=tertiaryNavigation
/// </summary>
/// <returns></returns>
[HttpPost]
public HttpResponseMessage Migrate7MultiURLPicker(string DocumentType, string DocumentTypeAlias)
{
//Define an Umbraco Context to Help us Navigate Content
UmbracoHelper help = new UmbracoHelper(UmbracoContext);
var root = help.TypedContentAtRoot().Single(x => x.DocumentTypeAlias == "SiteConfig");
List<string> NodesSuccessfullyUpdated = new List<string>();
List<string> NodesFailedUpdated = new List<string>();
var contentType = Services.ContentTypeService.GetContentType(DocumentType).Id;
var contentService = Services.ContentService;
var targetNodes = contentService.GetContentOfContentType(contentType);
foreach (var item in targetNodes)
{
//Only Proceed If the Item is Published Currently
if (item.Published && contentService.HasPublishedVersion(item.Id))
{
var thisItem = contentService.GetById(item.Id);
var thisNavigation = thisItem.GetValue(DocumentTypeAlias);
var relatedLinks = new List<RLinks>();
try
{
XElement nodes = XElement.Parse(thisNavigation.ToString());
foreach (var node in nodes.Elements("url-picker"))
{
var linkType = node.Attribute("mode").Value;
if (linkType == "Content")
{
//Process as Internal Content
relatedLinks.Add(new RLinks()
{
caption = node.Element("link-title").Value,
edit = false,
link = node.Element("node-id").Value,
isInternal = true,
Internal = node.Element("node-id").Value,
newWindow = (bool)node.Element("new-window"),
title = node.Element("link-title").Value,
type = "internal",
internalName = node.Element("link-title").Value
});
}
else
{
//Process as External Link
relatedLinks.Add(new RLinks()
{
caption = node.Element("link-title").Value,
edit = false,
link = node.Element("url").Value,
isInternal = false,
newWindow = (bool)node.Element("new-window"),
title = node.Element("link-title").Value,
type = "external"
});
}
// encode the object to Json format, Remember to convert Internal to => internal, and isinternal => to isInternal
var json = new JavaScriptSerializer().Serialize(relatedLinks).Replace("Internal", "internal").Replace("isinternal", "isInternal");
thisItem.SetValue(DocumentTypeAlias, json);
contentService.SaveAndPublishWithStatus(thisItem);
NodesSuccessfullyUpdated.Add(json);
}
}
catch
{
return Request.CreateResponse(HttpStatusCode.NotFound, "Nodes were not in XML Format - May have already been converted");
}
}
else
{
var thisItem = contentService.GetById(item.Id);
NodesFailedUpdated.Add(thisItem.Name + " :: " + thisItem.Id);
}
}
//Build up the result for the Web Service Return.
Dictionary<string, List<string>> result = new Dictionary<string, List<string>>();
result.Add("Fail", NodesFailedUpdated);
result.Add("Success", NodesSuccessfullyUpdated);
return Request.CreateResponse(HttpStatusCode.OK, result);
}
/// <summary>
/// Migrate7GoogleMapsDataType targets to clean up the data elements of Google Map Data Type.
/// In particular this Function will strip the zoom value and only preserve the lat and long, comma delimited.
/// Depends what GoogleMaps Package you use whether you need to run this or not.
/// "locationItem" is the name of the DocumentTypeAlias we are targetting.
/// </summary>
/// <returns></returns>
[HttpPost]
public HttpResponseMessage Migrate7GoogleMapsDataType()
{
//Define an Umbraco Context to Help us Navigate Content
UmbracoHelper help = new UmbracoHelper(UmbracoContext);
var root = help.TypedContentAtRoot().Single(x => x.DocumentTypeAlias == "SiteConfig");
List<string> NodesSuccessfullyUpdated = new List<string>();
List<string> NodesFailedUpdated = new List<string>();
var contentType = Services.ContentTypeService.GetContentType("locationItem").Id;
var contentService = Services.ContentService;
var locationNodes = contentService.GetContentOfContentType(contentType);
foreach (var item in locationNodes)
{
var thisItem = contentService.GetById(item.Id);
var currentCoordinates = thisItem.GetValue("coordinates");
var currentCoordinatesAsString = string.Empty;
if (currentCoordinates != null)
{
currentCoordinatesAsString = currentCoordinates.ToString();
}
string[] coords = currentCoordinatesAsString.Split(',').ToArray();
////Safety Check - essentially only perform the following for coords with Lat,Long,Zoom
//if (coords.Length > 2)
//{
// string[] newCoords = coords.Reverse().Skip(1).Reverse().ToArray();
// var updatedCoords = (string.Join(",", newCoords));
// thisItem.SetValue("coordinates", updatedCoords);
// contentService.SaveAndPublishWithStatus(thisItem);
// NodesSuccessfullyUpdated.Add(item.Name);
//}
//else
//{
// NodesFailedUpdated.Add(item.Name);
//}
if (coords.Length == 2)
{
//string[] newCoords = coords.Reverse().Skip(1).Reverse().ToArray();
var updatedCoords = (string.Join(",", coords));
updatedCoords = updatedCoords + ", 13";
thisItem.SetValue("coordinates", updatedCoords);
contentService.SaveAndPublishWithStatus(thisItem);
NodesSuccessfullyUpdated.Add(item.Name + " :: " + updatedCoords);
}
else
{
NodesFailedUpdated.Add(item.Name + " :: " + currentCoordinatesAsString);
}
}
//Build up the result for the Web Service Return.
Dictionary<string, List<string>> result = new Dictionary<string, List<string>>();
result.Add("Success", NodesSuccessfullyUpdated);
result.Add("Fail", NodesFailedUpdated);
return Request.CreateResponse(HttpStatusCode.OK, result);
}
/// <summary>
/// Migrate7URLPicker targets to celan up the data elements of MultiURl Pickers.
/// Turns a Ucomponents URL Picker into a URL Picker from Imulus UrlPicker - https://github.com/imulus/uWestFest/tree/master/urlpicker.
/// Sample: /umbraco/api/MaintenanceServicesAPI/Migrate7URLPicker?DocumentType=SiteConfig&DocumentTypeAlias=contactUsPrimaryForm
/// </summary>
/// <returns></returns>
[HttpPost]
public HttpResponseMessage Migrate7URLPicker(string DocumentType, string DocumentTypeAlias)
{
//Define an Umbraco Context to Help us Navigate Content
UmbracoHelper help = new UmbracoHelper(UmbracoContext);
var root = help.TypedContentAtRoot().Single(x => x.DocumentTypeAlias == "SiteConfig");
List<string> NodesSuccessfullyUpdated = new List<string>();
List<string> NodesFailedUpdated = new List<string>();
//Step 3 - Now the security checks are confirmed let's get to business
var contentType = Services.ContentTypeService.GetContentType(DocumentType).Id;
var contentService = Services.ContentService;
var targetNodes = contentService.GetContentOfContentType(contentType);
foreach (var item in targetNodes)
{
if (item.Published && contentService.HasPublishedVersion(item.Id))
{
UrlPickerTemp urlPicker = new UrlPickerTemp();
Meta urlPickerMeta = new Meta();
TypeData urlPickerTypeData = new TypeData();
var thisItem = contentService.GetById(item.Id);
var thisNavigation = thisItem.GetValue(DocumentTypeAlias);
try
{
XElement node = XElement.Parse(thisNavigation.ToString());
var linkType = node.Attribute("mode").Value;
if (linkType == "Content")
{
urlPickerMeta.title = node.Element("link-title").Value;
urlPickerMeta.newWindow = (bool)node.Element("new-window");
urlPickerTypeData.contentId = Convert.ToInt32(node.Element("node-id").Value);
//Process as Internal Content
urlPicker.type = "content";
urlPicker.meta = urlPickerMeta;
urlPicker.typeData = urlPickerTypeData;
}
else if (linkType == "URL")
{
urlPickerMeta.title = node.Element("link-title").Value;
urlPickerMeta.newWindow = (bool)node.Element("new-window");
urlPickerTypeData.url = node.Element("url").Value;
//Process as External Link
urlPicker.type = "url";
urlPicker.meta = urlPickerMeta;
urlPicker.typeData = urlPickerTypeData;
}
else if (linkType == "Media")
{
urlPickerMeta.title = node.Element("link-title").Value;
urlPickerMeta.newWindow = (bool)node.Element("new-window");
urlPickerTypeData.contentId = Convert.ToInt32(node.Element("node-id").Value);
//Process as External Link
urlPicker.type = "media";
urlPicker.meta = urlPickerMeta;
urlPicker.typeData = urlPickerTypeData;
}
// encode the object to Json format, Remember to convert Internal to => internal, and isinternal => to isInternal
var json = new JavaScriptSerializer().Serialize(urlPicker);
//Persist the updates to the Server and DB
thisItem.SetValue(DocumentTypeAlias, json);
contentService.SaveAndPublishWithStatus(thisItem);
NodesSuccessfullyUpdated.Add(thisNavigation.ToString());
NodesSuccessfullyUpdated.Add(json);
}
catch
{
if (thisNavigation != null)
{
NodesFailedUpdated.Add(thisNavigation.ToString());
}
else
{
NodesFailedUpdated.Add(item.Name);
}
}
}
else
{
var thisItem = contentService.GetById(item.Id);
NodesFailedUpdated.Add("Not Published: " + thisItem.Name + " :: " + thisItem.Id);
}
}
//Build up the result for the Web Service Return.
Dictionary<string, List<string>> result = new Dictionary<string, List<string>>();
result.Add("Fail", NodesFailedUpdated);
result.Add("Success", NodesSuccessfullyUpdated);
return Request.CreateResponse(HttpStatusCode.OK, result);
}
/// <summary>
/// Migrate7SimpleArchtype targets to clean up the data elements of the Ucomponents Data Grid Type.
/// Migrates Data Type Grid of Ucomponents to an Archetype configured Data Type
/// This one is not dynamic - the content structure to migrate is within the code. Bit of a hack but hey its just a bridge.
/// </summary>
/// <returns></returns>
[HttpPost]
public HttpResponseMessage Migrate7SimpleArchtype()
{
//Define an Umbraco Context to Help us Navigate Content
UmbracoHelper help = new UmbracoHelper(UmbracoContext);
var root = help.TypedContentAtRoot().Single(x => x.DocumentTypeAlias == "SiteConfig");
string HomeIntroGrid = "{\"fieldsets\":[{\"properties\":[{\"alias\":\"leadBoxTitle\",\"value\":\"Solutions for Your Industry\"},{\"alias\":\"leadBoxSubText\",\"value\":\"19 Industries\"},{\"alias\":\"leadBoxLink\",\"value\":\"/industries\"},{\"alias\":\"leadBoxImage\",\"value\":\"5902\"}],\"alias\":\"homeIntroBox\",\"disabled\":false},{\"properties\":[{\"alias\":\"leadBoxTitle\",\"value\":\"Experts In Your Area\"},{\"alias\":\"leadBoxSubText\",\"value\":\"20,000+ Specialists\"},{\"alias\":\"leadBoxLink\",\"value\":\"/locations\"},{\"alias\":\"leadBoxImage\",\"value\":\"5903\"}],\"alias\":\"homeIntroBox\",\"disabled\":false},{\"properties\":[{\"alias\":\"leadBoxTitle\",\"value\":\"Ideas Worth Talking About\"},{\"alias\":\"leadBoxSubText\",\"value\":\"550+ Articles\"},{\"alias\":\"leadBoxLink\",\"value\":\"/knowledge-center\"},{\"alias\":\"leadBoxImage\",\"value\":\"5904\"}],\"alias\":\"homeIntroBox\",\"disabled\":false}]}";
string BenefitSection2Items = "{\"fieldsets\":[{\"properties\":[{\"alias\":\"snippetTitle\",\"value\":\"Connect2MyBenefits\"},{\"alias\":\"snippetText\",\"value\":\"Designed to be your turnkey HR Intranet, Connect2MyBenefits is your easy-to-manage solution that provides 24/7 access for employees and dependents to access essential information and tools without needing to contact HR.\"},{\"alias\":\"snippetLink\",\"value\":\"http://www.xyz.com/solutions/benefits-hr-consulting/health-welfare/tools-programs/\"}],\"alias\":\"xyzSnippets\",\"disabled\":false},{\"properties\":[{\"alias\":\"snippetTitle\",\"value\":\"GBS Insight\"},{\"alias\":\"snippetText\",\"value\":\"GBS Insight uses a powerful portal framework to deliver secure, personalized online access to the latest information and tools you need to effectively manage your organizations’ human resources and employee benefit needs.\"},{\"alias\":\"snippetLink\",\"value\":\"http://www.xyz.com/solutions/benefits-hr-consulting/health-welfare/tools-programs/\"}],\"alias\":\"xyzSnippets\",\"disabled\":false},{\"properties\":[{\"alias\":\"snippetTitle\",\"value\":\"GBS Insider and Benchmarking \"},{\"alias\":\"snippetText\",\"value\":\"Assess where, how, and to what end your healthcare dollars are being spent with GBSInsider. This proprietary data warehouse and online analytics and reporting system, was specifically designed by our actuaries, underwriters, and analysts to provide you with the information needed to effectively understand and manage the cost and utilization of your health plans.\"},{\"alias\":\"snippetLink\",\"value\":\"http://www.xyz.com/solutions/benefits-hr-consulting/health-welfare/tools-programs/\"}],\"alias\":\"ajgSnippets\",\"disabled\":false},{\"properties\":[{\"alias\":\"snippetTitle\",\"value\":\"HCR Decision-Support Tools\"},{\"alias\":\"snippetText\",\"value\":\"Healthcare reform is impacting organizations across the country. How will it impact you? Gallagher’s Health & Welfare Consulting team offers a consultative process and a suite of support tools to help you assess the strategic, financial and operational impact of healthcare reform on your organization.\"},{\"alias\":\"snippetLink\",\"value\":\"http://www.xyz.com/solutions/benefits-hr-consulting/health-welfare/tools-programs/\"}],\"alias\":\"ajgSnippets\",\"disabled\":false},{\"properties\":[{\"alias\":\"snippetTitle\",\"value\":\"Gallagher Marketplace\"},{\"alias\":\"snippetText\",\"value\":\"Employers are seeking alternate methods for providing healthcare coverage and research shows many anticipate that the private exchange model is the answer they are looking for. To assist employers in solving their benefits challenges such as locating cost efficiencies, driving sustained employee engagement and creating administrative ease, Gallagher Marketplace was created.\"},{\"alias\":\"snippetLink\",\"value\":\"http://www.xyz.com/solutions/benefits-hr-consulting/private-exchange/a-tailored-approach/\"}],\"alias\":\"ajgSnippets\",\"disabled\":false}]}";
var contentService = Services.ContentService;
var targetHomeNode = contentService.GetById(1232);
var targetBenefitSolutionsNode = contentService.GetById(1430);
//Build up the result for the Web Service Return.
Dictionary<string, string> result = new Dictionary<string, string>();
try
{
targetHomeNode.SetValue("introGrid", HomeIntroGrid);
contentService.SaveAndPublishWithStatus(targetHomeNode);
result.Add("Home", "Completed");
}
catch
{
result.Add("Home", "Failed");
}
try
{
targetBenefitSolutionsNode.SetValue("section2Items", BenefitSection2Items);
contentService.SaveAndPublishWithStatus(targetBenefitSolutionsNode);
result.Add("Benefits", "Completed");
}
catch
{
result.Add("Benefits", "Failed");
}
//Now Let's Do the Landing Page
Dictionary<int,string> LandingPageBoxes= new Dictionary<int,string>();
LandingPageBoxes.Add(7728, "{\"fieldsets\":[{\"properties\":[{\"alias\":\"heading\",\"value\":\"Gain Strategic Insight\"},{\"alias\":\"text\",\"value\":\"Download the survey’s complimentary executive summary for an overview of the national data and strategic insights into the results.\"},{\"alias\":\"image\",\"value\":\"7733\"},{\"alias\":\"suppressBoxShadowOnImage\",\"value\":\"0\"},{\"alias\":\"callToActionLink\",\"value\":\"{\r\n \\\"type\\\": \\\"url\\\",\r\n \\\"meta\\\": {\r\n \\\"title\\\": \\\"Download Executive Summary\\\",\r\n \\\"newWindow\\\": true\r\n },\r\n \\\"typeData\\\": {\r\n \\\"url\\\": \\\"http://www.xyz.com/knowledge-center/whitepapers/2014-benefits-strategy-executive-summary-strategic-insights/?utm_source=lp&utm_medium=W&utm_content=LP_ExecSum&utm_campaign=NBS2014Exec\\\",\r\n \\\"contentId\\\": null,\r\n \\\"mediaId\\\": null\r\n }\r\n}\"},{\"alias\":\"colorCode\",\"value\":\"bg-lime-green\"}],\"alias\":\"landingPageCtA\",\"disabled\":false},{\"properties\":[{\"alias\":\"heading\",\"value\":\"Analyze and Compare\"},{\"alias\":\"text\",\"value\":\"Get information about the national report and additional options, including industry-specific, state-specific and custom reports.\"},{\"alias\":\"image\",\"value\":\"7732\"},{\"alias\":\"colorCode\",\"value\":\"bg-midnight-blue\"},{\"alias\":\"suppressBoxShadowOnImage\",\"value\":\"0\"},{\"alias\":\"callToActionLink\",\"value\":\"{\r\n \\\"type\\\": \\\"content\\\",\r\n \\\"meta\\\": {\r\n \\\"title\\\": \\\"Request Full Report\\\",\r\n \\\"newWindow\\\": false\r\n },\r\n \\\"typeData\\\": {\r\n \\\"url\\\": \\\"\\\",\r\n \\\"contentId\\\": 7750,\r\n \\\"mediaId\\\": null\r\n }\r\n}\"}],\"alias\":\"landingPageCtA\",\"disabled\":false},{\"properties\":[{\"alias\":\"heading\",\"value\":\"Choose the Right Path\"},{\"alias\":\"text\",\"value\":\"Combine the survey’s robust data set with practical expertise for help in deciding how to best plan and implement healthcare, wellness, retirement, absence management and other benefits.\"},{\"alias\":\"image\",\"value\":\"\"},{\"alias\":\"colorCode\",\"value\":\"bg-orange\"},{\"alias\":\"suppressBoxShadowOnImage\",\"value\":\"0\"},{\"alias\":\"callToActionLink\",\"value\":\"{\r\n \\\"type\\\": \\\"content\\\",\r\n \\\"meta\\\": {\r\n \\\"title\\\": \\\"Contact Us Today!\\\",\r\n \\\"newWindow\\\": false\r\n },\r\n \\\"typeData\\\": {\r\n \\\"url\\\": \\\"\\\",\r\n \\\"contentId\\\": 1499,\r\n \\\"mediaId\\\": null\r\n }\r\n}\"}],\"alias\":\"landingPageCtA\",\"disabled\":false}]}");
LandingPageBoxes.Add(7851, "{\"fieldsets\":[{\"properties\":[{\"alias\":\"heading\",\"value\":\"Gain Strategic Insight\"},{\"alias\":\"text\",\"value\":\"Download the survey’s complimentary executive summary for an overview of the national data and strategic insights into the results.\"},{\"alias\":\"image\",\"value\":\"7733\"},{\"alias\":\"colorCode\",\"value\":\"bg-lime-green\"},{\"alias\":\"suppressBoxShadowOnImage\",\"value\":\"0\"},{\"alias\":\"callToActionLink\",\"value\":\"{\r\n \\\"type\\\": \\\"url\\\",\r\n \\\"meta\\\": {\r\n \\\"title\\\": \\\"Download Executive Summary\\\",\r\n \\\"newWindow\\\": true\r\n },\r\n \\\"typeData\\\": {\r\n \\\"url\\\": \\\"http://www.xyz.com/knowledge-center/whitepapers/2014-benefits-strategy-executive-summary-strategic-insights/?utm_source=lp&utm_medium=W&utm_content=LP_ExecSum&utm_campaign=NBS2014Exec\\\",\r\n \\\"contentId\\\": null,\r\n \\\"mediaId\\\": null\r\n }\r\n}\"}],\"alias\":\"landingPageCtA\",\"disabled\":false},{\"properties\":[{\"alias\":\"heading\",\"value\":\"Analyze and Compare\"},{\"alias\":\"text\",\"value\":\"Request more information about purchasing additional data from the national survey, including reports specific to industry, location and organization size.\"},{\"alias\":\"image\",\"value\":\"7732\"},{\"alias\":\"colorCode\",\"value\":\"bg-midnight-blue\"},{\"alias\":\"suppressBoxShadowOnImage\",\"value\":\"0\"},{\"alias\":\"callToActionLink\",\"value\":\"{\r\n \\\"type\\\": \\\"content\\\",\r\n \\\"meta\\\": {\r\n \\\"title\\\": \\\"Request Additional Reports\\\",\r\n \\\"newWindow\\\": false\r\n },\r\n \\\"typeData\\\": {\r\n \\\"url\\\": \\\"\\\",\r\n \\\"contentId\\\": 7852,\r\n \\\"mediaId\\\": null\r\n }\r\n}\"}],\"alias\":\"landingPageCtA\",\"disabled\":false},{\"properties\":[{\"alias\":\"heading\",\"value\":\"Choose the Right Path\"},{\"alias\":\"text\",\"value\":\"Combine the survey’s robust data set with practical expertise for help in deciding how to best plan and implement healthcare, wellness, retirement, absence management and other benefits.\"},{\"alias\":\"image\",\"value\":\"\"},{\"alias\":\"colorCode\",\"value\":\"bg-orange\"},{\"alias\":\"suppressBoxShadowOnImage\",\"value\":\"0\"},{\"alias\":\"callToActionLink\",\"value\":\"{\r\n \\\"type\\\": \\\"content\\\",\r\n \\\"meta\\\": {\r\n \\\"title\\\": \\\"Contact Us Today!\\\",\r\n \\\"newWindow\\\": false\r\n },\r\n \\\"typeData\\\": {\r\n \\\"url\\\": \\\"\\\",\r\n \\\"contentId\\\": 1499,\r\n \\\"mediaId\\\": null\r\n }\r\n}\"}],\"alias\":\"landingPageCtA\",\"disabled\":false}]}");
LandingPageBoxes.Add(8172, "{\"fieldsets\":[{\"properties\":[{\"alias\":\"heading\",\"value\":\"Employer considerations when implementing counting hour rules\"},{\"alias\":\"text\",\"value\":\"View 12 questions to help you through the process of choosing and implementing the counting hours method that is appropriate for your business.\"},{\"alias\":\"image\",\"value\":\"\"},{\"alias\":\"colorCode\",\"value\":\"bg-lime-green\"},{\"alias\":\"suppressBoxShadowOnImage\",\"value\":\"0\"},{\"alias\":\"callToActionLink\",\"value\":\"{\r\n \\\"type\\\": \\\"url\\\",\r\n \\\"meta\\\": {\r\n \\\"title\\\": \\\"DOWNLOAD GUIDE\\\",\r\n \\\"newWindow\\\": true\r\n },\r\n \\\"typeData\\\": {\r\n \\\"url\\\": \\\"http://www.xyz.com/knowledge-center/articles/employer-considerations-when-implementing-counting-hours-rules/?utm_medium=Landing%20Page&utm_source=CountingHoursCampaign&utm_campaign=CountingHoursCampaign_Prospect_SepOct2014&utm_content=ImplemetingCountingHours_A_Content\\\",\r\n \\\"contentId\\\": null,\r\n \\\"mediaId\\\": null\r\n }\r\n}\"}],\"alias\":\"landingPageCtA\",\"disabled\":false},{\"properties\":[{\"alias\":\"heading\",\"value\":\"Communicate changes under the look-back method to employees\"},{\"alias\":\"text\",\"value\":\"Use our sample communications for new hires and ongoing employees to explain measurement, administrative, and stability periods.\"},{\"alias\":\"image\",\"value\":\"\"},{\"alias\":\"colorCode\",\"value\":\"bg-midnight-blue\"},{\"alias\":\"suppressBoxShadowOnImage\",\"value\":\"0\"},{\"alias\":\"callToActionLink\",\"value\":\"{\r\n \\\"type\\\": \\\"url\\\",\r\n \\\"meta\\\": {\r\n \\\"title\\\": \\\"DOWNLOAD COMMUNICATION\\\",\r\n \\\"newWindow\\\": true\r\n },\r\n \\\"typeData\\\": {\r\n \\\"url\\\": \\\"http://www.xyz.com/knowledge-center/articles/sample-employee-communications-explaining-eligibility-for-health-benefits-using-measurement,-administrative-and-stability-periods/?utm_medium=Landing%20Page&utm_source=CountingHoursCampaign&utm_campaign=CountingHoursCampaign_Prospect_SepOct2014&utm_content=SampleEmployeeCommunications_B_Content\\\",\r\n \\\"contentId\\\": null,\r\n \\\"mediaId\\\": null\r\n }\r\n}\"}],\"alias\":\"landingPageCtA\",\"disabled\":false},{\"properties\":[{\"alias\":\"heading\",\"value\":\"Respond to employee Frequently Asked Questions\"},{\"alias\":\"text\",\"value\":\"Modify and distribute our sample FAQ to employees about counting hours using the look-back method.\"},{\"alias\":\"image\",\"value\":\"\"},{\"alias\":\"colorCode\",\"value\":\"bg-orange\"},{\"alias\":\"suppressBoxShadowOnImage\",\"value\":\"0\"},{\"alias\":\"callToActionLink\",\"value\":\"{\r\n \\\"type\\\": \\\"url\\\",\r\n \\\"meta\\\": {\r\n \\\"title\\\": \\\"VIEW FAQs\\\",\r\n \\\"newWindow\\\": true\r\n },\r\n \\\"typeData\\\": {\r\n \\\"url\\\": \\\"http://www.xyz.com/knowledge-center/articles/sample-employee-faqs-explaining-benefits-eligibility/?utm_medium=Landing%20Page&utm_source=CountingHoursCampaign&utm_campaign=CountingHoursCampaign_Prospect_SepOct2014&utm_content=SampleEmployeeFAQ_C_Content\\\",\r\n \\\"contentId\\\": null,\r\n \\\"mediaId\\\": null\r\n }\r\n}\"}],\"alias\":\"landingPageCtA\",\"disabled\":false}]}");
LandingPageBoxes.Add(8184, "{\"fieldsets\":[{\"properties\":[{\"alias\":\"heading\",\"value\":\"Employer considerations when implementing counting hour rules\"},{\"alias\":\"text\",\"value\":\"View 12 questions to help you through the process of choosing and implementing the counting hours method that is appropriate for your business.\"},{\"alias\":\"image\",\"value\":\"\"},{\"alias\":\"colorCode\",\"value\":\"bg-lime-green\"},{\"alias\":\"suppressBoxShadowOnImage\",\"value\":\"0\"},{\"alias\":\"callToActionLink\",\"value\":\"{\r\n \\\"type\\\": \\\"url\\\",\r\n \\\"meta\\\": {\r\n \\\"title\\\": \\\"DOWNLOAD GUIDE\\\",\r\n \\\"newWindow\\\": true\r\n },\r\n \\\"typeData\\\": {\r\n \\\"url\\\": \\\"http://www.xyz.com/knowledge-center/articles/employer-considerations-when-implementing-counting-hours-rules/?utm_medium=Landing%20Page&utm_source=CountingHoursCampaign&utm_campaign=CountingHoursCampaign_Prospect_SepOct2014&utm_content=ImplemetingCountingHours_A_Content\\\",\r\n \\\"contentId\\\": null,\r\n \\\"mediaId\\\": null\r\n }\r\n}\"}],\"alias\":\"landingPageCtA\",\"disabled\":false},{\"properties\":[{\"alias\":\"heading\",\"value\":\"Communicate changes under the look-back method to employees\"},{\"alias\":\"text\",\"value\":\"Use our sample communications for new hires and ongoing employees to explain measurement, administrative, and stability periods.\"},{\"alias\":\"image\",\"value\":\"\"},{\"alias\":\"colorCode\",\"value\":\"bg-midnight-blue\"},{\"alias\":\"suppressBoxShadowOnImage\",\"value\":\"0\"},{\"alias\":\"callToActionLink\",\"value\":\"{\r\n \\\"type\\\": \\\"url\\\",\r\n \\\"meta\\\": {\r\n \\\"title\\\": \\\"DOWNLOAD COMMUNICATION\\\",\r\n \\\"newWindow\\\": true\r\n },\r\n \\\"typeData\\\": {\r\n \\\"url\\\": \\\"http://www.xyz.com/knowledge-center/articles/sample-employee-communications-explaining-eligibility-for-health-benefits-using-measurement,-administrative-and-stability-periods/?utm_medium=Landing%20Page&utm_source=CountingHoursCampaign&utm_campaign=CountingHoursCampaign_Prospect_SepOct2014&utm_content=SampleEmployeeCommunications_B_Content\\\",\r\n \\\"contentId\\\": null,\r\n \\\"mediaId\\\": null\r\n }\r\n}\"}],\"alias\":\"landingPageCtA\",\"disabled\":false},{\"properties\":[{\"alias\":\"heading\",\"value\":\"Respond to employee Frequently Asked Questions\"},{\"alias\":\"text\",\"value\":\"Modify and distribute our sample FAQ to employees about counting hours using the look-back method.\"},{\"alias\":\"image\",\"value\":\"\"},{\"alias\":\"colorCode\",\"value\":\"bg-orange\"},{\"alias\":\"suppressBoxShadowOnImage\",\"value\":\"0\"},{\"alias\":\"callToActionLink\",\"value\":\"{\r\n \\\"type\\\": \\\"url\\\",\r\n \\\"meta\\\": {\r\n \\\"title\\\": \\\"VIEW FAQs\\\",\r\n \\\"newWindow\\\": true\r\n },\r\n \\\"typeData\\\": {\r\n \\\"url\\\": \\\"http://www.xyz.com/knowledge-center/articles/sample-employee-faqs-explaining-benefits-eligibility/?utm_medium=Landing%20Page&utm_source=CountingHoursCampaign&utm_campaign=CountingHoursCampaign_Prospect_SepOct2014&utm_content=SampleEmployeeFAQ_C_Content\\\",\r\n \\\"contentId\\\": null,\r\n \\\"mediaId\\\": null\r\n }\r\n}\"}],\"alias\":\"landingPageCtA\",\"disabled\":false}]}");
LandingPageBoxes.Add(10019, "{\"fieldsets\":[{\"properties\":[{\"alias\":\"heading\",\"value\":\"Employer considerations when evaluating MBA Health Link\"},{\"alias\":\"text\",\"value\":\"\"},{\"alias\":\"image\",\"value\":\"\"},{\"alias\":\"colorCode\",\"value\":\"bg-midnight-blue\"},{\"alias\":\"suppressBoxShadowOnImage\",\"value\":\"0\"},{\"alias\":\"callToActionLink\",\"value\":\"{\r\n \\\"type\\\": \\\"media\\\",\r\n \\\"meta\\\": {\r\n \\\"title\\\": \\\"VIEW THE DOCUMENT\\\",\r\n \\\"newWindow\\\": true\r\n },\r\n \\\"typeData\\\": {\r\n \\\"url\\\": \\\"\\\",\r\n \\\"contentId\\\": null,\r\n \\\"mediaId\\\": 10021\r\n }\r\n}\"}],\"alias\":\"landingPageCtA\",\"disabled\":false},{\"properties\":[{\"alias\":\"heading\",\"value\":\"The employee experience\"},{\"alias\":\"text\",\"value\":\"\"},{\"alias\":\"image\",\"value\":\"\"},{\"alias\":\"colorCode\",\"value\":\"bg-olive-green\"},{\"alias\":\"suppressBoxShadowOnImage\",\"value\":\"0\"},{\"alias\":\"callToActionLink\",\"value\":\"{\r\n \\\"type\\\": \\\"url\\\",\r\n \\\"meta\\\": {\r\n \\\"title\\\": \\\"CHECK OUT THE BENEFITS SHOPPING EXPERIENCE\\\",\r\n \\\"newWindow\\\": true\r\n },\r\n \\\"typeData\\\": {\r\n \\\"url\\\": \\\"http://bcove.me/50k3cvix\\\",\r\n \\\"contentId\\\": null,\r\n \\\"mediaId\\\": null\r\n }\r\n}\"}],\"alias\":\"landingPageCtA\",\"disabled\":false},{\"properties\":[{\"alias\":\"heading\",\"value\":\"Learn more about private exchanges & employer opportunities\"},{\"alias\":\"text\",\"value\":\"\"},{\"alias\":\"image\",\"value\":\"\"},{\"alias\":\"colorCode\",\"value\":\"bg-maroon\"},{\"alias\":\"suppressBoxShadowOnImage\",\"value\":\"0\"},{\"alias\":\"callToActionLink\",\"value\":\"{\r\n \\\"type\\\": \\\"content\\\",\r\n \\\"meta\\\": {\r\n \\\"title\\\": \\\"DOWNLOAD THE WHITEPAPER\\\",\r\n \\\"newWindow\\\": true\r\n },\r\n \\\"typeData\\\": {\r\n \\\"url\\\": \\\"\\\",\r\n \\\"contentId\\\": 8782,\r\n \\\"mediaId\\\": null\r\n }\r\n}\"}],\"alias\":\"landingPageCtA\",\"disabled\":false}]}");
//landingPageCallToActionBasic
foreach(var item in LandingPageBoxes) {
var targetLandingPageNode = contentService.GetById(item.Key);
targetLandingPageNode.SetValue("landingPageCallToActionBasic", item.Value);
contentService.SaveAndPublishWithStatus(targetLandingPageNode);
result.Add("Landing Page :: " + item.Key, "Completed");
}
return Request.CreateResponse(HttpStatusCode.OK, result);
}
/// <summary>
/// Migrate7Relations targets to update current Relations to flip the Parent Id and Child Id accordingly.
/// We ahd noticed out ParentID and ChildId nodes flipped so this runs to flip them to keep our code working as expected.
/// Sample: /umbraco/api/MaintenanceServicesAPI/Migrate7Relations?RelationTypeAlias=RelateAuthorAndKnowledgeItem
/// </summary>
/// <returns></returns>
[HttpPost]
public HttpResponseMessage Migrate7Relations(string RelationTypeAlias)
{
//Define an Umbraco Context to Help us Navigate Content
UmbracoHelper help = new UmbracoHelper(UmbracoContext);
var root = help.TypedContentAtRoot().Single(x => x.DocumentTypeAlias == "SiteConfig");
List<string> NodesSuccessfullyUpdated = new List<string>();
List<string> NodesFailedUpdated = new List<string>();
var relationType = Services.RelationService.GetRelationTypeByAlias(RelationTypeAlias);
var relations = Services.RelationService.GetAllRelationsByRelationType(relationType.Id);
//Delete the current set of relations so we loop below on the "relation" var and create them new
//Services.RelationService.DeleteRelationsOfType(relationType);
foreach (var relation in relations)
{
try
{
//Create and Save the New "Flipped" Relation (flipping parentId and Child Id)
var newRelation = new Relation(relation.ChildId, relation.ParentId, relationType);
Services.RelationService.Save(newRelation);
//Delete The Old Relation
Services.RelationService.Delete(relation);
NodesSuccessfullyUpdated.Add(relation.ChildId + ", " + relation.ParentId + ", " + relationType.Alias);
}
catch{
NodesFailedUpdated.Add(relation.ChildId + ", " + relation.ParentId + ", " + relationType.Alias);
}
}
//Build up the result for the Web Service Return.
Dictionary<string, List<string>> result = new Dictionary<string, List<string>>();
result.Add("Fail", NodesFailedUpdated);
result.Add("Success", NodesSuccessfullyUpdated);
return Request.CreateResponse(HttpStatusCode.OK, result);
}
/// <summary>
/// Migrate7TagsPublish is a method to get the Tags published on the upgrade. It seems at upgrade the Tags Relationships are stripped.
/// </summary>
/// <returns></returns>
[HttpPost]
public HttpResponseMessage Migrate7TagsPublish()
{
//Define an Umbraco Context to Help us Navigate Content
UmbracoHelper help = new UmbracoHelper(UmbracoContext);
var root = help.TypedContentAtRoot().Single(x => x.DocumentTypeAlias == "SiteConfig");
List<string> NodesSuccessfullyUpdated = new List<string>();
List<string> NodesFailedNotPublished = new List<string>();
List<string> NodesFailedNoTags = new List<string>();
//Step 3 - Now the security checks are confirmed let's get to business
var contentService = Services.ContentService;
var targetNodes = contentService.GetDescendants(root.Id);
foreach (var item in targetNodes)
{
if (!item.Published)
{
if (!contentService.HasPublishedVersion(item.Id))
{
var thisItem = contentService.GetById(item.Id);
try
{
//thisItem.SetValue("tags", thisNavigation);
//Persist the updates to the Server and DB
contentService.SaveAndPublishWithStatus(thisItem);
contentService.UnPublish(thisItem);
NodesSuccessfullyUpdated.Add("Unpublished Tags: " + item.Name + " :: " + item.Id);
}
catch
{
NodesFailedNoTags.Add(item.Name + " :: " + item.Id);
}
}
else
{
NodesFailedNotPublished.Add(item.Name + " :: " + item.Id);
}
}
}
//Build up the result for the Web Service Return.
Dictionary<string, List<string>> result = new Dictionary<string, List<string>>();
result.Add("Drafts", NodesFailedNotPublished);
result.Add("NoTags", NodesFailedNoTags);
result.Add("Success", NodesSuccessfullyUpdated);
return Request.CreateResponse(HttpStatusCode.OK, result);
}
#endregion
/// <summary>
/// Fix7Relations targets to update current Relations to add in a step so the NuPickers can control the relation
/// </summary>
/// <returns></returns>
[HttpPost]
public HttpResponseMessage Fix7Relations(string RelationTypeAlias, string targetAlias)
{
//Define an Umbraco Context to Help us Navigate Content
UmbracoHelper help = new UmbracoHelper(UmbracoContext);
var root = help.TypedContentAtRoot().Single(x => x.DocumentTypeAlias == "SiteConfig");
List<string> NodesSuccessfullyUpdated = new List<string>();
List<string> NodesFailedUpdated = new List<string>();
var relationType = Services.RelationService.GetRelationTypeByAlias(RelationTypeAlias);
var relations = Services.RelationService.GetAllRelationsByRelationType(relationType.Id);
//Delete the current set of relations so we loop below on the "relation" var and create them new
//Services.RelationService.DeleteRelationsOfType(relationType);
foreach (var relation in relations)
{
try
{
var contentService = Services.ContentService;
var thisItem = contentService.GetById(relation.ChildId);
var contentTypeService = Services.ContentTypeService;
var thisItemType = contentTypeService.GetContentType(thisItem.ContentTypeId);
//Need to get the PropertyTypes on the ContentType and also get the inherited PropertyTypes and then Combine them
var thisPropertyTypes = thisItemType.PropertyTypes;
var parentAllPropertyTypes = thisItemType.CompositionPropertyTypes;
var thisAllPropertyTypes = thisPropertyTypes.Concat(parentAllPropertyTypes);
var targettedPropertyType = thisAllPropertyTypes.Where(x => x.Alias == targetAlias).First();
if (targettedPropertyType != null)
{
var PropertyTypeId = targettedPropertyType.Id;
var DataTypeDefinitionId = targettedPropertyType.DataTypeDefinitionId;
relation.Comment = "<RelationMapping PropertyAlias=\"" + targetAlias + "\" PropertyTypeId=\"" + PropertyTypeId + "\" DataTypeDefinitionId=\"" + DataTypeDefinitionId + "\" />";
Services.RelationService.Save(relation);
NodesSuccessfullyUpdated.Add(relation.ChildId + ", " + relation.ParentId + ", " + relationType.Alias);
}
}
catch
{
NodesFailedUpdated.Add(relation.ChildId + ", " + relation.ParentId + ", " + relationType.Alias);
}
}
//Build up the result for the Web Service Return.
Dictionary<string, List<string>> result = new Dictionary<string, List<string>>();
result.Add("Fail", NodesFailedUpdated);
result.Add("Success", NodesSuccessfullyUpdated);
return Request.CreateResponse(HttpStatusCode.OK, result);
}
}
#region Models used for Upgrade to 7
public class RLinks
{
public string caption { get; set; }
public string link { get; set; }
public bool newWindow { get; set; }
public bool edit { get; set; }
public bool isInternal { get; set; }
public string type { get; set; }
public string title { get; set; }
public string Internal { get; set; }
public string internalName { get; set; }
}
public class UrlPickerTemp
{
public string type { get; set; }
public Meta meta { get; set; }
public TypeData typeData { get; set; }
public string url { get; set; }
public string name { get; set; }
public enum UrlPickerTypes { Url, Content, Media };
}
public class TypeData
{
public string url { get; set; }
public int? contentId { get; set; }
public IPublishedContent content { get; set; }
public int? mediaId { get; set; }
public IPublishedContent media { get; set; }
}
public class Meta
{
public string title { get; set; }
public bool newWindow { get; set; }
}
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment