Skip to content
This repository has been archived by the owner on Jun 18, 2018. It is now read-only.

Commit

Permalink
Merge pull request #139 from umco/develop
Browse files Browse the repository at this point in the history
Preparing for v0.5.0 release
  • Loading branch information
leekelleher authored Aug 24, 2017
2 parents c38c11a + f4f9069 commit 217553d
Show file tree
Hide file tree
Showing 23 changed files with 393 additions and 363 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ A nested content property editor for Umbraco 7 that allows you to use Doc Types

### Installation

> *Note:* Nested Content has been developed against **Umbraco v7.1.4** and will support that version and above.
> *Note:* Nested Content has been developed against **Umbraco v7.1.5** and will support that version and above.
Nested Content can be installed from either Our Umbraco or NuGet package repositories, or build manually from the source-code:

Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# version format
version: 0.4.0.{build}
version: 0.5.0.{build}

# UMBRACO_PACKAGE_PRERELEASE_SUFFIX if a rtm release build this should be blank, otherwise if empty will default to alpha
# example UMBRACO_PACKAGE_PRERELEASE_SUFFIX=beta
Expand Down
2 changes: 1 addition & 1 deletion build/package.proj
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<PropertyGroup>
<ProjectName>Our.Umbraco.NestedContent</ProjectName>
<PackageName>Nested Content</PackageName>
<MinUmbracoVersion>7.1.4</MinUmbracoVersion>
<MinUmbracoVersion>7.1.5</MinUmbracoVersion>
<Readme>Nested Content is a list editing property editor for Umbraco 7.1+</Readme>
<AuthorName>Matt Brailsford, Lee Kelleher</AuthorName>
<AuthorUrl>https://github.com/umco/umbraco-nested-content/graphs/contributors</AuthorUrl>
Expand Down
33 changes: 24 additions & 9 deletions src/Our.Umbraco.NestedContent/Bootstrap.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,39 @@
using Umbraco.Core;
using Umbraco.Core.Events;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
using System;
using Newtonsoft.Json;
using Our.Umbraco.NestedContent.Helpers;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Sync;
using Umbraco.Web.Cache;

