Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e1deba5b95 | |||
| 5bce4e856a | |||
| 6f4cb1e609 | |||
| 033cbbc8f6 | |||
| 7ee3cfca5c | |||
| e9b478c186 | |||
| 21e784424f | |||
| 155355aa00 |
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Imulus
|
||||
Copyright (c) 2016 Kevin Giszewski LLC
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
|
||||
@@ -263,6 +263,7 @@
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="PropertyValueConverter\PropertyValueConverterTests.cs" />
|
||||
<Compile Include="PublishedContent\ArchetypePublishedContentTests.cs" />
|
||||
<Compile Include="PublishedContent\TypeConverterTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Archetype.Models;
|
||||
using Archetype.PropertyConverters;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Archetype.Tests.PublishedContent
|
||||
{
|
||||
[TestFixture]
|
||||
public class TypeConverterTests
|
||||
{
|
||||
private ArchetypeModel _archetype;
|
||||
|
||||
[TestFixtureSetUp]
|
||||
public void Init()
|
||||
{
|
||||
var archetypeJson = System.IO.File.ReadAllText("..\\..\\Data\\sample-1.json");
|
||||
var converter = new ArchetypeValueConverter();
|
||||
|
||||
_archetype = (ArchetypeModel)converter.ConvertDataToSource(null, archetypeJson, false);
|
||||
}
|
||||
|
||||
[TestCase(typeof(ArchetypeModel), true)]
|
||||
[TestCase(typeof(ArchetypePublishedContentSet), true)]
|
||||
[TestCase(typeof(IEnumerable<IPublishedContent>), true)]
|
||||
[TestCase(typeof(string), true)]
|
||||
[TestCase(typeof(int), false)]
|
||||
[TestCase(typeof(ArchetypeFieldsetModel), false)]
|
||||
public void ArchetypeModel_ConvertsTo_EnumerablePublishedContent(Type destinationType, bool expected)
|
||||
{
|
||||
Assert.IsNotNull(_archetype);
|
||||
|
||||
var attempt = _archetype.TryConvertTo(destinationType);
|
||||
|
||||
Assert.That(attempt.Success, Is.EqualTo(expected));
|
||||
|
||||
if (attempt.Success)
|
||||
{
|
||||
Assert.IsNotNull(attempt.Result);
|
||||
Assert.That(attempt.Result, Is.InstanceOf(destinationType));
|
||||
}
|
||||
}
|
||||
|
||||
[TestCase(typeof(ArchetypeFieldsetModel), true)]
|
||||
[TestCase(typeof(ArchetypePublishedContent), true)]
|
||||
[TestCase(typeof(IPublishedContent), true)]
|
||||
[TestCase(typeof(string), true)]
|
||||
[TestCase(typeof(int), false)]
|
||||
[TestCase(typeof(ArchetypeModel), false)]
|
||||
public void ArchetypeFieldsetModel_ConvertsTo_PublishedContent(Type destinationType, bool expected)
|
||||
{
|
||||
CollectionAssert.IsNotEmpty(_archetype.Fieldsets);
|
||||
|
||||
var attempt = _archetype.First().TryConvertTo(destinationType);
|
||||
|
||||
Assert.That(attempt.Success, Is.EqualTo(expected));
|
||||
|
||||
if (attempt.Success)
|
||||
{
|
||||
Assert.IsNotNull(attempt.Result);
|
||||
Assert.That(attempt.Result, Is.InstanceOf(destinationType));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -252,6 +252,8 @@
|
||||
<Compile Include="Properties\VersionInfo.cs" />
|
||||
<Compile Include="PropertyConverters\ArchetypeValueConverter.cs" />
|
||||
<Compile Include="PropertyEditors\ArchetypePropertyEditor.cs" />
|
||||
<Compile Include="TypeConverters\ArchetypeFieldsetModelConverter.cs" />
|
||||
<Compile Include="TypeConverters\ArchetypeModelConverter.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
|
||||
@@ -98,7 +98,7 @@ namespace Archetype.Extensions
|
||||
|
||||
return archetype;
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new ArchetypeModel();
|
||||
}
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Web.Security;
|
||||
using Archetype.TypeConverters;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Core;
|
||||
using System;
|
||||
|
||||
namespace Archetype.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Model that represents a fieldset stored as content JSON.
|
||||
/// </summary>
|
||||
[TypeConverter(typeof(ArchetypeFieldsetModelConverter))]
|
||||
public class ArchetypeFieldsetModel
|
||||
{
|
||||
[JsonProperty("alias")]
|
||||
@@ -63,7 +66,7 @@ namespace Archetype.Models
|
||||
{
|
||||
var property = GetProperty(propertyAlias);
|
||||
|
||||
if (IsEmptyProperty(property))
|
||||
if (IsEmptyProperty(property))
|
||||
{
|
||||
return default(T);
|
||||
}
|
||||
@@ -87,7 +90,7 @@ namespace Archetype.Models
|
||||
{
|
||||
var property = GetProperty(propertyAlias);
|
||||
|
||||
if (IsEmptyProperty(property))
|
||||
if (IsEmptyProperty(property))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
@@ -100,7 +103,7 @@ namespace Archetype.Models
|
||||
/// </summary>
|
||||
/// <param name="property">The property.</param>
|
||||
/// <returns></returns>
|
||||
private bool IsEmptyProperty(ArchetypePropertyModel property)
|
||||
private bool IsEmptyProperty(ArchetypePropertyModel property)
|
||||
{
|
||||
return (property == null || property.Value == null || string.IsNullOrEmpty(property.Value.ToString()));
|
||||
}
|
||||
@@ -145,24 +148,24 @@ namespace Archetype.Models
|
||||
/// <returns>true if this fieldset is disabled, false otherwise</returns>
|
||||
internal bool IsAvailable()
|
||||
{
|
||||
// explicitly disabled or implicitly disabled through publishing?
|
||||
var disabled = Disabled
|
||||
// explicitly disabled or implicitly disabled through publishing?
|
||||
var disabled = Disabled
|
||||
|| (ReleaseDate.HasValue && ReleaseDate > DateTime.UtcNow)
|
||||
|| (ExpireDate.HasValue && DateTime.UtcNow > ExpireDate);
|
||||
if(disabled)
|
||||
{
|
||||
// yes - the fieldset is not available
|
||||
return false;
|
||||
}
|
||||
// limitation on member group access?
|
||||
if(string.IsNullOrEmpty(AllowedMemberGroups))
|
||||
{
|
||||
// no - the fieldset is available
|
||||
return true;
|
||||
}
|
||||
// maybe - the fieldset is available if the current member is a member of the configured member groups
|
||||
var currentUserGroups = Roles.GetRolesForUser() ?? new string[0];
|
||||
return currentUserGroups.ContainsAny(AllowedMemberGroups.Split(','));
|
||||
if (disabled)
|
||||
{
|
||||
// yes - the fieldset is not available
|
||||
return false;
|
||||
}
|
||||
// limitation on member group access?
|
||||
if (string.IsNullOrEmpty(AllowedMemberGroups))
|
||||
{
|
||||
// no - the fieldset is available
|
||||
return true;
|
||||
}
|
||||
// maybe - the fieldset is available if the current member is a member of the configured member groups
|
||||
var currentUserGroups = Roles.GetRolesForUser() ?? new string[0];
|
||||
return currentUserGroups.ContainsAny(AllowedMemberGroups.Split(','));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using Archetype.TypeConverters;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
@@ -11,6 +13,7 @@ namespace Archetype.Models
|
||||
/// Model that represents an entire Archetype.
|
||||
/// </summary>
|
||||
[JsonObject]
|
||||
[TypeConverter(typeof(ArchetypeModelConverter))]
|
||||
public class ArchetypeModel : IEnumerable<ArchetypeFieldsetModel>
|
||||
{
|
||||
[JsonProperty("fieldsets")]
|
||||
|
||||
@@ -206,7 +206,7 @@ namespace Archetype.PropertyEditors
|
||||
else if (propDef.EditorState != null && propDef.EditorState.FileNames != null && propDef.EditorState.FileNames.Any())
|
||||
{
|
||||
// pass the uploaded files that belongs to this property (if any) to the value editor
|
||||
var propertyFiles = propDef.EditorState.FileNames.Select(f => uploadedFiles.FirstOrDefault(u => u.FileName == f)).Where(f => f != null).ToList();
|
||||
var propertyFiles = propDef.EditorState.FileNames.Select(f => uploadedFiles.FirstOrDefault(u => u.FileName != null && u.FileName.Equals(f, StringComparison.OrdinalIgnoreCase))).Where(f => f != null).ToList();
|
||||
if(propertyFiles.Any())
|
||||
{
|
||||
additionalData["files"] = propertyFiles;
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using Archetype.Extensions;
|
||||
using Archetype.Models;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Archetype.TypeConverters
|
||||
{
|
||||
public class ArchetypeFieldsetModelConverter : TypeConverter
|
||||
{
|
||||
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
|
||||
{
|
||||
if (destinationType == typeof(IPublishedContent) ||
|
||||
destinationType == typeof(ArchetypePublishedContent))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (destinationType == typeof(string))
|
||||
{
|
||||
// NOTE: The converter needs to return false here, otherwise `ArchetypeHelper.DeserializeJsonToArchetype` fails.
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.CanConvertTo(context, destinationType);
|
||||
}
|
||||
|
||||
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
|
||||
{
|
||||
if (value is ArchetypeFieldsetModel && (destinationType == typeof(IPublishedContent) || destinationType == typeof(ArchetypePublishedContent)))
|
||||
{
|
||||
return ((ArchetypeFieldsetModel)value).ToPublishedContent();
|
||||
}
|
||||
|
||||
return base.ConvertTo(context, culture, value, destinationType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using Archetype.Extensions;
|
||||
using Archetype.Models;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Archetype.TypeConverters
|
||||
{
|
||||
public class ArchetypeModelConverter : TypeConverter
|
||||
{
|
||||
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
|
||||
{
|
||||
if (destinationType == typeof(ArchetypePublishedContentSet) ||
|
||||
destinationType == typeof(IEnumerable<IPublishedContent>))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.CanConvertTo(context, destinationType);
|
||||
}
|
||||
|
||||
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
|
||||
{
|
||||
if (value is ArchetypeModel && (destinationType == typeof(ArchetypePublishedContentSet) || destinationType == typeof(IEnumerable<IPublishedContent>)))
|
||||
{
|
||||
return ((ArchetypeModel)value).ToPublishedContentSet();
|
||||
}
|
||||
|
||||
return base.ConvertTo(context, culture, value, destinationType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -211,6 +211,16 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc
|
||||
|
||||
}
|
||||
|
||||
// Checks if the specified array of fieldsets contains the specified fieldset.
|
||||
function arrayContainsFieldset(fieldset, fieldsets) {
|
||||
for (var i = 0; i < fieldsets.length; i++) {
|
||||
if (fieldsets[i] === fieldset) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Confirms that an array of properties is a subset of another array of properties.
|
||||
function arePropertiesSubset(subset, superset) {
|
||||
|
||||
@@ -857,12 +867,15 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc
|
||||
// The source scope is the scope of the fieldset being dragged.
|
||||
// The target scope is the scope of the Archetype to drop into.
|
||||
function canMove(sourceScope, targetScope) {
|
||||
var targetFieldsets = targetScope.model.config.fieldsets;
|
||||
var targetFieldsetConfigs = targetScope.model.config.fieldsets;
|
||||
var targetFieldsets = targetScope.model.value.fieldsets;
|
||||
var sourceFieldset = sourceScope.fieldset;
|
||||
var sameArchetype = arrayContainsFieldset(sourceFieldset, targetFieldsets);
|
||||
var model = sourceScope.fieldsetConfigModel;
|
||||
var canRemove = sourceScope.canRemove();
|
||||
var canAdd = targetScope.canAdd();
|
||||
var valid = canRemove && canAdd;
|
||||
valid = valid && modelMatchesAnyFieldset(model, targetFieldsets);
|
||||
var valid = sameArchetype || (canRemove && canAdd);
|
||||
valid = valid && modelMatchesAnyFieldset(model, targetFieldsetConfigs);
|
||||
return valid;
|
||||
}
|
||||
|
||||
|
||||
@@ -123,16 +123,17 @@ angular.module("umbraco.directives").directive('archetypeProperty', function ($c
|
||||
});
|
||||
|
||||
scope.$on('archetypeFormSubmitting', function (ev, args) {
|
||||
if(args.action !== 'save') {
|
||||
// validate all fieldset properties
|
||||
_.each(scope.fieldset.properties, function (property) {
|
||||
archetypeService.validateProperty(scope.fieldset, property, configFieldsetModel);
|
||||
});
|
||||
// #385 - revert the changes made in #311 to avoid publishing invalid fieldsets (leaving the code from #311 here, in case we figure out how to re-introduce "save as draft")
|
||||
// if(args.action !== 'save') {
|
||||
// validate all fieldset properties
|
||||
_.each(scope.fieldset.properties, function (property) {
|
||||
archetypeService.validateProperty(scope.fieldset, property, configFieldsetModel);
|
||||
});
|
||||
|
||||
var validationKey = "validation-f" + scope.fieldsetIndex;
|
||||
var validationKey = "validation-f" + scope.fieldsetIndex;
|
||||
|
||||
ngModelCtrl.$setValidity(validationKey, scope.fieldset.isValid);
|
||||
}
|
||||
ngModelCtrl.$setValidity(validationKey, scope.fieldset.isValid);
|
||||
// }
|
||||
|
||||
// did the value change (if it did, it most likely did so during the "formSubmitting" event)
|
||||
var property = archetypeService.getFieldsetProperty(scope);
|
||||
|
||||
Reference in New Issue
Block a user