namespace Our.Umbraco.NestedContent
{
public class Bootstrap : ApplicationEventHandler
{
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
DataTypeService.Saved += ExpireCache;
CacheRefresherBase<DataTypeCacheRefresher>.CacheUpdated += DataTypeCacheRefresher_Updated;
}

private void ExpireCache(IDataTypeService sender, SaveEventArgs<IDataTypeDefinition> e)
private void DataTypeCacheRefresher_Updated(DataTypeCacheRefresher sender, CacheRefresherEventArgs e)
{
foreach (var dataType in e.SavedEntities)
if (e.MessageType == MessageType.RefreshByJson)
{
ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheItem(
string.Concat("Our.Umbraco.NestedContent.GetPreValuesCollectionByDataTypeId_", dataType.Id));
var payload = JsonConvert.DeserializeObject<JsonPayload[]>((string)e.MessageObject);
if (payload != null)
{
foreach (var item in payload)
{
NestedContentHelper.ClearCache(item.Id);
}
}
}
}

private class JsonPayload
{
public Guid UniqueId { get; set; }
public int Id { get; set; }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@

namespace Our.Umbraco.NestedContent.Converters
{
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
[PropertyValueType(typeof(IEnumerable<IPublishedContent>))]
public class NestedContentValueConverter : PropertyValueConverterBase
public class NestedContentValueConverter : PropertyValueConverterBase, IPropertyValueConverterMeta
{
public override bool IsConverter(PublishedPropertyType propertyType)
{
Expand All @@ -30,5 +28,15 @@ public override object ConvertDataToSource(PublishedPropertyType propertyType, o

return null;
}

public virtual Type GetPropertyValueType(PublishedPropertyType propertyType)
{
return typeof (IEnumerable<IPublishedContent>);
}

public virtual PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType, PropertyCacheValue cacheValue)
{
return PropertyCacheLevel.Content;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@

namespace Our.Umbraco.NestedContent.Converters
{
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
[PropertyValueType(typeof(IPublishedContent))]
public class SingleNestedContentValueConverter : PropertyValueConverterBase
public class SingleNestedContentValueConverter : PropertyValueConverterBase, IPropertyValueConverterMeta
{
public override bool IsConverter(PublishedPropertyType propertyType)
{
Expand All @@ -29,5 +27,15 @@ public override object ConvertDataToSource(PublishedPropertyType propertyType, o

return null;
}

public virtual Type GetPropertyValueType(PublishedPropertyType propertyType)
{
return typeof(IPublishedContent);
}

public virtual PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType, PropertyCacheValue cacheValue)
{
return PropertyCacheLevel.Content;
}
}
}

This file was deleted.

19 changes: 19 additions & 0 deletions src/Our.Umbraco.NestedContent/Extensions/JsonExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using Newtonsoft.Json.Linq;

namespace Our.Umbraco.NestedContent.Extensions
{
internal static class JsonExtensions
{
public static void Rename(this JToken token, string newName)
{
var parent = token.Parent;

if (parent == null)
throw new InvalidOperationException("The parent is missing.");

var newToken = new JProperty(newName, token);
parent.Replace(newToken);
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public static bool IsSingleNestedContentProperty(this PublishedPropertyType publ
}

var preValueCollection = NestedContentHelper.GetPreValuesCollectionByDataTypeId(publishedProperty.DataTypeId);
var preValueDictionary = preValueCollection.AsPreValueDictionary();
var preValueDictionary = preValueCollection.PreValuesAsDictionary.ToDictionary(x => x.Key, x => x.Value.Value);

int minItems, maxItems;
return preValueDictionary.ContainsKey("minItems") &&
Expand All @@ -46,7 +46,7 @@ public static object ConvertPropertyToNestedContent(this PublishedPropertyType p
var processedValue = new List<IPublishedContent>();

var preValueCollection = NestedContentHelper.GetPreValuesCollectionByDataTypeId(propertyType.DataTypeId);
var preValueDictionary = preValueCollection.AsPreValueDictionary();
var preValueDictionary = preValueCollection.PreValuesAsDictionary.ToDictionary(x => x.Key, x => x.Value.Value);

for (var i = 0; i < rawValue.Count; i++)
{
Expand Down Expand Up @@ -90,16 +90,26 @@ public static object ConvertPropertyToNestedContent(this PublishedPropertyType p
}

// Get the current request node we are embedded in
var pcr = UmbracoContext.Current.PublishedContentRequest;
var pcr = UmbracoContext.Current == null ? null : UmbracoContext.Current.PublishedContentRequest;
var containerNode = pcr != null && pcr.HasPublishedContent ? pcr.PublishedContent : null;

processedValue.Add(new DetachedPublishedContent(
// Create the model based on our implementation of IPublishedContent
IPublishedContent content = new DetachedPublishedContent(
nameObj == null ? null : nameObj.ToString(),
publishedContentType,
properties.ToArray(),
containerNode,
i,
preview));
preview);

if (PublishedContentModelFactoryResolver.HasCurrent && PublishedContentModelFactoryResolver.Current.HasValue)
{
// Let the current model factory create a typed model to wrap our model
content = PublishedContentModelFactoryResolver.Current.Factory.CreateModel(content);
}

// Add the (typed) model as a result
processedValue.Add(content);
}

if (propertyType.IsSingleNestedContentProperty())
Expand Down
122 changes: 119 additions & 3 deletions src/Our.Umbraco.NestedContent/Helpers/NestedContentHelper.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
using Our.Umbraco.NestedContent.Extensions;
using Our.Umbraco.NestedContent.Models;
using Our.Umbraco.NestedContent.PropertyEditors;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence;

namespace Our.Umbraco.NestedContent.Helpers
{
internal static class NestedContentHelper
{
private const string CacheKeyPrefix = "Our.Umbraco.NestedContent.GetPreValuesCollectionByDataTypeId_";

public static PreValueCollection GetPreValuesCollectionByDataTypeId(int dtdId)
{
var preValueCollection = (PreValueCollection)ApplicationContext.Current.ApplicationCache.RuntimeCache.GetCacheItem(
string.Concat("Our.Umbraco.NestedContent.GetPreValuesCollectionByDataTypeId_", dtdId),
string.Concat(CacheKeyPrefix, dtdId),
() => ApplicationContext.Current.Services.DataTypeService.GetPreValuesCollectionByDataTypeId(dtdId));

return preValueCollection;
}

public static void ClearCache(int dtdId)
{
ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheItem(
string.Concat(CacheKeyPrefix, dtdId));
}

public static string GetContentTypeAliasFromItem(JObject item)
{
var contentTypeAliasProperty = item[NestedContentPropertyEditor.ContentTypeAliasPropertyKey];
Expand Down Expand Up @@ -60,7 +71,7 @@ public static void ConvertItemValueFromV011(JObject item, int dtdId, ref PreValu
ConvertPreValueCollectionFromV011(preValues);

// - get the content types prevalue as JArray
var preValuesAsDictionary = preValues.AsPreValueDictionary();
var preValuesAsDictionary = preValues.PreValuesAsDictionary.ToDictionary(x => x.Key, x => x.Value.Value);
if (!preValuesAsDictionary.ContainsKey(ContentTypesPreValueKey) || string.IsNullOrEmpty(preValuesAsDictionary[ContentTypesPreValueKey]) != false)
{
return;
Expand All @@ -81,7 +92,7 @@ public static void ConvertPreValueCollectionFromV011(PreValueCollection preValue
return;
}

var persistedPreValuesAsDictionary = preValueCollection.AsPreValueDictionary();
var persistedPreValuesAsDictionary = preValueCollection.PreValuesAsDictionary.ToDictionary(x => x.Key, x => x.Value.Value);

// do we have a "docTypeGuid" prevalue and no "contentTypes" prevalue?
if (persistedPreValuesAsDictionary.ContainsKey("docTypeGuid") == false || persistedPreValuesAsDictionary.ContainsKey(ContentTypesPreValueKey))
Expand Down Expand Up @@ -121,5 +132,110 @@ private static string ContentTypesPreValueKey
}

#endregion

public static void RemapDocTypeAlias(string oldAlias, string newAlias, Transaction transaction = null)
{
var db = ApplicationContext.Current.DatabaseContext.Database;

// Update references in property data
// We do 2 very similar replace statements, but one is without spaces in the JSON, the other is with spaces
// as we can't guarantee what format it will actually get saved in
var sql1 = string.Format(@"UPDATE cmsPropertyData
SET dataNtext = CAST(REPLACE(REPLACE(CAST(dataNtext AS nvarchar(max)), '""ncContentTypeAlias"":""{0}""', '""ncContentTypeAlias"":""{1}""'), '""ncContentTypeAlias"": ""{0}""', '""ncContentTypeAlias"": ""{1}""') AS ntext)
WHERE dataNtext LIKE '%""ncContentTypeAlias"":""{0}""%' OR dataNtext LIKE '%""ncContentTypeAlias"": ""{0}""%'", oldAlias, newAlias);

// Update references in prevalue
// We do 2 very similar replace statements, but one is without spaces in the JSON, the other is with spaces
// as we can't guarantee what format it will actually get saved in
var sql2 = string.Format(@"UPDATE cmsDataTypePreValues
SET [value] = CAST(REPLACE(REPLACE(CAST([value] AS nvarchar(max)), '""ncAlias"":""{0}""', '""ncAlias"":""{1}""'), '""ncAlias"": ""{0}""', '""ncAlias"": ""{1}""') AS ntext)
WHERE [value] LIKE '%""ncAlias"":""{0}""%' OR [value] LIKE '%""ncAlias"": ""{0}""%'", oldAlias, newAlias);

if (transaction == null)
{
using (var tr = db.GetTransaction())
{
db.Execute(sql1);
db.Execute(sql2);
tr.Complete();
}
}
else
{
db.Execute(sql1);
db.Execute(sql2);
}
}

public static void RemapPropertyAlias(string docTypeAlias, string oldAlias, string newAlias, Transaction transaction = null)
{
var db = ApplicationContext.Current.DatabaseContext.Database;

// Update references in property data
// We have to do it in code because there could be nested JSON so
// we need to make sure it only replaces at the specific level only
Action doQuery = () =>
{
var rows = GetPropertyDataRows(docTypeAlias);
foreach (var row in rows)
{
var tokens = row.Data.SelectTokens(string.Format("$..[?(@.ncContentTypeAlias == '{0}' && @.{1})]", docTypeAlias, oldAlias)).ToList();
if (tokens.Any())
{
foreach (var token in tokens)
{
token[oldAlias].Rename(newAlias);
}
db.Execute("UPDATE [cmsPropertyData] SET [dataNtext] = @0 WHERE [id] = @1", row.RawData, row.Id);
}
}
};

if (transaction == null)
{
using (var tr = db.GetTransaction())
{
doQuery();
tr.Complete();
}
}
else
{
doQuery();
}
}

public static void RemapDocTypeTabAlias(string docTypeAlias, string oldAlias, string newAlias, Transaction transaction = null)
{
var db = ApplicationContext.Current.DatabaseContext.Database;

// Update references in prevalue
// We do 2 very similar replace statements, but one is without spaces in the JSON, the other is with spaces
// as we can't guarantee what format it will actually get saved in
var sql1 = string.Format(@"UPDATE cmsDataTypePreValues
SET [value] = CAST(REPLACE(REPLACE(CAST([value] AS nvarchar(max)), '""ncTabAlias"":""{0}""', '""ncTabAlias"":""{1}""'), '""ncTabAlias"": ""{0}""', '""ncTabAlias"": ""{1}""') AS ntext)
WHERE [value] LIKE '%""ncAlias"":""{2}""%' OR [value] LIKE '%""ncAlias"": ""{2}""%'", oldAlias, newAlias, docTypeAlias);

if (transaction == null)
{
using (var tr = db.GetTransaction())
{
db.Execute(sql1);
tr.Complete();
}
}
else
{
db.Execute(sql1);
}
}

private static IEnumerable<JsonDbRow> GetPropertyDataRows(string docTypeAlias)
{
var db = ApplicationContext.Current.DatabaseContext.Database;
return db.Query<JsonDbRow>(string.Format(
@"SELECT [id], [dataNtext] as [rawdata] FROM cmsPropertyData WHERE dataNtext LIKE '%""ncContentTypeAlias"":""{0}""%' OR dataNtext LIKE '%""ncContentTypeAlias"": ""{0}""%'",
docTypeAlias)).ToList();
}
}
}
Loading

0 comments on commit 217553d

Please sign in to comment.